iconXP1.03脱壳篇
经过电神,小三,hying,BF,等高手的调教我也算是对aspr的壳“稍微”的了解了一点,算是个初入门的“小脱”吧!电神说过现在的人是幸福的,可以有很多的参考资料,以前的人都是自己啃的。哎!我们现在的人多幸福阿!有前辈们在脚下铺路,我们可以踏在前人的足迹(身上?^_^)大步的前进!
言归正传!
首先就是找程序的入口,还好这个程序是delphi写的,可以很容易找到入口的。如果不是?那就要很麻烦了,需要硬功夫才行。这里就不专门介绍VC/C++等的手动找入口的方法了,不过有很多可以参考的好文章阿!(介绍几个在看雪精华III中的文章:《如何跟踪asprotect》还有liotta[bcg]写的几个asprotect1.3X的文章。)
那么这个程序怎么找呢?还好电神已经告诉我们了,具体的方法是先运行程序,然后用Procdump工具dump下来,存为X.exe,再用winhex打开它,查找runtime,找到后向上查看找到55
8B EC 看看下面偏移量100118(记住)然后再用peditor载入X.exe文件,打开文件地址计算器,在偏移量处输入100118然后计算,看到虚拟地址为00500B18,哈哈!500B18就你要找的入口了!
其次就是脱壳了,运行superbpm(帮助你增强断点),运行trw2000,然后载入未脱壳的文件,然后load,下断点bpx 500B18,过一会儿程序就会被断下了,这里就是程序的入口了,suspend挂起程序。再次运行procdump,dump下现在的内存中的镜像存为dump.exe然后运行ImportREC
1.X找到进程iconxp.exe然后在oep处填上100B18(由500B18-400000得来)然后点IAT AutoSearch,importrec会自动找到RVA和Size的,再点Get
Imports就会得到很多的修复的和未修复的API然后点击Auto Trace程序会自动分析API的,当然还有未修复的,这就要手动来修了!方法如下:中断iconxp.exe的进程,再用trw再次载入,点load,用bpx
getversion下断点,然后按一次F12,记住API下面的[XXXXXXX]中的地址。然后按F5让程序继续运行,会断在入口处,再用U 00CEC960看看,记住[eax]中的地址,跟刚才的[XXXXXXXX]比较一下,看看是那个函数!就添入哪个就行了!
1001081F8kernel32.dll0158GetCurrentDirectoryA
0001081FC?000000CEC960
100108200kernel32.dll0133FreeLibrary
100108204kernel32.dll011CFindFirstFileA
有的是空函数,就用lockresource代替就行了!
100108338kernel32.dll0251MulDiv
00010833C?000000CEC968
100108340kernel32.dll022ELoadResource <----注意这里
100108344kernel32.dll022ALoadLibraryExA
有的要用freeresource代替
1001083ECkernel32.dll013EGetCPInfo
0001083F0?000000CEC974
1001083F4kernel32.dll0133FreeLibrary <-----注意这里
1001083F8kernel32.dll012DformatMessageA
都修复好了,就可以用Fix Dump来修复dump.exe了!
但是你会发现dump_.exe还是不能运行,这是怎么回事呢?让我们再次载入dump_.exe来看看吧!
0167:00500B16 PUSH EAX
0167:00500B17 ADD [EBP-75],DL
0167:00500B19 MOV EBP,ESP
0167:00500B1B ADD ESP,-0C
0167:00500B1E MOV EAX,00500700
0167:00500B23 CALL 004067F8
0167:00500B28 CALL [00506998] <-----注意这里的调用,进去后就没有反映了!
0167:00500B2E CALL 00403B88
0167:00500B33 NOP
0167:00500B34 ADD [EAX],AL
0167:00500B36 ADD [EAX],AL
0167:00500B38 ADD [EAX],AL
0167:00500B3A ADD [EAX],AL
0167:00500B3C ADD [EAX],AL
0167:00500B3E ADD [EAX],AL
我们再载入原版来看看吧!
0167:00CEC8FB NOP
0167:00CEC8FC CMP DWORD PTR [00CF35A8],00 <----进入后就来到这儿
0167:00CEC903 JZ 00CEC90B
0167:00CEC905 CALL [00CF35A8]
0167:00CEC90B RET
0167:00CEC90C PUSH EBP
0167:00CEC90D MOV EBP,ESP
0167:00CEC90F MOV EAX,[EBP+08]
0167:00CEC912 TEST EAX,EAX
0167:00CEC914 JNZ 00CEC91D
0167:00CEC916 MOV EAX,[00CF3560]
0167:00CEC91B JMP 00CEC923
0167:00CEC91D PUSH EAX
0167:00CEC91E CALL KERNEL32!GetModuleHandleA
0167:00CEC923 POP EBP
阿!我明白了,脱壳后的程序要用到CFXXXX的数据,那么我们只好添加进取了,用d CEC8FC看看这段数据有多少,我们统统地dump出来!
用alt+pageup向上查看,当看到数据框内如下显示就到了!
0030:00CE0FE0 ???????? ???????? ???????? ????????
................
0030:00CE0FF0 ???????? ???????? ???????? ????????
................ <---都是空的了
0030:00CE1000 7473060A 676E6972 00000000 00000000
..string........ <---从这里开始
0030:00CE1010 00000000 00000000 00CE103C 00000000
........<.......
0030:00CE1020 00CE116D 00000004 00000000 00CE29B0
m............)..
0030:00CE1030 00CE2898 00CE28C0 00CE2904 000B0011
.(...(...)......
0030:00CE1040 00CE2910 65724604 1C001365 0C00CE29
.)...Free...)...
0030:00CE1050 74696E49 74736E49 65636E61 29380016
InitInstance..8)
0030:00CE1060 430F00CE 6E61656C 6E497075 6E617473
...CleanupInstan
0030:00CE1070 00106563 00CE2854 616C4309 79547373
ce..T(...ClassTy
再向下看当看到:
0030:00CF7FA0 00000000 00000000 00000000 00000000
................
0030:00CF7FB0 00000000 00000000 00000000 00000000
................
0030:00CF7FC0 00000000 00000000 00000000 00000000
................
0030:00CF7FD0 00000000 00000000 00000000 00000000
................
0030:00CF7FE0 00000000 00000000 00000000 00000000
................
0030:00CF7FF0 00000000 00000000 00000000 00000000
................<---到这里结束了
0030:00CF8000 ???????? ???????? ???????? ????????
................<---空地址了
0030:00CF8010 ???????? ???????? ???????? ????????
................
0030:00CF8020 ???????? ???????? ???????? ????????
................
0030:00CF8030 ???????? ???????? ???????? ????????
................
就对了!算算这段数据有多大呢?以后会有用的,CF8000-CE1000=17000
好了,我们就截取这段地址吧!在trw2000中用w CE1000 CF8000 NEW.bin命令保存起来。
用winhex打开dump_.exe和NEW.bin把NEW.bin的内容粘贴到dump_.exe的最后,然后再打开peditor载入dump_.exe然后添加一个新段名字为new,然后编辑它
添入相关的数据,
虚拟大小添入17000,虚拟偏移量添入8E1000(CE1000-400000=8E1000),原始大小添入17000。然后就该重新建PE头了,好让他找到新的数据。
选择重建,在选项中只选使pe头区兼容win2000/nt,点确定就行了。这样就可以运行了,但是还是有个问题,有些功能却不能用,比如打开等,连退出都不行。经过大家的讨论,发现aspr的壳用到findfirstfilea作为检查是否被脱壳的判断。我们用bpx
findfirstfilea来下断看看
0167:00408CD3 CALL KERNEL32!FindFirstFileA
0167:00408CD8 MOV ESI,EAX
0167:00408CDA MOV [EBX+14],ESI
0167:00408CDD CMP ESI,-01
0167:00408CE0 JZ 00408CF8
0167:00408CE2 MOV EAX,EBX
0167:00408CE4 CALL 00408C54
0167:00408CE9 MOV ESI,EAX <---小三说修改这里为inc esi
,nop。就行了!当然用smc也可以做到,可惜我不会。
0167:00408CEB TEST ESI,ESI
0167:00408CED JZ 00408CFF
0167:00408CEF MOV EAX,EBX
0167:00408CF1 CALL 00408D2C
0167:00408CF6 JMP 00408CFF
0167:00408CF8 CALL KERNEL32!GetLastError <---修改后这里会被跳过。
0167:00408CFD MOV ESI,EAX
按一次F12就会发现比较的地方了!
0167:004D9317 CALL 0045E868
0167:004D931C MOV EBX,EAX
0167:004D931E CMP EBX,000F4240 <----这里就是比较地方了!
0167:004D9324 JLE 004D9351 <----如果这里用jz,可就麻烦了,必须用smc咯!哈哈!
0167:004D9326 LEA EDX,[EBP-08]
0167:004D9329 XOR EAX,EAX
0167:004D932B CALL 00402A70
0167:004D9330 MOV EAX,[EBP-08]
0167:004D9333 CALL 0045E868
0167:004D9338 SUB EBX,EAX
0167:004D933A MOV EAX,00000017
0167:004D933F CDQ
0167:004D9340 IDIV EBX
0167:004D9342 PUSH EAX
0167:004D9343 PUSH 00000988
到此就脱壳完成了,根据大家的研究结果,可以修复好脱壳后的程序了,都是前辈们的研究结果,我只是整理和享用而已!
希望对大家有帮助,也希望我可以想前辈们那样帮助刚刚入门的朋友们!
小球
2002.1.23