 |
|
 |
Great article. Please keep it up!
|
|
|
|
 |
|
 |
Hi,
Perfect for those working with WMI. However that is quite a bit of code to check for a simple bit. It could also be accomplished with the cpuid instruction in a much smaller function.
BOOL HaveHardwareDEP()
{
BOOL bHaveNX = FALSE;
__asm
{
mov eax,0x80000000
cpuid
cmp eax,0x80000001
jb no_features
mov eax,0x80000001
cpuid
and edx, 0x00100000
mov bHaveNX,edx
no_features:
}
return bHaveNX;
}
There is probably someone reading this post with their hand hovering over the reply button. They are probably wanting to reply with something like: 'Yeah, but you cannot use inline assembly with the Microsoft 64 bit compiler' and of course they would be correct. Rather than poison your source code with inline assembler you could use the Compiler Intrinsics[^] for your MMX,SSE or cpuid optimization. A translation of the function above would be something like:
BOOL HaveHardwareDEP()
{
BOOL bHaveNX = FALSE;
int cpuid[4] = {-1};
__cpuid(cpuid, 0x80000000);
if(0x80000001 < cpuid[0])
{
bHaveNX = (cpuid[3] & 0x00100000);
}
return bHaveNX;
}
So rather than adding 120KB to the executable size and a plethora of WMI dependencies... a small < 32 byte function might be preferable for some software engineers when checking for the NX bit.
Best Wishes,
-David Delaune
|
|
|
|
 |
|
 |
great!
My code has an advantage,if you change parameter of Get(L"DataExecutionPrevention_Available", 0, &vtProp, 0, 0) you can get more information. These parameters maybe:
class Win32_OperatingSystem : CIM_OperatingSystem
{
string BootDevice;
string BuildNumber;
string BuildType;
string Caption;
string CodeSet;
string CountryCode;
string CreationClassName;
string CSCreationClassName;
string CSDVersion;
string CSName;
sint16 CurrentTimeZone;
boolean DataExecutionPrevention_Available;
boolean DataExecutionPrevention_32BitApplications;
boolean DataExecutionPrevention_Drivers;
uint8 DataExecutionPrevention_SupportPolicy;
boolean Debug;
string Description;
boolean Distributed;
uint32 EncryptionLevel;
uint8 ForegroundApplicationBoost;
uint64 FreePhysicalMemory;
uint64 FreeSpaceInPagingFiles;
uint64 FreeVirtualMemory;
datetime InstallDate;
uint32 LargeSystemCache;
datetime LastBootUpTime;
datetime LocalDateTime;
string Locale;
string Manufacturer;
uint32 MaxNumberOfProcesses;
uint64 MaxProcessMemorySize;
string MUILanguages[];
string Name;
uint32 NumberOfLicensedUsers;
uint32 NumberOfProcesses;
uint32 NumberOfUsers;
uint32 OperatingSystemSKU;
string Organization;
string OSArchitecture;
uint32 OSLanguage;
uint32 OSProductSuite;
uint16 OSType;
string OtherTypeDescription;
Boolean PAEEnabled;
string PlusProductID;
string PlusVersionNumber;
boolean Primary;
uint32 ProductType;
string RegisteredUser;
string SerialNumber;
uint16 ServicePackMajorVersion;
uint16 ServicePackMinorVersion;
uint64 SizeStoredInPagingFiles;
string Status;
uint32 SuiteMask;
string SystemDevice;
string SystemDirectory;
string SystemDrive;
uint64 TotalSwapSpaceSize;
uint64 TotalVirtualMemorySize;
uint64 TotalVisibleMemorySize;
string Version;
string WindowsDirectory;
};
For example DataExecutionPrevention_SupportPolicy which will be mentioned in another article.
Thanks,your idea is very great!
|
|
|
|
 |
|
 |
Hi Jim Charles, (is that a pseudonym..?)
I am not a huge fan of WMI at all. I do not see anything within that struct that cannot be obtained via a registry key or other means. However I would say that one advantage of using WMI is so that you have a completely supported interface for obtaining those values. In other words... if Microsoft moves or changes the registry, file or memory containing the value... it would not break any code using the WMI interface... however would break direct registry, file or memory queries.
Jim Charles wrote: For example DataExecutionPrevention_SupportPolicy which will be mentioned in another article.
You can get this via the GetSystemDEPPolicy function[^]. If you are in an environment where the DEP policy is 'Opt out' you could check individual processes using the GetProcessDEPPolicy function[^].
Best Wishes,
-David Delaune
|
|
|
|
 |
