带libc源码gdb动态调试(导入glibc库使得可执行文件动态调试时可看见调用库函数源码)_pwndbg如何加载glibc符号表-程序员宅基地

技术标签: 源码调试  工具栏及相关使用  

参考部分

gdb带源码调试libc
查看编译是否是debug模式

使用gcc生成动态库及使用动态库的方法

查看源码是否编译时有-g

-g编译的可执行性程序多了很多.debug开头的段
而没有加-g的没有

在这里插入图片描述

调试信息和符号表

这里说的调试信息指的是 debug_* 相关信息,符号表是指 symtab 和 dynsym。

调试信息需要带上 -g 编译选项才能产生。

其实符号表包括 symtab 和 dynsym 两种。在没有 -g 编译也会产生,在重定位过程中需要处理。

  • symtab 包括两种类型符号:全局符号和本地静态符号。
  • dynsym 仅仅包加载动态库所需要的符号。

去掉符号表

去掉符号表通常指的是移除程序中包含的符号信息,以减小程序的大小或出于安全性/隐私的考虑。符号信息通常包括函数名、全局变量名和静态变量名等。这可以通过使用像 strip 这样的工具来实现,它能够从可执行文件和对象文件中删除所有符号信息。

比如说,对于一个使用 gcc 编译的 C 程序,你可以这样去掉符号表:


gcc -g -o my_program my_program.c
strip --strip-all my_program
 

用以上命令编译和去除符号信息之后,my_program 会失去所有符号信息,从而使得调试变得更加困难。如果没有符号表,在 gdb 中就无法通过函数名或变量名来设置断点、查看变量值等。在进行反向工程时,分析被 strip 过的程序也会更加的困难,因为缺少了符号信息。

需要指出的是,strip 只是移除符号表,不会移除由 -g 选项生成的调试信息,这些信息存储在程序的其他部分。如果你想彻底移除调试信息以及符号表,需要使用 strip 的不同选项或在编译时不加 -g 选项。例如:

strip --strip-debug my_program

这个命令会从文件中移除调试信息,而不仅仅是符号表

编译时如果带-g但是去掉了符号表能进行源代码级别调试(就是执行每行汇编的时候都能看到对应执行到源码的哪一行)?

当你在编译程序时带上 -g 选项,这会在可执行文件中添加调试信息,包括源代码中的行号信息。如果你之后使用工具(如strip)去掉了符号表,但没有去掉.debug部分的调试信息,则理论上你仍然可以在gdb中进行一定程度的源代码级别调试。这是因为源代码的行号信息通常存储在调试部分,而不是符号表中。

即使去除了符号表,只要.debug调试信息部分还在,gdb 应该仍然能够映射汇编指令到源代码中的行号。这意味着,在某些情况下,当你逐步执行程序时,你确实可以看到每个汇编指令对应的源代码行。

然而,去除符号表会导致以下限制:

  • 无法使用函数名或变量名来设置断点,因为这些信息通常存储在符号表中。
  • 查看和操作变量将变得非常困难,特别是局部变量和静态变量,因为它们的信息需要符号表中的数据来解析。

在 gdb 中加载 debug 调试信息

参考链接
在使用 GDB 调试的时候就不容易看到 libc 中的各种结构。所以我们需要加载符号表来方便调试。

Ubuntu 的软件维护者在编译对应的 ELF 文件时,会将符号表与 ELF 文件分离,将符号表命名为 “*-dbg.deb”。这样我们就可以通过手动下载符号表来方便调试。

如果是使用 “glibc all in one” 下载的 libc,会在 libc 等库放置的位置使用 “.debug” 文件夹存放好了 libc 的符号表,使用 gdb 可以自动加载。但是碰到 “glibc all in one” 没有的 libc 版本时就需要手动下载 debug 文件,并手动加载了。

将 debug 文件放入 “.debug” 文件夹

在放置 libc 的目录下新建 ".debug"文件夹,将 debug 文件放入其中即可。

