C++ 尝试使用NTDLL获取、复制和保护句柄

C++ 尝试使用NTDLL获取、复制和保护句柄,c++,process,native,handle,ntdll,C++,Process,Native,Handle,Ntdll,因此,我尝试在流程中循环,找到流程的流程id(有效),然后使用该pid打开一个流程(也有效),然后使用NtDuplicateObject复制它,并使用NtSetInformationObject保护它 问题是总有不对劲的地方。我第一次尝试它时,它不想复制它,快进到现在,在注释掉我试图关闭旧句柄的部分(我不能这样做,NtDuplicateObject也不应该这样做)后,它给了我一个句柄,但我不能将其用于writeprocessmemory或类似的东西。我将在这里发布函数,并在一个hastebin链

因此,我尝试在流程中循环,找到流程的流程id(有效),然后使用该pid打开一个流程(也有效),然后使用NtDuplicateObject复制它,并使用NtSetInformationObject保护它

问题是总有不对劲的地方。我第一次尝试它时,它不想复制它,快进到现在,在注释掉我试图关闭旧句柄的部分(我不能这样做,NtDuplicateObject也不应该这样做)后,它给了我一个句柄,但我不能将其用于writeprocessmemory或类似的东西。我将在这里发布函数,并在一个hastebin链接中发布完整代码(以防我的代码中存在需要缝合的混乱)

HANDLE-PROTO\u-HAND::GrabPerfectHandle(const-wchar\u t*\u-processName)
{
if(uu processName==nullptr)
返回重新解释类型(PRH错误参数);
NTSTATUS返回错误;
系统处理信息*\u系统处理信息;
无效*\uuuu系统信息;
void*\u分配缓冲区;
__allocationBuffer=VirtualAlloc(0,1024*1024,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
如果(!\uuuu分配缓冲区)
返回重新解释(PRH\U ERR\U CANNOTALLOC);
__systemProcessInfo=reinterpret\u cast(\uuu分配缓冲区);
如果(!NT_SUCCESS(_returnError=NtQuerySystemInformation(SystemProcessInformation,_systemProcessInfo,1024*1024,0)))
{
if(!VirtualFree(uu allocationBuffer,0,MEM_RELEASE))
返回重新解释(PRH\U ERR\U CANNOTDEALLOC);
返回重新解释类型(PRH\U ERR\U NTQUERYFAIL);
}
while(u systemProcessInfo->NextEntryOffset)
{
如果(\uuu systemProcessInfo->ImageName.Buffer!=nullptr)
{
如果(wcscmp(\uuuuSystemProcessInfo->ImageName.Buffer,\uuuProcessName)==0)
{
HANDLE\uuu basicHandle=OpenProcess(PROCESS\u ALL\u ACCESS,false,\uuu systemProcessInfo->UniqueProcessId);
句柄{0};
如果(!\u basicHandle)
{
if(!VirtualFree(uu allocationBuffer,0,MEM_RELEASE))
返回重新解释(PRH\U ERR\U CANNOTDEALLOC);
返回重新解释(PRH\U ERR\U OPENPROCFAIL);
}
如果(!NT_SUCCESS(NtDuplicateObject(GetCurrentProcess(),uu basicHandle,GetCurrentProcess(),&uu perfectHandle,PROCESS_ALL_ACCESS,0,DUPLICATE_SAME_ACCESS)))
{
if(!VirtualFree(uu allocationBuffer,0,MEM_RELEASE))
返回重新解释(PRH\U ERR\U CANNOTDEALLOC);
返回重新解释转换(PRH\U ERR\U DUPPHANDFAIL);
}
/*如果(!NtClose(uu basicHandle))
{
if(!VirtualFree(uu allocationBuffer,0,MEM_RELEASE))
返回重新解释(PRH\U ERR\U CANNOTDEALLOC);
如果(!CloseHandle(uu basicHandle))
返回重新解释铸型(PRH\U ERR\U cast cast);
返回重新解释铸型(PRH\U ERR\U cast cast);
}
如果(uu basicHandle!=nullptr)
{
if(!VirtualFree(uu allocationBuffer,0,MEM_RELEASE))
返回重新解释(PRH\U ERR\U CANNOTDEALLOC);
返回重新解释铸型(PRH\U ERR\U cast cast);
}*/
_对象\句柄\标志\信息\对象信息{0};
__objectInformation.ProtectFromClose={true};
如果(!NT_SUCCESS(NtSetInformationObject(uu perfectHandle,ObjectHandleFlagInformation,&uu objectInformation,sizeof(u OBJECT_HANDLE,FLAG,INFORMATION)))
{
if(!VirtualFree(uu allocationBuffer,0,MEM_RELEASE))
返回重新解释(PRH\U ERR\U CANNOTDEALLOC);
返回重新解释(PRH\U ERR\U PFCFAIL);
}
if(!VirtualFree(uu allocationBuffer,0,MEM_RELEASE))
返回重新解释(PRH\U ERR\U CANNOTDEALLOC);
返回uu perfectHandle;
}
}
__systemProcessInfo=reinterpret\u cast(reinterpret\u cast(\uuuuSystemProcessInfo)+\uuuuSystemProcessInfo->nexteryOffset);
}
if(!VirtualFree(uu allocationBuffer,0,MEM_RELEASE))
返回重新解释(PRH\U ERR\U CANNOTDEALLOC);
返回重新解释铸件(PRH\U ERR\U FELLTOUR);
}
Full:

粗略地看一下,我认为问题可能是您调用GetProcessHandle。返回一个伪句柄(一个常量),操作系统知道它的意思是“当前进程”:

A pseudo handle is a special constant, currently (HANDLE)-1, that is interpreted as the current process handle. For compatibility with future operating systems, it is best to call GetCurrentProcess instead of hard-coding this constant value. The calling process can use a pseudo handle to specify its own process whenever a process handle is required. Pseudo handles are not inherited by child processes.
现在,我可能错了,因为我只是浏览了一下您的代码,但是如果您使用这个API,那么您肯定不能复制从它返回的任何句柄(因为它不是一个真正的句柄,只是一个常量)

参考:

我很好奇你对意图的描述和代码之间的差异。为什么要迭代所有流程,只为了找到自己的流程?您可以通过一个API调用(例如GetProcessID)获得它的PID

因此,您可以将代码更改为类似这样的内容(这会使伪句柄“泄漏”,但由于它不是真正的句柄,因此不会泄漏任何内容!):


当然,如果您愿意,NT原生API等价物很容易确定,如果这对您有帮助的话,我将把它留给您。

我不想用我自己的进程来做这件事,我想用基本上任何其他进程来做。这是我的意图,“我的过程”语言让我困惑。当我仔细查看代码时,不清楚使用这个常量是否会有问题。可能不会,否则你会看到的。
A pseudo handle is a special constant, currently (HANDLE)-1, that is interpreted as the current process handle. For compatibility with future operating systems, it is best to call GetCurrentProcess instead of hard-coding this constant value. The calling process can use a pseudo handle to specify its own process whenever a process handle is required. Pseudo handles are not inherited by child processes.
HANDLE hRealHandle=OpenProcess(GetProcesssId(GetCurrentProcess()), ...);