예제 #1
0
        /// <summary>
        /// Will load all the memory region information of the program into a list for faster scanning
        /// </summary>
        private void LoadMemoryRegions()
        {
            // the current address being scanned
            var address = new IntPtr();

            _memoryRegionsSortedIndices = new SortedList <Int32, int>();
            var count = 0;

            while (true)
            {
                // get the memory information for the first region
                var memInfo = new MemoryApi.MemoryBasicInformation();
                int result  = MemoryApi.VirtualQueryEx(_process.Handle, address, out memInfo,
                                                       (uint)Marshal.SizeOf(memInfo));

                // virtualqueryex will return 0 when we're out of range of the application
                if (0 == result)
                {
                    break;
                }

                // filter out any that don't have commit or aren't writable
                if (0 != (memInfo.State & MemCommit) && 0 != (memInfo.Protect & Writable) &&
                    0 == (memInfo.Protect & PageGuard))
                {
                    // store the information
                    MemoryRegions.Add(memInfo);
                    _memoryRegionsSortedIndices.Add(memInfo.BaseAddress.ToInt32(), count++);
                }

                // move to the next memory region
                address = new IntPtr(memInfo.BaseAddress.ToInt32() + memInfo.RegionSize);
            }
        }
예제 #2
0
        public void Initialize(int processId, ErrorHandler errorHandler)
        {
            _process   = null;
            _processId = 0;
            _processMainWindowHandle = IntPtr.Zero;
            _baseAddress             = IntPtr.Zero;
            _errorHandler            = errorHandler;

            // get a reference to the process
            try
            {
                _process = Process.GetProcessById(processId);
            }
            catch
            {
                _process = null;
                return;
            }

            _processId = _process.Id;
            _processMainWindowHandle = _process.MainWindowHandle;
            _baseAddress             = GetBaseAddress();

            //Open the process and load all memory regions of game into the MemoryRegions list
            //Each entry in list is a struct (MemoryBasicInformation)
            _processHandle = MemoryApi.OpenProcess(MemoryApi.ProcessAccessFlags.All, 1, (uint)_processId);
            MemoryRegions  = new List <MemoryApi.MemoryBasicInformation>();
            LoadMemoryRegions();
        }
예제 #3
0
 public MemoryResult WriteProcessMemory(IntPtr memoryAddress, byte[] bytesToWrite, out int bytesWritten)
 {
     ResetError();
     if (
         MemoryApi.WriteProcessMemory(_processHandle, memoryAddress, bytesToWrite, (uint)bytesToWrite.Length,
                                      out bytesWritten) == 0)
     {
         HandleError("WriteProcessMemory - Address " + memoryAddress.ToString("X") + "; Written: " + bytesWritten);
     }
     return(LastMemoryResult);
 }
예제 #4
0
 /// <summary>
 /// Will close the handle and stop reading the process
 /// </summary>
 public void CloseHandle()
 {
     try
     {
         MemoryApi.CloseHandle(_processHandle);
     }
     catch (SEHException sehEx)
     {
         HandleError("Failed to close handle. Message " + sehEx.Message + "; Message length: " +
                     sehEx.Message.Length.ToString(CultureInfo.InvariantCulture));
     }
 }
예제 #5
0
 private static bool GetKeyboardState(byte[] keyStates)
 {
     if (keyStates == null)
     {
         throw new ArgumentNullException("keyStates");
     }
     if (keyStates.Length != 256)
     {
         throw new ArgumentException(@"The buffer must be 256 bytes long.", "keyStates");
     }
     return(MemoryApi.NativeGetKeyboardState(keyStates));
 }
예제 #6
0
        public MemoryResult ReadFloat(IntPtr memoryAddress, out float outFloat)
        {
            ResetError();
            var buffer = new byte[sizeof(float)];

            int ptrBytesRead; // error checking

            if (!MemoryApi.ReadProcessMemory(_processHandle, memoryAddress, buffer, sizeof(float), out ptrBytesRead) ||
                sizeof(int) != ptrBytesRead)
            {
                HandleError("ReadFloat - Address " + memoryAddress.ToString("X") + "; Read: " + ptrBytesRead);
            }

            outFloat = BitConverter.ToSingle(buffer, 0);
            return(LastMemoryResult);
        }
