예제 #1
0
            void parseSection64(uint protection, SegmentMap segmentMap)
            {
                var   abSectname = rdr.ReadBytes(16);
                var   abSegname  = rdr.ReadBytes(16);
                ulong addr;
                ulong size;
                uint  offset;
                uint  align;
                uint  reloff;
                uint  nreloc;
                uint  flags;
                uint  reserved1;
                uint  reserved2;
                uint  reserved3;

                if (!rdr.TryReadUInt64(out addr) ||
                    !rdr.TryReadUInt64(out size) ||
                    !rdr.TryReadUInt32(out offset) ||
                    !rdr.TryReadUInt32(out align) ||
                    !rdr.TryReadUInt32(out reloff) ||
                    !rdr.TryReadUInt32(out nreloc) ||
                    !rdr.TryReadUInt32(out flags) ||
                    !rdr.TryReadUInt32(out reserved1) ||
                    !rdr.TryReadUInt32(out reserved2) ||
                    !rdr.TryReadUInt32(out reserved3))
                {
                    throw new BadImageFormatException("Could not read Mach-O section.");
                }

                var sectionName = GetAsciizString(abSectname);
                var segmentName = GetAsciizString(abSegname);

                Debug.Print("Found section '{0}' in segment '{1}, addr = 0x{2:X}, size = 0x{3:X}.",
                            sectionName,
                            segmentName,
                            addr,
                            size);

                AccessMode am = 0;

                if ((protection & VM_PROT_READ) != 0)
                {
                    am |= AccessMode.Read;
                }
                if ((protection & VM_PROT_WRITE) != 0)
                {
                    am |= AccessMode.Write;
                }
                if ((protection & VM_PROT_EXECUTE) != 0)
                {
                    am |= AccessMode.Execute;
                }

                var bytes = rdr.CreateNew(this.ldr.RawImage, offset);
                var mem   = new MemoryArea(
                    Address.Ptr64(addr),
                    bytes.ReadBytes((uint)size));
                var imageSection = new ImageSegment(
                    string.Format("{0},{1}", segmentName, sectionName),
                    mem,
                    am);

                //imageSection.setBss((section.flags & SECTION_TYPE) == S_ZEROFILL);

                //if (!imageSection.isBss()) {
                //    auto pos = source_->pos();
                //    if (!source_->seek(section.offset)) {
                //        throw ParseError("Could not seek to the beginning of the section's content.");
                //    }
                //    auto bytes = source_->read(section.size);
                //    if (checked_cast<uint>(bytes.size()) != section.size) {
                //        log_.warning("Could not read all the section's content.");
                //    } else {
                //        imageSection->setContent(std::move(bytes));
                //    }
                //    source_->seek(pos);
                //}

                //sections_.push_back(imageSection.get());
                //image_->addSection(std::move(imageSection));
                segmentMap.AddSegment(imageSection);
            }
예제 #2
0
        public override RelocationResults Relocate(Program program, Address addrLoad)
        {
            SegmentMap        imageMap = segmentMap;
            EndianImageReader rdr      = new LeImageReader(exe.RawImage, exe.e_lfaRelocations);
            var relocations            = imgLoaded.Relocations;
            int i        = exe.e_cRelocations;
            var segments = new Dictionary <Address, ushort>();
            var linBase  = addrLoad.ToLinear();

            while (i != 0)
            {
                uint   offset    = rdr.ReadLeUInt16();
                ushort segOffset = rdr.ReadLeUInt16();
                offset += segOffset * 0x0010u;

                ushort seg = (ushort)(imgLoaded.ReadLeUInt16(offset) + addrLoad.Selector.Value);
                imgLoaded.WriteLeUInt16(offset, seg);
                relocations.AddSegmentReference(offset + linBase, seg);

                var segment = new ImageSegment(
                    seg.ToString("X4"),
                    Address.SegPtr(seg, 0),
                    imgLoaded,
                    AccessMode.ReadWriteExecute);
                segment = segmentMap.AddSegment(segment);
                segments[segment.Address] = seg;
                --i;
            }

            // Create an identifier for each segment.
            foreach (var de in segments)
            {
                var tmp = new TemporaryStorage(
                    string.Format("seg{0:X4}", de.Value),
                    0,
                    PrimitiveType.SegmentSelector);
                segmentMap.Segments[de.Key].Identifier = new Identifier(
                    tmp.Name,
                    PrimitiveType.SegmentSelector,
                    tmp);
            }

            // Found the start address.

            Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector.Value), exe.e_ip);

            segmentMap.AddSegment(new ImageSegment(
                                      addrStart.Selector.Value.ToString("X4"),
                                      Address.SegPtr(addrStart.Selector.Value, 0),
                                      imgLoaded,
                                      AccessMode.ReadWriteExecute));
            DumpSegments(imageMap);

            var ep = new ImageSymbol(addrStart)
            {
                Type           = SymbolType.Procedure,
                ProcessorState = arch.CreateProcessorState()
            };
            var sym     = platform.FindMainProcedure(program, addrStart);
            var results = new RelocationResults(
                new List <ImageSymbol> {
                ep
            },
                new SortedList <Address, ImageSymbol> {
                { ep.Address, ep }
            });

            if (sym != null)
            {
                results.Symbols[sym.Address] = sym;
                ep.NoDecompile = true;
            }

            LoadDebugSymbols(results.Symbols, addrLoad);
            return(results);
        }
