335 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			335 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| //  Detours Test Program (tstman.cpp of tstman.dll)
 | |
| //
 | |
| //  Microsoft Research Detours Package
 | |
| //
 | |
| //  Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| //
 | |
| //  This DLL doesn't detour any APIs, but it does enumerate the modules
 | |
| //  loaded in a process and look at their size and processor target.
 | |
| //
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <windows.h>
 | |
| #pragma warning(push)
 | |
| #if _MSC_VER > 1400
 | |
| #pragma warning(disable:6102 6103) // /analyze warnings
 | |
| #endif
 | |
| #include <strsafe.h>
 | |
| #pragma warning(pop)
 | |
| #include "detours.h"
 | |
| 
 | |
| static HMODULE s_hInst = NULL;
 | |
| static CHAR s_szDllPath[MAX_PATH];
 | |
| 
 | |
| static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
 | |
| static int (WINAPI * RawEntryPoint)(VOID) = NULL;
 | |
| 
 | |
| BOOL (WINAPI * Real_CreateProcessA)(LPCSTR a0,
 | |
|                                     LPSTR a1,
 | |
|                                     LPSECURITY_ATTRIBUTES a2,
 | |
|                                     LPSECURITY_ATTRIBUTES a3,
 | |
|                                     BOOL a4,
 | |
|                                     DWORD a5,
 | |
|                                     LPVOID a6,
 | |
|                                     LPCSTR a7,
 | |
|                                     struct _STARTUPINFOA* a8,
 | |
|                                     LPPROCESS_INFORMATION a9)
 | |
|     = CreateProcessA;
 | |
| 
 | |
| BOOL (WINAPI * Real_CreateProcessW)(LPCWSTR a0,
 | |
|                                     LPWSTR a1,
 | |
|                                     LPSECURITY_ATTRIBUTES a2,
 | |
|                                     LPSECURITY_ATTRIBUTES a3,
 | |
|                                     BOOL a4,
 | |
|                                     DWORD a5,
 | |
|                                     LPVOID a6,
 | |
|                                     LPCWSTR a7,
 | |
|                                     struct _STARTUPINFOW* a8,
 | |
|                                     LPPROCESS_INFORMATION a9)
 | |
|     = CreateProcessW;
 | |
| 
 | |
| 
 | |
| BOOL WINAPI Mine_CreateProcessA(LPCSTR lpApplicationName,
 | |
|                                 LPSTR lpCommandLine,
 | |
|                                 LPSECURITY_ATTRIBUTES lpProcessAttributes,
 | |
|                                 LPSECURITY_ATTRIBUTES lpThreadAttributes,
 | |
|                                 BOOL bInheritHandles,
 | |
|                                 DWORD dwCreationFlags,
 | |
|                                 LPVOID lpEnvironment,
 | |
|                                 LPCSTR lpCurrentDirectory,
 | |
|                                 LPSTARTUPINFOA lpStartupInfo,
 | |
|                                 LPPROCESS_INFORMATION lpProcessInformation)
 | |
