Linux gdb汇编调试

文章目录

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

一、示例代码

(1)

#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 指令等价于:

push 0x400566
jmp 0x40052d(add)

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

ret 指令等效于:

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 命令后面跟上寄存器名称的方式来查看指定寄存器的值。比如:

(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 命令来查看栈内存的内容,例如:

(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 寄存器的值。

(gdb) print $rip
$1 = (void (*)()) 0x400537 <add+10>
(gdb) info registers rip
rip            0x400537 0x400537 <add+10>

参考资料

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/28724.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Airbnb 引入 HTTP Streaming,网页性能得到大幅度提升

Airbnb 通过引入HTTP Streaming来提升网站的页面加载性能。他们将测试的每个页面&#xff08;包括主页&#xff09;的首次内容绘制&#xff08;First Contentful Paint&#xff0c;FCP&#xff09;时间降低了大约 100 毫秒。他们还最小化了后端慢查询对加载时间的影响。 Airbn…

​大华智慧园区综合管理平台存在任意文件上传漏洞

免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 大华智慧园区综合管理平台简介 大华智慧园区综合管理…

JavaScript数组所有方法集合

##方法 1、concat 用于合并两个或多个数组。此方法不会更改现有数组&#xff0c;而是返回一个新数组 2、copyWithin 浅复制数组的一部分到同一数组中的另一个位置&#xff0c;并返回它&#xff0c;不会改变原数组的长度 3、entries 返回一个新的 Array Iterator 对象&#xf…

使用Vue + FormData + axios实现图片上传功能实战

前言 上节回顾 上一小节中,我们添加了Vue-router的路有数据,这些数据都将是后续实战课程中的真实路由数据了。同时引入了ElementUI的el-menu做为左侧菜单的组件,但本专栏的特点就是遇到第三方功能和组件,自己尽量也要实现一遍,所以,在文章末尾又自己实现了一个tg-menu的…

数据结构--线性表以及其顺序存储结构

这里写目录标题 线性表的定义和特征定义特征 案例引入稀疏多项式链表实现多项式相加小结 线性表的类型定义&#xff08;抽象数据类型&#xff09;定义格式基本操作小结 线性表的顺序表示和实现实现1顺序存储表示顺序表中元素存储位置的计算 实现2顺序表的优点问题出现结构体表示…

消息推送(websocket)集群化解决方案

目录 需求分析解决方案实现步骤架构图配置websocket请求地址配置websocket连接前置和连接关闭监听配置websocket处理程序配置redis交换机配置redis订阅监听配置redis发布监听需求分析 及时信息传递:消息推送功能能够确保网站向用户发送及时的重要信息,包括新闻更新、促销活动…

SpringCloud(六)Config配置中心

一、配置中心 官方文档&#xff1a;**https://docs.spring.io/spring-cloud-config/docs/current/reference/html/ 经过前面的学习&#xff0c;我们对于一个分布式应用的技术选型和搭建已经了解得比较多了&#xff0c;但是如果我们的微服务项目需要部署很多个实例&#xff0c…

基于node.js中的serialport模块实现无线传感网上位机功能

半个月前的无线传感网课设上位机的实现遇到了很多困难&#xff0c;特写此文章给有需要的朋友一些帮助&#xff0c;欢迎私信探讨 文章目录 前言一、node.js中的serialport模块二、express框架三、echarts实现拓扑图四、实现下行数据五、成果展示总结 前言 本文所要实现的功能以…

Spring Boot : ORM 框架 JPA 与连接池 Hikari

数据库方面我们选用 Mysql &#xff0c; Spring Boot 提供了直接使用 JDBC 的方式连接数据库&#xff0c;毕竟使用 JDBC 并不是很方便&#xff0c;需要我们自己写更多的代码才能使用&#xff0c;一般而言在 Spring Boot 中我们常用的 ORM 框架有 JPA 和 Mybaties &#xff0c;本…

MySQL事务与事务的隔离级别

MySQL事务与事务的隔离级别 什么事务&#xff1f;事务的特点&#xff08;ACID&#xff09;事务的隔离级别多事务运行的并发问题隔离级别repeatable read&#xff08;可重复读&#xff09;之 MVCC&#xff08;多版本并发控制&#xff09; 并发机制优化 什么事务&#xff1f; 事务…

为什么要分表和分区?

目录 &#x1f976;为什么要分表和分区&#xff1f; &#x1f976;分表 &#x1f976;Mysql分表分为垂直切分和水平切分 &#x1f976;分表的几种方式&#xff1a; &#x1f976;mysql集群 &#x1f976;利用merge存储引擎来实现分表 &#x1f976;分区 &#x1f976;什么是分…

OpenCv之图像轮廓

目录 一、图像轮廓定义 二、绘制轮廓 三、计算轮廓面积与周长 一、图像轮廓定义 图像轮廓是具有相同颜色或灰度的连续带你的曲线.轮廓在形状分析和物体的检测和识别中很有用 轮廓的作用: 用于图形分析物体的识别与检测 注意点: 为了检测的准确性&#xff0c;需要先对图像…