首页
学习
活动
专区
圈层
工具
发布
30 篇文章
1
《coredump问题原理探究》Linux x86版6.4节虚函数
2
《coredump问题原理探究》Linux x86版7.3节List对象
3
《coredump问题原理探究》Linux x86版4.4节函数的逆向之循环结构
4
《coredump问题原理探究》windows版8.5节堆布局空闲堆块遍历
5
《coredump问题原理探究》windows版9.1节栈溢出
6
《coredump问题原理探究》Linux x86版3.2节栈布局之函数桢
7
《coredump问题原理探究》Linux x86版3.4节栈布局之函数参数
8
《coredump问题原理探究》Linux x86版4.1节函数的逆向之序言
9
《coredump问题原理探究》Linux x86版4.2节函数的逆向之顺序结构
10
《coredump问题原理探究》Linux x86版4.3节函数的逆向之条件结构
11
《coredump问题原理探究》windows版3.4节coredump例子
12
《coredump问题原理探究》windows版第四章函数的逆向
13
《coredump问题原理探究》windows版5.1节基本数据类型
14
《coredump问题原理探究》windows版5.2节数组
15
《coredump问题原理探究》windows版5.3节结构体
16
《coredump问题原理探究》windows版5.4节联合体
17
《coredump问题原理探究》windows版6.1节无成员变量的类
18
《coredump问题原理探究》windows版6.2节有成员变量的类
19
《coredump问题原理探究》windows版6.3节虚函数
20
《coredump问题原理探究》windows版6.4节单继承
21
《coredump问题原理探究》windows版6.5节多继承
22
《coredump问题原理探究》windows版7.1节vector
23
《coredump问题原理探究》windows版7.2节list
24
《coredump问题原理探究》windows版7.3节map
25
《coredump问题原理探究》windows版7.4节set
26
《coredump问题原理探究》windows版7.5节iterator
27
《coredump问题原理探究》windows版7.6节string
28
《coredump问题原理探究》windows版8.1节堆布局背景
29
《coredump问题原理探究》windows版8.2节堆布局堆块结构
30
《coredump问题原理探究》windows版3.1节函数桢

《coredump问题原理探究》Linux x86版7.3节List对象

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

先看一下例子:

代码语言:javascript
复制
1 #include <list>
  2 
  3 int main()
  4 {
  5     std::list<int> lst;
  6 
  7     lst.push_back( 0x12345678 );
  8     lst.push_front( 0xabcdef01 );
  9     lst.push_back( 0x24242522 );
 10 
 11     return 0;
 12 }

再看一下汇编:

代码语言:javascript
复制
(gdb) disassemble main
Dump of assembler code for function main:
   0x080485b4 <+0>:	push   %ebp
   0x080485b5 <+1>:	mov    %esp,%ebp
   0x080485b7 <+3>:	and    $0xfffffff0,%esp
   0x080485ba <+6>:	push   %esi
   0x080485bb <+7>:	push   %ebx
   0x080485bc <+8>:	sub    $0x38,%esp
   0x080485bf <+11>:	lea    0x1c(%esp),%eax
   0x080485c3 <+15>:	mov    %eax,(%esp)
   0x080485c6 <+18>:	call   0x8048674 <_ZNSt4listIiSaIiEEC2Ev>
   0x080485cb <+23>:	movl   $0x12345678,0x24(%esp)
   0x080485d3 <+31>:	lea    0x24(%esp),%eax
   0x080485d7 <+35>:	mov    %eax,0x4(%esp)
   0x080485db <+39>:	lea    0x1c(%esp),%eax
   0x080485df <+43>:	mov    %eax,(%esp)
   0x080485e2 <+46>:	call   0x80486de <_ZNSt4listIiSaIiEE9push_backERKi>
   0x080485e7 <+51>:	movl   $0xabcdef01,0x28(%esp)
   0x080485ef <+59>:	lea    0x28(%esp),%eax
   0x080485f3 <+63>:	mov    %eax,0x4(%esp)
   0x080485f7 <+67>:	lea    0x1c(%esp),%eax
   0x080485fb <+71>:	mov    %eax,(%esp)
   0x080485fe <+74>:	call   0x8048714 <_ZNSt4listIiSaIiEE10push_frontERKi>
   0x08048603 <+79>:	movl   $0x24242522,0x2c(%esp)
   0x0804860b <+87>:	lea    0x2c(%esp),%eax
   0x0804860f <+91>:	mov    %eax,0x4(%esp)
