应用安全 --- IDAPro签名 之 PAT文件解析
PAT 文件格式举例分析
一个完整的 PAT 行长这样
text
558BEC83C4F053568D45F050E8........8BD88D45EC508D45F4508D45F850 0A 1234 0040 :0000 _MyFunction ^001C _ExternalFunc ^0030 _AnotherFunc FF2500000000
---
把它完整拆开
原始行
text
558BEC83C4F053568D45F050E8........8BD88D45EC508D45F4508D45F850 0A 1234 0040 :0000 _MyFunction ^001C _ExternalFunc ^0030 _AnotherFunc FF2500000000
字段1:PATTERN(前32字节,64个十六进制字符)
text
558BEC83C4F053568D45F050E8........8BD88D45EC508D45F4508D45F850
对应机器码还原:
asm
偏移 字节 汇编
0x00 55 push ebp
0x01 8B EC mov ebp, esp
0x03 83 C4 F0 add esp, -0x10
0x06 53 push ebx
0x07 56 push esi
0x08 8D 45 F0 lea eax, [ebp-0x10]
0x0B 50 push eax
0x0C E8 ........ call _SomeInit ← 4字节相对偏移可变
0x11 8B D8 mov ebx, eax
0x13 8D 45 EC lea eax, [ebp-0x14]
0x16 50 push eax
0x17 8D 45 F4 lea eax, [ebp-0x0C]
0x1A 50 push eax
0x1B 8D 45 F8 lea eax, [ebp-0x08]
0x1E 50 push eax ← 第32字节结束
字段2:ALEN = 0A
text
从第33字节(偏移0x20)开始
连续 0x0A = 10 个固定字节参与CRC16计算
对应偏移 0x20 ~ 0x29 的机器码是固定的:
asm
0x20 E8 ........ call _CalcResult ← 注意:这里E8是固定的但偏移可变
0x21 xx xx xx xx call偏移(可变,不在CRC范围)
实际上 ALEN 统计的是这段里连续固定字节的数量,遇到可变字节就停止
字段3:ASUM = 1234
text
对上面 0x0A 个固定字节做 CRC16
结果是 0x1234
字段4:MODLEN = 0040
text
0x0040 = 64 字节
这个函数从起点到终点共占 64 字节
字段5:PUBLIC_NAMES = :0000 _MyFunction
text
:0000 _MyFunction
含义:
text
模块偏移 0x0000 处 = 函数入口点
函数名字是 _MyFunction
字段6:REFERENCED_NAMES
text
^001C _ExternalFunc
^0030 _AnotherFunc
对应机器码位置:
asm
; 偏移 0x1C 处
0x1C E8 ........ call _ExternalFunc ← ^001C 对应这里
; 偏移 0x30 处
0x30 FF 25 ........ jmp [_AnotherFunc] ← ^0030 对应这里
字段7:TAIL_BYTES = FF2500000000
text
FF 25 00 00 00 00
对应机器码:
asm
0x3A FF 25 00 00 00 00 jmp [0x00000000]
这里地址被写成
00000000是占位,实际链接后会被修正
但这6字节在这个例子里是固定的,所以直接写出来
完整对照图
text
┌─────────────────────────────────────────────────────────────────┐
│ PAT 行结构 │
├──────────────────────────────────────┬──┬────┬────┬────────────┤
│ PATTERN (64字符) │AL│ASUM│MLEN│ 其余字段 │
│558BEC83C4F053568D45F050E8........... │0A│1234│0040│ ... │
└──────────────────────────────────────┴──┴────┴────┴────────────┘
展开其余字段:
┌────────────────┬───────────────────┬───────────────────┬──────────────┐
│ PUBLIC_NAMES │ REFERENCED[0] │ REFERENCED[1] │ TAIL_BYTES │
│ :0000_MyFunc │ ^001C_ExternalFunc│ ^0030_AnotherFunc │ FF2500000000 │
└────────────────┴───────────────────┴───────────────────┴──────────────┘
多行PAT文件完整示例
pat
558BEC83C4F053568D45F050E8........8BD88D45EC508D45F4508D45F850 0A 1234 0040 :0000 _MyFunction ^001C _ExternalFunc ^0030 _AnotherFunc FF2500000000
4889544124488954244048894C2400554883EC30488B05........4831C4488945 00 0000 0060 :0000 _AnotherFunc ^0020 _malloc ^0050 _free ........C3
E8........C3909090909090909090909090909090909090909090909090909090 00 0000 0010 :0000 _TinyWrapper ^0001 _RealFunction
---
三行含义速览
| 行号 | 函数名 | 函数长度 | 特点 |
|---|---|---|---|
| 第1行 | _MyFunction |
0x40 = 64字节 | 有CRC区(0x0A字节),有尾部固定字节 |
| 第2行 | _AnotherFunc |
0x60 = 96字节 | 无CRC区(00 0000),尾部含RET(C3) |
| 第3行 | _TinyWrapper |
0x10 = 16字节 | 首字节即jmp,极短函数,无CRC无尾部 |
关键规律总结
text
可变字节出现位置 对应指令
E8 ........ call rel32
E9 ........ jmp rel32
FF 15 ........ call [mem]
FF 25 ........ jmp [mem]
8D 0D ........ lea ecx, [abs]
48 8D 0D ........ lea rcx, [rip+rel]
固定字节出现位置 对应内容
函数序言: 55 8B EC push ebp / mov ebp,esp
函数返回: C3 ret
NOP填充: 90 nop
免责声明
本文档所有内容仅供安全研究、学术交流与技术学习使用,严禁用于任何未经授权的逆向破解、网络攻击、隐私窃取、恶意软件开发及其他违反《中华人民共和国网络安全法》《数据安全法》等法律法规的行为,使用者应确保已获得目标软件权利人的合法授权并自行承担因使用本文档内容所产生的一切法律责任与后果,作者不对任何直接或间接损害承担任何责任,继续阅读即视为您已知悉并同意上述全部条款。
浙公网安备 33010602011771号