public ImageSymbolWorkItem(Scanner scanner, Program program, ImageSymbol sym, bool isEntryPoint) : base(sym.Address) { this.scanner = scanner; this.program = program; this.sym = sym; this.isEntryPoint = isEntryPoint; }
protected Program RewriteFile(string relativePath, Address addrBase) { sc = new ServiceContainer(); var config = new FakeDecompilerConfiguration(); var eventListener = new FakeDecompilerEventListener(); sc.AddService<IConfigurationService>(config); sc.AddService<DecompilerHost>(new FakeDecompilerHost()); sc.AddService<DecompilerEventListener>(eventListener); sc.AddService<IFileSystemService>(new FileSystemServiceImpl()); ILoader ldr = new Loader(sc); var program = ldr.AssembleExecutable( FileUnitTester.MapTestPath(relativePath), new X86TextAssembler(sc, new X86ArchitectureReal()), addrBase); program.Platform = new DefaultPlatform(sc, program.Architecture); var ep = new ImageSymbol(program.SegmentMap.BaseAddress); var project = new Project { Programs = { program } }; var scan = new Scanner( program, new ImportResolver(project, program, eventListener), sc); scan.EnqueueImageSymbol(ep, true); scan.ScanImage(); var importResolver = new ImportResolver(project, program, eventListener); var dfa = new DataFlowAnalysis(program, importResolver, eventListener); dfa.AnalyzeProgram(); return program; }
public override RelocationResults Relocate(Program program, Address addrLoad) { var uaddrEntry = MemoryArea.ReadLeUInt16(RawImage, 0x20); var entry = new ImageSymbol(Address.Ptr16(uaddrEntry)); return new RelocationResults( new List<ImageSymbol> { entry }, new SortedList<Address, ImageSymbol>()) { }; }
public override RelocationResults Relocate(Program program, Address addrLoad) { // Get the Reset address from offset $0004 of the interrupt vector. var addrReset = Address.Ptr32(MemoryArea.ReadBeUInt32(RawImage, 4)); var syms = new SortedList<Address, ImageSymbol>(); var eps = new List<ImageSymbol>(); if (program.SegmentMap.IsValidAddress(addrReset)) { var sym = new ImageSymbol(addrReset) { Name = "Reset", ProcessorState = program.Architecture.CreateProcessorState() }; syms.Add(sym.Address, sym); eps.Add(sym); } return new RelocationResults(eps, syms); }
protected void RunHexTest(string hexFile, string outputFile) { var svc = new ServiceContainer(); var cfg = new FakeDecompilerConfiguration(); var eventListener = new FakeDecompilerEventListener(); svc.AddService<IConfigurationService>(cfg); svc.AddService<DecompilerEventListener>(eventListener); svc.AddService<DecompilerHost>(new FakeDecompilerHost()); ILoader ldr = new Loader(svc); var imgLoader = new DchexLoader(FileUnitTester.MapTestPath( hexFile), svc, null); var program = imgLoader.Load(null); var project = new Project { Programs = { program } }; var ep = new ImageSymbol(program.ImageMap.BaseAddress); var importResolver = new ImportResolver(project, program, eventListener); var scan = new Scanner(program, importResolver, svc); scan.EnqueueImageSymbol(ep, true); scan.ScanImage(); var dfa = new DataFlowAnalysis(program, null, eventListener); dfa.AnalyzeProgram(); RunTest(program, outputFile); }
public override RelocationResults Relocate(Program program, Address addrLoad) { ImageReader rdr = new LeImageReader(RawImage, hdrOffset + relocationsOffset); ushort segCode = (ushort)(addrLoad.Selector.Value + (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); var segment = segmentMap.AddSegment(new ImageSegment( seg.ToString("X4"), Address.SegPtr(seg, 0), imgU, AccessMode.ReadWriteExecute)); } while (--cx != 0); } if (dx == 0xF000) break; dx += (ushort)0x1000U; } this.cs += segCode; segmentMap.AddSegment(Address.SegPtr(cs, 0), cs.ToString("X4"), AccessMode.ReadWriteExecute, 0); this.ss += segCode; 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(cs)); state.SetRegister(Registers.ss, Constant.Word16(ss)); state.SetRegister(Registers.bx, Constant.Word16(0)); var ep = new ImageSymbol(Address.SegPtr(cs, ip)) { ProcessorState = state }; var entryPoints = new List<ImageSymbol> { ep }; var imageSymbols = entryPoints.ToSortedList(e => e.Address, e => e); return new RelocationResults(entryPoints, imageSymbols); }
public override RelocationResults Relocate(Program program, Address addrLoad) { SegmentMap imageMap = segmentMap; ImageReader rdr = new LeImageReader(exe.RawImage, (uint) exe.e_lfaRelocations); var relocations = imgLoaded.Relocations; int i = exe.e_cRelocations; var segments = new Dictionary<Address, ushort>(); 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); var segment = new ImageSegment( seg.ToString("X4"), Address.SegPtr(seg, 0), imgLoaded, AccessMode.ReadWriteExecute); segment = segmentMap.AddSegment(segment); segments[segment.Address] = seg; --i; } // Create an identifier for each segment. foreach (var de in segments) { var tmp = new TemporaryStorage( string.Format("seg{0:X4}", de.Value), 0, PrimitiveType.SegmentSelector); segmentMap.Segments[de.Key].Identifier = new Identifier( tmp.Name, PrimitiveType.SegmentSelector, tmp); } // Found the start address. Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector.Value), exe.e_ip); segmentMap.AddSegment(new ImageSegment( addrStart.Selector.Value.ToString("X4"), Address.SegPtr(addrStart.Selector.Value, 0), imgLoaded, AccessMode.ReadWriteExecute)); DumpSegments(imageMap); var ep = new ImageSymbol(addrStart) { Type = SymbolType.Procedure, ProcessorState = arch.CreateProcessorState() }; var sym = platform.FindMainProcedure(program, addrStart); var results = new RelocationResults( new List<ImageSymbol> { ep }, new SortedList<Address, ImageSymbol> { { ep.Address, ep } }); if (sym != null) { results.Symbols[sym.Address] = sym; ep.NoDecompile = true; } return results; }
public override void LocateGotPointers(Program program, SortedList<Address, ImageSymbol> symbols) { // Locate the GOT //$REVIEW: there doesn't seem to be a reliable way to get that // information. var got = program.SegmentMap.Segments.Values.FirstOrDefault(s => s.Name == ".got"); if (got == null) return; var rdr = program.CreateImageReader(got.Address); while (rdr.Address < got.EndAddress) { var addrGot = rdr.Address; ulong uAddrSym; if (!rdr.TryReadUInt64(out uAddrSym)) break; var addrSym = Address.Ptr64(uAddrSym); ImageSymbol symbol; if (symbols.TryGetValue(addrSym, out symbol)) { // This GOT entry is a known symbol! if (symbol.Type == SymbolType.Procedure) { //$TODO: look up function signature. var gotSym = new ImageSymbol(addrGot, symbol.Name + "_GOT", new Pointer(new CodeType(), 4)); symbols[addrGot] = gotSym; Debug.Print("Found GOT entry at {0}, changing symbol at {1}", gotSym, symbol); } } } }
public void El32_Symbols_ReconstructPlt_BE() { var syms = new ImageSymbol[] { new ImageSymbol(Address.Ptr32(0x04000000)) { Name = "strcpy", Type = SymbolType.Procedure }, new ImageSymbol(Address.Ptr32(0x04000010)) { Name = "strcmp", Type = SymbolType.Procedure }, }.ToSortedList(k => k.Address); Given_ImageHeader(ElfMachine.EM_MIPS); Given_Program(); Given_BE32_GOT(0x0000000, 0x00000000, 0x04000010, 0x04000000); mr.ReplayAll(); When_CreateLoader32(); el32.LocateGotPointers(program, syms); Assert.AreEqual("strcmp_GOT", syms[Address.Ptr32(0x10000008)].Name); Assert.AreEqual("strcpy_GOT", syms[Address.Ptr32(0x1000000C)].Name); }
private void DoRewriteCore() { var cfgSvc = MockRepository.GenerateStub<IConfigurationService>(); var env = MockRepository.GenerateStub<OperatingEnvironment>(); var tlSvc = MockRepository.GenerateStub<ITypeLibraryLoaderService>(); var eventListener = new FakeDecompilerEventListener(); cfgSvc.Stub(c => c.GetEnvironment("ms-dos")).Return(env); cfgSvc.Replay(); env.Stub(e => e.TypeLibraries).Return(new List<ITypeLibraryElement>()); env.Stub(e => e.CharacteristicsLibraries).Return(new List<ITypeLibraryElement>()); env.Replay(); tlSvc.Replay(); sc.AddService<DecompilerHost>(new FakeDecompilerHost()); sc.AddService<DecompilerEventListener>(eventListener); sc.AddService<IConfigurationService>(cfgSvc); sc.AddService<ITypeLibraryLoaderService>(tlSvc); Project project = LoadProject(); project.Programs.Add(this.program); scanner = new Scanner( this.program, new ImportResolver(project, this.program, eventListener), sc); ImageSymbol ep = new ImageSymbol(baseAddress); scanner.EnqueueImageSymbol(ep, true); var program = project.Programs[0]; foreach (Procedure_v1 sp in program.User.Procedures.Values) { scanner.EnqueueUserProcedure(sp); } scanner.ScanImage(); }
public void EnqueueImageSymbol(ImageSymbol sym, bool isEntryPoint) { if (sym.ProcessorState == null) sym.ProcessorState = program.Architecture.CreateProcessorState(); queue.Enqueue(PriorityEntryPoint, new ImageSymbolWorkItem(this, program, sym, isEntryPoint)); }
public void ScanImageSymbol(Program program, ImageSymbol sym, bool isEntryPoint) { try { Address addr = sym.Address; Procedure proc; if (program.Procedures.TryGetValue(addr, out proc)) return; // Already scanned. Do nothing. if (sym.NoDecompile || IsNoDecompiledProcedure(addr)) return; proc = EnsureProcedure(addr, sym.Name); if (sym.Signature != null) { var sser = program.CreateProcedureSerializer(); proc.Signature = sser.Deserialize(sym.Signature, proc.Frame); } else if (sym.Name != null) { var exp = program.Platform.SignatureFromName(sym.Name); if (exp != null) { proc.Name = exp.Name; proc.Signature = exp.Signature; proc.EnclosingType = exp.EnclosingType; } else { proc.Name = sym.Name; } } //if (sp.Characteristics != null) //{ // proc.Characteristics = sp.Characteristics; //} var pb = ScanProcedure(sym.Address, sym.Name, sym.ProcessorState); proc = pb as Procedure; if (isEntryPoint && proc != null) { program.CallGraph.AddEntryPoint(proc); } } catch (AddressCorrelatedException aex) { Error(aex.Address, aex.Message); } }
public override RelocationResults Relocate(Program program, Address addrLoad) { Relocator.Relocate(program); var entryPoints = new List<ImageSymbol>(); var symbols = new SortedList<Address, ImageSymbol>(); foreach (var sym in Symbols.Values.SelectMany(seg => seg)) { var imgSym = CreateImageSymbol(sym, Header64.e_type); if (imgSym != null) { symbols[imgSym.Address] = imgSym; } } var addrEntry = GetEntryPointAddress(addrLoad); if (addrEntry != null) { ImageSymbol entrySymbol; if (symbols.TryGetValue(addrEntry, out entrySymbol)) { entryPoints.Add(entrySymbol); } else { var ep = new ImageSymbol(addrEntry) { ProcessorState = Architecture.CreateProcessorState() }; entryPoints.Add(ep); } } return new RelocationResults(entryPoints, symbols); }
public override RelocationResults Relocate(Program program, Address addrLoad) { var relocations = imgU.Relocations; 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); segmentMap.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)); var sym = new ImageSymbol(Address.SegPtr(pklCs, pklIp)) { Type = SymbolType.Procedure, ProcessorState = state }; return new RelocationResults( new List<ImageSymbol> { sym }, new SortedList<Address, ImageSymbol> { { sym.Address, sym } }); }
public void Scanner_CallGraphTree() { program = new Program(); var addr = Address.SegPtr(0xC00, 0); var m = new X86Assembler(sc, new DefaultPlatform(sc, new X86ArchitectureReal()), addr, new List<ImageSymbol>()); m.i86(); m.Proc("main"); m.Call("baz"); m.Ret(); m.Endp("main"); m.Proc("foo"); m.Ret(); m.Endp("foo"); m.Proc("bar"); m.Ret(); m.Endp("bar"); m.Proc("baz"); m.Call("foo"); m.Call("bar"); m.Jmp("foo"); m.Endp("baz"); program = m.GetImage(); program.Platform = new FakePlatform(null, arch); Given_Project(); var scan = new Scanner( program, new ImportResolver(project, program, eventListener), sc); var sym = new ImageSymbol(addr); scan.EnqueueImageSymbol(sym, true); scan.ScanImage(); Assert.AreEqual(4, program.Procedures.Count); }
private void BuildX86RealTest(Action<X86Assembler> test) { var addr = Address.SegPtr(0x0C00, 0); var m = new X86Assembler(sc, new FakePlatform(null, new X86ArchitectureReal()), addr, new List<ImageSymbol>()); test(m); this.program = m.GetImage(); this.scan = this.CreateScanner(this.program); var sym = new ImageSymbol(addr); scan.EnqueueImageSymbol(sym, true); }
// Fix up the relocations. public override RelocationResults Relocate(Program program, Address addrLoad) { // Seed the scanner with the start location. var sym = new ImageSymbol(Address.SegPtr((ushort)(lzCs + addrLoad.Selector), lzIp)) { Type = SymbolType.Procedure, ProcessorState = arch.CreateProcessorState() }; var imageSymbols = new SortedList<Address, ImageSymbol> { { sym.Address, sym } }; List<ImageSymbol> entryPoints = new List<ImageSymbol>() { sym }; if (isLz91) { Relocate91(RawImage, addrLoad.Selector.Value, imgLoaded); } else { Relocate90(RawImage, addrLoad.Selector.Value, imgLoaded); } return new RelocationResults(entryPoints, imageSymbols); }
/* bin = args.bin bin_args = args.args print "vamos: %s %s" % (bin, bin_args) # --- load binary --- hunk_file = HunkReader.HunkReader() fobj = file(bin,"rb") result = hunk_file.read_file_obj(bin,fobj,None) if result != Hunk.RESULT_OK: print "Error loading '%s'" % (bin) sys.exit(1) # build segments ok = hunk_file.build_segments() if not ok: print "Error building segments for '%s'" % (bin) sys.exit(2) # make sure its a loadseg() if hunk_file.type != Hunk.TYPE_LOADSEG: print "File not loadSeg()able: '%s'" % (bin) sys.exit(3) # --- create memory layout --- print "setting up memory layout" layout = MemoryLayout.MemoryLayout(verbose=True) context = MachineContext.MachineContext(MusashiCPU(),layout) # place prog segments prog_base = 0x010000 prog_start = prog_base off = prog_base relocator = HunkRelocate.HunkRelocate(hunk_file) prog_data = relocator.relocate_one_block(prog_base, padding=8) prog_size = len(prog_data) prog_mem = MemoryBlock.MemoryBlock("prog", prog_base, prog_size) prog_mem.write_data(prog_base, prog_data) layout.add_range(prog_mem) print prog_mem # some segment info seg_sizes = relocator.get_sizes() seg_addrs = relocator.get_seq_addrs(prog_base, padding=8) for i in xrange(len(seg_sizes)): print " seg: @%06x +%06x" % (seg_addrs[i], seg_sizes[i]) # setup stack magic_end = 0xff0000 stack_base = 0x080000 stack_size = 0x001000 stack_end = stack_base + stack_size stack_mem = MemoryBlock.MemoryBlock("stack", stack_base, stack_size) stack_initial = stack_end - 4 stack_mem.w32(stack_initial, magic_end) layout.add_range(stack_mem) # setup argument arg_base = 0x1000 arg_text = " ".join(bin_args) arg_len = len(arg_text) arg_size = arg_len + 1 arg_mem = MemoryBlock.MemoryBlock("args", arg_base, arg_size) arg_mem.write_data(arg_base, arg_text) arg_mem.write_mem(0, arg_base + arg_len, 0) layout.add_range(arg_mem) print "args: %s (%d)" % (arg_text, arg_len) print arg_mem */ public override RelocationResults Relocate(Program program, Address addrLoad) { var sym = new ImageSymbol(addrLoad) { Type = SymbolType.Procedure, ProcessorState = arch.CreateProcessorState() }; var entries = new List<ImageSymbol> { //$TODO: what are the registers on entry? }; return new RelocationResults( new List<ImageSymbol> { sym }, new SortedList<Address, ImageSymbol> { { sym.Address, sym } }); }
public List<ImageSymbol> LoadEntryPoints(Dictionary<int, string> names) { var rdr = new LeImageReader(RawImage, this.lfaNew + this.offEntryTable); var entries = new List<ImageSymbol>(); for (;;) { var cEntries = rdr.ReadByte(); if (cEntries == 0) break; var segNum = rdr.ReadByte(); var seg = this.segments[segNum - 1]; for (int i = 0; i < cEntries; ++i) { var flags = rdr.ReadByte(); var offset = rdr.ReadUInt16(); string name; var addr = seg.Address + offset; var state = arch.CreateProcessorState(); ImageSymbol ep = new ImageSymbol(addr); if (names.TryGetValue(entries.Count, out name)) { ep.Name = name; } ep.Type = SymbolType.Procedure; ep.ProcessorState = state; imageSymbols[ep.Address] = ep; entries.Add(ep); } } return entries; }