📄 memorydetour.cpp
字号:
//////////////////////////////////////////////////////////////////////
//
// File: tracemem.cpp
// Module: tracemem.dll
// Copyright: 1996-2001, Microsoft Corporation
//
// Microsoft Research Detours Package Version 1.5 (Build 46)
//
#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 LONG_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.
#ifndef _DEFINED_ASMBREAK_
#define _DEFINED_ASMBREAK_
#define ASMBREAK() __asm { int 3 }
//#define ASMBREAK() DebugBreak()
#endif // _DEFINED_ASMBREAK_
#define ASSERT_ALWAYS(x) \
do { \
if (!(x)) { \
AssertMessage(#x, __FILE__, __LINE__); \
ASMBREAK(); \
} \
} while (0)
#ifndef NDEBUG
#define ASSERT(x) ASSERT_ALWAYS(x)
#else
#define ASSERT(x)
#endif
#define UNUSED(c) (c) = (c)
#define ARRAYOF(x) (sizeof(x)/sizeof(x[0]))
//////////////////////////////////////////////////////////////////////
static HMODULE s_hInst = NULL;
static WCHAR s_wzDllPath[MAX_PATH];
VOID _PrintEnter(const CHAR *psz, ...);
VOID _PrintExit(const CHAR *psz, ...);
VOID _Print(const CHAR *psz, ...);
VOID _VPrint(PCSTR msg, va_list args, PCHAR pszBuf, LONG cbBuf);
VOID AssertMessage(CONST PCHAR pszMsg, CONST PCHAR pszFile, ULONG nLine);
/////////////////////////////////////////////////////////////
// Trampolines
//
#pragma warning(disable:4100) // Trampolines don't use formal parameters.
extern "C" {
DETOUR_TRAMPOLINE(HANDLE WINAPI
Real_CreateFileW(LPCWSTR a0,
DWORD a1,
DWORD a2,
LPSECURITY_ATTRIBUTES a3,
DWORD a4,
DWORD a5,
HANDLE a6),
CreateFileW);
DETOUR_TRAMPOLINE(BOOL WINAPI
Real_WriteFile(HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped),
WriteFile);
DETOUR_TRAMPOLINE(BOOL WINAPI
Real_FlushFileBuffers(HANDLE hFile),
FlushFileBuffers);
DETOUR_TRAMPOLINE(BOOL WINAPI
Real_CloseHandle(HANDLE hObject),
CloseHandle);
DETOUR_TRAMPOLINE(BOOL WINAPI
Real_WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut),
WaitNamedPipeW);
DETOUR_TRAMPOLINE(BOOL WINAPI
Real_SetNamedPipeHandleState(HANDLE hNamedPipe,
LPDWORD lpMode,
LPDWORD lpMaxCollectionCount,
LPDWORD lpCollectDataTimeout),
SetNamedPipeHandleState);
DETOUR_TRAMPOLINE(DWORD WINAPI
Real_GetCurrentProcessId(VOID),
GetCurrentProcessId);
DETOUR_TRAMPOLINE(VOID WINAPI
Real_GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime),
GetSystemTimeAsFileTime);
DETOUR_TRAMPOLINE(VOID WINAPI
Real_InitializeCriticalSection(LPCRITICAL_SECTION lpSection),
InitializeCriticalSection);
DETOUR_TRAMPOLINE(VOID WINAPI
Real_EnterCriticalSection(LPCRITICAL_SECTION lpSection),
EnterCriticalSection);
DETOUR_TRAMPOLINE(VOID WINAPI
Real_LeaveCriticalSection(LPCRITICAL_SECTION lpSection),
LeaveCriticalSection);
}
DETOUR_TRAMPOLINE(LPVOID WINAPI
Real_HeapAlloc(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes),
HeapAlloc);
DETOUR_TRAMPOLINE(DWORD WINAPI Real_GetModuleFileNameW(HMODULE a0,
LPWSTR a1,
DWORD a2),
GetModuleFileNameW);
DETOUR_TRAMPOLINE(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);
/////////////////////////////////////////////////////////////
// Detours
//
LPVOID WINAPI Mine_HeapAlloc(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes)
{
_PrintEnter("HeapAlloc(%lx, %lx, %lx))\n", hHeap, dwFlags, dwBytes);
LPVOID rv = 0;
__try {
rv = Real_HeapAlloc(hHeap, dwFlags, dwBytes);
} __finally {
_PrintExit("HeapAlloc() -> %lx\n", rv);
};
return rv;
}
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,%lx,%lx,%lx,%lx,%lx,%ls,%lx,%lx)\n",
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
_Print("Calling DetourCreateProcessWithDllW(,%ls)\n", s_wzDllPath);
BOOL rv = 0;
__try {
rv = DetourCreateProcessWithDllW(lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation,
s_wzDllPath,
Real_CreateProcessW);
} __finally {
_PrintExit("CreateProcessW(,,,,,,,,,) -> %lx\n", rv);
};
return rv;
}
/////////////////////////////////////////////////////////////
// TrampolineWith
//
VOID TrampolineWith(VOID)
{
DetourFunctionWithTrampoline((PBYTE)Real_HeapAlloc,
(PBYTE)Mine_HeapAlloc);
DetourFunctionWithTrampoline((PBYTE)Real_CreateProcessW,
(PBYTE)Mine_CreateProcessW);
}
////////////////////////////////////////////////////////////// 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)TlsGetValue(s_nTlsIndent);
TlsSetValue(s_nTlsIndent, (PVOID)(nIndent + 1));
}
if (s_nTlsThread >= 0) {
nThread = (LONG)TlsGetValue(s_nTlsThread);
}
if (s_bLog && psz) {
CHAR szBuf[1024];
PCHAR pszBuf = szBuf;
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) {
// Copy characters.
}
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)TlsGetValue(s_nTlsIndent) - 1;
ASSERT(nIndent >= 0);
TlsSetValue(s_nTlsIndent, (PVOID)nIndent);
}
if (s_nTlsThread >= 0) {
nThread = (LONG)TlsGetValue(s_nTlsThread);
}
if (s_bLog && psz) {
CHAR szBuf[1024];
PCHAR pszBuf = szBuf;
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) {
// Copy characters.
}
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)TlsGetValue(s_nTlsIndent);
}
if (s_nTlsThread >= 0) {
nThread = (LONG)TlsGetValue(s_nTlsThread);
}
if (s_bLog && psz) {
CHAR szBuf[1024];
PCHAR pszBuf = szBuf;
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) {
// Copy characters.
}
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);
}
VOID NullExport()
{
}
//////////////////////////////////////////////////////////////////////////////
//
// DLL module information
//
BOOL ThreadAttach(HMODULE hDll)
{
if (s_nTlsIndent >= 0) {
TlsSetValue(s_nTlsIndent, (PVOID)0);
}
if (s_nTlsThread >= 0) {
LONG nThread = InterlockedIncrement(&s_nThreadCnt);
TlsSetValue(s_nTlsThread, (PVOID)nThread);
}
return TRUE;
}
BOOL ThreadDetach(HMODULE 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 wzExeName[MAX_PATH];
s_hInst = hDll;
Real_GetModuleFileNameW(hDll, s_wzDllPath, ARRAYOF(s_wzDllPath));
Real_GetModuleFileNameW(NULL, wzExeName, ARRAYOF(wzExeName));
SyelogOpen("tracemem", SYELOG_FACILITY_APPLICATION);
Syelog(SYELOG_SEVERITY_INFORMATION, "##########################################\n");
Syelog(SYELOG_SEVERITY_INFORMATION, "### %ls\n", wzExeName);
TrampolineWith();
ThreadAttach(hDll);
s_bLog = TRUE;
return TRUE;
}
BOOL ProcessDetach(HMODULE hDll)
{
ThreadDetach(hDll);
s_bLog = FALSE;
SyelogClose();
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)
{
switch (dwReason) {
case DLL_PROCESS_ATTACH:
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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -