mirror of
https://github.com/winterknife/EVENSTAR
synced 2026-06-21 14:13:51 +00:00
added new project to check processor's CPL
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@ VisualStudioVersion = 17.11.35312.102
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReadCRDbgExt", "ReadCRDbgExt\ReadCRDbgExt.vcxproj", "{78BD9103-3B0A-46DF-9261-148EA8F34DF0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReadMSW", "ReadMSW\ReadMSW.vcxproj", "{F9AB9899-9F93-4252-B634-740F19CCC1DC}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GetCPL", "GetCPL\GetCPL.vcxproj", "{F9AB9899-9F93-4252-B634-740F19CCC1DC}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PagingDbgExt", "PagingDbgExt\PagingDbgExt.vcxproj", "{4321EA53-183E-4104-887D-5CBFC14E4211}"
|
||||
EndProject
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{f9ab9899-9f93-4252-b634-740f19ccc1dc}</ProjectGuid>
|
||||
<RootNamespace>ReadMSW</RootNamespace>
|
||||
<RootNamespace>GetCPL</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
@@ -72,14 +72,14 @@
|
||||
<ClCompile Include="Src\ExeMain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="Src\ReadMsw64.asm">
|
||||
<MASM Include="Src\GetCurrentPrivilegeLevel64.asm">
|
||||
<FileType>Document</FileType>
|
||||
</MASM>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Inc\BaseDataTypes.h" />
|
||||
<ClInclude Include="Inc\Common.h" />
|
||||
<ClInclude Include="Inc\ReadMsw.h" />
|
||||
<ClInclude Include="Inc\GetCurrentPrivilegeLevel.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
@@ -16,7 +16,7 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="Src\ReadMsw64.asm">
|
||||
<MASM Include="Src\GetCurrentPrivilegeLevel64.asm">
|
||||
<Filter>Source Files</Filter>
|
||||
</MASM>
|
||||
</ItemGroup>
|
||||
@@ -27,7 +27,7 @@
|
||||
<ClInclude Include="Inc\Common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Inc\ReadMsw.h">
|
||||
<ClInclude Include="Inc\GetCurrentPrivilegeLevel.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
// Modifications:
|
||||
// 2021-08-21 Created
|
||||
// 2025-01-09 Updated
|
||||
// 2025-06-16 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
@@ -17,7 +17,7 @@
|
||||
#pragma once
|
||||
|
||||
// Specify program entry point
|
||||
#pragma comment(linker, "/ENTRY:ExeInit")
|
||||
#pragma comment(linker, "/ENTRY:ExeEntry")
|
||||
|
||||
// Merge sections
|
||||
#if defined (_MSC_VER)
|
||||
@@ -36,8 +36,10 @@
|
||||
// ========================================================================
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define _NO_CRT_STDIO_INLINE
|
||||
#include <Windows.h>
|
||||
#include <intrin.h>
|
||||
#include <stdio.h>
|
||||
#include "BaseDataTypes.h"
|
||||
|
||||
#pragma intrinsic(__stosb)
|
||||
@@ -52,10 +54,19 @@
|
||||
#pragma region MACROS
|
||||
|
||||
// Module name
|
||||
#define __MODULE__ "ReadMSW"
|
||||
#define __MODULE__ "GetCPL"
|
||||
|
||||
// Comment out for final build
|
||||
//#define DEBUG_BUILD
|
||||
#define DEBUG_BUILD
|
||||
|
||||
// Print debug message macro
|
||||
#ifdef DEBUG_BUILD
|
||||
#define STRIP(...) __VA_ARGS__
|
||||
#define DEBUG_PREFIX "[DBG]: "
|
||||
#define DEBUG_PRINT(_x_, ...) printf(DEBUG_PREFIX _x_, ##__VA_ARGS__);
|
||||
#else
|
||||
#define DEBUG_PRINT(_x_, ...) void(0)
|
||||
#endif
|
||||
|
||||
// Stringizing operator macro
|
||||
#ifndef _CRT_STRINGIZE
|
||||
@@ -110,12 +121,12 @@
|
||||
#define OPTIMIZATION_SPEED optimize("gt", on)
|
||||
#endif
|
||||
|
||||
// Macro to fill a block of memory with zeroes given it's address and length in bytes by generating store string instruction(rep stosb)
|
||||
// Enhanced REP STOSB/MOVSB(ERMSB) are only available since Ivy Bridge Intel microarchitecture(2012/2013)
|
||||
// Macro to fill a block of memory with zeroes given it's address and length in bytes by generating store string instruction (rep stosb)
|
||||
// Enhanced REP STOSB/MOVSB (ERMSB) are only available since Ivy Bridge Intel microarchitecture (2012/2013)
|
||||
// Processors that provide support for enhanced MOVSB/STOSB operations are enumerated by the CPUID feature flag: CPUID:(EAX=7H, ECX=0H):EBX.ERMSB[bit 9] = 1
|
||||
#define ZERO_MEMORY(Destination, Length) __stosb((PBYTE)Destination, 0, Length)
|
||||
|
||||
// Macro to copy a block of memory given it's source address, destination address and the number of bytes to copy by generating move string instruction(rep movsb)
|
||||
// Macro to copy a block of memory given it's source address, destination address and the number of bytes to copy by generating move string instruction (rep movsb)
|
||||
#define COPY_MEMORY(Destination, Source, Count) __movsb((PBYTE)Destination, (const PBYTE)Source, Count)
|
||||
|
||||
#pragma endregion
|
||||
@@ -126,11 +137,11 @@
|
||||
|
||||
#pragma region INLINES
|
||||
|
||||
// Brief: To compare two blocks of memory and return the number of bytes that match
|
||||
// Parameter1: pcSource1 = Pointer to the first block of memory
|
||||
// Parameter2: pcSource2 = Pointer to the second block of memory
|
||||
// Parameter3: dwptrLength = The number of bytes to compare
|
||||
// Return: Number of bytes in the two blocks that match, if all bytes match up to the specified Length value, the Length value is returned
|
||||
/// @brief To compare two blocks of memory and return the number of bytes that match
|
||||
/// @param pcSource1 Pointer to the first block of memory
|
||||
/// @param pcSource2 Pointer to the second block of memory
|
||||
/// @param dwptrLength The number of bytes to compare
|
||||
/// @return Number of bytes in the two blocks that match, if all bytes match up to the specified Length value, the Length value is returned
|
||||
extern "C" __forceinline DWORD_PTR __stdcall compare_memory(_In_ const PVOID pcSource1, _In_ const PVOID pcSource2, _In_ DWORD_PTR dwptrLength) {
|
||||
// Init local variables
|
||||
DWORD_PTR dwptrIndex = 0;
|
||||
@@ -1,13 +1,13 @@
|
||||
// ========================================================================
|
||||
// File: ReadMsw.h
|
||||
// File: GetCurrentPrivilegeLevel.h
|
||||
//
|
||||
// Author: winterknife
|
||||
//
|
||||
// Description: Header file for ReadMsw32/64.asm source file
|
||||
// Description: Header file for GetCurrentPrivilegeLevel32/64.asm source file
|
||||
//
|
||||
// Modifications:
|
||||
// 2025-01-09 Created
|
||||
// 2025-01-09 Updated
|
||||
// 2025-06-16 Created
|
||||
// 2025-06-16 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
@@ -28,11 +28,11 @@
|
||||
|
||||
#pragma region DECLARATIONS
|
||||
|
||||
/// @brief Check if segment-level protection is enabled
|
||||
/// @brief Check the Current Privilege Level (CPL) of the processor
|
||||
/// @param None
|
||||
/// @return Returns TRUE if protected mode is enabled or FALSE if real-address mode is enabled
|
||||
_Success_(return != 0) _Must_inspect_result_ _IRQL_requires_max_(DISPATCH_LEVEL)
|
||||
extern "C" __declspec(noinline) BOOLEAN __fastcall is_protected_mode_enabled(
|
||||
/// @return Returns TRUE if CPL < 3 (supervisor-mode) or FALSE if CPL = 3 (user-mode)
|
||||
_Success_(return != 0) _Must_inspect_result_ _IRQL_requires_max_(HIGH_LEVEL)
|
||||
extern "C" __declspec(noinline) BOOLEAN __fastcall is_supervisor_mode(
|
||||
VOID
|
||||
);
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# EVENSTAR - GetCPL
|
||||
|
||||
## Version
|
||||
- `v1.0.0`
|
||||
|
||||
## Brief
|
||||
- `ISA: x86`
|
||||
- `Mode: Real, Protected, Long`
|
||||
- `Bitness: 16-bit, 32-bit, 64-bit`
|
||||
- `CPL: 0, 3`
|
||||
- `OS: Windows`
|
||||
- `Language: C`
|
||||
- Sample code that demonstrates the usage of the `SMSW` instruction to fetch the the `Machine Status Word` (bits 0 through 15 of control register `CR0`) and check the processor's `Current Privilege Level (CPL)` if the processor is running in `Protected` mode.
|
||||
|
||||
## Usage
|
||||
- There aren't a lot of useful bits in the `MSW`
|
||||
- One notable exception: `PE (Protection Enable)` bit (0)
|
||||
- This flag enables Segmentation
|
||||
- The processor maintains an internal state called `CPL` which is defined as the privilege level of the currently executing code
|
||||
- `CPL` is used to determine whether certain operations are permitted or not
|
||||
- `CPL` is given by `CS.RPL` (bits 0 and 1)
|
||||
```shell
|
||||
C:\pub\bld\DriverRun>GetCPL.exe
|
||||
[*] GetCPL Built Jun 16 2025 18:13:39
|
||||
Press any key to continue . . .
|
||||
[DBG]: user-mode
|
||||
Press any key to continue . . .
|
||||
|
||||
[DBG]: +++ GetCPL.sys Loaded +++
|
||||
[DBG]: GetCPL.sys Built Jun 17 2025 07:12:51
|
||||
[DBG]: GetCPL: DriverObject = FFFFC486721BDAF0
|
||||
[DBG]: GetCPL: RegistryPath = \REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\GetCPL
|
||||
[DBG]: supervisor-mode
|
||||
[DBG]: --- GetCPL.sys Unloaded ---
|
||||
```
|
||||
|
||||
## Tested OS Versions
|
||||
- `Windows 11 21H2 Build 22000 Revision 675 64-bit`
|
||||
|
||||
## References
|
||||
1. [SMSW — Store Machine Status Word](https://namazso.github.io/x86/html/SMSW.html)
|
||||
2. [The Segmented Memory Model and How It Works in Windows x64](https://antonioparata.blogspot.com/2023/01/the-segment-memory-model-and-how-it.html)
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
// Modifications:
|
||||
// 2025-01-08 Created
|
||||
// 2025-01-09 Updated
|
||||
// 2025-06-16 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
@@ -15,7 +15,7 @@
|
||||
// ========================================================================
|
||||
|
||||
#include "../Inc/Common.h"
|
||||
#include "../Inc/ReadMsw.h"
|
||||
#include "../Inc/GetCurrentPrivilegeLevel.h"
|
||||
#define _NO_CRT_STDIO_INLINE
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
@@ -30,7 +30,7 @@
|
||||
/// @brief EXE entry point
|
||||
/// @param None
|
||||
/// @return None
|
||||
extern "C" __declspec(noreturn) VOID __stdcall ExeInit(
|
||||
extern "C" __declspec(noreturn) VOID __stdcall ExeEntry(
|
||||
VOID
|
||||
) {
|
||||
printf("[*] %s Built %s %s\n", __MODULE__, __DATE__, __TIME__);
|
||||
@@ -45,14 +45,16 @@ extern "C" __declspec(noreturn) VOID __stdcall ExeInit(
|
||||
__nop();
|
||||
|
||||
// Init local variables
|
||||
BOOLEAN bProtectionEnable = FALSE;
|
||||
BOOLEAN bSupervisorMode = FALSE;
|
||||
|
||||
// Check if Segmentation is enabled
|
||||
bProtectionEnable = is_protected_mode_enabled();
|
||||
if (bProtectionEnable)
|
||||
printf("Processor Execution Mode == Protected Mode\n");
|
||||
else
|
||||
printf("Processor Execution Mode == Real-Address Mode\n");
|
||||
// Check processor's CPL
|
||||
bSupervisorMode = is_supervisor_mode();
|
||||
if (bSupervisorMode) {
|
||||
DEBUG_PRINT("supervisor-mode\n");
|
||||
}
|
||||
else {
|
||||
DEBUG_PRINT("user-mode\n");
|
||||
}
|
||||
|
||||
__nop();
|
||||
__nop();
|
||||
@@ -0,0 +1,54 @@
|
||||
; ------------------------------------------------------------------------
|
||||
; File: GetCurrentPrivilegeLevel64.asm
|
||||
;
|
||||
; Author: winterknife
|
||||
;
|
||||
; Description: x64 assembly routine to read the
|
||||
; Machine Status Word (bits 0 through 15 of control register CR0) using
|
||||
; the SMSW instruction and determine the Current Privilege Level (CPL)
|
||||
; if the execution mode of the processor is protected mode
|
||||
;
|
||||
; Modifications:
|
||||
; 2025-06-16 Created
|
||||
; 2025-06-16 Updated
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
; Start of .text segment
|
||||
.CODE
|
||||
|
||||
; Align by 16 bytes
|
||||
ALIGN 16
|
||||
|
||||
; Check the Current Privilege Level (CPL) of the processor
|
||||
is_supervisor_mode PROC PUBLIC
|
||||
; Store the Machine Status Word (bits 0 through 15 of control register CR0) into AX register
|
||||
smsw ax ; AX = CR0[15:0]
|
||||
|
||||
; Check if CR0.PE flag is set
|
||||
; Protection Enable (bit 0 of CR0) enables protected mode when set and enables real-address mode when clear
|
||||
bt ax, 0h ; EFLAGS.CF = Bit(AX, 0)
|
||||
jnc cleanup ; if (EFLAGS.CF == 0) goto cleanup
|
||||
|
||||
; Store the Code Segment (CS) register value in AX
|
||||
mov ax, cs ; AX = CS
|
||||
|
||||
; Check the CPL of the processor
|
||||
; Processor maintains an internal state called Current Privilege Level (CPL) which is defined as the privilege level of the currently executing code
|
||||
; CPL is used to determine whether certain operations are permitted or not
|
||||
; CPL is given by CS.RPL (bits 0 and 1)
|
||||
; Windows OS only uses CPL0 and CPL3
|
||||
and ax, 3h ; AX = AX & 0x03
|
||||
jz supervisor ; if (EFLAGS.ZF == 1) goto supervisor
|
||||
xor ax, ax ; AX = AX ^ AX = 0
|
||||
jmp cleanup ; goto cleanup
|
||||
supervisor:
|
||||
inc ax ; AX = AX + 0x01
|
||||
|
||||
; Cleanup
|
||||
cleanup:
|
||||
; Return AX register value to the calling procedure
|
||||
ret ; IP = [SP] and SP = SP + 0x02
|
||||
is_supervisor_mode ENDP
|
||||
|
||||
; End of MASM source
|
||||
END
|
||||
@@ -1,34 +0,0 @@
|
||||
# EVENSTAR - ReadMSW
|
||||
|
||||
## Version
|
||||
- `v1.0.0`
|
||||
|
||||
## Brief
|
||||
- `ISA: x86`
|
||||
- `Mode: Real, Protected, Long`
|
||||
- `Bitness: 16-bit, 32-bit, 64-bit`
|
||||
- `CPL: 0, 3`
|
||||
- `OS: Windows`
|
||||
- `Language: C`
|
||||
- Sample code that demonstrates the usage of the `SMSW` instruction to fetch the the `Machine Status Word` (bits 0 through 15 of control register `CR0`) and check if the processor is running in `Protected` mode.
|
||||
|
||||
## Usage
|
||||
- There aren't a lot of useful bits in the `MSW`
|
||||
- One notable exception: `PE (Protection Enable)` bit (0)
|
||||
- This flag enables Segmentation
|
||||
- Under normal circumstances, the sample code will always inform that `CR0.PE` bit is set
|
||||
- Only useful for low-level code such as `OS` and `Hypervisors`
|
||||
- Another possible use might be for `VM` detection but more testing is needed
|
||||
```shell
|
||||
C:\Users\winterknife\Desktop\ACED\EVENSTAR\ReadMSW\Bin\x64>ReadMSW.exe
|
||||
[*] ReadMSW Built Jan 14 2025 14:12:25
|
||||
Press any key to continue . . .
|
||||
Processor Execution Mode == Protected Mode
|
||||
Press any key to continue . . .
|
||||
```
|
||||
|
||||
## Tested OS Versions
|
||||
- `Windows 11 24H2 Build 26100 Revision 1882 64-bit`
|
||||
|
||||
## References
|
||||
1. [SMSW—Store Machine Status Word](https://namazso.github.io/x86/html/SMSW.html)
|
||||
@@ -1,34 +0,0 @@
|
||||
; ------------------------------------------------------------------------
|
||||
; File: ReadMsw64.asm
|
||||
;
|
||||
; Author: winterknife
|
||||
;
|
||||
; Description: x64 assembly routine to read the
|
||||
; Machine Status Word (bits 0 through 15 of control register CR0) using
|
||||
; the SMSW instruction
|
||||
;
|
||||
; Modifications:
|
||||
; 2025-01-09 Created
|
||||
; 2025-01-14 Updated
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
; Start of .text segment
|
||||
.CODE
|
||||
|
||||
; Align by 16 bytes
|
||||
ALIGN 16
|
||||
|
||||
; Check if segment-level protection is enabled
|
||||
is_protected_mode_enabled PROC PUBLIC
|
||||
; Store the Machine Status Word (bits 0 through 15 of control register CR0) into AX register
|
||||
smsw ax ; AX = CR0[15:0]
|
||||
|
||||
; Get CR0.PE flag
|
||||
and ax, 0001h ; AX = AX & 0x0001
|
||||
|
||||
; Return AX register value to the calling procedure
|
||||
ret ; IP = [SP] and SP = SP + 0x08
|
||||
is_protected_mode_enabled ENDP
|
||||
|
||||
; End of MASM source
|
||||
END
|
||||
Reference in New Issue
Block a user