예제 #7
0
        public MemoryResult ReadByte(IntPtr memoryAddress, out byte outByte)
        {
            ResetError();
            var buffer = new byte[1];

            int ptrBytesRead; // error checking

            if (!MemoryApi.ReadProcessMemory(_processHandle, memoryAddress, buffer, sizeof(byte), out ptrBytesRead) ||
                sizeof(byte) != ptrBytesRead)
            {
                HandleError("ReadByte - Address " + memoryAddress.ToString("X") + "; Read: " + ptrBytesRead);
            }

            outByte = buffer[0];
            return(LastMemoryResult);
        }
예제 #8
0
        /// <summary>
        /// Reads a pre-specified number of bytes and returns number of bytes read aas well as the values read, through its parameters
        /// </summary>
        public MemoryResult ReadMemory(IntPtr memoryAddress, int bytesToRead, out int bytesRead,
                                       out byte[] outByteArray)
        {
            ResetError();
            var buffer = new byte[bytesToRead];

            if (!MemoryApi.ReadProcessMemory(_processHandle, memoryAddress, buffer, bytesToRead, out bytesRead) ||
                bytesToRead != bytesRead)
            {
                HandleError("ReadMemory Array - Address " + memoryAddress.ToString("X") + "; Size: " + bytesToRead +
                            "; Read: " + bytesRead);
            }

            outByteArray = buffer;
            return(LastMemoryResult);
        }
예제 #9
0
        public static void PressKey(MemoryApi.KeyCode vk, bool press)
        {
            var lowOrderByte = (ushort)((ushort)vk & 0xff);
            var scanCode     = (ushort)MemoryApi.MapVirtualKey(lowOrderByte, 0);

            //Console.WriteLine("SendInput:: VK: " + (ushort)vk + " (" + vk + ") <-> SC: " + (ushort)(scanCode & 0xff));

            if (press)
            {
                KeyDown(scanCode);
            }
            else
            {
                KeyUp(scanCode);
            }
        }
예제 #10
0
        public MemoryResult ReadShort(IntPtr memoryAddress, out short outShort)
        {
            ResetError();
            byte[] buffer = new byte[2];

            int ptrBytesRead; // error checking

            if (!MemoryApi.ReadProcessMemory(_processHandle, memoryAddress, buffer, sizeof(short), out ptrBytesRead) ||
                sizeof(short) != ptrBytesRead)
            {
                HandleError("ReadShort - Address " + memoryAddress.ToString("X") + "; Read: " + ptrBytesRead);
            }

            outShort = BitConverter.ToInt16(buffer, 0);
            return(LastMemoryResult);
        }
예제 #11
0
        private void HandleError(string details)
        {
            _lastErrorSystemCode = MemoryApi.GetLastError();
            if (Enum.IsDefined(typeof(MemoryResult), (int)_lastErrorSystemCode))
            {
                _lastMemoryResult = (MemoryResult)_lastErrorSystemCode;
            }
            else
            {
                _lastMemoryResult = MemoryResult.Other;
            }

            if (_errorHandler != null)
            {
                _errorHandler(_lastMemoryResult, _lastErrorSystemCode, details);
            }
        }
예제 #12
0
        private static void KeyUp(ushort scanCode)
        {
            //Console.WriteLine("Key Up (SC): " + scanCode);
            var inputs = new MemoryApi.Input[1];

            inputs[0].type           = MemoryApi.INPUT_KEYBOARD;
            inputs[0].ki.wScan       = (ushort)(scanCode & 0xff);
            inputs[0].ki.dwFlags     = MemoryApi.KEYEVENTF_SCANCODE | MemoryApi.KEYEVENTF_KEYUP;
            inputs[0].ki.time        = 0;
            inputs[0].ki.dwExtraInfo = IntPtr.Zero;

            uint intReturn = MemoryApi.SendInput(1, inputs, Marshal.SizeOf(inputs[0]));

            if (intReturn != 1)
            {
                throw new Exception("Could not send key: " + scanCode);
            }
        }
