解密系列_调试篇_第21讲复现
-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n2]0x00. 分析-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n3]入口-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n7]第1次解密-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n11]第2次解密-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n18]第3次解密-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n26]第1次加密-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n33]第2次加密-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n38]退出-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n41]整体流程-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n53]0x01. 打补丁-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n55]第1种方法-%E8%B0%83%E8%AF%95%E7%AF%8721-%E5%8F%98%E5%BD%A2&%E5%A4%9A%E6%80%81%E7%97%85%E6%AF%92.html#header-n63]第2种方法0x00. 分析入口
00401288 > $6A 00 push 0
0040128A E8 db E80040128B EF db EF0040128C FF db FF0040128D FF db FF0040128E FF db FF0040128F A3 db A300401290 30314000 dd ReverseM.0040313000401294 .BF 11104000 mov edi, 0040101100401299 .E8 71000000 call 0040130F0040129E >E8 6EFDFFFF call 00401011
入口处指令需要去除分析,或者调试窗口-取消勾选自动对主模块进行分析。
00401288 >6A 00 push 0
0040128A E8 EFFFFFFF call <jmp.&KERNEL32.GetModuleHandleA>0040128F A3 30314000 mov dword ptr , eax00401294 BF 11104000 mov edi, 0040101100401299 E8 71000000 call 0040130F0040129E E8 6EFDFFFF call 00401011004012A3 33C0 xor eax, eax
第1次解密进入call 0040130F调用。
0040130F B8 00104000 mov eax, 00401000
00401314 8030 5A xor byte ptr , 5A00401317 40 inc eax00401318 3D 18124000 cmp eax, <jmp.&USER32.BeginPaint>0040131D^ 7C F5 jl short 004013140040131F C3 retn;信息面板00401218=<jmp.&USER32.BeginPaint>eax=00401002 (ReverseM.00401002)
这次调用是将0x00401000 ~ 0x00401218处的数据与0x5A异或。第2次解密进入call 00401011调用。
00401011 33C0 xor eax, eax ; ReverseM.00401218
00401013 66:C707 6A00 mov word ptr , 6A00401018 83C7 02 add edi, 20040101B C707 687D3040 mov dword ptr , 40307D6800401021 83C7 04 add edi, 400401024 C607 00 mov byte ptr , 000401027 47 inc edi00401028 C707 68343040 mov dword ptr , 403034680040102E 83C7 04 add edi, 400401031 C607 00 mov byte ptr , 000401034 47 inc edi00401035 66:C707 6A00 mov word ptr , 6A0040103A 83C7 02 add edi, 20040103D C707 E8300200 mov dword ptr , 230E800401043 83C7 04 add edi, 400401046 C607 00 mov byte ptr , 000401049 47 inc edi0040104A 66:C707 EB44 mov word ptr , 44EB ; 0x15 bytes at all0040104F 83EF 24 sub edi, 2400401052 FFD7 call edi00401054 E8 C7020000 call 0040132000401059 E8 64020000 call 004012C20040105E EB 15 jmp short 00401075
在第一次解密之前的入口部分,就有mov edi, 00401011,所以,第二次调用是将0x00401011 ~ 0x0x00401025部分解密,与第一次异或不同,这一次是纯替换。 而且,这部分代码其实是自己本身。下面是解密后内容指令。可以看到弹窗的标题和文本参数为乱码,这一部分后面应该还会解密。
00401011 $6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401013 .68 7D304000 push 0040307D ; |Title = 乱码00401018 .68 34304000 push 00403034 ; |Text = 乱码0040101D .6A 00 push 0 ; |hOwner = NULL0040101F .E8 30020000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA00401024 . /EB 44 jmp short 0040106A00401026 |00 db 0000401027 . |47 inc edi00401028 . |C707 68343040 mov dword ptr , 403034680040102E . |83C7 04 add edi, 400401031 . |C607 00 mov byte ptr , 000401034 . |47 inc edi00401035 . |66:C707 6A00mov word ptr , 6A0040103A . |83C7 02 add edi, 20040103D . |C707 E8300200 mov dword ptr , 230E800401043 . |83C7 04 add edi, 400401046 . |C607 00 mov byte ptr , 000401049 . |47 inc edi0040104A . |66:C707 EB44mov word ptr , 44EB0040104F . |83EF 24 sub edi, 2400401052 . |FFD7 call edi00401054 . |E8 C7020000 call 0040132000401059 . |E8 64020000 call 004012C20040105E . |EB 15 jmp short 00401075
进入0x00401052处的call edi调用,是第一次解密得到的指令。此时edi减去0x24后为0x00401000,第3次解密
00401000 > /B8 00304000 mov eax, 00403000
00401005 > |8030 B3 xor byte ptr , 0B300401008 . |40 inc eax00401009 . |3D 28314000 cmp eax, 004031280040100E .^|7C F5 jl short 0040100500401010 . |40 inc eax00401011 $6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL00401013 .68 7D304000 push 0040307D ; |Title = 乱码00401018 .68 34304000 push 00403034 ; |Text = 乱码0040101D .6A 00 push 0 ; |hOwner = NULL0040101F .E8 30020000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA00401024 . |EB 44 jmp short 0040106A
这一次是解密0x00403000 ~ 0x00403127的数据,而MessageBoxA()的标题和文本参数就在这一范围内。这一过程可以在数据窗口中观察。
00403000E1 D6 C5 D6 C1 C0 D6 FE D6 E7 C6 C7 DC C1 DA D2嶂胖晾筑昼魄芰谝
00403010DF B3 E1 D6 C5 D6 C1 C0 D6 FE D6 E7 C6 C7 DC C1叱嶂胖晾筑昼魄芰00403020DA D2 DF 89 93 E1 D6 DE DC C5 D6 93 C7 DB D6 93谝邏撫洲芘謸芹謸00403030DD D2 D4 B3 EA DC C6 93 DD D6 D6 D7 93 C7 DC 93菀猿贶茡葜肿撉軗00403040C1 D6 DE DC C5 D6 93 C7 DB D6 93 DD D2 D4 BE B9林捃胖撉壑撦以竟00403050E7 C1 CA 93 C7 DC 93 D7 DC 93 DA C7 93 DA DD 93缌蕮擒撟軗谇撢輷
解密后:
0040300052 65 76 65 72 73 65 4D 65 54 75 74 6F 72 69 61ReverseMeTutoria
004030106C 00 52 65 76 65 72 73 65 4D 65 54 75 74 6F 72l.ReverseMeTutor0040302069 61 6C 3A 20 52 65 6D 6F 76 65 20 74 68 65 20ial: Remove the004030306E 61 67 00 59 6F 75 20 6E 65 65 64 20 74 6F 20nag.You need to0040304072 65 6D 6F 76 65 20 74 68 65 20 6E 61 67 0D 0Aremove the nag..0040305054 72 79 20 74 6F 20 64 6F 20 69 74 20 69 6E 20Try to do it in00401010 .40 inc eax ;ReverseM.0040312800401011 $6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL00401013 .68 7D304000 push 0040307D ; |Title = "TutorialNag"00401018 .68 34304000 push 00403034 ; |Text = "You need to remove the nag",CR,LF,"Try to do it in a two byte patch. ",CR,LF,"Regards!"0040101D .6A 00 push 0 ; |hOwner = NULL0040101F .E8 30020000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA00401024 .EB 44 jmp short 0040106A
往下执行,就可以弹出第一个NAG窗口了。第1次加密0x00401024处jmp short 0040106A后,edi值仍为0x00401000,指令如下:
0040106A >83C7 11 add edi, 11
0040106D .66:C707 6A0Amov word ptr , 0A6A00401072 .83C7 02 add edi, 200401075 >C707 FF353431 mov dword ptr , 313435FF0040107B .83C7 04 add edi, 40040107E .66:C707 4000mov word ptr , 4000401083 .83C7 02 add edi, 200401086 .66:C707 6A00mov word ptr , 6A0040108B .83C7 02 add edi, 20040108E .C707 FF353031 mov dword ptr , 313035FF00401094 .83C7 04 add edi, 400401097 .66:C707 4000mov word ptr , 400040109C .83C7 02 add edi, 20040109F .C707 E8900000 mov dword ptr , 90E8004010A5 .83C7 04 add edi, 4004010A8 .C607 00 mov byte ptr , 0004010AB .47 inc edi004010AC .66:C707 EB2Cmov word ptr , 2CEB ;0x17 bytes at all004010B1 .83EF 15 sub edi, 15004010B4 .FFD7 call edi
这一部分是将0x00401011 ~ 0x00401027的指令加密。最后call edi时,减去0x15,edi的值又变回0x00401011。
00401011 $6A 0A push 0A
00401013 .FF35 34314000 push dword ptr 00401019 .6A 00 push 00040101B .FF35 30314000 push dword ptr ;ReverseM.0040000000401021 .E8 90000000 call 004010B600401026 .EB 2C jmp short 00401054
执行后,弹出了第2个NAG窗口,然后跳到0x00401054。第2次加密
00401054 >E8 C7020000 call 00401320
00401059 .E8 64020000 call 004012C20040105E .EB 15 jmp short 00401075
上面的指令是第1,2次解密得到的。
00401320/$B8 00304000 mov eax, 00403000 ;ASCII "ReverseMeTutorial"
00401325|>8030 8D /xor byte ptr , 8D00401328|.40 |inc eax00401329|.3D 28314000 |cmp eax, 004031280040132E|.^ 7C F5 \jl short 0040132500401330\.C3 retn
加密0x00403000 ~ 0x00403127的数据,注意我们第2次解密的时候是与0xB3异或。退出上一次加密后返回,调用0x004012c2。
004012C2/$50 push eax ; /ExitCode = 403128
004012C3\.E8 B0FFFFFF call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess
整体流程
[*]0040130F:解密0x00401000 ~ 0x00401218(XOR 0x5A)
[*]00401011 :解密0x00401011 ~ 0x0x00401025
[*]00401000:解密0x00403000 ~ 0x00403127(含窗口标题和文本)
[*]0040106A:加密0x00401011 ~ 0x00401027
[*]00401320:加密0x00403000 ~ 0x00403127
0x01. 打补丁我们的目的是把第一个NAG去掉,即由第2次解密得到、第3次解密之后马上执行的0x0040101F处的call指令。第1种方法一个方法是使MessageBoxA()的第一个参数hOwner即父句柄无效:6A 00 | push 0x0改为6A 0A | push 0x1。这句参数入栈的指令是由第2次解密时的这一句得到的。
00401035 66:C707 6A00 mov word ptr , 6A
直接改为mov word ptr , 0x016A是行不通滴,因为66:C707 6A00这一句指令又是由第一次解密时与0x5A异或得到哒 (- 。-)! 我们需要算一下与0x5A异或后得到0x01的字节。0x01 ^ 0x5A == 0x5B,那么在运行前改把00401039的0x5A为5B就行了。
00401034 1D 3C9D5D30 sbb eax, 305D9D3C
00401039 5B pop ebx
保存后执行,成功地直接显示第二个NAG窗口。第2种方法在弹窗之前,直接执行下面的跳转。
00401011 6A 00 push 0
00401013 |68 7D304000 push 0040307D ; ASCII "TutorialNag"00401018 |68 34304000 push 00403034 ; ASCII "You need to remove the nag",CR,LF,"Try to do it in a two byte patch. ",CR,LF,"Regards!"0040101D |6A 00 push 00040101F |E8 30020000 call <jmp.&USER32.MessageBoxA>
修改后:00401011 EB 57 jmp short 0040106AEB 57 XOR 5A == B1 0D ,所以回到找到第2次解密中对应的指令。
00401013 66:C707 6A00 mov word ptr , 6A
00401018 83C7 02 add edi, 2
回到运行前的00401016。
00401016 305A D9 xor byte ptr , bl
这里验证一下,30 5A XOR 5A == 6a 00,那么动手:
00000416 B1 0D mov cl, 0D
保存到执行文件,备份,成功去除第一个NAG。
不好意思排版乱了{:10_266:}发之前好好的 这...........{:10_266:}{:10_266:}{:10_266:}{:10_266:} 把你排好的版面文字直接复制到代码块里发布就好了。
0x00. 分析
入口
00401288 > [ DISCUZ_CODE_5 ]nbsp; 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
入口处指令需要去除分析,或者调试窗口-取消勾选自动对主模块进行分析。
00401288 >6A 00 push 0
0040128A E8 EFFFFFFF call <jmp.&KERNEL32.GetModuleHandleA>
0040128F A3 30314000 mov dword ptr , eax
00401294 BF 11104000 mov edi, 00401011
00401299 E8 71000000 call 0040130F
0040129E E8 6EFDFFFF call 00401011
004012A3 33C0 xor eax, eax
第1次解密
进入call 0040130F调用。
0040130F B8 00104000 mov eax, 00401000
00401314 8030 5A xor byte ptr , 5A
00401317 40 inc eax
00401318 3D 18124000 cmp eax, <jmp.&USER32.BeginPaint>
0040131D^ 7C F5 jl short 00401314
0040131F C3 retn
;信息面板
00401218=<jmp.&USER32.BeginPaint>
eax=00401002 (ReverseM.00401002)
这次调用是将0x00401000 ~ 0x00401218处的数据与0x5A异或。
第2次解密
进入call 00401011调用。
00401011 33C0 xor eax, eax ; ReverseM.00401218
00401013 66:C707 6A00 mov word ptr , 6A
00401018 83C7 02 add edi, 2
0040101B C707 687D3040 mov dword ptr , 40307D68
00401021 83C7 04 add edi, 4
00401024 C607 00 mov byte ptr , 0
00401027 47 inc edi
00401028 C707 68343040 mov dword ptr , 40303468
0040102E 83C7 04 add edi, 4
00401031 C607 00 mov byte ptr , 0
00401034 47 inc edi
00401035 66:C707 6A00 mov word ptr , 6A
0040103A 83C7 02 add edi, 2
0040103D C707 E8300200 mov dword ptr , 230E8
00401043 83C7 04 add edi, 4
00401046 C607 00 mov byte ptr , 0
00401049 47 inc edi
0040104A 66:C707 EB44 mov word ptr , 44EB ; 0x15 bytes at all
0040104F 83EF 24 sub edi, 24
00401052 FFD7 call edi
00401054 E8 C7020000 call 00401320
00401059 E8 64020000 call 004012C2
0040105E EB 15 jmp short 00401075
在第一次解密之前的入口部分,就有mov edi, 00401011,所以,第二次调用是将0x00401011 ~ 0x0x00401025部分解密,与第一次异或不同,这一次是纯替换。 而且,这部分代码其实是自己本身。
下面是解密后内容指令。可以看到弹窗的标题和文本参数为乱码,这一部分后面应该还会解密。
00401011 [ DISCUZ_CODE_659 ]nbsp; 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401013 .68 7D304000 push 0040307D ; |Title = 乱码
00401018 .68 34304000 push 00403034 ; |Text = 乱码
0040101D .6A 00 push 0 ; |hOwner = NULL
0040101F .E8 30020000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00401024 . /EB 44 jmp short 0040106A
00401026 |00 db 00
00401027 . |47 inc edi
00401028 . |C707 68343040 mov dword ptr , 40303468
0040102E . |83C7 04 add edi, 4
00401031 . |C607 00 mov byte ptr , 0
00401034 . |47 inc edi
00401035 . |66:C707 6A00mov word ptr , 6A
0040103A . |83C7 02 add edi, 2
0040103D . |C707 E8300200 mov dword ptr , 230E8
00401043 . |83C7 04 add edi, 4
00401046 . |C607 00 mov byte ptr , 0
00401049 . |47 inc edi
0040104A . |66:C707 EB44mov word ptr , 44EB
0040104F . |83EF 24 sub edi, 24
00401052 . |FFD7 call edi
00401054 . |E8 C7020000 call 00401320
00401059 . |E8 64020000 call 004012C2
0040105E . |EB 15 jmp short 00401075
进入0x00401052处的call edi调用,是第一次解密得到的指令。此时edi减去0x24后为0x00401000,
第3次解密
00401000 > /B8 00304000 mov eax, 00403000
00401005 > |8030 B3 xor byte ptr , 0B3
00401008 . |40 inc eax
00401009 . |3D 28314000 cmp eax, 00403128
0040100E .^|7C F5 jl short 00401005
00401010 . |40 inc eax
00401011 [ DISCUZ_CODE_660 ]nbsp; 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401013 .68 7D304000 push 0040307D ; |Title = 乱码
00401018 .68 34304000 push 00403034 ; |Text = 乱码
0040101D .6A 00 push 0 ; |hOwner = NULL
0040101F .E8 30020000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00401024 . |EB 44 jmp short 0040106A
这一次是解密0x00403000 ~ 0x00403127的数据,而MessageBoxA()的标题和文本参数就在这一范围内。
这一过程可以在数据窗口中观察。
00403000E1 D6 C5 D6 C1 C0 D6 FE D6 E7 C6 C7 DC C1 DA D2嶂胖晾筑昼魄芰谝
00403010DF B3 E1 D6 C5 D6 C1 C0 D6 FE D6 E7 C6 C7 DC C1叱嶂胖晾筑昼魄芰
00403020DA D2 DF 89 93 E1 D6 DE DC C5 D6 93 C7 DB D6 93谝邏撫洲芘謸芹謸
00403030DD D2 D4 B3 EA DC C6 93 DD D6 D6 D7 93 C7 DC 93菀猿贶茡葜肿撉軗
00403040C1 D6 DE DC C5 D6 93 C7 DB D6 93 DD D2 D4 BE B9林捃胖撉壑撦以竟
00403050E7 C1 CA 93 C7 DC 93 D7 DC 93 DA C7 93 DA DD 93缌蕮擒撟軗谇撢輷
解密后:
0040300052 65 76 65 72 73 65 4D 65 54 75 74 6F 72 69 61ReverseMeTutoria
004030106C 00 52 65 76 65 72 73 65 4D 65 54 75 74 6F 72l.ReverseMeTutor
0040302069 61 6C 3A 20 52 65 6D 6F 76 65 20 74 68 65 20ial: Remove the
004030306E 61 67 00 59 6F 75 20 6E 65 65 64 20 74 6F 20nag.You need to
0040304072 65 6D 6F 76 65 20 74 68 65 20 6E 61 67 0D 0Aremove the nag..
0040305054 72 79 20 74 6F 20 64 6F 20 69 74 20 69 6E 20Try to do it in
00401010 .40 inc eax ;ReverseM.00403128
00401011 [ DISCUZ_CODE_662 ]nbsp; 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401013 .68 7D304000 push 0040307D ; |Title = "TutorialNag"
00401018 .68 34304000 push 00403034 ; |Text = "You need to remove the nag",CR,LF,"Try to do it in a two byte patch. ",CR,LF,"Regards!"
0040101D .6A 00 push 0 ; |hOwner = NULL
0040101F .E8 30020000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00401024 .EB 44 jmp short 0040106A
往下执行,就可以弹出第一个NAG窗口了。
第1次加密
`0x00401024`处`jmp short 0040106A`后,`edi`值仍为`0x00401000`,指令如下:
0040106A >83C7 11 add edi, 11
0040106D .66:C707 6A0Amov word ptr , 0A6A
00401072 .83C7 02 add edi, 2
00401075 >C707 FF353431 mov dword ptr , 313435FF
0040107B .83C7 04 add edi, 4
0040107E .66:C707 4000mov word ptr , 40
00401083 .83C7 02 add edi, 2
00401086 .66:C707 6A00mov word ptr , 6A
0040108B .83C7 02 add edi, 2
0040108E .C707 FF353031 mov dword ptr , 313035FF
00401094 .83C7 04 add edi, 4
00401097 .66:C707 4000mov word ptr , 40
0040109C .83C7 02 add edi, 2
0040109F .C707 E8900000 mov dword ptr , 90E8
004010A5 .83C7 04 add edi, 4
004010A8 .C607 00 mov byte ptr , 0
004010AB .47 inc edi
004010AC .66:C707 EB2Cmov word ptr , 2CEB ;0x17 bytes at all
004010B1 .83EF 15 sub edi, 15
004010B4 .FFD7 call edi
这一部分是将`0x00401011 ~ 0x00401027`的指令加密。
最后`call edi`时,减去`0x15`,`edi`的值又变回`0x00401011`。
00401011 [ DISCUZ_CODE_664 ]nbsp; 6A 0A push 0A
00401013 .FF35 34314000 push dword ptr
00401019 .6A 00 push 0
0040101B .FF35 30314000 push dword ptr ;ReverseM.00400000
00401021 .E8 90000000 call 004010B6
00401026 .EB 2C jmp short 00401054
执行后,弹出了第2个NAG窗口,然后跳到`0x00401054`。
第2次加密
00401054 >E8 C7020000 call 00401320
00401059 .E8 64020000 call 004012C2
0040105E .EB 15 jmp short 00401075
上面的指令是第1,2次解密得到的。
00401320/[ DISCUZ_CODE_666 ]nbsp; B8 00304000 mov eax, 00403000 ;ASCII "ReverseMeTutorial"
00401325|>8030 8D /xor byte ptr , 8D
00401328|.40 |inc eax
00401329|.3D 28314000 |cmp eax, 00403128
0040132E|.^ 7C F5 \jl short 00401325
00401330\.C3 retn
加密`0x00403000 ~ 0x00403127`的数据,注意我们第2次解密的时候是与`0xB3`异或。
退出
上一次加密后返回,调用`0x004012c2`。
004012C2/[ DISCUZ_CODE_667 ]nbsp; 50 push eax ; /ExitCode = 403128
004012C3\.E8 B0FFFFFF call <jmp.&KERNEL32.ExitProcess> ; \ExitProcess
整体流程
1. 0040130F:解密`0x00401000 ~ 0x00401218`(XOR 0x5A)
2. 00401011 :解密`0x00401011 ~ 0x0x00401025`
3. 00401000:解密`0x00403000 ~ 0x00403127`(含窗口标题和文本)
4. 0040106A:加密`0x00401011 ~ 0x00401027`
5. 00401320:加密`0x00403000 ~ 0x00403127`
0x01. 打补丁
我们的目的是把第一个NAG去掉,即由第2次解密得到、第3次解密之后马上执行的`0x0040101F`处的`call`指令。
第1种方法
一个方法是使`MessageBoxA()`的第一个参数`hOwner`即父句柄无效:`6A 00 | push 0x0`改为`6A 0A | push 0x1`。
这句参数入栈的指令是由第2次解密时的这一句得到的。
00401035 66:C707 6A00 mov word ptr , 6A
直接改为mov word ptr , 0x016A是行不通滴,因为66:C707 6A00这一句指令又是由第一次解密时与`0x5A`异或得到哒 (- 。-)!我们需要算一下与`0x5A`异或后得到`0x01`的字节。
`0x01 ^ 0x5A == 0x5B`,那么在运行前改把00401039的`0x5A`为`5B`就行了。
00401034 1D 3C9D5D30 sbb eax, 305D9D3C
00401039 5B pop ebx
保存后执行,成功地直接显示第二个NAG窗口。
第2种方法
在弹窗之前,直接执行下面的跳转。
00401011 6A 00 push 0
00401013 |68 7D304000 push 0040307D ; ASCII "TutorialNag"
00401018 |68 34304000 push 00403034 ; ASCII "You need to remove the nag",CR,LF,"Try to do it in a two byte patch. ",CR,LF,"Regards!"
0040101D |6A 00 push 0
0040101F |E8 30020000 call <jmp.&USER32.MessageBoxA>
修改后:00401011 EB 57 jmp short 0040106A
EB 57 XOR 5A == B1 0D ,所以回到找到第2次解密中对应的指令。
00401013 66:C707 6A00 mov word ptr , 6A
00401018 83C7 02 add edi, 2
回到运行前的`00401016`。
00401016 305A D9 xor byte ptr , bl
这里验证一下,30 5A XOR 5A == 6a 00,那么动手:
00000416 B1 0D mov cl, 0D
保存到执行文件,备份,成功去除第一个NAG。
页:
[1]