|
本帖最后由 xiaoly99 于 2014-7-10 20:41 编辑
VB小子玩转驱动程序(6):结束线程
作者:0.0
①.准备工具
WinDbg和未导出函数符号包
未下载请打开:http://www.m5home.com/bbs/thread-3442-1-1.html
1.前提
本例使用了未导出函数PspExitThread,未导出函数KiInsertQueueApc经测试容易蓝屏,所以使用导出函数KeInsertQueueApc.
系统调用列表:NtTerminateProcess -> XXX -> PspTermianteThreadByPointer ->KeInsertQueueApc ->KiINsertQueueApc -> InsertHeadList -> PspExitThread
2.获得PspExitThread地址
PspExitThread貌似不被任何一个已导出函数调用,本例中通过查找未导出函数PspTerminateThreadByPointerAddr中,而PspTerminateThreadByPointerAddr被导出函数PsTerminateSystemThread调用.
lkd> u PsTerminateSystemThread l 10
nt!PsTerminateSystemThread:
805c9f74 8bff mov edi,edi
805c9f76 55 push ebp
805c9f77 8bec mov ebp,esp
805c9f79 64a124010000 mov eax,dword ptr fs:[00000124h]
805c9f7f f6804802000010 test byte ptr [eax+248h],10h
805c9f86 7507 jne nt!PsTerminateSystemThread+0x1b (805c9f8f)
805c9f88 b80d0000c0 mov eax,0C000000Dh
805c9f8d eb09 jmp nt!PsTerminateSystemThread+0x24 (805c9f98)
805c9f8f ff7508 push dword ptr [ebp+8]
805c9f92 50 push eax
805c9f93 e828fcffff call nt!PspTerminateThreadByPointer (805c9bc0)
注意:为什么用红色标注了两句呢?因为特征码是两句,特征码是50e8########,按照ULONG的读法就是e850########
驱动代码:
PVOID GetFunctionAddr(IN PCWSTR FunctionName){UNICODE_STRING UniCodeFunctionName;RtlInitUnicodeString(&UniCodeFunctionName,FunctionName);return MmGetSystemRoutineAddress(&UniCodeFunctionName);}
PUCHAR GetPspTerminateThreadByPointerAddr();
{
int i = 0;
PUCHAR psExitSystemThreadAddr = (PUCHAR)GetFunctionAddr(L"PsTerminateSystemThread");//获得函数地址
for ( i=0; i<= 0x50; i++)
{
psExitSystemThreadAddr ++;
if ( *(PWCHAR)psExitSystemThreadAddr == 0xe850 )//校验特征码
{
psExitSystemThreadAddr++;
return (PUCHAR)((ULONG)psExitSystemThreadAddr + 5 + *(PULONG)(psExitSystemThreadAddr + 1));//返回地址
break;
}
}
return;
}
lkd> u PspTerminateThreadByPointer l 20
nt!PspTerminateThreadByPointer:
805c9bc0 8bff mov edi,edi
805c9bc2 55 push ebp
805c9bc3 8bec mov ebp,esp
805c9bc5 83ec0c sub esp,0Ch
..............................................
805c9c0a ff750c push dword ptr [ebp+0Ch]
805c9c0d e87af7ffff call nt!PspExitThread (805c938c)
按照ULONG读出特征码就是0xe80C75FF
驱动代码:
PVOID GetPspExitThread()
PUCHAR PspTerminateThreadByPointerAddr = NULL;
int i = 0;
PspTerminateThreadByPointerAddr = GetPspTerminateThreadByPointerAddr();
for ( i = 0; i<= 0x50; i++)
{
PspTerminateThreadByPointerAddr ++;
if ( *(PULONG)PspTerminateThreadByPointerAddr == 0xe80C75FF)
{
PspTerminateThreadByPointerAddr++;
PspTerminateThreadByPointerAddr++;
PspTerminateThreadByPointerAddr++;
return (PSPEXITTHREAD)( (ULONG)PspTerminateThreadByPointerAddr + 5 + *(PULONG)(PspTerminateThreadByPointerAddr +1) );
break;
}
}
return;
}
3.调用(结束线程)
先声明:
NTKERNELAPI VOID KeInitializeApc (PRKAPC Apc,PKTHREAD Thread,KAPC_ENVIRONMENT Environment,PKKERNEL_ROUTINE KernelRoutine,PKRUNDOWN_ROUTINE RundownRoutine,PKNORMAL_ROUTINE NormalRoutine,KPROCESSOR_MODE ApcMode,PVOID NormalContext);
NTKERNELAPI BOOLEAN KeInsertQueueApc(IN PKAPC Apc,IN PVOID SystemArgument1,IN PVOID SystemArgument2,IN KPRIORITY PriorityBoost);
typedef VOID (*PSPEXITTHREAD)(IN NTSTATUS ExitStatus);
PSPEXITTHREAD PspExitThread = NULL;
代码和注释:
VOID KernelTerminateThreadRoutine(IN PKAPC Apc,IN OUT PKNORMAL_ROUTINE *NormalRoutine,IN OUT PVOID *NormalContext,IN OUT PVOID *SystemArgument1,IN OUT PVOID *SystemArgument2)
{
PspExitThread(0);//结束自身线程 因为已经通过Apc进行Attach到内部Exit的YY操作
}
VOID TerminateThread(PETHREAD Thread)
{
PKAPC Apc=NULL;
Apc=ExAllocatePool(NonPagedPool,sizeof(KAPC));//分配Apc内存
GetPspExitThreadAddr();//获得地址
KeInitializeApc(Apc,(PKTHREAD)Thread,OriginalApcEnvironment,KernelTerminateThreadRoutine,NULL,NULL,KernelMode,NULL); //初始化Apc
KeInsertQueueApc(Apc,0,0,0);//插Apc
ExFreePool(Apc);
} |
评分
-
查看全部评分
|