Mr Jhon
Mr Jhon

Reputation: 113

How to Get ConnectEx() pointer

I'm using MS Detours and I want get the ConnectEx() pointer but is load at run time, how to get pointer and use with MS Detours?

Upvotes: 1

Views: 464

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596713

ConnectEx() is not an exported DLL function. Per the ConnectEx() documentation:

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.

For example:

#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;
}

Once you have a pointer to ConnectEx(), you can detour it. Depending on the version of MSDetours you are using, you can either:

Use 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);

Use 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();
}

Upvotes: 1

Related Questions