in src/creatwth.cpp [1440:1536]
BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid,
_In_ DWORD nDlls,
_In_reads_(nDlls) LPCSTR *rlpDlls,
_In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW)
{
BOOL Result = FALSE;
PROCESS_INFORMATION pi;
STARTUPINFOW si;
WCHAR szExe[MAX_PATH];
WCHAR szCommand[MAX_PATH];
PDETOUR_EXE_HELPER helper = NULL;
HRESULT hr;
WCHAR szDllName[MAX_PATH];
int cchWrittenWideChar;
DWORD nLen = GetEnvironmentVariableW(L"WINDIR", szExe, ARRAYSIZE(szExe));
DETOUR_TRACE(("DetourProcessViaHelperDlls(pid=%lu,dlls=%lu)\n", dwTargetPid, nDlls));
if (nDlls < 1 || nDlls > 4096) {
SetLastError(ERROR_INVALID_PARAMETER);
goto Cleanup;
}
if (!AllocExeHelper(&helper, dwTargetPid, nDlls, rlpDlls)) {
goto Cleanup;
}
if (nLen == 0 || nLen >= ARRAYSIZE(szExe)) {
goto Cleanup;
}
#if DETOURS_OPTION_BITS
#if DETOURS_32BIT
hr = StringCchCatW(szExe, ARRAYSIZE(szExe), L"\\sysnative\\rundll32.exe");
#else // !DETOURS_32BIT
hr = StringCchCatW(szExe, ARRAYSIZE(szExe), L"\\syswow64\\rundll32.exe");
#endif // !DETOURS_32BIT
#else // DETOURS_OPTIONS_BITS
hr = StringCchCatW(szExe, ARRAYSIZE(szExe), L"\\system32\\rundll32.exe");
#endif // DETOURS_OPTIONS_BITS
if (!SUCCEEDED(hr)) {
goto Cleanup;
}
//for East Asia languages and so on, like Chinese, print format with "%hs" can not work fine before user call _tsetlocale(LC_ALL,_T(".ACP"));
//so we can't use "%hs" in format string, because the dll that contain this code would inject to any process, even not call _tsetlocale(LC_ALL,_T(".ACP")) before
cchWrittenWideChar = MultiByteToWideChar(CP_ACP, 0, &helper->rDlls[0], -1, szDllName, ARRAYSIZE(szDllName));
if (cchWrittenWideChar >= ARRAYSIZE(szDllName) || cchWrittenWideChar <= 0) {
goto Cleanup;
}
hr = StringCchPrintfW(szCommand, ARRAYSIZE(szCommand),
L"rundll32.exe \"%s\",#1", szDllName);
if (!SUCCEEDED(hr)) {
goto Cleanup;
}
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
DETOUR_TRACE(("DetourProcessViaHelperDlls(\"%ls\", \"%ls\")\n", szExe, szCommand));
if (pfCreateProcessW(szExe, szCommand, NULL, NULL, FALSE, CREATE_SUSPENDED,
NULL, NULL, &si, &pi)) {
if (!DetourCopyPayloadToProcess(pi.hProcess,
DETOUR_EXE_HELPER_GUID,
helper, helper->cb)) {
DETOUR_TRACE(("DetourCopyPayloadToProcess failed: %lu\n", GetLastError()));
TerminateProcess(pi.hProcess, ~0u);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
goto Cleanup;
}
ResumeThread(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD dwResult = 500;
GetExitCodeProcess(pi.hProcess, &dwResult);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
if (dwResult != 0) {
DETOUR_TRACE(("Rundll32.exe failed: result=%lu\n", dwResult));
goto Cleanup;
}
Result = TRUE;
}
else {
DETOUR_TRACE(("CreateProcess failed: %lu\n", GetLastError()));
goto Cleanup;
}
Cleanup:
FreeExeHelper(&helper);
return Result;
}