Delphi 能不能从Ring 3进入Ring 0?
有例子吗?
多谢.
有例子吗?
多谢.
解决方案 »
- 将图片拖动到窗体,便可激活图片查看器打开图片
- 高手请进,Indy9的tIDFtp的上传问题
- string[]的初始化
- TdxDBGridReportLink是什么控间??
- 如何把已经存在的EXCEL表 导到SQL SERVER 7里面
- 请高手来回答!!!!
- 做Web Services的数据库访问遇到难题,搞了几天也无法解决,请大侠指点
- 大虾们有没有用NMUDP控件传文件的例子,给我看看啊。谢谢
- 现有一问题!
- 关于QuickRep的问题,怎么才能将Memo中的内容赋给QRMemo呢?
- 请教一个难题!
- 江湖告急!!!上海创业,想在科技开发区或者软件园注册,哪个软件园好,可以提供资料和案例的朋友给分还给钱
《令win32应用程序跳入系统层》东南大学 卢威 [email protected]
是用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:
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;
飞思科技的《WINDOWS 核心编程》
http://www.delphibbs.com/keylife/iblog_show.asp?xid=6679
http://www.delphibbs.com/keylife/iblog_show.asp?xid=6680
http://www.delphibbs.com/keylife/iblog_show.asp?xid=6681
与我写的很接近啦只是Xp/2003下通过ZwSystemDebugControl还能支持访问虚拟地址在8000000H上的空间
而我实现FarCall使用的是另外的方法:内存Patch技术,比你的略为复杂点,但效果是一样的还有一个问题,VM上无法运行这个程序的,因为VM下,系统的GDT不在4MB区域,基本上都是FFC07000h的,且就算用别的工具访问到了,读出来的都是无效的0,看来是VM的奇怪“问题”,我就解决不了了http://lysoft.7u7.net
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.
我看过了你的例子,很佩服!!!!!procedure TForm1.Button2Click(Sender: TObject);
出错的问题也找到原因了,是没有保护现场.把ExecRing0Proc的定义改为下面这样就可以了.
function ExecRing0Proc( Entry,seglen : ULONG):Boolean; stdcall;我想在问一下老大,我怎么在rang0下用API啊?就是平常这样用吗?多谢.
var
s:string;
i:integer;
begin
self.Memo1.Lines.Add ( 'aa');
ZeroMemory(@R0Data, SizeOf(R0Data));
VirtualLock(@R0Data, SizeOf(R0Data));
ExecRing0Proc0(ULONG(@Ring0Func),$100);
VirtualUnlock(@R0Data, SizeOf(R0Data));
//¿ÉÄÜÊǶÑÕ»±»ÆÆ»µÁË£¬ÕâÀïµ÷Óþͳö´í£¬¸ßÊÖ°ï¿´¿´
i:= R0Data.mrc0;
s:=IntToHex(i, 8);
caption := s;
self.Memo1.Lines.Add ( 'aa');
Memo1.Lines.Add ('CR2 = $'+ IntToHex(R0Data.mrc2, 8));
Memo1.Lines.Add ('CR3 = $'+ IntToHex(R0Data.mrc3, 8));end;function ExecRing0Proc0( Entry,seglen : dword):Boolean;
asm
push ebx
push seglen
push Entry
call ExecRing0Proc
pop ebx
end;这样就可以了.
Zw的API或NtOSkrnl.exe中的API 能不能给个例子?
多谢.
begin
asm
pushad
pushf
cli mov esi, MemoryAddress.VirtualAddress
push esi
call _MmGetPhysicalAddress
mov MemoryAddress.PhysicalAddress.LowPart, eax // save low part of LARGE_INTEGER
mov MemoryAddress.PhysicalAddress.HighPart, edx // save high part of LARGE_INTEGER popf
popad
retf
end;
end;procedure MmGetPhysicalAddress;
var hNTDll: THandle;
begin
_MmGetPhysicalAddress := 0;
hNTDll := LoadLibrary('ntoskrnl.exe');
if hNTDll <> 0 then
begin
_MmGetPhysicalAddress := NTOSBaseAddr + Cardinal(GetProcAddress(hNTDll, 'MmGetPhysicalAddress')) - hNTDll;
FreeLibrary(hNTDll);
// ShowMessage(Format('Virtual address of MmGetPhysicalAddress in Kernel Mode : %s', [IntToHex(_MmGetPhysicalAddress, 8)]));
end;
if _MmGetPhysicalAddress > 0 then ExecRing0Proc(@Ring0Func, 32);
end;呵呵,NT OS Kernel的东西哦你不是有什么特殊的需求,最好不要随便用Ring0,作为技术研究还可以,真要做事情,还是老实用SYS的WDM驱动才是正路,Delphi不适合做这些事情的,选择VC吧,真的要Delphi就需要借助WinDriver这样的驱动开发包http://lysoft.7u7.net
我是想把验证的代码放在Ring0运行,如果通过了,就在Ring0修改code区。
我不知道能不能实现。
http://community.csdn.net/Expert/topic/3570/3570742.xml?temp=.5977899完整的见
http://blog.csdn.net/ly_liuyang/archive/2004/11/20/189013.aspx只是数值计算是可以的,但你要注意Ring0的代码是占用100%CPU的,不要过于复杂
另外这个方法是由条件限制的:不能在VM或VPC上使用,必须是管理员帐户登陆,系统允许调试权限http://lysoft.7u7.net
CIH的做法就是这样的,这样的东西省省吧