public override RelocationResults Relocate(Address addrLoad) { ImageMap imageMap = imgLoadedMap; ImageReader rdr = new LeImageReader(exe.RawImage, (uint) exe.e_lfaRelocations); var relocations = new RelocationDictionary(); int i = exe.e_cRelocations; while (i != 0) { uint offset = rdr.ReadLeUInt16(); ushort segOffset = rdr.ReadLeUInt16(); offset += segOffset * 0x0010u; ushort seg = (ushort) (imgLoaded.ReadLeUInt16(offset) + addrLoad.Selector); imgLoaded.WriteLeUInt16(offset, seg); relocations.AddSegmentReference(offset, seg); imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute); --i; } // Found the start address. Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector), exe.e_ip); imageMap.AddSegment(Address.SegPtr(addrStart.Selector, 0), addrStart.Selector.ToString("X4"), AccessMode.ReadWriteExecute); return new RelocationResults( new List<EntryPoint> { new EntryPoint(addrStart, arch.CreateProcessorState()) }, relocations); }
private MachineInstruction RunTest(params byte [] bytes) { var image = new LoadedImage(Address.Ptr16(0x0100), bytes); var rdr = new LeImageReader(image, 0); var dasm = new Z80Disassembler(rdr); return dasm.First(); }
public ExePackLoader(IServiceProvider services, string filename, byte[] imgRaw) : base(services, filename, imgRaw) { arch = new IntelArchitecture(ProcessorMode.Real); platform = new MsdosPlatform(Services, arch); var exe = new ExeImageLoader(services, filename, imgRaw); this.exeHdrSize = (uint)(exe.e_cparHeader * 0x10U); this.hdrOffset = (uint)(exe.e_cparHeader + exe.e_cs) * 0x10U; ImageReader rdr = new LeImageReader(RawImage, hdrOffset); this.ip = rdr.ReadLeUInt16(); this.cs = rdr.ReadLeUInt16(); rdr.ReadLeUInt16(); this.cbExepackHeader = rdr.ReadLeUInt16(); this.sp = rdr.ReadLeUInt16(); this.ss = rdr.ReadLeUInt16(); this.cpUncompressed = rdr.ReadLeUInt16(); int offset = ExePackHeaderOffset(exe); if (LoadedImage.CompareArrays(imgRaw, offset, signature, signature.Length)) { relocationsOffset = 0x012D; } else if (LoadedImage.CompareArrays(imgRaw, offset, signature2, signature2.Length)) { relocationsOffset = 0x0125; } else throw new ApplicationException("Not a recognized EXEPACK image."); }
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 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 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 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()); }
private MachineInstruction RunTest(params ushort [] words) { var bytes = new byte[words.Length * 2]; LeImageWriter writer = new LeImageWriter(bytes); foreach (ushort word in words) { writer.WriteLeUInt16(word); } var image = new LoadedImage(Address.Ptr16(0x200), bytes); var rdr = new LeImageReader(image, 0); var arch = new Pdp11Architecture(); var dasm = new Pdp11Disassembler(rdr, arch); return dasm.First(); }
public PeImageLoader(IServiceProvider services, string filename, byte [] img, uint peOffset) : base(services, filename, img) { ImageReader rdr = new LeImageReader(RawImage, peOffset); if (rdr.ReadByte() != 'P' || rdr.ReadByte() != 'E' || rdr.ReadByte() != 0x0 || rdr.ReadByte() != 0x0) { throw new BadImageFormatException("Not a valid PE header."); } importThunks = new Dictionary<uint, PseudoProcedure>(); importReferences = new Dictionary<Address, ImportReference>(); short expectedMagic = ReadCoffHeader(rdr); ReadOptionalHeader(rdr, expectedMagic); }
private FileHeader LoadHeader() { var rdr = new LeImageReader(RawImage, 0); var magic = rdr.ReadLeUInt16(); switch (magic) { case 0x014C: arch = new IntelArchitecture(ProcessorMode.Protected32); break; default: throw new NotSupportedException(); } return new FileHeader { f_magic = magic, f_nscns = rdr.ReadUInt16(), f_timdat = rdr.ReadUInt32(), f_symptr = rdr.ReadUInt32(), f_nsyms = rdr.ReadUInt32(), f_opthdr = rdr.ReadUInt16(), f_flags = rdr.ReadUInt16(), }; }
public void ReadCommonExeFields() { ImageReader rdr = new LeImageReader(RawImage, 0); e_magic = rdr.ReadLeUInt16(); e_cbLastPage = rdr.ReadLeUInt16(); e_cpImage = rdr.ReadLeUInt16(); this.e_cRelocations = rdr.ReadLeUInt16(); e_cparHeader = rdr.ReadLeUInt16(); e_minalloc = rdr.ReadLeUInt16(); e_maxalloc = rdr.ReadLeUInt16(); e_ss = rdr.ReadLeUInt16(); e_sp = rdr.ReadLeUInt16(); e_csum = rdr.ReadLeUInt16(); e_ip = rdr.ReadLeUInt16(); e_cs = rdr.ReadLeUInt16(); e_lfaRelocations = rdr.ReadLeUInt16(); e_ovno = rdr.ReadLeUInt16(); e_res = new ushort[4]; for (int i = 0; i != 4; ++i) { e_res[i] = rdr.ReadLeUInt16(); } e_oemid = rdr.ReadLeUInt16(); e_oeminfo = rdr.ReadLeUInt16(); e_res2 = new ushort[10]; for (int i = 0; i != 10; ++i) { e_res2[i] = rdr.ReadLeUInt16(); } e_lfanew = rdr.ReadLeUInt32(); }
public void Sr_ReadArray() { var rdr = new LeImageReader(new byte[] { 0x4A, 0x4B, // signature 0x08, 0x00, 0x00, 0x00, // pointer to directory 0xFF, 0xFF, // padding 0x10, 0, // Directory slot 0 0x13, 0, // Directory slot 1 0x16, 0, // Directory slot 2 0x19, 0, // Directory slot 3 0x61, 0x62, 0x00, 0x63, 0x64, 0x00, 0x65, 0x66, 0x00, 0x65, 0x78, 0x00, }); var test = new TestStruct6(); var sr = new StructureReader(test); sr.Read(rdr); Assert.IsNotNull(test.directory); Assert.IsNotNull(test.directory.sections); Assert.AreEqual(4, test.directory.sections.Length); Assert.AreEqual("ab", test.directory.sections[0].name); Assert.AreEqual("cd", test.directory.sections[1].name); Assert.AreEqual("ef", test.directory.sections[2].name); Assert.AreEqual("ex", test.directory.sections[3].name); }
public void Sr_ReadStructure() { var rdr = new LeImageReader(new byte[] { 0x4A, 0x4B, // signature 0x08, 0x00, 0x00, 0x00, // pointer to struct 0xFF, 0xFF, // padding 0x34, 0x12, // structure. }); var test = new TestStruct5(); var sr = new StructureReader(test); sr.Read(rdr); Assert.IsNotNull(test.extra); Assert.AreEqual((ushort) 0x1234, test.extra.sig); }
public void Pil32_BlankIat() { Given_Pe32Header(0x00100000); Given_Section(".text", 0x1000, 0x1000); Given_Section(".idata", 0x2000, 0x2000); writer.Position = RvaImportDescriptor; var rvaId = Given_ImportDescriptor32( Given_Ilt32("malloc", "free", "realloc"), "msvcrt.dll", Given_Ilt32(0u, 0u, 0u)); Given_PeLoader(); var program = peldr.Load(addrLoad); var rdrId = new LeImageReader(fileImage, (uint)rvaId); var ret = peldr.ReadImportDescriptor(rdrId, addrLoad); Assert.IsTrue(ret); Assert.AreEqual(3, program.ImportReferences.Count); ; Assert.AreEqual("msvcrt.dll!malloc", program.ImportReferences[Address.Ptr32(0x0010202A)].ToString()); Assert.AreEqual("msvcrt.dll!free", program.ImportReferences[Address.Ptr32(0x0010202E)].ToString()); Assert.AreEqual("msvcrt.dll!realloc", program.ImportReferences[Address.Ptr32(0x00102032)].ToString()); }
public byte[] GetBytes() { byte[] data; var stm = new MemoryStream(); var rdr = new LeImageReader(image, (uint) offset); byte trackNext = rdr.ReadByte(); while (trackNext != 0) { byte sectorNext = rdr.ReadByte(); data = rdr.ReadBytes(0xFE); stm.Write(data, 0, data.Length); rdr.Offset = (uint) SectorOffset(trackNext, sectorNext); trackNext = rdr.ReadByte(); } byte lastUsed = rdr.ReadByte(); data = rdr.ReadBytes(lastUsed - 2); stm.Write(data, 0, data.Length); return stm.ToArray(); }
public bool ReadDirectorySector(LeImageReader rdr, List<ArchiveDirectoryEntry> entries) { byte nextDirTrack = 0; byte nextDirSector = 0; for (int i = 0; i < 8; ++i) { if (i == 0) { nextDirTrack = rdr.ReadByte(); nextDirSector = rdr.ReadByte(); } else { rdr.Seek(2); } var fileType = (FileType) rdr.ReadByte(); var fileTrack = rdr.ReadByte(); var fileSector = rdr.ReadByte(); var sName = Encoding.ASCII.GetString(rdr.ReadBytes(16)) .TrimEnd((char) 0xA0); var relTrack = rdr.ReadByte(); var relSector = rdr.ReadByte(); var rel = rdr.ReadByte(); rdr.Seek(6); var sectorSize = rdr.ReadLeInt16(); if ((fileType & FileType.FileTypeMask) != FileType.DEL) { entries.Add(new D64FileEntry( sName, RawImage, SectorOffset(fileTrack, fileSector), fileType)); } } if (nextDirTrack != 0) { rdr.Offset = (uint) SectorOffset(nextDirTrack, nextDirSector); return true; } else { return false; } }
public List<ArchiveDirectoryEntry> LoadDiskDirectory() { var entries = new List<ArchiveDirectoryEntry>(); var rdr = new LeImageReader(RawImage, (uint)SectorOffset(18, 0)); byte track = rdr.ReadByte(); if (track == 0) return entries; byte sector = rdr.ReadByte(); rdr.Offset = (uint) D64Loader.SectorOffset(track, sector); while (ReadDirectorySector(rdr, entries)) ; return entries; }
public IEnumerable<Section> ReadSections(LeImageReader rdr, int sections) { for (int i = 0; i < sections; ++i) { yield return ReadSection(rdr); } }
public override RelocationResults Relocate(Address addrLoad) { ImageReader rdr = new LeImageReader(RawImage, hdrOffset + relocationsOffset); ushort segCode = (ushort)(addrLoad.Selector + (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); imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute); } while (--cx != 0); } if (dx == 0xF000) break; dx += (ushort)0x1000U; } this.cs += segCode; imageMap.AddSegment(Address.SegPtr(cs, 0), cs.ToString("X4"), AccessMode.ReadWriteExecute); this.ss += segCode; var state = arch.CreateProcessorState(); state.SetRegister(Registers.ds, Constant.Word16(addrLoad.Selector)); state.SetRegister(Registers.es, Constant.Word16(addrLoad.Selector)); state.SetRegister(Registers.cs, Constant.Word16(cs)); state.SetRegister(Registers.ss, Constant.Word16(ss)); state.SetRegister(Registers.bx, Constant.Word16(0)); var entryPoints = new List<EntryPoint> { new EntryPoint(Address.SegPtr(cs, ip), state) }; return new RelocationResults(entryPoints, new RelocationDictionary()); }
/// <summary> /// Loads the sections /// </summary> /// <param name="rvaSectionTable"></param> /// <returns></returns> private SortedDictionary<string, Section> LoadSections(Address addrLoad, uint rvaSectionTable, int sections) { var sectionMap = new SortedDictionary<string, Section>(); ImageReader rdr = new LeImageReader(RawImage, rvaSectionTable); var section = ReadSection(rdr); var sectionMax = section; sectionMap[section.Name] = section; for (int i = 1; i != sections; ++i) { section = ReadSection(rdr); sectionMap[section.Name] = section; if (section.VirtualAddress > sectionMax.VirtualAddress) sectionMax = section; Debug.Print(" Section: {0,10} {1:X8} {2:X8} {3:X8} {4:X8}", section.Name, section.OffsetRawData, section.SizeRawData, section.VirtualAddress, section.VirtualSize); } return sectionMap; }
public uint ReadEntryPointRva() { ImageReader rdr = new LeImageReader(RawImage, rvaSectionTable); for (int i = 0; i < sections; ++i) { var s = ReadSection(rdr); if (s.VirtualAddress <= rvaStartAddress && rvaStartAddress < s.VirtualAddress + s.VirtualSize) { return (rvaStartAddress - s.VirtualAddress) + s.OffsetRawData; } } return 0; }
public void ApplyRelocations(uint rvaReloc, uint size, uint baseOfImage, RelocationDictionary relocations) { ImageReader rdr = new LeImageReader(RawImage, rvaReloc); uint rvaStop = rvaReloc + size; while (rdr.Offset < rvaStop) { // Read fixup block header. uint page = rdr.ReadLeUInt32(); int cbBlock = rdr.ReadLeInt32(); if (page == 0 || cbBlock == 0) break; uint offBlockEnd = (uint)((int)rdr.Offset + cbBlock - 8); while (rdr.Offset < offBlockEnd) { ApplyRelocation(baseOfImage, page, rdr, relocations); } } }
public void Sr_ReadLeInt32_String() { var rdr = new LeImageReader(new byte[] { 0x34, 0x12, 0xAB, 0xCD, 0x48, 0x69, 0x00, 0x42, 0x79, 0x65, 0x21, 0x00}); var test = new TestStruct4(); var sr = new StructureReader(test); sr.Read(rdr); Assert.AreEqual("Hi", test.sField04); Assert.AreEqual("Bye!", test.sFieldnn); }
public LoadedImage Unpack(byte [] abC, Address addrLoad) { // Extract the LZ stuff. ImageReader rdr = new LeImageReader(abC, (uint) lzHdrOffset); lzIp = rdr.ReadLeUInt16(); lzCs = rdr.ReadLeUInt16(); ushort lzSp = rdr.ReadLeUInt16(); ushort lzSs = rdr.ReadLeUInt16(); ushort lzcpCompressed = rdr.ReadLeUInt16(); ushort lzcpDecompressed = rdr.ReadLeUInt16(); // Find the start of the compressed stream. int ifile = lzHdrOffset - (lzcpCompressed << 4); // Allocate space for the decompressed goo. int cbUncompressed = ((int) lzcpDecompressed + lzcpDecompressed) << 4; byte [] abU = new byte[cbUncompressed]; // Decompress this sorry mess. int len; int span; int p = 0; BitStream bits = new BitStream(abC, ifile); for (;;) { if (bits.GetBit() != 0) { // 1.... abU[p++] = bits.GetByte(); continue; } if (bits.GetBit() == 0) { // 00..... len = bits.GetBit() << 1; len |= bits.GetBit(); len += 2; span = bits.GetByte() | ~0xFF; } else { // 01..... span = bits.GetByte(); len = bits.GetByte();; span |= ((len & ~0x07)<<5) | ~0x1FFF; len = (len & 0x07) + 2; if (len == 2) { len = bits.GetByte(); if (len == 0) break; // end mark of compressed load module if (len == 1) continue; // segment change else ++len; } } for( ;len > 0; --len, ++p) { abU[p] = abU[p+span]; } } // Create a new image based on the uncompressed data. this.imgLoaded = new LoadedImage(addrLoad, abU); this.imageMap = imgLoaded.CreateImageMap(); return imgLoaded; }