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