通过 gdb 命令 set debug-file-directory directories

我们需要将 libc 等库的 debug 文件放入对应文件夹,并通过 set debug-file-directory $directories 命令将文件夹设为分离的 debug 文件目录,就可以让 gdb 加载 debug 文件。

GCC的gcc和g++区别

GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。

gcc是GCC中的GUN C Compiler(C 编译器)

g++是GCC中的GUN C++ Compiler(C++编译器)

一个有趣的事实就是,就本质而言,gcc和g++并不是编译器,也不是编译器的集合,它们只是一种驱动器,根据参数中要编译的文件的类型,调用对应的GUN编译器而已,比如,用gcc编译一个c文件的话,会有以下几个步骤:

Step1:Call a preprocessor, like cpp.

Step2:Call an actual compiler, like cc or cc1.

Step3:Call an assembler, like as.

Step4:Call a linker, like ld

由于编译器是可以更换的,所以gcc不仅仅可以编译C文件

所以,更准确的说法是:gcc调用了C compiler,而g++调用了C++ compiler

指定gcc/g++,glibc的版本进行编译

不同版本的GCC实现了不同版本的c和c++标准库。这对代码的兼容性有一定影响。每个版本的gcc和标准库版本的对应关系可以在官方文档中找到。使用不同版本的标准库可能会导致代码编译和运行的行为发生不同,甚至会报错。因此,在编写代码时应该了解所使用的标准库版本,并避免使用已经废弃或不再维护的标准库。

指定gcc/g++的版本

export CC=gcc的路径
export CXX=g++的路径

指定glibc的和ld版本

通过设置环境变量LD_LIBRARY_PATH增加默认库文件搜索路径,会优先匹配我们提供目录中的libc

通过gcc 的-L参数指定glibc库(libc.so)的路径

在gcc的编译参数中指定 -Wl,–dynamic-linker=glibc中动态链接器的路径,如下:

-Wl,--dynamic-linker=/动态连接器的路径/ld-linux-x86-64.so.2

apt安装后软件所在路径

参考链接

dpkg -L +软件包的名字,可以知道这个软件包包含了哪些文件, 这个方法可以列出所有安装后留在系统里的文件,查询系统中已安装的软件包所安装的位置.
系统安装软件一般在/usr/share,可执行的文件在/usr/bin,配置文件可能安装到了/etc下等。
在这里插入图片描述

文档一般在 /usr/share

可执行文件 /usr/bin

配置文件 /etc

lib文件 /usr/lib

gdb寻找单独的debug文件的路径

参考链接

gdb寻找单独的debug文件的路径是:

  1. 当前文件所在的目录。
  2. 当前文件所在目录下的.debug目录。
  3. debug-file-directory设置的目录下,寻找当前可执行程序的调试信息会根据文件所在的实际路径组合去寻找。(比如debug-file-directory设置的目录为/usr/lib/debug, 一个可执行文件所在的目录是/home/test/example,那么gdb就回去/usr/lib/debug/home/test/下去寻找example.debug文件)如果是要寻找动态库文件(.so)的调试信息,则会使用ldd所显示的目录。可以直接使用debug-file-directory目录+ldd显示目录进行拼接即可。(比如debug-file-directory设置的目录为/usr/lib/debug,ldd显示出来的liba.so的路径是/home/zy/debuginfo/fff/liba.so,gdb就会去/usr/lib/debug/home/zy/debuginfo/fff目录下去读取liba.so所对应的debuginfo文件)
set debug-file-directory directories
Set the directories which GDB searches for separate debugging information files to directory. Multiple path components can be set concatenating them by a path separator.

show debug-file-directory
Show the directories GDB searches for separate debugging information files.

