Win32 API功能封装
+ -

DuplicateHandle进程间传递

2023-10-24 15 0

学习USBIP的代码时,学到了新的知识。https://www.usbzh.com/article/detail-320.html

在应用层通过DuplicateHandle传递句柄给子进程,这样可以实现过继句柄。

主进程中:


static int
execute_attacher(HANDLE hdev, SOCKET sockfd, int rhport)
{
    STARTUPINFO    si;
    PROCESS_INFORMATION    pi;
    HANDLE    hRead, hWrite;
    HANDLE    hdev_attacher, sockfd_attacher;
    BOOL    res;
    int    ret = ERR_GENERAL;

    if (!create_pipe(&hRead, &hWrite))
        return ERR_GENERAL;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.hStdInput = hRead;
    si.dwFlags = STARTF_USESTDHANDLES;
    ZeroMemory(&pi, sizeof(pi));

    res = CreateProcess("attacher.exe", "attacher.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
    if (!res) {
        DWORD    err = GetLastError();
        if (err == ERROR_FILE_NOT_FOUND)
            ret = ERR_NOTEXIST;
        dbg("failed to create process: 0x%lx", err);
        goto out;
    }
    res = DuplicateHandle(GetCurrentProcess(), hdev, pi.hProcess, &hdev_attacher, 0, FALSE, DUPLICATE_SAME_ACCESS);
    if (!res) {
        dbg("failed to dup hdev: 0x%lx", GetLastError());
        goto out_proc;
    }
    res = DuplicateHandle(GetCurrentProcess(), (HANDLE)sockfd, pi.hProcess, &sockfd_attacher, 0, FALSE, DUPLICATE_SAME_ACCESS);
    if (!res) {
        dbg("failed to dup sockfd: 0x%lx", GetLastError());
        goto out_proc;
    }
    if (!write_handle_value(hWrite, hdev_attacher) || !write_handle_value(hWrite, sockfd_attacher))
        goto out_proc;
    ret = 0;
out_proc:
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
out:
    CloseHandle(hRead);
    CloseHandle(hWrite);
    return ret;
}

创建子进程需要的管道,然后使用DuplicateHandle将主进程的需要dump的两个句柄sockfd和hdev复制出来,并写入管道中去。
在子进程中,通过打开管道读取句柄,实现子进程的功能。

static HANDLE
read_handle_value(HANDLE hStdin)
{
    HANDLE    handle;
    LPBYTE    buf = (LPBYTE)&handle;
    DWORD    buflen = sizeof(HANDLE);

    while (buflen > 0) {
        DWORD    nread;

        if (!ReadFile(hStdin, buf + sizeof(HANDLE) - buflen, buflen, &nread, NULL)) {
            return INVALID_HANDLE_VALUE;
        }
        if (nread == 0)
            return INVALID_HANDLE_VALUE;
        buflen -= nread;
    }
    return handle;
}

static BOOL
setup_forwarder(void)
{
    HANDLE    hdev, sockfd;
    HANDLE    hStdin, hStdout;

    hStdin = GetStdHandle(STD_INPUT_HANDLE);
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    hdev = read_handle_value(hStdin);
    sockfd = read_handle_value(hStdin);

    usbip_forward(hdev, sockfd, FALSE);

    CloseHandle(hStdin);
    CloseHandle(hStdout);

    return TRUE;
}

int APIENTRY
wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
     _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    if (!setup_forwarder())
        return 1;

    return 0;
}

通过usbip_forward实现子进程的业务。

0 篇笔记 写笔记

DuplicateHandle进程间传递
学习USBIP的代码时,学到了新的知识。https://www.usbzh.com/article/detail-320.html在应用层通过DuplicateHandle传递句柄给子进程,这样可以实现过继句柄。主进程中:static intexecute_attacher(HANDLE ......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!