太难,想看答案,不过点了好像要注册才能看,还是自己动手吧!
用Od载入停在这里:
00401288 > $ 6A 00 push 0
0040128A E8 db E8
0040128B EF db EF
0040128C FF db FF
0040128D FF db FF
0040128E FF db FF
0040128F A3 db A3
00401290 30314000 dd ReverseM.00403130
00401294 BF 11104000 mov edi, 00401011 ; 入口地址
00401299 . E8 71000000 call 0040130F ; 跟进
0040129E E8 6EFDFFFF call 00401011
可以发现此处是对00401000地址内容的异或解密(第一次解密)
0040130F /$ B8 00104000 mov eax, 00401000 ; 解密起始地址
00401314 |> 8030 5A xor byte ptr [eax], 5A ; 异或解密
00401317 |. 40 inc eax
00401318 |. 3D 18124000 cmp eax, <jmp.&USER32.BeginPaint> ; 入口地址
0040131D |.^ 7C F5 jl short 00401314
0040131F \. C3 retn ; 返回到0040129E
0040129E处的call,跟进,此处是第二次变相解密
00401011 $ 33C0 xor eax, eax ;
00401013 . 66:C707 6A00 mov word ptr [edi], 6A ; edi指向地址401011,此处是变相解密,将00401011至00401024处的内容改写
00401018 . 83C7 02 add edi, 2
0040101B ? C707 687D3040 mov dword ptr [edi], 40307D68 ;
00401021 83C7 04 add edi, 4
00401024 . C607 00 mov byte ptr [edi], 0
00401027 . 47 inc edi
00401028 . C707 68343040 mov dword ptr [edi], 40303468
0040102E . 83C7 04 add edi, 4
00401031 . C607 00 mov byte ptr [edi], 0
00401034 . 47 inc edi
00401035 . 66:C707 6A00 mov word ptr [edi], 6A
0040103A . 83C7 02 add edi, 2
0040103D . C707 E8300200 mov dword ptr [edi], 230E8
00401043 . 83C7 04 add edi, 4
00401046 . C607 00 mov byte ptr [edi], 0
00401049 . 47 inc edi
0040104A . 66:C707 EB44 mov word ptr [edi], 44EB
0040104F . 83EF 24 sub edi, 24 ;edi指向00401000
00401052 . FFD7 call edi ; call 00401000
00401054 . E8 C7020000 call 00401320
00401059 . E8 64020000 call 004012C2
0040105E . EB 15 jmp short 00401075
跟进00401000,很明显第三次解密
00401000 > /B8 00304000 mov eax, 00403000
00401005 > |8030 B3 xor byte ptr [eax], 0B3 ; 又一个解密,从地址可知是对字符串解密
00401008 . |40 inc eax
00401009 . |3D 28314000 cmp eax, 00403128
0040100E .^|7C F5 jl short 00401005
00401010 . |40 inc eax
00401011 $ |6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401013 . |68 7D304000 push 0040307D ;
00401018 . |68 34304000 push 00403034 ;
0040101D . |6A 00 push 0 ; |hOwner = NULL
0040101F |E8 30020000 call <jmp.&USER32.MessageBoxA> ; 不用说了,就是得把这个搞掉
00401024 . |EB 44 jmp short 0040106A ;
反复跟了几遍才发现这是个自修改的ReverseMe,有几次解密,相当麻烦,开始太急躁,修改了四个字节绕过了MessageBox,但是显示的字符串是乱码,后来耐着性子,才发现第三次解密是对字符串的解密。看来只能按要求做2个字节的补丁了。我想了半天,只有对0040101F处调用MessageBoxA进行处理,让他直接调用00401024处的jmp,这样就不会有MessageBox了。
因为这个ReverseMe有几处解密,0040101F先是由第一次使用异或解密,然后又通过第二次变相解密修改了0040101F处的内容,所以我们主要是对第二次解密的内容进行处理,也就是下边这一句:
0040103D . C707 E8300200 mov dword ptr [edi], 230E8
其中的E8就是CALL的机器码,要直接CALL当前指令的下一条语句直接用CALL 0就可以了,所以我们只要将上一条语句修改成
mov dword ptr [edi], 000E8
就可以了。这样很容易找到内存地址从0401040开始,修改两个字节,要使其经过与5A异或解密后为0,就将这两个字节修改成5A 5A就可以了。