예제 #1
0
        internal override StackFrame UnwindStack(StackFrame frame, TargetMemoryAccess memory,
                                                 byte[] code, int offset)
        {
            if ((code != null) && (code.Length > 4))
            {
                return(read_prologue(frame, memory, code, offset));
            }

            TargetAddress rbp = frame.FrameAddress;

            int addr_size = TargetAddressSize;

            Registers regs = CopyRegisters(frame.Registers);

            TargetAddress new_rbp = memory.ReadAddress(rbp);

            regs [(int)X86_Register.RBP].SetValue(rbp, new_rbp);

            TargetAddress new_rip = memory.ReadAddress(rbp + addr_size);

            regs [(int)X86_Register.RIP].SetValue(rbp + addr_size, new_rip);

            TargetAddress new_rsp = rbp + 2 * addr_size;

            regs [(int)X86_Register.RSP].SetValue(rbp, new_rsp);

            rbp -= addr_size;

            return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs));
        }
예제 #2
0
        internal TargetClassObject GetCurrentObject(TargetMemoryAccess target,
                                                    TargetLocation location)
        {
            // location.Address resolves to the address of the MonoObject,
            // dereferencing it once gives us the vtable, dereferencing it
            // twice the class.
            TargetAddress address;

            address = target.ReadAddress(location.GetAddress(target));
            address = target.ReadAddress(address);

            TargetType current = File.MonoLanguage.ReadMonoClass(target, address);

            if (current == null)
            {
                return(null);
            }

            if (IsByRef && !current.IsByRef)             // Unbox
            {
                location = location.GetLocationAtOffset(
                    2 * target.TargetMemoryInfo.TargetAddressSize);
            }

            return((TargetClassObject)current.GetObject(target, location));
        }
예제 #3
0
        internal override TargetType GetCurrentType(TargetMemoryAccess target)
        {
            // location.Address resolves to the address of the MonoObject,
            // dereferencing it once gives us the vtable, dereferencing it
            // twice the class.
            TargetAddress address;
            address = target.ReadAddress (Location.GetAddress (target));
            address = target.ReadAddress (address);

            return Type.File.MonoLanguage.ReadMonoClass (target, address);
        }
예제 #4
0
        internal override TargetType GetCurrentType(TargetMemoryAccess target)
        {
            // location.Address resolves to the address of the MonoObject,
            // dereferencing it once gives us the vtable, dereferencing it
            // twice the class.
            TargetAddress address;

            address = target.ReadAddress(Location.GetAddress(target));
            address = target.ReadAddress(address);

            return(Type.File.MonoLanguage.ReadMonoClass(target, address));
        }
예제 #5
0
        public TargetAddress MonoClassGetMethod(TargetMemoryAccess memory, TargetAddress klass,
                                                int index)
        {
            TargetAddress methods = memory.ReadAddress(
                klass + MonoMetadataInfo.KlassMethodsOffset);

            if (methods.IsNull)
            {
                throw new TargetException(TargetError.ClassNotInitialized);
            }

            methods += index * memory.TargetAddressSize;
            return(memory.ReadAddress(methods));
        }
예제 #6
0
        internal override StackFrame GetLMF(ThreadServant thread, TargetMemoryAccess memory, ref TargetAddress lmf_address)
        {
            TargetAddress      lmf    = lmf_address;
            TargetBinaryReader reader = memory.ReadMemory(lmf_address, 88).GetReader();

            lmf_address = reader.ReadTargetAddress(); // prev
            reader.ReadTargetAddress();
            reader.ReadTargetAddress();               // method
            TargetAddress rip = reader.ReadTargetAddress();

            if (lmf_address.IsNull)
            {
                return(null);
            }

            TargetAddress rbx = reader.ReadTargetAddress();
            TargetAddress rbp = reader.ReadTargetAddress();
            TargetAddress rsp = reader.ReadTargetAddress();
            TargetAddress r12 = reader.ReadTargetAddress();
            TargetAddress r13 = reader.ReadTargetAddress();
            TargetAddress r14 = reader.ReadTargetAddress();
            TargetAddress r15 = reader.ReadTargetAddress();

            Registers regs = new Registers(this);

            if ((lmf_address.Address & 1) == 0)
            {
                rip = memory.ReadAddress(rsp - 8);
                regs [(int)X86_Register.RIP].SetValue(rsp - 8, rip);
                regs [(int)X86_Register.RBP].SetValue(lmf + 40, rbp);
            }
            else
            {
                TargetAddress new_rbp = memory.ReadAddress(rbp);
                regs [(int)X86_Register.RIP].SetValue(lmf + 24, rip);
                regs [(int)X86_Register.RBP].SetValue(rbp, new_rbp);
                rbp = new_rbp;
                lmf_address--;
            }

            regs [(int)X86_Register.RBX].SetValue(lmf + 32, rbx);
            regs [(int)X86_Register.RSP].SetValue(lmf + 48, rsp);
            regs [(int)X86_Register.R12].SetValue(lmf + 56, r12);
            regs [(int)X86_Register.R13].SetValue(lmf + 64, r13);
            regs [(int)X86_Register.R14].SetValue(lmf + 72, r14);
            regs [(int)X86_Register.R15].SetValue(lmf + 80, r15);

            return(CreateFrame(thread.Client, FrameType.LMF, memory, rip, rsp, rbp, regs));
        }
예제 #7
0
            void GetValue(TargetMemoryAccess target, Registers regs,
                          TargetAddress cfa, int reg, Column column)
            {
                switch (column.State)
                {
                case State.Register: {
                    GetRegisterValue(regs, reg, column);
                    break;
                }

                case State.SameValue:
                    regs [GetArchRegister(reg)].Valid = true;
                    break;

                case State.Undefined:
                    break;

                case State.Offset: {
                    TargetAddress addr  = cfa + column.Offset;
                    long          value = target.ReadAddress(addr).Address;
                    regs [GetArchRegister(reg)].SetValue(address, value);
                    break;
                }

                default:
                    throw new NotSupportedException();
                }
            }
예제 #8
0
        StackFrame try_unwind_sigreturn(StackFrame frame, TargetMemoryAccess memory)
        {
            byte[] data = memory.ReadMemory(frame.TargetAddress, 9).Contents;

            /*
             * Check for signal return trampolines:
             *
             *   mov __NR_rt_sigreturn, %eax
             *   syscall
             */
            if ((data [0] != 0x48) || (data [1] != 0xc7) ||
                (data [2] != 0xc0) || (data [3] != 0x0f) ||
                (data [4] != 0x00) || (data [5] != 0x00) ||
                (data [6] != 0x00) || (data [7] != 0x0f) ||
                (data [8] != 0x05))
            {
                return(null);
            }

            TargetAddress stack = frame.StackPointer;

            /* See `struct sigcontext' in <asm/sigcontext.h> */
            int[] regoffsets =
            {
                (int)X86_Register.R8,  (int)X86_Register.R9,
                (int)X86_Register.R10, (int)X86_Register.R11,
                (int)X86_Register.R12, (int)X86_Register.R13,
                (int)X86_Register.R14, (int)X86_Register.R15,
                (int)X86_Register.RDI, (int)X86_Register.RSI,
                (int)X86_Register.RBP, (int)X86_Register.RBX,
                (int)X86_Register.RDX, (int)X86_Register.RAX,
                (int)X86_Register.RCX, (int)X86_Register.RSP,
                (int)X86_Register.RIP, (int)X86_Register.EFLAGS
            };

            Registers regs = CopyRegisters(frame.Registers);

            int offset = 0x28;

            /* The stack contains the `struct ucontext' from <asm/ucontext.h>; the
             * `struct sigcontext' starts at offset 0x28 in it. */
            foreach (int regoffset in regoffsets)
            {
                TargetAddress new_value = memory.ReadAddress(stack + offset);
                regs [regoffset].SetValue(new_value);
                offset += 8;
            }

            TargetAddress rip = new TargetAddress(
                memory.AddressDomain, regs [(int)X86_Register.RIP].GetValue());
            TargetAddress rsp = new TargetAddress(
                memory.AddressDomain, regs [(int)X86_Register.RSP].GetValue());
            TargetAddress rbp = new TargetAddress(
                memory.AddressDomain, regs [(int)X86_Register.RBP].GetValue());

            Symbol name = new Symbol("<signal handler>", rip, 0);

            return(new StackFrame(
                       frame.Thread, FrameType.Signal, rip, rsp, rbp, regs, frame.Thread.NativeLanguage, name));
        }
