public override Program LoadProgram(Address?addrLoad) { addrLoad ??= PreferredBaseAddress; this.segPsp = (ushort)(addrLoad.Selector !.Value - 0x10); var ss = (ushort)(ExeLoader.e_ss + addrLoad.Selector.Value); this.addrStackTop = Address.SegPtr(ss, ExeLoader.e_sp); int iImageStart = (ExeLoader.e_cparHeader * 0x10); int cbImageSize = ExeLoader.e_cpImage * ExeImageLoader.CbPageSize - iImageStart; // The +4 is room for a far return address at the top of the stack. int offsetStackTop = (int)(addrStackTop - addrLoad) + 4; int cbExtraBytes = ExeLoader.e_minalloc * 0x10; cbImageSize = Math.Max(cbImageSize + cbExtraBytes, offsetStackTop); byte[] bytes = new byte[cbImageSize]; int cbCopy = Math.Min(cbImageSize, RawImage.Length - iImageStart); Array.Copy(RawImage, iImageStart, bytes, 0, cbCopy); imgLoaded = new ByteMemoryArea(addrLoad, bytes); var addrPsp = Address.SegPtr(segPsp, 0); var psp = MakeProgramSegmentPrefix(addrPsp, segMemTop); this.segmentMap = new SegmentMap( addrPsp, psp); var program = new Program(segmentMap, arch, platform); this.Relocate(program, addrLoad); Address addrStart = Address.SegPtr((ushort)(ExeLoader.e_cs + addrLoad.Selector.Value), ExeLoader.e_ip); var ep = CreateEntryPointSymbol(addrLoad, addrStart, addrStackTop); program.EntryPoints[ep.Address] = ep; var sym = platform.FindMainProcedure(program, addrStart); if (sym is not null) { program.ImageSymbols[sym.Address] = sym; ep.NoDecompile = true; } try { LoadDebugSymbols(program.ImageSymbols, addrLoad); } catch (Exception ex) { var listener = Services.RequireService <DecompilerEventListener>(); listener.Error( new NullCodeLocation(ImageLocation.FilesystemPath), ex, "Detected debug symbols but failed to load them."); } return(program); }
public ImageSymbol CreateMainEntryPoint(bool isDll, Address addrEp, IPlatform platform) { var s = platform.FindMainProcedure(this.program, addrEp); if (s != null) { return(s); } string name = null; SerializedSignature ssig = null; Func <string, string, Argument_v1> Arg = (n, t) => new Argument_v1 { Name = n, Type = new TypeReference_v1 { TypeName = t } }; if (isDll) { name = "DllMain"; //$TODO: ensure users can override this name ssig = new SerializedSignature { Convention = "stdapi", Arguments = new Argument_v1[] { Arg("hModule", "HANDLE"), Arg("dwReason", "DWORD"), Arg("lpReserved", "LPVOID") }, ReturnValue = Arg(null, "BOOL") }; } else { name = "Win32CrtStartup"; ssig = new SerializedSignature { Convention = "__cdecl", ReturnValue = Arg(null, "DWORD") }; } return(new ImageSymbol(addrEp) { Name = name, ProcessorState = arch.CreateProcessorState(), Signature = ssig, Type = SymbolType.Procedure }); }
public override RelocationResults Relocate(Program program, Address addrLoad) { SegmentMap imageMap = segmentMap; EndianImageReader rdr = new LeImageReader(exe.RawImage, exe.e_lfaRelocations); var relocations = imgLoaded.Relocations; int i = exe.e_cRelocations; var segments = new Dictionary <Address, ushort>(); var linBase = addrLoad.ToLinear(); 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 + linBase, 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; } try { LoadDebugSymbols(results.Symbols, addrLoad); } catch (Exception ex) { var listener = Services.RequireService <DecompilerEventListener>(); listener.Error( new NullCodeLocation(Filename), ex, "Detected Borland debug symbols but failed to load them."); } return(results); }
public ImageSymbol CreateMainEntryPoint(bool isDll, Address addrEp, IPlatform platform) { var s = platform.FindMainProcedure(this.program, addrEp); if (s != null) return s; string name = null; SerializedSignature ssig = null; Func<string, string, Argument_v1> Arg = (n, t) => new Argument_v1 { Name = n, Type = new TypeReference_v1 { TypeName = t } }; if (isDll) { name = "DllMain"; //$TODO: ensure users can override this name ssig = new SerializedSignature { Convention = "stdapi", Arguments = new Argument_v1[] { Arg("hModule", "HANDLE"), Arg("dwReason", "DWORD"), Arg("lpReserved", "LPVOID") }, ReturnValue = Arg(null, "BOOL") }; } else { name = "Win32CrtStartup"; ssig = new SerializedSignature { Convention = "__cdecl", ReturnValue = Arg(null, "DWORD") }; } return new ImageSymbol(addrEp) { Name = name, ProcessorState = arch.CreateProcessorState(), Signature = ssig, Type = SymbolType.Procedure }; }