Reputation: 113
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
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 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();
}
Upvotes: 1