First of all, I am new to hooking methods and dll manipulation. I have an assignment to first create a simple program that opens a message box using MessageBoxA. The Code:
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
int main() {
LPCSTR text = "Hello World!";
LPCSTR caption = "My Message Box";
MessageBoxA(NULL, text, caption, MB_OK);
return 0;
}
Afterwards, I need to create a DLL that hooks to the program above and opens a different message box. The code I wrote is:
#include "stdafx.h"
#include <windows.h>
#define SIZE 6
typedef int (WINAPI* pMessageBox)(HWND, LPCSTR, LPCSTR, UINT); //MessageBox function pointer
int WINAPI newMessageBoxA(HWND, LPCSTR, LPCSTR, UINT); // my detour
void redirect(LPVOID);
pMessageBox pOrigAddress = NULL;
DWORD oldProtect, newProtect = PAGE_EXECUTE_READWRITE;
BYTE origBytes[SIZE];
BYTE jmp[SIZE];
void __declspec(dllexport) myMessageBox() {
pOrigAddress = (pMessageBox)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA"); //get MessageBoxA address
if (pOrigAddress != NULL) {
redirect(newMessageBoxA);
}
}
/* Detour */
void redirect(LPVOID newFunc) {
BYTE tmpJmp[SIZE] = { 0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3 }; //initiate hook (0xE9 = jmp, 0xC3 = ret, 0x90 = nop)
memcpy(jmp, tmpJmp, SIZE);
DWORD jmpSize = (DWORD)newFunc - (DWORD)pOrigAddress - 5; //jump distance
VirtualProtect(pOrigAddress, SIZE, PAGE_EXECUTE_READWRITE, &oldProtect); //change protection to read-write and save previous protection value
memcpy(origBytes, pOrigAddress, SIZE); //save original value of function address
memcpy(&jmp[1], &jmpSize, 4); //fill the nops in tmpJmp with the address of the new function
memcpy(pOrigAddress, jmp, SIZE); //replace jump instruction of old function with new function
VirtualProtect(pOrigAddress, SIZE, oldProtect, NULL); //reset protection value
}
int WINAPI newMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uiType) {
VirtualProtect((LPVOID)pOrigAddress, SIZE, newProtect, NULL); // assign read write protection
memcpy(pOrigAddress, origBytes, SIZE); // restore backup
int retValue = MessageBoxA(hWnd, (LPCSTR)"This Message Box has been hijacked!", (LPCSTR)"Message Box Hijacked", uiType); // get return value of original function
memcpy(pOrigAddress, jmp, SIZE); // set the jump instruction again
VirtualProtect((LPVOID)pOrigAddress, SIZE, oldProtect, NULL); // reset protection
return retValue; // return original return value
}
After that I changed the first block of code to load the DLL using LoadLibrary:
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
typedef void(__stdcall *FNPTR)();
int main() {
HINSTANCE hInst = LoadLibrary(L"C:\\Users\\yuvalnissan\\Desktop\\Workspaces\\VS Workspace\\morphisecAssignment\\x64\\Debug\\dllinject.dll");
if (hInst == NULL) {
cout << "\nCould not load dll" << endl;
return 0;
}
FNPTR function = (FNPTR)GetProcAddress(hInst, "myMessageBox");
if (function == NULL) {
cout << "\nCould not locate function in dll" << endl;
return 0;
}
function();
FreeLibrary(hInst);
LPCSTR text = "Hello World!";
LPCSTR caption = "My Message Box";
MessageBoxA(NULL, text, caption, MB_OK);
return 0;
}
That DLL seems to load properly, but at the command prompt I get "Could not locate function in dll", indicating that the GetProcAddress() is not working properly.
What am I doing wrong?