首页
社区
课程
招聘
[原创]GDB调试器的详细使用介绍
发表于: 2019-4-14 00:12 18815

[原创]GDB调试器的详细使用介绍

2019-4-14 00:12
18815

最近一直在分析路由器和linux漏洞,所以linux下的工具用的比较多,特别是gdb调试器,一直都是用什么学什么,但是总感觉不是很系统,系统学习工具,框架,书籍一直是自己的一个学习习惯,因此总结了一下linux下的逆向分析工具和基础使用方法,在忘记的时候方便自己查看。


Linux 命令
1. 文件目录
1.1 特殊符号: 
1.1.1 . 当前目录
1.1.2 .. 上级目录
1.1.3 ~ 用户的home目录
1.2 cd - 切换目录
1.3 ls - 查看目录/文件属性
1.4 mv/cp/rm 剪切/拷贝/删除文件
1.5 rmdir 删除空目录
1.6 touch 创建新文件
1.7 查看文件内容 more(按页查看)/less(部分查看)/cat(查看全部)/head(查看前x行)/tail(查看后x行)
1.8 hexdump 以十六进制查看文件
	hexdump -C 文件名
	hexdump -C 文件名 | less
1.9 ln 创建文件链接
1.10 file - 查看文件类型
1.11 grep - 查找文件内容
1.12 find/whereis/whois

2. 用户/权限
2.1 useradd(命令)/adduser(脚本) 添加目录
2.1 passwd 修改用户登陆密码
2.3 userdel 删除用户
2.4 usermod 修改用户信息(用户名/主目录/用户组/登陆密码)
2.4 chmod 修改文件权限
2.5 chown 修改文件拥有者
2.6 groupadd/groupdel 添加用户组/删除用户组

3. 进程/任务
3.1 ps/top 查看当前进程信息
3.2 kill 结束进程

4. 磁盘
4.1 df/du 查看磁盘使用信息

5. 其它
	clear - 清屏
	source - 强行让一个脚本去立即影响当前的环境(不重启而更新配置)
	apt - 软件包管理
	更新源 sudo apt update
	更新软件 sudo apt upgrade
	安装软件 : sudo apt install 软件名
	卸载软件 : sudo apt remove / sudo apt autoremove
	
	
6. 常见配置文件
6.1 vimrc,bashrc . /etc目录下的配置文件

Linux 命令
1. 文件目录
1.1 特殊符号: 
1.1.1 . 当前目录
1.1.2 .. 上级目录
1.1.3 ~ 用户的home目录
1.2 cd - 切换目录
1.3 ls - 查看目录/文件属性
1.4 mv/cp/rm 剪切/拷贝/删除文件
1.5 rmdir 删除空目录
1.6 touch 创建新文件
1.7 查看文件内容 more(按页查看)/less(部分查看)/cat(查看全部)/head(查看前x行)/tail(查看后x行)
1.8 hexdump 以十六进制查看文件
	hexdump -C 文件名
	hexdump -C 文件名 | less
1.9 ln 创建文件链接
1.10 file - 查看文件类型
1.11 grep - 查找文件内容
1.12 find/whereis/whois

2. 用户/权限
2.1 useradd(命令)/adduser(脚本) 添加目录
2.1 passwd 修改用户登陆密码
2.3 userdel 删除用户
2.4 usermod 修改用户信息(用户名/主目录/用户组/登陆密码)
2.4 chmod 修改文件权限
2.5 chown 修改文件拥有者
2.6 groupadd/groupdel 添加用户组/删除用户组

3. 进程/任务
3.1 ps/top 查看当前进程信息
3.2 kill 结束进程

4. 磁盘
4.1 df/du 查看磁盘使用信息

5. 其它
	clear - 清屏
	source - 强行让一个脚本去立即影响当前的环境(不重启而更新配置)
	apt - 软件包管理
	更新源 sudo apt update
	更新软件 sudo apt upgrade
	安装软件 : sudo apt install 软件名
	卸载软件 : sudo apt remove / sudo apt autoremove
	
	
6. 常见配置文件
6.1 vimrc,bashrc . /etc目录下的配置文件

VIM常用命令


   1.1 退出
   1.2 移动光标 :
   ​	 k
    <-h   l->
   ​	 j
   1.2.1 w 下一个单词
   1.2.2 b 上一个单词
   1.2.3 $ 直接定位到行末
   1.2.4 ^ 直接定位到行首

  1.3 开始编辑
  1.3.1 i在当前光标下插入
  1.3.2 A在行尾插入
  1.3.3 I在行首插入
  1.3.4 o在另起一行插入
  1.3.5 O在上一行插入

  1.4 保存: w
  1.5 删除/撤销
  1.5.1 x - 删除一个字符
  1.5.2 dd - 删除一行字符
  1.5.3 u - 撤销一次删除
  1.6 复制/粘贴
  1.6.1 y 
  1.6.2 p
  1.7 命令执行次数 : 在任何命令之前输入一个数字,可以让命令重复执行多次. 例如要删除5行的内容可以输入: 5dd
  1.8 ctrl + v 选中多行多列

   1.1 退出
   1.2 移动光标 :
   ​	 k
    <-h   l->
   ​	 j
   1.2.1 w 下一个单词
   1.2.2 b 上一个单词
   1.2.3 $ 直接定位到行末
   1.2.4 ^ 直接定位到行首

  1.3 开始编辑
  1.3.1 i在当前光标下插入
  1.3.2 A在行尾插入
  1.3.3 I在行首插入
  1.3.4 o在另起一行插入
  1.3.5 O在上一行插入

  1.4 保存: w
  1.5 删除/撤销
  1.5.1 x - 删除一个字符
  1.5.2 dd - 删除一行字符
  1.5.3 u - 撤销一次删除
  1.6 复制/粘贴
  1.6.1 y 
  1.6.2 p
  1.7 命令执行次数 : 在任何命令之前输入一个数字,可以让命令重复执行多次. 例如要删除5行的内容可以输入: 5dd
  1.8 ctrl + v 选中多行多列


1. GCC 常用编译选项
   编译器将源文件生成成obj中间文件.
   然后再由链接器将多个obj文件打包成可执行文件格式.

2.1 -c : 只编译成中间文件,不链接
2.2 -S : 编译成汇编文件
2.3 -masm=intel : 生成intel masm格式的汇编
2.4 -m32 : 编译成32位的目标文件/可执行文件
2.5 -g : 支持调试
2.6 -o : 设置目标文件的文件名
2.7 -O0/-O1/-O2/-O3 : 优化级别,0最低,3最高
2.8 -static : 静态编译
2.9 -share : 动态编译 
2.10 -shared : 编译成so文件(动态链接库文件)

1. GCC 常用编译选项
   编译器将源文件生成成obj中间文件.
   然后再由链接器将多个obj文件打包成可执行文件格式.

2.1 -c : 只编译成中间文件,不链接
2.2 -S : 编译成汇编文件
2.3 -masm=intel : 生成intel masm格式的汇编
2.4 -m32 : 编译成32位的目标文件/可执行文件
2.5 -g : 支持调试
2.6 -o : 设置目标文件的文件名
2.7 -O0/-O1/-O2/-O3 : 优化级别,0最低,3最高
2.8 -static : 静态编译
2.9 -share : 动态编译 
2.10 -shared : 编译成so文件(动态链接库文件)


1. GDB 常用命令
   4.1 命令行参数系列
   4.1.1 set args
   4.1.2 show args

4.2 运行系列:
4.2.1 r - 运行
4.2.2 n - 单步步过(源码)
4.2.3 s - 单步步入
4.2.4 u - 运行到循环退出
4.2.5 c - 继续运行
4.2.6 si/ni - 汇编级单步步入/步过
4.2.7 jump - 设置eip到指定位置

4.3 断点系列
4.3.1 b 行号/函数名 - 设置断点
4.3.2 info b - 查看断点
4.3.3 d 断点号 - 删除断点
4.3.4 dis 断点号 - 禁用断点
4.3.5 enable 断点号 - 启用断点

4.4 信息查看系列
4.4.1 print 变量名 - 查看变量的值
4.4.2 set 变量名=VAL - 修改变量的值
4.4.3 set disassembly-flavor intel 以intel方式查看反汇编
4.4.4 list [函数名] - 查看源码

1. GDB 常用命令
   4.1 命令行参数系列
   4.1.1 set args
   4.1.2 show args

4.2 运行系列:
4.2.1 r - 运行
4.2.2 n - 单步步过(源码)
4.2.3 s - 单步步入
4.2.4 u - 运行到循环退出
4.2.5 c - 继续运行
4.2.6 si/ni - 汇编级单步步入/步过
4.2.7 jump - 设置eip到指定位置

4.3 断点系列
4.3.1 b 行号/函数名 - 设置断点
4.3.2 info b - 查看断点
4.3.3 d 断点号 - 删除断点
4.3.4 dis 断点号 - 禁用断点
4.3.5 enable 断点号 - 启用断点

4.4 信息查看系列
4.4.1 print 变量名 - 查看变量的值
4.4.2 set 变量名=VAL - 修改变量的值
4.4.3 set disassembly-flavor intel 以intel方式查看反汇编
4.4.4 list [函数名] - 查看源码


PE的组成

1. 头部
   1.1 DOS头
   1.2 NT头
   1.2.1 文件头
   1.2.2 扩展头
   1.3 区段头
2. 区段数据
   2.1 代码段: .text
   2.2 数据段: .data
   2.3 只读数据段: .rdata
   2.3.1 导入表的数据
   2.3.2 导出表的数据
   2.4 重定位数据段: .reloc 

