把 ASProtect 2.1x SKE -> Alexey Solodovnikov 送上流水线
目标程序:木马克星 5.51(引擎版本号 0515)加壳类型:ASProtect 2.1x SKE -> Alexey Solodovnikov
使用工具:OllyDbg 1.10 (OD),PEiD 0.94,StudPE 2.3
文章作者:looyoo //2006.7.7.
特别声明:此前已在看雪或一蓑烟雨发过 ASProtect 2.1x 脱壳帖的弟兄,皆为吾师,一并致谢!
七月流火,酷暑难当。昨晚忽得一夜喜雨,感觉舒坦了许多。为了打发世界杯决赛前的无聊,我捣鼓起了“壳壳”的干活,但无奈壳王的霸气,累战累败。为加快“围猎”的步伐起见,我用“自加自脱”的办法,放弃所有附加选项来加壳目标程序,集中火力打歼灭战,使脱壳变为只是处理“CALL xxxxxxx -> JMP DWORD PTR DS:[??????]”的单一问题,因为这才是我累战累败的麦城。我拿来试练的目标程序是一款剪贴板,加壳、调试、补丁、转储、修改,一切按部就班。几个回合下来,竟然也见到了晴天日出,我成功了!是简单至明了?是功到垂成?抑或是幸遇软蛋?都有可能,但将复杂抽象成简单再各个击破,是成功的一大法门。推倒重来吧,让模糊变得清晰,让偶然成为有章可循,如何?所幸仍然成功了。感觉有了点门道,于是想用文字记录下来。但该目标程序就一个问题、一个补丁,是否过于简单呢?我于是想加个附加选项,比如加密“IAT”,但无论我怎么设置,无论加壳后怎样清楚明白的显示,在 OD下都只有那个“CALL xxxxxx”问题,一头雾水,看来我还得为加壳去听讲座。万幸中的不幸,此时我家的电脑又偏偏不能上网,不然也用不着为了个目标程序而这样折腾。翻箱倒柜了半天后,总算在“库存”中找到了一款名为“木马克星 5.51”的程序(向作者致歉!),PEiD 下显示“ ASProtect 2.1x SKE -> Alexey Solodovnikov”,正合我意,就让它做标本上手术台吧,窃喜!^_^
我们可以分两步进行:1.获取有关信息;2.解剖剥离。
1.获取有关信息:
OD 加载目标程序,Shift+F9 直至显示程序界面,记下按键次数并留意 CPU 窗口数据。重新加载目标程序,Shift+F9 到最后一次异常,Alt+M 到内存窗口,记下 Data 的值 589000,在 401000 上设断,Shift+F9 至 OEP:588a6c,Ctrl+B 搜索 FF 25,得到 IAT 内的一个地址 5a3348 及壳调用位置(CALL xxxxxxx//004012B4 E8 47EDBA00 CALL 00FB0000) 00FB0000,IAT 还需要精确定位,留到下一步顺便解决吧。
第一步所得相关信息为:
OEP 588a6c
Data589000
TAT 5a3294~5a6d08(由第二步获取)
CALL00fb0000
2.解剖剥离:
OD 加载目标程序,Shift+F9 直至“00DBEA55MOV BYTE PTR DS:,0B6”,也可以在此前任何位置,搜索字符“85”,并双击返回到 CPU 窗口,在两个“85”之间的第二个 CALL (00DBEC09 CALL 00DB7818)上设断,Shift+F9 运行至此,撤销断点,F7 步入该 CALL,进入新界面后,向下滚屏至第一个返回点 00DB7989 RETN,设断,向上找到最近的一个 CALL//00DB795ACALL 00DB75B8,F4 至此,F7 步入后,向下滚屏至 00DB75F2CMP ESI,EAX,(CMP,JNZ,JMP 成组出现)设断,F9 运行,注意寄存器窗口 eax,esi,edi 的值的变化,F9 连续按键过程中,eax 相继出现三个参数 8c,9d,91,其中 9d 与 eax 的数据相同,不管它。当 esi 出现 91 时,edi 中的函数名随按键动作相应变化(每变化一次相对应的在数据窗口的 IAT 内增加一个函数名称),而 8c 则不然,据此判断 8c 被加密,而 91 未加密。至此,补丁参数已经确定,IAT 起始及终止地址这时也可从数据窗口读取,即:5a3294~5a3d08(命令槽口 d 5a3348,其中 5a3348 在第 1 步得知)。
再重新加载目标程序,Shift+F9 直接运行至 00DB75F2CMP ESI,EAX,设断,F9 运行,在寄存器 esi 中刚出现 8c 时开始第一次补丁。先用 OllyHelper 申请一块内存空间,我这里是 010B0000,修改 00DB75F4JNZ SHORT 00DB7654 为 00DB75F4JMP 010B0000,去断点,F8 至 010B0000 后,粘贴补丁:
010B0000- 0F84 F375D0FF JE 00DB75F9
010B0006 81FE 91000000 CMP ESI,91----------------------------------91 为未加密参数
010B000C- 0F84 4276D0FF JE 00DB7654
010B0012 BE 91000000 MOV ESI,91
010B0017- E9 3876D0FF JMP 00DB7654
----------------
0F 84 F3 75 D0 FF 81 FE 91 00 00 00 0F 84 42 76 D0 FF BE 91 00 00 00 E9 38 76 D0 FF
然后 F9 运行,IAT 随即被解密,可从命令槽口 d 5a3294,再在数据窗口观察验证。接下来,撤销 00DB75F4 处的更改(切记!),补丁是否撤销无碍,Shift+F9 至最后一次异常 00DBFAA5 C700 EFCA5C85 MOV DWORD PTR DS:,855CCAEF,Ctrl+B 搜索“89,45,F0,B8,00,07,00,00”,在 00DB7190 CALL 00D9254C 设断,Shift+F9 至此,撤销断点,沿用前面申请到的内存空间,改 CALL 00D9254C 为 JMP 010B0037 后,转到(注意不是运行到...)该内存空间,粘贴补丁:
010B0000 BA 00104000 MOV EDX,Iparmor.<ModuleEntryPoint>-----------新建 EIP 后 F9 运行//也可以 F8 运行,一步步地观察修改过程
010B0005 803A E8 CMP BYTE PTR DS:,0E8
010B0008 75 12 JNZ SHORT 010B001C
010B000A 8B42 01 MOV EAX,DWORD PTR DS:
010B000D 03C2 ADD EAX,EDX
010B000F 83C0 05 ADD EAX,5
010B0012 3D 0000FB00 CMP EAX,0FB0000------------------------------来自 CALL xxxxxxx
010B0017 75 03 JNZ SHORT 010B001C
010B0019 EB 0C JMP SHORT 010B0027
010B001B 90 NOP
010B001C 42 INC EDX
010B001D 81FA 00905800 CMP EDX,589000-------------------------------Data 起点
010B0023^ 72 E0 JB SHORT 010B0005
010B0025- EB FE JMP SHORT 010B0025
010B0027 8915 00010B01 MOV DWORD PTR DS:,EDX--------------- 要作相应修改,下同。
010B002D 60 PUSHAD
010B002E FFE2 JMP EDX
010B0030 90 NOP
010B0031 90 NOP
010B0032 90 NOP
010B0033 90 NOP
010B0034 90 NOP
010B0035 90 NOP
010B0036 90 NOP
010B0037 60 PUSHAD
010B0038 B8 94325A00 MOV EAX,5A3294-------------------------------IAT 起点
010B003D 90 NOP
010B003E 3910 CMP DWORD PTR DS:,EDX
010B0040 75 20 JNZ SHORT 010B0062
010B0042 8B0D 00010B01 MOV ECX,DWORD PTR DS:
010B0048 C701 FF250000 MOV DWORD PTR DS:,25FF
010B004E 8941 02 MOV DWORD PTR DS:,EAX
010B0051 61 POPAD
010B0052 90 NOP
010B0053 8B15 00010B01 MOV EDX,DWORD PTR DS:
010B0059 90 NOP
010B005A 90 NOP
010B005B 90 NOP
010B005C^ EB BE JMP SHORT 010B001C
010B005E 90 NOP
010B005F 90 NOP
010B0060 90 NOP
010B0061 90 NOP
010B0062 83C0 04 ADD EAX,4
010B0065 3D 083D5A00 CMP EAX,5A3D08-------------------------------IAT 终点
010B006A^ 7E D2 JLE SHORT 010B003E
010B006C^ EB E3 JMP SHORT 010B0051
----------------------------
BA 00 10 40 00 80 3A E8 75 12 8B 42 01 03 C2 83 C0 05 3D 00 00 FB 00 75 03 EB 0C 90 42 81 FA 00
90 58 00 72 E0 EB FE 89 15 00 01 0B 01 60 FF E2 90 90 90 90 90 90 90 60 B8 94 32 5A 00 90 39 10
75 20 8B 0D 00 01 0B 01 C7 01 FF 25 00 00 89 41 02 61 90 8B 15 00 01 0B 01 90 90 90 EB BE 90 90
90 90 83 C0 04 3D 08 3D 5A 00 7E D2 EB E3
修改那几个已标注的数据后,在补丁的第一行新建 EIP,F9 运行,这时“CALL xxxxxxx” 变成了“JMP DWORD PTR DS:[??????]”格式,可以搜索一下“CALL 0FB0000”看看是否还有遗漏,确认无遗漏后转储进程为可执行文件,PEiD 检测该文件,提示为无效 PE 文件,用 StudPE 修改 RVA 后再检测,提示为 Borland Delphi 4.0 - 5.0,显然已是有效 PE 文件了,但点击后仍然不能运行。OD 加载,F9 运行,主窗口变得一片空白,堆栈提示 0012F984 0040DFF4RETURN to 1.0040DFF4 from 1.0040A708,找到 0040A708JMP 00FF0000,显然 JMP 00FF0000 地址已经随壳而去,改为 JMP 0040a76d(见六楼附注),保存更改到可执行文件,点击运行,正常!解剖剥离手术到此结束。
希望我这一夜汗水对后来的弟兄有所帮助。
(主程序脱壳前 1038 KB,脱壳后 2308 KB)
一点体会:
1.判断 IAT 是否加密,只要在 00DB75F2CMP ESI,EAX 设断,F9 运行,观察寄存器 esi,edi 的联动反应即可。加密时,esi 的值不变,则 edi 的函数名也不变(若不存在该现象,则 IAT 未加密);未加密时,esi 的值不变,但 edi 中的函数名却会随 F9 的键击而变。这比通过数据窗口判断来得简单;
2.第一个补丁在加密参数刚出现时即操作,第二个补丁粘贴完成后要先新建 EIP,然后再 F9 运行,请后来的弟兄注意;
3.搜索“85”字符可以在 F9 初次运行后即执行,因为设断后 Shift+F9 运行自然会中断在指定位置,没有必要紧盯着寻找“0B6”之类。确定第二个补丁位置时,运行到最后一次异常即可搜索“89,45,F0,B8,00,07,00,00”,并定位在紧接其下的 CALL 处,其他的繁琐操作似乎均可略去。
本文旨在与菜鸟交流,谬误之处,请能者赐教!转载请注明作者并保持文章的完整, 谢谢! 不错!可是我的怎么不行啊!DATA段头你是怎么确定的啊!
好贴,精彩!!
兄弟有本事!~~学习了!~~!! 学习了,不过有点难 ASProtect 2.1x SKE 没用脚本的话是很麻烦! 这个壳。。很难。。。学习当中。。 猛壳。。。要对照练习先。。 好,学习猛壳 这个猛壳的脱法找好好久,我一定要好好学,这里的东东真多呀. 一定要学会这壳..碰到N多软件加这壳的了!搞N+M次都没弄明白
页:
[1]
2