64-битный доступ к памяти ReadProcessMemory запрещен

Я пытался запустить это с Process.EnterDebugMode(), но это тоже не работает.

Я хочу прочитать Notepad-memory, но я не знаю, как получить к нему доступ, или если 64-битная система создает проблемы.

Вот что я сделал:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;

public class MemoryRead
{

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

    [DllImport("kernel32.dll")]
    static extern bool ReadProcessMemory(int hProcess, Int64 lpBaseAddress, byte[] buffer, int size, ref int lpNumberOfBytesRead);

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

    static void Main(string[] args)
    {
        var pid = 10956; //notepad.exe
        var processHandle = OpenProcess(0x10, false, pid);

        byte[] buffer = new byte[24];
        int bytesRead = 0;
        ReadProcessMemory((int)processHandle, 0x21106B35770, buffer, buffer.Length, ref bytesRead); //0x21106B35770 is the address where "hello world" is written in notepad

        Console.WriteLine(Encoding.Unicode.GetString(buffer) +
           " (" + bytesRead.ToString() + "bytes)");
        Console.ReadLine();
        CloseHandle(processHandle);

        Console.ReadLine();
    }
}

person Le Flo    schedule 02.07.2016    source источник
comment
Запустите ваше приложение от имени администратора   -  person Hamid Pourjam    schedule 02.07.2016
comment
Я думаю, что вы должны запустить его как x86. Я делал это раньше, и мне не нужны были права администратора   -  person Vahid K.    schedule 02.07.2016
comment
вы можете получить объявления методов Pinvoke на www.pinvoke.net   -  person Vahid K.    schedule 03.07.2016


Ответы (1)


Ваше объявление PInvoke для ReadProcessMemory неверно (хотя должно работать в 32-битной системе).

Как видно из нативного объявления этой функции

BOOL WINAPI ReadProcessMemory(
  _In_  HANDLE  hProcess,
  _In_  LPCVOID lpBaseAddress,
  _Out_ LPVOID  lpBuffer,
  _In_  SIZE_T  nSize,
  _Out_ SIZE_T  *lpNumberOfBytesRead
);

его первый параметр — HANDLE, а это PVOID:

Указатель на любой тип.

Этот тип объявлен в WinNT.h следующим образом:

typedef недействительным *PVOID;

И указатель на что-либо в 64-битном процессе является 64-битным значением - IntPtr.

В основном то же самое относится к параметрам size и lpNumberOfBytesRead - они также 64-битные в 64-битном процессе.

Таким образом, ваше объявление должно выглядеть примерно так:

[[DllImport("kernel32.dll", SetLastError = true)]]
[return: MarshalAs(UnmanagedType.Bool)]
static extern Boolean ReadProcessMemory(
  [In]  IntPtr  hProcess,
  [In]  IntPtr lpBaseAddress,
  [Out] Byte[] lpBuffer,
  [In]  UIntPtr  nSize,
  [Out] out UIntPtr lpNumberOfBytesRead
);

P.S.: И немного бесстыдной саморекламы — если вам когда-нибудь придется много работать с PInvoke, то есть несколько хороших рекомендаций Я многому научился.

person Eugene Podskal    schedule 02.07.2016