
#include <cstdlib>
#include <cstring>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <windows.h>
class ApiCave
{
public:
void GenerateBytes();
void RestoreBytes();
void PlaceJump();
void GetOriginalFuncAddress(char * moduleName, char * functionName);
ApiCave(LPVOID DetourFunction, int iSize);
~ApiCave();
private:
int iInstructionSize;
BYTE *originalBytes, *hookBytes, *tempBytes;
DWORD OriginalFunctionAddress, DetourFunctionAddress, oldprotect;
DWORD myprotect;
};
void ApiCave::GenerateBytes()
{
tempBytes[0] = 0xE9;
tempBytes[5] = 0xC3; // 0xE9 = JMP 0x90 = NOP oxC3 = RET
memcpy(hookBytes, tempBytes, iInstructionSize); // store jmp instruction to JMP
DWORD JMPSize = ((DWORD)DetourFunctionAddress - (DWORD)OriginalFunctionAddress - 5); // calculate jump distance
VirtualProtect((LPVOID)OriginalFunctionAddress, iInstructionSize, // assign read write protection
myprotect, &oldprotect);
memcpy((LPVOID)originalBytes, (LPVOID)OriginalFunctionAddress, iInstructionSize); // make backup
memcpy(&hookBytes[1], &JMPSize, 4); // fill the nop's with the jump distance (JMP,distance(4bytes),RET)
VirtualProtect((LPVOID)OriginalFunctionAddress, iInstructionSize, oldprotect, NULL);
}
void ApiCave::RestoreBytes()
{
VirtualProtect((LPVOID)OriginalFunctionAddress, iInstructionSize, myprotect, &oldprotect);
memcpy((LPVOID)OriginalFunctionAddress, originalBytes, iInstructionSize);
VirtualProtect((LPVOID)OriginalFunctionAddress, iInstructionSize, oldprotect, NULL);
}
void ApiCave::PlaceJump()
{
VirtualProtect((LPVOID)OriginalFunctionAddress, iInstructionSize, myprotect, &oldprotect);
memcpy((LPVOID)OriginalFunctionAddress, hookBytes, iInstructionSize);
VirtualProtect((LPVOID)OriginalFunctionAddress, iInstructionSize, oldprotect, NULL);
}
void ApiCave::GetOriginalFuncAddress(char * moduleName, char * functionName)
{
OriginalFunctionAddress = (DWORD)GetProcAddress(GetModuleHandle(moduleName), functionName);
}
ApiCave::ApiCave(LPVOID DetourFunction, int iSize)
{
iInstructionSize = iSize;
myprotect = PAGE_EXECUTE_READWRITE;
DetourFunctionAddress = (DWORD)DetourFunction;
tempBytes = new BYTE[iSize];
originalBytes = new BYTE[iSize];
hookBytes = new BYTE[iSize];
}
ApiCave::~ApiCave()
{
delete[] tempBytes;
delete[] originalBytes;
delete[] hookBytes;
}
#include "hook.h"
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DoTheHook();
break;
}
return TRUE;
}
#include "hkClass.h"
int WINAPI MySend(SOCKET, const char *, int, int);
int WINAPI MyMessageBoxA(HWND, LPCTSTR, LPCTSTR, UINT);
ApiCave sendCave((LPVOID)MySend, 6);
ApiCave mbCave((LPVOID)MyMessageBoxA, 6);
int WINAPI MySend (SOCKET s, const char * buf, int len, int flags)
{
sendCave.RestoreBytes();
int retVal = send(s, buf, len, flags);
sendCave.PlaceJump();
return retVal;
}
int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR text, LPCTSTR title, UINT type)
{
mbCave.RestoreBytes();
int retVal = MessageBoxA(hWnd, text, title, type);
mbCave.PlaceJump();
return retVal;
}
void DoTheHook()
{
sendCave.GetOriginalFuncAddress("ws2_32.dll", "send");
mbCave.GetOriginalFuncAddress("user32.dll", "MessageBoxA");
sendCave.GenerateBytes();
mbCave.GenerateBytes();
sendCave.PlaceJump();
mbCave.PlaceJump();
}

