public void AddressNotInDictionary() { RelocationDictionary rd = new RelocationDictionary(); rd.AddPointerReference(0x020, 0x12312312); Assert.IsNull(rd[0x3243232]); Assert.IsFalse(rd.Contains(0x2341231)); }
public override void ApplyRelocation(Address baseOfImage, uint page, ImageReader rdr, RelocationDictionary relocations) { ushort fixup = rdr.ReadLeUInt16(); Address offset = baseOfImage + page + (fixup & 0x0FFFu); var imgR = program.CreateImageReader(offset); var imgW = program.CreateImageWriter(offset); switch (fixup >> 12) { case RelocationAbsolute: // Used for padding to 4-byte boundary, ignore. break; case RelocationHighLow: { uint n = (uint) (imgR.ReadUInt32() + (baseOfImage - program.ImageMap.BaseAddress)); imgW.WriteUInt32(n); relocations.AddPointerReference(offset.ToLinear() - imgW.MemoryArea.BaseAddress.ToLinear(), n); break; } case 0xA: break; default: dcSvc.Warn( dcSvc.CreateAddressNavigator(program, offset), string.Format( "Unsupported i386 PE fixup type: {0:X}", fixup >> 12)); break; } }
public override RelocationResults Relocate(Program program, 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.Value); imgLoaded.WriteLeUInt16(offset, seg); relocations.AddSegmentReference(offset, seg); imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute, 0); --i; } // Found the start address. Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector.Value), exe.e_ip); imageMap.AddSegment( Address.SegPtr(addrStart.Selector.Value, 0), addrStart.Selector.Value.ToString("X4"), AccessMode.ReadWriteExecute, 0); return new RelocationResults( new List<EntryPoint> { new EntryPoint(addrStart, arch.CreateProcessorState()) }, relocations, new List<Address>()); }
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 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 RelocationResults( List<EntryPoint> entryPoints, RelocationDictionary relocations, List<Address> functions) { this.EntryPoints = entryPoints; this.Relocations = relocations; this.Functions = functions; }
public RelocationResults( List <EntryPoint> entryPoints, RelocationDictionary relocations, List <Address> functions) { this.EntryPoints = entryPoints; this.Relocations = relocations; this.Functions = functions; }
public void Reld_Overlaps() { var rd = new RelocationDictionary(); rd.AddPointerReference(0x2000, 0x12312312); Assert.IsFalse(rd.Overlaps(Address.Ptr32(0x1FFC), 4)); Assert.IsFalse(rd.Overlaps(Address.Ptr32(0x2004), 1)); Assert.IsTrue(rd.Overlaps(Address.Ptr32(0x2003), 1)); Assert.IsTrue(rd.Overlaps(Address.Ptr32(0x1FFC), 5)); Assert.IsFalse(rd.Overlaps(Address.Ptr32(0x1FFF), 5)); Assert.IsFalse(rd.Overlaps(Address.Ptr32(0x2000), 4)); Assert.IsFalse(rd.Overlaps(Address.Ptr32(0x2000), 8)); Assert.IsFalse(rd.Overlaps(Address.Ptr32(0x1FFC), 8)); }
public const short IMAGE_REL_MIPS_PAIR = 0x0025; // This relocation is only valid when it immediately follows a REFHI or SECRELHI relocation. Its SymbolTableIndex contains a displacement and not an index into the symbol table. public override void ApplyRelocation(Address baseOfImage, uint page, ImageReader rdr, RelocationDictionary relocations) { ushort fixup = rdr.ReadUInt16(); Address offset = baseOfImage + page + (fixup & 0x0FFFu); var imgR = program.CreateImageReader(offset); var imgW = program.CreateImageWriter(offset); uint w = imgR.ReadUInt32(); int s; switch (fixup >> 12) { case IMAGE_REL_MIPS_ABSOLUTE: // Used for padding to 4-byte boundary, ignore. break; case IMAGE_REL_MIPS_REFWORD: break; case IMAGE_REL_MIPS_JMPADDR: break; case IMAGE_REL_MIPS_REFHI: w = imgR.ReadUInt32(); //w += (fixup & 0x0FFFu); //imgW.WriteUInt32(w); s = rdr.ReadInt16(); w = (uint)(w + s); // w points to something. break; case IMAGE_REL_MIPS_REFLO: // w points to something. break; default: dcSvc.Warn( dcSvc.CreateAddressNavigator(program, offset), string.Format( "Unsupported MIPS PE fixup type: {0:X}", fixup >> 12)); break; } }
public override RelocationResults Relocate(Program program, Address addrLoad) { if (image == null) throw new InvalidOperationException(); // No file loaded var entryPoints = new List<EntryPoint>(); var 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 if (Header64.e_machine == EM_X86_64) { RelocateX86_64(); } 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_MIPS: case EM_ARM: break; default: throw new NotImplementedException(); } } return new RelocationResults(entryPoints, relocations, new List<Address>()); }
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(Program program, Address addrLoad) { var relocations = new RelocationDictionary(); ushort segCode = (ushort) (addrLoad.Selector.Value + (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,0); } 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.Value)); state.SetRegister(Registers.es, Constant.Word16(addrLoad.Selector.Value)); 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, new List<Address>()); }
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)); } }
public RelocationResults(List <EntryPoint> entryPoints, RelocationDictionary relocations) { this.EntryPoints = entryPoints; this.Relocations = 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); */ }
// Fix up the relocations. public override RelocationResults Relocate(Program program, 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.Value, imgLoaded, relocations); } else { Relocate90(RawImage, addrLoad.Selector.Value, imgLoaded, relocations); } return new RelocationResults(entryPoints, relocations, new List<Address>()); }
public RelocationResults(List<EntryPoint> entryPoints, RelocationDictionary relocations) { this.EntryPoints = entryPoints; this.Relocations = relocations; }
public void ApplyRelocation(uint baseOfImage, uint page, ImageReader rdr, RelocationDictionary relocations) { ushort fixup = rdr.ReadLeUInt16(); uint offset = page + (fixup & 0x0FFFu); switch (fixup >> 12) { case RelocationAbsolute: // Used for padding to 4-byte boundary, ignore. break; case RelocationHighLow: { uint n = (uint) (imgLoaded.ReadLeUInt32(offset) + (baseOfImage - preferredBaseOfImage.ToLinear())); imgLoaded.WriteLeUInt32(offset, n); relocations.AddPointerReference(offset, n); break; } case 0xA: break; default: var dcSvc = Services.RequireService<DecompilerEventListener>(); dcSvc.Warn( dcSvc.CreateAddressNavigator(program, Address.Ptr32(offset)), string.Format( "Unsupported PE fixup type: {0:X}", fixup >> 12)); break; } }
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 abstract void ApplyRelocation(Address baseOfImage, uint page, ImageReader rdr, RelocationDictionary relocations);
// 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, 0); } return imageMap; }
public override void ApplyRelocation(Address baseOfImage, uint page, ImageReader rdr, RelocationDictionary relocations) { throw new NotImplementedException(); }
public void ApplyRelocation(uint baseOfImage, uint page, ImageReader rdr, RelocationDictionary relocations) { ushort fixup = rdr.ReadLeUInt16(); uint offset = page + (fixup & 0x0FFFu); switch (fixup >> 12) { case RelocationAbsolute: // Used for padding to 4-byte boundary, ignore. break; case RelocationHighLow: { uint n = (uint) (imgLoaded.ReadLeUInt32(offset) + (baseOfImage - preferredBaseOfImage.ToLinear())); imgLoaded.WriteLeUInt32(offset, n); relocations.AddPointerReference(offset, n); break; } case 0xA: break; default: var dcSvc = Services.RequireService<DecompilerEventListener>(); dcSvc.Warn( dcSvc.CreateAddressNavigator(program, Address.Ptr32(offset)), string.Format( "Unsupported PE fixup type: {0:X}", fixup >> 12)); break; } #if I386 // // I386 relocation types. // const static final ushort IMAGE_REL_I386_ABSOLUTE = 0x0000; // Reference is absolute, no relocation is necessary const static final ushort IMAGE_REL_I386_DIR16 = 0x0001; // Direct 16-bit reference to the symbols virtual address const static final ushort IMAGE_REL_I386_REL16 = 0x0002; // PC-relative 16-bit reference to the symbols virtual address const static final ushort IMAGE_REL_I386_DIR32 = 0x0006; // Direct 32-bit reference to the symbols virtual address const static final ushort IMAGE_REL_I386_DIR32NB = 0x0007; // Direct 32-bit reference to the symbols virtual address, base not included const static final ushort IMAGE_REL_I386_SEG12 = 0x0009; // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address const static final ushort IMAGE_REL_I386_SECTION = 0x000A; const static final ushort IMAGE_REL_I386_SECREL = 0x000B; const static final ushort IMAGE_REL_I386_TOKEN = 0x000C; // clr token const static final ushort IMAGE_REL_I386_SECREL7 = 0x000D; // 7 bit offset from base of section containing target const static final ushort IMAGE_REL_I386_REL32 = 0x0014; // PC-relative 32-bit reference to the symbols virtual address
public override RelocationResults Relocate(Address addrLoad) { if (image == null) throw new InvalidOperationException(); // No file loaded List<EntryPoint> entryPoints = new List<EntryPoint>(); 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 { if (Header32.e_machine == EM_386) { RelocateI386(); } else if (Header32.e_machine == EM_PPC) { RelocatePpc32(); } else { throw new NotImplementedException(); } } return new RelocationResults(entryPoints, relocations); }