Ignore:
Timestamp:
Mar 22, 2018, 8:50:04 PM (7 years ago)
Author:
bird
Message:

kmk_redirect,winchildren: WOW64 standard handle injection fixes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kmkbuiltin/redirect.c

    r3173 r3179  
    4040# include <process.h>
    4141#endif
    42 #if defined(KBUILD_OS_WINDOWS) || defined(KBUILD_OS_OS2)
     42#ifdef KBUILD_OS_WINDOWS
    4343# include <Windows.h>
    44 # include <Winternl.h>
    4544#endif
    4645#if defined(_MSC_VER)
     
    6766#include "err.h"
    6867#include "kbuild_version.h"
     68#ifdef KBUILD_OS_WINDOWS
     69# include "nt/nt_child_inject_standard_handles.h"
     70#endif
    6971#if defined(__gnu_hurd__) && !defined(kmk_builtin_redirect) /* need constant */
    7072# undef GET_PATH_MAX
     
    791793}
    792794
     795
    793796/**
    794797 * Alternative approach on windows that use CreateProcess and doesn't require
     
    805808 * @param   phProcess           Where to return process handle.
    806809 */
    807 static kRedirectCreateProcessWindows(const char *pszExecutable, int cArgs, char **papszArgs, char **papszEnvVars,
    808                                      const char *pszCwd, unsigned cOrders, REDIRECTORDERS *paOrders, HANDLE *phProcess)
     810static int kRedirectCreateProcessWindows(const char *pszExecutable, int cArgs, char **papszArgs, char **papszEnvVars,
     811                                         const char *pszCwd, unsigned cOrders, REDIRECTORDERS *paOrders, HANDLE *phProcess)
    809812{
    810     static NTSTATUS (NTAPI *s_pfnNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG) = NULL;
    811813    size_t cbArgs;
    812814    char  *pszCmdLine;
     
    816818    int    i;
    817819    int    rc;
    818 
    819     /*
    820      * Determin host bitness and APIs while we can still easily return.
    821      */
    822 #if K_ARCH_BITS == 32
    823     BOOL   f64BitHost = TRUE;
    824     if (!IsWow64Process(GetCurrentProcess(), &f64BitHost))
    825         return errx(9, "IsWow64Process failed: %u", GetLastError());
    826 #elif K_ARCH_BITS == 64
    827     BOOL const f64BitHost = TRUE;
    828 #else
    829 # error "K_ARCH_BITS is bad/missing"
    830 #endif
    831     if (cOrders > 0 && !s_pfnNtQueryInformationProcess)
    832     {
    833         *(FARPROC *)&s_pfnNtQueryInformationProcess = GetProcAddress(GetModuleHandleA("NTDLL.DLL"), "NtQueryInformationProcess");
    834         if (!s_pfnNtQueryInformationProcess)
    835             return errx(9, "NtQueryInformationProcess not found!");
    836     }
    837820
    838821    /*
     
    962945                                   FALSE /*fInheritHandles*/, CREATE_SUSPENDED, pszzEnv, pszCwd, &StartupInfo, &ProcInfo))
    963946                {
    964                     /*
    965                      * Figure out where we need to write the handles.
    966                      */
    967                     ULONG                     cbActual1 = 0;
    968                     PROCESS_BASIC_INFORMATION BasicInfo = { 0, 0, };
    969                     NTSTATUS rcNt = s_pfnNtQueryInformationProcess(ProcInfo.hProcess, ProcessBasicInformation,
    970                                                                    &BasicInfo, sizeof(BasicInfo), &cbActual1);
    971                     if (NT_SUCCESS(rcNt))
    972                     {
    973                         BOOL const   f32BitPeb  = !f64BitHost;
    974                         ULONG  const cbChildPtr = f32BitPeb ? 4 : 8;
    975                         PVOID        pvSrcInPeb = (char *)BasicInfo.PebBaseAddress + (f32BitPeb ? 0x10 : 0x20);
    976                         char *       pbDst      = 0;
    977                         SIZE_T       cbActual2  = 0;
    978                         if (ReadProcessMemory(ProcInfo.hProcess, pvSrcInPeb, &pbDst, cbChildPtr, &cbActual2))
    979                         {
    980                             union
    981                             {
    982                                 KU32 au32[3];
    983                                 KU64 au64[3];
    984                             } uBuf;
    985                             memset(&uBuf, 0, sizeof(uBuf));
    986                             pbDst += f32BitPeb ? 0x18 : 0x20;
    987                             if (   (afReplace[0] && afReplace[1] && afReplace[2])
    988                                 || ReadProcessMemory(ProcInfo.hProcess, pbDst, &uBuf, cbChildPtr * 3, &cbActual2))
    989                             {
    990                                 for (i = 0; i < 3; i++)
    991                                     if (afReplace[i])
    992                                     {
    993                                         HANDLE hInChild = INVALID_HANDLE_VALUE;
    994                                         if (   ahChild[i] == NULL /* just closed*/
    995                                             || DuplicateHandle(GetCurrentProcess(), ahChild[i], ProcInfo.hProcess, &hInChild,
    996                                                                0, TRUE /*fInheriable*/, DUPLICATE_SAME_ACCESS))
    997                                         {
    998                                             if (f32BitPeb)
    999                                                 uBuf.au32[i] = (KU32)(uintptr_t)hInChild;
    1000                                             else
    1001                                                 uBuf.au64[i] = (uintptr_t)hInChild;
    1002                                         }
    1003                                         else
    1004                                             rc = errx(10, "Error duplicating %p into the child: %u", ahChild[i], GetLastError());
    1005                                     }
    1006                                 if (    rc == 0
    1007                                     && !WriteProcessMemory(ProcInfo.hProcess, pbDst, &uBuf, cbChildPtr * 3, &cbActual2))
    1008                                     rc = errx(10, "Error writing standard handles at %p LB %u in the child: %u",
    1009                                               pbDst, cbChildPtr * 3, GetLastError());
    1010                             }
    1011                             else
    1012                                 rc = errx(10, "Error reading %p LB %u from the child: %u",
    1013                                           pbDst, cbChildPtr * 3, GetLastError());
    1014                         }
    1015                         else
    1016                             rc = errx(10, "Error reading %p LB %u from the child: %u", pvSrcInPeb, cbChildPtr);
    1017                     }
    1018                     else
    1019                         rc = errx(10, "NtQueryInformationProcess failed: %#x", rcNt);
    1020 
    1021                     /* Resume the bugger... */
    1022                     if (   rc == 0
    1023                         && !ResumeThread(ProcInfo.hThread))
     947                    /* Inject the handles and try make it start executing. */
     948                    char szErrMsg[128];
     949                    rc = nt_child_inject_standard_handles(ProcInfo.hProcess, afReplace, ahChild, szErrMsg, sizeof(szErrMsg));
     950                    if (rc)
     951                        rc = errx(10, "%s", szErrMsg);
     952                    else if (!ResumeThread(ProcInfo.hThread))
    1024953                        rc = errx(10, "ResumeThread failed: %u", GetLastError());
    1025954
    1026                     /* .. or kill it. */
     955                    /* Kill it if any of that fails. */
    1027956                    if (rc != 0)
    1028957                        TerminateProcess(ProcInfo.hProcess, rc);
Note: See TracChangeset for help on using the changeset viewer.