#define DISALLOW_VERBOSE_LOGGING // when defined will disallow verbose logging for performance reasons using System; using System.Collections.Generic; using System.Linq; using System.Text; using RomCheater.PluginFramework.Core; using System.IO; using System.Diagnostics; using RomCheater.Logging; using Sojaner.MemoryScanner.MemoryProviers; using RomCheater.PluginFramework.Interfaces; namespace RomCheater.CorePlugins.Config { public sealed class PCSX2Config : ConfigPlugin { #region Configuration Memvers const string PCXS2_PROCESS_MAGIC = "pcsx2"; const string PCXS2_LOOKUP_MAGIC_001 = "pcsx2"; const string PCXS2_LOOKUP_MAGIC_002 = "compiled on"; const uint VTLB_VADDR_OFFSET_DEBUG = 0x20000000; const uint VTLB_VADDR_SIZE = 0x02000000; #endregion public PCSX2Config() : base(false) { } public PCSX2Config(bool doinit) : base(doinit) { } protected override bool IsNotValidProcess(ProcContainer proc) { bool isDebug = false; uint VTLB_RELEASE_OFFSET = 0; bool notvalid = !IsValidPSX2Process(proc.ProcessInfo.Id, out isDebug, out VTLB_RELEASE_OFFSET, proc); this.MemoryRangeStart = VTLB_RELEASE_OFFSET; if (isDebug) this.MemoryRangeStart = VTLB_VADDR_OFFSET_DEBUG; this.MemoryRangeSize = VTLB_VADDR_SIZE; if (notvalid) { #if !DISALLOW_VERBOSE_LOGGING logger.VerboseDebug.WriteLine(" Not Allowing process {0} to be added because it was filterd out", proc.Name); #endif } else { #if !DISALLOW_VERBOSE_LOGGING logger.VerboseDebug.WriteLine(" Allowing process {0} to be added", proc.Name); #endif } return notvalid; } #region IPluginBase Members public override Guid ID { get { return new GuidGenerator(typeof(PCSX2Config).FullName).Guid; } } public override string Name { get { return "PCSX2 Configuration Plugin"; } } public override string Description { get { return "This plugin provides a configuration suitable for use with PCSX2"; } } #endregion private bool IsValidPSX2Process(int pid, out bool isDebug, out uint VTLB_RELEASE_OFFSET, ProcContainer proc) { bool isValid = false; isDebug = false; VTLB_RELEASE_OFFSET = 0; try { Process p = null; try { p = Process.GetProcessById(pid); } catch { return false; } string filename = p.MainModule.FileName; FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read); // BinaryReader r = new BinaryReader(fs); // byte[] exe_check = new byte[] { // 0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, // 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, // 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, // 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, // 0x6D, 0x6F, 0x64, 0x65, 0x2E // }; // r.BaseStream.Seek(0, SeekOrigin.Begin); // byte[] data = r.ReadBytes(exe_check.Length); // bool isExe = false; // for (int i = 0; i < exe_check.Length; i++) { if (exe_check[i] == data[i]) { isExe = true; } else { isExe = false; } } // r.Close(); // if (!isExe) // { //#if !DISALLOW_VERBOSE_LOGGING // logger.VerboseDebug.WriteLine(" Process: {0} is not a valid executable file", filename); //#endif // isValid = false; // } // else // { // check for valid pcsx2 exe fs = new FileStream(filename, FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(fs); string found_string = sr.ReadToEnd(); if (found_string.ToLower().Contains(PCXS2_LOOKUP_MAGIC_001.ToLower()) && found_string.ToLower().Contains(PCXS2_LOOKUP_MAGIC_002.ToLower())) { isValid = true; #if !DISALLOW_VERBOSE_LOGGING logger.VerboseDebug.WriteLine(" Process: {0} found MAGIC LOOKUP {1} and {2}", filename, PCXS2_LOOKUP_MAGIC_001.ToLower(), PCXS2_LOOKUP_MAGIC_002.ToLower()); #endif } sr.Close(); // check for debug fs = new FileStream(filename, FileMode.Open, FileAccess.Read); sr = new StreamReader(fs); found_string = sr.ReadToEnd(); // DebugBreak should only be present in debug build version(s) of pcsx2 if (found_string.ToLower().Contains("DebugBreak".ToLower())) { isDebug = true; #if !DISALLOW_VERBOSE_LOGGING logger.VerboseDebug.WriteLine(" Process: {0} found DebugBreak", filename); #endif } sr.Close(); // } //this.IsDebugBuild = isDebug; // run check to see if we have a later version with offset fixed at: 0x20000000 byte[] entrypoint_data = new byte[]{ 0x01, 0x80, 0x1A, 0x3C, 0x78, 0x53, 0x59, 0xFF, 0x00, 0x68, 0x19, 0x40, 0x01, 0x80, 0x1A, 0x3C, 0x7C, 0x00, 0x39, 0x33, 0x21, 0xD0, 0x59, 0x03, 0x40, 0x53, 0x5A, 0x8F, 0x01, 0x80, 0x19, 0x3C, 0x08, 0x00, 0x40, 0x03, 0x78, 0x53, 0x39, 0xDF }; //uint address = ramdumper.VTLB_VADDR_OFFSET_DEBUG; IAcceptsProcessAndConfig pconfig = new AcceptedProcessAndConfig(this, proc.ProcessInfo); GenericMemoryProvider provider = new GenericMemoryProvider(pconfig); provider.OpenProvider(); int bytesReadSize; byte[] check_data = new byte[entrypoint_data.Length]; provider.ReadProcessMemory(VTLB_VADDR_OFFSET_DEBUG, (uint)entrypoint_data.Length, out bytesReadSize, out check_data); isDebug = check_data.SequenceEqual(entrypoint_data); #if !DISALLOW_VERBOSE_LOGGING logger.VerboseDebug.WriteLine(" Process: {0} isDebug: {1}", filename, isDebug.ToString()); #endif //List addresses = new List(); if (!isDebug) { for (int i = 0x1000; i < 0x2000; i++) { try { uint t = ((uint)i << 16) | 0x5000; provider.ReadProcessMemory(t, (uint)entrypoint_data.Length, out bytesReadSize, out check_data); isValid = check_data.SequenceEqual(entrypoint_data); if (isValid) { //addresses.Add(t); VTLB_RELEASE_OFFSET = t; #if !DISALLOW_VERBOSE_LOGGING logger.VerboseDebug.WriteLine(" Process: {0} found release build entrypoint at 0x{1:x8}", filename, t); #endif break; //use only the first valid value } } catch { } } } provider.CloseProvider(); return isValid; } catch (System.ComponentModel.Win32Exception) { } catch (Exception) { } return isValid; } } }