1

我想向进程内存的某个地址写入偏移量,但我无法分配内存或将内存地址类型更改为“可写”。所以我不能将任何偏移量或值写入我的进程内存。我不确定,但我认为我的进程内存是可读的!请帮我解决这个问题。

这是我尝试过的:

    #region dll import

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

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, 
      byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);

    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint dwProcessId);

    [DllImport("kernel32.dll")]
    public static extern bool CloseHandle(IntPtr handle);

    [DllImport("kernel32.dll")]
    public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, 
      uint dwSize, uint flAllocationType, uint flProtect);

    [DllImport("kernel32.dll")]
    public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, 
      uint dwSize, uint dwFreeType);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, 
      int dwSize, uint flNewProtect, out uint lpflOldProtect);

    #endregion

    public const int
    PAGE_READWRITE = 0x40,
    PROCESS_VM_OPERATION = 0x0008,
    PROCESS_VM_READ = 0x0010,
    PROCESS_VM_WRITE = 0x0020;

    internal static bool write(IntPtr whWnd)
    {
        uint pid;
        GetWindowThreadProcessId(whWnd, out pid);
        if (pid != 0)
        {
            IntPtr hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
              PROCESS_VM_READ, false, pid);
            const int
               MEM_COMMIT = 0x1000,
               MEM_RELEASE = 0x800,
               MEM_RESERVE = 0x2000;
            byte[] data = System.Text.Encoding.UTF8.GetBytes
              ("write string to hex offset of memLoc");
            uint lpflOldProtect;
            int bytesWritten;
            IntPtr memLoc = (IntPtr)0x001D7AB4;
            IntPtr lpRemoteBuffer = IntPtr.Zero;
            VirtualProtectEx(hProcess, memLoc, 160, PAGE_READWRITE, 
              out lpflOldProtect);
            IntPtr cave = VirtualAllocEx(hProcess, IntPtr.Zero, 16, MEM_COMMIT | 
              MEM_RESERVE, PAGE_READWRITE);
            if (lpRemoteBuffer == IntPtr.Zero)
            {
                MessageBox.Show("can't VirtualAlloc");
                return false;
            }
            else
            {
                MessageBox.Show("VirtualAlloc ok");
                VirtualAllocEx(hProcess, memLoc, 4096, MEM_COMMIT, PAGE_READWRITE);
                VirtualFreeEx(hProcess, memLoc, 4096, MEM_RELEASE);
                WriteProcessMemory(hProcess, memLoc, data, 16, out bytesWritten);
                CloseHandle(hProcess);
                return true;
            }
        }
        else
        {
            MessageBox.Show("can't find the windows");
            return false;
        }
    }
    private void button1_Click(object sender, EventArgs e)
    {
        IntPtr whWnd = FindWindow(null, "the windows name");
        write( whWnd);
    }
}
}
4

1 回答 1

2

再读一遍你的代码。您创建一个带有值的 var 并在值保持不变后检查一些行。当然,这是相同的,因为您的代码不会更改它。

IntPtr lpRemoteBuffer = IntPtr.Zero;

// [...]

if (lpRemoteBuffer == IntPtr.Zero)
{
    MessageBox.Show("can't VirtualAlloc");
    return false;
}

我确定您想检查cave您的情况下的 var。:)

此外,要检查您的问题是否正确更改了进程内存,请使用Cheat Engine之类的程序。它允许您查看内存区域的保护情况并确保您的内存位置存在。

您还可以使用MemorySharp(我是作者)之类的注入库来执行您想要的操作。

// Set the address to edit
var address = new IntPtr(0x001D7AB4);

// Open the process with MemorySharp
using (var m = new MemorySharp(Process.GetCurrentProcess()))
{
    // Edit the address
    m[address].WriteString("write string to hex offset of memLoc");
}
于 2013-09-16T12:59:09.330 回答