Use Delphi to enter RING0 without drive solution from Ring3 in 2000 and XP2003

xiaoxiao2021-03-06  48

By Lysoft Liuyang

Jedi Win32 API (JWA) library support

Uses

Windows, Dialogs, Sysutils, NTDDK,

Jwawinnt, Jwawintype, JwantStatus, Jwaaccctrl, Jwaaclapi, NTDLL

Const

KGDT_NULL = 0;

KGDT_R0_CODE = 8;

KGDT_R0_DATA = 16;

KGDT_R3_CODE = 24;

KGDT_R3_DATA = 32;

KGDT_TSS = 40;

KGDT_R0_PCR = 48;

KGDT_R3_TEB = 56;

KGDT_VDM_TILE = 64;

KGDT_LDT = 72;

KGDT_DF_TSS = 80;

KGDT_NMI_TSS = 88;

Type

TGDT = Record

Limit,

Baselow,

Basehigh: Word;

END;

Physical_address = large_integer;

Callgate_descriptor = record

OFFSET_0_15, SELector: Word;

Gatedescriptor: Word;

OFFSET_16_31: Word;

END;

IMPLEMENTATION

Function Zwopense; External 'NTDLL.DLL';

Function ZWClose; External 'NTDLL.DLL';

Function setDebugprivilege (Candebug: Boolean): Boolean

Function EnablePrivilege (HTOKEN: Cardinal; Privname: String; Benable: Boolean;

VAR

TP: windows.token_privileges;

Dummy: cardinal

Begin

Tp.privilegecount: = 1;

LookuppprivileGeValue (Nil, Pchar (Privname), TP.Privileges [0] .luid);

IF Benable Then

Tp.privileges [0] .attributes: = SE_PRIVILE_ENABED

Else Tp.Privileges [0] .attributes: = 0;

AdjustTokenprivileges (HToken, False, TP, SizeOf (TP), NIL, DUMMY

Result: = getLastError = Error_suCcess;

END;

VAR

HToken: cardinal;

Begin

OpenProcessToken (getCurrentProcess, Token_adjust_Privileges, HTOKEN);

Result: = EnablePrivilege (HTOKEN, SE_DEBUG_NAME, CANDEBUG);

CloseHandle (HTOKEN);

END;

Function setPhyscialMemorysectionCanbewrite (HSECTION: THANDLE): Boolean

Label Cleanup;

VAR

PDACL, PNEWDACL: JWAWINNT.PACL;

PSD: jwawinnt.psecurity_descriptor;

DWRES: DWORD;

EA: EXPLICIT_ACCESS; Begin

Result: = FALSE;

PDACL: = NIL; PNEWDACL: = NIL; PSD: = NIL;

DWRES: = GetSecurityInfo (HSECTION, SE_KERNEL_Object, DACL_SECURITY_INFORMATION,

NIL, NIL, @PDACL, NIL, PSD);

IF dwres <> error_success the

Begin

Messagedlg (Format ('getSecurityInfo Error% D', [dwres]), mTerror, [Mbok], 0);

Goto cleanup;

END;

ZeromeMory (@ea, sizeof (expected_access));

Ea.grfaccesspermissions: = section_map_write

Ea.grfaccessmode: = GRANT_ACCESS;

Ea.grfinheritance: = no_inheritance;

Ea.trustee.trusteeform: = trustee_is_name;

Ea.trustee.trustetype: = trustee_use_user;

Ea.trustee.ptstrname: = 'current_user';

DWRES: = STENTRIESINACL (1, @ea, pdacl, pnewdacl);

IF dwres <> error_success the

Begin

Messagedlg (Format ('STENTRIESINACL ERROR:% D', [DWRES]), MTERROR, [Mbok], 0);

Goto cleanup;

END;

DWRES: = setsecurityInfo (HSECTION, SE_kernel_Object,

DACL_SECURITY_INFORMATION, NIL, NIL, PNEWDACL, NIL;

IF dwres <> error_success the

Begin

Messagedlg (Format ('setsecurityInfo error:% d', [dwres]), mTerror, [Mbok], 0);

Goto cleanup;

END;

RESULT: = TRUE

Cleanup:

IF PSD <> NIL THEN LOCALFREE (Cardinal (PSD));

IF pnewdacl <> nil damalfree (Cardinal (PNewDACL);

END;

Function openphysicalmemory: thandle;

VAR

HSECTION: THANDLE;

Status: NTSTATUS;

Objname: unicode_string;

Objectttributes: object_attributes;

Begin

Result: = 0;

RTLinitunicodeString (@objname, '/ device / physicalmemory');

InitializeObjectAttributes (@Objectattributes, @objname,

Obj_case_insensitive or obj_kernel_handle, 0, nil);

Status: = zwopensection (hsection, section_map_read or section_map_write, @Objectattributes); if (status = status_access_denied) THEN

Begin

Status: = zwopensection (HSECTION, RONCONTROL or WRITE_DAC, @Objecttributes);

If status = status_success the setphyscialMemorysectioncanbewrite;

ZWClose (HSECTION);

Status: = zwopensection (HSECTION, section_map_read or section_map_write, @Objectattribute);

END;

IF status = status_success the result: = HSECTION;

END;

Procedure ClosephysicalMemory (HPHYSICALMORYSECTION: THANDLE);

Begin

ZWClose (hphysicalmemorysection);

END;

Function Addressin4Mbpage (Address: Ulong): Boolean;

Begin

Result: = (Address> 0) and ($ 80000000 <= address) and (address <$ A0000000)

END;

Function MinimmgetPhysicalAddress (Vaddress: Ulong): Ulong;

Begin

IF addressin4mbpage (VADDRESS)

Then Result: = VADDRESS - $ 80000000

Else Result: = $ fffffff;

END;

Function MinimmgetPhysicalPageAddress (VirtualAddress: Ulong): Ulong;

Begin

IF addressin4mbpage (VirtualAddress)

Then Result: = VirtualAddress and $ 1FFF000

Else Result: = $ fffffff;

END;

Function Execring0Proc (ProcentryPoint: Pointer; SegmentLength: Ulong): Boolean;

VAR

GDT: TGDT; MapAddr: Ulong;

HSECTION: THANDLE;

CG: ^ Callgate_Descriptor;

Farcall: Array [0..2] of Word;

BaseAddress: Pointer;

Setcg: boolean;

i: cardinal

Begin

Result: = FALSE;

ASM SGDT GDT END;

i: = (gdt.basehigh shl 16) or gdt.blelow;

MapAddr: = minimmgetphysicalPageAddress (i);

IF mapAddr = $ fffffffff

Begin

Messagedlg (Format ('Can Not Convert GDT Virtual Address of [Base =% s Limit =% s]',

[INTTOHEX (I, 8), INTTOHEX (GDT.LIMIT, 4)]), MTERROR, [MBOK], 0);

END;

HSECTION: = OpenPhysicalMemory;

IF hsection = 0 THEN

Begin

Messagedlg ('Error In Open Physical Memory.', MTerror, [Mbok], 0);

EXIT;

END;

BaseEaddress: = MapViewoffile (HSECTION, FILE_MAP_READ OR File_MAP_WRITE, 0, MAPADDR, / / ​​LOW PART

(GDT.LIMIT 1));

If BaseAddress = nil dam

Begin

ZWClose (HSECTION);

Messagedlg (Format ('MapViewOffile Error:% SGDT: address =% s limit =% s ",

[SySerrorMessage (GetLastError), # 13 # 10, INTTOHEX (MapAddr, 8), INTTOHEX (GDT.LIMIT, 4)]), mTerror, [Mbok], 0);

EXIT;

END;

setcg: = false;

I: = cardinal (baseaddress) 8; // Skip first EMPTY ENTRY

While I

Begin

CG: = PTR (i);

With cg ^ do

Begin

IF INTTOHEX (GateDescriptor, 4) [2] = '0' TEN // Call Gate Not Present

Begin // Install Callgate

OFFSET_0_15: = LOWORD (Integer (Integer ");

Selector: = KGDT_R0_CODE; // Ring 0 CODE

// [Installed Flag = 1] [Ring 3 Code Can Call = 11] 0 [386 Call Gate = 1100] 00000000

GateDescriptor: = $ EC00;

OFFSET_16_31: = HiWord (Integer (ProcentryPoint);

setcg: = true;

Break;

END;

END;

INC (i, 8);

END;

IF not setcg then

Begin

UnmapViewoffile (BaseEaddress);

ZWClose (HSECTION);

Messagedlg ('Can Not Install Callgate in Your System GDT', MTERROR, [Mbok], 0);

EXIT;

END;

Farcall [0]: = 0; Farcall [1]: = 0;

Farcall [2]: = (Short (Ulong (cg) -ulong (baseaddress))) or 3; // Ring 3 CallGate;

IF Not Virtuallock (ProcentryPoint, SegmentLength) THEN

Begin

Messagedlg (SySerrorMessage (GetLastError), mTerror, [Mbok], 0);

EXIT;

END;

Try

SetthreadPriority (getcurrentthread, thread_priority_time_critical); Sleep (0);

ASM // Call Callgate

// push arg1 ... argn // call far fword ptr [farcall]

Lea Eax, Farcall // loading to EAX

DB 0FFH, 018H // Hardware Code, Means Call fword PTR [EAX]

END;

SetthreadPriority (getcurrentthread, thread_priority_normal);

RESULT: = TRUE;

Except

ON E: Exception Do Messagedlg (E.MESSAGE, MTERROR, [Mbok], 0);

END;

VirtualUnlock (ProcentryPoint, SegmentLength);

// Clear Callgate

Fillchar (cg ^, 8, 0);

UnmapViewoffile (BaseEaddress);

Closephysicalmemory (HSECTION);

END;

Use an example to read the CMOS clock:

Unit ntring0_unit;

Interface

Uses

Windows, Messages, Sysutils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, stdctrls, buttons;

Type

TFORM1 = Class (TFORM)

Bitbtn1: tbitbtn;

Procedure Bitbtn1click (Sender: TOBJECT);

Private

{Private Declarations}

public

{Public declarations}

END;

VAR

FORM1: TFORM1;

THOUR, TMIN, TSEC: BYTE

IMPLEMENTATION

{$ R * .dfm}

Uses ntring0;

PROCEDURE RING0PROC; stdcall;

Begin

ASM // Ring0 ProLog

Pushad // Push EAX, ECX, EPX, EBX, EBP, ESP, ESI, EDI ONTO THE Stack

Pushfd // Decrement Stack Pointer by 4 and Push Eflags Onto The Stack

CLI // Disable Interrupt

// Execute Your Ring0 Code Here ...

MOV AH, 0

MOV DX, $ 70

MOV

Al

AH

OUT

DX

,

Al

INC DX

IN Al, DX

Mov TSEC,

Al

//

MOV AH, 2

MOV DX, $ 70

MOV

Al

AH

OUT

DX

,

Al

INC DX

IN Al, DX

MOV TMIN,

Al

//

MOV AH, 4

MOV DX, $ 70

MOV

Al

AH

OUT

DX

,

Al

INC DX

IN Al, DX

Mov thor,

Al

// Ring0 Epilog

POPFD // Restore Registers Pushed by Pushfd

POPAD // Restore Registers Pushed by Pushhad

RETF // You May Retf if You Pass Arguments

END;

END;

Procedure TFORM1.BITBTN1CLICK (Sender: TOBJECT); Begin

// Execute Ring 0

If Execring0Proc (@ ring0proc, 100) THEN

ShowMessage (Format ('CMOS TIME IS% D:% D:% D',

[10 * (THOUR SHR 4) THOUR AND $ F,

10 * (Tmin SHR 4) TMIN AND $ F,

10 * (Tsec SHR 4) TSEC and $ f])));

END;

. End the call NTOSKrnl.exe Ring0 function implementation VA-> PA (virtual addresses into physical addresses) conversion type TMemoryAddress = record PhysicalAddress: PHYSICAL_ADDRESS; // * 000 VirtualAddress: DWord; // * 008 end; var MemoryAddress: TMemoryAddress ; _MMGETPHYSICALALADDRESS: cardinal

NtosbaseAddr: cardinal; // Ntoskern.exe load address, 2003 system default is $ 804DE000

Procedure Ring0Func; Stdcall; 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;

转载请注明原文地址:https://www.9cbs.com/read-80377.html

New Post(0)