c++ - 如何获取 ConnectEx() 指针

标签 c++ detours

我正在使用 MS Detours,我想获取 ConnectEx() 指针,但在运行时加载,如何获取指针并与 MS 一起使用走弯路

最佳答案

ConnectEx() 不是导出的 DLL 函数。根据 ConnectEx()文档:

Note The function pointer for the ConnectEx function must be obtained at run time by making a call to the WSAIoctl function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function must contain WSAID_CONNECTEX, a globally unique identifier (GUID) whose value identifies the ConnectEx extension function. On success, the output returned by the WSAIoctl function contains a pointer to the ConnectEx function. The WSAID_CONNECTEX GUID is defined in the Mswsock.h header file.

例如:

#include <winsock2.h> // Must be included before Mswsock.h
#include <mswsock.h>

#pragma comment(lib, "ws2_32.lib")

...

LPFN_CONNECTEX GetConnectExPtr(SOCKET s)
{
    LPFN_CONNECTEX lpConnectEx = NULL;
    GUID guid = WSAID_CONNECTEX;
    DWORD dwNumBytes = 0;
    WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), &lpConnectEx, sizeof(lpConnectEx), &dwNumBytes, NULL, NULL);
    return lpConnectEx;
}

一旦有了指向 ConnectEx() 的指针,就可以绕过它。根据您使用的 MSDetours 版本,您可以:

使用DetourFunction():

#include <winsock2.h> // Must be included before Mswsock.h
#include <mswsock.h>
#include <detours.h>

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "detours.lib")

...

LPFN_CONNECTEX Real_ConnectEx = NULL;
LPFN_CONNECTEX Trampoline_ConnectEx = NULL;

BOOL WINAPI MyConnectEx(SOCKET s, const struct sockaddr *name, int namelen, PVOID lpSendBuffer, DWORD dwSendDataLength, LPDWORD lpdwBytesSent, LPOVERLAPPED lpOverlapped)
{
    // do something...
    return Trampoline_ConnectEx(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, lpOverlapped);
}

...

SOCKET s = ...;
Real_ConnectEx = GetConnectExPtr(s);
if (Real_ConnectEx)
{
    Trampoline_ConnectEx = (LPFN_CONNECTEX) DetourFunction((PBYTE)Real_ConnectEx, (PBYTE)MyConnectEx);
}

...

if (Trampoline_ConnectEx)
    DetourRemoveTrampoline(Trampoline_ConnectEx);

使用DetourAttach/Ex():

#include <winsock2.h> // Must be included before Mswsock.h
#include <mswsock.h>
#include <detours.h>

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "detours.lib")
#pragma comment(lib, "detoured.lib")

...

LPFN_CONNECTEX Real_ConnectEx = NULL;
LPFN_CONNECTEX Trampoline_ConnectEx = NULL;

BOOL WINAPI MyConnectEx(SOCKET s, const struct sockaddr *name, int namelen, PVOID lpSendBuffer, DWORD dwSendDataLength, LPDWORD lpdwBytesSent, LPOVERLAPPED lpOverlapped)
{
    // do something...
    return Trampoline_ConnectEx(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, lpOverlapped);
}

...

SOCKET s = ...;
Real_ConnectEx = GetConnectExPtr(s);
if (Real_ConnectEx)
{
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());

    // using DetourAttach()...
    Trampoline_ConnectEx = Real_ConnectEx;
    DetourAttach((PVOID*)&Trampoline_ConnectEx, MyConnectEx);

    // using DetourAttachEx()...
    // DetourAttachEx(&Real_ConnectEx, MyConnectEx, (PDETOUR_TRAMPOLINE*)&Trampoline_ConnectEx, NULL, NULL);

    DetourTransactionCommit();
}

...

if ((Real_ConnectEx) && (Trampoline_ConnectEx))
{    
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());

    // if using DetourAttach()...
    DetourDetach((PVOID*)&Trampoline_ConnectEx, MyConnectEx);

    // if using DetourAttachEx()...
    // DetourDetach((PVOID*)&Real_ConnectEx, MyConnectEx);

    DetourTransactionCommit();
}

关于c++ - 如何获取 ConnectEx() 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41733041/

相关文章:

c++ - 如何使用回调使工作简单的按钮类?

c++ - 仅发布版本的大量链接器问题

c++ - 销毁期间派生的成员(member)国

c++ - 遍历不同类型集合的通用代码

c - Hook 用户调用功能?

c++ - 关于修改虚表绕道的问题

c++ - 从派生类之一调用基方法

c++ - 绕行函数在 printf 上崩溃

c++ - 绕行:防止通过其他软件杀死我的软件

c++ - 使用detours Hook 在记事本中书写文字