예제 #9
0
        internal override StackFrame GetLMF(ThreadServant thread, TargetMemoryAccess memory,
                                            ref TargetAddress lmf_address)
        {
            TargetAddress lmf = lmf_address;

            TargetBinaryReader reader = memory.ReadMemory(lmf, 36).GetReader();

            lmf_address = reader.ReadTargetAddress();              // prev

            reader.Position = 16;

            TargetAddress ebx = reader.ReadTargetAddress();
            TargetAddress edi = reader.ReadTargetAddress();
            TargetAddress esi = reader.ReadTargetAddress();
            TargetAddress ebp = reader.ReadTargetAddress();
            TargetAddress eip = reader.ReadTargetAddress();

            Registers regs = new Registers(this);

            regs [(int)X86_Register.RBX].SetValue(lmf + 16, ebx);
            regs [(int)X86_Register.RDI].SetValue(lmf + 20, edi);
            regs [(int)X86_Register.RSI].SetValue(lmf + 24, esi);
            regs [(int)X86_Register.RBP].SetValue(lmf + 28, ebp);
            regs [(int)X86_Register.RIP].SetValue(lmf + 32, eip);

            TargetAddress new_ebp = memory.ReadAddress(ebp);

            regs [(int)X86_Register.RBP].SetValue(ebp, new_ebp);

            TargetAddress new_esp = ebp + 8;

            regs [(int)X86_Register.RSP].SetValue(ebp, new_esp);

            return(CreateFrame(thread.Client, FrameType.LMF, memory, eip, new_esp, new_ebp, regs));
        }
예제 #10
0
        void update(TargetMemoryAccess target)
        {
            // If this is a reference type, the register just holds the
            // address of the actual data, so read the address from the
            // register and return it.
            if (!register.Valid)
            {
                is_valid = false;
                return;
            }

            long contents = register.Value;

            if (contents == 0)
            {
                address = TargetAddress.Null;
            }
            else
            {
                address = new TargetAddress(
                    target.AddressDomain, contents + regoffset);
            }

            if (is_byref && is_regoffset)
            {
                address = target.ReadAddress(address);
            }
            is_valid = true;
        }
예제 #11
0
        public TargetAddress MonoClassGetFieldType(TargetMemoryAccess memory, TargetAddress klass,
                                                   int index)
        {
            int offset = index * MonoMetadataInfo.FieldInfoSize +
                         MonoMetadataInfo.FieldInfoTypeOffset;

            TargetAddress fields = memory.ReadAddress(
                klass + MonoMetadataInfo.KlassFieldOffset);

            if (fields.IsNull)
            {
                throw new TargetException(TargetError.ClassNotInitialized);
            }

            return(memory.ReadAddress(fields + offset));
        }
예제 #12
0
        public bool MonoClassHasMethods(TargetMemoryAccess memory, TargetAddress klass)
        {
            TargetAddress methods = memory.ReadAddress(
                klass + MonoMetadataInfo.KlassMethodsOffset);

            return(!methods.IsNull);
        }
예제 #13
0
        internal void MonoArrayTypeGetBounds(TargetMemoryAccess memory,
                                             TargetAddress data)
        {
            //
            // FIXME: Only check whether the low bounds are all zero
            //
            int num_sizes = memory.ReadByte(data + memory.TargetAddressSize + 1);

            if (num_sizes != 0)
            {
                throw new InternalError();
            }

            int num_lobounds = memory.ReadByte(data + memory.TargetAddressSize + 2);

            if (num_lobounds == 0)
            {
                return;
            }

            TargetAddress      array  = memory.ReadAddress(data + 3 * memory.TargetAddressSize);
            TargetBinaryReader bounds = memory.ReadMemory(array, num_lobounds * 4).GetReader();

            for (int i = 0; i < num_lobounds; i++)
            {
                int bound = bounds.ReadInt32();
                if (bound != 0)
                {
                    throw new InternalError();
                }
            }
        }
예제 #14
0
        public MonoMethodSignature GetMethodSignature(MonoLanguageBackend mono,
                                                      TargetMemoryAccess memory,
                                                      TargetAddress signature)
        {
            int count = memory.ReadInteger(signature + 4) & 0x0000ffff;

            int           offset = memory.TargetAddressSize == 8 ? 16 : 12;
            TargetAddress ret    = memory.ReadAddress(signature + offset);

            TargetType ret_type = mono.ReadType(memory, ret);

            if (count == 0)
            {
                return(new MonoMethodSignature(ret_type, new TargetType [0]));
            }

            offset += memory.TargetAddressSize;
            TargetReader reader = new TargetReader(
                memory.ReadMemory(signature + offset, count * memory.TargetAddressSize));

            TargetType[] param_types = new TargetType [count];
            for (int i = 0; i < count; i++)
            {
                param_types [i] = mono.ReadType(memory, reader.ReadAddress());
            }

            return(new MonoMethodSignature(ret_type, param_types));
        }
예제 #15
0
 internal override TargetAddress GetAddress(TargetMemoryAccess target)
 {
     TargetAddress address = reference.GetAddress (target);
     if (address.IsNull)
         return TargetAddress.Null;
     else
         return target.ReadAddress (address);
 }
예제 #16
0
        internal override StackFrame UnwindStack(StackFrame frame, TargetMemoryAccess memory,
                                                 byte[] code, int offset)
        {
            StackFrame new_frame;

            if ((code != null) && (code.Length > 3))
            {
                new_frame = read_prologue(frame, memory, code, offset);
                if (new_frame != null)
                {
                    return(new_frame);
                }
            }

            TargetAddress ebp = frame.FrameAddress;

            new_frame = do_hacks(frame, memory);
            if (new_frame != null)
            {
                return(new_frame);
            }

            int addr_size = TargetAddressSize;

            Registers regs = new Registers(this);

            TargetAddress new_ebp = memory.ReadAddress(ebp);

            regs [(int)X86_Register.RBP].SetValue(ebp, new_ebp);

            TargetAddress new_eip = memory.ReadAddress(ebp + addr_size);

            regs [(int)X86_Register.RIP].SetValue(ebp + addr_size, new_eip);

            TargetAddress new_esp = ebp + 2 * addr_size;

            regs [(int)X86_Register.RSP].SetValue(ebp, new_esp);

            ebp -= addr_size;

            return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs));
        }
        internal override TargetAddress GetAddress(TargetMemoryAccess target)
        {
            TargetAddress address = reference.GetAddress(target);

            if (address.IsNull)
            {
                return(TargetAddress.Null);
            }
            else
            {
                return(target.ReadAddress(address));
            }
        }
예제 #18
0
        public MonoClassInfo ResolveClass(TargetMemoryAccess target, bool fail)
        {
            if (resolved)
            {
                return(class_info);
            }

            if (class_info == null)
            {
                if (class_ptr.IsNull)
                {
                    return(null);
                }

                TargetAddress klass = target.ReadAddress(class_ptr);
                if (klass.IsNull)
                {
                    return(null);
                }

                class_info = File.MonoLanguage.ReadClassInfo(target, klass);
            }

            if (class_info == null)
            {
                if (!fail)
                {
                    return(null);
                }

                throw new TargetException(TargetError.ClassNotInitialized,
                                          "Class `{0}' not initialized yet.", Name);
            }

            if (class_info.HasParent)
            {
                MonoClassInfo parent_info = class_info.GetParent(target);
                parent_type           = (IMonoStructType)parent_info.Type;
                parent_type.ClassInfo = parent_info;
                if (parent_type.ResolveClass(target, fail) == null)
                {
                    return(null);
                }
            }

            resolved = true;
            return(class_info);
        }
예제 #19
0
        //
        // The following API is new in `terrania'.
        //

        public GenericClassInfo GetGenericClass(TargetMemoryAccess memory,
                                                TargetAddress address)
        {
            int addr_size = memory.TargetMemoryInfo.TargetAddressSize;

            TargetReader  reader     = new TargetReader(memory.ReadMemory(address, 5 * addr_size));
            TargetAddress container  = reader.ReadAddress();
            TargetAddress class_inst = reader.ReadAddress();

            reader.ReadAddress();              /* method_inst */
            reader.ReadAddress();
            TargetAddress cached_class = reader.ReadAddress();

            int inst_id   = memory.ReadInteger(class_inst);
            int inst_data = memory.ReadInteger(class_inst + 4);

            TargetAddress inst_argv;

            if (MonoDebuggerInfo.MajorVersion == 80)
            {
                inst_argv = memory.ReadAddress(class_inst + 8);
            }
            else
            {
                inst_argv = class_inst + 8;
            }

            int type_argc = inst_data & 0x3fffff;

            TargetReader argv_reader = new TargetReader(
                memory.ReadMemory(inst_argv, type_argc * addr_size));

            TargetAddress[] type_args = new TargetAddress [type_argc];
            for (int i = 0; i < type_argc; i++)
            {
                type_args [i] = argv_reader.ReadAddress();
            }

            TargetAddress cached_class_ptr = address + 4 * addr_size;

            return(new GenericClassInfo(container, type_args, cached_class_ptr,
                                        cached_class));
        }
예제 #20
0
        internal bool GetTrampoline(TargetMemoryAccess memory, TargetAddress address,
                                    out TargetAddress trampoline, out bool is_start)
        {
            if (!has_got || (address < plt_start) || (address > plt_end))
            {
                is_start   = false;
                trampoline = TargetAddress.Null;
                return(false);
            }

            Instruction target_insn = Architecture.ReadInstruction(memory, address);

            if ((target_insn == null) || !target_insn.HasInstructionSize ||
                ((target_insn.InstructionType != Instruction.Type.Jump) &&
                 (target_insn.InstructionType != Instruction.Type.IndirectJump)))
            {
                is_start   = false;
                trampoline = TargetAddress.Null;
                return(false);
            }

            TargetAddress call_target = target_insn.GetEffectiveAddress(memory);

            if (call_target.IsNull)
            {
                is_start   = false;
                trampoline = TargetAddress.Null;
                return(false);
            }

            if (call_target != address + target_insn.InstructionSize)
            {
                is_start   = false;
                trampoline = call_target;
                return(true);
            }

            is_start   = true;
            trampoline = memory.ReadAddress(got_start + 3 * info.TargetAddressSize);
            return(true);
        }
예제 #21
0
        public override TargetAddress GetEffectiveAddress(TargetMemoryAccess memory)
        {
            if (!CallTarget.IsNull)
            {
                return(CallTarget);
            }

            Registers regs = memory.GetRegisters();

            long effective_displacement = Displacement;

            if (IndexRegister >= 0)
            {
                long index = regs [IndexRegister].GetValue();
                index *= 1 << SIB.Scale;
                effective_displacement += index;
            }

            TargetAddress effective_address;

            if (is_ip_relative)
            {
                effective_address = Address + InstructionSize;
            }
            else
            {
                effective_address = new TargetAddress(
                    memory.AddressDomain, regs [Register].GetValue());
            }

            effective_address += effective_displacement;

            if (DereferenceAddress)
            {
                effective_address = memory.ReadAddress(effective_address);
            }

            return(effective_address);
        }
예제 #22
0
        StackFrame try_syscall_trampoline(StackFrame frame, TargetMemoryAccess memory)
        {
            /*
             * This is a hack for system call trampolines on NPTL-enabled glibc's.
             */
            if (frame.TargetAddress.Address != 0xffffe002)
            {
                return(null);
            }

            Registers old_regs = frame.Registers;
            Registers regs     = CopyRegisters(old_regs);

            TargetAddress esp = frame.StackPointer;

            TargetAddress new_eip = memory.ReadAddress(esp);
            TargetAddress new_esp = esp + 4;
            TargetAddress new_ebp = frame.FrameAddress;

            regs [(int)X86_Register.RIP].SetValue(esp, new_eip);
            regs [(int)X86_Register.RBP].SetValue(new_ebp);

            return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs));
        }
예제 #23
0
 public TargetAddress MonoArrayTypeGetClass(TargetMemoryAccess memory,
                                            TargetAddress atype)
 {
     return(memory.ReadAddress(atype));
 }
예제 #24
0
 public TargetAddress MonoMethodGetClass(TargetMemoryAccess memory, TargetAddress method)
 {
     return(memory.ReadAddress(method + MonoMetadataInfo.MonoMethodKlassOffset));
 }
예제 #25
0
        internal void MonoArrayTypeGetBounds(TargetMemoryAccess memory,
						      TargetAddress data)
        {
            //
            // FIXME: Only check whether the low bounds are all zero
            //
            int num_sizes = memory.ReadByte (data + memory.TargetAddressSize + 1);
            if (num_sizes != 0)
                throw new InternalError ();

            int num_lobounds = memory.ReadByte (data + memory.TargetAddressSize + 2);
            if (num_lobounds == 0)
                return;

            TargetAddress array = memory.ReadAddress (data + 3 * memory.TargetAddressSize);
            TargetBinaryReader bounds = memory.ReadMemory (array, num_lobounds * 4).GetReader ();
            for (int i = 0; i < num_lobounds; i++) {
                int bound = bounds.ReadInt32 ();
                if (bound != 0)
                    throw new InternalError ();
            }
        }
예제 #26
0
 public TargetAddress MonoClassGetGenericContainer(TargetMemoryAccess memory,
                                                   TargetAddress klass)
 {
     return(memory.ReadAddress(klass + MonoMetadataInfo.KlassGenericContainerOffset));
 }
예제 #27
0
        StackFrame unwind_method(StackFrame frame, TargetMemoryAccess memory, byte[] code,
					  int pos, int offset)
        {
            Registers old_regs = frame.Registers;
            Registers regs = CopyRegisters (old_regs);

            if (!old_regs [(int) X86_Register.RBP].Valid)
                return null;

            TargetAddress rbp = new TargetAddress (
                memory.AddressDomain, old_regs [(int) X86_Register.RBP].Value);

            int addr_size = TargetAddressSize;
            TargetAddress new_rbp = memory.ReadAddress (rbp);
            regs [(int) X86_Register.RBP].SetValue (rbp, new_rbp);

            TargetAddress new_rip = memory.ReadAddress (rbp + addr_size);
            regs [(int) X86_Register.RIP].SetValue (rbp + addr_size, new_rip);

            TargetAddress new_rsp = rbp + 2 * addr_size;
            regs [(int) X86_Register.RSP].SetValue (rbp, new_rsp);

            rbp -= addr_size;

            int length = System.Math.Min (code.Length, offset);
            while (pos < length) {
                byte opcode = code [pos++];

                long value;
                if ((opcode == 0x41) && (pos < length)) {
                    byte opcode2 = code [pos++];

                    if ((opcode2 < 0x50) || (opcode2 > 0x57))
                        break;

                    switch (opcode2) {
                    case 0x50: /* r8 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R8].SetValue (rbp, value);
                        break;
                    case 0x51: /* r9 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R9].SetValue (rbp, value);
                        break;
                    case 0x52: /* r10 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R10].SetValue (rbp, value);
                        break;
                    case 0x53: /* r11 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R11].SetValue (rbp, value);
                        break;
                    case 0x54: /* r12 */
                        value = (long) memory.ReadAddress (rbp).Address;
                        regs [(int) X86_Register.R12].SetValue (rbp, value);
                        break;
                    case 0x55: /* r13 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R13].SetValue (rbp, value);
                        break;
                    case 0x56: /* r14 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R14].SetValue (rbp, value);
                        break;
                    case 0x57: /* r15 */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.R15].SetValue (rbp, value);
                        break;
                    }
                } else {
                    if ((opcode < 0x50) || (opcode > 0x57))
                        break;

                    switch (opcode) {
                    case 0x50: /* rax */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RAX].SetValue (rbp, value);
                        break;
                    case 0x51: /* rcx */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RCX].SetValue (rbp, value);
                        break;
                    case 0x52: /* rdx */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RDX].SetValue (rbp, value);
                        break;
                    case 0x53: /* rbx */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RBX].SetValue (rbp, value);
                        break;
                    case 0x56: /* rsi */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RSI].SetValue (rbp, value);
                        break;
                    case 0x57: /* rdi */
                        value = memory.ReadLongInteger (rbp);
                        regs [(int) X86_Register.RDI].SetValue (rbp, value);
                        break;
                    }
                }

                rbp -= addr_size;
            }

            return CreateFrame (frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs);
        }
예제 #28
0
        StackFrame unwind_method(StackFrame frame, TargetMemoryAccess memory, byte[] code,
                                 int pos, int offset)
        {
            Registers old_regs = frame.Registers;
            Registers regs     = CopyRegisters(old_regs);

            if (!old_regs [(int)X86_Register.RBP].Valid)
            {
                return(null);
            }

            TargetAddress rbp = new TargetAddress(
                memory.AddressDomain, old_regs [(int)X86_Register.RBP].Value);

            int           addr_size = TargetAddressSize;
            TargetAddress new_rbp   = memory.ReadAddress(rbp);

            regs [(int)X86_Register.RBP].SetValue(rbp, new_rbp);

            TargetAddress new_rip = memory.ReadAddress(rbp + addr_size);

            regs [(int)X86_Register.RIP].SetValue(rbp + addr_size, new_rip);

            TargetAddress new_rsp = rbp + 2 * addr_size;

            regs [(int)X86_Register.RSP].SetValue(rbp, new_rsp);

            rbp -= addr_size;

            int length = System.Math.Min(code.Length, offset);

            while (pos < length)
            {
                byte opcode = code [pos++];

                long value;
                if ((opcode == 0x41) && (pos < length))
                {
                    byte opcode2 = code [pos++];

                    if ((opcode2 < 0x50) || (opcode2 > 0x57))
                    {
                        break;
                    }

                    switch (opcode2)
                    {
                    case 0x50:                     /* r8 */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.R8].SetValue(rbp, value);
                        break;

                    case 0x51:                     /* r9 */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.R9].SetValue(rbp, value);
                        break;

                    case 0x52:                     /* r10 */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.R10].SetValue(rbp, value);
                        break;

                    case 0x53:                     /* r11 */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.R11].SetValue(rbp, value);
                        break;

                    case 0x54:                     /* r12 */
                        value = (long)memory.ReadAddress(rbp).Address;
                        regs [(int)X86_Register.R12].SetValue(rbp, value);
                        break;

                    case 0x55:                     /* r13 */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.R13].SetValue(rbp, value);
                        break;

                    case 0x56:                     /* r14 */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.R14].SetValue(rbp, value);
                        break;

                    case 0x57:                     /* r15 */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.R15].SetValue(rbp, value);
                        break;
                    }
                }
                else
                {
                    if ((opcode < 0x50) || (opcode > 0x57))
                    {
                        break;
                    }

                    switch (opcode)
                    {
                    case 0x50:                     /* rax */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.RAX].SetValue(rbp, value);
                        break;

                    case 0x51:                     /* rcx */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.RCX].SetValue(rbp, value);
                        break;

                    case 0x52:                     /* rdx */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.RDX].SetValue(rbp, value);
                        break;

                    case 0x53:                     /* rbx */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.RBX].SetValue(rbp, value);
                        break;

                    case 0x56:                     /* rsi */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.RSI].SetValue(rbp, value);
                        break;

                    case 0x57:                     /* rdi */
                        value = memory.ReadLongInteger(rbp);
                        regs [(int)X86_Register.RDI].SetValue(rbp, value);
                        break;
                    }
                }

                rbp -= addr_size;
            }

            return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs));
        }
예제 #29
0
        public TargetAddress MonoClassGetParent(TargetMemoryAccess memory,
							 TargetAddress klass)
        {
            return memory.ReadAddress (klass + MonoMetadataInfo.KlassParentOffset);
        }
예제 #30
0
            void GetValue(TargetMemoryAccess target, Registers regs,
				       TargetAddress cfa, int reg, Column column)
            {
                switch (column.State) {
                case State.Register: {
                    GetRegisterValue (regs, reg, column);
                    break;
                }

                case State.SameValue:
                    regs [GetArchRegister (reg)].Valid = true;
                    break;

                case State.Undefined:
                    break;

                case State.Offset: {
                    TargetAddress addr = cfa + column.Offset;
                    long value = target.ReadAddress (addr).Address;
                    regs [GetArchRegister (reg)].SetValue (address, value);
                    break;
                }

                default:
                    throw new NotSupportedException ();
                }
            }
예제 #31
0
        StackFrame try_syscall_trampoline(StackFrame frame, TargetMemoryAccess memory)
        {
            /*
             * This is a hack for system call trampolines on NPTL-enabled glibc's.
             */
            if (frame.TargetAddress.Address != 0xffffe002)
                return null;

            Registers old_regs = frame.Registers;
            Registers regs = CopyRegisters (old_regs);

            TargetAddress esp = frame.StackPointer;

            TargetAddress new_eip = memory.ReadAddress (esp);
            TargetAddress new_esp = esp + 4;
            TargetAddress new_ebp = frame.FrameAddress;

            regs [(int)X86_Register.RIP].SetValue (esp, new_eip);
            regs [(int)X86_Register.RBP].SetValue (new_ebp);

            return CreateFrame (frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs);
        }
