Linux GDB调试常见指令

Ring3程序编译时添加-g参数编译:
汇总常用gdb命令,持续添加…

命令说明
break当不带参数时,在所选栈帧中执行的下一条指令处设置断点
break “function”在function入口处添加断点
break “line”在当前源码文件指定行的开始处打断点
break “filename:line”在源码文件filename的line行处下断点
break “filename:function”在源码文件filename的function函数下断点
break “address”在address处下断点
break … if cond在cond值非零时停住程序
info break查看所有断点信息
list(l)从第一行开始例出原码(实测没有显示头文件)
回车键直接回车表示,重复上一次命令
run(r )运行程序
nest(n)单条语句执行,不进入函数
reverse-next反向步进程序,执行完子程序调用
step(s)单条语句执行,进入函数
reverse-step反向步进程序,直到到达另一个源码行的开头
return “expression”将expression的值作为函数的返回值并使函数直接返回
continue(c)继续运行程序
print(p)打印变量的值
bt查看函数堆栈
finish退出函数
quit(q)退出程序,结束调试
symbols(s)从指定文件中读取符号表 s file
thread(t)查看调试进程的pid号
help列出出gdb的命令种类
help + 类ex:help breakpoints显示断点相关命令
watch监视某个变量或者是表达式的值
catch设置捕捉点来补捉程序运行时的一些事件
show disassembly-flavorgdb默认反汇编为att格式的指令
set disassembly-flavor intel将反汇编格式设置为NASM
x /24xb + 0x555555554704以16进制方式显示起始地址为0x555555554704的24字节数据
info reg查看寄存器的值
info threads打印出所有线程的信息
info frame打印出指定栈帧的详细信息
info proc查看proc里的进程信息
info register edx查看edx寄存器的值

使用qemu + gdb 调试Linux内核时发现,并不是内核所有的函数都可以下断点的,需要找内核的导出函数;

//调试源码
#include <stdio.h>

void main()
{
	printf("%s %d %s", "Hello world", 233, "\n");

	printf("%s %d %s", "Hello world", 233, "\n");

}
//反汇编main函数
(gdb) disassemble main
Dump of assembler code for function main:
   0x0000555555554625 <+0>:	push   rbp
   0x0000555555554626 <+1>:	mov    rbp,rsp
=> 0x0000555555554629 <+4>:	lea    rcx,[rip+0xd4]        # 0x555555554704
   0x0000555555554630 <+11>:	mov    edx,0xe9
   0x0000555555554635 <+16>:	lea    rsi,[rip+0xca]        # 0x555555554706
   0x000055555555463c <+23>:	lea    rdi,[rip+0xcf]        # 0x555555554712
   0x0000555555554643 <+30>:	mov    eax,0x0
   0x0000555555554648 <+35>:	call   0x555555554520 <printf@plt>
   0x000055555555464d <+40>:	lea    rcx,[rip+0xb0]        # 0x555555554704
   0x0000555555554654 <+47>:	mov    edx,0xe9
   0x0000555555554659 <+52>:	lea    rsi,[rip+0xa6]        # 0x555555554706
   0x0000555555554660 <+59>:	lea    rdi,[rip+0xab]        # 0x555555554712
   0x0000555555554667 <+66>:	mov    eax,0x0
   0x000055555555466c <+71>:	call   0x555555554520 <printf@plt>
   0x0000555555554671 <+76>:	nop
   0x0000555555554672 <+77>:	pop    rbp
   0x0000555555554673 <+78>:	ret    
End of assembler dump.

// i r 查看当前寄存器的值
(gdb) i r
rax            0x555555554625	93824992232997
rbx            0x0	0
rcx            0x555555554680	93824992233088
rdx            0x7fffffffe578	140737488348536
rsi            0x7fffffffe568	140737488348520
rdi            0x1	1
rbp            0x7fffffffe480	0x7fffffffe480
rsp            0x7fffffffe480	0x7fffffffe480
r8             0x7ffff7dd0d80	140737351847296
r9             0x7ffff7dd0d80	140737351847296
r10            0x0	0
r11            0x1	1
r12            0x555555554540	93824992232768
r13            0x7fffffffe560	140737488348512
r14            0x0	0
r15            0x0	0
rip            0x555555554629	0x555555554629 <main+4>
eflags         0x246	[ PF ZF IF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
//十六进制形式查看给定内存地址的值
(gdb) x /24xb 0x555555554704
0x555555554704:	0x0a	0x00	0x48	0x65	0x6c	0x6c	0x6f	0x20
0x55555555470c:	0x77	0x6f	0x72	0x6c	0x64	0x00	0x25	0x73
0x555555554714:	0x20	0x25	0x64	0x20	0x25	0x73	0x00	0x00
//字符串形式查看给定内存地址的值
(gdb) x /4s 0x555555554704
0x555555554704:	"\n"
0x555555554706:	"Hello world"
0x555555554712:	"%s %d %s"
0x55555555471b:	""
//指令形式查看指定地址处的数据
(gdb) x /24i 0x555555554704
   0x555555554704:	or     al,BYTE PTR [rax]
   0x555555554706:	rex.W
   0x555555554707:	gs ins BYTE PTR es:[rdi],dx
   0x555555554709:	ins    BYTE PTR es:[rdi],dx
   0x55555555470a:	outs   dx,DWORD PTR ds:[rsi]
   0x55555555470b:	and    BYTE PTR [rdi+0x6f],dh
   0x55555555470e:	jb     0x55555555477c
   0x555555554710:	add    BYTE PTR fs:[rip+0x64252073],ah        # 0x5555b97a678a
   0x555555554717:	and    BYTE PTR [rip+0x1000073],ah        # 0x555556554790
   0x55555555471d:	sbb    eax,DWORD PTR [rbx]
   0x55555555471f:	cmp    edi,DWORD PTR [rax]
   0x555555554721:	add    BYTE PTR [rax],al
   0x555555554723:	add    BYTE PTR [rsi],al
   0x555555554725:	add    BYTE PTR [rax],al
   0x555555554727:	add    ah,dh
   0x555555554729:	std    
   0x55555555472a:	(bad)  
   0x55555555472b:	inc    DWORD PTR [rax+rax*1-0x1ec0000]
   0x555555554732:	(bad)  
   0x555555554733:	jmp    FWORD PTR [rax+rax*1-0x1dc0000]
   0x55555555473a:	(bad)  
   0x55555555473b:	call   QWORD PTR [rax+rax*1+0x0]
   0x55555555473f:	add    BYTE PTR [rcx],cl
   0x555555554741:	(bad) 
//打印线程信息
(gdb) info threads 
  Id   Target Id         Frame 
* 1    process 4663 "a.out" main () at format.c:5
//打印指定栈帧信息
(gdb) info frame
Stack level 0, frame at 0x7fffffffe490:
 rip = 0x555555554629 in main (format.c:5); saved rip = 0x7ffff7a05b97
 source language c.
 Arglist at 0x7fffffffe480, args: 
 Locals at 0x7fffffffe480, Previous frame's sp is 0x7fffffffe490
 Saved registers:
  rbp at 0x7fffffffe480, rip at 0x7fffffffe488
//查看proc里的进程信息
(gdb) info proc
process 4663
cmdline = '/mnt/hgfs/share/linux_c/int/a.out'
cwd = '/mnt/hgfs/share/linux_c/int'
exe = '/mnt/hgfs/share/linux_c/int/a.out'



从上面gdb分析的结果来看在call printf之前,会将参数从左到右依次压入栈中;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值