diff options
Diffstat (limited to 'samples/tracereg')
-rw-r--r-- | samples/tracereg/Makefile | 82 | ||||
-rw-r--r-- | samples/tracereg/trcreg.cpp | 1577 | ||||
-rw-r--r-- | samples/tracereg/trcreg.rc | 17 |
3 files changed, 1676 insertions, 0 deletions
diff --git a/samples/tracereg/Makefile b/samples/tracereg/Makefile new file mode 100644 index 0000000..459747f --- /dev/null +++ b/samples/tracereg/Makefile @@ -0,0 +1,82 @@ +############################################################################## +## +## Utility to registry and file access APIs. +## +## Microsoft Research Detours Package +## +## Copyright (c) Microsoft Corporation. All rights reserved. +## + +!include ..\common.mak + +LIBS=$(LIBS) kernel32.lib advapi32.lib + +all: dirs \ + $(BIND)\trcreg$(DETOURS_BITS).dll \ +!IF $(DETOURS_SOURCE_BROWSING)==1 + $(OBJD)\trcreg$(DETOURS_BITS).bsc \ +!ENDIF + option + +dirs: + @if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND) + @if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD) + +clean: + -del *~ test.txt 2>nul + -del $(BIND)\trcreg*.* 2>nul + -rmdir /q /s $(OBJD) 2>nul + +realclean: clean + -rmdir /q /s $(OBJDS) 2>nul + +############################################################################## + +$(OBJD)\trcreg.obj : trcreg.cpp + +$(OBJD)\trcreg.res : trcreg.rc + +$(BIND)\trcreg$(DETOURS_BITS).dll : $(OBJD)\trcreg.obj $(OBJD)\trcreg.res $(DEPS) + cl /LD $(CFLAGS) /Fe$@ /Fd$(@R).pdb \ + $(OBJD)\trcreg.obj $(OBJD)\trcreg.res \ + /link $(LINKFLAGS) /subsystem:console \ + /export:DetourFinishHelperProcess,@1,NONAME \ + $(LIBS) + +$(OBJD)\trcreg$(DETOURS_BITS).bsc : $(OBJD)\trcreg.obj + bscmake /v /n /o $@ $(OBJD)\trcreg.sbr + +############################################### Install non-bit-size binaries. + +!IF "$(DETOURS_OPTION_PROCESSOR)" != "" + +$(OPTD)\trcreg$(DETOURS_OPTION_BITS).dll: +$(OPTD)\trcreg$(DETOURS_OPTION_BITS).pdb: + +$(BIND)\trcreg$(DETOURS_OPTION_BITS).dll : $(OPTD)\trcreg$(DETOURS_OPTION_BITS).dll + @if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR). +$(BIND)\trcreg$(DETOURS_OPTION_BITS).pdb : $(OPTD)\trcreg$(DETOURS_OPTION_BITS).pdb + @if exist $? copy /y $? $(BIND) >nul && echo $@ copied from $(DETOURS_OPTION_PROCESSOR). + +option: \ + $(BIND)\trcreg$(DETOURS_OPTION_BITS).dll \ + $(BIND)\trcreg$(DETOURS_OPTION_BITS).pdb \ + +!ELSE + +option: + +!ENDIF + +############################################################################## + +test: all + @echo -------- Logging output to test.txt ------------ + start $(BIND)\syelogd.exe /o test.txt + $(BIND)\sleep5.exe 1 + @echo -------- Should load trcreg$(DETOURS_BITS).dll dynamically using withdll.exe ------------ + $(BIND)\withdll -d:$(BIND)\trcreg$(DETOURS_BITS).dll $(BIND)\sleepold.exe + @echo -------- Log from syelog ------------- + type test.txt + +################################################################# End of File. diff --git a/samples/tracereg/trcreg.cpp b/samples/tracereg/trcreg.cpp new file mode 100644 index 0000000..7e1b780 --- /dev/null +++ b/samples/tracereg/trcreg.cpp @@ -0,0 +1,1577 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Detours Test Program (trcreg.cpp of trcreg.dll) +// +// Microsoft Research Detours Package +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +#define _WIN32_WINNT 0x0400 +#define WIN32 +#define NT + +#define DBG_TRACE 0 + +#include <windows.h> +#include <stdio.h> +#include "detours.h" +#include "syelog.h" + +#define PULONG_PTR PVOID +#define PLONG_PTR PVOID +#define ULONG_PTR PVOID +#define ENUMRESNAMEPROCA PVOID +#define ENUMRESNAMEPROCW PVOID +#define ENUMRESLANGPROCA PVOID +#define ENUMRESLANGPROCW PVOID +#define ENUMRESTYPEPROCA PVOID +#define ENUMRESTYPEPROCW PVOID +#define STGOPTIONS PVOID + +////////////////////////////////////////////////////////////////////////////// +#pragma warning(disable:4127) // Many of our asserts are constants. + +#define ASSERT_ALWAYS(x) \ + do { \ + if (!(x)) { \ + AssertMessage(#x, __FILE__, __LINE__); \ + DebugBreak(); \ + } \ + } while (0) + +#ifndef NDEBUG +#define ASSERT(x) ASSERT_ALWAYS(x) +#else +#define ASSERT(x) +#endif + +#define UNUSED(c) (c) = (c) + +////////////////////////////////////////////////////////////////////////////// +static HMODULE s_hInst = NULL; +static CHAR s_szDllPath[MAX_PATH]; + +BOOL ProcessEnumerate(); +BOOL InstanceEnumerate(HINSTANCE hInst); + +VOID _PrintEnter(PCSTR psz, ...); +VOID _PrintExit(PCSTR psz, ...); +VOID _Print(PCSTR psz, ...); + +VOID AssertMessage(CONST PCHAR pszMsg, CONST PCHAR pszFile, ULONG nLine); + +////////////////////////////////////////////////////////////////////////////// +// +extern "C" { + HANDLE (WINAPI * + Real_CreateFileW)(LPCWSTR a0, + DWORD a1, + DWORD a2, + LPSECURITY_ATTRIBUTES a3, + DWORD a4, + DWORD a5, + HANDLE a6) + = CreateFileW; + + BOOL (WINAPI * + Real_WriteFile)(HANDLE hFile, + LPCVOID lpBuffer, + DWORD nNumberOfBytesToWrite, + LPDWORD lpNumberOfBytesWritten, + LPOVERLAPPED lpOverlapped) + = WriteFile; + BOOL (WINAPI * + Real_FlushFileBuffers)(HANDLE hFile) + = FlushFileBuffers; + BOOL (WINAPI * + Real_CloseHandle)(HANDLE hObject) + = CloseHandle; + + BOOL (WINAPI * + Real_WaitNamedPipeW)(LPCWSTR lpNamedPipeName, DWORD nTimeOut) + = WaitNamedPipeW; + BOOL (WINAPI * + Real_SetNamedPipeHandleState)(HANDLE hNamedPipe, + LPDWORD lpMode, + LPDWORD lpMaxCollectionCount, + LPDWORD lpCollectDataTimeout) + = SetNamedPipeHandleState; + + DWORD (WINAPI * + Real_GetCurrentProcessId)(VOID) + = GetCurrentProcessId; + VOID (WINAPI * + Real_GetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime) + = GetSystemTimeAsFileTime; + + VOID (WINAPI * + Real_InitializeCriticalSection)(LPCRITICAL_SECTION lpSection) + = InitializeCriticalSection; + VOID (WINAPI * + Real_EnterCriticalSection)(LPCRITICAL_SECTION lpSection) + = EnterCriticalSection; + VOID (WINAPI * + Real_LeaveCriticalSection)(LPCRITICAL_SECTION lpSection) + = LeaveCriticalSection; +} + +////////////////////////////////////////////////////////////////////////////// +// + +BOOL (WINAPI * Real_CopyFileExA)(LPCSTR a0, + LPCSTR a1, + LPPROGRESS_ROUTINE a2, + LPVOID a3, + LPBOOL a4, + DWORD a5) + = CopyFileExA; + +BOOL (WINAPI * Real_CopyFileExW)(LPCWSTR a0, + LPCWSTR a1, + LPPROGRESS_ROUTINE a2, + LPVOID a3, + LPBOOL a4, + DWORD a5) + = CopyFileExW; + +BOOL (WINAPI * Real_CreateDirectoryExW)(LPCWSTR a0, + LPCWSTR a1, + LPSECURITY_ATTRIBUTES a2) + = CreateDirectoryExW; + +BOOL (WINAPI * Real_CreateDirectoryW)(LPCWSTR a0, + LPSECURITY_ATTRIBUTES a1) + = CreateDirectoryW; + +BOOL (WINAPI * Real_CreateProcessW)(LPCWSTR lpApplicationName, + LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation) + = CreateProcessW; + +BOOL (WINAPI * Real_DeleteFileA)(LPCSTR a0) + = DeleteFileA; + +BOOL (WINAPI * Real_DeleteFileW)(LPCWSTR a0) + = DeleteFileW; + +HANDLE (WINAPI * Real_FindFirstFileExA)(LPCSTR a0, + FINDEX_INFO_LEVELS a1, + LPVOID a2, + FINDEX_SEARCH_OPS a3, + LPVOID a4, + DWORD a5) + = FindFirstFileExA; + +HANDLE (WINAPI * Real_FindFirstFileExW)(LPCWSTR a0, + FINDEX_INFO_LEVELS a1, + LPVOID a2, + FINDEX_SEARCH_OPS a3, + LPVOID a4, + DWORD a5) + = FindFirstFileExW; + +DWORD (WINAPI * Real_GetFileAttributesW)(LPCWSTR a0) + = GetFileAttributesW; + +DWORD (WINAPI * Real_GetModuleFileNameW)(HMODULE a0, + LPWSTR a1, + DWORD a2) + = GetModuleFileNameW; + +DWORD (WINAPI * Real_GetModuleFileNameA)(HMODULE a0, + LPSTR a1, + DWORD a2) + = GetModuleFileNameA; + +FARPROC (WINAPI * Real_GetProcAddress)(struct HINSTANCE__* a0, + LPCSTR a1) + = GetProcAddress; + +HMODULE (WINAPI * Real_LoadLibraryExW)(LPCWSTR a0, + HANDLE a1, + DWORD a2) + = LoadLibraryExW; + +BOOL (WINAPI * Real_MoveFileA)(LPCSTR a0, + LPCSTR a1) + = MoveFileA; + +BOOL (WINAPI * Real_MoveFileExA)(LPCSTR a0, + LPCSTR a1, + DWORD a2) + = MoveFileExA; + +BOOL (WINAPI * Real_MoveFileExW)(LPCWSTR a0, + LPCWSTR a1, + DWORD a2) + = MoveFileExW; + +BOOL (WINAPI * Real_MoveFileW)(LPCWSTR a0, + LPCWSTR a1) + = MoveFileW; + +HFILE (WINAPI * Real_OpenFile)(LPCSTR a0, + struct _OFSTRUCT* a1, + UINT a2) + = OpenFile; + +LONG (WINAPI * Real_RegCreateKeyExA)(HKEY a0, + LPCSTR a1, + DWORD a2, + LPSTR a3, + DWORD a4, + REGSAM a5, + LPSECURITY_ATTRIBUTES a6, + PHKEY a7, + LPDWORD a8) + = RegCreateKeyExA; + +LONG (WINAPI * Real_RegCreateKeyExW)(HKEY a0, + LPCWSTR a1, + DWORD a2, + LPWSTR a3, + DWORD a4, + REGSAM a5, + LPSECURITY_ATTRIBUTES a6, + PHKEY a7, + LPDWORD a8) + = RegCreateKeyExW; + +LONG (WINAPI * Real_RegDeleteKeyA)(HKEY a0, + LPCSTR a1) + = RegDeleteKeyA; + +LONG (WINAPI * Real_RegDeleteKeyW)(HKEY a0, + LPCWSTR a1) + = RegDeleteKeyW; + +LONG (WINAPI * Real_RegDeleteValueA)(HKEY a0, + LPCSTR a1) + = RegDeleteValueA; + + +LONG (WINAPI * Real_RegDeleteValueW)(HKEY a0, + LPCWSTR a1) + = RegDeleteValueW; + +LONG (WINAPI * Real_RegEnumKeyExA)(HKEY a0, + DWORD a1, + LPSTR a2, + LPDWORD a3, + LPDWORD a4, + LPSTR a5, + LPDWORD a6, + struct _FILETIME* a7) + = RegEnumKeyExA; + +LONG (WINAPI * Real_RegEnumKeyExW)(HKEY a0, + DWORD a1, + LPWSTR a2, + LPDWORD a3, + LPDWORD a4, + LPWSTR a5, + LPDWORD a6, + struct _FILETIME* a7) + = RegEnumKeyExW; + +LONG (WINAPI * Real_RegEnumValueA)(HKEY a0, + DWORD a1, + LPSTR a2, + LPDWORD a3, + LPDWORD a4, + LPDWORD a5, + LPBYTE a6, + LPDWORD a7) + = RegEnumValueA; + +LONG (WINAPI * Real_RegEnumValueW)(HKEY a0, + DWORD a1, + LPWSTR a2, + LPDWORD a3, + LPDWORD a4, + LPDWORD a5, + LPBYTE a6, + LPDWORD a7) + = RegEnumValueW; + +LONG (WINAPI * Real_RegOpenKeyExA)(HKEY a0, + LPCSTR a1, + DWORD a2, + REGSAM a3, + PHKEY a4) + = RegOpenKeyExA; + +LONG (WINAPI * Real_RegOpenKeyExW)(HKEY a0, + LPCWSTR a1, + DWORD a2, + REGSAM a3, + PHKEY a4) + = RegOpenKeyExW; + +LONG (WINAPI * Real_RegQueryInfoKeyA)(HKEY a0, + LPSTR a1, + LPDWORD a2, + LPDWORD a3, + LPDWORD a4, + LPDWORD a5, + LPDWORD a6, + LPDWORD a7, + LPDWORD a8, + LPDWORD a9, + LPDWORD a10, + struct _FILETIME* a11) + = RegQueryInfoKeyA; + +LONG (WINAPI * Real_RegQueryInfoKeyW)(HKEY a0, + LPWSTR a1, + LPDWORD a2, + LPDWORD a3, + LPDWORD a4, + LPDWORD a5, + LPDWORD a6, + LPDWORD a7, + LPDWORD a8, + LPDWORD a9, + LPDWORD a10, + struct _FILETIME* a11) + = RegQueryInfoKeyW; + +LONG (WINAPI * Real_RegQueryValueExA)(HKEY a0, + LPCSTR a1, + LPDWORD a2, + LPDWORD a3, + LPBYTE a4, + LPDWORD a5) + = RegQueryValueExA; + +LONG (WINAPI * Real_RegQueryValueExW)(HKEY a0, + LPCWSTR a1, + LPDWORD a2, + LPDWORD a3, + LPBYTE a4, + LPDWORD a5) + = RegQueryValueExW; + +LONG (WINAPI * Real_RegSetValueExA)(HKEY a0, + LPCSTR a1, + DWORD a2, + DWORD a3, + const BYTE* a4, + DWORD a5) + = RegSetValueExA; + +LONG (WINAPI * Real_RegSetValueExW)(HKEY a0, + LPCWSTR a1, + DWORD a2, + DWORD a3, + const BYTE* a4, + DWORD a5) + = RegSetValueExW; + +HFILE (WINAPI * Real__lcreat)(LPCSTR a0, + int a1) + = _lcreat; + +HFILE (WINAPI * Real__lopen)(LPCSTR a0, + int a1) + = _lopen; + +///////////////////////////////////////////////////////////// +// Detours +// +BOOL WINAPI Mine_WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut) +{ + return Real_WaitNamedPipeW(lpNamedPipeName, nTimeOut); +} + +BOOL WINAPI Mine_CloseHandle(HANDLE hObject) +{ + return Real_CloseHandle(hObject); +} + +VOID WINAPI Mine_GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) +{ + Real_GetSystemTimeAsFileTime(lpSystemTimeAsFileTime); +} + +BOOL WINAPI Mine_SetNamedPipeHandleState(HANDLE hNamedPipe, + LPDWORD lpMode, + LPDWORD lpMaxCollectionCount, + LPDWORD lpCollectDataTimeout) +{ + return Real_SetNamedPipeHandleState(hNamedPipe, + lpMode, + lpMaxCollectionCount, + lpCollectDataTimeout); +} + +BOOL WINAPI Mine_WriteFile(HANDLE hFile, + LPCVOID lpBuffer, + DWORD nNumberOfBytesToWrite, + LPDWORD lpNumberOfBytesWritten, + LPOVERLAPPED lpOverlapped) +{ + return Real_WriteFile(hFile, + lpBuffer, + nNumberOfBytesToWrite, + lpNumberOfBytesWritten, + lpOverlapped); +} + +BOOL WINAPI Mine_CreateProcessW(LPCWSTR lpApplicationName, + LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation) +{ + _PrintEnter("CreateProcessW(%ls,%ls,%p,%p,%x,%x,%p,%ls,%p,%p)\n", + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation); + + _Print("Calling DetourCreateProcessWithDllExW(,%hs)\n", s_szDllPath); + + BOOL rv = 0; + __try { + rv = DetourCreateProcessWithDllExW(lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation, + s_szDllPath, + Real_CreateProcessW); + } __finally { + _PrintExit("CreateProcessW(,,,,,,,,,) -> %x\n", rv); + }; + return rv; +} + +// +////////////////////////////////////////////////////////////////////////////// + +BOOL WINAPI Mine_CopyFileExA(LPCSTR a0, + LPCSTR a1, + LPPROGRESS_ROUTINE a2, + LPVOID a3, + LPBOOL a4, + DWORD a5) +{ + _PrintEnter("CopyFileExA(%hs,%hs,%p,%p,%p,%x)\n", a0, a1, a2, a3, a4, a5); + + BOOL rv = 0; + __try { + rv = Real_CopyFileExA(a0, a1, a2, a3, a4, a5); + } __finally { + _PrintExit("CopyFileExA(,,,,,) -> %x\n", rv); + }; + return rv; +} + +BOOL WINAPI Mine_CopyFileExW(LPCWSTR a0, + LPCWSTR a1, + LPPROGRESS_ROUTINE a2, + LPVOID a3, + LPBOOL a4, + DWORD a5) +{ + _PrintEnter("CopyFileExW(%ls,%ls,%p,%p,%p,%x)\n", a0, a1, a2, a3, a4, a5); + + BOOL rv = 0; + __try { + rv = Real_CopyFileExW(a0, a1, a2, a3, a4, a5); + } __finally { + _PrintExit("CopyFileExW(,,,,,) -> %x\n", rv); + }; + return rv; +} + +BOOL WINAPI Mine_CreateDirectoryExW(LPCWSTR a0, + LPCWSTR a1, + LPSECURITY_ATTRIBUTES a2) +{ + _PrintEnter("CreateDirectoryExW(%ls,%ls,%p)\n", a0, a1, a2); + + BOOL rv = 0; + __try { + rv = Real_CreateDirectoryExW(a0, a1, a2); + } __finally { + _PrintExit("CreateDirectoryExW(,,) -> %x\n", rv); + }; + return rv; +} + +BOOL WINAPI Mine_CreateDirectoryW(LPCWSTR a0, + LPSECURITY_ATTRIBUTES a1) +{ + _PrintEnter("CreateDirectoryW(%ls,%p)\n", a0, a1); + + BOOL rv = 0; + __try { + rv = Real_CreateDirectoryW(a0, a1); + } __finally { + _PrintExit("CreateDirectoryW(,) -> %x\n", rv); + }; + return rv; +} + +HANDLE WINAPI Mine_CreateFileW(LPCWSTR a0, + DWORD a1, + DWORD a2, + LPSECURITY_ATTRIBUTES a3, + DWORD a4, + DWORD a5, + HANDLE a6) +{ + _PrintEnter(NULL); + HANDLE rv = 0; + __try { + rv = Real_CreateFileW(a0, a1, a2, a3, a4, a5, a6); + } __finally { + _PrintExit("CreateFileW(%ls,%x,%x,%p,%x,%x,%p) -> %p\n", + a0, a1, a2, a3, a4, a5, a6, rv); + }; + return rv; +} + +BOOL WINAPI Mine_DeleteFileA(LPCSTR a0) +{ + _PrintEnter("DeleteFileA(%hs)\n", a0); + + BOOL rv = 0; + __try { + rv = Real_DeleteFileA(a0); + } __finally { + _PrintExit("DeleteFileA() -> %x\n", rv); + }; + return rv; +} + +BOOL WINAPI Mine_DeleteFileW(LPCWSTR a0) +{ + _PrintEnter("DeleteFileW(%ls)\n", a0); + + BOOL rv = 0; + __try { + rv = Real_DeleteFileW(a0); + } __finally { + _PrintExit("DeleteFileW() -> %x\n", rv); + }; + return rv; +} + +HANDLE WINAPI Mine_FindFirstFileExA(LPCSTR a0, + FINDEX_INFO_LEVELS a1, + LPVOID a2, + FINDEX_SEARCH_OPS a3, + LPVOID a4, + DWORD a5) +{ + _PrintEnter("FindFirstFileExA(%hs,%p,%p,%x,%p,%x)\n", a0, a1, a2, a3, a4, a5); + + HANDLE rv = 0; + __try { + rv = Real_FindFirstFileExA(a0, a1, a2, a3, a4, a5); + } __finally { + _PrintExit("FindFirstFileExA(,,,,,) -> %p\n", rv); + }; + return rv; +} + +HANDLE WINAPI Mine_FindFirstFileExW(LPCWSTR a0, + FINDEX_INFO_LEVELS a1, + LPVOID a2, + FINDEX_SEARCH_OPS a3, + LPVOID a4, + DWORD a5) +{ + _PrintEnter(NULL); + + HANDLE rv = 0; + __try { + rv = Real_FindFirstFileExW(a0, a1, a2, a3, a4, a5); + } __finally { + _PrintExit("FindFirstFileExW(%ls,%x,%p,%x,%p,%x) -> %p\n", + a0, a1, a2, a3, a4, a5, rv); + }; + return rv; +} + +DWORD WINAPI Mine_GetFileAttributesW(LPCWSTR a0) +{ + _PrintEnter(NULL); + + DWORD rv = 0; + __try { + rv = Real_GetFileAttributesW(a0); + } __finally { + _PrintExit("GetFileAttributesW(%ls) -> %x\n", a0, rv); + }; + return rv; +} + +DWORD WINAPI Mine_GetModuleFileNameW(HMODULE a0, LPWSTR a1, DWORD a2) +{ + _PrintEnter("GetModuleFileNameW(%p,%p,%x)\n", a0, a1, a2); + DWORD rv = 0; + __try { + rv = Real_GetModuleFileNameW(a0, a1, a2); + } __finally { + _PrintExit("GetModuleFileNameW(%p,%p:%ls,%p) -> %p\n", a0, a1, a1, a2, rv); + }; + return rv; +} + +FARPROC WINAPI Mine_GetProcAddress(HINSTANCE a0, + LPCSTR a1) +{ + WCHAR wzModule[MAX_PATH] = L""; + PWCHAR pwzModule = wzModule; + if (Real_GetModuleFileNameW(a0, wzModule, ARRAYSIZE(wzModule)) != 0) { + if ((pwzModule = wcsrchr(wzModule, '\\')) == NULL) { + if ((pwzModule = wcsrchr(wzModule, ':')) == NULL) { + pwzModule = wzModule; + } + else { + pwzModule++; // Skip ':' + } + } + else { + pwzModule++; // Skip '\\' + } + } + else { + wzModule[0] = '\0'; + } + + _PrintEnter(NULL); + FARPROC rv = 0; + __try { + rv = Real_GetProcAddress(a0, a1); + } __finally { + if (pwzModule[0] == 0) { + _PrintExit("GetProcAddress(%p,%hs) -> %p\n", a0, a1, rv); + } + else { + _PrintExit("GetProcAddress(%p:%ls,%hs) -> %p\n", a0, pwzModule, a1, rv); + } + }; + return rv; +} + +HMODULE WINAPI Mine_LoadLibraryExW(LPCWSTR a0, + HANDLE a1, + DWORD a2) +{ + _PrintEnter("LoadLibraryExW(%ls,%p,%x)\n", a0, a1, a2); + + HMODULE rv = 0; + __try { + rv = Real_LoadLibraryExW(a0, a1, a2); + } __finally { + _PrintExit("LoadLibraryExW(,,) -> %p\n", rv); + if (rv) { + InstanceEnumerate(rv); + } + }; + return rv; +} + +BOOL WINAPI Mine_MoveFileA(LPCSTR a0, + LPCSTR a1) +{ + _PrintEnter("MoveFileA(%hs,%hs)\n", a0, a1); + + BOOL rv = 0; + __try { + rv = Real_MoveFileA(a0, a1); + } __finally { + _PrintExit("MoveFileA(,) -> %x\n", rv); + }; + return rv; +} + +BOOL WINAPI Mine_MoveFileExA(LPCSTR a0, + LPCSTR a1, + DWORD a2) +{ + _PrintEnter("MoveFileExA(%hs,%hs,%x)\n", a0, a1, a2); + + BOOL rv = 0; + __try { + rv = Real_MoveFileExA(a0, a1, a2); + } __finally { + _PrintExit("MoveFileExA(,,) -> %x\n", rv); + }; + return rv; +} + +BOOL WINAPI Mine_MoveFileExW(LPCWSTR a0, + LPCWSTR a1, + DWORD a2) +{ + _PrintEnter("MoveFileExW(%ls,%ls,%x)\n", a0, a1, a2); + + BOOL rv = 0; + __try { + rv = Real_MoveFileExW(a0, a1, a2); + } __finally { + _PrintExit("MoveFileExW(,,) -> %x\n", rv); + }; + return rv; +} + +BOOL WINAPI Mine_MoveFileW(LPCWSTR a0, + LPCWSTR a1) +{ + _PrintEnter("MoveFileW(%ls,%ls)\n", a0, a1); + + BOOL rv = 0; + __try { + rv = Real_MoveFileW(a0, a1); + } __finally { + _PrintExit("MoveFileW(,) -> %x\n", rv); + }; + return rv; +} + +HFILE WINAPI Mine_OpenFile(LPCSTR a0, + LPOFSTRUCT a1, + UINT a2) +{ + _PrintEnter("OpenFile(%hs,%p,%x)\n", a0, a1, a2); + + HFILE rv = 0; + __try { + rv = Real_OpenFile(a0, a1, a2); + } __finally { + _PrintExit("OpenFile(,,) -> %p\n", rv); + }; + return rv; +} + +LONG WINAPI Mine_RegCreateKeyExA(HKEY a0, + LPCSTR a1, + DWORD a2, + LPSTR a3, + DWORD a4, + REGSAM a5, + LPSECURITY_ATTRIBUTES a6, + PHKEY a7, + LPDWORD a8) +{ + _PrintEnter("RegCreateKeyExA(%p,%hs,%x,%hs,%x,%x,%p,%p,%p)\n", a0, a1, a2, a3, a4, a5, a6, a7, a8); + + LONG rv = 0; + __try { + rv = Real_RegCreateKeyExA(a0, a1, a2, a3, a4, a5, a6, a7, a8); + } __finally { + _PrintExit("RegCreateKeyExA(,,,,,,,,) -> %x\n", rv); + }; + return rv; +} + +LONG WINAPI Mine_RegCreateKeyExW(HKEY a0, + LPCWSTR a1, + DWORD a2, + LPWSTR a3, + DWORD a4, + REGSAM a5, + LPSECURITY_ATTRIBUTES a6, + PHKEY a7, + LPDWORD a8) +{ + _PrintEnter(NULL); + LONG rv = 0; + __try { + rv = Real_RegCreateKeyExW(a0, a1, a2, a3, a4, a5, a6, a7, a8); + } __finally { + _PrintExit("RegCreateKeyExW(%p,%ls,%x,%ls,%x,%x,%p,%p,%p) -> %x\n", + a0, a1, a2, a3, a4, a5, a6, a7, a8, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegDeleteKeyA(HKEY a0, + LPCSTR a1) +{ + _PrintEnter(NULL); + LONG rv = 0; + __try { + rv = Real_RegDeleteKeyA(a0, a1); + } __finally { + _PrintExit("RegDeleteKeyA(%p,%hs) -> %x\n", a0, a1, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegDeleteKeyW(HKEY a0, + LPCWSTR a1) +{ + _PrintEnter(NULL); + LONG rv = 0; + __try { + rv = Real_RegDeleteKeyW(a0, a1); + } __finally { + _PrintExit("RegDeleteKeyW(%p,%ls) -> %x\n", a0, a1, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegDeleteValueA(HKEY a0, + LPCSTR a1) +{ + _PrintEnter("RegDeleteValueA(%p,%hs)\n", a0, a1); + + LONG rv = 0; + __try { + rv = Real_RegDeleteValueA(a0, a1); + } __finally { + _PrintExit("RegDeleteValueA(,) -> %x\n", rv); + }; + return rv; +} + +LONG WINAPI Mine_RegDeleteValueW(HKEY a0, + LPCWSTR a1) +{ + _PrintEnter("RegDeleteValueW(%p,%ls)\n", a0, a1); + + LONG rv = 0; + __try { + rv = Real_RegDeleteValueW(a0, a1); + } __finally { + _PrintExit("RegDeleteValueW(,) -> %x\n", rv); + }; + return rv; +} + +LONG WINAPI Mine_RegEnumKeyExA(HKEY a0, + DWORD a1, + LPSTR a2, + LPDWORD a3, + LPDWORD a4, + LPSTR a5, + LPDWORD a6, + LPFILETIME a7) +{ + _PrintEnter("RegEnumKeyExA(%p,%x,%p,%p,%p,%hs,%p,%p)\n", a0, a1, a2, a3, a4, a5, a6, a7); + + LONG rv = 0; + __try { + rv = Real_RegEnumKeyExA(a0, a1, a2, a3, a4, a5, a6, a7); + } __finally { + _PrintExit("RegEnumKeyExA(,,%hs,,,%hs,,) -> %x\n", a2, a5, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegEnumKeyExW(HKEY a0, + DWORD a1, + LPWSTR a2, + LPDWORD a3, + LPDWORD a4, + LPWSTR a5, + LPDWORD a6, + struct _FILETIME* a7) +{ + _PrintEnter("RegEnumKeyExW(%p,%x,%p,%p,%p,%ls,%p,%p)\n", a0, a1, a2, a3, a4, a5, a6, a7); + + LONG rv = 0; + __try { + rv = Real_RegEnumKeyExW(a0, a1, a2, a3, a4, a5, a6, a7); + } __finally { + _PrintExit("RegEnumKeyExW(,,%ls,,,%ls,,) -> %x\n", a2, a5, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegEnumValueA(HKEY a0, + DWORD a1, + LPSTR a2, + LPDWORD a3, + LPDWORD a4, + LPDWORD a5, + LPBYTE a6, + LPDWORD a7) +{ + _PrintEnter("RegEnumValueA(%p,%x,%p,%p,%p,%p,%p,%p)\n", a0, a1, a2, a3, a4, a5, a6, a7); + + LONG rv = 0; + __try { + rv = Real_RegEnumValueA(a0, a1, a2, a3, a4, a5, a6, a7); + } __finally { + _PrintExit("RegEnumValueA(,,%hs,,,,,) -> %x\n", a2, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegEnumValueW(HKEY a0, + DWORD a1, + LPWSTR a2, + LPDWORD a3, + LPDWORD a4, + LPDWORD a5, + LPBYTE a6, + LPDWORD a7) +{ + _PrintEnter("RegEnumValueW(%p,%x,%p,%p,%p,%p,%p,%p)\n", a0, a1, a2, a3, a4, a5, a6, a7); + + LONG rv = 0; + __try { + rv = Real_RegEnumValueW(a0, a1, a2, a3, a4, a5, a6, a7); + } __finally { + _PrintExit("RegEnumValueW(,,%ls,,,,,) -> %x\n", a2, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegOpenKeyExA(HKEY a0, + LPCSTR a1, + DWORD a2, + REGSAM a3, + PHKEY a4) +{ + _PrintEnter(NULL); + + LONG rv = 0; + __try { + rv = Real_RegOpenKeyExA(a0, a1, a2, a3, a4); + } __finally { + _PrintExit("RegOpenKeyExA(%p,%hs,%x,%x,%p) -> %x\n", + a0, a1, a2, a3, a4, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegOpenKeyExW(HKEY a0, + LPCWSTR a1, + DWORD a2, + REGSAM a3, + PHKEY a4) +{ + _PrintEnter(NULL); + + LONG rv = 0; + __try { + rv = Real_RegOpenKeyExW(a0, a1, a2, a3, a4); + } __finally { + _PrintExit("RegOpenKeyExW(%p,%ls,%x,%x,%p) -> %x\n", + a0, a1, a2, a3, a4, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegQueryInfoKeyA(HKEY a0, + LPSTR a1, + LPDWORD a2, + LPDWORD a3, + LPDWORD a4, + LPDWORD a5, + LPDWORD a6, + LPDWORD a7, + LPDWORD a8, + LPDWORD a9, + LPDWORD a10, + LPFILETIME a11) +{ + _PrintEnter("RegQueryInfoKeyA(%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p)\n", + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + + LONG rv = 0; + __try { + rv = Real_RegQueryInfoKeyA(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + } __finally { + _PrintExit("RegQueryInfoKeyA(,%hs,,,,,,,,,,) -> %x\n", a1, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegQueryInfoKeyW(HKEY a0, + LPWSTR a1, + LPDWORD a2, + LPDWORD a3, + LPDWORD a4, + LPDWORD a5, + LPDWORD a6, + LPDWORD a7, + LPDWORD a8, + LPDWORD a9, + LPDWORD a10, + LPFILETIME a11) +{ + _PrintEnter("RegQueryInfoKeyW(%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p)\n", + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + + LONG rv = 0; + __try { + rv = Real_RegQueryInfoKeyW(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + } __finally { + _PrintExit("RegQueryInfoKeyW(,%ls,,,,,,,,,,) -> %x\n", a1, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegQueryValueExA(HKEY a0, + LPCSTR a1, + LPDWORD a2, + LPDWORD a3, + LPBYTE a4, + LPDWORD a5) +{ + _PrintEnter(NULL); + + LONG rv = 0; + __try { + rv = Real_RegQueryValueExA(a0, a1, a2, a3, a4, a5); + } __finally { + _PrintExit("RegQueryValueExA(%p,%hs,%p,%p,%p,%p) -> %x\n", + a0, a1, a2, a3, a4, a5, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegQueryValueExW(HKEY a0, + LPCWSTR a1, + LPDWORD a2, + LPDWORD a3, + LPBYTE a4, + LPDWORD a5) +{ + _PrintEnter(NULL); + LONG rv = 0; + __try { + rv = Real_RegQueryValueExW(a0, a1, a2, a3, a4, a5); + } __finally { + _PrintExit("RegQueryValueExW(%p,%ls,%p,%p,%p,%p) -> %x\n", + a0, a1, a2, a3, a4, a5, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegSetValueExA(HKEY a0, + LPCSTR a1, + DWORD a2, + DWORD a3, + BYTE* a4, + DWORD a5) +{ + _PrintEnter(NULL); + LONG rv = 0; + __try { + rv = Real_RegSetValueExA(a0, a1, a2, a3, a4, a5); + } __finally { + _PrintExit("RegSetValueExA(%p,%hs,%x,%x,%p,%x) -> %x\n", + a0, a1, a2, a3, a4, a5, rv); + }; + return rv; +} + +LONG WINAPI Mine_RegSetValueExW(HKEY a0, + LPCWSTR a1, + DWORD a2, + DWORD a3, + BYTE* a4, + DWORD a5) +{ + _PrintEnter(NULL); + LONG rv = 0; + __try { + rv = Real_RegSetValueExW(a0, a1, a2, a3, a4, a5); + } __finally { + _PrintExit("RegSetValueExW(%p,%ls,%x,%x,%p,%x) -> %x\n", + a0, a1, a2, a3, a4, a5, rv); + }; + return rv; +} + +HFILE WINAPI Mine__lcreat(LPCSTR a0, int a1) +{ + _PrintEnter(NULL); + HFILE rv = 0; + __try { + rv = Real__lcreat(a0, a1); + } __finally { + _PrintExit("_lcreat(%hs,%x) -> %p\n", a0, a1, rv); + }; + return rv; +} + +HFILE WINAPI Mine__lopen(LPCSTR a0, int a1) +{ + _PrintEnter(NULL); + HFILE rv = 0; + __try { + rv = Real__lopen(a0, a1); + } __finally { + _PrintEnter("_lopen(%hs,%x) -> %p\n", a0, a1, rv); + }; + return rv; +} + +///////////////////////////////////////////////////////////// +// AttachDetours +// +PCHAR DetRealName(PCHAR psz) +{ + PCHAR pszBeg = psz; + // Move to end of name. + while (*psz) { + psz++; + } + // Move back through A-Za-z0-9 names. + while (psz > pszBeg && + ((psz[-1] >= 'A' && psz[-1] <= 'Z') || + (psz[-1] >= 'a' && psz[-1] <= 'z') || + (psz[-1] >= '0' && psz[-1] <= '9'))) { + psz--; + } + return psz; +} + +VOID DetAttach(PVOID *ppbReal, PVOID pbMine, PCHAR psz) +{ + LONG l = DetourAttach(ppbReal, pbMine); + if (l != 0) { + Syelog(SYELOG_SEVERITY_NOTICE, + "Attach failed: `%s': error %d\n", DetRealName(psz), l); + } +} + +VOID DetDetach(PVOID *ppbReal, PVOID pbMine, PCHAR psz) +{ + LONG l = DetourDetach(ppbReal, pbMine); + if (l != 0) { + Syelog(SYELOG_SEVERITY_NOTICE, + "Detach failed: `%s': error %d\n", DetRealName(psz), l); + } +} + +#define ATTACH(x) DetAttach(&(PVOID&)Real_##x,Mine_##x,#x) +#define DETACH(x) DetDetach(&(PVOID&)Real_##x,Mine_##x,#x) + +LONG AttachDetours(VOID) +{ + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + ATTACH(CloseHandle); + ATTACH(CopyFileExA); + ATTACH(CopyFileExW); + ATTACH(CreateDirectoryExW); + ATTACH(CreateDirectoryW); + ATTACH(CreateFileW); + ATTACH(CreateProcessW); + ATTACH(DeleteFileA); + ATTACH(DeleteFileW); + ATTACH(FindFirstFileExA); + ATTACH(FindFirstFileExW); + ATTACH(GetFileAttributesW); + ATTACH(GetModuleFileNameW); + ATTACH(GetProcAddress); + ATTACH(GetSystemTimeAsFileTime); + ATTACH(LoadLibraryExW); + ATTACH(MoveFileA); + ATTACH(MoveFileExA); + ATTACH(MoveFileExW); + ATTACH(MoveFileW); + ATTACH(OpenFile); + ATTACH(RegCreateKeyExA); + ATTACH(RegCreateKeyExW); + ATTACH(RegDeleteKeyA); + ATTACH(RegDeleteKeyW); + ATTACH(RegDeleteValueA); + ATTACH(RegDeleteValueW); + ATTACH(RegEnumKeyExA); + ATTACH(RegEnumKeyExW); + ATTACH(RegEnumValueA); + ATTACH(RegEnumValueW); + ATTACH(RegOpenKeyExA); + ATTACH(RegOpenKeyExW); + ATTACH(RegQueryInfoKeyA); + ATTACH(RegQueryInfoKeyW); + ATTACH(RegQueryValueExA); + ATTACH(RegQueryValueExW); + ATTACH(RegSetValueExA); + ATTACH(RegSetValueExW); + ATTACH(SetNamedPipeHandleState); + ATTACH(WaitNamedPipeW); + ATTACH(WriteFile); + ATTACH(_lcreat); + ATTACH(_lopen); + + return DetourTransactionCommit(); +} + +LONG DetachDetours(VOID) +{ + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + DETACH(CloseHandle); + DETACH(CopyFileExA); + DETACH(CopyFileExW); + DETACH(CreateDirectoryExW); + DETACH(CreateDirectoryW); + DETACH(CreateFileW); + DETACH(CreateProcessW); + DETACH(DeleteFileA); + DETACH(DeleteFileW); + DETACH(FindFirstFileExA); + DETACH(FindFirstFileExW); + DETACH(GetFileAttributesW); + DETACH(GetModuleFileNameW); + DETACH(GetProcAddress); + DETACH(GetSystemTimeAsFileTime); + DETACH(LoadLibraryExW); + DETACH(MoveFileA); + DETACH(MoveFileExA); + DETACH(MoveFileExW); + DETACH(MoveFileW); + DETACH(OpenFile); + DETACH(RegCreateKeyExA); + DETACH(RegCreateKeyExW); + DETACH(RegDeleteKeyA); + DETACH(RegDeleteKeyW); + DETACH(RegDeleteValueA); + DETACH(RegDeleteValueW); + DETACH(RegEnumKeyExA); + DETACH(RegEnumKeyExW); + DETACH(RegEnumValueA); + DETACH(RegEnumValueW); + DETACH(RegOpenKeyExA); + DETACH(RegOpenKeyExW); + DETACH(RegQueryInfoKeyA); + DETACH(RegQueryInfoKeyW); + DETACH(RegQueryValueExA); + DETACH(RegQueryValueExW); + DETACH(RegSetValueExA); + DETACH(RegSetValueExW); + DETACH(SetNamedPipeHandleState); + DETACH(WaitNamedPipeW); + DETACH(WriteFile); + DETACH(_lcreat); + DETACH(_lopen); + + return DetourTransactionCommit(); +} +// +////////////////////////////////////////////////////////////////////////////// + + +////////////////////////////////////////////////////////////// Logging System. +// +static BOOL s_bLog = 1; +static LONG s_nTlsIndent = -1; +static LONG s_nTlsThread = -1; +static LONG s_nThreadCnt = 0; + +VOID _PrintEnter(const CHAR *psz, ...) +{ + DWORD dwErr = GetLastError(); + + LONG nIndent = 0; + LONG nThread = 0; + if (s_nTlsIndent >= 0) { + nIndent = (LONG)(LONG_PTR)TlsGetValue(s_nTlsIndent); + TlsSetValue(s_nTlsIndent, (PVOID)(LONG_PTR)(nIndent + 1)); + } + if (s_nTlsThread >= 0) { + nThread = (LONG)(LONG_PTR)TlsGetValue(s_nTlsThread); + } + + if (s_bLog && psz) { + CHAR szBuf[1024]; + PCHAR pszBuf = szBuf; + PCHAR pszEnd = szBuf + ARRAYSIZE(szBuf) - 1; + LONG nLen = (nIndent > 0) ? (nIndent < 35 ? nIndent * 2 : 70) : 0; + *pszBuf++ = (CHAR)('0' + ((nThread / 100) % 10)); + *pszBuf++ = (CHAR)('0' + ((nThread / 10) % 10)); + *pszBuf++ = (CHAR)('0' + ((nThread / 1) % 10)); + *pszBuf++ = ' '; + while (nLen-- > 0) { + *pszBuf++ = ' '; + } + + va_list args; + va_start(args, psz); + + while ((*pszBuf++ = *psz++) != 0 && pszBuf < pszEnd) { + // Copy characters. + } + *pszEnd = '\0'; + SyelogV(SYELOG_SEVERITY_INFORMATION, + szBuf, args); + + va_end(args); + } + SetLastError(dwErr); +} + +VOID _PrintExit(const CHAR *psz, ...) +{ + DWORD dwErr = GetLastError(); + + LONG nIndent = 0; + LONG nThread = 0; + if (s_nTlsIndent >= 0) { + nIndent = (LONG)(LONG_PTR)TlsGetValue(s_nTlsIndent) - 1; + ASSERT(nIndent >= 0); + TlsSetValue(s_nTlsIndent, (PVOID)(LONG_PTR)nIndent); + } + if (s_nTlsThread >= 0) { + nThread = (LONG)(LONG_PTR)TlsGetValue(s_nTlsThread); + } + + if (s_bLog && psz) { + CHAR szBuf[1024]; + PCHAR pszBuf = szBuf; + PCHAR pszEnd = szBuf + ARRAYSIZE(szBuf) - 1; + LONG nLen = (nIndent > 0) ? (nIndent < 35 ? nIndent * 2 : 70) : 0; + *pszBuf++ = (CHAR)('0' + ((nThread / 100) % 10)); + *pszBuf++ = (CHAR)('0' + ((nThread / 10) % 10)); + *pszBuf++ = (CHAR)('0' + ((nThread / 1) % 10)); + *pszBuf++ = ' '; + while (nLen-- > 0) { + *pszBuf++ = ' '; + } + + va_list args; + va_start(args, psz); + + while ((*pszBuf++ = *psz++) != 0 && pszBuf < pszEnd) { + // Copy characters. + } + *pszEnd = '\0'; + SyelogV(SYELOG_SEVERITY_INFORMATION, + szBuf, args); + + va_end(args); + } + SetLastError(dwErr); +} + +VOID _Print(const CHAR *psz, ...) +{ + DWORD dwErr = GetLastError(); + + LONG nIndent = 0; + LONG nThread = 0; + if (s_nTlsIndent >= 0) { + nIndent = (LONG)(LONG_PTR)TlsGetValue(s_nTlsIndent); + } + if (s_nTlsThread >= 0) { + nThread = (LONG)(LONG_PTR)TlsGetValue(s_nTlsThread); + } + + if (s_bLog && psz) { + CHAR szBuf[1024]; + PCHAR pszBuf = szBuf; + PCHAR pszEnd = szBuf + ARRAYSIZE(szBuf) - 1; + LONG nLen = (nIndent > 0) ? (nIndent < 35 ? nIndent * 2 : 70) : 0; + *pszBuf++ = (CHAR)('0' + ((nThread / 100) % 10)); + *pszBuf++ = (CHAR)('0' + ((nThread / 10) % 10)); + *pszBuf++ = (CHAR)('0' + ((nThread / 1) % 10)); + *pszBuf++ = ' '; + while (nLen-- > 0) { + *pszBuf++ = ' '; + } + + va_list args; + va_start(args, psz); + + while ((*pszBuf++ = *psz++) != 0 && pszBuf < pszEnd) { + // Copy characters. + } + *pszEnd = '\0'; + SyelogV(SYELOG_SEVERITY_INFORMATION, + szBuf, args); + + va_end(args); + } + + SetLastError(dwErr); +} + +VOID AssertMessage(CONST PCHAR pszMsg, CONST PCHAR pszFile, ULONG nLine) +{ + Syelog(SYELOG_SEVERITY_FATAL, + "ASSERT(%s) failed in %s, line %d.\n", pszMsg, pszFile, nLine); +} + +////////////////////////////////////////////////////////////////////////////// +// +PIMAGE_NT_HEADERS NtHeadersForInstance(HINSTANCE hInst) +{ + PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hInst; + __try { + if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { + SetLastError(ERROR_BAD_EXE_FORMAT); + return NULL; + } + + PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + + pDosHeader->e_lfanew); + if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { + SetLastError(ERROR_INVALID_EXE_SIGNATURE); + return NULL; + } + if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) { + SetLastError(ERROR_EXE_MARKED_INVALID); + return NULL; + } + return pNtHeader; + } __except(EXCEPTION_EXECUTE_HANDLER) { + } + SetLastError(ERROR_EXE_MARKED_INVALID); + + return NULL; +} + +BOOL InstanceEnumerate(HINSTANCE hInst) +{ + WCHAR wzDllName[MAX_PATH]; + + PIMAGE_NT_HEADERS pinh = NtHeadersForInstance(hInst); + if (pinh && Real_GetModuleFileNameW(hInst, wzDllName, ARRAYSIZE(wzDllName))) { + Syelog(SYELOG_SEVERITY_INFORMATION, + "### %08lx: %-43.43ls %08x\n", + hInst, wzDllName, pinh->OptionalHeader.CheckSum); + return TRUE; + } + return FALSE; +} + +BOOL ProcessEnumerate() +{ + Syelog(SYELOG_SEVERITY_INFORMATION, + "######################################################### Binaries\n"); + for (HINSTANCE hInst = NULL; (hInst = DetourEnumerateModules(hInst)) != NULL;) { + InstanceEnumerate(hInst); + } + return TRUE; +} + +////////////////////////////////////////////////////////////////////////////// +// +// DLL module information +// +BOOL ThreadAttach(HMODULE hDll) +{ + (void)hDll; + + if (s_nTlsIndent >= 0) { + TlsSetValue(s_nTlsIndent, (PVOID)0); + } + if (s_nTlsThread >= 0) { + LONG nThread = InterlockedIncrement(&s_nThreadCnt); + TlsSetValue(s_nTlsThread, (PVOID)(LONG_PTR)nThread); + } + return TRUE; +} + +BOOL ThreadDetach(HMODULE hDll) +{ + (void)hDll; + + if (s_nTlsIndent >= 0) { + TlsSetValue(s_nTlsIndent, (PVOID)0); + } + if (s_nTlsThread >= 0) { + TlsSetValue(s_nTlsThread, (PVOID)0); + } + return TRUE; +} + +BOOL ProcessAttach(HMODULE hDll) +{ + s_bLog = FALSE; + s_nTlsIndent = TlsAlloc(); + s_nTlsThread = TlsAlloc(); + + s_hInst = hDll; + Real_GetModuleFileNameA(s_hInst, s_szDllPath, ARRAYSIZE(s_szDllPath)); + + SyelogOpen("trcreg" DETOURS_STRINGIFY(DETOURS_BITS), SYELOG_FACILITY_APPLICATION); + ProcessEnumerate(); + + LONG error = AttachDetours(); + if (error != NO_ERROR) { + Syelog(SYELOG_SEVERITY_FATAL, "### Error attaching detours: %d\n", error); + } + + ThreadAttach(hDll); + + s_bLog = TRUE; + return TRUE; +} + +BOOL ProcessDetach(HMODULE hDll) +{ + ThreadDetach(hDll); + s_bLog = FALSE; + + LONG error = DetachDetours(); + if (error != NO_ERROR) { + Syelog(SYELOG_SEVERITY_FATAL, "### Error detaching detours: %d\n", error); + } + + Syelog(SYELOG_SEVERITY_NOTICE, "### Closing.\n"); + SyelogClose(FALSE); + + if (s_nTlsIndent >= 0) { + TlsFree(s_nTlsIndent); + } + if (s_nTlsThread >= 0) { + TlsFree(s_nTlsThread); + } + return TRUE; +} + +BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, PVOID lpReserved) +{ + (void)hModule; + (void)lpReserved; + + if (DetourIsHelperProcess()) { + return TRUE; + } + + switch (dwReason) { + case DLL_PROCESS_ATTACH: + DetourRestoreAfterWith(); + return ProcessAttach(hModule); + case DLL_PROCESS_DETACH: + return ProcessDetach(hModule); + case DLL_THREAD_ATTACH: + return ThreadAttach(hModule); + case DLL_THREAD_DETACH: + return ThreadDetach(hModule); + } + return TRUE; +} +// +///////////////////////////////////////////////////////////////// End of File. diff --git a/samples/tracereg/trcreg.rc b/samples/tracereg/trcreg.rc new file mode 100644 index 0000000..37adf3c --- /dev/null +++ b/samples/tracereg/trcreg.rc @@ -0,0 +1,17 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Version information for trcreg.rc. +// +// Microsoft Research Detours Package +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +#include "detver.h" + +#define VER_INTERNALNAME_STR "trcreg" DETOURS_STRINGIFY(DETOURS_BITS) +#define VER_ORIGINALFILENAME_STR "trcreg" DETOURS_STRINGIFY(DETOURS_BITS) ".dll" +#define VER_FILEDESCRIPTION_STR "Detours Registry Trace Module" +#define VER_COMPANYNAME_STR "Microsoft Corporation" + +#include "common.ver" |