本文共 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;iTableSize;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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!