mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-05-01 20:38:21 +00:00
1180 lines
32 KiB
C++
Vendored
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.
|