return InitBufferedDisasm(target);
}
}
+
+ public class Disassembler : IDisposable
+ {
+ private readonly IntPtr _disasm;
+
+ private readonly byte[] _image;
+
+ private readonly Machine _machine;
+
+ public Disassembler(byte[] image, Machine machine)
+ {
+ _disasm = CoreDisTools.GetDisasm(machine);
+ _image = image;
+ _machine = machine;
+ }
+
+ public void Dispose()
+ {
+ if (_disasm != IntPtr.Zero)
+ {
+ CoreDisTools.FinishDisasm(_disasm);
+ }
+ }
+
+ public int GetInstruction(RuntimeFunction rtf, int imageOffset, int rtfOffset, out string instruction)
+ {
+ int instrSize = CoreDisTools.GetInstruction(_disasm, rtf, imageOffset, rtfOffset, _image, out instruction);
+
+ switch (_machine)
+ {
+ case Machine.Amd64:
+ case Machine.IA64:
+ ProbeX64Quirks(rtf, imageOffset, rtfOffset, instrSize, ref instruction);
+ break;
+
+ case Machine.I386:
+ break;
+
+ case Machine.ArmThumb2:
+ case Machine.Thumb:
+ break;
+
+ case Machine.Arm64:
+ break;
+
+ default:
+ throw new NotImplementedException();
+ }
+
+ return instrSize;
+ }
+
+ const string RelIPTag = "[rip ";
+
+ private void ProbeX64Quirks(RuntimeFunction rtf, int imageOffset, int rtfOffset, int instrSize, ref string instruction)
+ {
+ int relip = instruction.IndexOf(RelIPTag);
+ if (relip >= 0 && instruction.Length >= relip + RelIPTag.Length + 3)
+ {
+ int start = relip;
+ relip += RelIPTag.Length;
+ char sign = instruction[relip];
+ if (sign == '+' || sign == '-' &&
+ instruction[relip + 1] == ' ' &&
+ Char.IsDigit(instruction[relip + 2]))
+ {
+ relip += 2;
+ int offset = 0;
+ do
+ {
+ offset = 10 * offset + (int)(instruction[relip] - '0');
+ }
+ while (++relip < instruction.Length && Char.IsDigit(instruction[relip]));
+ if (relip < instruction.Length && instruction[relip] == ']')
+ {
+ relip++;
+ if (sign == '-')
+ {
+ offset = -offset;
+ }
+ int target = rtf.StartAddress + rtfOffset + instrSize + offset;
+ instruction = instruction.Substring(0, start) + $@"[0x{target:x4}]" + instruction.Substring(relip);
+ }
+ }
+ }
+ }
+ }
}
internal bool _raw;
internal bool _header;
internal bool _disasm;
- internal IntPtr _disassembler;
+ internal Disassembler _disassembler;
internal bool _unwind;
internal bool _gc;
internal bool _sectionContents;
abstract internal void DumpAllMethods();
abstract internal void DumpMethod(R2RMethod method, XmlNode parentNode = null);
abstract internal void DumpRuntimeFunction(RuntimeFunction rtf, XmlNode parentNode = null);
- abstract internal unsafe void DumpDisasm(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image, XmlNode parentNode = null);
+ abstract internal void DumpDisasm(RuntimeFunction rtf, int imageOffset, XmlNode parentNode = null);
abstract internal void DumpBytes(int rva, uint size, XmlNode parentNode = null, string name = "Raw", bool convertToOffset = true);
abstract internal void DumpSectionContents(R2RSection section, XmlNode parentNode = null);
abstract internal XmlNode DumpQueryCount(string q, string title, int count);
private IReadOnlyList<int> _runtimeFunctions = Array.Empty<int>();
private IReadOnlyList<string> _sections = Array.Empty<string>();
private bool _diff;
- private IntPtr _disassembler;
private bool _unwind;
private bool _gc;
private bool _sectionContents;
return 0;
}
+ Disassembler disassembler = null;
+
try
{
if (_inputFilenames.Count == 0)
if (_disasm)
{
- _disassembler = CoreDisTools.GetDisasm(r2r.Machine);
+ disassembler = new Disassembler(r2r.Image, r2r.Machine);
}
if (_xml)
{
- _dumper = new XmlDumper(_ignoreSensitive, r2r, _writer, _raw, _header, _disasm, _disassembler, _unwind, _gc, _sectionContents);
+ _dumper = new XmlDumper(_ignoreSensitive, r2r, _writer, _raw, _header, _disasm, disassembler, _unwind, _gc, _sectionContents);
}
else
{
- _dumper = new TextDumper(r2r, _writer, _raw, _header, _disasm, _disassembler, _unwind, _gc, _sectionContents);
+ _dumper = new TextDumper(r2r, _writer, _raw, _header, _disasm, disassembler, _unwind, _gc, _sectionContents);
}
Dump(r2r);
-
- if (_disasm)
- {
- CoreDisTools.FinishDisasm(_disassembler);
- }
}
}
catch (Exception e)
}
finally
{
+ if (disassembler != null)
+ {
+ disassembler.Dispose();
+ }
// close output stream
_writer.Close();
}
{
class TextDumper : Dumper
{
- public TextDumper(R2RReader r2r, TextWriter writer, bool raw, bool header, bool disasm, IntPtr disassembler, bool unwind, bool gc, bool sectionContents)
+ public TextDumper(R2RReader r2r, TextWriter writer, bool raw, bool header, bool disasm, Disassembler disassembler, bool unwind, bool gc, bool sectionContents)
{
_r2r = r2r;
_writer = writer;
if (_disasm)
{
- DumpDisasm(_disassembler, rtf, _r2r.GetOffset(rtf.StartAddress), _r2r.Image);
+ DumpDisasm(rtf, _r2r.GetOffset(rtf.StartAddress));
}
if (_raw)
SkipLine();
}
- internal unsafe override void DumpDisasm(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image, XmlNode parentNode = null)
+ internal override void DumpDisasm(RuntimeFunction rtf, int imageOffset, XmlNode parentNode = null)
{
int rtfOffset = 0;
int codeOffset = rtf.CodeOffset;
while (rtfOffset < rtf.Size)
{
string instr;
- int instrSize = CoreDisTools.GetInstruction(Disasm, rtf, imageOffset, rtfOffset, image, out instr);
+ int instrSize = _disassembler.GetInstruction(rtf, imageOffset, rtfOffset, out instr);
_writer.Write(instr);
if (rtf.Method.GcInfo != null && rtf.Method.GcInfo.Transitions.ContainsKey(codeOffset))
private bool _ignoreSensitive;
private XmlAttributeOverrides _ignoredProperties;
- public XmlDumper(bool ignoreSensitive, R2RReader r2r, TextWriter writer, bool raw, bool header, bool disasm, IntPtr disassembler, bool unwind, bool gc, bool sectionContents)
+ public XmlDumper(bool ignoreSensitive, R2RReader r2r, TextWriter writer, bool raw, bool header, bool disasm, Disassembler disassembler, bool unwind, bool gc, bool sectionContents)
{
_ignoreSensitive = ignoreSensitive;
_r2r = r2r;
if (_disasm)
{
- DumpDisasm(_disassembler, rtf, _r2r.GetOffset(rtf.StartAddress), _r2r.Image, rtfNode);
+ DumpDisasm(rtf, _r2r.GetOffset(rtf.StartAddress), rtfNode);
}
if (_raw)
}
}
- internal unsafe override void DumpDisasm(IntPtr Disasm, RuntimeFunction rtf, int imageOffset, byte[] image, XmlNode parentNode)
+ internal override void DumpDisasm(RuntimeFunction rtf, int imageOffset, XmlNode parentNode)
{
int rtfOffset = 0;
int codeOffset = rtf.CodeOffset;
while (rtfOffset < rtf.Size)
{
string instr;
- int instrSize = CoreDisTools.GetInstruction(Disasm, rtf, imageOffset, rtfOffset, image, out instr);
+ int instrSize = _disassembler.GetInstruction(rtf, imageOffset, rtfOffset, out instr);
AddXMLNode("offset"+codeOffset, instr, parentNode, $"{codeOffset}");
if (transitions.ContainsKey(codeOffset))