hook在windows下可以说是知名度相当高的一种"高级“技术
想在linux下面实现像windows下的那种hook的功能,不过网上的资料很少(LD_PRELOAD 也可以做类似的事)
自己研究了下,写了个类似功能的函数
思想很简单,就在运行时把一个函数的入口改成jmp到另一个地址
想在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;
- }