首页
学习
活动
专区
圈层
工具
发布
21 篇文章
1
《coredump问题原理探究》Linux x86版6.3节有成员变量的类coredump例子
2
《coredump问题原理探究》Linux x86版6.5节虚函数的coredump例子
3
《coredump问题原理探究》Linux x86版6.8节多继承coredump例子
4
《coredump问题原理探究》Linux x86版7.2节vector coredump例子
5
《coredump问题原理探究》Linux x86版7.4节List coredump例子
6
《coredump问题原理探究》Linux x86版7.6节 Map coredump例子
7
《coredump问题原理探究》Linux x86版5.9节C风格数据结构内存布局之联合体
8
《coredump问题原理探究》Linux x86版6.1节C++风格数据结构内存布局之无成员变量的类
9
《coredump问题原理探究》Linux x86版6.2节C++风格数据结构内存布局之有成员变量的类
10
《coredump问题原理探究》Linux x86版4.5节函数的逆向之coredump例子
11
《coredump问题原理探究》Linux x86版5.1节C风格数据结构内存布局之引言
12
《coredump问题原理探究》Linux x86版5.2节C风格数据结构内存布局之基本数据类型
13
《coredump问题原理探究》Linux x86版5.3节C风格数据结构内存布局之数组
14
《coredump问题原理探究》Linux x86版5.4节C风格数据结构内存布局之数组coredump例子
15
《coredump问题原理探究》Linux x86版5.5节C风格数据结构内存布局之基本数据类型构成的结构体
16
《coredump问题原理探究》Linux x86版5.6节C风格数据结构内存布局之复合类型构成的结构体
17
《coredump问题原理探究》Linux x86版5.7节C风格数据结构内存布局之结构体数组
18
《coredump问题原理探究》Linux x86版5.8节C风格数据结构内存布局之结构体数组结构体coredump
19
《coredump问题原理探究》Linux x86版3.5节栈布局之-fomit-frame-pointer编译选项
20
《coredump问题原理探究》Linux x86版3.6节栈布局之gcc内嵌关键字
21
《coredump问题原理探究》Linux x86版3.8节栈布局之栈溢出coredump例子

《coredump问题原理探究》Linux x86版5.6节C风格数据结构内存布局之复合类型构成的结构体

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1344508

由于结构体是不同类型数据结构的集合,那么一个结构体的成员可以是基本数据类型,也可以是另外一个结构体类型。那么复合类型的结构体又有什么特征呢。

先看一个例子:

代码语言:javascript
复制
 #include <stdio.h>
 struct xuzhina_dump_c05_s3_2_sub
 {   
     char a;
     short b;
 };
 
 struct xuzhina_dump_c05_s3_2
 {   
     int c;
     long d;
     struct xuzhina_dump_c05_s3_2_sub sub;
 };
 
 
 int main()
 {   
     struct xuzhina_dump_c05_s3_2 test;
     
     scanf( "%c, %hd, %d, %ld", &test.sub.a, &test.sub.b,
             &test.c, &test.d );
     
     return test.c + test.d;
 }

汇编

代码语言:javascript
复制
(gdb) disassemble main
Dump of assembler code for function main:
   0x08048570 <+0>:     push   %ebp
   0x08048571 <+1>:     mov    %esp,%ebp
   0x08048573 <+3>:     and    $0xfffffff0,%esp
   0x08048576 <+6>:     sub    $0x30,%esp
   0x08048579 <+9>:     lea    0x24(%esp),%eax
   0x0804857d <+13>:    add    $0x4,%eax
   0x08048580 <+16>:    mov    %eax,0x10(%esp)
   0x08048584 <+20>:    lea    0x24(%esp),%eax
   0x08048588 <+24>:    mov    %eax,0xc(%esp)

   0x0804858c <+28>:    lea    0x24(%esp),%eax
   0x08048590 <+32>:    add    $0xa,%eax
   0x08048593 <+35>:    mov    %eax,0x8(%esp)

   0x08048597 <+39>:    lea    0x24(%esp),%eax
   0x0804859b <+43>:    add    $0x8,%eax
   0x0804859e <+46>:    mov    %eax,0x4(%esp)

   0x080485a2 <+50>:    movl   $0x8048664,(%esp)
   0x080485a9 <+57>:    call   0x8048440 <scanf@plt>
   0x080485ae <+62>:    mov    0x24(%esp),%edx
   0x080485b2 <+66>:    mov    0x28(%esp),%eax
   0x080485b6 <+70>:    add    %edx,%eax
   0x080485b8 <+72>:    jmp    0x80485c2 <main+82>
   0x080485ba <+74>:    mov    %eax,(%esp)
   0x080485bd <+77>:    call   0x8048460 <_Unwind_Resume@plt>
   0x080485c2 <+82>:    leave  
   0x080485c3 <+83>:    ret    
End of assembler dump.

代码语言:javascript
复制
   0x08048597 <+39>:    lea    0x24(%esp),%eax
   0x0804859b <+43>:    add    $0x8,%eax
   0x0804859e <+46>:    mov    %eax,0x4(%esp)

对test.sub.a的访问,可知,它是直接把test的基地址esp+0x24加上8(c和d的大小总和为8)来访问。

同样对test.sub.b的访问:

代码语言:javascript
复制
   0x0804858c <+28>:    lea    0x24(%esp),%eax
   0x08048590 <+32>:    add    $0xa,%eax
   0x08048593 <+35>:    mov    %eax,0x8(%esp)

可知,它是直接把test的基地址esp+0x24加上10(0xa)(c和d的大小总和为8,而a是char由于对齐2个字节,所以偏移量为0xa)来访问。

也就是说,对test的成员变量sub的成员访问,完全可以无视sub的存在,不需要再设定sub的基地址。

由上可知,复合结构体和基本数据类型构成的结构体在特征上没什么区别。如果在coredump发现是结构体成员导致,可以通过结构体定义算偏移值来确定是哪个成员出了问题。

下一篇
举报
领券