Linux下汇编调试器GDB的使用

简介:

Linux下汇编调试器GDB的使用


      GDB 是GNU开源组织发布的一个强大的Linux/Unix下的程序调试工具。大家是否早已习惯了Windows下图形界面方式像VC、BCB等IDE的调试器,但如果你是在Linux平台下做软件调试,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。
先来看个实例:

 

 
  1. reader@cg:~/source $ gdb -q  
  2. (gdb) set dis intel  
  3. (gdb) quit  
  4. reader@cg:~/source $ echo "set dis intel" > ~/.gdbinit  
  5. reader@cg:~/source $ cat ~/.gdbinit  
  6. set dis intel  
  7. reader@cg:~/source $  

现在将GDB配置成为了使用Intel语法,让我们首先来认识Intel语法。在Intel语语法中,汇编指令一般遵循下面这种形式:
operation <destination>, <source>
目的操作数和源操作数可以是寄存器、内存地址或数值。操作通常是直观的助记符:mov操作会将源操作数中的值移动到目的操作数中,sub操作会减去,inc指令会增加等。例如,下面的指令将会扣ESP中的值移动到EBP中,然后从ESP中减去8(结果存储在ESP中)。
8048375:        89 e5                 mov    ebp,esp
8048377:        83 ec 08              sub    esp,0x8
还有用于控制执行流程的操作。cmp操作用于对数值进行比较,并且基本上所有以j为首字母的操作都用于转移到代码的不同部分(转移到哪一部分取决于比较的结果)。下面的例子中,首先将位于EBP中的一个4字节的值减去4与数值9进行比较。下一条指令是如果小于等于则转移的简写,它参考的是前一个比较的结果。如果那个数小于或等于9,那么程序就会转移到Ox8048393处的指令执行。否则,就转向下一条无条件转移指令执行。如果那个数不小于或等于9,那么程序执行就会转移到Ox80483a6处。
804838b:        83 7d fc 09           cmp    DWORD PTR [ebp-4],0x9
804838f:        7e 02                 jle    8048393 <main+0x1f>
8048391:        eb 13                 jmp    80483a6 <main+0x32>
这些例子来自于我们先前的反汇编,并且我们已经将调试工具配置为使用Intel语法,所以让我们使用调试工具在汇编指令级别上单步调试第一个程序吧。
GCC编译程序可以使用-g标记来包含附加的调试信息,这些调试信息会使得GDB能够访问源代码。
 

 
  1. reader@cg:~/source $ gcc -g firstprog.c   
  2. reader@cg:~/source $ ls -l a.out  
  3. -rwxr-xr-x 1 matrix users 11977 Jul 4 17:29 a.out  
  4. reader@cg:~/source $ gdb -q ./a.out  
  5. Using host libthread_db library "/lib/libthread_db.so.1".  
  6. (gdb) list  
  7. 1       #include <stdio.h> 
  8. 2  
  9. 3       int main()  
  10. 4       {  
  11. 5               int i;  
  12. 6               for(i=0; i < 10; i++)  
  13. 7               {  
  14.  8                       printf("Hello, world!\n");  
  15. 9               }  
  16. 10      }  
  17. (gdb) disassemble main  
  18. Dump of assembler code for function main():  
  19. 0x08048384 <main+0>:    push   ebp  
  20. 0x08048385 <main+1>:    mov    ebp,esp  
  21. 0x08048387 <main+3>:    sub    esp,0x8  
  22. 0x0804838a <main+6>:    and    esp,0xfffffff0  
  23. 0x0804838d <main+9>:    mov    eax,0x0  
  24. 0x08048392 <main+14>:   sub    esp,eax   
  25. 0x08048394 <main+16>:   mov    DWORD PTR [ebp-4],0x0   
  26. 0x0804839b <main+23>:   cmp    DWORD PTR [ebp-4],0x9  
  27. 0x0804839f <main+27>:   jle    0x80483a3 <main+31> 
  28. 0x080483a1 <main+29>:   jmp    0x80483b6 <main+50> 
  29. 0x080483a3 <main+31>:   mov    DWORD PTR [esp],0x80484d4  
  30. 0x080483aa <main+38>:   call   0x80482a8 <_init+56> 
  31. 0x080483af <main+43>:   lea    eax,[ebp-4]  
  32. 0x080483b2 <main+46>:   inc    DWORD PTR [eax]  
  33. 0x080483b4 <main+48>:   jmp    0x804839b <main+23> 
  34. 0x080483b6 <main+50>:   leave  
  35. 0x080483b7 <main+51>:   ret  
  36. End of assembler dump.  
  37. (gdb) break main  
  38. Breakpoint 1 at 0x8048394: file firstprog.c, line 6.  
  39. (gdb) run  
  40. Starting program: /cg/a.out  
  41.  
  42. Breakpoint 1, main() at firstprog.c:6  
  43. 6               for(i=0; i < 10; i++)  
  44. (gdb) info register eip  
  45. eip            0x8048394        0x8048394  
  46. (gdb)  
  47.  

