////////////////////////////////////////////////////////////////////////////// // // Detours Test Program (dumpi.cpp of dumpi.exe) // // Microsoft Research Detours Package // // Copyright (c) Microsoft Corporation. All rights reserved. // #include #include #include #include #pragma warning(push) #if _MSC_VER > 1400 #pragma warning(disable:6102 6103) // /analyze warnings #endif #include #pragma warning(pop) #include ////////////////////////////////////////////////////////////// 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