1
2i2Re2PLMaDnghL 2022-01-25 12:58:06 +08:00 1
首先物理地址应该是只有内核态下才能知道,每次冷启动都会导致内存随机化分布,内核的代码实际存在的位置是随机的,缓解缓冲区溢出覆盖代码区导致的影响(攻击者无法知道溢出之后覆盖到哪个函数那儿去)
|
2
kgdb00 OP @2i2Re2PLMaDnghL 感谢回复
https://www.kernel.org/doc/html/latest/x86/boot.html 这个文档讲物理地址 0x100000 以上是 Protected-mode kernel ,意思应是内核代码的物理地址在从 2MB 开始的区域,我猜测内核函数的物理地址随机化之后应该也是在靠近 2MB 的位置,不太可能是整个物理内存完全随机,因为那样的话就不好分配一个很大的物理地址连续的页框,不知道我猜的对不对。 |
4
yanqiyu 2022-01-26 07:49:43 +08:00 via Android 1
system.map 里面是没开 kaslr 的情况下内核被装载到的虚拟地址,开了之后会变,要用 root 去 /proc/kallsyms 下面读
至于物理地址,应该可以去 /proc/iomem 拿到 kernel 的基地址,再根据 system.map 算偏移就行 至于内核物理地址的随机化确实不是到处随机,而是在前 512M?记不清了?因为随机化内核还要避开一堆不能用的内存于是整个过程干的事情很杂乱 |
5
yanqiyu 2022-01-26 08:06:08 +08:00 via Android 1
@yanqiyu 重新看了下,是我记错了,基本上是完全随机的,避开一些不能用的内存,拿到一些 slots ,然后在这些 slots 里面随机选择,并加上一个偏移
那个 512M 是这些随机范围的下区间的最大值,实际上用不到,除非 hack 了 config https://github.com/torvalds/linux/blob/master/arch/x86/boot/compressed/kaslr.c |
6
kgdb00 OP @yanqiyu 感谢回复
我试了一下,关闭 kaslr 后通过查看 /proc/iomem 发现内核代码的起始地址固定是在物理内存 16MB ( qemu )或 32MB (物理机),不明白为什么不是在 2MB 。 |
8
yanqiyu 2022-01-26 20:11:16 +08:00 via Android
@kgdb00 因为现在内核是压缩过的,bootloader 加载到 2mb 位置的东西也是一个 loader 负责初始化和解压真正的内核
|
9
kgdb00 OP @yanqiyu 为什么这么认为?
https://www.kernel.org/doc/html/latest/x86/boot.html 这篇文档讲的就是 bzImage 的 kernel 的 Protected-mode kernel 地址是从 0x100000 开始的。 而且《 Understanding the LINUX KERNEL 》这本书的附录 1 的“Booting Linux from a Disk”节也这样讲: Invokes a BIOS procedure to load the rest of the kernel image from disk and puts the image in RAM starting from either low address 0x00010000 (for small kernel images compiled with make zImage) or high address 0x00100000 (for big kernel images compiled with make bzImage). |
10
kgdb00 OP @yanqiyu 更正一下我的描述,我说的 2MB 都是指从第二个 MB 开始的地址,也就是从 0x100000 开始的地址。
|
11
yanqiyu 2022-01-26 21:56:39 +08:00
@kgdb00 看样子我记错了,解压出来的 image 确实是在 0x1000000 的位置的,我把这个地址和实模式部分记混了,要不看看你的内核的 CONFIG_PHYSICAL_START 参数是?
|
12
kgdb00 OP @yanqiyu 我用的是 fedora35 默认的内核,CONFIG_PHYSICAL_ALIGN 和 CONFIG_PHYSICAL_START 都是 0x1000000 ,0x1000000 是第 17 个 MB 开始的地方,和《 Understanding the LINUX KERNEL 》这本书描述的不一样,我发现 2.6.23 版本的 linux 的 arch/i386/defconfig 这个文件确实定义了 CONFIG_PHYSICAL_START=0x100000 ,应该是后面的版本将这个值改大了。
另外我发现我的物理机的 kernel 的起始地址是 0x2000000 是因为使用 uefi 启动导致的,不知道为什么 uefi 启动会让内核的启起始地址从 0x1000000 变成 0x2000000 。 |