223 lines
7.7 KiB
C
223 lines
7.7 KiB
C
#include <detours.h>
|
|
#include <signal.h>
|
|
|
|
#include "../lib/util/pid.h"
|
|
#include "common.h"
|
|
#include "devices/_devices.h"
|
|
#include "drivers/mx.h"
|
|
#include "hooks/_hooks.h"
|
|
|
|
WCHAR exeName[MAX_PATH + 1];
|
|
char exeNameC[MAX_PATH + 1];
|
|
size_t imageOffset;
|
|
|
|
void apply_patches(HMODULE hModule) {
|
|
void* baseAddress = (void*)hModule;
|
|
|
|
DWORD imageBase = MiceGetImageBase();
|
|
if (imageBase == 0) {
|
|
log_error(plfBoot, "Failed to locate image base. Patches will not be applied.");
|
|
return;
|
|
}
|
|
imageOffset = (DWORD)hModule - imageBase;
|
|
|
|
if (!load_patches(MiceConfig.mice.patches_file, exeNameC)) {
|
|
log_error(plfBoot, "Failed to load patches file %s", MiceConfig.mice.patches_file);
|
|
return;
|
|
}
|
|
|
|
patch_t* patch = patch_list->next;
|
|
if (patch == NULL) {
|
|
log_info(plfBoot, "No patches to apply. Skipping.");
|
|
return;
|
|
}
|
|
while (patch) {
|
|
DWORD oldProt;
|
|
VirtualProtect((void*)(patch->address + imageOffset), patch->count, PAGE_EXECUTE_READWRITE,
|
|
&oldProt);
|
|
|
|
if (memcmp(patch->match, (void*)(patch->address + imageOffset), patch->count) != 0) {
|
|
log_error(plfBoot, "Patch %s failed! from-value missmatch", patch->name);
|
|
VirtualProtect((void*)(patch->address + imageOffset), patch->count, oldProt, &oldProt);
|
|
patch = patch->next;
|
|
continue;
|
|
}
|
|
|
|
memcpy((void*)(patch->address + imageOffset), patch->replace, patch->count);
|
|
log_misc(plfBoot, "Patched %d bytes at %08x (%s)", patch->count, patch->address,
|
|
patch->name);
|
|
|
|
patch = patch->next;
|
|
}
|
|
}
|
|
|
|
void prebind_hooks() {
|
|
hook_all();
|
|
install_devices();
|
|
}
|
|
|
|
void init_injection(HMODULE hModule) {
|
|
WideCharToMultiByte(CP_ACP, 0, exeName, -1, exeNameC, sizeof exeNameC, NULL, NULL);
|
|
|
|
// Make sure our CRC32 tables are ready for anything that might want to use them
|
|
amiCrc32RInit();
|
|
|
|
load_mice_config();
|
|
|
|
// We're in a new context now, so need to reconfigure
|
|
setup_logging();
|
|
MiceSetLogBasename(exeNameC);
|
|
log_info(plfBoot, "Handover complete. Now executing within %ls", exeName);
|
|
|
|
// Start Mice FS
|
|
if (!MiceFSInit()) {
|
|
log_error(plfFile, "Failed to initialise Mice FS stack: %d", GetLastError());
|
|
exit(1);
|
|
}
|
|
|
|
BOOL success = TRUE;
|
|
success &= MiceFSAddDevLayers();
|
|
|
|
CHAR szWorkPath[MAX_PATH + 1];
|
|
if (!MiceConfig.mice.original || MiceConfig.mice.original[0] == '\0') {
|
|
_GetCurrentDirectoryA(sizeof szWorkPath, szWorkPath);
|
|
success &= MiceFSAddLayer(RING_MOUNT_ORIGINAL, szWorkPath);
|
|
success &= MiceFSAddLayer(RING_MOUNT_GAME, szWorkPath);
|
|
} else {
|
|
success &= MiceFSAddLayer(RING_MOUNT_ORIGINAL, MiceConfig.mice.original);
|
|
success &= MiceFSAddLayer(RING_MOUNT_GAME, MiceConfig.mice.original);
|
|
}
|
|
if (MiceConfig.mice.patch && MiceConfig.mice.patch[0] != '\0') {
|
|
success &= MiceFSAddLayer(RING_MOUNT_PATCH, MiceConfig.mice.patch);
|
|
success &= MiceFSAddLayer(RING_MOUNT_GAME, MiceConfig.mice.patch);
|
|
}
|
|
if (MiceConfig.mice.extend && MiceConfig.mice.extend[0] != '\0') {
|
|
success &= MiceFSAddLayer(RING_MOUNT_EXTEND_VOL, MiceConfig.mice.extend);
|
|
success &= MiceFSAddLayer(RING_MOUNT_GAME, MiceConfig.mice.extend);
|
|
}
|
|
if (MiceConfig.mice.extend2 && MiceConfig.mice.extend2[0] != '\0') {
|
|
MiceFSAddLayer(RING_MOUNT_EXTEND2_VOL, MiceConfig.mice.extend2);
|
|
MiceFSAddLayer(RING_MOUNT_GAME, MiceConfig.mice.extend2);
|
|
}
|
|
|
|
success &= MiceFSAddRingedgeLayers(FALSE);
|
|
|
|
if (!success) {
|
|
log_error(plfFile, "Failed to add Mice FS layers: %d", GetLastError());
|
|
exit(1);
|
|
}
|
|
|
|
szWorkPath[0] = '\0';
|
|
strcat_s(szWorkPath, sizeof szWorkPath, RING_MOUNT_GAME "\\");
|
|
if (_miceIpcData && _miceIpcData->m_LauncherIsReady)
|
|
strcat_s(szWorkPath, sizeof szWorkPath, _miceIpcData->m_PathPrefix);
|
|
MiceFSSetCwd(szWorkPath);
|
|
|
|
// Setup default COM devices
|
|
init_com_devices();
|
|
|
|
// Apply any in-memory patches requested
|
|
if (MiceConfig.mice.apply_patches) apply_patches(hModule);
|
|
|
|
// Columba: Driver-level memory access, used to read the DMI tables
|
|
if (MiceConfig.drivers.columba) setup_columba();
|
|
// MX SRAM: SRAM-based nv memory
|
|
if (MiceConfig.drivers.mxsram) setup_mxsram();
|
|
// MX SuperIO: Communicate with the HW monitor chip
|
|
if (MiceConfig.drivers.mxsuperio) setup_mxsuperio();
|
|
// MX JVS: Interacting with JVS-based devices
|
|
if (MiceConfig.drivers.mxjvs) {
|
|
setup_mxjvs();
|
|
load_keybind_config();
|
|
}
|
|
// MX HW Reset: Forcibly reboot the machine
|
|
if (MiceConfig.drivers.mxhwreset) setup_mxhwreset();
|
|
// MX SMBus: Communicate over the LPC bus. This contains the EEPROM, and PCA9535
|
|
if (MiceConfig.drivers.mxsmbus) setup_mxsmbus();
|
|
// MX Parallel: The parallel port (i.e. keychip)
|
|
if (MiceConfig.drivers.mxparallel) setup_mxparallel();
|
|
// CrackProof
|
|
if (MiceConfig.drivers.htsysmnt) setup_htsysmnt();
|
|
|
|
if (MiceConfig.drivers.platform) {
|
|
if (!add_fake_device(&PLATFORM_GUID, L"\\\\.\\platform")) {
|
|
log_error(plfPlatform, "failed to install platform device");
|
|
}
|
|
}
|
|
|
|
// Must be the last thing called!
|
|
prebind_hooks();
|
|
|
|
setup_hooks();
|
|
|
|
start_devices();
|
|
}
|
|
|
|
void tea_hook_test(char* fmt, ...) {
|
|
va_list argp;
|
|
va_start(argp, fmt);
|
|
vlog_game(plfTea, fmt, argp);
|
|
va_end(argp);
|
|
}
|
|
|
|
BOOL g_bIsInDllMain = TRUE;
|
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
|
if (ul_reason_for_call != DLL_PROCESS_ATTACH) return TRUE;
|
|
g_bIsInDllMain = TRUE;
|
|
|
|
GetModuleFileNameW(NULL, exeName, MAX_PATH);
|
|
wcscpy_s(exeName, MAX_PATH + 1, PathFindFileNameW(exeName));
|
|
|
|
if (!MiceIpcSetup(FALSE)) {
|
|
fprintf(stderr, "Failed to initialise IPC from within micelib. Bailing hard!");
|
|
TerminateProcess(GetCurrentProcess(), 0);
|
|
return FALSE;
|
|
}
|
|
|
|
HMODULE exeModule = GetModuleHandleA(NULL);
|
|
init_injection(exeModule);
|
|
|
|
_MiceGotGameId(_miceIpcData->m_GameId);
|
|
|
|
// InitialD 8
|
|
if (false) {
|
|
DWORD dword = 0;
|
|
MiceHookPatchAtImage(exeModule, (PVOID)0x0126867c, &dword, 4);
|
|
|
|
BYTE movEax1[] = { 0xb8, 0x01, 0x00, 0x00, 0x00 };
|
|
// Bypass cgGcIsProfileSupported
|
|
MiceHookNopAtImage(exeModule, (PVOID)0xb4c9ac, 6);
|
|
MiceHookPatchAtImage(exeModule, (PVOID)0xb4c9ac, movEax1, sizeof movEax1);
|
|
MiceHookNopAtImage(exeModule, (PVOID)0xb4ca9f, 6);
|
|
MiceHookPatchAtImage(exeModule, (PVOID)0xb4ca9f, movEax1, sizeof movEax1);
|
|
|
|
// change glProgramEnvParameters4fvNV to EXT version that works with any GPUs
|
|
static const char* arb = "glProgramEnvParameters4fvEXT";
|
|
MiceHookPatchAtImage(exeModule, (PVOID)0xB70E26, &arb, 4);
|
|
// force volatile texture (driver bug(?) check) presence
|
|
MiceHookNopAtImage(exeModule, (PVOID)(0xB6BC20 + 0x5667), 2);
|
|
|
|
DWORD profile;
|
|
BOOL amd = TRUE;
|
|
if (amd)
|
|
profile = 6151; // CG_PROFILE_FP40
|
|
else
|
|
profile = 7000; // CG_PROFILE_ARBFP1
|
|
|
|
// Vertex shader is compiled with profile 6150
|
|
// Pixel shader is compiled with profile 7000
|
|
|
|
// Change shader profile for glareGenerator
|
|
MiceHookPatchAtImage(exeModule, (PVOID)0x7D06A8, &profile, 4);
|
|
|
|
DetourTransactionBegin();
|
|
DetourUpdateThread(GetCurrentThread());
|
|
void* original = (void*)0x00407850;
|
|
DetourAttach(&original, tea_hook_test);
|
|
DetourTransactionCommit();
|
|
}
|
|
|
|
g_bIsInDllMain = FALSE;
|
|
return TRUE;
|
|
}
|