使用GDB(三):调试程序反汇编方法

一、使用反汇编命令

GDB中反汇编的命令是disassemble,在《使用GDB(二):调试程序常用命令》——反汇编相关操作中有具体介绍,其中也有对GDB常用命令的总结。

如果想要反汇编当前正在执行的函数,可使用:

(gdb) bt
#0  main.max (num1=100, num2=200, ~r0=0)
#1  0x000000000009b95c in main.main ()
(gdb) disassemble // 反汇编 main.max 函数
...

如果想反汇编指定的某个函数,可使用:

(gdb) bt
#0  main.max (num1=100, num2=200, ~r0=0)
#1  0x000000000009b95c in main.main ()
(gdb) disassemble main.main // 反汇编 main.main 函数
...

如果想反汇编某一行源码,可使用:

(gdb) l
22	   if (num1 > num2) {
23	      result = num1
24	   } else {
(gdb) info line 23
Line 23 starts at address 0x9ba5c <main.max+68> and ends at 0x9ba68 <main.max+80>.
(gdb) disassemble 0x9ba5c, 0x9ba68

如果想反汇编指定的某个函数,且让每行源码与反汇编的结果对应,且显示出每条汇编指令的具体值,可使用:

(gdb) disassemble /mr main.main
...
7	   var a int = 100
   0x000000000009b930 <+40>:	04 90 c1 02	addi.d	$r4,$r0,100(0x64)
   0x000000000009b934 <+44>:	64 60 c1 29	st.d	$r4,$r3,88(0x58)

8	   var b int = 200
   0x000000000009b938 <+48>:	04 20 c3 02	addi.d	$r4,$r0,200(0xc8)
   0x000000000009b93c <+52>:	64 40 c1 29	st.d	$r4,$r3,80(0x50)

9	   var ret int
   0x000000000009b940 <+56>:	04 00 15 00	move	$r4,$r0
   0x000000000009b944 <+60>:	64 20 c1 29	st.d	$r4,$r3,72(0x48)

最后还有一个自动反汇编,程序每次一执行,都将执行所在行的源码反汇编,在反汇编相关操作中已经说的很详细了。

二、根据指令存放地址反汇编

这个主要就是借助xdisplay命令,常用的方法就是以下三种。

如果我们现在知道某一处地址中存放的就是机器指令,但是不知道具体的指令是什么且我们还想知道时,可使用:

9	   var ret int
   0x000000000009b940 <+56>:	04 00 15 00	move	$r4,$r0
   0x000000000009b944 <+60>:	64 20 c1 29	st.d	$r4,$r3,72(0x48)
...
(gdb) x/3i 0x000000000009b944	// 3表示显示该地值后面的三条指令
   0x9b944 <main.main+60>:	st.d	$r4,$r3,72(0x48)
   0x9b948 <main.main+64>:	ld.d	$r4,$r3,80(0x50)
   0x9b94c <main.main+68>:	ld.d	$r5,$r3,88(0x58)

PC寄存器中存放的都是当前将要执行的指令的地址,如果我们想要查看将要执行的指令,可使用:

(gdb) x/i $pc
=> 0x9ba48 <main.max+48>:	ld.d	$r4,$r3,32(0x20)

如果我们每次执行时都想知道将要执行的指令,可使用:

(gdb) display/i $pc
4: x/i $pc
=> 0x9ba50 <main.max+56>:	slt	$r4,$r4,$r5
(gdb) si
0x000000000009ba54	22	   if (num1 > num2) {
4: x/i $pc
=> 0x9ba54 <main.max+60>:	bne	$r4,$r0,8(0x8) # 0x9ba5c <main.max+68>
(gdb) si
0x000000000009ba58	22	   if (num1 > num2) {
4: x/i $pc
=> 0x9ba58 <main.max+64>:	beq	$r0,$r0,16(0x10) # 0x9ba68 <main.max+80

三、根据指令具体值反汇编

如果我们知道指令存放的地址,可以通过上面x/ni命令很容易反汇编出来具体的指令。但是若我们只知道汇编指令的值,不知道其存放的位置,该怎么将其反汇编呢?

print/i是不行的,这玩意不支持。但是咋有办法!

假设下面一堆值就是汇编指令的具体值,一行有4个值,每个值之间用4个空格键分割,总共有5行。

0x00155013    0x0010a9ad    0x13c4c014    0x00494294
0x381c5353    0x28c001ae    0x13c7c014    0x00494294
0x381c5357    0x28c161ce    0x13c56014    0x00494294
0x381c535b    0x11c1e014    0x00494294    0x0010d356
0x4c0001c0    0x0044854c    0x029ffc13    0x00409673

将上面的值存放到一个ass.s汇编文件中,修改成如下的格式,修改方式非常简单,使用vim替换操作即可。文件中.long是伪汇编操作,^@是换行符\n

.long 0x00155013^@.long 0x0010a9ad^@.long 0x13c4c014^@.long 0x00494294
.long 0x381c5353^@.long 0x28c001ae^@.long 0x13c7c014^@.long 0x00494294
.long 0x381c5357^@.long 0x28c161ce^@.long 0x13c56014^@.long 0x00494294
.long 0x381c535b^@.long 0x11c1e014^@.long 0x00494294^@.long 0x0010d356
.long 0x4c0001c0^@.long 0x0044854c^@.long 0x029ffc13^@.long 0x00409673

然后再对汇编文件进行汇编,汇编完后生成一个.o文件,最后再对.o文件反汇编:

[loongson@localhost workfile]$ vim ass.s 
[loongson@localhost workfile]$ gcc -c ass.s -o ass.o
[loongson@localhost workfile]$ objdump -d ass.o 

ass.o:     文件格式 elf64-loongarch


Disassembly of section .text:

0000000000000000 <.text>:
   0:	00155013 	or	$r19,$r0,$r20
   4:	0010a9ad 	add.d	$r13,$r13,$r10
   8:	13c4c014 	addu16i.d	$r20,$r0,-3792(0xf130)
   c:	00494294 	srai.d	$r20,$r20,0x10
  10:	381c5353 	stx.d	$r19,$r26,$r20
  14:	28c001ae 	ld.d	$r14,$r13,0
  18:	13c7c014 	addu16i.d	$r20,$r0,-3600(0xf1f0)
  1c:	00494294 	srai.d	$r20,$r20,0x10
  20:	381c5357 	stx.d	$r23,$r26,$r20
  24:	28c161ce 	ld.d	$r14,$r14,88(0x58)
  28:	13c56014 	addu16i.d	$r20,$r0,-3752(0xf158)
  2c:	00494294 	srai.d	$r20,$r20,0x10
  30:	381c535b 	stx.d	$r27,$r26,$r20
  34:	11c1e014 	addu16i.d	$r20,$r0,28792(0x7078)
  38:	00494294 	srai.d	$r20,$r20,0x10
  3c:	0010d356 	add.d	$r22,$r26,$r20
  40:	4c0001c0 	jirl	$r0,$r14,0
  44:	0044854c 	srli.w	$r12,$r10,0x1
  48:	029ffc13 	addi.w	$r19,$r0,2047(0x7ff)
  4c:	00409673 	slli.w	$r19,$r19,0x5
  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yelvens

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值