objdump 命令是 GNU Binutils 二进制工具集的一员,用于查看目标文件或可执行文件的组成信息,以可读的形式打印二进制文件的内容。

objdump [options] obj_file #[]表示可选,obj_file表示目标文件

常用

objdump -T libc.so.6 |grep system

objdump参数

-a, --archive-headers
显示档案头信息,展示档案每一个成员的文件格式。效果等同于命令 ar -tv
-b, --target=BFDNAME
指定目标码格式。这不是必须的,objdump 能自动识别许多格式,比如 objdump -b oasys -m vax -h fu.o 显示 fu.o 的头部摘要信息,明确指出该文件是 Vax 系统下用 Oasys 编译器生成的目标文件。objdump -i 将给出这里可以指定的目标码格式列表
-C, --demangle[=STYLE]
目标文件中的符号解码成用户级名称。比如移除符号修饰时在变量与函数名前添加的下划线等。
-d, --disassemble
反汇编目标文件,将机器指令反汇编成汇编代码
-D, --disassemble-all
与 -d 类似,但反汇编所有段(section)
-z, --disassemble-zeroes
一般反汇编输出将省略零块,该选项使得这些零块也被反汇编
-EB, -EL,--endian={big | little}
指定目标文件的字节序,在目标文件没描述字节序时很有用,例如 S-records。这个选项只影响反汇编
-f, --file-headers
显示每一个目标文件的头信息
-F, --file-offsets
反汇编时,打印每一个符号的偏移地址
--file-start-context
显示源码/汇编代码(假设为 -S)时,将上下文扩展到文件的开头
-g, --debugging
显示调试信息。企图解析保存在文件中的调试信息并以 C 语言的语法显示出来。仅仅支持某些类型的调试信息。有些其他的格式被readelf -w支持
-e, --debugging-tags
类似 -g 选项,但是生成的信息是和ctags工具相兼容的格式
-h, --section-headers, --headers
显示目标文件各个 section 的头部摘要信息
-i, --info
显示对于 -b 或者 -m 选项可用的架构和目标格式列表
-j, --section=NAME
仅显示指定名称的 section 的信息
-l, --line-numbers
用文件名和行号标注相应的目标代码,仅仅和 -d、-D 或者 -r 一起使用
-S,--source
反汇编时尽可能使用源代码表示。隐含了-d参数
-m, --architecture=MACHINE
指定反汇编目标文件时使用的架构,当待反汇编文件本身没描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构
-M, --disassembler-options=OPTIONS
给反汇编程序传递参数,可以指定多个,使用逗号分隔
-p, --private-headers
打印目标文件格式的特定信息。打印的信息取决于目标文件格式,对于某些目标文件格式,不打印任何附加信息。
-P, --private=OPTIONS
打印目标文件格式的特定信息。OPTIONS 是一个逗号分隔的列表。例如对于XCOFF,可用的选项有 header, aout, sections, syms, relocs, lineno, loader, except, typchk, traceback and toc
-r, --reloc
显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来
-R, --dynamic-reloc
显示文件的动态重定位入口,仅仅对于动态目标文件意义,比如某些共享库
-s, --full-contents
显示section的完整内容。默认所有的非空section都会被显示
-W[lLiaprmfFsoRt],--dwarf=[rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]
显示文件中调试段的内容,如果存在的话
-G, --stabs
显示请求的任何 section 的全部内容。显示段 .stab、.stab.index 和 .stab.excl 的内容
-t, --syms
显示文件的符号表入口。类似于nm -s提供的信息
-T, --dynamic-syms
显示文件的动态符号表入口,仅仅对动态目标文件意义,比如某些共享库。它显示的信息类似于 nm -D,--dynamic 显示的信息
-x, --all-headers
显示所可用的头信息,包括符号表、重定位入口。-x 等价于 -a -f -h -p -r -t 同时指定
-w, --wide
为具有超过80列的输出设备格式化某些行。也不要在显示符号名称时截断符号名称
--start-address=ADDRESS
从指定地址开始显示数据,该选项影响 -d、-r 和 -s 选项的输出
--stop-address=ADDRESS
显示数据直到指定地址为止,该项影响-d、-r和-s选项的输出
--prefix-addresses
反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式
--no-show-raw-insn
反汇编时,不显示汇编指令的机器码。当使用--prefix-addresses时,这是缺省选项
--adjust-vma=OFFSET
当解析信息时,首先给所有的段添加偏移值offset。当段地址与符号表不符时,这个选项很有用。比如将段放置到特殊地址,因为某个格式无法表示段地址,比如 a.out
--special-syms
显示特殊符号与用户不关心的符号
--prefix=PREFIX
当使用 -S 时,指定前缀添加到绝对路径中
--prefix-strip=LEVEL
指定剥离绝对路径中多少个前缀目录名。此选项只有在使用了选项 --prefix=PREFIX 才有效
--insn-width=WIDTH
指定反汇编后的指令输出的行宽,单位字节
-V, --version
版本信息
-H, --help
帮助信息

操作

1.查看C程序的汇编代码和源代码

gcc -g test.c -o test
#include <stdio.h>

int add(int a, int b)
{
return a+b;
}
int sub(int a, int b)
{
return a-b;
}

