有很多逆向题不能直接反汇编到我们需要的东东,第一步就得脱壳。这篇总结下脱壳的一些比较基础的方法。
目的:压缩或保护(就是反逆向)
壳可以看做一段加密程序,即在原PE文件(宿主文件)上加一个新的区段(也就是壳),然后从这个新的区段上开始运行。加壳后,原始程序代码在磁盘文件中以加密后的形式存在,只在执行时在内存中还原。防止程序被静态反编译和非法修改。如下图:
有名的压缩壳有UPX,ASPack,加密壳有ASProtect,Armadillo,EXECryptor,Themidia…
这些大多有现成的脱壳机或者直接用kali解决,若碰到自编壳(如不用系统提供的GetProcAdress函数而是自编一个),只能手动脱壳。
最简单快捷的就是用软件啦,比如exeinfope
和PEID
像这个就是UPX壳
当外壳所保护的程序运行时,会先执行外壳程序,外壳程序负责在内存中把原程序解压、还原, 并把控制权还给解压后的真正程序,再跳到原来的程序入口点。一般的壳在这里会有一条明显的“分 界线”,这个解压后真正的程序入口点称为“OEP” ( Original Entry Point,原程序入口点)
加壳后,原程序中多了一个区块.pediy。这个区块就是外壳,相当于一个文件加载器(Loader )。当RebPE运行时,各区块被Windows操作系统映射到内存中,现在的入口点地址是13000h,指向 外壳。当外壳拿到控制权后,会通过各种方式获得自己所需要的API地址,解密原程序各区块的数 据,填充IAT(导入地址表)。做完这些工作后,就准备跳到OEP处(即401130h)执行,如图:
这也告诉我们:OEP总是与大跳如影随形(JMP,JZ)
upx壳较为常见,一般使用cmd就很容易地可以脱掉
UPX -d 文件名
在upx基础上,一些保护工具如UPXPR可以使以上命令行失效,这个时候就要用手动脱壳了(方法与ASPack类似)。以下就以加了UPXPR为例的记事本进行练习。附件在文末。
先查壳
在很多基础的题目中,找OEP+Dump是一个脱壳通法,Dump可以用od直接搞定,故找OEP是重点。
以下是几个找ESP常用方法。
在编写加壳软件时,必须保证外壳初始化的现场环境(各寄存器值)与原程序的现场环境是相同的。通常用pushad/popad、pushfd/popfd来保存和恢复现场环境。即OEP的寄存器值等于入口(PUSHAD)的寄存器值,可利用硬件断点。
思路:将最开始esp压栈地址的值下断点,找到下一个使个寄存器值与之全部相等的语句位置。
注意,经验表明本方法可用范围:在pushad一次F8后,fpu里头的寄存器只有ESP是红的(EIP除外)
另:PUSHAD相当于push eax/ecx/eddx/ebx/esp/esi/edi (除EIP全压栈)
单步后只有ESP变了,可以用。
1.右键ESP,跟随Dump
2.选择弹出来的Hex Dump若干字符(多少无所谓),右键设置硬件byte断点(也不一定要byte)。这段就是一开始分析的入口和OEP一样的东东
可以通过Debug-hardware breakpoints 检查设置得咋样
3.shift+F9
运行看到popad和大跳
4.F8单步,果然~(一般OEP很容易是PUSH,段首嘛)
5.dump脱壳,就是把起始地址从0040E941换成004010CC(史前大跳)详见后文Dump操作
效率较低但是最踏实。
OD传统艺能,经典动态调试,总之就是只下不上。
技巧:
1.近CALL-F7,远CALL-F8,保证向下
2.要是要回跳在下一句F4
**3.关注大跳(JMP,JE,RETN),很快就OEP**
按下不表(其实是按到手酸QAQ)
这个也叫两次断点法,原理:利用OD断点-执行-消断点这一自动过程可以跳过大量繁琐无意义代码。因为一般的壳会依次对.text、.rdata、.data、.rsrc区块解压处理,所以可以先在.rdata、.data、.rsrc区块设置内存访问断点,等到程序中断,代码段就解压了,再对代码段.text设置内存访问断点,就可以直接到OEP
1.ALT+M
如图,露出了三个完整的程序代码块。注意**一定要是第一个程序代码块**,不能是DLL和壳的块。如图第一个设.data、.idata、.rsrc都行(其实本题.reloc只用设一次就欧了,但是重定位表一般情况下都会被删,所以一般还是看.rsrc)。断点-运行后再来第二次:.text,直接定到了OEP
优点:简便。
缺点:不是所有都能Dump,比如对DLL映像
在OEP语句右键-用OllydbgDump脱壳调试进程-脱壳(记得勾重建输入表-over
查壳,无壳状态。
抓进程-右键-Dump Fall
LordPE用法一样(U1S1LordPE好是好只能在XP虚拟机上挂太伤了)
见下一章XD
ctrl+F2
重载
F2设断点,shift+F9运行
遇到CALL,LOOP这些,F8路过,F7跟进
alt+M
打开内存镜像
alt+O
:Debugging options
(查了下可能会ESP定律没直接出现OEP)
定义一个锚(id):<span id="jump">跳转到的地方</span>
使用markdown语法:[点击跳转](#jump)
ctrl+B 加粗
Ctrl+I 斜体
Ctrl+U 下划线
Alt+shift+5 划掉
ctrl+\ 清除格式