博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用中断门
阅读量:5952 次
发布时间:2019-06-19

本文共 2279 字,大约阅读时间需要 7 分钟。

注意返回时得使用iretd。

通过sidt取得idtr,找到里面的基址和limit。遍历所有的表项,找到一个p位没有置位的,添加一个调用门。和使用call gate没什么大差别。
 
看了下,我机器里的第一个空白项是0x20,就懒得写和ring3通信的东西了。
 
ring3:
#include <stdio.h>
int main()
{
    __asm int 0x20
    return 1;
}
 
ring0:
#include <ntddk.h>
#pragma pack(1)
typedef struct _IDTR
{
    USHORT limit;
    ULONG base;
}IDTR, *PIDTR;
typedef struct _IDT_ENTRY
{
    USHORT OffsetLow;
    USHORT selector;
    UCHAR reserved;
    UCHAR type :4;
    UCHAR always0 :1;
    UCHAR dpl :2;
    UCHAR present :1;
    USHORT OffsetHigh;
}IDT_ENTRY, *PIDT_ENTRY;
#pragma pack()
ULONG IdtIndex = 0;
IDT_ENTRY IdtEntry = {0};
PIDT_ENTRY OrigIdtEntry = NULL;
ULONG SetInterruptGate(PVOID MyFuncAddr);
MyFunc();
VOID ring0func();
VOID DriverUnload(PDRIVER_OBJECT pDriverObject);
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
{
    IdtIndex = SetInterruptGate(MyFunc);
    pDriverObject->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}
ULONG SetInterruptGate(PVOID MyFuncAddr)
{
    IDTR idtr = {0};
    ULONG i = 0;
    PIDT_ENTRY pIdtEntry = NULL;
    __asm sidt idtr
    
    for(i = 0;i < idtr.limit;i++)
    {
        pIdtEntry = (PIDT_ENTRY)(idtr.base + i * 8);
        if(!pIdtEntry->present)
        {
            OrigIdtEntry = pIdtEntry;
            IdtEntry.OffsetLow = pIdtEntry->OffsetLow;
            IdtEntry.OffsetHigh = pIdtEntry->OffsetHigh;
            IdtEntry.selector = pIdtEntry->selector;
            IdtEntry.reserved = pIdtEntry->reserved;
            IdtEntry.type = pIdtEntry->type;
            IdtEntry.always0 = pIdtEntry->always0;
            IdtEntry.dpl = pIdtEntry->dpl;
            IdtEntry.present = pIdtEntry->present;
            pIdtEntry->OffsetLow = (USHORT)MyFuncAddr;
            pIdtEntry->OffsetHigh = (USHORT)((ULONG)MyFuncAddr >> 16);
            pIdtEntry->selector = 0x8;
            pIdtEntry->reserved = 0;
            pIdtEntry->type = 0xE;
            pIdtEntry->always0 = 0;
            pIdtEntry->dpl = 3;
            pIdtEntry->present = 1;
            break;
        }
    }
    return i;
}
__declspec(naked) MyFunc()
{
    __asm
    {
        pushad
        call ring0func
        popad
        iretd
    }
}
VOID ring0func()
{
    DbgPrint("interrupt gate");
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
    OrigIdtEntry->OffsetLow = IdtEntry.OffsetLow;
    OrigIdtEntry->OffsetHigh = IdtEntry.OffsetHigh;
    OrigIdtEntry->selector = IdtEntry.selector;
    OrigIdtEntry->reserved = IdtEntry.reserved;
    OrigIdtEntry->type = IdtEntry.type;
    OrigIdtEntry->always0 = IdtEntry.always0;
    OrigIdtEntry->dpl = IdtEntry.dpl;
    OrigIdtEntry->present = IdtEntry.present;
}

 

转载于:https://www.cnblogs.com/foohack/p/3582302.html

你可能感兴趣的文章
算法题解:找出包含给定字符的最小窗口(枚举的一般方法)
查看>>
超级账本HyperLedger初体验
查看>>
完美解决html中select的option不能隐藏的问题。
查看>>
推荐5大开源工具,用于开发Kubernetes项目
查看>>
制定2015年的移动开发策略
查看>>
JPA 2.2改进了易用性
查看>>
从蚂蚁金服实践入手,带你深入了解 Service Mesh
查看>>
24周年,“常青树”Delphi发布新版本10.3.1
查看>>
7. 从数据库获取数据- 从零开始学Laravel
查看>>
阿里百川码力APP监控 来了!
查看>>
使用dotenv管理环境变量
查看>>
温故js系列(11)-BOM
查看>>
Vuex学习
查看>>
bootstrap - navbar
查看>>
切图崽的自我修养-[ES6] 编程风格规范
查看>>
[React Native Android 安利系列]样式与布局的书写
查看>>
利用dxflib读写cad文件
查看>>
服务器迁移小记
查看>>
FastDFS存储服务器部署
查看>>
Android — 创建和修改 Fragment 的方法及相关注意事项
查看>>