ZLUDA/ext/detours/samples/dumpi/dumpi.cpp

270 lines
7.4 KiB
C++
Vendored

//////////////////////////////////////////////////////////////////////////////
//
// 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