문제

I have a vague knowledge of C++, but I have some extensive experience in C#, though it's not so useful in this instance. I have some code in C#, and it works just fine. I have what I presume is very similar code in C++, and I can't seem to get it working nor debug it. So, here is the C# code I've written and tested quite thoroughly:

    [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. I know 100% that this works provided I set the values correctly.

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++.

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. 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 ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top