A盾学习笔记(1)
发布日期:2021-06-29 01:11:23 浏览次数:2 分类:技术文章

本文共 19051 字,大约阅读时间需要 63 分钟。

功能模块

枚举Hook()

PE与内核重载

内核模块(驱动)

内核信息(线程,DPC定时器,系统回调)

过滤驱动

DISPATCH例程

系统进程

系统服务

网络连接(TCP/UDP端口与IP)

删文件(强删文件思路,正在运行中的程序,sectionObject里面的值清0,构造个IRP下发,独占的就去全局句柄表拷贝句柄,然后关掉,对于硬链接(不夸磁盘盘符的,通过引用计数,软连接是快捷方式)占坑的方式是XCB,或者磁盘填0删除)

杀进程(通过线程插入APC,通常线程运行的级别是PASSIVE_LEVEL,插入APC的话级别高,优先运行,就杀掉了。还可以通过ZwTerminateProcess更低的PspTerminateProcess)

禁止驱动加载

禁止进程创建

禁止文件创建

DriverEntry流程

应用层和内核层通信不是走到DeviceIoControl,通过Hook了ZwCreateFile,SSDT的NtReadFile。把其中的handle设置为控制码。所以如果为了方便以后观摩a盾的某些功能就去NtReadFile去查看。SSDThook也不一样,正常是拿SSDFT表首地址,然后通过eax(xp是ZW函数起始加1就是索引,后面版本搜索eax)拿index。然后找到函数地址。A盾是通过函数名字,解析ntdll.dll文件,找到索引号。通过将其加载到内存,再解析pe文件导出表,所以不能在x64运行。

NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath ){	ULONG ulSize;	ULONG ulKeServiceDescriptorTable;	int i = 0;	PEPROCESS EProcess;	HANDLE HThreadHandle;	HANDLE ThreadHandle;	DriverObject->DriverUnload = DriverUnload;	PDriverObject = DriverObject;//PDriverObject全局对象记录驱动对象	RetAddress=*(DWORD*)((DWORD)&DriverObject-4);//驱动调用约定是stdcall,所以栈从下到上依次是theRegistryPath,DriverObject,返回地址,老ebp,局部变量。DriverObject-4就是返回地址												//返回地址再Ntskernl.dll中因为是系统调用了driverEntry,拿返回地址为了栈回溯	ulMyDriverBase = DriverObject->DriverStart;	ulMyDriverSize = DriverObject->DriverSize;	DebugOn = FALSE;  //开启调式信息	KdPrint(("//---------------------------------------//\r\n"	       	"//  A-Protect Anti-Rootkit Kernel Module  //\r\n"			"//      Kernel Module Version 0.2.5      //\r\n"		     "//  website:http://www.3600safe.com     //\r\n"	         "//---------------------------------------//\r\n"));	//DriverEntry处于system上下文,拿到Eprocess属于系统的eprocess	SystemEProcess = PsGetCurrentProcess();	WinVersion = GetWindowsVersion();  //初始化系统版本	if (WinVersion)		KdPrint(("Init Windows version Success\r\n"));	DepthServicesRegistry = NULL;	//-----------------------------------------	//注册一个系统回调	if (PsCreateSystemThread(		&HThreadHandle,		0,		NULL,		NULL,		NULL,		IsKernelBooting,		NULL) == STATUS_SUCCESS)	{		ZwClose(HThreadHandle);	}	return STATUS_SUCCESS;}
WIN_VER_DETAIL GetWindowsVersion(){	UNICODE_STRING ustrFuncName = { 0 }; 	RTL_OSVERSIONINFOEXW osverinfo = { sizeof(osverinfo) }; 	PFN_RtlGetVersion pfnRtlGetVersion = NULL;	if (WinVersion)		return WinVersion;	RtlInitUnicodeString(&ustrFuncName, L"RtlGetVersion"); 	pfnRtlGetVersion = MmGetSystemRoutineAddress(&ustrFuncName); //根据函数名字拿地址,不直接用RtlGetVersion,而是这样,因为RtlGetVersion不是所有系统都有的	if (pfnRtlGetVersion)	{ 		pfnRtlGetVersion((PRTL_OSVERSIONINFOW)&osverinfo); 	} 	else 	{		PsGetVersion(&osverinfo.dwMajorVersion, &osverinfo.dwMinorVersion, &osverinfo.dwBuildNumber, NULL);	}// 	KdPrint(("[xxxxxxxx] OSVersion NT %d.%d:%d sp%d.%d\n", // 		osverinfo.dwMajorVersion, osverinfo.dwMinorVersion, osverinfo.dwBuildNumber, // 		osverinfo.wServicePackMajor, osverinfo.wServicePackMinor));	if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0) 	{		WinVersion = WINDOWS_VERSION_2K;	} 	else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1) 	{		WinVersion = WINDOWS_VERSION_XP;	} 	else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2) 	{		if (osverinfo.wServicePackMajor==0) 		{ 			WinVersion = WINDOWS_VERSION_2K3;		} 		else 		{			WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;		}	} 	else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0) 	{		WinVersion = WINDOWS_VERSION_2K3_SP1_SP2;	}	else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1)	{		WinVersion = WINDOWS_VERSION_7;	}	return WinVersion;}
VOID IsKernelBooting(IN PVOID Context){	PEPROCESS EProcess;	NTSTATUS status;	PUCHAR KiFastCallEntry;	while (1)	{		EProcess = NULL;		if (LookupProcessByName("Smss.exe",&EProcess) == STATUS_SUCCESS)//自己写查找进程链里有无这个smss的进程。eprocess里的imageName就是名字			//eprocess未导出。可以硬编码便宜长度,driverEntry拿到system的eprocess结构,然后自己的eprocess的imagename偏移距离其他eprocess应该一样。			//找smss因为,这个内核会启动会话管理器(Session Manager)这个是windows系统中,第一个创建的用户模式进程,其作用如下			/*			1.创建系统环境变量			2.启动win32k.sys,这是windows子系统的内核模式部分			3.启动csrss,这个是windows子系统用户模式部分			4.启动winlogon.exe			5.创建虚拟内存页面文件			6.对一些必要的文件进行改名,(主要是驱动文件,如果更新后,下次重启跟新)			*/		{			_asm			{//获取kifastcall,应用层进内核入口,检测隐藏进程				pushad;				mov ecx, 0x176;				rdmsr;				mov KiFastCallEntry, eax;				popad;			}			if (*KiFastCallEntry == 0xe9)//jmp,意味着被hook了			{				KdPrint(("Terminate System Thread"));				PsTerminateSystemThread(STATUS_SUCCESS);			}			if (ReLoadNtos(PDriverObject,RetAddress) == STATUS_SUCCESS)//重载内核			{				InitControl();				if (bKernelBooting)				{					//---------------------------------------					//demo,深度服务扫描隐藏					//---------------------------------------					DepthServicesRegistry = (PSERVICESREGISTRY)ExAllocatePool(NonPagedPool,(sizeof(SERVICESREGISTRY)+sizeof(SERVICESREGISTRY_INFORMATION))*1024);					if (DepthServicesRegistry)					{						memset(DepthServicesRegistry,0,(sizeof(SERVICESREGISTRY)+sizeof(SERVICESREGISTRY_INFORMATION))*1024);						status = QueryServicesRegistry(DepthServicesRegistry);						if (status == STATUS_SUCCESS)						{							Safe_CreateValueKey(								L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\3600safe",								REG_SZ,								L"QueryServicesRegistry",								L"success"								);						}					}					bKernelBooting = FALSE;				}				PsTerminateSystemThread(STATUS_SUCCESS);			}else			{				//不是随机启动,就退出线程				if (!bKernelBooting)					PsTerminateSystemThread(STATUS_SUCCESS);			}		}		else		{			bKernelBooting = TRUE;		}		WaitMicroSecond(1000);	}}NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath ){	ULONG ulSize;	ULONG ulKeServiceDescriptorTable;	int i = 0;	PEPROCESS EProcess;	HANDLE HThreadHandle;	HANDLE ThreadHandle;	DriverObject->DriverUnload = DriverUnload;	PDriverObject = DriverObject;//PDriverObject全局对象记录驱动对象	RetAddress=*(DWORD*)((DWORD)&DriverObject-4);//驱动调用约定是stdcall,所以栈从下到上依次是theRegistryPath,DriverObject,返回地址,老ebp,局部变量。DriverObject-4就是返回地址												//返回地址再Ntskernl.dll中因为是系统调用了driverEntry,拿返回地址为了栈回溯	ulMyDriverBase = DriverObject->DriverStart;	ulMyDriverSize = DriverObject->DriverSize;	DebugOn = FALSE;  //开启调式信息	KdPrint(("//---------------------------------------//\r\n"	       	"//  A-Protect Anti-Rootkit Kernel Module  //\r\n"			"//      Kernel Module Version 0.2.5      //\r\n"		     "//  website:http://www.3600safe.com     //\r\n"	         "//---------------------------------------//\r\n"));	//DriverEntry处于system上下文,拿到Eprocess属于系统的eprocess	SystemEProcess = PsGetCurrentProcess();	WinVersion = GetWindowsVersion();  //初始化系统版本	if (WinVersion)		KdPrint(("Init Windows version Success\r\n"));	DepthServicesRegistry = NULL;	//-----------------------------------------	//注册一个系统回调	if (PsCreateSystemThread(		&HThreadHandle,		0,		NULL,		NULL,		NULL,		IsKernelBooting,		NULL) == STATUS_SUCCESS)	{		ZwClose(HThreadHandle);	}	return STATUS_SUCCESS;}

 

BOOL GetSystemKernelModuleInfo(WCHAR **SystemKernelModulePath,PDWORD SystemKernelModuleBase,PDWORD SystemKernelModuleSize){	NTSTATUS status;	ULONG ulSize,i;	PMODULES pModuleList;	char *lpszKernelName=NULL;	ANSI_STRING AnsiKernelModule;	UNICODE_STRING UnicodeKernelModule;	BOOL bRet=TRUE;	__try	{		status=ZwQuerySystemInformation(			SystemModuleInformation,			NULL,			0,			&ulSize			);		if (status!=STATUS_INFO_LENGTH_MISMATCH)		{			return NULL;		}		pModuleList=(PMODULES)ExAllocatePool(NonPagedPool,ulSize);		if (pModuleList)		{			status=ZwQuerySystemInformation(				SystemModuleInformation,				pModuleList,				ulSize,				&ulSize				);			if (!NT_SUCCESS(status))			{				if (DebugOn)					KdPrint(("ZwQuerySystemInformation error:%x %d\r\n",status,RtlNtStatusToDosError(status)));				bRet = FALSE;			}		}		if (!bRet)		{			if (pModuleList)				ExFreePool(pModuleList);			return NULL;		}		*SystemKernelModulePath=ExAllocatePool(NonPagedPool,260*2);		if (*SystemKernelModulePath==NULL)		{			*SystemKernelModuleBase=0;			*SystemKernelModuleSize=0;			return NULL;		}		lpszKernelName = pModuleList->smi[0].ModuleNameOffset+pModuleList->smi[0].ImageName;		RtlInitAnsiString(&AnsiKernelModule,lpszKernelName);		RtlAnsiStringToUnicodeString(&UnicodeKernelModule,&AnsiKernelModule,TRUE);		RtlZeroMemory(*SystemKernelModulePath,260*2);		wcscat(*SystemKernelModulePath,L"\\SystemRoot\\system32\\");		memcpy(			*SystemKernelModulePath+wcslen(L"\\SystemRoot\\system32\\"),			UnicodeKernelModule.Buffer,			UnicodeKernelModule.Length			);		*SystemKernelModuleBase=(DWORD)pModuleList->smi[0].Base;		*SystemKernelModuleSize=(DWORD)pModuleList->smi[0].Size;		ExFreePool(pModuleList);		RtlFreeUnicodeString(&UnicodeKernelModule);	}__except(EXCEPTION_EXECUTE_HANDLER){	}	return TRUE;}

 

BOOL InitSafeOperationModule(PDRIVER_OBJECT pDriverObject,WCHAR *SystemModulePath,ULONG KernelModuleBase){	UNICODE_STRING FileName;	HANDLE hSection;	PDWORD FixdOriginalKiServiceTable;	PDWORD CsRootkitOriginalKiServiceTable;	int i=0;	if (DebugOn)		KdPrint(("Safe->Get System Kernel Module Info %ws:%08x\r\n",SystemModulePath,KernelModuleBase));	if (DebugOn)		KdPrint(("Safe->DriverObject:%08x\r\n",pDriverObject));	//自己peload 一个ntos*,这样就解决了跟其他安全软件的冲突啦~	if (!PeLoad(SystemModulePath,&ImageModuleBase,pDriverObject,KernelModuleBase))	{		if (DebugOn)			KdPrint(("Safe->PeLoad failed\n"));		return FALSE;	}	if (DebugOn)		KdPrint(("Safe->ModuleBase:%08x\r\n",ImageModuleBase));	OriginalKiServiceTable = ExAllocatePool(NonPagedPool,KeServiceDescriptorTable->TableSize*sizeof(DWORD));	if (!OriginalKiServiceTable)	{		if (DebugOn)			KdPrint(("OriginalKiServiceTable Failed\n"));		return FALSE;	}	if(!GetOriginalKiServiceTable(ImageModuleBase,KernelModuleBase,&OriginalKiServiceTable))	{		if (DebugOn)			KdPrint(("Safe->Get Original KiServiceTable Failed\n"));		ExFreePool(OriginalKiServiceTable);		return FALSE;	}	if (DebugOn)		KdPrint(("Safe->OriginalKiServiceTable %X\n",OriginalKiServiceTable));	//填充每一个ssdt对应函数地址~这里的地址是reload的    FixOriginalKiServiceTable((PDWORD)OriginalKiServiceTable,(DWORD)ImageModuleBase,KernelModuleBase);	OriginalServiceDescriptorTable=ExAllocatePool(NonPagedPool,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);	if (OriginalServiceDescriptorTable == NULL)	{		ExFreePool(OriginalKiServiceTable);		return FALSE;	}	RtlZeroMemory(OriginalServiceDescriptorTable,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);	//这是一个干净的原始表,每个表里所对应的SSDT函数的地址都是有效的~	OriginalServiceDescriptorTable->ServiceTable = (PDWORD)OriginalKiServiceTable;	OriginalServiceDescriptorTable->CounterTable = KeServiceDescriptorTable->CounterTable;	OriginalServiceDescriptorTable->TableSize    = KeServiceDescriptorTable->TableSize;	OriginalServiceDescriptorTable->ArgumentTable = KeServiceDescriptorTable->ArgumentTable;	CsRootkitOriginalKiServiceTable = ExAllocatePool(NonPagedPool,KeServiceDescriptorTable->TableSize*sizeof(DWORD));	if (CsRootkitOriginalKiServiceTable==NULL)	{		ExFreePool(OriginalServiceDescriptorTable);		ExFreePool(OriginalKiServiceTable);		return FALSE;	}	RtlZeroMemory(CsRootkitOriginalKiServiceTable,KeServiceDescriptorTable->TableSize*sizeof(DWORD));	Safe_ServiceDescriptorTable = ExAllocatePool(NonPagedPool,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);	if (Safe_ServiceDescriptorTable == NULL)	{		ExFreePool(OriginalServiceDescriptorTable);		ExFreePool(CsRootkitOriginalKiServiceTable);		ExFreePool(OriginalKiServiceTable);		return FALSE;	}	//这是一个干净的原始表,每个表里所对应的SSDT函数的地址都是原始函数	RtlZeroMemory(Safe_ServiceDescriptorTable,sizeof(SERVICE_DESCRIPTOR_TABLE)*4);		//填充原始函数地址	for (i=0;i
TableSize;i++) { CsRootkitOriginalKiServiceTable[i] = OriginalServiceDescriptorTable->ServiceTable[i]; } Safe_ServiceDescriptorTable->ServiceTable = (PDWORD)CsRootkitOriginalKiServiceTable; Safe_ServiceDescriptorTable->CounterTable = KeServiceDescriptorTable->CounterTable; Safe_ServiceDescriptorTable->TableSize = KeServiceDescriptorTable->TableSize; Safe_ServiceDescriptorTable->ArgumentTable = KeServiceDescriptorTable->ArgumentTable; //释放就会bsod //ExFreePool(OriginalKiServiceTable); return TRUE;}
BOOL PeLoad(	WCHAR *FileFullPath,	BYTE **ImageModeleBase,	PDRIVER_OBJECT DeviceObject,	DWORD ExistImageBase	){	NTSTATUS Status;	HANDLE hFile;	LARGE_INTEGER FileSize;	DWORD Length;	BYTE *FileBuffer;	BYTE *ImageBase;	IO_STATUS_BLOCK IoStatus;	Status=KernelOpenFile(FileFullPath,&hFile,0x100020,0x80,1,1,0x20);	if (!NT_SUCCESS(Status))	{		return FALSE;	}	if (DebugOn)		KdPrint(("Open File ok\n"));	Status=KernelGetFileSize(hFile,&FileSize);	if (!NT_SUCCESS(Status))	{		ZwClose(hFile);		return FALSE;	}	if (DebugOn)		KdPrint(("Get File Size ok\n"));	Length=FileSize.LowPart;	FileBuffer=ExAllocatePool(PagedPool,Length);	if (FileBuffer==NULL)	{		ZwClose(hFile);		return FALSE;	}	Status=KernelReadFile(hFile,NULL,Length,FileBuffer,&IoStatus);	if (!NT_SUCCESS(Status))	{		ZwClose(hFile);		ExFreePool(FileBuffer);		return FALSE;	}	if (DebugOn)		KdPrint(("Read File Ok\n"));	ZwClose(hFile);	if (DebugOn)		KdPrint(("ZwClose ok\n"));	if(!ImageFile(FileBuffer,&ImageBase))	{		if (DebugOn)			KdPrint(("ImageFile failed\n"));		ExFreePool(FileBuffer);		return FALSE;	}	ExFreePool(FileBuffer);	//2k3下MiFindExportedRoutine调用失败	if(!FixImportTable(ImageBase,ExistImageBase,DeviceObject))	{		if (DebugOn)			KdPrint(("FixImportTable failed\n"));		ExFreePool(ImageBase);		return FALSE;	}	if(!FixBaseRelocTable(ImageBase,ExistImageBase))	{		if (DebugOn)			KdPrint(("FixBaseRelocTable failed\n"));		ExFreePool(ImageBase);		return FALSE;	}	*ImageModeleBase=ImageBase;	if (DebugOn)		KdPrint(("reload success\n"));	return TRUE;}

其中要自己实现readfile等不能调用zwxxx因为可能已经被污染了。随便观察个比如readfile,通过自己构造irp,然后iocalldriver调用

NTSTATUS KernelReadFile(HANDLE hFile, PLARGE_INTEGER ByteOffset, ULONG Length, PVOID FileBuffer, PIO_STATUS_BLOCK IoStatusBlock){	NTSTATUS status;	PFILE_OBJECT FileObject;	PDEVICE_OBJECT DeviceObject,RealDevice;	FILE_STANDARD_INFORMATION FileInformation;	status=ObReferenceObjectByHandle(hFile, 0, *IoFileObjectType, KernelMode, &FileObject, 0);	if (!NT_SUCCESS(status))	{		return status;	}	if(!IoGetFileSystemVpbInfo(FileObject,&DeviceObject,&RealDevice))	{		ObDereferenceObject(FileObject);		return STATUS_UNSUCCESSFUL;	}	status=IrpReadFile(FileObject,DeviceObject,IoStatusBlock,FileBuffer,Length,ByteOffset);	ObDereferenceObject(FileObject);	return status;}
NTSTATUSIrpReadFile(			IN PFILE_OBJECT FileObject,			IN PDEVICE_OBJECT DeviceObject,			OUT PIO_STATUS_BLOCK IoStatusBlock,			OUT PVOID Buffer,			IN ULONG Length,			IN PLARGE_INTEGER ByteOffset OPTIONAL){	NTSTATUS ntStatus;	PIRP Irp;	KEVENT kEvent;	PIO_STACK_LOCATION IrpSp;// 	if(ByteOffset == NULL)	{		if(!(FileObject->Flags & FO_SYNCHRONOUS_IO))			return STATUS_INVALID_PARAMETER;		ByteOffset = &FileObject->CurrentByteOffset;	}	Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);	if(Irp == NULL) return STATUS_INSUFFICIENT_RESOURCES;	RtlZeroMemory(Buffer, Length);	if(FileObject->DeviceObject->Flags & DO_BUFFERED_IO)	{		Irp->AssociatedIrp.SystemBuffer = Buffer;	}	else if(FileObject->DeviceObject->Flags & DO_DIRECT_IO)	{		Irp->MdlAddress = IoAllocateMdl(Buffer, Length, 0, 0, 0);		if (Irp->MdlAddress == NULL)		{			IoFreeIrp(Irp);			return STATUS_INSUFFICIENT_RESOURCES;		}		MmBuildMdlForNonPagedPool(Irp->MdlAddress);	}	else	{		Irp->UserBuffer = Buffer;	}	KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);	Irp->UserEvent = &kEvent;	Irp->UserIosb = IoStatusBlock;	Irp->RequestorMode = KernelMode;	Irp->Flags = IRP_READ_OPERATION;	Irp->Tail.Overlay.Thread = PsGetCurrentThread();	Irp->Tail.Overlay.OriginalFileObject = FileObject;	IrpSp = IoGetNextIrpStackLocation(Irp);	IrpSp->MajorFunction = IRP_MJ_READ;	IrpSp->MinorFunction = IRP_MN_NORMAL;	IrpSp->DeviceObject = DeviceObject;	IrpSp->FileObject = FileObject;	IrpSp->Parameters.Read.Length = Length;	IrpSp->Parameters.Read.ByteOffset = *ByteOffset;	IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);	ntStatus = IoCallDriver(DeviceObject, Irp);	if (ntStatus == STATUS_PENDING)		KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);	return IoStatusBlock->Status;
ULONG ReLoadNtosCALL(WCHAR *lpwzFuncTion,ULONG ulOldNtosBase,ULONG ulReloadNtosBase){	UNICODE_STRING UnicodeFunctionName;	ULONG ulOldFunctionAddress;	ULONG ulReloadFunctionAddress;	int index=0;	PIMAGE_DOS_HEADER pDosHeader;	PIMAGE_NT_HEADERS NtDllHeader;	IMAGE_OPTIONAL_HEADER opthdr;	DWORD* arrayOfFunctionAddresses;	DWORD* arrayOfFunctionNames;	WORD* arrayOfFunctionOrdinals;	DWORD functionOrdinal;	DWORD Base, x, functionAddress,position;	char* functionName;	IMAGE_EXPORT_DIRECTORY *pExportTable;	ULONG ulNtDllModuleBase;	UNICODE_STRING UnicodeFunction;	UNICODE_STRING UnicodeExportTableFunction;	ANSI_STRING ExportTableFunction;	__try	{		if (RRtlInitUnicodeString &&			RRtlCompareUnicodeString &&			RMmGetSystemRoutineAddress &&			RMmIsAddressValid)		{			RRtlInitUnicodeString(&UnicodeFunctionName,lpwzFuncTion);			ulOldFunctionAddress = (DWORD)RMmGetSystemRoutineAddress(&UnicodeFunctionName);			ulReloadFunctionAddress = ulOldFunctionAddress - ulOldNtosBase + ulReloadNtosBase;			if (RMmIsAddressValid(ulReloadFunctionAddress))			{				return ulReloadFunctionAddress;			}			//从导出表里获取			ulNtDllModuleBase = ulReloadNtosBase;			pDosHeader = (PIMAGE_DOS_HEADER)ulReloadNtosBase;			if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)			{				KdPrint(("failed to find NtHeader\r\n"));				return NULL;			}			NtDllHeader=(PIMAGE_NT_HEADERS)(ULONG)((ULONG)pDosHeader+pDosHeader->e_lfanew);			if (NtDllHeader->Signature!=IMAGE_NT_SIGNATURE)			{				KdPrint(("failed to find NtHeader\r\n"));				return NULL;			}			opthdr = NtDllHeader->OptionalHeader;			pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*)ulNtDllModuleBase + opthdr.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); //得到导出表			arrayOfFunctionAddresses = (DWORD*)( (BYTE*)ulNtDllModuleBase + pExportTable->AddressOfFunctions);  //地址表			arrayOfFunctionNames = (DWORD*)((BYTE*)ulNtDllModuleBase + pExportTable->AddressOfNames);         //函数名表			arrayOfFunctionOrdinals = (WORD*)((BYTE*)ulNtDllModuleBase + pExportTable->AddressOfNameOrdinals);			Base = pExportTable->Base;			for(x = 0; x < pExportTable->NumberOfFunctions; x++) //在整个导出表里扫描			{				functionName = (char*)( (BYTE*)ulNtDllModuleBase + arrayOfFunctionNames[x]);				functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1; 				functionAddress = (DWORD)((BYTE*)ulNtDllModuleBase + arrayOfFunctionAddresses[functionOrdinal]);				RtlInitAnsiString(&ExportTableFunction,functionName);				RtlAnsiStringToUnicodeString(&UnicodeExportTableFunction,&ExportTableFunction,TRUE);								RRtlInitUnicodeString(&UnicodeFunction,lpwzFuncTion);				if (RRtlCompareUnicodeString(&UnicodeExportTableFunction,&UnicodeFunction,TRUE) == 0)				{					RtlFreeUnicodeString(&UnicodeExportTableFunction);					return functionAddress;				}				RtlFreeUnicodeString(&UnicodeExportTableFunction);			}			return NULL;		}		RtlInitUnicodeString(&UnicodeFunctionName,lpwzFuncTion);		ulOldFunctionAddress = (DWORD)MmGetSystemRoutineAddress(&UnicodeFunctionName);		ulReloadFunctionAddress = ulOldFunctionAddress - ulOldNtosBase + ulReloadNtosBase;		//KdPrint(("%ws:%08x:%08x",lpwzFuncTion,ulOldFunctionAddress,ulReloadFunctionAddress));		if (MmIsAddressValid(ulReloadFunctionAddress))		{			return ulReloadFunctionAddress;		}// 			}__except(EXCEPTION_EXECUTE_HANDLER){		KdPrint(("EXCEPTION_EXECUTE_HANDLER"));	}	return NULL;}

 

转载地址:https://blog.csdn.net/youyou519/article/details/94774294 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:A盾学习笔记(2)反inlinehook
下一篇:WFP笔记

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月22日 22时32分34秒