安裝驅動,啓動驅動,能夠動態載入ring0代碼。html
可是,每次都要簽名,安裝,啓動,並且每次寫驅動還都要寫一大堆框架得代碼,好比irp的dispatche函數配置,擴展數據結構等。數據結構
因而,我打算設計一個動態載入ring0代碼的機制,只須要關心irp的處理便可,並且無需簽名,編譯一個dll或exe便可,讓測試調試也容易一些。框架
參考了pagedpool和nopagedpool以及網上的一些在ring0執行應用層代碼的用例,好比下面這段:函數
來自:https://www.cnblogs.com/blogpro/p/11453641.html測試
//===================WinRing.pas=========================== unit WinRing; interface uses Windows,WinSvc,Dialogs,Forms; Type TRingData = Record AdjRing0Entry:ULONG ; RegData:array[0..6] of ULONG; end; TRing0Proc = Procedure;StdCall; procedure OpenWinRing; function CloseDriver:boolean; procedure ProcessRing0(Ring0Proc: TRing0Proc);StdCall; const DRIVER = 'WINRING'; implementation var DriverHandle: THandle; Ring: TRingData; RetByteWord; OSVersion: byte; Function WINRING_Access:Cardinal; Begin Result:=(($22) shl 16) or (($999) shl 2); End; Procedure _WinRing; Begin DeviceIoControl(DriverHandle,WINRING_Access,@Ring, sizeof(Ring),@Ring,sizeof(Ring),retbyte,Nil); End; function BuildDriverService:boolean; var scHandle, srvHandle: SC_Handle; achar; begin Result:=False; scHandle:=OpenSCManager(Nil,Nil,SC_MANAGER_ALL_ACCESS); if (scHandle<>0) then Begin srvHandle:=OpenService(scHandle,DRIVER,SERVICE_ALL_ACCESS); if (srvHandle=0) then begin srvHandle:=CreateService( scHandle, DRIVER, DRIVER, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, '.\WINRING.sys', Nil,Nil,Nil,nil,nil); end; if (srvHandle<>0) then Begin A:=''; StartService(srvHandle,0,A); CloseServiceHandle(srvHandle); CloseServiceHandle(scHandle); Result:= true; End; end; end; function OpenDriver:Boolean; begin if (BuildDriverService) then begin DriverHandle:=CreateFile( '\\.\'+DRIVER, GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0); Result:=(DriverHandle<>INVALID_HANDLE_VALUE); end else Result:=False; end; function DeleteDriverService:boolean; var srvStatus: TServiceStatus; scHandle,srvHandle: SC_HANDLE; begin scHandle:=OpenSCManager(Nil,Nil,SC_MANAGER_ALL_ACCESS); if (scHandle<>0) then begin srvHandle:=OpenService(scHandle,DRIVER,SERVICE_ALL_ACCESS); if (srvHandle<>0) then begin ControlService(srvHandle,SERVICE_CONTROL_STOP,srvStatus); DeleteService(srvHandle); end; CloseServiceHandle(srvHandle); CloseServiceHandle(scHandle); Result:=true; end Else Result:=False; end; function CloseDriver:boolean; begin CloseHandle(DriverHandle); Result:=DeleteDriverService; end; procedure OpenWinRing; begin OSVersion := LOBYTE(LOWORD(GetVersion)); if (OSVersion<>4) then begin if (not OpenDriver) then begin ShowMessage('Driver not ready!!!'); CloseDriver; Application.Terminate; end; end; end; procedure SaveAllReg;stdcall; Begin Asm push eax mov eax, offset Ring.RegData mov [eax][04], ebx mov [eax][08], ecx mov [eax][12], edx mov [eax][16], esi mov [eax][20], edi mov [eax][24], ebp mov ebx, eax pop eax mov [ebx], eax End; end; procedure ProcessRing0(Ring0Proc: TRing0Proc);StdCall; var retbyteWORD; Label ADJRing0,ADJRing; Begin SaveAllReg(); Asm Mov Ring.AdjRing0Entry, offset ADJRing0 End; DeviceIoControl(DriverHandle,WINRING_Access, @Ring, sizeof(Ring), @Ring, sizeof(Ring), retbyte, Nil); Asm jmp ADJRing ADJRing0: mov eax, [esp+4] End; Ring0Proc; Asm Ret ADJRing: End; end; end.
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,WinRing, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Button1: TButton; Timer1: TTimer; procedure Button1Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Timer1Timer(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; Timer:Array[0..2] Of Byte; V:Integer; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin OpenWinRing; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin CloseDriver; end; Procedure Test;StdCall; Var Val1,Index:Byte; I:Integer; Begin Asm cli End; for i:=0 to 2 Do Begin Index:=i*2; asm mov al, Index out $70, al in al, $71 mov Val1, al End; Timer:=Val1; End; Asm sti End; End; procedure TForm1.Timer1Timer(Sender: TObject); begin ProcessRing0(Test); Form1.Caption:=Format('%2x,%2x,%2x',[Timer[2],Timer[1],Timer[0]]); end; end.
重點在procedure ProcessRing0(Ring0Proc: TRing0Proc);StdCall;ui
其內部實現將一個ring3地址傳遞進ring0,也就是說pagedpool內存通過某種操做能夠直接執行的。spa