bool DerefOffsets(Process process, out IntPtr ptr) { if (!String.IsNullOrEmpty(_module)) { ProcessModuleWow64Safe module = process.ModulesWow64Safe().FirstOrDefault(m => m.ModuleName.ToLower() == _module.ToLower()); if (module == null) { ptr = IntPtr.Zero; return(false); } ptr = module.BaseAddress + _base; } else { ptr = process.MainModuleWow64Safe().BaseAddress + _base; } for (int i = 0; i < _offsets.Count - 1; i++) { if (!ReadProcessPtr32(process, ptr + _offsets[i], out ptr) || ptr == IntPtr.Zero) { return(false); } } return(true); }
public override void OnGameAttached(GameState state) { base.OnGameAttached(state); _cmdHandler.Init(state); ProcessModuleWow64Safe server = state.GetModule("server.dll"); var scanner = new SignatureScanner(state.GameProcess, server.BaseAddress, server.ModuleMemorySize); _getGlobalNameFuncPtr = scanner.Scan(new SigScanTarget("55 8B EC 51 FF 75 ?? 8D 45 ??")); _roHandler = new RemoteOpsHandler(state.GameProcess); if (GameMemory.GetBaseEntityMemberOffset("m_iHealth", state.GameProcess, scanner, out _baseEntityHealthOffset)) { Debug.WriteLine("CBaseEntity::m_iHealth offset = 0x" + _baseEntityHealthOffset.ToString("X")); } if (server.ModuleMemorySize < _serverModernModuleSize) { _ebEndCommand.BValue = true; // for mod, eb's final map name is different if (server.ModuleMemorySize <= _serverModModuleSize) { _ebEndMap = "bm_c3a2h"; } } }
public override void OnGameAttached(GameState state) { ProcessModuleWow64Safe server = state.GetModule("server.dll"); var scanner = new SignatureScanner(state.GameProcess, server.BaseAddress, server.ModuleMemorySize); if (GameMemory.GetBaseEntityMemberOffset("m_bSuppressingCrosshair", state.GameProcess, scanner, out _playerSuppressingCrosshairOffset)) { Debug.WriteLine("CPortalPlayer::m_bSuppressingCrosshair offset = 0x" + _playerSuppressingCrosshairOffset.ToString("X")); } }
public override void OnGameAttached(GameState state) { ProcessModuleWow64Safe server = state.GetModule("server.dll"); var scanner = new SignatureScanner(state.GameProcess, server.BaseAddress, server.ModuleMemorySize); if (GameMemory.GetBaseEntityMemberOffset("m_flLaggedMovementValue", state.GameProcess, scanner, out _laggedMovementOffset)) { Debug.WriteLine("CBasePlayer::m_flLaggedMovementValue offset = 0x" + _laggedMovementOffset.ToString("X")); } }
public override void OnGameAttached(GameState state) { ProcessModuleWow64Safe server = state.GetModule("server.dll"); var scanner = new SignatureScanner(state.GameProcess, server.BaseAddress, server.ModuleMemorySize); if (GameMemory.GetBaseEntityMemberOffset("m_iHealth", state.GameProcess, scanner, out _baseEntityHealthOffset)) { Debug.WriteLine("CBaseEntity::m_iHealth offset = 0x" + _baseEntityHealthOffset.ToString("X")); } }
public ExportTableParser(Process process, string module = null) { _process = process; _module = !string.IsNullOrEmpty(module) ? process.ModulesWow64Safe().FirstOrDefault(m => m.ModuleName.ToLower() == module.ToLower()) : process.MainModuleWow64Safe(); if (_module == null) { throw new ArgumentException("Module not found.", nameof(module)); } }
public override void OnGameAttached(GameState state) { ProcessModuleWow64Safe server = state.GameProcess.ModulesWow64Safe().FirstOrDefault(x => x.ModuleName.ToLower() == "server.dll"); Trace.Assert(server != null); var scanner = new SignatureScanner(state.GameProcess, server.BaseAddress, server.ModuleMemorySize); if (GameMemory.GetBaseEntityMemberOffset("m_iHealth", state.GameProcess, scanner, out _baseEntityHealthOffset)) { Debug.WriteLine("CBaseEntity::m_iHealth offset = 0x" + _baseEntityHealthOffset.ToString("X")); } }
public override void OnGameAttached(GameState state) { base.OnGameAttached(state); ProcessModuleWow64Safe vguimatsurface = state.GetModule("vguimatsurface.dll"); // there are other cleaner pointers but vguimatsurface is most unlikely to change // i would've tried to find a sigscanned method but the pointer is extremely hard to get to _creditsYPos = new MemoryWatcher <float>(new DeepPointer(vguimatsurface.BaseAddress + 0x147120, 0xF00, 0x2C, 0x9D4 + 0x1BC, 0x200)); _creditsCount = new MemoryWatcher <int>(new DeepPointer(vguimatsurface.BaseAddress + 0x147120, 0xF00, 0x2C, 0x9D4 + 0x1c8)); _yResolution = new MemoryWatcher <int>(vguimatsurface.BaseAddress + 0x136C28); _watcher = new MemoryWatcherList { _creditsYPos, _creditsCount, _yResolution }; }
public override void OnGameAttached(GameState state) { _ccHandler.Init(state); server = state.GetModule("server.dll"); client = state.GetModule("client.dll"); engine = state.GetModule("engine.dll"); var serverScanner = new SignatureScanner(state.GameProcess, server.BaseAddress, server.ModuleMemorySize); if (GameMemory.GetBaseEntityMemberOffset("m_angAbsRotation", state.GameProcess, serverScanner, out _baseEntityAngleOffset)) { Debug.WriteLine("CBaseEntity::m_angAbsRotation offset = 0x" + _baseEntityAngleOffset.ToString("X")); } if (GameMemory.GetBaseEntityMemberOffset("m_vecAngVelocity", state.GameProcess, serverScanner, out _baseEntityAngleVelOffset)) { Debug.WriteLine("CBaseEntity::m_vecAngVelocity offset = 0x" + _baseEntityAngleVelOffset.ToString("X")); } SigScanTarget _latest_Client_Trg = new SigScanTarget(0, Encoding.ASCII.GetBytes("ClientCommand, 0 length string supplied.")); _latest_Client_Trg.OnFound = (proc, scanner, ptr) => { byte[] b = BitConverter.GetBytes(ptr.ToInt32()); var target = new SigScanTarget(2, $"80 3D ?? ?? ?? ?? 00 75 ?? 68 {b[0]:X02} {b[1]:X02} {b[2]:X02} {b[3]:X02}"); // cmp byte ptr [clientcmdptr],00 IntPtr ptrPtr = scanner.Scan(target); if (ptrPtr == IntPtr.Zero) { return(IntPtr.Zero); } IntPtr ret; proc.ReadPointer(ptrPtr, out ret); Debug.WriteLine("CVEngineServer::ClientCommand szOut ptr is 0x" + ret.ToString("X")); return(ret); }; var engineScanner = new SignatureScanner(state.GameProcess, engine.BaseAddress, engine.ModuleMemorySize); _endingsWatcher.ResetAll(); _endingSeriousCount = 0; _latestClientCmd = new StringWatcher(engineScanner.Scan(_latest_Client_Trg), 50); _endingsWatcher.Add(_latestClientCmd); }
internal ProcessModuleWow64Safe TryGetProcess() { StationaryPrint sp = new StationaryPrint(_pr); again: ProcessModuleWow64Safe proc = Game.GetModuleWow64Safe(Name); if (proc == null) { sp.Print($"Couldn't find {Name}, retrying in 1s", PrintLevel.Warning); Thread.Sleep(1000); goto again; } sp.Return(); return(proc); }
/// <summary> /// Initialize signature scanners and sigscan. /// </summary> private static void Init() { Log("Starting with default values", false); Action <string, IntPtr> SigReport = (name, ptr) => { Console.WriteLine("[INIT] " + name + (ptr == IntPtr.Zero ? " WAS NOT FOUND" : " is 0x" + ptr.ToString("X"))); }; SigScanTarget _entListSig = new SigScanTarget(6, "40 ?? 48 ?? ?? ??", "48 ?? ?? ?? ?? ?? ??", // MOV RAX,qword ptr [DAT_1814e3bc0] "8b ?? 48 ?? ?? ?? ?? ?? ?? 48 ?? ?? ff ?? ?? ?? ?? ?? 4c ?? ??"); _entListSig.OnFound = (proc, scanner, ptr) => GetPointer(ptr, 3, 7); SigScanTarget _gamePathSig = new SigScanTarget(7, "48 8B 97 ?? ?? ?? ??", "48 8D 0D ?? ?? ?? ??", // LEA RCX,[mapname] "48 8B 5C 24 ??"); _gamePathSig.OnFound = (proc, scanner, ptr) => GetPointer(ptr, 3, 7); ProcessModuleWow64Safe[] modules = game.ModulesWow64Safe(); ProcessModuleWow64Safe server = modules.FirstOrDefault(x => x.ModuleName.ToLower() == "server.dll"); ProcessModuleWow64Safe engine = modules.FirstOrDefault(x => x.ModuleName.ToLower() == "engine2.dll"); while (server == null || engine == null) { Console.WriteLine("[INIT] Modules aren't yet loaded! Waiting 1 second until next try"); Thread.Sleep(1000); } var serverScanner = new SignatureScanner(game, server.BaseAddress, server.ModuleMemorySize); var engineScanner = new SignatureScanner(game, engine.BaseAddress, engine.ModuleMemorySize); _entListPtr = serverScanner.Scan(_entListSig); SigReport("entity list", _entListPtr); _gamePathPtr = engineScanner.Scan(_gamePathSig); SigReport("game path / map name", _gamePathPtr); Console.WriteLine("gamepath " + game.ReadString(_gamePathPtr, 255) + " "); _mapName = new StringWatcher(_mapNamePtr, 255); _watchers.Add(_mapName); }
public void Init(GameState state) { _remoteOps = new RemoteOpsHandler(state.GameProcess); _cmdBufferPtr = IntPtr.Zero; ProcessModuleWow64Safe engine = state.GetModule("engine.dll"); var scanner = new SignatureScanner(state.GameProcess, engine.BaseAddress, engine.ModuleMemorySize); IntPtr ptr = scanner.Scan(new SigScanTarget("68" + scanner.Scan(new SigScanTarget("execing %s\n".ConvertToHex())).GetByteString())); if (ptr == IntPtr.Zero) { goto fail; } byte[] bytes = state.GameProcess.ReadBytes(ptr, 100); for (int i = 0; i < 100; i++) { byte e = bytes[i]; if (e == 0xA1 || (bytes[i] >= 0xB8 && bytes[i] <= 0xBF)) { uint val = state.GameProcess.ReadValue <uint>(ptr + i + 1); if (scanner.IsWithin(val)) { _cmdBufferPtr = (IntPtr)val; Debug.WriteLine("Command buffer found at 0x" + _cmdBufferPtr.ToString("X")); break; } } } GetExecPtr(state); Update(state); SendConsoleMsg("\nSourceSplit Custom Commands are present, enter \"ss_list\" to list them, or \"ss_h\" for help!\n\n"); return; fail: _cmdBufferPtr = IntPtr.Zero; Debug.WriteLine("Failed to initialize custom command handler!"); return; }
public static SYMBOL_INFO[] AllSymbols(this Process process, ProcessModuleWow64Safe module, string symbol = "*") { var procHandle = process.Handle; if (!WinAPI.SymInitialize(procHandle, Path.GetDirectoryName(module.FileName), false)) { throw new Exception("Failed to initialize symbols."); } var symbols = new List <SYMBOL_INFO>(); try { if (WinAPI.SymLoadModuleEx(procHandle, IntPtr.Zero, module.ModuleName, null, (ulong)(module.BaseAddress), (uint)(module.ModuleMemorySize), IntPtr.Zero, 0) == 0) { throw new Exception("Failed to load module's symbols."); } WinAPI.PSYM_ENUMERATESYMBOLS_CALLBACK callback = new(enumSyms); if (!WinAPI.SymEnumSymbols(procHandle, (ulong)(module.BaseAddress), symbol, callback, IntPtr.Zero)) { throw new Exception("Failed to enumerate over module's symbols."); } } finally { WinAPI.SymCleanup(procHandle); } return(symbols.ToArray()); bool enumSyms(ref SYMBOL_INFO pSymInfo, uint SymbolSizem, IntPtr UserContext) { symbols.Add(pSymInfo); return(true); } }
public override void OnGameAttached(GameState state) { ProcessModuleWow64Safe server = state.GetModule("server.dll"); ProcessModuleWow64Safe bink = state.GetModule("video_bink.dll"); var scanner = new SignatureScanner(state.GameProcess, server.BaseAddress, server.ModuleMemorySize); if (GameMemory.GetBaseEntityMemberOffset("m_iHealth", state.GameProcess, scanner, out _baseEntityHealthOffset)) { Debug.WriteLine("CBaseEntity::m_iHealth offset = 0x" + _baseEntityHealthOffset.ToString("X")); } if (GameMemory.GetBaseEntityMemberOffset("m_flLaggedMovementValue", state.GameProcess, scanner, out _basePlayerLaggedMovementOffset)) { Debug.WriteLine("CBasePlayer::m_flLaggedMovementValue offset = 0x" + _basePlayerLaggedMovementOffset.ToString("X")); } _watcher.ResetAll(); // i would've sigscanned this but this dll is a 3rd party thing anyways so its unlikely to change between versions // and the game crashes when i try to debug it so oh well... _isInCutscene = new MemoryWatcher <byte>(bink.BaseAddress + 0x1b068); _watcher.Add(_isInCutscene); }
Process GetGameProcess() { Process game = Process.GetProcesses().FirstOrDefault(p => p.ProcessName.ToLower() == "pf" && !p.HasExited && !_ignorePIDs.Contains(p.Id)); if (game == null) { return null; } binkw32 = game.ModulesWow64Safe().FirstOrDefault(p => p.ModuleName.ToLower() == "binkw32.dll"); if (binkw32 == null) return null; if (game.MainModuleWow64Safe().ModuleMemorySize == (int)ExpectedDllSizes.PureFaction30d) { } else { _ignorePIDs.Add(game.Id); _uiThread.Send(d => MessageBox.Show("Unexpected game version. Red Faction (Pure Faction 3.0d) is required", "LiveSplit.RedFaction", MessageBoxButtons.OK, MessageBoxIcon.Error), null); return null; } return game; }
// TODO: log fails bool TryGetGameProcess(out Process p, out GameOffsets offsets) { #if DEBUG var sw = Stopwatch.StartNew(); #endif string[] procs = _settings.GameProcesses.Select(x => x.ToLower().Replace(".exe", String.Empty)).ToArray(); p = Process.GetProcesses().FirstOrDefault(x => procs.Contains(x.ProcessName.ToLower())); offsets = new GameOffsets(); if (p == null || p.HasExited || Util.IsVACProtectedProcess(p)) { return(false); } // process is up, check if engine and server are both loaded yet ProcessModuleWow64Safe engine = p.ModulesWow64Safe().FirstOrDefault(x => x.ModuleName.ToLower() == "engine.dll"); ProcessModuleWow64Safe server = p.ModulesWow64Safe().FirstOrDefault(x => x.ModuleName.ToLower() == "server.dll"); if (engine == null || server == null) { return(false); } // required engine stuff var scanner = new SignatureScanner(p, engine.BaseAddress, engine.ModuleMemorySize); if ((offsets.CurMapPtr = scanner.Scan(_curMapTarget)) == IntPtr.Zero || (offsets.CurTimePtr = scanner.Scan(_curTimeTarget)) == IntPtr.Zero || (offsets.GameDirPtr = scanner.Scan(_gameDirTarget)) == IntPtr.Zero || (offsets.HostStatePtr = scanner.Scan(_hostStateTarget)) == IntPtr.Zero || (offsets.ServerStatePtr = scanner.Scan(_serverStateTarget)) == IntPtr.Zero) { return(false); } if ((offsets.SignOnStatePtr = scanner.Scan(_signOnStateTarget1)) == IntPtr.Zero && (offsets.SignOnStatePtr = scanner.Scan(_signOnStateTarget2)) == IntPtr.Zero) { return(false); } // required server stuff var serverScanner = new SignatureScanner(p, server.BaseAddress, server.ModuleMemorySize); if ((offsets.GlobalEntityListPtr = serverScanner.Scan(_globalEntityListTarget)) == IntPtr.Zero) { return(false); } // entity offsets if (!GetBaseEntityMemberOffset("m_fFlags", p, serverScanner, out offsets.BaseEntityFlagsOffset) || !GetBaseEntityMemberOffset("m_vecAbsOrigin", p, serverScanner, out offsets.BaseEntityAbsOriginOffset) || !GetBaseEntityMemberOffset("m_iName", p, serverScanner, out offsets.BaseEntityTargetNameOffset) || !GetBaseEntityMemberOffset("m_hViewEntity", p, serverScanner, out offsets.BasePlayerViewEntity)) { return(false); } // find m_pParent offset. the string "m_pParent" occurs more than once so we have to do something else // in old engine it's right before m_iParentAttachment. in new engine it's right before m_nTransmitStateOwnedCounter // TODO: test on all engines int tmp; if (!GetBaseEntityMemberOffset("m_nTransmitStateOwnedCounter", p, serverScanner, out tmp)) { if (!GetBaseEntityMemberOffset("m_iParentAttachment", p, serverScanner, out tmp)) { return(false); } tmp -= 4; // sizeof m_iParentAttachment } tmp -= 4; // sizeof m_nTransmitStateOwnedCounter (4 aligned byte) offsets.BaseEntityParentHandleOffset = tmp; Debug.WriteLine("CBaseServer::m_szMapname ptr = 0x" + offsets.CurMapPtr.ToString("X")); Debug.WriteLine("CGlobalVarsBase::curtime ptr = 0x" + offsets.CurTimePtr.ToString("X")); Debug.WriteLine("CBaseClientState::m_nSignonState ptr = 0x" + offsets.SignOnStatePtr.ToString("X")); Debug.WriteLine("CBaseEntityList::(CEntInfo)m_EntPtrArray ptr = 0x" + offsets.GlobalEntityListPtr.ToString("X")); Debug.WriteLine("CBaseEntity::m_fFlags offset = 0x" + offsets.BaseEntityFlagsOffset.ToString("X")); Debug.WriteLine("CBaseEntity::m_vecAbsOrigin offset = 0x" + offsets.BaseEntityAbsOriginOffset.ToString("X")); Debug.WriteLine("CBaseEntity::m_iName offset = 0x" + offsets.BaseEntityTargetNameOffset.ToString("X")); Debug.WriteLine("CBaseEntity::m_pParent offset = 0x" + offsets.BaseEntityParentHandleOffset.ToString("X")); Debug.WriteLine("CBasePlayer::m_hViewEntity offset = 0x" + offsets.BasePlayerViewEntity.ToString("X")); #if DEBUG Debug.WriteLine("TryGetGameProcess took: " + sw.Elapsed); #endif return(true); }
void FIND_SleepUntilInput() { _context.Name = "SleepUntilInput"; _subContext1.Name = "CEngine::Frame"; IntPtr ptr = _scanner.FindStringPtr("fs_report_sync_opens"); ptr.Report(_pr, "string"); if (ptr == IntPtr.Zero) { return; } ptr = _scanner.Scan(new Signature("68" + ptr.GetByteString())); ptr = _scanner.BackTraceToFuncStart(ptr, Intermediate.Modify(vftable: 1)); ptr.Report(_pr, level: BlueFG); if (ptr == IntPtr.Zero) { return; } SigScanner tmpScanner = new SigScanner(Game, ptr, _scanner.TraceToFuncEnd(ptr)); SigCollection sc = new SigCollection( new Signature("75 ?? ?? ?? ?? ?? ?? ?? 75", 9), new Signature("0F 85 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 0F 85", 0xE)); ptr = tmpScanner.Scan(sc); ptr.Report(_pr, "Target instructions"); if (ptr == IntPtr.Zero) { return; } tmpScanner = new SigScanner(Game, ptr, Game.ReadValue <byte>(ptr) + 1); Signature sig = new Signature("8B 0D", 2); ptr = tmpScanner.Scan(sig); IntPtr inputDLLBase = Game.ReadPointer(ptr); inputDLLBase.Report(_pr, "Input DLL base", BlueFG); tmpScanner.Limit(ptr + 4); sig = new Signature("FF"); sig.EvaluateMatch = (a) => { for (int i = 0; i < 4; i++) { if (_scanner.IsWithin(Game.ReadRelativeReference(a - i))) { return(false); } } return(true); }; ptr = tmpScanner.Scan(sig); ptr.Report(_pr, "Scan region end"); if (ptr == IntPtr.Zero) { return; } _subContext1.Name = ""; int[] possibleOffsets = new int[2]; possibleOffsets[0] = Game.ReadValue <byte>(ptr + 0x2); byte[] bytes = Game.ReadBytes(tmpScanner.Start, ptr.SubtractI(tmpScanner.Start) + 2); for (int i = bytes.Count() - 1; i >= 0; i--) { if (bytes[i] == 0x8B) { possibleOffsets[1] = bytes[i + 2]; break; } } _pr.Print($"Possible offsets include 0x{possibleOffsets[0]:X} and 0x{possibleOffsets[1]:X}, testing both...", BlueFG); ProcessModuleWow64Safe inputDLL = Game.GetModuleWow64Safe("inputsystem.dll"); SigScanner inputDLLScanner = inputDLL == null ? null : new SigScanner(Game, inputDLL.BaseAddress, inputDLL.ModuleMemorySize); foreach (int off in possibleOffsets) { new DeepPointer(inputDLLBase, 0x0, off, 0x0).DerefOffsets(Game, out ptr); _pr.Print($"Offset 0x{off:X} leads to 0x{ptr.ToString("X8")}"); if (ptr != IntPtr.Zero) { if (!_scanner.IsWithin(ptr)) { if (inputDLLScanner != null) { if (!inputDLLScanner.IsWithin(ptr)) { continue; } } else { continue; } } ptr.Report(_pr, "candidate", BlueBG); break; } } }
public override void OnGameAttached(GameState state) { ProcessModuleWow64Safe server = state.GetModule("server.dll"); var scanner = new SignatureScanner(state.GameProcess, server.BaseAddress, server.ModuleMemorySize); this.EndOffsetTicks = 0; IntPtr getStringPtr(string str) { return(scanner.Scan(new SigScanTarget(0, str.ConvertToHex() + " 00"))); } IntPtr getPtrRef(IntPtr ptr, SignatureScanner scanner, params string[] prefixes) { if (ptr == IntPtr.Zero) { return(ptr); } string ptrStr = ptr.GetByteString(); SigScanTarget target = new SigScanTarget(); prefixes.ToList().ForEach(x => target.AddSignature(0, x + " " + ptrStr)); return(scanner.Scan(target)); } IntPtr ptr; SigScanTarget target; if ((ptr = getPtrRef(getStringPtr("n_max"), scanner, "68")) == IntPtr.Zero) { return; } bool found = false; target = new SigScanTarget(1, "68"); target.OnFound = (f_proc, f_scanner, f_ptr) => { IntPtr ptr = f_proc.ReadPointer(f_ptr); found = !(ptr.ToInt32() < scanner.Address.ToInt32() || ptr.ToInt32() > scanner.Address.ToInt32() + scanner.Size); return(f_ptr); }; var scanner2 = new SignatureScanner(state.GameProcess, ptr + 10, 0x1000); while ((ptr = scanner2.Scan(target)) != IntPtr.Zero && !found && scanner2.Size > 6) { scanner2 = new SignatureScanner( state.GameProcess, ptr, scanner2.Address.ToInt32() + 0x1000 - ptr.ToInt32()); } if (ptr == IntPtr.Zero) { return; } ptr = state.GameProcess.ReadPointer(ptr); target = new SigScanTarget(2, "80 ?? ?? ?? ?? 00 00 74"); target.AddSignature(2, "8A ?? ?? ?? 00 00 84"); scanner2 = new SignatureScanner(state.GameProcess, ptr, 0x100); ptr = scanner2.Scan(target); _nihiDeadOffset = state.GameProcess.ReadValue <int>(ptr); Debug.WriteLine("nihi dead bool offset is 0x" + _nihiDeadOffset.ToString("x")); }