ZLUDA/ext/detours/samples/tracereg/trcreg.cpp
2021-01-03 17:52:14 +01:00

1577 lines
46 KiB
C++
Vendored

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