JNA - CreateToolhelp32Snapshot 不返回所有 DLL
JNA - CreateToolhelp32Snapshot not returning all DLLs
我正在尝试从我有句柄的进程中获取模块的基地址。我已经使用 CreateToolhelp32Snapshot 和 EnumProcessModules 方法进行了尝试。
问题是这两种方法 return 只有这 5 个 DLL:
underrail.exe
ndll.dll
wow64.dll
wow64win.dll
wow64cpu.dll
我知道应该有更多模块并尝试在其他游戏中使用它return相同的 5 个模块。
我找到了同一个问题的一些答案,但两个都不适合我:
第一个不起作用,因为我不能使用 TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 作为方法中的标志。
第二个不起作用,因为我无法调用方法 EnumProcessModulesEx()
当我尝试调用 Psapi.INSTANCE.EnumProcessModulesEx(...)
这是我的代码片段:
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;
}
请注意,使用 Tlhelp32。TH32CS_SNAPMODULE32 不会 return 任何东西,而 Tlhelp32。TH32CS_SNAPALL return 与 lhelp32 相同。TH32CS_SNAPMODULE
感谢 Daniel Widdis 我找到了答案。
目前,EnumProcessModulesEx 方法未映射到 JNA 中,因此您必须制作自己的 Psapi 自定义版本,在我的例子中看起来像这样:
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);
}
然后您可以加载您的自定义 class 并使用您映射的方法。
public static CustomPsapi c_psapi = Native.load("psapi", CustomPsapi.class);
至于正确显示所有 DLL,您需要使用现在映射的 EnumProcessModulesEx 方法,并将所有模块的标志作为最后一个参数 (0x03)
所以方法应该是这样的:
c_psapi.EnumProcessModulesEx(process, modules, 1024, new IntByReference(1024), 0x03);
我正在尝试从我有句柄的进程中获取模块的基地址。我已经使用 CreateToolhelp32Snapshot 和 EnumProcessModules 方法进行了尝试。
问题是这两种方法 return 只有这 5 个 DLL:
underrail.exe
ndll.dll
wow64.dll
wow64win.dll
wow64cpu.dll
我知道应该有更多模块并尝试在其他游戏中使用它return相同的 5 个模块。
我找到了同一个问题的一些答案,但两个都不适合我:
第一个不起作用,因为我不能使用 TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 作为方法中的标志。
第二个不起作用,因为我无法调用方法 EnumProcessModulesEx() 当我尝试调用 Psapi.INSTANCE.EnumProcessModulesEx(...)
这是我的代码片段:
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;
}
请注意,使用 Tlhelp32。TH32CS_SNAPMODULE32 不会 return 任何东西,而 Tlhelp32。TH32CS_SNAPALL return 与 lhelp32 相同。TH32CS_SNAPMODULE
感谢 Daniel Widdis 我找到了答案。
目前,EnumProcessModulesEx 方法未映射到 JNA 中,因此您必须制作自己的 Psapi 自定义版本,在我的例子中看起来像这样:
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);
}
然后您可以加载您的自定义 class 并使用您映射的方法。
public static CustomPsapi c_psapi = Native.load("psapi", CustomPsapi.class);
至于正确显示所有 DLL,您需要使用现在映射的 EnumProcessModulesEx 方法,并将所有模块的标志作为最后一个参数 (0x03) 所以方法应该是这样的:
c_psapi.EnumProcessModulesEx(process, modules, 1024, new IntByReference(1024), 0x03);