diff options
Diffstat (limited to 'ext/detours/samples/findfunc')
-rw-r--r-- | ext/detours/samples/findfunc/Makefile | 178 | ||||
-rw-r--r-- | ext/detours/samples/findfunc/extend.cpp | 152 | ||||
-rw-r--r-- | ext/detours/samples/findfunc/extend.rc | 17 | ||||
-rw-r--r-- | ext/detours/samples/findfunc/findfunc.cpp | 35 | ||||
-rw-r--r-- | ext/detours/samples/findfunc/symtest.cpp | 385 | ||||
-rw-r--r-- | ext/detours/samples/findfunc/target.cpp | 41 | ||||
-rw-r--r-- | ext/detours/samples/findfunc/target.h | 14 | ||||
-rw-r--r-- | ext/detours/samples/findfunc/target.rc | 17 |
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" |