求教delphi访问硬盘绝对扇区的方法(100分)

  • 主题发起人 主题发起人 wingfly
  • 开始时间 开始时间
W

wingfly

Unregistered / Unconfirmed
GUEST, unregistred user!
我想用delphi编一个程序使他能访问硬盘的0面0到63扇区
以前用turbo pascal6.0做过,不知道用delphi行不行
 
Delphi 1.0 可以在源程序中嵌入汇编,直接调用相应的中断服务程序;
Delphi 2/3/4/5/6 都不允许直接在内嵌汇编中调用相应的中断,因为受到操作系统的限制。
办法是:一、写一个 VxD;二、直接在源程序中用嵌入汇编的方法将代码从 Ring3 级跳到
Ring0 级,然后就可以直接调用过去的磁盘访问中断服务程序了。
 
用VXD技术也只能在98下,在NT和2000下可就不好使了
 
to Phoenix2000能不能对二种方法详细解释一下或者给一些类似的站点,我再加50分
 
在 Win9x 中,可执行代码被划分权限等级,普通的应用程序代码处于 Ring3 级,不能直
接调用硬件中断,硬件中断被系统保护,只有处于 Ring0 级的代码才能够调用(就像过去
的 DOS 程序中的做法一样)。在 NT/2000 中没有 Ring0/Ring3 的概念,所以以下方法
不能在 NT/2000 中使用!在 NT/2000 中要使用 NT DDK 或者 WDM 驱动模型。

第一种方法:写一个 VxD 虚拟设备驱动程序,只在 Win9x 下有效,在 NT/2000 下无效。
主要是因为 VxD 代码处于系统 Ring0 级,与系统内核同级别,可以直接调用被系统保护
的硬件中断。

第二种方法:不使用 VxD 而直接使自己的代码进入系统 Ring0 级,目的是一样的。主要
是修改系统 IDT(中断描述表),可用于普通应用程序中。一旦自己的代码跳入 Ring0 级
别,就可以像设备驱动程序那样调用真正的硬件中断了。下面是在 C++ Builder 中的直接
跳入系统 Ring0 层的代码,供参考:

// =====================================================
#define IntNo 9
DWORDLONG IDTR, SavedGate;
WORD OurGate[4] = {0, 0x0028, 0xee00, 0x0000};
// =====================================================
// 系统Ring0层中执行的代码
void Ring0_Proc()
{
// 直接执行受系统保护的代码,如硬件中断
// ...
asm int 13h;
// ...
}
// =====================================================
// 新的中断函数
void __declspec(naked) NewInterrupt()
{
Ring0_Proc()
// 执行自己的Ring0函数
asm iretd
// 返回
}
// =====================================================
// 跳入系统Ring0的代码
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)
{
// 按下窗体上某个按钮就执行Ring0级保护代码
GotoRing0();
}
// ===================================================

用 Delphi 改写一上代码要注意,Delphi 的编译器中内嵌的汇编器不是对所有的汇编指令
都有效的,对于某些汇编代码需要变通修改,不方便。C++ Builder 内嵌汇编使用的仍然是
TASM32 汇编器,兼容所有的 x86 汇编指令(MMX 和 3D Now! 除外)。以上方法在 NT/2000
中无效!
 
Sorry,有个笔误,更正:

void GotoRing0()
{
asm
{
mov eax,offset NewInt

改为:

void GotoRing0()
{
asm
{
mov eax,offset NewInterrupt

 
多人接受答案了。
 
后退
顶部