aboutsummaryrefslogtreecommitdiffhomepage
path: root/ext/detours/samples/impmunge
diff options
context:
space:
mode:
Diffstat (limited to 'ext/detours/samples/impmunge')
-rw-r--r--ext/detours/samples/impmunge/Makefile56
-rw-r--r--ext/detours/samples/impmunge/impmunge.cpp464
2 files changed, 520 insertions, 0 deletions
diff --git a/ext/detours/samples/impmunge/Makefile b/ext/detours/samples/impmunge/Makefile
new file mode 100644
index 0000000..e320b0c
--- /dev/null
+++ b/ext/detours/samples/impmunge/Makefile
@@ -0,0 +1,56 @@
+##############################################################################
+##
+## Makefile for Detours Test Programs.
+##
+## Microsoft Research Detours Package
+##
+## Copyright (c) Microsoft Corporation. All rights reserved.
+##
+
+!include ..\common.mak
+
+LIBS=$(LIBS) kernel32.lib
+
+all: dirs \
+ $(BIND)\impmunge.exe \
+!IF $(DETOURS_SOURCE_BROWSING)==1
+ $(OBJD)\impmunge.bsc
+!ENDIF
+
+##############################################################################
+
+clean:
+ -del *~ test.exe.* 2>nul
+ -del $(BIND)\impmunge.* 2>nul
+ -rmdir /q /s $(OBJD) 2>nul
+
+realclean: clean
+ -rmdir /q /s $(OBJDS) 2>nul
+
+##############################################################################
+
+dirs:
+ @if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
+ @if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
+
+$(OBJD)\impmunge.obj : impmunge.cpp
+
+$(BIND)\impmunge.exe : $(OBJD)\impmunge.obj $(DEPS)
+ cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\impmunge.obj \
+ /link $(LINKFLAGS) $(LIBS) imagehlp.lib /subsystem:console
+
+$(OBJD)\impmunge.bsc : $(OBJD)\impmunge.obj
+ bscmake /v /n /o $@ $(OBJD)\impmunge.sbr
+
+##############################################################################
+
+test: $(BIND)\impmunge.exe
+ $(BIND)\impmunge.exe /m /o:test.exe.1 $(BIND)\impmunge.exe
+ $(BIND)\impmunge.exe /m /l- /o:test.exe.2 test.exe.1
+ $(BIND)\impmunge.exe /m /l- /o:test.exe.3 test.exe.2
+ $(BIND)\impmunge.exe /m /l- /o:test.exe.4 test.exe.3
+ $(BIND)\impmunge.exe /l test.exe.4
+ $(BIND)\impmunge.exe /r /l- /o:test.exe.0 test.exe.4
+ $(BIND)\impmunge.exe /l test.exe.0
+
+################################################################# End of File.
diff --git a/ext/detours/samples/impmunge/impmunge.cpp b/ext/detours/samples/impmunge/impmunge.cpp
new file mode 100644
index 0000000..95516dc
--- /dev/null
+++ b/ext/detours/samples/impmunge/impmunge.cpp
@@ -0,0 +1,464 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Detours Test Program (impmunge.cpp of impmunge.exe)
+//
+// Microsoft Research Detours Package
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+#pragma warning(push)
+#if _MSC_VER > 1400
+#pragma warning(disable:6102 6103) // /analyze warnings
+#endif
+#include <strsafe.h>
+#include <detours.h>
+#pragma warning(disable:4091) // empty typedef
+#include <imagehlp.h>
+#pragma warning(pop)
+
+////////////////////////////////////////////////////////////// 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 BOOLEAN s_fRestore = FALSE;
+static BOOLEAN s_fList = TRUE;
+static BOOLEAN s_fMunge = FALSE;
+static BOOLEAN s_fToSymbols = FALSE;
+
+//////////////////////////////////////////////////////////////////////////////
+//
+static BOOL CALLBACK ListByway(_In_opt_ PVOID pContext,
+ _In_opt_ LPCSTR pszFile,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutFile)
+{
+ (void)pContext;
+ (void)ppszOutFile;
+
+ printf(" byway -------------------------------- %s\n", pszFile ? pszFile : "");
+ return TRUE;
+}
+
+static BOOL CALLBACK ListFile(_In_opt_ PVOID pContext,
+ _In_ LPCSTR pszOrigFile,
+ _In_ LPCSTR pszFile,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutFile)
+{
+ (void)pContext;
+ (void)ppszOutFile;
+
+ printf(" file %-32.32s %-32.32s\n",
+ pszOrigFile ? pszOrigFile : "",
+ pszFile ? pszFile : "");
+ return TRUE;
+}
+
+static BOOL CALLBACK ListSymbol(_In_opt_ PVOID pContext,
+ _In_ ULONG nOrigOrdinal,
+ _In_ ULONG nOrdinal,
+ _Out_ ULONG *pnOutOrdinal,
+ _In_opt_ LPCSTR pszOrigSymbol,
+ _In_opt_ LPCSTR pszSymbol,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol)
+{
+ (void)pContext;
+ (void)pnOutOrdinal;
+ (void)ppszOutSymbol;
+
+ char szOrig[80];
+ char szLast[80];
+
+ if (pszOrigSymbol == NULL) {
+ StringCchPrintfA(szOrig, sizeof(szOrig), "#%d", nOrigOrdinal);
+ pszOrigSymbol = szOrig;
+ }
+ if (pszSymbol == NULL) {
+ StringCchPrintfA(szLast, sizeof(szLast), "#%d", nOrdinal);
+ pszSymbol = szLast;
+ }
+
+ printf(" symbol %-32.32s %-32.32s\n", pszOrigSymbol, pszSymbol);
+ return TRUE;
+}
+
+static BOOL CALLBACK ListCommit(PVOID pContext)
+{
+ (void)pContext;
+
+ printf(" commit\n");
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+struct MUNGE_STATE
+{
+ BOOL fLastWasByway;
+ LONG nBywayCount;
+ CHAR szBuffer[512];
+};
+
+static BOOL CALLBACK MungeByway(_In_opt_ PVOID pContext,
+ _In_opt_ LPCSTR pszFile,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutFile)
+{
+ MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
+
+ printf("|");
+
+ if (pState->fLastWasByway) {
+ return TRUE;
+ }
+
+ pState->fLastWasByway = TRUE;
+
+ if (pszFile == NULL) {
+ StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "mb_munge_%d.dll", pState->nBywayCount++);
+ *ppszOutFile = pState->szBuffer;
+ }
+ return TRUE;
+}
+
+static BOOL CALLBACK MungeFile(_In_opt_ PVOID pContext,
+ _In_ LPCSTR pszOrigFile,
+ _In_ LPCSTR pszFile,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutFile)
+{
+ (void)pszOrigFile;
+ MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
+
+ pState->fLastWasByway = FALSE;
+
+ printf("*");
+ StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "mf_%s", pszFile);
+ *ppszOutFile = pState->szBuffer;
+ return TRUE;
+}
+
+static BOOL CALLBACK MungeSymbol(_In_opt_ PVOID pContext,
+ _In_ ULONG nOrigOrdinal,
+ _In_ ULONG nOrdinal,
+ _Out_ ULONG *pnOutOrdinal,
+ _In_opt_ LPCSTR pszOrigSymbol,
+ _In_opt_ LPCSTR pszSymbol,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol)
+{
+ (void)nOrigOrdinal;
+ (void)pszOrigSymbol;
+ MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
+
+ pState->fLastWasByway = FALSE;
+
+ printf(".");
+ if (nOrdinal != 0) {
+ if (s_fToSymbols) {
+ StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "mo_%d", (int)nOrdinal);
+ *pnOutOrdinal = 0;
+ *ppszOutSymbol = pState->szBuffer;
+ }
+ else {
+ *pnOutOrdinal = 10000 + nOrdinal;
+ *ppszOutSymbol = NULL;
+ }
+ }
+ else {
+ StringCchPrintfA(pState->szBuffer, sizeof(pState->szBuffer), "ms_%s", pszSymbol);
+ *pnOutOrdinal = 0;
+ *ppszOutSymbol = pState->szBuffer;
+ }
+ return TRUE;
+}
+
+static BOOL CALLBACK MungeCommit(PVOID pContext)
+{
+ MUNGE_STATE *pState = (MUNGE_STATE *)pContext;
+
+ pState->fLastWasByway = FALSE;
+
+ printf("\n");
+ (void)pContext;
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+static BOOL CALLBACK RestoreByway(_In_opt_ PVOID pContext,
+ _In_opt_ LPCSTR pszFile,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutFile)
+{
+ (void)pContext;
+ (void)pszFile;
+
+ *ppszOutFile = NULL;
+ return TRUE;
+}
+
+static BOOL CALLBACK RestoreFile(_In_opt_ PVOID pContext,
+ _In_ LPCSTR pszOrigFile,
+ _In_ LPCSTR pszFile,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutFile)
+{
+ (void)pContext;
+ (void)pszFile;
+
+ *ppszOutFile = pszOrigFile;
+ return TRUE;
+}
+
+static BOOL CALLBACK RestoreSymbol(_In_opt_ PVOID pContext,
+ _In_ ULONG nOrigOrdinal,
+ _In_ ULONG nOrdinal,
+ _Out_ ULONG *pnOutOrdinal,
+ _In_opt_ LPCSTR pszOrigSymbol,
+ _In_opt_ LPCSTR pszSymbol,
+ _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol)
+{
+ (void)pContext;
+ (void)nOrdinal;
+ (void)pszSymbol;
+
+ *pnOutOrdinal = nOrigOrdinal;
+ *ppszOutSymbol = pszOrigSymbol;
+ return TRUE;
+}
+
+static BOOL CALLBACK RestoreCommit(PVOID pContext)
+{
+ (void)pContext;
+ return TRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+
+BOOL EditFile(PCHAR pszInput, PCHAR pszOutput)
+{
+ BOOL fGood = TRUE;
+
+ HANDLE hOld = INVALID_HANDLE_VALUE;
+ HANDLE hNew = INVALID_HANDLE_VALUE;
+ PDETOUR_BINARY pBinary = NULL;
+
+ if (pszOutput != NULL) {
+ printf("%s -> %s:\n", pszInput, pszOutput);
+ }
+ else {
+ printf("%s:\n", pszInput);
+ }
+
+ hOld = CreateFileA(pszInput,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hOld == INVALID_HANDLE_VALUE) {
+ printf("Couldn't open input file: %s, error: %ld\n",
+ pszInput, GetLastError());
+ fGood = FALSE;
+ goto end;
+ }
+
+ if ((pBinary = DetourBinaryOpen(hOld)) == NULL) {
+ printf("DetourBinaryOpen failed: %ld\n", GetLastError());
+ goto end;
+ }
+
+ if (hOld != INVALID_HANDLE_VALUE) {
+ CloseHandle(hOld);
+ hOld = INVALID_HANDLE_VALUE;
+ }
+
+ if (s_fRestore) {
+ if (!DetourBinaryEditImports(pBinary,
+ NULL,
+ RestoreByway,
+ RestoreFile,
+ RestoreSymbol,
+ RestoreCommit)) {
+
+ printf("DetourBinaryEditImports for munge failed: %ld\n", GetLastError());
+ }
+ }
+
+ if (s_fMunge) {
+ MUNGE_STATE state;
+ state.fLastWasByway = FALSE;
+ state.nBywayCount = 1;
+
+ if (!DetourBinaryEditImports(pBinary,
+ &state,
+ MungeByway,
+ MungeFile,
+ MungeSymbol,
+ MungeCommit)) {
+
+ printf("DetourBinaryEditImports for munge failed: %ld\n", GetLastError());
+ }
+ }
+
+ if (s_fList) {
+ if (!DetourBinaryEditImports(pBinary,
+ NULL,
+ ListByway,
+ ListFile,
+ ListSymbol,
+ ListCommit)) {
+
+ printf("DetourBinaryEditImports for list failed: %ld\n", GetLastError());
+ }
+ }
+
+ if (pszOutput != NULL) {
+ hNew = CreateFileA(pszOutput,
+ GENERIC_WRITE | GENERIC_READ, 0, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
+ if (hNew == INVALID_HANDLE_VALUE) {
+ printf("Couldn't open output file: %s, error: %ld\n",
+ pszOutput, GetLastError());
+ fGood = FALSE;
+ goto end;
+ }
+
+ if (!DetourBinaryWrite(pBinary, hNew)) {
+ printf("DetourBinaryWrite failed: %ld\n", GetLastError());
+ fGood = FALSE;
+ }
+
+ CloseHandle(hNew);
+ hNew = INVALID_HANDLE_VALUE;
+ }
+
+ DetourBinaryClose(pBinary);
+ pBinary = NULL;
+
+
+ if (fGood && pszOutput != NULL) {
+ if (!BindImageEx(BIND_NO_BOUND_IMPORTS, pszOutput, ".", ".", NULL)) {
+ printf("Warning: Couldn't bind binary %s: %ld\n", pszOutput, GetLastError());
+ }
+ }
+
+ end:
+ if (pBinary) {
+ DetourBinaryClose(pBinary);
+ pBinary = NULL;
+ }
+ if (hNew != INVALID_HANDLE_VALUE) {
+ CloseHandle(hNew);
+ hNew = INVALID_HANDLE_VALUE;
+ }
+ if (hOld != INVALID_HANDLE_VALUE) {
+ CloseHandle(hOld);
+ hOld = INVALID_HANDLE_VALUE;
+ }
+ return fGood;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void PrintUsage(void)
+{
+ printf("Usage:\n"
+ " impmunge [options] binary_files\n"
+ "Options:\n"
+ " /l : List imports.\n"
+ " /l- : Don't list imports.\n"
+ " /m : Munge imports.\n"
+ " /r : Remove import munges.\n"
+ " /o:file : Set name of output file; must be include with /m or /r.\n"
+ " /? : This help screen.\n");
+}
+
+//////////////////////////////////////////////////////////////////////// main.
+//
+int CDECL main(int argc, char **argv)
+{
+ BOOL fNeedHelp = FALSE;
+ PCHAR pszOutput = NULL;
+
+ int arg = 1;
+ for (; arg < argc && !fNeedHelp; 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 'l': // List contents of import table.
+ case 'L':
+ s_fList = (argn[1] != '-');
+ break;
+
+ case 'm': // Munge import table.
+ case 'M':
+ s_fMunge = (argn[1] != '-');
+ break;
+
+ case 'o': // Set output file name.
+ case 'O':
+ pszOutput = argp;
+ break;
+ case 'r': // Restore file to unmunged state.
+ case 'R':
+ s_fRestore = (argn[1] != '-');
+ break;
+
+ case 's': // Munge ordinals to symbols
+ case 'S':
+ s_fToSymbols = true;
+ break;
+
+ case '?': // Help
+ fNeedHelp = TRUE;
+ break;
+
+ default:
+ fNeedHelp = TRUE;
+ printf("Bad argument: %s:%s\n", argn, argp);
+ break;
+ }
+ }
+ else {
+ if (!s_fList && !s_fMunge && !s_fRestore) {
+ fNeedHelp = TRUE;
+ break;
+ }
+ if (pszOutput == NULL && (s_fMunge || s_fRestore)) {
+ fNeedHelp = TRUE;
+ break;
+ }
+
+ EditFile(argv[arg], pszOutput);
+ pszOutput = NULL;
+ }
+ }
+ if (argc == 1) {
+ fNeedHelp = TRUE;
+ }
+ if (fNeedHelp) {
+ PrintUsage();
+ return 1;
+ }
+ return 0;
+}
+
+// End of File