Java JNA – Base Address Finding

Tags: , , ,



I am currently attempting to read/write to memory through the use of JNA for Java. For the past week I have tried a multitude of solutions, mostly from similar projects I have found online, but nothing has resolved my problem.

I know I am receiving the correct process ID of the program, then I create a Pointer using the openProcess method. Then I call getBaseAddress using the newly created Pointer. The problem I believe lies within the EnumProcessModules/Psapi method/class.

Truthfully I am slightly in over my head but this is one of the last issues I am having with this program. My overall goal is to find the base address of the program, use various offsets to access the information I am trying to modify, and then modify it appropriately. The program is 32-bit, which I have seen other people say you need to use a EnumProcessModulesEx method for? but truthfully I am unsure of how/where to implement that.

Any help would be appreciated!

Here is a link to a github of the majority of my project

Answer

You’re getting an Access Denied error because Windows requires you to enable Debug privilege on your current process before accessing the memory of another process. So you will need to both run your program as Administrator, and before you call your OpenProcess code, enable debug privilege.

Here’s the JNA code in my application that does this. It’s a static method as I only call it once for the entire application:

/**
 * Enables debug privileges for this process, required for OpenProcess() to get
 * processes other than the current user
 *
 * @return {@code true} if debug privileges were successfully enabled.
 */
private static boolean enableDebugPrivilege() {
    HANDLEByReference hToken = new HANDLEByReference();
    boolean success = Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(),
            WinNT.TOKEN_QUERY | WinNT.TOKEN_ADJUST_PRIVILEGES, hToken);
    if (!success) {
        LOG.error("OpenProcessToken failed. Error: {}", Native.getLastError());
        return false;
    }
    try {
        WinNT.LUID luid = new WinNT.LUID();
        success = Advapi32.INSTANCE.LookupPrivilegeValue(null, WinNT.SE_DEBUG_NAME, luid);
        if (!success) {
            LOG.error("LookupPrivilegeValue failed. Error: {}", Native.getLastError());
            return false;
        }
        WinNT.TOKEN_PRIVILEGES tkp = new WinNT.TOKEN_PRIVILEGES(1);
        tkp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(luid, new DWORD(WinNT.SE_PRIVILEGE_ENABLED));
        success = Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(), false, tkp, 0, null, null);
        int err = Native.getLastError();
        if (!success) {
            LOG.error("AdjustTokenPrivileges failed. Error: {}", err);
            return false;
        } else if (err == WinError.ERROR_NOT_ALL_ASSIGNED) {
            LOG.debug("Debug privileges not enabled.");
            return false;
        }
    } finally {
        Kernel32.INSTANCE.CloseHandle(hToken.getValue());
    }
    return true;
}

I’m not sure from looking at your code whether you also have the right permissions for OpenProcess. Be sure you have the VM_READ permission. Here’s what I use, your mileage may vary (I assume you’ll need writing permissions as well).

final HANDLE pHandle = Kernel32.INSTANCE.OpenProcess(
    WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, 
    false, processID);


Source: stackoverflow