public static List <IntPtr> FindRelativeCalls(this SigScanner scanner, IntPtr ptr, IntPtr start, IntPtr end, int delta = 0) { _context.Update($"Relative Calls : 0x{ptr.ToString("X")}", ConsoleColor.Green); StationaryPrint sp = new StationaryPrint(_pr); char[] posArr = new char[8]; int boundary = 0; int deltaEnd = end.SubtractI(ptr).Abs(); int deltaStart = start.SubtractI(ptr).Abs(); boundary = deltaEnd > deltaStart ? deltaEnd : deltaStart; for (int i = 0x10000000, j = 0; i >= 1; i /= 0x10, j++) { posArr[_endianMapping[j]] = boundary > i ? '?' : '0'; } string pos = new string(posArr); string neg = pos.Replace('0', 'F'); SigCollection s = new SigCollection(); s.Add("E8 " + neg); s.Add("E8 " + pos); s.Add("E9 " + neg); s.Add("E9 " + pos); SigScanner newScanner = new SigScanner( scanner.Process, start, (int)end.Subtract(start)); s.EvaluateMatch = (a) => { if ((int)(Math.Abs(a.SubtractI(ptr))) < boundary && Math.Abs(scanner.Process.ReadRelativeReference(a).SubtractI(ptr)) <= delta) { sp.Print($"Match at 0x{a.ToString("X")}"); return(true); } return(false); }; try { return(newScanner.ScanAll(s)); } finally { sp.Return(); } }
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); }
void FIND_CheckJumpButton() { _context.Name = "CheckJumpButton"; _pr.Print("Running method 1 -- finding \"xc_uncrouch_on_jump\" string ref and retracing", BlueFG); _subContext1.Name = "1"; IntPtr ptr = _scanner.FindCVarBase("xc_uncrouch_on_jump"); IntPtr ptr2 = ptr; ptr.Report(_pr, "cvar base"); if (ptr == IntPtr.Zero) { goto method2; } Signature sig = new Signature((ptr + GetIntOffset).GetByteString()); ptr = _scanner.Scan(sig); if (ptr == IntPtr.Zero) { ptr = _scanner.FindMOVReferences(ptr2).FirstOrDefault(); } ptr.Report(_pr, "string ref"); ptr = _scanner.BackTraceToFuncStart(ptr, Extreme); ptr.Report(_pr, "estimated hl2 base", BlueBG); _listCheckJumpButtonMatches.Add(ptr); //------------------- method2: _subContext1.Name = ""; _pr.Print("Running method 2 -- finding float ref and retracing", BlueFG); _subContext1.Name = "2"; _pr.Print("There may be more than than one match", YellowFG); int i = 0; StationaryPrint sp = new StationaryPrint(_pr); Action <IntPtr, List <IntPtr> > commonCallback = (f, rl) => { float d = Game.ReadValue <float>(f); foreach (IntPtr r in rl) { _pr.Print($"Float {d} at 0x{f.ToString("X")} referenced at 0x{r.ToString("X")}"); IntPtr r2 = _scanner.BackTraceToFuncStart(r, Extreme); r2.Report(_pr, $"Estimate #{++i}", BlueBG); _listCheckJumpButtonMatches.Add(r2); sp.Update(); } }; SigCollection sc = new SigCollection( "00 00 20 43", "01 2A 86 43"); sc.EvaluateMatch = (a) => { sp.Print($"Float found at 0x{a.ToString("X")}"); Signature f_sig = new Signature(a.GetByteString() + "EB"); var f_tmp = _scanner.ScanAll(f_sig); if (f_tmp.Count != 0) { commonCallback(a, f_tmp); } return(true); }; var tmpSig = new Signature("00 00 34 42"); tmpSig.EvaluateMatch = (a) => { sp.Print($"Float found at 0x{a.ToString("X")}"); Signature f_sig = new Signature("8B ?? ?? F3 0F ?? ??" + a.GetByteString() + "8B"); var f_tmp = _scanner.ScanAll(f_sig); if (f_tmp.Count != 0) { commonCallback(a, f_tmp); } return(true); }; _scanner.ScanAll(sc); _scanner.Scan(tmpSig); sp.Return(); _listCheckJumpButtonMatches = _listCheckJumpButtonMatches.Where(x => x != IntPtr.Zero).ToList(); //------------------- _subContext1.Name = ""; _pr.Print("Final step -- coercing remaning matches through TryPlayerMove VFTable entries", BlueFG); _subContext1.Name = "final"; _listCheckJumpButtonMatches = _listCheckJumpButtonMatches.Distinct().ToList(); List <IntPtr> listTryPlayerMoveMatches = new List <IntPtr>(); i = 0; foreach (IntPtr cjbPtr in _listCheckJumpButtonMatches) { ptr = _scanner.FindVFTableEntries(cjbPtr).FirstOrDefault(); if (ptr == IntPtr.Zero || !_scanner.IsWithin(ptr = Game.ReadPointer(ptr + 0xc))) { continue; } ptr.Report(_pr, $"TryPlayerMove ptr candidate " + ++i); listTryPlayerMoveMatches.Add(ptr); } foreach (IntPtr tpmPtr in listTryPlayerMoveMatches) { sig = new Signature(tpmPtr.GetByteString()); var tpmMatches = _scanner.FindVFTableEntries(tpmPtr); foreach (IntPtr tpmVFT in tpmMatches) { ptr = Game.ReadPointer(tpmVFT - 0xC); if (_scanner.IsWithin(ptr) && !_listCheckJumpButtonMatches.Contains(ptr)) { _listCheckJumpButtonMatches.Add(ptr); ptr.Report(_pr, $"New potential CheckJumpButton match", BlueBG); } } } }
public static IntPtr BackTraceToFuncStart( this SigScanner scanner, IntPtr ptr, int boundary = 0x600, int interruptAmount = 3, bool checkVFTable = false, int checkCallBoundary = 0) { if (ptr == IntPtr.Zero) { return(IntPtr.Zero); } List <IntPtr> foundFunctions = new List <IntPtr>(); if (checkCallBoundary > 0) { foundFunctions = scanner.FindRelativeCalls(ptr - (boundary >> 1), checkCallBoundary, boundary >> 1); foundFunctions = foundFunctions.ConvertAll(x => Program.Game.ReadRelativeReference(x)); } //calls.ForEach(x => x.Report()); _context.Update($"Backtrace : 0x{ptr.ToString("X")}", ConsoleColor.Blue); StationaryPrint sp = new StationaryPrint(_pr); IntPtr curPtr = ptr; while (boundary > 0 && !curPtr.IsSmaller(scanner.Start)) { boundary--; curPtr = curPtr - 1; byte curByte = scanner.Process.ReadValue <byte>(curPtr, 1); byte lastByte = scanner.Process.ReadValue <byte>(curPtr + 1); sp.Print($"{boundary} bytes left, 0x{curPtr.ToString("X")} : {curByte:X02} {lastByte:X02}"); if (!_backTraceBytes.Contains(curByte) || _backTraceBytes.Contains(lastByte)) { continue; } try { if (interruptAmount > 0 && (curByte == 0x90 || curByte == 0xCC)) { byte[] interruptBytes = scanner.Process.ReadBytes(curPtr - interruptAmount, interruptAmount); if (interruptBytes.All(x => x == 0x90 || x == 0xCC)) { return(curPtr + 1); } } IntPtr tmp = curPtr + ((curByte == 0xC2) ? 0x3 : 0x1); if (checkVFTable) { if (scanner.FindVFTableEntries(tmp).Count != 0x0) { return(tmp); } } if (checkCallBoundary > 0 && foundFunctions.Count() > 0) { if (foundFunctions.Contains(tmp)) { return(tmp); } } } finally { sp.Return(); } } return(IntPtr.Zero); }