打桩代码

#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#define JMP_CMD	0xe9	//相对跳转指令 jmp xxx (总共长5个字节,后四个字节为地址)
						//0xff 绝对跳转指令:FF 
typedef struct stubInfo {
    void *funcAddr; //保存地址
	unsigned char byteCode[5]; //保存地址对应的指令
} stubInfo;

static void setJumpCode(void *codeAddr, char jumpCode[5])
{
   int pagesize = sysconf(_SC_PAGE_SIZE);//4096=0x1000
   if (mprotect((void*) ((unsigned long) codeAddr & (~(pagesize - 1))), pagesize, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {	//修改页面为可写
      return;
   }
   memcpy(codeAddr, jumpCode, 5);
}

void setStub(void *funcAddr, void *stubAddr, stubInfo *si)
{
    char jumpCode[5] = {0xe9}; //跳转指令
    int  dist = stubAddr - funcAddr - 5;	//相对偏移

    memcpy((void *)&jumpCode[1], (void *)&dist, sizeof(void *));
    si->funcAddr = funcAddr; //保存原函数的地址
    memcpy((void *)&si->byteCode[0], (void *)funcAddr, 5);	//保存原地址处的指令
    
	setJumpCode(funcAddr, jumpCode); //用跳转指令替换 原地址处的指令
	//此函数相当于:
	//*(char*)funcAddr=0xe9;
	//*(int*)((char*)funcAddr+1)=stubAddr-funcAddr-5;
}

void cleanStub(stubInfo *si)
{
    char   jumpCode[5]; //用来存放原地处的指令
    memcpy((void *)&jumpCode, (void *)&si->byteCode[0], 5);
    setJumpCode(si->funcAddr, jumpCode); //恢复原地址处的指令
	//(省略了还原原地址所在页的保护属性)
}
例:
int stub(){ //桩函数
        printf("this is stub func !\n");
        return 0;
}

int a(){  //测试函数,打桩点
        printf("this is a func !\n");
        return 0;
}

int main(){
        stubInfo si;
        setStub(a,stub,&si);
        a(); //此时会调用桩函数    
	cleanStub(&si);
        a();  

}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值