假设我有带有用于unknow CPU的代码的二进制文件,我可以以某种方式检测cpu体系结构吗?我知道这主要取决于编译器,但我认为对于大多数CPU架构,它应该有大量的CALL / RETN / JMP / PUSH / POP操作码(统计上要比其他更多)。还是应该在特定于CPU的代码中搜索某些模式(而不是出现操作码)?

评论

如果您有二进制文件,但不知道哪个CPU,那么如何查看操作码?如果您知道如何将二进制文件转换为操作码,那么您已经知道您拥有哪个CPU。 (或至少是哪个家族,例如Z80,Intel,ARM,摩托罗拉MC-680XX。)

阅读魔术,然后阅读文件格式。

1)(Stolas)在嵌入中,您通常没有魔法,或者魔法是他们发明的。 2)(Jongware)您可以看到操作码(常见的字节模式)而实际上不知道它们是什么,几乎可以像确定文件是否被压缩或加密而无法解密或解压缩的方式相同。
@jongware我认为您将操作码与汇编器指令相混淆。

@ n3vermind:..如果您不知道CPU,那么如何确定正在查看“操作码”?例如,ARM很简单(所有操作码均为4字节,大多数以0xE0开头),但要考虑使用Thumb模式。统计方法可能会起作用-但即使您知道CPU类型,也总是会遇到使代码/数据二分法变得困难的代码/数据二分法。

#1 楼

当您用锤子敲打时,所有问题看起来都像钉子...

前一段时间,我研究了一种称为归一化压缩距离-NCD的东西,如果有的话,我会尝试一下一个与您类似的问题。


我将建立示例数据库。对于每个要了解的体系结构,将采用20个程序,并以可变大小保存它们。示例。
我会选择最佳的(较小的)NCD,然后验证它是否是真正的匹配项(例如,尝试在发现的体系结构上运行它)。

更新

关于NCD,我总是手工完成。我是怎么做到的:


您有20个SPARC文件,并且将它们称为A01,A02,A03,依此类推。您的x86文件:B01,B02等。
您获得了未知文件,并将其命名为XX。
选择您喜欢的压缩工具(我使用了Gzip,但在此答案的结尾处有备注)。 br />计算第一对NCD:

NCD(XX,A01)=(Z(XX + A01)-min(Z(XX),Z(A01))/ max(Z( XX),Z(A01))

Z(something)->表示您使用Gzip压缩了某物,并在压缩后获得了文件大小,例如8763字节,因此Z(something)= 8763.

XX + A01->表示将所有内容连接在一起。您将A01文件附加到XX文件的末尾。在Linux中,您可以执行“ cat XX A01> XXA01”。 br />
min()和max()->您可以计算XX和A01的压缩大小,并使用获得的最小值和最大值。

因此,您将获得一个NCD值:介于0到1之间,并使用尽可能多的小数位,因为有时差异在7位数或8位数之间,就像比较0.999999887与0.999999524。

您会为e做非常文件,因此SPARC的NCD结果为20,x86的结果为20 ...

获得所有较小的NCD。假设B07文件为您提供了较小的NCD。因此,unknow文件可能是x86。

提示:


您的unknow和测试文件的大小必须相似。当您比较一个文件的大小时,NCD不会神奇。因此,如果您要测试5到10k的文件,我会得到2.5k,5k,7.5k,10k,12.5k的测试文件...
在我的硕士学位课程中,我总是使用NCD值越小。第二个最好的方法是进行投票:获得5个较小的NCD结果,并查看哪个体系结构获得了更多投票。例如:较小的NCD分别为A03,A05,B02,B06,B07-> B投3票,所以我说这是一个x86 ...基于Zip构造的压缩器的限制为32kB:在压缩事物时,他们一次只考虑32kB。如果您的XX + A01大于此值,则Gzip,Zip等将不会为您带来良好的效果。因此,对于大于15或16kB的文件,我会选择其他压缩器:PPMD,Bzip ...


评论


好主意。过去,我在其他分类问题上也取得了不错的成绩。

– 0xC0000022L♦
13年10月8日在18:12

@woliveirajr您对计算NCD的工具或库有任何建议吗?到目前为止,我发现CompLearn实用程序看起来很有前途。

– n3vermind
13-10-8在19:43

@ n3vermind我已经更新了我的答案:我想您可以使用CompLearn,但是由于我想要更多的控制权(例如要使用的压缩机),因此我做了一个小程序来满足我的需要。我解释了它是如何工作的...

–woliveirajr
13-10-9在11:58

@woliveirajr您是否有指向硕士论文的链接?我很想过去

–koukouviou
17-2-22在6:56

@koukouviou对不起,现在找不到它了(无论如何它是葡萄牙语)。但是,这是我们撰写的一篇文章:inf.ufpr.br/lesoliveira/download/FSI2013.pdf-请让我知道我是否可以为您提供帮助或提供更多信息。

–woliveirajr
17-2-24在17:08



#2 楼

有一些工具可以扫描二进制文件以查找各种体系结构中的常见操作码。 Binwalk的-A选项例如执行此操作(它扫描ARM / MIPS / x86和其他几种体系结构)。

#3 楼

通常,我首先尝试最常用的CPU(ARM,PPC,MIPS和AVR),尝试查找是否有任何纯字符串表示有关处理器的信息,等等。然后,当所有其他失败时,我尝试进行以下操作:您需要什么:操作码的统计分析(如果我确定它既未加密也未压缩)。

我建议您阅读Alexander Chernov和Katerina Troshina的演讲“逆向工程自定义虚拟机的二进制程序”。编写像他们编写的那样的工具一定很辛苦(我想),但是编写一种工具来尝试确定使用该演示文稿中描述的技术似乎要编译哪个CPU并不难(只要您可以收集足够的信息)多种不同架构的示例)。

