首页
社区
课程
招聘
比较稳定的ring3 API HeadInline HOOK,QQ显IP。。
发表于: 2013-6-28 20:25 17264

比较稳定的ring3 API HeadInline HOOK,QQ显IP。。

2013-6-28 20:25
17264
上次发的帖子觉得里面的hook方式不稳定,这次自己写一个,测试beta5版qq的时候可以使用了,上次发的bin在beta5版里会挂。

看到有不妥的地方,请告诉我,发帖的目的就是这个!

InterlockedExchange64这个函数在XP里不能用(ring3下),其实是使用lock cmpxchg8b指令,从ring0的bin里抠出来一个,组织成函数方便使用。

码如下:(dll工程,编译要去掉gs开关,还有一处需要注意的地方,见注释)

#include <windows.h>
#include <stdio.h>

#pragma comment(lib,"ws2_32")

#pragma pack(1)

typedef struct
{
    BYTE   jmp;
    int    address;
    BYTE   byte_3[3];
} JUMPCODE, *PJUMPCODE;

BYTE  characteristic[8] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0, 0, 0};
DWORD  pOrigFunc;
DWORD  RetAddr = 0;

LONGLONG _declspec(naked) _cdecl InlockExchange64 ( IN OUT LONGLONG volatile *Destination, IN LONGLONG ExChange)
{
        _asm
    {
        push    ebp
        mov     ebp, esp
            push    edi
            push    ebx
            push    edx

            mov     edi, [ebp+8]
            mov     eax, [edi]
            mov     edx, [edi+4]
            mov     ebx, dword ptr [ebp+0Ch]
            mov     ecx, dword ptr [ebp+0Ch+4]

            lock cmpxchg8b qword ptr [edi]

            pop     edx
            pop     ebx
            pop     edi
        mov     ebp, esp
        pop     ebp
        retn
    }
}

int __stdcall my_sendto(
                        SOCKET s,                        
                        const char FAR *buf,            
                        int len,                         
                        int flags,                       
                        const struct sockaddr FAR *to,  
                        int tolen                        
                        );

DWORD WINAPI my_thread(LPVOID lp);

int hook(PCSTR pszDllName, PCSTR pszFunctionName, DWORD hackfunc);

BOOL APIENTRY DllMain( HANDLE hModule, 
                      DWORD  ul_reason_for_call, 
                      LPVOID lpReserved
                      )
{
    DWORD dwOldProtect;
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        {
            OutputDebugString("-->[hook_sendto]\n");
            CreateThread(0, 0, my_thread, 0, 0, 0);
            break;
        }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        {
            OutputDebugString("<--[hook_sendto]\n");
            if (RetAddr)
            {
                VirtualProtect((PVOID)pOrigFunc, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect);

                InlockExchange64((PLONGLONG)pOrigFunc, *(PLONGLONG)&characteristic[0]);

                VirtualProtect((PVOID)pOrigFunc, 8, dwOldProtect, &dwOldProtect);
            }
            break;
        }
    }
    return TRUE;
}

DWORD WINAPI my_thread(LPVOID lp)
{
    hook("ws2_32.dll", "sendto", (DWORD)my_sendto);
    return 0;
}

int hook(PCSTR pszDllName, PCSTR pszFunctionName, DWORD hackfunc)
{
    HMODULE   hDll;
    JUMPCODE  jmpcode;
    DWORD     dwOldProtect;

        hDll = GetModuleHandle(pszDllName);
    if(hDll == NULL)
    {
        OutputDebugString("GetModuleHandle()");
        return 0;
    }

    pOrigFunc = (DWORD)GetProcAddress(hDll, pszFunctionName);
    if(pOrigFunc == NULL)
    {
        OutputDebugString("GetProcAddress()");
        return 0;
    }

    if (memcmp((PVOID)pOrigFunc, characteristic, 5))
    {
        OutputDebugString("memcmp()不相等");
        return 0;
    }

    jmpcode.jmp = 0xe9;
    jmpcode.address  = hackfunc - pOrigFunc - 5;
    jmpcode.byte_3[0] = *(PCHAR)(pOrigFunc + 5);
    jmpcode.byte_3[1] = *(PCHAR)(pOrigFunc + 6);
    jmpcode.byte_3[2] = *(PCHAR)(pOrigFunc + 7);

    characteristic[5] = *(PCHAR)(pOrigFunc + 5);
    characteristic[6] = *(PCHAR)(pOrigFunc + 6);
    characteristic[7] = *(PCHAR)(pOrigFunc + 7);

    VirtualProtect((PVOID)pOrigFunc, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect);

    InlockExchange64((PLONGLONG)pOrigFunc, *(PLONGLONG)&jmpcode);

    VirtualProtect((PVOID)pOrigFunc, 8, dwOldProtect, &dwOldProtect);

    RetAddr = pOrigFunc + 5;

    return 1;
}