ELF文件格式
ELF的组成部分

1. ELF头
   1.1 id数组
   1.1.1 前4位是魔数 0x74"elf"
   1.1.2 ELF文件种类(32位/64位)
   1.1.3 ELF文件数据的字节序(小端/大端)
   1.1.4 版本 : 1. 文件版本,2. 系统ABI版本
   1.2 文件类型 : 可重定位文件/可执行文件/动态库文件
2. 程序头
   2.1 段类型 : 决定了段的作用,以及段是否被加载到内存中. 一个ELF文件中,至少存在一个LOAD类型的段. ELF一般都有解释器段,这个段用于保存解释器的文件路径. 有可能也会存在动态链接段(用于链接外部模块)
   2.2 段数据的文件偏移/文件大小/内存地址/内存中的大小
   2.3 加载到内存中后的分页属性
   2.4 段的对齐粒度
3. 区段头
   3.1 区段名
   3.2 区段类型
   3.3 Link和info
   3.4 区段数据的文件偏移和大小,元素大小.
4. 区段数据
   4.1 符号表
   4.1.1 记录本模块的符号(导出)
     记录在.symtab符号表中
     记录一个符号的名字(例如函数名),记录了符号
     的绑定类型(LOCAL,GLOBAL),还记录了符号的类型(函数,区段),记录符号的值(根据符号的不同,有不同的值,例如函数是符号类型,值就是函数的地址)
   4.1.2 记录了导入的符号
     记录在.dynsym符号表
   4.2 重定位表
   4.2.1 重定位类型, 决定了修复重定位的方法
   可执行文件类型的ELF和共享库的ELF文件的重定位是不一样的.
   4.2.2 重定位的偏移(根据重定位类型决定)

elf的加载
do_execve();  

1. 其它
   5.1 PLT和GOT表
   call printf ==> jmp [GOT表项地址] =第二次以后=> printf真正的地址
   ​			    push XX
   ​				jmp  xxx ==> 加载printf所在的so文件,修复printf函数地址
   ​				

5.2 构造函数数组,析构函数数组
5.2.1 全局对象的初始化和析构.
5.3 ptrace - 调试相关

PE的组成

1. 头部
   1.1 DOS头
   1.2 NT头
   1.2.1 文件头
   1.2.2 扩展头
   1.3 区段头
2. 区段数据
   2.1 代码段: .text
   2.2 数据段: .data
   2.3 只读数据段: .rdata
   2.3.1 导入表的数据
   2.3.2 导出表的数据
   2.4 重定位数据段: .reloc 

ELF文件格式
ELF的组成部分

1. ELF头
   1.1 id数组
   1.1.1 前4位是魔数 0x74"elf"
   1.1.2 ELF文件种类(32位/64位)
   1.1.3 ELF文件数据的字节序(小端/大端)
   1.1.4 版本 : 1. 文件版本,2. 系统ABI版本
   1.2 文件类型 : 可重定位文件/可执行文件/动态库文件
2. 程序头
   2.1 段类型 : 决定了段的作用,以及段是否被加载到内存中. 一个ELF文件中,至少存在一个LOAD类型的段. ELF一般都有解释器段,这个段用于保存解释器的文件路径. 有可能也会存在动态链接段(用于链接外部模块)
   2.2 段数据的文件偏移/文件大小/内存地址/内存中的大小
   2.3 加载到内存中后的分页属性
   2.4 段的对齐粒度
3. 区段头
   3.1 区段名
   3.2 区段类型
   3.3 Link和info
   3.4 区段数据的文件偏移和大小,元素大小.
4. 区段数据
   4.1 符号表
   4.1.1 记录本模块的符号(导出)
     记录在.symtab符号表中
     记录一个符号的名字(例如函数名),记录了符号
     的绑定类型(LOCAL,GLOBAL),还记录了符号的类型(函数,区段),记录符号的值(根据符号的不同,有不同的值,例如函数是符号类型,值就是函数的地址)
   4.1.2 记录了导入的符号
     记录在.dynsym符号表
   4.2 重定位表
   4.2.1 重定位类型, 决定了修复重定位的方法
   可执行文件类型的ELF和共享库的ELF文件的重定位是不一样的.
   4.2.2 重定位的偏移(根据重定位类型决定)

elf的加载
do_execve();  

1. 其它
   5.1 PLT和GOT表
   call printf ==> jmp [GOT表项地址] =第二次以后=> printf真正的地址
   ​			    push XX
   ​				jmp  xxx ==> 加载printf所在的so文件,修复printf函数地址
   ​				

5.2 构造函数数组,析构函数数组
5.2.1 全局对象的初始化和析构.
5.3 ptrace - 调试相关



程序运行

gdb  程序名

然后 b main,再  r



