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(); }
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }