目录
hook
hook是什么
dlsym()函数
hook的实现步骤
加入hook的demo
C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂
hook
hook可以把系统或第三方库提供的函数,替换成我们写的同名函数。会调用我们实现的函数。
hook是什么
hook提供了两个接口;1. dlsym()是针对系统的,系统原始的api。2. dlopen()是针对第三方的库。
dlsym()函数
获取共享对象或可执行文件中符号的地址。
函数原型:
描述:
函数dlsym()接受dlopen()返回的动态加载共享对象的“句柄”以及以空结尾的符号名,并返回该符号加载到内存中的地址。如果在指定对象或加载对象时dlopen()自动加载的任何共享对象中找不到该符号,dlsym()将返回NULL。(dlsym()执行的搜索是通过这些共享对象的依赖关系树进行的广度优先搜索。)
handle中可以指定两个特殊的伪句柄:
返回值:
成功时,这些函数返回与符号关联的地址。
失败时,返回NULL;可以使用dlerror()诊断错误的原因。
hook的实现步骤
/* ******* ******************hook****************** ******* */
//第一步定义目标函数一样的类型
typedef int (*pthread_mutex_lock_t)(pthread_mutex_t *mutex);
typedef int (*pthread_mutex_unlock_t)(pthread_mutex_t *mutex);
pthread_mutex_lock_t pthread_mutex_lock_f;
pthread_mutex_unlock_t pthread_mutex_unlock_f;
//第二步实现目标函数名一致
//pthread_mutex_lock()会调用本函数
int pthread_mutex_lock(pthread_mutex_t *mutex) {
pthread_t selfid = pthread_self();
pthread_mutex_lock_f(mutex);
printf("pthread_mutex_lock: %ld, %p\n", selfid, mutex);
}
//pthread_mutex_unlock()会调用本函数
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
pthread_t selfid = pthread_self();
pthread_mutex_unlock_f(mutex);
printf("pthread_mutex_unlock: %ld, %p\n", selfid, mutex);
}
//第三步dlsym,放到main初始化
void init_hook(void) {
pthread_mutex_lock_f = dlsym(RTLD_NEXT, "pthread_mutex_lock");
pthread_mutex_unlock_f = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
}
加入hook的demo
//gcc Dead_lock.c -lpthread -ldl
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
/* ******* ******************hook****************** ******* */
//第一步定义目标函数一样的类型
typedef int (*pthread_mutex_lock_t)(pthread_mutex_t *mutex);
typedef int (*pthread_mutex_unlock_t)(pthread_mutex_t *mutex);
pthread_mutex_lock_t pthread_mutex_lock_f;
pthread_mutex_unlock_t pthread_mutex_unlock_f;
//第二步实现目标函数名一致
//pthread_mutex_lock()会调用本函数
int pthread_mutex_lock(pthread_mutex_t *mutex) {
pthread_t selfid = pthread_self();
pthread_mutex_lock_f(mutex);
printf("pthread_mutex_lock: %ld, %p\n", selfid, mutex);
}
//pthread_mutex_unlock()会调用本函数
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
pthread_t selfid = pthread_self();
pthread_mutex_unlock_f(mutex);
printf("pthread_mutex_unlock: %ld, %p\n", selfid, mutex);
}
//第三步dlsym,放到main初始化
void init_hook(void) {
pthread_mutex_lock_f = dlsym(RTLD_NEXT, "pthread_mutex_lock");
pthread_mutex_unlock_f = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
}
//测试代码
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex4 = PTHREAD_MUTEX_INITIALIZER;
void *thread_funcA(void *arg) {
pthread_mutex_lock(&mutex1);
sleep(1);
pthread_mutex_lock(&mutex2);
printf("thread_funcA\n");
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
}
void *thread_funcB(void *arg) {
pthread_mutex_lock(&mutex2);
sleep(1);
pthread_mutex_lock(&mutex3);
printf("thread_funcB\n");
pthread_mutex_unlock(&mutex3);
pthread_mutex_unlock(&mutex2);
}
void *thread_funcC(void *arg) {
pthread_mutex_lock(&mutex3);
sleep(1);
pthread_mutex_lock(&mutex4);
printf("thread_funcC\n");
pthread_mutex_unlock(&mutex4);
pthread_mutex_unlock(&mutex3);
}
void *thread_funcD(void *arg) {
pthread_mutex_lock(&mutex4);
sleep(1);
pthread_mutex_lock(&mutex1);
printf("thread_funcD\n");
pthread_mutex_unlock(&mutex1);
pthread_mutex_unlock(&mutex4);
}
int main() {
pthread_t tida, tidb, tidc, tidd;
init_hook();
pthread_create(&tida, NULL, thread_funcA, NULL);
pthread_create(&tidb, NULL, thread_funcB, NULL);
pthread_create(&tidc, NULL, thread_funcC, NULL);
pthread_create(&tidd, NULL, thread_funcD, NULL);
pthread_join(tida, NULL);
pthread_join(tidb, NULL);
pthread_join(tidc, NULL);
pthread_join(tidd, NULL);
return 0;
}