如前所述,如果将debuginfo文件直接放到/usr/lib/debug目录(或者通过set-debug-file-directory命令设置的根目录)下,也是可以的,但文件目录的组织结构必须和运行时的目录组织结构一样,这个地方有一个需要注意的地方,特别是对于so文件,在debug-root-directory目录下寻找对应的debuginfo文件时,和文件实际所在的位置不一定完全一致,而要看连接器能够找到的路径,即ldd所显示的路径。gdb是会到debug-root-directory/$LDD显示的目录下去寻找对应的debuginfo文件。而ldd显示出来的路径,可能是一个绝对路径,也可能是一个相对路径,者取决于你的操作系统中所设置的一些so查找路径,比如LD_LIBRARY_PATH设置为一个相对路径还是一个绝对路径,对于gdb来说,去debug-root-directory目录下寻找的路径也不一样。gdb会拿ldd显示出来的路径直接和debug-root-directory拼接一下。比如我当前的LD_LIBRARY_PATH设置为./fff,那么gdb就会去/usr/lib/debug/./fff目录下去读取liba.so所对应的debuginfo文件,因为ldd现实出来的liba.so的路径是./fff/liba.so。

gdb带源码调试libc(gdb寻找源码的路径)

在使用gcc编译时,如果采用带-g选项编译,即可在二进制文件中附加调试信息以便gdb进行源码级别的调试。如果二进制中存在调试信息,会去相关目录寻找源码,GDB首先在编译时目录中搜索,如果失败则在当前目录中搜索,即$cdir:$cwd,其中$cdir指的是编译时目录(compilation directory),$cwd指的是当前工作目录(current working directory)。如果找到了源码文件则可以使用gdb的list命令来查看源码。
通过在ubuntu中安装带调试信息的libc,并下载libc源码,即可配置gdb跟入libc的库函数后进行源码级别的调试

不过如果我们gdb在默认寻找的目录中找不到源码文件,则无法进行源码调试。如果源码在其他目录可以在gdb中用directory或dir命令指定,或者在启动gdb时用-d参数指定,一样可以看到源码。

libc6-dbg是一个包含C标准库调试符号的调试信息包

 sudo apt install libc6-dbg  
 sudo apt install libc6-dbg:i386

libc6-dev :当前gcc编译链接时使用的版本的libc库源码

  1. 首先修改/etc/apt/sources.list,将deb-src配置开启
  2. 更新sudo apt update
  3. 使用apt source下载源码apt source libc6-dev

然后在调试时用directory把目录指向对应子文件夹就可以了,比如我要调试malloc:

 gdb -q ./可执行性文件 -d 下载的libc库源码文件夹路径/malloc

或者是在gdb中直接用directory

directory   下载的libc库源码文件夹路径/malloc
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/llovewuzhengzi/article/details/135890126

智能推荐

HBase报错:TableNotEnabledException_tablenotenabledexception: qt_user_intimacy is disa-程序员宅基地

文章浏览阅读5.1k次。在以前创建表的时候自己程序有问题等待时间过长,中止程序。再次执行程序 发现disableTable语句报错原因:中断操作导致zookeeper中记录的表状态不一致导致在控制台下输入:hbase zkcli链接zookkeeper后,删除对应的表输入语句:delete /hbase/table/表名_tablenotenabledexception: qt_user_intimacy is disabled.

【RDMA】HCA卡的MTU仅仅对IPOIB有效,对RDMA没有速度提升? |IPoIB 和IBoE(ROCE、iWARP )的区别_roce hca-程序员宅基地

文章浏览阅读2k次。HCA卡的MTU仅仅对IPOIB有效,对RDMA没有速度提升.另外的几个知识点:1. HCA卡的MTU查看方式:ifconfig -a2.HCA卡connect mode 也仅仅适用于IPOIB.参考网址:https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Configuring_the_Subnet_Manager.html原文链接:https_roce hca

(附源码)计算机毕业设计SSM餐厅订餐系统_数据库网上订餐系统用例图-程序员宅基地

文章浏览阅读1.1k次。毕设帮助,指导,本源码分享,调试部署(见文末)_数据库网上订餐系统用例图

Cannot invoke “java.util.List.add(Object)“-程序员宅基地

