不要慌, 壳一般都是有对抗的. 先干对抗. 注意混淆代码的call 不能步过.
脱壳对抗
不要慌, 壳一般都是有对抗的. 先干对抗.
1. IAT表的混淆
混淆代码的call 不能步过
- 生成混淆代码
- 将IAT中原API地址放入混淆代码中, 以ret或其他特征jmp到原API地址
- 将混淆代码的地址, 覆盖原IAT项
2. 脚本
x64dbg 安装脚本(x64dbgpy)
- 环境: python 2.7
- API:
- ~/x64dbgpy/pluginsdk/_scriptapi
思路
- 遍历混淆后的IAT
- 逐项查找混淆代码的特征, 提取原API地址
- 逐项恢复IAT
- 遍历混淆后的IAT
实现
默认不支持中文注释
- # -*- coding:utf-8 -*-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28# -*- coding:utf-8 -*-
from x64dbgpy.pluginsdk._scriptapi import *
dwIatbase = 0x00475000 #iat表的首地址
dwIatCount = 0x48 #iat表中的个数
#循环取出iat表中的地址, 然后设为新eip,单步到ret
for i in range(0, dwIatCount+1):
#读取IAT表中的地址
dwAddr = ReadDword(dwIatbase + i*4)
#排除0
if(dwAddr == 0):
continue
#以此地址为新eip
SetEIP(dwAddr)
#单步执行
while True:
StepIn()
# 判断是否是ret
if(ReadByte(GetEIP()) == 0xC3):
#从栈顶取出真正的API地址,存入IAT表中对 应的位置
WriteDword(dwIatbase + i*4, ReadDword(GetESP()))
break #退出循环3. 打补丁
有时还会需要写一段shellcode, 调用壳函数得到API地址
- 思路
- 混淆IAT, 要用混淆后的代码地址覆盖原API地址
- 打补丁:
- 使IAT填入正确的API地址.
- 核心:
- 拿到真正API的地方
- 往IAT填入混淆代码地址的地方
- 打补丁:
- 拿到真正API地址的时候, 临时存一下
- 往IAT填入混淆代码地址时, 将真正的API写入IAT
- 混淆IAT, 要用混淆后的代码地址覆盖原API地址
- 混淆的关键流程
- 申请堆
- 拿到API地址
- 写入混淆代码
- 混淆代码中写入API地址
- 混淆代码地址写入IAT
- 切入点
- 申请堆
- 对申请的堆设置写入断点
- 观察栈和寄存器的情况, 写入实际API肯定会通过栈或寄存器传递.
- 申请堆
扩展
- VMP 壳, 带VMP字样的一般以月为单位.
- python目录尽量不用中文.