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

📄 wdmcheck.cpp

📁 Programming the Microsoft Windows driver model.2nd 随书光盘。内有很多作者送的实用工具和随书源码。WDM编程
💻 CPP
字号:
// wdmcheck.c -- Implementation of WDMCHECK.VXD

// Copyright (C) 2000 by Walter Oney

// All rights reserved



#include "stdvxd.h"

#include "wdmcheck.h"

#include "ioctls.h"

#include "version.h"



VOID GetStubInfo();

VOID DeleteStubInfo();

BOOL StringOkay(char* s, DWORD len);

DWORD IsExportDefined(char* module, char* fcn);



#define IOCTL_INTERNAL_WDMSTUB_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)



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

// Overrides for library new and delete operators.



void* __cdecl ::operator new(unsigned int size)

	{							// operator new

	return _HeapAllocate(size, 0);

	}							// operator new



void __cdecl ::operator delete(void* p)

	{							// operator delete

	if (p)

		_HeapFree(p, 0);

	}							// operator delete



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

// Global data areas:



#pragma VxD_PAGEABLE_DATA_SEG	// data which can be paged



CStubVersion* CStubVersion::Anchor = NULL;



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



WCHAR* wcscpy(WCHAR* target, WCHAR* source)

	{							// wcscpy

	WCHAR* result = target;

	WCHAR ch;

	do	{

		ch = *source++;

		*target++ = ch;

		}

	while (ch);



	return result;

	}							// wcscpy



int wcslen(WCHAR* s)

	{							// wcslen

	int len = 0;

	while (*s++)

		++len;

	return len;

	}							// wcslen



WCHAR* wcscat(WCHAR* target, WCHAR* source)

	{							// wcscat

	WCHAR* result = target;

	wcscpy(target + wcslen(target), source);

	return result;

	}							// wcscat



#pragma warning(disable:4035)



int  __declspec(naked) __cdecl _lstrcmpi(const char* left, const char* right)

	{							// _lstrcmpi

	VMMJmp(_lstrcmpi)

	}							// _lstrcmpi



Device_Location_List* VMM_GetVxDLocationList(DWORD& nvxds, DWORD& tabsize)

	{							// VMM_GetVxDLocationList

	VMMCall(VMM_GetVxDLocationList)

	_asm

		{

		jz		error

		push	eax

		mov		eax, nvxds

		mov		[eax], edx		; EDX = count of VxDs

		mov		eax, tabsize

		mov		[eax], ecx		; ECX = size of table

		pop		eax

	error:

		}

	}							// VMM_GetVxDLocationList



#pragma warning(default:4035)



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

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

// System control message handlers

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



#pragma VxD_INIT_CODE_SEG



SYSCTL BOOL __cdecl OnSysDynamicDeviceInit(void)

	{							// OnSysDynamicDeviceInit

	GetStubInfo();

	return TRUE;

	}							// OnSysDynamicDeviceInit



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



#pragma VxD_PAGEABLE_CODE_SEG



SYSCTL BOOL __cdecl OnSysDynamicDeviceExit(void)

	{							// OnSysDynamicDeviceExit

	DeleteStubInfo();

	return TRUE;

	}							// OnSysDynamicDeviceExit



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



#pragma VxD_PAGEABLE_CODE_SEG



