Changeset 3179 for trunk/src/kmk/w32


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/w32/winchildren.c

    r3173 r3179  
    7979#include <assert.h>
    8080#include <process.h>
     81#include <intrin.h>
     82
     83#include "nt/nt_child_inject_standard_handles.h"
    8184
    8285
     
    328331
    329332
     333#if K_ARCH_BITS == 32 && !defined(_InterlockedCompareExchangePointer)
     334/** _InterlockedCompareExchangePointer is missing? (VS2010) */
     335K_INLINE void *_InterlockedCompareExchangePointer(void * volatile *ppvDst, void *pvNew, void *pvOld)
     336{
     337    return (void *)_InterlockedCompareExchange((long volatile *)ppvDst, (intptr_t)pvNew, (intptr_t)pvOld);
     338}
     339#endif
     340
    330341
    331342/**
     
    698709        if (fHaveHandles)
    699710        {
    700             /*
    701              * Get the PEB address and figure out the child process bit count.
    702              */
    703             ULONG                     cbActual1 = 0;
    704             PROCESS_BASIC_INFORMATION BasicInfo = { 0, 0, };
    705             NTSTATUS rcNt = g_pfnNtQueryInformationProcess(ProcInfo.hProcess, ProcessBasicInformation,
    706                                                            &BasicInfo, sizeof(BasicInfo), &cbActual1);
    707             if (NT_SUCCESS(rcNt))
    708             {
    709                 /*
    710                  * Read the user process parameter pointer from the PEB.
    711                  *
    712                  * Note! Seems WOW64 processes starts out with a 64-bit PEB and
    713                  *       process parameter block.
    714                  */
    715                 BOOL const   f32BitPeb  = !g_f64BitHost;
    716                 ULONG  const cbChildPtr = f32BitPeb ? 4 : 8;
    717                 PVOID        pvSrcInPeb = (char *)BasicInfo.PebBaseAddress + (f32BitPeb ? 0x10 : 0x20);
    718                 char *       pbDst      = 0;
    719                 SIZE_T       cbActual2  = 0;
    720                 if (ReadProcessMemory(ProcInfo.hProcess, pvSrcInPeb, &pbDst, cbChildPtr, &cbActual2))
    721                 {
    722                     /*
    723                      * Duplicate the handles into the child.
    724                      */
    725                     union
    726                     {
    727                         ULONGLONG   au64Bit[2];
    728                         ULONG       au32Bit[2];
    729                     } WriteBuf;
    730                     ULONG  idx = 0;
    731                     HANDLE hChildStdOut = INVALID_HANDLE_VALUE;
    732                     HANDLE hChildStdErr = INVALID_HANDLE_VALUE;
    733 
    734                     pbDst += (f32BitPeb ? 0x1c : 0x28);
    735                     if (pChild->u.Process.hStdOut != INVALID_HANDLE_VALUE)
    736                     {
    737                         if (DuplicateHandle(GetCurrentProcess(), pChild->u.Process.hStdOut, ProcInfo.hProcess,
    738                                             &hChildStdOut, 0, TRUE /*fInheritable*/, DUPLICATE_SAME_ACCESS))
    739                         {
    740                             if (f32BitPeb)
    741                                 WriteBuf.au32Bit[idx++] = (DWORD)(uintptr_t)hChildStdOut;
    742                             else
    743                                 WriteBuf.au64Bit[idx++] = (uintptr_t)hChildStdOut;
    744                         }
    745                         else
    746                         {
    747                             dwErr = GetLastError();
    748                             fprintf(stderr, "Failed to duplicate %p (stdout) into the child: %u\n",
    749                                     pChild->u.Process.hStdOut, dwErr);
    750                         }
    751                     }
    752                     else
    753                         pbDst += cbChildPtr;
    754 
    755                     if (pChild->u.Process.hStdErr != INVALID_HANDLE_VALUE)
    756                     {
    757                         if (DuplicateHandle(GetCurrentProcess(), pChild->u.Process.hStdErr, ProcInfo.hProcess,
    758                                             &hChildStdErr, 0, TRUE /*fInheritable*/, DUPLICATE_SAME_ACCESS))
    759                         {
    760                             if (f32BitPeb)
    761                                 WriteBuf.au32Bit[idx++] = (DWORD)(uintptr_t)hChildStdOut;
    762                             else
    763                                 WriteBuf.au64Bit[idx++] = (uintptr_t)hChildStdOut;
    764                         }
    765                         else
    766                         {
    767                             dwErr = GetLastError();
    768                             fprintf(stderr, "Failed to duplicate %p (stderr) into the child: %u\n",
    769                                     pChild->u.Process.hStdOut, dwErr);
    770                         }
    771                     }
    772 
    773                     /*
    774                      * Finally write the handle values into the child.
    775                      */
    776                     if (   idx > 0
    777                         && !WriteProcessMemory(ProcInfo.hProcess, pbDst, &WriteBuf, idx * cbChildPtr, &cbActual2))
    778                     {
    779                         dwErr = GetLastError();
    780                         fprintf(stderr, "Failed to write %p LB %u into child: %u\n", pbDst, idx * cbChildPtr, dwErr);
    781                     }
    782                 }
    783                 else
    784                 {
    785                     dwErr = GetLastError();
    786                     fprintf(stderr, "Failed to read %p LB %u from the child: %u\n", pvSrcInPeb, cbChildPtr, dwErr);
    787                 }
    788             }
    789             else
    790             {
    791                 fprintf(stderr, "NtQueryInformationProcess failed on child: %#x\n", rcNt);
    792                 dwErr = (DWORD)rcNt;
    793             }
     711            char    szErrMsg[128];
     712            BOOL    afReplace[3] =
     713            { FALSE, pChild->u.Process.hStdOut != INVALID_HANDLE_VALUE, pChild->u.Process.hStdErr != INVALID_HANDLE_VALUE };
     714            HANDLE  ahChild[3] =
     715            { NULL,  pChild->u.Process.hStdOut,                         pChild->u.Process.hStdErr  };
     716
     717            dwErr = nt_child_inject_standard_handles(ProcInfo.hProcess, afReplace, ahChild, szErrMsg, sizeof(szErrMsg));
     718            if (dwErr != 0)
     719                fprintf(stderr, "%s\n", szErrMsg);
    794720        }
    795721
Note: See TracChangeset for help on using the changeset viewer.