2017-01-19 6 views

답변

0

ConnectEx()은 내 보낸 DLL 기능이 아닙니다. ConnectEx() 문서 당 :

ConnectEx 함수의 함수 포인터는 SIO_GET_EXTENSION_FUNCTION_POINTER 오피 코드와 WSAIoctl 함수를 호출하여 런타임에을 지정 받아야합니다. WSAIoctl 함수에 전달 된 입력 버퍼에는 ConnectEx 확장 함수를 식별하는 GUID (globally unique identifier) ​​인 WSAID_CONNECTEX이 포함되어야합니다. 성공시 WSAIoctl 함수에 의해 반환 된 결과는 ConnectEx 함수에 대한 포인터를 포함합니다. WSAID_CONNECTEX GUIDMswsock.h 헤더 파일에 정의되어 있습니다. 예를 들어

: 당신이 ConnectEx()에 대한 포인터가 있으면

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

, 당신은 그것을 우회 할 수 있습니다. 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(); 
} 
+0

예, 그렇지만 실행 시간에 포인터를 얻는 방법은 무엇입니까? –

+0

예제를 추가했습니다 (이 정보를 찾기 위해 웹 검색을 할 수 있었고, 쉽게 사용할 수 있으며 StackOverflow에 여러 번 게시되었습니다). –

+0

정말 고맙습니다. 그 코드도 발견되었지만 MS Destour에 어떻게 적용 할 수 있는지 모르겠군요. –