先列出了源代码,并且显示了main()函数的反汇编。然后,在main()函数开始的地方设置了一个断点,并且开始运行程序。这个断点只是告诉调试工具当程序运行到该点时暂停程序的执行。由于断点设置在了main()函数开始的地方,实际上在执行main()中的任何指令之前,程序会到达该断点并且暂停。然后,显示了EIP(指令指针)的值。
EIP包含一个内存地址,该地址指向main()函数的反汇编指令中的一条指令(以粗体显示)。我们把在这之前的指令(以斜体显示)一起称为函数序言,它们由编译程序生成,用于为main()函数的局部变量设置内存空间。在C语言中需要声明变量的部分原因就是辅助建立这部分代码。调试工具知道这部分代码是自动产生的,并且聪明地将其跳过。我们随后会详细讨论函数序言,但现在我们可以从GDB中获得它的一些信息并暂时将其跳过。
GDB调试工具提供了一个直接检查内存的方法,即使用命令x,它是检查(examine)的简写。对于任何Hacker来说,检查内存都是一项很关键的技术。大多数Hacker的漏洞发掘很像魔术——它们似乎令人惊讶并且不可思议,除非您知道这些戏法和误导。但是使用像GDB这样的调试工具,程序执行的每个方面都可以被确定地检查、暂停、单步跟踪并且可以随心所欲地重复。因为一个正在运行的程序的主体是处理器和若干内存段,所以检查内存是查看到底正在干什么的首要方法。
 



 本文转自 李晨光 51CTO博客,原文链接:http://blog.51cto.com/chenguang/746692,如需转载请自行联系原作者





相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
4月前
|
安全 Linux iOS开发
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
520 53
Binary Ninja 5.1.8104 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
|
4月前
|
Linux API iOS开发
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
357 14
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
|
9月前
|
NoSQL Linux 编译器
GDB符号表概念和在Linux下获取符号表的方法
通过掌握这些关于GDB符号表的知识,你可以更好地管理和理解你的程序,希望这些知识可以帮助你更有效地进行调试工作。
414 16
|
8月前
|
NoSQL Linux 开发工具
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
本文介绍了yum 包管理工具、Vim 编辑器、gcc/g++ 编译器、gdb 调试器、编译原理及 Makefile 的使用,同时还配备了如何使用,以及图解。旨在帮助读者更好地理解和应用这些工具与技术。
434 0
|
NoSQL Linux 编译器
内核实验(一):使用QEMU+GDB断点调试Linux内核代码
如何配置环境并使用QEMU虚拟机结合GDB进行Linux内核代码的断点调试,包括安装QEMU、交叉编译工具链,编译内核以及通过GDB远程连接进行调试的详细步骤。
1606 1
内核实验(一):使用QEMU+GDB断点调试Linux内核代码
|
NoSQL Linux C语言
Linux GDB 调试
Linux GDB 调试
275 10
|
5月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
652 2
二、Linux文本处理与文件操作核心命令
|
5月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
415 137
|
5月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
1002 57