首页
论坛
课程
招聘
比较稳定的ring3 API HeadInline HOOK,QQ显IP。。
2013-6-28 20:25 15660

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

2013-6-28 20:25
15660
上次发的帖子觉得里面的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
    }
}

[培训] 优秀毕业生寄语:恭喜id咸鱼炒白菜拿到远超3W月薪的offer,《安卓高级研修班》火热招生!!!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (26)
雪    币: 142
活跃值: 活跃值 (29)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
山村野人 活跃值 1 2013-6-28 20:34
2
0
原来QQ显ip原理是这样的啊,学习了
雪    币: 819
活跃值: 活跃值 (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zyicai 活跃值 2013-6-28 20:47
3
0
不错的资源,楼主辛苦了。
雪    币: 19
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
foolday 活跃值 2013-6-28 21:24
4
0
mark , 回头看看. thanks for share!
雪    币: 238
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
封心锁爱 活跃值 2013-6-29 00:04
5
0
感谢分享,先mark
雪    币: 276
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
loveqqc 活跃值 2013-6-29 07:27
6
0
这个没什么用吧
雪    币: 12
活跃值: 活跃值 (72)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
moonkit 活跃值 2013-7-20 21:05
7
0
我愚昧的问一下,这是不是hook了send函数呀?
雪    币: 290
活跃值: 活跃值 (824)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
囧囧 活跃值 2013-7-20 21:18
8
0
是的。。
雪    币: 38
活跃值: 活跃值 (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
jaix 活跃值 2013-7-26 11:31
9
0
我似乎懂一点了。爪机mark
雪    币: 228
活跃值: 活跃值 (104)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xuezhimeng 活跃值 2013-7-26 13:51
10
0
谢谢楼主分享。
雪    币: 290
活跃值: 活跃值 (824)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
囧囧 活跃值 2013-7-26 14:20
11
0
xxxxx
雪    币: 2921
活跃值: 活跃值 (736)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
IamHuskar 活跃值 4 2013-9-7 20:14
12
0
我记得现在的QQ都是服务器中转了,这种方法应该不行了
雪    币: 613
活跃值: 活跃值 (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
天高 活跃值 2013-9-7 20:15
13
0
mark
雪    币: 410
活跃值: 活跃值 (91)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
rockhard 活跃值 4 2013-9-7 20:22
14
0
现在QQ消息,在一个设备上发的内容,比如手机QQ,电脑上要是同时登录了,也会收到,所以,消息应该是经过腾讯服务器了,还有聊天记录可以保存7天,所以数据肯定是经过服务器的才能实现这个功能
雪    币: 2921
活跃值: 活跃值 (736)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
IamHuskar 活跃值 4 2013-9-7 20:54
15
0
如果都在线的话是可以用这种方法的。
如果不在线或者隐身就不行了
雪    币: 209
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
sertty 活跃值 1 2013-9-13 01:23
16
0
内联汇编的InlockExchange64,可以把ebp,esp的那头两行,和尾两行去除. 这个VC帮你做了, 不信你OLLYDBG看看就知道了.
雪    币: 125
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
killalarm 活跃值 2013-9-14 01:20
17
0
楼上知道 啥是naked不 不知道别乱说误导新人哦
雪    币: 9
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kec 活跃值 2013-9-14 10:08
18
0
以后看看。。。。
雪    币: 209
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
sertty 活跃值 1 2013-9-21 17:07
19
0
不懂哦, 我说的是VC++的内联汇编.
雪    币: 14
活跃值: 活跃值 (24)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nullily 活跃值 2013-9-21 17:14
20
0
谢谢楼主了 很有帮助!!!
雪    币: 1174
活跃值: 活跃值 (193)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
zhujian 活跃值 2 2013-9-22 10:21
21
0
inline hook最大的问题是大家都hook同一个函数,如何处理稳定,这才是关键。
雪    币: 200
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xbibid 活跃值 2014-1-6 14:31
22
0
mark了哦,好东西
雪    币: 5488
活跃值: 活跃值 (560)
能力值: ( LV5,RANK:78 )
在线值:
发帖
回帖
粉丝
zhighest 活跃值 2014-1-9 13:58
23
0
好东西,楼主辛苦了。
雪    币: 671
活跃值: 活跃值 (86)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
瀚海云烟 活跃值 1 2014-1-9 18:26
24
0
不错不错
雪    币: 290
活跃值: 活跃值 (824)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
囧囧 活跃值 2014-1-9 19:05
25
0
[QUOTE=瀚海云烟;1254248]哎,你这个代码基本无效的,因为装了迅雷以后的 speed_viewer1.0.2.32.dll 肯定会去hook send recv sendto recvfrom 等函数的
[/QUOTE]

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