linux 下hook函数

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

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <string.h>
  6. #include <sys/mman.h>
  7. #include <errno.h>
  8. #include <unistd.h>

  9. void set_hook(void *to_mock_func, void *mock_func)
  10. {
  11.     uint8_t machine_code[] = {
  12.             //movq $0x0, %rax 后面8个字节的0为64位立即数
  13.             0x48, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  14.             //jmpq *%rax
  15.             0xff, 0xe0
  16.         };

  17.     int pagesize = sysconf(_SC_PAGE_SIZE);
  18.     if (pagesize == -1)
  19.     {
  20.         exit(errno);
  21.     }

  22.     uint8_t *mem = (uint8_t *) to_mock_func;
  23.     void *= (uint8_t*) (mem - ((uint64_t) mem % pagesize));
  24.     if (mprotect(p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC))
  25.     {
  26.         perror("mprotect error");
  27.         exit(errno);
  28.     }

  29.     //改写立即数为mock的地址,写入函数入口处
  30.     memcpy(machine_code + 2, &mock_func, sizeof(mock_func));
  31.     memcpy(mem, machine_code, sizeof(machine_code));

  32.     if (mprotect(p, pagesize, PROT_EXEC))
  33.     {
  34.         perror("mprotect error");
  35.         exit(errno);
  36.     }
  37. }

  38. using namespace std;
  39. class Cal
  40. {
  41. public:
  42.     int Sum(int a, int b, long c, long d, long e)
  43.     {
  44.         std::cout << "Cal::Sum called... " << std::endl;
  45.         return 0;
  46.     }
  47.     int m;
  48. };

  49. int MockCalSum(Cal *p, int a, int b, long c, long d, long e)
  50. {
  51.     int x = 0;
  52.     x += a + b + c + d;
  53.     std::cout << "MockCalSum called... " << std::endl;
  54.     p->= x;
  55.     return x;
  56. }

  57. int main()
  58. {
  59.     int a = 0;
  60.     int b = 1;
  61.     long c = 2;
  62.     long d = 3;
  63.     long e = 4;
  64.     Cal cal;
  65.     cal.Sum(a, b, c, d, e);
  66.     MockCalSum(&cal, a, b, c, d, e);
  67.     set_hook((void*)&Cal::Sum, (void*)MockCalSum);
  68.     cal.Sum(a, b, c, d, e);
  69.     return 0;
  70. }

你可能感兴趣的:(linux 下hook函数)