【破解作者】 layper
【作者邮箱】 layper2002@yahoo.com.cn
【作者主页】 www.sy135.com
【使用工具】 peid,od,
【破解平台】 Win9x/NT/2000/XP
【软件名称】 壳乱弹(4)单步分析
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【破解内容】
我们继续分析ASProtect 1.2x - 1.3x壳,经过三个算法解码之后,005AC354变成了以下这个样子
005AC354 E8 05000000 call CWoool.005AC35E ;F7跟进
005AC359 B9 FE5FAC75 mov ecx,75AC5FFE
005AC35E 66:BF D6AA mov di,0AAD6 ;EDI=4BC9AAD6
005AC362 5E pop esi ;返回地址出栈,
005AC363 B3 9E mov bl,9E ;EBX=FFFFFA9E
005AC365 81C6 D2050000 add esi,5D2 ;指向005AC359+5D2=5AC92B
005AC36B B9 6B767804 mov ecx,478766B ;ECX=478766B
005AC370 81E9 21757804 sub ecx,4787521 ;ECX=478766B-4787521=14A
005AC376 B0 A7 mov al,0A7 ;EAX=000005A7
005AC378 FF36 push dword ptr ds:[esi] ;ds:[005AC92B]=C2CDACD5
005AC37A 50 push eax ;EAX=000005A7
005AC37B BB 6A63D365 mov ebx,65D3636A ;EBX=65D3636A
005AC380 5F pop edi ;EDI=000005A7
005AC381 5A pop edx ;EDX=ds:[005AC92B]=C2CDACD5
005AC382 66:BF C2F5 mov di,0F5C2 ;EDI=0000F5C2
005AC386 81EA 055CEE21 sub edx,21EE5C05 ;EDX=ds:[005AC92B]-21EE5C05=A0DF50D0
005AC38C E8 0E000000 call CWoool.005AC39F ;F7跟进
005AC391 0E push cs
005AC392 2F das
005AC393 3C C5 cmp al,0C5
005AC395 1A4B 28 sbb cl,byte ptr ds:[ebx+28]
005AC398 41 inc ecx
005AC399 E6 27 out 27,al
005AC39B D4 7D aam 7D
005AC39D ^ 72 C3 jb short CWoool.005AC362
005AC39F 66:B8 1F89 mov ax,891F ;EAX=891F
005AC3A3 5B pop ebx ;堆栈 [0012FF90]=005AC391 (CWoool.005AC391)
005AC3A4 81EA 5AE46403 sub edx,364E45A ;EDX=ds:[005AC92B]-21EE5C05-364E45A=9D7A6C76
005AC3AA E9 0D000000 jmp CWoool.005AC3BC ;跳走
005AC3AF B1 96 mov cl,96
005AC3B1 17 pop ss
005AC3B2 04 ED add al,0ED
005AC3B4 22B3 70E96E0F and dh,byte ptr ds:[ebx+F6EE970]
005AC3BA 9C pushfd
005AC3BB A5 movs dword ptr es:[edi],dword ptr>
005AC3BC 81C2 8BD62427 add edx,2724D68B ;EDX=ds:[005AC92B]-21EE5C05-364E45A+2724D68B=C49F4301
005AC3C2 81C8 4618CF13 or eax,13CF1846 ;891F XOR 13CF1846=13CF995F
005AC3C8 52 push edx ;计算结果入栈
005AC3C9 E8 07000000 call CWoool.005AC3D5 ;F7跟进
005AC3CE A3 A0591EFF mov dword ptr ds:[FF1E59A0],eax
005AC3D3 CC int3
005AC3D4 15 0F850500 adc eax,5850F
005AC3D9 0000 add byte ptr ds:[eax],al
005AC3D5 /0F85 05000000 jnz CWoool.005AC3E0
005AC3DB |66:81EF C9BF sub di,0BFC9
005AC3E0 \5F pop edi ;返回地址果出栈到EDI
005AC3E1 8F06 pop dword ptr ds:[esi] ;计算结果放回原处
005AC3E3 83EE 04 sub esi,4 ;遗向下一个地址
005AC3E6 E8 08000000 call CWoool.005AC3F3 ;F7跟进
005AC3EB 0039 add byte ptr ds:[ecx],bh ;
005AC3ED ^ 7E DF jle short CWoool.005AC3CE
005AC3EF 2C F5 sub al,0F5
005AC3F1 8AFB mov bh,bl
005AC3F3 0FB7FF movzx edi,di ;到这里EDI=C3F3
005AC3F6 58 pop eax ;返回地址出栈
005AC3F7 81E9 01000000 sub ecx,1 ;ECX=14A,ECX为计数器
005AC3FD ^ 0F85 75FFFFFF jnz CWoool.005AC378
算法如下:
从005AC92B到5AC407
EDX=ds:[005AC92B]-21EE5C05-364E45A+2724D68B
005AC403 66:BB 5C09 mov bx,95C ;指向5AC095C
005AC407 E8 00000000 call CWoool.005AC40C ;F7
005AC40C 5D pop ebp ;EBP=005AC40C
005AC40D 5B pop ebx ;005AC048
005AC40E 895D 5B mov dword ptr ss:[ebp+5B],ebx ;[005AC467]=005AC048
005AC411 5B pop ebx ;堆栈 [0012FF98]=7C80B529 (kernel32.GetModuleHandleA)
005AC412 895D 5F mov dword ptr ss:[ebp+5F],ebx ;[005AC46B]=7C80B529 (kernel32.GetModuleHandleA)
005AC415 58 pop eax ;堆栈 [0012FF9C]=00400000 (CWoool.00400000), ASCII "MZP"
005AC416 8985 0D040000 mov dword ptr ss:[ebp+40D],eax ;SS:[005AC819]=00400000 (CWoool.00400000), ASCII "MZP"
005AC41C 58 pop eax ;堆栈 [0012FFA0]=005AC066 (CWoool.005AC066)
005AC41D 807D 5A 01 cmp byte ptr ss:[ebp+5A],1 ;比较ss:[005AC466]=00是否是0
005AC421 75 59 jnz short CWoool.005AC47C ;不是则跳,我们是跳走
005AC423 8985 25040000 mov dword ptr ss:[ebp+425],eax
005AC429 60 pushad
005AC42A 8D45 33 lea eax,dword ptr ss:[ebp+33]
005AC42D 50 push eax
005AC42E 33C0 xor eax,eax
005AC430 64:FF30 push dword ptr fs:[eax] ;用到FS,可能是异常处理
005AC433 64:8920 mov dword ptr fs:[eax],esp
005AC436 8BC3 mov eax,ebx
005AC438 E8 E4020000 call CWoool.005AC721
005AC43D EB 1C jmp short CWoool.005AC45B
005AC47C E8 9C020000 call CWoool.005AC71D ;跳到这里,F7跟进
005AC71D 8B4424 24 mov eax,dword ptr ss:[esp+24] ; kernel32.7C816D4F
005AC721 25 0000FFFF and eax,FFFF0000 ;EAX AND FFFF0000 =7C810000
005AC726 05 00000100 add eax,10000 ; UNICODE "=::=::\"
005AC72B 2D 00000100 sub eax,10000 ; UNICODE "=::=::\"
005AC730 66:8138 4D5A cmp word ptr ds:[eax],5A4D ;ds:[7C810000]=0109比较是否是"ZM"
005AC735 ^ 75 F4 jnz short CWoool.005AC72B ;不是则跳回,这三步就是寻找"ZM",最后文件头是在7C8000
005AC737 60 pushad ;寄存器值全部压入栈
005AC738 8985 F8030000 mov dword ptr ss:[ebp+3F8],eax ;eax=7C800000 (kernel32.7C800000) ss:[005AC804]=00000000保存kernel32文件头地址
005AC73E 8BD0 mov edx,eax ;EDX=7C800000 (kernel32.7C800000)
005AC740 8BD8 mov ebx,eax ;EBX=7C800000 (kernel32.7C800000)
005AC742 0340 3C add eax,dword ptr ds:[eax+3C] ;指向7C8000C3,文件头"PE"地址
005AC745 0358 78 add ebx,dword ptr ds:[eax+78] ;指向ds:[7C800160]=0000262C,输出表偏移
005AC748 899D 0D030000 mov dword ptr ss:[ebp+30D],ebx ;保存输出表偏移在005AC719处
005AC74E 8D9D CC030000 lea ebx,dword ptr ss:[ebp+3CC] ;EBX指向005AC7D8
005AC754 8DBD E4030000 lea edi,dword ptr ss:[ebp+3E4] ;EDI指向005AC7F0
005AC75A 8B33 mov esi,dword ptr ds:[ebx] ;取005AC7D8的数据=B72551A7
005AC75C 89B5 7C030000 mov dword ptr ss:[ebp+37C],esi ;esi=B72551A7,ss:[005AC788]=12345678奇怪,竟然是12345678
005AC762 E8 0B000000 call CWoool.005AC772 ;F7进
005AC767 AB stos dword ptr es:[edi] ;把AX(字)中的数据存储到DI为目的串地址指针所寻址的存储器单元中去。
005AC768 83C3 04 add ebx,4
005AC76B 833B 00 cmp dword ptr ds:[ebx],0
005AC76E ^ 75 EA jnz short CWoool.005AC75A
005AC770 61 popad
005AC771 C3 retn ;返回005AC481
005AC772 60 pushad ;来到这里
005AC773 8B9D 0D030000 mov ebx,dword ptr ss:[ebp+30D] ;输出表地址出栈
005AC779 8B4B 20 mov ecx,dword ptr ds:[ebx+20] ;指向输出表函数名地址表的rva=ds:[7C80264C]=00003528
005AC77C 03CA add ecx,edx ;指向函数名地址表7c803528
005AC77E 8B31 mov esi,dword ptr ds:[ecx] ;取函数名偏移
005AC780 03F2 add esi,edx ;指向函数名edx=7C804B73
005AC782 E8 2F000000 call CWoool.005AC7B6 ;跟进
005AC7B6 52 push edx ;到这里,保存"ZM"文件头地址
005AC7B7 BA 8E243B9C mov edx,9C3B248E ;EDX=9C3B248E
005AC7BC AC lods byte ptr ds:[esi] ;送字符串字节到AL
005AC7BD 0AC0 or al,al ;是否是0
005AC7BF 74 14 je short CWoool.005AC7D5 ;是则跳走
005AC7C1 32D0 xor dl,al ;与DL异或后放回DL,EDX=9C3B24CF
005AC7C3 B0 08 mov al,8 ;al=8
005AC7C5 D1EA shr edx,1 ;逻辑右移一位,EDX=4E1D9267
005AC7C7 73 06 jnb short CWoool.005AC7CF ;不低于则跳
005AC7C9 81F2 9AF3A7C1 xor edx,C1A7F39A ;再次异或,8FBA61FD
005AC7CF FEC8 dec al ;AL减1
005AC7D1 ^ 75 F2 jnz short CWoool.005AC7C5 ;循环8次
005AC7D3 ^ EB E7 jmp short CWoool.005AC7BC ;
005AC7D5 92 xchg eax,edx ;计算结果与文件头地址交换
005AC7D6 5A pop edx ;保证是文件头地址
005AC7D7 C3 retn ;返回005AC787
005AC7B6到005AC7D7的算法叙述如下:
1)取函数地址名的一位字符串
2)与EDX(初始为9C3B248E)的DL数据异或
3)EDX逻辑左移一位
4)不低于的话在左移一位
5)低于的话EDX在与C1A7F39A异或,结果放回EDX
6)3--5步总共循环八次
7)完之后跳向函数名的下一位
005AC77E 8B31 mov esi,dword ptr ds:[ecx] ;取函数名偏移
005AC780 03F2 add esi,edx ;指向函数名edx=7C804B73
005AC782 E8 2F000000 call CWoool.005AC7B6 ;跟进
005AC787 BF A75125B7 mov edi,B72551A7 ;跳回这里,EDI=B72551A7,这个数据随着005AC75C的esi变化,而变化。
005AC78C 3BC7 cmp eax,edi ;比较刚才的结果是否是B72551A7
005AC78E 74 05 je short CWoool.005AC795 ;是则往下
005AC790 83C1 04 add ecx,4 ;不是则移向下一个保存函数名地址的偏移地址
005AC793 ^ EB E9 jmp short CWoool.005AC77E ;跳回继续
005AC795 2B4B 20 sub ecx,dword ptr ds:[ebx+20]
005AC798 2BCA sub ecx,edx ;这两步得出函数名rva相对于第一个函数地址表的位置
005AC79A D1E9 shr ecx,1 ;逻辑左移一位
005AC79C 034B 24 add ecx,dword ptr ds:[ebx+24] ;[ebx+24]指向函数名序号表的起始RVA=ds:[7C802650]=000043FC,这一步加法运算某个函数的RVA
005AC79F 03CA add ecx,edx ;获得函数序号数组索引值
005AC7A1 0FB709 movzx ecx,word ptr ds:[ecx] ;取相对于起始项的偏移
005AC7A4 C1E1 02 shl ecx,2
005AC7A7 034B 1C add ecx,dword ptr ds:[ebx+1C] ;获得函数地址表中的某项的偏移
005AC7AA 03CA add ecx,edx ;指向那项的地址
005AC7AC 8B09 mov ecx,dword ptr ds:[ecx] ;取函数入口RVA
005AC7AE 03CA add ecx,edx ;函数入口地址
005AC7B0 894C24 1C mov dword ptr ss:[esp+1C],ecx ;保存函数入口地址
005AC7B4 61 popad
005AC7B5 C3 retn
其实005AC77E到005AC793这几步是找函数名,这里是获取几个函数的入口,上面这一部分,总共在Kernel32.dll中得到了
以下这几个函数入口:
005AC7F0 7C80AC28 kernel32.GetProcAddress
005AC7F4 7C80B529 kernel32.GetModuleHandleA
005AC7F8 7C801D77 kernel32.LoadLibraryA
005AC7FC 7C809A81 kernel32.VirtualAlloc
005AC800 7C809B14 kernel32.VirtualFree
005AC481 FC cld ;DF置0
005AC482 8DB5 8C000000 lea esi,dword ptr ss:[ebp+8C] ;esi=005AC498,
005AC488 AD lods dword ptr ds:[esi] ;把SI寻址的源串的数据字节送AL或数据字送AX中去,
;EAX=ds:[esi]=[005AC498]=00401000,看来是原程序的code段的起始地址
005AC489 0BC0 or eax,eax ;是否是0
005AC48B 74 1B je short CWoool.005AC4A8
005AC48D 8BF8 mov edi,eax ;EDI=EAX=00401000
005AC48F B9 0C000000 mov ecx,0C ;ECX=0C
005AC494 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi] ; 字符串传送,CX为次数,修改了00401000至0040100C的数据
005AC496 EB 10 jmp short CWoool.005AC4A8
005AC4A8 89A5 29040000 mov dword ptr ss:[ebp+429],esp
005AC4AE 6A 40 push 40 ;设置提交的物理空间为可读\可写\可执行属性
005AC4B0 68 00100000 push 1000 ;为指定的地址空间提交物理内存
005AC4B5 FFB5 08040000 push dword ptr ss:[ebp+408] ;大小为4300
005AC4BB 6A 00 push 0 ;自行保留
005AC4BD FF95 F0030000 call dword ptr ss:[ebp+3F0] ;ss:[005AC7FC]=7C809A81 (kernel32.VirtualAlloc),保留或提交一段地址空间
;0012FF90 005AC4C3 /CALL 到 VirtualAlloc 来自 CWoool.005AC4BD
;|Address = NULL
;|Size = 43000 (274432.)
;00001000 |AllocationType = MEM_COMMIT
;00000040 \Protect = PAGE_EXECUTE_READWRITE
005AC4C3 8985 CC010000 mov dword ptr ss:[ebp+1CC],eax ;保存提交地址中的第一页的起始线程地址00F50000
005AC4C9 8B9D 00040000 mov ebx,dword ptr ss:[ebp+400] ;ss:[005AC80C]=001AF7D4
005AC4CF 039D 0D040000 add ebx,dword ptr ss:[ebp+40D] ;ss:[005AC819]=00400000 (CWoool.00400000), ASCII "MZP",原程序的文件头加上001AF7D4=005AF7D4
005AC4D5 50 push eax ;保存地址
005AC4D6 53 push ebx ;保存地址
005AC4D7 E8 04010000 call CWoool.005AC5E0 ;跟进
005AC5E0 55 push ebp ; CWoool.005AC40C
005AC5E1 8BEC mov ebp,esp
005AC5E3 60 pushad ;所有寄存器值压入栈
005AC5E4 55 push ebp ;EBP=12FFA94
005AC5E5 8B75 08 mov esi,dword ptr ss:[ebp+8] ;ESI=文件头+001AF7D4地址=005AF7D4
005AC5E8 8B7D 0C mov edi,dword ptr ss:[ebp+C] ;EDI=分配的内存地址=00F50000
005AC5EB FC cld ;DF置0
005AC5EC B2 80 mov dl,80 ;EDX=7C92EB80
005AC5EE 8A06 mov al,byte ptr ds:[esi] ;ds:[005AF7D4]=A4,EAX=00F500A4
005AC5F0 46 inc esi ;ESI=005AF7D5
005AC5F1 8807 mov byte ptr ds:[edi],al ;起始地址放入A4
005AC5F3 47 inc edi ;EDI=00F50001
005AC5F4 02D2 add dl,dl ;EDX=7C92EB00
005AC5F6 75 05 jnz short CWoool.005AC5FD
005AC5F8 8A16 mov dl,byte ptr ds:[esi] ;ds:[005AF7D5]=38 ('8')
005AC5FA 46 inc esi ;ESI=005AF7D6
005AC5FB 12D2 adc dl,dl ;EDI=7C92EB71
005AC5FD ^ 73 EF jnb short CWoool.005AC5EE ;循环之后变成00F50000 000418A4
005AC5FF 02D2 add dl,dl ;7C92EB88
005AC601 /75 05 jnz short CWoool.005AC608 ;不等则跳走
005AC603 |8A16 mov dl,byte ptr ds:[esi]
005AC605 |46 inc esi
005AC606 |12D2 adc dl,dl
005AC608 \73 4A jnb short CWoool.005AC654 ;不低于跳走,最里边循环的出口
005AC60A 33C0 xor eax,eax ;清空EAX
005AC60C 02D2 add dl,dl ;7C92EB10
005AC60E 75 05 jnz short CWoool.005AC615 ;不等则跳
005AC610 8A16 mov dl,byte ptr ds:[esi]
005AC612 46 inc esi
005AC613 12D2 adc dl,dl
005AC615 0F83 D6000000 jnb CWoool.005AC6F1 ;外面的循环出口
005AC61B 02D2 add dl,dl ;7c92eb20
005AC61D 75 05 jnz short CWoool.005AC624
005AC61F 8A16 mov dl,byte ptr ds:[esi]
005AC621 46 inc esi
005AC622 12D2 adc dl,dl
005AC624 13C0 adc eax,eax
005AC626 02D2 add dl,dl
005AC628 75 05 jnz short CWoool.005AC62F
005AC62A 8A16 mov dl,byte ptr ds:[esi]
005AC62C 46 inc esi
005AC62D 12D2 adc dl,dl
005AC62F 13C0 adc eax,eax
005AC631 02D2 add dl,dl
005AC633 75 05 jnz short CWoool.005AC63A
005AC635 8A16 mov dl,byte ptr ds:[esi]
005AC637 46 inc esi
005AC638 12D2 adc dl,dl
005AC63A 13C0 adc eax,eax
005AC63C 02D2 add dl,dl
005AC63E 75 05 jnz short CWoool.005AC645
005AC640 8A16 mov dl,byte ptr ds:[esi] ;7C92EB70
005AC642 46 inc esi
005AC643 12D2 adc dl,dl
005AC645 13C0 adc eax,eax
005AC647 74 06 je short CWoool.005AC64F
005AC649 57 push edi
005AC64A 2BF8 sub edi,eax
005AC64C 8A07 mov al,byte ptr ds:[edi]
005AC64E 5F pop edi
005AC64F 8807 mov byte ptr ds:[edi],al
005AC651 47 inc edi
005AC652 ^ EB A0 jmp short CWoool.005AC5F4
005AC654 B8 01000000 mov eax,1
005AC659 02D2 add dl,dl
005AC65B 75 05 jnz short CWoool.005AC662
005AC65D 8A16 mov dl,byte ptr ds:[esi]
005AC65F 46 inc esi
005AC660 12D2 adc dl,dl
005AC662 13C0 adc eax,eax
005AC664 02D2 add dl,dl
005AC666 75 05 jnz short CWoool.005AC66D
005AC668 8A16 mov dl,byte ptr ds:[esi]
005AC66A 46 inc esi
005AC66B 12D2 adc dl,dl
005AC66D ^ 72 EA jb short CWoool.005AC659
005AC66F 83E8 02 sub eax,2
005AC672 75 28 jnz short CWoool.005AC69C
005AC674 B9 01000000 mov ecx,1
005AC679 02D2 add dl,dl
005AC67B 75 05 jnz short CWoool.005AC682
005AC67D 8A16 mov dl,byte ptr ds:[esi]
005AC67F 46 inc esi
005AC680 12D2 adc dl,dl
005AC682 13C9 adc ecx,ecx
005AC684 02D2 add dl,dl
005AC686 75 05 jnz short CWoool.005AC68D
005AC688 8A16 mov dl,byte ptr ds:[esi]
005AC68A 46 inc esi
005AC68B 12D2 adc dl,dl
005AC68D ^ 72 EA jb short CWoool.005AC679
005AC68F 56 push esi
005AC690 8BF7 mov esi,edi
005AC692 2BF5 sub esi,ebp
005AC694 F3:A4 rep movs byte ptr es:[edi],byte pt>
005AC696 5E pop esi
005AC697 ^ E9 58FFFFFF jmp CWoool.005AC5F4
005AC69C 48 dec eax
005AC69D C1E0 08 shl eax,8
005AC6A0 8A06 mov al,byte ptr ds:[esi]
005AC6A2 46 inc esi
005AC6A3 8BE8 mov ebp,eax
005AC6A5 B9 01000000 mov ecx,1
005AC6AA 02D2 add dl,dl
005AC6AC 75 05 jnz short CWoool.005AC6B3
005AC6AE 8A16 mov dl,byte ptr ds:[esi]
005AC6B0 46 inc esi
005AC6B1 12D2 adc dl,dl
005AC6B3 13C9 adc ecx,ecx
005AC6B5 02D2 add dl,dl
005AC6B7 75 05 jnz short CWoool.005AC6BE
005AC6B9 8A16 mov dl,byte ptr ds:[esi]
005AC6BB 46 inc esi
005AC6BC 12D2 adc dl,dl
005AC6BE ^ 72 EA jb short CWoool.005AC6AA
005AC6C0 3D 007D0000 cmp eax,7D00
005AC6C5 73 1A jnb short CWoool.005AC6E1
005AC6C7 3D 00050000 cmp eax,500
005AC6CC 72 0E jb short CWoool.005AC6DC
005AC6CE 41 inc ecx
005AC6CF 56 push esi
005AC6D0 8BF7 mov esi,edi
005AC6D2 2BF0 sub esi,eax
005AC6D4 F3:A4 rep movs byte ptr es:[edi],byte pt>
005AC6D6 5E pop esi
005AC6D7 ^ E9 18FFFFFF jmp CWoool.005AC5F4
005AC6DC 83F8 7F cmp eax,7F
005AC6DF 77 03 ja short CWoool.005AC6E4
005AC6E1 83C1 02 add ecx,2
005AC6E4 56 push esi
005AC6E5 8BF7 mov esi,edi
005AC6E7 2BF0 sub esi,eax
005AC6E9 F3:A4 rep movs byte ptr es:[edi],byte pt>
005AC6EB 5E pop esi
005AC6EC ^ E9 03FFFFFF jmp CWoool.005AC5F4
005AC6F1 8A06 mov al,byte ptr ds:[esi]
005AC6F3 46 inc esi
005AC6F4 33C9 xor ecx,ecx
005AC6F6 C0E8 01 shr al,1
005AC6F9 74 12 je short CWoool.005AC70D ;第三个出口
005AC6FB 83D1 02 adc ecx,2
005AC6FE 8BE8 mov ebp,eax
005AC700 56 push esi
005AC701 8BF7 mov esi,edi
005AC703 2BF0 sub esi,eax
005AC705 F3:A4 rep movs byte ptr es:[edi],byte pt>
005AC707 5E pop esi
005AC708 ^ E9 E7FEFFFF jmp CWoool.005AC5F4
005AC70D 5D pop ebp ;0012FF94指针出栈
005AC70E 2B7D 0C sub edi,dword ptr ss:[ebp+C] ;堆栈 ss:[0012FFA0]=00F50000,edi=00F6B800-00F50000=1B800
005AC711 897D FC mov dword ptr ss:[ebp-4],edi ;把1B800放入12FF90
005AC714 61 popad ;恢复以前的寄存器
005AC715 5D pop ebp ;堆栈 [0012FF94]=005AC40C (CWoool.005AC40C),ebp=0012FF94
005AC716 C2 0800 retn 8
这个call还是解码,把前面一些代码还原到刚申请的地址中.
005AC4DC 6A 40 push 40 ;设置可读\可写\可执行属性
005AC4DE 68 00100000 push 1000 ;为指定的地址空间提交物理内存
005AC4E3 FFB5 08040000 push dword ptr ss:[ebp+408] ;[005AC814]=00043000申请内存大小
005AC4E9 6A 00 push 0 ;指定需要保留或提交空间的位置为自行保留
005AC4EB FF95 F0030000 call dword ptr ss:[ebp+3F0] ;保留或提交一段地址空间VirtualAlloc
005AC4F1 8985 31040000 mov dword ptr ss:[ebp+431],eax ;[005AC83D]=eax=00FA0000
005AC4F7 8985 D0010000 mov dword ptr ss:[ebp+1D0],eax ;ss:[005AC5DC]=00FA0000
005AC4FD 64:67:A1 0000 mov eax,dword ptr fs:[0] ;eax=fs:[00000000]=[7FFDF000]=0012FFE0
005AC502 8985 2D040000 mov dword ptr ss:[ebp+42D],eax ;ss:[005AC839]=0012FFE0异常指针
005AC508 8B55 5B mov edx,dword ptr ss:[ebp+5B] ;EDX=ss:[005AC467]=005AC048 (CWoool.005AC048)
005AC50B 8B85 D0010000 mov eax,dword ptr ss:[ebp+1D0] ;EAX=ss:[005AC5DC]=00FA0000
005AC511 8902 mov dword ptr ds:[edx],eax ;ds:[005AC048]=eax=00FA0000
005AC513 8B85 08040000 mov eax,dword ptr ss:[ebp+408] ;eax=ss:[005AC814]=00043000申请内存大小
005AC519 8942 04 mov dword ptr ds:[edx+4],eax ;eax=ds:[005AC04C]=00043000
005AC51C 8D85 9F030000 lea eax,dword ptr ss:[ebp+39F] ;eax=地址=005AC7AB
005AC522 8B40 55 mov eax,dword ptr ds:[eax+55] ;eax=ds:[005AC800]=7C809B14 (kernel32.VirtualFree)
005AC525 8942 08 mov dword ptr ds:[edx+8],eax ;ds:[005AC050]=eax=7C809B14 (kernel32.VirtualFree)
005AC528 8B85 EC030000 mov eax,dword ptr ss:[ebp+3EC] ;eax=ss:[005AC7F8]=7C801D77 (kernel32.LoadLibraryA)
005AC52E 8942 10 mov dword ptr ds:[edx+10],eax ;ds:[005AC058]=eax=7C801D77 (kernel32.LoadLibraryA)
005AC531 8B85 E8030000 mov eax,dword ptr ss:[ebp+3E8] ;eax=ss:[005AC7F4]=7C80B529 (kernel32.GetModuleHandleA)
005AC537 8942 14 mov dword ptr ds:[edx+14],eax ;ds:[005AC05C]=eax=7C80B529 (kernel32.GetModuleHandleA)这几步其实就是用EAX传递入口地址
005AC53A 8B95 CC010000 mov edx,dword ptr ss:[ebp+1CC] ;edx=ss:[005AC5D8]=00F50000
005AC540 BB F8010000 mov ebx,1F8 ;ebx=1F8
005AC545 8B7C1A 0C mov edi,dword ptr ds:[edx+ebx+C];edi=ds:[00F50204]=00001000
005AC549 0BFF or edi,edi ;
005AC54B 74 1E je short CWoool.005AC56B
005AC54D 8B4C1A 10 mov ecx,dword ptr ds:[edx+ebx+10];ecx=ds:[00F50208]=00017800
005AC551 0BC9 or ecx,ecx
005AC553 74 11 je short CWoool.005AC566
005AC555 03BD D0010000 add edi,dword ptr ss:[ebp+1D0] ;edi=00FA0000+00001000
005AC55B 8B741A 14 mov esi,dword ptr ds:[edx+ebx+14];esi=ds:[00F5020C]=00000400
005AC55F 03F2 add esi,edx ;esi=00F50400
005AC561 C1F9 02 sar ecx,2 ; 算术右移两位
005AC564 F3:A5 rep movs dword ptr es:[edi],dword >;ECX=0000000,ESI=00F67C00,EDI=00FB8800
005AC566 83C3 28 add ebx,28 ;EBX=220
005AC569 ^ EB DA jmp short CWoool.005AC545 ;这几步是把代码读入00FA0000
005AC56B 8B85 CC010000 mov eax,dword ptr ss:[ebp+1CC] ;ss:[005AC5D8]=00F50000,eax=7C80B529 (kernel32.GetModuleHandleA)
005AC571 50 push eax ;保存EAX=00F50000在堆栈
005AC572 8B95 D0010000 mov edx,dword ptr ss:[ebp+1D0] ;edx=ss:[005AC5DC]=00FA0000
005AC578 52 push edx ;保存00FA0000在堆栈
005AC579 8B18 mov ebx,dword ptr ds:[eax] ;ebx=ds:[00F50000]=000418A4
005AC57B 03DA add ebx,edx ;edx=00FA0000,ebx=000418A4
005AC57D 8B85 E4030000 mov eax,dword ptr ss:[ebp+3E4]
005AC583 8903 mov dword ptr ds:[ebx],eax ;ds:[00FE18A4]=eax=7C80AC28 (kernel32.GetProcAddress)把这几个函数入口放入
005AC585 8B85 E8030000 mov eax,dword ptr ss:[ebp+3E8]
005AC58B 8943 04 mov dword ptr ds:[ebx+4],eax ;ds:[00FE18A8]=eax=7C80B529 (kernel32.GetModuleHandleA)
005AC58E 8B85 EC030000 mov eax,dword ptr ss:[ebp+3EC]
005AC594 8943 08 mov dword ptr ds:[ebx+8],eax ;00FE18AC=7C801D77 kernel32.LoadLibraryA
005AC597 5F pop edi ;EDI=00FA0000
005AC598 5E pop esi ;ESI00F50000
005AC599 8B46 04 mov eax,dword ptr ds:[esi+4] ;00041000
005AC59C 03C7 add eax,edi ;EAX=00FE1000
005AC59E 8985 C7010000 mov dword ptr ss:[ebp+1C7],eax ;ss:[005AC5D3]=eax=00FE1000
005AC5A4 8B55 5B mov edx,dword ptr ss:[ebp+5B] ;edx=ss:[005AC467]=005AC048 (CWoool.005AC048)
005AC5A7 8B85 C7010000 mov eax,dword ptr ss:[ebp+1C7] ;eax=ss:[005AC5D3]=00FE1000,005AC5D3是下面的地址
005AC5AD 8942 0C mov dword ptr ds:[edx+C],eax ;ds:[005AC054]=eax=00FE1000
005AC5B0 8D9D 0D040000 lea ebx,dword ptr ss:[ebp+40D] ;ebx=地址=005AC819,文件头"MZP"的地址
005AC5B6 53 push ebx
005AC5B7 6A 00 push 0
005AC5B9 6A 00 push 0
005AC5BB 6A 01 push 1
005AC5BD 57 push edi ;EDI=00FA0000
005AC5BE 8B5E 08 mov ebx,dword ptr ds:[esi+8] ;ebx=ds:[00F50008]=0003062C
005AC5C1 03DF add ebx,edi ;EBX=00FD062C
005AC5C3 53 push ebx
005AC5C4 68 00800000 push 8000
005AC5C9 6A 00 push 0
005AC5CB 56 push esi ;esi=00F50000
005AC5CC FF95 F4030000 call dword ptr ss:[ebp+3F4] ;ss:[005AC800]=7C809B14 (kernel32.VirtualFree)释放地址空间
;0012FF7C 005AC5D2 /CALL 到 VirtualFree 来自 CWoool.005AC5CC
;0012FF80 00F50000 |Address = 00F50000 指定的地址
;0012FF84 00000000 |Size = 0 大小
;0012FF88 00008000 \FreeType = MEM_RELEASE 释放保留的地址空间
005AC5D2 68 00000000 push 0 ;这里变成了
005AC5D2 68 0010FE00 push 0FE1000
005AC5D7 C3 retn ;这里就变成了返回0FE1000
呵呵,这个部分呢把代码动态解码到00FA0000处,并且用了一个手段跳到00FE1000,在005AC5A7把005AC5D3写入返回的00FE1000地址,动态修改了push后压入的地址,然后在后面用一个retn
就返回了00FE1000,真够精彩!!
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!