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

📄 vxdmon.c

📁 VxDMon_系统驱动监视器,对感兴趣的人会有帮助的。
💻 C
📖 第 1 页 / 共 4 页
字号:
	CloseHandle( fp );
	return;
}

/******************************************************************************
*
*	FUNCTION:	ClickPoint
*
*	PURPOSE:	Return the point, in window-space coordinates, where the
*				cursor was clicked.
*
******************************************************************************/
POINT ClickPoint( HWND hWnd )
{
	POINT	point;
	DWORD	dwpos = GetMessagePos();
	point.x = LOWORD( dwpos );
	point.y = HIWORD( dwpos );
	MapWindowPoints( HWND_DESKTOP, hWnd, &point, 1 );
	return point;
}


/******************************************************************************
*
*	FUNCTION:	CreateCallTree
*
*	PURPOSE:	Open a descendant/ancestor call tree window.
*				Uses global variables to determine what type of tree is desired.
******************************************************************************/
void CreateCallTree( HWND hWnd, struct vxdmon_stats * item, BOOL calldown )
{
	HWND		hCallTree;

	// Set global variables indicating contents of new window
	CallTreeStat = item;
	CallTreeDown = calldown;

	// Set name of window
	if ( CallTreeDown )
		wsprintf( msgbuf, "Services called by %s", 
				LookupService(((struct vxdmon_stats *) CallTreeStat)->Ordinal)->Name );
	else
		wsprintf( msgbuf, "Callers of %s", 
				LookupService(((struct vxdmon_stats *) CallTreeStat)->Ordinal)->Name ); 

	// Create a call-tree window for the service
	hCallTree = CreateWindow( calldown ? "VxDMonCallDownClass" : "VxDMonCallUpClass",
						msgbuf,
						WS_OVERLAPPEDWINDOW,
						CW_USEDEFAULT, CW_USEDEFAULT, 300, 300,
						NULL, NULL, hInst, NULL );
	if ( !hCallTree )  {
		wsprintf( msgbuf, "Call tree not created: Error %d", GetLastError() );
		MessageBox( hWnd, msgbuf, NULL, MB_OK );
	}
	// Display the window
	ShowWindow( hCallTree, SW_SHOWNORMAL );
	UpdateWindow( hCallTree );
}


/******************************************************************************
*
*	FUNCTION:	WriteCallData
*
*	PURPOSE:	Write the call-tree information to a file
*
******************************************************************************/
void WriteCallData( HANDLE fp, HWND hTree, HTREEITEM hItem, int depth )
{
	HTREEITEM	Child;
	char		Line[ 100 ];
	DWORD		cnt = 0;
	TV_ITEM		tvi;
	int			i;
	char		servicename[64];

	// Get the item's name
	tvi.hItem 	= hItem;
	tvi.mask 	= TVIF_TEXT | TVIF_PARAM;
	tvi.pszText	= servicename;
	tvi.cchTextMax	= sizeof servicename;
	TreeView_GetItem( hTree, &tvi );

	// don't print root since its redundant
	if ( depth >= 0 ) {
		// Print a number of tabs equal to depth
		for ( i = 0; i < depth; i++ )  {
			wsprintf( Line, "\t");
			WriteFile( fp, Line, strlen(Line), &cnt, NULL );
		}
		// Print the name of the service
		wsprintf( Line,"%s\r\n", servicename );
		WriteFile( fp, Line, strlen(Line), &cnt, NULL );
	}

	// If any children exist then recurse on them
	for ( Child = TreeView_GetChild( hTree, hItem );
		  Child != NULL;
		  Child = TreeView_GetNextSibling( hTree, Child ) )
	{
		WriteCallData( fp, hTree, Child, depth+1 );
	}

	return;
}


/******************************************************************************
*
*	FUNCTION:	SaveCallData
*
*	PURPOSE:	Write a call tree to an ASCII file.
*
******************************************************************************/
void SaveCallData( HWND hWnd, char * CallFileName, HWND hWndTreeView )
{
	SECURITY_ATTRIBUTES	security;
	HANDLE				fp;
	char				Line[128];
	int					cnt;

	// Open the file
	memset( &security, 0, sizeof security );
	security.nLength = sizeof security;
	fp = CreateFile( CallFileName, GENERIC_WRITE, FILE_SHARE_WRITE, 
					 &security, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
	if ( fp == INVALID_HANDLE_VALUE )  {
		wsprintf( msgbuf, "Can't open \"%s\": Error %d", CallFileName, GetLastError() );
		MessageBox( NULL, msgbuf, NULL, MB_OK );
		return;
	}

	// Fetch text from title bar of window
	GetWindowText( hWnd, msgbuf, sizeof msgbuf );
	// Write title bar to file
	wsprintf( Line, "%s:\r\n\n", msgbuf );
	WriteFile( fp, Line, strlen(Line), &cnt, NULL );

	// Write call tree data to file
	WriteCallData( fp, hWndTreeView, TreeView_GetChild(hWndTreeView, 0 ), -1 );
	
	// Close file and exit
  	CloseHandle( fp );
	return;
}


/****************************************************************************
*
*    FUNCTION: CallWndProc( HWND, unsigned, WORD, LONG )
*
*    PURPOSE:  Processes messages for call-tree windows
*
****************************************************************************/

LONG APIENTRY CallWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam )
{
	HWND			hWndTreeView;   // Handle of the tree window
	RECT 			rc;				// rectangle for setting size of window
	NM_TREEVIEW *	tv;

	// Get value of tree window saved during WM_CREATE
	hWndTreeView = (HWND) GetWindowLong( hWnd, 0 );

	switch ( message )  {

		case WM_CREATE:
			// Get the size and position of the parent window.
			GetClientRect( hWnd, &rc );

			// Create the tree view window.
			hWndTreeView = CreateWindowEx( 0L, WC_TREEVIEW,	"",
				WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT,
				0, 0, rc.right - rc.left, rc.bottom - rc.top - 15,
				hWnd, (HMENU)ID_CALLVIEW, hInst, NULL );
			if ( hWndTreeView == NULL )
				MessageBox( NULL, "Call Tree View not created!", NULL, MB_OK );

			// Save the treeview handle for later invocations
			SetWindowLong( hWnd, 0, (LONG)hWndTreeView );

			// Set image list for tree
	   		TreeView_SetImageList( hWndTreeView, hCallImageList, 0 );

			// post hourglass icon
			SetCapture(hWnd);
			hSaveCursor = SetCursor(hHourGlass);

			// Add all callers/callees to tree
			AddCallTreeItems( hWndTreeView, TVI_ROOT, CallTreeStat, 0 );

			// notify user that operation is done
			SetCursor(hSaveCursor);
			ReleaseCapture();

			break;          

        case WM_SIZE:
			// Move or resize window
            MoveWindow( hWndTreeView, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
            break;

		case WM_NOTIFY:
			// Detect double clicks on items
			if ( wParam != ID_CALLVIEW )
				return 0;
	    	tv = (NM_TREEVIEW *) lParam;
			if ( tv->hdr.code == NM_DBLCLK  ||  tv->hdr.code == NM_RDBLCLK )  {
				// Have a double click
		        TV_HITTESTINFO	tvhti;
		        HTREEITEM		htiItemClicked;

				// Ensure the click was on something interesting
		        tvhti.pt = ClickPoint( hWndTreeView );
		        htiItemClicked = TreeView_HitTest( hWndTreeView, &tvhti );
				if ( htiItemClicked  &&  tvhti.flags & TVHT_ONITEM )  {
					// Create call graph for item clicked on
					TV_ITEM		Item;

					// Determine which service was clicked
					Item.mask		= TVIF_PARAM;
					Item.hItem		= htiItemClicked;
					if ( ! TreeView_GetItem( hWndTreeView, &Item ) )
						return 0;

					// Create the window
					CreateCallTree( hWnd,
									(struct vxdmon_stats *) Item.lParam,
									tv->hdr.code == NM_DBLCLK );
				}
			}
			break;

		case WM_COMMAND:
			switch ( LOWORD( wParam ) )  {
				case IDM_ANCESTORS:
				case IDM_DESCENDANTS:  {
					// Create call graph for currently selected item
					TV_ITEM		Item;
					HTREEITEM	hItem = TreeView_GetSelection( hWndTreeView );
					if ( ! hItem )
						return 0;

					// Get info about currently select item
					Item.mask	= TVIF_PARAM;
					Item.hItem	= hItem;
					if ( ! TreeView_GetItem( hWndTreeView, &Item ) )
						return 0;

					// Create the window
					CreateCallTree( hWnd,
									(struct vxdmon_stats *) Item.lParam,
									LOWORD(wParam) == IDM_DESCENDANTS );
					return 0;
				}

				case IDM_CALLSAVE:
					// Save call graph to file
 					if( GetFileName( hWnd, CallFileName, "Call Graph Files (*.CLL)\0*.CLL\0", 
 								"CLL" )) 
						SaveCallData( hWnd, CallFileName, hWndTreeView );
					return 0;

				case IDM_EXIT:
					// Close call graph
					SendMessage( hWnd, WM_CLOSE, 0, 0 );
					return 0;

				default:
					return DefWindowProc( hWnd, message, wParam, lParam );
			}
			break;

		default:
			return DefWindowProc( hWnd, message, wParam, lParam );
	}
	return 0;
}

/******************************************************************************
*
*	FUNCTION:	AddCallTreeItems
*
*	PURPOSE:	Build a call tree based upon contents of statitics buffer.
*				We rely on brute force searching of all the data, rather
*				than doing anything intelligent.
*
******************************************************************************/
BOOL AddCallTreeItems( HWND hTree, HTREEITEM Parent, struct vxdmon_stats * stats, int depth )
{
	DWORD		j;
	HTREEITEM	me;
	char	*	Name = LookupService(stats->Ordinal)->Name;
	TV_ITEM		tvi;

	// Add the given, top-level, item
	me = AddOneTreeViewItem( hTree, Parent, TVI_SORT, Name, (DWORD)stats );

	// Set image for direction of call
	tvi.hItem			= me;
	tvi.mask			= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
	tvi.iImage			= depth == 0 ? CALL_NONE : CallTreeDown ? CALL_DOWN : CALL_UP;
	tvi.iSelectedImage	= tvi.iImage;
	TreeView_SetItem( hTree, &tvi );
	
	// Check if we appear as our own ancestor
	while ( Parent != NULL  &&  Parent != TVI_ROOT )  {
		TV_ITEM	Item;
		Item.mask	= TVIF_PARAM;
		Item.hItem	= Parent;
		TreeView_GetItem( hTree, &Item ); 
		if ( Item.lParam == (int)stats )
			// We're part of a cycle.  Don't recurse on children
			return TRUE;
		Parent = TreeView_GetParent( hTree, Parent ); 
	}

	if ( CallTreeDown )  {
		// Add everything item calls
		for ( j = 0; j < numStats; ++j )  {
			DWORD c;
			for ( c = 0; c < CALLER_CNT; ++c )  {
				if ( Stats[j].Caller[c] == stats->Ordinal )  {
					// Make sure item is not already in tree
					HTREEITEM Sibling;
					for ( Sibling = TreeView_GetChild( hTree, me );
						  Sibling != NULL;
						  Sibling = TreeView_GetNextSibling( hTree, Sibling ) )
					{		   
						TV_ITEM		tvi;

						// Get sibling info
						tvi.hItem = Sibling;
						tvi.mask = TVIF_PARAM;
						TreeView_GetItem( hTree, &tvi );
						if ( tvi.lParam == (int) &Stats[j] )
							goto duplicate_callee;
					}

				 	// Add item to tree
					AddCallTreeItems( hTree, me, &Stats[j], depth+1 );
				}
			}
			duplicate_callee:;
		}
	} else {
		// Add everything calling item
		for ( j = 0; j < CALLER_CNT; ++j )  {
			DWORD child = stats->Caller[j];
			if ( child )  {
				DWORD c;

				// Ensure we haven't already added child
				for ( c = 0; c < j; ++c )
					if ( stats->Caller[c] == child )
						goto duplicate_caller;

				// Locate child
				for ( c = 0; c < numStats; ++c )
					if ( Stats[c].Ordinal == child )
						break;
				if ( c >= numStats )
					continue;

				// Recurse on child
				AddCallTreeItems( hTree, me, &Stats[c], depth+1 );
			}
			duplicate_caller:;
		}
	}

	// Initially have tree fully expanded (except first level)
	if ( depth != 1 )
		TreeView_Expand( hTree, me, TVE_EXPAND ); 

	return TRUE;
}


/***************************************************************************
* 
*    FUNCTION:	HookServices
*
*    PURPOSE:	Hook/unhook all services marked in selection tree view  
*
****************************************************************************/

BOOL HookServices( HWND hTree, HTREEITEM hItem )
{
	HTREEITEM		Child 			= TreeView_GetChild( hTree, hItem );
	static DWORD  	NotLoadedOrd	= (DWORD) -1;
    DWORD           nb;

	if ( Child )  {
		// This is not a leaf item.  Recurse on all children.
		while ( Child != NULL )  {
			HookServices( hTree, Child );
			Child = TreeView_GetNextSibling( hTree, Child );
		}
	} else {
		// Leaf item.  Tell VxD to hook/unhook it.
		TV_ITEM				tvi;
		struct service	*	pService;

		// Determine current hook state
		tvi.hItem = hItem;
		tvi.mask = TVIF_IMAGE | TVIF_PARAM;
		TreeView_GetItem( hTree, &tvi );
		pService = (struct service *) tvi.lParam;
		if ( pService->Hooked != (tvi.iImage == HOOK_YES) )  {
			// do we already know that vxd is not loaded?
			if( NotLoadedOrd == (pService->Ordinal >> 16 )) {
				// Reset state of item
				SetTreeItemState( hTree, hItem,
							pService->Hooked ? HOOK_YES : HOOK_NO, FALSE );
			} else {
				// try to hook the service
				if ( DeviceIoControl( vxd_handle,
									pService->Hooked
										? VXDMON_unhookservice
										: VXDMON_hookservice,
									&pService->Ordinal, sizeof(DWORD),
									NULL, 0, &nb, NULL ) )
				{
					// Successfully hooked/unhooked service.  Mark as such.
					NotLoadedOrd 	 = (DWORD) -1;
					pService->Hooked = !pService->Hooked;
				} else {
					// Hook/unhook failed.  Find out why.
					DWORD ErrorCode = GetLastError();
					char vxdname[ 12 ];

					// get VxD name for error message
					tvi.hItem		= TreeView_GetParent( hTree, hItem );
					tvi.mask		= TVIF_TEXT | TVIF_PARAM;
					tvi.pszText		= vxdname;
					tvi.cchTextMax	= sizeof vxdname;
					TreeView_GetItem( hTree, &tvi );

					// error because VxD not loaded?
					if ( ErrorCode == VXDMON_ERROR_NOSUCHVXD ) {
						wsprintf( msgbuf, "\nVxD %s is not loaded\n\n", vxdname );
						NotLoadedOrd = pService->Ordinal >> 16;		
					} else { 
						// unknown error
						wsprintf( msgbuf, "Couldn't %s service\n\n%s:%s\n#0x%08X",
								 pService->Hooked ? "unhook" : "hook",
								 vxdname, pService->Name, pService->Ordinal );
					}
					MessageBox( NULL, msgbuf, NULL, MB_ICONEXCLAMATION );

					// Reset state of item to what it was before being selected/deselected
					SetTreeItemState( hTree, hItem,
								pService->Hooked ? HOOK_YES : HOOK_NO, FALSE );
				}
			}
		}
	}

	return TRUE;
}

/****************************************************************************
*
*	FUNCTION:	About
*
*	PURPOSE:	Processes messages for "About" dialog box
*
****************************************************************************/

BOOL APIENTRY About( HWND hDlg, UINT message, UINT wParam, LONG lParam )
{
	switch ( message )  {
	   case WM_INITDIALOG:
		  return TRUE;

	   case WM_COMMAND:              
		  if ( LOWORD( wParam ) == IDOK )	 {
			  EndDialog( hDlg, TRUE );
			  return TRUE;
		  }
		  break;
	}
	return FALSE;   
}

⌨️ 快捷键说明

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