public void Setup() { mr = new MockRepository(); seg1 = new ImageMapSegment("seg1", AccessMode.Execute) { Address = Address.Ptr32(0x01000) }; seg2 = new ImageMapSegment("seg2", AccessMode.Execute) { Address = Address.Ptr32(0x02000) }; map = new ImageMap(seg1.Address, 0x4000); }
public ImageMapSegment AddSegment(Address addr, string segmentName, AccessMode access) { ImageMapSegment seg; if (!TryFindSegment(addr, out seg)) { ImageMapSegment segNew = new ImageMapSegment(segmentName, access); segNew.Address = addr; segNew.Size = ~0U; segments.Add(segNew.Address, segNew); MapChanged.Fire(this); return(segNew); } long delta = addr - seg.Address; Debug.Assert(delta >= 0); if (delta > 0) { // Need to split the segment. //$REVIEW: or do we? x86 segments can overlap. var segNew = new ImageMapSegment(segmentName, access); segNew.Address = addr; segNew.Size = (uint)(seg.Size - delta); seg.Size = (uint)delta; segments.Add(segNew.Address, segNew); // And split any items in the segment. AddItem(addr, new ImageMapItem()); MapChanged.Fire(this); return(segNew); } return(seg); }
public void DisplayImageSegment(ImageMapSegment segment, Program program) { if (segment == null) return; ShowWindow("imageSegmentViewer", "Segment: " + segment.Name, pane); pane.DisplaySegment(segment, program); }
public override void Render(ImageMapSegment segment, Program program, Formatter formatter) { var entries = shdr.sh_size / shdr.sh_entsize; var symtab = (int)shdr.sh_link; var rdr = loader.CreateReader(shdr.sh_offset); for (int i = 0; i < entries; ++i) { uint iName; if (!rdr.TryReadUInt32(out iName)) return; uint value; if (!rdr.TryReadUInt32(out value)) return; uint size; if (!rdr.TryReadUInt32(out size)) return; byte info; if (!rdr.TryReadByte(out info)) return; byte other; if (!rdr.TryReadByte(out other)) return; ushort shIndex; if (!rdr.TryReadUInt16(out shIndex)) return; string symStr = loader.GetStrPtr(symtab, iName); string segName = loader.GetSectionName(shIndex); formatter.Write("{0,-40} {1:X8} {2:X8} {3:X2} {4}", symStr, value, size, info & 0xFF, segName); formatter.WriteLine(); } }
public override void Initialize(object obj) { this.segment = (ImageMapSegment) obj; base.TreeNode.Text = segment.Name; base.TreeNode.ImageName = GetImageName(); base.TreeNode.ToolTipText = GetTooltip(); PopulateChildren(); }
public override void Render(ImageMapSegment segment, Program program, Formatter formatter) { // Get the entry that has the segment# for the string table. var dynStrtab = loader.GetDynEntries(shdr.sh_offset).Where(d => d.d_tag == DT_STRTAB).FirstOrDefault(); if (dynStrtab == null) return; var strtabSection = loader.GetSectionInfoByAddr(dynStrtab.d_ptr); foreach (var entry in loader.GetDynEntries(shdr.sh_offset)) { switch (entry.d_tag) { default: formatter.Write("{0,-12} {1:X8}", entry.d_tag, entry.d_val); break; case DT_DEBUG: formatter.Write("{0,-12} {1:X8}", "DT_DEBUG", entry.d_val); break; case DT_FINI: formatter.Write("{0,-12} ", "DT_FINI"); formatter.WriteHyperlink(string.Format("{0:X8}", entry.d_ptr), Address.Ptr32(entry.d_ptr)); break; case DT_HASH: formatter.Write("{0,-12} ", "DT_HASH"); formatter.WriteHyperlink(string.Format("{0:X8}", entry.d_ptr), Address.Ptr32(entry.d_ptr)); break; case DT_INIT: formatter.Write("{0,-12} ", "DT_INIT"); formatter.WriteHyperlink(string.Format("{0:X8}", entry.d_ptr), Address.Ptr32(entry.d_ptr)); break; case DT_JMPREL: formatter.Write("{0,-12} ", "DT_JMPREL"); formatter.WriteHyperlink(string.Format("{0:X8}", entry.d_ptr), Address.Ptr32(entry.d_ptr)); break; case DT_NEEDED: formatter.Write("{0,-12} {1}", "DT_NEEDED", loader.ReadAsciiString(loader.RawImage, strtabSection.sh_offset + entry.d_ptr)); break; case DT_STRSZ: formatter.Write("{0,-12} {1:X}", "DT_STRSZ", entry.d_val); break; case DT_STRTAB: formatter.Write("{0,-12} ", "DT_STRTAB"); formatter.WriteHyperlink(string.Format("{0:X8}", entry.d_ptr), Address.Ptr32(entry.d_ptr)); break; case DT_SYMENT: formatter.Write("{0,-12} {1}", "DT_SYMENTTRTAB", entry.d_val); break; case DT_SYMTAB: formatter.Write("{0,-12} ", "DT_SYMTAB"); formatter.WriteHyperlink(string.Format("{0:X8}", entry.d_ptr), Address.Ptr32(entry.d_ptr)); break; } formatter.WriteLine(); } }
/// <summary> /// Disassemble every byte of the image, marking those addresses that likely /// are code as MaybeCode, everything else as data. /// </summary> /// <param name="segment"></param> /// <returns>An array of bytes classifying each byte as code or data. /// </returns> public byte[] ScanSegment(ImageMapSegment segment) { var G = new DiGraph<Address>(); G.AddNode(bad); var y = new byte[segment.ContentSize]; var step = program.Architecture.InstructionBitSize / 8; bool inDelaySlot = false; for (var a = 0; a < y.Length; a += step) { y[a] = MaybeCode; var i = Dasm(segment, a); if (i == null || i.InstructionClass == InstructionClass.Invalid) { AddEdge(G, bad, i.Address); inDelaySlot = false; } else { if (MayFallThrough(i)) { if (!inDelaySlot) { if (a + i.Length < y.Length) AddEdge(G, i.Address + i.Length, i.Address); else AddEdge(G, bad, i.Address); } } if ((i.InstructionClass & InstructionClass.Transfer) != 0) { var dest = Destination(i); if (dest != null) { if (IsExecutable(dest)) AddEdge(G, dest, i.Address); else AddEdge(G, bad, i.Address); } } // If this is a delayed unconditional branch... inDelaySlot = i.InstructionClass == DT; } } foreach (var a in new DfsIterator<Address>(G).PreOrder(bad)) { if (a != bad) { y[a - segment.Address] = Data; } } return y; }
public void SetAddressSpan(Address addr, uint size) { items.Clear(); segments.Clear(); ImageMapSegment seg = new ImageMapSegment("Image base", size, AccessMode.ReadWrite); seg.Address = addr; segments.Add(addr, seg); ImageMapItem it = new ImageMapItem(size) { DataType = new UnknownType() }; it.Address = addr; items.Add(addr, it); }
public override void Render(ImageMapSegment segment, Program program, Formatter formatter) { var entries = shdr.sh_size / shdr.sh_entsize; var symtab = (int)shdr.sh_link; var rdr = loader.CreateReader(shdr.sh_offset); for (int 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.GetSymbol(symtab, (int)sym); formatter.Write("{0:X8} {1,3} {2:X8} {3}", offset, info & 0xFF, sym, symStr); formatter.WriteLine(); } }
public void DisplaySegment(ImageMapSegment 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(ImageMapSegment segment, Program program, Formatter formatter) { var entries = shdr.sh_size / shdr.sh_entsize; var symtab = (int)shdr.sh_link; var rdr = loader.CreateReader(shdr.sh_offset); 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, (int)sym); formatter.Write("{0:X8} {1,3} {2:X8} {3:X16} {4} ({5})", offset, info & 0xFFFFFFFF, sym, addend, symStr, sym); formatter.WriteLine(); } }
private ImageMapSegment[] ExtractSegments() { ImageMapSegment [] segs = new ImageMapSegment[map.Segments.Count]; map.Segments.Values.CopyTo(segs, 0); return segs; }
public abstract void Render(ImageMapSegment segment, Program program, Formatter formatter);
void parseSection64(uint protection) { 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 imageSection = new ImageMapSegment( string.Format("{0},{1}", segmentName, sectionName), (uint)size, am); //imageSection.setData(!imageSection->isCode()); //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)); }
public void Dump(Program program, ImageMap map, TextWriter stm) { ImageMapSegment segment = null; if (map == null) { DumpAssembler(program.Image, program.Image.BaseAddress, program.Image.BaseAddress + (uint)program.Image.Length, stm); } else { foreach (ImageMapItem i in map.Items.Values) { if (!program.Image.IsValidAddress(i.Address)) { continue; } ImageMapSegment seg; if (!map.TryFindSegment(i.Address, out seg)) { continue; } if (seg != segment) { segment = seg; stm.WriteLine(";;; Segment {0} ({1})", seg.Name, seg.Address); } // Address addrLast = i.Address + i.Size; ImageMapBlock block = i as ImageMapBlock; if (block != null) { stm.WriteLine(); if (program.Procedures.ContainsKey(block.Address)) { stm.WriteLine(block.Address.GenerateName("fn", "()")); } else { stm.WriteLine(block.Address.GenerateName("l", ":")); } DumpAssembler(program.Image, block.Address, block.Address + block.Size, stm); continue; } ImageMapVectorTable table = i as ImageMapVectorTable; if (table != null) { stm.WriteLine("{0} table at {1} ({2} bytes)", table.IsCallTable?"Call":"Jump", table.Address, table.Size); foreach (Address addr in table.Addresses) { stm.WriteLine("\t{0}", addr != null ? addr.ToString() : "-- null --"); } DumpData(program.Image, i.Address, i.Size, stm); } else { var segLast = segment.Address + segment.ContentSize; var size = segLast - i.Address; size = Math.Min(i.Size, size); DumpData(program.Image, i.Address, size, stm); } } } }
protected override void OnMouseDown(MouseEventArgs me) { base.OnMouseDown(me); ImageMapSegment [] mapSegments = ExtractSegments(); float scaleFactor = (float) Height / (float) ImageSize(mapSegments); ulong start = mapSegments[0].Address.ToLinear(); foreach (ImageMapSegment seg in mapSegments) { float y = scaleFactor * (seg.Address.ToLinear() - start); float dy = scaleFactor * seg.Size; if (y <= me.Y && me.Y < y + dy) { SelectedSegment = seg; return; } } }
private void PaintSegment(ImageMapSegment seg, Graphics g, Rectangle rc) { g.FillRectangle(Brushes.White, rc); g.DrawRectangle(seg == segSelected ? Pens.Red : Pens.Black, rc); }
private RtlInstructionCluster DasmOld(ImageMapSegment segment, int a) { var rw = program.Architecture.CreateRewriter( program.CreateImageReader(segment.Address + a), program.Architecture.CreateProcessorState(), program.Architecture.CreateFrame(), host); return rw.FirstOrDefault(); }
/// <summary> /// Returns the segment that contains the specified address. /// </summary> /// <param name="addr"></param> /// <returns></returns> public bool TryFindSegment(Address addr, out ImageMapSegment segment) { return(segments.TryGetLowerBound(addr, out segment)); }
public override void Render(ImageMapSegment segment, Program program, Formatter formatter) { throw new NotImplementedException(); }
private uint ImageSize(ImageMapSegment [] segs) { Address addrStart = segs[0].Address; Address addrEnd = segs[segs.Length - 1].Address; return segs[segs.Length - 1].Size + (uint) (addrEnd - addrStart); }
private MachineInstruction Dasm(ImageMapSegment segment, int a) { var dasm = program.CreateDisassembler(segment.Address + a); return dasm.FirstOrDefault(); }