解析Windows2000的IDT扩展机制
2006-07-20 11:40:19 来源:WEB开发网通过添加软件中断,我们可以扩展系统的功能,改变系统的很多操作行为。在前面我们介绍过为系统添加新的系统服务调用来扩展系统,通过添加新的软件中断同样可以到达添加系统服务调用的目的,并且我们可以在新添的中断处理程序中执行Ring 0级别的任意代码,那是何等的让人欣慰!
其实在IDT中,256个中断门单元并不是被完全利用的,还剩下一些流给将来扩展使用的中断门,我们可以自己给这些未使用的中断门添加一些机制为我所用。其实添加软件中断的过程和前面我们详细讲解的添加软件中断钩子有很多相似的地方,所以在此我就不做很详细的介绍了。同样是,首先获得IDT的基地址,然后在中断描述符表中查找我们将要添加的中断号对应的中断门描述符,之后给相关的参数赋值,使其成为名副其实的软件中断门。这时我们就可以在应用程序中使用中断指令int xx来调用我们自己中断门中的服务程序了。
7、添加软件中断的实现过程
相关程序为T-ADDIG(Add Interrupt Gate),我们来看看代码哈~ NTSTATUS
后记
InstallIG()
{
……
//判断我们想要添加的中断是否已被占用;
if(IdtEntry[ADDINTID].OffsetLow != 0
││ IdtEntry[ADDINTID].OffsetHigh != 0)
{
return STATUS_UNSUCCESSFUL;
}
//复制原始的中断门描述信息;
RtlCopyMemory(&OldIdtEntry,&IdtEntry[ADDINTID],sizeof(OldIdtEntry));
//关中断
__asm cli
//更新执行代码偏移量的底16位;
IdtEntry[ADDINTID].OffsetLow = (unsigned short)InterruptServiceRoutine;
//目的代码段的段选择器,CS为8;
IdtEntry[ADDINTID].Selector = 8;
//保留位,始终为零;
IdtEntry[ADDINTID].Reserved = 0;
//门类型,0xe代表中断门;
IdtEntry[ADDINTID].Type = 0xe;
//SegmentFlag设置0代码为段;
IdtEntry[ADDINTID].SegmentFlag = 0;
//描述符权限等级为3,允许用户模式程序调用本中断;
IdtEntry[ADDINTID].DPL = 3;
//呈现标志位,设置为一;
IdtEntry[ADDINTID].Present = 1;
//更新执行代码偏移量的高16位;
IdtEntry[ADDINTID].OffsetHigh = (unsigned short)((unsigned int)InterruptServiceRoutine >> 16);
//开中断
__asm sti
return STATUS_SUCCESS;
}
VOID
RemoveIG()
{
……
__asm cli
//恢复我们修改过的中断门描述符;
RtlCopyMemory(&IdtEntry[ADDINTID],&OldIdtEntry,sizeof(OldIdtEntry));
__asm sti
}
extern
void
_cdecl
InterruptServiceRoutine(VOID)
{
unsigned int Command;
//获取eax寄存器中的数值,接受从用户模式传入的命令参数;
__asm mov Command,eax;
//执行内核代码,获取操作系统版本号;
DbgPrint("NtBuildNumber == %d\n",(unsigned short)NtBuildNumber);
//中断返回;
__asm iretd;
}
写到这儿,我们只是介绍了扩展IDT的一些基本方法,当然还有很多更深入的,更值得我们研究的课题需要大家努力去探索。比如我们可以将T-HookInt扩展,不仅仅是监视系统注册表操作相关的系统服务调用,不过在Windows XP/2003上由于其内在机制的一些变更,所以通过Hook int 0x2e来截获系统服务调用就不这么现实了。当然还有基于IDT的内核级后门,可以通过添加新的软件中断为任意用户提供SYSTEM权限级别的Command等。总之,探究Windows内核奥秘的旅行还未结束,或许这只能算是一次起航罢了。
更多精彩
赞助商链接