int WINAPI TimedEntryPoint(VOID) { // We couldn't call LoadLibrary in DllMain, // so we detour SleepEx here... LONG error; TrueSleepEx = (DWORD (WINAPI *)(DWORD, BOOL)) DetourFindFunction("kernel32.dll", "SleepEx"); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx); error = DetourTransactionCommit(); if (error == NO_ERROR) { printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Detoured SleepEx().\n"); } else { printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Error detouring SleepEx(): %d\n", error); } Verify("SleepEx", (PVOID)SleepEx); printf("\n"); fflush(stdout); printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Calling EntryPoint\n"); fflush(stdout); return TrueEntryPoint(); }
BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, PVOID lpReserved) { (void)hModule; (void)lpReserved; BOOL ret; if (DetourIsHelperProcess()) { return TRUE; } switch (dwReason) { case DLL_PROCESS_ATTACH: DetourRestoreAfterWith(); OutputDebugString("trcapi" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:" " DllMain DLL_PROCESS_ATTACH\n"); return ProcessAttach(hModule); case DLL_PROCESS_DETACH: ret = ProcessDetach(hModule); OutputDebugString("trcapi" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:" " DllMain DLL_PROCESS_DETACH\n"); return ret; case DLL_THREAD_ATTACH: OutputDebugString("trcapi" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:" " DllMain DLL_THREAD_ATTACH\n"); return ThreadAttach(hModule); case DLL_THREAD_DETACH: OutputDebugString("trcapi" DETOURS_STRINGIFY(DETOURS_BITS) ".dll:" " DllMain DLL_THREAD_DETACH\n"); return ThreadDetach(hModule); } return TRUE; }
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved) { LONG error; (void)hinst; (void)reserved; if (DetourIsHelperProcess()) { return TRUE; } if (dwReason == DLL_PROCESS_ATTACH) { DetourRestoreAfterWith(); printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Starting.\n"); Verify("SleepEx", (PVOID)SleepEx); printf("\n"); fflush(stdout); // NB: DllMain can't call LoadLibrary, so we hook the app entry point. TrueEntryPoint = (int (WINAPI *)(VOID))DetourGetEntryPoint(NULL); RawEntryPoint = TrueEntryPoint; Verify("EntryPoint", RawEntryPoint); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)TrueEntryPoint, TimedEntryPoint); error = DetourTransactionCommit(); Verify("EntryPoint after attach", RawEntryPoint); Verify("EntryPoint trampoline", TrueEntryPoint); if (error == NO_ERROR) { printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Detoured EntryPoint().\n"); } else { printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Error detouring EntryPoint(): %d\n", error); } } else if (dwReason == DLL_PROCESS_DETACH) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); if (TrueSleepEx != NULL) { DetourDetach(&(PVOID&)TrueSleepEx, (PVOID)TimedSleepEx); } DetourDetach(&(PVOID&)TrueEntryPoint, TimedEntryPoint); error = DetourTransactionCommit(); printf("dslept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Removed Sleep() detours (%d), slept %d ticks.\n", error, dwSlept); fflush(stdout); } return TRUE; }
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved) { LONG error; (void)hinst; (void)reserved; if (DetourIsHelperProcess()) { return TRUE; } if (dwReason == DLL_PROCESS_ATTACH) { DetourRestoreAfterWith(); printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Starting.\n"); PVOID pbExeEntry = DetourGetEntryPoint(NULL); PVOID pbDllEntry = DetourGetEntryPoint(hinst); printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " ExeEntry=%p, DllEntry=%p\n", pbExeEntry, pbDllEntry); Verify("SleepEx", (PVOID)SleepEx); printf("\n"); fflush(stdout); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)TrueSleepEx, TimedSleepEx); error = DetourTransactionCommit(); if (error == NO_ERROR) { printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Detoured SleepEx() @ %p.\n", TrueSleepEx); } else { printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Error detouring SleepEx(): %d\n", error); } } else if (dwReason == DLL_PROCESS_DETACH) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)TrueSleepEx, TimedSleepEx); error = DetourTransactionCommit(); printf("slept" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: " " Removed SleepEx() detour (%d), slept %d ticks.\n", error, dwSlept); fflush(stdout); } return TRUE; }
BOOL ProcessAttach(HMODULE hDll) { s_bLog = FALSE; s_nTlsIndent = TlsAlloc(); s_nTlsThread = TlsAlloc(); ThreadAttach(hDll); WCHAR wzExeName[MAX_PATH]; s_hInst = hDll; Real_GetModuleFileNameW(hDll, s_wzDllPath, ARRAYSIZE(s_wzDllPath)); Real_GetModuleFileNameW(NULL, wzExeName, ARRAYSIZE(wzExeName)); sprintf_s(s_szDllPath, ARRAYSIZE(s_szDllPath), "%ls", s_wzDllPath); SyelogOpen("trcapi" DETOURS_STRINGIFY(DETOURS_BITS), SYELOG_FACILITY_APPLICATION); ProcessEnumerate(); LONG error = AttachDetours(); if (error != NO_ERROR) { Syelog(SYELOG_SEVERITY_FATAL, "### Error attaching detours: %d\n", error); } s_bLog = TRUE; return TRUE; }
DWORD main(int argc, char **argv) { HANDLE hCompletionPort; BOOL fNeedHelp = FALSE; WCHAR wzzDrop[1024] = L"build\0nmake\0"; GetSystemTimeAsFileTime((FILETIME *)&s_llStartTime); StringCchPrintfA(s_szPipe, ARRAYSIZE(s_szPipe), "%s.%d", TBLOG_PIPE_NAME, GetCurrentProcessId()); int arg = 1; for (; arg < argc && (argv[arg][0] == '-' || argv[arg][0] == '/'); arg++) { CHAR *argn = argv[arg] + 1; CHAR *argp = argn; while (*argp && *argp != ':' && *argp != '=') { argp++; } if (*argp == ':' || *argp == '=') { *argp++ = '\0'; } switch (argn[0]) { case 'd': // Drop Processes case 'D': if (*argp) { PWCHAR pwz = wzzDrop; while (*argp) { if (*argp == ';') { *pwz++ = '\0'; } else { *pwz++ = *argp++; } } *pwz++ = '\0'; *pwz = '\0'; } case 'o': // Output file. case 'O': StringCchCopyA(s_szLogFile, ARRAYSIZE(s_szLogFile), argp); break; case 'v': // Verbose case 'V': s_fVerbose = TRUE; break; case '?': // Help. fNeedHelp = TRUE; break; default: fNeedHelp = TRUE; printf("TRACEBLD: Bad argument: %s:%s\n", argn, argp); break; } } if (arg >= argc) { fNeedHelp = TRUE; } if (fNeedHelp) { printf("Usage:\n" " tracebld [options] command {command arguments}\n" "Options:\n" " /o:file Log all events to the output files.\n" " /? Display this help message.\n" "Summary:\n" " Runs the build commands and figures out which files have dependencies..\n" "\n"); exit(9001); } // Create the completion port. hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0); if (hCompletionPort == NULL) { MyErrExit("CreateIoCompletionPort"); } // Create completion port worker threads. // CreateWorkers(hCompletionPort); CreatePipeConnection(hCompletionPort, 0); printf("TRACEBLD: Ready for clients. Press Ctrl-C to stop.\n"); /////////////////////////////////////////////////////////// Validate DLLs. // CHAR szTmpPath[MAX_PATH]; CHAR szExePath[MAX_PATH]; CHAR szDllPath[MAX_PATH]; PCHAR pszFilePart = NULL; if (!GetModuleFileNameA(NULL, szTmpPath, ARRAYSIZE(szTmpPath))) { printf("TRACEBLD: Couldn't retreive exe name.\n"); return 9002; } if (!GetFullPathNameA(szTmpPath, ARRAYSIZE(szExePath), szExePath, &pszFilePart) || pszFilePart == NULL) { printf("TRACEBLD: Error: %s is not a valid path name..\n", szTmpPath); return 9002; } StringCchCopyA(pszFilePart, szExePath + ARRAYSIZE(szExePath) - pszFilePart, "trcbld" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"); StringCchCopyA(szDllPath, ARRAYSIZE(szDllPath), szExePath); ////////////////////////////////////////////////////////////////////////// STARTUPINFOA si; PROCESS_INFORMATION pi; CHAR szCommand[2048]; CHAR szExe[MAX_PATH]; CHAR szFullExe[MAX_PATH] = "\0"; PCHAR pszFileExe = NULL; ZeroMemory(&si, sizeof(si)); ZeroMemory(&pi, sizeof(pi)); si.cb = sizeof(si); szCommand[0] = L'\0'; StringCchCopyA(szExe, sizeof(szExe), argv[arg]); for (; arg < argc; arg++) { if (strchr(argv[arg], ' ') != NULL || strchr(argv[arg], '\t') != NULL) { StringCchCatA(szCommand, sizeof(szCommand), "\""); StringCchCatA(szCommand, sizeof(szCommand), argv[arg]); StringCchCatA(szCommand, sizeof(szCommand), "\""); } else { StringCchCatA(szCommand, sizeof(szCommand), argv[arg]); } if (arg + 1 < argc) { StringCchCatA(szCommand, sizeof(szCommand), " "); } } printf("TRACEBLD: Starting: `%s'\n", szCommand); printf("TRACEBLD: with `%s'\n", szDllPath); fflush(stdout); DWORD dwFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED; SetLastError(0); SearchPathA(NULL, szExe, ".exe", ARRAYSIZE(szFullExe), szFullExe, &pszFileExe); if (!DetourCreateProcessWithDllExA(szFullExe[0] ? szFullExe : NULL, szCommand, NULL, NULL, TRUE, dwFlags, NULL, NULL, &si, &pi, szDllPath, NULL)) { printf("TRACEBLD: DetourCreateProcessWithDllEx failed: %d\n", GetLastError()); ExitProcess(9007); } ZeroMemory(&s_Payload, sizeof(s_Payload)); s_Payload.nParentProcessId = GetCurrentProcessId(); s_Payload.nTraceProcessId = GetCurrentProcessId(); s_Payload.nGeneology = 1; s_Payload.rGeneology[0] = 0; StringCchCopyW(s_Payload.wzStdin, ARRAYSIZE(s_Payload.wzStdin), L"\\\\.\\CONIN$"); StringCchCopyW(s_Payload.wzStdout, ARRAYSIZE(s_Payload.wzStdout), L"\\\\.\\CONOUT$"); StringCchCopyW(s_Payload.wzStderr, ARRAYSIZE(s_Payload.wzStderr), L"\\\\.\\CONOUT$"); StringCchCopyW(s_Payload.wzParents, ARRAYSIZE(s_Payload.wzParents), L""); CopyEnvironment(s_Payload.wzzDrop, wzzDrop); LPWCH pwStrings = GetEnvironmentStringsW(); CopyEnvironment(s_Payload.wzzEnvironment, pwStrings); FreeEnvironmentStringsW(pwStrings); if (!DetourCopyPayloadToProcess(pi.hProcess, s_guidTrace, &s_Payload, sizeof(s_Payload))) { printf("TRACEBLD: DetourCopyPayloadToProcess failed: %d\n", GetLastError()); ExitProcess(9008); } ResumeThread(pi.hThread); WaitForSingleObject(pi.hProcess, INFINITE); DWORD dwResult = 0; if (!GetExitCodeProcess(pi.hProcess, &dwResult)) { printf("TRACEBLD: GetExitCodeProcess failed: %d\n", GetLastError()); return 9008; } printf("TRACEBLD: %d processes.\n", s_nTotalClients); return dwResult; }