hook在windows下可以说是知名度相当高的一种"高级“技术
想在linux下面实现像windows下的那种hook的功能,不过网上的资料很少(LD_PRELOAD 也可以做类似的事)
自己研究了下,写了个类似功能的函数
思想很简单,就在运行时把一个函数的入口改成jmp到另一个地址
-
#include <iostream>
-
#include <stdlib.h>
-
#include <stdio.h>
-
#include <stdint.h>
-
#include <string.h>
-
#include <sys/mman.h>
-
#include <errno.h>
-
#include <unistd.h>
-
-
void set_hook(void *to_mock_func, void *mock_func)
-
{
-
uint8_t machine_code[] = {
-
//movq $0x0, %rax 后面8个字节的0为64位立即数
-
0x48, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
-
//jmpq *%rax
-
0xff, 0xe0
-
};
-
-
int pagesize = sysconf(_SC_PAGE_SIZE);
-
if (pagesize == -1)
-
{
-
exit(errno);
-
}
-
-
uint8_t *mem = (uint8_t *) to_mock_func;
-
void *p = (uint8_t*) (mem - ((uint64_t) mem % pagesize));
-
if (mprotect(p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC))
-
{
-
perror("mprotect error");
-
exit(errno);
-
}
-
-
//改写立即数为mock的地址,写入函数入口处
-
memcpy(machine_code + 2, &mock_func, sizeof(mock_func));
-
memcpy(mem, machine_code, sizeof(machine_code));
-
-
if (mprotect(p, pagesize, PROT_EXEC))
-
{
-
perror("mprotect error");
-
exit(errno);
-
}
-
}
-
-
using namespace std;
-
class Cal
-
{
-
public:
-
int Sum(int a, int b, long c, long d, long e)
-
{
-
std::cout << "Cal::Sum called... " << std::endl;
-
return 0;
-
}
-
int m;
-
};
-
-
int MockCalSum(Cal *p, int a, int b, long c, long d, long e)
-
{
-
int x = 0;
-
x += a + b + c + d;
-
std::cout << "MockCalSum called... " << std::endl;
-
p->m = x;
-
return x;
-
}
-
-
int main()
-
{
-
int a = 0;
-
int b = 1;
-
long c = 2;
-
long d = 3;
-
long e = 4;
-
Cal cal;
-
cal.Sum(a, b, c, d, e);
-
MockCalSum(&cal, a, b, c, d, e);
-
set_hook((void*)&Cal::Sum, (void*)MockCalSum);
-
cal.Sum(a, b, c, d, e);
-
return 0;
-
}
阅读(4215) | 评论(0) | 转发(0) |