aboutsummaryrefslogtreecommitdiffhomepage
path: root/ext/detours/samples/findfunc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/detours/samples/findfunc')
-rw-r--r--ext/detours/samples/findfunc/Makefile178
-rw-r--r--ext/detours/samples/findfunc/extend.cpp152
-rw-r--r--ext/detours/samples/findfunc/extend.rc17
-rw-r--r--ext/detours/samples/findfunc/findfunc.cpp35
-rw-r--r--ext/detours/samples/findfunc/symtest.cpp385
-rw-r--r--ext/detours/samples/findfunc/target.cpp41
-rw-r--r--ext/detours/samples/findfunc/target.h14
-rw-r--r--ext/detours/samples/findfunc/target.rc17
8 files changed, 839 insertions, 0 deletions
diff --git a/ext/detours/samples/findfunc/Makefile b/ext/detours/samples/findfunc/Makefile
new file mode 100644
index 0000000..2ea19dc
--- /dev/null
+++ b/ext/detours/samples/findfunc/Makefile
@@ -0,0 +1,178 @@
+##############################################################################
+##
+## Program to test DetourFindFunction.
+##
+## Microsoft Research Detours Package
+##
+## Copyright (c) Microsoft Corporation. All rights reserved.
+##
+
+!include ..\common.mak
+
+# ARM64 does not like base addresses below 4GB.
+# Append two extra zeros for it.
+#
+!if "$(DETOURS_TARGET_PROCESSOR)" == "ARM64"
+TARGET_BASE=0x190000000
+EXTEND_BASE=0x1a0000000
+!else
+TARGET_BASE=0x1900000
+EXTEND_BASE=0x1a00000
+!endif
+
+LIBS=$(LIBS) kernel32.lib
+
+##############################################################################
+
+all: dirs \
+ $(BIND)\target$(DETOURS_BITS).dll \
+ $(BIND)\extend$(DETOURS_BITS).dll \
+ $(BIND)\findfunc.exe \
+ $(BIND)\symtest.exe \
+ $(BIND)\dbghelp.dll \
+ \
+!IF $(DETOURS_SOURCE_BROWSING)==1
+ $(OBJD)\target$(DETOURS_BITS).bsc \
+ $(OBJD)\extend$(DETOURS_BITS).bsc \
+ $(OBJD)\findfunc.bsc \
+ $(OBJD)\symtest.bsc \
+!ENDIF
+ option
+
+##############################################################################
+
+dirs:
+ @if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
+ @if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
+
+$(OBJD)\target.obj : target.cpp
+
+$(OBJD)\target.res : target.rc
+
+$(BIND)\target$(DETOURS_BITS).dll $(BIND)\target$(DETOURS_BITS).lib: \
+ $(OBJD)\target.obj $(OBJD)\target.res $(DEPS)
+ cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
+ $(OBJD)\target.obj $(OBJD)\target.res \
+ /link $(LINKFLAGS) /subsystem:console \
+ /export:Target \
+ /base:$(TARGET_BASE) \
+ $(LIBS)
+
+$(OBJD)\target$(DETOURS_BITS).bsc : $(OBJD)\target.obj
+ bscmake /v /n /o $@ $(OBJD)\target.sbr
+
+$(OBJD)\extend.obj : extend.cpp
+
+$(OBJD)\extend.res : extend.rc
+
+$(BIND)\extend$(DETOURS_BITS).dll $(BIND)\extend$(DETOURS_BITS).lib: \
+ $(OBJD)\extend.obj $(OBJD)\extend.res $(DEPS)
+ cl /LD $(CFLAGS) /Fe$(@R).dll /Fd$(@R).pdb \
+ $(OBJD)\extend.obj $(OBJD)\extend.res \
+ /link $(LINKFLAGS) /subsystem:console \
+ /export:DetourFinishHelperProcess,@1,NONAME \
+ /base:$(EXTEND_BASE) \
+ $(LIBS)
+
+$(OBJD)\extend$(DETOURS_BITS).bsc : $(OBJD)\extend.obj
+ bscmake /v /n /o $@ $(OBJD)\extend.sbr
+
+$(OBJD)\findfunc.obj : findfunc.cpp
+
+$(BIND)\findfunc.exe : $(OBJD)\findfunc.obj $(BIND)\target$(DETOURS_BITS).lib $(DEPS)
+ cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\findfunc.obj \
+ /link $(LINKFLAGS) $(LIBS) \
+ /subsystem:console /fixed:no $(BIND)\target$(DETOURS_BITS).lib
+
+$(OBJD)\findfunc.bsc : $(OBJD)\findfunc.obj
+ bscmake /v /n /o $@ $(OBJD)\findfunc.sbr
+
+$(OBJD)\symtest.obj : symtest.cpp
+
+$(BIND)\symtest.exe : $(OBJD)\symtest.obj $(BIND)\target$(DETOURS_BITS).lib $(DEPS)
+ cl $(CFLAGS) /Fe$@ /Fd$(@R).pdb $(OBJD)\symtest.obj \
+ /link $(LINKFLAGS) $(LIBS) \
+ /subsystem:console /fixed:no $(BIND)\target$(DETOURS_BITS).lib
+
+$(OBJD)\symtest.bsc : $(OBJD)\symtest.obj
+ bscmake /v /n /o $@ $(OBJD)\symtest.sbr
+
+# We try to get the 64-bit dbghelp first because it is a lot more useful.
+$(BIND)\dbghelp.dll : {"$(PROGRAMFILES)\Debugging Tools for Windows 64-bit";$(PATH)}dbghelp.dll
+ -copy $** $(BIND)\dbghelp.dll
+
+##############################################################################
+
+clean:
+ -del *~ 2>nul
+ -del $(BIND)\target*.* $(BIND)\extend*.* 2>nul
+ -del $(BIND)\findfunc.* $(BIND)\symtest.* $(BIND)\dbghelp.dll 2>nul
+ -rmdir /q /s $(OBJD) 2>nul
+
+realclean: clean
+ -rmdir /q /s $(OBJDS) 2>nul
+
+############################################### Install non-bit-size binaries.
+
+!IF "$(DETOURS_OPTION_PROCESSOR)" != ""
+
+$(OPTD)\extend$(DETOURS_OPTION_BITS).dll:
+$(OPTD)\extend$(DETOURS_OPTION_BITS).pdb:
+$(OPTD)\target$(DETOURS_OPTION_BITS).dll:
+$(OPTD)\target$(DETOURS_OPTION_BITS).pdb:
+
+$(BIND)\extend$(DETOURS_OPTION_BITS).dll : $(OPTD)\extend$(DETOURS_OPTION_BITS).dll
+ @if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
+$(BIND)\extend$(DETOURS_OPTION_BITS).pdb : $(OPTD)\extend$(DETOURS_OPTION_BITS).pdb
+ @if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
+$(BIND)\target$(DETOURS_OPTION_BITS).dll : $(OPTD)\target$(DETOURS_OPTION_BITS).dll
+ @if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
+$(BIND)\target$(DETOURS_OPTION_BITS).pdb : $(OPTD)\target$(DETOURS_OPTION_BITS).pdb
+ @if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR).
+
+option: \
+ $(BIND)\extend$(DETOURS_OPTION_BITS).dll \
+ $(BIND)\extend$(DETOURS_OPTION_BITS).pdb \
+ $(BIND)\target$(DETOURS_OPTION_BITS).dll \
+ $(BIND)\target$(DETOURS_OPTION_BITS).pdb \
+
+!ELSE
+
+option:
+
+!ENDIF
+
+##############################################################################
+
+verbose: all
+ cls
+ $(BIND)\symtest.exe
+
+test: all
+ @echo -------- Reseting test binaries to initial state. -----------------------
+ $(BIND)\setdll.exe -r $(BIND)\findfunc.exe
+ @echo.
+ @echo -------- Should not load extend$(DETOURS_BITS).dll--------------------------------------
+ $(BIND)\findfunc.exe
+ @echo.
+ @echo -------- Adding extend$(DETOURS_BITS).dll to findfunc.exe ------------------------------
+ $(BIND)\setdll.exe -d:$(BIND)\extend$(DETOURS_BITS).dll $(BIND)\findfunc.exe
+ @echo.
+ @echo -------- Should load extend$(DETOURS_BITS).dll statically ------------------------------
+ $(BIND)\findfunc.exe
+ @echo.
+ @echo -------- Removing extend$(DETOURS_BITS).dll from findfunc.exe --------------------------
+ $(BIND)\setdll.exe -r $(BIND)\findfunc.exe
+ @echo.
+ @echo -------- Should not load extend$(DETOURS_BITS).dll -------------------------------------
+ $(BIND)\findfunc.exe
+ @echo.
+ @echo -------- Should load extend$(DETOURS_BITS).dll dynamically using withdll.exe -----------
+ $(BIND)\withdll.exe -d:$(BIND)\extend$(DETOURS_BITS).dll $(BIND)\findfunc.exe
+ @echo.
+ @echo -------- Should list symbols using symtest.exe -----------
+ $(BIND)\symtest.exe
+ @echo.
+ @echo -------- Test completed. ------------------------------------------------
+
+################################################################# End of File.
diff --git a/ext/detours/samples/findfunc/extend.cpp b/ext/detours/samples/findfunc/extend.cpp
new file mode 100644
index 0000000..744a3ab
--- /dev/null
+++ b/ext/detours/samples/findfunc/extend.cpp
@@ -0,0 +1,152 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Detour Test Program (extend.cpp of extend.dll)
+//
+// Microsoft Research Detours Package
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// An example dynamically detouring a function.
+//
+#include <stdio.h>
+#include <windows.h>
+#include "detours.h"
+
+static LONG nExtends = 0;
+static LONG nInterns = 0;
+
+static DWORD (WINAPI * TrueTarget)(DWORD dwCount) = NULL;
+static DWORD (WINAPI * TrueHidden)(DWORD dwCount) = NULL;
+static int (WINAPI * TrueEntryPoint)(VOID) = NULL;
+
+// Extend is a detour for Target.
+static DWORD WINAPI Extend(DWORD dwCount)
+{
+ InterlockedIncrement(&nExtends);
+
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Extend (%ld) -> %ld.\n", dwCount, dwCount + 1000);
+ dwCount = TrueTarget(dwCount + 1000);
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Extend (.....) -> %ld.\n", dwCount);
+ return dwCount;
+}
+
+// Intern is a detour for Hidden.
+static DWORD WINAPI Intern(DWORD dwCount)
+{
+ InterlockedIncrement(&nInterns);
+
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Intern (%ld) -> %ld.\n", dwCount, dwCount + 10);
+ dwCount = TrueHidden(dwCount + 10);
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Intern (.....) -> %ld.\n", dwCount);
+ return dwCount;
+}
+
+static int WINAPI ExtendEntryPoint()
+{
+ // We couldn't call LoadLibrary in DllMain, so our functions here.
+ LONG error;
+
+ // We separate out the functions in the export table (Target)
+ // from the ones that require debug symbols (Hidden).
+ TrueTarget =
+ (DWORD (WINAPI *)(DWORD))
+ DetourFindFunction("target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll", "Target");
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourAttach(&(PVOID&)TrueTarget, Extend);
+ error = DetourTransactionCommit();
+
+ if (error == NO_ERROR) {
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Detoured Target().\n");
+ }
+ else {
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Error detouring Target(): %ld\n", error);
+ }
+
+ // Now try to detour the functions requiring debug symbols.
+ TrueHidden =
+ (DWORD (WINAPI *)(DWORD))
+ DetourFindFunction("target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll", "Hidden");
+ if (TrueHidden == NULL) {
+ error = GetLastError();
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: TrueHidden = %p (error = %ld)\n", TrueHidden, error);
+ }
+
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourAttach(&(PVOID&)TrueHidden, Intern);
+ error = DetourTransactionCommit();
+
+ if (error == NO_ERROR) {
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Detoured Hidden().\n");
+ }
+ else {
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Error detouring Hidden(): %ld\n", error);
+ }
+
+ // Now let the application start executing.
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Calling EntryPoint\n");
+ fflush(stdout);
+
+ return TrueEntryPoint();
+}
+
+BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
+{
+ LONG error;
+ (void)hinst;
+ (void)reserved;
+
+ if (DetourIsHelperProcess()) {
+ return TRUE;
+ }
+
+ if (dwReason == DLL_PROCESS_ATTACH) {
+ DetourRestoreAfterWith();
+
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Starting.\n");
+ fflush(stdout);
+
+ // NB: DllMain can't call LoadLibrary, so we hook the app entry point.
+
+ TrueEntryPoint = (int (WINAPI *)())DetourGetEntryPoint(NULL);
+
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourAttach(&(PVOID&)TrueEntryPoint, ExtendEntryPoint);
+ error = DetourTransactionCommit();
+
+ if (error == NO_ERROR) {
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Detoured EntryPoint().\n");
+ }
+ else {
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Error detouring EntryPoint(): %ld\n", error);
+ }
+ }
+ else if (dwReason == DLL_PROCESS_DETACH) {
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+
+ // Detach functions found from the export table.
+ if (TrueTarget != NULL) {
+ DetourDetach(&(PVOID&)TrueTarget, (PVOID)Extend);
+ }
+
+ // Detach functions found from debug symbols.
+ if (TrueHidden != NULL) {
+ DetourDetach(&(PVOID&)TrueHidden, (PVOID)Intern);
+ }
+
+ // Detach the entry point.
+ DetourDetach(&(PVOID&)TrueEntryPoint, ExtendEntryPoint);
+ error = DetourTransactionCommit();
+
+ printf("extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll: Removed Target() detours (%ld), %ld/%ld calls.\n",
+ error, nExtends, nInterns);
+
+ fflush(stdout);
+ }
+ return TRUE;
+}
+//
+///////////////////////////////////////////////////////////////// End of File.
diff --git a/ext/detours/samples/findfunc/extend.rc b/ext/detours/samples/findfunc/extend.rc
new file mode 100644
index 0000000..a6e3f52
--- /dev/null
+++ b/ext/detours/samples/findfunc/extend.rc
@@ -0,0 +1,17 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Version information for extend.rc.
+//
+// Microsoft Research Detours Package
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+#include "detver.h"
+
+#define VER_INTERNALNAME_STR "extend" DETOURS_STRINGIFY(DETOURS_BITS)
+#define VER_ORIGINALFILENAME_STR "extend" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
+#define VER_FILEDESCRIPTION_STR "Detours Dyanmic Interception Test Module"
+#define VER_COMPANYNAME_STR "Microsoft Corporation"
+
+#include "common.ver"
diff --git a/ext/detours/samples/findfunc/findfunc.cpp b/ext/detours/samples/findfunc/findfunc.cpp
new file mode 100644
index 0000000..3c7f15b
--- /dev/null
+++ b/ext/detours/samples/findfunc/findfunc.cpp
@@ -0,0 +1,35 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Detour Test Program (findfunc.cpp of findfunc.exe)
+//
+// Microsoft Research Detours Package
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+#include <windows.h>
+#include <stdio.h>
+#include <detours.h>
+#include "target.h"
+
+int __cdecl main(void)
+{
+ printf("findfunc.exe: Starting.\n");
+ fflush(stdout);
+
+ printf("DLLs:\n");
+ for (HMODULE hModule = NULL; (hModule = DetourEnumerateModules(hModule)) != NULL;) {
+ CHAR szName[MAX_PATH] = { 0 };
+ GetModuleFileNameA(hModule, szName, sizeof(szName) - 1);
+ printf(" %p: %s\n", hModule, szName);
+ }
+
+ DWORD dwCount = 10000;
+ for (int i = 0; i < 3; i++) {
+ printf("findfunc.exe: Calling (%ld).\n", dwCount);
+ dwCount = Target(dwCount) + 10000;
+ }
+ return 0;
+}
+//
+///////////////////////////////////////////////////////////////// End of File.
diff --git a/ext/detours/samples/findfunc/symtest.cpp b/ext/detours/samples/findfunc/symtest.cpp
new file mode 100644
index 0000000..74cd539
--- /dev/null
+++ b/ext/detours/samples/findfunc/symtest.cpp
@@ -0,0 +1,385 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Detour Test Program (symtest.cpp of symtest.exe)
+//
+// Microsoft Research Detours Package
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+#include <windows.h>
+#include <stdio.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>
+#include "target.h"
+
+#if (_MSC_VER < 1299)
+#include <imagehlp.h>
+typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
+typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
+typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
+typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
+#else
+#pragma warning(push)
+#pragma warning(disable:4091) // empty typedef
+#include <dbghelp.h>
+#pragma warning(pop)
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//
+typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(LPAPI_VERSION AppVersion);
+
+typedef BOOL (NTAPI *PF_SymInitialize)(IN HANDLE hProcess,
+ IN LPCSTR UserSearchPath,
+ IN BOOL fInvadeProcess);
+typedef DWORD (NTAPI *PF_SymSetOptions)(IN DWORD SymOptions);
+typedef DWORD (NTAPI *PF_SymGetOptions)(VOID);
+typedef DWORD64 (NTAPI *PF_SymLoadModule64)(IN HANDLE hProcess,
+ IN HANDLE hFile,
+ IN PSTR ImageName,
+ IN PSTR ModuleName,
+ IN DWORD64 BaseOfDll,
+ IN DWORD SizeOfDll);
+typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(IN HANDLE hProcess,
+ IN DWORD64 qwAddr,
+ OUT PIMAGEHLP_MODULE64 ModuleInfo);
+typedef BOOL (NTAPI *PF_SymFromName)(IN HANDLE hProcess,
+ IN LPSTR Name,
+ OUT PSYMBOL_INFO Symbol);
+#if (_MSC_VER < 1299)
+typedef BOOL (NTAPI *PF_SymRegisterCallback64)();
+typedef BOOL (NTAPI *PF_SymEnumerateModules64)();
+typedef BOOL (NTAPI *PF_SymEnumSymbols)();
+#else
+typedef BOOL (NTAPI *PF_SymRegisterCallback64)(IN HANDLE hProcess,
+ IN PSYMBOL_REGISTERED_CALLBACK64
+ CallbackFunction,
+ IN ULONG64 UserContext);
+typedef BOOL (NTAPI *PF_SymEnumerateModules64)(IN HANDLE hProcess,
+ IN PSYM_ENUMMODULES_CALLBACK64
+ EnumModulesCallback,
+ IN PVOID UserContext);
+typedef BOOL (NTAPI *PF_SymEnumSymbols)(IN HANDLE hProcess,
+ IN ULONG64 BaseOfDll,
+ IN PCSTR Mask,
+ IN PSYM_ENUMERATESYMBOLS_CALLBACK
+ EnumSymbolsCallback,
+ IN PVOID UserContext);
+#endif
+
+PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx = NULL;
+PF_SymInitialize pfSymInitialize = NULL;
+PF_SymSetOptions pfSymSetOptions = NULL;
+PF_SymGetOptions pfSymGetOptions = NULL;
+PF_SymLoadModule64 pfSymLoadModule64 = NULL;
+PF_SymGetModuleInfo64 pfSymGetModuleInfo64 = NULL;
+PF_SymFromName pfSymFromName = NULL;
+PF_SymRegisterCallback64 pfSymRegisterCallback64 = NULL;
+PF_SymEnumerateModules64 pfSymEnumerateModules64 = NULL;
+PF_SymEnumSymbols pfSymEnumSymbols = NULL;
+
+//////////////////////////////////////////////////////////////////////////////
+//
+
+#if (_MSC_VER > 1299)
+static BOOL WINAPI SymEnumerateCallback(
+ PCSTR pszModule,
+ DWORD64 base,
+ PVOID pvUserContext)
+{
+ (void)pvUserContext;
+ printf(" %p: %s\n", (PVOID)base, pszModule);
+ return TRUE;
+}
+
+static int nSymbolCount = 0;
+static BOOL WINAPI SymEnumerateSymbols(PSYMBOL_INFO pSym,
+ ULONG size,
+ PVOID pvUserContext)
+{
+ (void)size;
+ (void)pvUserContext;
+ if (strstr(pSym->Name, "Target") != NULL ||
+ strstr(pSym->Name, "Hidden") != NULL) {
+ printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
+ nSymbolCount++;
+ }
+ else if (nSymbolCount < 5) {
+ printf(" %p: %s\n", (PVOID)pSym->Address, pSym->Name);
+ nSymbolCount++;
+ }
+ return TRUE;
+}
+
+static void truncate(PCHAR data)
+{
+ size_t len = strlen(data);
+ if (len > 0 && data[len-1] == '\r') {
+ data[--len] = '\0';
+ }
+ if (len > 0 && data[len-1] == '\n') {
+ data[--len] = '\0';
+ }
+}
+
+BOOL WINAPI CallbackFunction(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 context)
+{
+ (void)context;
+
+ switch (action) {
+ case CBA_DEBUG_INFO:
+ truncate((PCHAR)data);
+ printf("::> %s\n", (PCHAR)data);
+ return TRUE;
+
+ case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
+ printf("::> proc=%p action=%08lx data=%p\n",
+ (PVOID)hProcess,
+ action,
+ (PVOID)data);
+ {
+ PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 pi = (PIMAGEHLP_DEFERRED_SYMBOL_LOAD64)data;
+ printf("pi->SizeOfStruct = %ld\n", pi->SizeOfStruct);
+ printf("pi->BaseOfImage = %p\n", (PVOID)(size_t)pi->BaseOfImage);
+ printf("pi->CheckSum = %8lx\n", pi->CheckSum);
+ printf("pi->FileName = %p [%s]\n", pi->FileName, pi->FileName);
+ printf("pi->Reparse = %d\n", pi->Reparse);
+ }
+ return FALSE;
+ default:
+ printf("::> proc=%p action=%08lx data=%p\n",
+ (PVOID)hProcess,
+ action,
+ (PVOID)data);
+ return FALSE;
+ }
+}
+#endif
+
+int __cdecl main(void)
+{
+ printf("symtest.exe: Starting.\n");
+ fflush(stdout);
+
+ //////////////////////////////////////////////////////// Get the functions.
+ //
+ HMODULE hDbgHelp = LoadLibraryA("dbghelp.dll");
+ if (hDbgHelp == NULL) {
+ printf("Couldn't load dbghelp.dll");
+ return 1;
+ }
+
+ pfImagehlpApiVersionEx
+ = (PF_ImagehlpApiVersionEx)GetProcAddress(hDbgHelp,
+ "ImagehlpApiVersionEx");
+ pfSymInitialize
+ = (PF_SymInitialize)GetProcAddress(hDbgHelp, "SymInitialize");
+ pfSymSetOptions
+ = (PF_SymSetOptions)GetProcAddress(hDbgHelp, "SymSetOptions");
+ pfSymGetOptions
+ = (PF_SymGetOptions)GetProcAddress(hDbgHelp, "SymGetOptions");
+ pfSymLoadModule64
+ = (PF_SymLoadModule64)GetProcAddress(hDbgHelp, "SymLoadModule64");
+ pfSymGetModuleInfo64
+ = (PF_SymGetModuleInfo64)GetProcAddress(hDbgHelp, "SymGetModuleInfo64");
+ pfSymFromName
+ = (PF_SymFromName)GetProcAddress(hDbgHelp, "SymFromName");
+ pfSymRegisterCallback64
+ = (PF_SymRegisterCallback64)GetProcAddress(hDbgHelp, "SymRegisterCallback64");
+ pfSymEnumerateModules64
+ = (PF_SymEnumerateModules64)GetProcAddress(hDbgHelp, "SymEnumerateModules64");
+ pfSymEnumSymbols
+ = (PF_SymEnumSymbols)GetProcAddress(hDbgHelp, "SymEnumSymbols");
+
+ //////////////////////////////////////////////////////////////////////////////
+ //
+ HANDLE hProcess = GetCurrentProcess();
+
+ API_VERSION av;
+ ZeroMemory(&av, sizeof(av));
+ av.MajorVersion = API_VERSION_NUMBER;
+
+ pfImagehlpApiVersionEx(&av);
+ printf(" Version: %d.%d (%d)\n",
+ av.MajorVersion,
+ av.MinorVersion,
+ API_VERSION_NUMBER);
+
+ if (!pfSymInitialize(hProcess, NULL, FALSE)) {
+ printf("SymInitialize failed: %ld\n", GetLastError());
+ return 1;
+ }
+
+#if (_MSC_VER > 1299)
+ pfSymRegisterCallback64(hProcess, CallbackFunction, NULL);
+#endif
+
+ DWORD dw = pfSymGetOptions();
+ printf("GetOptions = %08lx\n", dw);
+ dw &= ~(SYMOPT_CASE_INSENSITIVE |
+ SYMOPT_UNDNAME |
+ SYMOPT_DEFERRED_LOADS |
+ 0);
+ dw |= (
+#if defined(SYMOPT_EXACT_SYMBOLS)
+ SYMOPT_EXACT_SYMBOLS |
+#endif
+#if defined(SYMOPT_DEBUG)
+ SYMOPT_DEBUG |
+#endif
+#if defined(SYMOPT_NO_UNQUALIFIED_LOADS)
+ SYMOPT_NO_UNQUALIFIED_LOADS |
+#endif
+#if defined(SYMOPT_FAIL_CRITICAL_ERRORS)
+ SYMOPT_FAIL_CRITICAL_ERRORS |
+#endif
+#if defined(SYMOPT_INCLUDE_32BIT_MODULES)
+ SYMOPT_INCLUDE_32BIT_MODULES |
+#endif
+ 0);
+ printf("SetOptions = %08lx\n", dw);
+ pfSymSetOptions(dw);
+
+ /////////////////////////////////////////////// First, try GetProcAddress.
+ //
+ PCHAR pszFile = "target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll";
+ HMODULE hModule = LoadLibraryA(pszFile);
+ if (hModule == NULL) {
+ printf("LoadLibraryA(%s) failed: %ld\n", pszFile, GetLastError());
+ return 2;
+ }
+
+ ////////////////////////////////////////////////////// Then try ImageHelp.
+ //
+#if (_MSC_VER > 1299)
+
+ //CHAR szFull[MAX_PATH];
+ //GetModuleFileNameA(hModule, szFull, sizeof(szFull));
+ printf("SymLoadModule64(%s) will be called.\n", pszFile /*szFull*/);
+ DWORD64 loaded = pfSymLoadModule64(hProcess, NULL,
+ (PCHAR)pszFile/*szFull*/, NULL,
+ (DWORD64)hModule, 0);
+ if (loaded == 0) {
+ printf("SymLoadModule64(%p) failed: %ld\n", hProcess, GetLastError());
+ printf("\n");
+ }
+ else {
+ printf("SymLoadModule64(%p) succeeded: 0x%p\n", hProcess, (PVOID)loaded);
+ }
+
+ CHAR szModName[512];
+
+ printf("Modules:\n");
+// The first parameter of PSYM_ENUMMODULES_CALLBACK64 changed from PSTR to PCSTR
+// between Windows 2003 and Windows 7. Cast here to work with either.
+ pfSymEnumerateModules64(hProcess, (PSYM_ENUMMODULES_CALLBACK64)SymEnumerateCallback, NULL);
+ printf("\n");
+
+ IMAGEHLP_MODULE64 modinfo;
+ ZeroMemory(&modinfo, sizeof(modinfo));
+ modinfo.SizeOfStruct = 512/*sizeof(modinfo)*/;
+ if (!pfSymGetModuleInfo64(hProcess, (DWORD64)hModule, &modinfo)) {
+ printf("SymGetModuleInfo64(%p, %p) [64] failed: %ld\n",
+ hProcess, hModule, GetLastError());
+ }
+ else {
+ printf("SymGetModuleInfo64(%p, %p) [64] succeeded: %ld\n",
+ hProcess, hModule, GetLastError());
+ StringCchCopyA(szModName, ARRAYSIZE(szModName), modinfo.ModuleName);
+ StringCchCatA(szModName, ARRAYSIZE(szModName), "!");
+
+ printf("NumSyms: %ld\n", modinfo.NumSyms);
+ printf("SymType: %d\n", modinfo.SymType);
+ printf("ModuleName: %s\n", modinfo.ModuleName);
+ printf("ImageName: %s\n", modinfo.ImageName);
+ printf("LoadedImageName: %s\n", modinfo.LoadedImageName);
+ }
+
+ printf("\n");
+ fflush(stdout);
+
+ printf("DLLs:\n");
+ for (hModule = NULL; (hModule = DetourEnumerateModules(hModule)) != NULL;) {
+ CHAR szName[MAX_PATH];
+ GetModuleFileNameA(hModule, szName, sizeof(szName));
+ printf(" %p: %s\n", hModule, szName);
+ }
+
+ if (pfSymEnumSymbols == NULL) {
+ printf("Couldn't find SymEnumSymbols.\n");
+ }
+ else {
+ printf("===Enum===\n");
+ SetLastError(0);
+ nSymbolCount = 0;
+ if (!pfSymEnumSymbols(hProcess, (DWORD64)hModule, NULL, SymEnumerateSymbols, NULL)) {
+ printf("SymEnumSymbols() failed: %ld\n",
+ GetLastError());
+ }
+ }
+
+ // Look for specific symbols.
+ struct CFullSymbol : SYMBOL_INFO {
+ CHAR szRestOfName[MAX_SYM_NAME];
+ } symbol;
+ CHAR szFullName[512];
+
+ // Look for Target
+ StringCchCopyA(szFullName, ARRAYSIZE(szFullName), szModName);
+ StringCchCatA(szFullName, ARRAYSIZE(szFullName), "Target");
+ printf("Symbol: [%s]\n", szFullName);
+
+ ZeroMemory(&symbol, sizeof(symbol));
+ symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
+#ifdef DBHLPAPI
+ symbol.MaxNameLen = MAX_SYM_NAME;
+#else
+ symbol.MaxNameLength = MAX_SYM_NAME;
+#endif
+
+ SetLastError(0);
+ if (!pfSymFromName(hProcess, szFullName, &symbol)) {
+ printf("--SymFromName(%s) failed: %ld\n", szFullName, GetLastError());
+ }
+ if (symbol.Address != 0) {
+ printf("--SymFromName(%s) succeeded\n", szFullName);
+ }
+
+ printf("%s => %p\n\n", szFullName, (PBYTE)symbol.Address);
+
+ // Look for Hidden
+ StringCchCopyA(szFullName, ARRAYSIZE(szFullName), szModName);
+ StringCchCatA(szFullName, ARRAYSIZE(szFullName), "Hidden");
+ printf("Symbol: [%s]\n", szFullName);
+
+ ZeroMemory(&symbol, sizeof(symbol));
+ symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
+#ifdef DBHLPAPI
+ symbol.MaxNameLen = MAX_SYM_NAME;
+#else
+ symbol.MaxNameLength = MAX_SYM_NAME;
+#endif
+
+ SetLastError(0);
+ if (!pfSymFromName(hProcess, szFullName, &symbol)) {
+ printf("--SymFromName(%s) failed: %ld\n", szFullName, GetLastError());
+ }
+ if (symbol.Address != 0) {
+ printf("--SymFromName(%s) succeeded\n", szFullName);
+ }
+
+ printf("%s => %p\n\n", szFullName, (PBYTE)symbol.Address);
+#endif
+
+ // We call Target once to insure it is loaded.
+ Target(0);
+ return 0;
+}
+//
+///////////////////////////////////////////////////////////////// End of File.
diff --git a/ext/detours/samples/findfunc/target.cpp b/ext/detours/samples/findfunc/target.cpp
new file mode 100644
index 0000000..052e2ab
--- /dev/null
+++ b/ext/detours/samples/findfunc/target.cpp
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Detour Test Program (target.cpp of target.dll)
+//
+// Microsoft Research Detours Package
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+#include <stdio.h>
+#include <windows.h>
+#include "target.h"
+
+extern "C" DWORD WINAPI Hidden(DWORD dwCount)
+{
+ printf("target.dll: Hidden(%ld) -> %ld.\n", dwCount, dwCount + 1);
+ return dwCount + 1;
+}
+
+// We use this point to ensure Hidden isn't inlined.
+static DWORD (WINAPI * SelfHidden)(DWORD dwCount) = Hidden;
+
+DWORD WINAPI Target(DWORD dwCount)
+{
+ printf("target.dll: Target (%ld) -> %ld.\n", dwCount, dwCount + 100);
+ dwCount = SelfHidden(dwCount + 100);
+ printf("target.dll: Target (.....) -> %ld.\n", dwCount);
+ return dwCount;
+}
+
+BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
+{
+ (void)hinst;
+ (void)dwReason;
+ (void)reserved;
+
+ return TRUE;
+}
+
+//
+///////////////////////////////////////////////////////////////// End of File.
diff --git a/ext/detours/samples/findfunc/target.h b/ext/detours/samples/findfunc/target.h
new file mode 100644
index 0000000..076da2e
--- /dev/null
+++ b/ext/detours/samples/findfunc/target.h
@@ -0,0 +1,14 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Detour Test Program (target.h of target.dll)
+//
+// Microsoft Research Detours Package
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+#pragma once
+
+DWORD WINAPI Target(DWORD dwCount);
+
+//
+///////////////////////////////////////////////////////////////// End of File.
diff --git a/ext/detours/samples/findfunc/target.rc b/ext/detours/samples/findfunc/target.rc
new file mode 100644
index 0000000..b75e4ec
--- /dev/null
+++ b/ext/detours/samples/findfunc/target.rc
@@ -0,0 +1,17 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// Version information for target.rc.
+//
+// Microsoft Research Detours Package
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+#include "detver.h"
+
+#define VER_INTERNALNAME_STR "target" DETOURS_STRINGIFY(DETOURS_BITS)
+#define VER_ORIGINALFILENAME_STR "target" DETOURS_STRINGIFY(DETOURS_BITS) ".dll"
+#define VER_FILEDESCRIPTION_STR "Detours Test Module"
+#define VER_COMPANYNAME_STR "Microsoft Corporation"
+
+#include "common.ver"