我正在尝试破解/理解 nullfs 内核模块(在 FreeBSD 上),为此,我执行以下操作:
在目标机器上:
kldstat
给出:
Id Refs Address Size Name
1 10 0xffffffff80200000 17e10c8 kernel
2 1 0xffffffff819e2000 4cf0 vmxnet.ko
3 1 0xffffffff819e7000 16e0 echo.ko
4 1 0xffffffff81c11000 23dc vmmemctl.ko
5 1 0xffffffff81c14000 641b nullfs.ko
nm /boot/kernel/nullfs.ko | grep mount
00000000000018f0 t null_getwritemount
0000000000000540 t nullfs_mount
0000000000000930 t nullfs_unmount
U vfs_mountedfrom
U vop_getwritemount_desc
在通过充当串行控制台的命名管道连接到目标的本地计算机上(我正在使用虚拟机):
(kgdb) tr0
kdb_sysctl_enter (oidp=<value optimized out>, arg1=<value optimized out>,
arg2=0xfffffe004e7cc7f0,
req=<value optimized out>) at /usr/src/sys/kern/subr_kdb.c:446
446 kdb_why = KDB_WHY_UNSET;
Current language: auto; currently minimal
(kgdb) getsyms
During symbol reading, Incomplete CFI data; unspecified registers at
0xffffffff8099497a.
Id Refs Address Size Name
1 10 0x80200000 17e10c8 kernel
2 1 0x819e2000 4cf0 vmxnet.ko
3 1 0x819e7000 16e0 echo.ko
4 1 0x81c11000 23dc vmmemctl.ko
5 1 0x81c14000 641b nullfs.ko
Select the list above with the mouse, paste into the screen
and then press ^D. Yes, this is annoying.
5 1 0x81c14000 641b nullfs.ko
add symbol table from file
"/usr/obj/usr/src/sys/AIJAZ-DEBUG/modules/usr/src/sys/modules/nullfs/nullfs.ko.debug"
at
.text_addr = 0x81c14000
.data_addr = 0x81c14000
.bss_addr = 0x81c14000
(kgdb) add-kld nullfs.ko
add symbol table from file "/boot/kernel/nullfs.ko.symbols" at
.text_addr = 0xffffffff81c14000
set_sysinit_set_addr = 0xffffffff81c15c90
set_sysuninit_set_addr = 0xffffffff81c15cb0
.rodata.str1.1_addr = 0xffffffff81c15cc8
set_modmetadata_set_addr = 0xffffffff81c15e48
set_sysctl_set_addr = 0xffffffff81c15e58
.data_addr = 0xffffffff81c15e60
.bss_addr = 0xffffffff81c16360
(y or n) y
Reading symbols from /boot/kernel/nullfs.ko.symbols...
location expression too complex...done.
(kgdb) b nullfs_mount
Cannot access memory at address 0x81c14540
从上面的“nm”和“kldstat”的输出可以看出,地址确实是正确的。
我什至尝试在上述地址设置“硬件断点”:
(kgdb) hbreak *0x81c14540
Hardware assisted breakpoint 1 at 0x81c14540: file
/usr/src/sys/modules/nullfs/../../fs/nullfs/null_vfsops.c, line 74.
(kgdb) c
Continuing.
Warning:
Cannot insert breakpoint 1.
Error accessing memory address 0x81c14540: Input/output error.
然而,这一次虽然断点已注册,但它永远不会被插入。在 Linux 上搜索此错误时,似乎可以通过关闭 CONFIG_DEBUG_RODATA 作为内核配置的一部分来解决此问题(根据此链接,这似乎是某种保护机制,可检测内核的文本部分何时由于某种原因被覆盖)。这有助于设置否则不会设置的软件断点。我不知道这是否也是这里的原因。
其次,我想知道虽然目标上的实际地址在上面0xffffffff00000000
,但调试器只报告低 8 位。是因为它被理解/假设了吗?
渴望听到你们的消息