x64 win7 KeInsertQueueApc结束进程 插apc结束进程已不是什么新鲜事,x86 xp 下插apc网上也有很多demo,但是64位win7下在网上却找不到,我们来实现一下。 先看一下32位平台和64平台下插apc不同的地方,插apc需要获取eprocess中的几个偏移地址,关键在于偏移地址的改变: 第一个是线程数量的偏移地址,x64 win7下ActiveThreads偏移是0x328, x86 xp下是 0x1a0,所以线程数量的获取如下: num=(ULONG)*(ULONGLONG *)(epro+0x328); 第二个是ThreadListHead 的偏移量: Head=epro+0x308; //x64 win7下List_entry偏移是0x308,x86 xp下是 0x190 第三个是线程地址的偏移量: address=Head-0x428; //win7 x64下是0x428,x86 xp下是 0x22c 代码如下: VOID KillThreadRoutine(IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2) { ExFreePool(Apc); //释放APC PspExitThread(STATUS_SUCCESS);//根据PspTerminateThreadByPointer定位PspExitThread地址 } VOID KillProcessWithApc(ULONGLONG epro) { BOOLEAN status; PKAPC ExitApc=NULL; PEPROCESS eprocess; PETHREAD ethread; ULONGLONG i; ULONG num; //线程数量 ULONGLONG Head; //链表头 ULONGLONG address;//地址 num=(ULONG)*(ULONGLONG *)(epro+0x328); //x64 win7下ActiveThreads偏移是0x328, x86 xp下是 0x1a0 DbgPrint("[RecordThreadAddress] num: 0x%llx\n",num); //打印线程数量 Head=epro+0x308; //x64 win7下List_entry偏移是0x308,x86 xp下是 0x190 for(i=0;i<num;i++) { //记录线程地址 Head=(ULONGLONG)((PLIST_ENTRY)Head)->Flink; address=Head-0x428; //win7 x64下是0x428,x86 xp下是 0x22c DbgPrint("[ThreadAddress] address: 0x%llx\n",address); //打印线程地址 ethread=(PETHREAD)address; //转换成线程指针 ExitApc=(PKAPC)ExAllocatePoolWithTag(NonPagedPool,sizeof(KAPC),MEM_TAG); if(ExitApc==NULL) { DbgPrint("[KillProcessWithApc] malloc memory failed \n"); return; } KeInitializeApc(ExitApc, ethread, OriginalApcEnvironment, KillThreadRoutine, NULL, NULL, KernelMode, NULL);//为线程初始化APC status=KeInsertQueueApc(ExitApc,ExitApc,NULL,2); //插入Apc到线程队列 } } PspExitThread 自己需要定位实现
|