2017-09-24 6 views
-2

J'essaie donc de faire une boucle dans les processus, de trouver l'identifiant de processus de mon processus (qui fonctionne), puis d'ouvrir un processus avec ce pid (qui fonctionne également) et puis dupliquez-le avec NtDuplicateObject et protégez-le avec NtSetInformationObject.Essayer de saisir, dupliquer et protéger une poignée avec NTDLL

Le problème est qu'il y a toujours quelque chose qui ne va pas. La première fois que je l'ai essayé, il ne voulait pas le dupliquer, avancer rapidement jusqu'à maintenant et après avoir commenté la partie où j'essaie de fermer l'ancien handle (ce que je ne peux pas faire et le NtDuplicateObject ne devrait pas le faire non plus) me donne un handle mais je ne peux pas l'utiliser pour writeprocessmemory ou quelque chose comme ça. Je posterai la fonction ici et le code complet dans un lien hastebin (au cas où il y a confusion dans mon code qui ont besoin d'une couture)

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); 
} 

complète: https://hastebin.com/moyehijehe.cpp

Répondre

0

un coup d'œil rapide, je pense le problème peut être votre appel de GetProcessHandle. Cela renvoie une pseudo-poignée (une constante) que le système d'exploitation connaît signifie « le processus en cours »:

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. 

Maintenant, je peux me tromper, comme je viens de jetai un regard à votre code, mais si vous utilisez cette API, alors vous ne pouvez certainement pas dupliquer n'importe quel handle retourné (car ce n'est pas un vrai handle, juste une constante).

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

Je suis curieux de savoir la disparité entre votre description de l'intention et le code. Pourquoi parcourir tous les processus juste pour trouver votre propre processus? Vous pouvez obtenir ce PID avec un seul appel API (par exemple GetProcessID).

Ainsi, vous pouvez changer votre code à quelque chose comme (ce qui laisse la pseudo-poignée « fuite », mais comme il est pas vraiment une poignée, rien ne fuit!):

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

Bien sûr, les équivalents de Native API NT sont faciles à déterminer, si vous les préférez, et je vous laisse le soin de le faire, si cela vous est utile.

+0

Je ne veux pas le faire avec mon propre processus, je veux le faire avec, eh bien, fondamentalement tout autre processus. C'était mon intention –

+0

Ah, le langage "* my * process" m'a troublé. En regardant de plus près le code, il n'est pas clair si l'utilisation de cette constante serait un problème. Probablement pas, sinon tu l'aurais vu. –