| 1439 | } |
| 1440 | |
| 1441 | BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, |
| 1442 | _In_ DWORD nDlls, |
| 1443 | _In_reads_(nDlls) LPCSTR *rlpDlls, |
| 1444 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW) |
| 1445 | { |
| 1446 | BOOL Result = FALSE; |
| 1447 | PROCESS_INFORMATION pi; |
| 1448 | STARTUPINFOW si; |
| 1449 | WCHAR szExe[MAX_PATH]; |
| 1450 | WCHAR szCommand[MAX_PATH]; |
| 1451 | PDETOUR_EXE_HELPER helper = NULL; |
| 1452 | HRESULT hr; |
| 1453 | WCHAR szDllName[MAX_PATH]; |
| 1454 | int cchWrittenWideChar; |
| 1455 | DWORD nLen = GetEnvironmentVariableW(L"WINDIR", szExe, ARRAYSIZE(szExe)); |
| 1456 | |
| 1457 | DETOUR_TRACE(("DetourProcessViaHelperDlls(pid=%lu,dlls=%lu)\n", dwTargetPid, nDlls)); |
| 1458 | if (nDlls < 1 || nDlls > 4096) { |
| 1459 | SetLastError(ERROR_INVALID_PARAMETER); |
| 1460 | goto Cleanup; |
| 1461 | } |
| 1462 | if (!AllocExeHelper(&helper, dwTargetPid, nDlls, rlpDlls)) { |
| 1463 | goto Cleanup; |
| 1464 | } |
| 1465 | |
| 1466 | if (nLen == 0 || nLen >= ARRAYSIZE(szExe)) { |
| 1467 | goto Cleanup; |
| 1468 | } |
| 1469 | |
| 1470 | #if DETOURS_OPTION_BITS |
| 1471 | #if DETOURS_32BIT |
| 1472 | hr = StringCchCatW(szExe, ARRAYSIZE(szExe), L"\\sysnative\\rundll32.exe"); |
| 1473 | #else // !DETOURS_32BIT |
| 1474 | hr = StringCchCatW(szExe, ARRAYSIZE(szExe), L"\\syswow64\\rundll32.exe"); |
| 1475 | #endif // !DETOURS_32BIT |
| 1476 | #else // DETOURS_OPTIONS_BITS |
| 1477 | hr = StringCchCatW(szExe, ARRAYSIZE(szExe), L"\\system32\\rundll32.exe"); |
| 1478 | #endif // DETOURS_OPTIONS_BITS |
| 1479 | if (!SUCCEEDED(hr)) { |
| 1480 | goto Cleanup; |
| 1481 | } |
| 1482 | |
| 1483 | //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")); |
| 1484 | //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 |
| 1485 | |
| 1486 | cchWrittenWideChar = MultiByteToWideChar(CP_ACP, 0, &helper->rDlls[0], -1, szDllName, ARRAYSIZE(szDllName)); |
| 1487 | if (cchWrittenWideChar >= ARRAYSIZE(szDllName) || cchWrittenWideChar <= 0) { |
| 1488 | goto Cleanup; |
| 1489 | } |
| 1490 | hr = StringCchPrintfW(szCommand, ARRAYSIZE(szCommand), |
| 1491 | L"rundll32.exe \"%s\",#1", szDllName); |
| 1492 | if (!SUCCEEDED(hr)) { |
| 1493 | goto Cleanup; |
| 1494 | } |
| 1495 | |
| 1496 | ZeroMemory(&pi, sizeof(pi)); |
| 1497 | ZeroMemory(&si, sizeof(si)); |
| 1498 | si.cb = sizeof(si); |
no test coverage detected
searching dependent graphs…