예제 #1
0
        /// <summary>
        /// Finds a game process with a known engine.dll.
        /// </summary>
        Process GetGameProcess(out IntPtr curMapPtr, out IntPtr curTimePtr, out IntPtr signOnStatePtr)
        {
            string[] procs = _settings.GameProcesses.Select(x => x.ToLower().Replace(".exe", String.Empty)).ToArray();
            Process  p     = Process.GetProcesses().FirstOrDefault(x => procs.Contains(x.ProcessName.ToLower()));

            if (p != null && !p.HasExited && !IsVACProtectedProcess(p))
            {
                ProcessModuleEx engine = GetProcessModules(p).FirstOrDefault(x => x.ModuleName.ToLower() == "engine.dll");
                if (engine != null)
                {
                    var scanner = new SignatureScanner(p, engine.BaseAddress, engine.ModuleMemorySize);
                    curMapPtr  = scanner.Scan(_curMapTarget);
                    curTimePtr = scanner.Scan(_curTimeTarget);

                    signOnStatePtr = scanner.Scan(_signOnStateTarget1);
                    if (signOnStatePtr == IntPtr.Zero)
                    {
                        signOnStatePtr = scanner.Scan(_signOnStateTarget2);
                    }

                    if (curMapPtr != IntPtr.Zero && curTimePtr != IntPtr.Zero && signOnStatePtr != IntPtr.Zero)
                    {
                        return(p);
                    }
                }

                Debug.WriteLine("Invalid process or unknown engine.dll");
            }

            curMapPtr = curTimePtr = signOnStatePtr = IntPtr.Zero;
            return(null);
        }
예제 #2
0
        // also works for anything derived from CBaseEntity (player etc) (no multiple inheritance)
        // var must be included by one of the DEFINE_FIELD macros
        public static bool GetBaseEntityMemberOffset(string member, Process game, SignatureScanner scanner, out int offset)
        {
            offset = -1;

            IntPtr stringPtr = scanner.Scan(new SigScanTarget(0, Encoding.ASCII.GetBytes(member)));

            if (stringPtr == IntPtr.Zero)
            {
                return(false);
            }

            var b = BitConverter.GetBytes(stringPtr.ToInt32());

            var target = new SigScanTarget(10,
                                           String.Format("C7 05 ?? ?? ?? ?? {0:X02} {1:X02} {2:X02} {3:X02}", b[0], b[1], b[2], b[3])); // mov     dword_15E2BF1C, offset aM_fflags ; "m_fFlags"

            target.OnFound = (proc, s, ptr) => {
                // this instruction is almost always directly after above one, but there are a few cases where it isn't
                // so we have to scan down and find it
                var proximityScanner = new SignatureScanner(proc, ptr, 256);
                return(proximityScanner.Scan(new SigScanTarget(6, "C7 05 ?? ?? ?? ?? ?? ?? 00 00")));         // mov     dword_15E2BF20, 0CCh
            };

            IntPtr addr = scanner.Scan(target);

            if (addr == IntPtr.Zero)
            {
                return(false);
            }

            return(game.ReadInt32(addr, out offset));
        }
예제 #3
0
        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;
        }
예제 #4
0
        // also works for anything derived from CBaseEntity (player etc) (no multiple inheritance)
        // var must be included by one of the DEFINE_FIELD macros
        public static bool GetBaseEntityMemberOffset(string member, Process game, SignatureScanner scanner, out int offset)
        {
            offset = -1;

            IntPtr stringPtr = scanner.Scan(new SigScanTarget(0, Encoding.ASCII.GetBytes(member)));

            if (stringPtr == IntPtr.Zero)
            {
                return(false);
            }

            var b = BitConverter.GetBytes(stringPtr.ToInt32());

            var target = new SigScanTarget(10,
                                           $"C7 05 ?? ?? ?? ?? {b[0]:X02} {b[1]:X02} {b[2]:X02} {b[3]:X02}"); // mov     dword_15E2BF1C, offset aM_fflags ; "m_fFlags"

            target.OnFound = (proc, s, ptr) => {
                // this instruction is almost always directly after above one, but there are a few cases where it isn't
                // so we have to scan down and find it
                var proximityScanner = new SignatureScanner(proc, ptr, 256);
                return(proximityScanner.Scan(new SigScanTarget(6, "C7 05 ?? ?? ?? ?? ?? ?? 00 00")));         // mov     dword_15E2BF20, 0CCh
            };

            IntPtr addr = scanner.Scan(target);

            if (addr == IntPtr.Zero)
            {
                // seen in Black Mesa Source (legacy version)
                var target2 = new SigScanTarget(1,
                                                "68 ?? ?? ?? ??",                                   // push    256
                                                $"68 {b[0]:X02} {b[1]:X02} {b[2]:X02} {b[3]:X02}"); // push    offset aM_fflags ; "m_fFlags"
                addr = scanner.Scan(target2);

                if (addr == IntPtr.Zero)
                {
                    return(false);
                }
            }

            return(game.ReadValue(addr, out offset));
        }
예제 #5
0
        // 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
            ProcessModule engine = p.Modules.Cast <ProcessModule>().FirstOrDefault(x => x.ModuleName.ToLower() == "engine.dll");
            ProcessModule server = p.Modules.Cast <ProcessModule>().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)
            {
                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);
        }
예제 #6
0
        // 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
            ProcessModule engine = p.Modules.Cast<ProcessModule>().FirstOrDefault(x => x.ModuleName.ToLower() == "engine.dll");
            ProcessModule server = p.Modules.Cast<ProcessModule>().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)
                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;
        }
예제 #7
0
        // also works for anything derived from CBaseEntity (player etc) (no multiple inheritance)
        // var must be included by one of the DEFINE_FIELD macros
        public static bool GetBaseEntityMemberOffset(string member, Process game, SignatureScanner scanner, out int offset)
        {
            offset = -1;

            IntPtr stringPtr = scanner.Scan(new SigScanTarget(0, Encoding.ASCII.GetBytes(member)));
            if (stringPtr == IntPtr.Zero)
                return false;

            var b = BitConverter.GetBytes(stringPtr.ToInt32());

            var target = new SigScanTarget(10,
                String.Format("C7 05 ?? ?? ?? ?? {0:X02} {1:X02} {2:X02} {3:X02}", b[0], b[1], b[2], b[3])); // mov     dword_15E2BF1C, offset aM_fflags ; "m_fFlags"
            target.OnFound = (proc, s, ptr) => {
                // this instruction is almost always directly after above one, but there are a few cases where it isn't
                // so we have to scan down and find it
                var proximityScanner = new SignatureScanner(proc, ptr, 256);
                return proximityScanner.Scan(new SigScanTarget(6, "C7 05 ?? ?? ?? ?? ?? ?? 00 00"));         // mov     dword_15E2BF20, 0CCh
            };

            IntPtr addr = scanner.Scan(target);
            if (addr == IntPtr.Zero)
                return false;

            return game.ReadInt32(addr, out offset);
        }