| {
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = DetourCreateProcessWithDllExA(lpApplicationName,
 | |
|                                            lpCommandLine,
 | |
|                                            lpProcessAttributes,
 | |
|                                            lpThreadAttributes,
 | |
|                                            bInheritHandles,
 | |
|                                            dwCreationFlags,
 | |
|                                            lpEnvironment,
 | |
|                                            lpCurrentDirectory,
 | |
|                                            lpStartupInfo,
 | |
|                                            lpProcessInformation,
 | |
|                                            s_szDllPath,
 | |
|                                            Real_CreateProcessA);
 | |
|     } __finally {
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| BOOL WINAPI Mine_CreateProcessW(LPCWSTR lpApplicationName,
 | |
|                                 LPWSTR lpCommandLine,
 | |
|                                 LPSECURITY_ATTRIBUTES lpProcessAttributes,
 | |
|                                 LPSECURITY_ATTRIBUTES lpThreadAttributes,
 | |
|                                 BOOL bInheritHandles,
 | |
|                                 DWORD dwCreationFlags,
 | |
|                                 LPVOID lpEnvironment,
 | |
|                                 LPCWSTR lpCurrentDirectory,
 | |
|                                 LPSTARTUPINFOW lpStartupInfo,
 | |
|                                 LPPROCESS_INFORMATION lpProcessInformation)
 | |
| {
 | |
|     BOOL rv = 0;
 | |
|     __try {
 | |
|         rv = DetourCreateProcessWithDllExW(lpApplicationName,
 | |
|                                            lpCommandLine,
 | |
|                                            lpProcessAttributes,
 | |
|                                            lpThreadAttributes,
 | |
|                                            bInheritHandles,
 | |
|                                            dwCreationFlags,
 | |
|                                            lpEnvironment,
 | |
|                                            lpCurrentDirectory,
 | |
|                                            lpStartupInfo,
 | |
|                                            lpProcessInformation,
 | |
|                                            s_szDllPath,
 | |
|                                            Real_CreateProcessW);
 | |
|     } __finally {
 | |
|     };
 | |
|     return rv;
 | |
| }
 | |
| 
 | |
| void DumpModuleInfo(HMODULE hModule)
 | |
| {
 | |
|     PBYTE pbModule = (PBYTE)hModule;
 | |
|     PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)pbModule;
 | |
|     PIMAGE_NT_HEADERS pinh = (PIMAGE_NT_HEADERS)(pbModule + pidh->e_lfanew);
 | |
|     CHAR szFile[MAX_PATH] = "";
 | |
| 
 | |
|     GetModuleFileNameA(hModule, szFile, sizeof(szFile));
 | |
| 
 | |
|     CHAR szMagic[64];
 | |
|     CHAR szMachine[64];
 | |
|     CHAR szClr[64];
 | |
| 
 | |
|     PIMAGE_DATA_DIRECTORY pdir
 | |
|         = (pinh->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
 | |
|         ? ((PIMAGE_NT_HEADERS32)pinh)->OptionalHeader.DataDirectory
 | |
|         : ((PIMAGE_NT_HEADERS64)pinh)->OptionalHeader.DataDirectory;
 | |
| 
 | |
|     if (pdir[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != 0 &&
 | |
|         pdir[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size != 0) {
 | |
| 
 | |
|         PDETOUR_CLR_HEADER pch
 | |
|             = (PDETOUR_CLR_HEADER)
 | |
|             (pbModule + pdir[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress);
 | |
| 
 | |
|         if ((pch->Flags & 0x3) == 0x0) {
 | |
|             StringCchPrintfA(szClr, ARRAYSIZE(szClr), "clr   ");   // 32- or 64-bit.
 | |
|         }
 | |
|         else if ((pch->Flags & 0x3) == 0x1) {
 | |
|             StringCchPrintfA(szClr, ARRAYSIZE(szClr), "clri  ");   // IL-Only, 32- or 64-bit.
 | |
|         }
 | |
|         else if ((pch->Flags & 0x3) == 0x2) {
 | |
|             StringCchPrintfA(szClr, ARRAYSIZE(szClr), "clr32 ");   // must be 32-bit.
 | |
|         }
 | |
|         else if ((pch->Flags & 0x3) == 0x3) {
 | |
|             StringCchPrintfA(szClr, ARRAYSIZE(szClr), "clr32i");   // IL-Only, must be 32-bit.
 | |
|         }
 | |
|     }
 | |
|     else {
 | |
|         StringCchPrintfA(szClr, ARRAYSIZE(szClr), "      ");
 | |
|     }
 | |
| 
 | |
|     if (pinh->OptionalHeader.Magic == 0x10b) {
 | |
|         StringCchPrintfA(szMagic, ARRAYSIZE(szMagic), "32");
 | |
|     }
 | |
|     else if (pinh->OptionalHeader.Magic == 0x20b) {
 | |
|         StringCchPrintfA(szMagic, ARRAYSIZE(szMagic), "64");
 | |
|     }
 | |
|     else {
 | |
|         StringCchPrintfA(szMagic, ARRAYSIZE(szMagic), "??");
 | |
|     }
 | |
| 
 | |
|     if (pinh->FileHeader.Machine == 0x8664) {
 | |
|         StringCchPrintfA(szMachine, ARRAYSIZE(szMachine), "x64", pinh->FileHeader.Machine);
 | |
|     }
 | |
|     else if (pinh->FileHeader.Machine == 0x014c) {
 | |
|         StringCchPrintfA(szMachine, ARRAYSIZE(szMachine), "x86", pinh->FileHeader.Machine);
 | |
|     }
 | |
|     else if (pinh->FileHeader.Machine == 0x0200) {
 | |
|         StringCchPrintfA(szMachine, ARRAYSIZE(szMachine), "i64", pinh->FileHeader.Machine);
 | |
|     }
 | |
|     else if (pinh->FileHeader.Machine == 0x01c0) {
 | |
|         StringCchPrintfA(szMachine, ARRAYSIZE(szMachine), "arm", pinh->FileHeader.Machine);
 | |
|     }
 | |
|     else {
 | |
|         StringCchPrintfA(szMachine, ARRAYSIZE(szMachine), "%04x", pinh->FileHeader.Machine);
 | |
|         DWORD dwSize = DetourGetSizeOfPayloads(hModule);
 | |
|         if (dwSize > 0) {
 | |
|             StringCchPrintfA(szMachine, ARRAYSIZE(szMachine), "     ");
 | |
|             StringCchPrintfA(szFile, ARRAYSIZE(szFile), "-- %d byte payload.", dwSize);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     printf("%16I64x: %s %s %s %s\n", (ULONG64)hModule, szMagic, szMachine, szClr, szFile);
 | |
| }
 | |
| 
 | |
| void DumpMemory(PBYTE pbData, DWORD cbData)
 | |
| {
 | |
|     for (DWORD i = 0; i < cbData; i += 16) {
 | |
|         printf("  %p:", pbData + i);
 | |
|         for (DWORD j = 0; j < 16; j++) {
 | |
|             if (i + j < cbData) {
 | |
|                 printf("%02x", pbData[i+j]);
 | |
|             }
 | |
|             else {
 | |
|                 printf("  ");
 | |
|             }
 | |
|         }
 | |
|         printf(" ");
 | |
|         for (DWORD j = 0; j < 16; j++) {
 | |
|             if (i + j < cbData) {
 | |
|                 if ( pbData[i+j] >= ' ' && pbData[i+j] < 127) {
 | |
|                     printf("%c", pbData[i+j]);
 | |
|                 }
 | |
|                 else {
 | |
|                     printf(".");
 | |
|                 }
 | |
|             }
 | |
|             else {
 | |
|                 printf(" ");
 | |
|             }
 | |
|         }
 | |
|         printf("\n");
 | |
|     }
 | |
| }
 | |
| 
 | |
| int WINAPI Test3264(int arg)
 | |
| {
 | |
|     return arg + 1;
 | |
| }
 | |
| 
 | |
| int WINAPI TestEntryPoint(VOID)
 | |
| {
 | |
| #if DETOURS_64BIT
 | |
|     printf("----------------: ");
 | |
| #else
 | |
|     printf("--------: ");
 | |
| #endif
 | |
| 
 | |
|     printf("Calling EntryPoint() from detour.\n");
 | |
|     fflush(stdout);
 | |
| 
 | |
|     return TrueEntryPoint();
 | |
| }
 | |
| 
 | |
| BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
 | |
| {
 | |
|     (void)hinst;
 | |
|     (void)reserved;
 | |
| 
 | |
|     if (DetourIsHelperProcess()) {
 | |
|         return TRUE;
 | |
|     }
 | |
| 
 | |
|     if (dwReason == DLL_PROCESS_ATTACH) {
 | |
|         DetourRestoreAfterWith();
 | |
| 
 | |
|         s_hInst = hinst;
 | |
|         GetModuleFileNameA(s_hInst, s_szDllPath, ARRAYSIZE(s_szDllPath));
 | |
| 
 | |
| #if DETOURS_64BIT
 | |
|         printf("----------------: ");
 | |
| #else
 | |
|         printf("--------: ");
 | |
| #endif
 | |
| 
 | |
|         SYSTEM_INFO si;
 | |
|         GetSystemInfo(&si);
 | |
| 
 | |
|         if (si.wProcessorArchitecture == 9) {
 | |
|             printf("x64 Processor\n");
 | |
|         }
 | |
|         else if (si.wProcessorArchitecture == 0) {
 | |
|             printf("x86 Processor\n");
 | |
|         }
 | |
|         else if (si.wProcessorArchitecture == 6) {
 | |
|             printf("ia64 Processor\n");
 | |
|         }
 | |
|         else {
 | |
|             printf("%04x Processor\n", si.wProcessorArchitecture);
 | |
|         }
 | |
| 
 | |
|         HMODULE hSelf = GetModuleHandle(NULL);
 | |
|         HMODULE hTest = (HMODULE)DetourGetContainingModule(DetourCodeFromPointer(Test3264, NULL));
 | |
|         HMODULE hKern = (HMODULE)DetourGetContainingModule(DetourCodeFromPointer(CreateProcessW, NULL));
 | |
| 
 | |
|         DumpModuleInfo(hSelf);
 | |
|         DumpModuleInfo(hTest);
 | |
|         DumpModuleInfo(hKern);
 | |
|         for (HINSTANCE hInst = NULL; (hInst = DetourEnumerateModules(hInst)) != NULL;) {
 | |
|             if (hInst == hSelf || hInst == hTest || hInst == hKern) {
 | |
|                 continue;
 | |
|             }
 | |
| 
 | |
|             DumpModuleInfo(hInst);
 | |
|         }
 | |
|         fflush(stdout);
 | |
| 
 | |
|         TrueEntryPoint = (int (WINAPI *)(VOID))DetourGetEntryPoint(NULL);
 | |
|         RawEntryPoint = TrueEntryPoint;
 | |
| 
 | |
|         DetourTransactionBegin();
 | |
|         DetourUpdateThread(GetCurrentThread());
 | |
|         DetourAttach(&(PVOID&)TrueEntryPoint, TestEntryPoint);
 | |
|         DetourAttach(&(PVOID&)Real_CreateProcessA, Mine_CreateProcessA);
 | |
|         DetourAttach(&(PVOID&)Real_CreateProcessW, Mine_CreateProcessW);
 | |
|         LONG error = DetourTransactionCommit();
 | |
| 
 | |
| #if DETOURS_64BIT
 | |
|         printf("----------------: ");
 | |
| #else
 | |
|         printf("--------: ");
 | |
| #endif
 | |
| 
 | |
|         if (error == NO_ERROR) {
 | |
|             printf("Detoured EntryPoint().\n");
 | |
|         }
 | |
|         else {
 | |
|             printf("Error detouring EntryPoint(): %ld (@ %p)\n", error, RawEntryPoint);
 | |
|             __debugbreak();
 | |
|         }
 | |
|     }
 | |
|     else if (dwReason == DLL_PROCESS_DETACH) {
 | |
| 
 | |
|         DetourTransactionBegin();
 | |
|         DetourUpdateThread(GetCurrentThread());
 | |
|         DetourDetach(&(PVOID&)TrueEntryPoint, TestEntryPoint);
 | |
|         DetourDetach(&(PVOID&)Real_CreateProcessA, Mine_CreateProcessA);
 | |
|         DetourDetach(&(PVOID&)Real_CreateProcessW, Mine_CreateProcessW);
 | |
|         LONG error = DetourTransactionCommit();
 | |
| 
 | |
|         if (error != NO_ERROR) {
 | |
|             printf("Error detach detours failed: %ld\n", error);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| //
 | |
| ///////////////////////////////////////////////////////////////// End of File.
 |