buu-reverse-新年快乐
预备知识
壳是什么?
壳分为压缩壳和加密壳:
- 压缩壳:压缩文件大小
- 加密壳:经过加密,或者使用一些反追踪代码阻止你进行反编译
- 无论是哪一种壳,一旦进行加壳操作,都无法直接反编译获得源码(如IDA工具就是做这个的)
本题中的UPX壳本质上就是一种压缩壳
脱壳基本原理
OEP:(Original Entry Point),程序的入口点,软件加壳就是隐藏了OEP(或者用了假的OEP), 只要我们找到程序真正的OEP,就可以立刻脱壳。
pushad
(压栈) 代表程序的入口点popad
表程序的出口点,与PUSHAD相对应,一般找到这个OEP就在附近啦。
只要找到OEP然后用专有工具就可以进行脱壳操作了!(本题中使用OD自带的脱壳工具)
工具简介
我懒得一个个找工具资源,所以直接用 吾爱的虚拟机2.0 里面内置了一大堆软件了
- PEid:查询是否加密
OD:动态调试,本题中用于找OEP
- 注:OD用于动态调试,IDA用于静态调试。
- 注:动态调试相当于,让程序一步步运行(OD中的F8)
- 注:静态调试相当于,直接看反编译的汇编或者C进行理解(IDA在对应函数按F5)
- IDA 32位:用于脱壳后静态分析代码
其他本题用不到但与脱壳相关的工具
- LordPE:Dump工具
- ImportREConstructor:脱壳后import库的修复(不一定需要用到,本题中用不到)
OD工具的一些快捷键
OD是由于动态调试的那就涉及到断点调试,基本操作如下
- F2是在该指令处设置断点
- F9是继续执行,按下后会从执行点开始执行,直到下一个断点处
- F8是单步执行,会从执行点执行到下一个执行点
- 在找到OEP对应的位置后可以打开OD自带的脱壳工具生成脱壳文件
本题UPX壳的的获得OEP的方法
总结就是通过断点调试,然后定位到popad
下面的jmp
(jmp是汇编中用于地址跳转的,根据教程中jmp后的就是OEP地址了),所以只需要程序执行到popad
下面的jmp
的下一步就可以了。于是可以在popad
下面的jmp
的位置下一个断点然后让程序执行到这里停住,然后在执行这句代码(执行一次OD中就是F8),所跳转到的位置就是OEP的位置了。
参考可见其中的第四种,其中的0X01 硬件断点快速脱壳。
解题
确认壳的类型
本题和前几题(可见buu-reverse1的题解)的差别就在于加了一个压缩壳UPX v0.89.6 - v1.02 / v1.05 - v1.22
用PEID查询的结果(因为直接打开IDA函数数量不正常所以怀疑是加壳,然后使用查壳软件进行查询):
UPX最简单的脱壳
用OD打开,Ctrl+F
搜索popad
找到下面最近的一个jm
指令行,按F2下断点(下断点后左侧对应的二进制地址会变红),再按F9将程序执行到这里(左侧对应的二进制地址会变灰)
然后再按F8执行这一条jm
语句,会跳转到OEP的位置如图就是OEP的位置了
此时在右侧的空白处右键中打开自带的脱壳工具(会自动填入OEP)然后点击脱壳,任选一个名字保存即可
脱壳后和之前的做法一样
使用IDA 32打开脱壳后的exe文件分析代码,在string中搜索flag关键字,定位到对应函数,按F5看源码,搞定。
这一步的操作不会的详细见buu-reverse1的题解:http://poilzero.sipc115.club/index.php/archives/32/
最后解得flag{HappyNewYear!}
,果然是新年快乐哈