Linux 内核编译生成的 System.map 文件的内容到底是什么意思? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
kgdb00
V2EX    Linux

Linux 内核编译生成的 System.map 文件的内容到底是什么意思?

  •  
  •   kgdb00 2022-01-25 11:44:09 +08:00 2719 次点击
    这是一个创建于 1436 天前的主题,其中的信息可能已经有所发展或是发生改变。
    这个文件记录的函数地址不可能是物理地址,因为数值非常大,比如这一行:

    [root@develop linux]# grep kvm_guest_init System.map
    ffffffff81afa999 t kvm_guest_init

    我在这个函数的入口打印它的地址和 System.map 记录的是一样的。

    这个地址是分页前的线性地址吗?如果是的话,那我怎么知道这个函数实际运行过程中的物理地址?
    12 条回复    2022-01-26 23:15:04 +08:00
    2i2Re2PLMaDnghL
        1
    2i2Re2PLMaDnghL  
       2022-01-25 12:58:06 +08:00   1
    首先物理地址应该是只有内核态下才能知道,每次冷启动都会导致内存随机化分布,内核的代码实际存在的位置是随机的,缓解缓冲区溢出覆盖代码区导致的影响(攻击者无法知道溢出之后覆盖到哪个函数那儿去)
    kgdb00
        2
    kgdb00  
    OP
       2022-01-25 13:12:25 +08:00
    @2i2Re2PLMaDnghL 感谢回复
    https://www.kernel.org/doc/html/latest/x86/boot.html 这个文档讲物理地址 0x100000 以上是 Protected-mode kernel ,意思应是内核代码的物理地址在从 2MB 开始的区域,我猜测内核函数的物理地址随机化之后应该也是在靠近 2MB 的位置,不太可能是整个物理内存完全随机,因为那样的话就不好分配一个很大的物理地址连续的页框,不知道我猜的对不对。
    kgdb00
        3
    kgdb00  
    OP
       2022-01-25 13:14:45 +08:00
    @kgdb00 #2 更正:一个页框 -> 一组页框
    yanqiyu
        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?记不清了?因为随机化内核还要避开一堆不能用的内存于是整个过程干的事情很杂乱
    yanqiyu
        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
    kgdb00
        6
    kgdb00  
    OP
       2022-01-26 16:12:25 +08:00
    @yanqiyu 感谢回复
    我试了一下,关闭 kaslr 后通过查看 /proc/iomem 发现内核代码的起始地址固定是在物理内存 16MB ( qemu )或 32MB (物理机),不明白为什么不是在 2MB 。
    kgdb00
        7
    kgdb00  
    OP
       2022-01-26 17:05:30 +08:00
    @yanqiyu 顺便问一下,怎么知道内核的 stack 是在物理内存和虚拟内存的哪个位置?
    yanqiyu
        8
    yanqiyu  
       2022-01-26 20:11:16 +08:00 via Android
    @kgdb00 因为现在内核是压缩过的,bootloader 加载到 2mb 位置的东西也是一个 loader 负责初始化和解压真正的内核
    kgdb00
        9
    kgdb00  
    OP
       2022-01-26 20:44:28 +08:00
    @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).
    kgdb00
        10
    kgdb00  
    OP
       2022-01-26 21:23:27 +08:00
    @yanqiyu 更正一下我的描述,我说的 2MB 都是指从第二个 MB 开始的地址,也就是从 0x100000 开始的地址。
    yanqiyu
        11
    yanqiyu  
       2022-01-26 21:56:39 +08:00
    @kgdb00 看样子我记错了,解压出来的 image 确实是在 0x1000000 的位置的,我把这个地址和实模式部分记混了,要不看看你的内核的 CONFIG_PHYSICAL_START 参数是?
    kgdb00
        12
    kgdb00  
    OP
       2022-01-26 23:15:04 +08:00
    @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 。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4748 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 51ms UTC 09:03 PVG 17:03 LAX 01:03 JFK 04:03
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86