返回列表 发帖

各位,关于RING0的切换。不知道谁愿意透露点呢。

我最近要对NT下的硬件断口进行随意的切换,当然,我是有ADMINISTRATOR的权限的。
但是,在网上没看到比较好的介绍,(或者是我太笨了)。
呵呵,希望各位来讨论讨论。
我想,使用VC,直接跳入RING0。

各位,关于RING0的切换。不知道谁愿意透露点呢。

看来呢, 是我自己来解决了。
这个是常规的方法的。用驱动办法来搞定啦。
这里有个例子,先用了。
其实这些大家应该都知道了, 但是,如何让程序自己一下从RING3进入RING0确实还是有点困难。希望高手能够给点指导。
#include "ntddk.h"
#include "string.h"
#ifndef DWORD
#define DWORD unsigned int
#endif
#ifndef WORD
#define WORD unsigned short
#endif
#define LOWORD(l)           ((unsigned short)(unsigned int)(l))
#define HIWORD(l)           ((unsigned short)((((unsigned int)(l)) >> 16) & 0xFFFF))

typedef unsigned long    ULONG;
static NTSTATUS  MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);
#pragma pack(push,1)

typedef struct tagGDTR{
    WORD    wLimit;
    DWORD   *dwBase;
}GDTR, *PGDTR;
typedef struct tagGDT_DESCRIPTOR{
    unsigned limit         : 16;
    unsigned baselo         : 16;
    unsigned basemid     : 8;
    unsigned type        : 4;
    unsigned system      : 1;
    unsigned dpl         : 2;
    unsigned present     : 1;
    unsigned limithi     : 4;
    unsigned available   : 1;
    unsigned zero        : 1;
    unsigned size        : 1;
    unsigned granularity : 1;
    unsigned basehi : 8;
}GDT_DESCRIPTOR, *PGDT_DESCRIPTOR;
typedef struct tagCALLGATE_DESCRIPTOR{
    unsigned short   offset_0_15;
    unsigned short   selector;
    unsigned char    param_count : 4;
    unsigned char    some_bits   : 4;
    unsigned char    type        : 4;
    unsigned char    app_system  : 1;
    unsigned char    dpl         : 2;
    unsigned char    present     : 1;
    unsigned short   offset_16_31;
} CALLGATE_DESCRIPTOR, *PCALLGATE_DESCRIPTOR;
#pragma pack(pop)
void __declspec(naked) Ring0Call()
{
    PHYSICAL_ADDRESS  PhyAdd;
    __asm {
        pushad
        pushfd
        cli
    }
     DbgPrint("WSS - My CallGate \n");
     //
     // 这里可以添加你想要执行的 ring 0 代码。
     //
    __asm {
       popfd
       popad
       retf
    }
}
VOID AddCallGate( ULONG FuncAddr )
{
    GDTR                    gdtr;
    PGDT_DESCRIPTOR         gdt;
    PCALLGATE_DESCRIPTOR    callgate;
    WORD                    wGDTIndex = 1;

    __asm {
        sgdt  gdtr                  // 得到 GDT 基地址与界限
    }
    gdt = (PGDT_DESCRIPTOR) ( gdtr.dwBase + 8 );  // 跳过空选择子
    while ( wGDTIndex < ( gdtr.wLimit / 8 ) )
    {
       if ( gdt->present == 0 )     //从 GDT 中找到空描述符
       {           
            callgate = (PCALLGATE_DESCRIPTOR)gdt;
            callgate->offset_0_15             = LOWORD(FuncAddr);
            callgate->selector         = 8;                     // 内核段选择子
            callgate->param_count             = 0;               // 参数复制数量
            callgate->some_bits         = 0;                    
            callgate->type             = 0xC;              // 386调用门
            callgate->app_system             = 0;                    // 系统描述符
            callgate->dpl             = 3;                    // RING 3 可调用
            callgate->present         = 1;                    // 设置存在位
            callgate->offset_16_31   = HIWORD(FuncAddr);
            DbgPrint("Add CallGate\n");
            return;
       }
       gdt ++;        
       wGDTIndex ++;
    }
}

// 驱动入口
NTSTATUS  DriverEntry( IN PDRIVER_OBJECT DriverObject,  IN PUNICODE_STRING RegistryPath )
{
   
    UNICODE_STRING  nameString, linkString;
    PDEVICE_OBJECT  deviceObject;
    NTSTATUS        status;
    HANDLE          hHandle;
    int                i;
   
    //卸载驱动
    DriverObject->DriverUnload = DriverUnload;
    //建立设备
    RtlInitUnicodeString( &nameString, L"\\Device\\WssAddCallGate" );
   
    status = IoCreateDevice( DriverObject,
                             0,
                             &nameString,
                             FILE_DEVICE_UNKNOWN,
                             0,
                             TRUE,
                             &deviceObject
                           );
                           
    if (!NT_SUCCESS( status ))
        return status;
   
    RtlInitUnicodeString( &linkString, L"\\DosDevices\\WssAddCallGate" );
    status = IoCreateSymbolicLink (&linkString, &nameString);
    if (!NT_SUCCESS( status ))
    {
        IoDeleteDevice (DriverObject->DeviceObject);
        return status;
    }   
   
    AddCallGate((ULONG)Ring0Call);
    for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)    {
          DriverObject->MajorFunction = MydrvDispatch;
    }
      DriverObject->DriverUnload = DriverUnload;
     
  return STATUS_SUCCESS;
}

//处理设备对象操作
static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0L;
    IoCompleteRequest( Irp, 0 );
    return Irp->IoStatus.Status;
   
}

VOID DriverUnload (IN PDRIVER_OBJECT    pDriverObject)
{
    UNICODE_STRING  nameString;
    RtlInitUnicodeString( &nameString, L"\\DosDevices\\WssAddCallGate" );   
    IoDeleteSymbolicLink(&nameString);
    IoDeleteDevice(pDriverObject->DeviceObject);
    return;
}

TOP

各位,关于RING0的切换。不知道谁愿意透露点呢。

高手,请教,教上教!!!吼吼......................


以上纯属胡说,相信必究!

TOP

返回列表 回复 发帖