-2

所以我试图基本上循环处理进程,找到我的进程的进程ID(有效),然后使用该pid打开一个进程(也有效),然后用NtDuplicateObject复制它并用NtSetInformationObject保护它。

问题是总是有问题。我第一次尝试它不想复制它,快进到现在,在注释掉我尝试关闭旧句柄的部分之后(我不能这样做,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

4

1 回答 1

0

粗略一看,我认为问题可能出在您对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,那么你当然不能复制从它返回的任何句柄(因为它不是真正的句柄,只是一个常量)。

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

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

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

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

当然,NT Native API 等价物很容易确定,如果您更喜欢它们,我会留给您,如果这有帮助的话。

于 2017-09-24T15:28:05.147 回答