程序会断在main函数入口处

基本界面


下面是寄存器窗口



汇编代码窗口



堆栈窗口



当前执行信息



栈回溯



查看寄存器


i r



i r a



i r esp



i r pc



 查看内存


(gdb) x /wx 0x80040000    # 以16进制显示指定地址处的数据



(gdb) x /8x $esp



(gdb) x /16x $esp+12



(gdb) x /16s 0x86468700   # 以字符串形式显示指定地址处的数据



(gdb) x /24i 0x8048a51      # 以指令形式显示指定地址处的数据(24条)



  

修改寄存器的值


(gdb) set $v0 = 0x004000000



(gdb) set $epc = 0xbfc00000  

修改内存的值


(gdb) set {unsigned int}0x8048a51=0x0



(gdb) set *(unsigned int*)0x8048a54=0x55aa55aa  



内存搜索


  
Usage: find <start> <end> <count> <value>

(gdb) define find                             
set $ptr = $arg0
set $cnt = 0
while ( ($ptr<=$arg1) && ($cnt<$arg2) )
​    if ( *(unsigned int *)$ptr == $arg3 )
​        x /wx $ptr
​        set $cnt = $cnt + 1
​    end
​    set $ptr = $ptr + 4
end
end  





断点、监测点


(gdb) b *0x80400000



(gdb) watch *(unsigned int *)0xbffff400==0x90909090  

其他重要命令


查看当前程序栈的内容: **$**x/10x $sp-->打印stack的前10个元素



查看当前程序栈的信息: **$**info frame----list general info about the frame



查看当前程序栈的参数: **$**info args---lists arguments to the function


查看当前程序栈的局部变量: **$**info locals---list variables stored in the frame

查看当前寄存器的值:**$**info registers(不包括浮点寄存器) info all-registers(包括浮点寄存器)



查看当前栈帧中的异常处理器:**$**info catch(exception handlers)

用于详细查看内存信息:

x/ (n,f,u为可选参数)

n: 需要显示的内存单元个数,也就是从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义,比如1,2,3,4,5,。。。

f:显示格式,比如:
​               x(hex) 按十六进制格式显示变量。
​               d(decimal) 按十进制格式显示变量。
​               u(unsigned decimal) 按十进制格式显示无符号整型。
​               o(octal) 按八进制格式显示变量。
​               t(binary) 按二进制格式显示变量。
​               a(address) 按十六进制格式显示变量。
​               c(char) 按字符格式显示变量。

​                f(float) 按浮点数格式显示变量

​           

u:每个单元的大小,按字节数来计算。默认是4 bytes。GDB会从指定内存地址开始读取指定字节,并把其当作一个值取出来,并使用格式f来显示
​               b:1 byte     h:2 bytes     w:4 bytes g:8 bytes

 比如x/3uh 0x54320表示从内存地址0x54320读取内容,h表示以双字节为单位,3表示输出3个单位,u表示按照十六进制显示。


程序运行

gdb  程序名

gdb  程序名

然后 b main,再  r



程序会断在main函数入口处


下面是寄存器窗口



汇编代码窗口



堆栈窗口



当前执行信息



栈回溯




i r



i r a



i r esp



i r pc




(gdb) x /wx 0x80040000    # 以16进制显示指定地址处的数据



(gdb) x /8x $esp



[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 5
支持
分享
最新回复 (13)
雪    币: 697
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
最近估计要用, 多谢了。
2019-4-14 10:00
0
雪    币: 4560
活跃值: (1002)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
好东西,收藏了
2019-4-14 11:55
0
雪    币: 3738
活跃值: (3872)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
回帖收藏!
2019-4-14 12:45
0
雪    币: 783
活跃值: (1121)
能力值: ( LV5,RANK:78 )
在线值:
发帖
回帖
粉丝
5
mark
2019-4-14 13:36
0
雪    币: 120
活跃值: (1597)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
回帖收藏。
2019-4-22 23:11
0
雪    币: 1564
活跃值: (3572)
能力值: ( LV13,RANK:420 )
在线值:
发帖
回帖
粉丝
7
mark
2019-4-22 23:24
0
雪    币: 1250
活跃值: (3550)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
mark 学习了
2019-5-29 15:06
0
雪    币: 1319
活跃值: (1955)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
习惯了vs远程调试LINUX,gdb调试简直是受不了....
2019-5-29 15:36
0
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
10
收藏一下,以后把玩gdb时可做参考^^
2019-5-30 22:32
0
雪    币: 566
活跃值: (231)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
11
回帖收藏
2019-5-31 07:21
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
回帖收藏
2020-7-20 21:05
0
雪    币: 213
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
mark
2020-12-8 16:59
0
雪    币: 178
活跃值: (1306)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
感谢分享
2020-12-11 14:57
0
游客
登录 | 注册 方可回帖
返回
//