阅读:1570回复:0
如何确保修改多个CPU上的IDT?
寒江独钓的书中讲到可以通过修改IDT来HOOK中断,但是没有讲到如何在多CPU上实现,查了一些资料,还来弄不明白。下面是网上找的一个代码,不知道能不能确保在多CPU上成功修改IDT。
void HookIDT() { ULONG handler1,handler2,idtbase,tempidt,a; UCHAR idtr[8]; //get the addresses that we have write to IDT handler1=(ULONG)&replacementbuff[0];handler2=(ULONG)&replacementbuff[32]; //allocate temp. memory. This should be our first step - from the moment we disable interrupts //till return we don't risk to call any code that has not been written by ourselves // (theoretically this code may re-enable interrupts without our knowledge, and then.....) tempidt=(ULONG)ExAllocatePool(NonPagedPool,2048); _asm { cli sidt idtr lea ebx,idtr mov eax,dword ptr[ebx+2] mov idtbase,eax } //check whether our IDT has already been hooked. If yes, re-enable interrupts and return for(a=0;a<IdtsHooked;a++) { if(idtbases[a]==idtbase) { _asm sti ExFreePool((void*)tempidt); KeSetEvent(&event,0,0); PsTerminateSystemThread(0); } } _asm { //now we are going to load the copy of IDT into IDTR register // in my experience, modifying memory,pointed to by IDTR register, is unsafe mov edi,tempidt mov esi,idtbase mov ecx,2048 rep movs lea ebx,idtr mov eax,tempidt mov dword ptr[ebx+2],eax lidt idtr //now we can safely modify IDT. Get ready mov ecx,idtbase //hook INT 1 add ecx,8 mov ebx,handler1 mov word ptr[ecx],bx shr ebx,16 mov word ptr[ecx+6],bx ///hook INT 3 add ecx,16 mov ebx,handler2 mov word ptr[ecx],bx shr ebx,16 mov word ptr[ecx+6],bx //reload the original idt lea ebx,idtr mov eax,idtbase mov dword ptr[ebx+2],eax lidt idtr sti } //now add the address of IDT we just hooked to the list of hooked IDTs idtbases[IdtsHooked]=idtbase; IdtsHooked++; ExFreePool((void*)tempidt); KeSetEvent(&event,0,0); PsTerminateSystemThread(0); } NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver,IN PUNICODE_STRING path) { ULONG a;PUCHAR pool=0; UCHAR idtr[8];HANDLE threadhandle=0; //fill the array with machine codes replacementbuff[0]=255;replacementbuff[1]=37; a=(long)&replacementbuff[6]; memmove(&replacementbuff[2],&a,4); a=(long)&INT1Proxy; memmove(&replacementbuff[6],&a,4); replacementbuff[32]=255;replacementbuff[33]=37; a=(long)&replacementbuff[38]; memmove(&replacementbuff[34],&a,4); a=(long)&BPXProxy; memmove(&replacementbuff[38],&a,4); //save the original addresses of INT 1 handler _asm { sidt idtr lea ebx,idtr mov ecx,dword ptr[ebx+2] /////save INT1 add ecx,8 mov ebx,0 mov bx,word ptr[ecx+6] shl ebx,16 mov bx,word ptr[ecx] mov Int1RealHandler,ebx /////save INT3 add ecx,16 mov ebx,0 mov bx,word ptr[ecx+6] shl ebx,16 mov bx,word ptr[ecx] mov BPXRealHandler,ebx } //hook INT 1 and INT 3 handlers - it has to be done before overwriting NDIS //Run HookUnhookIDT() as a separate thread until all IDTs get hooked KeInitializeEvent(&event,SynchronizationEvent,0); RtlZeroMemory(&idtbases[0],64); a=KeNumberProcessors[0]; while(1) { PsCreateSystemThread(&threadhandle,(ACCESS_MASK) 0L,0,0,0,(PKSTART_ROUTINE)HookIDT,0); KeWaitForSingleObject(&event,Executive,KernelMode,0,0); if(IdtsHooked==a)break; } KeSetEvent(&event,0,0); //fill the structure... a=(ULONG)&IoCreateDevice; HookedFunctionDescriptor.RealCode=a; pool=ExAllocatePool(NonPagedPool,8); memmove(pool,a,8); HookedFunctionDescriptor.ProxyCode=(ULONG)pool; //now let's proceed to overwriting memory _asm { //remove protection before overwriting mov eax,cr0 push eax and eax,0xfffeffff mov cr0,eax //insert breakpoint (0xCC opcode) mov ebx,a mov al,0xcc mov byte ptr[ebx],al //restore protection pop eax mov cr0,eax } return 0; } |
|