예제 #32
0
        public override TargetAddress GetEffectiveAddress(TargetMemoryAccess memory)
        {
            if (!CallTarget.IsNull)
                return CallTarget;

            Registers regs = memory.GetRegisters ();

            long effective_displacement = Displacement;
            if (IndexRegister >= 0) {
                long index = regs [IndexRegister].GetValue ();
                index *= 1 << SIB.Scale;
                effective_displacement += index;
            }

            TargetAddress effective_address;
            if (is_ip_relative)
                effective_address = Address + InstructionSize;
            else
                effective_address = new TargetAddress (
                    memory.AddressDomain, regs [Register].GetValue ());

            effective_address += effective_displacement;

            if (DereferenceAddress)
                effective_address = memory.ReadAddress (effective_address);

            return effective_address;
        }
예제 #33
0
        StackFrame unwind_method(StackFrame frame, TargetMemoryAccess memory, byte[] code,
					  int pos, int offset)
        {
            Registers old_regs = frame.Registers;
            Registers regs = new Registers (old_regs);

            TargetAddress ebp = new TargetAddress (
                memory.AddressDomain, old_regs [(int) X86_Register.RBP].GetValue ());

            int addr_size = TargetAddressSize;
            TargetAddress new_ebp = memory.ReadAddress (ebp);
            regs [(int) X86_Register.RBP].SetValue (ebp, new_ebp);

            TargetAddress new_eip = memory.ReadAddress (ebp + addr_size);
            regs [(int) X86_Register.RIP].SetValue (ebp + addr_size, new_eip);

            TargetAddress new_esp = ebp + 2 * addr_size;
            regs [(int) X86_Register.RSP].SetValue (ebp, new_esp);

            regs [(int) X86_Register.RSI].Valid = true;
            regs [(int) X86_Register.RDI].Valid = true;

            ebp -= addr_size;

            int length = System.Math.Min (code.Length, offset);
            while (pos < length) {
                byte opcode = code [pos++];

                if ((opcode < 0x50) || (opcode > 0x57))
                    break;

                long value;
                switch (opcode) {
                case 0x50: /* eax */
                    value = (long) (uint) memory.ReadInteger (ebp);
                    regs [(int) X86_Register.RAX].SetValue (ebp, value);
                    break;
                case 0x51: /* ecx */
                    value = (long) (uint) memory.ReadInteger (ebp);
                    regs [(int) X86_Register.RCX].SetValue (ebp, value);
                    break;
                case 0x52: /* edx */
                    value = (long) (uint) memory.ReadInteger (ebp);
                    regs [(int) X86_Register.RDX].SetValue (ebp, value);
                    break;
                case 0x53: /* ebx */
                    value = (long) (uint) memory.ReadInteger (ebp);
                    regs [(int) X86_Register.RBX].SetValue (ebp, value);
                    break;
                case 0x56: /* esi */
                    value = (long) (uint) memory.ReadInteger (ebp);
                    regs [(int) X86_Register.RSI].SetValue (ebp, value);
                    break;
                case 0x57: /* edi */
                    value = (long) (uint) memory.ReadInteger (ebp);
                    regs [(int) X86_Register.RDI].SetValue (ebp, value);
                    break;
                }

                ebp -= addr_size;
            }

            return CreateFrame (frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs);
        }
예제 #34
0
        void update(TargetMemoryAccess target)
        {
            // If this is a reference type, the register just holds the
            // address of the actual data, so read the address from the
            // register and return it.
            if (!register.Valid) {
                is_valid = false;
                return;
            }

            long contents = register.Value;

            if (contents == 0)
                address = TargetAddress.Null;
            else
                address = new TargetAddress (
                    target.AddressDomain, contents + regoffset);

            if (is_byref && is_regoffset)
                address = target.ReadAddress (address);
            is_valid = true;
        }
예제 #35
0
 public TargetAddress GetObjectClass(TargetMemoryAccess memory)
 {
     return(memory.ReadAddress(MonoMetadataInfo.MonoDefaultsAddress +
                               MonoMetadataInfo.MonoDefaultsObjectOffset));
 }
예제 #36
0
        StackFrame try_pthread_cond_timedwait(StackFrame frame, TargetMemoryAccess memory)
        {
            Symbol name = frame.Name;

            /*
             * This is a hack for pthread_cond_timedwait() on Red Hat 9.
             */
            if ((name == null) || (name.Name != "pthread_cond_timedwait") ||
                (name.Offset != 0xe5))
                return null;

            /*
             * Disassemble some bytes of the method to find out whether
             * it's the "correct" one.
             */
            uint data = (uint) memory.ReadInteger (name.Address);
            if (data != 0x53565755)
                return null;
            data = (uint) memory.ReadInteger (name.Address + 4);
            if (data != 0x14245c8b)
                return null;
            data = (uint) memory.ReadInteger (name.Address + 8);
            if (data != 0x1c246c8b)
                return null;

            data = (uint) memory.ReadInteger (frame.TargetAddress);
            if (data != 0x8910eb83)
                return null;

            data = (uint) memory.ReadInteger (frame.TargetAddress + 0x7b);
            if (data != 0x852cc483)
                return null;
            data = (uint) memory.ReadInteger (frame.TargetAddress + 0x7f);
            if (data != 0xc6440fc0)
                return null;

            TargetAddress esp = frame.StackPointer;

            Registers regs = new Registers (this);

            TargetAddress ebx = memory.ReadAddress (esp + 0x2c);
            TargetAddress esi = memory.ReadAddress (esp + 0x30);
            TargetAddress edi = memory.ReadAddress (esp + 0x34);
            TargetAddress ebp = memory.ReadAddress (esp + 0x38);
            TargetAddress eip = memory.ReadAddress (esp + 0x3c);

            regs [(int)X86_Register.RBX].SetValue (esp + 0x2c, ebx);
            regs [(int)X86_Register.RSI].SetValue (esp + 0x30, esi);
            regs [(int)X86_Register.RDI].SetValue (esp + 0x34, edi);
            regs [(int)X86_Register.RBP].SetValue (esp + 0x38, ebp);
            regs [(int)X86_Register.RIP].SetValue (esp + 0x3c, eip);

            esp += 0x40;
            regs [(int)X86_Register.RSP].SetValue (esp.Address);

            return CreateFrame (frame.Thread, FrameType.Normal, memory, eip, esp, ebp, regs);
        }
예제 #37
0
 public TargetAddress GetExceptionClass(TargetMemoryAccess memory)
 {
     return(memory.ReadAddress(MonoMetadataInfo.MonoDefaultsAddress +
                               MonoMetadataInfo.MonoDefaultsExceptionOffset));
 }
예제 #38
0
        public TargetAddress MonoClassGetGenericContainer(TargetMemoryAccess memory,
								   TargetAddress klass)
        {
            return memory.ReadAddress (klass + MonoMetadataInfo.KlassGenericContainerOffset);
        }
예제 #39
0
        public TargetAddress MonoClassGetMethod(TargetMemoryAccess memory, TargetAddress klass,
							 int index)
        {
            TargetAddress methods = memory.ReadAddress (
                klass + MonoMetadataInfo.KlassMethodsOffset);

            if (methods.IsNull)
                throw new TargetException (TargetError.ClassNotInitialized);

            methods += index * memory.TargetAddressSize;
            return memory.ReadAddress (methods);
        }
