逆向基础3. 结构体数组的汇编结构
结构体数组的汇编结构
在栈上的数组数据结构
测试使用结构体如下
cpp
typedef struct {
int id;
int count;
int count2;
int count3;
} GameObject;测试代码如下
cpp
int main()
{
GameObject objs[3] = {
GameObject{1, 0x12, 0x23, 0x34},
GameObject{2, 0x45, 0x56, 0x67},
GameObject{3, 0x78, 0x89, 0x90}
};
auto obj1 = &objs[0];
auto obj2 = &objs[1];
auto obj3 = &objs[2];
auto count1 = obj1->count;
auto count2 = obj2->count2;
auto count3 = obj3->count3;
auto sum = count1 + count2 + count3;
return 0;
}生成汇编如下:
asm
sub rsp, 0x90 ; 分配栈空间
lea rdi, [rsp + 0x20] ; 数组开始地址为 rsp + 0x20
; 填充内存为0xcccccccc
mov ecx, 0x1c
mov eax, 0xcccccccc
rep stosd dword ptr es:[rdi], eax
; 填充初始化数据
mov dword ptr [rsp + 0x28], 0x1
mov dword ptr [rsp + 0x2c], 0x12
mov dword ptr [rsp + 0x30], 0x23
mov dword ptr [rsp + 0x34], 0x34
mov dword ptr [rsp + 0x38], 0x2
mov dword ptr [rsp + 0x3c], 0x45
mov dword ptr [rsp + 0x40], 0x56
mov dword ptr [rsp + 0x44], 0x67
mov dword ptr [rsp + 0x48], 0x3
mov dword ptr [rsp + 0x4c], 0x78
mov dword ptr [rsp + 0x50], 0x89
mov dword ptr [rsp + 0x54], 0x90
; [rsp + 0x68] = &objs[0]
mov eax, 0x10
imul rax, rax, 0x0
lea rax, [rsp + rax + 0x28]
mov qword ptr [rsp + 0x68], rax
; [rsp + 0x70] = &objs[1]
mov eax, 0x10
imul rax, rax, 0x1
lea rax, [rsp + rax + 0x28]
mov qword ptr [rsp + 0x70], rax
; [rsp + 0x78] = &objs[2]
mov eax, 0x10
imul rax, rax, 0x2
lea rax, [rsp + rax + 0x28]
mov qword ptr [rsp + 0x78], rax
; [rsp + 0x80] = objs[0].count
mov rax, qword ptr [rsp + 0x68]
mov eax, dword ptr [rax + 0x4]
mov dword ptr [rsp + 0x80], eax
; [rsp + 0x84] = objs[1].count2
mov rax, qword ptr [rsp + 0x70]
mov eax, dword ptr [rax + 0x8]
mov dword ptr [rsp + 0x84], eax
; [rsp + 0x88] = objs[2].count3
mov rax, qword ptr [rsp + 0x78]
mov eax, dword ptr [rax + 0xc]
mov dword ptr [rsp + 0x88], eax
; sum = count1 + count2 + count3
mov eax, dword ptr [rsp + 0x84]
mov ecx, dword ptr [rsp + 0x80]
add ecx, eax
mov eax, ecx
add eax, dword ptr [rsp + 0x88]
mov dword ptr [rsp + 0x8c], eax
...可以看出其栈如下
| rsp偏移 | 类型 | 内容 | 值 |
|---|---|---|---|
0x28 | dword | objs[0].id | 1 |
0x2c | dword | objs[0].count | 0x12 |
0x30 | dword | objs[0].count2 | 0x23 |
0x34 | dword | objs[0].count3 | 0x34 |
0x38 | dword | objs[1].id | 2 |
0x3c | dword | objs[1].count | 0x45 |
0x40 | dword | objs[1].count2 | 0x56 |
0x44 | dword | objs[1].count3 | 0x67 |
0x48 | dword | objs[2].id | 3 |
0x4c | dword | objs[2].count | 0x78 |
0x50 | dword | objs[2].count2 | 0x89 |
0x54 | dword | objs[2].count3 | 0x90 |
0x68 | qword | &objs[0] | rsp + 0x28 |
0x70 | qword | &objs[1] | rsp + 0x38 |
0x78 | qword | &objs[2] | rsp + 0x48 |
0x80 | dword | objs[0].count | |
0x84 | dword | objs[1].count2 | |
0x88 | dword | objs[2].count3 | |
0x8c | dword | sum |
其取值的方式为[&arr + sizeof(obj) * offset + member_offset]
在堆上的数组取值方式
代码:
cpp
GameObject **createObjArr()
{
auto **objs = new GameObject *[3];
objs[0] = new GameObject{1, 0x12, 0x23, 0x34};
objs[1] = new GameObject{2, 0x45, 0x56, 0x67};
objs[2] = new GameObject{3, 0x78, 0x89, 0x90};
return objs;
}
int main()
{
auto objs = createObjArr();
int count1 = objs[0]->count;
int count2 = objs[1]->count2;
int count3 = objs[2]->count3;
int sum = count1 + count2 + count3;
return 0;
}Warning | 此处忽略内存回收, 忽略分析创建, 仅仅研究如何取值 |
生成汇编如下:
asm
; [rsp + 0x20] = &arr
mov qword ptr [rsp + 0x20], rax
mov eax, 0x8
imul rax, rax, 0x0
mov rcx, qword ptr [rsp + 0x20]
mov rax, qword ptr [rcx + rax]
mov eax, dword ptr [rax + 0x4]
mov dword ptr [rsp + 0x28], eax
mov eax, 0x8 ; eax = sizeof(GameObject *)
imul rax, rax, 0x1 ; rax = sizeof(GameObject *) * 1
mov rcx, qword ptr [rsp + 0x20]
mov rax, qword ptr [rcx + rax] ; rax = &arr + eax
mov eax, dword ptr [rax + 0x8] ; eax = [rax + 0x8]
mov dword ptr [rsp + 0x2c], eax ; [rsp + 0x2c] = eax
mov eax, 0x8
imul rax, rax, 0x2
mov rcx, qword ptr [rsp + 0x20]
mov rax, qword ptr [rcx + rax]
mov eax, dword ptr [rax + 0xc]
mov dword ptr [rsp + 0x30], eax
mov eax, dword ptr [rsp + 0x2c]
mov ecx, dword ptr [rsp + 0x28]
add ecx, eax
mov eax, ecx
add eax, dword ptr [rsp + 0x30]
mov dword ptr [rsp + 0x34], eax对于堆上的数组, 取值为[[&arr + sizeof(obj*) * offset] + member_offset]
逆向基础3. 结构体数组的汇编结构
https://simonkimi.githubio.io/2024/07/29/逆向基础3-结构体数组的汇编结构/