- Timestamp:
- Mar 22, 2018, 8:50:04 PM (7 years ago)
- Location:
- trunk/src
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/redirect.c
r3173 r3179 40 40 # include <process.h> 41 41 #endif 42 #if defined(KBUILD_OS_WINDOWS) || defined(KBUILD_OS_OS2)42 #ifdef KBUILD_OS_WINDOWS 43 43 # include <Windows.h> 44 # include <Winternl.h>45 44 #endif 46 45 #if defined(_MSC_VER) … … 67 66 #include "err.h" 68 67 #include "kbuild_version.h" 68 #ifdef KBUILD_OS_WINDOWS 69 # include "nt/nt_child_inject_standard_handles.h" 70 #endif 69 71 #if defined(__gnu_hurd__) && !defined(kmk_builtin_redirect) /* need constant */ 70 72 # undef GET_PATH_MAX … … 791 793 } 792 794 795 793 796 /** 794 797 * Alternative approach on windows that use CreateProcess and doesn't require … … 805 808 * @param phProcess Where to return process handle. 806 809 */ 807 static kRedirectCreateProcessWindows(const char *pszExecutable, int cArgs, char **papszArgs, char **papszEnvVars,808 const char *pszCwd, unsigned cOrders, REDIRECTORDERS *paOrders, HANDLE *phProcess)810 static int kRedirectCreateProcessWindows(const char *pszExecutable, int cArgs, char **papszArgs, char **papszEnvVars, 811 const char *pszCwd, unsigned cOrders, REDIRECTORDERS *paOrders, HANDLE *phProcess) 809 812 { 810 static NTSTATUS (NTAPI *s_pfnNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG) = NULL;811 813 size_t cbArgs; 812 814 char *pszCmdLine; … … 816 818 int i; 817 819 int rc; 818 819 /*820 * Determin host bitness and APIs while we can still easily return.821 */822 #if K_ARCH_BITS == 32823 BOOL f64BitHost = TRUE;824 if (!IsWow64Process(GetCurrentProcess(), &f64BitHost))825 return errx(9, "IsWow64Process failed: %u", GetLastError());826 #elif K_ARCH_BITS == 64827 BOOL const f64BitHost = TRUE;828 #else829 # error "K_ARCH_BITS is bad/missing"830 #endif831 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 }837 820 838 821 /* … … 962 945 FALSE /*fInheritHandles*/, CREATE_SUSPENDED, pszzEnv, pszCwd, &StartupInfo, &ProcInfo)) 963 946 { 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)) 1024 953 rc = errx(10, "ResumeThread failed: %u", GetLastError()); 1025 954 1026 /* .. or kill it. */955 /* Kill it if any of that fails. */ 1027 956 if (rc != 0) 1028 957 TerminateProcess(ProcInfo.hProcess, rc); -
trunk/src/kmk/w32/winchildren.c
r3173 r3179 79 79 #include <assert.h> 80 80 #include <process.h> 81 #include <intrin.h> 82 83 #include "nt/nt_child_inject_standard_handles.h" 81 84 82 85 … … 328 331 329 332 333 #if K_ARCH_BITS == 32 && !defined(_InterlockedCompareExchangePointer) 334 /** _InterlockedCompareExchangePointer is missing? (VS2010) */ 335 K_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 330 341 331 342 /** … … 698 709 if (fHaveHandles) 699 710 { 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); 794 720 } 795 721 -
trunk/src/lib/Makefile.kmk
r3114 r3179 55 55 nt/ntunlink.c \ 56 56 nt/ntutimes.c \ 57 nt/nt_child_inject_standard_handles.c \ 57 58 nt/fts-nt.c \ 58 59 nt/kFsCache.c \
Note:
See TracChangeset
for help on using the changeset viewer.