воскресенье, 19 февраля 2012 г.

Get another process command line, image path, parent PID, current directory C#


 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;
        }


Комментариев нет:

Отправить комментарий