这是从(可能)用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
两次
答案 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