脱壳笔记-手工脱UPX压缩壳

本文示例程序及upx加壳工具

一、基本概念的理解

壳的脱壳:如果我们将一个应用程序比喻成一个鸡蛋,程序中对我们有用的程序代码为鸡蛋清,而我们需要获取鸡蛋清的时候,就必须打破鸡蛋外面的鸡蛋壳,也就是进行脱壳的处理。
脱壳的方式:不同的壳对应的脱壳方式会不一样,甚至相同的壳但是不同的版本,脱壳的方式也会可能不同。

二、示例程序演示

示例程序为win7自带的notepad.exe ,该程序原本没有加壳
这里写图片描述

对该应用程序notepad-UPX.exe进行UPX加壳
这里写图片描述
压缩之后查壳
这里写图片描述

进行upx加壳前后对比
这里写图片描述

三、脱UPX壳

1、脱壳的基本过程
手动跟踪到程序的OEP(程序原始入口点),将程序和数据dump下来,然后再进行IAT的相关修复即可。

2、如可查找OEP
(1)需要熟悉各种编译器生成的程序的入口点的指令。例如vs 程序的入口点一般为:
push ebp
mov ebp,esp
(2)壳进行解压缩的代码通常在一个自己的区段里面运行,解压缩完成后通常会跳转到原始程序入口点进行运行,此时跳转到OEP往往需要一个JMP或CALL,保证EIP指针指向了原始的OEP地址。注:原始的OEP与解压缩的代码通常不在一个区段内,所以JMP与CALL往往实现的是跨区段的跳转。

3、手动的跟踪脱UPX壳
OD载入程序后,先运行的是壳的解压缩代码,逐步F8往下跟踪,跟踪完解压缩代码后,跳转到OEP。
(1)UPX壳所用到的API:LoadLibraryA和GetProcAddress,这两个API将进行对原始程序的导入函数进行还原。LoadLibraryA进行加载导入函数相关的动态链接库,GetProcAddress在动态链接库里面获取导入函数的地址进行还原。
LoadLibraryA
这里写图片描述
GetProcAddress
这里写图片描述

(2)注意相关的逻辑循环,使用F4运行到指定位置,跳出循环(注意:如果碰到nop的指令,F4定到下一条语句,否则程序会跑飞)。UPX在完成解压缩之后,会进行跳转到原始程序入口点,这是跨区段的跳转,在F8与F4往下运行的同时,注意跨区段的JMP
这里写图片描述
地址 0x0055B9D4与0x004E53C2,地址之间相差巨大,此时往往为跨区段的跳转。该条指令就是跳转到原始程序的入口点,F8自动步入到OEP
这里写图片描述

(3)打开LoadPE,选中该应用程序进程,右键先“修正镜像大小”,再“完整转存”,将OD跟进到OEP的程序转储下来。
这里写图片描述
此时转储下来的dumped.exe程序无法运行,因为导入表还没有进行修复
这里写图片描述
接下来我们进行导入表的修复

(4)计算出OEP的RVA值,也可以在我们跟进的OEP处,右键选中Dump Process插件(注:不同的OD的名称有细微的差别),获取当前EIP作为OEP的RVA值(Get EIP as OEP)
这里写图片描述
获取到OEP的值为 0x000E53C2

(5)使用ImpREC进行对导入表的修复
这里写图片描述
填写我们的OEP值,然后点击“自动查找IAT”,再点击“获取输入表”,最后进行转储到文件,进行修复dump下来的导入表(无效的指针在脱UPX壳中可以不用删除)
这里写图片描述
修正后的可执行文件dumped_.exe
这里写图片描述
dumped_.exe就是可以正常运行的程序了,我们最后再来查壳看看该程序,此时没有壳
这里写图片描述

脱upx壳小技巧:通过脱壳发现,upx壳的解压缩完成后跳转到OEP的jmp指令后面为nop指令,通常只需要鼠标往下滚动,发现很多nop指令时,就能找到该jmp指令。

四、脱壳找IAT小技巧

我们在进行跟进到OEP后,有可能壳的解压缩程序并没有完全的帮我们恢复IAT(例如:FSG壳),而ImpREC并不能帮我们完整的修复,此时就需要我们手动进行修复,如何查找到IAT?
调用系统的API的call指令的二进制指令代码为 FF 15,所以我们只需要在OD中,查找FF 15二进制指令就能找到某个导入函数的地址,然后再数据窗口中跳转到该地址就能到IAT的位置,再进行上下滚动就能查找了。

基本步骤:
1、Ctrl+B或在OD中右键->查找->二进制子串
这里写图片描述
输入FF 15,点击确定就能查找到某一个导入函数的地址

2、此时查找到的API为kernel32里面的GetCommandLineA,它在内存中的地址为0x53230C,我们在数据窗口中Ctrl+G,输入该导入函数的地址跳转到0x53230C(注:数据窗口中需要右键->长型->地址才能查看到API的名称)
这里写图片描述
此时查找到IAT,就可以进行一些相关恢复。
upx壳的解压缩代码已经进行了完全的恢复,所以此处并不需要进行相关修复。

本文难免有所错误,如有问题欢迎留言

### 使用 x64dbg 对 UPX 压缩的程序进行脱壳 #### 工具简介 x64dbg 是一款功能强大的开源调试器,支持 32 位和 64 位应用程序的调试与分析。通过结合静态反汇编调试技术和动态调试方法,可以有效应对诸如 UPX 加壳程序的解压需求。 --- #### 静态分析初步了解目标程序 在处理 UPX 压缩的目标程序时,可以通过静态分析快速确认其是否被 UPX 打包。这一步骤有助于验证后续操作的方向性和必要性[^1]。 以下是常见的静态检测方式: - **文件头特征**:UPX 修改后的 PE 文件头部会显示特定标志字符串(如 `UPX!` 或其他变体),可通过十六进制编辑器查看。 - **工具辅助判断**:使用像 `PEiD` 这样的工具扫描 EXE/DLL 文件,自动匹配已知加壳模式。 如果发现目标确实采用 UPX,则需进一步准备手动脱壳流程。 --- #### 动手实践——利用 x64dbg 实现 UPX 脱壳 ##### 准备工作 下载并安装最新版本的 x64dbg 和目标样本文件。确保环境配置无误后启动调试过程: ```plaintext 打开 x64dbg -> File -> Open -> 浏览至待分析的 UPX 压缩二进制文件。 ``` 此时加载完成之后进入初始界面展示的是 OEP (Original Entry Point) 的重定向入口而非实际代码逻辑起点。 --- ##### 设置断点定位真实 EntryPoint 为了捕获到原始未压缩状态下的执行流路径,需要设置合适的断点位置以便暂停于正确时机处。一般推荐如下策略之一: 1. **寻找解密循环**: 寻找具有明显重复结构的操作序列(比如大量 MOV/ADD/XOR 指令),它们可能参与数据还原阶段的工作; 2. **监控堆栈变化**: 当前 SP/BP 寄存器值频繁更新期间往往暗示即将跳转回正常控制权转移区域; 3. **跟踪 API 调用链路**: 特定函数调用节点也可能成为良好候选对象,例如 GetProcAddress/NtCreateThreadEx 等系统服务请求动作发生前后均值得留意观察。 一旦确定合理切入点即可按下 F2 键设定软中断标记等待触发事件到来。 --- ##### 继续运行直至抵达真正 EP 地址 随着上述条件满足而停止下来以后,逐步单步跟进(F8/F7键切换前进层次深浅程度),直到最终到达未经任何篡改过的纯净形式下真正的程序起始地址为止。此过程中务必密切注视寄存器数值以及内存映射布局状况的变化趋势。 当达到预期效果即看到熟悉的非加密编码片段呈现出来的时候,意味着已经成功突破外壳屏障限制获得了内部核心部分展现的机会. --- ##### 提取干净副本保存成果 最后一步就是导出修复好的镜像文档供后续深入探究或者二次开发用途所用了。具体做法如下所示: ```plaintext Right Click Inside Dump Window -> Select 'Dump' Option From Context Menu -> Specify Desired Output Path & Filename. ``` 至此整个基于 X64Dbg 平台之上针对 Upacked Executables 的探索之旅圆满结束! --- ### 注意事项 尽管自动化解决方案存在局限性特别是面对高度定制化改造实例时常显得力不从心之时,掌握扎实的手工技艺便显得尤为重要起来。因此建议多积累实战经验不断磨练技能水平才能从容应对各种复杂场景挑战[^2]. 此外还需注意静态解析虽然迅速高效但也存在一定缺陷难以全面覆盖所有情形故应灵活运用动静结合手段综合考量问题解决之道[^3]. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值