我翻译成Delphi的。我测试过你的程序在BCB中可以通过,但是在Delphi中,sidt 指令却不能编译,那位高手知道如何修改?我可以单独开贴子送分!
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;//此处不能通过!如何修改?
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=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;//此处不能通过!如何修改?
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;
lea ebx, idtr;
sidt [ebx]
直接修改原中断门,程序就出错,原来数组中
第三项0ee00h是门属性,不能不设,不太明白;
IDTR与SavedGate可以合二为一成Buf,注意:
此Buf可以须是全局或静态变量,不能是栈中
分配的动态变量,原因可能是传送指令movsd的
操作数不是相对于栈段;
void Ring0Proc() // 在Ring0中执行你自已的子程序
{
asm mov eax,CR0; // 测验Ring3不能执行的特权指令
}
// =====================================================
void __declspec(naked) NewInt() //新中断
{
Ring0Proc();
asm iretd;
}
#define IntNo 3void GotoRing0()
{
static DWORDLONG Buf; //静态或全局变量
asm
{
mov edi,offset Buf;
sidt [edi]; // 取IDT->Buf
mov ebx,[edi+2]; // 求中断门基址
add ebx,IntNo*8;
mov esi,ebx;
push edi;
push esi;
movsd; //保存原中断门->Buf
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;
}
}
// ===================================================void __fastcall TForm1::Button1Click(TObject *Sender)
{
GotoRing0();
}改动后的程序,若有新问题,请再贴!!!!!!
$EE00代表:已经映射到物理内存的访问等级为3的386中断门。
我在2K下,没有调试。不过,不觉得你这样写程序有什么好。虽然是少用了4字节的存储空间,且不说代码却多了2条。而且使得程序流程晦涩难懂,这在汇编程序中是致命的问题。
sidt [esp-02h]
pop ebx
这样如何?
对于门属性,未改前好象是8e00h,要改成0ee00h,才能成功,不知为什么?
代码重改的理由,不是针对几个字节或指令,主要是针对OurGate 数组:
OurGate[1]是选择子,它设成0028h,没有必要;所以取消
OurGate数组是应该的,改动后的流程还能算符合常理:
取IDT->取中断门地址->保存旧中断门(且暂存源、目)-> 修改中断门->
执行中断->取出源、目且恢复旧门
修改后如果仍能正常,就满意了!
最后一个问题:
取得了特权ring0,我们能搞些什么应用????看了原文章,主要:
1.能执行特权指令了;
2.能执行BIOS了;
3.能执行VMM(虚拟管理器)管理了;
4.能执行DPMI服务了;
除了共知的CIH外,似乎“用处”大得“狠”,请高手解释!!!!!!!!!
Win9x下所有的选择子的基址像都一样,所以修改了也没关系。不然,你只修改了入口地址,却没有把门的段选择子改为自己代码段选择子,也是有问题的。如果要保险起见,可以将CS也填入到OurGate中去。取得Ring0其实最重要的作用是执行特权指令,以便随意访问硬件资源(主要是内存),从而可以修改Windwos的核心。2~3的内容在NT下都废除了,用处不大。另外,Ring0下CLI然后HLT,可就真的死机了,只能Reset了^_^。
是你“改进”后出现“兰屏”,还是本人提供的程序就出现“兰屏”?
在RING0下,也就是一会儿,又回到Ring3,象你用“开关”式的切换
可能较困难.
经测试:选择子,修改前后,都是0028H,我原想就不设定了;
另外,你的意思int 3前加一条 STI,
ok!
你要常调用GotoRing0(),可将原Ring0Proc 稍改到一下,用函数名
做参数如:
GotoRing0(Ring0Proc1);
.....
GotoRing0(Ring0Proc2);
.....
就没必要做成“开关”式的切换了,拥有
“特权”的时间不宜太长.
我的意思是只有Ring0下才能轻易让机器彻底死掉。所以一般不要切过来,在Ring0下,程序错误的后果会非常严重。
***********************************************
你要常调用GotoRing0(),可将原Ring0Proc 稍改到一下,用函数名
做参数如:
GotoRing0(Ring0Proc1);
~~~~~~~~~~
.....
GotoRing0(Ring0Proc2);
~~~~~~~~~~~
.....
就没必要做成“开关”式的切换了,拥有
“特权”的时间不宜太长.
****************************************