|
 |
You're so smart!
By the way,I have a question to ask you.
Do you still have the idea of getting BcdOSLoaderBoolean_KernelDebuggerEnabled value of BcdOSLoaderElementTypes. Thanks first !
typedef enum BcdOSLoaderElementTypes {
BcdOSLoaderDevice_OSDevice = 0x21000001,
BcdOSLoaderString_SystemRoot = 0x22000002,
BcdOSLoaderObject_AssociatedResumeObject = 0x23000003,
BcdOSLoaderBoolean_DetectKernelAndHal = 0x26000010,
BcdOSLoaderString_KernelPath = 0x22000011,
BcdOSLoaderString_HalPath = 0x22000012,
BcdOSLoaderString_DbgTransportPath = 0x22000013,
BcdOSLoaderInteger_NxPolicy = 0x25000020,
BcdOSLoaderInteger_PAEPolicy = 0x25000021,
BcdOSLoaderBoolean_WinPEMode = 0x26000022,
BcdOSLoaderBoolean_DisableCrashAutoReboot = 0x26000024,
BcdOSLoaderBoolean_UseLastGoodSettings = 0x26000025,
BcdOSLoaderBoolean_AllowPrereleaseSignatures = 0x26000027,
BcdOSLoaderBoolean_NoLowMemory = 0x26000030,
BcdOSLoaderInteger_RemoveMemory = 0x25000031,
BcdOSLoaderInteger_IncreaseUserVa = 0x25000032,
BcdOSLoaderBoolean_UseVgaDriver = 0x26000040,
BcdOSLoaderBoolean_DisableBootDisplay = 0x26000041,
BcdOSLoaderBoolean_DisableVesaBios = 0x26000042,
BcdOSLoaderInteger_ClusterModeAddressing = 0x25000050,
BcdOSLoaderBoolean_UsePhysicalDestination = 0x26000051,
BcdOSLoaderInteger_RestrictApicCluster = 0x25000052,
BcdOSLoaderBoolean_UseBootProcessorOnly = 0x26000060,
BcdOSLoaderInteger_NumberOfProcessors = 0x25000061,
BcdOSLoaderBoolean_ForceMaximumProcessors = 0x26000062,
BcdOSLoaderBoolean_ProcessorConfigurationFlags = 0x25000063,
BcdOSLoaderInteger_UseFirmwarePciSettings = 0x26000070,
BcdOSLoaderInteger_MsiPolicy = 0x26000071,
BcdOSLoaderInteger_SafeBoot = 0x25000080,
BcdOSLoaderBoolean_SafeBootAlternateShell = 0x26000081,
BcdOSLoaderBoolean_BootLogInitialization = 0x26000090,
BcdOSLoaderBoolean_VerboseObjectLoadMode = 0x26000091,
BcdOSLoaderBoolean_KernelDebuggerEnabled = 0x260000a0,
BcdOSLoaderBoolean_DebuggerHalBreakpoint = 0x260000a1,
BcdOSLoaderBoolean_EmsEnabled = 0x260000b0,
BcdOSLoaderInteger_DriverLoadFailurePolicy = 0x250000c1,
BcdOSLoaderInteger_BootStatusPolicy = 0x250000E0
} BcdOSLoaderElementTypes;
|
|
|
|
 |
|
 |
