public void AddressNotInDictionary() { RelocationDictionary rd = new RelocationDictionary(); rd.AddPointerReference(0x020, 0x12312312); Assert.IsNull(rd[0x3243232]); Assert.IsFalse(rd.Contains(0x2341231)); }
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 void AddSegmentRelocation() { RelocationDictionary rd = new RelocationDictionary(); rd.AddSegmentReference(0xD234, 0x0C00); Assert.AreEqual(1, rd.Count); Constant c = rd[0xD234]; Assert.AreEqual("selector", c.DataType.ToString()); }
public void AddPointerRelocation() { RelocationDictionary rd = new RelocationDictionary(); rd.AddPointerReference(0x100400, 0x100500); Assert.AreEqual(1, rd.Count); Constant c = rd[0x0100400]; Assert.AreEqual("ptr32", c.DataType.ToString()); }
public RelocationResults(List<EntryPoint> entryPoints, RelocationDictionary relocations) { this.EntryPoints = entryPoints; this.Relocations = relocations; }
public override RelocationResults Relocate(Address addrLoad) { if (image == null) throw new InvalidOperationException(); // No file loaded RelocationDictionary relocations = new RelocationDictionary(); var addrEntry = GetEntryPointAddress(); if (addrEntry != null) { var ep = new EntryPoint(addrEntry, arch.CreateProcessorState()); entryPoints.Add(ep); } if (fileClass == ELFCLASS64) { if (Header64.e_machine == EM_PPC64) { //$TODO } else throw new NotImplementedException(string.Format("Relocations for architecture {0} not implemented.", Header64.e_machine)); } else { switch (Header32.e_machine) { case EM_386: RelocateI386(); break; case EM_PPC: RelocatePpc32(); break; case EM_ARM: RelocateArm(); break; default: throw new NotImplementedException(string.Format("ELF relocation for {0} is not implemented yet.", arch.GetType().Name)); } } return new RelocationResults(entryPoints, relocations); }
// for LZEXE ver 0.90 private ImageMap Relocate90(byte [] pgmImg, ushort segReloc, LoadedImage pgmImgNew, RelocationDictionary relocations) { int ifile = lzHdrOffset + 0x19D; // 0x19d=compressed relocation table address throw new NotImplementedException(); /* unsigned int c; ushort rel_count=0; ushort rel_seg,rel_off; rel_seg=0; do { c=getw(ifile); for(;c>0;c--) { rel_off=getw(ifile); putw(rel_off,ofile); putw(rel_seg,ofile); rel_count++; } rel_seg += 0x1000; } while(rel_seg!=(0xf000+0x1000)); ohead[3]=rel_count; return(SUCCESS); */ }
// Unpacks the relocation entries in a LzExe 0.91 binary private ImageMap Relocate91(byte [] abUncompressed, ushort segReloc, LoadedImage pgmImgNew, RelocationDictionary relocations) { const int CompressedRelocationTableAddress = 0x0158; int ifile = lzHdrOffset + CompressedRelocationTableAddress; int rel_off=0; for (;;) { ushort span = abUncompressed[ifile++]; if (span == 0) { span = abUncompressed[ifile++]; span |= (ushort) (abUncompressed[ifile++] << 8); if (span == 0) { rel_off += 0x0FFF0; continue; } else if (span == 1) { break; } } rel_off += span; ushort seg = (ushort) (pgmImgNew.ReadLeUInt16((uint)rel_off) + segReloc); pgmImgNew.WriteLeUInt16((uint)rel_off, seg); relocations.AddSegmentReference((uint)rel_off, seg); imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute); } return imageMap; }
// Fix up the relocations. public override RelocationResults Relocate(Address addrLoad) { // Seed the scanner with the start location. List<EntryPoint> entryPoints = new List<EntryPoint>() { new EntryPoint(Address.SegPtr((ushort) (lzCs + addrLoad.Selector), lzIp), arch.CreateProcessorState()), }; var relocations = new RelocationDictionary(); if (isLz91) { Relocate91(RawImage, addrLoad.Selector, imgLoaded, relocations); } else { Relocate90(RawImage, addrLoad.Selector, imgLoaded, relocations); } return new RelocationResults(entryPoints, relocations); }
public override RelocationResults Relocate(Address addrLoad) { var entryPoints = new List<EntryPoint>(); var relocations = new RelocationDictionary(); if (rsrcFork != null) { rsrcFork.Dump(); rsrcFork.AddResourcesToImageMap(addrLoad, imageMap, entryPoints); } return new RelocationResults(entryPoints, relocations); }
public override RelocationResults Relocate(Address addrLoad) { var relocations = new RelocationDictionary(); ushort segCode = (ushort) (addrLoad.Selector + (PspSize >> 4)); for (;;) { int relocs = (ushort) bitStm.GetByte(); if (relocs == 0) break; uint relocBase = PspSize + bitStm.GetWord() * 0x10u; do { ushort relocOff = bitStm.GetWord(); ushort seg = imgU.ReadLeUInt16(relocBase + relocOff); seg = (ushort) (seg + segCode); imgU.WriteLeUInt16(relocBase + relocOff, seg); relocations.AddSegmentReference(relocBase + relocOff, seg); imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute); } while (--relocs != 0); } ushort pklSs = (ushort) (bitStm.GetWord() + segCode); ushort pklSp = (ushort) bitStm.GetWord(); pklCs = (ushort) (bitStm.GetWord() + segCode); pklIp = bitStm.GetWord(); 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(pklCs)); state.SetRegister(Registers.ax, Constant.Word16(0)); state.SetRegister(Registers.bx, Constant.Word16(0)); state.SetRegister(Registers.cx, Constant.Word16(0)); state.SetRegister(Registers.dx, Constant.Word16(0)); state.SetRegister(Registers.bp, Constant.Word16(0)); state.SetRegister(Registers.sp, Constant.Word16(pklSp)); state.SetRegister(Registers.si, Constant.Word16(0)); state.SetRegister(Registers.di, Constant.Word16(0)); return new RelocationResults( new List<EntryPoint> {new EntryPoint(Address.SegPtr(pklCs, pklIp), state) }, relocations); }
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 ApplyRelocation(uint baseOfImage, uint page, ImageReader rdr, RelocationDictionary relocations) { ushort fixup = rdr.ReadLeUInt16(); switch (fixup >> 12) { case RelocationAbsolute: // Used for padding to 4-byte boundary, ignore. break; case RelocationHighLow: { uint offset = page + (fixup & 0x0FFFu); uint n = (uint) (imgLoaded.ReadLeUInt32(offset) + (baseOfImage - preferredBaseOfImage.ToLinear())); imgLoaded.WriteLeUInt32(offset, n); relocations.AddPointerReference(offset, n); break; } case 0xA: break; default: throw new NotImplementedException(string.Format("Fixup type: {0:X}", fixup >> 12)); } }