returns FALSE if need to block execution
| 2826 | |
| 2827 | // returns FALSE if need to block execution |
| 2828 | BOOL CShellProc::OnCreateProcessW(LPCWSTR* asFile, LPCWSTR* asCmdLine, LPCWSTR* asDir, DWORD* anCreationFlags, LPSTARTUPINFOW* ppStartupInfo) |
| 2829 | { |
| 2830 | if (!ppStartupInfo || !*ppStartupInfo || !IsInterceptionEnabled()) |
| 2831 | { |
| 2832 | LogShellString(L"OnCreateProcessW skipped"); |
| 2833 | return TRUE; // don't intercept, pass to kernel |
| 2834 | } |
| 2835 | |
| 2836 | // VS 2019 passes cb==0 while starting console applications (run & debug) |
| 2837 | // ruby.exe passes cb==0 while starting powershell |
| 2838 | const DWORD cbParamStartupInfoSize = (*ppStartupInfo)->cb ? (*ppStartupInfo)->cb |
| 2839 | : IsBadReadPtr(*ppStartupInfo, sizeof(STARTUPINFOW)) ? 0 : static_cast<DWORD>(sizeof(STARTUPINFOW)); |
| 2840 | |
| 2841 | const size_t cbLocalStartupInfoSize = std::max<size_t>(sizeof(STARTUPINFOW), cbParamStartupInfoSize); |
| 2842 | m_lpStartupInfoW.reset(static_cast<LPSTARTUPINFOW>(calloc(1, cbLocalStartupInfoSize))); |
| 2843 | if (!m_lpStartupInfoW) |
| 2844 | { |
| 2845 | LogShellString(L"OnCreateProcessW failed"); |
| 2846 | return TRUE; // don't intercept, pass to kernel |
| 2847 | } |
| 2848 | |
| 2849 | auto* lpSi = m_lpStartupInfoW.get(); |
| 2850 | if (cbParamStartupInfoSize) |
| 2851 | { |
| 2852 | memmove_s(lpSi, cbLocalStartupInfoSize, *ppStartupInfo, cbParamStartupInfoSize); |
| 2853 | if (!lpSi->cb) |
| 2854 | lpSi->cb = cbParamStartupInfoSize; |
| 2855 | |
| 2856 | #ifdef DEBUG_SHELL_LOG_OUTPUT |
| 2857 | wchar_t dbgBuf[200]; |
| 2858 | msprintf(dbgBuf, countof(dbgBuf), L"OnCreateProcessW cFlags=x%X sFlags=x%X sw=x%X in=x%X out=x%X err=x%X", |
| 2859 | anCreationFlags ? *anCreationFlags : 0, (*ppStartupInfo)->dwFlags, (*ppStartupInfo)->wShowWindow, |
| 2860 | LODWORD((*ppStartupInfo)->hStdInput), LODWORD((*ppStartupInfo)->hStdOutput), LODWORD((*ppStartupInfo)->hStdError)); |
| 2861 | LogShellString(dbgBuf); |
| 2862 | #endif |
| 2863 | } |
| 2864 | else |
| 2865 | { |
| 2866 | lpSi->cb = sizeof(*lpSi); |
| 2867 | LogShellString(L"OnCreateProcessW creating new default STARTUPINFOW"); |
| 2868 | } |
| 2869 | |
| 2870 | // Preprocess flags and options |
| 2871 | auto state = OnCreateProcessPrepare(anCreationFlags, lpSi->dwFlags, lpSi->wShowWindow, lpSi->dwX, lpSi->dwY); |
| 2872 | |
| 2873 | _ASSERTEX(!mpwsz_TempRetFile && !mpwsz_TempRetParam && !mpwsz_TempRetDir); |
| 2874 | |
| 2875 | // Main logic |
| 2876 | const auto prepareResult = PrepareExecuteParams(eCreateProcess, |
| 2877 | nullptr, |
| 2878 | asFile ? *asFile : nullptr, |
| 2879 | asCmdLine ? *asCmdLine : nullptr, |
| 2880 | asDir ? *asDir : nullptr, |
| 2881 | nullptr, anCreationFlags, &lpSi->dwFlags, &state.showCmd, |
| 2882 | &lpSi->hStdInput, &lpSi->hStdOutput, &lpSi->hStdError, |
| 2883 | mpwsz_TempRetFile, mpwsz_TempRetParam, mpwsz_TempRetDir); |
| 2884 | if (prepareResult == PrepareExecuteResult::Restrict) |
| 2885 | return false; |