GKLBB

当你经历了暴风雨,你也就成为了暴风雨

导航

应用安全 --- 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
 

posted on 2026-06-21 06:35  GKLBB  阅读(0)  评论(0)    收藏  举报