---Type <return> to continue, or q <return> to quit---
   0x08048613 <+95>:	lea    0x1c(%esp),%eax
   0x08048617 <+99>:	mov    %eax,(%esp)
   0x0804861a <+102>:	call   0x80486de <_ZNSt4listIiSaIiEE9push_backERKi>
   0x0804861f <+107>:	mov    $0x0,%ebx
   0x08048624 <+112>:	lea    0x1c(%esp),%eax
   0x08048628 <+116>:	mov    %eax,(%esp)
   0x0804862b <+119>:	call   0x8048660 <_ZNSt4listIiSaIiEED2Ev>
   0x08048630 <+124>:	mov    %ebx,%eax
   0x08048632 <+126>:	add    $0x38,%esp
   0x08048635 <+129>:	pop    %ebx
   0x08048636 <+130>:	pop    %esi
   0x08048637 <+131>:	mov    %ebp,%esp
   0x08048639 <+133>:	pop    %ebp
   0x0804863a <+134>:	ret    
   0x0804863b <+135>:	mov    %edx,%ebx
   0x0804863d <+137>:	mov    %eax,%esi
   0x0804863f <+139>:	lea    0x1c(%esp),%eax
   0x08048643 <+143>:	mov    %eax,(%esp)
   0x08048646 <+146>:	call   0x8048660 <_ZNSt4listIiSaIiEED2Ev>
   0x0804864b <+151>:	mov    %esi,%eax
   0x0804864d <+153>:	mov    %ebx,%edx
   0x0804864f <+155>:	mov    %eax,(%esp)
   0x08048652 <+158>:	call   0x80484e8 <_Unwind_Resume@plt>
End of assembler dump.

由0x080485c6附近的汇编来看,this指针放在esp+0x1c

在0x080485c6, 0x080485e2,0x080485fe, 0x0804861a, 0x0804862b打断点

代码语言:javascript
复制
(gdb) b *0x080485c6
Breakpoint 1 at 0x80485c6
(gdb) b *0x080485e2
Breakpoint 2 at 0x80485e2
(gdb) b *0x080485fe
Breakpoint 3 at 0x80485fe
(gdb) b *0x0804861a
Breakpoint 4 at 0x804861a
(gdb) b *0x0804862b
Breakpoint 5 at 0x804862b

先看一下list运行构造函数后会怎样.

代码语言:javascript
复制
Breakpoint 1, 0x080485c6 in main ()
(gdb) x /8x $esp+0x1c
0xbffff24c:	0x08048aa9	0x028ea550	0x0804832e	0x00000000
0xbffff25c:	0x009faff4	0x08048a90	0x08048500	0x009faff4
(gdb) ni
0x080485cb in main ()
(gdb) x /8x $esp+0x1c
0xbffff24c:	0xbffff24c	0xbffff24c	0x0804832e	0x00000000
0xbffff25c:	0x009faff4	0x08048a90	0x08048500	0x009faff4

可以看出list对象有两个成员, 且这两个成员的值均指向自身。可见,这两个成员是指针。

再看一下第一个push_back后

代码语言:javascript
复制
Breakpoint 2, 0x080485e2 in main ()
(gdb) x /8x $esp+0x1c
0xbffff24c:	0xbffff24c	0xbffff24c	0x12345678	0x00000000
0xbffff25c:	0x009faff4	0x08048a90	0x08048500	0x009faff4
(gdb) ni
0x080485e7 in main ()
(gdb) x /8x $esp+0x1c
0xbffff24c:	0x0804b008	0x0804b008	0x12345678	0x00000000
0xbffff25c:	0x009faff4	0x08048a90	0x08048500	0x009faff4
(gdb) x /8x 0x0804b008
0x804b008:	0xbffff24c	0xbffff24c	0x12345678	0x00020ff1
0x804b018:	0x00000000	0x00000000	0x00000000	0x00000000

用结构表示如下:

再看一下push_front

代码语言:javascript
复制
Breakpoint 3, 0x080485fe in main ()
(gdb) x /8x $esp+0x1c
0xbffff24c:	0x0804b008	0x0804b008	0x12345678	0xabcdef01
0xbffff25c:	0x009faff4	0x08048a90	0x08048500	0x009faff4
(gdb) x /8x 0x0804b008
0x804b008:	0xbffff24c	0xbffff24c	0x12345678	0x00020ff1
0x804b018:	0x00000000	0x00000000	0x00000000	0x00000000
(gdb) ni
0x08048603 in main ()
(gdb) x /8x $esp+0x1c
0xbffff24c:	0x0804b018	0x0804b008	0x12345678	0xabcdef01
0xbffff25c:	0x009faff4	0x08048a90	0x08048500	0x009faff4
(gdb) x /8x 0x0804b018
0x804b018:	0x0804b008	0xbffff24c	0xabcdef01	0x00020fe1
0x804b028:	0x00000000	0x00000000	0x00000000	0x00000000
(gdb) x /8x 0x0804b008
0x804b008:	0xbffff24c	0x0804b018	0x12345678	0x00000011
0x804b018:	0x0804b008	0xbffff24c	0xabcdef01	0x00020fe1

用图形来表示就如下(只表示第一个成员).

如果考察这三个地址的第二个成员,就会变成这样的图形

同样考察第二个push_back,并参照list的代码,会得到这样的结论.

1.     list有两个成员,第一个成员指向链表的头部,第二个成员指向链表的尾部

2.     链表的每一个节点都有三个元素,第一个_M_next,指向下一个节点.第二个_M_prev指向前一个节点.第三个_M_data存储节点的值.

3.     list所指向的链表每一个节点的_M_next, _M_prev指针应该都不为空的,也必须是指向有效地址.

下一篇
举报
领券