예제 #3
0
파일: ElfLoader64.cs 프로젝트: Seabreg/reko
        public override SegmentMap LoadImageBytes(IPlatform platform, byte[] rawImage, Address addrPreferred)
        {
            var segMap = AllocateMemoryAreas(
                Segments
                .Where(p => IsLoadable(p.p_pmemsz, p.p_type))
                .Select(p => Tuple.Create(
                            platform.MakeAddressFromLinear(p.p_vaddr, false),
                            (uint)p.p_pmemsz)));

            foreach (var ph in Segments)
            {
                DebugEx.Inform(ElfImageLoader.trace, "ph: addr {0:X8} filesize {0:X8} memsize {0:X8}", ph.p_vaddr, ph.p_filesz, ph.p_pmemsz);
                if (!IsLoadable(ph.p_pmemsz, ph.p_type))
                {
                    continue;
                }
                var vaddr = platform.MakeAddressFromLinear(ph.p_vaddr, false);
                segMap.TryGetLowerBound(vaddr, out var mem);
                if (ph.p_filesz > 0)
                {
                    Array.Copy(
                        rawImage,
                        (long)ph.p_offset, mem.Bytes,
                        vaddr - mem.BaseAddress, (long)ph.p_filesz);
                }
            }
            var segmentMap = new SegmentMap(addrPreferred);

            if (Sections.Count > 0)
            {
                foreach (var section in Sections)
                {
                    if (section.Name == null || section.Address == null)
                    {
                        continue;
                    }
                    if (segMap.TryGetLowerBound(section.Address, out var mem) &&
                        section.Address < mem.EndAddress)
                    {
                        AccessMode mode = AccessModeOf(section.Flags);
                        var        seg  = segmentMap.AddSegment(new ImageSegment(
                                                                    section.Name,
                                                                    section.Address,
                                                                    mem, mode)
                        {
                            Size = (uint)section.Size
                        });
                        seg.Designer = CreateRenderer64(section);
                    }
                    else
                    {
                        //$TODO: warn
                    }
                }
            }
            else
            {
                // There are stripped ELF binaries with 0 sections. If we have one
                // create a pseudo-section from the segMap.
                foreach (var segment in segMap)
                {
                    var imgSegment = new ImageSegment(
                        segment.Value.BaseAddress.GenerateName("seg", ""),
                        segment.Value,
                        AccessMode.ReadExecute)        //$TODO: writeable segments.
                    {
                        Size = (uint)segment.Value.Length,
                    };
                    segmentMap.AddSegment(imgSegment);
                }
            }
            segmentMap.DumpSections();
            return(segmentMap);
        }
예제 #4
0
        private IEnumerable <int> GetMatches(ImageSegment s, Core.Dfa.Automaton re)
        {
            var mem = (ByteMemoryArea)s.MemoryArea;

            return(re.GetMatches(mem.Bytes, 0));
        }
예제 #5
0
 private string DetermineFilename(ImageMapItem item, ImageSegment seg)
 {
     return(FilenameBasedOnSegment(item.Address, seg));
 }
예제 #6
0
 private ImageSegment [] ExtractSegments()
 {
     ImageSegment [] segs = new ImageSegment[map.Segments.Count];
     map.Segments.Values.CopyTo(segs, 0);
     return(segs);
 }
예제 #7
0
        public override void Render(ImageSegment segment, Program program, Formatter formatter)
        {
            ulong fileOffset = shdr.FileOffset;

            Render(fileOffset, formatter);
        }
