脱壳经验1

脱壳-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

脱壳经验1_第1张图片
image.png

脱壳-2.exe
① 找OEP
单步跟踪

② IAT加密,解密IAT
解密IAT需要先找到加密IAT的地方,然后将其删除或是能还原。

找加密IAT代码的方式
① 对IAT设置硬件写入断点
对GetVersion所在的iat设置硬件写入断点,最终可以找到填充IAT的地方
004385EE 8907 MOV DWORD PTR DS:[EDI],EAX ; 填充IAT 函数地址

修改附近代码

修改前


脱壳经验1_第2张图片
image.png

修改后


脱壳经验1_第3张图片
image.png

② 对IAT相关的API设置断点
LoadLibraryA
GetProcAddress
GetModuleHandleA
VirtualProtect

脱壳中的一些问题
拿到程序怎么办?
以脱壳为目的,尽可能完成脱壳
技巧的使用?
① API下断注意的问题
API下断之后,第一应该观察的是堆栈,确定返回地址是我们要分析的模块

脱壳经验1_第4张图片
image.png

②注意当前分析的模块是不是主模块

脱壳经验1_第5张图片
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!"

你可能感兴趣的:(脱壳经验1)