예제 #13
0
        /// <summary>
        /// Will open the process and get the handle for reading. If successful returns true.
        /// </summary>
        public bool OpenProcess(int processId)
        {
            // get reference to the process
            _process = Process.GetProcessById(processId);

            // open the process
            _processHandle = MemoryApi.OpenProcess(MemoryApi.ProcessAccessFlags.All, 1, (uint)processId);

            if (_processHandle == null)
            {
                return(false);
            }

            MemoryRegions = new List <MemoryApi.MemoryBasicInformation>();

            LoadMemoryRegions();

            return(true);
        }
예제 #14
0
        public void VirtualQuery()
        {
            const long maxAddress = 0x7fffffff;
            long       address    = 0;

            do
            {
                MemoryApi.MemoryBasicInformation m;
                int result = MemoryApi.VirtualQueryEx(Process.GetCurrentProcess().Handle, (IntPtr)address, out m,
                                                      (uint)Marshal.SizeOf(typeof(MemoryApi.MemoryBasicInformation)));
                Console.WriteLine(@"{0}-{1} : {2} bytes result={3}", m.BaseAddress,
                                  (uint)m.BaseAddress + m.RegionSize - 1, m.RegionSize, result);
                if (address == (long)m.BaseAddress + m.RegionSize)
                {
                    break;
                }
                address = (long)m.BaseAddress + m.RegionSize;
            } while (address <= maxAddress);
        }
예제 #15
0
        public void SwitchWindow()
        {
            if (MemoryApi.GetForegroundWindow() == MainWindowHandle)
            {
                return;
            }

            IntPtr foregroundWindowHandle = MemoryApi.GetForegroundWindow();
            uint   currentThreadId        = MemoryApi.GetCurrentThreadId();
            uint   temp;
            uint   foregroundThreadId = MemoryApi.GetWindowThreadProcessId(foregroundWindowHandle, out temp);

            MemoryApi.AttachThreadInput(currentThreadId, foregroundThreadId, true);
            MemoryApi.SetForegroundWindow(MainWindowHandle);
            MemoryApi.AttachThreadInput(currentThreadId, foregroundThreadId, false);

            while (MemoryApi.GetForegroundWindow() != MainWindowHandle)
            {
            }
        }
예제 #16
0
        public MemoryResult ReadMemory(IntPtr memoryAddress, int bytesToRead, ref byte[] outBuffer, out int bytesRead)
        {
            ResetError();
            bytesRead = 0;
            if (outBuffer == null || bytesToRead < 0)
            {
                return(MemoryResult.InvalidArguments);
            }

            int workingReadCount = Math.Min(outBuffer.Length, bytesToRead);

            if (!MemoryApi.ReadProcessMemory(_processHandle, memoryAddress, outBuffer, workingReadCount, out bytesRead) ||
                bytesToRead != bytesRead)
            {
                HandleError("ReadMemory Buffer - Address " + memoryAddress.ToString("X") + "; Size: " + workingReadCount +
                            "; Read: " + bytesRead);
            }

            return(LastMemoryResult);
        }
