英文:
Why does Kernel32 OpenProcess function return null?
问题
// 已知进程 ID(pid)
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);
如何获得进程句柄?
英文:
I'm trying to make an application that reads the memory of another (non-Java & 32bit) application using JNA. So far I know how to find process ID
and base address
of modules. And right before reading memory I need to open process and the OpenProcess
function simply returns null. Also, I'm using 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);
How can I get a process handle?
答案1
得分: 4
/**
* 为当前进程启用调试特权,以便查询不属于当前用户的进程的信息。
* 链接显示了C语言中的代码,但你可以将该代码移植到JNA。
*
* 这是在程序启动时进行的一次性方法调用。
*
* 下面是我的实现(感谢[@RbMm](https://stackoverflow.com/users/6401656/rbmm)的改进):
*/
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 失败。错误:{}", 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 失败。错误:{}", 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 失败。错误:{}", err);
return false;
} else if (err == WinError.ERROR_NOT_ALL_ASSIGNED) {
LOG.debug("未启用调试特权。");
return false;
}
} finally {
Kernel32.INSTANCE.CloseHandle(hToken.getValue());
}
return true;
}
英文:
You need to enable debug privilege for your current process in order to query information for processes owned by anyone other than the current user. The link shows the code in C, but you can port that code to JNA.
This is a one-time method call when your program starts up.
Here's how I do it (hat tip to @RbMm for improvements):
/**
* 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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论