A盾学习笔记(1)

85 篇文章 6 订阅
83 篇文章 9 订阅

功能模块

枚举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<KeServiceDescriptorTable->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;

}
NTSTATUS
IrpReadFile(
			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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
//************************************************************************************ //* //* A电脑防护 http://www.3600safe.com/ //* //*说明: //* 终于有点魄力开源了。谨以此薄码献给天下的母亲们 2012-5-13。 //* //*AD下: //* www.3600safe.com 是一个内核安全编程技术网站,收集了各种神牛的技术文章, //* 搞内核编程的不妨把它当成一个资料库 :) //* //************************************************************************************ 文件列表: I:. │ 3600safe.sln │ readme.txt │ ├─3600safe │ │ 3600safe.aps │ │ 3600safe.cpp │ │ 3600safe.h │ │ 3600safe.rc │ │ 3600safe.vcxproj │ │ 3600safe.vcxproj.filters │ │ 3600safe.vcxproj.user │ │ 3600safeDoc.cpp │ │ 3600safeDoc.h │ │ 3600safeView.cpp │ │ 3600safeView.h │ │ AboutDlg.cpp │ │ AboutDlg.h │ │ Atapi.cpp │ │ Atapi.h │ │ C3600Splash.cpp │ │ C3600Splash.h │ │ ClrListCtrl.cpp │ │ ClrListCtrl.h │ │ DLLModule.cpp │ │ DLLModule.h │ │ DpcTimer.cpp │ │ DpcTimer.h │ │ FilterDriver.cpp │ │ FilterDriver.h │ │ FsdHook.cpp │ │ FsdHook.h │ │ HipsLog.cpp │ │ HipsLog.h │ │ Install.cpp │ │ Install.h │ │ Kbdclass.cpp │ │ Kbdclass.h │ │ KernelHook.cpp │ │ KernelHook.h │ │ KernelModule.cpp │ │ KernelModule.h │ │ KernelThread.cpp │ │ KernelThread.h │ │ MainFrm.cpp │ │ MainFrm.h │ │ Md5.cpp │ │ Md5.h │ │ Mouclass.cpp │ │ Mouclass.h │ │ Nsiproxy.cpp │ │ Nsiproxy.h │ │ ntdll.lib │ │ ObjectHook.cpp │ │ ObjectHook.h │ │ Process.cpp │ │ Process.h │ │ ProcessHandle.cpp │ │ ProcessHandle.h │ │ ProcessThread.cpp │ │ ProcessThread.h │ │ ReadMe.txt │ │ resource.h │ │ Services.cpp │ │ Services.h │ │ ShadowSSDT.cpp │ │ ShadowSSDT.h │ │ SSDT.cpp │ │ SSDT.h │ │ stdafx.cpp │ │ stdafx.h │ │ SubModule.cpp │ │ SubModule.h │ │ SystemNotify.cpp │ │ SystemNotify.h │ │ SystemThread.cpp │ │ SystemThread.h │ │ targetver.h │ │ Tcpip.cpp │ │ Tcpip.h │ │ TcpView.cpp │ │ TcpView.h │ │ uninstall360.cpp │ │ uninstall360.h │ │ UnloadDllModule.h │ │ UserImages.bmp │ │ Windows2003SP1_CN.h │ │ Windows2003SP2_CN.h │ │ Windows7Home_CN.h │ │ Windows7SP1_CN.h │ │ WindowsXPSP2_CN.h │ │ WindowsXPSP3_CN.h │ │ │ ├─Release │ └─res │ 3600safe - 副本.ico │ 3600safe.bmp │ 3600safe.ico │ Dispatch.ico │ GDriver.ico │ Hips.ico │ KernelHook.ico │ KernelModule.ico │ KernelThread.ico │ My3600safe.rc2 │ Process.ico │ ring3.ico │ Services.ico │ Tcpview.ico │ Toolbar.bmp │ Toolbar256.bmp │ ├─bin │ │ A-Protect.exe │ │ A-Protect.txt │ │ │ └─A-ProtectSDK │ │ readme.txt │ │ │ ├─example │ │ A-ProtectConsole.cpp │ │ A-ProtectConsole.h │ │ A-ProtectConsole.sln │ │ A-ProtectConsole.vcxproj │ │ Install.cpp │ │ Install.h │ │ KernelModule.h │ │ ntdll.lib │ │ │ └─include │ A-ProtectSDK.h │ └─Driver │ AntiInlineHook.c │ AntiInlineHook.h │ Atapi.c │ Atapi.h │ buildchk_win7_x86.log │ buildchk_win7_x86.wrn │ Common.h │ Control.c │ Control.h │ DeleteFile.c │ DeleteFile.h │ DpcTimer.c │ DpcTimer.h │ DriverHips.c │ DriverHips.h │ drvcommon.h │ drvversion.h │ drvversion.rc │ dump.c │ dump.h │ file.c │ file.h │ FileSystem.c │ FileSystem.h │ Fixrelocation.c │ Fixrelocation.h │ Function.c │ Function.h │ InitWindowsVersion.c │ InitWindowsVersion.h │ InlineHook.c │ InlineHook.h │ kbdclass.c │ kbdclass.h │ KernelFilterDriver.c │ KernelFilterDriver.h │ KernelHookCheck.c │ KernelHookCheck.h │ KernelReload.c │ KernelReload.h │ KernelThread.c │ KernelThread.h │ KillProcess.c │ KillProcess.h │ ldasm.c │ ldasm.h │ libdasm.c │ libdasm.h │ makefile │ Mouclass.c │ Mouclass.h │ NetworkDefense.c │ NetworkDefense.h │ nsiproxy.c │ nsiproxy.h │ Ntfs.c │ Ntfs.h │ ntifs.h │ ntos.c │ ntos.h │ ObjectHookCheck.c │ ObjectHookCheck.h │ Port.c │ Port.h │ Process.c │ Process.h │ ProcessModule.c │ ProcessModule.h │ Protect.c │ Protect.h │ ReLoadSSDTTableHook.c │ ReLoadSSDTTableHook.h │ SafeSystem.c │ SafeSystem.h │ SafeSystem.sln │ SafeSystem.vcxproj │ SafeSystem.vcxproj.filters │ SafeSystem.vcxproj.user │ SDTShadowRestore.h │ Services.c │ Services.h │ ShadowSSDT.c │ ShadowSSDT.h │ sources │ SSDT.c │ SSDT.h │ SysModule.c │ SysModule.h │ SystemNotify.c │ SystemNotify.h │ SystemThread.c │ SystemThread.h │ tables.h │ Tcpip.c │ Tcpip.h │ win32k.c │ win32k.h │ ├─objchk_win7_x86 │ └─i386 │ a.bat │ bin2c.exe │ └─Release //******************************************************************** //end //********************************************************************
你可曾遇到以下问题:员工辞职了,把公司的客户资料也拷走了;设计图纸落到了竞争对手手中;市场推广计划被个别员工泄露了……你发现在这个信息安全变得越来越重要的时代,你却对企业局域网内的信息安全束手无策。最痛苦的是,作为行政部或IT部的管理者,老板将一切责任归到你的头上……. 绿信息安全管理软件,可以帮您彻底解决以上问题。 软件名称:绿信息安全管理软件 版本信息:V1.10 大小:11.75MB 支持语言:中文版本/英文版本 适用系统:Windows 2000/XP/2003 开发商:厦门天锐科技有限公司 官方下载:www.ldsafe.com 功能简介: 一、文件加密模块 通过绿信息安全管理软件,系统在不改变用户原有工作流程和文件使用习惯的前提下,对需要保护的文件进行强制加密保护,并对文件的使用进行全程监控,即文件只能在企业局域网内部查看,离开局域网则为密文,这样有效防止了被动和主动泄密,消除内部安全隐患于无形之中。 1、系统方案:在服务器上(其他客户机可以和它通信的电脑)安装绿服务端,然后在文件服务器和需要使用共享文件的电脑上安装绿终端。在绿服务端上创建若干终端帐户,绿终端使用这些帐户登入。只有安装了绿终端的电脑在登入帐户后才可以使用或查看加密的文件,离开局域网后需要使用或查看加密文件需要得到服务端的解密或者授权才可。安装绿终端用户的文件在创建、存储、应用、传输等环节中均以加密形式存在,可以杜绝黑客工具的窃取和监听。 2、文件外发方案:如有内部文件需要外发,可把这些文件发送到只解密不加密的绿终端(通过设置登入终端的帐户类型实现),通过这些终端电脑将这些文件另存,另存后的文件即以明文的形式存在并可根据实际需要发送给企业外部客户。 3、离线方案:如企业内部员工需要带笔记本电脑脱离局域网(出差或在家查看加密文档),可以使用绿的离线策略。离线策略需要向管理员申请,获得批准后导入即可。且离线策略可以灵活设定离线使用天数,这样在方便员工外部办公的同时也有效地保证了文档的安全。 二、内网安全管理模块 1、实时操作日志 :实时详细地记录所有终端的操作日志。包括终端上窗口标题的变换、程序的启动关闭、浏览的网址、收发的邮件标题、创建删除文件等; 2、屏幕快照、屏幕追踪、屏幕回放  3、应用程序使用记录、使用限制、使用统计: 详细记录各个应用程序的开启关闭的时间,运行时间,活动时间等信息; 提供应用程序白名单和黑名单功能,方便地限制员工可以运行哪些程序,不能运行哪些程序; 4、文件及目录操作记录:详细记录文件创建、重命名、删除的情况;详细记录文件夹(目录)创建、重命名、删除等情况。 5、打印机操作记录:记录员工的打印机使用情况,包括打印的文档名、页数、打印时间等。 6、硬件使用限制: 限制使用USB设备、USB存储设备、光驱、软驱的使用。支持移动磁盘、光盘刻录文件操作的监视; 7、软硬件清单、变化记:远程列出员工计算机的软件和硬件清单及配置变化的记录; 8、YAHOO通/贸易通/新浪UC/ICQ/AOL/E话通/SKYPE/MSN专业版/TM/QQ等聊天内容记录监视 9、报警功能 10、Arp防火墙功能: 可进行IP、MAC 绑定,防止ARP攻击 。 11、远程控制功能: 重启、关闭计算机;注销WINDOWS;发送信息 。 12、资产管理功能 由于软件大于10MB,无法全部上传,只能上传一部分,请大家见谅。如果要下载的话,请到官方网站www.ldsafe.com下载。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值