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

1180 lines
32 KiB
C++
Vendored

//////////////////////////////////////////////////////////////////////////////
//
// Detours Test Program (trcser.cpp of trcser.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];
VOID _PrintDump(HANDLE h, PCHAR pszData, INT cbData);
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;
}
DWORD (WINAPI * Real_GetModuleFileNameW)(HMODULE a0,
LPWSTR a1,
DWORD a2)
= GetModuleFileNameW;
DWORD (WINAPI * Real_GetModuleFileNameA)(HMODULE a0,
LPSTR a1,
DWORD a2)
= GetModuleFileNameA;
BOOL (WINAPI * Real_CreateProcessW)(LPCWSTR a0,
LPWSTR a1,
LPSECURITY_ATTRIBUTES a2,
LPSECURITY_ATTRIBUTES a3,
BOOL a4,
DWORD a5,
LPVOID a6,
LPCWSTR a7,
struct _STARTUPINFOW* a8,
LPPROCESS_INFORMATION a9)
= CreateProcessW;
BOOL (WINAPI * Real_BuildCommDCBA)(LPCSTR a0,
struct _DCB* a1)
= BuildCommDCBA;
BOOL (WINAPI * Real_BuildCommDCBAndTimeoutsA)(LPCSTR a0,
struct _DCB* a1,
struct _COMMTIMEOUTS* a2)
= BuildCommDCBAndTimeoutsA;
BOOL (WINAPI * Real_BuildCommDCBAndTimeoutsW)(LPCWSTR a0,
struct _DCB* a1,
struct _COMMTIMEOUTS* a2)
= BuildCommDCBAndTimeoutsW;
BOOL (WINAPI * Real_BuildCommDCBW)(LPCWSTR a0,
struct _DCB* a1)
= BuildCommDCBW;
BOOL (WINAPI * Real_ClearCommBreak)(HANDLE a0)
= ClearCommBreak;
BOOL (WINAPI * Real_ClearCommError)(HANDLE a0,
LPDWORD a1,
struct _COMSTAT* a2)
= ClearCommError;
HANDLE (WINAPI * Real_CreateFileA)(LPCSTR a0,
DWORD a1,
DWORD a2,
LPSECURITY_ATTRIBUTES a3,
DWORD a4,
DWORD a5,
HANDLE a6)
= CreateFileA;
BOOL (WINAPI * Real_EscapeCommFunction)(HANDLE a0,
DWORD a1)
= EscapeCommFunction;
BOOL (WINAPI * Real_GetCommConfig)(HANDLE a0,
LPCOMMCONFIG a1,
LPDWORD a2)
= GetCommConfig;
BOOL (WINAPI * Real_GetCommMask)(HANDLE a0,
LPDWORD a1)
= GetCommMask;
BOOL (WINAPI * Real_GetCommModemStatus)(HANDLE a0,
LPDWORD a1)
= GetCommModemStatus;
BOOL (WINAPI * Real_GetCommProperties)(HANDLE a0,
LPCOMMPROP a1)
= GetCommProperties;
BOOL (WINAPI * Real_GetCommState)(HANDLE a0,
struct _DCB* a1)
= GetCommState;
BOOL (WINAPI * Real_GetCommTimeouts)(HANDLE a0,
struct _COMMTIMEOUTS* a1)
= GetCommTimeouts;
DWORD (WINAPI * Real_GetCurrentThreadId)(void)
= GetCurrentThreadId;
BOOL (WINAPI * Real_GetOverlappedResult)(HANDLE a0,
LPOVERLAPPED a1,
LPDWORD a2,
BOOL a3)
= GetOverlappedResult;
BOOL (WINAPI * Real_PurgeComm)(HANDLE a0,
DWORD a1)
= PurgeComm;
BOOL (WINAPI * Real_ReadFile)(HANDLE a0,
LPVOID a1,
DWORD a2,
LPDWORD a3,
LPOVERLAPPED a4)
= ReadFile;
BOOL (WINAPI * Real_SetCommBreak)(HANDLE a0)
= SetCommBreak;
BOOL (WINAPI * Real_SetCommConfig)(HANDLE a0,
LPCOMMCONFIG a1,
DWORD a2)
= SetCommConfig;
BOOL (WINAPI * Real_SetCommMask)(HANDLE a0,
DWORD a1)
= SetCommMask;
BOOL (WINAPI * Real_SetCommState)(HANDLE a0,
struct _DCB* a1)
= SetCommState;
BOOL (WINAPI * Real_SetCommTimeouts)(HANDLE a0,
struct _COMMTIMEOUTS* a1)
= SetCommTimeouts;
BOOL (WINAPI * Real_SetupComm)(HANDLE a0,
DWORD a1,
DWORD a2)
= SetupComm;
BOOL (WINAPI * Real_TransmitCommChar)(HANDLE a0,
char a1)
= TransmitCommChar;
BOOL (WINAPI * Real_WaitCommEvent)(HANDLE a0,
LPDWORD a1,
LPOVERLAPPED a2)
= WaitCommEvent;
/////////////////////////////////////////////////////////////
// Detours
//
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_BuildCommDCBA(LPCSTR a0,
LPDCB a1)
{
_PrintEnter("BuildCommDCBA(%hs,%p)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_BuildCommDCBA(a0, a1);
} __finally {
_PrintExit("BuildCommDCBA(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_BuildCommDCBAndTimeoutsA(LPCSTR a0,
LPDCB a1,
LPCOMMTIMEOUTS a2)
{
_PrintEnter("BuildCommDCBAndTimeoutsA(%hs,%p,%p)\n", a0, a1, a2);
BOOL rv = 0;
__try {
rv = Real_BuildCommDCBAndTimeoutsA(a0, a1, a2);
} __finally {
_PrintExit("BuildCommDCBAndTimeoutsA(,,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_BuildCommDCBAndTimeoutsW(LPCWSTR a0,
LPDCB a1,
LPCOMMTIMEOUTS a2)
{
_PrintEnter("BuildCommDCBAndTimeoutsW(%ls,%p,%p)\n", a0, a1, a2);
BOOL rv = 0;
__try {
rv = Real_BuildCommDCBAndTimeoutsW(a0, a1, a2);
} __finally {
_PrintExit("BuildCommDCBAndTimeoutsW(,,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_BuildCommDCBW(LPCWSTR a0,
LPDCB a1)
{
_PrintEnter("BuildCommDCBW(%ls,%p)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_BuildCommDCBW(a0, a1);
} __finally {
_PrintExit("BuildCommDCBW(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_ClearCommBreak(HANDLE a0)
{
_PrintEnter("ClearCommBreak(%p)\n", a0);
BOOL rv = 0;
__try {
rv = Real_ClearCommBreak(a0);
} __finally {
_PrintExit("ClearCommBreak() -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_ClearCommError(HANDLE a0,
LPDWORD a1,
LPCOMSTAT a2)
{
_PrintEnter("ClearCommError(%p,%p,%p)\n", a0, a1, a2);
BOOL rv = 0;
__try {
rv = Real_ClearCommError(a0, a1, a2);
} __finally {
_PrintExit("ClearCommError(,,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_CloseHandle(HANDLE a0)
{
_PrintEnter("CloseHandle(%p)\n", a0);
BOOL rv = 0;
__try {
rv = Real_CloseHandle(a0);
} __finally {
_PrintExit("CloseHandle() -> %x\n", rv);
};
return rv;
}
HANDLE WINAPI Mine_CreateFileA(LPCSTR a0,
DWORD a1,
DWORD a2,
LPSECURITY_ATTRIBUTES a3,
DWORD a4,
DWORD a5,
HANDLE a6)
{
_PrintEnter("CreateFileA(%hs,%x,%x,%p,%x,%x,%p)\n", a0, a1, a2, a3, a4, a5, a6);
HANDLE rv = 0;
__try {
rv = Real_CreateFileA(a0, a1, a2, a3, a4, a5, a6);
} __finally {
_PrintExit("CreateFileA(,,,,,,) -> %p\n", rv);
};
return rv;
}
HANDLE WINAPI Mine_CreateFileW(LPCWSTR a0,
DWORD a1,
DWORD a2,
LPSECURITY_ATTRIBUTES a3,
DWORD a4,
DWORD a5,
HANDLE a6)
{
_PrintEnter("CreateFileW(%ls,%x,%x,%p,%x,%x,%p)\n", a0, a1, a2, a3, a4, a5, a6);
HANDLE rv = 0;
__try {
rv = Real_CreateFileW(a0, a1, a2, a3, a4, a5, a6);
} __finally {
_PrintExit("CreateFileW(,,,,,,) -> %p\n", rv);
};
return rv;
}
BOOL WINAPI Mine_EscapeCommFunction(HANDLE a0,
DWORD a1)
{
_PrintEnter("EscapeCommFunction(%p,%x)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_EscapeCommFunction(a0, a1);
} __finally {
_PrintExit("EscapeCommFunction(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_GetCommConfig(HANDLE a0,
LPCOMMCONFIG a1,
LPDWORD a2)
{
_PrintEnter("GetCommConfig(%p,%p,%p)\n", a0, a1, a2);
BOOL rv = 0;
__try {
rv = Real_GetCommConfig(a0, a1, a2);
} __finally {
_PrintExit("GetCommConfig(,,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_GetCommMask(HANDLE a0,
LPDWORD a1)
{
_PrintEnter("GetCommMask(%p,%p)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_GetCommMask(a0, a1);
} __finally {
_PrintExit("GetCommMask(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_GetCommModemStatus(HANDLE a0,
LPDWORD a1)
{
_PrintEnter("GetCommModemStatus(%p,%p)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_GetCommModemStatus(a0, a1);
} __finally {
_PrintExit("GetCommModemStatus(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_GetCommProperties(HANDLE a0,
LPCOMMPROP a1)
{
_PrintEnter("GetCommProperties(%p,%p)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_GetCommProperties(a0, a1);
} __finally {
_PrintExit("GetCommProperties(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_GetCommState(HANDLE a0,
LPDCB a1)
{
_PrintEnter("GetCommState(%p,%p)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_GetCommState(a0, a1);
} __finally {
_PrintExit("GetCommState(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_GetCommTimeouts(HANDLE a0,
LPCOMMTIMEOUTS a1)
{
_PrintEnter("GetCommTimeouts(%p,%p)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_GetCommTimeouts(a0, a1);
} __finally {
_PrintExit("GetCommTimeouts(,) -> %x\n", rv);
};
return rv;
}
DWORD WINAPI Mine_GetCurrentThreadId(void)
{
_PrintEnter("GetCurrentThreadId()\n");
DWORD rv = 0;
__try {
rv = Real_GetCurrentThreadId();
} __finally {
_PrintExit("GetCurrentThreadId() -> %x\n", rv);
};
return rv;
}
DWORD WINAPI Mine_GetModuleFileNameW(HINSTANCE 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(,%ls,) -> %x\n", a1, rv);
};
return rv;
}
BOOL WINAPI Mine_GetOverlappedResult(HANDLE a0,
LPOVERLAPPED a1,
LPDWORD a2,
BOOL a3)
{
_PrintEnter("GetOverlappedResult(%p,%p,%p,%x)\n", a0, a1, a2, a3);
BOOL rv = 0;
__try {
rv = Real_GetOverlappedResult(a0, a1, a2, a3);
} __finally {
_PrintExit("GetOverlappedResult(,,,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_PurgeComm(HANDLE a0,
DWORD a1)
{
_PrintEnter("PurgeComm(%p,%x)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_PurgeComm(a0, a1);
} __finally {
_PrintExit("PurgeComm(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_ReadFile(HANDLE a0,
LPVOID a1,
DWORD a2,
LPDWORD a3,
LPOVERLAPPED a4)
{
_PrintEnter("ReadFile(%p,%p,%x,%p,%p)\n", a0, a1, a2, a3, a4);
BOOL rv = 0;
__try {
rv = Real_ReadFile(a0, a1, a2, a3, a4);
} __finally {
_PrintExit("ReadFile(,,,,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_SetCommBreak(HANDLE a0)
{
_PrintEnter("SetCommBreak(%p)\n", a0);
BOOL rv = 0;
__try {
rv = Real_SetCommBreak(a0);
} __finally {
_PrintExit("SetCommBreak() -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_SetCommConfig(HANDLE a0,
LPCOMMCONFIG a1,
DWORD a2)
{
_PrintEnter("SetCommConfig(%p,%p,%x)\n", a0, a1, a2);
BOOL rv = 0;
__try {
rv = Real_SetCommConfig(a0, a1, a2);
} __finally {
_PrintExit("SetCommConfig(,,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_SetCommMask(HANDLE a0,
DWORD a1)
{
_PrintEnter("SetCommMask(%p,%x)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_SetCommMask(a0, a1);
} __finally {
_PrintExit("SetCommMask(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_SetCommState(HANDLE a0,
LPDCB a1)
{
_PrintEnter("SetCommState(%p,%p)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_SetCommState(a0, a1);
} __finally {
_PrintExit("SetCommState(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_SetCommTimeouts(HANDLE a0,
LPCOMMTIMEOUTS a1)
{
_PrintEnter("SetCommTimeouts(%p,%p)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_SetCommTimeouts(a0, a1);
} __finally {
_PrintExit("SetCommTimeouts(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_SetupComm(HANDLE a0,
DWORD a1,
DWORD a2)
{
_PrintEnter("SetupComm(%p,%x,%x)\n", a0, a1, a2);
BOOL rv = 0;
__try {
rv = Real_SetupComm(a0, a1, a2);
} __finally {
_PrintExit("SetupComm(,,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_TransmitCommChar(HANDLE a0,
char a1)
{
_PrintEnter("TransmitCommChar(%p,%x)\n", a0, a1);
BOOL rv = 0;
__try {
rv = Real_TransmitCommChar(a0, a1);
} __finally {
_PrintExit("TransmitCommChar(,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_WaitCommEvent(HANDLE a0,
LPDWORD a1,
LPOVERLAPPED a2)
{
_PrintEnter("WaitCommEvent(%p,%p,%p)\n", a0, a1, a2);
BOOL rv = 0;
__try {
rv = Real_WaitCommEvent(a0, a1, a2);
} __finally {
_PrintExit("WaitCommEvent(,,) -> %x\n", rv);
};
return rv;
}
BOOL WINAPI Mine_WriteFile(HANDLE a0,
LPCVOID a1,
DWORD a2,
LPDWORD a3,
LPOVERLAPPED a4)
{
_PrintEnter("WriteFile(%p,%p,%x,%p,%p)\n", a0, a1, a2, a3, a4);
BOOL rv = 0;
__try {
_PrintDump(a0, (PCHAR)a1, a2);
rv = Real_WriteFile(a0, a1, a2, a3, a4);
} __finally {
_PrintExit("WriteFile(,,,,) -> %x\n", 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(BuildCommDCBA);
ATTACH(BuildCommDCBAndTimeoutsA);
ATTACH(BuildCommDCBAndTimeoutsW);
ATTACH(BuildCommDCBW);
ATTACH(ClearCommBreak);
ATTACH(ClearCommError);
ATTACH(CloseHandle);
ATTACH(CreateFileA);
ATTACH(CreateFileW);
ATTACH(EscapeCommFunction);
ATTACH(GetCommConfig);
ATTACH(GetCommMask);
ATTACH(GetCommModemStatus);
ATTACH(GetCommProperties);
ATTACH(GetCommState);
ATTACH(GetCommTimeouts);
ATTACH(GetCurrentThreadId);
ATTACH(GetModuleFileNameW);
ATTACH(GetOverlappedResult);
ATTACH(PurgeComm);
ATTACH(ReadFile);
ATTACH(SetCommBreak);
ATTACH(SetCommConfig);
ATTACH(SetCommMask);
ATTACH(SetCommState);
ATTACH(SetCommTimeouts);
ATTACH(SetupComm);
ATTACH(TransmitCommChar);
ATTACH(WaitCommEvent);
ATTACH(WriteFile);
return DetourTransactionCommit();
}
LONG DetachDetours(VOID)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DETACH(BuildCommDCBA);
DETACH(BuildCommDCBAndTimeoutsA);
DETACH(BuildCommDCBAndTimeoutsW);
DETACH(BuildCommDCBW);
DETACH(ClearCommBreak);
DETACH(ClearCommError);
DETACH(CloseHandle);
DETACH(CreateFileA);
DETACH(CreateFileW);
DETACH(EscapeCommFunction);
DETACH(GetCommConfig);
DETACH(GetCommMask);
DETACH(GetCommModemStatus);
DETACH(GetCommProperties);
DETACH(GetCommState);
DETACH(GetCommTimeouts);
DETACH(GetCurrentThreadId);
DETACH(GetModuleFileNameW);
DETACH(GetOverlappedResult);
DETACH(PurgeComm);
DETACH(ReadFile);
DETACH(SetCommBreak);
DETACH(SetCommConfig);
DETACH(SetCommMask);
DETACH(SetCommState);
DETACH(SetCommTimeouts);
DETACH(SetupComm);
DETACH(TransmitCommChar);
DETACH(WaitCommEvent);
DETACH(WriteFile);
return DetourTransactionCommit();
}
/////////////////////////////////////////////////////////////
// Detours
//
VOID _PrintDump(HANDLE h, PCHAR pszData, INT cbData)
{
if (pszData && cbData > 0) {
CHAR szBuffer[256];
PCHAR pszBuffer = szBuffer;
INT cbBuffer = 0;
INT nLines = 0;
while (cbData > 0) {
if (nLines > 20) {
*pszBuffer++ = '.';
*pszBuffer++ = '.';
*pszBuffer++ = '.';
cbBuffer += 3;
break;
}
if (*pszData == '\t') {
*pszBuffer++ = '\\';
*pszBuffer++ = 't';
cbBuffer += 2;
pszData++;
cbData--;
continue;
}
if (*pszData == '\r') {
*pszBuffer++ = '\\';
*pszBuffer++ = 'r';
cbBuffer += 2;
pszData++;
cbData--;
continue;
}
else if (*pszData == '\n') {
*pszBuffer++ = '\\';
*pszBuffer++ = 'n';
cbBuffer += 2;
*pszBuffer++ = '\0';
_Print("%p: %hs\n", h, szBuffer);
nLines++;
pszBuffer = szBuffer;
cbBuffer = 0;
pszData++;
cbData--;
continue;
}
else if (cbBuffer >= 80) {
*pszBuffer++ = '\0';
_Print("%p: %hs\n", h, szBuffer);
nLines++;
pszBuffer = szBuffer;
cbBuffer = 0;
}
if (*pszData < ' ' || *pszData >= 127) {
*pszBuffer++ = '\\';
*pszBuffer++ = 'x';
*pszBuffer++ = "0123456789ABCDEF"[(*pszData & 0xf0) >> 4];
*pszBuffer++ = "0123456789ABCDEF"[(*pszData & 0x0f)];
cbBuffer += 4;
}
else {
*pszBuffer++ = *pszData;
}
cbBuffer++;
pszData++;
cbData--;
}
if (cbBuffer > 0) {
*pszBuffer++ = '\0';
_Print("%p: %hs\n", h, szBuffer);
}
}
}
////////////////////////////////////////////////////////////// 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);
}
//////////////////////////////////////////////////////////////////////////////
//
// 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();
WCHAR wzExePath[MAX_PATH];
s_hInst = hDll;
Real_GetModuleFileNameA(s_hInst, s_szDllPath, ARRAYSIZE(s_szDllPath));
Real_GetModuleFileNameW(NULL, wzExePath, ARRAYSIZE(wzExePath));
SyelogOpen("trcser" DETOURS_STRINGIFY(DETOURS_BITS), SYELOG_FACILITY_APPLICATION);
Syelog(SYELOG_SEVERITY_INFORMATION,
"##################################################################\n");
Syelog(SYELOG_SEVERITY_INFORMATION,
"### %ls\n", wzExePath);
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.