首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CreateProcessAsUser太快,无法跟踪进程

CreateProcessAsUser太快,无法跟踪进程
EN

Stack Overflow用户
提问于 2020-01-15 13:02:02
回答 2查看 161关注 0票数 0

我们调用CreateProcessAsUser(),在检查结果之后,我们开始跟踪可能创建其他进程的流程。

在1种情况下,第一个进程是如此之快,以至于它会创建另一个进程并在我们开始跟踪它之前终止。

我甚至尝试而不是检查结果,并在调用CreateProcessAsUser()之后立即开始跟踪,但速度不够快。

我的想法是从一个launcher.exe启动进程,这样我们就可以跟踪所有生成的进程。

还有别的解决办法吗?我们有终止过程的PID。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-15 15:15:22

如果我们启动子进程并想要方式,当它和--所有子进程--终止--时,我们可以使用作业对象。一般步骤

通过CreateJobObjectW

  • 创建新的作业对象

SetInformationJobObject设置

通过AssignProcessToJobObject将进程添加到作业中

现在,系统将在新进程启动或退出时将通知发送到我们的完成端口。当作业中没有更多的进程将JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO消息发送到端口时,表示活动进程计数已减少到0。

当然,我们也需要通过CreateIoCompletionPort来创建I/O完成端口,以及一个或多个线程(如果只用于这个任务--多个线程)线程,这些线程将在端口上调用GetQueuedCompletionStatus直到结束信号。

例如,我们可以使用lpCompletionKey作为指向具有虚拟函数的对象的指针,并且每个对象都知道如何处理操作事件。演示代码:

代码语言:javascript
复制
struct __declspec(novtable) PortTask 
{
    virtual bool OnIoCompletion(OVERLAPPED* lpOverlapped, ULONG NumberOfBytesTransferred) = 0;
};

struct EndTask : public PortTask 
{
    virtual bool OnIoCompletion(OVERLAPPED* /*lpOverlapped*/, ULONG /*NumberOfBytesTransferred*/)
    {
        DbgPrint("%s<%p>\n", __FUNCTION__, this);
        delete this;
        return false;
    }
};

struct IOPort 
{
    HANDLE CompletionPort;
    LONG dwRefCount;

    IOPort() : dwRefCount(1), CompletionPort(0) {
        DbgPrint("%s<%p>\n", __FUNCTION__, this);
    }

    ~IOPort(){
        if (CompletionPort) CloseHandle(CompletionPort);
        DbgPrint("%s<%p>\n", __FUNCTION__, this);
    }

    void AddRef(){
        InterlockedIncrementNoFence(&dwRefCount);
    }

    void Release(){
        if (!InterlockedDecrement(&dwRefCount)) {
            delete this;
        }
    }

    static ULONG WINAPI PortThread(PVOID This)
    {
        union {
            ULONG_PTR CompletionKey;
            PortTask* pTask;
        };

        ULONG NumberOfBytesTransferred;
        OVERLAPPED* lpOverlapped;

        HANDLE CompletionPort = reinterpret_cast<IOPort*>(This)->CompletionPort;

        while (GetQueuedCompletionStatus(CompletionPort, &NumberOfBytesTransferred, &CompletionKey, &lpOverlapped, INFINITE) &&
            pTask->OnIoCompletion(lpOverlapped, NumberOfBytesTransferred)) continue;

        reinterpret_cast<IOPort*>(This)->Release();
        return 0;
    }

    ULONG Create()
    {
        if (CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1))
        {
            AddRef();

            if (HANDLE hThread = CreateThread(0, 0, PortThread, this, 0, 0))
            {
                CloseHandle(hThread);
                return NOERROR;
            }
            Release();
        }

        return GetLastError();
    }

    ULONG Stop()
    {
        if (EndTask* pTask = new EndTask)
        {
            if (!PostQueuedCompletionStatus(CompletionPort, 0, (ULONG_PTR)pTask, 0))
            {
                ULONG dwError = GetLastError();
                delete pTask;
                return dwError;
            }
            return NOERROR;
        }

        return ERROR_NO_SYSTEM_RESOURCES;
    }
};

