能力值:
( LV2,RANK:10 )
|
-
-
2 楼
no,由于PC的指令编码长度是可变的,所以,在反汇编的时候,就存在着指令切分的问题。如果切分不正确,则得到的指令就会不正确。所有的花指令都和跳转有关系,正常情况下,跳转指令落脚的位置,应该恰好就是指令边界,这样,反汇编时的指令切分就不会有问题。而如果加入无效指令,对反汇编器的指令切分加以干扰,让跳转指令看上去没有落脚在指令边界上,结果,你就无法看到跳转后的下一条指令。而这些,仅仅能迷惑人和反汇编器,对CPU却毫无影响,因为CPU是按执行顺序而不是逻辑顺序来解析指令的,因此,总是能正确地加载和执行每一条指令。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
反汇编的时候也是根据不同的opcode来识别指令的长度然后计算下一条指令的地址,而cpu执行指令的时候也是得到本条指令的长度得到下一条指令的开始地址,这个过程是一样的呀?不明白你说的执行顺序和逻辑顺序?
|
能力值:
( LV3,RANK:30 )
|
-
-
4 楼
花指令如果被执行了一般是对程序逻辑没有影响的指令
花指令如果没有被执行的话一般是在某个正常指令的前面加一个字节,使得OD等软件反汇编起来很麻烦,很容易看出来的,nop掉就行了
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
CPU 对指令的执行在没有跳转指令的情况下会严格按照由前向后逐条按顺序进行,遇到跳转指令这个顺序会被打乱。所以,由前向后是指令的逻辑顺序,而在跳转指令的作用下,这个顺序会被打乱,于是,就有了执行顺序。
反汇编对代码的解析也是按照由前往后的顺序进行的,一条指令的解析结果直接影响到后续指令的解析,花指令就是利用了这个特点,让垃圾指令和跳转指令配合达到混淆后续操作码、操作数,从而干扰静态分析代码的目的。
现举例说明:
【代码1】:
00406760 E8 01000000 call 00406766
00406765 90 nop
00406766 83C4 04 add esp, 4
00406769 8B83 2C030000 mov eax, dword ptr [ebx+32C]
0040676F |. E8 14F70800 call 00495E88
00406774 |. 8D45 B0 lea eax, dword ptr [ebp-50]
00406777 |. 8B00 mov eax, dword ptr [eax]
00406779 |. 33D2 xor edx, edx
【代码2】:
00406760 E8 01000000 call 00406766
00406765 E8 83C4048B call 8B452BED
0040676A |? 832C03 00 sub dword ptr [ebx+eax], 0
0040676E |? 00E8 add al, ch
00406770 |? 14 F7 adc al, 0F7
00406772 |? 0800 or byte ptr [eax], al
00406774 |. 8D45 B0 lea eax, dword ptr [ebp-50]
00406777 |. 8B00 mov eax, dword ptr [eax]
00406779 |. 33D2 xor edx, edx
【代码1】是正常反汇编的结果,【代码2】是加入了花指令干扰的结果。可以看到,由于在内存地址 00406765 加入了垃圾指令 e8 从而导致从这一地址开始,一直到 00406774 地址处的一系列指令错乱。其原因很简单,因为垃圾指令 e8 是 5 字节指令,反汇编器会把 e8 后续的4个字节作为操作数对待,然后继续解析后续指令,从而造成了一系列操作码、操作数错位,使反汇编结果出现混乱。由于 e8 的前一条指令具有无条件跳转性质,恰好跳过了这个指令,所以,这个 e8 指令永远都没有机会被执行。
与反汇编器相比,CPU 不需要逐条对指令进行反汇编,只需要解析和执行当前指令,定位和解析、加载下一条指令,不执行的指令根本不予理会,因而花指令的存在丝毫不会影响到CPU对指令的正确加载与执行。
00406760 E8 01000000 call 00406766
00406765 E8 83C4048B call 8B452BED
CPU 在执行 00406760 处的指令时,会将其调用地址 00406766 处的指令作为下一条指令加载和执行,然后,会按顺序继续加载 00406769、0040676F、00406774 处的指令继续执行,而不会像在反汇编器中呈现的那样,好像要按顺序执行后续的 00406765 、0040676A 、0040676E 等处的指令。 所以,CPU 永远都能找到正确的下一条指令,永远不会犯错,会犯错的只能是反汇编器,因为它还不是足够聪明,搞不清楚哪些是用来执行的指令,哪些是用来捣乱的指令,因而表现比较笨拙和被动。
【代码1】和【代码2】虽然在形式上存在着很大的不同,但是,两段代码执行的指令内容及指令顺序完全相同,不存在任何区别,由此我们得出结论,反汇编得到的代码并不一定就是CPU实际要执行的代码,对于存在花指令的程序,尤其如此。
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
gooddddddddd
|
|
|