public NativeBitmap(int bits) { if (bits <= 0) throw new ArgumentOutOfRangeException("The number of bits must be positive."); _buffer = new MemoryAlloc(Utils.DivideUp(bits, 32) * 4); Win32.RtlInitializeBitMap(out _bitmap, _buffer, bits); }
/// <summary> /// Enumerates the handles opened by every running process. /// </summary> /// <returns>An array containing information about the handles.</returns> public static SystemHandleEntry[] GetHandles() { int retLength; int handleCount; SystemHandleEntry[] returnHandles; if (_handlesBuffer == null) { _handlesBuffer = new MemoryAlloc(0x1000); } MemoryAlloc data = _handlesBuffer; NtStatus status; // This is needed because NtQuerySystemInformation with SystemHandleInformation doesn't // actually give a real return length when called with an insufficient buffer. This code // tries repeatedly to call the function, doubling the buffer size each time it fails. while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemHandleInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) { throw new OutOfMemoryException(); } } status.ThrowIf(); // The structure of the buffer is the handle count plus an array of SYSTEM_HANDLE_INFORMATION // structures. handleCount = data.ReadStruct <SystemHandleInformation>().NumberOfHandles; returnHandles = new SystemHandleEntry[handleCount]; // Unsafe code for speed. unsafe { SystemHandleEntry *handlesPtr = (SystemHandleEntry *)((byte *)data.Memory + SystemHandleInformation.HandlesOffset); for (int i = 0; i < handleCount; i++) { //returnHandles[i] = data.ReadStruct<SystemHandleEntry>(SystemHandleInformation.HandlesOffset, i); returnHandles[i] = handlesPtr[i]; } } return(returnHandles); }
public NativeBitmap(int bits) { if (bits <= 0) { throw new ArgumentOutOfRangeException("The number of bits must be positive."); } _buffer = new MemoryAlloc(Utils.DivideUp(bits, 32) * 4); Win32.RtlInitializeBitMap(out _bitmap, _buffer, bits); }
/// <summary> /// Enumerates the modules loaded by the kernel. /// </summary> /// <param name="enumCallback">A callback for the enumeration.</param> public static void EnumKernelModules(EnumKernelModulesDelegate enumCallback) { NtStatus status; int retLength; if (_kernelModulesBuffer == null) { _kernelModulesBuffer = new MemoryAlloc(0x1000); } status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemModuleInformation, _kernelModulesBuffer, _kernelModulesBuffer.Size, out retLength ); if (status == NtStatus.InfoLengthMismatch) { _kernelModulesBuffer.ResizeNew(retLength); status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemModuleInformation, _kernelModulesBuffer, _kernelModulesBuffer.Size, out retLength ); } if (status >= NtStatus.Error) { Win32.Throw(status); } RtlProcessModules modules = _kernelModulesBuffer.ReadStruct <RtlProcessModules>(); for (int i = 0; i < modules.NumberOfModules; i++) { var module = _kernelModulesBuffer.ReadStruct <RtlProcessModuleInformation>(RtlProcessModules.ModulesOffset, i); var moduleInfo = new Debugging.ModuleInformation(module); if (!enumCallback(new KernelModule( moduleInfo.BaseAddress, moduleInfo.Size, moduleInfo.Flags, moduleInfo.BaseName, FileUtils.GetFileName(moduleInfo.FileName) ))) { break; } } }
/// <summary> /// Gets the page files currently active. /// </summary> /// <returns>A collection of page file information structures.</returns> public static SystemPagefile[] GetPagefiles() { int retLength; List <SystemPagefile> pagefiles = new List <SystemPagefile>(); using (MemoryAlloc data = new MemoryAlloc(0x200)) { NtStatus status; while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemPageFileInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) { throw new OutOfMemoryException(); } } if (status >= NtStatus.Error) { Win32.Throw(status); } pagefiles = new List <SystemPagefile>(2); int i = 0; SystemPagefileInformation currentPagefile; do { currentPagefile = data.ReadStruct <SystemPagefileInformation>(i, 0); pagefiles.Add(new SystemPagefile( currentPagefile.TotalSize, currentPagefile.TotalInUse, currentPagefile.PeakUsage, FileUtils.GetFileName(currentPagefile.PageFileName.Read()) )); i += currentPagefile.NextEntryOffset; } while (currentPagefile.NextEntryOffset != 0); return(pagefiles.ToArray()); } }
private static string GetObjectNameNt(ProcessHandle process, IntPtr handle, GenericHandle dupHandle) { int retLength; int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc oniMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength, out baseAddress) >= NtStatus.Error) { throw new Exception("ZwQueryObject failed."); } } else { if (Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) { throw new Exception("NtQueryObject failed."); } } var oni = oniMem.ReadStruct <ObjectNameInformation>(); var str = oni.Name; if (KProcessHacker.Instance != null) { str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress)); } return(str.Read()); } } throw new Exception("NtQueryObject failed."); }
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle, ProcessHandle process) { NtStatus status = NtStatus.Success; IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; GenericHandle objectHandle = null; int retLength; int baseAddress; if (KProcessHacker.Instance == null) { if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) { Win32.Throw(); } objectHandle = new GenericHandle(objectHandleI); } try { using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(ObjectBasicInformation)))) { if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength, out baseAddress); } else { status = Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength); } if (status >= NtStatus.Error) { Win32.Throw(status); } return(data.ReadStruct <ObjectBasicInformation>()); } } finally { if (objectHandle != null) { objectHandle.Dispose(); } } }
/// <summary> /// Gets a dictionary containing the services on the system. /// </summary> /// <returns>A dictionary, indexed by service name.</returns> public static Dictionary <string, EnumServiceStatusProcess> GetServices() { using (ServiceManagerHandle manager = new ServiceManagerHandle(ScManagerAccess.EnumerateService)) { int requiredSize; int servicesReturned; int resume = 0; if (_servicesBuffer == null) { _servicesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _servicesBuffer; if (!Win32.EnumServicesStatusEx(manager, IntPtr.Zero, ServiceQueryType.Win32 | ServiceQueryType.Driver, ServiceQueryState.All, data, data.Size, out requiredSize, out servicesReturned, ref resume, null)) { // resize buffer data.ResizeNew(requiredSize); if (!Win32.EnumServicesStatusEx(manager, IntPtr.Zero, ServiceQueryType.Win32 | ServiceQueryType.Driver, ServiceQueryState.All, data, data.Size, out requiredSize, out servicesReturned, ref resume, null)) { Win32.Throw(); } } var dictionary = new Dictionary <string, EnumServiceStatusProcess>(servicesReturned); for (int i = 0; i < servicesReturned; i++) { var service = data.ReadStruct <EnumServiceStatusProcess>(i); dictionary.Add(service.ServiceName, service); } return(dictionary); } }
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle, ProcessHandle process) { NtStatus status = NtStatus.Success; IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; GenericHandle objectHandle = null; int retLength; int baseAddress; if (KProcessHacker.Instance == null) { if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) Win32.Throw(); objectHandle = new GenericHandle(objectHandleI); } try { using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(ObjectBasicInformation)))) { if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength, out baseAddress); } else { status = Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength); } if (status >= NtStatus.Error) Win32.Throw(status); return data.ReadStruct<ObjectBasicInformation>(); } } finally { if (objectHandle != null) objectHandle.Dispose(); } }
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle, ProcessHandle process) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; GenericHandle objectHandle = null; int retLength; Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0 ).ThrowIf(); try { objectHandle = new GenericHandle(objectHandleI); using (MemoryAlloc data = new MemoryAlloc(ObjectBasicInformation.SizeOf)) { Win32.NtQueryObject( objectHandle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength ).ThrowIf(); return(data.ReadStruct <ObjectBasicInformation>()); } } finally { if (objectHandle != null) { objectHandle.Dispose(); } } }
public static void RefreshFileNamePrefixes() { // Just create a new dictionary to avoid having to lock the existing one. var newPrefixes = new Dictionary <string, string>(); for (char c = 'A'; c <= 'Z'; c++) { using (var data = new MemoryAlloc(1024)) { int length; if ((length = Win32.QueryDosDevice(c.ToString() + ":", data, data.Size / 2)) > 2) { newPrefixes.Add(data.ReadUnicodeString(0, length - 2), c.ToString() + ":"); } } } _fileNamePrefixes = newPrefixes; }
public static string FindFileWin32(string fileName) { using (MemoryAlloc data = new MemoryAlloc(0x400)) { IntPtr filePart; int retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart); if (retLength * 2 > data.Size) { data.ResizeNew(retLength * 2); retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart); } if (retLength == 0) return null; return data.ReadUnicodeString(0, retLength); } }
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle, ProcessHandle process) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; GenericHandle objectHandle = null; int retLength; Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0 ).ThrowIf(); try { objectHandle = new GenericHandle(objectHandleI); using (MemoryAlloc data = new MemoryAlloc(ObjectBasicInformation.SizeOf)) { Win32.NtQueryObject( objectHandle, ObjectInformationClass.ObjectBasicInformation, data, data.Size, out retLength ).ThrowIf(); return data.ReadStruct<ObjectBasicInformation>(); } } finally { if (objectHandle != null) objectHandle.Dispose(); } }
public static string FindFileWin32(string fileName) { using (MemoryAlloc data = new MemoryAlloc(0x400)) { IntPtr filePart; int retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart); if (retLength * 2 > data.Size) { data.ResizeNew(retLength * 2); retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart); } if (retLength == 0) { return(null); } return(data.ReadUnicodeString(0, retLength)); } }
public static unsafe string GetVistaFileName(int pid) { using (MemoryAlloc buffer = new MemoryAlloc(0x100)) { SystemProcessImageNameInformation info; info.ProcessId = pid; info.ImageName.Length = 0; info.ImageName.MaximumLength = 0x100; info.ImageName.Buffer = buffer; NtStatus status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessImageName, &info, SystemProcessImageNameInformation.SizeOf, null ); if (status == NtStatus.InfoLengthMismatch) { // Our buffer was too small. The required buffer length is stored in MaximumLength. buffer.ResizeNew(info.ImageName.MaximumLength); status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessImageName, &info, SystemProcessImageNameInformation.SizeOf, null ); } status.ThrowIf(); return(GetFileName(info.ImageName.Text)); } }
private static string GetObjectNameNt(ProcessHandle process, IntPtr handle, GenericHandle dupHandle) { int retLength; Win32.NtQueryObject( dupHandle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength ); if (retLength > 0) { using (MemoryAlloc oniMem = new MemoryAlloc(retLength)) { Win32.NtQueryObject( dupHandle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength ).ThrowIf(); ObjectNameInformation oni = oniMem.ReadStruct <ObjectNameInformation>(); UnicodeString str = oni.Name; //if (KProcessHacker.Instance != null) //str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress)); return(str.Text); } } throw new Exception("NtQueryObject failed."); }
/// <summary> /// Gets a dictionary containing the currently running processes. /// </summary> /// <param name="getThreads">Whether to get thread information.</param> /// <returns>A dictionary, indexed by process ID.</returns> public static Dictionary<int, SystemProcess> GetProcesses(bool getThreads) { int retLength; Dictionary<int, SystemProcess> returnProcesses; if (_processesBuffer == null) _processesBuffer = new MemoryAlloc(0x10000); MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessInformation, data, data.Size, out retLength )) >= NtStatus.Error) { if (attempts > 3) Win32.ThrowLastError(status); data.Resize(retLength); } else { break; } } returnProcesses = new Dictionary<int, SystemProcess>(32); // 32 processes on a computer? int i = 0; SystemProcess currentProcess = new SystemProcess(); do { currentProcess.Process = data.ReadStruct<SystemProcessInformation>(i, 0); currentProcess.Name = currentProcess.Process.ImageName.Read(); if (getThreads && currentProcess.Process.ProcessId != 0) { currentProcess.Threads = new Dictionary<int, SystemThreadInformation>(); for (int j = 0; j < currentProcess.Process.NumberOfThreads; j++) { var thread = data.ReadStruct<SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); currentProcess.Threads.Add(thread.ClientId.ThreadId, thread); } } returnProcesses.Add(currentProcess.Process.ProcessId, currentProcess); i += currentProcess.Process.NextEntryOffset; } while (currentProcess.Process.NextEntryOffset != 0); return returnProcesses; }
/// <summary> /// Gets a dictionary containing the threads owned by the specified process. /// </summary> /// <param name="pid">A process ID.</param> /// <returns>A dictionary, indexed by thread ID.</returns> public static Dictionary <int, SystemThreadInformation> GetProcessThreads(int pid) { int retLength; if (_processesBuffer == null) { _processesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation(SystemInformationClass.SystemProcessInformation, data.Memory, data.Size, out retLength)) >= NtStatus.Error) { if (attempts > 3) { Win32.ThrowLastError(status); } data.Resize(retLength); } else { break; } } int i = 0; SystemProcessInformation process; do { process = data.ReadStruct <SystemProcessInformation>(i, 0); if (process.ProcessId == pid) { var threads = new Dictionary <int, SystemThreadInformation>(); for (int j = 0; j < process.NumberOfThreads; j++) { var thread = data.ReadStruct <SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); threads.Add(thread.ClientId.ThreadId, thread); } return(threads); } i += process.NextEntryOffset; } while (process.NextEntryOffset != 0); return(null); }
private static string GetSignerNameFromStateData(IntPtr stateData) { // Well, here's a shitload of indirection for you... // 1. State data -> Provider data IntPtr provData = Win32.WTHelperProvDataFromStateData(stateData); if (provData == IntPtr.Zero) return null; // 2. Provider data -> Provider signer IntPtr signerInfo = Win32.WTHelperGetProvSignerFromChain(provData, 0, false, 0); if (signerInfo == IntPtr.Zero) return null; CryptProviderSgnr sngr = (CryptProviderSgnr)Marshal.PtrToStructure(signerInfo, typeof(CryptProviderSgnr)); if (sngr.CertChain == IntPtr.Zero) return null; if (sngr.CertChainCount == 0) return null; // 3. Provider signer -> Provider cert CryptProviderCert cert = (CryptProviderCert)Marshal.PtrToStructure(sngr.CertChain, typeof(CryptProviderCert)); if (cert.Cert == IntPtr.Zero) return null; // 4. Provider cert -> Cert context CertContext context = (CertContext)Marshal.PtrToStructure(cert.Cert, typeof(CertContext)); if (context.CertInfo != IntPtr.Zero) { // 5. Cert context -> Cert info CertInfo certInfo = (CertInfo)Marshal.PtrToStructure(context.CertInfo, typeof(CertInfo)); unsafe { using (MemoryAlloc buffer = new MemoryAlloc(0x200)) { int length; // 6. Cert info subject -> Subject X.500 string length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); if (length > buffer.Size / 2) { buffer.ResizeNew(length * 2); length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); } string name = buffer.ReadUnicodeString(0); // 7. Subject X.500 string -> CN or OU value string value = GetX500Value(name, "CN"); if (string.IsNullOrEmpty(value)) value = GetX500Value(name, "OU"); return value; } } } return null; }
private static string GetReparsePointTarget(FileHandle fhandle) { using (var data = new MemoryAlloc(FileSystem.MaximumReparseDataBufferSize)) { fhandle.IoControl(FileSystem.FsCtlGetReparsePoint, IntPtr.Zero, 0, data, data.Size); FileSystem.ReparseDataBuffer buffer = data.ReadStruct<FileSystem.ReparseDataBuffer>(); // Make sure it is in fact a mount point. if (buffer.ReparseTag != (uint)IoReparseTag.MountPoint) Win32.Throw(NtStatus.InvalidParameter); return data.ReadUnicodeString( FileSystem.ReparseDataBuffer.MountPointPathBuffer + buffer.SubstituteNameOffset, buffer.SubstituteNameLength / 2 ); } }
private static string GetObjectNameNt(ProcessHandle process, IntPtr handle, GenericHandle dupHandle) { int retLength; int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc oniMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength, out baseAddress) >= NtStatus.Error) throw new Exception("ZwQueryObject failed."); } else { if (Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) throw new Exception("NtQueryObject failed."); } var oni = oniMem.ReadStruct<ObjectNameInformation>(); var str = oni.Name; if (KProcessHacker.Instance != null) str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress)); return str.Read(); } } throw new Exception("NtQueryObject failed."); }
public static string GetVolumeName(string deviceName) { using (var data = new MemoryAlloc(MountMgrMountPoint.Size + deviceName.Length * 2)) { MountMgrMountPoint mountPoint = new MountMgrMountPoint(); mountPoint.DeviceNameLength = (ushort)(deviceName.Length * 2); mountPoint.DeviceNameOffset = MountMgrMountPoint.Size; data.WriteStruct<MountMgrMountPoint>(mountPoint); data.WriteUnicodeString(mountPoint.DeviceNameOffset, deviceName); using (var fhandle = OpenMountManager((FileAccess)StandardRights.Synchronize)) { NtStatus status; int retLength; using (var outData = new MemoryAlloc(0x100)) { while (true) { status = fhandle.IoControl( IoCtlQueryPoints, data.Memory, data.Size, outData.Memory, outData.Size, out retLength ); if (status == NtStatus.BufferOverflow) { outData.ResizeNew(Marshal.ReadInt32(outData.Memory)); // read Size field continue; } else { break; } } if (status >= NtStatus.Error) Win32.Throw(status); MountMgrMountPoints mountPoints = outData.ReadStruct<MountMgrMountPoints>(); // Go through the mount points given and return the first symbolic link that seems // to be a volume name. for (int i = 0; i < mountPoints.NumberOfMountPoints; i++) { MountMgrMountPoint mp = outData.ReadStruct<MountMgrMountPoint>( MountMgrMountPoints.MountPointsOffset, i ); string symLinkName; symLinkName = Marshal.PtrToStringUni( outData.Memory.Increment(mp.SymbolicLinkNameOffset), mp.SymbolicLinkNameLength / 2 ); if (IsVolumePath(symLinkName)) return symLinkName; } return null; } } } }
private static void Notify(bool created, string sourceVolumeName, string targetVolumeName) { using (var data = new MemoryAlloc( MountMgrVolumeMountPoint.Size + sourceVolumeName.Length * 2 + targetVolumeName.Length * 2 )) { MountMgrVolumeMountPoint mountPoint = new MountMgrVolumeMountPoint(); mountPoint.SourceVolumeNameLength = (ushort)(sourceVolumeName.Length * 2); mountPoint.SourceVolumeNameOffset = (ushort)MountMgrVolumeMountPoint.Size; mountPoint.TargetVolumeNameLength = (ushort)(targetVolumeName.Length * 2); mountPoint.TargetVolumeNameOffset = (ushort)(mountPoint.SourceVolumeNameOffset + mountPoint.SourceVolumeNameLength); data.WriteStruct<MountMgrVolumeMountPoint>(mountPoint); data.WriteUnicodeString(mountPoint.SourceVolumeNameOffset, sourceVolumeName); data.WriteUnicodeString(mountPoint.TargetVolumeNameOffset, targetVolumeName); using (var fhandle = OpenMountManager(FileAccess.GenericRead | FileAccess.GenericWrite)) { fhandle.IoControl( created ? IoCtlVolumeMountPointCreated : IoCtlVolumeMountPointDeleted, data.Memory, data.Size, IntPtr.Zero, 0 ); } } }
public static unsafe string GetVistaFileName(int pid) { using (MemoryAlloc buffer = new MemoryAlloc(0x100)) { SystemProcessImageNameInformation info; info.ProcessId = pid; info.ImageName.Length = 0; info.ImageName.MaximumLength = 0x100; info.ImageName.Buffer = buffer; NtStatus status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessImageName, &info, SystemProcessImageNameInformation.SizeOf, null ); if (status == NtStatus.InfoLengthMismatch) { // Our buffer was too small. The required buffer length is stored in MaximumLength. buffer.ResizeNew(info.ImageName.MaximumLength); status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessImageName, &info, SystemProcessImageNameInformation.SizeOf, null ); } status.ThrowIf(); return GetFileName(info.ImageName.Text); } }
/// <summary> /// Gets a dictionary containing the threads owned by the specified process. /// </summary> /// <param name="pid">A process ID.</param> /// <returns>A dictionary, indexed by thread ID.</returns> public static Dictionary<int, SystemThreadInformation> GetProcessThreads(int pid) { int retLength; if (_processesBuffer == null) _processesBuffer = new MemoryAlloc(0x10000); MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessInformation, data.Memory, data.Size, out retLength) ).IsError()) { if (attempts > 3) Win32.Throw(status); data.ResizeNew(retLength); } else { break; } } int i = 0; SystemProcessInformation process; do { unsafe { //process = data.ReadStruct<SystemProcessInformation>(i, 0); process = *(SystemProcessInformation*)((byte*)data.Memory + i); } if (process.ProcessId == pid) { Dictionary<int, SystemThreadInformation> threads = new Dictionary<int, SystemThreadInformation>(); for (int j = 0; j < process.NumberOfThreads; j++) { SystemThreadInformation thread = data.ReadStruct<SystemThreadInformation>(i + SystemProcessInformation.SizeOf, SystemThreadInformation.SizeOf, j); if (pid != 0) { threads.Add(thread.ClientId.ThreadId, thread); } else { // Fix System Idle Process threads. // There is one thread per CPU, but they // all have a TID of 0. Assign unique TIDs. threads.Add(j, thread); } } return threads; } i += process.NextEntryOffset; } while (process.NextEntryOffset != 0); return null; }
/// <summary> /// Gets the network connections currently active. /// </summary> /// <returns>A dictionary of network connections.</returns> public static Dictionary <int, List <NetworkConnection> > GetNetworkConnections() { var retDict = new Dictionary <int, List <NetworkConnection> >(); int length; // TCP IPv4 length = 0; Win32.GetExtendedTcpTable(IntPtr.Zero, ref length, false, AiFamily.INet, TcpTableClass.OwnerPidAll, 0); using (var mem = new MemoryAlloc(length)) { if (Win32.GetExtendedTcpTable(mem, ref length, false, AiFamily.INet, TcpTableClass.OwnerPidAll, 0) != 0) { Win32.Throw(); } int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { var struc = mem.ReadStruct <MibTcpRowOwnerPid>(sizeof(int), i); if (!retDict.ContainsKey(struc.OwningProcessId)) { retDict.Add(struc.OwningProcessId, new List <NetworkConnection>()); } retDict[struc.OwningProcessId].Add(new NetworkConnection() { Protocol = NetworkProtocol.Tcp, Local = new IPEndPoint(struc.LocalAddress, ((ushort)struc.LocalPort).Reverse()), Remote = new IPEndPoint(struc.RemoteAddress, ((ushort)struc.RemotePort).Reverse()), State = struc.State, Pid = struc.OwningProcessId }); } } // UDP IPv4 length = 0; Win32.GetExtendedUdpTable(IntPtr.Zero, ref length, false, AiFamily.INet, UdpTableClass.OwnerPid, 0); using (var mem = new MemoryAlloc(length)) { if (Win32.GetExtendedUdpTable(mem, ref length, false, AiFamily.INet, UdpTableClass.OwnerPid, 0) != 0) { Win32.Throw(); } int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { var struc = mem.ReadStruct <MibUdpRowOwnerPid>(sizeof(int), i); if (!retDict.ContainsKey(struc.OwningProcessId)) { retDict.Add(struc.OwningProcessId, new List <NetworkConnection>()); } retDict[struc.OwningProcessId].Add( new NetworkConnection() { Protocol = NetworkProtocol.Udp, Local = new IPEndPoint(struc.LocalAddress, ((ushort)struc.LocalPort).Reverse()), Pid = struc.OwningProcessId }); } } // TCP IPv6 length = 0; Win32.GetExtendedTcpTable(IntPtr.Zero, ref length, false, AiFamily.INet6, TcpTableClass.OwnerPidAll, 0); using (var mem = new MemoryAlloc(length)) { if (Win32.GetExtendedTcpTable(mem, ref length, false, AiFamily.INet6, TcpTableClass.OwnerPidAll, 0) == 0) { int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { var struc = mem.ReadStruct <MibTcp6RowOwnerPid>(sizeof(int), i); if (!retDict.ContainsKey(struc.OwningProcessId)) { retDict.Add(struc.OwningProcessId, new List <NetworkConnection>()); } retDict[struc.OwningProcessId].Add(new NetworkConnection() { Protocol = NetworkProtocol.Tcp6, Local = new IPEndPoint(new IPAddress(struc.LocalAddress, struc.LocalScopeId), ((ushort)struc.LocalPort).Reverse()), Remote = new IPEndPoint(new IPAddress(struc.RemoteAddress, struc.RemoteScopeId), ((ushort)struc.RemotePort).Reverse()), State = struc.State, Pid = struc.OwningProcessId }); } } } // UDP IPv6 length = 0; Win32.GetExtendedUdpTable(IntPtr.Zero, ref length, false, AiFamily.INet6, UdpTableClass.OwnerPid, 0); using (var mem = new MemoryAlloc(length)) { if (Win32.GetExtendedUdpTable(mem, ref length, false, AiFamily.INet6, UdpTableClass.OwnerPid, 0) == 0) { int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { var struc = mem.ReadStruct <MibUdp6RowOwnerPid>(sizeof(int), i); if (!retDict.ContainsKey(struc.OwningProcessId)) { retDict.Add(struc.OwningProcessId, new List <NetworkConnection>()); } retDict[struc.OwningProcessId].Add( new NetworkConnection() { Protocol = NetworkProtocol.Udp6, Local = new IPEndPoint(new IPAddress(struc.LocalAddress, struc.LocalScopeId), ((ushort)struc.LocalPort).Reverse()), Pid = struc.OwningProcessId }); } } } return(retDict); }
private static string GetSignerNameFromStateData(IntPtr stateData) { // Well, here's a shitload of indirection for you... // 1. State data -> Provider data IntPtr provData = Win32.WTHelperProvDataFromStateData(stateData); if (provData == IntPtr.Zero) { return(null); } // 2. Provider data -> Provider signer IntPtr signerInfo = Win32.WTHelperGetProvSignerFromChain(provData, 0, false, 0); if (signerInfo == IntPtr.Zero) { return(null); } CryptProviderSgnr sngr = (CryptProviderSgnr)Marshal.PtrToStructure(signerInfo, typeof(CryptProviderSgnr)); if (sngr.CertChain == IntPtr.Zero) { return(null); } if (sngr.CertChainCount == 0) { return(null); } // 3. Provider signer -> Provider cert CryptProviderCert cert = (CryptProviderCert)Marshal.PtrToStructure(sngr.CertChain, typeof(CryptProviderCert)); if (cert.Cert == IntPtr.Zero) { return(null); } // 4. Provider cert -> Cert context CertContext context = (CertContext)Marshal.PtrToStructure(cert.Cert, typeof(CertContext)); if (context.CertInfo != IntPtr.Zero) { // 5. Cert context -> Cert info CertInfo certInfo = (CertInfo)Marshal.PtrToStructure(context.CertInfo, typeof(CertInfo)); unsafe { using (MemoryAlloc buffer = new MemoryAlloc(0x200)) { int length; // 6. Cert info subject -> Subject X.500 string length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); if (length > buffer.Size / 2) { buffer.ResizeNew(length * 2); length = Win32.CertNameToStr( 1, new IntPtr(&certInfo.Subject), 3, buffer, buffer.Size / 2 ); } string name = buffer.ReadUnicodeString(0); // 7. Subject X.500 string -> CN or OU value string value = GetX500Value(name, "CN"); if (string.IsNullOrEmpty(value)) { value = GetX500Value(name, "OU"); } return(value); } } } return(null); }
public static VerifyResult VerifyFile(string fileName) { VerifyResult result = VerifyResult.NoSignature; using (MemoryAlloc strMem = new MemoryAlloc(fileName.Length * 2 + 2)) { WintrustFileInfo fileInfo = new WintrustFileInfo(); strMem.WriteUnicodeString(0, fileName); strMem.WriteByte(fileName.Length * 2, 0); strMem.WriteByte(fileName.Length * 2 + 1, 0); fileInfo.Size = Marshal.SizeOf(fileInfo); fileInfo.FilePath = strMem; WintrustData trustData = new WintrustData(); trustData.Size = 12 * 4; trustData.UIChoice = 2; // WTD_UI_NONE trustData.UnionChoice = 1; // WTD_CHOICE_FILE trustData.RevocationChecks = WtRevocationChecks.None; trustData.ProvFlags = WtProvFlags.Safer; if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista)) { trustData.ProvFlags |= WtProvFlags.CacheOnlyUrlRetrieval; } using (MemoryAlloc mem = new MemoryAlloc(fileInfo.Size)) { Marshal.StructureToPtr(fileInfo, mem, false); trustData.UnionData = mem; uint winTrustResult = Win32.WinVerifyTrust(IntPtr.Zero, WintrustActionGenericVerifyV2, ref trustData); result = StatusToVerifyResult(winTrustResult); } } if (result == VerifyResult.NoSignature) { using (FileHandle sourceFile = FileHandle.CreateWin32(fileName, FileAccess.GenericRead, FileShareMode.Read, FileCreationDispositionWin32.OpenExisting)) { byte[] hash = new byte[256]; int hashLength = 256; if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0)) { hash = new byte[hashLength]; if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0)) { return(VerifyResult.NoSignature); } } StringBuilder memberTag = new StringBuilder(hashLength * 2); for (int i = 0; i < hashLength; i++) { memberTag.Append(hash[i].ToString("X2")); } IntPtr catAdmin; if (!Win32.CryptCATAdminAcquireContext(out catAdmin, DriverActionVerify, 0)) { return(VerifyResult.NoSignature); } IntPtr catInfo = Win32.CryptCATAdminEnumCatalogFromHash(catAdmin, hash, hashLength, 0, IntPtr.Zero); if (catInfo == IntPtr.Zero) { Win32.CryptCATAdminReleaseContext(catAdmin, 0); return(VerifyResult.NoSignature); } CatalogInfo ci; if (!Win32.CryptCATCatalogInfoFromContext(catInfo, out ci, 0)) { Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0); Win32.CryptCATAdminReleaseContext(catAdmin, 0); return(VerifyResult.NoSignature); } WintrustCatalogInfo wci = new WintrustCatalogInfo(); wci.Size = Marshal.SizeOf(wci); wci.CatalogFilePath = ci.CatalogFile; wci.MemberFilePath = fileName; wci.MemberTag = memberTag.ToString(); WintrustData trustData = new WintrustData(); trustData.Size = 12 * 4; trustData.UIChoice = 1; trustData.UnionChoice = 2; trustData.RevocationChecks = WtRevocationChecks.None; if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista)) { trustData.ProvFlags = WtProvFlags.CacheOnlyUrlRetrieval; } using (MemoryAlloc mem = new MemoryAlloc(wci.Size)) { Marshal.StructureToPtr(wci, mem, false); try { trustData.UnionData = mem; uint winTrustResult = Win32.WinVerifyTrust(IntPtr.Zero, DriverActionVerify, ref trustData); result = StatusToVerifyResult(winTrustResult); } finally { Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0); Win32.CryptCATAdminReleaseContext(catAdmin, 0); Marshal.DestroyStructure(mem, typeof(WintrustCatalogInfo)); } } } } return(result); }
public static ObjectInformation GetHandleInfo(this SystemHandleEntry thisHandle, ProcessHandle process, bool getName) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; int retLength = 0; GenericHandle objectHandle = null; if (thisHandle.Handle == 0 || thisHandle.Handle == -1 || thisHandle.Handle == -2) { throw new WindowsException(NtStatus.InvalidHandle); } // Duplicate the handle if we're not using KPH if (KProcessHacker.Instance == null) { NtStatus status; if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) { Win32.ThrowLastError(status); } objectHandle = new GenericHandle(objectHandleI); } ObjectInformation info = new ObjectInformation(); // If the cache contains the object type's name, use it. Otherwise, query the type // for its name. lock (Windows.ObjectTypes) { if (Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { info.TypeName = Windows.ObjectTypes[thisHandle.ObjectTypeNumber]; } else { int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc otiMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength, out baseAddress) >= NtStatus.Error) { throw new Exception("ZwQueryObject failed."); } } else { if (Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength) >= NtStatus.Error) { throw new Exception("NtQueryObject failed."); } } var oti = otiMem.ReadStruct <ObjectTypeInformation>(); var str = oti.Name; if (KProcessHacker.Instance != null) { str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress)); } info.TypeName = str.Read(); Windows.ObjectTypes.Add(thisHandle.ObjectTypeNumber, info.TypeName); } } } } if (!getName) { return(info); } // Get the object's name. If the object is a file we must take special // precautions so that we don't hang. if (info.TypeName == "File") { if (KProcessHacker.Instance != null) { // Use KProcessHacker for files to avoid hangs. info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle); } else { // 0: No hack, query the thing normally. // 1: No hack, use NProcessHacker. // 2: Hack. int hackLevel = 1; // Can't use NPH because XP had a bug where a thread hanging // on NtQueryObject couldn't be terminated. if (OSVersion.IsBelowOrEqual(WindowsVersion.XP)) { hackLevel = 2; } // On Windows 7 and above the hanging bug appears to have // been fixed. Query the object normally. // UPDATE: Not so. It still happens. //if (OSVersion.IsAboveOrEqual(WindowsVersion.Seven)) // hackLevel = 0; if (hackLevel == 1) { try { // Use NProcessHacker. using (MemoryAlloc oniMem = new MemoryAlloc(0x4000)) { if (NProcessHacker.PhQueryNameFileObject( objectHandle, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) { throw new Exception("PhQueryNameFileObject failed."); } var oni = oniMem.ReadStruct <ObjectNameInformation>(); info.OrigName = oni.Name.Read(); } } catch (DllNotFoundException) { hackLevel = 2; } } if (hackLevel == 0) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } else if (hackLevel == 2) { // KProcessHacker and NProcessHacker not available. Fall back to using hack // (i.e. not querying the name at all if the access is 0x0012019f). if ((int)thisHandle.GrantedAccess != 0x0012019f) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } } } } else { // Not a file. Query the object normally. info.OrigName = GetObjectNameNt(process, handle, objectHandle); } // Get a better name for the handle. try { switch (info.TypeName) { case "File": // Resolves \Device\Harddisk1 into C:, for example. if (!string.IsNullOrEmpty(info.OrigName)) { info.BestName = FileUtils.GetFileName(info.OrigName); } break; case "Key": info.BestName = NativeUtils.FormatNativeKeyName(info.OrigName); break; case "Process": { int processId; if (KProcessHacker.Instance != null) { processId = KProcessHacker.Instance.KphGetProcessId(process, handle); if (processId == 0) { throw new Exception("Invalid PID"); } } else { using (var processHandle = new NativeHandle <ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess)) { if ((processId = Win32.GetProcessId(processHandle)) == 0) { Win32.ThrowLastError(); } } } info.BestName = (new ClientId(processId, 0)).GetName(false); } break; case "Thread": { int processId; int threadId; if (KProcessHacker.Instance != null) { threadId = KProcessHacker.Instance.KphGetThreadId(process, handle, out processId); if (threadId == 0 || processId == 0) { throw new Exception("Invalid TID or PID"); } } else { using (var threadHandle = new NativeHandle <ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess)) { var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation(); threadId = basicInfo.ClientId.ThreadId; processId = basicInfo.ClientId.ProcessId; } } info.BestName = (new ClientId(processId, threadId)).GetName(true); } break; case "TmEn": { using (var enHandleDup = new NativeHandle <EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation)) { var enHandle = EnlistmentHandle.FromHandle(enHandleDup); info.BestName = enHandle.GetBasicInformation().EnlistmentId.ToString("B"); } } break; case "TmRm": { using (var rmHandleDup = new NativeHandle <ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation)) { var rmHandle = ResourceManagerHandle.FromHandle(rmHandleDup); info.BestName = rmHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) { info.BestName = rmHandle.GetGuid().ToString("B"); } } } break; case "TmTm": { using (var tmHandleDup = new NativeHandle <TmAccess>(process, handle, TmAccess.QueryInformation)) { var tmHandle = TmHandle.FromHandle(tmHandleDup); info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.GetLogFileName())); if (string.IsNullOrEmpty(info.BestName)) { info.BestName = tmHandle.GetBasicInformation().TmIdentity.ToString("B"); } } } break; case "TmTx": { using (var transactionHandleDup = new NativeHandle <TransactionAccess>(process, handle, TransactionAccess.QueryInformation)) { var transactionHandle = TransactionHandle.FromHandle(transactionHandleDup); info.BestName = transactionHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) { info.BestName = transactionHandle.GetBasicInformation().TransactionId.ToString("B"); } } } break; case "Token": { using (var tokenHandleDup = new NativeHandle <TokenAccess>(process, handle, TokenAccess.Query)) { var tokenHandle = TokenHandle.FromHandle(tokenHandleDup); var sid = tokenHandle.GetUser(); using (sid) info.BestName = sid.GetFullName(true) + ": 0x" + tokenHandle.GetStatistics().AuthenticationId.ToString(); } } break; default: if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } break; } } catch { if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } } if (objectHandle != null) { objectHandle.Dispose(); } return(info); }
public static VerifyResult VerifyFile(string fileName, out string signerName) { VerifyResult result; using (MemoryAlloc strMem = new MemoryAlloc(fileName.Length * 2 + 2)) { WintrustFileInfo fileInfo = new WintrustFileInfo(); strMem.WriteUnicodeString(0, fileName); strMem.WriteInt16(fileName.Length * 2, 0); fileInfo.Size = WintrustFileInfo.SizeOf; fileInfo.FilePath = strMem; WintrustData trustData = new WintrustData { Size = WintrustData.SizeOf, UIChoice = 2, // WTD_UI_NONE UnionChoice = 1, // WTD_CHOICE_FILE RevocationChecks = WtdRevocationChecks.None, ProvFlags = WtdProvFlags.Safer, StateAction = WtdStateAction.Verify }; if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista)) trustData.ProvFlags |= WtdProvFlags.CacheOnlyUrlRetrieval; using (MemoryAlloc mem = new MemoryAlloc(fileInfo.Size)) { mem.WriteStruct(fileInfo); trustData.UnionData = mem; uint winTrustResult = Win32.WinVerifyTrust(IntPtr.Zero, WintrustActionGenericVerifyV2, ref trustData); result = StatusToVerifyResult(winTrustResult); try { if (result != VerifyResult.NoSignature) { signerName = GetSignerNameFromStateData(trustData.StateData); return result; } } finally { // Close the state data. trustData.StateAction = WtdStateAction.Close; Win32.WinVerifyTrust(IntPtr.Zero, WintrustActionGenericVerifyV2, ref trustData); } } } signerName = null; using (FileHandle sourceFile = FileHandle.CreateWin32(fileName, FileAccess.GenericRead, FileShareMode.Read, FileCreationDispositionWin32.OpenExisting)) { byte[] hash = new byte[256]; int hashLength = 256; if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0)) { hash = new byte[hashLength]; if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0)) return VerifyResult.NoSignature; } StringBuilder memberTag = new StringBuilder(hashLength * 2); for (int i = 0; i < hashLength; i++) memberTag.Append(hash[i].ToString("X2")); IntPtr catAdmin; if (!Win32.CryptCATAdminAcquireContext(out catAdmin, DriverActionVerify, 0)) return VerifyResult.NoSignature; IntPtr catInfo = Win32.CryptCATAdminEnumCatalogFromHash(catAdmin, hash, hashLength, 0, IntPtr.Zero); if (catInfo == IntPtr.Zero) { Win32.CryptCATAdminReleaseContext(catAdmin, 0); return VerifyResult.NoSignature; } CatalogInfo ci; if (!Win32.CryptCATCatalogInfoFromContext(catInfo, out ci, 0)) { Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0); Win32.CryptCATAdminReleaseContext(catAdmin, 0); return VerifyResult.NoSignature; } WintrustCatalogInfo wci = new WintrustCatalogInfo { Size = WintrustCatalogInfo.SizeOf, CatalogFilePath = ci.CatalogFile, MemberFilePath = fileName, MemberTag = memberTag.ToString() }; WintrustData trustData = new WintrustData { Size = WintrustData.SizeOf, UIChoice = 1, UnionChoice = 2, RevocationChecks = WtdRevocationChecks.None, StateAction = WtdStateAction.Verify }; if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista)) trustData.ProvFlags = WtdProvFlags.CacheOnlyUrlRetrieval; using (MemoryAlloc mem = new MemoryAlloc(wci.Size)) { mem.WriteStruct(wci); try { trustData.UnionData = mem; uint winTrustResult = Win32.WinVerifyTrust(IntPtr.Zero, DriverActionVerify, ref trustData); result = StatusToVerifyResult(winTrustResult); if (result != VerifyResult.NoSignature) { signerName = GetSignerNameFromStateData(trustData.StateData); } } finally { try { // Close the state data. trustData.StateAction = WtdStateAction.Close; Win32.WinVerifyTrust(IntPtr.Zero, DriverActionVerify, ref trustData); } finally { Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0); Win32.CryptCATAdminReleaseContext(catAdmin, 0); mem.DestroyStruct<WintrustCatalogInfo>(); } } } } return result; }
/// <summary> /// Enumerates the handles opened by every running process. /// </summary> /// <returns>An array containing information about the handles.</returns> public static SystemHandleEntry[] GetHandles() { int retLength; int handleCount; SystemHandleEntry[] returnHandles; if (_handlesBuffer == null) _handlesBuffer = new MemoryAlloc(0x1000); MemoryAlloc data = _handlesBuffer; NtStatus status; // This is needed because NtQuerySystemInformation with SystemHandleInformation doesn't // actually give a real return length when called with an insufficient buffer. This code // tries repeatedly to call the function, doubling the buffer size each time it fails. while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemHandleInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) throw new OutOfMemoryException(); } status.ThrowIf(); // The structure of the buffer is the handle count plus an array of SYSTEM_HANDLE_INFORMATION // structures. handleCount = data.ReadStruct<SystemHandleInformation>().NumberOfHandles; returnHandles = new SystemHandleEntry[handleCount]; // Unsafe code for speed. unsafe { SystemHandleEntry* handlesPtr = (SystemHandleEntry*)((byte*)data.Memory + SystemHandleInformation.HandlesOffset); for (int i = 0; i < handleCount; i++) { //returnHandles[i] = data.ReadStruct<SystemHandleEntry>(SystemHandleInformation.HandlesOffset, i); returnHandles[i] = handlesPtr[i]; } } return returnHandles; }
public static ObjectInformation GetHandleInfo(this SystemHandleEntry thisHandle, ProcessHandle process, bool getName) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; int retLength; GenericHandle objectHandle = null; if (thisHandle.Handle == 0 || thisHandle.Handle == -1 || thisHandle.Handle == -2) { throw new WindowsException(NtStatus.InvalidHandle); } // Duplicate the handle if we're not using KPH //if (KProcessHacker.Instance == null) { Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0 ).ThrowIf(); objectHandle = new GenericHandle(objectHandleI); } ObjectInformation info = new ObjectInformation(); // If the cache contains the object type's name, use it. Otherwise, query the type // for its name. Windows.ObjectTypesLock.AcquireShared(); try { if (Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { info.TypeName = Windows.ObjectTypes[thisHandle.ObjectTypeNumber]; } } finally { Windows.ObjectTypesLock.ReleaseShared(); } if (string.IsNullOrEmpty(info.TypeName)) { Win32.NtQueryObject( objectHandle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength ); if (retLength > 0) { using (MemoryAlloc otiMem = new MemoryAlloc(retLength)) { Win32.NtQueryObject( objectHandle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength ).ThrowIf(); ObjectTypeInformation oti = otiMem.ReadStruct <ObjectTypeInformation>(); UnicodeString str = oti.Name; //if (KProcessHacker.Instance != null) //str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress)); info.TypeName = str.Text; Windows.ObjectTypesLock.AcquireExclusive(); try { if (!Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { Windows.ObjectTypes.Add(thisHandle.ObjectTypeNumber, info.TypeName); } } finally { Windows.ObjectTypesLock.ReleaseExclusive(); } } } } if (!getName) { return(info); } // Get the object's name. If the object is a file we must take special // precautions so that we don't hang. if (string.Equals(info.TypeName, "File", StringComparison.OrdinalIgnoreCase)) { //if (KProcessHacker.Instance != null) //{ // // Use KProcessHacker for files to avoid hangs. // info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle); //} //else { // 0: No hack, query the thing normally. // 1: No hack, use NProcessHacker. // 2: Hack. int hackLevel = 1; // If we already tried to use NPH but it wasn't present, // skip to level 2. if (NphNotAvailable) { hackLevel = 2; } // Can't use NPH because XP had a bug where a thread hanging // on NtQueryObject couldn't be terminated. if (OSVersion.IsBelowOrEqual(WindowsVersion.XP)) { hackLevel = 2; } // On Windows 7 and above the hanging bug appears to have // been fixed. Query the object normally. // UPDATE: Not so. It still happens. //if (OSVersion.IsAboveOrEqual(WindowsVersion.Seven)) // hackLevel = 0; if (hackLevel == 1) { try { // Use NProcessHacker. using (MemoryAlloc oniMem = new MemoryAlloc(0x4000)) { NProcessHacker.PhQueryNameFileObject( objectHandle, oniMem, oniMem.Size, out retLength ).ThrowIf(); var oni = oniMem.ReadStruct <ObjectNameInformation>(); info.OrigName = oni.Name.Text; } } catch (DllNotFoundException) { hackLevel = 2; NphNotAvailable = true; } } if (hackLevel == 0) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } else if (hackLevel == 2) { // KProcessHacker and NProcessHacker not available. Fall back to using hack // (i.e. not querying the name at all if the access is 0x0012019f). if (thisHandle.GrantedAccess != 0x0012019f) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } } } } else { // Not a file. Query the object normally. info.OrigName = GetObjectNameNt(process, handle, objectHandle); } // Get a better name for the handle. try { switch (info.TypeName) { case "File": // Resolves \Device\HarddiskVolume1 into C:, for example. if (!string.IsNullOrEmpty(info.OrigName)) { info.BestName = FileUtils.GetFileName(info.OrigName); } break; case "Key": info.BestName = NativeUtils.FormatNativeKeyName(info.OrigName); break; case "Process": { int processId; using (NativeHandle <ProcessAccess> processHandle = new NativeHandle <ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess)) { if ((processId = Win32.GetProcessId(processHandle)) == 0) { Win32.Throw(); } } info.BestName = (new ClientId(processId, 0)).GetName(false); } break; case "Thread": { int processId; int threadId; using (var threadHandle = new NativeHandle <ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess)) { var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation(); threadId = basicInfo.ClientId.ThreadId; processId = basicInfo.ClientId.ProcessId; } info.BestName = (new ClientId(processId, threadId)).GetName(true); } break; case "TmEn": { using (NativeHandle <EnlistmentAccess> enHandleDup = new NativeHandle <EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation)) using (EnlistmentHandle enHandle = EnlistmentHandle.FromHandle(enHandleDup)) { info.BestName = enHandle.BasicInformation.EnlistmentId.ToString("B"); } } break; case "TmRm": { using (var rmHandleDup = new NativeHandle <ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation)) { var rmHandle = ResourceManagerHandle.FromHandle(rmHandleDup); info.BestName = rmHandle.Description; if (string.IsNullOrEmpty(info.BestName)) { info.BestName = rmHandle.Guid.ToString("B"); } } } break; case "TmTm": { using (NativeHandle <TmAccess> tmHandleDup = new NativeHandle <TmAccess>(process, handle, TmAccess.QueryInformation)) using (TmHandle tmHandle = TmHandle.FromHandle(tmHandleDup)) { info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.LogFileName)); if (string.IsNullOrEmpty(info.BestName)) { info.BestName = tmHandle.BasicInformation.TmIdentity.ToString("B"); } } } break; case "TmTx": { using (var transactionHandleDup = new NativeHandle <TransactionAccess>(process, handle, TransactionAccess.QueryInformation)) { TransactionHandle transactionHandle = TransactionHandle.FromHandle(transactionHandleDup); info.BestName = transactionHandle.Description; if (string.IsNullOrEmpty(info.BestName)) { info.BestName = transactionHandle.BasicInformation.TransactionId.ToString("B"); } } } break; case "Token": { using (var tokenHandleDup = new NativeHandle <TokenAccess>(process, handle, TokenAccess.Query)) using (TokenHandle tokenHandle = TokenHandle.FromHandle(tokenHandleDup)) using (tokenHandle.User) { info.BestName = tokenHandle.User.GetFullName(true) + ": 0x" + tokenHandle.Statistics.AuthenticationId; } } break; default: if (!string.IsNullOrEmpty(info.OrigName)) { info.BestName = info.OrigName; } else { info.BestName = null; } break; } } catch { if (!string.IsNullOrEmpty(info.OrigName)) { info.BestName = info.OrigName; } else { info.BestName = null; } } if (objectHandle != null) { objectHandle.Dispose(); } return(info); }
/// <summary> /// Gets the page files currently active. /// </summary> /// <returns>A collection of page file information structures.</returns> public static SystemPagefile[] GetPagefiles() { int retLength; using (MemoryAlloc data = new MemoryAlloc(0x200)) { NtStatus status; while ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemPageFileInformation, data, data.Size, out retLength) ) == NtStatus.InfoLengthMismatch) { data.ResizeNew(data.Size * 2); // Fail if we've resized it to over 16MB - protect from infinite resizing if (data.Size > 16 * 1024 * 1024) throw new OutOfMemoryException(); } status.ThrowIf(); List<SystemPagefile> pagefiles = new List<SystemPagefile>(2); int i = 0; SystemPagefileInformation currentPagefile; do { currentPagefile = data.ReadStruct<SystemPagefileInformation>(i, SystemPagefileInformation.SizeOf, 0); pagefiles.Add(new SystemPagefile( currentPagefile.TotalSize, currentPagefile.TotalInUse, currentPagefile.PeakUsage, FileUtils.GetFileName(currentPagefile.PageFileName.Text) )); i += currentPagefile.NextEntryOffset; } while (currentPagefile.NextEntryOffset != 0); return pagefiles.ToArray(); } }
public static VerifyResult VerifyFile(string fileName) { VerifyResult result = VerifyResult.NoSignature; using (MemoryAlloc strMem = new MemoryAlloc(fileName.Length * 2 + 2)) { WintrustFileInfo fileInfo = new WintrustFileInfo(); strMem.WriteUnicodeString(0, fileName); strMem.WriteByte(fileName.Length * 2, 0); strMem.WriteByte(fileName.Length * 2 + 1, 0); fileInfo.Size = Marshal.SizeOf(fileInfo); fileInfo.FilePath = strMem; WintrustData trustData = new WintrustData(); trustData.Size = 12 * 4; trustData.UIChoice = 2; // WTD_UI_NONE trustData.UnionChoice = 1; // WTD_CHOICE_FILE trustData.RevocationChecks = WtRevocationChecks.None; trustData.ProvFlags = WtProvFlags.Safer; if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista)) trustData.ProvFlags |= WtProvFlags.CacheOnlyUrlRetrieval; using (MemoryAlloc mem = new MemoryAlloc(fileInfo.Size)) { Marshal.StructureToPtr(fileInfo, mem, false); trustData.UnionData = mem; uint winTrustResult = Win32.WinVerifyTrust(IntPtr.Zero, WintrustActionGenericVerifyV2, ref trustData); result = StatusToVerifyResult(winTrustResult); } } if (result == VerifyResult.NoSignature) { using (FileHandle sourceFile = FileHandle.CreateWin32(fileName, FileAccess.GenericRead, FileShareMode.Read, FileCreationDispositionWin32.OpenExisting)) { byte[] hash = new byte[256]; int hashLength = 256; if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0)) { hash = new byte[hashLength]; if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0)) return VerifyResult.NoSignature; } StringBuilder memberTag = new StringBuilder(hashLength * 2); for (int i = 0; i < hashLength; i++) memberTag.Append(hash[i].ToString("X2")); IntPtr catAdmin; if (!Win32.CryptCATAdminAcquireContext(out catAdmin, DriverActionVerify, 0)) return VerifyResult.NoSignature; IntPtr catInfo = Win32.CryptCATAdminEnumCatalogFromHash(catAdmin, hash, hashLength, 0, IntPtr.Zero); if (catInfo == IntPtr.Zero) { Win32.CryptCATAdminReleaseContext(catAdmin, 0); return VerifyResult.NoSignature; } CatalogInfo ci; if (!Win32.CryptCATCatalogInfoFromContext(catInfo, out ci, 0)) { Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0); Win32.CryptCATAdminReleaseContext(catAdmin, 0); return VerifyResult.NoSignature; } WintrustCatalogInfo wci = new WintrustCatalogInfo(); wci.Size = Marshal.SizeOf(wci); wci.CatalogFilePath = ci.CatalogFile; wci.MemberFilePath = fileName; wci.MemberTag = memberTag.ToString(); WintrustData trustData = new WintrustData(); trustData.Size = 12 * 4; trustData.UIChoice = 1; trustData.UnionChoice = 2; trustData.RevocationChecks = WtRevocationChecks.None; if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista)) trustData.ProvFlags = WtProvFlags.CacheOnlyUrlRetrieval; using (MemoryAlloc mem = new MemoryAlloc(wci.Size)) { Marshal.StructureToPtr(wci, mem, false); try { trustData.UnionData = mem; uint winTrustResult = Win32.WinVerifyTrust(IntPtr.Zero, DriverActionVerify, ref trustData); result = StatusToVerifyResult(winTrustResult); } finally { Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0); Win32.CryptCATAdminReleaseContext(catAdmin, 0); Marshal.DestroyStructure(mem, typeof(WintrustCatalogInfo)); } } } } return result; }
public static string GetDeviceName(FileHandle fhandle) { using (var data = new MemoryAlloc(600)) { fhandle.IoControl(IoCtlQueryDeviceName, IntPtr.Zero, 0, data, data.Size); MountDevName name = data.ReadStruct<MountDevName>(); return data.ReadUnicodeString(MountDevName.NameOffset, name.NameLength / 2); } }
private void M1Internal() { using (MemoryAlloc alloc = new MemoryAlloc(0x1000)) { using (ProcessHandle phandle = new ProcessHandle(_pid, ProcessAccess.QueryInformation | Program.MinProcessWriteMemoryRights)) { phandle.EnumMemory(info => { for (int i = 0; i < info.RegionSize.ToInt32(); i += 0x1000) { try { phandle.WriteMemory(info.BaseAddress.Increment(i), (IntPtr)alloc, 0x1000); } catch { } } return true; }); } } }
/// <summary> /// Gets a dictionary containing the threads owned by the specified process. /// </summary> /// <param name="pid">A process ID.</param> /// <returns>A dictionary, indexed by thread ID.</returns> public static Dictionary<int, SystemThreadInformation> GetProcessThreads(int pid) { int retLength; if (_processesBuffer == null) _processesBuffer = new MemoryAlloc(0x10000); MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation(SystemInformationClass.SystemProcessInformation, data.Memory, data.Size, out retLength)) >= NtStatus.Error) { if (attempts > 3) Win32.ThrowLastError(status); data.Resize(retLength); } else { break; } } int i = 0; SystemProcessInformation process; do { process = data.ReadStruct<SystemProcessInformation>(i, 0); if (process.ProcessId == pid) { var threads = new Dictionary<int, SystemThreadInformation>(); for (int j = 0; j < process.NumberOfThreads; j++) { var thread = data.ReadStruct<SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); threads.Add(thread.ClientId.ThreadId, thread); } return threads; } i += process.NextEntryOffset; } while (process.NextEntryOffset != 0); return null; }
public static ObjectInformation GetHandleInfo(this SystemHandleEntry thisHandle, ProcessHandle process, bool getName) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; int retLength = 0; GenericHandle objectHandle = null; if (thisHandle.Handle == 0 || thisHandle.Handle == -1 || thisHandle.Handle == -2) throw new WindowsException(NtStatus.InvalidHandle); // Duplicate the handle if we're not using KPH if (KProcessHacker.Instance == null) { NtStatus status; if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) Win32.Throw(status); objectHandle = new GenericHandle(objectHandleI); } ObjectInformation info = new ObjectInformation(); // If the cache contains the object type's name, use it. Otherwise, query the type // for its name. Windows.ObjectTypesLock.AcquireShared(); try { if (Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { info.TypeName = Windows.ObjectTypes[thisHandle.ObjectTypeNumber]; } } finally { Windows.ObjectTypesLock.ReleaseShared(); } if (info.TypeName == null) { int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc otiMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength, out baseAddress) >= NtStatus.Error) throw new Exception("ZwQueryObject failed."); } else { if (Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength) >= NtStatus.Error) throw new Exception("NtQueryObject failed."); } var oti = otiMem.ReadStruct<ObjectTypeInformation>(); var str = oti.Name; if (KProcessHacker.Instance != null) str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress)); info.TypeName = str.Read(); Windows.ObjectTypesLock.AcquireExclusive(); try { if (!Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) Windows.ObjectTypes.Add(thisHandle.ObjectTypeNumber, info.TypeName); } finally { Windows.ObjectTypesLock.ReleaseExclusive(); } } } } if (!getName) return info; // Get the object's name. If the object is a file we must take special // precautions so that we don't hang. if (info.TypeName == "File") { if (KProcessHacker.Instance != null) { // Use KProcessHacker for files to avoid hangs. info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle); } else { // 0: No hack, query the thing normally. // 1: No hack, use NProcessHacker. // 2: Hack. int hackLevel = 1; // If we already tried to use NPH but it wasn't present, // skip to level 2. if (NphNotAvailable) hackLevel = 2; // Can't use NPH because XP had a bug where a thread hanging // on NtQueryObject couldn't be terminated. if (OSVersion.IsBelowOrEqual(WindowsVersion.XP)) hackLevel = 2; // On Windows 7 and above the hanging bug appears to have // been fixed. Query the object normally. // UPDATE: Not so. It still happens. //if (OSVersion.IsAboveOrEqual(WindowsVersion.Seven)) // hackLevel = 0; if (hackLevel == 1) { try { // Use NProcessHacker. using (MemoryAlloc oniMem = new MemoryAlloc(0x4000)) { if (NProcessHacker.PhQueryNameFileObject( objectHandle, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) throw new Exception("PhQueryNameFileObject failed."); var oni = oniMem.ReadStruct<ObjectNameInformation>(); info.OrigName = oni.Name.Read(); } } catch (DllNotFoundException) { hackLevel = 2; NphNotAvailable = true; } } if (hackLevel == 0) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } else if (hackLevel == 2) { // KProcessHacker and NProcessHacker not available. Fall back to using hack // (i.e. not querying the name at all if the access is 0x0012019f). if ((int)thisHandle.GrantedAccess != 0x0012019f) info.OrigName = GetObjectNameNt(process, handle, objectHandle); } } } else { // Not a file. Query the object normally. info.OrigName = GetObjectNameNt(process, handle, objectHandle); } // Get a better name for the handle. try { switch (info.TypeName) { case "File": // Resolves \Device\HarddiskVolume1 into C:, for example. if (!string.IsNullOrEmpty(info.OrigName)) info.BestName = FileUtils.GetFileName(info.OrigName); break; case "Key": info.BestName = NativeUtils.FormatNativeKeyName(info.OrigName); break; case "Process": { int processId; if (KProcessHacker.Instance != null) { processId = KProcessHacker.Instance.KphGetProcessId(process, handle); if (processId == 0) throw new Exception("Invalid PID"); } else { using (var processHandle = new NativeHandle<ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess)) { if ((processId = Win32.GetProcessId(processHandle)) == 0) Win32.Throw(); } } info.BestName = (new ClientId(processId, 0)).GetName(false); } break; case "Thread": { int processId; int threadId; if (KProcessHacker.Instance != null) { threadId = KProcessHacker.Instance.KphGetThreadId(process, handle, out processId); if (threadId == 0 || processId == 0) throw new Exception("Invalid TID or PID"); } else { using (var threadHandle = new NativeHandle<ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess)) { var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation(); threadId = basicInfo.ClientId.ThreadId; processId = basicInfo.ClientId.ProcessId; } } info.BestName = (new ClientId(processId, threadId)).GetName(true); } break; case "TmEn": { using (var enHandleDup = new NativeHandle<EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation)) { var enHandle = EnlistmentHandle.FromHandle(enHandleDup); info.BestName = enHandle.GetBasicInformation().EnlistmentId.ToString("B"); } } break; case "TmRm": { using (var rmHandleDup = new NativeHandle<ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation)) { var rmHandle = ResourceManagerHandle.FromHandle(rmHandleDup); info.BestName = rmHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) info.BestName = rmHandle.GetGuid().ToString("B"); } } break; case "TmTm": { using (var tmHandleDup = new NativeHandle<TmAccess>(process, handle, TmAccess.QueryInformation)) { var tmHandle = TmHandle.FromHandle(tmHandleDup); info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.GetLogFileName())); if (string.IsNullOrEmpty(info.BestName)) info.BestName = tmHandle.GetBasicInformation().TmIdentity.ToString("B"); } } break; case "TmTx": { using (var transactionHandleDup = new NativeHandle<TransactionAccess>(process, handle, TransactionAccess.QueryInformation)) { var transactionHandle = TransactionHandle.FromHandle(transactionHandleDup); info.BestName = transactionHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) info.BestName = transactionHandle.GetBasicInformation().TransactionId.ToString("B"); } } break; case "Token": { using (var tokenHandleDup = new NativeHandle<TokenAccess>(process, handle, TokenAccess.Query)) { var tokenHandle = TokenHandle.FromHandle(tokenHandleDup); var sid = tokenHandle.GetUser(); using (sid) info.BestName = sid.GetFullName(true) + ": 0x" + tokenHandle.GetStatistics().AuthenticationId.ToString(); } } break; default: if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } break; } } catch { if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } } if (objectHandle != null) objectHandle.Dispose(); return info; }
public static ObjectInformation GetHandleInfo(this SystemHandleEntry thisHandle, ProcessHandle process, bool getName) { IntPtr handle = new IntPtr(thisHandle.Handle); IntPtr objectHandleI; int retLength = 0; GenericHandle objectHandle = null; if (thisHandle.Handle == 0 || thisHandle.Handle == -1 || thisHandle.Handle == -2) throw new WindowsException(NtStatus.InvalidHandle); if (KProcessHacker.Instance == null) { NtStatus status; if ((status = Win32.NtDuplicateObject( process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error) Win32.ThrowLastError(status); objectHandle = new GenericHandle(objectHandleI); } ObjectInformation info = new ObjectInformation(); lock (Windows.ObjectTypes) { if (Windows.ObjectTypes.ContainsKey(thisHandle.ObjectTypeNumber)) { info.TypeName = Windows.ObjectTypes[thisHandle.ObjectTypeNumber]; } else { int baseAddress = 0; if (KProcessHacker.Instance != null) { KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength, out baseAddress); } else { Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, IntPtr.Zero, 0, out retLength); } if (retLength > 0) { using (MemoryAlloc otiMem = new MemoryAlloc(retLength)) { if (KProcessHacker.Instance != null) { if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength, out baseAddress) >= NtStatus.Error) throw new Exception("ZwQueryObject failed."); } else { if (Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation, otiMem, otiMem.Size, out retLength) >= NtStatus.Error) throw new Exception("NtQueryObject failed."); } var oti = otiMem.ReadStruct<ObjectTypeInformation>(); var str = oti.Name; if (KProcessHacker.Instance != null) str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress)); info.TypeName = str.Read(); Windows.ObjectTypes.Add(thisHandle.ObjectTypeNumber, info.TypeName); } } } } if (!getName) return info; if (info.TypeName == "File") { if (KProcessHacker.Instance != null) { info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle); } else { int hackLevel = 1; if (OSVersion.IsBelowOrEqual(WindowsVersion.XP)) hackLevel = 2; if (hackLevel == 1) { try { using (MemoryAlloc oniMem = new MemoryAlloc(0x4000)) { if (NProcessHacker.PhQueryNameFileObject( objectHandle, oniMem, oniMem.Size, out retLength) >= NtStatus.Error) throw new Exception("PhQueryNameFileObject failed."); var oni = oniMem.ReadStruct<ObjectNameInformation>(); info.OrigName = oni.Name.Read(); } } catch (DllNotFoundException) { hackLevel = 2; } } if (hackLevel == 0) { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } else if (hackLevel == 2) { if ((int)thisHandle.GrantedAccess != 0x0012019f) info.OrigName = GetObjectNameNt(process, handle, objectHandle); } } } else { info.OrigName = GetObjectNameNt(process, handle, objectHandle); } try { switch (info.TypeName) { case "File": if (!string.IsNullOrEmpty(info.OrigName)) info.BestName = FileUtils.GetFileName(info.OrigName); break; case "Key": info.BestName = NativeUtils.FormatNativeKeyName(info.OrigName); break; case "Process": { int processId; if (KProcessHacker.Instance != null) { processId = KProcessHacker.Instance.KphGetProcessId(process, handle); if (processId == 0) throw new Exception("Invalid PID"); } else { using (var processHandle = new NativeHandle<ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess)) { if ((processId = Win32.GetProcessId(processHandle)) == 0) Win32.ThrowLastError(); } } info.BestName = (new ClientId(processId, 0)).GetName(false); } break; case "Thread": { int processId; int threadId; if (KProcessHacker.Instance != null) { threadId = KProcessHacker.Instance.KphGetThreadId(process, handle, out processId); if (threadId == 0 || processId == 0) throw new Exception("Invalid TID or PID"); } else { using (var threadHandle = new NativeHandle<ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess)) { var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation(); threadId = basicInfo.ClientId.ThreadId; processId = basicInfo.ClientId.ProcessId; } } info.BestName = (new ClientId(processId, threadId)).GetName(true); } break; case "TmEn": { using (var enHandleDup = new NativeHandle<EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation)) { var enHandle = EnlistmentHandle.FromHandle(enHandleDup); info.BestName = enHandle.GetBasicInformation().EnlistmentId.ToString("B"); } } break; case "TmRm": { using (var rmHandleDup = new NativeHandle<ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation)) { var rmHandle = ResourceManagerHandle.FromHandle(rmHandleDup); info.BestName = rmHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) info.BestName = rmHandle.GetGuid().ToString("B"); } } break; case "TmTm": { using (var tmHandleDup = new NativeHandle<TmAccess>(process, handle, TmAccess.QueryInformation)) { var tmHandle = TmHandle.FromHandle(tmHandleDup); info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.GetLogFileName())); if (string.IsNullOrEmpty(info.BestName)) info.BestName = tmHandle.GetBasicInformation().TmIdentity.ToString("B"); } } break; case "TmTx": { using (var transactionHandleDup = new NativeHandle<TransactionAccess>(process, handle, TransactionAccess.QueryInformation)) { var transactionHandle = TransactionHandle.FromHandle(transactionHandleDup); info.BestName = transactionHandle.GetDescription(); if (string.IsNullOrEmpty(info.BestName)) info.BestName = transactionHandle.GetBasicInformation().TransactionId.ToString("B"); } } break; case "Token": { using (var tokenHandleDup = new NativeHandle<TokenAccess>(process, handle, TokenAccess.Query)) { var tokenHandle = TokenHandle.FromHandle(tokenHandleDup); var sid = tokenHandle.GetUser(); using (sid) info.BestName = sid.GetFullName(true) + ": 0x" + tokenHandle.GetStatistics().AuthenticationId.ToString(); } } break; default: if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } break; } } catch { if (info.OrigName != null && info.OrigName != "") { info.BestName = info.OrigName; } else { info.BestName = null; } } if (objectHandle != null) objectHandle.Dispose(); return info; }
/// <summary> /// Enumerates the modules loaded by the kernel. /// </summary> /// <param name="enumCallback">A callback for the enumeration.</param> public static void EnumKernelModules(EnumKernelModulesDelegate enumCallback) { int retLength; if (_kernelModulesBuffer == null) _kernelModulesBuffer = new MemoryAlloc(0x1000); NtStatus status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemModuleInformation, _kernelModulesBuffer, _kernelModulesBuffer.Size, out retLength ); if (status == NtStatus.InfoLengthMismatch) { _kernelModulesBuffer.ResizeNew(retLength); status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemModuleInformation, _kernelModulesBuffer, _kernelModulesBuffer.Size, out retLength ); } status.ThrowIf(); RtlProcessModules modules = _kernelModulesBuffer.ReadStruct<RtlProcessModules>(); for (int i = 0; i < modules.NumberOfModules; i++) { var module = _kernelModulesBuffer.ReadStruct<RtlProcessModuleInformation>(RtlProcessModules.ModulesOffset, RtlProcessModuleInformation.SizeOf, i); var moduleInfo = new Debugging.ModuleInformation(module); if (!enumCallback(new KernelModule( moduleInfo.BaseAddress, moduleInfo.Size, moduleInfo.Flags, moduleInfo.BaseName, FileUtils.GetFileName(moduleInfo.FileName) ))) break; } }
public static VerifyResult VerifyFile(string fileName, out string signerName) { VerifyResult result; using (MemoryAlloc strMem = new MemoryAlloc(fileName.Length * 2 + 2)) { WintrustFileInfo fileInfo = new WintrustFileInfo(); strMem.WriteUnicodeString(0, fileName); strMem.WriteInt16(fileName.Length * 2, 0); fileInfo.Size = WintrustFileInfo.SizeOf; fileInfo.FilePath = strMem; WintrustData trustData = new WintrustData { Size = WintrustData.SizeOf, UIChoice = 2, // WTD_UI_NONE UnionChoice = 1, // WTD_CHOICE_FILE RevocationChecks = WtdRevocationChecks.None, ProvFlags = WtdProvFlags.Safer, StateAction = WtdStateAction.Verify }; if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista)) { trustData.ProvFlags |= WtdProvFlags.CacheOnlyUrlRetrieval; } using (MemoryAlloc mem = new MemoryAlloc(fileInfo.Size)) { mem.WriteStruct(fileInfo); trustData.UnionData = mem; uint winTrustResult = Win32.WinVerifyTrust(IntPtr.Zero, WintrustActionGenericVerifyV2, ref trustData); result = StatusToVerifyResult(winTrustResult); try { if (result != VerifyResult.NoSignature) { signerName = GetSignerNameFromStateData(trustData.StateData); return(result); } } finally { // Close the state data. trustData.StateAction = WtdStateAction.Close; Win32.WinVerifyTrust(IntPtr.Zero, WintrustActionGenericVerifyV2, ref trustData); } } } signerName = null; using (FileHandle sourceFile = FileHandle.CreateWin32(fileName, FileAccess.GenericRead, FileShareMode.Read, FileCreationDispositionWin32.OpenExisting)) { byte[] hash = new byte[256]; int hashLength = 256; if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0)) { hash = new byte[hashLength]; if (!Win32.CryptCATAdminCalcHashFromFileHandle(sourceFile, ref hashLength, hash, 0)) { return(VerifyResult.NoSignature); } } StringBuilder memberTag = new StringBuilder(hashLength * 2); for (int i = 0; i < hashLength; i++) { memberTag.Append(hash[i].ToString("X2")); } IntPtr catAdmin; if (!Win32.CryptCATAdminAcquireContext(out catAdmin, DriverActionVerify, 0)) { return(VerifyResult.NoSignature); } IntPtr catInfo = Win32.CryptCATAdminEnumCatalogFromHash(catAdmin, hash, hashLength, 0, IntPtr.Zero); if (catInfo == IntPtr.Zero) { Win32.CryptCATAdminReleaseContext(catAdmin, 0); return(VerifyResult.NoSignature); } CatalogInfo ci; if (!Win32.CryptCATCatalogInfoFromContext(catInfo, out ci, 0)) { Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0); Win32.CryptCATAdminReleaseContext(catAdmin, 0); return(VerifyResult.NoSignature); } WintrustCatalogInfo wci = new WintrustCatalogInfo { Size = WintrustCatalogInfo.SizeOf, CatalogFilePath = ci.CatalogFile, MemberFilePath = fileName, MemberTag = memberTag.ToString() }; WintrustData trustData = new WintrustData { Size = WintrustData.SizeOf, UIChoice = 1, UnionChoice = 2, RevocationChecks = WtdRevocationChecks.None, StateAction = WtdStateAction.Verify }; if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista)) { trustData.ProvFlags = WtdProvFlags.CacheOnlyUrlRetrieval; } using (MemoryAlloc mem = new MemoryAlloc(wci.Size)) { mem.WriteStruct(wci); try { trustData.UnionData = mem; uint winTrustResult = Win32.WinVerifyTrust(IntPtr.Zero, DriverActionVerify, ref trustData); result = StatusToVerifyResult(winTrustResult); if (result != VerifyResult.NoSignature) { signerName = GetSignerNameFromStateData(trustData.StateData); } } finally { try { // Close the state data. trustData.StateAction = WtdStateAction.Close; Win32.WinVerifyTrust(IntPtr.Zero, DriverActionVerify, ref trustData); } finally { Win32.CryptCATAdminReleaseCatalogContext(catAdmin, catInfo, 0); Win32.CryptCATAdminReleaseContext(catAdmin, 0); mem.DestroyStruct <WintrustCatalogInfo>(); } } } } return(result); }
/// <summary> /// Gets the network connections currently active. /// </summary> /// <returns>A dictionary of network connections.</returns> public static Dictionary<int, List<NetworkConnection>> GetNetworkConnections() { var retDict = new Dictionary<int, List<NetworkConnection>>(); int length = 0; // TCP IPv4 Win32.GetExtendedTcpTable(IntPtr.Zero, ref length, false, AiFamily.INet, TcpTableClass.OwnerPidAll, 0); using (MemoryAlloc mem = new MemoryAlloc(length)) { if (Win32.GetExtendedTcpTable(mem, ref length, false, AiFamily.INet, TcpTableClass.OwnerPidAll, 0) != 0) Win32.Throw(); int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { MibTcpRowOwnerPid struc = mem.ReadStruct<MibTcpRowOwnerPid>(sizeof(int), MibTcpRowOwnerPid.SizeOf, i); if (!retDict.ContainsKey(struc.OwningProcessId)) retDict.Add(struc.OwningProcessId, new List<NetworkConnection>()); retDict[struc.OwningProcessId].Add(new NetworkConnection { Protocol = NetworkProtocol.Tcp, Local = new IPEndPoint(struc.LocalAddress, ((ushort)struc.LocalPort).Reverse()), Remote = new IPEndPoint(struc.RemoteAddress, ((ushort)struc.RemotePort).Reverse()), State = struc.State, Pid = struc.OwningProcessId }); } } // UDP IPv4 length = 0; Win32.GetExtendedUdpTable(IntPtr.Zero, ref length, false, AiFamily.INet, UdpTableClass.OwnerPid, 0); using (MemoryAlloc mem = new MemoryAlloc(length)) { if (Win32.GetExtendedUdpTable(mem, ref length, false, AiFamily.INet, UdpTableClass.OwnerPid, 0) != 0) Win32.Throw(); int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { MibUdpRowOwnerPid struc = mem.ReadStruct<MibUdpRowOwnerPid>(sizeof(int), MibUdpRowOwnerPid.SizeOf, i); if (!retDict.ContainsKey(struc.OwningProcessId)) retDict.Add(struc.OwningProcessId, new List<NetworkConnection>()); retDict[struc.OwningProcessId].Add(new NetworkConnection { Protocol = NetworkProtocol.Udp, Local = new IPEndPoint(struc.LocalAddress, ((ushort)struc.LocalPort).Reverse()), Pid = struc.OwningProcessId }); } } // TCP IPv6 length = 0; Win32.GetExtendedTcpTable(IntPtr.Zero, ref length, false, AiFamily.INet6, TcpTableClass.OwnerPidAll, 0); using (MemoryAlloc mem = new MemoryAlloc(length)) { if (Win32.GetExtendedTcpTable(mem, ref length, false, AiFamily.INet6, TcpTableClass.OwnerPidAll, 0) == 0) { int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { MibTcp6RowOwnerPid struc = mem.ReadStruct<MibTcp6RowOwnerPid>(sizeof(int), MibTcp6RowOwnerPid.SizeOf, i); if (!retDict.ContainsKey(struc.OwningProcessId)) retDict.Add(struc.OwningProcessId, new List<NetworkConnection>()); retDict[struc.OwningProcessId].Add(new NetworkConnection { Protocol = NetworkProtocol.Tcp6, Local = new IPEndPoint(new IPAddress(struc.LocalAddress, struc.LocalScopeId), ((ushort)struc.LocalPort).Reverse()), Remote = new IPEndPoint(new IPAddress(struc.RemoteAddress, struc.RemoteScopeId), ((ushort)struc.RemotePort).Reverse()), State = struc.State, Pid = struc.OwningProcessId }); } } } // UDP IPv6 length = 0; Win32.GetExtendedUdpTable(IntPtr.Zero, ref length, false, AiFamily.INet6, UdpTableClass.OwnerPid, 0); using (MemoryAlloc mem = new MemoryAlloc(length)) { if (Win32.GetExtendedUdpTable(mem, ref length, false, AiFamily.INet6, UdpTableClass.OwnerPid, 0) == 0) { int count = mem.ReadInt32(0); for (int i = 0; i < count; i++) { MibUdp6RowOwnerPid struc = mem.ReadStruct<MibUdp6RowOwnerPid>(sizeof(int), MibUdp6RowOwnerPid.SizeOf, i); if (!retDict.ContainsKey(struc.OwningProcessId)) retDict.Add(struc.OwningProcessId, new List<NetworkConnection>()); retDict[struc.OwningProcessId].Add(new NetworkConnection { Protocol = NetworkProtocol.Udp6, Local = new IPEndPoint(new IPAddress(struc.LocalAddress, struc.LocalScopeId), ((ushort)struc.LocalPort).Reverse()), Pid = struc.OwningProcessId }); } } } return retDict; }
private static string GetObjectNameNt(ProcessHandle process, IntPtr handle, GenericHandle dupHandle) { int retLength; Win32.NtQueryObject( dupHandle, ObjectInformationClass.ObjectNameInformation, IntPtr.Zero, 0, out retLength ); if (retLength > 0) { using (MemoryAlloc oniMem = new MemoryAlloc(retLength)) { Win32.NtQueryObject( dupHandle, ObjectInformationClass.ObjectNameInformation, oniMem, oniMem.Size, out retLength ).ThrowIf(); ObjectNameInformation oni = oniMem.ReadStruct<ObjectNameInformation>(); UnicodeString str = oni.Name; //if (KProcessHacker.Instance != null) //str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress)); return str.Text; } } throw new Exception("NtQueryObject failed."); }
/// <summary> /// Gets a dictionary containing the currently running processes. /// </summary> /// <param name="getThreads">Whether to get thread information.</param> /// <returns>A dictionary, indexed by process ID.</returns> public static Dictionary<int, SystemProcess> GetProcesses(bool getThreads) { int retLength; if (_processesBuffer == null) _processesBuffer = new MemoryAlloc(0x10000); MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessInformation, data, data.Size, out retLength )).IsError()) { if (attempts > 3) Win32.Throw(status); data.ResizeNew(retLength); } else { break; } } Dictionary<int, SystemProcess> returnProcesses = new Dictionary<int, SystemProcess>(32); int i = 0; SystemProcess currentProcess = new SystemProcess(); do { //currentProcess.Process = data.ReadStruct<SystemProcessInformation>(i, 0); unsafe { currentProcess.Process = *(SystemProcessInformation*)((byte*)data.Memory + i); } currentProcess.Name = currentProcess.Process.ImageName.Text; if (getThreads && currentProcess.Process.ProcessId != 0) { currentProcess.Threads = new Dictionary<int, SystemThreadInformation>(); for (int j = 0; j < currentProcess.Process.NumberOfThreads; j++) { var thread = data.ReadStruct<SystemThreadInformation>(i + SystemProcessInformation.SizeOf, SystemThreadInformation.SizeOf, j); currentProcess.Threads.Add(thread.ClientId.ThreadId, thread); } } returnProcesses.Add(currentProcess.Process.ProcessId, currentProcess); i += currentProcess.Process.NextEntryOffset; } while (currentProcess.Process.NextEntryOffset != 0); return returnProcesses; }
private static void DeleteSymbolicLink(string path) { using (var data = new MemoryAlloc(MountMgrMountPoint.Size + path.Length * 2)) using (var outData = new MemoryAlloc(1600)) { MountMgrMountPoint mountPoint = new MountMgrMountPoint(); mountPoint.SymbolicLinkNameLength = (ushort)(path.Length * 2); mountPoint.SymbolicLinkNameOffset = MountMgrMountPoint.Size; data.WriteStruct<MountMgrMountPoint>(mountPoint); data.WriteUnicodeString(mountPoint.SymbolicLinkNameOffset, path); using (var fhandle = OpenMountManager(FileAccess.GenericRead | FileAccess.GenericWrite)) { fhandle.IoControl(IoCtlDeletePoints, data.Memory, data.Size, outData.Memory, outData.Size); } } }
/// <summary> /// Gets a dictionary containing the services on the system. /// </summary> /// <returns>A dictionary, indexed by service name.</returns> public static Dictionary<string, EnumServiceStatusProcess> GetServices() { using (ServiceManagerHandle manager = new ServiceManagerHandle(ScManagerAccess.EnumerateService)) { int requiredSize; int servicesReturned; int resume = 0; if (_servicesBuffer == null) _servicesBuffer = new MemoryAlloc(0x10000); MemoryAlloc data = _servicesBuffer; if (!Win32.EnumServicesStatusEx(manager, IntPtr.Zero, ServiceQueryType.Win32 | ServiceQueryType.Driver, ServiceQueryState.All, data, data.Size, out requiredSize, out servicesReturned, ref resume, null)) { // resize buffer data.ResizeNew(requiredSize); if (!Win32.EnumServicesStatusEx(manager, IntPtr.Zero, ServiceQueryType.Win32 | ServiceQueryType.Driver, ServiceQueryState.All, data, data.Size, out requiredSize, out servicesReturned, ref resume, null)) Win32.Throw(); } Dictionary<string, EnumServiceStatusProcess> dictionary = new Dictionary<string, EnumServiceStatusProcess>(servicesReturned); for (int i = 0; i < servicesReturned; i++) { EnumServiceStatusProcess service = data.ReadStruct<EnumServiceStatusProcess>(0, EnumServiceStatusProcess.SizeOf, i); dictionary.Add(service.ServiceName, service); } return dictionary; } }
/// <summary> /// Gets a dictionary containing the currently running processes. /// </summary> /// <param name="getThreads">Whether to get thread information.</param> /// <returns>A dictionary, indexed by process ID.</returns> public static Dictionary <int, SystemProcess> GetProcesses(bool getThreads) { int retLength; Dictionary <int, SystemProcess> returnProcesses; if (_processesBuffer == null) { _processesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation( SystemInformationClass.SystemProcessInformation, data, data.Size, out retLength )) >= NtStatus.Error) { if (attempts > 3) { Win32.Throw(status); } data.ResizeNew(retLength); } else { break; } } returnProcesses = new Dictionary <int, SystemProcess>(32); // 32 processes on a computer? int i = 0; SystemProcess currentProcess = new SystemProcess(); do { //currentProcess.Process = data.ReadStruct<SystemProcessInformation>(i, 0); unsafe { currentProcess.Process = *(SystemProcessInformation *)((byte *)data.Memory + i); } currentProcess.Name = currentProcess.Process.ImageName.Read(); if (getThreads && currentProcess.Process.ProcessId != 0) { currentProcess.Threads = new Dictionary <int, SystemThreadInformation>(); for (int j = 0; j < currentProcess.Process.NumberOfThreads; j++) { var thread = data.ReadStruct <SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); currentProcess.Threads.Add(thread.ClientId.ThreadId, thread); } } returnProcesses.Add(currentProcess.Process.ProcessId, currentProcess); i += currentProcess.Process.NextEntryOffset; } while (currentProcess.Process.NextEntryOffset != 0); return(returnProcesses); }
public static void RefreshFileNamePrefixes() { if (_fileNamePrefixes == null) { // Just create a new dictionary to avoid having to lock the existing one. _fileNamePrefixes = new Dictionary<string, string>(); for (char c = 'A'; c <= 'Z'; c++) { using (MemoryAlloc data = new MemoryAlloc(1024)) { int length; if ((length = Win32.QueryDosDevice(c.ToString() + ":", data, data.Size/2)) > 2) { _fileNamePrefixes.Add(data.ReadUnicodeString(0, length - 2), c.ToString() + ":"); } } } } }
/// <summary> /// Gets a dictionary containing the threads owned by the specified process. /// </summary> /// <param name="pid">A process ID.</param> /// <returns>A dictionary, indexed by thread ID.</returns> public static Dictionary <int, SystemThreadInformation> GetProcessThreads(int pid) { int retLength; if (_processesBuffer == null) { _processesBuffer = new MemoryAlloc(0x10000); } MemoryAlloc data = _processesBuffer; NtStatus status; int attempts = 0; while (true) { attempts++; if ((status = Win32.NtQuerySystemInformation(SystemInformationClass.SystemProcessInformation, data.Memory, data.Size, out retLength)) >= NtStatus.Error) { if (attempts > 3) { Win32.Throw(status); } data.ResizeNew(retLength); } else { break; } } int i = 0; SystemProcessInformation process; do { unsafe { //process = data.ReadStruct<SystemProcessInformation>(i, 0); process = *(SystemProcessInformation *)((byte *)data.Memory + i); } if (process.ProcessId == pid) { var threads = new Dictionary <int, SystemThreadInformation>(); for (int j = 0; j < process.NumberOfThreads; j++) { var thread = data.ReadStruct <SystemThreadInformation>(i + Marshal.SizeOf(typeof(SystemProcessInformation)), j); if (pid != 0) { threads.Add(thread.ClientId.ThreadId, thread); } else { // Fix System Idle Process threads. // There is one thread per CPU, but they // all have a TID of 0. Assign unique TIDs. threads.Add(j, thread); } } return(threads); } i += process.NextEntryOffset; } while (process.NextEntryOffset != 0); return(null); }
private void dumpMemoryMenuItem_Click(object sender, EventArgs e) { SaveFileDialog sfd = new SaveFileDialog(); sfd.FileName = "Memory.bin"; sfd.Filter = "Binary Files (*.bin)|*.bin|All Files (*.*)|*.*"; if (sfd.ShowDialog() == DialogResult.OK) { try { using (var phandle = new ProcessHandle(_pid, ProcessAccess.VmRead)) using (var fhandle = FileHandle.CreateWin32(sfd.FileName, FileAccess.GenericWrite, FileShareMode.Read)) { foreach (ListViewItem litem in listMemory.SelectedItems) { MemoryItem item = (MemoryItem)litem.Tag; using (MemoryAlloc alloc = new MemoryAlloc((int)item.Size)) { try { unsafe { phandle.ReadMemory(item.Address, (IntPtr)alloc, (int)item.Size); fhandle.Write(alloc.Memory, (int)item.Size); } } catch (WindowsException) { } } } } } catch (Exception ex) { PhUtils.ShowException("Unable to dump the selected memory regions", ex); } } }
private unsafe void ScanHiddenObjects() { KVars vars = this.GetKVars(); int bytesRead; throw new NotSupportedException(); listHiddenObjects.Items.Clear(); using (var currentPage = new MemoryAlloc(Windows.PageSize)) { for ( IntPtr address = vars.NonPagedPoolStart; address.CompareTo(vars.NonPagedPoolStart.Increment(vars.NonPagedPoolSize)) == -1; address = address.Increment(Windows.PageSize) ) { try { KProcessHacker.Instance.KphReadVirtualMemoryUnsafe( ProcessHandle.Current, address.ToInt32(), (IntPtr)currentPage, Windows.PageSize, out bytesRead ); } catch { continue; } for ( IntPtr inner = address; inner.CompareTo(address.Increment(Windows.PageSize)) == -1; inner = inner.Increment(8) ) { } labelObjectsScanProgress.Text = string.Format("Scanned 0x{0:x8}", address.ToInt32()); Application.DoEvents(); } } labelObjectsScanProgress.Text = "Finished."; }