SYSCTL DWORD __cdecl OnW32DeviceIoControl(PDIOCPARAMETERS p)

	{							// OnW32DeviceIoControl

	switch (p->dwIoControlCode)

		{						// process IOCTL operation



	case DIOC_OPEN:

	case DIOC_CLOSEHANDLE:

		return 0;



	case IOCTL_GET_VERSION:

		if (p->cbOutBuffer < sizeof(DWORD))

			return ERROR_INVALID_PARAMETER;

		*(PDWORD) p->lpvOutBuffer = (VERMAJOR << 16) | VERMINOR;

		if (p->lpcbBytesReturned)

			*(PDWORD) p->lpcbBytesReturned = sizeof(DWORD);

		return 0;



	case IOCTL_EXPORT_DEFINED:

		{						// IOCTL_EXPORT_DEFINE

		if (p->cbInBuffer < sizeof(EXPORT_DEFINED_PARMS))

			return ERROR_INVALID_PARAMETER;

		if (p->cbOutBuffer < sizeof(DWORD))

			return ERROR_INVALID_PARAMETER;



		PEXPORT_DEFINED_PARMS parms = (PEXPORT_DEFINED_PARMS) p->lpvInBuffer;



		if (!StringOkay(parms->modname, parms->modlen))

			return ERROR_INVALID_PARAMETER;

		if (HIWORD(parms->fcn))

			{					// function name is a string

			if (!StringOkay(parms->fcn, parms->fcnlen))

				return ERROR_INVALID_PARAMETER;

			}					// function name is a string



		*(PDWORD) p->lpvOutBuffer = IsExportDefined(parms->modname, parms->fcn);

		if (p->lpcbBytesReturned)

			*(PDWORD) p->lpcbBytesReturned = sizeof(DWORD);

		return 0;

		}						// IOCTL_EXPORT_DEFINED



	default:

		return ERROR_INVALID_FUNCTION;

		}						// process IOCTL operation

	}							// OnW32DeviceIoControl



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



VOID GetStubInfo()

	{							// GetStubInfo



	// Look for a VxD version of WDMSTUB



	PVMMDDB ddb = Get_DDB(0, "WDMSTUB ");

	if (ddb)

		new CStubVersion(ddb);



	// Look for WDMSTUB.SYS and OEM clones thereof



	for (ULONG index = 0; index < 100; ++index)

		{						// for each possible driver index

		WCHAR namebuf[32];

		UNICODE_STRING devname;



		// Note: _snwprintf not exported in wdmvxd.clb



		wcscpy(namebuf, L"\\Device\\WDMSTUB");

		char indexbuf[3];

		WCHAR windexbuf[3];

		_Sprintf(indexbuf, "%d", index);

		windexbuf[0] = indexbuf[0];

		windexbuf[1] = indexbuf[1];

		windexbuf[2] = indexbuf[2];

		wcscat(namebuf, windexbuf);

		RtlInitUnicodeString(&devname, namebuf);



		PFILE_OBJECT fop;

		PDEVICE_OBJECT clone;

		NTSTATUS status = IoGetDeviceObjectPointer(&devname, FILE_READ_DATA, &fop, &clone);



		if (NT_SUCCESS(status))

			{					// found another version

			new CStubVersion(clone);

			ObDereferenceObject(fop);

			}					// found another version

		}						// for each possible driver index



	if (!CStubVersion::Anchor)

		return;					// no WDMSTUB versions loaded, so just return



	// Run through the list of all loaded drivers (which is presumably much longer

	// than the list of WDMSTUBs) to determine the addresses of the sections in

	// these drivers. We have to run VXDLDR's and VMM's lists of drivers to get all

	// of this info



	for (DeviceInfo* dip = VXDLDR_GetDeviceList(); dip; dip = dip->DI_Next)

		{						// for each device

		char drvname[256];

		_Sprintf(drvname, "\\Driver\\%s.sys", dip->DI_ModuleName);

		for (CStubVersion* stub = CStubVersion::Anchor; stub; stub = stub->m_next)

			{					// for each WDMSTUB

			if (stub->m_ddb == dip->DI_DDB

				|| stub->m_name &&_lstrcmpi(stub->m_name, drvname) == 0)

				stub->GetSectionInfo(dip);

			}					// for each WDMSTUB

		}						// for each device



	DWORD nvxds;

	DWORD size;



	Device_Location_List* loclist = VMM_GetVxDLocationList(nvxds, size);

	for (DWORD ivxd = 0; ivxd < nvxds; ++ivxd)

		{						// for each VxD

		for (CStubVersion* stub = CStubVersion::Anchor; stub; stub = stub->m_next)

			{					// for each WDMSTUB

			if (stub->m_ddb == (PVMMDDB) loclist->DLL_DDB)

				stub->GetSectionInfo(loclist);

			}					// for each WDMSTUB

		loclist = (Device_Location_List*) (loclist->DLL_ObjLocation + loclist->DLL_NumObjects);

		}						// for each VxD

	}							// GetStubInfo



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