struct ActiveProcessZeroTask : public PortTask 
{
    //HWND hwnd; // in real code you send some message to hwnd instead thread
    HANDLE _hJob;
    ULONG _dwThreadId;

    ActiveProcessZeroTask() : _hJob(0), _dwThreadId(GetCurrentThreadId()) { }

    ~ActiveProcessZeroTask() {
        CloseHandle(_hJob);
        PostThreadMessageW(_dwThreadId, WM_QUIT, 0, 0);
    }

    virtual bool OnIoCompletion(OVERLAPPED* dwProcessId, ULONG MessageId)
    {
        DbgPrint("%s<%p>(%x %p)\n", __FUNCTION__, this, MessageId, dwProcessId);
        switch (MessageId)
        {
        case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
            DbgPrint("%p - ACTIVE_PROCESS_ZERO\n", dwProcessId);
            delete this;
            break;
        case JOB_OBJECT_MSG_NEW_PROCESS:
            DbgPrint("%p - NEW_PROCESS\n", dwProcessId);
            break;
        case JOB_OBJECT_MSG_EXIT_PROCESS:
            DbgPrint("%p - EXIT_PROCESS\n", dwProcessId);
            break;
        case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS:
            DbgPrint("%p - ABNORMAL_EXIT_PROCESS\n", dwProcessId);
            break;
        }
        return true;
    }

    ULONG Create(HANDLE CompletionPort, PCWSTR ApplicationName)
    {
        if (HANDLE hJob = CreateJobObjectW(0, 0))
        {
            _hJob = hJob;

            JOBOBJECT_ASSOCIATE_COMPLETION_PORT jacp = { this, CompletionPort };

            if (SetInformationJobObject(hJob, JobObjectAssociateCompletionPortInformation, &jacp, sizeof(jacp)))
            {
                STARTUPINFO si = { sizeof(si)};
                PROCESS_INFORMATION pi;
                if (CreateProcessW(ApplicationName, 0, 0, 0, 0, CREATE_SUSPENDED, 0, 0, &si, &pi))
                {
                    ULONG dwError = NOERROR;

                    if (!AssignProcessToJobObject(hJob, pi.hProcess) || 
                        !ResumeThread(pi.hThread))
                    {
                        dwError = GetLastError();
                        TerminateProcess(pi.hProcess, 0);
                    }
                    CloseHandle(pi.hThread);
                    CloseHandle(pi.hProcess);

                    return dwError;
                }
            }
        }

        return GetLastError();
    }
};

void demo()
{
    if (IOPort* port = new IOPort)
    {
        if (port->Create() == NOERROR)
        {
            MessageBoxW(0, 0, L"just for demo #1", MB_ICONINFORMATION);

            // exec cmd for demo
            WCHAR ApplicationName[MAX_PATH];
            if (GetEnvironmentVariableW(L"ComSpec", ApplicationName, RTL_NUMBER_OF(ApplicationName)))
            {
                if (ActiveProcessZeroTask* pTask = new ActiveProcessZeroTask)
                {
                    if (pTask->Create(port->CompletionPort, ApplicationName) != NOERROR)
                    {
                        delete pTask;
                    }
                }
            }

            // wait all childs exit
            MessageBoxW(0, 0, L"Wait for MSG_ACTIVE_PROCESS_ZERO", MB_ICONINFORMATION);

            // stop track thread

            if (port->Stop() != NOERROR) __debugbreak();

        }

        port->Release();
    }

    {
        MSG msg;
        // remove Wm_QUIT
        while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) continue;
        MessageBoxW(0, 0, L"just for demo #2", MB_ICONINFORMATION);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2020-01-15 13:33:08

您需要实现显式同步机制(信号量)。贝娄算法:

父进程中的 :

代码语言:javascript
复制
semaphore my_semaphore = CreateSemaphore ("my_semphaore");  
args my_arguments ("my_semphaore");  
CreateProcessAsUser (my_arguments); 
Create_Asynchronous_Thread { releasesemaphore (my_semaphore );} // unblock shild process}
waitforSingleObject (shild_process_PID)

shild过程中的 :

代码语言:javascript
复制
// do something ...
semaphore my_semaphore = CreateSemaphore ("my_semphaore");  
// do something (parent is blocked)
waitforsingleobject (my_semaphore);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59752021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档