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 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 void Setup() { mr = new MockRepository(); rd = null; this.graph = new DiGraph <Address>(); this.instrs = new SortedList <Address, MachineInstruction>(); }
public void AddressNotInDictionary() { RelocationDictionary rd = new RelocationDictionary(); rd.AddPointerReference(0x020, 0x12312312); Assert.IsNull(rd[0x3243232]); Assert.IsFalse(rd.Contains(0x2341231)); }
private void Given_Image(IProcessorArchitecture arch, params byte[] bytes) { var image = new MemoryArea( Address.Ptr32(0x10000), bytes); this.rd = image.Relocations; CreateProgram(image, arch); }
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()); }
private void Given_x86_Image(params byte[] bytes) { var image = new ByteMemoryArea( Address.Ptr32(0x10000), bytes); this.rd = image.Relocations; var arch = new X86ArchitectureFlat32(new ServiceContainer(), "x86-protected-32", new Dictionary <string, object>()); CreateProgram(image, arch); }
private void Given_x86_Image(params byte[] bytes) { var image = new MemoryArea( Address.Ptr32(0x10000), bytes); this.rd = image.Relocations; var arch = new X86ArchitectureFlat32("x86-protected-32"); CreateProgram(image, arch); }
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 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 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
// 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 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 Setup() { rd = null; this.graph = new DiGraph <Address>(); }
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format public override void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations) { ushort fixup = rdr.ReadLeUInt16(); var rt = (ArmRt)(fixup >> 12); DebugEx.Verbose(PeImageLoader.trace, " {0:X4} {1}", fixup, rt); //switch (fixup) //{ //} }
public override void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations) { throw new NotImplementedException(); }
public void Setup() { mr = new MockRepository(); rd = null; this.graph = new DiGraph <Address>(); }
public abstract void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations);
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, EndianImageReader rdr, RelocationDictionary relocations) { ushort fixup = rdr.ReadUInt16(); Address offset = baseOfImage + page + (fixup & 0x0FFFu); var arch = program.Architecture; var imgR = program.CreateImageReader(arch, offset); var imgW = program.CreateImageWriter(arch, 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; } }
// 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); }
// 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); */ }
public override void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations) { //$TODO: where to find docs for this? :-) rdr.ReadLeUInt32(); }
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format public override void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations) { ushort fixup = rdr.ReadLeUInt16(); var rt = (Arm64Rt)(fixup >> 12); Address offset = baseOfImage + page + (fixup & 0x0FFFu); DebugEx.Verbose(PeImageLoader.trace, " {0:X4} {1}", fixup, rt); var imgR = program.CreateImageReader(program.Architecture, offset); var imgW = program.CreateImageWriter(program.Architecture, offset); switch (rt) { case Arm64Rt.IMAGE_REL_ARM64_ABSOLUTE: break; case Arm64Rt.IMAGE_REL_ARM64_SECREL_HIGH12A: var uInstr = imgR.ReadLeUInt32(); break; default: eventListener.Warn( eventListener.CreateAddressNavigator(program, offset), string.Format( "Unsupported AArch64 PE fixup type: {0:X}", fixup >> 12)); break; } }
public override void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations) { rdr.ReadUInt16(); return; }
public override void ApplyRelocation(Address baseOfImage, uint page, EndianImageReader rdr, RelocationDictionary relocations) { ushort fixup = rdr.ReadLeUInt16(); Address offset = baseOfImage + page + (fixup & 0x0FFFu); var arch = program.Architecture; var imgR = program.CreateImageReader(arch, offset); var imgW = program.CreateImageWriter(arch, 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(), 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 abstract void ApplyRelocation(uint baseOfImage, uint page, ImageReader rdr, RelocationDictionary relocations);