271 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| //  Detours Test Program (dumpi.cpp of dumpi.exe)
 | |
| //
 | |
| //  Microsoft Research Detours Package
 | |
| //
 | |
| //  Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| //
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <windows.h>
 | |
| #include <shellapi.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>
 | |
| 
 | |
| ////////////////////////////////////////////////////////////// Error Messages.
 | |
| //
 | |
| VOID AssertMessage(PCSTR szMsg, PCSTR szFile, DWORD nLine)
 | |
| {
 | |
|     printf("ASSERT(%s) failed in %s, line %ld.", szMsg, szFile, nLine);
 | |
| }
 | |
| 
 | |
| #define ASSERT(x)   \
 | |
| do { if (!(x)) { AssertMessage(#x, __FILE__, __LINE__); DebugBreak(); }} while (0)
 | |
|     ;
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| static CHAR s_szFile[MAX_PATH] = "\0";
 | |
| 
 | |
| static BOOL CALLBACK ListFileCallback(_In_opt_ PVOID pContext,
 | |
|                                       _In_z_ LPCSTR pszOrigFile,
 | |
|                                       _In_z_ LPCSTR pszFile,
 | |
|                                       _Outptr_result_maybenull_ LPCSTR *ppszOutFile)
 | |
| {
 | |
|     (void)pContext;
 | |
|     (void)pszFile;
 | |
| 
 | |
|     *ppszOutFile = NULL;
 | |
| 
 | |
|     StringCchCopyA(s_szFile, sizeof(s_szFile), pszOrigFile);
 | |
| 
 | |
|     PCHAR psz;
 | |
|     if ((psz = strchr(s_szFile, '.')) != NULL) {
 | |
|         *psz = '\0';
 | |
|     }
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| BOOL CALLBACK ListSymbolCallback(_In_opt_ PVOID pContext,
 | |
|                                  _In_ ULONG nOrigOrdinal,
 | |
|                                  _In_ ULONG nOrdinal,
 | |
|                                  _Out_ ULONG *pnOutOrdinal,
 | |
|                                  _In_opt_z_ LPCSTR pszOrigSymbol,
 | |
|                                  _In_opt_z_ LPCSTR pszSymbol,
 | |
|                                  _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol)
 | |
| {
 | |
|     (void)pContext;
 | |
|     (void)nOrdinal;
 | |
|     (void)pszSymbol;
 | |
| 
 | |
|     *ppszOutSymbol = NULL;
 | |
|     *pnOutOrdinal = 0;
 | |
| 
 | |
|     if (nOrigOrdinal != 0) {
 | |
|         printf("  %s::#%ld\n",
 | |
|                s_szFile, nOrigOrdinal);
 | |
|     }
 | |
|     else {
 | |
|         printf("  %s::%s\n",
 | |
|                s_szFile, pszOrigSymbol);
 | |
|     }
 | |
| 
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| BOOL DimpFile(PCHAR pszPath)
 | |
| {
 | |
|     BOOL bGood = TRUE;
 | |
|     HANDLE hOld = INVALID_HANDLE_VALUE;
 | |
|     PDETOUR_BINARY pBinary = NULL;
 | |
| 
 | |
| 
 | |
|     hOld = CreateFileA(pszPath,
 | |
|                        GENERIC_READ,
 | |
|                        FILE_SHARE_READ,
 | |
|                        NULL,
 | |
|                        OPEN_EXISTING,
 | |
|                        FILE_ATTRIBUTE_NORMAL,
 | |
|                        NULL);
 | |
| 
 | |
|     if (hOld == INVALID_HANDLE_VALUE) {
 | |
|         printf("%s: Failed to open input file with error: %ld\n",
 | |
|                pszPath, GetLastError());
 | |
|         bGood = FALSE;
 | |
|         goto end;
 | |
|     }
 | |
| 
 | |
|     if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
 | |
|         printf("%s: DetourBinaryOpen failed: %ld\n", pszPath, GetLastError());
 | |
|         goto end;
 | |
|     }
 | |
| 
 | |
|     if (hOld != INVALID_HANDLE_VALUE) {
 | |
|         CloseHandle(hOld);
 | |
|         hOld = INVALID_HANDLE_VALUE;
 | |
|     }
 | |
| 
 | |
|     printf("%s:\n", pszPath);
 | |
|     if (!DetourBinaryEditImports(pBinary,
 | |
|                                  NULL,
 | |
|                                  NULL,
 | |
|                                  ListFileCallback,
 | |
|                                  ListSymbolCallback,
 | |
|                                  NULL)) {
 | |
| 
 | |
|         printf("%s: DetourBinaryEditImports failed: %ld\n", pszPath, GetLastError());
 | |
|     }
 | |
| 
 | |
|     DetourBinaryClose(pBinary);
 | |
|     pBinary = NULL;
 | |
| 
 | |
|   end:
 | |
|     if (pBinary) {
 | |
|         DetourBinaryClose(pBinary);
 | |
|         pBinary = NULL;
 | |
|     }
 | |
|     if (hOld != INVALID_HANDLE_VALUE) {
 | |
|         CloseHandle(hOld);
 | |
|         hOld = INVALID_HANDLE_VALUE;
 | |
|     }
 | |
|     return bGood;
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| int DimpArgument(char *dir, char *argp, int fDoSubs)
 | |
| {
 | |
|     //////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
|     WIN32_FIND_DATAA wfd;
 | |
|     HANDLE  hFind = NULL;
 | |
|     char    name[1024];
 | |
|     int     nFound = 0;
 | |
| 
 | |
|     StringCchCopyA(name, sizeof(name), dir ? dir : "");
 | |
|     StringCchCatA(name, sizeof(name), argp);
 | |
| 
 | |
|     hFind = FindFirstFileA(name, &wfd);
 | |
|     if (hFind != INVALID_HANDLE_VALUE) {
 | |
|         do {
 | |
|             if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
 | |
|                 StringCchCopyA(name, sizeof(name), dir ? dir : "");
 | |
|                 StringCchCatA(name, sizeof(name), wfd.cFileName);
 | |
| 
 | |
|                 nFound += DimpFile(name);
 | |
|             }
 | |
|         } while (FindNextFileA(hFind, &wfd));
 | |
|         FindClose(hFind);
 | |
|     }
 | |
| 
 | |
|     if (fDoSubs) {
 | |
|         StringCchCopyA(name, sizeof(name), dir ? dir : "");
 | |
|         StringCchCatA(name, sizeof(name), "*");
 | |
| 
 | |
|         hFind = FindFirstFileA(name, &wfd);
 | |
|         if (hFind == INVALID_HANDLE_VALUE)
 | |
|             return nFound;
 | |
| 
 | |
|         do {
 | |
|             if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
 | |
|                 wfd.cFileName[0] != '.') {
 | |
| 
 | |
|                 StringCchCopyA(name, sizeof(name), dir ? dir : "");
 | |
|                 StringCchCatA(name, sizeof(name), wfd.cFileName);
 | |
|                 StringCchCatA(name, sizeof(name), "\\");
 | |
| 
 | |
|                 nFound += DimpArgument(name, argp, fDoSubs);
 | |
|             }
 | |
|         } while (FindNextFileA(hFind, &wfd));
 | |
|         FindClose(hFind);
 | |
|     }
 | |
|     return nFound;
 | |
| }
 | |
| 
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| void PrintUsage(void)
 | |
| {
 | |
|     printf("Usage:\n"
 | |
|            "    dimp [options] binary_files\n"
 | |
|            "Options:\n"
 | |
|            "    /s           : Recurse through subdirectories.\n"
 | |
|            "    /?           : This help screen.\n"
 | |
|            "Examples:\n"
 | |
|            "    dimp /s *.exe\n"
 | |
|            "");
 | |
| }
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////// main.
 | |
| //
 | |
| int CDECL main(int argc, char **argv)
 | |
| {
 | |
|     BOOL fNeedHelp = FALSE;
 | |
|     BOOL fSubdirs = FALSE;
 | |
| 
 | |
|     int arg = 1;
 | |
|     for (; arg < argc; arg++) {
 | |
|         if (argv[arg][0] == '-' || argv[arg][0] == '/') {
 | |
|             CHAR *argn = argv[arg] + 1;
 | |
|             CHAR *argp = argn;
 | |
|             while (*argp && *argp != ':')
 | |
|                 argp++;
 | |
|             if (*argp == ':')
 | |
|                 *argp++ = '\0';
 | |
| 
 | |
|             switch (argn[0]) {
 | |
| 
 | |
|               case 's':                                 // Do Subdirectories.
 | |
|               case 'S':
 | |
|                 fSubdirs = TRUE;
 | |
|                 break;
 | |
| 
 | |
|               case '?':                                 // Help.
 | |
|                 fNeedHelp = TRUE;
 | |
|                 break;
 | |
| 
 | |
|               default:
 | |
|                 fNeedHelp = TRUE;
 | |
|                 printf("Bad argument: %s:%s\n", argn, argp);
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|         else {
 | |
|             CHAR szDir[MAX_PATH] = "";
 | |
|             CHAR szArg[MAX_PATH] = "";
 | |
|             PCHAR pszDir;
 | |
| 
 | |
|             if ((pszDir = strrchr(argv[arg], '\\')) != NULL) {
 | |
|                 *pszDir++ = '\0';
 | |
|                 StringCchCopyA(szArg, sizeof(szArg), pszDir);
 | |
|                 StringCchCopyA(szDir, sizeof(szDir), argv[arg]);
 | |
|                 StringCchCatA(szDir, sizeof(szDir), "\\");
 | |
|             }
 | |
|             else {
 | |
|                 if (GetCurrentDirectoryA(sizeof(szDir), szDir) > 3) {
 | |
|                     StringCchCatA(szDir, sizeof(szDir), "\\");
 | |
|                 }
 | |
|                 StringCchCopyA(szArg, sizeof(szArg), argv[arg]);
 | |
|             }
 | |
| 
 | |
|             DimpArgument(szDir, szArg, fSubdirs);
 | |
|         }
 | |
|     }
 | |
|     if (argc == 1) {
 | |
|         fNeedHelp = TRUE;
 | |
|     }
 | |
|     if (fNeedHelp) {
 | |
|         PrintUsage();
 | |
|         return 1;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| // End of File
 |