예제 #40
0
        public MonoClassInfo ResolveClass(TargetMemoryAccess target, bool fail)
        {
            if (resolved)
                return class_info;

            if (class_info == null) {
                if (class_ptr.IsNull)
                    return null;

                TargetAddress klass = target.ReadAddress (class_ptr);
                if (klass.IsNull)
                    return null;

                class_info = File.MonoLanguage.ReadClassInfo (target, klass);
            }

            if (class_info == null) {
                if (!fail)
                    return null;

                throw new TargetException (TargetError.ClassNotInitialized,
                               "Class `{0}' not initialized yet.", Name);
            }

            if (class_info.HasParent) {
                MonoClassInfo parent_info = class_info.GetParent (target);
                parent_type = (IMonoStructType) parent_info.Type;
                parent_type.ClassInfo = parent_info;
                if (parent_type.ResolveClass (target, fail) == null)
                    return null;
            }

            resolved = true;
            return class_info;
        }
예제 #41
0
        StackFrame try_unwind_sigreturn(StackFrame frame, TargetMemoryAccess memory)
        {
            byte[] data = memory.ReadMemory (frame.TargetAddress, 9).Contents;

            /*
             * Check for signal return trampolines:
             *
             *   mov __NR_rt_sigreturn, %eax
             *   syscall
             */
            if ((data [0] != 0x48) || (data [1] != 0xc7) ||
                (data [2] != 0xc0) || (data [3] != 0x0f) ||
                (data [4] != 0x00) || (data [5] != 0x00) ||
                (data [6] != 0x00) || (data [7] != 0x0f) ||
                (data [8] != 0x05))
                return null;

            TargetAddress stack = frame.StackPointer;
            /* See `struct sigcontext' in <asm/sigcontext.h> */
            int[] regoffsets = {
                (int) X86_Register.R8,  (int) X86_Register.R9,
                (int) X86_Register.R10, (int) X86_Register.R11,
                (int) X86_Register.R12, (int) X86_Register.R13,
                (int) X86_Register.R14, (int) X86_Register.R15,
                (int) X86_Register.RDI, (int) X86_Register.RSI,
                (int) X86_Register.RBP, (int) X86_Register.RBX,
                (int) X86_Register.RDX, (int) X86_Register.RAX,
                (int) X86_Register.RCX, (int) X86_Register.RSP,
                (int) X86_Register.RIP, (int) X86_Register.EFLAGS
            };

            Registers regs = CopyRegisters (frame.Registers);

            int offset = 0x28;
            /* The stack contains the `struct ucontext' from <asm/ucontext.h>; the
             * `struct sigcontext' starts at offset 0x28 in it. */
            foreach (int regoffset in regoffsets) {
                TargetAddress new_value = memory.ReadAddress (stack + offset);
                regs [regoffset].SetValue (new_value);
                offset += 8;
            }

            TargetAddress rip = new TargetAddress (
                memory.AddressDomain, regs [(int) X86_Register.RIP].GetValue ());
            TargetAddress rsp = new TargetAddress (
                memory.AddressDomain, regs [(int) X86_Register.RSP].GetValue ());
            TargetAddress rbp = new TargetAddress (
                memory.AddressDomain, regs [(int) X86_Register.RBP].GetValue ());

            Symbol name = new Symbol ("<signal handler>", rip, 0);

            return new StackFrame (
                frame.Thread, FrameType.Signal, rip, rsp, rbp, regs, frame.Thread.NativeLanguage, name);
        }
예제 #42
0
        internal override StackFrame UnwindStack(StackFrame frame, TargetMemoryAccess memory,
							  byte[] code, int offset)
        {
            StackFrame new_frame;
            if ((code != null) && (code.Length > 3)) {
                new_frame = read_prologue (frame, memory, code, offset);
                if (new_frame != null)
                    return new_frame;
            }

            TargetAddress ebp = frame.FrameAddress;

            new_frame = do_hacks (frame, memory);
            if (new_frame != null)
                return new_frame;

            int addr_size = TargetAddressSize;

            Registers regs = new Registers (this);

            TargetAddress new_ebp = memory.ReadAddress (ebp);
            regs [(int) X86_Register.RBP].SetValue (ebp, new_ebp);

            TargetAddress new_eip = memory.ReadAddress (ebp + addr_size);
            regs [(int) X86_Register.RIP].SetValue (ebp + addr_size, new_eip);

            TargetAddress new_esp = ebp + 2 * addr_size;
            regs [(int) X86_Register.RSP].SetValue (ebp, new_esp);

            ebp -= addr_size;

            return CreateFrame (frame.Thread, FrameType.Normal, memory, new_eip, new_esp, new_ebp, regs);
        }
예제 #43
0
        internal override StackFrame GetLMF(ThreadServant thread, TargetMemoryAccess memory,
						     ref TargetAddress lmf_address)
        {
            TargetAddress lmf = lmf_address;

            TargetBinaryReader reader = memory.ReadMemory (lmf, 36).GetReader ();
            lmf_address = reader.ReadTargetAddress (); // prev

            reader.Position = 16;

            TargetAddress ebx = reader.ReadTargetAddress ();
            TargetAddress edi = reader.ReadTargetAddress ();
            TargetAddress esi = reader.ReadTargetAddress ();
            TargetAddress ebp = reader.ReadTargetAddress ();
            TargetAddress eip = reader.ReadTargetAddress ();

            Registers regs = new Registers (this);
            regs [(int) X86_Register.RBX].SetValue (lmf + 16, ebx);
            regs [(int) X86_Register.RDI].SetValue (lmf + 20, edi);
            regs [(int) X86_Register.RSI].SetValue (lmf + 24, esi);
            regs [(int) X86_Register.RBP].SetValue (lmf + 28, ebp);
            regs [(int) X86_Register.RIP].SetValue (lmf + 32, eip);

            TargetAddress new_ebp = memory.ReadAddress (ebp);
            regs [(int) X86_Register.RBP].SetValue (ebp, new_ebp);

            TargetAddress new_esp = ebp + 8;
            regs [(int) X86_Register.RSP].SetValue (ebp, new_esp);

            return CreateFrame (thread.Client, FrameType.LMF, memory, eip, new_esp, new_ebp, regs);
        }
예제 #44
0
        internal TargetClassObject GetCurrentObject(TargetMemoryAccess target,
							      TargetLocation location)
        {
            // location.Address resolves to the address of the MonoObject,
            // dereferencing it once gives us the vtable, dereferencing it
            // twice the class.
            TargetAddress address;
            address = target.ReadAddress (location.GetAddress (target));
            address = target.ReadAddress (address);

            TargetType current = File.MonoLanguage.ReadMonoClass (target, address);
            if (current == null)
                return null;

            if (IsByRef && !current.IsByRef) // Unbox
                location = location.GetLocationAtOffset (
                    2 * target.TargetMemoryInfo.TargetAddressSize);

            return (TargetClassObject) current.GetObject (target, location);
        }
예제 #45
0
 //
 // Fundamental types
 //
 public TargetAddress GetBooleanClass(TargetMemoryAccess memory)
 {
     return memory.ReadAddress (MonoMetadataInfo.MonoDefaultsAddress +
                    MonoMetadataInfo.MonoDefaultsBooleanOffset);
 }
