首页
社区
课程
招聘
[原创]自认为巧妙的ring3 HOOK模板,欢迎大牛指点
发表于: 2011-4-19 20:19 11997

[原创]自认为巧妙的ring3 HOOK模板,欢迎大牛指点

2011-4-19 20:19
11997

typedef struct _PUSH_CONTEXT { //represent pushad and pushfd on the stack
        DWORD dwEflags;
        DWORD dwEDI;
        DWORD dwESI;
        DWORD dwEBP;
        DWORD dwESP;
        DWORD dwEBX;
        DWORD dwEDX;
        DWORD dwECX;
        DWORD dwEAX;
} PUSH_CONTEXT, *PPUSH_CONTEXT;

void __cdecl get_data(LPVOID lpParam, const PUSH_CONTEXT context) //context 参数必须定义成传值,刚好和pushad,pushfd相对应
{
        //hook 后取数据的函数可以用C写了,呵呵
       
        return ;
}

/*
* 挂钩任意内存地址,并执行指定的函数,函数参数为lpParam
* 函数原型为 VOID __cdecl get_data(LPVOID lpParam, const PUSH_CONTEXT context);
* 要hook的地方不能有相对转移指令,如call,jmp等
* hook后执行lpHookProc时堆栈增加0x2C字节
* LPVOID lpHookAddress 要挂钩的地址
* DWORD dwHookLen 挂钩时要改写的长度
* LPVOID lpHookProc 挂钩后要执行的函数的地址
* LPVOID lpParam 挂钩后要执行的函数的参数,
* 次参数和CreateThread函数中线程函数的参数差不多
*/
BOOL CreateHook(LPVOID lpHookAddress, DWORD dwHookLen, LPVOID lpHookProc,LPVOID lpParam)
{
        DWORD dwOldProtect;
        LPVOID lpHookThunk;
        DWORD dwHookThunkStart;
        DWORD dwParamStart;
        DWORD dwHookThunkLen;
        UCHAR jmpCode[5] = {0x90,0x90,0x90,0x90,0x90};

        __asm
        {
                lea eax,ASM_HOOKTHUNK_START
                mov dword ptr[dwHookThunkStart],eax
                lea edx,ASM_HOOKTHUNK_END
                sub edx,eax
                mov dword ptr[dwHookThunkLen],edx
                lea edx,param
                sub edx,eax
                mov dword ptr[dwParamStart],edx
                jmp HookStart

        ASM_HOOKTHUNK_START:
                pushad
                pushfd
                call L1
        param:
                _emit 0x00
                _emit 0x00
                _emit 0x00
                _emit 0x00
                _emit 0x00
                _emit 0x00
                _emit 0x00
                _emit 0x00
        L1:
                pop eax
                push dword ptr[eax]
                call dword ptr[eax+0x04]
                add esp,0x04
                popfd
                popad
        ASM_HOOKTHUNK_END:
        }

HookStart:
        if(!VirtualProtect(lpHookAddress, dwHookLen, PAGE_EXECUTE_READWRITE,&dwOldProtect))
        {
#ifdef _DEBUG
                OutputDebugStringEx("CreateHook() can't change protect at address:0x%08X",lpHookAddress);
#endif
                return FALSE;
        }
        lpHookThunk = VirtualAlloc(NULL,dwHookThunkLen
                                        + dwHookLen
                                        + 5,
                                        MEM_COMMIT,
                                        PAGE_EXECUTE_READWRITE);
        if(lpHookThunk == NULL)
        {
                #ifdef _DEBUG
                        OutputDebugString("VirtualAlloc() failed in CreateHook()");
                #endif
                return FALSE;
        }

        memcpy(lpHookThunk,(void *)dwHookThunkStart,dwHookThunkLen); //copy hook thunk code
        *(LPVOID*)((DWORD)lpHookThunk + dwParamStart) = lpParam;
        *(LPVOID*)((DWORD)lpHookThunk + dwParamStart + 0x04) = lpHookProc;
        memcpy((LPVOID)((DWORD)lpHookThunk+dwHookThunkLen),lpHookAddress,dwHookLen); //copy old address's code
        jmpCode[0] = 0xE9;
        *(DWORD*)(&jmpCode[1]) = (DWORD)lpHookAddress + dwHookLen
          -        ((DWORD)lpHookThunk+dwHookThunkLen+dwHookLen+5);
        memcpy((LPVOID)((DWORD)lpHookThunk+dwHookThunkLen+dwHookLen),jmpCode,5); // make the code jump to old address

        jmpCode[0] = 0xE9;
        *(DWORD*)(&jmpCode[1]) =
        (DWORD)lpHookThunk - (DWORD)lpHookAddress - 5;
        __asm
        {
                mov ecx,0x05
                lea esi,jmpCode
                mov edi,dword ptr[lpHookAddress]
                rep movsb //create hook code
        }

        if(!VirtualProtect(lpHookAddress,dwHookLen,dwOldProtect,&dwOldProtect))
        {
#ifdef _DEBUG
                OutputDebugStringEx("CreateHook() can't restore old protect at address:0x%08X",lpHookAddress);
#endif
        };

        return TRUE;
}

typedef struct _MY_STRUCT
{
        char buf[256];//???
} MY_STRUCT;

void main()
{
        MY_STRUCT my_data;
        CreateHook((LPVOID)target_addr, 0x05/*??*/, (LPVOID)get_data, &my_data);
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (14)
雪    币: 94
活跃值: (455)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持WIN7么?
2011-4-20 08:01
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
3
用detour / mhook 的飘过...
2011-4-20 09:17
0
雪    币: 949
活跃值: (18)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
4
看起来挺复杂,有什么优点
2011-4-20 09:24
0
雪    币: 208
活跃值: (148)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
优点就是
hook 后,要跳到到自己的函数,自己的函数可以不用汇编写

在自己的函数中,直接用
context 参数就可以取拦截到的数据了

比如
context->dwEAX;
......
2011-4-20 11:17
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
太强大了,实在是用不上吖
2011-4-20 11:23
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
嗯,还行,哈哈。我上次写个有Pre和Post回调的R3 HOOK引擎,两个回调都是用原始参数,比如你hook ReadFile,那么Pre和Post函数就直接使用ReadFile一样的参数列表,回调函数里直接使用参数就可以获得相关数据,支持cdcel、stdcall、fastcall调用方式。
2011-4-20 11:42
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
嗯,用了,很好用。这个改一个下,即可用于ring0,膜拜楼主
2011-4-20 13:45
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
9
用了内联汇编,不支持64位啊。。
2011-4-20 15:55
0
雪    币: 62
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
咋那么像俺去年写的那个。。。。http://bbs.pediy.com/showthread.php?t=115449&highlight=
2011-4-20 17:00
0
雪    币: 88
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11

国内比较流行的有戏马很流行使用这一的hook方式..
大同小异,hook后就不用管了
2011-4-20 20:06
0
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
没意思,几百年前就写出来了
2011-5-7 10:09
0
雪    币: 107
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
进这个帖子 看了楼主的发言 然后大家说的都是自己干了什么  用了什么
讨论楼主的东西的。。。。基本没有
2011-5-7 13:51
0
雪    币: 203
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
嗯,还没习惯吗?国内没啥讨论的风气的,每个人都NB的很
2011-5-7 14:10
0
雪    币: 1602
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
巧妙,就是还没用到
2011-5-7 15:36
0
游客
登录 | 注册 方可回帖
返回
//