利用LD_PRELOAD进行hook

简介: 利用LD_PRELOAD进行hook

原文地址:http://hbprotoss.github.io/posts/li-yong-ld_preloadjin-xing-hook.html

 

好久没玩hook这种猥琐的东西里,今天在Linux下体验了一把。


loader在进行动态链接的时候,会将有相同符号名的符号覆盖成LD_PRELOAD指定的so文件中的符号。换句话说,可以用我们自己的so库中的函数替换原来库里有的函数,从而达到hook的目的。这和Windows下通过修改import table来hook API很类似。相比较之下,LD_PRELOAD更方便了,都不用自己写代码了,系统的loader会帮我们搞定。但是LD_PRELOAD有个限制:只能hook动态链接的库,对静态链接的库无效,因为静态链接的代码都写到可执行文件里了嘛,没有坑让你填。


上代码


先是受害者,我们的主程序main.c,通过strcmp比较字符串是否相等:


#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;
}


然后是用来hook的库hook.c:

#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
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("hack function invoked. s1=<%s> s2=<%s>\n", s1, s2);
    return old_strcmp(s1, s2);
}


因为hook的目标是strcmp,所以typedef了一个STRCMP函数指针。由于hook的目的是要控制函数行为,所以需要从原库libc.so.6中拿到“正版”strcmp指针,保存成old_strcmp以备调用。


Makefile:


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


执行:


$ LD_PRELOAD=./hook.so ./test 123
hack function invoked. s1=<123> s2=<test>
Incorrect password
$ LD_PRELOAD=./hook.so ./test test
hack function invoked. s1=<test> s2=<test>
Correct password


其中有一点不理解的是,dlopen打开libc.so.6能拿到“正版”strcmp地址,打开libc.so就是hook后的地址。照理说libc.so不是libc.so.6的一个软链吗?为什么结果会不一样嘞?


目录
相关文章
|
安全 Unix Linux
LD_PRELOAD劫持(超详细篇)
LD_PRELOAD劫持(超详细篇)
654 0
|
JavaScript
dyld: Library not loaded:解决办法
dyld: Library not loaded:解决办法
499 1
|
11月前
|
Ubuntu Linux 编译器
如何解决使用libevent时的共享库加载问题“error while loading shared libraries: libevent-2.1.so.7: cannot open ...“
如何解决使用libevent时的共享库加载问题“error while loading shared libraries: libevent-2.1.so.7: cannot open ...“
343 0
|
Linux
linux运行protoc出现错误 while loading shared libraries: libprotoc.so.19
linux运行protoc出现错误 while loading shared libraries: libprotoc.so.19
136 0
|
Android开发
【错误记录】NDK 动态库报错 ( dlopen failed: file offset for the library /lib/arm64/libwebp.so“ >= file size:0)
【错误记录】NDK 动态库报错 ( dlopen failed: file offset for the library /lib/arm64/libwebp.so“ >= file size:0)
454 0
【错误记录】NDK 动态库报错 ( dlopen failed: file offset for the library /lib/arm64/libwebp.so“ >= file size:0)
|
缓存 关系型数据库 MySQL
Linux环境变量设置(PATH/LIBRARY_PATH/LD_LIBRARY_PATH)
Linux环境变量设置(PATH/LIBRARY_PATH/LD_LIBRARY_PATH)
4614 0
如何解决:./real.exe: error while loading shared libraries: libhdf5hl_fortran.so.100: cannot open shared
如何解决:./real.exe: error while loading shared libraries: libhdf5hl_fortran.so.100: cannot open shared
如何解决:./real.exe: error while loading shared libraries: libhdf5hl_fortran.so.100: cannot open shared
mod_lua.cpp:37:10: fatal error: lua.h
mod_lua.cpp:37:10: fatal error: lua.h
90 0
|
Java Android开发 C++
preload-classes的前世今生(1)
Android的preload-classes是一种通过预加载来加快应用启动速度的好办法,这篇文章来讲如何针对某特定手机去实现自己预加载列表。
8091 0
|
C++
error LNK2005: DllMain 已经在MSVCRT.lib中定义
error LNK2005: DllMain 已经在MSVCRT.lib中定义
420 0