mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
Merge branch 'main' into new-index-but-better
This commit is contained in:
commit
19ab68d202
10 changed files with 88 additions and 30 deletions
|
@ -196,10 +196,10 @@ if (WIN32)
|
|||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
|
||||
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
|
||||
# target x86 on windows with clang
|
||||
target_compile_options(${PROJECT_NAME} INTERFACE --target=i686-pc-windows-msvc)
|
||||
target_link_options(${PROJECT_NAME} INTERFACE --target=i686-pc-windows-msvc)
|
||||
add_compile_options(--target=i686-pc-windows-msvc)
|
||||
add_link_options(--target=i686-pc-windows-msvc)
|
||||
target_compile_options(${PROJECT_NAME} INTERFACE --target=x86_64-pc-windows-msvc)
|
||||
target_link_options(${PROJECT_NAME} INTERFACE --target=x86_64-pc-windows-msvc)
|
||||
add_compile_options(--target=x86_64-pc-windows-msvc)
|
||||
add_link_options(--target=x86_64-pc-windows-msvc)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
BIN
loader/include/link/fmod.lib
Normal file
BIN
loader/include/link/fmod.lib
Normal file
Binary file not shown.
BIN
loader/include/link/gdstring.lib
Normal file
BIN
loader/include/link/gdstring.lib
Normal file
Binary file not shown.
BIN
loader/include/link/glew32.lib
Normal file
BIN
loader/include/link/glew32.lib
Normal file
Binary file not shown.
BIN
loader/include/link/libExtensions.lib
Normal file
BIN
loader/include/link/libExtensions.lib
Normal file
Binary file not shown.
BIN
loader/include/link/libcocos2d.lib
Normal file
BIN
loader/include/link/libcocos2d.lib
Normal file
Binary file not shown.
BIN
loader/include/link/libcurl.lib
Normal file
BIN
loader/include/link/libcurl.lib
Normal file
Binary file not shown.
BIN
loader/include/link/z.lib
Normal file
BIN
loader/include/link/z.lib
Normal file
Binary file not shown.
|
@ -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
|
||||
static_cast<uint8_t>((jumpAddr >> 0) & 0xFF), static_cast<uint8_t>((jumpAddr >> 8) & 0xFF), static_cast<uint8_t>((jumpAddr >> 16) & 0xFF), static_cast<uint8_t>((jumpAddr >> 24) & 0xFF),
|
||||
static_cast<uint8_t>((jumpAddr >> 32) & 0xFF), static_cast<uint8_t>((jumpAddr >> 40) & 0xFF), static_cast<uint8_t>((jumpAddr >> 48) & 0xFF), static_cast<uint8_t>((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);
|
||||
|
||||
auto jmpAddr = reinterpret_cast<uintptr_t>(&gdMainHook);
|
||||
uint8_t patchBytes[patchSize] = {
|
||||
// jmp [rip + 0]
|
||||
0xff, 0x25, 0x00, 0x00, 0x00, 0x00,
|
||||
// pointer to gdMainHook
|
||||
static_cast<uint8_t>((jmpAddr >> 0) & 0xFF), static_cast<uint8_t>((jmpAddr >> 8) & 0xFF), static_cast<uint8_t>((jmpAddr >> 16) & 0xFF), static_cast<uint8_t>((jmpAddr >> 24) & 0xFF),
|
||||
static_cast<uint8_t>((jmpAddr >> 32) & 0xFF), static_cast<uint8_t>((jmpAddr >> 40) & 0xFF), static_cast<uint8_t>((jmpAddr >> 48) & 0xFF), static_cast<uint8_t>((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 "";
|
||||
}
|
||||
|
||||
|
|
|
@ -159,16 +159,18 @@ intptr_t Addresser::followThunkFunction(intptr_t address) {
|
|||
|
||||
auto jmpOffset = *reinterpret_cast<int32_t*>(address + 7 + 1);
|
||||
auto tailMergeAddr = address + 7 + jmpOffset + 5;
|
||||
// this is quite a scary offset, but lets hope it works
|
||||
auto leaAddr = tailMergeAddr + 51;
|
||||
// make sure leaAddr is pointing to a lea rcx, [rip + ...]
|
||||
if (leaAddr && checkByteSequence(leaAddr, {0x48, 0x8d, 0x0d})) {
|
||||
auto offset = *reinterpret_cast<int32_t*>(leaAddr + 3);
|
||||
auto did = reinterpret_cast<PCImgDelayDescr>(leaAddr + 7 + offset);
|
||||
address = reinterpret_cast<intptr_t>(__delayLoadHelper2(did, reinterpret_cast<FARPROC*>(leaAddress)));
|
||||
// inside of the tail merge, try to find the lea rcx, [rip + ...]
|
||||
for (uintptr_t leaOffset = 10; leaOffset < 100; ++leaOffset) {
|
||||
auto leaAddr = tailMergeAddr + leaOffset;
|
||||
if (checkByteSequence(leaAddr, {0x48, 0x8d, 0x0d})) {
|
||||
auto offset = *reinterpret_cast<int32_t*>(leaAddr + 3);
|
||||
auto did = reinterpret_cast<PCImgDelayDescr>(leaAddr + 7 + offset);
|
||||
address = reinterpret_cast<intptr_t>(__delayLoadHelper2(did, reinterpret_cast<FARPROC*>(leaAddress)));
|
||||
|
||||
if (address == -1) {
|
||||
address = 0;
|
||||
if (address == -1) {
|
||||
address = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue