我给200分

解决方案 »

  1.   

    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:
    stiend;
    ----------------------------------
    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;
      

  2.   


    button1 : 直接执行Int 03h,在IDE环境中会产生单步调试的中断,独立运行会发生异常,是为了证明button2执行的代码正确性而设置的。 
    button2 : 实际获取Ring 0 级的代码,使用了内嵌汇编。 
    button3 : 停止button2中的发声 unit main; interface uses 
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
      StdCtrls; type 
      TForm1 = class(TForm) 
        Button1: TButton; 
        Button2: TButton; 
        Button3: TButton; 
        procedure Button1Click(Sender: TObject); 
        procedure Button2Click(Sender: TObject); 
        procedure Button3Click(Sender: TObject); 
      private 
        { Private declarations } 
      public 
        { Public declarations } 
      end; var 
      Form1: TForm1; 
     var  IDT : array [0..5] of byte; // 保存中断描述符表 
          lpOldGate : dword;          // 存放旧向量 
    implementation {$R *.DFM} procedure aa; stdcall; 
    const ExceptionUsed = $03;        // 中断号。 
    begin 
       asm 
         sidt IDT                   //  读入中断描述符表 
         mov ebx, dword ptr [IDT+2]   
         add ebx, 8*ExceptionUsed 
         cli 
         mov dx, word ptr [ebx+6] 
         shl edx, 16d 
         mov dx, word ptr [ebx] 
         mov [lpOldGate], edx 
         mov eax, offset @@Ring0Code    // 修改向量,指向Ring0级代码段 
         mov word ptr [ebx], ax 
         shr eax, 16d 
         mov word ptr [ebx+6], ax 
         int ExceptionUsed             // 发生中断 
         mov ebx, dword ptr [IDT+2] 
         add ebx, 8*ExceptionUsed 
         mov edx, [lpOldGate] 
         mov word ptr [ebx], dx 
         shr edx, 16d 
         mov word ptr [ebx+6], dx      // 恢复被改了的向量 
         ret     @@Ring0Code:   // Ring0级代码段   
          mov eax,cr0  // 此句在Ring3级会发生异常错误 
          mov dx, $61  // 以下语句是为了证明执行了此段代码,让PCSpeak发声 
          mov al, $ff 
          out dx, al 
          mov dx, $43 
          mov al, $b6 
          out dx, al 
          mov dx, $42 
          mov al, $f0 
          out dx, al 
          mov dx, $42 
          mov al, $0 
          out dx, al 
          iretd         // 中断返回 
       end; 
    end; procedure TForm1.Button1Click(Sender: TObject); 
    begin 
        aa;      
    end; procedure TForm1.Button2Click(Sender: TObject); 
    begin 
        asm 
           int 03h           //  
        end; 
    end; procedure TForm1.Button3Click(Sender: TObject); 
    var bvalue : byte; 
       value : word; 
    begin //  停止PCSpeak发声 
      asm 
         mov dx, $61 
         in al, dx 
         mov bValue, al 
      end ; 
      value := bValue and $fc; 
      bValue := Trunc(Value and 255); 
      asm 
        mov dx, $61 
       mov al, bValue 
       out dx, al 
      end; 
    end; end.