mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-25 11:41:16 +07:00
update heap
This commit is contained in:
parent
403225985a
commit
1231d2e3d1
@ -13,6 +13,7 @@
|
|||||||
- [1.5.5 静态链接](doc/1.5.5_static_link.md)
|
- [1.5.5 静态链接](doc/1.5.5_static_link.md)
|
||||||
- [1.5.6 动态链接](doc/1.5.6_dynamic_link.md)
|
- [1.5.6 动态链接](doc/1.5.6_dynamic_link.md)
|
||||||
- [1.5.7 内存管理](doc/1.5.7_memory.md)
|
- [1.5.7 内存管理](doc/1.5.7_memory.md)
|
||||||
|
- [1.5.8 glibc malloc](doc/glibc_malloc.md)
|
||||||
- [1.6 密码学基础](doc/1.6_crypto_basic.md)
|
- [1.6 密码学基础](doc/1.6_crypto_basic.md)
|
||||||
- [1.7 Android 安全基础](doc/1.7_android_basic.md)
|
- [1.7 Android 安全基础](doc/1.7_android_basic.md)
|
||||||
|
|
||||||
@ -39,6 +40,7 @@
|
|||||||
- [四、技巧篇](doc/4_tips.md)
|
- [四、技巧篇](doc/4_tips.md)
|
||||||
- [4.1 AWD模式](doc/4.1_AWD.md)
|
- [4.1 AWD模式](doc/4.1_AWD.md)
|
||||||
- [4.2 Linux 命令行技巧](doc/4.2_Linux_terminal_tips.md)
|
- [4.2 Linux 命令行技巧](doc/4.2_Linux_terminal_tips.md)
|
||||||
|
- [4.3 GCC 安全编译参数](doc/4.3_gcc.md)
|
||||||
|
|
||||||
- [五、高级篇](doc/5_advanced.md)
|
- [五、高级篇](doc/5_advanced.md)
|
||||||
- [5.1 Fuzz 测试](doc/5.1_fuzz.md)
|
- [5.1 Fuzz 测试](doc/5.1_fuzz.md)
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
* [1.5.5 静态链接](doc/1.5.5_static_link.md)
|
* [1.5.5 静态链接](doc/1.5.5_static_link.md)
|
||||||
* [1.5.6 动态链接](doc/1.5.6_dynamic_link.md)
|
* [1.5.6 动态链接](doc/1.5.6_dynamic_link.md)
|
||||||
* [1.5.7 内存管理](doc/1.5.7_memory.md)
|
* [1.5.7 内存管理](doc/1.5.7_memory.md)
|
||||||
|
* [1.5.8 glibc malloc](doc/glibc_malloc.md)
|
||||||
* [1.6 密码学基础](doc/1.6_crypto_basic.md)
|
* [1.6 密码学基础](doc/1.6_crypto_basic.md)
|
||||||
* [1.7 Android 安全基础](doc/1.7_android_basic.md)
|
* [1.7 Android 安全基础](doc/1.7_android_basic.md)
|
||||||
* [二、工具篇](doc/2_tools.md)
|
* [二、工具篇](doc/2_tools.md)
|
||||||
@ -37,6 +38,7 @@
|
|||||||
* [四、技巧篇](doc/4_tips.md)
|
* [四、技巧篇](doc/4_tips.md)
|
||||||
* [4.1 AWD模式](doc/4.1_AWD.md)
|
* [4.1 AWD模式](doc/4.1_AWD.md)
|
||||||
* [4.2 Linux 命令行技巧](doc/4.2_Linux_terminal_tips.md)
|
* [4.2 Linux 命令行技巧](doc/4.2_Linux_terminal_tips.md)
|
||||||
|
* [4.3 GCC 安全编译参数](doc/4.3_gcc.md)
|
||||||
* [五、高级篇](doc/5_advanced.md)
|
* [五、高级篇](doc/5_advanced.md)
|
||||||
* [5.1 Fuzz 测试](doc/5.1_fuzz.md)
|
* [5.1 Fuzz 测试](doc/5.1_fuzz.md)
|
||||||
* [5.2 Pin 动态二进制插桩](doc/5.2_pin.md)
|
* [5.2 Pin 动态二进制插桩](doc/5.2_pin.md)
|
||||||
@ -46,5 +48,5 @@
|
|||||||
* [6.1 更多 Linux 工具](doc/6.1_Linuxtools.md)
|
* [6.1 更多 Linux 工具](doc/6.1_Linuxtools.md)
|
||||||
* [6.2 更多 Windows 工具](doc/6.2_wintools.md)
|
* [6.2 更多 Windows 工具](doc/6.2_wintools.md)
|
||||||
* [6.3 博客、文章和书籍](doc/6.3_books&blogs.md)
|
* [6.3 博客、文章和书籍](doc/6.3_books&blogs.md)
|
||||||
* [6.4 习题 write*up](doc/6.4_writeup.md)
|
* [6.4 习题 write-up](doc/6.4_writeup.md)
|
||||||
* [6.5 Linux x86-64 系统调用表](doc/6.5_syscall.md)
|
* [6.5 Linux x86-64 系统调用表](doc/6.5_syscall.md)
|
||||||
|
@ -99,20 +99,20 @@ Dump of assembler code for function main:
|
|||||||
0x0000058e <+43>: push DWORD PTR [ebp-0xc] ;将 b 压入栈中
|
0x0000058e <+43>: push DWORD PTR [ebp-0xc] ;将 b 压入栈中
|
||||||
0x00000591 <+46>: push DWORD PTR [ebp-0x10] ;将 a 压入栈中
|
0x00000591 <+46>: push DWORD PTR [ebp-0x10] ;将 a 压入栈中
|
||||||
0x00000594 <+49>: call 0x53d <add> ;调用 add() 函数,返回值保存在 eax 中
|
0x00000594 <+49>: call 0x53d <add> ;调用 add() 函数,返回值保存在 eax 中
|
||||||
0x00000599 <+54>: add esp,0x8
|
0x00000599 <+54>: add esp,0x8 ;清理 add() 的参数
|
||||||
0x0000059c <+57>: sub esp,0x8
|
0x0000059c <+57>: sub esp,0x8 ;调整 esp 使 16 位对齐
|
||||||
0x0000059f <+60>: push eax ;eax 入栈
|
0x0000059f <+60>: push eax ;eax 入栈
|
||||||
0x000005a0 <+61>: lea eax,[ebx-0x19b0] ;ebx-0x19b0 的地址保存到 eax,该地址处保存字符串 "%d\n"
|
0x000005a0 <+61>: lea eax,[ebx-0x19b0] ;ebx-0x19b0 的地址保存到 eax,该地址处保存字符串 "%d\n"
|
||||||
0x000005a6 <+67>: push eax ;eax 入栈
|
0x000005a6 <+67>: push eax ;eax 入栈
|
||||||
0x000005a7 <+68>: call 0x3d0 <printf@plt> ;调用 printf() 函数
|
0x000005a7 <+68>: call 0x3d0 <printf@plt> ;调用 printf() 函数
|
||||||
0x000005ac <+73>: add esp,0x10 ;调整栈顶指针 esp,删除 add() 和 printf() 的参数
|
0x000005ac <+73>: add esp,0x10 ;调整栈顶指针 esp,清理 printf() 的参数
|
||||||
0x000005af <+76>: mov eax,0x0 ;eax=0x0
|
0x000005af <+76>: mov eax,0x0 ;eax=0x0
|
||||||
0x000005b4 <+81>: lea esp,[ebp-0x8] ;ebp-0x8 的地址保存到 esp
|
0x000005b4 <+81>: lea esp,[ebp-0x8] ;ebp-0x8 的地址保存到 esp
|
||||||
0x000005b7 <+84>: pop ecx ;弹栈恢复 ecx、ebx、ebp
|
0x000005b7 <+84>: pop ecx ;弹栈恢复 ecx、ebx、ebp
|
||||||
0x000005b8 <+85>: pop ebx
|
0x000005b8 <+85>: pop ebx
|
||||||
0x000005b9 <+86>: pop ebp
|
0x000005b9 <+86>: pop ebp
|
||||||
0x000005ba <+87>: lea esp,[ecx-0x4] ;ecx-0x4 的地址保存到 esp
|
0x000005ba <+87>: lea esp,[ecx-0x4] ;ecx-0x4 的地址保存到 esp
|
||||||
0x000005bd <+90>: ret ;返回
|
0x000005bd <+90>: ret ;返回,相当于 pop eip;
|
||||||
End of assembler dump.
|
End of assembler dump.
|
||||||
gdb-peda$ disassemble add
|
gdb-peda$ disassemble add
|
||||||
Dump of assembler code for function add:
|
Dump of assembler code for function add:
|
||||||
@ -155,7 +155,7 @@ Dump of assembler code for function _start:
|
|||||||
0x0000042c <+44>: call 0x3e0 <__libc_start_main@plt> ;call 指令调用 main() 函数
|
0x0000042c <+44>: call 0x3e0 <__libc_start_main@plt> ;call 指令调用 main() 函数
|
||||||
0x00000431 <+49>: hlt ;hlt 指令使程序停止运行,处理器进入暂停状态,不执行任何操作,不影响标志。当 RESET 线上有复位信号、CPU 响应非屏蔽终端、CPU 响应可屏蔽终端 3 种情况之一时,CPU 脱离暂停状态,执行下一条指令
|
0x00000431 <+49>: hlt ;hlt 指令使程序停止运行,处理器进入暂停状态,不执行任何操作,不影响标志。当 RESET 线上有复位信号、CPU 响应非屏蔽终端、CPU 响应可屏蔽终端 3 种情况之一时,CPU 脱离暂停状态,执行下一条指令
|
||||||
0x00000432 <+50>: mov ebx,DWORD PTR [esp] ;esp 强制转换为双字数据后保存到 ebx
|
0x00000432 <+50>: mov ebx,DWORD PTR [esp] ;esp 强制转换为双字数据后保存到 ebx
|
||||||
0x00000435 <+53>: ret ;返回
|
0x00000435 <+53>: ret ;返回,相当于 pop eip;
|
||||||
0x00000436 <+54>: xchg ax,ax ;交换 ax 和 ax 的数据,相当于 nop
|
0x00000436 <+54>: xchg ax,ax ;交换 ax 和 ax 的数据,相当于 nop
|
||||||
0x00000438 <+56>: xchg ax,ax
|
0x00000438 <+56>: xchg ax,ax
|
||||||
0x0000043a <+58>: xchg ax,ax
|
0x0000043a <+58>: xchg ax,ax
|
||||||
@ -180,11 +180,146 @@ cdecl | 函数调用方 | 从右到左的顺序压参数入栈 | 下划线+函
|
|||||||
stdcall | 函数本身 | 从右到左的顺序压参数入栈 | 下划线+函数名+@+参数的字节数
|
stdcall | 函数本身 | 从右到左的顺序压参数入栈 | 下划线+函数名+@+参数的字节数
|
||||||
fastcall | 函数本身 | 都两个 DWORD(4 字节)类型或者占更少字节的参数被放入寄存器,其他剩下的参数按从右到左的顺序压入栈 | @+函数名+@+参数的字节数
|
fastcall | 函数本身 | 都两个 DWORD(4 字节)类型或者占更少字节的参数被放入寄存器,其他剩下的参数按从右到左的顺序压入栈 | @+函数名+@+参数的字节数
|
||||||
|
|
||||||
|
除了参数的传递之外,函数与调用方还可以通过返回值进行交互。当返回值不大于 4 字节时,返回值存储在 eax 寄存器中,当返回值在 5~8 字节时,采用 eax 和 edx 结合的形式返回,其中 eax 存储低 4 字节, edx 存储高 4 字节。
|
||||||
|
|
||||||
|
|
||||||
## 堆与内存管理
|
## 堆与内存管理
|
||||||
#### 堆
|
#### 堆
|
||||||
堆是用于存放除了栈里的东西之外所有其他东西的内存区域,当使用 `malloc()` 和 `free()` 时就是在操作堆中的内存。对于堆来说,释放工作由程序员控制,容易产生 memory leak。
|
堆是用于存放除了栈里的东西之外所有其他东西的内存区域,有动态内存分配器负责维护。分配器将堆视为一组不同大小的块(block)的集合来维护,每个块就是一个连续的虚拟内存器片(chunk)。当使用 `malloc()` 和 `free()` 时就是在操作堆中的内存。对于堆来说,释放工作由程序员控制,容易产生内存泄露。
|
||||||
|
|
||||||
堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
|
堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
|
||||||
|
|
||||||
|
如果每次申请内存时都直接使用系统调用,会严重影响程序的性能。通常情况下,运行库先向操作系统“批发”一块较大的堆空间,然后“零售”给程序使用。当全部“售完”之后或者剩余空间不能满足程序的需求时,再根据情况向操作系统“进货”。
|
||||||
|
|
||||||
#### 进程堆管理
|
#### 进程堆管理
|
||||||
|
Linux 提供了两种堆空间分配的方式,一个是 `brk()` 系统调用,另一个是 `mmap()` 系统调用。可以使用 `man brk`、`man mmap` 查看。
|
||||||
|
|
||||||
|
`brk()` 的声明如下:
|
||||||
|
```c
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int brk(void *addr);
|
||||||
|
|
||||||
|
void *sbrk(intptr_t increment);
|
||||||
|
```
|
||||||
|
参数 `*addr` 是进程数据段的结束地址,`brk()` 通过改变该地址来改变数据段的大小,当结束地址向高地址移动,进程内存空间增大,当结束地址向低地址移动,进程内存空间减小。`brk()`调用成功时返回 0,失败时返回 -1。 `sbrk()` 与 `brk()` 类似,但是参数 `increment` 表示增量,即增加或减少的空间大小,调用成功时返回增加后减小后数据段的结束地址,失败时返回 -1。
|
||||||
|
|
||||||
|
`mmap()` 的声明如下:
|
||||||
|
```c
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
void *mmap(void *addr, size_t len, int prot, int flags,
|
||||||
|
int fildes, off_t off);
|
||||||
|
```
|
||||||
|
`mmap()` 函数用于创建新的虚拟内存区域,并将对象映射到这些区域中,当它不将地址空间映射到某个文件时,我们称这块空间为匿名(Anonymous)空间,匿名空间可以用来作为堆空间。`mmap()` 函数要求内核创建一个从地址 `addr` 开始的新虚拟内存区域,并将文件描述符 `fildes` 指定的对象的一个连续的片(chunk)映射到这个新区域。连续的对象片大小为 `len` 字节,从距文件开始处偏移量为 `off` 字节的地方开始。`prot` 描述虚拟内存区域的访问权限位,`flags` 描述被映射对象类型的位组成。
|
||||||
|
|
||||||
|
`munmap()` 则用于删除虚拟内存区域:
|
||||||
|
```c
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
int munmap(void *addr, size_t len);
|
||||||
|
```
|
||||||
|
|
||||||
|
C 标准库提供了一个叫做 `malloc` 的分配器,程序通过调用 `malloc()` 函数来从堆中分配块,声明如下:
|
||||||
|
```c
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void *malloc(size_t size);
|
||||||
|
void free(void *ptr);
|
||||||
|
void *calloc(size_t nmemb, size_t size);
|
||||||
|
void *realloc(void *ptr, size_t size);
|
||||||
|
```
|
||||||
|
|
||||||
|
示例:
|
||||||
|
```
|
||||||
|
#include<stdio.h>
|
||||||
|
#include<malloc.h>
|
||||||
|
void foo(int n) {
|
||||||
|
int *p;
|
||||||
|
p = (int *)malloc(n * sizeof(int));
|
||||||
|
|
||||||
|
for (int i=0; i<n; i++) {
|
||||||
|
p[i] = i;
|
||||||
|
printf("%d ", p[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
int n;
|
||||||
|
scanf("%d", &n);
|
||||||
|
|
||||||
|
foo(n);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
运行结果:
|
||||||
|
```text
|
||||||
|
$ ./malloc
|
||||||
|
4
|
||||||
|
0 1 2 3
|
||||||
|
$ ./malloc
|
||||||
|
8
|
||||||
|
0 1 2 3 4 5 6 7
|
||||||
|
$ ./malloc
|
||||||
|
16
|
||||||
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 gdb 查看反汇编代码:
|
||||||
|
```text
|
||||||
|
gdb-peda$ disassemble foo
|
||||||
|
Dump of assembler code for function foo:
|
||||||
|
0x0000066d <+0>: push ebp
|
||||||
|
0x0000066e <+1>: mov ebp,esp
|
||||||
|
0x00000670 <+3>: push ebx
|
||||||
|
0x00000671 <+4>: sub esp,0x14
|
||||||
|
0x00000674 <+7>: call 0x570 <__x86.get_pc_thunk.bx>
|
||||||
|
0x00000679 <+12>: add ebx,0x1987
|
||||||
|
0x0000067f <+18>: mov eax,DWORD PTR [ebp+0x8]
|
||||||
|
0x00000682 <+21>: shl eax,0x2
|
||||||
|
0x00000685 <+24>: sub esp,0xc
|
||||||
|
0x00000688 <+27>: push eax
|
||||||
|
0x00000689 <+28>: call 0x4e0 <malloc@plt>
|
||||||
|
0x0000068e <+33>: add esp,0x10
|
||||||
|
0x00000691 <+36>: mov DWORD PTR [ebp-0xc],eax
|
||||||
|
0x00000694 <+39>: mov DWORD PTR [ebp-0x10],0x0
|
||||||
|
0x0000069b <+46>: jmp 0x6d9 <foo+108>
|
||||||
|
0x0000069d <+48>: mov eax,DWORD PTR [ebp-0x10]
|
||||||
|
0x000006a0 <+51>: lea edx,[eax*4+0x0]
|
||||||
|
0x000006a7 <+58>: mov eax,DWORD PTR [ebp-0xc]
|
||||||
|
0x000006aa <+61>: add edx,eax
|
||||||
|
0x000006ac <+63>: mov eax,DWORD PTR [ebp-0x10]
|
||||||
|
0x000006af <+66>: mov DWORD PTR [edx],eax
|
||||||
|
0x000006b1 <+68>: mov eax,DWORD PTR [ebp-0x10]
|
||||||
|
0x000006b4 <+71>: lea edx,[eax*4+0x0]
|
||||||
|
0x000006bb <+78>: mov eax,DWORD PTR [ebp-0xc]
|
||||||
|
0x000006be <+81>: add eax,edx
|
||||||
|
0x000006c0 <+83>: mov eax,DWORD PTR [eax]
|
||||||
|
0x000006c2 <+85>: sub esp,0x8
|
||||||
|
0x000006c5 <+88>: push eax
|
||||||
|
0x000006c6 <+89>: lea eax,[ebx-0x17e0]
|
||||||
|
0x000006cc <+95>: push eax
|
||||||
|
0x000006cd <+96>: call 0x4b0 <printf@plt>
|
||||||
|
0x000006d2 <+101>: add esp,0x10
|
||||||
|
0x000006d5 <+104>: add DWORD PTR [ebp-0x10],0x1
|
||||||
|
0x000006d9 <+108>: mov eax,DWORD PTR [ebp-0x10]
|
||||||
|
0x000006dc <+111>: cmp eax,DWORD PTR [ebp+0x8]
|
||||||
|
0x000006df <+114>: jl 0x69d <foo+48>
|
||||||
|
0x000006e1 <+116>: sub esp,0xc
|
||||||
|
0x000006e4 <+119>: push 0xa
|
||||||
|
0x000006e6 <+121>: call 0x500 <putchar@plt>
|
||||||
|
0x000006eb <+126>: add esp,0x10
|
||||||
|
0x000006ee <+129>: sub esp,0xc
|
||||||
|
0x000006f1 <+132>: push DWORD PTR [ebp-0xc]
|
||||||
|
0x000006f4 <+135>: call 0x4c0 <free@plt>
|
||||||
|
0x000006f9 <+140>: add esp,0x10
|
||||||
|
0x000006fc <+143>: nop
|
||||||
|
0x000006fd <+144>: mov ebx,DWORD PTR [ebp-0x4]
|
||||||
|
0x00000700 <+147>: leave
|
||||||
|
0x00000701 <+148>: ret
|
||||||
|
End of assembler dump.
|
||||||
|
```
|
||||||
|
关于 glibc 中的 malloc 实现是一个很重要的话题,我们会在后面的章节详细介绍。
|
||||||
|
1
doc/1.5.8_glibc_malloc.md
Normal file
1
doc/1.5.8_glibc_malloc.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# glibc malloc
|
@ -12,5 +12,6 @@
|
|||||||
- [1.5.5 静态链接](1.5.5_static_link.md)
|
- [1.5.5 静态链接](1.5.5_static_link.md)
|
||||||
- [1.5.6 动态链接](1.5.6_dynamic_link.md)
|
- [1.5.6 动态链接](1.5.6_dynamic_link.md)
|
||||||
- [1.5.7 内存管理](1.5.7_memory.md)
|
- [1.5.7 内存管理](1.5.7_memory.md)
|
||||||
|
- [1.5.8 glibc malloc](doc/glibc_malloc.md)
|
||||||
- [1.6 密码学基础](1.6_crypto_basic.md)
|
- [1.6 密码学基础](1.6_crypto_basic.md)
|
||||||
- [1.7 Android 安全基础](1.7_android_basic.md)
|
- [1.7 Android 安全基础](1.7_android_basic.md)
|
||||||
|
1
doc/4.3_gcc.md
Normal file
1
doc/4.3_gcc.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# GCC 安全编译参数
|
@ -2,3 +2,4 @@
|
|||||||
|
|
||||||
- [4.1 AWD模式](4.1_AWD.md)
|
- [4.1 AWD模式](4.1_AWD.md)
|
||||||
- [4.2 Linux 命令行技巧](4.2_Linux_terminal_tips.md)
|
- [4.2 Linux 命令行技巧](4.2_Linux_terminal_tips.md)
|
||||||
|
- [4.3 GCC 安全编译参数](4.3_gcc.md)
|
||||||
|
@ -3,3 +3,4 @@
|
|||||||
- [5.1 Fuzz 测试](5.1_fuzz.md)
|
- [5.1 Fuzz 测试](5.1_fuzz.md)
|
||||||
- [5.2 Pin 动态二进制插桩](5.2_pin.md)
|
- [5.2 Pin 动态二进制插桩](5.2_pin.md)
|
||||||
- [5.3 angr 二进制自动化分析](5.3_angr.md)
|
- [5.3 angr 二进制自动化分析](5.3_angr.md)
|
||||||
|
- [5.4 反调试技术](5.4_antidbg.md)
|
||||||
|
Loading…
Reference in New Issue
Block a user