看似不必要的循环

时间:2012-09-07 21:47:53

标签: visual-c++ assembly x86

这是从(可能)用MSVC创建的x86 exe中拆解的 这些循环的任何原因还是只是膨胀?

00428D08   |> B9 02000000    MOV ECX,2
00428D0D   |> 33C0           /XOR EAX,EAX
00428D0F   |> 8BF0           |/MOV ESI,EAX
00428D11   |. 48             ||DEC EAX
00428D12   |. 83F8 E9        ||CMP EAX,-17
00428D15   |.^7F F8          |\JG SHORT File.00428D0F
00428D17   |. 49             |DEC ECX
00428D18   |.^75 F3          \JNZ SHORT File.00428D0D

ESI后来用于某种跳转表,但在我看来,这似乎是一种过于复杂的方式来设置ESI两次

1 个答案:

答案 0 :(得分:2)

如果没有其他入口点且没有自修改代码,则可以通过一种独特的方式来执行代码:

mov ecx,2              ; ecx = 2
xor eax,eax            ; eax = 0, ecx = 2, SF = 0, ZF = 0
mov esi,eax            ; eax = 0, ecx = 2, esi = 0, no changes to flags
dec eax                ; eax = 0xFFFFFFFF, ecx = 2, esi = 0, SF = 1, ZF = 0
cmp eax,-17            ; OF = 0, SF = 1, ZF = 0
jg SHORT File.00428D0F ; jump if (SF==OF and ZF==0) -> jump.

mov esi, eax; eax = 0xFFFFFFFF,ecx = 2,esi = 0xFFFFFFFF ... 在16个内循环之后,情况如下:

mov esi,eax            ; eax = -16, ecx = 2, esi = -16
dec eax                ; eax = -17, ecx = 2, esi = -16, SF = 1, ZF = 0
cmp eax,-17            ; OF = 0, SF = 0, ZF = 1
jg SHORT File.00428D0F ; jump if (SF==OF and ZF==0) -> no jump.
dec ecx                ; eax = -17, esi = -16, ecx = 1, SF = 0, ZF = 0

外环非常简单。如果确定除了00428D08(此代码的开头mov ecx,2)之外没有其他入口点,那么代码不会从其他地方修改,并且该代码不用作数据,代码可以是替换为:

如果在此代码结束后使用flags'值:

mov eax,-17
cmp eax,-17
mov ecx,1
dec ecx
mov esi,-16

如果标志值不重要:

mov eax,-17
mov ecx,0
mov esi,-16