能力值:
( LV12,RANK:210 )
76 楼
NormalRoutine为0是一种特殊的情况,在这种情况下KernelRoutine所指的内核函数无条件地得到调用。但是,如果NormalRoutine非0,那么首先得到调用的是KernelRoutine,而指针NormalRoutine的地址是作为参数传下去的。KernelRoutine的执行有可能改变这个指针的值。这样,如果执行KernelRoutine以后NormalRoutine仍为非0,那就说明需要加以执行,所以通过这个函数指针予以调用。
能力值:
( LV12,RANK:210 )
77 楼
不是很理解啊
能力值:
( LV12,RANK:210 )
78 楼
要自己写个NormalRoutine吗?
能力值:
( LV12,RANK:210 )
79 楼
有去看了下WRK还是没理解
能力值:
( LV12,RANK:210 )
80 楼
不知道为何会重入呢?代码要如何修改下呢
能力值:
( LV3,RANK:20 )
81 楼
VOID
KeInitializeApc (
__out PRKAPC Apc,
__in PRKTHREAD Thread,
__in KAPC_ENVIRONMENT Environment,
__in PKKERNEL_ROUTINE KernelRoutine,
__in_opt PKRUNDOWN_ROUTINE RundownRoutine,
__in_opt PKNORMAL_ROUTINE NormalRoutine, //应该是这个
__in_opt KPROCESSOR_MODE ApcMode,
__in_opt PVOID NormalContext
)
KeInitializeApc 初始化NormalRoutine 看看..
再不行,就只能呼叫强大的MJ了..
能力值:
( LV3,RANK:20 )
82 楼
/*++
Routine Description:
This function initializes a kernel APC object. The thread, kernel
routine, and optionally a normal routine, processor mode, and normal
context parameter are stored in the APC object.
Arguments:
Apc - Supplies a pointer to a control object of type APC.
Thread - Supplies a pointer to a dispatcher object of type thread.
Environment - Supplies the environment in which the APC will execute.
Valid values for this parameter are: OriginalApcEnvironment,
AttachedApcEnvironment, CurrentApcEnvironment, or InsertApcEnvironment
KernelRoutine - Supplies a pointer to a function that is to be
executed at IRQL APC_LEVEL in kernel mode.
RundownRoutine - Supplies an optional pointer to a function that is to be
called if the APC is in a thread's APC queue when the thread terminates.
NormalRoutine - Supplies an optional pointer to a function that is
to be executed at IRQL 0 in the specified processor mode. If this
parameter is not specified, then the ProcessorMode and NormalContext
parameters are ignored.
ApcMode - Supplies the processor mode in which the function specified
by the NormalRoutine parameter is to be executed.
NormalContext - Supplies a pointer to an arbitrary data structure which is
to be passed to the function specified by the NormalRoutine parameter.
Return Value:
None.
能力值:
( LV12,RANK:210 )
83 楼
NormalRoutine为0是一种特殊的情况,在这种情况下KernelRoutine所指的内核函数无条件地得到调用。
能力值:
( LV12,RANK:210 )
84 楼
KeInitializeApc(ExitApc,
ethread, //线程
OriginalApcEnvironment,
KernelKillThreadRoutine,
NULL,
NULL,
KernelMode,
NULL);//为线程初始化APC
status=KeInsertQueueApc(ExitApc,NULL,NULL,0); //插入Apc到线程队列
能力值:
( LV12,RANK:210 )
85 楼
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;
ThreadFlags=(ULONG *)((ULONG)PsGetCurrentThread()+0x248); //ETHREAD中CrossThreadFlags的偏移量为0x248
if(MmIsAddressValid(ThreadFlags)) //地址进行下验证
{
*ThreadFlags=(*ThreadFlags) | PS_CROSS_THREAD_FLAGS_SYSTEM; //修改为系统权限
PsTerminateSystemThread(STATUS_SUCCESS); //结束线程
}
}
能力值:
( LV12,RANK:210 )
86 楼
内核特殊APC NormalRoutine为空 调用KernelRoutine 怎么会出现重入呢?
在虚拟机杀冰刃才蓝屏
本机次次蓝屏
能力值:
( LV12,RANK:210 )
87 楼
等待MJ给出合理解释啊
能力值:
( LV2,RANK:10 )
88 楼
我也正在学习,来看看有啥可以值得看的
能力值:
( LV12,RANK:760 )
89 楼
KeInsertQueueApc(ExitApc,NULL,NULL,0);
改成
KeInsertQueueApc( ExitApc, ExitApc, NULL, 2 );
试试~~
我是来看MJ的~
能力值:
( LV12,RANK:210 )
90 楼
WRK是这么写的
KeInsertQueueApc( ExitApc, ExitApc, NULL, 2 );
能力值:
( LV12,RANK:210 )
91 楼
我们都是来看MJ的
能力值:
( LV12,RANK:210 )
92 楼
不知道道什么原因啊 我觉得跟NormalRoutine无关
能力值:
( LV2,RANK:10 )
93 楼
这个不蓝,太多了,我没仔细看你们的讨论。你自己对照找找问题。2000到vista都可以.
83aK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2A6i4K6u0W2j5X3q4A6k6s2g2Q4x3X3g2U0L8$3#2Q4x3V1k6S2L8r3g2^5i4K6g2X3M7$3g2U0i4K6u0r3j5X3I4G2k6#2)9J5c8X3W2@1k6h3#2Q4x3V1k6S2j5h3y4U0j5X3p5#2z5r3x3%4z5h3g2X3y4U0t1K6x3U0V1K6y4r3j5H3j5K6q4Q4x3X3g2Z5N6r3#2D9
能力值:
( LV12,RANK:210 )
94 楼
我代码跟他没什么差别 在我机器不行 蓝
能力值:
( LV12,RANK:210 )
95 楼
代码按照我的理解写的 存在一些问题 但是我不知道那里出问题了
能力值:
( LV12,RANK:210 )
96 楼
#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);
ThreadFlags=(ULONG *)((ULONG)PsGetCurrentThread()+0x248); //ETHREAD中CrossThreadFlags的偏移量为0x248
if(MmIsAddressValid(ThreadFlags)) //地址进行下验证
{
*ThreadFlags=(*ThreadFlags) | PS_CROSS_THREAD_FLAGS_SYSTEM; //修改为系统权限
PsTerminateSystemThread(STATUS_SUCCESS); //结束线程
}
else
{
}
return;
}
VOID KillProcessWithApc(ULONG epro)
{
//遍历线程有2种做法:1、PsGetNextProcessThread(未导出函数,自己定位地址) 2、从EPROCESS的list链中ActiveThreads记录线程数量
//3、遍历pspcidtable
//为了防止KeInsertQueueApc被HOOK 我利用R3下函数GetProcessAddress获取地址,然后传入R0
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)
KdPrint(("KeInsertQueueApc success\n"));
else
KdPrint(("KeInsertQueueApc failed\n"));
}
}
能力值:
( LV2,RANK:10 )
97 楼
看看炉子写的那个,然后对照你的看看
能力值:
( LV6,RANK:90 )
98 楼
楼主可以试一下在
PsTerminateSystemThread(STATUS_SUCCESS); //结束线程
下一个断点,观察一下当前线程的APC队列。
看了一下PspExitThread。
kd> ub nt!PspExitThread+0x279
nt!PspExitThread+0x25e:
805c80b2 ff86d4000000 inc dword ptr [esi+0D4h]
805c80b8 7513 jne nt!PspExitThread+0x279 (805c80cd)
805c80ba 8d4634 lea eax,[esi+34h]
805c80bd 3900 cmp dword ptr [eax],eax //是否还有APC
805c80bf 740c je nt!PspExitThread+0x279 (805c80cd)
805c80c1 c6464901 mov byte ptr [esi+49h],1
805c80c5 b101 mov cl,1
805c80c7 ff1500874d80 call dword ptr [nt!_imp_HalRequestSoftwareInterrupt (804d8700)] 估计这里还有很多个相同的APC(全部都是调用KernelKillThreadRoutine),造成重入。
会不会是调用KillProcessWithApc出了问题啊~
能力值:
( LV12,RANK:300 )
99 楼
我试了93楼给出的代码(改成汇编了
)虚拟机里结束IceSword没蓝。
楼主的代码与93楼给出的代码的差别在于对各线程ETHREAD的获取方式,楼主采用EPROCESS中的ActiveThreads作为计数。不知道会不会是这里出的问题造成楼上所说的向同一个线程重复插入了APC。
倒,用ActiveThreads的作法我在虚拟机也试了,结束IceSword进程照样没蓝,IceSword是1.22中文版……
能力值:
( LV12,RANK:210 )
100 楼
诡异的问题啊 我换台电脑用95楼代码虚拟机测试结束冰刃竟然不蓝屏了