What: I want to hijack the current process' startup procedure to run pre-initialization startup code, which would allow my framework backend to function without any setup by the programmer.
Why: I want to initialize my application shell backend (including any managers) before the program enters but after statics are initialized.
What's the problem: Well, there's two….
1) Identifying the actual entry point. I'm currently focusing solely on Windows, but even here I have multiple possible entry points to handle. Most importantly, WinMainA() and WinMainW(), but also main(), wmain(), etc. I'm not a sure what would be the best way to locate and handle the entry point.
2) The worse thing is that I get sporadic crashes. I'm not 100% sure why, but these don't happen in some cases but do happen when the code is changed.
Here's the code I'm using to inject and restore WinMainW. I do not know what the Assembly instructions do. These are from the internet:
#ifdef DEF64
//define the jump for 64 bit
uint8_t jmpTrap[] = { 0x48, 0xb8, 0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 0xff, 0xe0 }; //mov rax,64-bit; jmp raz
#else
uint8_t jmpTrap[] = { 0xB8, 0, 0, 0, 0, 0xff, 0xe0 }; //mov eax,32-bit; jmp eax
#endif
void Inject() {
DWORD dPermission = 0;
VirtualProtect((LPVOID)oldFunction, sizeof(restore), PAGE_EXECUTE_READWRITE, &dPermission);
UINT64 i = (UINT64)newFunction;
if(sizeof(void*) == 4) { memcpy(&jmpTrap[1], &i, sizeof(void*)); }
else if(sizeof(void*) == 8) { memcpy(&jmpTrap[2], &i, sizeof(void*)); }
// store the original so as to restore it later
memcpy(restore, oldFunction, sizeof(restore));
memcpy((LPVOID)oldFunction, jmpTrap, sizeof(jmpTrap));
}
void Restore() {
DWORD dPermission = 0;
VirtualProtect((LPVOID)oldFunction, sizeof(jmpTrap), PAGE_EXECUTE_READWRITE, &dPermission);
memcpy((LPVOID)oldFunction, restore, sizeof(restore));
}
Here's how I use the above code.
int WINAPI wInjectedWinMain(
_In HINSTANCE hInstance,
_In HINSTANCE hPrevInstance,
_In LPWSTR lpCmdLine,
_In int nCmdShow)
{
sys::startup::OnMain();
injWinMainW.Restore();
return wWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
I guess my question is: if the code is correct, what am I doing wrong. Or if there's something amiss, what might it be? ?