代码:
//===========================================插APC杀进程================================================= //进程结束内幕: // // // //原理:遍历进程所有线程---初始化APC---插入APC //结束线程的内核Apc例程 #define PS_CROSS_THREAD_FLAGS_SYSTEM 0x00000010UL typedef enum _KAPC_ENVIRONMENT { OriginalApcEnvironment, AttachedApcEnvironment, CurrentApcEnvironment, InsertApcEnvironment } KAPC_ENVIRONMENT; VOID KeInitializeApc ( PKAPC Apc, PETHREAD Thread, KAPC_ENVIRONMENT Environment, PKKERNEL_ROUTINE KernelRoutine, PKRUNDOWN_ROUTINE RundownRoutine, PKNORMAL_ROUTINE NormalRoutine, KPROCESSOR_MODE ProcessorMode, PVOID NormalContext ); BOOLEAN KeInsertQueueApc(PKAPC Apc,PVOID SystemArg1,PVOID SystemArg2,KPRIORITY Increment); VOID KernelKillThreadRoutine(IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2) { //调用PsTerminateSystemThread结束线程 //修改当前线程的ThreadFlags为系统线程 PULONG ThreadFlags; ExFreePool(Apc); //释放APC ThreadFlags=(ULONG *)((ULONG)PsGetCurrentThread()+0x248); //ETHREAD中CrossThreadFlags的偏移量为0x248 if(MmIsAddressValid(ThreadFlags)) //地址进行下验证 { *ThreadFlags=(*ThreadFlags) | PS_CROSS_THREAD_FLAGS_SYSTEM; //修改为系统权限 PsTerminateSystemThread(STATUS_SUCCESS); //结束系统线程,需要修改权限 //PspExitThread(STATUS_SUCCESS);根据PspTerminateThreadByPointer定位PspExitThread地址 } } VOID KillProcessWithApc(ULONG epro) { //遍历线程有2种做法:1、PsGetNextProcessThread(未导出函数,自己定位地址) 2、从EPROCESS的list链中ActiveThreads记录线程数量 //3、遍历pspcidtable BOOLEAN status; PKAPC ExitApc=NULL; PEPROCESS eprocess; PETHREAD ethread; ULONG i; ULONG num; //线程数量 ULONG Head; //链表头 ULONG address;//地址 num=*(ULONG *)(epro+0x1a0); //EPROCESS中ActiveThreads的数量 0x1a0是EPROCESS中ActiveThread的偏移量 KdPrint(("[RecordThreadAddress] num: 0x%x\n",num)); //打印线程数量 Head=epro+0x190; //List_entry第一个节点地址 for(i=0;i<num;i++) { //记录线程地址 Head=(ULONG)((PLIST_ENTRY)Head)->Flink; address=Head-0x22c; KdPrint(("[RecordThreadAddress] address: 0x%x\n",address)); //打印线程地址 ethread=(PETHREAD)address; //转换成线程指针 ExitApc=(PKAPC)ExAllocatePoolWithTag(NonPagedPool,sizeof(KAPC),MEM_TAG); if(ExitApc==NULL) { KdPrint(("[KillProcessWithApc] malloc memory failed \n")); return; } KeInitializeApc(ExitApc, ethread, //线程 OriginalApcEnvironment, KernelKillThreadRoutine, NULL, NULL, KernelMode, NULL);//为线程初始化APC status=KeInsertQueueApc(ExitApc,ExitApc,NULL,2); //插入Apc到线程队列 if(status==STATUS_SUCCESS) KdPrint(("KeInsertQueueApc success\n")); else KdPrint(("KeInsertQueueApc failed\n")); } }