完美脱壳组装PE的一般步骤(Obsidium1.3.6.4 DEMO 主程序)
最近学习了天草视频。记录一下笔记。
Obsidium1.3.6.4DEMO版本主程序下载地址:http://download.csdn.net/detail/whatday/5244425
前期准备工作:
这里主要记录的完美脱壳的PE组装的一些步骤,脱壳部分用脚本带过。
一般脱壳的OD脚本如下:(跳过脚本)
/*
repair Obsidium 1.3.6.4 main program function:
1.Go to OEP
2.Fix IAT
3.Fix stolen OEP
4.Fix two type the encrypted code
5.Fix SDK API
*/var iatStart
var iatAddr
var iatKey
var iatValue
var resApiBk
var resApiBk1
var resApiBk2
var sysApiBk
var number
var oepAddr
var dataBase
var encrypteAddrmov iatStart, 00581B96 ; The code here because of different computer// This variable is used for the reduction treatment the third type special API
xor number,number// Set VirtualProtect breakpoint
gpa "VirtualProtect", "kernel32"
find $RESULT, #E9??????#
gci $RESULT, DESTINATION
gci $RESULT, DESTINATION
find $RESULT, #E8??????#
cmp $RESULT, 0
jz err5
bp $RESULT
mov sysApiBk,$RESULT// Set the code section attributes
loop0:
esto
cmp [esp + c], 1
jnz loop0
mov [esp + c], 40
esto
findmem #66623A432B2B484F4F4B#
cmp $RESULT,0
jz err6
find $RESULT, #E8??????#
cmp $RESULT,0
jz err7
bprm $RESULT,1
mov oepAddr,$RESULT
loop0_1:
esto
cmp eip,$RESULT
jnz loop0_1//Set noraml api breakpoint
findmem #0FB746026A01506A00FF7604FF37FF535485C0#
cmp $RESULT, 0
jz err1
mov resApiBk,$RESULT
add resApiBk,e
bp resApiBk// 0f 84 je set breakpoint
mov resApiBk1,resApiBk
sub resApiBk1,60
find resApiBk1, #0f84????#
cmp $RESULT,0
jz err3
cmp $RESULT,resApiBk
jae err3
gci $RESULT,DESTINATION
bp $RESULT// 75 jnz set breakpoint
mov resApiBk1,resApiBk
sub resApiBk1,40
find resApiBk1, #75??????#
cmp $RESULT,0
jz err2
cmp $RESULT,resApiBk
jae err2
gci $RESULT,DESTINATION
find $RESULT,#85c0????#
cmp $RESULT, 0
jz err4
bp $RESULT
mov resApiBk2, $RESULT// 0F 85 jnz set breakpoint
mov resApiBk1,resApiBk
sub resApiBk1,40
loop1:
find resApiBk1, #0F85????#
cmp $RESULT,0
jz next1
cmp $RESULT,resApiBk
jae next1
mov resApiBk1, $RESULT
gci resApiBk1,DESTINATION
bp $RESULT
add resApiBk1,2
jmp loop1
next1:// Set last 0f 85 breakpoint, becase it is a special breakpoint
sub resApiBk1,2
gci resApiBk1,DESTINATION
bc $RESULT
gci $RESULT, DESTINATION
mov resApiBk1,$RESULT
add resApiBk1,3
bp resApiBk1// Cycle to restore an API
mov iatAddr, iatStart
loop2:
add iatAddr,6
cmp [iatAddr], 0
jz fun3
cmp [iatAddr], #FF25#, 2
jz next3
sub iatAddr, 5
jmp loop2
next3:
mov iatKey, [iatAddr+2]
gci iatAddr,DESTINATION
mov iatValue, $RESULT//Fix noraml api
mov eip,iatValue
cmp [eip], #60#, 1
jnz next5
esto
cmp eip,resApiBk
jnz next2
sto
mov [iatKey],eax
jmp loop2//Fix first type special API
next2:
cmp eip,resApiBk2
jnz next4
mov [iatKey],eax
jmp loop2 // Fix second type special API
next4:
cmp eip,resApiBk1
jnz loop2
cmp eax,0
jnz case2
gpa "VirtualQuery", "kernel32.dll"
jmp default
case2:
cmp eax,2
jnz case3
gpa "FreeResource", "kernel32.dll"
jmp default
case3:
cmp eax,3
jnz case4
gpa "ExitThread", "kernel32.dll"
jmp default
case4:
cmp eax,4
jnz loop2
gpa "ExitProcess", "kernel32.dll"
default:
mov [iatKey], $RESULT
jmp loop2// Fix third type special API
next5:
cmp [eip], #B8#, 1
jnz test4
inc number
cmp number,1
jnz test1
gpa "GetCommandLineA", "kernel32.dll"
jmp default2
test1:
cmp number,2
jnz test2
gpa "GetCurrentProcessId", "kernel32.dll"
jmp default2
test2:
cmp number,3
jnz test4
gpa "GetVersion", "kernel32.dll"
jmp default2test4:
cmp [eip], #55#, 1
jnz loop2
gpa "lstrlenA", "kernel32.dll"
default2:
mov [iatKey], $RESULT
jmp loop2// Repair stolen OEP
fun3:
sub oepAddr,10
mov [oepAddr], #A18B904700C1E002A38F904700526A00#
findmem #426F726C616E6420432B2B#
cmp $RESULT,0
jz ret8
mov dataBase,$RESULT
mov [oepAddr+1],dataBase+8b
mov [oepAddr+9],dataBase+8f
mov eip,oepAddr + 10
sub oepAddr, 13
mov [oepAddr], #90EB10#, 3
add oepAddr, 1//clear breakpoints for the next run
clean:
bpmc
bc// Decrypting the encrypted code
mov encrypteAddr,401000
loop:
inc encrypteAddr
find encrypteAddr,#68????????FF15F2006500#
cmp $RESULT,0
je next7
mov encrypteAddr,$RESULT
mov eip,encrypteAddr
bphws eip+B, "x"
esto
fill encrypteAddr,B,90
bphwc
jmp loopnext7:
mov encrypteAddr,401000
loop4:
inc encrypteAddr
find encrypteAddr,#68????????FF15FA006500#
cmp $RESULT,0
je next8
mov encrypteAddr,$RESULT
fill encrypteAddr,B,90
jmp loop4// Fix the second type for encrypted code
next8:
mov encrypteAddr,401000
loop5:
inc encrypteAddr
find encrypteAddr, #68????????E8#
cmp $RESULT,0
je next9
mov encrypteAddr,$RESULT
mov number, [encrypteAddr+1]
add number,a
cmp number,1000
ja loop5
add number,encrypteAddr
cmp [number],#EB08#,2
jnz loop5
mov number, [encrypteAddr+1]
add number, 5
mov [encrypteAddr], #E9#, 1
mov [encrypteAddr+1],number
jmp loop5// Fix SDK API
next9:
add iatStart,6
/*jmp 005829B8nopmov eax, 0x1retnretnnopnopnopnopnop
*/
mov [iatStart], #E9170E000090B801000000C3C39090909090#
gci iatStart, DESTINATION
/*cmp dword ptr [esp], 00403063jnz L007mov dword ptr [esp+0x38], 0x7373694Bmov dword ptr [esp+0x3C], 0x70555B79mov dword ptr [esp+0x40], 0x5D4Bmov edx, 00583034retn 0x8
L007:mov dword ptr [esp+0x18], 0x2E777777mov dword ptr [esp+0x1C], 0x61706E75mov dword ptr [esp+0x20], 0x632E6B63mov word ptr [esp+0x24], 0x6Emov edx, 00583034retn 0x8
*/
mov [$RESULT], #813C24633040007520C74424384B697373C744243C795B5570C74424404B5D0000BA34305800C20800C74424187777772EC744241C756E7061C7442420636B2E6366C74424246E00BA34305800C20800#// Output log and positioning OEP
eval "OEP地址:{oepAddr}"
log $RESULT
mov eip, oepAddr
jmp ret1err1:
msg "没有找到模拟api的代码"
jmp ret1err2:
msg "模拟api的代码已经改变"
jmp ret1err3:
msg "模拟api的代码已经改变2"
jmp ret1err4:
msg "模拟api的代码已经改变3"
jmp ret1err5:
msg "定位VirtualProtect错误"
jmp ret1err6:
msg "没有找到BC的特征码"
jmp ret1err7:
msg "没有找到BC的入口的CALL"
jmp ret1err8:
msg "没有找到数据段"
jmp ret1err9:
msg "修复加密代码错误"
jmp ret1ret1:
ret
运行此脚本后 OD停在OEP处
第一步:
此时用LordPE Deluxe dump 得到dumped.exe文件 在dump之前先要修复一下镜像大小,这也是anti dump的一种方法。
修复大小
dump
这里查看一下区段信息
发现资源段还存在这里可以备份一份文件,后边修复资源使用。
如果是一般脱壳到这里只需要修复IAT就完成了。接下来是找一个相同编译器的生成的无壳程序,把它的PE头覆盖复制到dump文件上 ,这里是BC程序所以找一个BC程序
第二步:
用C32Asm打开dump文件和无壳的BC程序 复制无壳程序PE头道dump文件
点击按钮是 然后保存
这个时候发现dump程序的图标不显示了
这是因为资源段找不到,本质就是PE头和PE节不匹配造成的,因为要完美脱壳,所以必须在原本的PE头基础上来拼装各个节表,这样才算完美。
这个时候用LordPE查看一下节表信息
可以看出各个节表都有了,这点和无壳程序完全一样了,但是这只是PE头,具体对应的节表还需要修复。
第三步:
接下来通过跟踪 VirtualProtect函数 可以得到原始的节区段信息,这个是OB的一个特点,其他壳不知道。
重新载入DEMO程序,bp VirtualProtect 循环shift+F9 得出原始区段信息
可以看出 第一张和最后一张不在范围了 所以实际上得到4个区段 转换为RVA分别是
001000 - 181A00
183000 - 31200
1B9000 - 200
1BB000 - 3C00
原本的头文件区段应该有
.text
.data
.tls
.rdata
.idata
.edata
.rsrc
.reloc
通过无壳的BC文件发现 .tls .rdata段一般都为1000 在回想下前边修复IAT的过程 IAT比较零散比较大,可以得到结论,3C00不是.rdata段的大小,应该是.idata段的大小 .rdata段和.edata没有出现 所以我们自己添加剩下的段,只有资源段和重定位段 资源段需要专门修复 重定位段可以随便添加。又由于PE头文件中一般设定的内存块对齐是1000h。这里得出的区段信息如下:
001000 - 182000 .text
183000 - 36000 .data
1B9000 - 1000 .tls
1BA000 - 1000 .rdata
1BB000 - 4000 .idata
1BF000 - 4000 .edata
1C3000 - 未知 .rsrc
未知 .reloc
第四步:
通过LordPE修改dump各区段信息
需要注意2点,第一点各个段的属性 可以改成E0000060(可读 可写 可执行 包含执行代码 包含初始化数据) 这样排除因为权限造成的错误 在脱壳最后还需要根据无壳程序改回来。第二点 修改地址大小的时候 一定要把VirtualAddress VirtualSize RwaOffset RwaSize都修改了,因为每个区段在磁盘文件中和虚拟内存上都需要正确的信息,这点我先前没有修改RwaOffset 后来造成数据错位,后来想想,既然是全部自己拼装PE,当然内存映射的 和 磁盘的都需要考虑到。
由于资源段和重定位段要自己修复添加 所以这里先删除
第五步:
导出表,导入表,资源表,TLS都需要我们自己修复 所以先清空数据目录
PE头清空以后 对应的区段也需要清空 这里用的是PE Tools
把.tls .rdata .idata .edata 全部00填充 在相应的节鼠标右键Fill section 00填充
到现在清空了数据,后边修复数据就不会被其他数据影响了
第六步:
修复IAT 需要注意的是 平时都是选了Add new section这个选项的 但是这里的IAT都在的区段我们已经准备好了 而且清空了所以这个不能勾选此选项
RVA填入1BB000(1BB000 - 4000 .idata)
修复后用LordPE查看一下 输入表信息 看是否正确
第七步:
修复资源表 使用DT FixResource 把前边的dump备份文件拖进去
NewRVA填入1C3000(1C3000 - 未知 .rsrc)由于我们的PE文件头设置的文件块对齐是200 所以这里也填200 然后 Dump Resource
在LordPE中load section from disk 选中刚才保存的资源段
修改PE数据目录的资源段信息 并验证
资源段的大小可以通过导入资源段后查看得到
返回PE头信息窗口 看看还有什么需要修改的 发现BaseOfData还有问题 修改成我们先前得到的00183000
保存后 刷新一下可以看到有图标了
这个时候在win7运行可以正常了 但是在XP有可能还需要修复TLS 现在继续修复TLS
第八步:
TLS的修复需要参照无壳程序和加壳的源程序来看 以OD本身为例 通过TLS和区段目录可以发现
DataBlockStartVA就是tls段的起始地址 DataBlockEndVA=DataBlockStartVA+9C
注意点1:这里的9C不是固定的 是编译器根据程序的不同而生成的 所以这里需要参考加壳的源程序
显然加壳程序中的大小比9C大 如果这里填入9C 程序也可以正常运行但是就会出现 退出时错误,
原因跟踪发现,就是 线程局部存储 块比程序中设计的小了,原程序中的各个程序设计都是按照CC来做的
比如memcpy设定的长度等等,如果是9C 这样一来就会造成数据的错误,从而在退出程序清理内存时出现错误。
继续来定位TLS各项
IndexVariableVA是OEP指向的指令的内存寻址值
这里是0x58308B
CallBackTableVA=下一个区段起始地址+10=5BA000+10=5BA010
总结一下tls的值为
tls
5B9000
5B909c
58308B
5BA010
修改dump文件的tls
运行下程序 可以运行了 PEID查看一下
发现有附加数据段 用File Format Identifier去除附加数据段
在用PEID看一下
第九步:
到目前为止还需要添加一个重定位段和修改各个段的属性 以及 块对齐 这样可以减少PE文件大小
重定位可以随便添加一个 但是需要注意用Import REConstructor添加段 只是在PE头中添加 不会有相应的磁盘段对应 可以利用上一个段的剩余 也可以用其他工具修改下
各个段属性的修改就是比对无壳程序进行的 。
块对齐使用的是 PE Optimizer 工具 选择我们的文件 点process
可以看出来 大小缩小了2%
对比下先前和现在文件的大小
的确有变化
这个时候运行发生错误 通过OD跟踪发现 call 49af5c 造成的 但是49af5c为00 初步怀疑是PE Optimizer优化造成的,
实验发现是 kill Relocation造成的。LordPE加载未优化的文件
把重定位RVA+400000=496000 再观察节表
显然这个重定位地址是在代码段,PE Optimizer的优化恰好把代码清0了,
回想下重定位信息是先前我们复制PE头自带的 我们没有修改它 也没有清除它
这里把重定位信息清除掉 在优化可以运行了。
以上步骤完成后 在关闭脱壳文件任然要报错,还需要修复。通过 注意点1 解决了错误。
总结一下:PE的拼装关键就是要把PE头和各个区段分开看,PE头和区段一一对应,然后还有PE头中一些基本选项的修改,以及数据目录的修改 。
完美脱壳组装PE的一般步骤(Obsidium1.3.6.4 DEMO 主程序)相关推荐
- 对themida(1.8.5.5)加密VC++程序的完美脱壳
-------------------------------------------------------------------------------- [详细过程] 我经过探索 ...
- 华为电脑Linux进pe,华为 matebook X Pro用U盘PE重装系统步骤(xp)
华为matebook X Pro作为一款性能游戏的笔记本电脑,受到了很多用户的欢迎.一些用户想要通过U盘PE为其重装经典的xp系统,但不知道从何入手.U盘重装对于初次使用的用户来说比较复杂,但学会之后 ...
- 用python画六瓣雪花剪纸折法_4种完美六瓣雪花剪纸方法步骤
4种完美[六瓣雪花]剪纸方法步骤 昨天,后台的朋友给我留言,问能不能多分享一些雪花的图案,感觉两个太少,可选择的余地比较小.既然大家觉得不过瘾,今天就再推出一篇完美版,总有一个是你的菜. 我准备了四雪 ...
- 魅族魅蓝5x完美打开USB调试模式的步骤
当我们使用安卓手机通过数据线连接上pc的时候,或者使用的有些软件比如我们企业营销部门当使用的软件引号精灵,以前使用的老版本就需要开启USB调试模式下使用,现当新版本不需要了,如果手机没有开启USB调试 ...
- 魅族note9完美开启Usb调试模式的步骤
就在我们使用安卓手机链上pc的时候,或者使用的有些APP比如我们单位营销小组就在使用的APP引号精灵,之前的老版本就需要开启Usb调试模式下使用,现就在新版本不需要了,如果手机没有开启Usb调试模式, ...
- 瀑布流ajax思路步骤,原生ajax瀑布流demo分享(必看篇)
最近听朋友们说起瀑布流挺多的,自己就去研究下了,一个简单的原生demo,分享给大家... 简单分为三个文档,有详细的注释:img:ajax.php:demo.php 其中img文件夹中放入图片 1.j ...
- 用文字总结出计算机组装步骤,电脑技术的实结
电脑技术的实结 一. 实习的目的和任务: 本次实习环节的任务是对微型计算机系统的硬件结构及其工作原理有初步定的认识:了解Windows 操作系统的安装,熟悉Windows环境及其有关的基本操作,掌握床 ...
- 天草脱壳视频学习笔记(逆向 OD)
天草壳世界学习笔记: 1.OD的查找支持模糊查找 ?? 比如 要查找 E82091FBFFA1B8 可模糊查找:E8??91FBFF??B8 2.OD的插件idaficator 可以支持回滚 就是记 ...
- 天草脱壳视频学习笔记
天草壳世界学习笔记: 1.OD的查找支持模糊查找 ?? 比如 要查找 E82091FBFFA1B8 可模糊查找:E8??91FBFF??B8 2.OD的插件idaficator 可以支持回滚 就是记 ...
最新文章
- linux ubuntu make 安装
- 还在使用 SimpleDateFormat?你的项目崩没?
- Python 怎么样在函数内部对全局变量进行修改
- HTML学习笔记——选择器
- 计算机负数用英语怎么说,负数在计算机中如何表示
- 分布式系统概念:一致性协议、一致性模型、拜占庭问题、租约、副本协议
- springmvc中对日期格式化的处理
- 毕业季offer怎么拿?收下这份非典型求职面试指南
- 一分钟在云端快速创建MySQL数据库实例
- xcode 把cocos2d-x 以源码的形式包含进自己的项目适合, 性能分析问题的错误
- 自动驾驶技术(1)--控制工程篇概述
- Visual Studio 安装 FLTK
- 红帽linux9 iso,RedHat Linux9.0 ISO 原版下载
- 实时数仓和离线数仓的概念
- 贾扬清:从授之以鱼到授之以data,人工智能如何重塑传统软件行业
- Shiro(一)之shiro简介与工作原理
- 52-20210322华为海思Hi3516DV300的linux系统编译(eMMC模式)1
- 统计工作随笔—同比与环比(同期为负值)、百分点
- android获取多媒体库的视频、音频、图片
- 985大学计算机专业保研率排名,中国高校保研率排名,前二十名多数是985大学