Jim Charles wrote: You're so smart!
Not really, I have simply been anonymously studying Zui Quan Kung-Fu longer than the younger software engineering generation. Plus... I stayed at a Holiday Inn last night.
Jim Charles wrote: Do you still have the idea of getting BcdOSLoaderBoolean_KernelDebuggerEnabled value of BcdOSLoaderElementTypes. Thanks first !
Yes, but it is a little advanced... I spent quite a bit of time reverse engineering the pseudo-documented BCD store. Btw... you can also get the DEP status from the BCD store on OS >= Vista.
Here are the steps required:
[A] First thing you will need is the disk signature at the end of the MBR from the drive where the OS booted. You can obtain it by doing something like the following:
1.) Collect all of the mounted DosDevices at HKLM\\SYSTEM\\MountedDevices and store them into a std::vector or container of your choice;
2.) Call GetSystemDirectory and compare the drive letter to the info in your std::vector and find the system drive.
3.) The bytes you see in the HKLM\SYSTEM\MountedDevices registry key... at subkey 'Data' contain the disk signature from the master boot record at sizeof(int);
[B] Now you will need to locate the GUID from the BCD store using the disk signature from the master boot record that you just obtained.
1.) Open the HKLM\\BCD00000000\\Objects registry key and loop through the GUID keys... you are looking for \\Description\\Type value of 0x10200003 (OS Loader)
2.) When you find a "Type" value of 0x10200003 then you need to read the value of \\Elements\\21000001 and compare the bytes at offset 56 sizeof(int) to the disk signature you obtained in the previous step.
3.) When you find a match... then you have found the key containing the OS loader for the current OS. Save the GUID part of the registry key.
[C] Now we have all of the information we need to read DEP status and 'kernel debugger enabled'
1.) Open HKLM\\BCD00000000\\Objects\\[GUID]\\Elements\\25000020 and read this value. This is the current DEP status.
2.) Open HKLM\\BCD00000000\\Objects\\[GUID]\\Elements\\260000a0 and read this value. This is the kernel debugger status. (key does not exist == no debugger)
Btw... that is quite a bit of work for simply checking for a kernel debugger. You would be better off calling the CheckRemoteDebuggerPresent function[^].
Or if your a really paranoid type of guy who believes that perhaps the function has been hooked... you could call NtQuerySystemInformation function[^] with the SystemKernelDebuggerInformation index at 0x23. Or from kernelmode you can call KdDebuggerEnabled.
Best Wishes,
-David Delaune
|
|
|
|
 |
|
 |
Very Great!
My purpose is to disable PatchGuard.I need a STABLE and EASY manner.Now,I use following commands.
Bcdedit /debug ON
Bcdedit /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200 /start AUTOENABLE /noumex
But there are still some problems.Here is my code.
#define ADL_WIN64
if (Is64BitOS())
{
#ifdef ADL_WIN64
bool KernelDebuggerEnabled = detect_KernelDebugger_status();
int DataExecutionPrevention_SupportPolicy = get_DataExecutionPrevention_SupportPolicy();
if(DataExecutionPrevention_SupportPolicy==3||DataExecutionPrevention_SupportPolicy==1 || !KernelDebuggerEnabled)
{
MessageBeep (MB_ICONEXCLAMATION);
if (AskWarnYesNo () == IDYES)
{
if(DataExecutionPrevention_SupportPolicy==3||DataExecutionPrevention_SupportPolicy==1)
{
ShellExecute(NULL,"runas","bcdedit.exe"," /set {current} nx OptIn","",SW_HIDE);
}
if(!KernelDebuggerEnabled)
{
ShellExecute(NULL,"runas","bcdedit.exe"," /debug ON","",SW_HIDE);
ShellExecute(NULL,"runas","bcdedit.exe"," /dbgsettings SERIAL DEBUGPORT:1 BAUDRATE:115200 /start AUTOENABLE /noumex","",SW_HIDE);
ShellExecute(NULL,"runas","bcdedit.exe"," /timeout 5","",SW_HIDE);
}
RestartComputer();
ExitProcess(0);
}
else
{
ExitProcess(0);
}
}
else
{
ShellExecute(NULL,"open","ADL_Register.EXE","","",SW_SHOW); ExitProcess(0);
}
#else
MessageBoxW(NULL, L"This program can't run in 64-bit Operating System.",L"Run failed.",MB_OK|MB_ICONWARNING);
ExitProcess(0);
#endif
}
else
{
#ifdef ADL_WIN64
MessageBoxW(NULL, L"This program can't run in 32-bit Operating System.",L"Run failed.",MB_OK|MB_ICONWARNING);
ExitProcess(0);
#else
ShellExecute(NULL,"open","ADL_Register.EXE","","",SW_SHOW); ExitProcess(0);
#endif
}
ExitProcess(0);
return TRUE; }
The problem is Why can't we invoke "C:\Windows\System32\bcdedit.exe" directly? Is there a better way?
In addition,about disable PatchGuard. Do you have a better way to disable PatchGuard ?STABLE and EASY.
Thanks.
|
|
|
|
 |
|