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

📄 cping.cpp

📁 微软提供的截取Win32 API函数的开发包和例子detours-src-1.2.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//////////////////////////////////////////////////////////////////////////////
//
//	Module:		cping.exe - COM Ping
//	File:		cping.cpp
//	Author:		Galen C. Hunt
//	Copyright:	1996-1999, Microsoft Corporation
//
//	http://www.research.microsoft.com/sn/detours
//

#define INITGUID
#include <objbase.h>
#include <objidl.h>
#include <ocidl.h>
#include <olectl.h>
#include <shellapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <rpc.h>
#include <rpcdcep.h>
#include <detours.h>
#include "iping.h"

////////////////////////////////////////////////////////// Assertion Handling.
//
#ifndef _DEFINED_ASMBREAK_
#define _DEFINED_ASMBREAK_
#define ASMBREAK()	__asm { int 3 }
//#define ASMBREAK()	DebugBreak()
#endif	// _DEFINED_ASMBREAK_

#ifndef NODEBUG
#undef ASSERT
VOID PingAssertMessage(CONST PCHAR szMsg, CONST PCHAR szFile, ULONG nLine);
#define ASSERT(x)   \
do { if (!(x)) { PingAssertMessage(#x, __FILE__, __LINE__); ASMBREAK(); }} while (0)
	;
#else	// NODEBUG
#undef ASSERT
#define ASSERT(x)
#endif	// NODEBUG

//////////////////////////////////////////////////////////////////////////////
#define PingLoadCycleCount(x) \
_asm { \
	__asm	lea	ecx, x			\
	__asm 	_emit 0x0f			\
	__asm 	_emit 0x31			\
	__asm	mov [ecx], eax		\
	__asm	mov [ecx+4], edx	\
}

#define arrayof(x)		(sizeof(x)/sizeof(x[0]))
#define	wcssize(x)		((wcslen(x) + 1) * sizeof(WCHAR))
#define	strsize(x)		((strlen(x) + 1) * sizeof(CHAR))

extern "C" {
	ULONG WINAPI iping_DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
	HRESULT STDAPICALLTYPE iping_DllRegisterServer(void);
	HRESULT STDAPICALLTYPE iping_DllUnregisterServer(void);
	HRESULT STDAPICALLTYPE iping_DllGetClassObject(REFCLSID rclsid,
												  REFIID riid, PVOID *ppv);
	HRESULT STDAPICALLTYPE iping_DllCanUnloadNow(void);
}

STDAPI PingMessage(PCSTR msg, ...);

///////////////////////////////////////////////////////////////////// Globals.

FILE *				g_fpLog = NULL;
void *				g_pBuffer = NULL;
WCHAR				g_wzServerName[128];
WCHAR				g_wzClientName[128];
ULONG				g_cbBufferMax = 262144;
double				g_dCyclesPerSecond = 0.0;
double				g_dMsPerCycle = 0.0;
double				g_dLatency = 0.0;
BOOL 				g_fSummarize = TRUE;
ULONG				g_nFixedToClient = 0;
ULONG				g_nFixedToServer = 0;

//////////////////////////////////////////////////////////////////////////////
//
static CHAR s_szMessageBuf[2048];

STDAPI PingMessage(PCSTR msg, ...)
{
	double d = 0.0;										// Required for FP support
	va_list args;

	va_start(args, msg);
	vsprintf(s_szMessageBuf, msg, args);
	
	// OutputDebugStringA(s_szMessageBuf);

	fwrite(s_szMessageBuf, 1, strlen(s_szMessageBuf), stdout);
	fflush(stdout);
	return S_FALSE;
}

VOID PingAssertMessage(CONST PCHAR szMsg, CONST PCHAR szFile, ULONG nLine)
{
	PingMessage("%08lx ASSERT(%s) failed in %s, line %d.\n",
				 GetCurrentThreadId(), szMsg, szFile, nLine);
	printf("ASSERT(%s) failed in %s, line %d.\n", szMsg, szFile, nLine);
}

BOOLEAN CheckResult(HRESULT hr, PCSTR pszMsg, ...)
{
	if (FAILED(hr)) {
		va_list args;
		
		va_start(args, pszMsg);
		vsprintf(s_szMessageBuf, pszMsg, args);
		
		printf("  %-57.57s -> %08lx\n", s_szMessageBuf, hr);
		return FALSE;
	}
	return TRUE;
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
#define NTSYSAPI			DECLSPEC_IMPORT
#define NTAPI				__stdcall
#define NTSTATUS			LONG
#define PIO_APC_ROUTINE		PVOID

typedef struct 
{
	NTSTATUS	Status;
	LONG		Information;
} *PIO_STATUS_BLOCK;

NTSTATUS (NTAPI *s_pNtWaitForSingleObject)(HANDLE Handle,
										   BOOLEAN Alertable,
										   PLARGE_INTEGER Timeout) = NULL;

NTSTATUS (NTAPI *s_pNtDeviceIoControlFile)(HANDLE FileHandle,
										   HANDLE Event,
										   PIO_APC_ROUTINE ApcRoutine,
										   PVOID ApcContext,
										   PIO_STATUS_BLOCK IoStatusBlock,
										   ULONG IoControlCode,
										   PVOID InputBuffer,
										   ULONG InputBufferLength,
										   PVOID OutputBuffer,
										   ULONG OutputBufferLength) = NULL;

NTSTATUS (NTAPI *s_pTrampoline_NtWaitForSingleObject)(HANDLE Handle,
													   BOOLEAN Alertable,
													   PLARGE_INTEGER Timeout) = NULL;

NTSTATUS (NTAPI *s_pTrampoline_NtDeviceIoControlFile)(HANDLE FileHandle,
													   HANDLE Event,
													   PIO_APC_ROUTINE ApcRoutine,
													   PVOID ApcContext,
													   PIO_STATUS_BLOCK IoStatusBlock,
													   ULONG IoControlCode,
													   PVOID InputBuffer,
													   ULONG InputBufferLength,
													   PVOID OutputBuffer,
													   ULONG OutputBufferLength) = NULL;

//////////////////////////////////////////////////////////////////////////////
//
static LONG 	s_nInCall = 0;
static LONG 	s_nInIRpc = 0;
static ULONG	s_nThread = 0;

enum {
	E_MinValue = 0,
	E_Sleep = 1,
	
	E_Proxy,
	
	E_I_RpcGetBuffer,
	E_I_RpcSendReceive,
	E_I_RpcFreeBuffer,
	E_I_RpcSend,
	E_I_RpcReceive,
	E_I_RpcFreePipeBuffer,
	E_I_RpcReallocPipeBuffer,
	E_I_RpcRequestMutex,
	E_I_RpcClearMutex,
	E_I_RpcAllocate,
	E_I_RpcFree,
	E_I_RpcPauseExecution,
	E_I_RpcMonitorAssociation,
	E_I_RpcStopMonitorAssociation,

	E_Recv,
	E_RecvFrom,
	E_NtWaitForSingleObject,
	E_NtDeviceIoControlFileRecv,
	E_NtDeviceIoControlFile,

	E_Send,
	E_SendTo,
	E_NtDeviceIoControlFileSend,
	
	E_DCOM,
	E_RPC,
	E_UDP,
	E_NET,

	E_MaxValue,
	
	E_DcomBeg = E_Proxy,
	E_DcomEnd = E_Proxy,

	E_RpcBeg = E_I_RpcGetBuffer,
	E_RpcEnd = E_I_RpcStopMonitorAssociation,
	
	E_UdpBeg = E_Send,
	E_UdpEnd = E_NtDeviceIoControlFileSend,
	
	E_NetBeg = E_Recv,
	E_NetEnd = E_NtDeviceIoControlFile,
};

PCHAR s_rgRouteNames[E_MaxValue] =
{
	"<NULL>",
	"Sleep",
	"Proxy",
	"I_RpcGetBuffer",
	"I_RpcSendReceive",
	"I_RpcFreeBuffer",
	"I_RpcSend",
	"I_RpcReceive",
	"I_RpcFreePipeBuffer",
	"I_RpcReallocPipeBuffer",
	"I_RpcRequestMutex",
	"I_RpcClearMutex",
	"I_RpcAllocate",
	"I_RpcFree",
	"I_RpcPauseExecution",
	"I_RpcMonitorAssociation",
	"I_RpcStopMonitorAssociation",
	"Recv",
	"RecvFrom",
	"NtWaitForSingleObject",
	"NtDeviceIoControlRecv",
	"NtDeviceIoControlFile",
	"Send",
	"SendTo",
	"NtDeviceIoControlSend",
	"DCOM",
	"RPC",
	"UDP/TCP (Send Only)",
	"NET",
};

LONGLONG 	s_rgCycles[E_MaxValue];
LONGLONG 	s_rgTotals[E_MaxValue];
LONG		s_rgCounts[E_MaxValue];

class CRouteTime 
{
public:
	inline CRouteTime(LONG nRoute)
	{
		if (s_nInCall && GetCurrentThreadId() == s_nThread) {
			LONGLONG llBeg;
			m_nOldRoute = s_nRoute;
			m_llOldMinus = s_llMinus;
			
			s_nRoute = m_nRoute = nRoute;

			s_rgCounts[m_nRoute]++;
			s_llMinus = 0;
			ASSERT(m_nRoute != m_nOldRoute);
			
			PingLoadCycleCount(llBeg);
			m_llBeg = llBeg;
		}
		else {
			m_nRoute = 0;
		}
	}
	
	inline ~CRouteTime()
	{
		if (m_nRoute) {
			LONGLONG llEnd;
			PingLoadCycleCount(llEnd);
			llEnd -= m_llBeg;
			s_rgTotals[m_nRoute] += llEnd;
			s_rgCycles[m_nRoute] += llEnd - s_llMinus;
			s_nRoute = m_nOldRoute;
			s_llMinus = m_llOldMinus + llEnd;
		}
	}

	inline BOOL Routed()
	{
		return m_nRoute;
	}
	
public:
	ULONG		m_nRoute;
	ULONG		m_nOldRoute;
	LONGLONG	m_llBeg;
	LONGLONG	m_llOldMinus;
	static ULONG	s_nRoute;
	static LONGLONG	s_llMinus;
};

ULONG		CRouteTime::s_nRoute = 0;
LONGLONG	CRouteTime::s_llMinus = 0;

VOID ZeroCycles(VOID)
{
	for (ULONG n = 0; n < E_MaxValue; n++) {
		s_rgCycles[n] = 0;
		s_rgTotals[n] = 0;
		s_rgCounts[n] = 0;
	}
}

VOID DumpCycles(LONG nRoute)
{
	if (s_rgCycles[nRoute] != 0 || s_rgTotals[nRoute] != 0) {
		printf(";;   %-21.21s %10I64d %8.3fms %10I64d %8.3fms :%6d\n",
			   s_rgRouteNames[nRoute],
			   s_rgCycles[nRoute], (double)s_rgCycles[nRoute] * g_dMsPerCycle,
			   s_rgTotals[nRoute], (double)s_rgTotals[nRoute] * g_dMsPerCycle,
			   s_rgCounts[nRoute]);
	}
}

VOID SummarizeCycles(VOID)
{
	for (ULONG n = E_DCOM; n <= E_NET; n++) {
		s_rgCycles[n] = 0;
		s_rgTotals[n] = 0;
		s_rgCounts[n] = 0;
	}
	
	for (n = E_DcomBeg; n <= E_DcomEnd; n++) {
		s_rgCycles[E_DCOM] += s_rgCycles[n];
		s_rgTotals[E_DCOM] += s_rgTotals[n];
	}
	for (n = E_RpcBeg; n <= E_RpcEnd; n++) {
		s_rgCycles[E_RPC] += s_rgCycles[n];
		s_rgTotals[E_RPC] += s_rgTotals[n];
	}
	for (n = E_UdpBeg; n <= E_UdpEnd; n++) {
		s_rgCycles[E_UDP] += s_rgCycles[n];
		s_rgTotals[E_UDP] += s_rgTotals[n];
	}
	for (n = E_NetBeg; n <= E_NetEnd; n++) {
		s_rgCycles[E_NET] += s_rgCycles[n];
		s_rgTotals[E_NET] += s_rgTotals[n];
	}

#ifdef BE_VERBOSE	
	printf("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
		   "::::::::::::::::::\n");
	printf(":: Protocol Cycles:\n");
	DumpCycles(E_DCOM);
	DumpCycles(E_RPC);
	DumpCycles(E_UDP);
	DumpCycles(E_NET);
#endif	
	
	s_rgCycles[E_DCOM] /= s_rgCounts[E_DCOM];
	s_rgCycles[E_RPC] /= s_rgCounts[E_DCOM];
	s_rgCycles[E_UDP] /= s_rgCounts[E_DCOM];
	s_rgCycles[E_NET] /= s_rgCounts[E_DCOM];
	s_rgTotals[E_DCOM] /= s_rgCounts[E_DCOM];
	s_rgTotals[E_RPC] /= s_rgCounts[E_DCOM];
	s_rgTotals[E_UDP] /= s_rgCounts[E_DCOM];
	s_rgTotals[E_NET] /= s_rgCounts[E_DCOM];
	
#ifdef BE_VERBOSE
	printf("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
		   "::::::::::::::::::\n");
	printf(":: Protocol Cycles Per DCOM Call:\n");
	DumpCycles(E_DCOM);
	DumpCycles(E_RPC);
s	DumpCycles(E_UDP);
	DumpCycles(E_NET);
#endif	

	for (n = 0; n < E_DCOM; n++) {
		s_rgCycles[n] = 0;
		s_rgTotals[n] = 0;
		s_rgCounts[n] = 0;
	}
}

//////////////////////////////////////////////////////////////////////////////
//
// To re-route you need three things:
//	1) DETOUR_TRAMPOLINE:
//		Name of function to be re-routed
//		Prototype of original function (the base) trampoline function (Trampoline_*).
// 	2) Instrumentation function. (Catch_*)
//	3) Insert instrumentation in the function (modify the binary):
//		DetourFunctionWithTrampoline((PBYTE)Trampoline_Sleep, (PBYTE)Detour_Sleep);
//
DETOUR_TRAMPOLINE(VOID WINAPI Trampoline_Sleep(DWORD dwMilliseconds),
				  Sleep);
DETOUR_TRAMPOLINE(int WSAAPI Trampoline_send(SOCKET s,
											 const char * buf, int len, int flags),
				  send);
DETOUR_TRAMPOLINE(int WSAAPI Trampoline_sendto(SOCKET s,
											   const char * buf, int len, int flags,
											   const struct sockaddr * to, int tolen),
				  sendto);
DETOUR_TRAMPOLINE(int WSAAPI Trampoline_recv(SOCKET s, char * buf, int len, int flags),
				  recv);
DETOUR_TRAMPOLINE(int WSAAPI Trampoline_recvfrom(SOCKET s,char * buf, int len, int flags,
												 struct sockaddr * from, int * fromlen),
				  recvfrom);

DETOUR_TRAMPOLINE(RPC_STATUS RPC_ENTRY
				  Trampoline_I_RpcGetBuffer(RPC_MESSAGE * Message),
				  I_RpcGetBuffer);
DETOUR_TRAMPOLINE(RPC_STATUS RPC_ENTRY
				  Trampoline_I_RpcSendReceive(RPC_MESSAGE * Message),
				  I_RpcSendReceive);
DETOUR_TRAMPOLINE(RPC_STATUS RPC_ENTRY
				  Trampoline_I_RpcFreeBuffer(RPC_MESSAGE * Message),
				  I_RpcFreeBuffer);
DETOUR_TRAMPOLINE(RPC_STATUS RPC_ENTRY
				  Trampoline_I_RpcSend(PRPC_MESSAGE Message),
				  I_RpcSend);
DETOUR_TRAMPOLINE(RPC_STATUS RPC_ENTRY
				  Trampoline_I_RpcReceive(PRPC_MESSAGE Message,
										  unsigned int Size),
				  I_RpcReceive);
DETOUR_TRAMPOLINE(RPC_STATUS RPC_ENTRY
				  Trampoline_I_RpcFreePipeBuffer(RPC_MESSAGE * Message),
				  I_RpcFreePipeBuffer);
DETOUR_TRAMPOLINE(RPC_STATUS RPC_ENTRY
				  Trampoline_I_RpcReallocPipeBuffer(PRPC_MESSAGE Msg,
													unsigned int Size),
				  I_RpcReallocPipeBuffer);
DETOUR_TRAMPOLINE(void RPC_ENTRY
				  Trampoline_I_RpcRequestMutex(I_RPC_MUTEX * Mutex),
				  I_RpcRequestMutex);
DETOUR_TRAMPOLINE(void RPC_ENTRY
				  Trampoline_I_RpcClearMutex(I_RPC_MUTEX Mutex),
				  I_RpcClearMutex);
DETOUR_TRAMPOLINE(void * RPC_ENTRY
				  Trampoline_I_RpcAllocate(unsigned int Size),
				  I_RpcAllocate);
DETOUR_TRAMPOLINE(void RPC_ENTRY
				  Trampoline_I_RpcFree(void * Object),
				  I_RpcFree);
DETOUR_TRAMPOLINE(void RPC_ENTRY
				  Trampoline_I_RpcPauseExecution(unsigned long Milliseconds),
				  I_RpcPauseExecution);
DETOUR_TRAMPOLINE(RPC_STATUS RPC_ENTRY
				  Trampoline_I_RpcMonitorAssociation(RPC_BINDING_HANDLE Handle,
													 PRPC_RUNDOWN RundownRoutine,
													 void * Context),
				  I_RpcMonitorAssociation);
DETOUR_TRAMPOLINE(RPC_STATUS RPC_ENTRY
				  Trampoline_I_RpcStopMonitorAssociation(RPC_BINDING_HANDLE Handle),
				  I_RpcStopMonitorAssociation);

//////////////////////////////////////////////////////////////////////////////
//
static VOID WINAPI Detour_Sleep(DWORD dwMilliseconds)
{
	CRouteTime rt(E_Sleep);
	Trampoline_Sleep(dwMilliseconds);
}

static int WSAAPI Detour_send(SOCKET s, const char * buf, int len, int flags)
{
	CRouteTime rt(E_Send);
	return Trampoline_send(s, buf, len, flags);
}

static int WSAAPI Detour_sendto(SOCKET s, const char * buf, int len, int flags,
							   const struct sockaddr * to, int tolen)
{
	CRouteTime rt(E_SendTo);
	return Trampoline_sendto(s, buf, len, flags, to, tolen);
}


static int WSAAPI Detour_recv(SOCKET s, char * buf, int len, int flags)
{
	CRouteTime rt(E_Recv);
	return recv(s, buf, len, flags);
}

static int WSAAPI Detour_recvfrom(SOCKET s,char * buf, int len, int flags,
								 struct sockaddr * from, int * fromlen)
{
	CRouteTime rt(E_RecvFrom);
	return recvfrom(s, buf, len, flags, from, fromlen);
}

static VOID DumpStack(PCHAR pszDesc, PULONG pStack)
{
	printf("%-15.15s:", pszDesc);
	for (ULONG n = 0; n < 6; n++) {
		__try {
			printf(" %08x", pStack[1]);
			pStack = (PULONG)pStack[0];
		} __except(EXCEPTION_EXECUTE_HANDLER) {
			n = 8;
		}
	}
	printf("\n");
}

static NTSTATUS NTAPI Detour_NtWaitForSingleObject(HANDLE Handle,
												  BOOLEAN Alertable,
												  PLARGE_INTEGER Timeout)
{
	CRouteTime rt(E_NtWaitForSingleObject);
	if (rt.Routed()) {
		//printf("WaitForSingle(%d, %I64d)\n", Alertable, Timeout->QuadPart);
	}
	
#ifdef INCLUDE_THIS	
	if (rt.Routed()) {
		PULONG pStack = NULL;
		
		__asm mov pStack, ebp;
		DumpStack("NtWaitForSingle", pStack);
	}
#endif	
	return s_pTrampoline_NtWaitForSingleObject(Handle, Alertable, Timeout);
}

#define IO_CONTROL_AFD_SEND_DATAGRAM		0x12023
#define IO_CONTROL_AFD_SEND					0x1201f
#define IO_CONTROL_AFD_RECV_DATAGRAM		0x1201b
#define IO_CONTROL_AFD_RECV					0x12017

static NTSTATUS NTAPI Detour_NtDeviceIoControlFile(HANDLE FileHandle,
												   HANDLE Event,
												   PIO_APC_ROUTINE ApcRoutine,
												   PVOID ApcContext,
												   PIO_STATUS_BLOCK IoStatusBlock,
												   ULONG IoControlCode,
												   PVOID InputBuffer,
												   ULONG InputBufferLength,
												   PVOID OutputBuffer,
												   ULONG OutputBufferLength)
{
	if (IoControlCode == IO_CONTROL_AFD_SEND_DATAGRAM ||
		IoControlCode == IO_CONTROL_AFD_SEND) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -