调试UPX压缩的notepad
@date: 2016/11/29
@author: dlive
0x01 运行时压缩
对比upx压缩前后的notepad可以看到如下特点
- PE头的大小一样
- 节区名称改变(.text -> .UPX0, .data -> .UPX1)
- 第一个节区的SizeOfRawData=0,即第一个节区在磁盘上的大小为0,但是第一个节区的VirtualSize的值被设置为0x10000
- notepad_upx.exe的EP位于第二个节区,原notepad.exe的EP在第一个节区
- 资源节区(.rsrc)的大小几乎无变化
解压缩代码与压缩的源代码都在第二个节区(UPX1)。文件运行时首先执行解压缩代码,把处于压缩状态的源代码解压到第一个节区(UPX0)。解压结束后即运行源文件的EP代码。
0x02 调试UPX压缩的notepad
EP与OEP:
EP(Enter Point): Windows可执行文件的代码入口点,是执行应用程序时最先执行的代码的其实位置
OEP(Original Enter Point): 对于加壳程序,称源文件的EP为OEP
使用OD打开未加壳的notepad.exe
可以看到notepad.exe的EP为0100739D,入口处代码调用了GetModuleHandleA用来获取notepad的ImageBase
下面开始调试notepad_upx.exe,upx的解壳过程可以分为以下几个阶段:
1. 壳入口的初始化操作
用OD打开notepad_upx.exe,程序停在EP处
复习一下前面PE的知识XD : 可以验证EP地址为01015330 == Address of Entry Point + Image Base (IMAGE_OPTIONAL_HEADER32)
notepad_upx.exe在入口点进行了pushad操作(依次将EAX、ECX、EDX、EBX、ESI、EDI压栈)
然后将UPX0,UPX1节区的地址分别保存在EDI,ESI寄存器中。调试时这样同时设置EDI,ESI,就能预见从ESI所指缓冲区到EDI所指缓冲区的内存发生了复制,此时从Source(ESI)读取数据,解压缩后保存到Destination(EDI)。
之后代码通过jmp调到解压缩代码。
我们的目标是跟踪全部UPX EP代码,并最终找到原notepad的EP代码,如第一张图所示
2. 代码还原
在UPX解压缩的过程中一共有4个循环。
前里两个循环完成代码还原的功能,正式的解码循环为第二个循环。
跟踪数量庞大的代码时,请遵循如下法则:遇到循环时,先了解作用再跳出
在OD中Ctrl+F8调试第二个解码循环,同时在memory窗口观察UPX0节区的数据变化(也可以在OD CPU窗口左下方的数据窗口查看UPX0内数据变化),可以看到第二个循环将解码后的数据写入UPX0节区。
3. CALL/JMP修复
第三个循环从0101540A开始,主要用于恢复源代码的CALL/JMP指令(Opcode:E8/E9)的destination地址。
可以在memory窗口中选中UPX0区段,右键设置内存写入断点来判断第三个循环确实有对UPX0进行修改。
4. 恢复IAT
UPX压缩原notepad.exe事,会分析其IAT,提取出程序中调用的API名称列表,形成API名称字符串。
用这些API名称字符串调用GetProcAddress函数,获取API的地址。然后把API地址输入原notepad.exe的IAT区域。
最终恢复原notepad.exe的IAT
5. 将程序的控制返回到程序OEP
在notepad.exe全部解压缩完成后,将程序的控制返回到OEP处。
010154AD地址处的popad指令与notepad_upx.exe的第一条指令pushad对应,用来把寄存器状态恢复。
最终使用010154BB处的jmp指令跳转到OEP,跳转的目标地址(0100739D)就是notepad.exe的EP
可以看到OEP处的代码和源notepad.exe相同
虽然没有详细看懂upx的每条指令的含义,但是对其代码片段的功能有了基本了解
UPX详细分析可参考:
http://www.52pojie.cn/thread-294773-1-1.html
http://www.chinapyg.com/thread-76768-1-1.html
0x03 快速查找UPX OEP&UPX脱壳
1.快速查找OEP
这里用到了OD的硬件断点,关于硬件断点可以参考:
https://www.zhihu.com/question/52625624/answer/131557817
notepad_upx.exe的EP先执行了pushad,在解压完成后又使用popad恢复程序初始运行时的寄存器和堆栈状态。
我们现在知道UPX在解压完成后一定会执行popad(依次pop edi, esi, ebx, edx,ecx, eax),那么就可以在栈地址上设置硬件断点,在程序访问这个地址的数据时就会被断下。
在数据窗口找到执行完pushad后在esp对应地址,然后选择该地址开始的1字节,右键设置硬件断点(或者按书p133那样设置硬件断点均可)。
当程序执行popad时会首先从这个地址上读取数据到edi(pop edi),此时会触发硬件断点,程序断下。其下方即是跳转到OEP的JMP指令。
不过和软件断点(INT 3)断点不同的是,触发断点的指令执行(popad)完成后程序才会停止运行,即程序会断在popad下一条指令。
OD的硬件断点可以在调试->硬件断点里看到。
2.UPX脱壳
继续运行程序到OEP,然后再OD中右键选择Dump debugged process(52pojie OD中为“用Ollydump脱壳调试进程”)
修改EP为OEP(该功能会自动修改EP为EIP,此时EIP即为OEP,所以无需手动修改),点击脱壳,另存脚本为notepad_dump.exe
对UPX脱壳而言,进行到这一步就可以了,但是如果是另外一些壳,可能还需要对程序的输入表进行修复操作。
脱壳后的程序可以正常运行,并且使用IDA可以正常反编译。
使用PEID查壳可以看到提示“Microsoft Visual C++ 6.0”信息,而非UPX
3.修复IAT
(为什么要修复IAT,IAT是什么原因被破坏这个我还不是很清楚,不过先有个大致概念,以后再深入研究)
打开ImportREC程序,首先在进程列表中选择正在用OD调试的那个notepad_upx.exe进程,然后在OEP中填入739D,然后点击“IAT AutoSearch”按钮,接着点击“GetImports”按钮,就可以看到程序的输入表信息了。
点击右侧的“Show Invalid”按钮,看看是否存在无效的输入表项目。无效的输入表项目前面带有问号(?),如果有可以使用右键菜单删除。这里没有无效的输入表项目,所以选择“Fix Dump”按钮,对我们的notepad_dump.exe进行修复,得到notepad_dumped_.exe程序。
至此脱壳完成。
调试UPX压缩的notepad的更多相关文章
- Reverse Core 第二部分 - 14&15章 - 运行时压缩&调试UPX压缩的notepad
@date: 2016/11/29 @author: dlive 0x00 前言 周六周日两天在打HCTF2016线上赛,没时间看书,打完比赛接着看~~ 0x01 运行时压缩 对比upx压缩前后的no ...
- 手动脱UPX压缩壳
示例程序演示 样例程序选择win7自带的notepad.exe,该程序原本是没有加壳的: 拷贝notepad.exe文件一个副本,重命名为notepad - upx.exe,我们对notepad - ...
- UPX压缩
什么是UPX UPX (the Ultimate Packer for eXecutables)是一款先进的可执行程序文件压缩器,压缩过的可执行文件体积缩小50%-70% ,这样减少了磁盘占用空间.网 ...
- 脱壳第三讲,UPX压缩壳,以及补充壳知识
脱壳第三讲,UPX压缩壳,以及补充壳知识 一丶什么是压缩壳.以及壳的原理 在理解什么是压缩壳的时候,我们先了解一下什么是壳 1.什么是壳 壳可以简单理解为就是在自己的PE文件中包含了代码.而有不影响我 ...
- upx压缩notepad.exe(运行时压缩)
PEView:https://www.lanzous.com/i5k9vbg UPX:https://www.lanzous.com/i5k9vch notepad.exe:https://www.l ...
- Upx 压缩go编译的程序 frp
1. frp 程序占用大 .路由器 不够空间 2. UPX 下载地址 https://github.com/upx/upx/releases/ 3. 压缩命令 upx.exe -9 C ...
- UPX和WinUpack压缩壳的使用和脱法 - 脱壳篇06
UPX和WinUpack压缩壳的使用和脱法 - 脱壳篇06 让编程改变世界 Change the world by program 今天小甲鱼给大家介绍两款压缩壳:UPX和WinUpack. UPX是 ...
- LoardPe与Import REC X64dbg脚本 脱壳 Upx
目录 LoardPe与Import REC X64dbg脚本 脱壳 Upx 一丶X64dbg调试器与脚本 1.1 起因 1.2 脚本的调试 1.3 Upx脱壳脚本 二丶LoardPe 内存Dump与I ...
- Windbg调试命令详解
作者:张佩][原文:http://www.yiiyee.cn/Blog] 1. 概述 用户成功安装微软Windows调试工具集后,能够在安装目录下发现四个调试器程序,分别是:cdb.exe.ntsd. ...
随机推荐
- java.lang.ClassCastException: com.sun.proxy.$Proxy53 cannot be cast to cn.service.impl.WorkinggServiceImpl
java.lang.ClassCastException: com.sun.proxy.$Proxy53 cannot be cast to cn.service.impl.WorkinggServi ...
- hprose 1.0(rpc 框架) - 关于跨域和P3P的声明
private function sendHeader($context) { if ($this->onSendHeader !== null) { $sendHeader = $this-& ...
- Android Studio 安装与使用ADB wifi 无线调试
首先,安装ADB WIFI File->Settings->Plugins 其次,用USB连接手机与电脑(并开启手机的调试模式) 任务栏若无提示,即可拔下USB线,开始无线调试 任务栏若是 ...
- 51nod_1255字典序最小的子序列
作为贪心算法的某道例题,赶脚药丸啊..这么简单的代码重构第三遍才过... 首先是贪心算法思想, 1,证明贪心算法有效性:贪心策略,使用栈结构实现,遍历输入串中所有元素,对于某个元素有如下两种情况: 情 ...
- Selenium与PhantomJS【转】
爬虫(Spider),反爬虫(Anti-Spider),反反爬虫(Anti-Anti-Spider) 之间恢宏壮阔的斗争... Day 1 小莫想要某站上所有的电影,写了标准的爬虫(基于HttpCli ...
- (HTML)A标签伪元素选择器的继承关系
①如果a:link{}也存在,那么不管a{}放到哪里,a{}和a:link{}冲突的属性都会采用a:link{}的,不冲突的属性若存在a{}中,会被a:link{}. a:visited{} .a:h ...
- Ntdsutil.exe
Ntdsutil.exe 编辑 本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! Ntdsutil.exe 是一个为 Active Directory 提供管理设施的命令行工具 ...
- N宫格
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...
- IOS笔记051-手势使用
UIGestureRecognizer 利用UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势 UIGestureRecognizer是一个抽象类,定义了所有手势 ...
- STL学习笔记4--set and multiset
集合(Set)是一种包含已排序对象的关联容器.多元集合(MultiSets)和集合(Sets)相像,只不过支持重复对象,其用法与set基本相同. 用法介绍 1.insert()函数 首先把头文件set ...