【Key的GDB学习日记(1)】


在我的目前了解中,gdb能够让我们进入程序的内部,深入的观察程序的运行,就行编辑器中的debug调试,通过各个命令找出问题出现的地方(例如找到栈溢出的地址)进行后续操作。

gdb介绍

GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。

一般来说,GDB主要帮助你完成下面四个方面的功能:

1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。

2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式

3、当程序被停住时,可以检查此时你的程序中所发生的事。

4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。

(来自百度百科)

gdb功能

运行

·步入,步过,步出,步止

·断点(设置,删除,显示)

·查看内存、寄存器、各种参数

·设置内存、寄存器、各种参数(加载文件)

·远程调试

·其他辅助功能

gdb常用命令

$ gdb:启动gdb,再终端输入gdb进入交互模式。

(gdb) -tui:分屏可以将屏幕分为两个部分,一边看源码一边gdb

(gdb)help:查看命令帮助,具体命令查询在gdb中输入help + 命令,简写h

(gdb)run:执行要调试的程序,会在第一个断点停下(run-text:加载文本文件,run-bin:加载二进制文件),简写r

(gdb)start:单步执行,运行程序,停在第一执行语句
(gdb)continue:在断点停止运行后,继续执行程序到下一个断点或结束,简写c

(gdb)list:查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数),简写l

(gdb)set:设置变量的值

(gdb)next:单步调试(逐过程,函数直接执行),简写n

(gdb)step:单步调试(逐语句:进入自定义函数内部执行),简写s

(gdb)backtrace:查看函数的调用的栈帧和层级关系,简写bt

(gdb)frame:切换函数的栈帧,简写f

(gdb)info:查看函数内部局部变量的数值,简写i

(gdb)finish:结束当前函数,返回到函数调用点,单步执行如果已经进入了某函数,可使用命令finish.退出该函数返回到它的调用函数中

(gdb)return:强制返回当前函数,忽略当前函数还没有执行完毕的语句,强制返回

(gdb)print:打印值及地址,简写p

(gdb)quit:退出gdb,简写q

(gdb)break+num:在第num行设置断点,简写b

(gdb)info breakpoints:查看当前设置的所有断点

(gdb)delete breakpoints num:删除第num个断点,简写d

(gdb)display:追踪查看具体变量值

(gdb)undisplay:取消追踪观察变量

(gdb)watch:被设置观察点的变量发生修改时,打印显示

(gdb)i watch:显示观察点

(gdb)enable breakpoints:启用断点

(gdb)disable breakpoints:禁用断点

(gdb)x:查看内存x/20xw 显示20个单元,16进制,4字节每单元

(gdb)run argv[1] argv[2]:调试时命令行传参

gdb使用

(gdb) i r:查看寄存器

寄存器

(gdb) i r
rax            0x555555555275      93824992236149
rbx            0x0                 0
rcx            0x555555557d98      93824992247192
rdx            0x7fffffffdf78      140737488347000
rsi            0x7fffffffdf68      140737488346984
rdi            0x1                 1
rbp            0x7fffffffde50      0x7fffffffde50
rsp            0x7fffffffde50      0x7fffffffde50
r8             0x7ffff7f9cf10      140737353731856
r9             0x7ffff7fc9040      140737353912384
r10            0x7ffff7fc3908      140737353890056
r11            0x7ffff7fde680      140737354000000
r12            0x7fffffffdf68      140737488346984
r13            0x555555555275      93824992236149
r14            0x555555557d98      93824992247192
r15            0x7ffff7ffd040      140737354125376
rip            0x55555555527d      0x55555555527d <main+8>
eflags         0x246               [ PF ZF IF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
k0             0x20000             131072
k1             0x11000804          285214724
k2             0x0                 0
k3             0x0                 0

rsp寄存器,**stack pointer, 它存储的值永远是栈顶的地址,所以它又被叫做栈顶指针。**我们可以用(%rsp)来获取栈顶存储的值,通过a(%rsp), 其中a是任何一个整数,来获取地址是rsp存储的值加a处的内存单元的值。比如说,2(%rsp)就是栈顶上方(逻辑地址增大方向)2个字节处的值,-2(%rsp)就是栈顶下方(逻辑地址减小方向)2个字节处的值。

以r开头的寄存器如rbp、rsp一般表示64位寄存器,而以e开头的寄存器如ebp、esp表示32位寄存器。一般不影响比较,即把rbp作用等同于ebp即可。

rbp寄存器:为基指针(Base Pointer)寄存器,通过它减去一定的偏移值,来访问栈中的元素;

rax、rdx常作为函数返回值使用,通用寄存器

rdi、rsi、rdx、rcx、r8、r9等寄存器常用于存放函数参数

rip作为指令指针存储着CPU下一条要执行的指令的地址
一旦CPU读取一条指令,rip会自动指向下一条指令(存储下一条指令的地址)

ARM

1.ARMv8提供了31个通用寄存器 R0R30;在AArch32架构,通用寄存器w0w30是32bit宽度;在AArch64架构,通用寄存器x0~x30是64bit宽度;

\2. 6 个状态寄存器,

3.共有 7 种不同的处理器模式:用户模式(User),快速中断模式(FIQ),普通中断模式(IRQ),管理模式(Svc),数据访问中止模式(Abort),未定义指令中止模式(Und),系统模式(Sys),

汇编语言

汇编语言是直接在硬件之上工作的编程语言

汇编语言组成
  • 汇编指令:机器码的助记符,有对应的机器码。
  • 伪指令:没有对应的机器码,由编译器执行,计算并不执行。
  • 其他符号:如+、—、*、/等由编译器识别,没有对应的机器码。

核心汇编指令,决定了汇编语言的特性

//一个由二进制文件反编译得到的汇编代码
; Attributes: noreturn fuzzy-sp

; void __fastcall __noreturn start(__int64, __int64, void (*)(void))
public start
start proc near
; __unwind {
endbr64
xor     ebp, ebp
mov     r9, rdx         ; rtld_fini
pop     rsi             ; argc
mov     rdx, rsp        ; ubp_av
and     rsp, 0FFFFFFFFFFFFFFF0h
push    rax
push    rsp             ; stack_end
lea     r8, fini        ; fini
lea     rcx, init       ; init
lea     rdi, main       ; main
call    cs:__libc_start_main_ptr
hlt
; } // starts at 11E0
start endp
基本指令

cmp a,b 比较a与b
mov a,b 把b的值送给a

lea reg,src ; 把源操作数的有效地址送给指定的寄存器

ret 返回主程序
nop 无作用,英文“no operation”的简写,意思是“do nothing”(机器码90)***机器码的含义参看上面
(解释:ultraedit打开编辑exe文件时你看到90,等同于汇编语句nop)
call 调用子程序
je 或jz 若相等则跳(机器码74 或0F84)
jne或jnz 若不相等则跳(机器码75或0F85)
jmp 无条件跳(机器码EB)
jb 若小于则跳
ja 若大于则跳
jg 若大于则跳
jge 若大于等于则跳
jl 若小于则跳
jle 若小于等于则跳
pop 出栈
push 压栈

具体全部指令可参考8080/8086汇编手册数据传输指令

汇编格式
intelAT&T
mov eax, 8movl $8, %eax
mov ebx, 0ffffhmovl $0xffff, %ebx
int 80hint $80
mov eax, [ecx]movl (%ecx), %eax


可以看下这个[《100个gdb小技巧》] (https://wizardforcel.gitbooks.io/100-gdb-tips/content/index.html)点此跳转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值