VOID DeleteStubInfo()

	{							// DeleteStubInfo

	while (CStubVersion::Anchor)

		delete CStubVersion::Anchor;

	}							// DeleteStubInfo



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

// Verify that a string pointer is valid and that null terminator is within

// the specified length



#pragma VxD_PAGEABLE_CODE_SEG



BOOL StringOkay(char* s, DWORD len)

	{							// StringOkay

	if (!_Assert_Range(s, len, 0, 0, 0))

		return FALSE;			// pointer is invalid in some way



	while (len--)

		if (!*s++)

			return TRUE;



	return FALSE;				// exhausted length before finding NUL

	}							// StringOkay



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



#pragma VxD_PAGEABLE_CODE_SEG



DWORD IsExportDefined(char* module, char* fcn)

	{							// IsExportDefined

	DWORD addr = (DWORD) _PELDR_GetProcAddress((HPEMODULE) module, fcn, NULL);

	if (!addr)

		return WDMCHECK_NOT_DEFINED;



	// This symbol is defined. See if the definition is inside WDMSTUB



	for (CStubVersion* stub = CStubVersion::Anchor; stub; stub = stub->m_next)

		{						// for each stub

		if (!stub->m_sections)

			continue;			// we never found this guy's sections

		for (ULONG i = 0; i < stub->m_nsections; ++i)

			if (addr >= stub->m_sections[i].startaddr && addr < stub->m_sections[i].endaddr)

				return WDMCHECK_STUB_DEFINED;

		}						// for each stub



	// The symbol must be exported by the regular kernel



	return 0;

	}							// IsExportDefined



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



CStubVersion::CStubVersion(PVMMDDB ddb)

	{							// CStubVersion::CStubVersion

	Initialize();

	m_ddb = ddb;

	}							// CStubVersion::CStubVersion



CStubVersion::CStubVersion(PDEVICE_OBJECT DeviceObject)

	{							// CStubVersion::CStubVersion

	Initialize();

	PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;

	ANSI_STRING as = {0};

	RtlUnicodeStringToAnsiString(&as, &DriverObject->DriverName, TRUE);

	m_name = as.Buffer;

	}							// CStubVersion::CStubVersion



CStubVersion::~CStubVersion()

	{							// CStubVersion::~CStubVersion

	if (m_next)

		m_next->m_prev = m_prev;

	if (m_prev)

		m_prev->m_next = m_next;

	else

		Anchor = m_next;

		

	if (m_name)

		_HeapFree(m_name, 0);

	if (m_nsections)

		delete [] m_sections;

	}							// CStubVersion::~CStubVersion



void CStubVersion::GetSectionInfo(DeviceInfo* dip)

	{							// CStubVersion::GetSectionInfo

	m_nsections = dip->DI_ObjCount;

	m_sections = new SECTION_INFO[m_nsections];

	for (ULONG i = 0; i < m_nsections; ++i)

		{						// for each section

		m_sections[i].startaddr = dip->DI_ObjInfo[i].OI_LinearAddress;

		m_sections[i].endaddr = dip->DI_ObjInfo[i].OI_LinearAddress + dip->DI_ObjInfo[i].OI_Size;

		}						// for each section

	}							// CStubVersion::GetSectionInfo



void CStubVersion::GetSectionInfo(Device_Location_List* dll)

	{							// CStubVersion::GetSectionInfo

	m_nsections = dll->DLL_NumObjects;

	m_sections = new SECTION_INFO[m_nsections];

	for (ULONG i = 0; i < m_nsections; ++i)

		{						// for each section

		m_sections[i].startaddr = dll->DLL_ObjLocation[i].OL_LinearAddr;

		m_sections[i].endaddr = dll->DLL_ObjLocation[i].OL_LinearAddr + dll->DLL_ObjLocation[i].OL_Size;

		}						// for each section

	}							// CStubVersion::GetSectionInfo



void CStubVersion::Initialize()

	{							// CStubVersion::Initialize

	m_next = Anchor;

	m_prev = NULL;

	if (Anchor)

		Anchor->m_prev = this;

	Anchor = this;



	m_ddb = NULL;

	m_name = NULL;

	m_nsections = 0;

	m_sections = NULL;

	}							// CStubVersion::Initialize

⌨️ 快捷键说明

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