1

I'm trying to get the base address of a module from a process to which I have a handle to. I've tried this using the CreateToolhelp32Snapshot and EnumProcessModules methods.


The problem is it both methods return only these 5 DLLs:

underrail.exe
ndll.dll
wow64.dll
wow64win.dll
wow64cpu.dll

I know there should be more modules and trying to use this in other games returns the same 5 modules.

I have found some answers to the same question but both of them don't work out for me:

  1. https://www.unknowncheats.me/forum/counterstrike-global-offensive/169030-modules.html
  2. JNA - EnumProcessModules() not returning all DLLs?

The first one doesn't work since I can't use TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 as the flags in the method.

The second one doesn't work because I can't call the method EnumProcessModulesEx() when I try to call Psapi.INSTANCE.EnumProcessModulesEx(...)

Here is a snippet of my code:

public static int getModuleBaseAddress(int process_id) {

    DWORD pid = new DWORD(process_id);
    HANDLE snapshot = null;

    snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPMODULE, pid);
    MODULEENTRY32W module = new MODULEENTRY32W();


    while(Kernel32.INSTANCE.Module32NextW(snapshot, module)) {

        String s = Native.toString(module.szModule);
        Pointer x = module.modBaseAddr;
        System.out.println(s);
        System.out.println(x);
        System.out.println("---");

    }

    return 0;


}

Note that using Tlhelp32.TH32CS_SNAPMODULE32 doesn't return anything and Tlhelp32.TH32CS_SNAPALL returns the same as lhelp32.TH32CS_SNAPMODULE

Baseus
  • 31
  • 5
  • How are you obtaining the handle? What flags are you passing to `OpenProcess` (assuming that's how you're getting it). – Daniel Widdis Oct 29 '19 at 20:52
  • Why can't you use `EnumProcessModulesEx`? Is it incompatible with your system? Are you using 32-bit or 64-bit Windows? – Daniel Widdis Oct 29 '19 at 20:59
  • I'm using 64bit windows. I'm not sure why I can't call EnumProcessModulesEx, I've looked into the JNA PSAPI API and it looks like the method doesn't exist, but I already saw some code using it. As for the flags I'm using PROCESS_VM_READ PROCESS_VM_WRITE and PROCESS_VM_OPERATION – Baseus Oct 29 '19 at 21:20
  • Ah, `EnumProcessModulesEx` is not yet mapped in JNA. You can add your own `Psapi.java` class and extend the JNA version, and add your own mapping (and then contribute the change to JNA to help out people like you in the future!). The top google result for `EnumProcessModulesEx` has sample code [here](https://github.com/ZabuzaW/Mem-Eater-Bug/blob/master/src/de/zabuza/memeaterbug/winapi/jna/Psapi.java) showing how to extend and map that function, and a [util class](https://github.com/ZabuzaW/Mem-Eater-Bug/blob/master/src/de/zabuza/memeaterbug/winapi/jna/util/PsapiUtil.java) which uses it. – Daniel Widdis Oct 29 '19 at 21:33
  • Thank you so much for your helpful answer. I created a custom psapi and mapped the method (I was not aware this was possible). And now it works perfectly. – Baseus Oct 30 '19 at 10:18

1 Answers1

0

Thanks to Daniel Widdis I have the answer.

Currently, the method EnumProcessModulesEx is not mapped into JNA so you have to make your own custom version of Psapi, which in my case looks something like this:

import com.sun.jna.Native;
import com.sun.jna.platform.win32.Psapi;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.W32APIOptions;

public interface CustomPsapi extends Psapi{

    Psapi INSTANCE = Native.load("psapi", Psapi.class, 
    W32APIOptions.DEFAULT_OPTIONS);

    public void EnumProcessModulesEx(HANDLE hProcess, HMODULE[] lphModule, int cb, 
    IntByReference lpcbNeeded, int dwFilterFlag);


}

Then you can load your custom class and use the methods that you mapped.

public static CustomPsapi c_psapi = Native.load("psapi", CustomPsapi.class);

As for getting all the DLLs showing up correctly, you need to use the now mapped EnumProcessModulesEx method with the flag for all modules as the last argument (0x03) so the method should look something like this:

c_psapi.EnumProcessModulesEx(process, modules, 1024, new IntByReference(1024), 0x03);
Baseus
  • 31
  • 5