#4 楼

我的懒惰黑客:一个小的Python脚本,用于计算bigram和trigram计数。然后,我在Google上搜索了两个最常见的序列(称为hex)。我经常设法找到一些十六进制转储,并且可以从上下文中确定CPU。如果Google可以按原始二进制值进行搜索,效果会更好...

评论


可能是我迟到了,但是此站点具有Python API,并且肯定可以搜索原始二进制值:binar.ly/search

–安东·科赫科夫(Anton Kochkov)
16年7月20日在20:36

@AntonKochkov谢谢,看起来很有趣!太糟糕了,似乎只索引了恶意软件...

–伊戈尔·斯科钦斯基♦
16年7月21日在7:33

#5 楼

尚未提及的另外两种方法。
binwalk的反汇编扫描
Disassembly Scan Options:
    -Y, --disasm                 Identify the CPU architecture of a file using the capstone disassembler
    -T, --minsn=<int>            Minimum number of consecutive instructions to be considered valid (default: 500)
    -k, --continue               Don't stop at the first match


示例输出(图像为ARM LE):
$ binwalk -Yk image.img

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
3             0x3             ARM executable code, 32-bit, big endian, at least 726 valid instructions
1048576       0x100000        ARM executable code, 32-bit, little endian, at least 1250 valid instructions
2099012       0x200744        ARM executable code, 32-bit, little endian, at least 846 valid instructions
3158316       0x30312C        ARM executable code, 32-bit, little endian, at least 899 valid instructions
4201328       0x401B70        ARM executable code, 32-bit, little endian, at least 1250 valid instructions
5253066       0x5027CA        ARM executable code, 16-bit (Thumb), big endian, at least 2499 valid instructions
6308406       0x604236        ARM executable code, 16-bit (Thumb), little endian, at least 2499 valid instructions

cpu_rec
既可以用作独立工具,也可以用作binwalk模块。
binwalk用法:
Statistical CPU guessing Options:
    -%, --markov                 Identify the CPU opcodes in a file using statistical analysis

示例输出,用作binwalk模块(图像为ARM LE):
$ binwalk -% image.img

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             None (size=0x800, entropy=0.757822)
2048          0x800           CLIPPER (size=0x800, entropy=0.728492)
4096          0x1000          None (size=0x2000, entropy=0.129643)
12288         0x3000          ARMel (size=0x35c000, entropy=0.795123)
3534848       0x35F000        None (size=0x800, entropy=0.797443)
3536896       0x35F800        ARMel (size=0x16800, entropy=0.834972)
3629056       0x376000        None (size=0x800, entropy=0.764094)
3631104       0x376800        ARMel (size=0x16a000, entropy=0.797543)
5113856       0x4E0800        None (size=0x1800, entropy=0.841936)
5120000       0x4E2000        ARMel (size=0x1000, entropy=0.812677)
5124096       0x4E3000        None (size=0x1000, entropy=0.844949)
5128192       0x4E4000        ARMel (size=0xc000, entropy=0.792995)
5177344       0x4F0000        None (size=0x24000, entropy=0.763681)
5324800       0x514000        6502 (size=0x24000, entropy=0.974422)
5472256       0x538000        None (size=0x137800, entropy=0.728785)



#6 楼

机器学习可用于高度准确地识别机器代码的目标CPU。例如,ISAdetect工具可以使用机器学习识别针对23种不同体系结构的机器代码。有一个Web API,可以用来上传可执行的二进制文件或机器代码片段以供此工具分析。
本文讨论了ISAdetect实现的技术:
迈向可用的CPU自动检测任意二进制文件和目标代码序列的体系结构和字节序