Example #1
0
        public MemoryEditor(int PID, IntPtr Address, long Length)
        {
            InitializeComponent();
            this.AddEscapeToClose();
            this.SetTopMost();

            _pid = PID;
            _address = Address;
            _length = Length;

            Program.MemoryEditors.Add(this.Id, this);

            this.Text = Program.ProcessProvider.Dictionary[_pid].Name + " (PID " + _pid.ToString() +
                "), " + Utils.FormatAddress(_address) + "-" +
                Utils.FormatAddress(_address.Increment(_length)) + " - Memory Editor";

            try
            {
                ReadMemory();
            }
            catch
            {
                this.Visible = false;
                MessageBox.Show("Could not read process memory:\n\n" + Win32.GetLastErrorMessage(),
                    "Process Hacker", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }

            hexBoxMemory.Select();
        }
        public static T ElementAt <T>(this IntPtr ptr, int index)
        {
            var offset    = Marshal.SizeOf(typeof(T)) * index;
            var offsetPtr = ptr.Increment(offset);

            return((T)Marshal.PtrToStructure(offsetPtr, typeof(T)));
        }
        public AlignedMemoryAlloc(int size, int alignment)
        {
            if (alignment <= 0 || Utils.CountBits(alignment) != 1)
                throw new ArgumentOutOfRangeException("alignment");

            _realMemory = MemoryAlloc.PrivateHeap.Allocate(0, size + alignment - 1);

            this.Memory = _realMemory.Increment(alignment - 1).And((alignment - 1).ToIntPtr().Not());
            this.Size = size;
        }
        internal SymbolInformation(IntPtr symbolInfo, int symbolSize)
        {
            SymbolInfo si = (SymbolInfo)Marshal.PtrToStructure(symbolInfo, typeof(SymbolInfo));

            this.Flags = si.Flags;
            this.Index = si.Index;
            this.ModuleBase = si.ModBase;
            this.Name = Marshal.PtrToStringAnsi(symbolInfo.Increment(Win32.SymbolInfoNameOffset), si.NameLen);
            this.Size = symbolSize;
            this.Address = si.Address;
        }
        public AlignedMemoryAlloc(int size, int alignment)
        {
            // Make sure the alignment is positive and a power of two.
            if (alignment <= 0 || Utils.CountBits(alignment) != 1)
                throw new ArgumentOutOfRangeException("alignment");

            // Since we are going to align our pointer, we need to account for 
            // any padding at the beginning.
            _realMemory = MemoryAlloc.PrivateHeap.Allocate(0, size + alignment - 1);

            // aligned memory = (memory + alignment - 1) & ~(alignment - 1)
            this.Memory = _realMemory.Increment(alignment - 1).And((alignment - 1).ToIntPtr().Not());
            this.Size = size;
        }
Example #6
0
        public unsafe static void CopyProcessParameters(
            ProcessHandle processHandle,
            IntPtr peb,
            ProcessCreationFlags creationFlags,
            string imagePathName,
            string dllPath,
            string currentDirectory,
            string commandLine,
            EnvironmentBlock environment,
            string windowTitle,
            string desktopInfo,
            string shellInfo,
            string runtimeInfo,
            ref StartupInfo startupInfo
            )
        {
            UnicodeString imagePathNameStr;
            UnicodeString dllPathStr;
            UnicodeString currentDirectoryStr;
            UnicodeString commandLineStr;
            UnicodeString windowTitleStr;
            UnicodeString desktopInfoStr;
            UnicodeString shellInfoStr;
            UnicodeString runtimeInfoStr;

            // Create the unicode strings.

            imagePathNameStr = new UnicodeString(imagePathName);
            dllPathStr = new UnicodeString(dllPath);
            currentDirectoryStr = new UnicodeString(currentDirectory);
            commandLineStr = new UnicodeString(commandLine);
            windowTitleStr = new UnicodeString(windowTitle);
            desktopInfoStr = new UnicodeString(desktopInfo);
            shellInfoStr = new UnicodeString(shellInfo);
            runtimeInfoStr = new UnicodeString(runtimeInfo);

            try
            {
                NtStatus status;
                IntPtr processParameters;

                // Create the process parameter block.

                status = Win32.RtlCreateProcessParameters(
                    out processParameters,
                    ref imagePathNameStr,
                    ref dllPathStr,
                    ref currentDirectoryStr,
                    ref commandLineStr,
                    environment,
                    ref windowTitleStr,
                    ref desktopInfoStr,
                    ref shellInfoStr,
                    ref runtimeInfoStr
                    );

                if (status >= NtStatus.Error)
                    Win32.Throw(status);

                try
                {
                    // Allocate a new memory region in the remote process for 
                    // the environment block and copy it over.

                    int environmentLength;
                    IntPtr newEnvironment;

                    environmentLength = environment.GetLength();
                    newEnvironment = processHandle.AllocateMemory(
                        environmentLength,
                        MemoryProtection.ReadWrite
                        );

                    processHandle.WriteMemory(
                        newEnvironment,
                        environment,
                        environmentLength
                        );

                    // Copy over the startup info data.
                    RtlUserProcessParameters* paramsStruct = (RtlUserProcessParameters*)processParameters;

                    paramsStruct->Environment = newEnvironment;
                    paramsStruct->StartingX = startupInfo.X;
                    paramsStruct->StartingY = startupInfo.Y;
                    paramsStruct->CountX = startupInfo.XSize;
                    paramsStruct->CountY = startupInfo.YSize;
                    paramsStruct->CountCharsX = startupInfo.XCountChars;
                    paramsStruct->CountCharsY = startupInfo.YCountChars;
                    paramsStruct->FillAttribute = startupInfo.FillAttribute;
                    paramsStruct->WindowFlags = startupInfo.Flags;
                    paramsStruct->ShowWindowFlags = startupInfo.ShowWindow;

                    if ((startupInfo.Flags & StartupFlags.UseStdHandles) == StartupFlags.UseStdHandles)
                    {
                        paramsStruct->StandardInput = startupInfo.StdInputHandle;
                        paramsStruct->StandardOutput = startupInfo.StdOutputHandle;
                        paramsStruct->StandardError = startupInfo.StdErrorHandle;
                    }

                    // TODO: Add console support.

                    // Allocate a new memory region in the remote process for 
                    // the process parameters.

                    IntPtr newProcessParameters;
                    IntPtr regionSize = paramsStruct->Length.ToIntPtr();

                    newProcessParameters = processHandle.AllocateMemory(
                        IntPtr.Zero,
                        ref regionSize,
                        MemoryFlags.Commit,
                        MemoryProtection.ReadWrite
                        );

                    paramsStruct->MaximumLength = regionSize.ToInt32();

                    processHandle.WriteMemory(newProcessParameters, processParameters, paramsStruct->Length);

                    // Modify the process parameters pointer in the PEB.
                    processHandle.WriteMemory(
                        peb.Increment(Peb.ProcessParametersOffset),
                        &newProcessParameters,
                        IntPtr.Size
                        );
                }
                finally
                {
                    Win32.RtlDestroyProcessParameters(processParameters);
                }
            }
            finally
            {
                imagePathNameStr.Dispose();
                dllPathStr.Dispose();
                currentDirectoryStr.Dispose();
                commandLineStr.Dispose();
                windowTitleStr.Dispose();
                desktopInfoStr.Dispose();
                shellInfoStr.Dispose();
                runtimeInfoStr.Dispose();
            }
        }
Example #7
0
        private unsafe int ReadOnce(StructField field, IntPtr offset, out FieldValue valueOut)
        {
            FieldValue value = new FieldValue() { FieldType = field.Type, Name = field.Name };
            int readSize = 0;

            switch (field.Type)
            {
                case FieldType.Bool32:
                    value.Value = Utils.ToInt32(IOProvider.ReadBytes(offset, 4),
                        Utils.Endianness.Little) != 0;
                    readSize = 4;
                    break;
                case FieldType.Bool8:
                    value.Value = IOProvider.ReadBytes(offset, 1)[0] != 0;
                    readSize = 1;
                    break;
                case FieldType.CharASCII:
                    value.Value = (char)IOProvider.ReadBytes(offset, 1)[0];
                    readSize = 1;
                    break;
                case FieldType.CharUTF16:
                    value.Value = Encoding.Unicode.GetString(IOProvider.ReadBytes(offset, 2))[0];
                    readSize = 2;
                    break;
                case FieldType.Double:
                    {
                        long data = Utils.ToInt64(
                            IOProvider.ReadBytes(offset, 8), Utils.Endianness.Little);

                        value.Value = *(double*)&data;
                        readSize = 8;
                    }
                    break;
                case FieldType.Int16:
                    value.Value = (short)Utils.ToUInt16(
                        IOProvider.ReadBytes(offset, 2), Utils.Endianness.Little);
                    readSize = 2;
                    break;
                case FieldType.Int32:
                    value.Value = Utils.ToInt32(
                        IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little);
                    readSize = 4;
                    break;
                case FieldType.Int64:
                    value.Value = Utils.ToInt64(
                        IOProvider.ReadBytes(offset, 8), Utils.Endianness.Little);
                    readSize = 8;
                    break;
                case FieldType.Int8:
                    value.Value = (sbyte)IOProvider.ReadBytes(offset, 1)[0];
                    readSize = 1;
                    break;
                case FieldType.PVoid:
                    value.Value = IOProvider.ReadBytes(offset, IntPtr.Size).ToIntPtr();
                    readSize = IntPtr.Size;
                    break;
                case FieldType.Single:
                    {
                        int data = Utils.ToInt32(
                            IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little);

                        value.Value = *(float*)&data;
                        readSize = 4;
                    }
                    break;
                case FieldType.StringASCII:
                    {
                        StringBuilder str = new StringBuilder();

                        if (field.VarLength == -1)
                        {
                            int i;

                            for (i = 0; ; i++)
                            {
                                byte b = IOProvider.ReadBytes(offset.Increment(i), 1)[0];

                                if (b == 0)
                                    break;

                                str.Append((char)b);
                            }

                            readSize = i;
                        }
                        else
                        {
                            str.Append(Encoding.ASCII.GetString(
                                IOProvider.ReadBytes(offset, field.VarLength)));
                            readSize = field.VarLength;
                        }

                        value.Value = str.ToString();
                    }

                    break;
                case FieldType.StringUTF16:
                    {
                        StringBuilder str = new StringBuilder();

                        if (field.VarLength == -1)
                        {
                            int i;

                            for (i = 0; ; i += 2)
                            {
                                byte[] b = IOProvider.ReadBytes(offset.Increment(i), 2);

                                if (Utils.IsEmpty(b))
                                    break;

                                str.Append(Encoding.Unicode.GetString(b));
                            }

                            readSize = i;
                        }
                        else
                        {
                            str.Append(Encoding.Unicode.GetString(
                                IOProvider.ReadBytes(offset, field.VarLength * 2))); // each char is 2 bytes
                            readSize = field.VarLength;
                        }

                        value.Value = str.ToString();
                    }

                    break;
                case FieldType.Struct:
                    {
                        FieldValue[] valuesOut;
                        StructDef struc = Structs[field.StructName];

                        struc.IOProvider = this.IOProvider;
                        struc.Offset = offset;
                        struc.Structs = this.Structs;
                        readSize = struc.Read(out valuesOut);
                        value.Value = valuesOut;
                        value.StructName = field.StructName;
                    }

                    break;
                case FieldType.UInt16:
                    value.Value = Utils.ToUInt16(
                        IOProvider.ReadBytes(offset, 2), Utils.Endianness.Little);
                    readSize = 2;
                    break;
                case FieldType.UInt32:
                    value.Value = Utils.ToUInt32(
                        IOProvider.ReadBytes(offset, 4), Utils.Endianness.Little);
                    readSize = 4;
                    break;
                case FieldType.UInt64:
                    value.Value = (ulong)Utils.ToInt64(
                        IOProvider.ReadBytes(offset, 8), Utils.Endianness.Little);
                    readSize = 8;
                    break;
                case FieldType.UInt8:
                    value.Value = IOProvider.ReadBytes(offset, 1)[0];
                    readSize = 1;
                    break;
                default:
                    readSize = 0;
                    break;
            }

            valueOut = value;

            return readSize;
        }
Example #8
0
        private int Read(StructField field, IntPtr offset, out FieldValue valueOut)
        {
            if (!field.IsArray)
                return this.ReadOnce(field, offset, out valueOut);

            // read array
            FieldValue value = new FieldValue() { FieldType = field.RawType, Name = field.Name };
            int readSize = 0;
            List<FieldValue> valueArray = new List<FieldValue>();

            for (int i = 0; i < field.VarArrayLength; i++)
            {
                FieldValue elementValue;

                readSize = offset.Increment(readSize).Align(field.Alignment).Decrement(offset).ToInt32();
                readSize += this.ReadOnce(field, offset.Increment(readSize), out elementValue);
                elementValue.Name = "[" + i.ToString() + "]";

                valueArray.Add(elementValue);
            }

            value.Value = valueArray.ToArray();
            value.StructName = field.StructName;
            valueOut = value;

            return readSize;
        }
 public static IntPtr Increment <T>(this IntPtr ptr)
 {
     return(ptr.Increment(Marshal.SizeOf(typeof(T))));
 }