C#读取另一个进程内存

时间:2018-06-04 00:49:43

标签: c#

我无法从游戏中读取简单的int。我找到了一个带有Cheat Engine的静态地址,如果我手动将其插入列表中,它每次都有效。但是当我尝试用C#读取它时,它总是读取0个字节。如果有人可以提供帮助,那就太棒了!

谢谢!

 class Program
{
    private static readonly int PROCESS_WM_READ = 0x0010;

    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

    [DllImport("kernel32.dll")]
    public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);

    const string procName = "hl";
    static Process process = null;
    static IntPtr processHandle;

    public static byte[] Read(int handle, int address, int size, ref int bytes)
    {
        byte[] buffer = new byte[size];
        ReadProcessMemory(handle, address, buffer, size, ref bytes);
        return buffer;
    }

    static void Main(string[] args)
    {
        int bytesRead = 0;
        byte[] value = new byte[20];
        int address = 0x019EF0D7;

        Console.WriteLine("Starting");
        process = Process.GetProcessesByName(procName)[0];
        processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id);

        while (true)
        {
            //ReadProcessMemory((int)processHandle, jumpAddresses, jumpValues, jumpValues.Length, ref bytesRead);
            value = Read((int)processHandle, address, 20, ref bytesRead);
            Console.WriteLine(int.Parse(bytesRead.ToString()) + " " + bytesRead);
            Thread.Sleep(100);
        }

    }
}

1 个答案:

答案 0 :(得分:2)

Attatching:

var Found = false;

while (!Found) {
    Thread.Sleep(250);
    Found = Memory.Attatch("Processname");
}

GetModuleAddress:

int MyDll = Memory.GetModuleAddress("MyDll.dll");

写作:

Memory.WriteMemory<type>(offset, value);

阅读

var Value = Memory.ReadMemory<type>(offset);
internal class Memory {
        private static Process m_iProcess;
        private static IntPtr m_iProcessHandle;

        private static int m_iBytesWritten;
        private static int m_iBytesRead;

        public static bool Attatch(string ProcName) {
            if (Process.GetProcessesByName(ProcName).Length > 0) {
                m_iProcess = Process.GetProcessesByName(ProcName)[0];
                m_iProcessHandle =
                    Imports.OpenProcess(Flags.PROCESS_VM_OPERATION | Flags.PROCESS_VM_READ | Flags.PROCESS_VM_WRITE,
                        false, m_iProcess.Id);
                return true;
            }

            return false;
        }

        public static void WriteMemory<T>(int Address, object Value) {
            var buffer = StructureToByteArray(Value);

            Imports.NtWriteVirtualMemory((int) m_iProcessHandle, Address, buffer, buffer.Length, out m_iBytesWritten);
        }

        public static void WriteMemory<T>(int Adress, char[] Value) {
            var buffer = Encoding.UTF8.GetBytes(Value);

            Imports.NtWriteVirtualMemory((int) m_iProcessHandle, Adress, buffer, buffer.Length, out m_iBytesWritten);
        }

        public static T ReadMemory<T>(int address) where T : struct {
            var ByteSize = Marshal.SizeOf(typeof(T));

            var buffer = new byte[ByteSize];

            Imports.NtReadVirtualMemory((int) m_iProcessHandle, address, buffer, buffer.Length, out m_iBytesRead);

            return ByteArrayToStructure<T>(buffer);
        }

        public static byte[] ReadMemory(int offset, int size) {
            var buffer = new byte[size];

            Imports.NtReadVirtualMemory((int) m_iProcessHandle, offset, buffer, size, out m_iBytesRead);

            return buffer;
        }

        public static float[] ReadMatrix<T>(int Adress, int MatrixSize) where T : struct {
            var ByteSize = Marshal.SizeOf(typeof(T));
            var buffer = new byte[ByteSize * MatrixSize];
            Imports.NtReadVirtualMemory((int) m_iProcessHandle, Adress, buffer, buffer.Length, out m_iBytesRead);

            return ConvertToFloatArray(buffer);
        }

        public static int GetModuleAddress(string Name) {
            try {
                foreach (ProcessModule ProcMod in m_iProcess.Modules)
                    if (Name == ProcMod.ModuleName)
                        return (int) ProcMod.BaseAddress;
            }
            catch {
            }

            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("ERROR: Cannot find - " + Name + " | Check file extension.");
            Console.ResetColor();

            return -1;
        }

        #region Other

        internal struct Flags {
            public const int PROCESS_VM_OPERATION = 0x0008;
            public const int PROCESS_VM_READ = 0x0010;
            public const int PROCESS_VM_WRITE = 0x0020;
        }

        #endregion

        #region Conversion

        public static float[] ConvertToFloatArray(byte[] bytes) {
            if (bytes.Length % 4 != 0)
                throw new ArgumentException();

            var floats = new float[bytes.Length / 4];

            for (var i = 0; i < floats.Length; i++)
                floats[i] = BitConverter.ToSingle(bytes, i * 4);

            return floats;
        }

        private static T ByteArrayToStructure<T>(byte[] bytes) where T : struct {
            var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
            try {
                return (T) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
            }
            finally {
                handle.Free();
            }
        }

        private static byte[] StructureToByteArray(object obj) {
            var length = Marshal.SizeOf(obj);

            var array = new byte[length];

            var pointer = Marshal.AllocHGlobal(length);

            Marshal.StructureToPtr(obj, pointer, true);
            Marshal.Copy(pointer, array, 0, length);
            Marshal.FreeHGlobal(pointer);

            return array;
        }

        #endregion
    }
}