/// <summary> /// Reads a unicode string from the specified process. /// </summary> /// <param name="processHandle">The process handle from where the string will be read.</param> /// <param name="unicodeString">The <seealso cref="UNICODE_STRING"/> to read.</param> /// <returns>Returns the string read from the process, or an empty string on failure.</returns> /// <remarks> /// Note that an empty string may also be returned if the string was indeed empty in the process. /// </remarks> public static string ReadProcessUnicodeString(SafeHandle processHandle, UNICODE_STRING unicodeString) { string result = string.Empty; if ((unicodeString.Length != 0) && (unicodeString.Buffer != IntPtr.Zero)) { var stringBuffer = Marshal.AllocHGlobal(unicodeString.Length); ulong stringBytesRead; try { // ReadProcessMemory will return false if it cannot transfer all of the // data requested by unicodeString.Length. This can occur when ReadProcessMemory // cannot access the memory requestd in the process. Key takeaway, // the function will not return true unless it can read all of the // data requested. if (ReadProcessMemory(processHandle, unicodeString.Buffer, stringBuffer, unicodeString.Length, out stringBytesRead)) { result = Marshal.PtrToStringUni(stringBuffer, unicodeString.Length / 2); } } finally { Marshal.FreeHGlobal(stringBuffer); } } return(result); }
public static void Initialize(string payload) { UIntPtr regKeyHandle = UIntPtr.Zero; string runKeyPath = RegistryKeys.RunKey; string runKeyPathTrick = "\0\0" + RegistryKeys.RunKey; uint Status = 0xc0000000; uint STATUS_SUCCESS = 0x00000000; RegOpenKeyEx(HKEY_LOCAL_MACHINE, runKeyPath, 0, KEY_SET_VALUE, out regKeyHandle); UNICODE_STRING ValueName = new UNICODE_STRING(runKeyPathTrick) { Length = 2 * 11, MaximumLength = 0 }; IntPtr ValueNamePtr = StructureToPtr(ValueName); UNICODE_STRING ValueData; ValueData = new UNICODE_STRING("\"" + payload + "\""); Status = NtSetValueKey(regKeyHandle, ValueNamePtr, 0, RegistryKeyType.REG_SZ, ValueData.buffer, ValueData.MaximumLength); if (Status.Equals(STATUS_SUCCESS)) { Console.WriteLine("[+] Hidden key successfully added"); } else { Console.WriteLine("[-] Hidden key failed"); } }
public IoctlProcessStruct(Boolean load, String procName) { Load = load; ProcessName = new UNICODE_STRING(procName); ProcessId = 0; Buffer = IntPtr.Zero; }
private static string ReadUnicodeString(ref IntPtr ptr) { UNICODE_STRING str = (UNICODE_STRING)Marshal.PtrToStructure(ptr, typeof(UNICODE_STRING)); ptr = (IntPtr)((long)ptr + Marshal.SizeOf(typeof(UNICODE_STRING))); return(Marshal.PtrToStringUni(str.Buffer, str.Length / 2)); }
/// <summary> /// Reads the kernel object name for a given windows usermode handle. /// Executes in approx. 100 micro secounds. /// </summary> /// <remarks> /// <para> /// This allows you to translate a handle back to the associated filename for example. /// But keep in mind that such names are only valid for kernel service routines, like /// <c>NtCreateFile</c>. You won't have success when calling <c>CreateFile</c> on such /// object names! The regular windows user mode API has some methods that will allow /// you to convert such kernelmode names back into usermode names. I know this because I did it /// some years ago but I've already forgotten how it has to be done! I can only give you /// some hints: <c>FindFirstVolume()</c>, <c>FindFirstVolumeMountPoint()</c>, /// <c>QueryDosDevice()</c>, <c>GetVolumePathNamesForVolumeName()</c> /// </para> /// <param name="InHandle">A valid usermode handle.</param> /// </remarks> /// <returns>The kernel object name associated with the given handle.</returns> /// <exception cref="ArgumentException"> /// The given handle is invalid or could not be accessed for unknown reasons. /// </exception> public static String GetNameByHandle(IntPtr InHandle) { Int32 RequiredSize; NativeAPI.DbgHandleToObjectName( InHandle, IntPtr.Zero, 0, out RequiredSize); lock (Buffer) { Buffer.Alloc(RequiredSize + 1); NativeAPI.DbgHandleToObjectName( InHandle, Buffer.Buffer, RequiredSize, out RequiredSize); var Result = new UNICODE_STRING(); Marshal.PtrToStructure(Buffer.Buffer, Result); return Result.Buffer; } }
public Result <string> GetLinkTarget() { var type = NtdllHelper.GetObjectType(Name); if (type != "SymbolicLink") { return(Result <string> .Failed("Not a symbolic link")); } var objectAttributes = new OBJECT_ATTRIBUTES(Name, 0); var status = Ntdll.NtOpenSymbolicLinkObject( out var linkHandle, ACCESS_MASK.GENERIC_READ, ref objectAttributes); if (status < 0) { return(Result <string> .Failed("Open file failed with status " + status)); } using (linkHandle) { var targetBuffer = new UNICODE_STRING(new string(' ', 512)); status = Ntdll.NtQuerySymbolicLinkObject( linkHandle, ref targetBuffer, out var len); return(status < 0 ? Result <string> .Failed("Query link failed with status " + status) : Result <string> .Succeeded(targetBuffer.ToString())); } }
internal static string GetLocalMachineSid() { string machineSid; var server = new UNICODE_STRING("localhost"); var obj = default(OBJECT_ATTRIBUTES); SamConnect(ref server, out var serverHandle, SamAccessMasks.SamServerLookupDomain | SamAccessMasks.SamServerConnect, ref obj); var san = new UNICODE_STRING(Environment.MachineName); try { SamLookupDomainInSamServer(serverHandle, ref san, out var temp); machineSid = new SecurityIdentifier(temp).Value; } catch { //This happens on domain controllers machineSid = Environment.MachineName; } SamCloseHandle(serverHandle); return(machineSid); }
public extern static bool RtlIsNameInExpression( ref UNICODE_STRING Expression, ref UNICODE_STRING Name, [MarshalAs(UnmanagedType.U1)] bool IgnoreCase, IntPtr Zero );
public void SpoofArgs() { var pbi = GetPBI(); // x64 only var rtlUserProcessParameters = 0x20; var commandLine = 0x70; var readSize = 0x8; Thread.Sleep(500); var pProcessParams = ReadRemoteMemory(pbi.PebBaseAddress + rtlUserProcessParameters, readSize); var processParams = Marshal.ReadInt64(pProcessParams); var cmdLineUnicodeStruct = new IntPtr(processParams + commandLine); var currentCmdLineStruct = new UNICODE_STRING(); var uniStructSize = Marshal.SizeOf(currentCmdLineStruct); var pCmdLineStruct = ReadRemoteMemory(cmdLineUnicodeStruct, uniStructSize); currentCmdLineStruct = (UNICODE_STRING)Marshal.PtrToStructure(pCmdLineStruct, typeof(UNICODE_STRING)); WriteRemoteMemory(currentCmdLineStruct.Buffer, currentCmdLineStruct.Length); Thread.Sleep(500); ResumeThread(pi.hThread); }
public OBJECT_ATTRIBUTES(UNICODE_STRING objectName) : this() { Length = (uint)Marshal.SizeOf(this); ObjectName = Marshal.AllocHGlobal(Marshal.SizeOf(objectName)); Marshal.StructureToPtr(objectName, ObjectName, false); }
protected void EnsureUnloaded() { if (!DriverHandle.IsInvalid) { try { AddDriverToRegistry(); AdjustPrivilege(); var registryUnicode = new UNICODE_STRING("\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" + Path.GetFileNameWithoutExtension(FilePath)); var status = NtUnloadDriver(ref registryUnicode); if (status != NtStatus.Success) { Logger.Log($"NtUnloadDriver failed {status}"); } } catch (Exception e) { Logger.Log($"LoadDriver exception: {e.Message}"); EnsureUnloaded(); } DriverHandle.Close(); } RemoveDriverFromRegistry(); RemoveFromSystemDirectory(); }
/// <summary> /// Return whether or not the given expression matches the given name. Takes standard /// Windows wildcards (*, ?, <, > "). /// </summary> public unsafe static bool IsNameInExpression(string expression, string name, bool ignoreCase) { if (string.IsNullOrEmpty(expression) || string.IsNullOrEmpty(name)) { return(false); // If ignore case is set, the API will uppercase the name *if* an UpcaseTable // is not provided. It then flips to case-sensitive. In this state the expression // has to be uppercase to match as expected. fixed(char *e = ignoreCase?expression.ToUpperInvariant() : expression) fixed(char *n = name) { UNICODE_STRING *eus = null; UNICODE_STRING *nus = null; if (e != null) { var temp = new UNICODE_STRING(e, expression.Length); eus = &temp; } if (n != null) { var temp = new UNICODE_STRING(n, name.Length); nus = &temp; } return(Imports.RtlIsNameInExpression(eus, nus, ignoreCase, IntPtr.Zero)); } }
private static SafeHandle OpenObjectHelper(string path, Func <OBJECT_ATTRIBUTES, SafeHandle> invoker) { unsafe { fixed(char *pathPointer = path) { ushort length = checked ((ushort)(path.Length * sizeof(char))); var objectName = new UNICODE_STRING { Length = length, MaximumLength = length, Buffer = pathPointer }; OBJECT_ATTRIBUTES attributes = new OBJECT_ATTRIBUTES { Length = (uint)Marshal.SizeOf <OBJECT_ATTRIBUTES>(), RootDirectory = IntPtr.Zero, ObjectName = (IntPtr)(&objectName), SecurityDescriptor = IntPtr.Zero, SecurityQualityOfService = IntPtr.Zero }; SafeHandle handle = invoker(attributes); return(handle); } } }
private void dataGridView2_DoubleClick(object sender, EventArgs e) { UNICODE_STRING unicodeString = new UNICODE_STRING(); RtlInitUnicodeString(ref unicodeString, "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" + (string)dataGridView2.SelectedRows[0].Cells["BaseName"].Value); privilege driverPrivilege = new privilege("SeLoadDriverPrivilege"); uint wynik = ZwLoadDriver(ref unicodeString); if (wynik == 0) { getRunningDrivers(); return; } wynik = ZwUnloadDriver(ref unicodeString); if (wynik == 0) { getRunningDrivers(); return; } if (wynik == 0xC0000061) { MessageBox.Show("Zostań administratorem"); } else { MessageBox.Show(wynik.ToString("X8")); } }
public static void Emit_UNICODE_STRING(IntPtr hProcess, IntPtr lpBaseAddress, UInt32 dwSize, string data) { // Set access protections -> PAGE_EXEcUTE_READWRITE UInt32 lpfOldProtect = 0; bool CallResult = false; CallResult = Kernel32.VirtualProtectEx(hProcess, lpBaseAddress, dwSize, 0x40, ref lpfOldProtect); //Create replacement struct UNICODE_STRING UnicodeObject = new UNICODE_STRING(); string UnicodeObject_Buffer = data; UnicodeObject.Length = (ushort)(UnicodeObject_Buffer.Length * 2); UnicodeObject.MaximumLength = (ushort)(UnicodeObject.Length + 1); UnicodeObject.Buffer = Marshal.StringToHGlobalUni(UnicodeObject_Buffer); IntPtr InMemoryStruct = new IntPtr(); InMemoryStruct = Marshal.AllocHGlobal((int)dwSize); Marshal.StructureToPtr(UnicodeObject, InMemoryStruct, true); //Console.WriteLine("[>] Overwriting Current Process Information"); //Overwrite PEB UNICODE_STRING struct UInt32 lpNumberOfBytesWritten = 0; CallResult = Kernel32.WriteProcessMemory(hProcess, lpBaseAddress, InMemoryStruct, dwSize, ref lpNumberOfBytesWritten); //Free InMemoryStruct Marshal.FreeHGlobal(InMemoryStruct); }
public static IntPtr GetLocalExportOffset(String Module, String Export) { UNICODE_STRING uModuleName = new UNICODE_STRING(); RtlInitUnicodeString(ref uModuleName, Module); IntPtr hModule = IntPtr.Zero; UInt32 CallResult = LdrGetDllHandle(IntPtr.Zero, IntPtr.Zero, ref uModuleName, ref hModule); if (CallResult != 0 || hModule == IntPtr.Zero) { return(IntPtr.Zero); } // Hey MSFT, why is RtlInitAnsiString not working on Win7..? UNICODE_STRING uFuncName = new UNICODE_STRING(); RtlInitUnicodeString(ref uFuncName, Export); ANSI_STRING aFuncName = new ANSI_STRING(); RtlUnicodeStringToAnsiString(ref aFuncName, ref uFuncName, true); IntPtr pExport = IntPtr.Zero; CallResult = LdrGetProcedureAddress(hModule, ref aFuncName, 0, ref pExport); if (CallResult != 0 || pExport == IntPtr.Zero) { return(IntPtr.Zero); } IntPtr FuncOffset = (IntPtr)((Int64)(pExport) - (Int64)(hModule)); return(FuncOffset); }
private static extern uint LsaOpenPolicy( #endif ref UNICODE_STRING SystemName, ref OBJECT_ATTRIBUTES ObjectAttributes, int AccessMask, out SafeLsaPolicyHandle PolicyHandle );
/// <summary> /// Reads the kernel object name for a given windows usermode handle. /// Executes in approx. 100 micro secounds. /// </summary> /// <remarks><para> /// This allows you to translate a handle back to the associated filename for example. /// But keep in mind that such names are only valid for kernel service routines, like /// <c>NtCreateFile</c>. You won't have success when calling <c>CreateFile</c> on such /// object names! The regular windows user mode API has some methods that will allow /// you to convert such kernelmode names back into usermode names. I know this because I did it /// some years ago but I've already forgotten how it has to be done! I can only give you /// some hints: <c>FindFirstVolume()</c>, <c>FindFirstVolumeMountPoint()</c>, /// <c>QueryDosDevice()</c>, <c>GetVolumePathNamesForVolumeName()</c> /// </para> /// <param name="InHandle">A valid usermode handle.</param> /// </remarks> /// <returns>The kernel object name associated with the given handle.</returns> /// <exception cref="ArgumentException"> /// The given handle is invalid or could not be accessed for unknown reasons. /// </exception> public static String GetNameByHandle(IntPtr InHandle) { Int32 RequiredSize; NativeAPI.DbgHandleToObjectName( InHandle, IntPtr.Zero, 0, out RequiredSize); lock (Buffer) { Buffer.Alloc(RequiredSize + 1); NativeAPI.DbgHandleToObjectName( InHandle, Buffer.Buffer, RequiredSize, out RequiredSize); UNICODE_STRING Result = new UNICODE_STRING(); Marshal.PtrToStructure(Buffer.Buffer, Result); return(Result.Buffer); } }
private static string GetFileName(OBJECT_ATTRIBUTES ObjectAttributes) { UNICODE_STRING us = (UNICODE_STRING)Marshal.PtrToStructure(ObjectAttributes.ObjectName, typeof(UNICODE_STRING)); string s = Marshal.PtrToStringUni(us.Buffer, us.Length / sizeof(char)); return(s.Replace(@"\??\C:\", @"C:\")); }
internal static extern UInt32 SamCreateUser2InDomain(IntPtr domainHandle, ref UNICODE_STRING accountName, Int32 accountType, UInt32 desiredAccess, out IntPtr userHandle, out UInt32 grantedAccess, out UInt32 relativeId);
/// <summary> /// Read a UNICODE_STRING from the buffer. Advances the reader offset. /// </summary> /// <remarks> /// LSA_UNICODE_STRING has the same definition as UNICODE_STRING. /// </remarks> public unsafe string ReadUNICODE_STRING() { UNICODE_STRING us = *(UNICODE_STRING *)BytePointer; string value = new string(us.Buffer, 0, us.Length / sizeof(char)); ByteOffset += (ulong)sizeof(UNICODE_STRING); return(value); }
internal static extern uint LsaLookupNames2( SafeLsaPolicyHandle handle, int flags, int count, UNICODE_STRING[] names, ref SafeLsaMemoryHandle referencedDomains, ref SafeLsaMemoryHandle sids );
public unsafe void ToUpperInvariant(string value, string expected) { using (var buffer = new StringBuffer(value)) { UNICODE_STRING s = buffer.ToUnicodeString(); StringMethods.ToUpperInvariant(ref s); s.ToString().Should().Be(expected); } }
public static unsafe void ToUpperInvariant(ref UNICODE_STRING value) { NTSTATUS status = Imports.RtlUpcaseUnicodeString( (UNICODE_STRING *)Structs.AddressOf(ref value), (UNICODE_STRING *)Structs.AddressOf(ref value), false); if (!ErrorMacros.NT_SUCCESS(status)) { ErrorMethods.GetIoExceptionForNTStatus(status); } }
public static IEnumerable <ObjectInformation> GetDirectoryEntries(SafeDirectoryObjectHandle directoryHandle) { List <ObjectInformation> infos = new List <ObjectInformation>(); BufferHelper.CachedInvoke((StringBuffer buffer) => { buffer.EnsureCharCapacity(1024); uint context = 0; uint returnLength; NTSTATUS status; do { status = Direct.NtQueryDirectoryObject( DirectoryHandle: directoryHandle, Buffer: buffer, Length: (uint)buffer.ByteCapacity, ReturnSingleEntry: false, RestartScan: false, Context: ref context, ReturnLength: out returnLength); if (status != NTSTATUS.STATUS_SUCCESS && status != NTSTATUS.STATUS_MORE_ENTRIES) { break; } CheckedReader reader = new CheckedReader(buffer); do { UNICODE_STRING name = reader.ReadStruct <UNICODE_STRING>(); if (name.Length == 0) { break; } UNICODE_STRING type = reader.ReadStruct <UNICODE_STRING>(); infos.Add(new ObjectInformation { Name = name.ToString(), TypeName = type.ToString() }); } while (true); } while (status == NTSTATUS.STATUS_MORE_ENTRIES); if (status != NTSTATUS.STATUS_SUCCESS) { throw ErrorHelper.GetIoExceptionForNTStatus(status); } }); return(infos.OrderBy(i => i.Name));; }
static unsafe USysCall64() { UNICODE_STRING szNtdll = new UNICODE_STRING("ntdll"); UIntPtr ptrNtdll = UIntPtr.Zero; long ntstatus = LdrGetDllHandle(IntPtr.Zero, IntPtr.Zero, ref szNtdll, ref ptrNtdll); if (ntstatus != 0) { Debugger.Break(); } byte * lpNtdll = (byte *)ptrNtdll; IMAGE_DOS_HEADER * piDH = (IMAGE_DOS_HEADER *)lpNtdll; IMAGE_OPTIONAL_HEADER64 *piOH = (IMAGE_OPTIONAL_HEADER64 *)(lpNtdll + piDH->e_lfanew + 0x18); IMAGE_EXPORT_DIRECTORY * exportDir = (IMAGE_EXPORT_DIRECTORY *)(lpNtdll + piOH->ExportTable.VirtualAddress); uint * names = (uint *)(lpNtdll + exportDir->AddressOfNames); uint * functions = (uint *)(lpNtdll + exportDir->AddressOfFunctions); ushort *ordinals = (ushort *)(lpNtdll + exportDir->AddressOfNameOrdinals); var listOfNames = new List <string>(); var dictOfZwFunctions = new Dictionary <string, ulong>(); for (int i = 0; i < exportDir->NumberOfNames; i++) { var name = Marshal.PtrToStringAnsi(new IntPtr(lpNtdll + names[i])); if (!name.StartsWith("Zw")) { continue; } var fnAddr = new UIntPtr(lpNtdll + functions[ordinals[i]]); dictOfZwFunctions.Add(name, fnAddr.ToUInt64()); } var sortedByAddr = dictOfZwFunctions .OrderBy(x => x.Value) .ToDictionary(x => "Nt" + x.Key.Substring(2, x.Key.Length - 2), x => x.Value); var sysCallLookup = new Dictionary <string, uint>(); uint sysNo = 0; foreach (var entry in sortedByAddr) { sysCallLookup.Add(entry.Key, sysNo); sysNo++; } SysCallTable = sysCallLookup; }
public static IntPtr GetLocalExportOffset(String Module, String Export) { UNICODE_STRING uModuleName = new UNICODE_STRING(); IntPtr pFunction = Generic.GetLibraryAddress(@"ntdll.dll", "RtlInitUnicodeString"); RtlInitUnicodeString rtlInitUnicodeString = (RtlInitUnicodeString)Marshal.GetDelegateForFunctionPointer(pFunction, typeof(RtlInitUnicodeString)); rtlInitUnicodeString(ref uModuleName, Module); IntPtr hModule = Generic.GetPebLdrModuleEntry(Module); if (hModule == IntPtr.Zero) { Console.WriteLine("[!] Failed to get " + Module + " handle.."); return(IntPtr.Zero); } else { Console.WriteLine(" |-> LdrGetDllHandle OK"); } UNICODE_STRING uFuncName = new UNICODE_STRING(); rtlInitUnicodeString(ref uFuncName, Export); ANSI_STRING aFuncName = new ANSI_STRING(); pFunction = Generic.GetLibraryAddress(@"ntdll.dll", "RtlUnicodeStringToAnsiString"); RtlUnicodeStringToAnsiString rtlUnicodeStringToAnsiString = (RtlUnicodeStringToAnsiString)Marshal.GetDelegateForFunctionPointer(pFunction, typeof(RtlUnicodeStringToAnsiString)); rtlUnicodeStringToAnsiString(ref aFuncName, ref uFuncName, true); IntPtr pExport = IntPtr.Zero; pFunction = Generic.GetLibraryAddress(@"ntdll.dll", "LdrGetProcedureAddress"); LdrGetProcedureAddress ldrGetProcedureAddress = (LdrGetProcedureAddress)Marshal.GetDelegateForFunctionPointer(pFunction, typeof(LdrGetProcedureAddress)); UInt32 CallResult = ldrGetProcedureAddress(hModule, ref aFuncName, 0, ref pExport); if (CallResult != 0 || pExport == IntPtr.Zero) { Console.WriteLine("[!] Failed to get " + Export + " address.."); return(IntPtr.Zero); } else { Console.WriteLine(" |-> " + Export + ": 0x" + String.Format("{0:X}", (pExport).ToInt64())); } IntPtr FuncOffset = (IntPtr)((Int64)pExport - (Int64)hModule); Console.WriteLine(" |-> Offset: 0x" + String.Format("{0:X}", (FuncOffset).ToInt64())); return(FuncOffset); }
public static void RtlInitUnicodeString(ref UNICODE_STRING DestinationString, [MarshalAs(UnmanagedType.LPWStr)] string SourceString) { object[] funcargs = { DestinationString, SourceString }; Generic.DynamicAPIInvoke(@"ntdll.dll", @"RtlInitUnicodeString", typeof(DELEGATES.RtlInitUnicodeString), ref funcargs); DestinationString = (UNICODE_STRING)funcargs[0]; }
public static void Open() { IO_STATUS_BLOCK ioStatus; var objectAttributes = new OBJECT_ATTRIBUTES(); objectAttributes.Length = Marshal.SizeOf(typeof(OBJECT_ATTRIBUTES)); var deviceName = new UNICODE_STRING(@"\Device\shalz"); objectAttributes.ObjectName = new IntPtr(&deviceName); var status = NtOpenFile(out DeviceHandle, (uint)(0xC0100000), &objectAttributes, &ioStatus, System.IO.FileShare.None, 3u); }
public OBJECT_ATTRIBUTES(string name, uint attrs) { Length = 0; RootDirectory = IntPtr.Zero; objectName = IntPtr.Zero; Attributes = attrs; SecurityDescriptor = IntPtr.Zero; SecurityQualityOfService = IntPtr.Zero; Length = Marshal.SizeOf(this); if (name != null) ObjectName = new UNICODE_STRING(name); }
public static IntPtr EmitUnicodeString(String Data) { UNICODE_STRING StringObject = new UNICODE_STRING(); StringObject.Length = (UInt16)(Data.Length * 2); StringObject.MaximumLength = (UInt16)(StringObject.Length + 1); StringObject.Buffer = Marshal.StringToHGlobalUni(Data); IntPtr pUnicodeString = Marshal.AllocHGlobal(16); Marshal.StructureToPtr(StringObject, pUnicodeString, true); return(pUnicodeString); }
/// <summary> /// You ain't gonna need it but it's here anyway. /// </summary> /// <param name="name">Specifies the full path of the file.</param> /// <param name="attrs">Attributes for the file.</param> public OBJECT_ATTRIBUTES(string name, uint attrs) { Length = 0; RootDirectory = IntPtr.Zero; objectName = IntPtr.Zero; Attributes = attrs; SecurityDescriptor = IntPtr.Zero; SecurityQualityOfService = IntPtr.Zero; Length = Marshal.SizeOf(this); ObjectName = new UNICODE_STRING(name); }
public bool TryGetSymbolicLinkTarget(out string result, out NtStatus returnCode) { if (Type != WellKnownType.SymbolicLink) { throw new InvalidOperationException($"Not a symbolic link, was {Type}"); } OBJECT_ATTRIBUTES attrib = new OBJECT_ATTRIBUTES(FullName, 0); returnCode = Win32.NtOpenSymbolicLinkObject(out SafeFileHandle handle, DirectoryAccessEnum.DIRECTORY_QUERY, ref attrib); using (handle) { UNICODE_STRING target = new UNICODE_STRING(); returnCode = Win32.NtQuerySymbolicLinkObject(handle, ref target, out int retLength); if (returnCode == NtStatus.STATUS_SUCCESS) { result = target.ToString(); return(returnCode == NtStatus.STATUS_SUCCESS); } if (returnCode != NtStatus.STATUS_BUFFER_TOO_SMALL) { result = null; return(false); } target = new UNICODE_STRING((ushort)retLength); returnCode = Win32.NtQuerySymbolicLinkObject(handle, ref target, out retLength); if (returnCode != NtStatus.STATUS_SUCCESS) { result = null; return(false); } result = target.ToString(); if (result.Contains(";")) { result = result.Substring(0, result.IndexOf(';')); } if (result.EndsWith("\\")) { result = result.Substring(0, result.Length - 1); } return(true); } }
public unsafe void NtOpenSection_Test() { string nameString = "\\Device\\PhysicalMemory"; fixed (char* name = nameString) { var objectNameUnicode = new UNICODE_STRING { Buffer = name, Length = (ushort)(nameString.Length * sizeof(char)), MaximumLength = (ushort)(nameString.Length * sizeof(char)), }; var attrs = OBJECT_ATTRIBUTES.Create(); attrs.ObjectName = &objectNameUnicode; attrs.Attributes = OBJECT_ATTRIBUTES.ObjectHandleAttributes.OBJ_CASE_INSENSITIVE; SafeNTObjectHandle hObject; NTSTATUS status = NtOpenSection(out hObject, Kernel32.ACCESS_MASK.StandardRight.STANDARD_RIGHTS_READ, attrs); Assert.Equal<NTSTATUS>(NTSTATUS.Code.STATUS_ACCESS_DENIED, status); } }
public static String GetProcessCommand(IntPtr Handle) { var objStr = new UNICODE_STRING(new string(' ', 512)); //var objStr = new UNICODE_STRING(); //IntPtr ipStr = IntPtr.Zero; String result = String.Empty; int pSize = 0; try { //IntPtr ipTemp = IntPtr.Zero; //String s = String.Empty; //s = s.PadLeft(512, ' '); //objStr.Length = (ushort)(s.Length * 2); //objStr.MaximumLength = (ushort)(objStr.Length + 2); //objStr.Buffer = Marshal.StringToHGlobalUni(s); //ipStr = Marshal.AllocHGlobal(Marshal.SizeOf(objStr)); if (-1 != NtQueryInformationProcess(Handle, PROCESSINFOCLASS.ProcessImageFileName, ref objStr, Marshal.SizeOf(objStr), ref pSize)) { //objStr = (UNICODE_STRING)Marshal.PtrToStructure(ipStr, objStr.GetType()); //if (Is64Bits()) //{ // ipTemp = new IntPtr(Convert.ToInt64(objStr.Buffer.ToString(), 10) >> 32); //} //else //{ // ipTemp = objStr.Buffer; //} //result = Marshal.PtrToStringUni(ipTemp, objStr.Length >> 1); result = objStr.ToString(); objStr.Dispose(); //str.Dispose(); return result; //return String.Empty; } else { return String.Empty; } } catch { return String.Empty; } finally { //Marshal.FreeHGlobal(ipStr); } }
internal static extern UInt32 SamCreateUser2InDomain(IntPtr domainHandle, ref UNICODE_STRING accountName, Int32 accountType, UInt32 desiredAccess, out IntPtr userHandle, out UInt32 grantedAccess, out UInt32 relativeId);
public static extern bool ReadProcessMemory( IntPtr hProcess, IntPtr lpBaseAddress, ref UNICODE_STRING lpBuffer, IntPtr dwSize, IntPtr lpNumberOfBytesRead);
public static extern void RtlInitUnicodeString(ref UNICODE_STRING DestinationString, [MarshalAs(UnmanagedType.LPWStr)] string SourceString);
/// <summary> /// Create a new group in the specified domain. /// </summary> /// <param name="groupInfo"> /// A <see cref="LocalGroup"/> object containing information about the new group. /// </param> /// <param name="domainHandle">Handle to the domain in which to create the new group.</param> /// <returns> /// A LocalGroup object that represents the newly-created group. /// </returns> private LocalGroup CreateGroup(LocalGroup groupInfo, IntPtr domainHandle) { IntPtr aliasHandle = IntPtr.Zero; IntPtr buffer = IntPtr.Zero; UNICODE_STRING str = new UNICODE_STRING(); UInt32 status; try { UInt32 relativeId; str = new UNICODE_STRING(groupInfo.Name); buffer = Marshal.AllocHGlobal(Marshal.SizeOf(str)); Marshal.StructureToPtr(str, buffer, false); status = SamApi.SamCreateAliasInDomain(domainHandle, buffer, Win32.MAXIMUM_ALLOWED, out aliasHandle, out relativeId); ClrFacade.DestroyStructure<UNICODE_STRING>(buffer); Marshal.FreeHGlobal(buffer); buffer = IntPtr.Zero; ThrowOnFailure(status); if (!string.IsNullOrEmpty(groupInfo.Description)) { ALIAS_ADM_COMMENT_INFORMATION info = new ALIAS_ADM_COMMENT_INFORMATION(); info.AdminComment = new UNICODE_STRING(groupInfo.Description); buffer = Marshal.AllocHGlobal(Marshal.SizeOf(info)); Marshal.StructureToPtr(info, buffer, false); status = SamApi.SamSetInformationAlias(aliasHandle, ALIAS_INFORMATION_CLASS.AliasAdminCommentInformation, buffer); ClrFacade.DestroyStructure<ALIAS_ADM_COMMENT_INFORMATION>(buffer); Marshal.FreeHGlobal(buffer); buffer = IntPtr.Zero; ThrowOnFailure(status); } return MakeLocalGroupObject(new SamRidEnumeration { domainHandle = domainHandle, Name = groupInfo.Name, RelativeId = relativeId }, aliasHandle); } finally { if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer); if (aliasHandle != IntPtr.Zero) status = SamApi.SamCloseHandle(aliasHandle); } }
public static extern void RtlFreeUnicodeString(ref UNICODE_STRING UnicodeString);
private static string GetProcessParametersString(int processId, PebProcessParametersMember offsetType) { IntPtr handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, processId); if (handle == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error()); try { bool isTargetWow64Process = Is64BitChecker.IsWow64Process(handle); bool isTarget64BitProcess = Environment.Is64BitOperatingSystem && !isTargetWow64Process; long processParametersOffset = GetProcessParametersOffset(isTarget64BitProcess); long offset = GetProcessParametersMemberOffset(offsetType, isTarget64BitProcess); if (isTargetWow64Process) { IntPtr peb32 = new IntPtr(); int hr = NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessWow64Information, ref peb32, IntPtr.Size, IntPtr.Zero); if (hr != 0) throw new Win32Exception(hr); long pebAddress = peb32.ToInt64(); IntPtr pp = new IntPtr(); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); UNICODE_STRING_32 us = new UNICODE_STRING_32(); if (!ReadProcessMemory(handle, new IntPtr(pp.ToInt64() + offset), ref us, new IntPtr(Marshal.SizeOf(us)), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); if ((us.Buffer == 0) || (us.Length == 0)) return null; string s = new string('\0', us.Length / 2); if (!ReadProcessMemory(handle, new IntPtr(us.Buffer), s, new IntPtr(us.Length), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); return s; } else { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int hr = NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), IntPtr.Zero); if (hr != 0) throw new Win32Exception(hr); long pebAddress = pbi.PebBaseAddress.ToInt64(); IntPtr pp = new IntPtr(); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); UNICODE_STRING us = new UNICODE_STRING(); if (!ReadProcessMemory(handle, new IntPtr((long)pp + offset), ref us, new IntPtr(Marshal.SizeOf(us)), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); if ((us.Buffer == IntPtr.Zero) || (us.Length == 0)) return null; string s = new string('\0', us.Length / 2); if (!ReadProcessMemory(handle, us.Buffer, s, new IntPtr(us.Length), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); return s; } } finally { CloseHandle(handle); } }
public static extern int ZwQueryInformationProcess(int ProcessHandle, PROCESS_INFORMATION_CLASS ProcessInformationClass, ref UNICODE_STRING ProcessInformation, int ProcessInformationLength, out int ReturnLength);
public static extern int ZwQuerySymbolicLinkObject(int LinkHandle, ref UNICODE_STRING LinkName, out int DataWritten);
private static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS pic, ref UNICODE_STRING str, int cb, ref int pSize);
public static extern UInt32 SamConnect(ref UNICODE_STRING serverName, out IntPtr serverHandle, UInt32 desiredAccess, ref OBJECT_ATTRIBUTES objectAttributes);
/// <summary> /// Create a new user in the specified domain. /// </summary> /// <param name="userInfo"> /// A <see cref="LocalUser"/> object containing information about the new user. /// </param> /// <param name="password">A <see cref="System.Security.SecureString"/> containing /// the initial password to be set for the new local user. If this parameter is null, /// no password is set. /// </param> /// <param name="domainHandle"> /// Handle to the domain in which to create the new user. /// </param> /// <param name="setPasswordNeverExpires"> /// Indicates whether PasswordNeverExpires was specified /// </param> /// <returns> /// A LocalUser object that represents the newly-created user /// </returns> private LocalUser CreateUser(LocalUser userInfo, System.Security.SecureString password, IntPtr domainHandle, bool setPasswordNeverExpires) { IntPtr userHandle = IntPtr.Zero; IntPtr buffer = IntPtr.Zero; UNICODE_STRING str = new UNICODE_STRING(); UInt32 status = 0; try { UInt32 relativeId = 0; UInt32 grantedAccess = 0; str = new UNICODE_STRING(userInfo.Name); buffer = Marshal.AllocHGlobal(Marshal.SizeOf(str)); Marshal.StructureToPtr(str, buffer, false); status = SamApi.SamCreateUser2InDomain(domainHandle, ref str, (int) SamApi.USER_NORMAL_ACCOUNT, Win32.MAXIMUM_ALLOWED, out userHandle, out grantedAccess, out relativeId); ClrFacade.DestroyStructure<UNICODE_STRING>(buffer); Marshal.FreeHGlobal(buffer); buffer = IntPtr.Zero; ThrowOnFailure(status); // set the various properties of the user. A SID is required because some // operations depend on it. userInfo.SID = RidToSid(domainHandle, relativeId); SetUserData(userHandle, userInfo, UserProperties.AllCreateable, password, PasswordExpiredState.NotExpired, setPasswordNeverExpires); return MakeLocalUserObject(new SamRidEnumeration { domainHandle = domainHandle, Name = userInfo.Name, RelativeId = relativeId }, userHandle); } finally { if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer); if (userHandle != IntPtr.Zero) status = SamApi.SamCloseHandle(userHandle); } }
public static extern int NtQuerySymbolicLinkObject(SafeFileHandle LinkHandle, ref UNICODE_STRING LinkTarget, out int ReturnedLength);
/// <summary> /// Open the handles stored by Sam instances. /// </summary> private void OpenHandles() { var systemName = new UNICODE_STRING(); var oa = new OBJECT_ATTRIBUTES(); IntPtr pInfo = IntPtr.Zero; IntPtr pSid = IntPtr.Zero; IntPtr lsaHandle = IntPtr.Zero; UInt32 status = 0; try { status = Win32.LsaOpenPolicy(ref systemName, ref oa, (UInt32)LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION, out lsaHandle); ThrowOnFailure(status); POLICY_PRIMARY_DOMAIN_INFO domainInfo; status = Win32.LsaQueryInformationPolicy(lsaHandle, POLICY_INFORMATION_CLASS.PolicyAccountDomainInformation, out pInfo); ThrowOnFailure(status); status = Win32.LsaClose(lsaHandle); ThrowOnFailure(status); lsaHandle = IntPtr.Zero; domainInfo = ClrFacade.PtrToStructure<POLICY_PRIMARY_DOMAIN_INFO>(pInfo); status = SamApi.SamConnect(ref systemName, out samHandle, SamApi.SAM_SERVER_LOOKUP_DOMAIN, ref oa); ThrowOnFailure(status); // Open the local domain status = SamApi.SamOpenDomain(samHandle, Win32.MAXIMUM_ALLOWED, domainInfo.Sid, out localDomainHandle); ThrowOnFailure(status); // Open the "BuiltIn" domain SecurityIdentifier sid = new SecurityIdentifier("S-1-5-32"); byte[] bSid = new byte[sid.BinaryLength]; int size = ClrFacade.SizeOf<byte>() * bSid.Length; pSid = Marshal.AllocHGlobal(size); sid.GetBinaryForm(bSid, 0); Marshal.Copy(bSid, 0, pSid, bSid.Length); status = SamApi.SamOpenDomain(samHandle, Win32.MAXIMUM_ALLOWED, pSid, out builtinDomainHandle); ThrowOnFailure(status); } finally { if (pInfo != IntPtr.Zero) status = Win32.LsaFreeMemory(pInfo); Marshal.FreeHGlobal(pSid); if (lsaHandle != IntPtr.Zero) status = Win32.LsaClose(lsaHandle); } }