上次帮敏毅兄脱那个 PEtite 壳的程序,顺便把手脱 PEtite 壳的一般方法写一下,大家可以对照来自己手脱这类的壳。当然,程序各有不同,我只是就 xmplay 3.3 这个软件来写的,我希望方法能通用。不过别的程序你按我这个方法没脱掉,可不要怪我啊,呵呵。下面用到的工具我都是按我汉化的来解释的,要是给你带来困惑的话,还请原谅!写这个只是希望能给大家一个参考。不多废话,下面进入正题:
一、DLL的脱壳方法:
我们从官方网站下载的原始压缩包中选一个 xmp-wma.dll 来测试一下。用 OllyDBG 载入,会有一个请求载入 DLL 文件的对话框,问是否用 LOADDLL.EXE 载入,我们选“是”。稍等一会又出来一个入口点警告的对话框,点“确定”,接着又有个询问是否为压缩代码,是否需要分析的对话框,这里我们选“否”。进入程序,我们停在这:
10017039 > B8 00700110 MOV EAX,xmp-wma.10017000 ; 开始停在这
1001703E 68 00500110 PUSH xmp-wma.10015000
10017043 64:FF35 0000000>PUSH DWORD PTR FS:[0]
1001704A 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
10017051 66:9C PUSHFW
10017053 60 PUSHAD
10017054 50 PUSH EAX
不要管它,直接 F9 运行(在我这跳出一个异常对话框,不管它,点确定,SHIFT+F9继续运行),稍后 OllyDBG 的左下角会显示“要调试的 DLL 初始化结束”,我们暂停在这里:
10001000 /$ 55 PUSH EBP ; 停在这里
10001001 |. 8BEC MOV EBP,ESP
10001003 |. 83EC 20 SUB ESP,20
10001006 |. 53 PUSH EBX
10001007 |. 56 PUSH ESI
10001008 |. 8BF1 MOV ESI,ECX
1000100A |. 33DB XOR EBX,EBX
1000100C |. 57 PUSH EDI
1000100D |. 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C]
现在继续不管,还是在 OllyDBG 中 F9 运行,再用鼠标左键点击任务栏那的绿色的 LOADDLL.EXE 的图标,出来一个小窗口,点关闭图标关掉它,我们将在 OllyDBG 中停在这里:
10017039 > $- E9 08B5FFFF JMP xmp-wma.10012546 ; 停在这里,跳转目标就是OEP
1001703E $- E9 84307F6C JMP kernel32.WideCharToMultiByte
10017043 $- E9 75297F6C JMP kernel32.LocalAlloc
10017048 $- E9 79BA7F6C JMP kernel32.GetSystemInfo
1001704D $- E9 24A47F6C JMP kernel32.DisableThreadLibraryCalls
10017052 $- E9 CEA57E6C JMP kernel32.DeviceIoControl
10017057 $- E9 5B81806C JMP kernel32.GlobalMemoryStatus
1001705C $- E9 4C38D067 JMP USER32.wsprintfA
10017061 $- E9 C65F9966 JMP ole32.CoTaskMemFree
大家可以注意看一下,和刚开始进入的地址是不是一样啊?呵呵。这时按一下 F8 单步一下,来到这里:
10012546 /. 55 PUSH EBP ; OEP,可直接用插件 OllyDump 脱壳
10012547 |. 8BEC MOV EBP,ESP
10012549 |. 53 PUSH EBX
1001254A |. 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+8]
1001254D |. 56 PUSH ESI
1001254E |. 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
10012551 |. 57 PUSH EDI
10012552 |. 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10]
这里找 OEP 的方法是利用了 DLL 退出时会再次中断在EP处的原理,记得 fly 曾经说过。如果你和我一样用的是 OllyDump v3.00.110 版的插件的话,这个 DLL 脱出来后都不需修复输入表。如果不是的话,修复也很简单:
用插件脱壳后先不要关 OllyDBG ,继续让 OllyDBG 暂停在上面 10012546 地址处,启动 ImportREC_fix.exe,在进程列表中选择 loaddll.exe,再点后面的“选取 DLL”按钮,选择 xmp-wma.dll 后按确定,把选项中的“使用来自磁盘的 PE 文件头”选项去掉,“重建原始 FT”选项勾上,在OEP中填12546,点“自动查找 IAT”按钮,出来一个对话框,点“确定”,再点“获取输入表按钮”,会有一些函数无效。点“显示无效的”按钮,在无效函数上右击,选“跟踪级别 1 (反汇编)”菜单,这时所有无效函数都已修复,现在点“修复转存文件”按钮把你刚才脱出来的文件修复一下就可以了。
到此为止我们的脱壳工作已告一段落,剩下的就是修复重定位表的问题了。现在我们打开 PE Tools 1.5,点菜单 插件->Reloc 重建器,选择我们刚才脱壳后的文件,点“重建”按钮,OK,完工!测试一下,一切正常!到此可再用 PE Tools 优化一下文件,减小一下体积。
二、主程序
OllyDBG 载入,停止这里:
0054B039 > B8 00B05400 MOV EAX,xmplay.0054B000 ; 载入后停在这里
0054B03E 68 BDA74400 PUSH xmplay.0044A7BD
0054B043 64:FF35 0000000>PUSH DWORD PTR FS:[0] ; F8运行到这一步时在命令行中输 hr esp
现在F9运行,会中断6次。第6次断下来时代码如下:
0044367E 55 PUSH EBP ; OEP,真正的入口点
0044367F 8BEC MOV EBP,ESP ; 我们断在这里
00443681 6A FF PUSH -1
00443683 68 18874400 PUSH xmplay.00448718
记住上面的OEP地址,删除硬件断点,重新载入程序,前面步骤一样,也是先F8单步到 54B043 位置时在命令行中输 hr esp 命令,F9运行。数一下断下来的次数,当第5次时删除硬件断点,在OllyDBG中按快捷键CTR+G,输入地址0044367E后按确定,这时光标将停在
0044367E 55 PUSH EBP
这一句上。这时按一下F4键,OllyDBG将运行到这个位置并暂停。此时操作就和前面脱DLL的壳一样,直接用插件 OllyDump 脱壳,再用 ImportREC_fix.exe 修正输入表就OK了。
总结一下脱主程序步骤:载入后F8运行到代码的第三行,在命令行中输入 hr esp 命令后回车,F9运行,中断6次后(次数并不是主要的)看代码是否与上面的类似,是的话就记住最后中断位置上面一句的地址,再删硬件断点,重新启动程序,前面步骤一样,在比上次少一次时删硬件断点,CTR+G到刚才记下来的地址,F4运行到这里,用插件脱壳,再用 ImportREC 重建输入表。
原则上上面的方法适合一般的 PEtite 加壳的程序,照搬就可以了。
点击参与源贴讨论
一、DLL的脱壳方法:
我们从官方网站下载的原始压缩包中选一个 xmp-wma.dll 来测试一下。用 OllyDBG 载入,会有一个请求载入 DLL 文件的对话框,问是否用 LOADDLL.EXE 载入,我们选“是”。稍等一会又出来一个入口点警告的对话框,点“确定”,接着又有个询问是否为压缩代码,是否需要分析的对话框,这里我们选“否”。进入程序,我们停在这:
CODE
10017039 > B8 00700110 MOV EAX,xmp-wma.10017000 ; 开始停在这
1001703E 68 00500110 PUSH xmp-wma.10015000
10017043 64:FF35 0000000>PUSH DWORD PTR FS:[0]
1001704A 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
10017051 66:9C PUSHFW
10017053 60 PUSHAD
10017054 50 PUSH EAX
不要管它,直接 F9 运行(在我这跳出一个异常对话框,不管它,点确定,SHIFT+F9继续运行),稍后 OllyDBG 的左下角会显示“要调试的 DLL 初始化结束”,我们暂停在这里:
CODE
10001000 /$ 55 PUSH EBP ; 停在这里
10001001 |. 8BEC MOV EBP,ESP
10001003 |. 83EC 20 SUB ESP,20
10001006 |. 53 PUSH EBX
10001007 |. 56 PUSH ESI
10001008 |. 8BF1 MOV ESI,ECX
1000100A |. 33DB XOR EBX,EBX
1000100C |. 57 PUSH EDI
1000100D |. 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C]
现在继续不管,还是在 OllyDBG 中 F9 运行,再用鼠标左键点击任务栏那的绿色的 LOADDLL.EXE 的图标,出来一个小窗口,点关闭图标关掉它,我们将在 OllyDBG 中停在这里:
CODE
10017039 > $- E9 08B5FFFF JMP xmp-wma.10012546 ; 停在这里,跳转目标就是OEP
1001703E $- E9 84307F6C JMP kernel32.WideCharToMultiByte
10017043 $- E9 75297F6C JMP kernel32.LocalAlloc
10017048 $- E9 79BA7F6C JMP kernel32.GetSystemInfo
1001704D $- E9 24A47F6C JMP kernel32.DisableThreadLibraryCalls
10017052 $- E9 CEA57E6C JMP kernel32.DeviceIoControl
10017057 $- E9 5B81806C JMP kernel32.GlobalMemoryStatus
1001705C $- E9 4C38D067 JMP USER32.wsprintfA
10017061 $- E9 C65F9966 JMP ole32.CoTaskMemFree
大家可以注意看一下,和刚开始进入的地址是不是一样啊?呵呵。这时按一下 F8 单步一下,来到这里:
CODE
10012546 /. 55 PUSH EBP ; OEP,可直接用插件 OllyDump 脱壳
10012547 |. 8BEC MOV EBP,ESP
10012549 |. 53 PUSH EBX
1001254A |. 8B5D 08 MOV EBX,DWORD PTR SS:[EBP+8]
1001254D |. 56 PUSH ESI
1001254E |. 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
10012551 |. 57 PUSH EDI
10012552 |. 8B7D 10 MOV EDI,DWORD PTR SS:[EBP+10]
这里找 OEP 的方法是利用了 DLL 退出时会再次中断在EP处的原理,记得 fly 曾经说过。如果你和我一样用的是 OllyDump v3.00.110 版的插件的话,这个 DLL 脱出来后都不需修复输入表。如果不是的话,修复也很简单:
用插件脱壳后先不要关 OllyDBG ,继续让 OllyDBG 暂停在上面 10012546 地址处,启动 ImportREC_fix.exe,在进程列表中选择 loaddll.exe,再点后面的“选取 DLL”按钮,选择 xmp-wma.dll 后按确定,把选项中的“使用来自磁盘的 PE 文件头”选项去掉,“重建原始 FT”选项勾上,在OEP中填12546,点“自动查找 IAT”按钮,出来一个对话框,点“确定”,再点“获取输入表按钮”,会有一些函数无效。点“显示无效的”按钮,在无效函数上右击,选“跟踪级别 1 (反汇编)”菜单,这时所有无效函数都已修复,现在点“修复转存文件”按钮把你刚才脱出来的文件修复一下就可以了。
到此为止我们的脱壳工作已告一段落,剩下的就是修复重定位表的问题了。现在我们打开 PE Tools 1.5,点菜单 插件->Reloc 重建器,选择我们刚才脱壳后的文件,点“重建”按钮,OK,完工!测试一下,一切正常!到此可再用 PE Tools 优化一下文件,减小一下体积。
二、主程序
OllyDBG 载入,停止这里:
CODE
0054B039 > B8 00B05400 MOV EAX,xmplay.0054B000 ; 载入后停在这里
0054B03E 68 BDA74400 PUSH xmplay.0044A7BD
0054B043 64:FF35 0000000>PUSH DWORD PTR FS:[0] ; F8运行到这一步时在命令行中输 hr esp
现在F9运行,会中断6次。第6次断下来时代码如下:
CODE
0044367E 55 PUSH EBP ; OEP,真正的入口点
0044367F 8BEC MOV EBP,ESP ; 我们断在这里
00443681 6A FF PUSH -1
00443683 68 18874400 PUSH xmplay.00448718
记住上面的OEP地址,删除硬件断点,重新载入程序,前面步骤一样,也是先F8单步到 54B043 位置时在命令行中输 hr esp 命令,F9运行。数一下断下来的次数,当第5次时删除硬件断点,在OllyDBG中按快捷键CTR+G,输入地址0044367E后按确定,这时光标将停在
CODE
0044367E 55 PUSH EBP
这一句上。这时按一下F4键,OllyDBG将运行到这个位置并暂停。此时操作就和前面脱DLL的壳一样,直接用插件 OllyDump 脱壳,再用 ImportREC_fix.exe 修正输入表就OK了。
总结一下脱主程序步骤:载入后F8运行到代码的第三行,在命令行中输入 hr esp 命令后回车,F9运行,中断6次后(次数并不是主要的)看代码是否与上面的类似,是的话就记住最后中断位置上面一句的地址,再删硬件断点,重新启动程序,前面步骤一样,在比上次少一次时删硬件断点,CTR+G到刚才记下来的地址,F4运行到这里,用插件脱壳,再用 ImportREC 重建输入表。
原则上上面的方法适合一般的 PEtite 加壳的程序,照搬就可以了。
点击参与源贴讨论