hook glibc

我们知道,Linux的用C库的都是glibc,有一个叫libc.so.6的文件,这是几乎所有Linux下命令的动态链接中,其中有标准C的各种函数,默认情况下,linux所编译的程序中对标准C函数的链接,都是通过动态链接方式来链接libc.so.6这个函数库的。这也意味着我们在通过我们注入的.so来实现函数覆盖劫持之后需要从libc.so.6中取得原本的正常函数,让程序继续正常执行

正常程序main.c:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
  if( strcmp(argv[1], "test") )
  {
    printf("Incorrect password\n");
  }
  else
  {
    printf("Correct password\n");
  }
  return 0;
}

用于劫持函数的.so代码hook.c

#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
/*
hook的目标是strcmp,所以typedef了一个STRCMP函数指针
hook的目的是要控制函数行为,从原库libc.so.6中拿到strcmp指针,保存成old_strcmp以备调用
*/
typedef int(*STRCMP)(const char*, const char*);

int strcmp(const char *s1, const char *s2)
{
  static void *handle = NULL;
  static STRCMP old_strcmp = NULL;

  if( !handle )
  {
    handle = dlopen("libc.so.6", RTLD_LAZY);
    old_strcmp = (STRCMP)dlsym(handle, "strcmp");
  }
  printf("oops!!! hack function invoked. s1=<%s> s2=<%s>\n", s1, s2);
  return old_strcmp(s1, s2);
}

编译:

gcc -o test main.c
gcc -fPIC -shared -o hook.so hook.c -ldl

运行:

LD_PRELOAD=./hook.so ./test 123
### 调试 glibc 中 `malloc` 函数的方法 #### 使用 GDB 进行调试 为了有效地调试 glibc 的 `malloc` 实现,可以利用 GNU Debugger (GDB),这是一个强大的工具,能够帮助开发者深入了解程序运行时的行为。 启动带有调试信息的应用程序并附加 GDB 是一种常见方法。确保编译应用程序时启用了调试选项 `-g`,以便获得更好的调试体验: ```bash gcc -o myapp -g myapp.c gdb ./myapp ``` 在 GDB 内部加载源码路径以访问 glibc 源文件有助于理解具体实现细节。对于基于 Debian/Ubuntu 系统而言,可以通过安装特定版本的 debug symbols 包来简化此过程,例如 `libc6-dbg` 或者更精确匹配当前使用的 libc 版本号的包[^1]。 #### 设置断点 针对 `malloc` 及其内部调用链路设置多个关键位置上的断点是非常有用的。考虑到实际执行流程可能涉及不同的入口点(如前所述),建议至少考虑以下几个方面: - **初始化阶段**:当首次调用 `malloc` 之前会触发一次性的初始化操作,在这里放置一个断点可以帮助观察环境配置情况以及线程私有数据结构创建的过程。 ```c b malloc_hook_ini ``` - **主要分配逻辑**:这是最核心的部分,负责处理不同大小请求的实际分配工作流。根据输入参数的不同会选择合适的算法分支来进行空间划分或映射。 ```c b __int_malloc b __libc_malloc ``` - **边界调整机制**:有时还需要关注与堆增长有关的操作,特别是涉及到系统调用层面的变化。 ```c b brk b sbrk ``` 这些命令会在每次遇到相应的函数调用时暂停程序执行,允许进一步检查变量状态、寄存器内容甚至单步跟踪指令级行为[^2]。 #### 查看内存布局 借助 GDB 提供的各种内置命令也可以方便地查看进程地址空间内的各个部分是如何被组织起来的,这对于诊断某些类型的错误特别有用。比如使用 `(gdb) info proc mappings` 可以展示目标进程中所有已映射段的信息;而像 `(gdb) x /8wx $sp` 这样的表达式则能快速浏览栈顶附近的几个机器字的内容[^4]。 另外值得注意的是,默认情况下由于性能原因很多优化措施会被开启,这可能会使得反汇编后的代码看起来比较复杂难以阅读。因此可以在测试前尝试关闭一些不必要的优化级别重新构建项目,从而让调试变得更加直观简单[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值