目录
pwndbg
如何加载文件
如何运行到Main函数停止
如何查看程序的内存布局
查看内存地址存储的值
如何查看某个地址存储的指令
搜索字符串
打印
调试相关
断点相关
查看栈内数据
查看栈调用顺序
从程序回到gdb
修改内存中的值
file
可执行文件特征
动态链接文件特征
静态链接文件特征
-L参数:用于解析符号链接的文件类型
objdump
查看可执行文件反汇编
查看指定函数反汇编
查看指定节反汇编
readelf
查看可执行文件文件头
查看符号表
pwndbg
命令行下动态调试程序
如何加载文件
如何运行到Main函数停止
下断点在main函数位置 b main
如何查看程序的内存布局
vmmap:查看程序内存布局
查看内存地址存储的值
示例:x/100gx 地址 查看100个8字节的数据,4字节g 第二个x表示16进制显示内容
如何查看某个地址存储的指令
x/8i 地址 显示8个8字节的指令
搜索字符串
search 'bin/sh'
x/s 0xf7f521dc 把这个地址8字节转为字符串显示
打印
打印函数地址:p &__函数名
调试相关
n:单步步过
s:单步步入
q:停止运行gdb,退出
info r:查看寄存器的值
finish:直接执行到函数结束位置 ret
continue:后面没断电执行到结束;有断点,执行到断点
断点相关
b:下断点
Info b :查看所有断点
delete Num:根据Num值删除断点
查看栈内数据
stack 20 查看站内最上面20条指令
查看栈调用顺序
从程序回到gdb
CTRL+C 就可以了
修改内存中的值
set指令
监控内存中的在程序运行时是否改变
watch 地址
file
file命令用于检测给定文件的类型,包含文件系统、魔法幻数和语言3个检测过程。file几乎是使用频率最高的命令,当我们拿到一个未知文件时,首先要做的就是确定其文件类型,获取一些最基本的信息。
file 文件名 // Linux系统大小写敏感
可执行文件特征
可获得信息如下:
- ELF 64-bit LSB executable是可执行文件的标识,表示一个可以直接运行的程序。
- x86-64指明了该可执行文件适用于64位的x86架构。
- version 1 (GNU/Linux)表示该可执行文件符合GNU/Linux操作系统的规范,并且使用了版本1的格式。
- 静态链接(statically linked)表示该可执行文件在编译时已将所需的库文件静态地链接到可执行文件中,因此在运行时不需要依赖外部的动态链接库。这也意味着该可执行文件可以在没有额外库文件的情况下独立运行。
- for GNU/Linux 3.2.0说明该可执行文件是为GNU/Linux 3.2.0版本设计的,可能依赖于该版本的系统库和功能。
- not stripped表示该可执行文件未被剥离(stripped),即保留了符号表等调试信息,方便进行调试和分析。
- BuildID[sha1]是一个唯一标识符,可用于识别特定版本的可执行文件。
动态链接文件特征
可获得信息如下:
- ELF 64-bit LSB shared object是动态链接库的标识,表示一个具有可重定位代码和数据的二进制文件格式。
- x86-64指明了该动态链接库适用于64位的x86架构。
- version 1 (SYSV)表示该动态链接库符合System V规范,并且使用了版本1的格式。
- 动态链接(dynamically linked)表示该动态链接库在运行时才会被加载到内存中,并且可以被多个程序共享使用。因此,它通常用于减小程序文件的体积,优化内存占用,以及支持动态扩展等需求。
- not stripped表示该动态链接库未被剥离(stripped),即保留了符号表等调试信息。这对于开发和调试应用程序非常有用。
- BuildID[sha1]是一个唯一标识符,可用于识别特定版本的动态链接库。
静态链接文件特征
可获得信息如下:
- 最主要的信息是 "current ar archive",它表明这是一个静态链接库文件。
- 除了 "current ar archive" 之外,还可能会显示其他信息,如具体的体系结构(如x86_64)和使用的编译器版本等
-L参数:用于解析符号链接的文件类型
可解析得到符号链接指向的文件
解析gcc链接的文件类型
objdump
objdump命令用于查看目标文件的信息,具备反汇编能力是其最大的亮点,但其反汇编过于依赖ELF节头,且不会进行控制流分析,导致其健壮性略差。
常用参数说明:
- 选项“-s”用于将目标文件转换成十六进制表示;
- 选项“-d”或者“-D”用于对目标文件进行反汇编;
- 选项”-j“,可以指定某个节
查看可执行文件反汇编
用于查看目标文件或可执行文件的反汇编代码
objdump -d hello -M intel
会按照节的划分显示所有的反汇编代码
查看指定函数反汇编
objdump -d hello -M intel | grep -A 7 "<main>"
|
:这是管道符号,用于将objdump
输出的结果传递给下一个命令。grep
:这是一个用于在输入中搜索匹配模式的命令。-A 7
:这是grep
命令的选项之一,用于指定在匹配行之后显示多少行的上下文。"<main>"
:这是要搜索的目标函数名,用尖括号括起来指示精确匹配。
查看指定节反汇编
objdump -s -j .rodata pwn
readelf
readelf命令用于解析ELF格式目标文件的信息。该工具与objdump类似,但显示的内容更具体,且不依赖BFD库
常用参数如下:
- 选项“-h”:用于显示文件头信息
- 选项“-1”:用于显示程序头信息
- 选项:“-S”:用于显示节区头信息
- 选项“-s”:用于显示符号表
- 选项“--dyn-syms":用于显示动态符号表。例如在 libc中查找system函数的偏移量(常用于Return-into-libc攻击)。
查看可执行文件文件头
readelf -h 路径/文件
包含信息如下:
Magic
:ELF文件的魔数,用于标识该文件格式。Class
:指定了ELF文件的位数,这里是64位。Data
:指定了数据的字节顺序,这里是小端法(little endian)。Version
:指定了ELF文件的版本号。OS/ABI
:指定了目标操作系统和ABI(Application Binary Interface),即UNIX - GNU。ABI Version
:指定了ABI的版本号。Type
:指定了ELF文件的类型,这里是可执行文件。Machine
:指定了目标机器体系结构,这里是Advanced Micro Devices X86-64。Entry point address
:指定了程序的入口点地址,即程序开始执行的第一个指令的地址。Start of program headers
:指定了程序头部表的起始位置,它包含描述可执行文件的段或节的信息。Start of section headers
:指定了节头部表的起始位置,它包含描述文件所有节的信息。Flags
:指定了一些标志位,这里为0表示没有特殊标志。Size of this header
:指定了ELF头部的大小。Size of program headers
:指定了程序头部表的条目大小。Number of program headers
:指定了程序头部表的条目数量。Size of section headers
:指定了节头部表的条目大小。Number of section headers
:指定了节头部表的条目数量。Section header string table index
:指定了节头部字符串表的索引,用于查找节头部表中的节名称。
查看符号表
raedelf -s 路径/文件
ELF文件的符号表(Symbol Table)是一种数据结构,用于存储与程序中定义和引用的符号相关的信息。符号可以是函数、变量、常量或其他命名实体。
符号表通常包含以下信息:
- 符号名称:每个符号都有一个唯一的名称,用于在程序中标识该符号。
- 符号类型:指定该符号是函数、全局变量、局部变量等。
- 符号绑定:指定该符号是全局符号还是局部符号。
- 符号地址:指定该符号在内存中的地址或偏移量。
- 符号大小:指定该符号的大小,用于在内存中分配适当的空间。
- 符号可见性:指定该符号是否对其他模块可见。
- 符号所属节:指定该符号所在的节或段。
符号表对于链接器和调试器非常重要。
- 链接器使用符号表来解析多个目标文件之间的符号引用,并将它们解析为正确的地址。
- 调试器使用符号表来将程序的运行时状态与源代码进行关联,以便更好地进行调试和错误排查。