예제 #17
0
        public void Initialize(string processName, ErrorHandler errorHandler)
        {
            _process   = null;
            _processId = 0;
            _processMainWindowHandle = IntPtr.Zero;
            _baseAddress             = IntPtr.Zero;
            _errorHandler            = errorHandler;
            Process[] processList;

            try
            {
                processList = Process.GetProcessesByName(processName);
            }
            catch
            {
                _process = null;
                return;
            }

            if (processList.Length < 1)
            {
                return;
            }

            // get a reference to the process
            _process   = processList[0];
            _processId = _process.Id;
            _processMainWindowHandle = _process.MainWindowHandle;
            _baseAddress             = GetBaseAddress();

            //Open the process and load all memory regions of game into the MemoryRegions list
            //Each entry in list is a struct (MemoryBasicInformation)
            _processHandle = MemoryApi.OpenProcess(MemoryApi.ProcessAccessFlags.All, 1, (uint)_processId);
            MemoryRegions  = new List <MemoryApi.MemoryBasicInformation>();
            LoadMemoryRegions();
        }
예제 #18
0
        /// <summary>
        /// <para>Searches the loaded process for the given byte signature.</para>
        /// <para>Uses the character ? as a wildcard</para>
        /// </summary>
        /// <param name="signature">The hex pattern to search for</param>
        /// <param name="startAddress">An startAddress to add to the pointer VALUE</param>
        /// <param name="searchType">What type of result to return</param>
        /// <returns>The pointer found at the matching location</returns>
        public IntPtr FindSignature(string signature, int startAddress, ScanResultType searchType)
        {
            // make sure we have a valid signature
            if (signature.Length == 0 || signature.Length % 2 != 0)
            {
                throw new Exception("FindSignature(): Invalid signature");
            }

            for (var index = 0; index < _memoryRegionsSortedIndices.Count; index++)
            {
                int workingIndex = _memoryRegionsSortedIndices.Values[index];

                MemoryApi.MemoryBasicInformation region = MemoryRegions[_memoryRegionsSortedIndices.Values[index]];

                // Skip memory regions until we find one that contains the startAddress but startAddress of zero means skip none
                if (startAddress > 0)
                {
                    if (region.BaseAddress.ToInt32() + region.RegionSize < startAddress ||
                        region.BaseAddress.ToInt32() > startAddress)
                    {
                        continue;
                    }
                }

                var buffer    = new byte[region.RegionSize];
                var bytesRead = 0;

                // ReadProcessMemory will return 0 if some form of error occurs
                if (
                    !MemoryApi.ReadProcessMemory(_process.Handle, region.BaseAddress, buffer, (int)region.RegionSize,
                                                 out bytesRead))
                {
                    // get the error code thrown from ReadProcessMemory
                    int errorCode = Marshal.GetLastWin32Error();

                    // For now, if error reading, we will still search what amount was able to be read so no exception throwing.
                }

                var bufferOffset = 0;
                if (startAddress > 0 && region.BaseAddress.ToInt32() < startAddress &&
                    region.BaseAddress.ToInt32() + bytesRead > startAddress)
                {
                    // Since requested startAddress is somewhere in the current regions address space, set startAddress from beginning of region
                    bufferOffset = startAddress - region.BaseAddress.ToInt32();
                }
                IntPtr searchResult = FindSignature(buffer, signature, bufferOffset, searchType);

                // If we found our signature, we're done
                if (IntPtr.Zero == searchResult)
                {
                    continue;
                }

                // if we passed the ! flag we want the beginning address of where it found the sig
                if (ScanResultType.AddressStartOfSig == searchType)
                {
                    searchResult = new IntPtr(region.BaseAddress.ToInt32() + searchResult.ToInt32());
                }

                return(searchResult);
            }
            return(IntPtr.Zero);
        }
예제 #19
0
 public static bool IsKeyLocked(MemoryApi.KeyCode vk)
 {
     return((((ushort)MemoryApi.GetKeyState((int)vk)) & 0xffff) != 0);
 }
예제 #20
0
 public static bool IsKeyPushedDown(MemoryApi.KeyCode vKey)
 {
     return(0 != (MemoryApi.GetAsyncKeyState((int)vKey) & 0x8000));
 }
예제 #21
0
        public static void PressKey(char ch, bool press)
        {
            ushort vk = MemoryApi.VkKeyScan(ch);

            PressKey((MemoryApi.KeyCode)vk, press);
        }