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