首页
社区
课程
招聘
[求助]IDTHOOK 中右移16是什么意思?
发表于: 2010-1-16 09:11 4889

[求助]IDTHOOK 中右移16是什么意思?

2010-1-16 09:11
4889
#include <ntddk.h>
#include <stdio.h>

#define MAKELONG(a, b) ((unsigned long) (((unsigned short) (a)) | ((unsigned long) ((unsigned short) (b))) << 16))

#define MAX_IDT_ENTRIES 0xFF
#define NT_INT_TIMER        0x30

unsigned long g_i_count = 0;

///////////////////////////////////////////////////
// IDT structures
///////////////////////////////////////////////////
#pragma pack(1)

// entry in the IDT, this is sometimes called
// an "interrupt gate"
typedef struct
{
        unsigned short LowOffset;
        unsigned short selector;
        unsigned char unused_lo;
        unsigned char segment_type:4;  //0x0E is an interrupt gate
        unsigned char system_segment_flag:1;
        unsigned char DPL:2;         // descriptor privilege level
        unsigned char P:1;            /* present */
        unsigned short HiOffset;
} IDTENTRY;

/* sidt returns idt in this format */
typedef struct
{
        unsigned short IDTLimit;
        unsigned short LowIDTbase;
        unsigned short HiIDTbase;
} IDTINFO;

#pragma pack()

unsigned long old_ISR_pointer;  // better save the old one!!

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{  
        IDTINFO    idt_info;    // this structure is obtained by calling STORE IDT (sidt)
        IDTENTRY*  idt_entries;  // and then this pointer is obtained from idt_info
        char _t[255];

        // load idt_info
        __asm  sidt  idt_info  
                idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);

        DbgPrint("ROOTKIT: OnUnload called\n");

        _snprintf(_t, 253, "called %d times", g_i_count);
        DbgPrint(_t);

        DbgPrint("UnHooking Interrupt...");

        // restore the original interrupt handler
        __asm cli
                idt_entries[NT_INT_TIMER].LowOffset = (unsigned short) old_ISR_pointer;
        idt_entries[NT_INT_TIMER].HiOffset = (unsigned short)((unsigned long)old_ISR_pointer >> 16);
        __asm sti

                DbgPrint("UnHooking Interrupt complete.");
}

// using stdcall means that this function fixes the stack before returning (opposite of cdecl)
void __stdcall count_syscall( unsigned long system_call_number )
{
        g_i_count++;
}

// naked functions have no prolog/epilog code - they are functionally like the
// target of a goto statement
__declspec(naked) my_interrupt_hook()
{
        __asm
        {
                push  eax
                        call  count_syscall
                        jmp    old_ISR_pointer
        }
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
        IDTINFO    idt_info;    // this structure is obtained by calling STORE IDT (sidt)
        IDTENTRY*  idt_entries;  // and then this pointer is obtained from idt_info
        IDTENTRY*  i;
        unsigned long   addr;
        unsigned long  count;
        char _t[255];

        theDriverObject->DriverUnload  = OnUnload;

        // load idt_info
        __asm  sidt  idt_info

                idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);

        for(count=0;count < MAX_IDT_ENTRIES;count++)
        {
                i = &idt_entries[count];
                addr = MAKELONG(i->LowOffset, i->HiOffset);

                _snprintf(_t, 253, "Interrupt %d: ISR 0x%08X", count, addr);
                DbgPrint(_t);
        }

        DbgPrint("Hooking Interrupt...");
        // lets hook an interrupt
        // exercise - choose your own interrupt
        old_ISR_pointer = MAKELONG(idt_entries[NT_INT_TIMER].LowOffset,idt_entries[NT_INT_TIMER].HiOffset);

        // debug, use this if you want some additional info on what is going on
#if 0
        _snprintf(_t, 253, "old address for ISR is 0x%08x", old_ISR_pointer);
        DbgPrint(_t);
        _snprintf(_t, 253, "address of my function is 0x%08x", my_interrupt_hook);
        DbgPrint(_t);
#endif

        // remember we disable interrupts while we patch the table
        __asm cli
                idt_entries[NT_INT_TIMER].LowOffset = (unsigned short)my_interrupt_hook;
        idt_entries[NT_INT_TIMER].HiOffset = (unsigned short)((unsigned long)my_interrupt_hook >> 16);
        __asm sti

                // debug - use this if you want to check what is now placed in the interrupt vector
#if 0
                i = &idt_entries[NT_INT_TIMER];
        addr = MAKELONG(i->LowOffset, i->HiOffset);
        _snprintf(_t, 253, "Interrupt ISR 0x%08X", addr);
        DbgPrint(_t);  
#endif

        DbgPrint("Hooking Interrupt complete");

        return STATUS_SUCCESS;
}

完整代码如上!

红色部分为什么那么写?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 445
活跃值: (25)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
idt中中断例程的地址中高16位跟低16位分开存储在两个WORD变量中
2010-1-16 19:31
0
雪    币: 246
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
就是把高字节 和低字节 连到一起变成地址。 楼主对IDT好感兴趣
2010-1-18 11:59
0
雪    币: 253
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
举个例子:
0x1234右移16位成为0x12340000明白了吗,就是将那两个偏移合并为一个DWORD型
2010-10-26 13:55
0
游客
登录 | 注册 方可回帖
返回
//