1. LoadLibrary()
2. GetProcAddress()
fun* p = (fun*)GetProcAddress(GetModuleHandle(L"moduleName"), "functionName");
>>recv
int WSAAPI recv(
_In_ SOCKET s,
__out_data_source(NETWORK) char FAR * buf,
_In_ int len,
_In_ int flags);
-->
typedef int (WINAPI *pRecv)(UINT, PSTR, int, int);
>>send
int WSAAPI send(
_In_ SOCKET s,
_In_reads_bytes_(len) const char FAR * buf,
_In_ int len,
_In_ int flags
);
-->
typedef int (WINAPI *pSend)(UINT, PSTR, int, int);
jmp addr ==> E9 XX XX XX XX
1.win32程序地址占四个字节.
2.jmp和E9对应占一字节.
3.程序内存空间虽然分页管理但是地址还是连续的,即函数之间的位移可以计算.
地址A:Recv函数的开始地址
地址A+5:jmp addr(跳转指令)
地址B:MyRecv函数的开始地址
addr = B-(A+5)
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <windows.h>
#include <stdio.h>
#define SIZE 6
BYTE oldBytes[SIZE] = { 0 };
BYTE JMP[SIZE] = { 0 };
DWORD oldProtect, myProtect = PAGE_EXECUTE_READWRITE;
typedef int (WINAPI *pRecv)(UINT, PSTR, int, int);
pRecv pOrigAddress = NULL;
void BeginRedirect(LPVOID);
int WINAPI MyRecv(UINT s, PSTR buf, int len, int flags);
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
pOrigAddress = (pRecv)GetProcAddress(GetModuleHandle(L"WS2_32.dll"), "recv");
if (pOrigAddress != NULL)
BeginRedirect(MyRecv);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int WINAPI MyRecv(UINT s, PSTR buf, int len, int flags)
{
VirtualProtect((LPVOID)pOrigAddress, SIZE, myProtect, &oldProtect);
memcpy(pOrigAddress, oldBytes, SIZE);
int retValue = recv(s, buf, len, flags);
memcpy(pOrigAddress, JMP, SIZE);
VirtualProtect((LPVOID)pOrigAddress, SIZE, oldProtect, &myProtect);
OutputDebugStringA("do Something!!");
printf("MyRecv>>%s\n",buf);
return retValue;
}