Example #1
0
        private static Dictionary <string, string> GetEnvironmentVariablesCore(IntPtr hProcess)
        {
            IntPtr penv = GetPenv(hProcess);

            int dataSize;

            if (!HasReadAccess(hProcess, penv, out dataSize))
            {
                throw new Win32Exception("Unable to read environment block.");
            }

            // Limit env size to 10 MB to be defensive
            const int maxEnvSize = 10 * 1000 * 1000;

            if (dataSize > maxEnvSize)
            {
                dataSize = maxEnvSize;
            }

            var  envData = new byte[dataSize];
            var  res_len = IntPtr.Zero;
            bool b       = ProcessNativeMethods.ReadProcessMemory(
                hProcess,
                penv,
                envData,
                new IntPtr(dataSize),
                ref res_len);

            if (!b || (int)res_len != dataSize)
            {
                throw new Win32Exception("Unable to read environment block data.");
            }

            return(EnvToDictionary(envData));
        }
Example #2
0
        private static string GetCommandLineCore(IntPtr hProcess)
        {
            int targetProcessBitness = GetProcessBitness(hProcess);

            if (targetProcessBitness == 64 && !System.Environment.Is64BitProcess)
            {
                throw new Win32Exception(
                          "The current process should run in 64 bit mode to be able to get the environment of another 64 bit process.");
            }

            var pPeb = targetProcessBitness == 64 ? GetPeb64(hProcess) : GetPeb32(hProcess);
            //dt -r ntdll!PEB for offset values of the PEB
            var offset = targetProcessBitness == 64 ? 0x20 : 0x10;
            var unicodeStringOffset = targetProcessBitness == 64 ? 0x70 : 0x40;

            IntPtr ptr;

            if (!TryReadIntPtr(hProcess, pPeb + offset, out ptr))
            {
                throw new Win32Exception("Unable to read PEB.");
            }

            int    commandLineLength;
            IntPtr commandLineBuffer;

            if ((targetProcessBitness == 64 && System.Environment.Is64BitProcess) ||
                (targetProcessBitness == 32 && !System.Environment.Is64BitProcess))
            {
                //we running same bitness as the target process, use native UNICODE_STRING
                var unicodeString = new ProcessNativeMethods.UNICODE_STRING();
                if (!ProcessNativeMethods.ReadProcessMemory(hProcess, ptr + unicodeStringOffset, ref unicodeString, new IntPtr(Marshal.SizeOf(unicodeString)), IntPtr.Zero))
                {
                    throw new Win32Exception(String.Format("Unable to read command line, win32 error {0}", Marshal.GetLastWin32Error()));
                }
                commandLineLength = unicodeString.Length;
                commandLineBuffer = unicodeString.Buffer;
            }
            else
            {
                //we are running 64 but target process is 32, use UNICODE_STRING_32
                var unicodeString = new ProcessNativeMethods.UNICODE_STRING_32();
                if (!ProcessNativeMethods.ReadProcessMemory(hProcess, ptr + unicodeStringOffset, ref unicodeString, new IntPtr(Marshal.SizeOf(unicodeString)), IntPtr.Zero))
                {
                    throw new Win32Exception(String.Format("Unable to read command line, win32 error {0}", Marshal.GetLastWin32Error()));
                }
                commandLineLength = unicodeString.Length;
                commandLineBuffer = new IntPtr(unicodeString.Buffer);
            }

            var bytes = new byte[commandLineLength];

            if (!ProcessNativeMethods.ReadProcessMemory(hProcess, commandLineBuffer, bytes, new IntPtr(commandLineLength), IntPtr.Zero))
            {
                throw new Win32Exception(String.Format("Unable to read command line, win32 error {0}", Marshal.GetLastWin32Error()));
            }

            return(Encoding.Unicode.GetString(bytes));
        }
Example #3
0
        // should just be ReadIntPtr not TryReadIntPtr, throw when failed
        private static bool TryReadIntPtr(IntPtr hProcess, IntPtr ptr, out IntPtr readPtr)
        {
            var dataSize = new IntPtr(IntPtr.Size);
            var res_len  = IntPtr.Zero;

            if (!ProcessNativeMethods.ReadProcessMemory(
                    hProcess,
                    ptr,
                    out readPtr,
                    dataSize,
                    ref res_len))
            {
                // automatically GetLastError() and format message
                throw new Win32Exception();
            }

            // This is more like an assert
            return(res_len == dataSize);
        }