public void Sm_Overlaps() { SegmentMap im = new SegmentMap(Address.SegPtr(0x8000, 0)); var mem = new MemoryArea(im.BaseAddress, new byte[40]); var seg = new ImageSegment("8000", Address.SegPtr(0x8000, 10), mem, AccessMode.ReadWrite); im.AddSegment(seg); }
public void DisplayImageSegment(ImageSegment segment, Program program) { if (segment == null) return; ShowWindow("imageSegmentViewer", "Segment: " + segment.Name, program, pane); pane.DisplaySegment(segment, program); }
public ImageSegment AddSegment(ImageSegment segNew) { ImageSegment seg; if (!TryFindSegment(segNew.Address, out seg)) { EnsureSegmentSize(segNew); segments.Add(segNew.Address, segNew); MapChanged.Fire(this); //DumpSections(); return segNew; } long delta = segNew.Address - seg.Address; Debug.Assert(delta >= 0); if (delta > 0) { // Need to split the segment. //$REVIEW: or do we? x86 segments can overlap. var segSplit = new ImageSegment(segNew.Name, segNew.Address, segNew.MemoryArea, segNew.Access); segSplit.Size = (uint)(seg.Size - delta); seg.Size = (uint)delta; segments.Add(segNew.Address, segSplit); // And split any items in the segment MapChanged.Fire(this); //DumpSections(); return segSplit; } return seg; }
public void DisplayGlobals(Program program, ImageSegment segment) { var pane = new CombinedCodeViewInteractor(); var windowType = typeof(CombinedCodeViewInteractor).Name; var label = string.Format(Resources.SegmentGlobalsFmt, segment.Name); var frame = ShowWindow(windowType, label, segment, pane); ((CombinedCodeViewInteractor)frame.Pane).DisplayGlobals(program, segment); }
public void Sm_AddSegment() { var map = new SegmentMap(addrBase); var mem = new MemoryArea(addrBase, new byte[0x4000]); var seg = new ImageSegment("8100", Address.SegPtr(0x8100, 0), mem, AccessMode.ReadWriteExecute); map.AddSegment(seg); Assert.AreEqual(0x3000, seg.Size); }
private ImageSegment Given_Image(int size) { var bytes = Enumerable.Range(0, size).Select(b => (byte)b).ToArray(); var mem = new MemoryArea(Address.Ptr32(0x1000000), bytes); var seg = new ImageSegment(".text", mem, AccessMode.ReadExecute); program.SegmentMap = new SegmentMap(mem.BaseAddress, seg); return seg; }
public void Setup() { mr = new MockRepository(); seg1 = new ImageSegment("seg1", new MemoryArea(Address.Ptr32(0x01000), new byte[0x1000]), AccessMode.Execute); seg2 = new ImageSegment("seg2", new MemoryArea(Address.Ptr32(0x02000), new byte[0x1000]), AccessMode.Execute); map = new SegmentMap(seg1.Address, seg1, seg2); }
public override void Initialize(object obj) { this.segment = (ImageSegment) obj; base.TreeNode.Text = segment.Name; base.TreeNode.ImageName = GetImageName(); base.TreeNode.ToolTipText = GetTooltip(); PopulateChildren(); }
public ImageSegment AddSegment(MemoryArea mem, string segmentName, AccessMode mode) { var segment = new ImageSegment( segmentName, mem, mode); AddSegment(segment); return segment; }
private IEnumerable<ProgramAddress> GetPointersInSegment(ImageSegment s) { var rdr = s.CreateImageReader(program.Architecture); return program.Platform.CreatePointerScanner( program.SegmentMap, rdr, addresses, PointerScannerFlags.All) .Select(a => new ProgramAddress(program, a)); }
protected void Given_Image32(uint addr, string sBytes) { var bytes = HexStringToBytes(sBytes); mem = new MemoryArea(Address.Ptr32(addr), bytes); program = new Program { SegmentMap = new SegmentMap( mem.BaseAddress, new ImageSegment("prôg", mem, AccessMode.ReadExecute)) }; program.ImageMap = program.SegmentMap.CreateImageMap(); segment = program.SegmentMap.Segments.Values.First(); }
public DisassemblyTextModel(Program program, ImageSegment segment) { if (program == null) throw new ArgumentNullException("program"); this.program = program; if (segment == null) throw new ArgumentNullException("segment"); if (segment.MemoryArea == null) throw new ArgumentException("segment", "ImageSegment must have a valid memory area."); this.mem = segment.MemoryArea; this.addrStart = Address.Max(segment.Address, mem.BaseAddress); this.position = addrStart; this.addrEnd = Address.Min(segment.Address + segment.Size, mem.EndAddress); }
private void Given_Segment(ushort selector, string name) { var seg = new ImageSegment(name, new MemoryArea(Address.SegPtr(selector, 0), new byte[100]), AccessMode.ReadWriteExecute); seg.Identifier = new Identifier(name, PrimitiveType.SegmentSelector, RegisterStorage.None); program.SegmentMap.AddSegment(seg); var tv = store.EnsureExpressionTypeVariable(factory, seg.Identifier); var dt = new StructureType { IsSegment = true, }; tv.Class.DataType = dt; tv.DataType = new Pointer(tv.Class, 2); tv.OriginalDataType = PrimitiveType.SegmentSelector; }
private void DisassemblyControlForm_Load(object sender, EventArgs e) { var random = new Random(0x4711); var mem = new MemoryArea(Address.Ptr32(0x00100000), Enumerable.Range(0, 10000) .Select(i => (byte)random.Next(256)).ToArray()); var seg = new ImageSegment(".text", mem, AccessMode.ReadExecute); var segmentMap = new SegmentMap(mem.BaseAddress, seg); disassemblyControl1.Model = new DisassemblyTextModel( new CoreProgram { //new Decompiler.Arch.X86.X86ArchitectureFlat32(); Architecture = new Reko.Arch.PowerPC.PowerPcArchitecture32(), SegmentMap = segmentMap }, seg); disassemblyControl1.StartAddress = mem.BaseAddress; }
public override void Render(ImageSegment segment, Program program, Formatter formatter) { var entries = shdr.Size / shdr.EntrySize; var symtab = shdr.LinkedSection; var rdr = loader.CreateReader(shdr.FileOffset); for (ulong i = 0; i < entries; ++i) { uint offset; if (!rdr.TryReadUInt32(out offset)) return; uint info; if (!rdr.TryReadUInt32(out info)) return; uint sym = info >> 8; string symStr = loader.GetSymbolName(symtab, sym); formatter.Write("{0:X8} {1,3} {2:X8} {3}", offset, info & 0xFF, sym, symStr); formatter.WriteLine(); } }
public void DisplaySegment(ImageSegment segment, Program program) { try { if (segmentView == null || segment == null || segment.Designer == null) return; this.program = program; var tsf = new TextSpanFormatter(); segment.Designer.Render( segment, program, tsf); this.segmentView.TextView.Model = tsf.GetModel(); } catch { } }
public override void Render(ImageSegment segment, Program program, Formatter formatter) { var entries = shdr.EntryCount(); var symtab = shdr.LinkedSection; var rdr = loader.CreateReader(shdr.FileOffset); for (ulong i = 0; i < entries; ++i) { ulong offset; if (!rdr.TryReadUInt64(out offset)) return; ulong info; if (!rdr.TryReadUInt64(out info)) return; ulong addend; if (!rdr.TryReadUInt64(out addend)) return; ulong sym = info >> 32; string symStr = loader.GetSymbol64(symtab, sym); formatter.Write("{0:X8} {1,3} {2:X8} {3:X16} {4} ({5})", offset, info & 0xFFFFFFFF, sym, addend, symStr, sym); formatter.WriteLine(); } }
/// <summary> /// Grab a single instruction. /// </summary> /// <param name="segment"></param> /// <param name="a"></param> /// <returns></returns> private MachineInstruction Dasm(ImageSegment segment, int a) { var addr = segment.Address + a; if (!segment.IsInRange(addr) || !segment.MemoryArea.IsValidAddress(addr)) return null; var dasm = program.CreateDisassembler(addr); return dasm.FirstOrDefault(); }
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); }
public override RelocationResults Relocate(Program program, Address addrLoad) { SegmentMap imageMap = segmentMap; ImageReader rdr = new LeImageReader(exe.RawImage, (uint) exe.e_lfaRelocations); var relocations = imgLoaded.Relocations; int i = exe.e_cRelocations; var segments = new Dictionary<Address, ushort>(); 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, 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; } return results; }
public override void Render(ImageSegment segment, Program program, Formatter formatter) { // Get the entry that has the segment# for the string table. var dynStrtab = loader.GetDynEntries64(shdr.FileOffset).Where(d => d.d_tag == DT_STRTAB).FirstOrDefault(); if (dynStrtab == null) return; this.strtabSection = loader.GetSectionInfoByAddr64(dynStrtab.d_ptr); foreach (var entry in loader.GetDynEntries64(shdr.FileOffset)) { DtFormat fmt; string entryName; Entry dser; if (!entries.TryGetValue(entry.d_tag, out dser)) { entryName = string.Format("{0:X8} ", entry.d_tag); fmt = DtFormat.Hexadecimal; } else { entryName = dser.Name; fmt = dser.Format; } RenderEntry(entryName, fmt, entry, formatter); formatter.WriteLine(); } }
public abstract void Render(ImageSegment segment, Program program, Formatter formatter);
public void EqSegmentConstantsWithAllocatedSegment() { var tmp = new TemporaryStorage("seg1234", 0, PrimitiveType.SegmentSelector); var segment = new ImageSegment( "seg1234", new MemoryArea(Address.SegPtr(0x1234, 0), new byte[100]), AccessMode.ReadWriteExecute) { Identifier = new Identifier(tmp.Name, PrimitiveType.SegmentSelector, tmp) }; eqb.EnsureSegmentTypeVariables(new[] { segment }); Constant seg1 = Constant.Create(PrimitiveType.SegmentSelector, 0x1234); seg1.Accept(eqb); Assert.AreSame(seg1.TypeVariable.Class, segment.Identifier.TypeVariable.Class); }
public void TearDownStack(ImageSegment stackSeg) { }
/// <summary> /// Returns the segment that contains the specified address. /// </summary> /// <param name="addr"></param> /// <returns></returns> public bool TryFindSegment(Address addr, out ImageSegment segment) { if (!segments.TryGetLowerBound(addr, out segment)) return false; if (segment.Address.ToLinear() == addr.ToLinear()) return true; return segment.IsInRange(addr); }
private void EnsureSegmentSize(ImageSegment seg) { Address addrAbove; if (seg.Size == 0) { if (!Segments.TryGetUpperBoundKey(seg.Address, out addrAbove)) { // No segment above this one, consume all remaining space. seg.Size = (uint)((seg.MemoryArea.BaseAddress - seg.Address) + seg.MemoryArea.Length); } else { seg.Size = (uint)(addrAbove - seg.Address); } } }
public GlobalVariablesNodeDesigner(ImageSegment segment) { this.segment = segment; }
/// <summary> /// For each location in the segment, read a pointer-sized chunk and return it. /// </summary> /// <param name="seg"></param> /// <returns></returns> public IEnumerable<Address> GetPossiblePointers(ImageSegment seg) { //$TODO: this assumes pointers must be aligned. Not the case for older machines. uint ptrSize = (uint)program.Platform.PointerType.Size; var rdr = program.CreateImageReader(seg.Address); Constant c; while (rdr.TryRead(program.Platform.PointerType, out c)) { yield return program.Architecture.MakeAddressFromConstant(c); } }
private void SetTreeNodeProperties(ImageSegment segment) { this.TreeNode.Text = Resources.Node_GlobalVariables; this.TreeNode.ImageName = "Data.ico"; }
public void TerSelector() { var sExp = #region Expected @"// Before /////// // test // Return size: 0 void test() test_entry: // succ: l1 l1: ds = 0x1234 Mem0[ds:0x0010:word32] = 0x00010004 test_exit: // After /////// // test // Return size: 0 void test() test_entry: // succ: l1 l1: ds = seg1234 ds->dw0010 = 0x00010004 test_exit: " ; #endregion var seg = new ImageSegment( "1234", new MemoryArea(Address.SegPtr(0x1234, 0), new byte[0x100]), AccessMode.ReadWriteExecute); seg.Identifier = Identifier.CreateTemporary("seg1234", PrimitiveType.SegmentSelector); imageSegments.Add(seg.Address, seg); RunStringTest(m => { var ds = m.Frame.CreateTemporary("ds", PrimitiveType.SegmentSelector); m.Assign(ds, Constant.Create(ds.DataType, 0x1234)); m.SegStore(ds, m.Word16(0x10), m.Word32(0x010004)); }, sExp); }
/// <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, }; }