脱壳-0.upx.exe
① 找OEP
ESP定律
脱壳-0.exe(FSG 2.0)
① 找oep
单步跟踪
跳转到OEP代码:
JMP DWORD PTR DS:[EBX+0xC]
② dump内存
。。
③ 修复IAT
FSG 2.0对内存中的IAT 进行了一些空隙填充,需要将其改为0
脱壳-2.exe
① 找OEP
单步跟踪
② IAT加密,解密IAT
解密IAT需要先找到加密IAT的地方,然后将其删除或是能还原。
找加密IAT代码的方式
① 对IAT设置硬件写入断点
对GetVersion所在的iat设置硬件写入断点,最终可以找到填充IAT的地方
004385EE 8907 MOV DWORD PTR DS:[EDI],EAX ; 填充IAT 函数地址
修改附近代码
修改前
image.png
修改后
image.png
② 对IAT相关的API设置断点
LoadLibraryA
GetProcAddress
GetModuleHandleA
VirtualProtect
脱壳中的一些问题
拿到程序怎么办?
以脱壳为目的,尽可能完成脱壳
技巧的使用?
① API下断注意的问题
API下断之后,第一应该观察的是堆栈,确定返回地址是我们要分析的模块
②注意当前分析的模块是不是主模块
image.png脱壳-4.exe(未知壳)
① 找OEP
ESP定律
② IAT加密
这个壳使用一些加密技术:
IAT函数地址是不规则的
填充IAT时有混淆代码
自己实现了一个GetProcAddress
字符串使用Hash值来存储
壳代码填充IAT的代码是在申请的内存中执行
混淆规则
jmp 地址
等价于
call 地址
LEA ESP,DWORD PTR SS:[ESP+0x4]
哈希算法
edx=0, 保存计算之后的结果
LODS BYTE PTR DS:[ESI]
TEST AL,AL
JE SHORT 002F1CCB
ROL EDX,0x3
XOR DL,AL
寻找OEP脚本
// 1. 定义变量
VAR dwWriteIATAddr // 填充IAT地址的下一行地址
VAR dwGetAPIAddr // 获取到了API地址
VAR dwOEP // 原始OEP
VAR dwGetBaseAddr // 申请的内存
VAR dwTmp // 临时变量
// 2. 初始化变了
MOV dwOEP, 0047148B
MOV dwGetBaseAddr,0047A37F
// 0047A37F 0BC>OR EAX,EAX ; eax=申请的基地址
MOV dwWriteIATAddr,0897
// 001D0895 890>MOV DWORD PTR DS:[EDX],EAX ; 填充IAT
// 001D0897 E8 >CALL 001D08D5
//00300895 890>MOV DWORD PTR DS:[EDX],EAX
//00300897 E8 >CALL 003008D5
MOV dwGetAPIAddr, 0828
//00300828 ^\E9 >JMP 00300474 ; eax=函数地址
// 3. 清除所有断点
BPHWC
BPMC
BC
// 4. 设置断点
BPHWS dwGetBaseAddr, "x"
BPHWS dwOEP, "x"
// 5. 循环判断
LOOP0:
RUN
CMP eip,dwGetBaseAddr
JNZ NEXT1
ADD dwWriteIATAddr,eax
ADD dwGetAPIAddr,eax
BPHWS dwWriteIATAddr, "x"
BPHWS dwGetAPIAddr, "x"
JMP LOOP0
NEXT1:
CMP eip,dwGetAPIAddr
JNZ NEXT2
MOV dwTmp,eax
JMP LOOP0
NEXT2:
CMP eip,dwWriteIATAddr
JNZ NEXT3
MOV [edx],dwTmp
JMP LOOP0
NEXT3:
CMP eip,dwOEP
JNZ LOOP0
MSG "到达OEP!"
网友评论