starr 发表于 2019-8-16 21:08:29

解密系列_调试篇_第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 in​00401010   .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。


starr 发表于 2019-8-16 21:12:37

不好意思排版乱了{:10_266:}发之前好好的

迷雾少年 发表于 2019-8-16 21:15:18

这...........{:10_266:}{:10_266:}{:10_266:}{:10_266:}

jackz007 发表于 2019-8-16 21:19:39

      把你排好的版面文字直接复制到代码块里发布就好了。

starr 发表于 2019-8-16 21:26:38




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]
查看完整版本: 解密系列_调试篇_第21讲复现