| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1171 人关注过本帖
标题:【原创】抽丝剥茧InlineHook
只看楼主 加入收藏
五当家
Rank: 12Rank: 12Rank: 12
等 级:火箭侠
威 望:2
帖 子:1112
专家分:3674
注 册:2010-10-20
结帖率:96.3%
收藏
 问题点数:0 回复次数:2 
【原创】抽丝剥茧InlineHook
这是一篇我自己学习InlineHook的笔记,网上代码很多,但都没详细解释细节,于是了这篇文章算是给自己复习用.
自学编程,有不对的地方请指正.

//首先我们不Hook系统API函数,写2个函数一个加法,一个减法。

int add(int a,int b)
{
    printf("这里是加法");
    return a+b;
}

int sub(int a,int b)
{
    printf("这里是减法");
    return a-b;
}

//把hook 操作封装在这个函数下

void Inlinehook()
{
    //取到2个函数地址
    DWORD addrAdd= (DWORD)add;
    DWORD addrSub =(DWORD)sub;
   
    *(BYTE *)addrAdd = 0xE9;  //!!!!!
    *(DWORD *)addrAdd = (DWORD) (addrSub - addrAdd - 5);//!!!!!

    //下面通过调试一个函数看看上面2步的意思
    //void main()
    //{
    //    add(10,20); 这里下断点进行调试 ==》转到反汇编
    //}
    //004115B5  push        20    ==>跟进
    //004115B7  push        10    ==>跟进
    //004115B9  call        add (4110A0h) ==>跟进 调用add函数
     //004110A0  jmp         add (4113E0h)  ==>jmp 到add 地址
    //看到了吗?
    //函数首5字节是jmp指令, jmp xxxx , jmp 的机器码为:0xE9  
    //剩下的4个字节是相对偏移地址 计算方式:【我们的函数地址 - 被hook函数地址 - 5】
    //那么-5 干什么,因为jmp指令要占用5个字节
}
//开始写程序测试下 ,看看调用 add 函数能不能进入sub函数

void main()
{
    add(10,20);
}
//运行是不是报错了?因为我们是跑在保护模式下的,内存是不能随意改变的
//因此需要改变内存的保护属性改为PAGE_EXECUTE_READWRITE
//把Inlinehook 函数改成下面形式
void Inlinehook()
{
    DWORD addrAdd= (DWORD)add;
    DWORD addrSub =(DWORD)sub;
    //修改add函数0偏移处5字节为PAGE_EXECUTE_READWRITE
    MEMORY_BASIC_INFORMATION mbi;
    VirtualProtect((LPVOID)addrAdd,5,PAGE_EXECUTE_READWRITE,&(mbi.Protect));

    *(BYTE *)addrAdd = 0xE9;
    *(DWORD *)addrAdd = (DWORD) (addrSub - addrAdd - 5);
}
//再次测试下
void main()
{
    add(10,20);
    //输出结果为:这里是减法
}
//结果成功进入sub函数 说明InlineHook成功了

//*********************************************如果上面你能成功测试,就可以去hook一下系统api了,**************************************************
//测试函数FindWindowA,原理是一样的我就不赘述了
贴上代码
#include "stdafx.h"
#include "windows.h"
#include "Winnt.h"


struct FIVE
{
    unsigned int first;
    unsigned long four;
}five;

typedef HWND (*RealFindWindowA)(LPCSTR clsName,LPCSTR winName);
RealFindWindowA realFindWindowA;

DWORD g_old_addr;

HWND My_FindWindowA(LPCSTR clsName,LPCSTR winName)
{
    *(BYTE *)g_old_addr = (BYTE)five.first;
    *(DWORD *)(g_old_addr+1) = (DWORD)five.four;

    realFindWindowA = (RealFindWindowA)g_old_addr;
   

    if(strcmp(winName,"无标题 - 记事本") ==0)
    {
        MessageBoxA(NULL,"FindWindowA被成功InlineHook","xx",MB_OK);
        return (HWND)-1;
    }

    return realFindWindowA(clsName,winName);
}

void main()
{
    DWORD addr = (DWORD)add;

    DWORD old_addr = (DWORD)GetProcAddress(LoadLibraryA("user32.dll"),"FindWindowA");
    g_old_addr = old_addr;
    DWORD my_addr = (DWORD)My_FindWindowA;
   
    MEMORY_BASIC_INFORMATION mbi;
    VirtualProtect((LPVOID)old_addr,5,PAGE_EXECUTE_READWRITE,&(mbi.Protect));
    five.first = *(BYTE *)old_addr;
    five.four = *(DWORD *)(old_addr+1);
    *(LPBYTE)old_addr= 0xE9;
    *(LPDWORD)(old_addr+1) = (DWORD)(my_addr-old_addr-5);

    FindWindowA(NULL,"无标题 - 记事本");
}

//这些都是简单的操作,毕竟这样的函数都是公开的,对未公开的函数就要定位内存来进行hook了
//有不对的地方请指正

[ 本帖最后由 五当家 于 2011-12-22 13:43 编辑 ]
收到的鲜花
  • zaixuexi2011-12-22 10:26 送鲜花  50朵   附言:鼓励原创
搜索更多相关主题的帖子: return 文章 
2011-12-22 08:35
zaixuexi
Rank: 12Rank: 12Rank: 12
来 自:上海
等 级:火箭侠
威 望:8
帖 子:858
专家分:3233
注 册:2010-12-1
收藏
得分:0 
上面有2句+1写漏了吧
*(DWORD *)(addrAdd + 1)= (DWORD) (addrSub - addrAdd - 5);//!!!!!
*(DWORD *)(addrAdd + 1) = (DWORD) (addrSub - addrAdd - 5);
//再次测试下
void main()
{
    Inlinehook();先调用一下
    add(10,20);
    //输出结果为:这里是减法
}


技术问题,请不要以短消息方式提问
2011-12-22 10:22
五当家
Rank: 12Rank: 12Rank: 12
等 级:火箭侠
威 望:2
帖 子:1112
专家分:3674
注 册:2010-10-20
收藏
得分:0 
嗯,忘了

经验积累中............
2011-12-22 13:22
快速回复:【原创】抽丝剥茧InlineHook
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023819 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved