예제 #1
0
        /// <summary>
        /// Performs a shingle scan of the executable segments of the program,
        /// returning the interprocedural control flow graph (ICFG) and locations
        /// of likely call destinations.
        /// </summary>
        /// <returns></returns>
        public ScanResults ScanNew()
        {
            ICodeLocation location = null;
            Exception     error;

            try
            {
                var q = ScanExecutableSegments();
            }
            catch (AddressCorrelatedException aex)
            {
                location = eventListener.CreateAddressNavigator(program, aex.Address);
                error    = aex;
            }
            catch (Exception ex)
            {
                location = new NullCodeLocation("");
                error    = ex;
            }
            if (location != null)
            {
                eventListener.Error(location, "An error occurred while scanning {0}.");
            }
            return(new ScanResults
            {
                ICFG = new DiGraph <RtlBlock>(),
                DirectlyCalledAddresses = this.sr.DirectlyCalledAddresses,
                KnownProcedures = sr.KnownProcedures,
            });
        }
예제 #2
0
        public override void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations)
        {
            ushort  fixup  = rdr.ReadLeUInt16();
            Address offset = baseOfImage + page + (fixup & 0x0FFFu);
            var     arch   = program.Architecture;
            var     imgR   = program.CreateImageReader(arch, offset);
            var     imgW   = program.CreateImageWriter(arch, offset);

            switch (fixup >> 12)
            {
            case RelocationAbsolute:
                // Used for padding to 4-byte boundary, ignore.
                break;

            case RelocationHighLow:
            {
                uint n = (uint)(imgR.ReadUInt32() + (baseOfImage - program.ImageMap.BaseAddress));
                imgW.WriteUInt32(n);
                relocations.AddPointerReference(offset.ToLinear(), n);
                break;
            }

            case 0xA:
                break;

            default:
                dcSvc.Warn(
                    dcSvc.CreateAddressNavigator(program, offset),
                    string.Format(
                        "Unsupported i386 PE fixup type: {0:X}",
                        fixup >> 12));
                break;
            }
        }
예제 #3
0
        private UserProcedure?LoadUserProcedure(
            Program program,
            Procedure_v1 sup)
        {
            if (!program.Architecture.TryParseAddress(sup.Address, out Address addr))
            {
                return(null);
            }

            if (!sup.Decompile && sup.Signature == null && string.IsNullOrEmpty(sup.CSignature))
            {
                listener.Warn(
                    listener.CreateAddressNavigator(program, addr),
                    "User procedure '{0}' has been marked 'no decompile' but its signature " +
                    "has not been specified.",
                    sup.Name ?? "<unnamed>");
            }

            string name = sup.Name ?? NamingPolicy.Instance.ProcedureName(addr);

            var up = new UserProcedure(addr, name)
            {
                Ordinal         = sup.Ordinal,
                Signature       = sup.Signature,
                Characteristics = sup.Characteristics ?? new ProcedureCharacteristics(),
                Decompile       = sup.Decompile,
                Assume          = sup.Assume?.ToList() ?? new List <RegisterValue_v2>(),
                CSignature      = sup.CSignature,
                OutputFile      = sup.OutputFile
            };

            return(up);
        }
예제 #4
0
        // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
        public override void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations)
        {
            ushort  fixup  = rdr.ReadLeUInt16();
            var     rt     = (Arm64Rt)(fixup >> 12);
            Address offset = baseOfImage + page + (fixup & 0x0FFFu);

            DebugEx.Verbose(PeImageLoader.trace, "  {0:X4} {1}", fixup, rt);
            var imgR = program.CreateImageReader(program.Architecture, offset);
            var imgW = program.CreateImageWriter(program.Architecture, offset);

            switch (rt)
            {
            case Arm64Rt.IMAGE_REL_ARM64_ABSOLUTE:
                break;

            case Arm64Rt.IMAGE_REL_ARM64_SECREL_HIGH12A:
                var uInstr = imgR.ReadLeUInt32();
                break;

            default:
                eventListener.Warn(
                    eventListener.CreateAddressNavigator(program, offset),
                    string.Format(
                        "Unsupported AArch64 PE fixup type: {0:X}",
                        fixup >> 12));
                break;
            }
        }
예제 #5
0
파일: ProjectLoader.cs 프로젝트: ntzwq/reko
 private KeyValuePair<Address, Procedure_v1> LoadUserProcedure_v1(
     Program program,
     Procedure_v1 sup)
 {
     program.Architecture.TryParseAddress(sup.Address, out Address addr);
     if (!sup.Decompile && sup.Signature == null && string.IsNullOrEmpty(sup.CSignature))
     {
         listener.Warn(
             listener.CreateAddressNavigator(program, addr),
             "User procedure '{0}' has been marked 'no decompile' but its signature " +
             "has not been specified.",
             sup.Name ?? "<unnamed>");
     }
     return new KeyValuePair<Address, Procedure_v1>(addr, sup);
 }
예제 #6
0
        public const short IMAGE_REL_MIPS_PAIR      = 0x0025; // This relocation is only valid when it immediately follows a REFHI or SECRELHI relocation. Its SymbolTableIndex contains a displacement and not an index into the symbol table.

        public override void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations)
        {
            ushort  fixup  = rdr.ReadUInt16();
            Address offset = baseOfImage + page + (fixup & 0x0FFFu);
            var     arch   = program.Architecture;
            var     imgR   = program.CreateImageReader(arch, offset);
            var     imgW   = program.CreateImageWriter(arch, offset);
            uint    w      = imgR.ReadUInt32();
            int     s;

            switch (fixup >> 12)
            {
            case IMAGE_REL_MIPS_ABSOLUTE:
                // Used for padding to 4-byte boundary, ignore.
                break;

            case IMAGE_REL_MIPS_REFWORD:
                break;

            case IMAGE_REL_MIPS_JMPADDR:
                break;

            case IMAGE_REL_MIPS_REFHI:
                w = imgR.ReadUInt32();
                //w += (fixup & 0x0FFFu);
                //imgW.WriteUInt32(w);
                s = rdr.ReadInt16();
                w = (uint)(w + s);
                // w points to something.
                break;

            case IMAGE_REL_MIPS_REFLO:
                // w points to something.
                break;

            default:
                dcSvc.Warn(
                    dcSvc.CreateAddressNavigator(program, offset),
                    string.Format(
                        "Unsupported MIPS PE fixup type: {0:X}",
                        fixup >> 12));
                break;
            }
        }
예제 #7
0
 public void Warn(string format, params object [] args)
 {
     decompilerEventListener.Warn(
         decompilerEventListener.CreateAddressNavigator(program, addr),
         string.Format(format, args));
 }
예제 #8
0
 public void Warn(Address addr, string message)
 {
     eventListener.Warn(eventListener.CreateAddressNavigator(Program, addr), message);
 }
예제 #9
0
        public TableExtent DiscoverTableExtent(Address addrSwitch, RtlTransfer xfer, DecompilerEventListener listener)
        {
            if (!Start(rtlBlock, host.BlockInstructionCount(rtlBlock) - 1, xfer.Target))
            {
                // No registers were found, so we can't trace back.
                return(null);
            }
            while (Step())
            {
                ;
            }

            var jumpExpr = this.JumpTableFormat;
            var interval = this.JumpTableIndexInterval;
            var index    = this.JumpTableIndexToUse;
            var ctx      = new Dictionary <Expression, ValueSet>(new ExpressionValueComparer());

            if (index == null)
            {
                // Weren't able to find the index register,
                // try finding it by blind pattern matching.
                index = this.FindIndexWithPatternMatch(this.JumpTableFormat);
                if (index == null)
                {
                    // This is likely an indirect call like a C++
                    // vtable dispatch. Since these are common, we don't
                    // spam the user with warnings.
                    return(null);
                }

                // We have a jump table, and we've guessed the index expression.
                // At this point we've given up on knowing the exact size
                // of the table, but we do know that it must be at least
                // more than one entry. The safest assumption is that it
                // has two entries.
                listener.Warn(
                    listener.CreateAddressNavigator(host.Program, addrSwitch),
                    "Unable to determine size of call or jump table; there may be more than 2 entries.");
                ctx.Add(index, new IntervalValueSet(index.DataType, StridedInterval.Create(1, 0, 1)));
            }
            else if (interval.IsEmpty)
            {
                return(null);
            }
            else if (interval.High == Int64.MaxValue)
            {
                // We have no reasonable upper bound. We make the arbitrary
                // assumption that the jump table has 2 items; it wouldn't
                // make sense to be indexing otherwise.
                listener.Warn(
                    listener.CreateAddressNavigator(host.Program, addrSwitch),
                    "Unable to determine the upper bound of an indirect call or jump; there may be more than 2 entries.");
                var vs = new IntervalValueSet(
                    this.JumpTableIndex.DataType,
                    StridedInterval.Create(1, interval.Low, interval.Low + 1));
                ctx.Add(this.JumpTableIndexToUse, vs);
            }
            else
            {
                ctx.Add(this.JumpTableIndex, new IntervalValueSet(this.JumpTableIndex.DataType, interval));
            }
            var vse = new ValueSetEvaluator(host.Architecture, host.SegmentMap, ctx, this.processorState);

            var(values, accesses) = vse.Evaluate(jumpExpr);
            var vector = values.Values
                         .TakeWhile(c => c != Constant.Invalid)
                         .Take(2000)    // Arbitrary limit
                         .Select(ForceToAddress)
                         .TakeWhile(a => a != null)
                         .ToList();

            if (vector.Count == 0)
            {
                return(null);
            }
            return(new TableExtent
            {
                Targets = vector,
                Accesses = accesses,
                Index = index,
            });
        }