int _tmain(int argc, _TCHAR* argv[]) { // This sample will take path to the executable which will invoke GetVersionEx // so that our detoured function will return them our custom version details if (argc != 5) { // Usage is: // // ForceVersion <path> <major ver> <minor ver> <build #> // // For e.g. // // ForceVersion c:\app.exe 4 1 2000 // // will return OS version as 4.1.2000 when the application calls GetVersionEx API printf("ForceVersion - returns a user defined OS version details to application\n"); printf("by Gaurav Khanna - http://www.wintoolzone.com/\n\n"); printf("Usage:\n\nForceVersion <app path> <major ver> <minor ver> <build #>\nwhere:\n"); printf("\t<app path> - path to the executable which will request OS version\n"); printf("\t<major ver> - OS major version to be returned to calling applications\n"); printf("\t<minor ver> - OS minor version to be returned to calling applications\n"); printf("\t<build #> - OS build version to be returned to calling applications\n"); return 0; } // Get the version details VersionPayLoad payload; payload.iMajor = atoi(argv[2]); payload.iMinor = atoi(argv[3]); payload.iBuild = atoi(argv[4]); // Now, we will ask Detours to launch this executable and load our DetourDLL into the process STARTUPINFO startup; memset(&startup, 0, sizeof(startup)); PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(pi)); startup.cb = sizeof(startup); // init the buffer that will hold the current working folder of the application TCHAR tCurDir[MAX_PATH]; memset(tCurDir,0, sizeof(tCurDir)); DWORD dwCount = GetCurrentDirectory(MAX_PATH,tCurDir); if (!dwCount) { printf("Unable to get the working folder!"); return -1; } // Form the paths to the DETOURED.DLL and our Detouring DLL TCHAR szDetouredPath[MAX_PATH]; memset(szDetouredPath, 0, sizeof(szDetouredPath)); TCHAR szInjectDLLPath[MAX_PATH]; memset(szInjectDLLPath, 0, sizeof(szInjectDLLPath)); if (FormPath(szDetouredPath, tCurDir, _TEXT("detoured.dll")) == FALSE) { printf("Unable to form path to DETOURED.DLL!\n"); return -1; } if (FormPath(szInjectDLLPath, tCurDir, _TEXT("ForceVersionDLL.dll")) == FALSE) { printf("Unable to form path to Injection DLL!\n"); return -1; } // We create the process as suspended since we will copy payload // to the target process containing the versions we want it to get BOOL fLaunchApp = DetourCreateProcessWithDll(argv[1], 0,0,0,TRUE,CREATE_SUSPENDED|CREATE_DEFAULT_ERROR_MODE,0,0,&startup,&pi, szDetouredPath, szInjectDLLPath, NULL); if (!fLaunchApp) { printf("Error: %d\n",GetLastError()); return -1; } // Send the payload data... BOOL fRetVal = DetourCopyPayloadToProcess(pi.hProcess, my_guid, (PVOID)&payload, sizeof(payload)); if (!fRetVal) { printf("Unable to write version information in the target process!"); return -1; } // Resume thread and wait on the process.. ResumeThread(pi.hThread); WaitForSingleObject(pi.hProcess, INFINITE); return 0; }
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; }