简体   繁体   English

C#程序员用C ++编写的ReadProcessMemory,始终失败

[英]ReadProcessMemory in C++ by a C# programmer, failing consistantly

I have a vague knowledge of C++, but I have some extensive experience in C#, though it's not so useful in this instance. 我对C ++的知识很模糊,但是我在C#方面有丰富的经验,尽管在这种情况下它并不是那么有用。 I have some code in C#, and it works just fine. 我在C#中有一些代码,效果很好。 I have what I presume is very similar code in C++, and I can't seem to get it working nor debug it. 我假设我的C ++代码非常相似,而且似乎无法正常运行或调试它。 So, here is the C# code I've written and tested quite thoroughly: 因此,这是我已经编写并充分测试的C#代码:

    [DllImport("kernel32.dll")]
    public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
        [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);

    public byte[] ReadBytes(IntPtr Handle, Int64 Address, uint BytesToRead)
    {
        IntPtr ptrBytesRead;
        byte[] buffer = new byte[BytesToRead];
        ReadProcessMemory(Handle, new IntPtr(Address), buffer, BytesToRead, out ptrBytesRead);
        return buffer;
    }

    public int ReadInt32(long Address, uint length = 4, IntPtr? Handle = null)
    {
        return BitConverter.ToInt32(ReadBytes(getIntPtr(Handle), Address, length), 0);
    }

So, this function ReadInt32 takes an address, adds it to the base address I've stored upon initialising my Util class, and reads the memory up to 4 bytes, using a handle which once again is acquired upon initialisation. 因此,此函数ReadInt32接收一个地址,将其添加到初始化Util类时存储的基址中,并使用句柄读取内存(最多4个字节),该句柄在初始化时再次获取。 I know 100% that this works provided I set the values correctly. 如果我正确设置值,我知道100%可以使用。

This code is a little long, excuse my ignorance but I don't want to leave any of this to imagination, I can't begin to suggest what may be incorrect, as I'm not too well trained in the world of C++. 这段代码有点长,请原谅我的无知,但是我不想让这一切浮想联翩,因为我在C ++领域受过良好的训练,所以我无法开始提出可能不正确的建议。

DWORD address = 0x3C02A8;
int value = 0;
DWORD pid;
HWND hwnd;
DWORD baseAddress;
DWORD toread;
SIZE_T bytesRead;

// Get a process handle
hwnd = FindWindow(NULL,L"Tibia - Knightski"); //Finds the Window called "Minesweeper"
if(!hwnd) //If none, display an error
{
    cout <<"Window not found!\n";
    cin.get();
}
else
{
    cout << "Window found: " << hwnd << endl;
    cin.get();
}

// Get a base address
GetWindowThreadProcessId(hwnd,&pid); //Get the process id and place it in pid
HANDLE phandle = OpenProcess(PROCESS_VM_READ,0,pid); //Get permission to read
if(!phandle) //Once again, if it fails, tell us
{
    cout <<"Could not get handle!\n";
    cin.get();
}
else
{
    cout << "Handle obtained: " << phandle << endl;
    cin.get();
    baseAddress = (DWORD)phandle;
    cout << "Base Address obtained: " << baseAddress << endl;
    cin.get();
}

toread = baseAddress + address;

// Read memory at base + address
if (ReadProcessMemory(phandle, (void*)address, &value, 4, &bytesRead))
{
    cout << value;
    cin.get();
}
else
{
    cout << "Failed to read memory" << GetLastError() << endl;
    cout << "Bytes read: " << bytesRead << endl;
    cin.get();
}

The memory address I'm trying to read is 0x3BE1E0, but I've added the base address (0x20C8) to this to get 0x3C02A8. 我尝试读取的内存地址为0x3BE1E0,但我已将基本地址(0x20C8)添加到此地址以获得0x3C02A8。 I will assume that the readers on this site know of the handle and what not... 我将假定该站点的读者知道该手柄,而没有什么...

Thank you for your time. 感谢您的时间。 Note that I'm hoping for an explanation of what I'm doing wrong more so than an answer, so please bare that in mind if you've the time free. 请注意,我希望对自己做错的事情的解释多于一个答案,因此,如果有时间,请记住这一点。 An answer will do, as I can most likely research the result anyway. 答案是可以的,因为无论如何我很可能可以研究结果。

The output is this: 输出是这样的:

Window found: 00D5014C

Handle obtained: 00000044

Base Address obtained: 68

Failed to read memory299
Bytes read: 0

This conversion is completely wrong. 这种转换是完全错误的。

baseAddress = (DWORD)phandle;

A process handle isn't a memory address at all (although a module handle is). 进程句柄根本不是内存地址(尽管模块句柄是)。 A process handle is an index into an array kept by the kernel. 进程句柄是内核保存的数组索引。

You'll need to enumerate the process's modules remotely. 您需要远程枚举流程的模块。

or 要么

will allow you to get module base addresses. 将允许您获取模块基地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM