首页  编辑  

取得0级特权

Tags: /超级猛料/OS.操作系统/权限控制/   Date Created:

]、。·ˉˇ¨〃々—~‖…’”〕〉》」』〗】∶!"'),.:;?]` 我发现了一篇发表在1999.11.29 b13版的

《令win32应用程序跳入系统层》东南大学 卢威 luwei@126.com

是用vc++嵌汇编做的,

很接近了,可试试

BCB或DELPHI进入Ring0

东南大学卢威1999.12发表在<<计算机世界>>报上的一篇

<<WIN32跳入系统0层>>,原采用VC++编程,现改成C++Builder

供诸位参考,DELPHI类似;

void Ring0Proc()  // 在Ring0中执行你自已的代码

{

   // .......

   asm mov eax,CR0;  // 试验一下Ring3不能执行的特权指令

   // .......

}

// =====================================================

void  __declspec(naked) NewInt() //新中断

{

     Ring0Proc();

     asm  iretd;

}

#define  IntNo  9

DWORDLONG  IDTR,SavedGate;

WORD OurGate[4]={0,0x0028,0xee00,0x0000};

void  GotoRing0()

{

     asm

       {

           mov  eax,offset NewInt;

           mov  [OurGate],ax;

           shr  eax,16;

           mov  [OurGate+6],ax;

           sidt fword ptr IDTR;

           mov  ebx,dword ptr [IDTR+2];

           add  ebx,IntNo*8;

           mov  edi,offset SavedGate;

           mov  esi,ebx;

           movsd;

           movsd;

           mov  edi,ebx;

           mov  esi,offset OurGate;

           movsd;

           movsd;

           int  IntNo;

           mov  edi,ebx;  // 开始恢复原中断门

           mov  esi,offset SavedGate;

           movsd;

           movsd;

       }

}

// ===================================================

void __fastcall TForm1::Button1Click(TObject *Sender)

{

   GotoRing0();

}

***********************************************

编译是通过了,你自己调试一下吧。

lea    esi, MyInt; 一句语法应该有逻辑错误,要在Debug中仔细看一下。

procedure MyInt;

asm

 // 这里面的内容可要你自己写哦。

end;

const HookExceptionNumber = 3;

procedure GetRing0;

asm

// 连续压入8个字节作为缓冲区

push    eax

push    eax;

// 取得idt偏移,共6字节,含段选择子2字节,偏移4字节。

sidt    [esp-02h]; // Get IDT Base Address

// 弹出4字节偏移

pop    ebx;

// 每个中断门8字节,所以偏移是HookExceptionNumber*08h

// 另外的4字节是定位到中心,因为中断门的4字节偏移分开放在8字节的0、1、6、7中。

// 0、1存放偏移低16位,6、7存放高16位。2,3是段选择子。4、5是门属性。

add    ebx, HookExceptionNumber*08h + 04h;

// 关中断,准备修改idt。

cli

// 取得中断门的4、5、6、7字节,其中6、7字节在ebp高16位

mov    ebp, [ebx]; // Get Exception Base

// 取得中断门的0、1字节到bp(实际上是ebp的低16位)。

mov    bp, [ebx-04h]; // Entry Point

// 这样就合成了完整的32位偏移。

// 取得自己中断函数入口地址,放入esi中。

lea    esi, MyInt;  

// 压入堆栈

push    esi

// 填充入口低16位到中断门0、1字节。

mov    [ebx-04h], si;

// 将高16位移动到低16位。

shr    esi, 16; // Modify Exception

// 填充入口高16位到中断门6、7字节。

mov    [ebx+02h], si; // Entry Point Address

// idt修改完毕。

// 调整堆栈

pop    esi

// 此时堆栈比初始状态多压8字节。估计是在引发的中断中处理。

// ebp的初始中断入口估计也是在自己的中断函数中用于恢复现场。

// 后面的就是引发软中断,取得ring0权力。

// 不过说句老实话。CIH的创意是不错,不过CIH的汇编的水平其实很一般。

int    HookExceptionNumber; // GenerateException

// ReadyRestoreSE:

sti

end;

----------------------------------

const IntNo=9;

var

IDTR,SavedGate:int64;

OurGate:array[0..3] of word=(0,$0028,$ee00,$0000);

procedure Ring0Proc;  // 在Ring0中执行你自已的代码

begin

   // .......

   asm

   mov eax,CR0;  // 试验一下Ring3不能执行的特权指令

   end;

end;

// =====================================================

procedure   NewInt(); //新中断

begin

     Ring0Proc();

     asm

     iretd;

     end;

end;

procedure  GotoRing0;

begin

     asm

           mov  eax,offset NewInt;

           mov  word ptr[OurGate],ax;

           shr  eax,16;

           mov  word ptr[OurGate+6],ax;

           sidt fword ptr IDTR;//在Delphi中应该改成:lea ebx, idtr;     sidt [ebx]

           mov  ebx,dword ptr [IDTR+2];

           add  ebx,IntNo*8;

           mov  edi,offset SavedGate;

           mov  esi,ebx;

           movsd;

           movsd;

           mov  edi,ebx;

           mov  esi,offset OurGate;

           movsd;

           movsd;

           int  IntNo;

           mov  edi,ebx;  // 开始恢复原中断门

           mov  esi,offset SavedGate;

           movsd;

           movsd;

       end;

end;

// ===================================================

procedure TForm1.Button1Click(Sender: TObject);

begin

gotoring0;

end;

********************************

const IntNo=3;

//var

//IDTR,SavedGate:int64;

procedure Ring0Proc;  // 在Ring0中执行你自已的代码

begin

   // .......

//    showmessage('kfsdj;fk');

   asm

   mov eax,CR0;  // 试验一下Ring3不能执行的特权指令

   end;

end;

// =====================================================

procedure   NewInt(); //新中断

begin

     Ring0Proc();

     asm

     iretd;

     end;

end;

procedure  GotoRing0;

begin

     asm

           mov  edi,offset buf;

           sidt [edi];    //Get IDT-->buf;

           mov ebx,[edi+2]   //求中断门基址

           add ebx,IntNo*8;

           mov esi,ebx;

           push edi;

           push esi;

           movsd;

           movsd;

           cli;

           mov eax,offset newint;

           mov [ebx],ax;

           shr eax,16;

           mov [ebx+6],ax;

           mov ax,0ee00h;

           mov [ebx+4],ax;

           int intno;

           pop edi

           pop esi;

           movsd;

           movsd;

           sti;

       end;

end;