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

xiaoxiao2021-03-06  63

This code is very meaningful to the father's commemorative version, which is developed in the most painful period in my life. Oh, everything is eternal nostalgic ...

Note: Jedi Win32 API (JWA) support is required

In addition, this method is not suitable for PAE mode (WinXP SP2 is equipped with AMD64 or EMT64 processor system), and cannot support Win2003 SP1

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: 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, @Objectattribute);

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);

EXIT;

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) Thenbegin

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 Pushadretf // 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-89395.html

New Post(0)