windows样本高级静态分析之识别汇编中C代码结构四
字数 1577 2025-08-24 23:51:13
Windows样本高级静态分析:识别汇编中的C代码结构
引言
在二进制安全分析中,理解如何将汇编指令映射回高级语言结构是一项核心技能。本文详细讲解如何通过静态分析识别汇编代码中的数组、结构体和链表等常见C语言数据结构。
分析方法论
- 编写源代码并生成对应程序
- 反汇编目标程序
- 分析汇编代码,总结数据类型特征
- 建立汇编模式与高级语言结构的对应关系
数组类型的识别
源代码示例
#include <stdio.h>
void main() {
int arr[5];
arr[0] = 1;
arr[1] = 2;
for(int i = 2; i < 5; i++) {
arr[i] = i;
}
}
汇编特征分析
-
内存分配方式:
- 通常在栈上分配连续内存块
- 基址通常为
ebp+arr(栈帧指针加偏移)
-
元素访问模式:
- 使用索引访问:
[ebp+eax*4+arr] - 元素长度一致(本例中为4字节int)
- 连续填充数据到内存块中
- 使用索引访问:
-
典型指令模式:
mov [ebp+eax*4+arr], ecx- 看到这种基址+索引*元素大小的指令模式,通常对应数组访问
识别要点
- 一块连续内存区域
- 每个元素长度一致
- 通过基址+索引*元素大小的方式访问
结构体类型的识别
源代码示例
#include <stdio.h>
#include <stdlib.h>
struct mystruct {
int x[5];
char y;
};
struct mystruct *test;
void main() {
test = (struct mystruct*)malloc(sizeof(struct mystruct));
for(int i = 0; i < 5; i++) {
test->x[i] = i;
}
test->y = 'a';
}
汇编特征分析
-
内存分配方式:
- 通常通过
malloc动态分配 - 分配大小通过
sizeof计算结构体总大小
- 通常通过
-
元素访问模式:
- 混合类型访问:
mov [ecx+eax*4], edx(访问int数组) - 单字节访问:
mov byte ptr [eax+14h], 'a'(访问char成员) - 同一内存块内不同偏移处有不同类型的数据
- 混合类型访问:
-
典型指令模式:
- 对同一基址的不同偏移进行不同类型的数据操作
- 偏移量计算可能包含编译时确定的常量(如
14h)
识别要点
- 通过
malloc分配的内存块 - 同一内存区域包含不同类型的数据
- 不同成员通过固定偏移量访问
- 访问指令的数据宽度不一致(如dword和byte混用)
链表类型的识别
源代码示例
#include <stdio.h>
#include <stdlib.h>
struct node {
int x;
struct node *next;
};
typedef node pnode;
void main() {
pnode *curr, *head;
int i;
head = NULL;
for(i = 1; i <= 3; i++) {
curr = (pnode*)malloc(sizeof(pnode));
curr->x = i;
curr->next = head;
head = curr;
}
}
汇编特征分析
-
内存分配方式:
- 多次调用
malloc分配节点 - 每个节点大小相同
- 多次调用
-
元素访问模式:
- 节点包含数据成员(如
mov [eax], ecx设置x值) - 节点包含指针成员(如
mov [eax+4], edx设置next指针) - 指针成员指向相同类型的其他内存块
- 节点包含数据成员(如
-
链接特征:
- 通过指针成员将多个内存块连接起来
- 常见操作如将新节点的next指向当前head,然后更新head
-
典型指令模式:
- 内存块中包含指向同类内存块的指针
- 通过指针遍历多个相同结构的节点
识别要点
- 动态分配的多个内存块
- 每个块中包含指向同类块的指针
- 通过指针字段将多个块链接起来
- 通常伴随插入、遍历等操作模式
总结对比表
| 数据类型 | 内存特征 | 访问模式 | 典型指令模式 | 关键识别点 |
|---|---|---|---|---|
| 数组 | 连续内存块,元素大小相同 | 基址+索引*元素大小 | mov [ebp+eax*4+arr], ecx |
连续内存,统一大小的元素,索引访问 |
| 结构体 | 单块内存包含不同类型数据 | 固定偏移访问不同成员 | mov [ecx+eax*4], edx和mov byte ptr [eax+14h], 'a'混用 |
同一内存块内混合类型访问,固定偏移 |
| 链表 | 多个动态分配节点 | 节点包含数据和指针成员 | mov [eax], ecx和mov [eax+4], edx |
内存块中包含指向同类块的指针 |
实践建议
- 在分析时注意内存访问指令的操作数宽度
- 观察同一基址不同偏移处的访问模式
- 注意指针解引用操作,特别是循环遍历模式
- 结合上下文理解数据结构的用途
- 对动态分配的内存,跟踪其生命周期和访问方式
掌握这些模式识别技巧,可以大大提高逆向工程中重构高级语言数据结构的效率和准确性。