int __stdcall my_sendto(
                        SOCKET s,                        
                        const char FAR *buf,            
                        int len,                         
                        int flags,                       
                        const struct sockaddr FAR *to,  
                        int tolen                        
                        )
{
    char  buff[22];

    if(len >= 27)
    {
        if (*(DWORD*)buf == 0x10003)
        {
            memset(buff, 0, sizeof(buff));
            sprintf(&buff[strlen(buff)], "=IP: %s\n", inet_ntoa(((struct sockaddr_in *)to)->sin_addr));
            OutputDebugString(buff);
        }
    }  

    __asm
    {
        pop esi    // 反编译后看到我的编译器会push esi
        add esp, 18h    // 反编译后看到我的编译器会sub esp, 18h
        mov eax, RetAddr
        jmp eax
    }
}

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

上传的附件:
收藏
免费 5
支持
分享
最新回复 (26)
雪    币: 154
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
2
原来QQ显ip原理是这样的啊,学习了
2013-6-28 20:34
0
雪    币: 437
活跃值: (78)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错的资源,楼主辛苦了。
2013-6-28 20:47
0
雪    币: 19
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
mark , 回头看看. thanks for share!
2013-6-28 21:24
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢分享,先mark
2013-6-29 00:04
0
雪    币: 276
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这个没什么用吧
2013-6-29 07:27
0
雪    币: 12
活跃值: (395)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我愚昧的问一下,这是不是hook了send函数呀?
2013-7-20 21:05
0
雪    币: 284
活跃值: (3389)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
8
是的。。
2013-7-20 21:18
0
雪    币: 42
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
我似乎懂一点了。爪机mark
2013-7-26 11:31
0
雪    币: 2480
活跃值: (2503)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢楼主分享。
2013-7-26 13:51
0
雪    币: 284
活跃值: (3389)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
11
xxxxx
2013-7-26 14:20
0
雪    币: 1392
活跃值: (4867)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
12
我记得现在的QQ都是服务器中转了,这种方法应该不行了
2013-9-7 20:14
0
雪    币: 623
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
mark
2013-9-7 20:15
0
雪    币: 441
活跃值: (149)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
14
现在QQ消息,在一个设备上发的内容,比如手机QQ,电脑上要是同时登录了,也会收到,所以,消息应该是经过腾讯服务器了,还有聊天记录可以保存7天,所以数据肯定是经过服务器的才能实现这个功能
2013-9-7 20:22
0
雪    币: 1392
活跃值: (4867)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
15
如果都在线的话是可以用这种方法的。
如果不在线或者隐身就不行了
2013-9-7 20:54
0
雪    币: 216
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16
内联汇编的InlockExchange64,可以把ebp,esp的那头两行,和尾两行去除. 这个VC帮你做了, 不信你OLLYDBG看看就知道了.
2013-9-13 01:23
0
雪    币: 342
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
楼上知道 啥是naked不 不知道别乱说误导新人哦
2013-9-14 01:20
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kec
18
以后看看。。。。
2013-9-14 10:08
0
雪    币: 216
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
不懂哦, 我说的是VC++的内联汇编.
2013-9-21 17:07
0
雪    币: 14
活跃值: (24)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
谢谢楼主了 很有帮助!!!
2013-9-21 17:14
0
雪    币: 1254
活跃值: (630)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
21
inline hook最大的问题是大家都hook同一个函数,如何处理稳定,这才是关键。
2013-9-22 10:21
0
雪    币: 200
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
mark了哦,好东西
2014-1-6 14:31
0
雪    币: 4458
活跃值: (3874)
能力值: ( LV8,RANK:138 )
在线值:
发帖
回帖
粉丝
23
好东西,楼主辛苦了。
2014-1-9 13:58
0
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
24
不错不错
2014-1-9 18:26
0
雪    币: 284
活跃值: (3389)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
25
[QUOTE=瀚海云烟;1254248]哎,你这个代码基本无效的,因为装了迅雷以后的 speed_viewer1.0.2.32.dll 肯定会去hook send recv sendto recvfrom 等函数的
[/QUOTE]

我很不理解,都是在看雪上发帖的。
你费力截了两张图,证明了我6月多发的一份示例代码,在安装了某软件以后会失效的事情。
你想证明什么?
2014-1-9 19:05
0
游客
登录 | 注册 方可回帖
返回
//