Java 为什么Kernel32 OpenProcess函数返回null?

Java 为什么Kernel32 OpenProcess函数返回null?,java,winapi,jna,handle,Java,Winapi,Jna,Handle,我正在尝试创建一个应用程序,该应用程序使用JNA读取另一个(非Java&32位)应用程序的内存。到目前为止,我知道如何查找模块的进程ID和基址。在读取内存之前,我需要打开进程,OpenProcess函数只返回null。另外,我使用的是Windows10 //进程id(pid)已知 最终int进程_VM_READ=0x0010; 最终整型过程查询信息=0x0400; WinNT.HANDLE processHandle=Kernel32.INSTANCE.OpenProcess(PROCESS_V

我正在尝试创建一个应用程序,该应用程序使用JNA读取另一个(非Java&32位)应用程序的内存。到目前为止,我知道如何查找模块的
进程ID
基址
。在读取内存之前,我需要打开进程,
OpenProcess
函数只返回null。另外,我使用的是Windows10

//进程id(pid)已知
最终int进程_VM_READ=0x0010;
最终整型过程查询信息=0x0400;
WinNT.HANDLE processHandle=Kernel32.INSTANCE.OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,true,pid);
如何获取进程句柄?

您需要为当前进程启用,以便查询当前用户以外的任何人拥有的进程的信息。该链接以C语言显示代码,但您可以将该代码移植到JNA

这是程序启动时的一次性方法调用

以下是我如何做到这一点的(改进建议):

/**
*启用此进程的调试权限,这是OpenProcess()获取
*当前用户以外的进程
*
*@return{@code true}如果调试权限已成功启用。
*/
私有静态布尔enableDebugPrivilege(){
HANDLEByReference hToken=新的HANDLEByReference();
布尔成功=Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(),
WinNT.TOKEN_QUERY | WinNT.TOKEN_ADJUST_PRIVILEGES,hToken);
如果(!成功){
错误(“OpenProcessToken失败。错误:{}”,Native.getLastError());
返回false;
}
试一试{
WinNT.LUID LUID=新的WinNT.LUID();
success=Advapi32.INSTANCE.LookupPrivilegeValue(null,WinNT.SE_DEBUG_NAME,luid);
如果(!成功){
LOG.error(“LookupPrivilegeValue失败。错误:{}”,Native.getLastError());
返回false;
}
WinNT.TOKEN_特权tkp=新的WinNT.TOKEN_特权(1);
tkp.Privileges[0]=新的WinNT.LUID_和_属性(LUID,新的DWORD(WinNT.SE_PRIVILEGE_启用));
success=Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(),false,tkp,0,null,null);
int err=Native.getLastError();
如果(!成功){
LOG.error(“AdjustTokenPrivileges失败。错误:{}”,err);
返回false;
}else if(err==WinError.ERROR\u未\u分配全部\u){
debug(“未启用调试权限”);
返回false;
}
}最后{
CloseHandle(hToken.getValue());
}
返回true;
}
您需要为当前流程启用,以便查询当前用户以外的任何人拥有的流程的信息。该链接以C语言显示代码,但您可以将该代码移植到JNA

这是程序启动时的一次性方法调用

以下是我如何做到这一点的(改进建议):

/**
*启用此进程的调试权限,这是OpenProcess()获取
*当前用户以外的进程
*
*@return{@code true}如果调试权限已成功启用。
*/
私有静态布尔enableDebugPrivilege(){
HANDLEByReference hToken=新的HANDLEByReference();
布尔成功=Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(),
WinNT.TOKEN_QUERY | WinNT.TOKEN_ADJUST_PRIVILEGES,hToken);
如果(!成功){
错误(“OpenProcessToken失败。错误:{}”,Native.getLastError());
返回false;
}
试一试{
WinNT.LUID LUID=新的WinNT.LUID();
success=Advapi32.INSTANCE.LookupPrivilegeValue(null,WinNT.SE_DEBUG_NAME,luid);
如果(!成功){
LOG.error(“LookupPrivilegeValue失败。错误:{}”,Native.getLastError());
返回false;
}
WinNT.TOKEN_特权tkp=新的WinNT.TOKEN_特权(1);
tkp.Privileges[0]=新的WinNT.LUID_和_属性(LUID,新的DWORD(WinNT.SE_PRIVILEGE_启用));
success=Advapi32.INSTANCE.AdjustTokenPrivileges(hToken.getValue(),false,tkp,0,null,null);
int err=Native.getLastError();
如果(!成功){
LOG.error(“AdjustTokenPrivileges失败。错误:{}”,err);
返回false;
}else if(err==WinError.ERROR\u未\u分配全部\u){
debug(“未启用调试权限”);
返回false;
}
}最后{
CloseHandle(hToken.getValue());
}
返回true;
}

Kernel32.GetLastError()
或者更好的
ntdll.RtlGetLastNtStatus()
说出原因。最常见的原因-拒绝访问和无效进程idOkay我检查了这个,我得到了拒绝访问。那么,我如何获得此访问权限?如果您具有调试权限,请启用它。这在您的情况下必须有所帮助
Kernel32.GetLastError()
或者更好的
ntdll.RtlGetLastNtStatus()
告诉您原因。最常见的原因-拒绝访问和无效进程idOkay我检查了这个,我得到了拒绝访问。那么,我如何获得此访问权限?如果您具有调试权限,请启用它。这对你的情况一定有帮助,因为代码的结尾是错误的<代码>调整令牌权限即使失败也返回true。糟糕的api设计。需要调用
GetLastError()
始终在此处查看检查结果。然而,更简单的方法是通过单个调用
booleanb;RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE、TRUE、FALSE和b)@RbMm谢谢你的指针。我会调整的。然而,关于“即使失败也返回true”,只有在部分成功的情况下才是如此。然而,当设置单个特权时,这是一个不可能的结果,因此它要么完全成功,要么完全失败。我没有看到Windows API中记录的
RtlAdjustPrivilege()
。使用未记录的函数是一种糟糕的做法。但是,当设置单个特权时,这是不可能的结果,因此