脱壳分为几步?
三步
1,找OEP
2,在OEP处dump内存到文件
3,修复文件(修复IAT,重建导入表)
壳代码流程
- 保存寄存器环境
- 初始化一些必要的变量,加载一些必要的API
- 解密/解压缩代码和数据
- 重定位
- 填充IAT
- 恢复寄存器环境
- 跳转到OEP(一般是一个大跳)
串操作指令
STOS [EDI] //eax中的数据放入的edi所指的地址中
MOVS [EDI],[ESI]
LODS[EDI] //将源操作数的内容取到AL或AX寄存器
SCAS[ESI] //用al(或ax)中的值对目的串bai(es:di或edi)中的字节(或字du)进行扫描
CMPS[EDI],[ESI]
重定位
- 计算重定位地址
重定位地址=基地址+重定位RVA+offset - 重定位数据
值=[重定位地址]-400000+当前模块基地址
值=[重定位地址]+(当前模块基地址-400000)
填充IAT
- 从导入表中获取DLL字符串
- 通过API-LoadLibraryA 获取模块基地址
- 从导入表中的INT或IAT获取一个函数的序号或者字符串
- 通过API-GetProcAddress 获取API地址
- 将API地址填充IAT中
破解程序可以不脱壳吗?
可以,是建立在自己对程序的了解熟悉程度之上的
解密IAT如何分析?
- 找到IAT,在IAT上设置硬件写入断点
- 重新运行程序,等到断下分析上下文
字符串hash在病毒、壳中如何应用?
API的函数名都是一些字符串,为了能够更好的加密,病毒的作者
会将函数名事先求一个字符串hash,一般是4个字节,存放到程序中
当需要某个函数时,会从目标模块导出表中遍历函数字符串,求hash,
然后与自己的字符串hash进行比较,从而找到对应的函数。
字符串hash是如何求的?
使用一些hash算法,只要能保证函数字符串的hash不重复即可
清除硬件断点的方法有哪些?
修改调试寄存器,CONTEXT结构体
- API
SetThreadContext - 异常
异常回调中可以修改CONTEXT
寻找OEP有哪些技巧?
- ESP定律
- 特征定位
- API
- 入口点特征
- 入口点附近CALL的特征
- 区段名
- 代码中IAT调用FF25,FF15
- 单步跟踪
壳为什么会保存寄存器环境?
早期程序是依赖入口点系统上下文环境的,如果不保存,程序会出问题
现在,大多数编译器都有自己的运行库代码,所以对系统依赖较少
不平衡也没关系,平衡是良心活儿
脱壳的环境最好是在什么情况下脱?
- 系统32位
如果系统是64位的,需要WOW64系列的DLL导入,
还有apphelp.dll会做一些IAT hook,甚至是inline hook - 最好是干净的,没有安装任何杀毒软件/防火墙/入侵检测系统/沙盘
- 分析外挂、软件这是一种破坏行为,软件本身可以进行反击
所以分析环境必须在虚拟机,这样安全可控
混淆代码的分析技巧
可以使用Ctrl+↑和Ctrl+↓微调反汇编窗口,即时的展示反汇编代码
评论区