|

楼主 |
发表于 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 [403130], 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 [eax], 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 [edi], 6A
- 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 ; 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 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 [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
- 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 [eax], 0B3
- 00401008 . |40 inc eax
- 00401009 . |3D 28314000 cmp eax, 00403128
- 0040100E .^|7C F5 jl short 00401005
- 00401010 . |40 inc eax
- 00401011 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()的标题和文本参数就在这一范围内。
这一过程可以在数据窗口中观察。
- 00403000 E1 D6 C5 D6 C1 C0 D6 FE D6 E7 C6 C7 DC C1 DA D2 嶂胖晾筑昼魄芰谝
- 00403010 DF B3 E1 D6 C5 D6 C1 C0 D6 FE D6 E7 C6 C7 DC C1 叱嶂胖晾筑昼魄芰
- 00403020 DA D2 DF 89 93 E1 D6 DE DC C5 D6 93 C7 DB D6 93 谝邏撫洲芘謸芹謸
- 00403030 DD D2 D4 B3 EA DC C6 93 DD D6 D6 D7 93 C7 DC 93 菀猿贶茡葜肿撉軗
- 00403040 C1 D6 DE DC C5 D6 93 C7 DB D6 93 DD D2 D4 BE B9 林捃胖撉壑撦以竟
- 00403050 E7 C1 CA 93 C7 DC 93 D7 DC 93 DA C7 93 DA DD 93 缌蕮擒撟軗谇撢輷
复制代码
解密后:
- 00403000 52 65 76 65 72 73 65 4D 65 54 75 74 6F 72 69 61 ReverseMeTutoria
- 00403010 6C 00 52 65 76 65 72 73 65 4D 65 54 75 74 6F 72 l.ReverseMeTutor
- 00403020 69 61 6C 3A 20 52 65 6D 6F 76 65 20 74 68 65 20 ial: Remove the
- 00403030 6E 61 67 00 59 6F 75 20 6E 65 65 64 20 74 6F 20 nag.You need to
- 00403040 72 65 6D 6F 76 65 20 74 68 65 20 6E 61 67 0D 0A remove the nag..
- 00403050 54 72 79 20 74 6F 20 64 6F 20 69 74 20 69 6E 20 Try to do it in
- 00401010 . 40 inc eax ; ReverseM.00403128
- 00401011 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 6A0A mov word ptr [edi], 0A6A
- 00401072 . 83C7 02 add edi, 2
- 00401075 > C707 FF353431 mov dword ptr [edi], 313435FF
- 0040107B . 83C7 04 add edi, 4
- 0040107E . 66:C707 4000 mov word ptr [edi], 40
- 00401083 . 83C7 02 add edi, 2
- 00401086 . 66:C707 6A00 mov word ptr [edi], 6A
- 0040108B . 83C7 02 add edi, 2
- 0040108E . C707 FF353031 mov dword ptr [edi], 313035FF
- 00401094 . 83C7 04 add edi, 4
- 00401097 . 66:C707 4000 mov word ptr [edi], 40
- 0040109C . 83C7 02 add edi, 2
- 0040109F . C707 E8900000 mov dword ptr [edi], 90E8
- 004010A5 . 83C7 04 add edi, 4
- 004010A8 . C607 00 mov byte ptr [edi], 0
- 004010AB . 47 inc edi
- 004010AC . 66:C707 EB2C mov word ptr [edi], 2CEB ;0x17 bytes at all
- 004010B1 . 83EF 15 sub edi, 15
- 004010B4 . FFD7 call edi
复制代码
这一部分是将`0x00401011 ~ 0x00401027`的指令加密。
最后`call edi`时,减去`0x15`,`edi`的值又变回`0x00401011`。
- 00401011 nbsp; 6A 0A push 0A
- 00401013 . FF35 34314000 push dword ptr [403134]
- 00401019 . 6A 00 push 0
- 0040101B . FF35 30314000 push dword ptr [403130] ; 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 /nbsp; B8 00304000 mov eax, 00403000 ; ASCII "ReverseMeTutorial"
- 00401325 |> 8030 8D /xor byte ptr [eax], 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 /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 [edi], 6A
复制代码
直接改为mov word ptr [edi], 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 [edi], 6A
- 00401018 83C7 02 add edi, 2
复制代码
回到运行前的`00401016`。
- 00401016 305A D9 xor byte ptr [edx-27], bl
复制代码
这里验证一下,30 5A XOR 5A == 6a 00,那么动手:
- 00000416 B1 0D mov cl, 0D
复制代码
保存到执行文件,备份,成功去除第一个NAG。
|
|