mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-01 07:40:18 -04:00
windows 64 bit entry that i have in fact not tested
This commit is contained in:
parent
ccfa6edf53
commit
8b79a9b484
1 changed files with 73 additions and 17 deletions
|
@ -65,39 +65,62 @@ std::string loadGeode() {
|
|||
|
||||
gdTimestamp = ntHeader->FileHeader.TimeDateStamp;
|
||||
|
||||
#ifdef GEODE_IS_WINDOWS32
|
||||
|
||||
constexpr size_t trampolineSize = 12;
|
||||
constexpr size_t trampolineSize = GEODE_WINDOWS64(32) GEODE_WINDOWS32(12);
|
||||
mainTrampolineAddr = VirtualAlloc(
|
||||
nullptr, trampolineSize,
|
||||
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE
|
||||
);
|
||||
|
||||
auto entryAddr = geode::base::get() + ntHeader->OptionalHeader.AddressOfEntryPoint;
|
||||
const uintptr_t entryAddr = geode::base::get() + ntHeader->OptionalHeader.AddressOfEntryPoint;
|
||||
// function that calls main
|
||||
auto preWinMainAddr = entryAddr + 5 + *reinterpret_cast<uintptr_t*>(entryAddr + 6) + 5;
|
||||
// 32 bit:
|
||||
// e8 xx xx xx xx call (security)
|
||||
// e9 xx xx xx xx jmp
|
||||
// 64 bit:
|
||||
// 48 83 ec 28 sub rsp, 0x28
|
||||
// e8 xx xx xx xx call (security)
|
||||
// 48 83 c4 28 add rsp, 0x28
|
||||
// e9 xx xx xx xx jmp
|
||||
|
||||
// 6a 00 push 0
|
||||
// 68 00 00 40 00 push geode::base::get()
|
||||
// e8 ... call ...
|
||||
uint64_t mainSearchBytes = 0xe80000000068006a;
|
||||
constexpr ptrdiff_t mainCallJmpOffset = GEODE_WINDOWS64(13) GEODE_WINDOWS32(5);
|
||||
const uintptr_t mainCallJmpAddress = entryAddr + mainCallJmpOffset;
|
||||
const int32_t mainCallJmpValue = *reinterpret_cast<int32_t*>(mainCallJmpAddress + 1);
|
||||
const uintptr_t preWinMainAddr = mainCallJmpAddress + mainCallJmpValue + 5;
|
||||
|
||||
// the search bytes for the main function
|
||||
// 32 bit:
|
||||
// 6a 00 push 0
|
||||
// 68 00 00 40 00 push geode::base::get()
|
||||
// e8 ... call ...
|
||||
// 64 bit:
|
||||
// 44 8b cb mov r9d, ebx
|
||||
// 4c 8b c0 mov r8, rax
|
||||
// 33 d2 xor edx, edx
|
||||
// 48 8d 0d xx xx xx xx lea rcx, [rip + ...]
|
||||
// e8 ... call ...
|
||||
|
||||
constexpr uint64_t mainSearchBytes = GEODE_WINDOWS64(0xd233c08b4ccb8b44) GEODE_WINDOWS32(0x004000006a006800);
|
||||
constexpr ptrdiff_t mainSearchCallOffset = GEODE_WINDOWS64(15) GEODE_WINDOWS32(7);
|
||||
|
||||
#ifdef GEODE_IS_WINDOWS32
|
||||
mainSearchBytes |= static_cast<uint64_t>(geode::base::get()) << 24;
|
||||
#endif
|
||||
|
||||
uintptr_t patchAddr = 0;
|
||||
// 0x10000 should be enough of a limit here..
|
||||
for (auto searchAddr = preWinMainAddr; searchAddr < preWinMainAddr + 0x10000; searchAddr++) {
|
||||
// 0x1000 should be enough of a limit here..
|
||||
for (auto searchAddr = preWinMainAddr; searchAddr < preWinMainAddr + 0x1000; searchAddr++) {
|
||||
if (*reinterpret_cast<uint64_t*>(searchAddr) != mainSearchBytes)
|
||||
continue;
|
||||
// follow near call address, this is the call to main
|
||||
patchAddr = searchAddr + 12 + *reinterpret_cast<ptrdiff_t*>(searchAddr + 8);
|
||||
const uintptr_t callAddress = searchAddr + mainSearchCallOffset;
|
||||
const int32_t callValue = *reinterpret_cast<int32_t*>(callAddress + 1);
|
||||
patchAddr = callAddress + callValue + 5;
|
||||
break;
|
||||
}
|
||||
|
||||
if (patchAddr == 0)
|
||||
return "Geode could not find the main function, not loading Geode.";
|
||||
|
||||
constexpr size_t patchSize = 6;
|
||||
|
||||
#define JMP_ADDR(from, to) (std::bit_cast<uintptr_t>(to) - std::bit_cast<uintptr_t>(from) - 5)
|
||||
#define JMP_BYTES(from, to) \
|
||||
static_cast<uint8_t>((JMP_ADDR(from, to) >> 0) & 0xFF), \
|
||||
|
@ -105,6 +128,41 @@ std::string loadGeode() {
|
|||
static_cast<uint8_t>((JMP_ADDR(from, to) >> 16) & 0xFF), \
|
||||
static_cast<uint8_t>((JMP_ADDR(from, to) >> 24) & 0xFF)
|
||||
|
||||
#ifdef GEODE_IS_WINDOWS64
|
||||
constexpr size_t patchSize = 15;
|
||||
|
||||
uintptr_t jumpAddr = patchAddr + patchSize;
|
||||
uint8_t trampolineBytes[trampolineSize] = {
|
||||
// mov [rsp + 8], rbx
|
||||
0x48, 0x89, 0x5c, 0x24, 0x08,
|
||||
// mov [rsp + 10], rsi
|
||||
0x48, 0x89, 0x74, 0x24, 0x10,
|
||||
// mov [rsp + 18], rdi
|
||||
0x48, 0x89, 0x7c, 0x24, 0x18,
|
||||
// jmp [rip + 0]
|
||||
0xff, 0x25, 0x00, 0x00, 0x00, 0x00,
|
||||
// pointer to main + 15
|
||||
(jumpAddr >> 0) & 0xFF, (jumpAddr >> 8) & 0xFF, (jumpAddr >> 16) & 0xFF, (jumpAddr >> 24) & 0xFF,
|
||||
(jumpAddr >> 32) & 0xFF, (jumpAddr >> 40) & 0xFF, (jumpAddr >> 48) & 0xFF, (jumpAddr >> 56) & 0xFF,
|
||||
// nop to pad it out, helps the asm to show up properly on debuggers
|
||||
0x90, 0x90, 0x90
|
||||
};
|
||||
|
||||
std::memcpy(mainTrampolineAddr, trampolineBytes, trampolineSize);
|
||||
|
||||
jmpAddr = reinterpret_cast<uintptr_t>(&gdMainHook);
|
||||
uint8_t patchBytes[patchSize] = {
|
||||
// jmp [rip + 0]
|
||||
0xff, 0x25, 0x00, 0x00, 0x00, 0x00,
|
||||
// pointer to gdMainHook
|
||||
(jmpAddr >> 0) & 0xFF, (jmpAddr >> 8) & 0xFF, (jmpAddr >> 16) & 0xFF, (jmpAddr >> 24) & 0xFF,
|
||||
(jmpAddr >> 32) & 0xFF, (jmpAddr >> 40) & 0xFF, (jmpAddr >> 48) & 0xFF, (jmpAddr >> 56) & 0xFF,
|
||||
// nop to pad it out, helps the asm to show up properly on debuggers
|
||||
0x90
|
||||
};
|
||||
#else
|
||||
constexpr size_t patchSize = 6;
|
||||
|
||||
uint8_t trampolineBytes[trampolineSize] = {
|
||||
// push ebp
|
||||
0x55,
|
||||
|
@ -124,15 +182,13 @@ std::string loadGeode() {
|
|||
// nop to pad it out, helps the asm to show up properly on debuggers
|
||||
0x90
|
||||
};
|
||||
#endif
|
||||
|
||||
DWORD oldProtect;
|
||||
if (!VirtualProtectEx(process, reinterpret_cast<void*>(patchAddr), patchSize, PAGE_EXECUTE_READWRITE, &oldProtect))
|
||||
return "Geode could not hook the main function, not loading Geode.";
|
||||
std::memcpy(reinterpret_cast<void*>(patchAddr), patchBytes, patchSize);
|
||||
VirtualProtectEx(process, reinterpret_cast<void*>(patchAddr), patchSize, oldProtect, &oldProtect);
|
||||
#else
|
||||
#pragma message("64-bit entry is not implemented yet.")
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue