|
阅读:1655回复: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;
} |
|