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?
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 theWSAIoctl
function with theSIO_GET_EXTENSION_FUNCTION_POINTER
opcode specified. The input buffer passed to theWSAIoctl
function must containWSAID_CONNECTEX
, a globally unique identifier (GUID) whose value identifies theConnectEx
extension function. On success, the output returned by theWSAIoctl
function contains a pointer to theConnectEx
function. TheWSAID_CONNECTEX GUID
is defined in theMswsock.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();
}