예제 #46
0
        // This method reads the MonoDebuggerSymbolTable structure
        // (struct definition is in mono-debug-debugger.h)
        void do_read_symbol_table(TargetMemoryAccess memory)
        {
            TargetAddress symtab_address = memory.ReadAddress (info.SymbolTable);
            if (symtab_address.IsNull)
                throw new SymbolTableException ("Symbol table is null.");

            TargetReader header = new TargetReader (
                memory.ReadMemory (symtab_address, info.SymbolTableSize));

            long magic = header.BinaryReader.ReadInt64 ();
            if (magic != MonoDebuggerInfo.DynamicMagic)
                throw new SymbolTableException (
                    "Debugger symbol table has unknown magic {0:x}.", magic);

            int version = header.ReadInteger ();
            if (version < MonoDebuggerInfo.MinDynamicVersion)
                throw new SymbolTableException (
                    "Debugger symbol table has version {0}, but " +
                    "expected at least {1}.", version,
                    MonoDebuggerInfo.MinDynamicVersion);
            if (version > MonoDebuggerInfo.MaxDynamicVersion)
                throw new SymbolTableException (
                    "Debugger symbol table has version {0}, but " +
                    "expected at most {1}.", version,
                    MonoDebuggerInfo.MaxDynamicVersion);

            int total_size = header.ReadInteger ();
            if (total_size != info.SymbolTableSize)
                throw new SymbolTableException (
                    "Debugger symbol table has size {0}, but " +
                    "expected {1}.", total_size, info.SymbolTableSize);

            TargetAddress corlib_address = header.ReadAddress ();
            TargetAddress global_data_table_ptr = header.ReadAddress ();
            TargetAddress data_table_list = header.ReadAddress ();

            TargetAddress symfile_by_index = header.ReadAddress ();

            if (corlib_address.IsNull)
                throw new SymbolTableException ("Corlib address is null.");
            corlib = load_symfile (memory, corlib_address);
            if (corlib == null)
                throw new SymbolTableException ("Cannot read corlib!");

            TargetAddress ptr = symfile_by_index;
            while (!ptr.IsNull) {
                TargetAddress next_ptr = memory.ReadAddress (ptr);
                TargetAddress address = memory.ReadAddress (
                    ptr + memory.TargetMemoryInfo.TargetAddressSize);

                ptr = next_ptr;
                load_symfile (memory, address);
            }

            ptr = data_table_list;
            while (!ptr.IsNull) {
                TargetAddress next_ptr = memory.ReadAddress (ptr);
                TargetAddress address = memory.ReadAddress (
                    ptr + memory.TargetMemoryInfo.TargetAddressSize);

                ptr = next_ptr;
                add_data_table (memory, address);
            }

            global_data_table = new GlobalDataTable (this, global_data_table_ptr);
        }
예제 #47
0
 public TargetAddress MonoTypeGetData(TargetMemoryAccess memory, TargetAddress type)
 {
     return memory.ReadAddress (type);
 }
예제 #48
0
        void read_mono_debugger_info(TargetMemoryAccess memory)
        {
            runtime = MetadataHelper.Create (memory, info);

            trampolines = new TargetAddress [info.MonoTrampolineNum];

            TargetAddress address = info.MonoTrampolineCode;
            for (int i = 0; i < trampolines.Length; i++) {
                trampolines [i] = memory.ReadAddress (address);
                address += memory.TargetMemoryInfo.TargetAddressSize;
            }

            symfile_by_index = new Hashtable ();
            symfile_by_image_addr = new Hashtable ();
            symfile_hash = new Hashtable ();
            assembly_hash = new Hashtable ();
            assembly_by_name = new Hashtable ();
            class_hash = new Hashtable ();
            class_info_by_addr = new Dictionary<TargetAddress,MonoClassInfo> ();
        }
예제 #49
0
 public TargetAddress MonoTypeGetData(TargetMemoryAccess memory, TargetAddress type)
 {
     return(memory.ReadAddress(type));
 }
예제 #50
0
        public void Read(TargetMemoryAccess memory)
        {
            int address_size = memory.TargetMemoryInfo.TargetAddressSize;
            int header_size = 16 + address_size;

            if (first_chunk.IsNull) {
                first_chunk = memory.ReadAddress (TableAddress + 8);
                current_chunk = first_chunk;
            }

            if (current_chunk.IsNull)
                return;

            again:
            TargetReader reader = new TargetReader (
                memory.ReadMemory (current_chunk, header_size));

            reader.ReadInteger (); /* size */
            int allocated_size = reader.ReadInteger ();
            int current_offset = reader.ReadInteger ();
            reader.ReadInteger (); /* dummy */
            TargetAddress next = reader.ReadAddress ();

            read_data_items (memory, current_chunk + header_size,
                     last_offset, current_offset);

            last_offset = current_offset;

            if (!next.IsNull && (current_offset == allocated_size)) {
                current_chunk = next;
                last_offset = 0;
                goto again;
            }
        }
예제 #51
0
 public TargetAddress MonoMethodGetClass(TargetMemoryAccess memory, TargetAddress method)
 {
     return memory.ReadAddress (method + MonoMetadataInfo.MonoMethodKlassOffset);
 }
예제 #52
0
        public MethodSource GetTrampoline(TargetMemoryAccess memory,
						   TargetAddress address)
        {
            #if FIXME
            int insn_size;
            TargetAddress target;
            CallTargetType type = memory.Architecture.GetCallTarget (
                memory, address, out target, out insn_size);
            if (type != CallTargetType.MonoTrampoline)
                return null;

            int token = memory.ReadInteger (target + 4);
            TargetAddress klass = memory.ReadAddress (target + 8);
            TargetAddress image = memory.ReadAddress (klass);

            foreach (MonoSymbolFile file in symfile_by_index.Values) {
                if (file.MonoImage != image)
                    continue;

                return file.GetMethodByToken (token);
            }
            #endif

            return null;
        }
예제 #53
0
 public TargetAddress GetDelegateClass(TargetMemoryAccess memory)
 {
     return(memory.ReadAddress(MonoMetadataInfo.MonoDefaultsAddress +
                               MonoMetadataInfo.MonoDefaultsDelegateOffset));
 }
예제 #54
0
        internal override StackFrame GetLMF(ThreadServant thread, TargetMemoryAccess memory, ref TargetAddress lmf_address)
        {
            TargetAddress lmf = lmf_address;
            TargetBinaryReader reader = memory.ReadMemory (lmf_address, 88).GetReader ();

            lmf_address = reader.ReadTargetAddress (); // prev
            reader.ReadTargetAddress ();
            reader.ReadTargetAddress (); // method
            TargetAddress rip = reader.ReadTargetAddress ();

            if (lmf_address.IsNull)
                return null;

            TargetAddress rbx = reader.ReadTargetAddress ();
            TargetAddress rbp = reader.ReadTargetAddress ();
            TargetAddress rsp = reader.ReadTargetAddress ();
            TargetAddress r12 = reader.ReadTargetAddress ();
            TargetAddress r13 = reader.ReadTargetAddress ();
            TargetAddress r14 = reader.ReadTargetAddress ();
            TargetAddress r15 = reader.ReadTargetAddress ();

            Registers regs = new Registers (this);

            if ((lmf_address.Address & 1) == 0) {
                rip = memory.ReadAddress (rsp - 8);
                regs [(int) X86_Register.RIP].SetValue (rsp - 8, rip);
                regs [(int) X86_Register.RBP].SetValue (lmf + 40, rbp);
            } else {
                TargetAddress new_rbp = memory.ReadAddress (rbp);
                regs [(int) X86_Register.RIP].SetValue (lmf + 24, rip);
                regs [(int) X86_Register.RBP].SetValue (rbp, new_rbp);
                rbp = new_rbp;
                lmf_address--;
            }

            regs [(int) X86_Register.RBX].SetValue (lmf + 32, rbx);
            regs [(int) X86_Register.RSP].SetValue (lmf + 48, rsp);
            regs [(int) X86_Register.R12].SetValue (lmf + 56, r12);
            regs [(int) X86_Register.R13].SetValue (lmf + 64, r13);
            regs [(int) X86_Register.R14].SetValue (lmf + 72, r14);
            regs [(int) X86_Register.R15].SetValue (lmf + 80, r15);

            return CreateFrame (thread.Client, FrameType.LMF, memory, rip, rsp, rbp, regs);
        }
