Linux调试工具之strings

功能

strings命令的作用是查找指定文本文件或者二进制文件中的可打印字符串。默认打印字符串长度大于等于4的字符串。

参数说明

  • -a : 搜索整个文件,而不仅仅是数据段,以寻找可显示的字符串。如果省略这个标志,那么 strings 命令只在对象文件的初始化数据空间内寻找。
  • -n number(-number):指定寻找打印字符串的最小长度,默认最小长度为4,可以通过此参数设置最小长度为1或2等。最长不能超过4096
  • -o : 显示可打印字符串以及可打印字符串在文件中的位置,位置以8进制形式显示。
  • -t format:显示可打印字符串以及可打印字符串在文件中的位置,format可指定显示位置的格式是(o)8,(d)10,(x)16进制。

实例

1
2
3
4
5
6
7
8
#include <stdio.h>
int main() {
char l_data =0;
int a = 0;
a;
return 0;
}
  1. 直接使用stirngs,默认只显示长度大于等于4的可打印字符串

    1
    2
    3
    4
    5
    6
    $ strings main.cpp
    #include <stdio.h>
    int main() {
    char l_data =0;
    int a = 0;
    return 0;
  2. -n参数

    1
    2
    3
    4
    5
    6
    7
    8
    $strings -1 main.cpp
    #include <stdio.h>
    int main() {
    char l_data =0;
    int a = 0;
    a;
    return 0;
    }
  3. -o 参数

前面为其在文件中的8进制位置

1
2
3
4
5
6
$strings -o main.cpp
0 #include <stdio.h>
24 int main() {
41 char l_data =0;
63 int a = 0;
104 return 0;

  1. -t format参数
    -t o参数与-o参数作用一样
1
2
3
4
5
6
$strings -t d main.cpp
0 #include <stdio.h>
20 int main() {
33 char l_data =0;
51 int a = 0;
68 return 0;

用途

当我们将多个文件编译到一个库文件或者可执行文件的时候,我们可以通过strings命令查看新增文件的一些可打印字符串是否在库中,来判断该文件是否已经编译到库中。

Comment and share

Linux调试工具之readelf

readelf命令可以用来查看elf格式文件的信息,与objdump相比,该工具显示的信息较为详细

elf文件

ELF(excutable and linking format)是一种对象文件格式,用于定义不同类型的对象文件中存放了那些东西,以及以什么格式存放。ELF文件可分为三种:

  • 可重定位对象文件(relocatable file)
  • 可执行对象文件(excutable file)
  • 可被共享的对象文件(shared object file)

可重定位对象文件

可重定位对象文件中包含适合于与其他目标文件链接来创建可执行文件或者共享目标文件的代码和数据。一般包括如汇编器汇编生成的.o文件

可执行文件

可执行文件是一个可执行文件,此文件规定了exec()如何创建一个程序的进程映像

可被共享的对象文件

可被共享的对象文件中包含可在两种上下文中链接的代码和数据。首先链接编辑器可将它与其他可重定位文件和目标文件和可共享目标文件一起处理,生成另外一个目标文件,其次,动态链接器可以将它与某个可执行文件以及其他可共享目标一起组合,创建进程映像。

readelf调试工具

readelf参数较多,可直接通过readelf -h获取readelf的所有参数及用法,此处只对其中的几个常用参数以及数据详解。

readelf -h

readelf -h参数的作用是读取指定elf文件的头信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ readelf -h
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400800
Start of program headers: 64 (bytes into file)
Start of section headers: 7344 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 28

重要参数解释:

  • Class : 该elf文件的类型,这里是64位的elf格式
  • Data : 该参数指明了文件中数据的组织方式是大端规则还是小端规则,此处为二进制存储的小端规则
  • OS/ABI : 生成该文件的操作系统类型,ABI(Application Binary Interface)
  • Type : 当前文件的类型,EXEC(可执行文件), REL(可重定位文件),DYN(可被共享文件)
  • Machine : 处理器类型
  • Entry point address : 程序的虚拟地址入口点,可执行文件之外的类型该值为0x0
  • Start of program headers : 程序头的开始处,从程序入口地址偏移地址开始。程序头table中记录elf文件中段的信息
  • Start of section headers : 段头的开始处,从程序入口地址偏移地址开始

readelf -s

readelf的作用是用来查看当前elf文件的符号表,符号表中的信息只包括全局变量和函数名
动态符号表(.synsym)用来保存与动态链接相关的导入导出符号,不包括模块内的符号;而sy,tab表则保存所有的符号,包括.dynsym中的符号。
动态符号表所包含的符号的符号名保存在动态符号字符串表.dynstr中。

如下所示程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
//main.c
int g_data;
static int gs_data;
void hello() {
printf("hello world");
}
int main() {
static int a = 0;
char l_data =0;
hello();
return 0;
}

将上述文件编译汇编成目标文件main.o文件,使用readelf -s main.o,结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Symbol table '.symtab' contains 15 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.cpp
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000004 4 OBJECT LOCAL DEFAULT 4 _ZL7gs_data
6: 0000000000000000 0 SECTION LOCAL DEFAULT 5
7: 0000000000000008 4 OBJECT LOCAL DEFAULT 4 _ZZ4mainE7ls_data
8: 0000000000000000 0 SECTION LOCAL DEFAULT 7
9: 0000000000000000 0 SECTION LOCAL DEFAULT 8
10: 0000000000000000 0 SECTION LOCAL DEFAULT 6
11: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 g_data
12: 0000000000000000 22 FUNC GLOBAL DEFAULT 1 _Z5hellov
13: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
14: 0000000000000016 24 FUNC GLOBAL DEFAULT 1 main

可以看出全局变量,静态全局变量,静态局部变量,全局函数名都会出现在符号表中,而局部变量不会被保存在符号表中。

Comment and share

  • page 1 of 1

魏传柳(2824759538@qq.com)

author.bio


Tencent


ShenZhen,China