目录
笔记:
壳的功能:缩减程序的大小,阻碍对加壳程序的探测和分析
解析函数导入表:1.仅导入LoadLibrary和GetProcessAddress两个函数。先脱出原始文件,再读取原始可执行文件的导入函数信息。
2.保持原始导入函数表的完整,让Windows加载器加载所有的DLL及导入函数---->缺乏隐蔽性
3.为原始导入表中的每个DLL保留一个导入函数,解析时只用查看每个导入库中的一个函数---->比第二个隐蔽性高
4.不导入任何函数,脱壳存根从库中查找所有需要的函数。
尾部跳转:ret call NtContinue ZwContinue 隐藏跳转
识别加壳程序:加壳标识----->导入函数仅有LoadLibrary和GetProcessAddress
只有少量代码被识别
加壳警告
节名中包含加壳的警告
.text原始数据大小为0,但虚拟大小不为0
阕值计算------>压缩或者加密数据更接近于随机数据,因此有一个较高的阕值(Mandiant Red Curtain/Red Curtain)
脱壳:自动脱壳--->PE Explorer
手动脱壳--->1.找到加壳算法,编写一个程序逆向运行它
2.运行脱壳程序,让脱壳存根帮你工作,让它从内存中转储处进程,然后修正PE头部
查找OEP:自动工具----->OllyDump,通过Section Hop调用Find OEP(如果一个call函数没有返回,节与节之间的大跳转)
手动查找----->查找尾部跳转指令(jmp,ret)
在栈上设置读断点
在代码每个循环后面设置断点
在GetProcAddress函数设置断点,多数脱壳器会使用GetProcAddress函数来解析原始函数的导出表
不要让代码执行向上跳
不同程序:1.命令行程序--->Getversion与GetCommandlineA
2.GUI程序------->GetModuleHandleA与Getversion
OllyDbg的Run Trace选项
手动修复导入表:利用OD标注导入函数
常见壳:UPX:压缩壳
PECompact:包含反调试异常和混淆代码
ASPack:自我修改代码-----设置硬件断点
Petite:单步异常---------硬件断点---------每个库至少导出一个函数
WinUpack:有GUI终端的壳优化压缩--------GetModuleHandleA/GetCommandlineA
Themida:复杂,具有反调试与反逆向分析。会在原始程序运行后继续运行。---------ProcDump转储Windows进程的内容
不完全脱壳的情况下分析:并不需要让其完全脱壳再去分析这个程序。进行转储,IDApro分析特定的节,找到一个地址,标记为代码,拿strings分析。
加壳的dll:在OD中加载dll时,DllMain函数会在od中断之前就运行。
解决:定位IMAGE_FILE_HEADER,在0x2000处的值为1,表示是一个DLL文件,但如果为0,表示一个EXE文件。
ProcDump
实验:
Lab18-1
加了壳的软件
明显的尾部跳转
Lab18-2
加壳
使用od插件寻找OEP,然后转化为code
Lab18-3
可以看出来加壳了,但用od插件并不能定位到OEP
查看代码尾部跳转
然而这里也并不能找到OEP
程序的开始位置,有pushfd和pushad的操作把寄存器的值压入栈,当脱壳完成后。这些寄存器的值还会pop出来
所以执行到如图位置后,在esp中下硬件访问断点。
再次运行,停在OEP位置,然后转化为代码
Lab18-4
同样利用上面的那个esp堆栈平衡
Lab18-5
这个壳隐藏了导入信息,同样利用上面的那个esp堆栈平衡