예제 #55
0
 public bool MonoClassHasMethods(TargetMemoryAccess memory, TargetAddress klass)
 {
     TargetAddress methods = memory.ReadAddress (
         klass + MonoMetadataInfo.KlassMethodsOffset);
     return !methods.IsNull;
 }
예제 #56
0
        internal override StackFrame UnwindStack(StackFrame frame, TargetMemoryAccess memory,
							  byte[] code, int offset)
        {
            if ((code != null) && (code.Length > 4))
                return read_prologue (frame, memory, code, offset);

            TargetAddress rbp = frame.FrameAddress;

            int addr_size = TargetAddressSize;

            Registers regs = CopyRegisters (frame.Registers);

            TargetAddress new_rbp = memory.ReadAddress (rbp);
            regs [(int) X86_Register.RBP].SetValue (rbp, new_rbp);

            TargetAddress new_rip = memory.ReadAddress (rbp + addr_size);
            regs [(int) X86_Register.RIP].SetValue (rbp + addr_size, new_rip);

            TargetAddress new_rsp = rbp + 2 * addr_size;
            regs [(int) X86_Register.RSP].SetValue (rbp, new_rsp);

            rbp -= addr_size;

            return CreateFrame (frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs);
        }
예제 #57
0
        //
        // MonoClass
        //

        public TargetAddress MonoClassGetMonoImage(TargetMemoryAccess memory,
                                                   TargetAddress klass)
        {
            return(memory.ReadAddress(klass + MonoMetadataInfo.KlassImageOffset));
        }
예제 #58
0
        StackFrame read_prologue(StackFrame frame, TargetMemoryAccess memory,
					  byte[] code, int offset)
        {
            int length = code.Length;
            int pos = 0;

            if (length < 4)
                return null;

            while ((pos < length) &&
                   (code [pos] == 0x90) || (code [pos] == 0xcc))
                pos++;

            if (pos+5 >= length) {
                // unknown prologue
                return null;
            }

            if (pos >= offset) {
                Registers regs = CopyRegisters (frame.Registers);

                TargetAddress new_rip = memory.ReadAddress (frame.StackPointer);
                regs [(int) X86_Register.RIP].SetValue (frame.StackPointer, new_rip);

                TargetAddress new_rsp = frame.StackPointer + TargetAddressSize;
                TargetAddress new_rbp = frame.FrameAddress;

                regs [(int) X86_Register.RSP].SetValue (new_rsp);

                return CreateFrame (frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs);
            }

            // push %ebp
            if (code [pos++] != 0x55) {
                // unknown prologue
                return null;
            }

            if (pos >= offset) {
                Registers regs = CopyRegisters (frame.Registers);

                int addr_size = TargetAddressSize;
                TargetAddress new_rbp = memory.ReadAddress (frame.StackPointer);
                regs [(int) X86_Register.RBP].SetValue (frame.StackPointer, new_rbp);

                TargetAddress new_rsp = frame.StackPointer + addr_size;
                TargetAddress new_rip = memory.ReadAddress (new_rsp);
                regs [(int) X86_Register.RIP].SetValue (new_rsp, new_rip);
                new_rsp -= addr_size;

                regs [(int) X86_Register.RSP].SetValue (new_rsp);

                return CreateFrame (frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs);
            }

            if (code [pos++] != 0x48) {
                // unknown prologue
                return null;
            }

            // mov %ebp, %esp
            if (((code [pos] != 0x8b) || (code [pos+1] != 0xec)) &&
                ((code [pos] != 0x89) || (code [pos+1] != 0xe5))) {
                // unknown prologue
                return null;
            }

            pos += 2;
            if (pos >= offset)
                return null;

            return unwind_method (frame, memory, code, pos, offset);
        }
예제 #59
0
        public TargetAddress MonoClassGetFieldType(TargetMemoryAccess memory, TargetAddress klass,
							    int index)
        {
            int offset = index * MonoMetadataInfo.FieldInfoSize +
                MonoMetadataInfo.FieldInfoTypeOffset;

            TargetAddress fields = memory.ReadAddress (
                klass + MonoMetadataInfo.KlassFieldOffset);
            if (fields.IsNull)
                throw new TargetException (TargetError.ClassNotInitialized);

            return memory.ReadAddress (fields + offset);
        }
예제 #60
0
        StackFrame read_prologue(StackFrame frame, TargetMemoryAccess memory,
                                 byte[] code, int offset)
        {
            int length = code.Length;
            int pos    = 0;

            if (length < 4)
            {
                return(null);
            }

            while ((pos < length) &&
                   (code [pos] == 0x90) || (code [pos] == 0xcc))
            {
                pos++;
            }

            if (pos + 5 >= length)
            {
                // unknown prologue
                return(null);
            }

            if (pos >= offset)
            {
                Registers regs = CopyRegisters(frame.Registers);

                TargetAddress new_rip = memory.ReadAddress(frame.StackPointer);
                regs [(int)X86_Register.RIP].SetValue(frame.StackPointer, new_rip);

                TargetAddress new_rsp = frame.StackPointer + TargetAddressSize;
                TargetAddress new_rbp = frame.FrameAddress;

                regs [(int)X86_Register.RSP].SetValue(new_rsp);

                return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs));
            }

            // push %ebp
            if (code [pos++] != 0x55)
            {
                // unknown prologue
                return(null);
            }

            if (pos >= offset)
            {
                Registers regs = CopyRegisters(frame.Registers);

                int           addr_size = TargetAddressSize;
                TargetAddress new_rbp   = memory.ReadAddress(frame.StackPointer);
                regs [(int)X86_Register.RBP].SetValue(frame.StackPointer, new_rbp);

                TargetAddress new_rsp = frame.StackPointer + addr_size;
                TargetAddress new_rip = memory.ReadAddress(new_rsp);
                regs [(int)X86_Register.RIP].SetValue(new_rsp, new_rip);
                new_rsp -= addr_size;

                regs [(int)X86_Register.RSP].SetValue(new_rsp);

                return(CreateFrame(frame.Thread, FrameType.Normal, memory, new_rip, new_rsp, new_rbp, regs));
            }

            if (code [pos++] != 0x48)
            {
                // unknown prologue
                return(null);
            }

            // mov %ebp, %esp
            if (((code [pos] != 0x8b) || (code [pos + 1] != 0xec)) &&
                ((code [pos] != 0x89) || (code [pos + 1] != 0xe5)))
            {
                // unknown prologue
                return(null);
            }

            pos += 2;
            if (pos >= offset)
            {
                return(null);
            }

            return(unwind_method(frame, memory, code, pos, offset));
        }