1

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][1] 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!

  • 1
    You're a little vague on exactly the problem you have and the symptoms/errors. Can you please be more specific in a paraticular command/function/method you are trying to use and what doesn't work with it? I've started to go down this road on my own project and one of the first things you need to do is enable Debug Privilege, but before randomly answering I'd like to see what you're trying to do. – Daniel Widdis Mar 29 '17 at 07:00
  • Currently the getBaseAddress method in Editor.java is starting by creating a list of Modules using the EnumProcessModules method (from PsapiTools) based on the given pointer. I believe I am providing it the correct pointer so that shouldnt be a problem. Hopping over to that EnumProcessModules method, it seems to fail at Psapi.INSTANCE.EnumProcessModules(...); line and then sets Success to false and lastly throws an error all the way up the chain. I have no clue why this is. –  Mar 29 '17 at 14:20
  • 1
    What error is being thrown? Is it an access violation? – Daniel Widdis Mar 29 '17 at 15:05
  • EnumProcessModules throws the error because "success" is not true. The error spits out "EnumProcessModules failed. Error: 5". The list of error codes I looked at indicated error 5 is "Access Denied". I set my privileges to all access (which is it ok to leave it that way?), and it no longer throws that error. However, it is returning 0 under getBaseAddress, which indicates it is unable to find a module thats filename contains the games name. In debug I can see that the entire List is size of 10 but all of their lpBaseOfDll variables are null, which must be caused by EnumProcessModules? –  Mar 29 '17 at 17:31

1 Answers1

1

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);
Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
  • I just committed some changes to my github repo that include what you recommended. I managed to stop the error by changing privileges to all access (which I'm unsure if I should leave that way). And also included your method for safe measure. Now the problem is that getBaseAddress is returning 0, which indicates its not able to find a filename containing what I am providing it. In debug I can see that the list of modules, "hModules", is empty(?) and all entries look similar to this: https://puu.sh/v2tGg/346a73ef8b.png I am assuming that is some issue with EnumProcessModules? –  Mar 29 '17 at 18:15
  • 1
    This is starting to stray from Q&A to debugging help. :) Looking at your `EnumProcessModules` code I see you have an `IntByReference` for `lpcbNeededs` when the Windows signature is a `DWORDByReference`. Don't know if that would cause the problem. – Daniel Widdis Mar 29 '17 at 19:55
  • 1
    Also you're passing the array length `lphModule.length` when that needs to be the byte size of the whole array, so multiply that length times the size of a `Pointer`. – Daniel Widdis Mar 29 '17 at 20:01
  • 1
    And this looks directly relevant. http://stackoverflow.com/questions/28394955/jna-enumprocessmodules-not-returning-all-dlls – Daniel Widdis Mar 29 '17 at 20:12
  • 1
    Thank you so much! That link you posted had an extremely helpful github repo on how to accomplish obtaining the base address. I believe I have the base address function working, now I just have to finish up finding the dynamic address based on offsets and I should be good to go. I appreciate all of your help. To anyone else looking for a solution to a similar problem, my github should be updated (and soon with dynamic addresses as well). –  Mar 29 '17 at 22:30