/// <summary> /// Logon user using S4U /// </summary> /// <param name="user">The username.</param> /// <param name="realm">The user's realm.</param> /// <param name="type">The type of logon token.</param> /// <param name="auth_package">The name of the auth package to user.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The logged on token.</returns> public static NtResult <NtToken> LsaLogonS4U(string user, string realm, SecurityLogonType type, string auth_package, bool throw_on_error) { if (user is null) { throw new ArgumentNullException(nameof(user)); } if (realm is null) { throw new ArgumentNullException(nameof(realm)); } byte[] user_bytes = Encoding.Unicode.GetBytes(user); byte[] realm_bytes = Encoding.Unicode.GetBytes(realm); using (var buffer = new SafeStructureInOutBuffer <KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true)) { KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON { MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon }; SafeHGlobalBuffer data_buffer = buffer.Data; logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle(); data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length); logon_struct.ClientUpn.Length = (ushort)user_bytes.Length; logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length; logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length; data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length); logon_struct.ClientRealm.Length = (ushort)realm_bytes.Length; logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length; buffer.Result = logon_struct; return(LsaLogonUser(type, auth_package, "S4U", buffer, null, throw_on_error)); } }
/// <summary> /// Sets UI restrictions. /// </summary> /// <param name="uiRestrictionsClass">The restriction class for the UI.</param> public void SetUiRestrictions(JOB_OBJECT_UILIMIT_FLAGS uiRestrictionsClass = JOB_OBJECT_UILIMIT_FLAGS.ALL) { this.tracer.Trace(nameof(JobObject), "Setting UI restrictions"); var uiRestrictions = new JOBOBJECT_BASIC_UI_RESTRICTIONS { UIRestrictionsClass = uiRestrictionsClass, }; using (var nativeUiRestrictions = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(JOBOBJECT_BASIC_UI_RESTRICTIONS)))) { Marshal.StructureToPtr( uiRestrictions, nativeUiRestrictions.DangerousGetHandle(), false /* fDeleteOld */); if (!Methods.SetInformationJobObject( this.handle, JOB_OBJECT_INFO_CLASS.JobObjectBasicUIRestrictions, nativeUiRestrictions.DangerousGetHandle(), nativeUiRestrictions.Size)) { throw new SandboxException( "Unable to set job object basic ui restrictions", new Win32Exception()); } } }
/// <summary> /// Sets limits. /// </summary> /// <param name="activeProcessLimit">The number of processes that can be added to the job object.</param> /// <param name="jobMemoryLimitInBytes">The total amount of memory that can be consumed by all processes in the job object.</param> /// <param name="limitFlags">The limits that are in effect.</param> /// <param name="processMemoryLimitInBytes">The maximum number of bytes a process can consume.</param> public void SetLimits( uint? activeProcessLimit = null, ulong? jobMemoryLimitInBytes = null, JOB_OBJECT_LIMIT_FLAGS limitFlags = JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, ulong? processMemoryLimitInBytes = null) { this.tracer.Trace(nameof(JobObject), "Setting limits"); var extendedLimitInformation = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION { BasicLimitInformation = { LimitFlags = limitFlags, }, }; if (activeProcessLimit.HasValue) { extendedLimitInformation.BasicLimitInformation.ActiveProcessLimit = activeProcessLimit.GetValueOrDefault(); extendedLimitInformation.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_ACTIVE_PROCESS; } if (jobMemoryLimitInBytes.HasValue) { extendedLimitInformation.JobMemoryLimit = new UIntPtr(jobMemoryLimitInBytes.GetValueOrDefault()); extendedLimitInformation.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_JOB_MEMORY; } if (processMemoryLimitInBytes.HasValue) { extendedLimitInformation.ProcessMemoryLimit = new UIntPtr(processMemoryLimitInBytes.GetValueOrDefault()); extendedLimitInformation.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_PROCESS_MEMORY; } // Apply the limits to the job object. using (var nativeExtendedLimitInformation = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)))) { Marshal.StructureToPtr(extendedLimitInformation, nativeExtendedLimitInformation.DangerousGetHandle(), fDeleteOld: false); if (!Methods.SetInformationJobObject( this.handle, JOB_OBJECT_INFO_CLASS.JobObjectExtendedLimitInformation, nativeExtendedLimitInformation.DangerousGetHandle(), nativeExtendedLimitInformation.Size)) { throw new SandboxException( "Unable to set job object limit information", new Win32Exception()); } } }
public static NtToken LogonS4U(string user, string realm, SecurityLogonType type) { SafeLsaHandle hlsa = null; LsaString pkgName = new LsaString("Negotiate"); LsaConnectUntrusted(out hlsa).ToNtException(); using (hlsa) { uint authnPkg; LsaLookupAuthenticationPackage(hlsa, pkgName, out authnPkg).ToNtException(); byte[] user_bytes = Encoding.Unicode.GetBytes(user); byte[] realm_bytes = Encoding.Unicode.GetBytes(realm); using (var buffer = new SafeStructureInOutBuffer <KERB_S4U_LOGON>(user_bytes.Length + realm_bytes.Length, true)) { KERB_S4U_LOGON logon_struct = new KERB_S4U_LOGON(); logon_struct.MessageType = KERB_LOGON_SUBMIT_TYPE.KerbS4ULogon; SafeHGlobalBuffer data_buffer = buffer.Data; logon_struct.ClientUpn.Buffer = data_buffer.DangerousGetHandle(); data_buffer.WriteArray(0, user_bytes, 0, user_bytes.Length); logon_struct.ClientUpn.Length = (ushort)user_bytes.Length; logon_struct.ClientUpn.MaximumLength = (ushort)user_bytes.Length; logon_struct.ClientRealm.Buffer = data_buffer.DangerousGetHandle() + user_bytes.Length; data_buffer.WriteArray((ulong)user_bytes.Length, realm_bytes, 0, realm_bytes.Length); logon_struct.ClientRealm.Length = (ushort)realm_bytes.Length; logon_struct.ClientRealm.MaximumLength = (ushort)realm_bytes.Length; Marshal.StructureToPtr(logon_struct, buffer.DangerousGetHandle(), false); TOKEN_SOURCE tokenSource = new TOKEN_SOURCE("NtLmSsp"); AllocateLocallyUniqueId(out tokenSource.SourceIdentifier); LsaString originName = new LsaString("S4U"); IntPtr profile; int cbProfile; Luid logon_id; NtStatus subStatus; QUOTA_LIMITS quota_limits; SafeKernelObjectHandle token_handle; LsaLogonUser(hlsa, originName, type, authnPkg, buffer, buffer.Length, IntPtr.Zero, tokenSource, out profile, out cbProfile, out logon_id, out token_handle, out quota_limits, out subStatus).ToNtException(); LsaFreeReturnBuffer(profile); return(NtToken.FromHandle(token_handle)); } } }
private SecurityInformationImpl(string obj_name, Dictionary <uint, string> names, GenericMapping generic_mapping, bool read_only) { _mapping = generic_mapping; _obj_name = new SafeStringBuffer(obj_name); _access_map = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SiAccess)) * names.Count); SiAccess[] sis = new SiAccess[names.Count]; IntPtr current_ptr = _access_map.DangerousGetHandle(); _names = new DisposableList <SafeStringBuffer>(); int i = 0; foreach (KeyValuePair <uint, string> pair in names) { _names.Add(new SafeStringBuffer(pair.Value)); SiAccess si = new SiAccess { pguid = IntPtr.Zero, dwFlags = SiAccessFlags.SI_ACCESS_SPECIFIC | SiAccessFlags.SI_ACCESS_GENERAL, mask = pair.Key, pszName = _names[i].DangerousGetHandle() }; sis[i] = si; i++; } _access_map.WriteArray(0, sis, 0, names.Count); _read_only = read_only; }
public void AddAttribute(IntPtr attribute, SafeHGlobalBuffer value) { if (!UpdateProcThreadAttribute(handle, 0, attribute, value.DangerousGetHandle(), new IntPtr(value.Length), IntPtr.Zero, IntPtr.Zero)) { throw new SafeWin32Exception(); } }
private SafeBuffer GetInitialBuffer() { if (Buffer != null) { return(new SafeHGlobalBuffer(Buffer.DangerousGetHandle(), (int)Buffer.ByteLength, false)); } else if (Bytes != null) { return(new SafeHGlobalBuffer(Bytes)); } else { using (var buffer = new SafeHGlobalBuffer(Marshal.SizeOf(Value))) { Marshal.StructureToPtr(Value, buffer.DangerousGetHandle(), false); return(buffer.Detach()); } } }
internal static SECURITY_CAPABILITIES CreateSecuityCapabilities(Sid package_sid, IEnumerable <Sid> capabilities, DisposableList resources) { SECURITY_CAPABILITIES caps = new SECURITY_CAPABILITIES { AppContainerSid = resources.AddResource(package_sid.ToSafeBuffer()).DangerousGetHandle() }; if (capabilities.Any()) { SidAndAttributes[] cap_sids = capabilities.Select(s => new SidAndAttributes() { Sid = resources.AddResource(s.ToSafeBuffer()).DangerousGetHandle(), Attributes = GroupAttributes.Enabled }).ToArray(); SafeHGlobalBuffer cap_buffer = resources.AddResource(new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SidAndAttributes)) * cap_sids.Length)); cap_buffer.WriteArray(0, cap_sids, 0, cap_sids.Length); caps.Capabilities = cap_buffer.DangerousGetHandle(); caps.CapabilityCount = cap_sids.Length; } return(caps); }
private SafeHGlobalBuffer GetAttributes(DisposableList <IDisposable> resources) { int count = GetAttributeCount(); if (count == 0) { return(SafeHGlobalBuffer.Null); } var attr_list = resources.AddResource(new SafeProcThreadAttributeListBuffer(count)); if (ParentProcess != null) { attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeParentProcess, ParentProcess.Handle.DangerousGetHandle()); } if (MitigationOptions2 != ProcessMitigationOptions2.None) { MemoryStream stm = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stm); writer.Write((ulong)MitigationOptions); writer.Write((ulong)MitigationOptions2); attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeMitigationPolicy, stm.ToArray()); } else if (MitigationOptions != ProcessMitigationOptions.None) { attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeMitigationPolicy, (ulong)MitigationOptions); } if (Win32kFilterFlags != Win32kFilterFlags.None) { Win32kFilterAttribute filter = new Win32kFilterAttribute(); filter.Flags = Win32kFilterFlags; filter.FilterLevel = Win32kFilterLevel; attr_list.AddAttributeBuffer(ProcessAttributes.ProcThreadAttributeWin32kFilter, resources.AddResource(filter.ToBuffer())); } if ((CreationFlags & CreateProcessFlags.ProtectedProcess) != 0) { attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeProtectionLevel, (int)ProtectionLevel); } if (InheritHandleList.Count > 0) { int total_size = IntPtr.Size * InheritHandleList.Count; var handle_list = resources.AddResource(new SafeHGlobalBuffer(total_size)); handle_list.WriteArray(0, InheritHandleList.ToArray(), 0, InheritHandleList.Count); attr_list.AddAttributeBuffer(ProcessAttributes.ProcThreadAttributeHandleList, handle_list); } if (AppContainerSid != null) { SECURITY_CAPABILITIES caps = new SECURITY_CAPABILITIES(); caps.AppContainerSid = resources.AddResource(AppContainerSid.ToSafeBuffer()).DangerousGetHandle(); if (Capabilities.Count > 0) { SidAndAttributes[] cap_sids = new SidAndAttributes[Capabilities.Count]; for (int i = 0; i < Capabilities.Count; ++i) { cap_sids[i] = new SidAndAttributes() { Sid = resources.AddResource(Capabilities[i].ToSafeBuffer()).DangerousGetHandle(), Attributes = GroupAttributes.Enabled }; } SafeHGlobalBuffer cap_buffer = resources.AddResource(new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SidAndAttributes)) * Capabilities.Count)); cap_buffer.WriteArray(0, cap_sids, 0, cap_sids.Length); caps.Capabilities = cap_buffer.DangerousGetHandle(); caps.CapabilityCount = cap_sids.Length; } attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeSecurityCapabilities, caps); } if (LowPrivilegeAppContainer) { attr_list.AddAttribute(ProcessAttributes.ProcThreadAttributeAllApplicationPackagesPolicy, 1); } return(attr_list); }
private SafeHGlobalBuffer GetAttributes(DisposableList <IDisposable> resources) { int count = GetAttributeCount(); if (count == 0) { return(SafeHGlobalBuffer.Null); } var attr_list = resources.AddResource(new SafeProcThreadAttributeListBuffer(count)); if (ParentProcess != null) { attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeParentProcess, ParentProcess.Handle.DangerousGetHandle()); } if (MitigationOptions2 != ProcessMitigationOptions2.None) { MemoryStream stm = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stm); writer.Write((ulong)MitigationOptions); writer.Write((ulong)MitigationOptions2); attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeMitigationPolicy, stm.ToArray()); } else if (MitigationOptions != ProcessMitigationOptions.None) { attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeMitigationPolicy, (ulong)MitigationOptions); } if (Win32kFilterFlags != Win32kFilterFlags.None) { Win32kFilterAttribute filter = new Win32kFilterAttribute { Flags = Win32kFilterFlags, FilterLevel = Win32kFilterLevel }; attr_list.AddAttributeBuffer(Win32ProcessAttributes.ProcThreadAttributeWin32kFilter, resources.AddResource(filter.ToBuffer())); } if ((CreationFlags & CreateProcessFlags.ProtectedProcess) != 0 && ProtectionLevel != ProtectionLevel.None) { attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeProtectionLevel, (int)ProtectionLevel); } if (InheritHandleList.Count > 0) { int total_size = IntPtr.Size * InheritHandleList.Count; var handle_list = resources.AddResource(new SafeHGlobalBuffer(total_size)); handle_list.WriteArray(0, InheritHandleList.ToArray(), 0, InheritHandleList.Count); attr_list.AddAttributeBuffer(Win32ProcessAttributes.ProcThreadAttributeHandleList, handle_list); } if (AppContainerSid != null) { SECURITY_CAPABILITIES caps = new SECURITY_CAPABILITIES { AppContainerSid = resources.AddResource(AppContainerSid.ToSafeBuffer()).DangerousGetHandle() }; if (Capabilities.Count > 0) { SidAndAttributes[] cap_sids = new SidAndAttributes[Capabilities.Count]; for (int i = 0; i < Capabilities.Count; ++i) { cap_sids[i] = new SidAndAttributes() { Sid = resources.AddResource(Capabilities[i].ToSafeBuffer()).DangerousGetHandle(), Attributes = GroupAttributes.Enabled }; } SafeHGlobalBuffer cap_buffer = resources.AddResource(new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SidAndAttributes)) * Capabilities.Count)); cap_buffer.WriteArray(0, cap_sids, 0, cap_sids.Length); caps.Capabilities = cap_buffer.DangerousGetHandle(); caps.CapabilityCount = cap_sids.Length; } attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeSecurityCapabilities, caps); } if (LowPrivilegeAppContainer) { attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeAllApplicationPackagesPolicy, 1); } if (RestrictChildProcessCreation || OverrideChildProcessCreation) { int flags = RestrictChildProcessCreation ? 1 : 0; flags |= OverrideChildProcessCreation ? 2 : 0; attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeChildProcessPolicy, flags); } if (DesktopAppBreakaway != ProcessDesktopAppBreakawayFlags.None) { attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeDesktopAppPolicy, (int)DesktopAppBreakaway); } if (!string.IsNullOrWhiteSpace(PackageName)) { byte[] str_bytes = Encoding.Unicode.GetBytes(PackageName); var string_buffer = resources.AddResource(new SafeHGlobalBuffer(str_bytes)); attr_list.AddAttributeBuffer(Win32ProcessAttributes.ProcThreadAttributePackageName, string_buffer); } if (PseudoConsole != IntPtr.Zero) { attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributePseudoConsole, PseudoConsole); } if (!string.IsNullOrEmpty(BnoIsolationPrefix)) { var prefix = new BnoIsolationAttribute() { IsolationEnabled = 1, IsolationPrefix = BnoIsolationPrefix }; attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeBnoIsolation, prefix); } if (SafeOpenPromptOriginClaim != null) { var bytes = (byte[])SafeOpenPromptOriginClaim.Clone(); Array.Resize(ref bytes, 524); attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeSafeOpenPromptOriginClaim, bytes); } if (ExtendedFlags != ProcessExtendedFlags.None) { attr_list.AddAttribute(Win32ProcessAttributes.ProcThreadAttributeExtendedFlags, (int)ExtendedFlags); } return(attr_list); }
public void AddAttribute(IntPtr attribute, SafeHGlobalBuffer value) { if (!UpdateProcThreadAttribute(handle, 0, attribute, value.DangerousGetHandle(), new IntPtr(value.Length), IntPtr.Zero, IntPtr.Zero)) { throw new SafeWin32Exception(); } }
private SecurityIdentifier GetLogonSid() { // Get the token for the current user. Note that we need to create a SafeTokenHandle of the token in order to safely call // the token functions, but the token that's available is owned by the WindowsIdentity instance and should not be closed // after we're done with it. using (var currentToken = new SafeTokenHandle(this.currentUser.Value.Token, ownsHandle: false)) { // Get the current access token and query it for the token groups. The logon SID can then be extracted by // enumerating the resulting structures. int tokenInformationLength; Methods.GetTokenInformation( currentToken, TOKEN_INFORMATION_CLASS.TokenGroups, IntPtr.Zero, 0 /* tokenInformationLength */, out tokenInformationLength); if (tokenInformationLength <= 0) { throw new SandboxException( "Unable to determine length of the current token information", new Win32Exception()); } using (var nativeTokenInformation = new SafeHGlobalBuffer(tokenInformationLength)) { Methods.GetTokenInformation( currentToken, TOKEN_INFORMATION_CLASS.TokenGroups, nativeTokenInformation.DangerousGetHandle(), nativeTokenInformation.Size, out tokenInformationLength); if (tokenInformationLength <= 0) { throw new SandboxException( "Unabled to get the current token information", new Win32Exception()); } var tokenGroups = (TOKEN_GROUPS)Marshal.PtrToStructure( nativeTokenInformation.DangerousGetHandle(), typeof(TOKEN_GROUPS)); int sidAndAttributeSize = Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES)); // Get a pointer to the start of the Groups array. IntPtr groupsPtr = IntPtr.Add( nativeTokenInformation.DangerousGetHandle(), (int)Marshal.OffsetOf(typeof(TOKEN_GROUPS), "Groups")); // Now iterate through all of the groups and look for our Logon SID. for (int i = 0; i < tokenGroups.GroupCount; i++) { var sidAndAttributes = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure( IntPtr.Add(groupsPtr, i * sidAndAttributeSize), typeof(SID_AND_ATTRIBUTES)); if ((sidAndAttributes.Attributes & SID_ATTRIBUTES.SE_GROUP_LOGON_ID) == SID_ATTRIBUTES.SE_GROUP_LOGON_ID) { return(new SecurityIdentifier(sidAndAttributes.Sid)); } } } } // LocalSystem doesn't have a Logon SID and and so it's not possible to create a restricted process using // this approach for processes executing using that identity. Since this is a known scenario make sure the // error message helps debug it. if (this.CurrentUserSid == this.LocalSystemSid) { throw new SandboxException( "Cannot create a restricted process as LocalSystem (does not have a Logon SID)"); } throw new SandboxException( "Could not determine the Logon SID required to generate a restricted token"); }
/// <summary> /// Constructor from an manged buffer. /// </summary> /// <param name="sid">A buffer containing a valid SID.</param> /// <exception cref="NtException">Thrown if the buffer is not valid.</exception> public Sid(byte[] sid) { using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(sid)) { InitializeFromPointer(buffer.DangerousGetHandle()); } }
/// <summary> /// Get a list of handles /// </summary> /// <param name="pid">A process ID to filter on. If -1 will get all handles</param> /// <param name="allow_query">True to allow the handles returned to query for certain properties</param> /// <returns>The list of handles</returns> public static IEnumerable<NtHandle> GetHandles(int pid, bool allow_query) { SafeHGlobalBuffer handleInfo = new SafeHGlobalBuffer(0x10000); try { NtStatus status = 0; int return_length = 0; while ((status = NtSystemCalls.NtQuerySystemInformation(SystemInformationClass.SystemHandleInformation, handleInfo.DangerousGetHandle(), handleInfo.Length, out return_length)) == NtStatus.STATUS_INFO_LENGTH_MISMATCH) { int length = handleInfo.Length * 2; handleInfo.Close(); handleInfo = new SafeHGlobalBuffer(length); } status.ToNtException(); IntPtr handleInfoBuf = handleInfo.DangerousGetHandle(); int handle_count = Marshal.ReadInt32(handleInfoBuf); List<NtHandle> ret = new List<NtHandle>(); handleInfoBuf += IntPtr.Size; for (int i = 0; i < handle_count; ++i) { SystemHandleTableInfoEntry entry = (SystemHandleTableInfoEntry)Marshal.PtrToStructure(handleInfoBuf, typeof(SystemHandleTableInfoEntry)); if (pid == -1 || entry.UniqueProcessId == pid) { ret.Add(new NtHandle(entry, allow_query)); } handleInfoBuf += Marshal.SizeOf(typeof(SystemHandleTableInfoEntry)); } return ret; } finally { handleInfo.Close(); } }
public void GetAccessRights(ref Guid pguidObjectType, SiObjectInfoFlags dwFlags, out IntPtr ppAccess, out uint pcAccesses, out uint piDefaultAccess) { ppAccess = _access_map.DangerousGetHandle(); pcAccesses = (uint)_names.Count; piDefaultAccess = 0; }
private void ParseExports() { _exports = new List <DllExport>(); try { IntPtr exports = Win32NativeMethods.ImageDirectoryEntryToDataEx(handle, MappedAsImage, IMAGE_DIRECTORY_ENTRY_EXPORT, out int size, out IntPtr header_ptr); if (exports == IntPtr.Zero) { return; } SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(exports, size, false); ImageExportDirectory export_directory = buffer.Read <ImageExportDirectory>(0); if (export_directory.NumberOfFunctions == 0) { return; } IntPtr funcs = RvaToVA(export_directory.AddressOfFunctions); IntPtr names = RvaToVA(export_directory.AddressOfNames); IntPtr name_ordinals = RvaToVA(export_directory.AddressOfNameOrdinals); long export_base = buffer.DangerousGetHandle().ToInt64(); long export_top = export_base + buffer.Length; int[] func_rvas = new int[export_directory.NumberOfFunctions]; Marshal.Copy(funcs, func_rvas, 0, func_rvas.Length); IntPtr[] func_vas = func_rvas.Select(r => r != 0 ? RvaToVA(r) : IntPtr.Zero).ToArray(); int[] name_rvas = new int[export_directory.NumberOfNames]; Marshal.Copy(names, name_rvas, 0, name_rvas.Length); IntPtr[] name_vas = name_rvas.Select(r => r != 0 ? RvaToVA(r) : IntPtr.Zero).ToArray(); short[] ordinals = new short[export_directory.NumberOfNames]; Marshal.Copy(name_ordinals, ordinals, 0, ordinals.Length); Dictionary <int, string> ordinal_to_names = new Dictionary <int, string>(); for (int i = 0; i < name_vas.Length; ++i) { string name = Marshal.PtrToStringAnsi(name_vas[i]); int ordinal = ordinals[i]; ordinal_to_names[ordinal] = name; } for (int i = 0; i < func_vas.Length; ++i) { string forwarder = string.Empty; long func_va = func_vas[i].ToInt64(); if (func_va >= export_base && func_va < export_top) { forwarder = Marshal.PtrToStringAnsi(func_vas[i]); func_va = 0; } _exports.Add(new DllExport(ordinal_to_names.ContainsKey(i) ? ordinal_to_names[i] : null, i + export_directory.Base, func_va, forwarder)); } } catch { } }
public SecurityInformationImpl(string obj_name, NtObject handle, Dictionary<uint, string> names, GenericMapping generic_mapping) { _mapping = generic_mapping; _handle = handle; _obj_name = new SafeStringBuffer(obj_name); _access_map = new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SiAccess)) * names.Count); SiAccess[] sis = new SiAccess[names.Count]; IntPtr current_ptr = _access_map.DangerousGetHandle(); _names = new DisposableList<SafeStringBuffer>(); int i = 0; foreach (KeyValuePair<uint, string> pair in names) { _names.Add(new SafeStringBuffer(pair.Value)); SiAccess si = new SiAccess(); si.dwFlags = SiAccessFlags.SI_ACCESS_SPECIFIC | SiAccessFlags.SI_ACCESS_GENERAL; si.mask = pair.Key; si.pszName = _names[i].DangerousGetHandle(); sis[i] = si; i++; } _access_map.WriteArray(0, sis, 0, names.Count); }