Linux gdb汇编调试

文章目录

  • 一、示例代码
  • 二、gdb汇编指令
    • [2.1 step/stepi](#2.1 step/stepi)
    • [2.2 next/nexti](#2.2 next/nexti)
    • [2.3 info registers](#2.3 info registers)
    • [2.4 set](#2.4 set)
    • [2.5 x](#2.5 x)
    • [2.6 rsp寄存器](#2.6 rsp寄存器)
    • [2.7 rip 寄存器](#2.7 rip 寄存器)
  • 参考资料

一、示例代码

(1)

c 复制代码
#include <stdio.h>

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

int main()
{
    int a = 3;
    int b = 5;

    int c = add(a, b);

    printf("c = %d\n", c);

    return 0;
}

main,add函数下断点:

main函数调用 call add函数时,将下一条指令的地址0x400566压入栈中,然后跳转到函数add的地址 0x40052d处去执行。

call 指令等价于:

c 复制代码
push 0x400566
jmp 0x40052d(add)

进入到 add 函数,在执行 ret 指令之前,然后 rsp 寄存器的内存地址中的值是 0x400566,即main函数调用add函数压入栈中的地址,执行 stepi指令,add函数执行 ret 指令,pop出该地址 0x400566 ,然后跳转到 0x400566 地址去执行指令,rip寄存器的值也是 0x400566。

ret 指令等效于:

c 复制代码
pop 0x400566
jmp 0x400566

(2)

接下来修改一下这个返回地址,调用 add时,add返回地址应该是 0x400566,我们将其修改为0x40056c。

可以看到当在 add 调用 ret 指令后,将要执行的下一条指令的地址存放在 0x40056c 中而不是 call add 的下一条指令的地址。

二、gdb汇编指令

2.1 step/stepi

(1)step:用于单步执行程序并停在下一个源代码行,会进入函数。

使用 step 命令时,GDB 会执行当前行的代码,如果当前行包含函数调用,GDB 会跳进函数并停在函数内的第一行代码。如果当前行不包含函数调用,GDB 会停在下一行代码处。如果程序在当前行内包含多条语句,GDB 会执行完当前行内的所有语句并停在下一行代码处。

(2)stepi:以单步执行程序的汇编指令,汇编指令call 函数时,会进入函数。

用于单步执行一条汇编指令并停止。与 step 命令不同的是,step 命令会将当前源代码行(比如C源代码行)作为一个单独的步骤来执行,而 stepi 命令会将汇编指令作为执行的最小单位。

使用 stepi 命令时,GDB 会执行当前指令,并将 PC 寄存器指向下一条指令,然后停止程序的执行。如果当前指令是跳转指令,那么 stepi 命令会跳转到跳转指令的目标地址继续执行。如果当前指令是函数调用指令,那么 stepi 命令会跳转到被调用函数的入口地址,等待下一个命令。

stepi 命令是按照汇编指令执行的,而不是按照源代码行执行的。

2.2 next/nexti

next:用于单步执行程序并停在下一行源代码,不会进入函数。

使用 next 命令时,GDB 会执行当前行的代码,如果当前行包含函数调用,GDB 会跳过函数并停在函数调用的下一行代码。如果当前行不包含函数调用,GDB 会停在下一行代码处。如果程序在当前行内包含多条语句,GDB 只会执行当前行的第一条语句并停在下一行代码处。

nexti:用于执行下一条汇编指令并停止。

使用 nexti 命令时,GDB 会执行当前指令,并将 PC 寄存器指向下一条指令,然后停止程序的执行。如果当前指令是跳转指令,那么 nexti 命令会跳转到跳转指令的目标地址继续执行。如果当前指令是函数调用指令,那么 nexti 命令会将函数作为一个整体执行,并在函数返回时停止。

nexti 命令是按照汇编指令执行的,而不是按照源代码行执行的。

2.3 info registers

info registers 用于查看当前程序的寄存器状态,包括通用寄存器、浮点寄存器、协处理器寄存器等。

使用 info registers 命令时,GDB 会列出当前程序的寄存器状态,每个寄存器的名称、值和格式(十六进制或十进制)都会被显示出来。通常情况下,一般只需要查看一部分寄存器的值,可以使用 info registers 命令后面跟上寄存器名称的方式来查看指定寄存器的值。比如:

c 复制代码
(gdb) info registers rsp

可以使用 set $register=value 命令来设置寄存器的值,以便进行调试和测试。

2.4 set

用于设置变量、内存地址、寄存器或者其他 GDB 配置选项的值。使用 set 命令可以在调试过程中修改变量的值或者更改 GDB 的配置选项,以便更好地进行调试和分析。

2.5 x

显示内存中的内容,格式如下:

x/[n][f][size] address:其中,n表示要显示的数据的数量,f表示要显示的数据的格式,size表示每个数据的大小,address表示要显示的内存地址。

f 选项可以用于指定要显示的数据的格式。下面是一些常见的数据格式:

x: 以十六进制格式显示数据。

d: 以十进制格式显示数据。

u: 以十进制无符号整数格式显示数据。

o: 以八进制格式显示数据。

t: 以二进制格式显示数据。

a: 以地址格式显示数据。

c: 以字符格式显示数据。

f: 以浮点数格式显示数据。

s: 以字符串格式显示数据。

i: 以指令格式显示数据。

size 选项可以用于指定要显示的每个数据的大小。下面是一些常见的数据大小选项:

b: 每个数据的大小为1字节(即8位)。

h: 每个数据的大小为2字节(即16位)。

w: 每个数据的大小为4字节(即32位)。

g: 每个数据的大小为8字节(即64位)。

2.6 rsp寄存器

rsp 寄存器是 x86_64 架构中的一个 64 位寄存器,用于存储栈指针(Stack Pointer,SP)。栈指针是一个指向当前栈顶的内存地址的指针,用于指示下一个入栈或出栈操作的位置。

在函数调用时,rsp 寄存器会被用于存储当前函数的栈帧信息,包括函数的返回地址、参数、局部变量等。在函数返回时,rsp 寄存器会被重新设置为之前保存的值,以便恢复上一个函数的栈帧信息。

在程序执行过程中,rsp 寄存器的值会随着栈的变化而不断改变。当程序执行入栈操作时,rsp 寄存器的值会减小,指向新的栈顶位置。当程序执行出栈操作时,rsp 寄存器的值会增加,指向上一个栈顶位置。

在 GDB 中,可以使用 info registers 命令或 print $rsp 命令来查看 rsp 寄存器的值。

同时,可以使用 x 命令来查看栈内存的内容,例如:

c 复制代码
(gdb) x/8xg $rsp

这样就可以以十六进制格式查看栈顶的 8 个 64 位数据。

2.7 rip 寄存器

rip 寄存器是 x86_64 架构中的一个 64 位寄存器,用于存储指令指针(Instruction Pointer,IP)。指令指针是一个指向下一条将要执行的指令的地址的指针,用于指示程序的执行位置。

在程序执行过程中,rip 寄存器的值会随着指令的执行而不断改变。当程序执行一条指令时,rip 寄存器的值会自动增加,指向下一条指令的地址。如果程序遇到跳转指令,rip 寄存器的值会被修改为跳转目标的地址,以便程序跳转到指定位置继续执行。

在 GDB 中,可以使用 info registers 命令或 print $rip 命令来查看 rip 寄存器的值。

c 复制代码
(gdb) print $rip
$1 = (void (*)()) 0x400537 <add+10>
(gdb) info registers rip
rip            0x400537 0x400537 <add+10>

参考资料

https://cloud.tencent.com/developer/article/1646414

相关推荐
RuoZoe1 小时前
重塑WPF辉煌?基于DirectX 12的现代.NET UI框架Jalium
c语言
数据智能老司机3 小时前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机3 小时前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954484 小时前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star4 小时前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954488 小时前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
chlk1231 天前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑1 天前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件1 天前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
深紫色的三北六号2 天前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移