state("pcsx2-qt") { } state("pcsx2-qtx64-avx2") { } state("pcsx2") { } startup { vars.modBase = IntPtr.Zero; vars.EEBase = IntPtr.Zero; vars.loading = (byte)0; vars.DEBUG = true; vars.lastLoading = (byte)255; vars.reinitCooldown = 0; } init { System.Diagnostics.Process p = game; vars.modBase = IntPtr.Zero; for (int i = 0; i < modules.Count(); i++) { string n = modules[i].ModuleName.ToLower(); if (n.StartsWith("pcsx2")) { vars.modBase = modules[i].BaseAddress; break; } } if ((IntPtr)vars.modBase == IntPtr.Zero) return false; vars.EEBase = IntPtr.Zero; IntPtr baseAddr = (IntPtr)vars.modBase; int e_lfanew = p.ReadValue(IntPtr.Add(baseAddr, 0x3C)); if (e_lfanew > 0) { IntPtr nt = IntPtr.Add(baseAddr, e_lfanew); int sig = p.ReadValue(nt); if (sig == 0x00004550) { short magic = p.ReadValue(IntPtr.Add(nt, 0x18)); int dataDir = (magic == 0x10B) ? 0x60 : 0x70; int exportRva = p.ReadValue(IntPtr.Add(IntPtr.Add(nt, 0x18), dataDir + 0)); int exportSize = p.ReadValue(IntPtr.Add(IntPtr.Add(nt, 0x18), dataDir + 4)); if (exportRva != 0 && exportSize != 0) { IntPtr exportDir = IntPtr.Add(baseAddr, exportRva); int numberOfNames = p.ReadValue(IntPtr.Add(exportDir, 0x18)); int addressOfFunctions = p.ReadValue(IntPtr.Add(exportDir, 0x1C)); int addressOfNames = p.ReadValue(IntPtr.Add(exportDir, 0x20)); int addressOfOrdinals = p.ReadValue(IntPtr.Add(exportDir, 0x24)); for (int i = 0; i < numberOfNames; i++) { int nameRva = p.ReadValue(IntPtr.Add(IntPtr.Add(baseAddr, addressOfNames), i * 4)); byte[] b = p.ReadBytes(IntPtr.Add(baseAddr, nameRva), 8); if (b.Length >= 6 && b[0] == 0x45 && b[1] == 0x45 && b[2] == 0x6D && b[3] == 0x65 && b[4] == 0x6D && b[5] == 0x00) { short ordinalIndex = p.ReadValue(IntPtr.Add(IntPtr.Add(baseAddr, addressOfOrdinals), i * 2)); int funcRva = p.ReadValue(IntPtr.Add(IntPtr.Add(baseAddr, addressOfFunctions), ordinalIndex * 4)); IntPtr exportAddr = IntPtr.Add(baseAddr, funcRva); vars.EEBase = p.ReadPointer(exportAddr); break; } } } } } return (IntPtr)vars.EEBase != IntPtr.Zero; } update { System.Diagnostics.Process p = game; if ((int)vars.reinitCooldown > 0) vars.reinitCooldown = (int)vars.reinitCooldown - 1; if ((IntPtr)vars.EEBase == IntPtr.Zero) { if ((int)vars.reinitCooldown == 0) { if ((bool)vars.DEBUG) print("EEBase missing; attempting reinit..."); vars.reinitCooldown = 30; vars.modBase = IntPtr.Zero; for (int i = 0; i < modules.Count(); i++) { string n = modules[i].ModuleName.ToLower(); if (n.StartsWith("pcsx2")) { vars.modBase = modules[i].BaseAddress; break; } } if ((IntPtr)vars.modBase != IntPtr.Zero) { vars.EEBase = IntPtr.Zero; IntPtr baseAddr = (IntPtr)vars.modBase; int e_lfanew = p.ReadValue(IntPtr.Add(baseAddr, 0x3C)); if (e_lfanew > 0) { IntPtr nt = IntPtr.Add(baseAddr, e_lfanew); int sig = p.ReadValue(nt); if (sig == 0x00004550) { short magic = p.ReadValue(IntPtr.Add(nt, 0x18)); int dataDir = (magic == 0x10B) ? 0x60 : 0x70; int exportRva = p.ReadValue(IntPtr.Add(IntPtr.Add(nt, 0x18), dataDir + 0)); int exportSize = p.ReadValue(IntPtr.Add(IntPtr.Add(nt, 0x18), dataDir + 4)); if (exportRva != 0 && exportSize != 0) { IntPtr exportDir = IntPtr.Add(baseAddr, exportRva); int numberOfNames = p.ReadValue(IntPtr.Add(exportDir, 0x18)); int addressOfFunctions = p.ReadValue(IntPtr.Add(exportDir, 0x1C)); int addressOfNames = p.ReadValue(IntPtr.Add(exportDir, 0x20)); int addressOfOrdinals = p.ReadValue(IntPtr.Add(exportDir, 0x24)); for (int i = 0; i < numberOfNames; i++) { int nameRva = p.ReadValue(IntPtr.Add(IntPtr.Add(baseAddr, addressOfNames), i * 4)); byte[] b = p.ReadBytes(IntPtr.Add(baseAddr, nameRva), 8); if (b.Length >= 6 && b[0] == 0x45 && b[1] == 0x45 && b[2] == 0x6D && b[3] == 0x65 && b[4] == 0x6D && b[5] == 0x00) { short ordinalIndex = p.ReadValue(IntPtr.Add(IntPtr.Add(baseAddr, addressOfOrdinals), i * 2)); int funcRva = p.ReadValue(IntPtr.Add(IntPtr.Add(baseAddr, addressOfFunctions), ordinalIndex * 4)); IntPtr exportAddr = IntPtr.Add(baseAddr, funcRva); vars.EEBase = p.ReadPointer(exportAddr); break; } } } } } if ((bool)vars.DEBUG && (IntPtr)vars.EEBase != IntPtr.Zero) print("Reinit OK; EEBase=0x" + ((IntPtr)vars.EEBase).ToString("X")); } } return; } IntPtr ee = (IntPtr)vars.EEBase; IntPtr hostFlagAddr = IntPtr.Add(ee, 0x2502C0); byte v; if (!p.ReadValue(hostFlagAddr, out v)) { if ((bool)vars.DEBUG) print("HostFlag read failed; clearing pointers for reinit."); vars.modBase = IntPtr.Zero; vars.EEBase = IntPtr.Zero; vars.loading = (byte)0; vars.lastLoading = (byte)255; vars.reinitCooldown = 0; return; } vars.loading = v; if ((bool)vars.DEBUG && v != (byte)vars.lastLoading) { print("EEBase = 0x" + ee.ToString("X")); print("HostFlagAddr = 0x" + hostFlagAddr.ToString("X")); print("Loading Value= " + v); vars.lastLoading = v; } } isLoading { return vars.loading != 0; }