这个东西是在研究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相关推荐

  1. Linux系统接口ioc,Linux下SCSI API研究及应用

    Linux下SCSI API研究及应用 Linux SCSI体系结构及API数据结构的操作原理和相关的系统调用,运用SCSI API实现了有关的数据存储. 关键词: SCSI通用驱动器  SCSI接口 ...

  2. 在Windows/Linux下调用API函数实现重启系统

    一.Linux下重启系统 linux下很简单,直接看代码: #include <unistd.h> #include <sys/reboot.h>bool rebootSyst ...

  3. es linux下使用api进行es故障操作处理

    ES api记录: 在某些时候,我们没有安装ES kibana 及 es Head,那么就需要纯使用调用api的方式,执行某些操作,以下以linux为例,举例一些我平时常用的api,以供后续使用. 解 ...

  4. linux skype 接口,ubuntu /linux下skype api开发环境搭建

    1.安装Skype: 下载skype for linux,地址:http://www.skype.com/download/skype/linux/choose/ 可以下载一个ubuntu 8.10 ...

  5. linux下ALSA API采集声音遇到的坑

    alsa 的api网上一大把,昨天抄了个抓取程序放在自己的程序中,一读数据就崩溃,折腾了好久 alsa 声卡数据抓取函数原型: snd_pcm_sframes_t snd_pcm_readi (snd ...

  6. Linux 2.6 下通过 ptrace 和 plt 实现用户态 API Hook

    (转载兼整理)Linux 2.6 下通过 ptrace 和 plt 实现用户态 API Hook 这厮此文写的相当实用,不知道为啥不好好整理一下,得,我代劳了吧.作者:l04m33@gmail.com ...

  7. (转载兼整理)Linux 2.6 下通过 ptrace 和 plt 实现用户态 API Hook

    这厮此文写的相当实用,不知道为啥不好好整理一下,得,我代劳了吧.作者:l04m33@gmail.com,原文.去看一眼就知道我干嘛干这个脏活儿了... 感觉这篇文章有上首页的素质,可惜不是我自己写的, ...

  8. Linux下HOOK动态链接库中API的方法

    2012年,我写了一篇介绍Windows系统下Ring3层API的hook方案--<一种注册表沙箱的思路.实现--Hook Nt函数>,其在底层使用了微软的Detours库.5年后,我又遇 ...

  9. Linux下C++中可使用的3种Hook方法

    Hook即钩子,截获API调用的技术,是将执行流程重定向到你自己的代码,类似于hack.如使程序运行时调用你自己实现的malloc函数代替调用系统库中的malloc函数.这里介绍下Linux下C++中 ...

最新文章

  1. springboot静态资源访问
  2. 在Ubuntu下增加root用户
  3. Django报错SocialApp matching query does not exist以及Django的SITE_ID = 1的含义
  4. 一个好用的Visual Studio Code扩展 - Live Server,适用于前端小工具开发
  5. java servlet 3_java – Servlet 2.5和3之间有什么区别?
  6. 【Java架构师面试题】设计模式面试专题(共35题含答案)
  7. 如何让Mac电脑在Finder窗口顶部显示文件路径?
  8. 2015年7月15日 JS第一课(JS,声明变量,数据类型)
  9. Mybatis selectKey标签的keyProperty属性报错,关键字间隔不能有空格
  10. 关于身份证号两个格式转换的问题
  11. 图像处理R包magick学习笔记
  12. 电脑计算机显示向程序发送命令时出现问题,word提示向程序发送命令时出现问题怎么解决 wo...
  13. 在闲鱼实习是一种什么样的体验
  14. vin端口是什么意思_5G新在哪儿(6)?-天线端口的故事
  15. 把opencv Mat 按位存成bmp二值图像 (1bit 1pixel)(位深度为1)
  16. 普通话测试app怎么样可以不交钱_如何说普通话才算标准?
  17. 科目二 车速忽快忽慢
  18. 西南大学907专硕考研,西南大学计算机808学硕
  19. java后台报错cant found font [times New Roman] installed on the system
  20. Java 的核心目的和并发编程

热门文章

  1. 一车abs线路怎么量_神木沥青拌合站烧火油怎么购买更划算
  2. ai怎么画路线_AI换脸的本质是把颜值和表情分开
  3. web控制串口.html,[转]web串口调试助手,浏览器控制串口设备
  4. c语言字符串每个字母加4,C语言基础:各字符型数据
  5. oracle 树形结构表,树结构表递归查询在ORACLE和MSSQL中的实现方法
  6. AT3 two-dimensional surfaces : the sphere
  7. ResNeXt结构(code)
  8. YOLOv5瓷砖表面瑕疵质检
  9. 华为又对这一领域下手了,网友:太难了……
  10. PaddleOCR 文本检测训练+推理模型转换教程