【文章标题】: SoftWrap 6.x之四:IAT修复之VC类
【文章作者】: wynney
【软件名称】: Fractal PC 3.01
【下载地址】: http://www.fractalpc.com/resources/SetupFractalPC30.exe
【使用工具】: OD、CodeCaver
--------------------------------------------------------------------------------
【详细过程】
一、 前言
在前面一章中,已经有提到,一般程序有以下几种IAT格式
1、Jmp Dword ptr ds:[API] ->6字节
2、Call Dword ptr ds:[API] ->6字节
3、mov eax, Dword ptr ds:[API] ->5字节
4、mov REG,Dword ptr ds:[API] ->6字节[eax外的寄存器,且esp、edx基本不被使用]
而SoftWrap加密之后分别被改成这种形式
1、Call DWORD PTR DS:[addr] ->6字节
2、Call DWORD PTR DS:[addr] ->6字节
3、Call addr ->5字节
4、Call addr ->5字节+1个字节的寄存器类型识别指令
上面最难修复的就是第4种,同时需要指出的是第3种形式有时候不会有,4种全用上才是最强加密。
二、 Patch IAT代码需要的数据
1、Jmp dword ptr ds:[API]- ->Call dword ptr ds:[Addr]
2、Call dword ptr ds:[API] - -> Call dword ptr ds:[Addr]
3、Mov eax, dword ptr ds:[API] - ->Call Addr
4、Mov REG, dword ptr ds:[API] - ->Call Addr
我们需要的就是4个Addr以及判定REG类型的数据
去OEP溜达吧,获取上面需要的数据,忽略除了特权指令和指定异常之外的所有异常
,4次Shift+F9,出现试用框,点Try Now,中断后继续Shift+F9两次,在Code段下内存访问断点[不可以F2],
Shift+F9,两次,即可到达OEP了。
0041679B 6A 60 push 60 ; OEP
0041679D 68 103E4200 push 00423E10
004167A2 E8 AD030000 call 00416B54
004167A7 BF 94000000 mov edi, 94
004167AC 8BC7 mov eax, edi
004167AE E8 4D3A0000 call 0041A200
004167B3 8965 E8 mov dword ptr [ebp-18], esp
004167B6 8BF4 mov esi, esp
004167B8 893E mov dword ptr [esi], edi
004167BA 56 push esi
004167BB FF15 40924500 call dword ptr [459240] ; Enter
0045C013 6A 00 push 0
0045C015 9C pushfd
0045C016 50 push eax
0045C017 53 push ebx
0045C018 8B5C24 10 mov ebx, dword ptr [esp+10]
0045C01C 53 push ebx
0045C01D 83EB 06 sub ebx, 6
0045C020 68 E9260000 push 26E9
0045C025 68 00004801 push 1480000
0045C02A C3 retn
查找'所有命令' push 1480000
Found commands
Address Disassembly Comment
0045B962 push 1480000
0045B97A push 1480000
0045BA61 push 1480000
0045BFFD push 1480000
0045C025 push 1480000 (Initial CPU selection)
全部设断,Shift+F9,第一次中断
0045C013 6A 00 push 0
0045C015 9C pushfd
0045C016 50 push eax
0045C017 53 push ebx
0045C018 8B5C24 10 mov ebx, dword ptr [esp+10]
0045C01C 53 push ebx
0045C01D 83EB 06 sub ebx, 6
0045C020 68 E9260000 push 26E9
0045C025 68 00004801 push 1480000 ; 中断在这,删除断点,看堆栈
0045C02A C3 retn
0012FE90 000026E9 ?..
0012FE94 004167C1 羐A. RETURN to FractalP.004167C1 from FractalP.0045C013
0012FE98 7FFD6000 .`?
004167BB FF15 40924500 call dword ptr [459240] ; Call类的,要改成Call类
004167C1 8B4E 10 mov ecx, dword ptr [esi+10] ; 反汇编中跟随到这
① 459240就是要获取的Call dword ptr ds:[API]-> Call dword ptr ds:[Addr]中的Addr
继续Shift+F9,第2次中断
0045B968 9C pushfd
0045B969 60 pushad
0045B96A 8B5C24 24 mov ebx, dword ptr [esp+24]
0045B96E 43 inc ebx
0045B96F 53 push ebx
0045B970 83EB 06 sub ebx, 6
0045B973 8BD3 mov edx, ebx
0045B975 68 76200000 push 2076
0045B97A 68 00004801 push 1480000 ; 中断在这,删除断点,看堆栈
0045B97F C3 retn
0012FEA4 00000246 F ..
0012FEA8 0041680D .hA. RETURN to FractalP.0041680D from FractalP.0045924A
0012FEAC 00000000 ....
00416808 E8 3D2A0400 call 0045924A ; 这里是Mov REG或者eax类的
0041680D 1AFF sbb bh,bh ; 反汇编中跟随到这
0041680F D7 xlat byte ptr [ebx+al] ; 具体是那一类我们来分析
下面两条指令比较奇怪,我们把1A给nop掉[就nop掉这一个字节],看看
00416808 E8 3D2A0400 call 0045924A
0041680D 90 nop
0041680E FFD7 call edi
看到效果了吧,那么上6个字节[包括90]应该是mov edi,dword ptr ds:[API]了
那么上面被我们nop掉的1A就是壳用来识别到底是那个寄存器的指令了,接下来看看别的
00410C54 E8 F1850400 call 0045924A
00410C59 1E push ds
00410C5A 8D9B 00000000 lea ebx, dword ptr [ebx]
00410C60 03C5 add eax, ebp
00410C62 50 push eax
00410C63 8D5424 30 lea edx, dword ptr [esp+30]
00410C67 52 push edx
00410C68 51 push ecx
00410C69 FFD3 call ebx
这个我们不需要nop掉1E就知道,1E是ebx的识别指令
其他的大家可以自己看看,我们有简单的方法来辨别
下第2次中断的push 1480000下面就有辨别代码
0045B97A 68 00004801 push 1480000 ; 中断在这,删除断点,看堆栈
0045B97F C3 retn
0045B980 ^ 71 98 jno short 0045B91A
0045B982 E7 B9 out 0B9, eax
0045B984 A3 8004E933 mov dword ptr [33E90480], eax
0045B989 C0FF 4C sar bh, 4C
0045B98C 24 24 and al, 24
0045B98E EB 0E jmp short 0045B99E
0045B990 5D pop ebp
0045B991 91 xchg eax, ecx
0045B992 99 cdq
0045B993 B9 84A709A5 mov ecx, A509A784
0045B998 0FB642 05 movzx eax, byte ptr [edx+5] ; [edx+5]的值就是识别代码,F2
0045B99C 34 1D xor al, 1D
0045B99E B9 06000000 mov ecx, 6
0045B9A3 33D2 xor edx, edx
0045B9A5 F7E1 mul ecx
0045B9A7 E8 00000000 call 0045B9AC
0045B9AC 5A pop edx
0045B9AD 8D9402 0A000000 lea edx, dword ptr [edx+eax+A]
0045B9B4 FFE2 jmp edx
0045B9B6 895C24 1C mov dword ptr [esp+1C], ebx ; eax,F2
0045B9BA EB 27 jmp short 0045B9E3
0045B9BC 895C24 18 mov dword ptr [esp+18], ebx ; ecx,F2
0045B9C0 EB 21 jmp short 0045B9E3
0045B9C2 895C24 14 mov dword ptr [esp+14], ebx ; edx,F2
0045B9C6 EB 1B jmp short 0045B9E3
0045B9C8 895C24 10 mov dword ptr [esp+10], ebx ; ebx,F2
0045B9CC EB 15 jmp short 0045B9E3
0045B9CE 895C24 0C mov dword ptr [esp+C], ebx ; esp,F2
0045B9D2 EB 0F jmp short 0045B9E3
0045B9D4 895C24 08 mov dword ptr [esp+8], ebx ; ebp,F2
0045B9D8 EB 09 jmp short 0045B9E3
0045B9DA 895C24 04 mov dword ptr [esp+4], ebx ; esi,F2
0045B9DE EB 03 jmp short 0045B9E3
0045B9E0 891C24 mov dword ptr [esp], ebx ; edi,F2
0045B9E3 61 popad
0045B9E4 FF4424 04 inc dword ptr [esp+4] ; 上面寄存器的顺序是按右边寄存器的顺序
0045B7F6 3A0D 00003401 cmp cl, byte ptr [1340000]
0045B7FC 74 0E je short 0045B80C
0045B7FE FE05 00003401 inc byte ptr [1340000]
0045B804 66:8305 0400340>add word ptr [1340004], 4
0045B80C 8B1D 04003401 mov ebx, dword ptr [1340004]
0045B812 8903 mov dword ptr [ebx], eax
0045B814 66:8305 0400340>add word ptr [1340004], 4
01490087 B9 08003401 mov ecx, 1340008 ; IAT的起始位置
0149008C 3901 cmp dword ptr [ecx], eax
0149008E 74 05 je short 01490095
01490090 83C1 04 add ecx, 4
01490093 ^ EB F7 jmp short 0149008C
01490095 8BD1 mov edx, ecx
01490097 81C2 00100000 add edx, 1000
0149009D 8902 mov dword ptr [edx], eax
0149009F 83C4 1C add esp, 1C
014900A2 3E:8B0424 mov eax, dword ptr ds:[esp]
014900A6 83E8 06 sub eax, 6
014900A9 66:C700 FF25 mov word ptr [eax], 25FF ; 改成jmp类型
014900AE 83C0 02 add eax, 2
014900B1 8910 mov dword ptr [eax], edx
014900B3 90 nop
014900B4 90 nop
014900B5 813D 04003401 0>cmp dword ptr [1340004], 41D000 ; ★写完代码,在这新建EIP,Code段尾
014900BF 74 2C je short 014900ED
014900C1 8B0D 04003401 mov ecx, dword ptr [1340004] ; FractalP.00401000
014900C7 66:8139 FF15 cmp word ptr [ecx], 15FF ; 查找是否是Call类型
014900CC 75 17 jnz short 014900E5
014900CE 8BC1 mov eax, ecx
014900D0 83C0 02 add eax, 2
014900D3 8138 3C924500 cmp dword ptr [eax], 45923C ; 得到的Addr
014900D9 75 0A jnz short 014900E5
014900DB 83C0 04 add eax, 4
014900DE A3 04003401 mov dword ptr [1340004], eax
014900E3 FFE1 jmp ecx ; 跳回下一个循环
014900E5 FF05 04003401 inc dword ptr [1340004] ; FractalP.00401000
014900EB ^ EB C8 jmp short 014900B5
014900ED - EB FE jmp short 014900ED ; ★写完代码这里设断
014900EF 90 nop
014900F0 90 nop
014900F1 90 nop
014900F2 90 nop
B9 08 00 34 01 39 01 74 05 83 C1 04 EB F7 8B D1 81 C2 00 10 00 00 89 02 83 C4 1C 3E 8B 04 24 83 E8 06 66 C7 00 FF 25 83 C0 02 89 10 90 90 81 3D 04 00 34 01 00 D0 41 00 74 2C 8B 0D 04 00 34 01 66 81 39 FF 15 75 17 8B C1 83 C0 02 81 38 3C 92 45 00 75 0A 83 C0 04 A3 04 00 34 01 FF E1 FF 05 04 00 34 01 EB C8 EB FE 90 90 90 90
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)