C语言gdb查看寄存器的值,使用GDB中修改特定寄存器值及其原理

2013 November 20 GDB, C/C++

使用GDB中修改特定寄存器值及其原理

使用GDB中修改特定寄存器值及其原理

最近重新学习了一下gdb的使用,以前我只是熟悉特定的命令。现在配合听课和ppt。对于functions载入内存的过程有了一定的了解,结合我前面写的assemble笔记中那个linux中程序的栈帧分配图,会达到一个很好的效果。click me

首先我们知道64bit的机器,寄存器数量大大增加,%rsp是栈指针 %rip是顺序执行的指令指针,准确的来讲就是将要执行的下一条指令(instruction)。%rbp是frame的基地址。了解了这些就具备了我们要debug 程序的基础。 以下面程序为例:>#include#includeint foo1(void) { int i_foo1=4,j_foo2=5; printf("foo1\n"); return 1; } int foo2(void) { printf("foo2\n"); return 1; } int main(int argc ,char **argv) { int i=0,j=1,k=2; foo1(); //printf("Hello\n"); return 0; } 这个程序里面,既有main的全局变量,也有局部的变量。 编译的时候我们要加入一些option gcc -g3 -o test test.c 这样可以方便我们调试。 PS:在调试过程中,我们经常遇到segment fault或者是page fault 。如果我们要查看特定的错误,使用ulimit -u 20000之后,发生错误的时候,我们就可以在这个source code下面生成core.XXX的文件。使用 gdb sourcecode core.XXX就可以进入gdb查看最后出现错误的代码! 假如我们已经生成了一个调试版本的可执行二进制文件。[root@localhost dslab]# gdb test1

GNU gdb (GDB) Fedora (7.5.1-38.fc18)

Copyright (C) 2012 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. Type "show copying"

and "show warranty" for details.

This GDB was configured as "x86_64-redhat-linux-gnu".

For bug reporting instructions, please see:

...

Reading symbols from /home/lzz/dslab/test1...done.

(gdb) b foo1

Breakpoint 1 at 0x400534: file test1.c, line 5.

(gdb) b foo2

Breakpoint 2 at 0x400557: file test1.c, line 11.

(gdb) b main

Breakpoint 3 at 0x400577: file test1.c, line 16.

(gdb) r

Starting program: /home/lzz/dslab/test1

Breakpoint 3, main (argc=1, argv=0x7fffffffe0e8) at test1.c:16

warning: Source file is more recent than executable.

16 int i=0,j=1,k=2;

Missing separate debuginfos, use: debuginfo-install glibc-2.16-34.fc18.x86_64

(gdb) disassemble

Dump of assembler code for function main:

0x0000000000400568 : push %rbp

0x0000000000400569 : mov %rsp,%rbp

0x000000000040056c : sub $0x20,%rsp

0x0000000000400570 : mov %edi,-0x14(%rbp)

0x0000000000400573 : mov %rsi,-0x20(%rbp)

=> 0x0000000000400577 : movl $0x0,-0x4(%rbp)

0x000000000040057e : movl $0x1,-0x8(%rbp)

0x0000000000400585 : movl $0x2,-0xc(%rbp)

0x000000000040058c : callq 0x40052c

0x0000000000400591 : mov $0x0,%eax

0x0000000000400596 : leaveq

0x0000000000400597 : retq

End of assembler dump.

(gdb)首先我们要先明白几个命令b (break)就是在特定的funtion上加break断点。 然后我们使用 r (run)来运行程序。 使用disassemble 来查看当前的汇编代码。如果在后面加 funtion 显示的是funtion的汇编代码。 我们可以通过自己计算偏移量来修改寄存器的值,比如 0×0000000000400573 : mov %rsi,-0×20(%rbp)就是在%rbp的地址上减去-0×20个单位 有时候我们也要打印某些寄存器的制,可是进制可能不是我们想要的,这个时候,可以显示寄存器可以使用的格式 p/格式 变量 格式 说明 x 显示为十六进制 d 显示为十进制 u 显示为无符号十进制(unsigned) o 显示为八进制 下面我们来修改某个寄存器的值。 set *addr value 其中*addr可以是地址的解引用或者是特定的某个寄存器的值。 下面我们来使用gdb脚本来强制让程序执行特定的路径。>#include#include#include #include #include #define FILE "/home/lzz/dslab/exercise/file" int main(int argc,char **argv) { int fd = 0 ; fd = open(FILE,O_CREAT,440); if(-1 == fd) { printf("open file error!\n"); } else { printf("open file success!\n"); } return 0; } 上面的程序正常运行的话会打印open file success的语句,我们把gdb中单步调式的语句写在一个shellscript里面,例如:#!/bin.bash //filename : gdbscript.sh

file a.out //file后面要跟你调式的文件

break 11

run

set fd =-1

c

q然后后执行 gdb -x gdbscript.sh .gdb就会自动化执行我们写在脚本里面的操作。 打印信息:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值