예제 #8
0
 public void TearDownStack(ImageSegment stackSeg)
 {
 }
예제 #9
0
파일: XexLoader.cs 프로젝트: chostelet/reko
        private void LoadPEImage()
        {
            long fileDataSize = rdr.Bytes.Length - xexData.header.header_size;

            BeImageReader memRdr    = new BeImageReader(xexData.memoryData);
            DOSHeader     dosHeader = memRdr.ReadStruct <DOSHeader>();

            dosHeader.Validate();

            memRdr.Offset = dosHeader.e_lfanew;

            UInt32 peSignature = memRdr.ReadUInt32();

            if (peSignature != 0x50450000)
            {
                throw new BadImageFormatException("PE: Invalid or Missing PE Signature");
            }

            COFFHeader coffHeader = memRdr.ReadStruct <COFFHeader>();

            if (coffHeader.Machine != 0x1F2)
            {
                throw new BadImageFormatException($"PE: Machine type does not match Xbox360 (found 0x{coffHeader.Machine:X})");
            }

            if ((coffHeader.Characteristics & 0x0100) == 0)
            {
                throw new BadImageFormatException("PE: Only 32-bit images are supported");
            }

            if (coffHeader.SizeOfOptionalHeader != 224)
            {
                throw new BadImageFormatException($"PE: Invalid size of optional header (got {coffHeader.SizeOfOptionalHeader}");
            }

            PEOptHeader optHeader = memRdr.ReadStruct <PEOptHeader>();

            if (optHeader.signature != 0x10b)
            {
                throw new BadImageFormatException($"PE: Invalid signature of optional header (got 0x{optHeader.signature})");
            }

            if (optHeader.Subsystem != IMAGE_SUBSYSTEM_XBOX)
            {
                throw new BadImageFormatException($"PE: Invalid subsystem (got {optHeader.Subsystem})");
            }

            xexData.peHeader = optHeader;

            uint extendedMemorySize = 0;
            uint numSections        = coffHeader.NumberOfSections;

            List <PESection> peSections = new List <PESection>();

            for (uint i = 0; i < numSections; i++)
            {
                COFFSection section = memRdr.ReadStruct <COFFSection>();

                string sectionName = Encoding.ASCII.GetString(section.Name).Trim('\0');

                uint lastMemoryAddress = section.VirtualAddress + section.VirtualSize;
                if (lastMemoryAddress > extendedMemorySize)
                {
                    extendedMemorySize = lastMemoryAddress;
                }

                if (section.SizeOfRawData == 0)
                {
                    decompilerEventListener.Info(new NullCodeLocation(""),
                                                 $"Skipping empty section {sectionName}"
                                                 );
                    continue;
                }

                byte[] sectionData = memRdr.ReadAt <byte[]>(section.PointerToRawData, rdr => rdr.ReadBytes(section.SizeOfRawData));

                AccessMode acc = AccessMode.Read;
                if (section.Flags.HasFlag(PESectionFlags.IMAGE_SCN_MEM_WRITE))
                {
                    acc |= AccessMode.Write;
                }
                if (section.Flags.HasFlag(PESectionFlags.IMAGE_SCN_MEM_EXECUTE))
                {
                    acc |= AccessMode.Execute;
                }

                PESection managedSection = new PESection(section);
                peSections.Add(managedSection);

                ImageSegment seg = new ImageSegment(sectionName, new MemoryArea(
                                                        new Address32(managedSection.PhysicalOffset + xexData.exe_address), sectionData
                                                        ), acc);
                segments.Add(seg);
            }

            if (extendedMemorySize > xexData.memorySize)
            {
                decompilerEventListener.Info(new NullCodeLocation(""),
                                             $"PE: Image sections extend beyond virtual memory range loaded from file ({extendedMemorySize} > {xexData.memorySize}). Extending by {extendedMemorySize - xexData.memorySize} bytes."
                                             );

                UInt32 oldMemorySize = xexData.memorySize;

                byte[] newMemoryData = new byte[extendedMemorySize];
                Array.Copy(xexData.memoryData, newMemoryData, xexData.memorySize);
                xexData.memorySize = extendedMemorySize;
                xexData.memoryData = newMemoryData;

                for (int i = 0; i < peSections.Count; i++)
                {
                    PESection section = peSections[i];

                    if (section.PhysicalSize == 0)
                    {
                        continue;
                    }

                    if (section.PhysicalSize + section.PhysicalOffset > fileDataSize)
                    {
                        decompilerEventListener.Warn(new NullCodeLocation(""),
                                                     $"PE: Section '{section.Name}' lies outside any phyisical data we have {section.PhysicalOffset} (size {section.PhysicalSize})"
                                                     );
                        continue;
                    }

                    if (section.VirtualOffset >= oldMemorySize)
                    {
                        uint sizeToCopy = section.PhysicalSize;
                        if (section.VirtualSize < sizeToCopy)
                        {
                            sizeToCopy = section.VirtualSize;
                        }

                        Array.Copy(
                            xexData.memoryData, section.PhysicalOffset,
                            newMemoryData, section.VirtualOffset,
                            sizeToCopy);
                    }
                }
            }
        }
예제 #10
0
        public override SegmentMap LoadImageBytes(IPlatform platform, byte[] rawImage, Address addrPreferred)
        {
            var segMap = AllocateMemoryAreas(
                Segments
                .Where(p => IsLoadable(p.p_pmemsz, p.p_type))
                .OrderBy(p => p.p_vaddr)
                .Select(p => (
                            Address.Ptr32((uint)p.p_vaddr),
                            (uint)p.p_pmemsz)));

            foreach (var ph in Segments)
            {
                ElfImageLoader.trace.Inform("ph: addr {0:X8} filesize {0:X8} memsize {0:X8}", ph.p_vaddr, ph.p_filesz, ph.p_pmemsz);
                if (!IsLoadable(ph.p_pmemsz, ph.p_type))
                {
                    continue;
                }
                var vaddr = Address.Ptr32((uint)ph.p_vaddr);
                segMap.TryGetLowerBound(vaddr, out var mem);
                if (ph.p_filesz > 0)
                {
                    Array.Copy(
                        rawImage,
                        (long)ph.p_offset, mem.Bytes,
                        vaddr - mem.BaseAddress, (long)ph.p_filesz);
                }
            }
            var segmentMap = new SegmentMap(addrPreferred);

            if (Sections.Count > 0)
            {
                foreach (var section in Sections)
                {
                    if (string.IsNullOrEmpty(section.Name) || section.Address == null)
                    {
                        continue;
                    }

                    if (segMap.TryGetLowerBound(section.Address, out var mem) &&
                        section.Address - mem.BaseAddress < mem.Length)
                    {
                        AccessMode mode = AccessModeOf(section.Flags);
                        var        seg  = segmentMap.AddSegment(new ImageSegment(
                                                                    section.Name,
                                                                    section.Address,
                                                                    mem, mode)
                        {
                            Size = (uint)section.Size
                        });
                        seg.Designer = CreateRenderer(section, machine);
                    }
                    else
                    {
                        //$TODO: warn
                    }
                }
            }
            else
            {
                // There are stripped ELF binaries with 0 sections. If we have one
                // create a pseudo-section from the segMap.
                foreach (var segment in segMap)
                {
                    var elfSegment = this.GetSegmentByAddress(segment.Value.BaseAddress.ToLinear());
                    var imgSegment = new ImageSegment(
                        segment.Value.BaseAddress.GenerateName("seg", ""),
                        segment.Value,
                        elfSegment != null
                            ? elfSegment.GetAccessMode()
                            : AccessMode.ReadExecute)

                    {
                        Size = (uint)segment.Value.Length,
                    };
                    segmentMap.AddSegment(imgSegment);
                }
            }
            segmentMap.DumpSections();
            return(segmentMap);
        }
예제 #11
0
파일: ResourceFork.cs 프로젝트: qcyb/reko
 private static bool SegmentNamedA5Init(ImageSegment segment)
 {
     return(segment.Name.Length >= 12 && segment.Name.Substring(5, 7) == "%A5Init");
 }
예제 #12
0
 public void Setup()
 {
     this.relocator = null;
     this.mem       = new ByteMemoryArea(Address.Ptr32(0x00100000), new byte[4096]);
     this.a5world   = new ImageSegment("A5World", mem, AccessMode.ReadWriteExecute);
 }
예제 #13
0
 private bool TryFindSegment(Program program, string segName, out ImageSegment seg)
 {
     seg = program.SegmentMap.Segments.Values.FirstOrDefault(s => s.Name == segName);
     return(seg is not null);
 }
예제 #14
0
 private void TearDownStack(ImageSegment stackSeg)
 {
     this.ImageMap.Segments.Remove(stackSeg.Address);
 }
예제 #15
0
 private string DetermineFilename(ImageMapItem item, ImageSegment seg, string fileExtension)
 {
     return(FilenameBasedOnSegment(item.Address, seg, fileExtension));
 }
예제 #16
0
 public override void Render(ImageSegment segment, Program program, Formatter formatter)
 {
     throw new NotImplementedException();
 }
예제 #17
0
 private void PaintSegment(ImageSegment seg, Graphics g, Rectangle rc)
 {
     g.FillRectangle(Brushes.White, rc);
     g.DrawRectangle(seg == segSelected ? Pens.Red : Pens.Black, rc);
 }
예제 #18
0
 public GlobalVariablesNodeDesigner(ImageSegment segment)
 {
     this.segment = segment;
 }
예제 #19
0
        /// <summary>
        /// Disassemble every byte of the segment, marking those addresses
        /// that likely are code as MaybeCode, everything else as data.
        /// </summary>
        /// <remarks>
        /// The plan is to disassemble every location of the segment, building
        /// a reverse control graph. Any jump to an illegal address or any
        /// invalid instruction will result in an edge from "bad" to that
        /// instruction.
        /// </remarks>
        /// <param name="segment"></param>
        /// <returns>An array of bytes classifying each byte as code or data.
        /// </returns>
        public ScannedSegment ScanSegment(ImageSegment segment, ulong workToDo)
        {
            var G = new DiGraph <Address>();

            G.AddNode(bad);
            var cbAlloc = Math.Min(
                segment.Size,
                segment.MemoryArea.EndAddress - segment.Address);
            var y = new byte[cbAlloc];

            // Advance by the instruction granularity.
            var step      = program.Architecture.InstructionBitSize / 8;
            var delaySlot = InstructionClass.None;

            for (var a = 0; a < y.Length; a += step)
            {
                y[a] = MaybeCode;
                var i = Dasm(segment, a);
                if (i == null)
                {
                    AddEdge(G, bad, segment.Address + a);
                    break;
                }
                if (IsInvalid(segment.MemoryArea, i))
                {
                    AddEdge(G, bad, i.Address);
                    delaySlot = InstructionClass.None;
                    y[a]      = Data;
                }
                else
                {
                    if (MayFallThrough(i))
                    {
                        if (delaySlot != DT)
                        {
                            if (a + i.Length < y.Length)
                            {
                                // Still inside the segment.
                                AddEdge(G, i.Address + i.Length, i.Address);
                            }
                            else
                            {
                                // Fell off segment, i must be a bad instruction.
                                AddEdge(G, bad, i.Address);
                                y[a] = Data;
                            }
                        }
                    }
                    if ((i.InstructionClass & InstructionClass.Transfer) != 0)
                    {
                        var addrDest = DestinationAddress(i);
                        if (addrDest != null)
                        {
                            if (IsExecutable(addrDest))
                            {
                                // call / jump destination is executable
                                AddEdge(G, addrDest, i.Address);
                                if ((i.InstructionClass & InstructionClass.Call) != 0)
                                {
                                    int callTally;
                                    if (!this.possibleCallDestinationTallies.TryGetValue(addrDest, out callTally))
                                    {
                                        callTally = 0;
                                    }
                                    this.possibleCallDestinationTallies[addrDest] = callTally + 1;
                                }
                            }
                            else
                            {
                                // Jump to data / hyperspace.
                                AddEdge(G, bad, i.Address);
                                y[a] = Data;
                            }
                        }
                    }

                    // If this is a delayed unconditional branch...
                    delaySlot = i.InstructionClass;
                }
                if (y[a] == MaybeCode)
                {
                    instructions.Add(i.Address, i);
                }
                eventListener.ShowProgress("Shingle scanning", instructions.Count, (int)workToDo);
            }

            // Find all places that are reachable from "bad" addresses.
            // By transitivity, they must also be be bad.
            foreach (var a in new DfsIterator <Address>(G).PreOrder(bad))
            {
                if (a != bad)
                {
                    y[a - segment.Address] = Data;
                    instructions.Remove(a);

                    // Destination can't be a call destination.
                    possibleCallDestinationTallies.Remove(a);
                }
            }

            // Build blocks out of sequences of instructions.
            var blocks = BuildBlocks(G, instructions);

            return(new ScannedSegment
            {
                Blocks = blocks,
                CodeFlags = y,
            });
        }