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
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
|
||||||
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
|
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
|
||||||
# target x86 on windows with clang
|
# target x86 on windows with clang
|
||||||
target_compile_options(${PROJECT_NAME} INTERFACE --target=i686-pc-windows-msvc)
|
target_compile_options(${PROJECT_NAME} INTERFACE --target=x86_64-pc-windows-msvc)
|
||||||
target_link_options(${PROJECT_NAME} INTERFACE --target=i686-pc-windows-msvc)
|
target_link_options(${PROJECT_NAME} INTERFACE --target=x86_64-pc-windows-msvc)
|
||||||
add_compile_options(--target=i686-pc-windows-msvc)
|
add_compile_options(--target=x86_64-pc-windows-msvc)
|
||||||
add_link_options(--target=i686-pc-windows-msvc)
|
add_link_options(--target=x86_64-pc-windows-msvc)
|
||||||
endif()
|
endif()
|
||||||
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;
|
gdTimestamp = ntHeader->FileHeader.TimeDateStamp;
|
||||||
|
|
||||||
#ifdef GEODE_IS_WINDOWS32
|
constexpr size_t trampolineSize = GEODE_WINDOWS64(32) GEODE_WINDOWS32(12);
|
||||||
|
|
||||||
constexpr size_t trampolineSize = 12;
|
|
||||||
mainTrampolineAddr = VirtualAlloc(
|
mainTrampolineAddr = VirtualAlloc(
|
||||||
nullptr, trampolineSize,
|
nullptr, trampolineSize,
|
||||||
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE
|
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
|
// 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
|
constexpr ptrdiff_t mainCallJmpOffset = GEODE_WINDOWS64(13) GEODE_WINDOWS32(5);
|
||||||
// 68 00 00 40 00 push geode::base::get()
|
const uintptr_t mainCallJmpAddress = entryAddr + mainCallJmpOffset;
|
||||||
// e8 ... call ...
|
const int32_t mainCallJmpValue = *reinterpret_cast<int32_t*>(mainCallJmpAddress + 1);
|
||||||
uint64_t mainSearchBytes = 0xe80000000068006a;
|
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;
|
mainSearchBytes |= static_cast<uint64_t>(geode::base::get()) << 24;
|
||||||
|
#endif
|
||||||
|
|
||||||
uintptr_t patchAddr = 0;
|
uintptr_t patchAddr = 0;
|
||||||
// 0x10000 should be enough of a limit here..
|
// 0x1000 should be enough of a limit here..
|
||||||
for (auto searchAddr = preWinMainAddr; searchAddr < preWinMainAddr + 0x10000; searchAddr++) {
|
for (auto searchAddr = preWinMainAddr; searchAddr < preWinMainAddr + 0x1000; searchAddr++) {
|
||||||
if (*reinterpret_cast<uint64_t*>(searchAddr) != mainSearchBytes)
|
if (*reinterpret_cast<uint64_t*>(searchAddr) != mainSearchBytes)
|
||||||
continue;
|
continue;
|
||||||
// follow near call address, this is the call to main
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patchAddr == 0)
|
if (patchAddr == 0)
|
||||||
return "Geode could not find the main function, not loading Geode.";
|
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_ADDR(from, to) (std::bit_cast<uintptr_t>(to) - std::bit_cast<uintptr_t>(from) - 5)
|
||||||
#define JMP_BYTES(from, to) \
|
#define JMP_BYTES(from, to) \
|
||||||
static_cast<uint8_t>((JMP_ADDR(from, to) >> 0) & 0xFF), \
|
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) >> 16) & 0xFF), \
|
||||||
static_cast<uint8_t>((JMP_ADDR(from, to) >> 24) & 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] = {
|
uint8_t trampolineBytes[trampolineSize] = {
|
||||||
// push ebp
|
// push ebp
|
||||||
0x55,
|
0x55,
|
||||||
|
@ -124,15 +182,13 @@ std::string loadGeode() {
|
||||||
// nop to pad it out, helps the asm to show up properly on debuggers
|
// nop to pad it out, helps the asm to show up properly on debuggers
|
||||||
0x90
|
0x90
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
DWORD oldProtect;
|
DWORD oldProtect;
|
||||||
if (!VirtualProtectEx(process, reinterpret_cast<void*>(patchAddr), patchSize, PAGE_EXECUTE_READWRITE, &oldProtect))
|
if (!VirtualProtectEx(process, reinterpret_cast<void*>(patchAddr), patchSize, PAGE_EXECUTE_READWRITE, &oldProtect))
|
||||||
return "Geode could not hook the main function, not loading Geode.";
|
return "Geode could not hook the main function, not loading Geode.";
|
||||||
std::memcpy(reinterpret_cast<void*>(patchAddr), patchBytes, patchSize);
|
std::memcpy(reinterpret_cast<void*>(patchAddr), patchBytes, patchSize);
|
||||||
VirtualProtectEx(process, reinterpret_cast<void*>(patchAddr), patchSize, oldProtect, &oldProtect);
|
VirtualProtectEx(process, reinterpret_cast<void*>(patchAddr), patchSize, oldProtect, &oldProtect);
|
||||||
#else
|
|
||||||
#pragma message("64-bit entry is not implemented yet.")
|
|
||||||
#endif
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,16 +159,18 @@ intptr_t Addresser::followThunkFunction(intptr_t address) {
|
||||||
|
|
||||||
auto jmpOffset = *reinterpret_cast<int32_t*>(address + 7 + 1);
|
auto jmpOffset = *reinterpret_cast<int32_t*>(address + 7 + 1);
|
||||||
auto tailMergeAddr = address + 7 + jmpOffset + 5;
|
auto tailMergeAddr = address + 7 + jmpOffset + 5;
|
||||||
// this is quite a scary offset, but lets hope it works
|
// inside of the tail merge, try to find the lea rcx, [rip + ...]
|
||||||
auto leaAddr = tailMergeAddr + 51;
|
for (uintptr_t leaOffset = 10; leaOffset < 100; ++leaOffset) {
|
||||||
// make sure leaAddr is pointing to a lea rcx, [rip + ...]
|
auto leaAddr = tailMergeAddr + leaOffset;
|
||||||
if (leaAddr && checkByteSequence(leaAddr, {0x48, 0x8d, 0x0d})) {
|
if (checkByteSequence(leaAddr, {0x48, 0x8d, 0x0d})) {
|
||||||
auto offset = *reinterpret_cast<int32_t*>(leaAddr + 3);
|
auto offset = *reinterpret_cast<int32_t*>(leaAddr + 3);
|
||||||
auto did = reinterpret_cast<PCImgDelayDescr>(leaAddr + 7 + offset);
|
auto did = reinterpret_cast<PCImgDelayDescr>(leaAddr + 7 + offset);
|
||||||
address = reinterpret_cast<intptr_t>(__delayLoadHelper2(did, reinterpret_cast<FARPROC*>(leaAddress)));
|
address = reinterpret_cast<intptr_t>(__delayLoadHelper2(did, reinterpret_cast<FARPROC*>(leaAddress)));
|
||||||
|
|
||||||
if (address == -1) {
|
if (address == -1) {
|
||||||
address = 0;
|
address = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue