public unsafe IEnumerable <NamedOffset> FindOffsets(NamedPattern[] patterns, IntPtrEx @base, int size)
        {
            var buff = new byte[size];

            fixed(byte *ptr = buff)
            if (!this.TryReadRawMemory(@base, ptr, size, out var read) || read != size)
            {
                return(null);
            }

            var baseval = @base.Pointer.ToInt32();

            var offsets = new NamedOffset[patterns.Length];

            for (var i = 0; i < patterns.Length; i++)
            {
                var pattern = patterns[i];
                var off     = this.FindPattern(pattern.Pattern, buff);

                var ptr = 0;
                if (!this.TryReadRawMemory(@base + off + pattern.PointerStart, &ptr, sizeof(int), out var read) || read != sizeof(int))
                {
                    throw new InvalidProcessException();
                }

                offsets[i] = new NamedOffset(ptr - baseval, pattern.Name);
            }

            return(offsets);
        }
        /// <summary>
        /// Reads and follows a pointer chain.
        /// </summary>
        /// <param name="addr">Address to start at.</param>
        /// <param name="offsets">Offsets to follow.</param>
        /// <returns>Final pointer.</returns>
        public unsafe IntPtrEx ReadPointerChain(IntPtrEx addr, params int[] offsets)
        {
            foreach (var offset in offsets)
            {
                addr = this.ReadPointer(addr + offset);
            }

            return(addr);
        }
Exemple #3
0
        private GameProcess(Process p, IntPtrEx gameModule, int moduleSize)
        {
            this._proc       = p;
            this._module     = gameModule;
            this._moduleSize = moduleSize;
            this._cts        = new CancellationTokenSource();
            this._ct         = this._cts.Token;

            this._proc.Exited += this._proc_Exited;
        }
        /// <summary>
        /// Reads a pointer from the process' memory.
        /// </summary>
        /// <param name="addr">Address to read from.</param>
        /// <returns>Read pointer.</returns>
        public unsafe IntPtrEx ReadPointer(IntPtrEx addr)
        {
            var ptrval = 0;

            if (!this.TryReadRawMemory(addr, &ptrval, sizeof(int), out var read) || read != sizeof(int))
            {
                throw new MemoryReadException();
            }

            return(new IntPtr(ptrval));
        }
        private unsafe bool TryReadRawMemory(IntPtrEx addr, void *buff, int size, out int read)
        {
            read = -1;
            if (!PInvoke.ReadProcessMemory(this._proc.Handle, addr.Pointer, buff, new IntPtr(size), out var pread))
            {
                return(false);
            }

            read = pread.ToInt32();
            return(true);
        }
        /// <summary>
        /// Reads data of a blittable data structure.
        /// </summary>
        /// <typeparam name="T">Type of data to read.</typeparam>
        /// <param name="addr">Address to read from.</param>
        /// <returns>Read data.</returns>
        public unsafe T Read <T>(IntPtrEx addr)
            where T : unmanaged
        {
            var val  = default(T);
            var size = sizeof(T);

            if (!this.TryReadRawMemory(addr, &val, size, out var read) || read != size)
            {
                throw new MemoryReadException();
            }

            return(val);
        }
        /// <summary>
        /// Reads a string from the process' memory.
        /// </summary>
        /// <param name="addr">Address to read from.</param>
        /// <param name="maxLength">Maximum string length to read.</param>
        /// <returns>Read string.</returns>
        public unsafe string ReadString(IntPtrEx addr, int maxLength = 256)
        {
            var buff = stackalloc char[maxLength];

            if (!this.TryReadRawMemory(addr, buff, maxLength * sizeof(char), out var read))
            {
                throw new MemoryReadException();
            }

            var spbuff = new Span <char>(buff, read / sizeof(char));
            var len    = spbuff.IndexOf('\0');

            if (len < 0)
            {
                return(new string(spbuff));
            }

            return(new string(spbuff.Slice(0, len)));
        }
        /// <summary>
        /// Reads an ANSI string from the process' memory.
        /// </summary>
        /// <param name="addr">Address to read from.</param>
        /// <param name="maxLength">Maximum string length to read.</param>
        /// <returns>Read string.</returns>
        public unsafe string ReadAnsiString(IntPtrEx addr, int maxLength = 256)
        {
            var buff = stackalloc byte[maxLength];

            if (!this.TryReadRawMemory(addr, buff, maxLength, out var read))
            {
                throw new MemoryReadException();
            }

            var spbuff = new Span <byte>(buff, read);
            var len    = spbuff.IndexOf((byte)0x00);

            if (len >= 0)
            {
                spbuff = spbuff.Slice(0, len);
            }

            return(Encoding.ASCII.GetString(spbuff));
        }
Exemple #9
0
        private void ValidateKlass(IntPtrEx klassPtr, params string[] refNames)
        {
            // For whatever bloody reason, the pointers are off by one sometimes.
            // Always case with LSB
            var ptrv = klassPtr.Pointer.ToInt32();

            if ((ptrv & 0x1) == 0x1)
            {
                ptrv &= ~0x1;
            }

            var klass = this._mem.Read <RawClassInfo>(new IntPtr(ptrv));
            var name  = this._mem.ReadAnsiString(klass.Name);

            if (!refNames.Any(x => name == x))
            {
                throw new InvalidProcessException();
            }
        }
Exemple #10
0
        public GameReader(ProcessMemory pmem, IntPtrEx module, int moduleSize)
        {
            this._mem        = pmem;
            this._module     = module;
            this._moduleSize = moduleSize;
            this._state      = new GameStateInfo();

            var offsets = this._mem.FindOffsets(new NamedPattern[]
            {
                new NamedPattern(Offsets.ClientName, Offsets.ClientPattern, Offsets.ClientPatternPtrLocation),
                new NamedPattern(Offsets.MeetingHudName, Offsets.MeetingHudPattern, Offsets.MeetingHudPatternPtrLocation),
                new NamedPattern(Offsets.GameDataName, Offsets.GameDataPattern, Offsets.GameDataPatternPtrLocation),
                new NamedPattern(Offsets.ShipStatusName, Offsets.ShipStatusPattern, Offsets.ShipStatusPatternPtrLocation)
            }, this._module, this._moduleSize);

            foreach (var offset in offsets)
            {
                switch (offset.Name)
                {
                case Offsets.ClientName:
                    Offsets.ClientBase = offset.Offset;
                    break;

                case Offsets.MeetingHudName:
                    Offsets.MeetingHudBase = offset.Offset;
                    break;

                case Offsets.GameDataName:
                    Offsets.GameDataBase = offset.Offset;
                    break;

                case Offsets.ShipStatusName:
                    Offsets.ShipStatusBase = offset.Offset;
                    break;
                }
            }

            if (Offsets.ClientBase == 0 || Offsets.MeetingHudBase == 0 || Offsets.GameDataBase == 0 || Offsets.ShipStatusBase == 0)
            {
                throw new InvalidProcessException();
            }
        }