0
点赞
收藏
分享

微信扫一扫

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法


前言 

这个问题是 衍生自 malloc 的问题的调试 

malloc 虚拟内存分配的调试(1)

malloc 虚拟内存分配的调试(2)

假设我们使用 gdb 或者 gdbserver 启动调试的该测试用例对应的可执行程序  

我们可以观察到的现象是 p1, p2, p3 的地址是固定的, 均是类似于 elf 中最大的虚拟地址 直接向上扩展 

(gdb) run
Starting program: /root/ClionWorkStations/HelloWorld/Test01Sum 
p1 : 0x602010 - 0x602030 
p1 : 0x602010 - 0x602030 
p3 : 0x602440 - 0x602440 
[Inferior 1 (process 63076) exited normally]
(gdb) run
Starting program: /root/ClionWorkStations/HelloWorld/Test01Sum 
p1 : 0x602010 - 0x602030 
p1 : 0x602010 - 0x602030 
p3 : 0x602440 - 0x602440 
[Inferior 1 (process 63080) exited normally]
(gdb) run
Starting program: /root/ClionWorkStations/HelloWorld/Test01Sum 
p1 : 0x602010 - 0x602030 
p1 : 0x602010 - 0x602030 
p3 : 0x602440 - 0x602440 
[Inferior 1 (process 63081) exited normally]
(gdb) run
Starting program: /root/ClionWorkStations/HelloWorld/Test01Sum 
p1 : 0x602010 - 0x602030 
p1 : 0x602010 - 0x602030 
p3 : 0x602440 - 0x602440 
[Inferior 1 (process 63082) exited normally]

但是 假设我们直接执行, 我们会发现 地址是在不断变化的, 呵呵 

这个就和 brk 的相关初始化机制存在关联了 

root@ubuntu:~/ClionWorkStations/HelloWorld# ./Test01Sum 
p1 : 0xc56010 - 0xc56030 
p1 : 0xc56010 - 0xc56030 
p3 : 0xc56440 - 0xc56440 
root@ubuntu:~/ClionWorkStations/HelloWorld# ./Test01Sum 
p1 : 0x67d010 - 0x67d030 
p1 : 0x67d010 - 0x67d030 
p3 : 0x67d440 - 0x67d440 
root@ubuntu:~/ClionWorkStations/HelloWorld# ./Test01Sum 
p1 : 0x7ec010 - 0x7ec030 
p1 : 0x7ec010 - 0x7ec030 
p3 : 0x7ec440 - 0x7ec440 
root@ubuntu:~/ClionWorkStations/HelloWorld# ./Test01Sum 
p1 : 0x1af9010 - 0x1af9030 
p1 : 0x1af9010 - 0x1af9030 
p3 : 0x1af9440 - 0x1af9440

brk 的随机初始化 

我们这里 先来看 brk 的随机初始化相关, 因为 这个比较好构造 

brk 的初始化有几个地方, 加载 elf program headers 的地方 

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_glibc

elf 中各个 program headers 加载完成之后, 会有 start_brk, start_code, end_code, start_data, end_data 

之后会有一个 brk 的初始化, 初始化为 elf 中记录的最大的虚拟地址 按照分页上对齐之后的地址 

这个就是 我们 gdb 调试的时候, 看到的初始化的 brk, 我们演示的程序中经常为 0x602000 

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_glibc_02

然后 最后一个是 elf 加载过程中 有一个 brk 随机初始化的流程, 如下 

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_brk_03

brk 的随机初始化具体的处理如下 

也就是在 初始化的 brk 之后的 [0 - 8192) 页, 每一页大小为 4k 

为什么是 8192?, 这是上面 arch_randomize_brk 传入的 range 为 0x2000000, 然后这里 range >>= PAGE_SHIFT 之后, range 为 8192 

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_linux_04

我们这次执行, 初始化的 brk 为 0x130d000 

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_mm_05

然后 测试用例 中 printf 调用 malloc 的时候会调用 brk 来分配空间 

看这里的 addr 即为 brk 初始化之后的值, 可以看一下 和上面 加载 elf 之后随机初始化的 地址是一致的, 均为 0x130d000 

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_mm_06

再来一次, 初始化的 brk 为 0x762000 

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_linux_07

printf 调用 malloc 分配空间的时候 brk 也是 0x762000  

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_glibc_08

gdb 或者 gdbserver 启动调试的 brk 初始化

 brk 在 加载 elf 的 program headers 完成之后的初始化 

elf 中映射的虚拟地址的末尾是 6295616 = 0x601040, ALIGN_UP(0x601040, PAGE_SIZE) 根据分页上对齐之后将 brk 初始化为 0x602000 

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_linux_09

 brk 初始化为 6299648 = 0x602000 

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_brk_10

为什么 gdb/gdbserver 未对 brk 进行随机初始化? 

有可能是没有进这个判断, 或者 有什么因素 影响到了 arch_randomize_brk 的计算??

21 brk 的初始化malloc 虚拟内存分配的调试(1)malloc 虚拟内存分配的调试(2)这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法_glibc_11

这个是因为 alsr 机制 Linux下关闭ASLR(地址空间随机化)的方法

在启动 gdb 的时候, 默认 禁用aslr, 将这个配置置为 false, 即可以启动 aslr 

然后 这里相关, 影响到的应该是这个 random_va_

(gdb) set disable-randomization off
(gdb) show disable-randomization off
Disabling randomization of debuggee's virtual address space is off.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/ClionWorkStations/HelloWorld/Test01Sum 

Breakpoint 1, main (argc=1, argv=0x7ffc8c89b608) at Test01Sum.c:9
9	char *p1 = (char *)malloc(20);
(gdb) c
Continuing.
p1 : 0x19bf010 - 0x19bf030 
p1 : 0x19bf010 - 0x19bf030 
p3 : 0x19bf440 - 0x19bf440 
[Inferior 1 (process 63432) exited normally]
(gdb) delete 1
(gdb) run
Starting program: /root/ClionWorkStations/HelloWorld/Test01Sum 
p1 : 0x23d2010 - 0x23d2030 
p1 : 0x23d2010 - 0x23d2030 
p3 : 0x23d2440 - 0x23d2440 
[Inferior 1 (process 63433) exited normally]
(gdb) run
Starting program: /root/ClionWorkStations/HelloWorld/Test01Sum 
p1 : 0x1c93010 - 0x1c93030 
p1 : 0x1c93010 - 0x1c93030 
p3 : 0x1c93440 - 0x1c93440 
[Inferior 1 (process 63434) exited normally]

linux 系统上面关闭 ASLR  

echo 0 > /proc/sys/kernel/randomize_va_space

彩蛋[2022.11.06]

呵呵 为了测试 aslr, 妈的 安装 pwn 把虚拟机搞挂了

又要重新 安装环境啥的了, 悲剧 

参考

Linux下关闭ASLR(地址空间随机化)的方法


 

举报

相关推荐

0 条评论