int main()
{
int a = 88;
int b = 66;

int sum = add(a, b);
printf("a=%d, b=%d, a+b=%d\n", a, b, sum);

int dif = sub(a, b);
printf("a=%d, b=%d, a-b=%d\n", a, b, dif);
}
objdump -D test | less #objdump -D命令来查看test的汇编代码。
objdump -S test | less #objdump -S命令来以汇编和源代码的形式查看test的代码。

2.查看可执行文件中函数调用的地址

可以使用以下命令来查看可执行文件中的函数调用地址:

objdump -d -j .plt test

3.查看共享库中函数的地址

可以使用以下命令来查看共享库中函数的地址:

objdump -T /lib/libc.so.6

4.查看可执行文件中的符号表

objdump -t test

可以在符号表中找到sub,add的地址

#objdump -t test

test: file format elf64-x86-64

SYMBOL TABLE:
0000000000400238 l d .interp 0000000000000000 .interp
0000000000400254 l d .note.ABI-tag 0000000000000000 .note.ABI-tag
0000000000400274 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id
0000000000400298 l d .gnu.hash 0000000000000000 .gnu.hash
00000000004002b8 l d .dynsym 0000000000000000 .dynsym
0000000000400318 l d .dynstr 0000000000000000 .dynstr
0000000000400358 l d .gnu.version 0000000000000000 .gnu.version
0000000000400360 l d .gnu.version_r 0000000000000000 .gnu.version_r
0000000000400380 l d .rela.dyn 0000000000000000 .rela.dyn
0000000000400398 l d .rela.plt 0000000000000000 .rela.plt
00000000004003c8 l d .init 0000000000000000 .init
00000000004003f0 l d .plt 0000000000000000 .plt
0000000000400420 l d .plt.got 0000000000000000 .plt.got
0000000000400430 l d .text 0000000000000000 .text
0000000000400634 l d .fini 0000000000000000 .fini
0000000000400640 l d .rodata 0000000000000000 .rodata
0000000000400678 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr
00000000004006c0 l d .eh_frame 0000000000000000 .eh_frame
0000000000600e10 l d .init_array 0000000000000000 .init_array
0000000000600e18 l d .fini_array 0000000000000000 .fini_array
0000000000600e20 l d .jcr 0000000000000000 .jcr
0000000000600e28 l d .dynamic 0000000000000000 .dynamic
0000000000600ff8 l d .got 0000000000000000 .got
0000000000601000 l d .got.plt 0000000000000000 .got.plt
0000000000601028 l d .data 0000000000000000 .data
000000000060102c l d .bss 0000000000000000 .bss
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000600e20 l O .jcr 0000000000000000 __JCR_LIST__
0000000000400460 l F .text 0000000000000000 deregister_tm_clones
0000000000400490 l F .text 0000000000000000 register_tm_clones
00000000004004d0 l F .text 0000000000000000 __do_global_dtors_aux
000000000060102c l O .bss 0000000000000001 completed.6355
0000000000600e18 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry
00000000004004f0 l F .text 0000000000000000 frame_dummy
0000000000600e10 l O .init_array 0000000000000000 __frame_dummy_init_array_entry
0000000000000000 l df *ABS* 0000000000000000 test.c
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
00000000004007f0 l O .eh_frame 0000000000000000 __FRAME_END__
0000000000600e20 l O .jcr 0000000000000000 __JCR_END__
0000000000000000 l df *ABS* 0000000000000000
0000000000600e18 l .init_array 0000000000000000 __init_array_end
0000000000600e28 l O .dynamic 0000000000000000 _DYNAMIC
0000000000600e10 l .init_array 0000000000000000 __init_array_start
0000000000400678 l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR
0000000000601000 l O .got.plt 0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000400630 g F .text 0000000000000002 __libc_csu_fini
0000000000601028 w .data 0000000000000000 data_start
000000000040051d g F .text 0000000000000014 add
000000000060102c g .data 0000000000000000 _edata
0000000000400634 g F .fini 0000000000000000 _fini
0000000000000000 F *UND* 0000000000000000 printf@@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.5
0000000000601028 g .data 0000000000000000 __data_start
0000000000000000 w *UND* 0000000000000000 __gmon_start__
0000000000400648 g O .rodata 0000000000000000 .hidden __dso_handle
0000000000400640 g O .rodata 0000000000000004 _IO_stdin_used
00000000004005c0 g F .text 0000000000000065 __libc_csu_init
0000000000601030 g .bss 0000000000000000 _end
0000000000400430 g F .text 0000000000000000 _start
000000000060102c g .bss 0000000000000000 __bss_start
0000000000400547 g F .text 0000000000000070 main
0000000000601030 g O .data 0000000000000000 .hidden __TMC_END__
0000000000400531 g F .text 0000000000000016 sub
00000000004003c8 g F .init 0000000000000000 _init

5.查看.o文件的信息

objdump -h test.o

![[Pasted image 20250124143403.png]]
接着可以用nm查看函数和全局变量,静态变量

[root@localhost test]# nm test.o
0000000000000000 T add
000000000000002a T main
U printf
0000000000000014 T sub

局部变量不会生成符号,最终是分配在栈内存中,不会在函数外部被引用