private V1Disassembler(SmxFile file, SmxCodeV1Section code, int proc_offset) { data_ = file.Header.Data; code_start_ = code.CodeStart; proc_offset_ = proc_offset; cursor_ = proc_offset; cursor_limit_ = code.Header.CodeSize; }
public static V1Instruction[] TryDisassemble(SmxFile file, SmxCodeV1Section code, int proc_offset) { try { return(Disassemble(file, code, proc_offset)); } catch { return(null); } }
public SmxFile(BinaryReader br) { Header = FileHeader.From(br); // Parse precursor sections. foreach (var section in Header.Sections) { if (section.Name == ".names") { Names = new SmxNameTable(Header, section); } else if (section.Name == ".dbg.strings") { DebugNames = new SmxNameTable(Header, section); } else if (section.Name == ".dbg.info") { DebugInfo = new SmxDebugInfoSection(Header, section); } } CalledFunctions = new SmxCalledFunctionsTable(); // .dbg.names was removed when RTTI was added. if (DebugNames == null) { DebugNames = Names; } // Parse out other sections. var unknown = new List <SectionEntry>(); foreach (var section in Header.Sections) { try { switch (section.Name) { case ".names": case ".dbg.strings": case ".dbg.info": break; case ".natives": Natives = new SmxNativeTable(Header, section, Names); break; case ".publics": Publics = new SmxPublicTable(Header, section, Names); break; case ".pubvars": Pubvars = new SmxPubvarTable(Header, section, Names); break; case ".tags": Tags = new SmxTagTable(Header, section, Names); break; case ".data": Data = new SmxDataSection(Header, section); break; case ".code": CodeV1 = new SmxCodeV1Section(Header, section); break; case ".dbg.files": DebugFiles = new SmxDebugFilesTable(Header, section, DebugNames); break; case ".dbg.lines": DebugLines = new SmxDebugLinesTable(Header, section); break; case ".dbg.natives": DebugNatives = new SmxDebugNativesTable(Header, section, DebugNames); break; case ".dbg.symbols": DebugSymbols = new SmxDebugSymbolsTable(Header, section, DebugInfo, DebugNames); break; case ".dbg.methods": DebugMethods = new SmxDebugMethods(Header, section, Names); break; case ".dbg.globals": DebugGlobals = new SmxDebugGlobals(Header, section, Names); break; case ".dbg.locals": DebugLocals = new SmxDebugLocals(this, Header, section, Names); break; case "rtti.data": RttiData = new SmxRttiData(this, Header, section); break; case "rtti.classdefs": RttiClassDefs = new SmxRttiClassDefTable(Header, section, Names); break; case "rtti.fields": RttiFields = new SmxRttiFieldTable(Header, section, Names); break; case "rtti.methods": RttiMethods = new SmxRttiMethodTable(Header, section, Names); break; case "rtti.natives": RttiNatives = new SmxRttiNativeTable(Header, section, Names); break; case "rtti.enums": RttiEnums = new SmxRttiEnumTable(Header, section, Names); break; case "rtti.typedefs": RttiTypedefs = new SmxRttiTypedefTable(Header, section, Names); break; case "rtti.typesets": RttiTypesets = new SmxRttiTypesetTable(Header, section, Names); break; default: unknown.Add(section); break; } } catch { // Set a breakpoint here to see why the section failed to be parsed. unknown.Add(section); } } UnknownSections = unknown.ToArray(); // Disassemble all functions right away to find all called functions. if (DebugSymbols != null) { foreach (var entry in DebugSymbols.Entries) { if (entry.Ident != SymKind.Function) { continue; } V1Disassembler.TryDisassemble(this, CodeV1, entry.Address); } } if (Publics != null) { foreach (var pubfun in Publics.Entries) { V1Disassembler.TryDisassemble(this, CodeV1, (int)pubfun.Address); } } if (CalledFunctions != null) { foreach (var fun in CalledFunctions.Entries) { V1Disassembler.TryDisassemble(this, CodeV1, (int)fun.Address); } } }
public static V1Instruction[] Disassemble(SmxFile file, SmxCodeV1Section code, int proc_offset) { var disassembler = new V1Disassembler(file, code, proc_offset); return(disassembler.disassemble()); }
public static V1Instruction[] Disassemble(SmxFile file, SmxCodeV1Section code, int proc_offset) { var disassembler = new V1Disassembler(file, code, proc_offset); return disassembler.disassemble(); }
private void renderCodeSection(TreeNode root, SmxCodeV1Section code) { root.Tag = new NodeData(delegate() { renderSectionHeaderDetail(code.SectionHeader); addDetailLine("codesize = {0} bytes", code.Header.CodeSize); addDetailLine("cellsize = {0} bytes", code.Header.CellSize); addDetailLine("codeversion = 0x{0:x}", code.Header.CodeVersion); addDetailLine("flags = 0x{0:x} ; {0}", code.Header.Flags, code.Header.Flags.ToString()); addDetailLine("main = 0x{0:x}", code.Header.main); addDetailLine("codeoffs = 0x{0:x}", code.Header.codeoffs); endDetailUpdate(); }, code); root.Nodes.Add("cell view").Tag = new NodeData(delegate() { renderHexView(code.Reader(), (int)code.Header.CodeSize); }, null); var functionMap = new Dictionary<string, uint>(); if (file_.Publics != null) { foreach (var pubfun in file_.Publics.Entries) { functionMap[pubfun.Name] = pubfun.Address; } } if (file_.DebugSymbols != null) { foreach (var sym in file_.DebugSymbols.Entries) { if (sym.Ident != SymKind.Function) continue; functionMap[sym.Name] = sym.CodeStart; } } foreach (var pair in functionMap) { var name = pair.Key; var address = functionMap[pair.Key]; root.Nodes.Add(pair.Key).Tag = new NodeData(delegate() { renderCodeView(code, name, (int)address); }, null); } }
private void renderCodeView(SmxCodeV1Section code, string name, int address) { startDetailUpdate(); V1Instruction[] insns; try { insns = V1Disassembler.Disassemble(file_, code, address); } catch (Exception e) { addDetailLine("Could not disassemble method {0}: {1}", name, e.Message); endDetailUpdate(); return; } addDetailLine("; {0}", name); addDetailLine("; {0} instruction(s)", insns.Length); addDetailLine("; starts at code address 0x{0:x}", address); addDetailLine("---"); if (insns.Length == 0) { endDetailUpdate(); return; } // Find the largest address so we can get consistent column length. int last_address = insns[insns.Length - 1].Address; var ndigits = string.Format("{0:x}", last_address).Length; var addrfmt = "0x{0:x" + ndigits + "}: "; var buffer = new StringBuilder(); var comment = new StringBuilder(); foreach (var insn in insns) { buffer.Clear(); comment.Clear(); buffer.Append(insn.Info.Name); for (var i = 0; i < insn.Params.Length; i++) { if (i >= insn.Info.Params.Length) break; var kind = insn.Info.Params[i]; var value = insn.Params[i]; switch (kind) { case V1Param.Constant: case V1Param.CaseTable: buffer.Append(string.Format(" 0x{0:x}", value)); comment.Append(string.Format(" {0}", value)); break; case V1Param.Native: buffer.Append(string.Format(" {0}", value)); if (file_.Natives != null && value < file_.Natives.Length) comment.Append(string.Format(" {0}", file_.Natives[value].Name)); break; case V1Param.Jump: int delta = value - insn.Address; buffer.Append(string.Format(" 0x{0:x}", value)); if (delta >= 0) comment.Append(string.Format(" +0x{0:x}", delta)); else comment.Append(string.Format(" -0x{0:x}", -delta)); break; case V1Param.Address: { DebugSymbolEntry sym = null; if (file_.DebugSymbols != null) sym = file_.DebugSymbols.FindDataRef(value); buffer.Append(string.Format(" 0x{0:x}", value)); if (sym != null) comment.Append(string.Format(" {0}", sym.Name)); else comment.Append(string.Format(" {0}", value)); break; } case V1Param.Stack: { DebugSymbolEntry sym = null; if (file_.DebugSymbols != null) sym = file_.DebugSymbols.FindStackRef(insn.Address, value); buffer.Append(string.Format(" 0x{0:x}", value)); if (sym != null) comment.Append(string.Format(" {0}", sym.Name)); else comment.Append(string.Format(" {0}", value)); break; } case V1Param.Function: string fun = file_.FindFunctionName(value); buffer.Append(string.Format(" 0x{0:x}", value)); comment.Append(string.Format(" {0}", fun)); break; } } detail_buffer_.Append(string.Format(addrfmt, insn.Address)); detail_buffer_.Append(string.Format("{0,-32}", buffer)); if (comment.Length > 0) { detail_buffer_.Append(string.Format(" ;{1}", buffer, comment)); } detail_buffer_.Append("\r\n"); } endDetailUpdate(); }
public SmxFile(BinaryReader br) { Header = FileHeader.From(br); // Parse precursor sections. foreach (var section in Header.Sections) { if (section.Name == ".names") { Names = new SmxNameTable(Header, section); } else if (section.Name == ".dbg.strings") { DebugNames = new SmxNameTable(Header, section); } else if (section.Name == ".dbg.info") { DebugInfo = new SmxDebugInfoSection(Header, section); } } // Parse out other sections. var unknown = new List <SectionEntry>(); foreach (var section in Header.Sections) { switch (section.Name) { case ".names": case ".dbg.strings": case ".dbg.info": break; case ".natives": Natives = new SmxNativeTable(Header, section, Names); break; case ".publics": Publics = new SmxPublicTable(Header, section, Names); break; case ".pubvars": Pubvars = new SmxPubvarTable(Header, section, Names); break; case ".tags": Tags = new SmxTagTable(Header, section, Names); break; case ".data": Data = new SmxDataSection(Header, section); break; case ".code": CodeV1 = new SmxCodeV1Section(Header, section); break; case ".dbg.files": DebugFiles = new SmxDebugFilesTable(Header, section, DebugNames); break; case ".dbg.lines": DebugLines = new SmxDebugLinesTable(Header, section); break; case ".dbg.natives": DebugNatives = new SmxDebugNativesTable(Header, section, DebugNames); break; case ".dbg.symbols": DebugSymbols = new SmxDebugSymbolsTable(Header, section, DebugInfo, DebugNames); break; default: unknown.Add(section); break; } } UnknownSections = unknown.ToArray(); }
public SmxFile(BinaryReader br) { Header = FileHeader.From(br); // Parse precursor sections. foreach (var section in Header.Sections) { if (section.Name == ".names") Names = new SmxNameTable(Header, section); else if (section.Name == ".dbg.strings") DebugNames = new SmxNameTable(Header, section); else if (section.Name == ".dbg.info") DebugInfo = new SmxDebugInfoSection(Header, section); } // Parse out other sections. var unknown = new List<SectionEntry>(); foreach (var section in Header.Sections) { switch (section.Name) { case ".names": case ".dbg.strings": case ".dbg.info": break; case ".natives": Natives = new SmxNativeTable(Header, section, Names); break; case ".publics": Publics = new SmxPublicTable(Header, section, Names); break; case ".pubvars": Pubvars = new SmxPubvarTable(Header, section, Names); break; case ".tags": Tags = new SmxTagTable(Header, section, Names); break; case ".data": Data = new SmxDataSection(Header, section); break; case ".code": CodeV1 = new SmxCodeV1Section(Header, section); break; case ".dbg.files": DebugFiles = new SmxDebugFilesTable(Header, section, DebugNames); break; case ".dbg.lines": DebugLines = new SmxDebugLinesTable(Header, section); break; case ".dbg.natives": DebugNatives = new SmxDebugNativesTable(Header, section, DebugNames); break; case ".dbg.symbols": DebugSymbols = new SmxDebugSymbolsTable(Header, section, DebugInfo, DebugNames); break; default: unknown.Add(section); break; } } UnknownSections = unknown.ToArray(); }