2017-09-24 62 views
-2

所以我試圖基本上循環低谷的進程,找到我的進程(工程)的進程ID,然後打開一個進程與該PID(這也適用)和然後用NtDuplicateObject複製它並用NtSetInformationObject保護它。試圖抓取,複製和保護與NTDLL的句柄

問題是總會有些問題。第一次嘗試時,它不想複製它,直到現在快進了,然後在註釋掉我試圖關閉舊句柄的部分(我不能這樣做,NtDuplicateObject也不應該這樣做)給我一個句柄,但我不能用它來寫writeprocessmemory或類似的東西。我將張貼在這裏的功能,並在hastebin鏈接的完整代碼(如果有在我的代碼需要一些拼接的混亂)

HANDLE PROTO_HAND::GrabPerfectHandle(const wchar_t *__processName) 
{ 
    if (__processName == nullptr) 
     return reinterpret_cast<HANDLE>(PRH_ERR_BADPARAM); 

    NTSTATUS __returnError; 

    SYSTEM_PROCESS_INFORMATION *__systemProcessInfo; 
    void *__systemInfo; 
    void *__allocationBuffer; 

    __allocationBuffer = VirtualAlloc(0, 1024 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 

    if (!__allocationBuffer) 
     return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTALLOC); 

    __systemProcessInfo = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(__allocationBuffer); 

    if (!NT_SUCCESS(__returnError = NtQuerySystemInformation(SystemProcessInformation, __systemProcessInfo, 1024 * 1024, 0))) 
    { 
     if (!VirtualFree(__allocationBuffer, 0, MEM_RELEASE)) 
      return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTDEALLOC); 

     return reinterpret_cast<HANDLE>(PRH_ERR_NTQUERYFAIL); 
    } 

    while (__systemProcessInfo->NextEntryOffset) 
    { 
     if (__systemProcessInfo->ImageName.Buffer != nullptr) 
     { 
      if (wcscmp(__systemProcessInfo->ImageName.Buffer, __processName) == 0) 
      { 
       HANDLE __basicHandle = OpenProcess(PROCESS_ALL_ACCESS, false, __systemProcessInfo->UniqueProcessId); 
       HANDLE __perfectHandle{ 0 }; 

       if (!__basicHandle) 
       { 
        if (!VirtualFree(__allocationBuffer, 0, MEM_RELEASE)) 
         return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTDEALLOC); 

        return reinterpret_cast<HANDLE>(PRH_ERR_OPENPROCFAIL); 
       } 

       if (!NT_SUCCESS(NtDuplicateObject(GetCurrentProcess(), __basicHandle, GetCurrentProcess(), &__perfectHandle, PROCESS_ALL_ACCESS, 0, DUPLICATE_SAME_ACCESS))) 
       { 
        if (!VirtualFree(__allocationBuffer, 0, MEM_RELEASE)) 
         return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTDEALLOC); 

        return reinterpret_cast<HANDLE>(PRH_ERR_DUPHANDFAIL); 
       } 

       /*if(!NtClose(__basicHandle)) 
       { 
        if (!VirtualFree(__allocationBuffer, 0, MEM_RELEASE)) 
         return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTDEALLOC); 

        if(!CloseHandle(__basicHandle)) 
         return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTCLOSEHAND); 

        return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTCLOSEHAND); 
       } 

       if(__basicHandle != nullptr) 
       { 
        if (!VirtualFree(__allocationBuffer, 0, MEM_RELEASE)) 
         return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTDEALLOC); 

        return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTCLOSEHAND); 
       }*/ 

       _OBJECT_HANDLE_FLAG_INFORMATION __objectInformation{ 0 }; 
       __objectInformation.ProtectFromClose = { true }; 

       if (!NT_SUCCESS(NtSetInformationObject(__perfectHandle, ObjectHandleFlagInformation, &__objectInformation, sizeof(_OBJECT_HANDLE_FLAG_INFORMATION)))) 
       { 
        if (!VirtualFree(__allocationBuffer, 0, MEM_RELEASE)) 
         return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTDEALLOC); 

        return reinterpret_cast<HANDLE>(PRH_ERR_PFCFAIL); 
       } 

       if (!VirtualFree(__allocationBuffer, 0, MEM_RELEASE)) 
        return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTDEALLOC); 

       return __perfectHandle; 
      } 
     } 

     __systemProcessInfo = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(reinterpret_cast<BYTE*>(__systemProcessInfo) + __systemProcessInfo->NextEntryOffset); 
    } 

    if (!VirtualFree(__allocationBuffer, 0, MEM_RELEASE)) 
     return reinterpret_cast<HANDLE>(PRH_ERR_CANNOTDEALLOC); 

    return reinterpret_cast<HANDLE>(PRH_ERR_FELLTROUGH); 
} 

全:https://hastebin.com/moyehijehe.cpp

回答

0

在粗略地看一眼,我認爲問題可能是您撥打GetProcessHandle。返回一個僞句柄(常量),該OS知道的意思是「當前進程」:

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,那麼你肯定不能複製從它返回的任何句柄(因爲它不是一個真正的句柄,只是一個常量)。

編號:https://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx

我很好奇你的意圖和代碼的描述之間的差距。爲什麼遍歷所有進程只是爲了找到自己的進程?您可以通過一個API調用獲得它的PID(例如GetProcessID)。

所以,你可以將代碼更改爲類似(這留下的僞句柄「泄漏」,但由於它是不是一個真正的手柄,沒有泄漏!):

HANDLE hRealHandle=OpenProcess(GetProcesssId(GetCurrentProcess()), ...); 

當然, NT Native API的等價物很容易確定,如果你更喜歡它們,我會把它留給你,如果這甚至有幫助。

+0

我不想用我自己的過程做到這一點,我想要做的,基本上任何其他過程。那是我的意圖 –

+0

啊,「我的*進程」語言讓我困惑。當我仔細觀察代碼時,不清楚使用這個常量是否會成爲問題。可能不會,否則你會看到它。 –