更改KiSwapContext中SwapContext的地址。实现自己接管线程切换,大量硬编码~~完全是为了学习。可以做到检测隐藏进程。
如果再往上实现到KiSwapThread也是可以的,不过很多东西内核没导出不好弄,在优化优化,是否可以再某种程度上提升操作系统速度呢?呵呵
,不过。兼容性和稳定性肯定很差。
贴出完整代码。直接WDK编译。我系统XPSP3,CPU酷睿T双核。无SMT~无NUMA处理。(PS:我啥时候能有i7…)
#include ULONG HalpIRQLtoTPR = 0; ULONG OrigSwapContext; VOID Unload(PDRIVER_OBJECT DriverObject) { ULONG KThread; NTSTATUS status; status = PsLookupThreadByThreadId((PVOID)8, &(PETHREAD)KThread); if(!NT_SUCCESS(status)) { return; } __asm cli *(ULONG*)(*(ULONG*)(*(ULONG*)(KThread+0x28)+8)-4) = OrigSwapContext- *(ULONG*)(*(ULONG*)(KThread+0x28)+8); __asm sti DbgPrint("Unload/n"); } //寄存器状态 //edi oldKthread //esi newKthread //ebx KPCR __declspec (naked) void MySwapContext() { __asm { or cl,cl mov byte ptr [esi+2dh],2 //state = running pushfd mov ecx,dword ptr [ebx] //kpcr->exceptionlist cmp dword ptr [ebx+0994h],0 ////KPRCB->DpcRoutineActive push ecx jne BugCheck mov ebp,cr0 mov edx,ebp mov cl,byte ptr [esi+02Ch] //KTHREAD->DebugActive mov byte ptr [ebx+050h],cl //KPCR->DebugActive cli mov dword ptr [edi+028h],esp //kernalstack mov eax,dword ptr [esi+018h] // Kthread->InitialStack mov ecx,dword ptr [esi+01Ch] //Kthread->StackLimit sub eax,0210h //sizeof(FX_SAVE_AREA) mov dword ptr [ebx+08h],ecx //KPCR->NT_TIB->StackLimit mov dword ptr [ebx+04h],eax //KPCR->NT_TIB->pStackBase xor ecx,ecx mov cl,byte ptr [esi+031h] //KThread->NpxState and edx,0FFFFFFF1h or ecx,edx or ecx,dword ptr [eax+20Ch] //FX_SAVE_AREA->Cr0NpxState cmp ebp,ecx je NOT_FLUSH_CR0 mov cr0,ecx NOT_FLUSH_CR0: test dword ptr [eax-01Ch],020000h //KTRAP_FRAME->EFlags第17位(VM) jne NOT_V86 sub eax,010h NOT_V86: mov ecx,dword ptr [ebx+040h] //KPCR->TSS mov dword ptr [ecx+4],eax //TSS->Esp0 mov esp,dword ptr [esi+028h] //KTHREAD->KernelStack mov eax,dword ptr [esi+020h] //KTHREAD->TEB->NT_TIB mov dword ptr [ebx+018h],eax //KPCR->NT_TIB->Self sti mov eax,dword ptr [edi+044h] //自己添加的输出进程名 pushad add eax,174h push eax call DbgPrint add esp,4 popad cmp eax,dword ptr [esi+044h] mov byte ptr [edi+050h],0 je SAME_PROCESS mov edi,dword ptr [esi+044h] test word ptr [edi+020h],0FFFFh //NewKThread->KProcess->LdtDescriptor->LimitLow jne LDT_ENABLE //为了兼容16位ldt。其实无用。 xor eax,eax GO_ON: lldt ax xor eax,eax mov gs,ax mov eax,dword ptr [edi+18h] //NewKprocess->DirectoryTableBase mov ebp,dword ptr [ebx+40h] //KPCR->TSS mov ecx,dword ptr [edi+30h] //KProcess->IopmOffset mov dword ptr [ebp+1Ch],eax //TSS->CR3 mov cr3,eax mov word ptr [ebp+66h],cx //TSS->IoMapBase SAME_PROCESS: mov eax,dword ptr [ebx+18h] //KPCR->TEB mov ecx,dword ptr [ebx+3Ch] //KPCR->GDT mov word ptr [ecx+3Ah],ax //存入GDT的TEB项。 shr eax,10h mov byte ptr [ecx+3Ch],al mov byte ptr [ecx+3Fh],ah inc dword ptr [esi+4Ch] //NewKthread->ContextSwitches inc dword ptr [ebx+61Ch] //KPRCB->KeContextSwitches pop ecx mov dword ptr [ebx],ecx cmp byte ptr [esi+49h],0 //KTHREAD->KernelApcPending。 jne APC popfd xor eax,eax ret //切换结束 LDT_ENABLE: mov ebp,dword ptr [ebx+03Ch] //KPCR->GDT mov eax,dword ptr [edi+020h] //NewKProcess->LdtDescriptor mov dword ptr [ebp+048h],eax //把LdtDescriptor赋予GDT的LDT项 mov eax,dword ptr [edi+024h] //继续赋值 mov dword ptr [ebp+04Ch],eax mov eax,048h mov ebp,dword ptr [ebx+038h] //KPCR->IDT mov ecx,dword ptr [edi+028h] //NewKProcess->Int21Descriptor,int21为16位程序的系统调用中断 mov dword ptr [ebp+0108h],ecx //装载到idt相应的位置,使之可以使用21中断 mov ecx,dword ptr [edi+02Ch] mov dword ptr [ebp+010Ch],ecx jmp GO_ON APC: popfd jne APC1 mov al,1 ret APC1: mov cl,1 //APC_LEVEL call HalRequestSoftwareInterrupt xor eax,eax ret BugCheck: HalRequestSoftwareInterrupt: cmp cl,byte ptr ds:[0FFDFF095h] je RETURN xor eax,eax mov al,cl xor ecx,ecx mov cl,byte ptr [HalpIRQLtoTPR] or ecx,40000h pushfd cli A: test dword ptr ds:[0FFFE0300h],1000h jne A mov dword ptr ds:[0FFFE0300h],ecx B: test dword ptr ds:[0FFFE0300h],1000h jne B popfd ret RETURN: mov byte ptr ds:[0FFDFF096h],1 ret } } NTSTATUS HookSwapContext() { ULONG KThread; NTSTATUS status; status = PsLookupThreadByThreadId((PVOID)8, &(PETHREAD)KThread); if(!NT_SUCCESS(status)) { return STATUS_UNSUCCESSFUL; } KdPrint(("%x/n",*(ULONG*)(*(ULONG*)(KThread+0x28)+8))); OrigSwapContext = *(ULONG*)(*(ULONG*)(*(ULONG*)(KThread+0x28)+8)-4) + *(ULONG*)(*(ULONG*)(KThread+0x28)+8); KdPrint(("OrigSwapContext:%x/n",OrigSwapContext)); __asm cli *(ULONG*)(*(ULONG*)(*(ULONG*)(KThread+0x28)+8)-4) = (ULONG)MySwapContext - *(ULONG*)(*(ULONG*)(KThread+0x28)+8); __asm sti ; return STATUS_SUCCESS; } NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { UNICODE_STRING FuncName; ULONG i=0; ULONG HalBeginSystemInterrupt = 0; DriverObject->DriverUnload = Unload; RtlInitUnicodeString(&FuncName,L"HalBeginSystemInterrupt"); HalBeginSystemInterrupt = (ULONG)MmGetSystemRoutineAddress(&FuncName); if(!HalBeginSystemInterrupt) { return STATUS_UNSUCCESSFUL; } for(i=HalBeginSystemInterrupt;i