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:
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
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);