Assembly 查看x86机器代码,如何确定下一条指令的起始位置?

Assembly 查看x86机器代码,如何确定下一条指令的起始位置?,assembly,x86,disassembly,machine-code,Assembly,X86,Disassembly,Machine Code,x86机器代码中的指令长度可变。我已经仔细研究过了。我已经读到了。但到目前为止,我在研究中没有看到处理器如何知道一条指令的结束和下一条指令的开始(可能我遗漏了什么) 采取以下行动: XOR CL, [12H] = 00110010 00001110 00010010 00000000 = 32H 0EH 12H 00H XOR CL, 12H = 10000000 11110001 00010010 = 80 F1 12 如果我在看: 00110010 00001110 00010010 00

x86机器代码中的指令长度可变。我已经仔细研究过了。我已经读到了。但到目前为止,我在研究中没有看到处理器如何知道一条指令的结束和下一条指令的开始(可能我遗漏了什么)

采取以下行动:

XOR CL, [12H] = 00110010 00001110 00010010 00000000 = 32H 0EH 12H 00H
XOR CL, 12H = 10000000 11110001 00010010 = 80 F1 12
如果我在看:

00110010 00001110 00010010 00000000 10000000 11110001 00010010 ... 32H 0EH 12H 00H 80 F1 12 ... ^ How do I know the next instruction starts here? 00110010 00001110 00010010 00000000 10000000 11110001 00010010 ... 32H 0EH 12H 00H 80 F1 12。。。 ^ 我如何知道下一条指令从这里开始? 当我在研究网络中的OSI模型时,数据包将通过在每个组件的开头包含一个值来解决可变层大小的问题,告诉您层将包含多少内容。但CPU指令比数据包紧凑得多,而且似乎不包含数据包

为什么??我到底想做什么,真的

我的目标是分析程序的机器代码(没有反汇编程序——我需要最大的处理速度来分析大量数据,反汇编程序做的工作比我需要做的更多,比如将二进制语法映射到字符串语法),并记录所用操作码的某些统计信息。但我显然必须弄清楚一条指令在哪里结束,下一条指令在哪里开始


查看x86机器代码,如何确定下一条指令的起始位置?

没有明确的标记。您需要依次解码每条指令。每条指令都有一定的长度,下一条指令紧跟其后


如果查看更现代的可变长度编码(如UTF-8),您会发现它们比x86指令集的定义更具逻辑性。这只是经验教训的结果。ARM也学到了这一课,并将所有指令都设置为32位。

没有明确的标记。您需要依次解码每条指令。每条指令都有一定的长度,下一条指令紧跟其后


如果查看更现代的可变长度编码(如UTF-8),您会发现它们比x86指令集的定义更具逻辑性。这只是经验教训的结果。ARM也吸取了教训,并将所有指令都设置为32位。

不幸的是,没有简单的方法可以做到这一点。你不需要编写一个完整的反汇编程序,但是你需要在你的程序中有指令编码表,以便为任意指令编写一个长度解码器,考虑到它的起始地址。请注意,模糊化的可执行文件可能会使静态反汇编变得困难:如果您只是从
.text
部分的顶部开始,就像
objdump-d
所做的那样,那么您假设不会有任何跳转回到您认为是指令的中间,或者,如果不跳过跳过的字节,则转发到解码方式不同的内容:。但是,对于普通编译器(如GCC和clang)生成的x86可执行文件,线性反汇编是不错的;他们不会混合数据和代码。@PeterCordes我的项目实际上是围绕着克服混淆的概念展开的,所以这已经是我一直在寻找的东西了。攻击者的混淆技术可以重定向控制流的次数没有限制,如果它选择,它可以在每条指令之间重定向,甚至可以将
jmp
重定向到另一条
jmp
。我将从大量无辜的可执行代码中建立一个基线,我相信任何极端级别的控制流重定向都应该脱颖而出。任何非极端的东西都不会妨碍分析。@J.Todd:请注意,模糊处理可以使用
jcc
处理无法轻松静态计算的值;您必须实际运行该程序才能知道它是否一直被使用。此外,只需一个
jmp
就可以使解码不同步,并为多条指令提供“错误”解码,直到解码恢复同步(虽然通常x86机器代码不是自同步的,并且理论上可以构造一个字节串,在公共insn结束点之前很长一段时间内以两种不同的方式进行解码,但在实践中,这往往会发生在多条指令中)@PeterCordes感谢您的提醒,这是有效的,但是:他们只能在可执行文件的控制流操作比率远远超过任何可执行文件中正常操作的平均值之前,在一定程度上做到这一点,我可以明确地标记该文件值得一看(一些假阳性分析是可以接受的)。除此之外,我正在分析逻辑中的某些关系模式,我认为攻击者无法完全混淆,而不会触发某些明确的“这看起来可疑”阈值。不幸的是,没有简单的方法可以做到这一点。您不需要编写一个完整的反汇编程序来实现这一点,但您的程序中确实需要有指令编码表,以便为给定起始地址的任意指令编写长度解码器。请注意,混淆的可执行文件可能会使静态反汇编变得困难汇编:如果您只是从
.text
部分的顶部开始,如
objdump-d
所做的那样,那么您假设不会有任何跳转回到您认为是一条指令的中间,或者如果不跳过跳转的字节,就不会跳转到解码方式不同的地方:。线性反汇编适用于x86执行但是,由GCC和clang等普通编译器生成的代码;它们不会混合数据和代码。@PeterCordes我的项目实际上围绕着击败混淆的概念,所以这已经是我一直在寻找的东西。攻击者的混淆技术可以重定向控制流的次数没有限制,它可以在每个指令,如果它选择的话,甚至
jmp
到另一个
jmp
。我将在