Last active
September 9, 2022 20:48
-
-
Save Wack0/d657e5ca7296243c3af7576fe4f1a422 to your computer and use it in GitHub Desktop.
Secure Boot Policy parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using LipingShare.LCLib.Asn1Processor; | |
using System.Runtime.InteropServices; | |
using System.Collections.Generic; | |
using System.Text; | |
using System.Security.Cryptography; | |
namespace SbpParse { | |
enum BcdElementTypes : uint | |
{ | |
BcdLibraryDevice_ApplicationDevice = 0x11000001, | |
BcdLibraryString_ApplicationPath = 0x12000002, | |
BcdLibraryString_Description = 0x12000004, | |
BcdLibraryString_PreferredLocale = 0x12000005, | |
BcdLibraryObjectList_InheritedObjects = 0x14000006, | |
BcdLibraryInteger_TruncatePhysicalMemory = 0x15000007, | |
BcdLibraryObjectList_RecoverySequence = 0x14000008, | |
BcdLibraryBoolean_AutoRecoveryEnabled = 0x16000009, | |
BcdLibraryIntegerList_BadMemoryList = 0x1700000a, | |
BcdLibraryBoolean_AllowBadMemoryAccess = 0x1600000b, | |
BcdLibraryInteger_FirstMegabytePolicy = 0x1500000c, | |
BcdLibraryInteger_RelocatePhysicalMemory = 0x1500000D, | |
BcdLibraryInteger_AvoidLowPhysicalMemory = 0x1500000E, | |
BcdLibraryBoolean_DebuggerEnabled = 0x16000010, | |
BcdLibraryInteger_DebuggerType = 0x15000011, | |
BcdLibraryInteger_SerialDebuggerPortAddress = 0x15000012, | |
BcdLibraryInteger_SerialDebuggerPort = 0x15000013, | |
BcdLibraryInteger_SerialDebuggerBaudRate = 0x15000014, | |
BcdLibraryInteger_1394DebuggerChannel = 0x15000015, | |
BcdLibraryString_UsbDebuggerTargetName = 0x12000016, | |
BcdLibraryBoolean_DebuggerIgnoreUsermodeExceptions = 0x16000017, | |
BcdLibraryInteger_DebuggerStartPolicy = 0x15000018, | |
BcdLibraryString_DebuggerBusParameters = 0x12000019, | |
BcdLibraryInteger_DebuggerNetHostIP = 0x1500001A, | |
BcdLibraryInteger_DebuggerNetPort = 0x1500001B, | |
BcdLibraryBoolean_DebuggerNetDhcp = 0x1600001C, | |
BcdLibraryString_DebuggerNetKey = 0x1200001D, | |
BcdLibraryBoolean_EmsEnabled = 0x16000020, | |
BcdLibraryInteger_EmsPort = 0x15000022, | |
BcdLibraryInteger_EmsBaudRate = 0x15000023, | |
BcdLibraryString_LoadOptionsString = 0x12000030, | |
BcdLibraryBoolean_DisplayAdvancedOptions = 0x16000040, | |
BcdLibraryBoolean_DisplayOptionsEdit = 0x16000041, | |
BcdLibraryDevice_BsdLogDevice = 0x11000043, | |
BcdLibraryString_BsdLogPath = 0x12000044, | |
BcdLibraryBoolean_GraphicsModeDisabled = 0x16000046, | |
BcdLibraryInteger_ConfigAccessPolicy = 0x15000047, | |
BcdLibraryBoolean_DisableIntegrityChecks = 0x16000048, | |
BcdLibraryBoolean_AllowPrereleaseSignatures = 0x16000049, | |
BcdLibraryString_FontPath = 0x1200004A, | |
BcdLibraryInteger_SiPolicy = 0x1500004B, | |
BcdLibraryInteger_FveBandId = 0x1500004C, | |
BcdLibraryBoolean_ConsoleExtendedInput = 0x16000050, | |
BcdLibraryInteger_GraphicsResolution = 0x15000052, | |
BcdLibraryBoolean_RestartOnFailure = 0x16000053, | |
BcdLibraryBoolean_GraphicsForceHighestMode = 0x16000054, | |
BcdLibraryBoolean_IsolatedExecutionContext = 0x16000060, | |
BcdLibraryBoolean_BootUxDisable = 0x1600006C, | |
BcdLibraryBoolean_BootShutdownDisabled = 0x16000074, | |
BcdLibraryIntegerList_AllowedInMemorySettings = 0x17000077, | |
BcdLibraryBoolean_ForceFipsCrypto = 0x16000079, | |
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, | |
BcdOSLoaderBoolean_DisableVgaMode = 0x26000043, | |
BcdOSLoaderInteger_ClusterModeAddressing = 0x25000050, | |
BcdOSLoaderBoolean_UsePhysicalDestination = 0x26000051, | |
BcdOSLoaderInteger_RestrictApicCluster = 0x25000052, | |
BcdOSLoaderBoolean_UseLegacyApicMode = 0x26000054, | |
BcdOSLoaderInteger_X2ApicPolicy = 0x25000055, | |
BcdOSLoaderBoolean_UseBootProcessorOnly = 0x26000060, | |
BcdOSLoaderInteger_NumberOfProcessors = 0x25000061, | |
BcdOSLoaderBoolean_ForceMaximumProcessors = 0x26000062, | |
BcdOSLoaderBoolean_ProcessorConfigurationFlags = 0x25000063, | |
BcdOSLoaderBoolean_MaximizeGroupsCreated = 0x26000064, | |
BcdOSLoaderBoolean_ForceGroupAwareness = 0x26000065, | |
BcdOSLoaderInteger_GroupSize = 0x25000066, | |
BcdOSLoaderInteger_UseFirmwarePciSettings = 0x26000070, | |
BcdOSLoaderInteger_MsiPolicy = 0x25000071, | |
BcdOSLoaderInteger_SafeBoot = 0x25000080, | |
BcdOSLoaderBoolean_SafeBootAlternateShell = 0x26000081, | |
BcdOSLoaderBoolean_BootLogInitialization = 0x26000090, | |
BcdOSLoaderBoolean_VerboseObjectLoadMode = 0x26000091, | |
BcdOSLoaderBoolean_KernelDebuggerEnabled = 0x260000a0, | |
BcdOSLoaderBoolean_DebuggerHalBreakpoint = 0x260000a1, | |
BcdOSLoaderBoolean_UsePlatformClock = 0x260000A2, | |
BcdOSLoaderBoolean_ForceLegacyPlatform = 0x260000A3, | |
BcdOSLoaderInteger_TscSyncPolicy = 0x250000A6, | |
BcdOSLoaderBoolean_EmsEnabled = 0x260000b0, | |
BcdOSLoaderInteger_DriverLoadFailurePolicy = 0x250000c1, | |
BcdOSLoaderInteger_BootMenuPolicy = 0x250000C2, | |
BcdOSLoaderBoolean_AdvancedOptionsOneTime = 0x260000C3, | |
BcdOSLoaderInteger_BootStatusPolicy = 0x250000E0, | |
BcdOSLoaderBoolean_DisableElamDrivers = 0x260000E1, | |
BcdOSLoaderInteger_HypervisorLaunchType = 0x250000F0, | |
BcdOSLoaderBoolean_HypervisorDebuggerEnabled = 0x260000F2, | |
BcdOSLoaderInteger_HypervisorDebuggerType = 0x250000F3, | |
BcdOSLoaderInteger_HypervisorDebuggerPortNumber = 0x250000F4, | |
BcdOSLoaderInteger_HypervisorDebuggerBaudrate = 0x250000F5, | |
BcdOSLoaderInteger_HypervisorDebugger1394Channel = 0x250000F6, | |
BcdOSLoaderInteger_BootUxPolicy = 0x250000F7, | |
BcdOSLoaderString_HypervisorDebuggerBusParams = 0x220000F9, | |
BcdOSLoaderInteger_HypervisorNumProc = 0x250000FA, | |
BcdOSLoaderInteger_HypervisorRootProcPerNode = 0x250000FB, | |
BcdOSLoaderBoolean_HypervisorUseLargeVTlb = 0x260000FC, | |
BcdOSLoaderInteger_HypervisorDebuggerNetHostIp = 0x250000FD, | |
BcdOSLoaderInteger_HypervisorDebuggerNetHostPort = 0x250000FE, | |
BcdOSLoaderInteger_TpmBootEntropyPolicy = 0x25000100, | |
BcdOSLoaderString_HypervisorDebuggerNetKey = 0x22000110, | |
BcdOSLoaderBoolean_HypervisorDebuggerNetDhcp = 0x26000114, | |
BcdOSLoaderInteger_HypervisorIommuPolicy = 0x25000115, | |
BcdOSLoaderInteger_XSaveDisable = 0x2500012b, | |
BcdBootMgrObjectList_DisplayOrder = 0x24000001, | |
BcdBootMgrObjectList_BootSequence = 0x24000002, | |
BcdBootMgrObject_DefaultObject = 0x23000003, | |
BcdBootMgrInteger_Timeout = 0x25000004, | |
BcdBootMgrBoolean_AttemptResume = 0x26000005, | |
BcdBootMgrObject_ResumeObject = 0x23000006, | |
BcdBootMgrObjectList_ToolsDisplayOrder = 0x24000010, | |
BcdBootMgrBoolean_DisplayBootMenu = 0x26000020, | |
BcdBootMgrBoolean_NoErrorDisplay = 0x26000021, | |
BcdBootMgrDevice_BcdDevice = 0x21000022, | |
BcdBootMgrString_BcdFilePath = 0x22000023, | |
BcdBootMgrBoolean_ProcessCustomActionsFirst = 0x26000028, | |
BcdBootMgrIntegerList_CustomActionsList = 0x27000030, | |
BcdBootMgrBoolean_PersistBootSequence = 0x26000031 | |
} | |
struct ValueRange32 { | |
public uint Default; | |
public uint Start, End; | |
public ValueRange32(byte[] BinaryData) { | |
Default = BitConverter.ToUInt32(BinaryData, 2); | |
Start = BitConverter.ToUInt32(BinaryData, 6); | |
End = BitConverter.ToUInt32(BinaryData, 10); | |
} | |
} | |
struct ValueChoice32 { | |
public uint Default; | |
public uint[] Choices; | |
public ValueChoice32(byte[] BinaryData) { | |
Default = BitConverter.ToUInt32(BinaryData, 2); | |
var count = BitConverter.ToUInt16(BinaryData,6); | |
Choices = new uint[count]; | |
for (int i = 0; i < count; i++) Choices[i] = BitConverter.ToUInt32(BinaryData,8 + (i * sizeof(uint))); | |
} | |
} | |
struct ValueRange64 { | |
public ulong Default; | |
public ulong Start, End; | |
public ValueRange64(byte[] BinaryData) { | |
Default = BitConverter.ToUInt64(BinaryData, 2); | |
Start = BitConverter.ToUInt64(BinaryData, 10); | |
End = BitConverter.ToUInt64(BinaryData, 18); | |
} | |
} | |
struct ValueChoice64 { | |
public ulong Default; | |
public ulong[] Choices; | |
public ValueChoice64(byte[] BinaryData) { | |
Default = BitConverter.ToUInt64(BinaryData, 2); | |
var count = BitConverter.ToUInt16(BinaryData,10); | |
Choices = new ulong[count]; | |
for (int i = 0; i < count; i++) Choices[i] = BitConverter.ToUInt64(BinaryData,12 + (i * sizeof(ulong))); | |
} | |
} | |
class PolicyValue { | |
private int Type; | |
private bool BitLocker; | |
private bool VBS; | |
public object data; | |
public PolicyValue(byte[] BinaryData) { | |
Type = BinaryData[0] & 0x1f; | |
BitLocker = (BinaryData[0] & 0x20) != 0; | |
VBS = (BinaryData[0] & 0x40) != 0; | |
byte[] RawData; | |
switch (Type) { | |
case 0: // string | |
RawData = new byte[BitConverter.ToUInt16(BinaryData,2)]; | |
Buffer.BlockCopy(BinaryData,4,RawData,0,RawData.Length); | |
data = Encoding.Unicode.GetString(RawData); | |
break; | |
case 1: // bool | |
ushort bval = BitConverter.ToUInt16(BinaryData,2); | |
bool val = (bval != 0); | |
data = val; | |
break; | |
case 2: // dword | |
data = BitConverter.ToUInt32(BinaryData,2); | |
break; | |
case 3: // dword range | |
data = new ValueRange32(BinaryData); | |
break; | |
case 4: // dword choice | |
data = new ValueChoice32(BinaryData); | |
break; | |
case 5: // qword | |
data = BitConverter.ToUInt64(BinaryData,2); | |
break; | |
case 6: // qword range | |
data = new ValueRange64(BinaryData); | |
break; | |
case 7: // qword choice | |
data = new ValueChoice64(BinaryData); | |
break; | |
case 8: // option | |
data = BitConverter.ToUInt16(BinaryData,2); | |
break; | |
case 10: // binary | |
RawData = new byte[BitConverter.ToUInt16(BinaryData,2)]; | |
Buffer.BlockCopy(BinaryData,4,RawData,0,RawData.Length); | |
data = RawData; | |
break; | |
default: | |
throw new Exception("Unknown type "+Type); | |
} | |
} | |
public override string ToString() { | |
StringBuilder sb; | |
bool first = true; | |
string ret = ""; | |
if (BitLocker) ret = "if BitLocker - "; | |
if (VBS) ret += "if VBS - "; | |
switch (Type) { | |
case 0: | |
return ret+"string - "+(string)data; | |
case 1: | |
return ret+"bool - "+( (bool)data ).ToString(); | |
case 2: | |
return ret+"dword - 0x"+( (uint)data ).ToString("X"); | |
case 3: | |
var r32 = (ValueRange32)data; | |
return ret+"range32: 0x"+r32.Start.ToString("X")+"-"+r32.End.ToString("X")+" ("+r32.Default.ToString("X")+")"; | |
case 4: | |
var v32 = (ValueChoice32)data; | |
sb = new StringBuilder("choice32 - "); | |
foreach (var choice in v32.Choices) { | |
if (!first) sb.Append(';'); | |
else first = false; | |
sb.Append("0x"); | |
sb.Append(choice.ToString("X")); | |
} | |
sb.Append(" (0x"); | |
sb.Append(v32.Default.ToString("X")); | |
sb.Append(')'); | |
return ret+sb.ToString(); | |
case 5: | |
return ret+"qword - 0x"+( (ulong)data ).ToString("X"); | |
case 6: | |
var r64 = (ValueRange64)data; | |
return ret+"range64: 0x"+r64.Start.ToString("X")+"-"+r64.End.ToString("X")+" ("+r64.Default.ToString("X")+")"; | |
case 7: | |
var v64 = (ValueChoice64)data; | |
sb = new StringBuilder("choice64 - "); | |
foreach (var choice in v64.Choices) { | |
if (!first) sb.Append(';'); | |
else first = false; | |
sb.Append("0x"); | |
sb.Append(choice.ToString("X")); | |
} | |
sb.Append(" (0x"); | |
sb.Append(v64.Default.ToString("X")); | |
sb.Append(')'); | |
return ret+sb.ToString(); | |
case 8: | |
bool present = (ushort)data != 0; | |
return ret+"option - " + (present ? "no operation" : "always not found"); | |
case 10: | |
return ret+"byte[] - "+BitConverter.ToString( (byte[])data ).Replace("-",""); | |
default: | |
throw new Exception("Unknown type "+Type); | |
} | |
} | |
} | |
class SecureBootPolicy { | |
[StructLayout(LayoutKind.Sequential, Pack = 1)] | |
struct SBPHeader { | |
public ushort FormatVersion; | |
public uint PolicyVersion; | |
public Guid PolicyPublisher; | |
public ushort CanUpdateCount; | |
} | |
[StructLayout(LayoutKind.Sequential, Pack = 1)] | |
struct SBPFlags { | |
public uint OptionFlags; | |
public ushort BcdRulesCount; | |
public ushort RegistryRulesCount; | |
} | |
[StructLayout(LayoutKind.Sequential, Pack = 1)] | |
struct BcdRuleStruct { | |
public uint ObjectType; | |
public uint Element; | |
public uint ValueOffset; | |
} | |
class BcdRule { | |
uint ObjectType; | |
uint Element; | |
PolicyValue Value; | |
public BcdRule(BcdRuleStruct s,byte[] ValueTable) { | |
ObjectType = s.ObjectType; | |
Element = s.Element; | |
byte[] RawData = new byte[ValueTable.Length - s.ValueOffset]; | |
Buffer.BlockCopy(ValueTable,(int)s.ValueOffset,RawData,0,RawData.Length); | |
Value = new PolicyValue(RawData); | |
} | |
public override string ToString() { | |
var sb = new StringBuilder(); | |
if (ObjectType == 0) sb.AppendLine(" ObjectType: any"); | |
else sb.AppendLine(" ObjectType: 0x"+ObjectType.ToString("X")); | |
sb.AppendLine(string.Format(" Element: {0} (0x{1})", (BcdElementTypes)Element, Element.ToString("X"))); | |
sb.AppendLine(" Value: "+Value.ToString()); | |
return sb.ToString(); | |
} | |
} | |
[StructLayout(LayoutKind.Sequential, Pack = 1)] | |
struct RegistryRuleStruct { | |
public uint RootKey; | |
public uint SubkeyNameOffset; | |
public uint ValueNameOffset; | |
public uint ValueOffset; | |
} | |
class RegistryRule { | |
uint RootKey; | |
string SubkeyName; | |
string ValueName; | |
PolicyValue Value; | |
public RegistryRule(RegistryRuleStruct s,byte[] ValueTable) { | |
RootKey = s.RootKey; | |
byte[] RawData = new byte[BitConverter.ToUInt16(ValueTable,(int)s.SubkeyNameOffset)]; | |
Buffer.BlockCopy(ValueTable,(int)s.SubkeyNameOffset + 2,RawData,0,RawData.Length); | |
SubkeyName = Encoding.Unicode.GetString(RawData); | |
RawData = new byte[BitConverter.ToUInt16(ValueTable,(int)s.ValueNameOffset)]; | |
Buffer.BlockCopy(ValueTable,(int)s.ValueNameOffset + 2,RawData,0,RawData.Length); | |
ValueName = Encoding.Unicode.GetString(RawData); | |
RawData = new byte[ValueTable.Length - s.ValueOffset]; | |
Buffer.BlockCopy(ValueTable,(int)s.ValueOffset,RawData,0,RawData.Length); | |
Value = new PolicyValue(RawData); | |
} | |
public override string ToString() { | |
var sb = new StringBuilder(); | |
sb.AppendLine(" Path: 0x"+RootKey.ToString("X")+" "+SubkeyName+"\\"+ValueName); | |
sb.AppendLine(" Value: "+Value.ToString()); | |
return sb.ToString(); | |
} | |
} | |
private SBPHeader Header; | |
ushort FormatVersion { get { return Header.FormatVersion; } set { Header.FormatVersion = value; } } | |
uint PolicyVersion { get { return Header.PolicyVersion; } set { Header.PolicyVersion = value; } } | |
Guid PolicyPublisher { get { return Header.PolicyPublisher; } set { Header.PolicyPublisher = value; } } | |
List<Guid> CanUpdate; | |
private SBPFlags Flags; | |
uint OptionFlags { get { return Flags.OptionFlags; } set { Flags.OptionFlags = value; } } | |
List<BcdRule> BcdRules; | |
List<RegistryRule> RegistryRules; | |
byte[] Sha256Hash; | |
private static Dictionary<int, string> s_OptionFlagsBits = new Dictionary<int, string>() { | |
{ 0, "Allowed:Prerelease Signers" }, | |
{ 1, "Allowed:Kits Signers" }, | |
{ 2, "Enabled:UMCI" }, | |
{ 3, "Disabled:Winload Driver Signature Enforcement Menu" }, | |
{ 4, "Enabled:UMCI Debug Options" }, | |
{ 5, "Enabled:UMCI Cache Data Volumes" }, | |
{ 6, "Policy intended for Windows Phone - Allowed:SeQuerySigningPolicy Extension" }, | |
{ 7, "Required:WHQL" }, | |
{ 8, "Enabled:Filter Edited Boot Options" }, | |
{ 9, "Disabled:UMCI USN 0 Protection" }, | |
{ 10, "Disabled:Winload Debugging Mode Menu" }, | |
{ 14, "Enabled:UMCI Trust USN 0" }, | |
{ 20, "Enabled:Flight Signing" }, | |
{ 21, "Ignored:Flight Signing EKU" } | |
}; | |
public SecureBootPolicy(string filename) { | |
byte[] RawPolicy; | |
try { | |
var Policy = new Asn1Parser(); | |
Policy.LoadData(filename); | |
RawPolicy = Policy.GetNodeByPath("/1/0/2/1/0").Data; | |
} catch (Exception) { | |
RawPolicy = File.ReadAllBytes(filename); | |
} | |
Sha256Hash = new SHA256Managed().ComputeHash(RawPolicy); | |
int offset = 0; | |
Header = ByteArrayToStructure<SBPHeader>(RawPolicy,ref offset); | |
CanUpdate = new List<Guid>(); | |
for (int i = 0; i < Header.CanUpdateCount; i++) | |
CanUpdate.Add(ByteArrayToStructure<Guid>(RawPolicy,ref offset)); | |
Flags = ByteArrayToStructure<SBPFlags>(RawPolicy,ref offset); | |
var BcdRulesRaw = new List<BcdRuleStruct>(); | |
for (int i = 0; i < Flags.BcdRulesCount; i++) { | |
BcdRulesRaw.Add(ByteArrayToStructure<BcdRuleStruct>(RawPolicy,ref offset)); | |
} | |
var RegistryRulesRaw = new List<RegistryRuleStruct>(); | |
for (int i = 0; i < Flags.RegistryRulesCount; i++) | |
RegistryRulesRaw.Add(ByteArrayToStructure<RegistryRuleStruct>(RawPolicy,ref offset)); | |
byte[] ValueTable = new byte[(RawPolicy.Length - offset)]; | |
Buffer.BlockCopy(RawPolicy,offset,ValueTable,0,ValueTable.Length); | |
BcdRules = new List<BcdRule>(); | |
foreach (BcdRuleStruct BcdRaw in BcdRulesRaw) | |
BcdRules.Add(new BcdRule(BcdRaw,ValueTable)); | |
RegistryRules = new List<RegistryRule>(); | |
foreach (RegistryRuleStruct RegRaw in RegistryRulesRaw) | |
RegistryRules.Add(new RegistryRule(RegRaw,ValueTable)); | |
} | |
public string OptionFlagsToString() { | |
var sb = new StringBuilder(); | |
var bits = OptionFlags; | |
uint bit = 1 << 0; | |
for (int i = 0; i < 32; i++, bit <<= 1) { | |
string flagDesc; | |
if ((bits & bit) != 0) { | |
if (!s_OptionFlagsBits.TryGetValue(i, out flagDesc)) | |
flagDesc = string.Format("(unknown bit {0})", i); | |
sb.AppendLine(" " + flagDesc); | |
} | |
} | |
return sb.ToString(); | |
} | |
public override string ToString() { | |
var sb = new StringBuilder(); | |
sb.AppendLine("SHA256 hash: "+BitConverter.ToString(Sha256Hash).Replace("-","")); | |
sb.AppendLine("Format version: "+FormatVersion); | |
sb.AppendLine("Policy version: "+PolicyVersion); | |
sb.AppendLine("Policy publisher: "+PolicyPublisher.ToString()); | |
sb.AppendLine("Option flags: 0x"+OptionFlags.ToString("X")); | |
sb.Append(OptionFlagsToString()); | |
sb.AppendLine("CanUpdate GUIDs: "+CanUpdate.Count); | |
foreach (Guid cu in CanUpdate) | |
sb.AppendLine(" "+cu.ToString()); | |
sb.AppendLine("BCD rules: "+BcdRules.Count); | |
foreach (var Bcd in BcdRules) | |
sb.AppendLine(" "+Bcd.ToString()); | |
sb.AppendLine("Registry rules: "+RegistryRules.Count); | |
foreach (var Reg in RegistryRules) | |
sb.AppendLine(" "+Reg.ToString()); | |
return sb.ToString(); | |
} | |
private T ByteArrayToStructure<T>(byte[] bytes,ref int position) where T: struct { | |
int length = Marshal.SizeOf(typeof(T)); | |
IntPtr ptr = Marshal.AllocHGlobal(length); | |
Marshal.Copy(bytes, 0, ptr, length); | |
T stuff = (T)Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(bytes, position), typeof(T)); | |
position += length; | |
Marshal.FreeHGlobal(ptr); | |
return stuff; | |
} | |
} | |
class Cli { | |
public static void Main(string[] args) { | |
foreach (string arg in args) { | |
Console.WriteLine(new SecureBootPolicy(arg).ToString()); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment