objdump命令
在Linux中,可以使用objdump命令来反汇编ko文件并查看其中的宏定义值。
以下是怎样使用objdump命令查看ko文件中的宏定义值的示例:
objdump -d | grep ''
其中,-d参数表示反汇编目标文件,grep命令用于查找特定的宏定义。
比如,假若您想查看ko文件中MODULE_LICENSE宏的定义值,可以使用以下命令:
objdump -d hello.ko | grep ''
这将输出类似以下内容的结果:
ffffffffa0000f3c :
ffffffffa0000f52: 48 8b 15 a5 11 00 00 mov 0x11a5(%rip),%rdx # ffffffff815e1f00
ffffffffa0000f59: 48 8b 0d 9a 11 00 00 mov 0x119a(%rip),%rcx # ffffffff815e1f00
ffffffffa0000f60: 48 8b 05 95 11 00 00 mov 0x1195(%rip),%rax # ffffffff815e1f00
ffffffffa0000f67: 48 8b 35 90 11 00 00 mov 0x1190(%rip),%rsi # ffffffff815e1f00
ffffffffa0000f6e: 48 8b 2d 8b 11 00 00 mov 0x118b(%rip),%rbp # ffffffff815e1f00
ffffffffa0000f75: 48 8d 15 84 11 00 00 lea 0x1184(%rip),%rdx # ffffffff815e1f00
ffffffffa0000f7c: 48 8d 0d 7d 11 00 00 lea 0x117d(%rip),%rcx # ffffffff815e1f00
ffffffffa0000f83: 48 8d 05 76 11 00 00 lea 0x1176(%rip),%rax # ffffffff815e1f00
ffffffffa0000f8a: 48 8d 35 71 11 00 00 lea 0x1171(%rip),%rsi # ffffffff815e1f00
ffffffffa0000f91: 48 8d 2d 6c 11 00 00 lea 0x116c(%rip),%rbp # ffffffff815e1f00
ffffffffa0000f98: 48 81 ec b8 00 00 00 sub $0xb8,%rsp
ffffffffa0000f9f: 48 8b 05 1e 11 00 00 mov 0x111e(%rip),%rax # ffffffff815e1f00
...
nm命令
在这个示例中,可以看见MODULE_LICENSE宏定义值在ffffffff815815ee11ff0000地址中,可以按照须要进一步查看这个地址的内容。
在Linux系统中,可以使用nm命令查看目标文件或共享库中的符号表信息。nm命令可以列举目标文件或共享库中定义的符号名以及每位符号名对应的地址、类型和其他属性。
下边是使用nm命令查看ko文件中符号表信息的示例:
nm -g
其中,-g参数表示只显示全局符号表,即在模块中定义而且可以被其他模块引用的符号。
比如,假定我们有一个名为hello.ko的内核模块文件,可以使用以下命令查看hello.ko文件中的符号表信息:
nm -g hello.ko
这将列举hello.ko文件中定义的所有全局符号及其地址,比如:
0000000000000000 T hello_init
0000000000000010 T hello_exit
其中,T表示符号类型为Text段,即代码段。hello_init和hello_exit是在hello.ko模块中定义的函数名。
须要注意的是,nm命令只能查看已编译的目标文件或共享库中的符号表信息,不能查看源代码中的符号定义。倘若您须要查看源代码中的符号定义linux 搜索文件内容,可以使用grep等工具进行搜索。
U一般是指在Linux符号表中的一种符号类型,表示未定义的符号(UndefinedSymbol)。在程序编译时,假如某个函数或变量在当前模块中没有定义,但在其他模块中有定义,编译器都会在符号表中为该符号创建一个U类型的符号表项,表示该符号未定义。
比如,假定我们有两个模块A和B,模块A中定义了一个函数foo(),而模块B中调用了函数foo()。在编译模块B时,编译器会在符号表中为函数foo()创建一个U类型的符号表项,表示该符号在当前模块中未定义,但在其他模块中有定义。
在链接时,编译器会将所有模块中的符号进行解析和链接,将所有未定义的符号与其他模块中的定义进行匹配,最终生成可执行文件或共享库。
为此linux端口映射,假如在使用nm命令查看符号表时linux 搜索文件内容,发觉某个符号的类型为U,就表示该符号未在当前模块中定义。
readelf
readelf是一个用于查看ELF文件信息的命令行工具,-p参数表示显示特定段的内容,.mand.line是一个特定的段名,用于储存编译器命令行参数。
因而,readelf-p.mand.lineaa.ko命令的含意是显示aa.ko文件中.mand.line段的内容,即编译器执行时使用的命令行参数。
在Linux内核中,.mand.line段一般用于储存内核模块的编译参数,比如编译器版本、编译选项等。通过查看该段的内容,可以了解内核模块的编译信息,比如是否开启了调试信息、是否启用了个别特定的编译选项等。
不仅查看.mand.line段的内容之外linux命令手册,readelf命令还可以用于查看ELF文件的其他信息,包括:
通过readelf命令,可以深入了解ELF文件的结构和内容,以及了解内核模块的编译信息、符号表信息等。比如,以下是一些常用的readelf命令示例:
须要注意的是,readelf命令须要安装binutils工具包能够使用,可以通过以下命令安装:
sudo apt-get install binutils