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