Exemple #1
0
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;
}