Linux下的 API Hook
这个东西是在研究Linux下屏幕抓词的时候写的,用于观察相关API的运行情况。
HookFunc 是要先执行自己的代码,再执行目标程序。
HookFuncEx 是要先执行目标API,再到自己的函数中拦截结果。
要点:编译不要时不要采用优化选项,可以写成动态库,用LD_PRELOAD方式加载。
#define LEAVE_SPACE 40
#define JMP_ORGFUNC()\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
__asm__ __volatile__ ("nop");\
typedef struct FUNC_INFOTag
{
void *pFunc;
void *pHookFunc;
char cFuncName[32];
unsigned int nAsm;
unsigned char cAsm[16];//
}FUNC_INFO;
void HookFunc(const FUNC_INFO *pfi)
{
int nSize = getpagesize();
if ( mprotect((void *)((unsigned int)pfi->pFunc / nSize * nSize),nSize * 2,7) < 0)
{
#ifdef _HDEBUG_
printf("mprotect error 0, %s , address=%d\n",pfi->cFuncName,(unsigned int)pfi->pFunc / nSize * nSize);
#endif
return;
}
if ( mprotect((void *)((unsigned int)pfi->pHookFunc / nSize * nSize),nSize * 2,7) < 0)
{
#ifdef _HDEBUG_
printf("mprotect error 1, %s , address=%d\n",pfi->cFuncName,(unsigned int)pfi->pHookFunc / nSize * nSize);
#endif
return;
}
unsigned char *pc0 = (unsigned char *)pfi->pFunc;
unsigned int *pn0 = (unsigned int *)(pc0+1);
if (pc0[0] == 0xe9)
{
#ifdef _HDEBUG_
printf("%s, is allready hooked!\n",pfi->cFuncName);
#endif
return;
}
memcpy((void *)pfi->cAsm,(void *)pc0,pfi->nAsm);
*pc0=0xe9;
*pn0 = (unsigned int)pfi->pHookFunc - (unsigned int)pfi->pFunc - 5 ;
unsigned char *pc1 = (unsigned char *)pfi->pHookFunc;
int i = 0;
int j;
int nFind;
while(1)
{//leave=0xc9
nFind = 1;
for (j = 0; j < LEAVE_SPACE; j++)
{
if (pc1[i+j] != 0x90)
{
nFind = 0;
break;
}
}
if ( nFind == 1)
{
break;
}
i++;
}
pc1 += i;//first nop
i = LEAVE_SPACE;
while(1)
{//leave=0xc9//pc1[i]==0xc3)
nFind = ((pc1[i]==0x55) && (pc1[i+1]==0x89) && (pc1[i+2]==0xe5));
if ( nFind != 0 )
{
break;
}
i++;
}
while (1)
{
if (pc1[i] == 0xc3)
{//
break;
}
i--;
}
int nCopyNumber = i - LEAVE_SPACE;
//
memcpy(pc1,pc1 + LEAVE_SPACE, nCopyNumber);
pc1 += nCopyNumber;
//
memcpy(pc1, pfi->cAsm,pfi->nAsm);
//add jmp
pc1 += pfi->nAsm;
*pc1 = 0xe9;
pc1++;
unsigned int *pn1 = (unsigned int *)(pc1);
pc1+=4;
*pn1 = (unsigned int)(pc0 + pfi->nAsm ) - (unsigned int)(pc1) ;
}
void HookFuncEx(const FUNC_INFO *pfi, int nParaSize)
{
int nSize = getpagesize();
if ( mprotect((void *)((unsigned int)pfi->pFunc / nSize * nSize),nSize * 2,7) < 0)
{
#ifdef _HDEBUG_
printf("mprotect error 0, %s , address=%d\n",pfi->cFuncName,(unsigned int)pfi->pFunc / nSize * nSize);
#endif
return;
}
if ( mprotect((void *)((unsigned int)pfi->pHookFunc / nSize * nSize),nSize * 2,7) < 0)
{
#ifdef _HDEBUG_
printf("mprotect error 1, %s , address=%d\n",pfi->cFuncName,(unsigned int)pfi->pHookFunc / nSize * nSize);
#endif
return;
}
unsigned char *pc0 = (unsigned char *)pfi->pFunc;
unsigned int *pn0 = (unsigned int *)(pc0+1);
if (pc0[0] == 0xe9)
{
#ifdef _HDEBUG_
printf("%s, is allready hooked!\n",pfi->cFuncName);
#endif
return;
}
memcpy((void *)pfi->cAsm,(void *)pc0,pfi->nAsm);
*pc0=0xe9;
*pn0 = (unsigned int)pfi->pHookFunc - (unsigned int)pfi->pFunc - 5 ;
unsigned char *pc1 = (unsigned char *)pfi->pHookFunc;
int i = 0;
int j;
int nFind;
while(1)
{//leave=0xc9
nFind = 1;
for (j = 0; j < LEAVE_SPACE * 10; j++)
{
if (pc1[i+j] != 0x90)
{
nFind = 0;
break;
}
}
if ( nFind == 1)
{
break;
}
i++;
}
// move my code
memcpy(pc1 + LEAVE_SPACE * 10, pc1, i);
//804f8aa: 55 push %ebp
//804f8ab: 89 e5 mov %esp,%ebp
*pc1++=(unsigned char)0x55;
*pc1++=(unsigned char)0x89;
*pc1++=(unsigned char)0xe5;
//804f8ae: 83 ec 34 sub $0x34,%esp
*pc1++=(unsigned char)0x83;
*pc1++=(unsigned char)0xec;
*pc1++=(unsigned char)nParaSize + 4;
for (i= 0 ;i < nParaSize; i++)
{
//804efee: 8a 45 01 mov 0x1(%ebp),%al
//804eff1: 88 44 24 01 mov %al,0x1(%esp)
*pc1++= (unsigned char)0x8a;
*pc1++= (unsigned char)0x45;
*pc1++= (unsigned char)(0x8 + i);
*pc1++= (unsigned char)0x88;
*pc1++= (unsigned char)0x44;
*pc1++= (unsigned char)0x24;
*pc1++= (unsigned char)(0x0 + i);
}
// 804efee: 68 ff ff ff ff push 0xffffffff
*pc1 ++= (unsigned char)0x68;
*((unsigned int *)(pc1)) = (unsigned int)(pc1 + 4 + pfi->nAsm + 5 );
pc1 += 4;
memcpy(pc1, pfi->cAsm,pfi->nAsm);
pc1+= pfi->nAsm;
//jmp XXXXXXX
*pc1 ++= (unsigned char)0xe9;
*((unsigned int *)(pc1)) = (unsigned int)(pc0 + pfi->nAsm ) - (unsigned int)(pc1 + 4);
pc1 += 4;
*pc1++=(unsigned char)0xc9;
}
下面是Hook的例子:
//先执行目标程序,拦截返回值,需要用HookFuncEx方式。
Picture XRenderCreatePictureHook (Display *dpy,
Drawable drawable,
_Xconst XRenderPictFormat *format,
unsigned long valuemask,
_Xconst XRenderPictureAttributes *attributes)
{
JMP_ORGFUNC();
JMP_ORGFUNC();
JMP_ORGFUNC();
JMP_ORGFUNC();
JMP_ORGFUNC();
JMP_ORGFUNC();
JMP_ORGFUNC();
JMP_ORGFUNC();
JMP_ORGFUNC();
JMP_ORGFUNC();
Picture picture = 0;
__asm__ __volatile__ ("mov %%eax,%0":"=g"(picture));
//your code .....
#ifdef _HDEBUG_
printf("XRenderCreatePictureHook : Picture=%x, Drawable=%x\n", picture, drawable);
#endif
return picture;
}
//先执行拦截程序,用HookFunc方式。
void XRenderFreePictureHook (Display *dpy, Picture picture)
{
#ifdef _HDEBUG_
printf("XRenderFreePictureHook: display=%x, picture=%x\n",dpy,picture);
#endif
//your code .....
JMP_ORGFUNC();
return;
}
调用:
FUNC_INFO _g_func_infos[] ={
{0,(void *)XRenderCreatePictureHook,"XRenderCreatePicture",5,""},
{0,(void *)XRenderFreePictureHook,"XRenderFreePicture",6,""}
}
HookFuncEx(&_g_func_infos[0], 20);
HookFunc(&_g_func_infos[1]);
转载于:https://blog.51cto.com/laokaddk/496024
Linux下的 API Hook相关推荐
- Linux系统接口ioc,Linux下SCSI API研究及应用
Linux下SCSI API研究及应用 Linux SCSI体系结构及API数据结构的操作原理和相关的系统调用,运用SCSI API实现了有关的数据存储. 关键词: SCSI通用驱动器 SCSI接口 ...
- 在Windows/Linux下调用API函数实现重启系统
一.Linux下重启系统 linux下很简单,直接看代码: #include <unistd.h> #include <sys/reboot.h>bool rebootSyst ...
- es linux下使用api进行es故障操作处理
ES api记录: 在某些时候,我们没有安装ES kibana 及 es Head,那么就需要纯使用调用api的方式,执行某些操作,以下以linux为例,举例一些我平时常用的api,以供后续使用. 解 ...
- linux skype 接口,ubuntu /linux下skype api开发环境搭建
1.安装Skype: 下载skype for linux,地址:http://www.skype.com/download/skype/linux/choose/ 可以下载一个ubuntu 8.10 ...
- linux下ALSA API采集声音遇到的坑
alsa 的api网上一大把,昨天抄了个抓取程序放在自己的程序中,一读数据就崩溃,折腾了好久 alsa 声卡数据抓取函数原型: snd_pcm_sframes_t snd_pcm_readi (snd ...
- Linux 2.6 下通过 ptrace 和 plt 实现用户态 API Hook
(转载兼整理)Linux 2.6 下通过 ptrace 和 plt 实现用户态 API Hook 这厮此文写的相当实用,不知道为啥不好好整理一下,得,我代劳了吧.作者:l04m33@gmail.com ...
- (转载兼整理)Linux 2.6 下通过 ptrace 和 plt 实现用户态 API Hook
这厮此文写的相当实用,不知道为啥不好好整理一下,得,我代劳了吧.作者:l04m33@gmail.com,原文.去看一眼就知道我干嘛干这个脏活儿了... 感觉这篇文章有上首页的素质,可惜不是我自己写的, ...
- Linux下HOOK动态链接库中API的方法
2012年,我写了一篇介绍Windows系统下Ring3层API的hook方案--<一种注册表沙箱的思路.实现--Hook Nt函数>,其在底层使用了微软的Detours库.5年后,我又遇 ...
- Linux下C++中可使用的3种Hook方法
Hook即钩子,截获API调用的技术,是将执行流程重定向到你自己的代码,类似于hack.如使程序运行时调用你自己实现的malloc函数代替调用系统库中的malloc函数.这里介绍下Linux下C++中 ...
最新文章
- springboot静态资源访问
- 在Ubuntu下增加root用户
- Django报错SocialApp matching query does not exist以及Django的SITE_ID = 1的含义
- 一个好用的Visual Studio Code扩展 - Live Server,适用于前端小工具开发
- java servlet 3_java – Servlet 2.5和3之间有什么区别?
- 【Java架构师面试题】设计模式面试专题(共35题含答案)
- 如何让Mac电脑在Finder窗口顶部显示文件路径?
- 2015年7月15日 JS第一课(JS,声明变量,数据类型)
- Mybatis selectKey标签的keyProperty属性报错,关键字间隔不能有空格
- 关于身份证号两个格式转换的问题
- 图像处理R包magick学习笔记
- 电脑计算机显示向程序发送命令时出现问题,word提示向程序发送命令时出现问题怎么解决 wo...
- 在闲鱼实习是一种什么样的体验
- vin端口是什么意思_5G新在哪儿(6)?-天线端口的故事
- 把opencv Mat 按位存成bmp二值图像 (1bit 1pixel)(位深度为1)
- 普通话测试app怎么样可以不交钱_如何说普通话才算标准?
- 科目二 车速忽快忽慢
- 西南大学907专硕考研,西南大学计算机808学硕
- java后台报错cant found font [times New Roman] installed on the system
- Java 的核心目的和并发编程
热门文章
- 一车abs线路怎么量_神木沥青拌合站烧火油怎么购买更划算
- ai怎么画路线_AI换脸的本质是把颜值和表情分开
- web控制串口.html,[转]web串口调试助手,浏览器控制串口设备
- c语言字符串每个字母加4,C语言基础:各字符型数据
- oracle 树形结构表,树结构表递归查询在ORACLE和MSSQL中的实现方法
- AT3 two-dimensional surfaces : the sphere
- ResNeXt结构(code)
- YOLOv5瓷砖表面瑕疵质检
- 华为又对这一领域下手了,网友:太难了……
- PaddleOCR 文本检测训练+推理模型转换教程