private int GetParentProcessID(IntPtr handle)
{
NativeMethods.ProcessBasicInformation pbi = new NativeMethods.ProcessBasicInformation();
int returnLength;
int status = NativeMethods.NtQueryInformationProcess(handle, 0, out pbi, Marshal.SizeOf(pbi), out returnLength);
if (status != 0) throw new Win32Exception(status);
var result = pbi.InheritedFromUniqueProcessId.ToInt32();
return result;
}
private string GetProcessCommandLine(IntPtr handle)
{
NativeMethods.ProcessBasicInformation pbi;
int returnLength;
int status = NativeMethods.NtQueryInformationProcess(handle, 0, out pbi, Marshal.SizeOf(typeof(NativeMethods.ProcessBasicInformation)), out returnLength);
if (status != 0) throw new Win32Exception(status);
var result = GetPebString(PebOffset.CommandLine, pbi.PebBaseAddress, handle);
return result;
}
private string GetProcessImagePath(IntPtr handle)
{
NativeMethods.ProcessBasicInformation pbi;
int returnLength;
int status = NativeMethods.NtQueryInformationProcess(handle, 0, out pbi, Marshal.SizeOf(typeof(NativeMethods.ProcessBasicInformation)), out returnLength);
if (status != 0) throw new Win32Exception(status);
var result = GetPebString(PebOffset.ImagePathName, pbi.PebBaseAddress, handle);
return result;
}
private IntPtr IncrimentPtr(IntPtr ptr, int value)
{
return IntPtr.Size == sizeof(Int32) ? new IntPtr(ptr.ToInt32() + value) : new IntPtr(ptr.ToInt64() + value);
}
private unsafe string GetPebString(PebOffset offset, IntPtr pebBaseAddress, IntPtr handle)
{
byte* buffer = stackalloc byte[IntPtr.Size];
ReadMemory(IncrimentPtr(pebBaseAddress, NativeMethods.Peb.ProcessParametersOffset), buffer, IntPtr.Size, handle);
IntPtr processParameters = *(IntPtr*)buffer;
int realOffset = GetPebOffset(offset);
NativeMethods.UnicodeString pebStr;
ReadMemory(IncrimentPtr(processParameters, realOffset), &pebStr, Marshal.SizeOf(typeof(NativeMethods.UnicodeString)), handle);
var str = Encoding.Unicode.GetString(ReadMemory(pebStr.Buffer, pebStr.Length, handle), 0, pebStr.Length);
return str;
}
private int GetPebOffset(PebOffset offset)
{
switch (offset)
{
case PebOffset.CommandLine:
return NativeMethods.RtlUserProcessParameters.CommandLineOffset;
case PebOffset.CurrentDirectoryPath:
return NativeMethods.RtlUserProcessParameters.CurrentDirectoryOffset;
case PebOffset.DesktopName:
return NativeMethods.RtlUserProcessParameters.DesktopInfoOffset;
case PebOffset.DllPath:
return NativeMethods.RtlUserProcessParameters.DllPathOffset;
case PebOffset.ImagePathName:
return NativeMethods.RtlUserProcessParameters.ImagePathNameOffset;
case PebOffset.RuntimeData:
return NativeMethods.RtlUserProcessParameters.RuntimeDataOffset;
case PebOffset.ShellInfo:
return NativeMethods.RtlUserProcessParameters.ShellInfoOffset;
case PebOffset.WindowTitle:
return NativeMethods.RtlUserProcessParameters.WindowTitleOffset;
default:
throw new ArgumentException("offset");
}
}
private byte[] ReadMemory(IntPtr baseAddress, int length, IntPtr handle)
{
byte[] buffer = new byte[length];
ReadMemory(baseAddress, buffer, length, handle);
return buffer;
}
private unsafe int ReadMemory(IntPtr baseAddress, byte[] buffer, int length, IntPtr handle)
{
fixed (byte* bufferPtr = buffer) return ReadMemory(baseAddress, bufferPtr, length, handle);
}
private unsafe int ReadMemory(IntPtr baseAddress, void* buffer, int length, IntPtr handle)
{
return ReadMemory(baseAddress, new IntPtr(buffer), length, handle);
}
private int ReadMemory(IntPtr baseAddress, IntPtr buffer, int length, IntPtr handle)
{
int status;
IntPtr retLengthIntPtr;
if ((status = NativeMethods.NtReadVirtualMemory(handle, baseAddress, buffer, new IntPtr(length), out retLengthIntPtr)) > 0) throw new Win32Exception(status);
return retLengthIntPtr.ToInt32();
}
[DllImport("ntdll.dll")]
internal static extern int NtQueryInformationProcess(
[In] IntPtr ProcessHandle,
[In] int ProcessInformationClass,
[Out] out ProcessBasicInformation ProcessInformation,
[In] int ProcessInformationLength,
[Out] [Optional] out int ReturnLength
);
[DllImport("ntdll.dll")]
public static extern int NtReadVirtualMemory(
[In] IntPtr processHandle,
[In] [Optional] IntPtr baseAddress,
[In] IntPtr buffer,
[In] IntPtr bufferSize,
[Out] [Optional] out IntPtr returnLength
);
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct UnicodeString
{
public ushort Length;
public ushort MaximumLength;
public IntPtr Buffer;
}
[StructLayout(LayoutKind.Sequential)]
public struct ListEntry
{
public IntPtr Flink;
public IntPtr Blink;
}
[StructLayout(LayoutKind.Sequential)]
public unsafe struct Peb
{
public static readonly int ImageSubsystemOffset =
Marshal.OffsetOf(typeof(Peb), "ImageSubsystem").ToInt32();
public static readonly int LdrOffset =
Marshal.OffsetOf(typeof(Peb), "Ldr").ToInt32();
public static readonly int ProcessHeapOffset =
Marshal.OffsetOf(typeof(Peb), "ProcessHeap").ToInt32();
public static readonly int ProcessParametersOffset =
Marshal.OffsetOf(typeof(Peb), "ProcessParameters").ToInt32();
[MarshalAs(UnmanagedType.I1)]
public bool InheritedAddressSpace;
[MarshalAs(UnmanagedType.I1)]
public bool ReadImageFileExecOptions;
[MarshalAs(UnmanagedType.I1)]
public bool BeingDebugged;
[MarshalAs(UnmanagedType.I1)]
public bool BitField;
public IntPtr Mutant;
public IntPtr ImageBaseAddress;
public IntPtr Ldr; // PebLdrData*
public IntPtr ProcessParameters; // RtlUserProcessParameters*
public IntPtr SubSystemData;
public IntPtr ProcessHeap;
public IntPtr FastPebLock;
public IntPtr AtlThunkSListPtr;
public IntPtr SparePrt2;
public int EnvironmentUpdateCount;
public IntPtr KernelCallbackTable;
public int SystemReserved;
public int SpareUlong;
public IntPtr FreeList;
public int TlsExpansionCounter;
public IntPtr TlsBitmap;
public unsafe fixed int TlsBitmapBits[2];
public IntPtr ReadOnlySharedMemoryBase;
public IntPtr ReadOnlySharedMemoryHeap;
public IntPtr ReadOnlyStaticServerData;
public IntPtr AnsiCodePageData;
public IntPtr OemCodePageData;
public IntPtr UnicodeCaseTableData;
public int NumberOfProcessors;
public int NtGlobalFlag;
public long CriticalSectionTimeout;
public IntPtr HeapSegmentReserve;
public IntPtr HeapSegmentCommit;
public IntPtr HeapDeCommitTotalFreeThreshold;
public IntPtr HeapDeCommitFreeBlockThreshold;
public int NumberOfHeaps;
public int MaximumNumberOfHeaps;
public IntPtr ProcessHeaps;
public IntPtr GdiSharedHandleTable;
public IntPtr ProcessStarterHelper;
public int GdiDCAttributeList;
public IntPtr LoaderLock;
public int OSMajorVersion;
public int OSMinorVersion;
public short OSBuildNumber;
public short OSCSDVersion;
public int OSPlatformId;
public int ImageSubsystem;
public int ImageSubsystemMajorVersion;
public int ImageSubsystemMinorVersion;
public IntPtr ImageProcessAffinityMask;
public unsafe fixed byte GdiHandleBuffer[GDI_HANDLE_BUFFER_SIZE];
public IntPtr PostProcessInitRoutine;
public IntPtr TlsExpansionBitmap;
public unsafe fixed int TlsExpansionBitmapBits[32];
public int SessionId;
public long AppCompatFlags;
public long AppCompatFlagsUser;
public IntPtr pShimData;
public IntPtr AppCompatInfo;
public UnicodeString CSDVersion;
public IntPtr ActivationContextData;
public IntPtr ProcessAssemblyStorageMap;
public IntPtr SystemDefaultActivationContextData;
public IntPtr SystemAssemblyStorageMap;
public IntPtr MinimumStackCommit;
public IntPtr FlsCallback;
public ListEntry FlsListHead;
public IntPtr FlsBitmap;
public unsafe fixed int FlsBitmapBits[FLS_MAXIMUM_AVAILABLE / (sizeof(int) * 8)];
public int FlsHighIndex;
}
[StructLayout(LayoutKind.Sequential)]
public struct RtlUserProcessParameters
{
public static readonly int CurrentDirectoryOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "CurrentDirectory").ToInt32();
public static readonly int DllPathOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "DllPath").ToInt32();
public static readonly int ImagePathNameOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "ImagePathName").ToInt32();
public static readonly int CommandLineOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "CommandLine").ToInt32();
public static readonly int EnvironmentOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "Environment").ToInt32();
public static readonly int WindowTitleOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "WindowTitle").ToInt32();
public static readonly int DesktopInfoOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "DesktopInfo").ToInt32();
public static readonly int ShellInfoOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "ShellInfo").ToInt32();
public static readonly int RuntimeDataOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "RuntimeData").ToInt32();
public static readonly int CurrentDirectoriesOffset =
Marshal.OffsetOf(typeof(RtlUserProcessParameters), "CurrentDirectories").ToInt32();
public struct CurDir
{
public NativeMethods.UnicodeString DosPath;
public IntPtr Handle;
}
public struct RtlDriveLetterCurDir
{
public ushort Flags;
public ushort Length;
public uint TimeStamp;
public IntPtr DosPath;
}
public int MaximumLength;
public int Length;
public RtlUserProcessFlags Flags;
public int DebugFlags;
public IntPtr ConsoleHandle;
public int ConsoleFlags;
public IntPtr StandardInput;
public IntPtr StandardOutput;
public IntPtr StandardError;
public CurDir CurrentDirectory;
public NativeMethods.UnicodeString DllPath;
public NativeMethods.UnicodeString ImagePathName;
public NativeMethods.UnicodeString CommandLine;
public IntPtr Environment;
public int StartingX;
public int StartingY;
public int CountX;
public int CountY;
public int CountCharsX;
public int CountCharsY;
public int FillAttribute;
public StartupFlags WindowFlags;
public int ShowWindowFlags;
public NativeMethods.UnicodeString WindowTitle;
public NativeMethods.UnicodeString DesktopInfo;
public NativeMethods.UnicodeString ShellInfo;
public NativeMethods.UnicodeString RuntimeData;
public RtlDriveLetterCurDir CurrentDirectories;
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessBasicInformation
{
public int ExitStatus;
public IntPtr PebBaseAddress;
public IntPtr AffinityMask;
public int BasePriority;
public IntPtr UniqueProcessId;
public IntPtr InheritedFromUniqueProcessId;
}
Комментариев нет:
Отправить комментарий