Linux中使用nm和grep技巧 (linux nm grep)
Linux是许多程序员喜欢使用的操作系统之一,因为它提供了许多强大的工具来帮助程序员进行工作。其中两个在调试和分析二进制文件时非常有用的工具是nm和grep。本文将介绍如何在Linux中使用这两个工具。
一、什么是nm
nm是Linux上查看目标文件或可执行文件中符号表的命令。符号表是一个列表,其中包含所有全局变量、函数、类、结构体和其他代码实体的名称和地址。nm命令提供了各种选项,以过滤输出并仅显示您感兴趣的符号。以下是一些常见的选项:
1. -A:显示所有符号,包括本地符号。
2. -g:仅显示全局符号。
3. -D:仅显示动态符号。
4. -t :指定输出格式。可用格式包括sysv、bsd、posix和darwin。
nm命令的输出格式可能有所不同,取决于您使用的选项和文件类型。无论如何,您将会看到一个列表,其中包含所选文件中涉及的所有全局符号。该列表通常按字母顺序排列,并包含每个符号的类型和地址。
为了更好地理解nm的输出及其含义,我们来尝试一下:
在Linux终端中,我们创建了一个新的C文件,以及一个名为“test”的可执行文件。该C文件包含了一个简单的打印语句和一个全局整数变量:
“`
#include
int global_int = 32;
void print_message() {
printf(“Hello, World!\n”);
}
int mn() {
print_message();
printf(“The value of global_int is %d.\n”, global_int);
return 0;
}
“`
要查看“test”可执行文件中的符号表,您可以使用以下命令:`nm test`。输出的结果如下:
“`
0000000000004010 T mn
0000000000004027 T print_message
0000000000601028 D global_int
0000000000400b20 r __FRAME_END__
0000000000601028 B __bss_start
0000000000601028 b completed.6527
0000000000601018 b dtor_idx.6529
0000000000400900 t deregister_tm_clones
0000000000400990 t register_tm_clones
00000000004009d0 t __do_global_dtors_aux
0000000000600e48 t frame_dummy
0000000000601000 t __do_global_ctors_aux
00000000004008c0 t _init
0000000000400b30 R _IO_stdin_used
“`
您可以看到有三个符号被列出:`mn`、`print_message`和`global_int`。其中,`mn`和`print_message`是C文件中定义的函数的名称,`global_int`是C文件中定义的全局变量的名称。如果您仔细看,您可能会注意到“global_int”前面有一个“D”字母,表示这是一个定义符号(也称为数据符号),而“mn”和“print_message”前面有一个“T”字母,表示这是一个文本符号(也称为代码符号)。
二、什么是grep
grep是一种Linux命令,用于在文件中查找字符串匹配项。grep非常灵活,可以使用各种选项以不同的方式搜索匹配项。以下是一些常见的选项:
1. -i:不区分大小写地搜索。
2. -n:显示行号。
3. -r:在目录及其子目录中递归搜索。
4. -v:仅显示未匹配的行。
5. -w:仅匹配完全匹配的单词。
grep命令可以与其他命令一起使用,以便将输出重定向到另一个文件或进一步处理。grep也可以使用正则表达式,以便更精细地匹配需要搜索的文本。以下是一些常见的正则表达式符号:
1. ^:表示以什么开头。
2. $:表示以什么结尾。
3. +:表示出现一次或多次。
4. *:表示出现任意次。
5. [ ]:表示范围。
为了更好地理解grep和它的使用,我们来演示一下:
我们将使用grep和nm命令一起查找特定符号名称。在上面的例子中,我们已经知道了三个符号的名称:“mn”、“print_message”和“global_int”。但是在实际开发过程中,通常会遇到更复杂的符号名称。例如,想象一下您正在尝试解决一个系统崩溃问题,并且需要找到涉及特定函数名的所有可执行文件。在这种情况下,grep可以派上用场。
要查找所有可执行文件中包含特定函数名的文件,您可以使用以下命令:
“`
find / -type f -perm +111 -exec nm {} \; | grep -w ‘print_message’
“`
该命令将运行一个Linux命令`find`,该命令将在文件系统中查找所有具有可执行权限(即`-perm +111`)的文件。然后它将此文件列表重定向到nm命令中,该命令将为每个文件生成符号表输出。grep命令将搜索nm输出以查找包含单词“print_message”的行。
该命令的输出将是一组在含有函数“print_message”可执行文件中找到的行,格式类似于这种:
“`
/path/to/executable:0000000000004027 T print_message
“`
这个输出告诉我们,函数打印语句“Hello, World!”的代码位于“/path/to/executable”可执行文件中的地址4027处。
三、结论