⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tracemem.cpp

📁 微软提供的截取Win32 API函数的开发包和例子detours-src-1.2.rar
💻 CPP
字号:
//////////////////////////////////////////////////////////////////////
//
//	Module:		tracemem.dll
//	Author:		Galen C. Hunt
//	Copyright:	1996-1999, Microsoft Corporation
//
//	Version 1.2. (Build 35)
//

//////////////////////////////////////////////////////////////////////

#define _WIN32_WINNT		0x0400
#define WIN32
#define NT

#define DBG_TRACE   0

#include <windows.h>
#include <stdio.h>
#include "detours.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

//////////////////////////////////////////////////////////////////////

#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)

//////////////////////////////////////////////////////////////////////

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);

/////////////////////////////////////////////////////////////
// Trampolines
//

DETOUR_TRAMPOLINE(LPVOID WINAPI
				  Real_HeapAlloc(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes),
                  HeapAlloc);

/////////////////////////////////////////////////////////////
// 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;
}

/////////////////////////////////////////////////////////////
// TrampolineWith
//
VOID TrampolineWith(VOID)
{
    DetourFunctionWithTrampoline((PBYTE)Real_HeapAlloc,
                                 (PBYTE)Mine_HeapAlloc);
}

////////////////////////////////////////////////////////////// Logging System.
//
static PCHAR do_hex(PCHAR pszOut, DWORD dwValue)
{
	CHAR szHex[9];
	for (int nHex = 7; nHex >= 0; nHex--) {
		szHex[nHex] = "0123456789ABCDEF"[dwValue & 0xf];
		dwValue >>= 4;
	}
	for (nHex = 0; nHex < 7 && szHex[nHex] == '0'; nHex++) {
		// skip leading zeros.
	}
	for (; nHex < 8; nHex++) {
		*pszOut++ = szHex[nHex];
	}
	return pszOut;
}

static VOID _VPrint(PCSTR pszMsg, va_list args, PCHAR pszBuffer, LONG cbBuffer)
{
	PCHAR pszOut = pszBuffer;
	pszBuffer[0] = '\0';

	__try {
		while (*pszMsg) {
			if (*pszMsg == '%') {
				pszMsg++;
				
				BOOL fLarge = FALSE;
				if (*pszMsg == 'h') {
					fLarge = FALSE;
					pszMsg++;
				}
				else if (*pszMsg == 'l') {
					fLarge = TRUE;
					pszMsg++;
				}

				if (*pszMsg == 's') {
					pszMsg++;
					PCHAR pszBuf = pszOut;
					PVOID pvData = va_arg(args, PVOID);
					
					__try {
						*pszOut++ = '\"';
						if (fLarge) {
							PWCHAR pwz = (PWCHAR)pvData;

							for (int n = 0; *pwz && n < 120; n++) {
								WCHAR w = *pwz++;
								*pszOut++ = (w >= ' ' && w < 127) ? (CHAR)w : '.';
							}
						}
						else {
							PCHAR psz = (PCHAR)pvData;

							for (int n = 0; *psz && n < 120; n++) {
								CHAR c = *psz++;
								*pszOut++ = (c >= ' ' && c < 127) ? c : '.';
							}
						}
						*pszOut++ = '\"';
					} __except(EXCEPTION_EXECUTE_HANDLER) {
						pszOut = pszBuf;
						*pszOut++ = 'x';
						pszOut = do_hex(pszOut, (DWORD)pvData);
					}
				}
				else if (*pszMsg == 'x') {
					pszMsg++;
					*pszOut++ = 'x';
					pszOut = do_hex(pszOut, va_arg(args, DWORD));
				}	
				else {
					*pszOut++ = *pszMsg++;
				}
			}
			else {
				*pszOut++ = *pszMsg++;
			}
		}
		*pszOut = '\0';
		pszBuffer[cbBuffer - 1] = '\0';
	} __except(EXCEPTION_EXECUTE_HANDLER) {
		strcpy(pszBuffer, "<exception>");
	}
}

class CLog
{
  public:
	static VOID Print(PCSTR msg, ...);
	static VOID Write(PCHAR pszBuf, LONG cbBuf);
	static VOID Close();

  protected:
	static BOOL Open();
	
	static HANDLE	s_hLogFile;
	static WCHAR	s_wzLogFile[];
};

HANDLE 	CLog::s_hLogFile = (HANDLE)-2L;
WCHAR 	CLog::s_wzLogFile[] = L"\\tracemem.log";

BOOL CLog::Open()
{
	if (s_hLogFile == (HANDLE)-2L) {
		s_hLogFile = CreateFileW(s_wzLogFile,
									  GENERIC_WRITE,
									  FILE_SHARE_READ,
									  NULL,
									  CREATE_ALWAYS,
									  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
									  NULL);
	}
	return (s_hLogFile != INVALID_HANDLE_VALUE);
}

VOID CLog::Write(PCHAR pszBuf, LONG cbBuf)
{
	if (Open()) {
		DWORD cbWritten = 0;
		WriteFile(s_hLogFile, pszBuf, cbBuf, &cbWritten, NULL);
	}
}

VOID CLog::Close()
{
	if (s_hLogFile != (HANDLE)-2L && s_hLogFile != INVALID_HANDLE_VALUE) {
		CloseHandle(s_hLogFile);
		s_hLogFile = INVALID_HANDLE_VALUE;
	}
}

VOID CLog::Print(PCSTR pszMsg, ...)
{
	CHAR szBuf[4096];
	
	va_list args;
	va_start(args, pszMsg);
	_VPrint(pszMsg, args, szBuf, sizeof(szBuf));
	va_end(args);

	Write(szBuf, strlen(szBuf));
}

//
//////////////////////////////////////////////////////////////////////////////

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) {
		CHAR szBuf[4096];
		LONG nLen = 3 + (nIndent < 35 ? nIndent * 2 : 70);
		FillMemory(szBuf, nLen, ' ');

		szBuf[0] = '0' + ((nThread / 10) % 10);
		szBuf[1] = '0' + ((nThread / 1) % 10);
		
		va_list  args;
		va_start(args, psz);
		_VPrint(psz, args, szBuf + nLen, sizeof(szBuf) - nLen);
		va_end(args);
		
		CLog::Write(szBuf, strlen(szBuf));
	}
	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;
		TlsSetValue(s_nTlsIndent, (PVOID)nIndent);
	}
	if (s_nTlsThread >= 0) {
		nThread = (LONG)TlsGetValue(s_nTlsThread);
	}
		
	if (s_bLog) {
		CHAR szBuf[4096];
		LONG nLen = 3 + (nIndent < 35 ? nIndent * 2 : 70);
		FillMemory(szBuf, nLen, ' ');
	
		szBuf[0] = '0' + ((nThread / 10) % 10);
		szBuf[1] = '0' + ((nThread / 1) % 10);
		
		va_list  args;
		va_start(args, psz);
		_VPrint(psz, args, szBuf + nLen, sizeof(szBuf) - nLen);
		va_end(args);
		
		CLog::Write(szBuf, strlen(szBuf));
	}
	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);
	}

	CHAR szBuf[4096];
	LONG nLen = 3 + (nIndent < 35 ? nIndent * 2 : 70);
	FillMemory(szBuf, nLen, ' ');
	
	szBuf[0] = '0' + ((nThread / 10) % 10);
	szBuf[1] = '0' + ((nThread / 1) % 10);
		
    va_list  args;
    va_start(args, psz);
	_VPrint(psz, args, szBuf + nLen, sizeof(szBuf) - nLen);
    va_end(args);
	
	CLog::Write(szBuf, strlen(szBuf));
	
	SetLastError(dwErr);
}

VOID AssertMessage(CONST PCHAR pszMsg, CONST PCHAR pszFile, ULONG nLine)
{
	CHAR szBuf[512];
    sprintf(szBuf, "ASSERT(%s) failed in %s, line %d.\n", pszMsg, pszFile, nLine);

	CLog::Write(szBuf, strlen(szBuf));
}

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 wzDllName[MAX_PATH];
	WCHAR wzExeName[MAX_PATH];

	GetModuleFileNameW(hDll, wzDllName, sizeof(wzDllName));
	GetModuleFileNameW(NULL, wzExeName, sizeof(wzExeName));

	CLog::Print("##################################################################\n");
	CLog::Print("### %ls\n", wzExeName);
	CLog::Print("### %ls built %hs %hs\n", wzDllName, __DATE__, __TIME__);
	TrampolineWith();

	ThreadAttach(hDll);
	
	s_bLog = TRUE;
	return TRUE;
}

BOOL ProcessDetach(HMODULE hDll)
{
	ThreadDetach(hDll);
	
	s_bLog = FALSE;
	CLog::Close();

	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 + -