private IEnumerable <AArch32Instruction> CreateA32Disassembler(MemoryArea mem) { var arch = new Arm32Architecture("arm"); var rdr = new LeImageReader(mem, mem.BaseAddress); var dasm = new A32Disassembler(arch, rdr); return(dasm); }
public string ReadResourceString(uint rva) { var rdr = new LeImageReader(imgLoaded, rva); var len = rdr.ReadLeInt16(); var abStr = rdr.ReadBytes(len); return(Encoding.ASCII.GetString(abStr)); }
private MachineInstruction RunTest(params byte [] bytes) { var image = new ByteMemoryArea(Address.Ptr16(0x0100), bytes); var rdr = new LeImageReader(image, 0); var dasm = arch.CreateDisassembler(rdr); return(dasm.First()); }
private IEnumerable <RtlInstructionCluster> CreateA32Rewriter(MemoryArea mem) { var arch = new Arm32Architecture("arm"); var rdr = new LeImageReader(mem, mem.BaseAddress); var rw = arch.CreateRewriter(rdr, arch.CreateProcessorState(), new StorageBinder(), new RewriterHost(new Dictionary <Address, ImportReference>())); return(rw); }
private IEnumerable <RtlInstructionCluster> CreateT32Rewriter(ByteMemoryArea mem) { var arch = new ThumbArchitecture(sc, "arm-thumb", new Dictionary <string, object>()); var rdr = new LeImageReader(mem, mem.BaseAddress); var rw = arch.CreateRewriter(rdr, arch.CreateProcessorState(), new StorageBinder(), new RewriterHost(new Dictionary <Address, ImportReference>())); return(rw); }
private IEnumerable <AArch32Instruction> CreateA32Disassembler(ByteMemoryArea mem) { var arch = new Arm32Architecture(sc, "arm", new Dictionary <string, object>()); var rdr = new LeImageReader(mem, mem.BaseAddress); var dasm = new A32Disassembler(arch, rdr); return(dasm); }
private (byte, ushort) ReadMovableSegmentEntry(LeImageReader rdr) { var int3f = rdr.ReadLeUInt16(); var iSeg = rdr.ReadByte(); var offset = rdr.ReadLeUInt16(); return(iSeg, offset); }
private MachineInstruction RunTest(params byte[] bytes) { var image = new LoadedImage(Address.Ptr32(0x200), bytes); var rdr = new LeImageReader(image, 0); var dasm = new Disassembler(rdr); return(dasm.First()); }
public static object ReadNumericLeaf(LeImageReader rdr) { var b = rdr.PeekByte(0); if (0 <= b && b <= 0x7F) return rdr.ReadByte(); else return ReadLeaf(rdr); }
private static object[] ReadList(LeImageReader rdr) { var list = new List<object>(); while (rdr.IsValid) { list.Add(ReadLeaf(rdr)); } return list.ToArray(); }
private string ReadString(LeImageReader rdr) { var cStr = rdr.ReadLengthPrefixedString( PrimitiveType.Byte, PrimitiveType.Char, Encoding.ASCII); return(cStr?.ToString()); }
public List <ImageSymbol> LoadEntryPoints( uint offEntryTable, NeSegment [] segments, Dictionary <int, string> names, IProcessorArchitecture arch) { DebugEx.PrintIf(trace.TraceInfo, "== Loading entry points from offset {0:X}", offEntryTable); var rdr = new LeImageReader(RawImage, offEntryTable); var entries = new List <ImageSymbol>(); int bundleOrdinal = 1; int nextbundleOrdinal = 1; for (; ;) { var cBundleEntries = rdr.ReadByte(); if (cBundleEntries == 0) { break; } nextbundleOrdinal = bundleOrdinal + cBundleEntries; var segNum = rdr.ReadByte(); for (int i = 0; i < cBundleEntries; ++i) { byte flags = rdr.ReadByte(); if (flags == 0) { break; } (byte iSeg, ushort offset)entry; if (segNum == 0xFF) { entry = ReadMovableSegmentEntry(rdr); } else { entry = ReadFixedSegmentEntry(rdr, segNum); } var state = arch.CreateProcessorState(); var seg = segments[entry.iSeg - 1]; var addr = seg.Address + entry.offset; ImageSymbol ep = new ImageSymbol(addr); if (names.TryGetValue(bundleOrdinal + i, out string name)) { ep.Name = name; } ep.Type = SymbolType.Procedure; ep.ProcessorState = state; imageSymbols[ep.Address] = ep; entries.Add(ep); DebugEx.PrintIf(trace.TraceVerbose, " {0}", ep); } bundleOrdinal = nextbundleOrdinal; } return(entries); }
public void Sr_ReadLeUInt16_Field() { var rdr = new LeImageReader(new byte[] { 0x34, 0x12 }, 0); var test = new TestStruct(); var sr = new StructureReader(test); sr.Read(rdr); Assert.AreEqual((ushort)0x1234, test.usField); }
public void Sr_ReadLeInt32_Field() { var rdr = new LeImageReader(new byte[] { 0x34, 0x12, 0xAB, 0xCD, 0x78, 0x56, 0x34, 0x12 }, 0); var test = new TestStruct2(); var sr = new StructureReader(test); sr.Read(rdr); Assert.AreEqual((int)0x12345678, test.lField); }
public void ReadCString() { var img = new LeImageReader(new byte[] { 0x12, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x12 }, 1); StringConstant str = img.ReadCString(PrimitiveType.Char); Assert.AreEqual("Hello world!", str.ToString()); }
public List<ImageSymbol> LoadEntryPoints( uint offEntryTable, NeSegment [] segments, Dictionary<int, string> names, IProcessorArchitecture arch) { DebugEx.Inform(trace, "== Loading entry points from offset {0:X}", offEntryTable); var rdr = new LeImageReader(RawImage, offEntryTable); var entries = new List<ImageSymbol>(); int bundleOrdinal = 1; int nextbundleOrdinal = 1; for (; ; ) { var cBundleEntries = rdr.ReadByte(); if (cBundleEntries == 0) break; nextbundleOrdinal = bundleOrdinal + cBundleEntries; var segNum = rdr.ReadByte(); if (segNum != 0) { // If segNum had been 0, it would have // meant that all we want to do is allocate // (skip) some ordinal numbers. Since it wasn't 0, // we proceed to generate entry points. for (int i = 0; i < cBundleEntries; ++i) { byte flags = rdr.ReadByte(); (byte iSeg, ushort offset) entry; if (segNum == 0xFF) { entry = ReadMovableSegmentEntry(rdr); } else { entry = ReadFixedSegmentEntry(rdr, segNum); } var seg = segments[entry.iSeg - 1]; var addr = seg.Address + entry.offset; var ep = ImageSymbol.Procedure(arch, addr); if (names.TryGetValue(bundleOrdinal + i, out string name)) { ep.Name = name; } ep.Type = SymbolType.Procedure; ep.ProcessorState = arch.CreateProcessorState(); imageSymbols[ep.Address] = ep; entries.Add(ep); DebugEx.Verbose(trace, " {0:X2} {1} {2} - {3}", segNum, ep.Address, ep.Name, bundleOrdinal + i); } } bundleOrdinal = nextbundleOrdinal; } return entries; }
private static Label ReadLabel(LeImageReader rdr) { var nil = (LeafType)ReadLeaf(rdr); if (nil != LeafType.Nil) throw new FormatException(); var labelType = (LeafType)ReadLeaf(rdr); return new Label { Type = labelType }; }
public void Sr_ReadLeInt32_Padding() { var rdr = new LeImageReader(new byte[] { 0x34, 0x12, 0xAB, 0xCD, 0x78, 0x56, 0x34, 0x12 }); var test = new StructureReader <TestStruct3>(rdr).Read(); Assert.AreEqual((int)0x12345678, test.lField); }
public void Relocate(Program program, Address addrLoad) { SegmentMap imageMap = segmentMap; EndianImageReader rdr = new LeImageReader(ExeLoader.RawImage, ExeLoader.e_lfaRelocations); int i = ExeLoader.e_cRelocations; var segments = new Dictionary <Address, ushort>(); var linBase = addrLoad.ToLinear(); segmentMap.AddOverlappingSegment( addrLoad.Selector !.Value !.ToString("X4"), imgLoaded, addrLoad, AccessMode.ReadWriteExecute); segments.Add(addrLoad, addrLoad.Selector.Value); 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); var segment = AddSegmentReference(offset + linBase, seg); 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)(ExeLoader.e_cs + addrLoad.Selector.Value), ExeLoader.e_ip); segmentMap.AddSegment(new ImageSegment( addrStart.Selector !.Value.ToString("X4"), Address.SegPtr(addrStart.Selector.Value, 0), imgLoaded, AccessMode.ReadWriteExecute)); DumpSegments(imageMap); }
public void ImrBounded_ReadByte() { // The memarea is 2 bytes... var mem = new MemoryArea(Address.Ptr32(0x1213), new byte[] { 0x12, 0x34 }); // ...but we wish to limit it to 1 byte var rdr = new LeImageReader(mem, mem.BaseAddress, mem.BaseAddress + 1); Assert.IsTrue(rdr.IsValid); Assert.AreEqual((byte)0x12, rdr.ReadByte()); Assert.IsFalse(rdr.IsValid, "Should have respected the limit."); }
public List <ProgramResource> Load() { if (rvaResources == 0) { return(new List <ProgramResource>()); } var rsrcSection = new LeImageReader(this.imgLoaded, rvaResources); var rdr = rsrcSection.Clone(); return(ReadResourceDirectory(rdr)); }
private void Given_Type(int typeIndex, string hexString) { var bytes = BytePattern.FromHexBytes(hexString); var rdr = new LeImageReader(bytes); this.typesByIndex.Add(typeIndex, new TypeDefinition { Leaves = new object[] { CodeViewTypeLoader.ReadLeaf(rdr) } }); }
public void ReadLengthPrefixedString() { var img = new LeImageReader( new LoadedImage( Address.Ptr32(0x10000), new byte[] { 0x12, 0x34, 0x03, 0x00, 0x00, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x02, 0x02 }), 2); StringConstant str = img.ReadLengthPrefixedString(PrimitiveType.Int32, PrimitiveType.WChar); Assert.AreEqual("Foo", str.ToString()); }
public static object ReadNumericLeaf(LeImageReader rdr) { var b = rdr.PeekByte(0); if (0 <= b && b <= 0x7F) { return(rdr.ReadByte()); } else { return(ReadLeaf(rdr)); } }
public NeImageLoader(IServiceProvider services, string filename, byte[] rawBytes, uint e_lfanew) : base(services, filename, rawBytes) { ImageReader rdr = new LeImageReader(RawImage, e_lfanew); diags = Services.RequireService <IDiagnosticsService>(); this.lfaNew = e_lfanew; this.importStubs = new Dictionary <uint, Tuple <Address, ImportReference> >(); if (!LoadNeHeader(rdr)) { throw new BadImageFormatException("Unable to read NE header."); } }
private MachineInstruction _runTest(params ushort[] words) { byte[] bytes = words.SelectMany(w => new byte[] { (byte)w, (byte)(w >> 8), }).ToArray(); var image = new ByteMemoryArea(baseAddr, bytes); var rdr = new LeImageReader(image, 0); var dasm = picModel.CreateDisassembler(arch, rdr); return(dasm.First()); }
/// <summary> /// Reads a resource directory, starting at the position of the given image /// reader. /// </summary> /// <param name="rdr">A little endian <see cref="EndianImageReader"/>.</param> /// <returns>A list of the resources found in the directory.</returns> public List <ProgramResource> ReadResourceDirectory(EndianImageReader rdr) { const uint DIR_MASK = 0x80000000; var flags = rdr.ReadUInt32(); var date = rdr.ReadUInt32(); var version = rdr.ReadUInt32(); var cNameEntries = rdr.ReadUInt16(); var cIdEntries = rdr.ReadUInt16(); var entries = new List <ProgramResource>(); // Read the named entries. for (int i = 0; i < cNameEntries; ++i) { var rvaName = rdr.ReadUInt32(); var rvaEntry = rdr.ReadUInt32(); var subRdr = new LeImageReader(imgLoaded, rvaResources + (rvaEntry & ~DIR_MASK)); if ((rvaEntry & DIR_MASK) == 0) { throw new BadImageFormatException(); } if ((rvaName & DIR_MASK) != 0) { var e = new ProgramResourceGroup { //Name = ReadResourceString(rvaName), Name = ReadResourceUtf16leString(rvaResources + (rvaName & ~DIR_MASK)), }; e.Resources.AddRange(ReadNameDirectory(subRdr, PeResourceType.FromInt(0))); entries.Add(e); } } // Read the entries accessed by numeric ID. for (int i = 0; i < cIdEntries; ++i) { var id = rdr.ReadInt32(); var rvaEntry = rdr.ReadUInt32(); var subRdr = new LeImageReader(imgLoaded, rvaResources + (rvaEntry & ~DIR_MASK)); if ((rvaEntry & DIR_MASK) == 0) { throw new BadImageFormatException(); } var rt = PeResourceType.FromInt(id); var e = new ProgramResourceGroup { Name = rt.Name }; e.Resources.AddRange(ReadNameDirectory(subRdr, rt)); entries.Add(e); } return(entries); }
public override RelocationResults Relocate(Program program, Address addrLoad) { EndianImageReader rdr = new LeImageReader(RawImage, hdrOffset + relocationsOffset); ushort segCode = (ushort)(addrLoad.Selector.Value + (ExeImageLoader.CbPsp >> 4)); ushort dx = 0; for (; ;) { int cx = rdr.ReadLeUInt16(); if (cx != 0) { uint relocBase = ExeImageLoader.CbPsp + dx * 0x10u; do { ushort relocOff = rdr.ReadLeUInt16(); ushort seg = imgU.FixupLeUInt16(relocBase + relocOff, segCode); var segment = segmentMap.AddSegment(new ImageSegment( seg.ToString("X4"), Address.SegPtr(seg, 0), imgU, AccessMode.ReadWriteExecute)); } while (--cx != 0); } if (dx == 0xF000) { break; } dx += (ushort)0x1000U; } this.cs += segCode; segmentMap.AddOverlappingSegment(cs.ToString("X4"), imgU, Address.SegPtr(cs, 0), AccessMode.ReadWriteExecute); this.ss += segCode; var state = arch.CreateProcessorState(); state.SetRegister(Registers.ds, Constant.Word16(addrLoad.Selector.Value)); state.SetRegister(Registers.es, Constant.Word16(addrLoad.Selector.Value)); state.SetRegister(Registers.cs, Constant.Word16(cs)); state.SetRegister(Registers.ss, Constant.Word16(ss)); state.SetRegister(Registers.bx, Constant.Word16(0)); var ep = new ImageSymbol(Address.SegPtr(cs, ip)) { ProcessorState = state }; var entryPoints = new List <ImageSymbol> { ep }; var imageSymbols = entryPoints.ToSortedList(e => e.Address, e => e); return(new RelocationResults(entryPoints, imageSymbols)); }
/// <summary> /// Reads LDA data blocks /// </summary> /// <remarks> /// The format of LDA blocks is: /// +------+ /// | 0001 | - word16 - Magic /// |------| /// | BC | - word16 - Count /// |------| /// | ADDR | - word16 - Absolute load address /// |------| /// | Data | - byte[] - Data (`Count` bytes, including the first 6 bytes) /// ... /// |------| /// | Chk | - byte - Checksum /// +------+ /// </remarks> /// <param name="rdr"></param> /// <returns></returns> public Tuple <ushort, byte[]> ReadDataBlock(LeImageReader rdr) { ushort w; ushort count; ushort uAddr; byte b; // Eat bytes until 1 followed by 0. do { while (rdr.TryReadByte(out b) && b != 1) { ; } if (b != 1) { return(null); // invalid file } if (!rdr.TryReadByte(out b)) { return(null); } } while (b != 0); if (!rdr.TryReadLeUInt16(out count)) { return(null); } if (!rdr.TryReadLeUInt16(out uAddr)) { return(null); } if (count == 6) { return(new Tuple <ushort, byte[]>(uAddr, null)); } var data = rdr.ReadBytes(count - 6); if (data == null || data.Length < count - 6) { return(null); } if (!rdr.TryReadByte(out b)) // read (and ignore) checksum { return(null); } Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count); return(Tuple.Create(uAddr, data)); }
public static object ReadLeaf(LeImageReader rdr) { var b = rdr.ReadByte(); var lt = (LeafType)b; switch (lt) { default: throw new NotImplementedException($"CodeView leaf type {lt} {(int)lt:X2} not implemented yet."); case LeafType.Int8: return(rdr.ReadSByte()); case LeafType.UInt16: return(rdr.ReadLeUInt16()); case LeafType.ARRAY: return(ReadArray(rdr)); case LeafType.INDEX: // Type index return(rdr.ReadLeUInt16()); case LeafType.LABEL: return(ReadLabel(rdr)); case LeafType.LIST: return(ReadList(rdr)); case LeafType.POINTER: return(ReadPointer(rdr)); case LeafType.PROCEDURE: return(ReadProcedure(rdr)); case LeafType.STRING: return(ReadString(rdr)); case LeafType.STRUCTURE: return(ReadStructure(rdr)); case LeafType.Nil: case LeafType.C_FAR: case LeafType.C_NEAR: case LeafType.FAR: case LeafType.NEAR: case LeafType.UNPACKED: case (LeafType)0x81: //$REVIEW: void? return(lt); } }