我正在使用 MS Detours ,我希望得到 ConnectEx()指针但是在运行时加载,如何获取指针并与 MS Detours ?
答案 0 :(得分:1)
ConnectEx()
不是导出的DLL函数。根据{{3}}文档:
注意 必须通过
ConnectEx
调用ConnectEx()
函数,在运行时获取SIO_GET_EXTENSION_FUNCTION_POINTER
函数的函数指针指定操作码。传递给WSAIoctl
函数的输入缓冲区必须包含WSAID_CONNECTEX
,这是一个全局唯一标识符(GUID),其值标识ConnectEx
扩展函数。成功时,WSAIoctl
函数返回的输出包含指向ConnectEx
函数的指针。WSAID_CONNECTEX GUID
在Mswsock.h
头文件中定义。
例如:
#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();
}