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); }
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."); }
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 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; }
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 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()); }