绕过Head Inline Hook

大理寺少卿 · · 编程&逆向技术交流
3

本文共计2254个字,预计阅读时长9分钟。

``` #include <NTDDK.H> #include "passinline.h" #include "irql.h" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp); VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject ); typedef struct _KAPC_STATE { LIST_ENTRY ApcListHead[2]; PVOID Process; BOOLEAN KernelApcInProgress; BOOLEAN KernelApcPending; BOOLEAN UserApcPending; }KAPC_STATE, *PKAPC_STATE; typedef enum _KAPC_ENVIRONMENT { OriginalApcEnvironment, AttachedApcEnvironment, CurrentApcEnvironment, InsertApcEnvironment }KAPC_ENVIRONMENT; NTKERNELAPI VOID KeInitializeApc ( IN PRKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT Environment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL, IN KPROCESSOR_MODE ApcMode, IN PVOID NormalContext ); NTKERNELAPI VOID KeTerminateThread( KPRIORITY Increment); typedef BOOLEAN (__stdcall *KEINSERTQUEUEAPC) ( PKAPC Apc, PVOID SystemArgument1, PVOID SystemArgument2, KPRIORITY Increment ); KEINSERTQUEUEAPC MsInsertQueueApc; typedef VOID (__fastcall *KIINSERTQUEUEAPC) ( PKAPC Apc, KPRIORITY Increment ); KIINSERTQUEUEAPC KiInsertQueueApc; ULONG KillProc; ULONG KiAddr; BYTE KiInsertQueueApc_orig_code[20] = { 0x00 }; //常量声明:XP下KTHREAD结构的一些偏移 const ULONG ThreadListEntryOffset=0x22c; const ULONG ThreadListHeadOffset=0x190; //作用:得到导出函数地址 ULONG GetFunctionAddr(IN PCWSTR FunctionName) { UNICODE_STRING UniCodeFunctionName; RtlInitUnicodeString( &UniCodeFunctionName, FunctionName ); return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName ); } //得到KiInsertQueueApc的地址 ULONG GetKiInsertQueueApc() { UCHAR *cPtr, *pOpcode; ULONG Length, CallCount=1, ETAddr=0; ULONG AddressOf_KeInsertQueueApc,AddressOf_KiInsertQueueApc=0; //Get KeInsertQueueApc Address AddressOf_KeInsertQueueApc=GetFunctionAddr(L"KeInsertQueueApc"); //Get KiInsertQueueApc Address for (cPtr = (PUCHAR)AddressOf_KeInsertQueueApc; cPtr <(PUCHAR)AddressOf_KeInsertQueueApc + PAGE_SIZE; cPtr += Length) { Length = SizeOfCode(cPtr, &pOpcode); if (!Length) return ETAddr; if (*pOpcode == 0xE8) { CallCount++; if (CallCount==3) //XP: The Third e8 is KiInsertQueueApc { AddressOf_KiInsertQueueApc=(*(PULONG)(pOpcode+1)+(ULONG)cPtr + 5); DbgPrint("KiInsertQueueApc Address = %X",AddressOf_KiInsertQueueApc); break; } } } ETAddr=AddressOf_KiInsertQueueApc; return ETAddr; } VOID XPRestoreKiInsertQueueApc() { PUCHAR addr; ULONG uladdr; KIRQL oldIrql; uladdr = GetKiInsertQueueApc(); if (uladdr!=0) { addr = (PUCHAR)uladdr; //获得KiInsertQueueApc的前12字节 GetOldCode(uladdr,12,KiInsertQueueApc_orig_code); //判断得到了字节没有 if( KiInsertQueueApc_orig_code[0]==0x8B && KiInsertQueueApc_orig_code[1]==0xFF ) { //禁止系统写保护,提升IRQL到DPC,然后恢复KiInsertQueueApc的Inline Hook WPOFF(); oldIrql = KeRaiseIrqlToDpcLevel(); //恢复KeInsertQueueApc的前12字节 RtlCopyMemory ( (BYTE*)addr, KiInsertQueueApc_orig_code, 12 ); KeLowerIrql(oldIrql); WPON(); DbgPrint("XP RestoreKiInsertQueueApc Success!\n"); } else { DbgPrint("XP RestoreKiInsertQueueApc Failed: Can not get KiInsertQueueApc bytes\n"); } } else { DbgPrint("XP RestoreKiInsertQueueApc Failed: Can not get KiInsertQueueApc Address\n"); } } //作用:内核APC例程 VOID ApcCallBack(PKAPC Apc,PKNORMAL_ROUTINE *NormalRoutine,PVOID *NormalContext,PVOID *SystemArgument1,PVOID *SystemArgument2) { NTSTATUS st; ExFreePool(Apc); st=PsTerminateSystemThread(STATUS_SUCCESS); if(!NT_SUCCESS(st)) KeTerminateThread(0); } //作用:结束线程 NTSTATUS TerminateThread(IN PETHREAD Thread) { NTSTATUS st = STATUS_UNSUCCESSFUL; ULONG Size = 0; ULONG i = 0; PKAPC pApc = 0; ULONG EToffSET=0x248; if ( MmIsAddressValid((PVOID)Thread) == TRUE) { pApc = ExAllocatePool(NonPagedPool, sizeof(KAPC)); //Fix Thread Type To SYSTEM THREAD *(PULONG)((ULONG)Thread+EToffSET)=0x10; //XP=0x248, 2K3=0x240, VISTA+2k8=0x260, Win7=0x280 //If APC is OK if (pApc) { KeInitializeApc(pApc, (PKTHREAD)Thread, OriginalApcEnvironment, ApcCallBack, 0, 0, KernelMode, 0); //MsInsertQueueApc(pApc, NULL, NULL, 0); //Test Use KiInsertQueueApc pApc->SystemArgument1=NULL; pApc->SystemArgument2=NULL; pApc->Inserted = FALSE; //KiInsertQueueApc=(KIINSERTQUEUEAPC)GetKiInsertQueueApc(); //KiInsertQueueApc(pApc,0); KiInsertQueueApc(pApc,0); DbgPrint("KiInsertQueueApc Over!"); } st = STATUS_SUCCESS; } return st; } PETHREAD GetNextProcessThread(IN PEPROCESS Process,IN PETHREAD Thread OPTIONAL) { PETHREAD FoundThread = NULL; PLIST_ENTRY ListHead, Entry; PAGED_CODE(); if (Thread) { Entry = (PLIST_ENTRY)((ULONG)(Thread) + ThreadListEntryOffset);//+0x22c ThreadListEntry : _LIST_ENTRY Entry=Entry->Flink; } else { Entry = (PLIST_ENTRY)((ULONG)(Process) + ThreadListHeadOffset);//+0x190 ThreadListHead : _LIST_ENTRY Entry = Entry->Flink; } ListHead = (PLIST_ENTRY)((ULONG)Process + ThreadListHeadOffset); while (ListHead != Entry) { FoundThread = (PETHREAD)((ULONG)Entry - ThreadListEntryOffset); if (ObReferenceObject(FoundThread)) break; FoundThread = NULL; Entry = Entry->Flink; } if (Thread) ObDereferenceObject(Thread); return FoundThread; } NTSTATUS TerminateProcess(PEPROCESS Process) { NTSTATUS Status; PETHREAD Thread; Status = STATUS_SUCCESS; KiAddr=GetKiInsertQueueApc(); if(KiAddr!=0) { KiInsertQueueApc=ExAllocatePool( NonPagedPool, 20 );//分配20字节 memset(KiInsertQueueApc,0x90,20);//NOP GetOldCode(KiAddr,12,(PBYTE)KiInsertQueueApc); } else { DbgPrint("Can not get KiInsertQueueApc!"); return STATUS_UNSUCCESSFUL; } __try { for (Thread=GetNextProcessThread(Process,NULL); Thread!=NULL; Thread=GetNextProcessThread(Process,Thread)) { TerminateThread(Thread); DbgPrint("Thread Terminated: %x",(ULONG)Thread); } } __except(EXCEPTION_EXECUTE_HANDLER) { Status = GetExceptionCode(); } return Status; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) { UNICODE_STRING uniDeviceName; UNICODE_STRING uniSymLink; NTSTATUS ntStatus; PDEVICE_OBJECT deviceObject = NULL; RtlInitUnicodeString(&uniDeviceName, NT_DEVICE_NAME); RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME); DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; DriverObject->DriverUnload = UnloadDriver; ntStatus = IoCreateDevice(DriverObject, 0,&uniDeviceName,FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE,&deviceObject); if (!NT_SUCCESS(ntStatus)) return ntStatus; ntStatus = IoCreateSymbolicLink(&uniSymLink, &uniDeviceName); if (!NT_SUCCESS(ntStatus)) { IoDeleteDevice(deviceObject); return ntStatus; } DbgPrint("driver loaded!\n"); return STATUS_SUCCESS; } NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { pIrp->IoStatus.Information = 0; pIrp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;//STATUS_UNSUCCESSFUL;// PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; ULONG inBufLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; ULONG outBufLength =pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; PVOID OutputBuffer = pIrp->UserBuffer; PVOID InputBuffer = pIrp->AssociatedIrp.SystemBuffer; ULONG Ki; switch(uIoControlCode) { case IOCTL_BypassInline: { /*MsInsertQueueApc=ExAllocatePool( NonPagedPool, 20 );//分配20字节 memset(MsInsertQueueApc,0x90,20);//NOP GetOldCode(GetFunctionAddr(L"KeInsertQueueApc"),10,(PBYTE)MsInsertQueueApc);*/ /*GetOldCode(GetKiInsertQueueApc(),12,KiInsertQueueApc_orig_code); for(Ki=0;Ki<12;Ki++) DbgPrint("KiInsertQueueApc[%d]=%x",Ki,KiInsertQueueApc_orig_code[Ki]);*/ break; } case IOCTL_KillProcByEP: { memcpy(&KillProc,InputBuffer,sizeof(ULONG)); //XPRestoreKiInsertQueueApc(); TerminateProcess((PEPROCESS)KillProc); break; } } pIrp->IoStatus.Status = ntStatus; //pIrp->IoStatus.Information = outBufLength; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return ntStatus; } VOID UnloadDriver( IN PDRIVER_OBJECT DriverObject ) { PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; UNICODE_STRING uniSymLink; RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME); if (MsInsertQueueApc) ExFreePool(MsInsertQueueApc); DbgPrint("driver unloaded.\n"); IoDeleteSymbolicLink(&uniSymLink); IoDeleteDevice(deviceObject); } ```
本帖中包含附件 XIUNO提示您如需下载请先回复并刷新本帖!

最新回复 ( 3 )
全部楼主