文章浏览阅读1.5w次,点赞8次,收藏6次。Cannot invoke “java.util.List.add(Object)”背景想要将一组动态的字符串加入数组,实现内存中处理字符串组的功能。import java.util.List;...private List jarList;...jarList.add(file);...参照URL:https://docs.oracle.com/javase/6/docs/api/java/util/List.html报错Cannot invoke "java.util.List._cannot invoke

LayUI上传图片-程序员宅基地

文章浏览阅读3.2k次,点赞3次,收藏11次。layui现学现用一段时间发现还挺好用的。对一些不复杂的功能来说还算是方便。记录一下上传图片方式,layui集成了图片上传及预览的方式。看看效果图前端HTML代码,用于展示上传图片按钮及预览的位置; 还带进度条哦... <div class="layui-upload" style="margin-left: 110px;margin-bottom: 30px;"> <button type="button" class="layui-.._layui上传图片

java使用poi工具读取word文档并将数据存储到数据库中_java读取work文件将数据存入数据库-程序员宅基地

文章浏览阅读8.4k次,点赞10次,收藏59次。因为是项目收尾阶段,需要帮客户录入数据,产品小姐姐发过来的是一个word文档,以前呐,都是解析excel文档然后保存到数据库,这次来个新花样是word文档。????只好发挥我一年多面向百度编程的经验一顿查,踩了好多坑最后确定了还是使用Apache poi工具,咱程序员呐,可以当时写不出来但是一定得会面向百度编程????????。从网上找了一些POI工具介绍 Apache poi的hwpf模块是专门用来对word doc文件进行读写操作的。在hwpf里面我们使用HWPFDocument来表示一个w_java读取work文件将数据存入数据库

随便推点

Linux 截取日志-程序员宅基地

文章浏览阅读746次。Linux 关于日志的截取_linux 截取日志

PHP-laravel框架一1_php laravel框架-程序员宅基地

文章浏览阅读8.9k次,点赞13次,收藏62次。_php laravel框架

request.getParameter讲解-程序员宅基地

文章浏览阅读6.7k次。JavaWeb getParameter代码片段总结一下:request解控中四个非常重要的方法getParameterMap();getParameterNames();getParameterValues(“name”)getParameter(“name”)下面是四个方法的例子package com.xy.test.servlet;import jakarta.servlet.ServletException;import jakarta.servlet.http.HttpSe_request.getparameter

KerberosToken_kerberos_token-程序员宅基地

文章浏览阅读1.3k次。BinarySecurityToken---KerberosToken在WS-Security规范出现之前,针对Web Service或者其他的分布式技术并不是没有安全协议来保证它们的安全。只是这些协议一旦跨越了企业边界往往会受到防火墙的影响,而不再起作用。在WS-Security中,并没有抛弃这些现有的协议,而是将这些Binary的Security Token通过Encoding的方式集成到XM_kerberos_token

Cmake 内置变量-程序员宅基地

文章浏览阅读4.6k次。2019 May 31 cmake Cmake 内置变量 信息变量 CMAKE_SYSTEM 系统名称,例如 Linux-2.6.22、FreeBSD-5.4-RELEASE、Windows 5.1 CAMKE_SYSTEM_NAME 系统名称,如 Linux、FreeBSD、Windows CMAKE_SYSTEM_VERSION 系统版本,如 2.6.22 CMAKE_SYS..._cmake_system_processor是内置的嘛

“MATLAB拒绝访问”问题的解决方法_matlab写入出错拒绝访问-程序员宅基地

文章浏览阅读1.2w次。MATLAB拒绝访问问题的解决方法参考https://www.ilovematlab.cn/thread-46789-1-1.html中的解决方案,“安装MATLAB的时候会涉及到很多的脚本文件,为安全起见,杀毒软件就会限制一些脚本文件的运行,也就会限制此些文件的访问!”电脑上没有其他的杀毒软件,但是有自带的defender。解决方案:病毒和威胁防护设置–>文件夹限制访问->..._matlab写入出错拒绝访问

推荐文章

热门文章

相关标签