在拜读了kanxue坛主的文章:
Asprotect SKE 2.2 的Advanced Import protection保护技术
之后有了这篇文章。
因为Volx的IAT脚本1.02版已经不能对付它了,所以手工修复,一个字:累。
福建体彩“22选5”选号专家 3.0 Build 2006.07.29
软件大小:14161KB
软件语言:简体中文
软件类别:国产软件/共享版/彩票工具
运行环境:WinNT/2000/XP/2003
加入时间:2006-7-29 16:23:55
软件详细信息
《福建体彩“22选5”选号专家》是一款集号码走势分析、号码选取、号码过滤(缩水)、开核对,历史数据自动网上更新为一体的界面美观、操作简单的专用于福建体彩“22选5”彩票的软件!其内置了各种最有效的彩票过滤方法!其独特的智能化过滤缩水功能,可过滤掉众多的垃圾组合,为您好节省大把的买彩资金,使彩票投资的效益最大化!
ASProtect 2.1x SKE -> Alexey Solodovnikov
Version: ASProtect 2.11 SKE build 03.13 Release [1]
1.Stolen OEP+IAT:
Volx脚本:Asprotect 2.xx SKE OEP finder.txt
停在伪OEP:
014C0303 6A 64 push 64
014C0305 66:9C pushfw
014C0307 57 push edi
014C0308 EB 02 jmp short 014C030C
Alt+M在code下断,停在004037DE,VB程序:
004037D2 - FF25 E8104000 jmp dword ptr ds:[4010E8] ; msvbvm60.GetMem4
004037D8 - FF25 28114000 jmp dword ptr ds:[401128] ; msvbvm60.PutMem4
004037DE - FF25 E4124000 jmp dword ptr ds:[4012E4] ; msvbvm60.ThunRTMain
004037E4 - E9 1ACB0B01 jmp 014C0303 ; oep
004037E9 2853 0A sub byte ptr ds:[ebx+A],dl
004037EC 87E7 xchg edi,esp
堆栈:
0012FFBC 014C0342 返回到 014C0342 来自 01630000
0012FFC0 004356C8 ASCII "VB5!6&vb6chs.dll" // push
0012FFC4 77E687F5 返回到 kernel32.77E687F5
被偷的代码:
push 004356C8
call 4037DE
即:
004037DE - FF25 E4124000 jmp dword ptr ds:[4012E4] ; msvbvm60.ThunRTMain
004037E4 68 C8564300 push fjTC225.004356C8 ; ASCII "VB5!6&vb6chs.dll"
004037E9 E8 F0FFFFFF call fjTC225.004037DE ; jmp to msvbvm60.ThunRTMain
IAT没有加密:
00401000 >660C9ADE msvbvm60.EVENT_SINK_GetIDsOfNames
00401004 66109881 msvbvm60.__vbaVarTstGt
00401008 6610782A msvbvm60.__vbaVarSub
0040100C 660DF9B9 msvbvm60.__vbaStrI2
...
0040138C 660D9A27 msvbvm60.__vbaFreeObj
00401390 660E60B0 msvbvm60.__vbaFreeStr
00401394 660D2DD4 msvbvm60.rtcR8ValFromBstr
00401398 00000000
此时上ImportREC,添入OEP=000037E4,自动搜索,Level1,全部有效,保存备用。
此时还不能dump,因为还有Advanced Import protection没有搞定。
搜索E8:004D5D9F E8 5CA20101 call 014F0000
n多这样的函数,Volx的IAT修复脚本用不上,只好手工上。
参考kanxue文章:Asprotect SKE 2.2 的Advanced Import protection保护技术
2.Advanced Import Protection的分类位置:
进入call 014F0000 后总共3层:
第一层:保存所有当前寄存器 (出来后还要继续运行的,不能影响后面,不过它不是明目张胆的pushad)
第二层:1. 决定是哪一种方式的导入函数调用
a. 第一种方式:将call 014F0000 变成call F00004之类,出来后再次从原地进入F00004进入导入函数
b. 第二种方式:直接带着参数进入导入函数
2. 决定这个调用是call (ff15)还是jmp (ff25)
不要以为C的都是call,delphi的都是jmp
c. 如果是call (ff15),返回地址要+1,比如inc [esp],因为call 014F0000占5个字节,call(ff15)占6个字节
d. 如果是jmp (ff25),要esp+4
3. 如果是1.b的情况,可能有更邪恶的对下一行的偷代码
第三层:恢复所有的寄存器返回
进入到第一层,一路F7,直到碰到call eax(也可能是call ecx等,第一个call):
014F0000 /3E:EB 02 jmp short 014F0005
014F0003 |CD20 509C8D44 vxdjump 448D9C50
014F0009 35 432BC683 xor eax,83C62B43
014F000E EC in al,dx
014F000F 2013 and byte ptr ds:[ebx],dl
...
014F0197 /EB 01 jmp short 014F019A
014F0199 |C7 ??? ; 未知命令
014F019A \FFD0 call eax // 就是这里
014F019C FF7424 0C push dword ptr ss:[esp+C]
014F01A0 8D4447 7C lea eax,dword ptr ds:[edi+eax*2+7C]
014F01A4 65:EB 01 jmp short 014F01A8
进入call eax到第二层:可以一路F8
0127B348 55 push ebp
0127B349 8BEC mov ebp,esp
0127B34B 83C4 D4 add esp,-2C
0127B34E 53 push ebx
0127B34F 56 push esi
0127B350 57 push edi
0127B351 33C0 xor eax,eax
0127B353 8945 D8 mov dword ptr ss:[ebp-28],eax
0127B356 8945 D4 mov dword ptr ss:[ebp-2C],eax
0127B359 8945 DC mov dword ptr ss:[ebp-24],eax
0127B35C 8B5D 08 mov ebx,dword ptr ss:[ebp+8]
...
0127B481 8B7483 68 mov esi,dword ptr ds:[ebx+eax*4+68]
0127B485 8B45 FC mov eax,dword ptr ss:[ebp-4]
0127B488 FFD6 call esi
0127B48A 8BF0 mov esi,eax
0127B48C 3B75 F8 cmp esi,dword ptr ss:[ebp-8]
0127B48F 75 63 jnz short 0127B4F4
0127B491 807B 20 00 cmp byte ptr ds:[ebx+20],0
0127B495 74 3C je short 0127B4D3 ; 分类处
...
0127B4A1 8B5483 68 mov edx,dword ptr ds:[ebx+eax*4+68]
0127B4A5 8B45 FC mov eax,dword ptr ss:[ebp-4]
0127B4A8 FFD2 call edx ; 再次分类
0127B4AA 3C 01 cmp al,1 ; eax为1则是a情况
0127B4AC 75 25 jnz short 0127B4D3 ; eax为0则是b情况
0127B4AE 56 push esi
0127B4AF 8D45 FC lea eax,dword ptr ss:[ebp-4]
0127B4B2 50 push eax
0127B4B3 8B45 14 mov eax,dword ptr ss:[ebp+14]
0127B4B6 50 push eax
0127B4B7 8B45 18 mov eax,dword ptr ss:[ebp+18]
0127B4BA 50 push eax
0127B4BB 8B45 0C mov eax,dword ptr ss:[ebp+C]
0127B4BE 50 push eax
0127B4BF 8B45 F0 mov eax,dword ptr ss:[ebp-10]
0127B4C2 50 push eax
0127B4C3 8B4D 1C mov ecx,dword ptr ss:[ebp+1C]
0127B4C6 8B55 10 mov edx,dword ptr ss:[ebp+10]
0127B4C9 8BC3 mov eax,ebx
0127B4CB E8 C0010000 call 0127B690 ; a情况
0127B4D0 /EB 01 jmp short 0127B4D3
...
0127B4D3 8D45 FC lea eax,dword ptr ss:[ebp-4]
0127B4D6 50 push eax
0127B4D7 8B45 14 mov eax,dword ptr ss:[ebp+14]
0127B4DA 50 push eax
0127B4DB 8B45 18 mov eax,dword ptr ss:[ebp+18]
0127B4DE 50 push eax
0127B4DF 8B45 0C mov eax,dword ptr ss:[ebp+C]
0127B4E2 50 push eax
0127B4E3 8B45 F0 mov eax,dword ptr ss:[ebp-10]
0127B4E6 50 push eax
0127B4E7 8B4D 1C mov ecx,dword ptr ss:[ebp+1C]
0127B4EA 8B55 10 mov edx,dword ptr ss:[ebp+10]
0127B4ED 8BC3 mov eax,ebx
0127B4EF E8 64F1FFFF call 0127A658 ; b情况
0127B4F4 81C7 FF000000 add edi,0FF
0127B4FA 3B7D F4 cmp edi,dword ptr ss:[ebp-C]
0127B4FD ^ 0F86 64FFFFFF jbe 0127B467
0127B503 EB 01 jmp short 0127B506
a情况,进入call 0127B690:
0127B7DD 8B45 F4 mov eax,dword ptr ss:[ebp-C]
0127B7E0 8B80 E0000000 mov eax,dword ptr ds:[eax+E0]
0127B7E6 0345 E4 add eax,dword ptr ss:[ebp-1C]
0127B7E9 8945 FC mov dword ptr ss:[ebp-4],eax // [ebp-4]是解密出来的API
0127B7EC 33C0 xor eax,eax
0127B7EE 8AC3 mov al,bl
0127B7F0 0145 10 add dword ptr ss:[ebp+10],eax
0127B7F3 57 push edi
0127B7F4 6A 00 push 0
0127B7F6 8D4D E0 lea ecx,dword ptr ss:[ebp-20]
0127B7F9 8B45 F4 mov eax,dword ptr ss:[ebp-C]
0127B7FC 8B40 3C mov eax,dword ptr ds:[eax+3C]
0127B7FF 8B55 FC mov edx,dword ptr ss:[ebp-4]
0127B802 E8 6DB9FFFF call 01277174
0127B807 8945 FC mov dword ptr ss:[ebp-4],eax
0127B80A 8B45 E0 mov eax,dword ptr ss:[ebp-20]
0127B80D 8B00 mov eax,dword ptr ds:[eax]
0127B80F E8 C0E6FFFF call 01279ED4
0127B814 8BD0 mov edx,eax
0127B816 0255 DF add dl,byte ptr ss:[ebp-21] ; 这里得到dl
0127B819 8B4D FC mov ecx,dword ptr ss:[ebp-4] ; [ebp-4C]就是我们要的函数
0127B81C 8B45 F4 mov eax,dword ptr ss:[ebp-C]
到了这里 [ebp-4C]是我们需要的导入函数的地址,dl中的值决定了是call(ff15)还是jmp(ff25)
dl中的值不同的程序是随机,找几个call 014F0000进去出来看一下就知道当前的程序中哪个对应ff15,哪个对应ff25了
b情况,进入call 0127A658,一路F8:
0127A7D6 8B7C82 68 mov edi,dword ptr ds:[edx+eax*4+68]
0127A7DA 8B06 mov eax,dword ptr ds:[esi]
0127A7DC FFD7 call edi
0127A7DE 8845 CA mov byte ptr ss:[ebp-36],al
0127A7E1 8B45 F4 mov eax,dword ptr ss:[ebp-C]
0127A7E4 8A40 4A mov al,byte ptr ds:[eax+4A]
0127A7E7 3A45 EF cmp al,byte ptr ss:[ebp-11] ; al的值决定是FF15还是FF25
0127A7EA 0F85 9C000000 jnz 0127A88C ; 不跳是FF15情况
0127A7F0 EB 01 jmp short 0127A7F3
al中的值,不同程序是不同的。我的是F7。
FF15:
0127A7F3 8B45 F4 mov eax,dword ptr ss:[ebp-C]
0127A7F6 8B80 E0000000 mov eax,dword ptr ds:[eax+E0]
0127A7FC 0145 FC add dword ptr ss:[ebp-4],eax ; [ebp-4]是解密出来的API
0127A7FF EB 01 jmp short 0127A802 ; 这里下断就能得到API
FF25:
0127A8A5 8B45 F4 mov eax,dword ptr ss:[ebp-C]
0127A8A8 8B80 E0000000 mov eax,dword ptr ds:[eax+E0]
0127A8AE 0145 FC add dword ptr ss:[ebp-4],eax ; [ebp-4]是解密出来的API
0127A8B1 8D45 0C lea eax,dword ptr ss:[ebp+C] ; 这里下断就能得到API
0127A7FC或0127A8AE或0127B7E9执行完后[ebp-4] 是需要的输入函数的地址,再看看[ebp-2c],如果它是FFFFFFFF,说明这个导入函数调用是干净的,如果它有值,表示它的下一行也偷了。
因此只要在0127A7FF&0127A8B1&0127B819处下断即可获得API。
[1] [2] [3] [4] 下一页