为什么 Kernel32 OpenProcess 函数 return 为空?
Why does Kernel32 OpenProcess function return null?
我正在尝试制作一个使用 JNA 读取另一个(非 Java 和 32 位)应用程序内存的应用程序。到目前为止,我知道如何找到 process ID
和 base address
模块。在读取内存之前,我需要打开进程,OpenProcess
函数只是 returns null。另外,我正在使用 Windows 10.
// process id (pid) is known
final int PROCESS_VM_READ=0x0010;
final int PROCESS_QUERY_INFORMATION=0x0400;
WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, true, pid);
如何获取进程句柄?
您需要为当前进程启用 debug privilege 才能查询当前用户以外的任何人拥有的进程的信息。 link 显示 C 中的代码,但您可以将该代码移植到 JNA。
这是程序启动时的 one-time 方法调用。
我是这样做的(向 @RbMm 提出改进建议):
/**
* 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;
}
我正在尝试制作一个使用 JNA 读取另一个(非 Java 和 32 位)应用程序内存的应用程序。到目前为止,我知道如何找到 process ID
和 base address
模块。在读取内存之前,我需要打开进程,OpenProcess
函数只是 returns null。另外,我正在使用 Windows 10.
// process id (pid) is known
final int PROCESS_VM_READ=0x0010;
final int PROCESS_QUERY_INFORMATION=0x0400;
WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, true, pid);
如何获取进程句柄?
您需要为当前进程启用 debug privilege 才能查询当前用户以外的任何人拥有的进程的信息。 link 显示 C 中的代码,但您可以将该代码移植到 JNA。
这是程序启动时的 one-time 方法调用。
我是这样做的(向 @RbMm 提出改进建议):
/**
* 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;
}