-2

I'm trying to read a part from the memory of a Notepad instance, but I'm always getting system error 299 when calling kernel32's ReadProcessMemory().

This is the code I have so far:

package memreadtest;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.W32APIOptions;

public class MemReader {

    private final static Kernel32 kernel32 = Native.load("kernel32", Kernel32.class, W32APIOptions.DEFAULT_OPTIONS);
    private final static User32 user32 = Native.load("user32", User32.class, W32APIOptions.DEFAULT_OPTIONS);

    private final static int PROCESS_VM_READ = 0x0010;

    public static void main(String[] args) {
        int bytesToRead = 1024;

        Memory notepadDump = readProcessMemory("*Untitled - Notepad", bytesToRead);

        Memory.disposeAll();
    }

    private static Memory readProcessMemory(String winTitle, int bytesToRead) {
        Memory output = new Memory(bytesToRead);

        IntByReference pid = new IntByReference(0);

        user32.GetWindowThreadProcessId(user32.FindWindow(null, winTitle), pid);

        HANDLE handle = kernel32.OpenProcess(PROCESS_VM_READ, true, pid.getValue());

        if (!kernel32.ReadProcessMemory(handle, handle.getPointer(), output, bytesToRead, null)) {
            System.err.println("Failed to read memory of process " + pid.getValue() + ". System Error Code: " + kernel32.GetLastError());
            return null;
        }

        return output;
    }
}

What am I doing wrong?

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
sasieightynine
  • 434
  • 1
  • 5
  • 16
  • `handle.getPointer()` as second argument of `ReadProcessMemory` of course wrong. *I'm trying to read a part from the memory* - what concrete part ? what you try to read ? – RbMm Dec 26 '19 at 13:53
  • The first 1024 bytes of the memory taken by the process. – sasieightynine Dec 26 '19 at 14:00
  • so range [0, 1024) ? this range is always invalid memory (unmapped) and what sense try do this ? and anyway i not view attempt read by 0 address. i view address - `handle.getPointer()` - what is this ? – RbMm Dec 26 '19 at 14:53
  • The final goal is to read the whole memory that is taken by notepad or any other chosen app then further processing the data as a byte array. I just thought it might be easier to read only the first x bytes for starters. – sasieightynine Dec 26 '19 at 14:58
  • no sense read *whole memory*. in any case you need first call `VirtualQueryEx` for get valid memory ranges in process (with it type,size) and only after this read something. – RbMm Dec 26 '19 at 15:26
  • The returned data of `VirtualQueryEx` is meaningless, unless the target process is suspended. – IInspectable Dec 26 '19 at 15:28
  • The memory mapped by a process is not necessarily contiguous. What are you actually trying to do? But in any case, the question that you asked has been answered. – David Heffernan Dec 26 '19 at 16:25
  • @IInspectable - *unless the target process is suspended* false. not need suspend process. of course at any time new virtual memory can be allocated or free. and so what ? even if process suspended - another process can still allocate or free memory in target process. and so what ? – RbMm Dec 26 '19 at 16:46
  • @rbm: Correctness is nothing *you* need to worry about. For the rest of us, correctness matters. And if correctness matters, you cannot call `VirtualQueryEx` on a process that isn't suspended. – IInspectable Dec 26 '19 at 17:28
  • @IInspectable - can. and very strange that you forget write that you cannot call **`ReadProcessMemory`** on a process that isn't suspended – RbMm Dec 26 '19 at 19:44

1 Answers1

0

You are reading an address that there is no reason to expect is valid in the external process. A process handle is not expected to be a valid address in the process.

I'm not sure what you are trying to read from this process, but l whatever it is you will need to somehow find an appropriate address.

You clarify in comments that you want to read from the module base address. For instance see: Get base address of process

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490