Module refinery.units.sinks.dnasm

Expand source code Browse git
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re

from refinery.lib.dotnet.disassembler import Disassembler
from refinery.lib.dotnet.disassembler.factory import OutputFactory
from refinery.lib.meta import metavars
from refinery.units.formats.pe.dotnet.dnopc import DotnetDisassemblerUnit
from refinery.units.sinks import Arg


class dnasm(DotnetDisassemblerUnit):
    """
    Disassembles the input data as MSIL (.NET/C# bytecode) and produces a human-readable disassembly listing. If you are
    looking for a more programmatic disassembly, take a look at `refinery.dnopc`.
    """

    def __init__(
        self, *,
        count=None, until=None,
        no_il_refs: Arg.Switch('-I', help='Disable reference resolution to IL_*.') = False,
        no_address: Arg.Switch('-A', help='Disable address display.') = False,
        no_hexdump: Arg.Switch('-H', help='Disable opcodes hexdump.') = False,
        no_args: Arg.Switch('-O', help='Disable output of instruction arguments.') = False,
        description: Arg.Switch('-d', help='Enable opcodes descriptions in output.') = False,
    ):
        self._output_factory = OutputFactory(
            il_refs=not no_il_refs,
            address=not no_address,
            hexdump=not no_hexdump,
            arguments=not no_args,
        )
        self._disassembler = Disassembler()
        super().__init__(
            count=count,
            until=until,
            description=description,
        )

    def process(self, data):
        meta = metavars(data)
        r = re.compile(r't[0-9a-f]+', re.IGNORECASE)
        self._output_factory.extend_token_labels({int(k[1:], 16): v for k, v in meta.items() if r.match(k)})
        until = str(self.args.until or '').lower()

        max_line_length = 0
        if self.args.description:
            disasm = []
            for ins in self._disassembler.disasm(data, self.args.count):
                disasm.append(ins)
                line = self._output_factory.instruction(ins)
                max_line_length = max(max_line_length, len(line))
        else:
            disasm = self._disassembler.disasm(data, self.args.count)

        for ins in disasm:
            line = self._output_factory.instruction(ins)
            if self.args.description:
                line += ' ' * (max_line_length - len(line) + 2)
                line += f'-- {ins.op.description}'
            yield line.encode("utf-8")

            if until and until in line.lower():
                break

Classes

class dnasm (*, count=None, until=None, no_il_refs=False, no_address=False, no_hexdump=False, no_args=False, description=False)

Disassembles the input data as MSIL (.NET/C# bytecode) and produces a human-readable disassembly listing. If you are looking for a more programmatic disassembly, take a look at dnopc.

Expand source code Browse git
class dnasm(DotnetDisassemblerUnit):
    """
    Disassembles the input data as MSIL (.NET/C# bytecode) and produces a human-readable disassembly listing. If you are
    looking for a more programmatic disassembly, take a look at `refinery.dnopc`.
    """

    def __init__(
        self, *,
        count=None, until=None,
        no_il_refs: Arg.Switch('-I', help='Disable reference resolution to IL_*.') = False,
        no_address: Arg.Switch('-A', help='Disable address display.') = False,
        no_hexdump: Arg.Switch('-H', help='Disable opcodes hexdump.') = False,
        no_args: Arg.Switch('-O', help='Disable output of instruction arguments.') = False,
        description: Arg.Switch('-d', help='Enable opcodes descriptions in output.') = False,
    ):
        self._output_factory = OutputFactory(
            il_refs=not no_il_refs,
            address=not no_address,
            hexdump=not no_hexdump,
            arguments=not no_args,
        )
        self._disassembler = Disassembler()
        super().__init__(
            count=count,
            until=until,
            description=description,
        )

    def process(self, data):
        meta = metavars(data)
        r = re.compile(r't[0-9a-f]+', re.IGNORECASE)
        self._output_factory.extend_token_labels({int(k[1:], 16): v for k, v in meta.items() if r.match(k)})
        until = str(self.args.until or '').lower()

        max_line_length = 0
        if self.args.description:
            disasm = []
            for ins in self._disassembler.disasm(data, self.args.count):
                disasm.append(ins)
                line = self._output_factory.instruction(ins)
                max_line_length = max(max_line_length, len(line))
        else:
            disasm = self._disassembler.disasm(data, self.args.count)

        for ins in disasm:
            line = self._output_factory.instruction(ins)
            if self.args.description:
                line += ' ' * (max_line_length - len(line) + 2)
                line += f'-- {ins.op.description}'
            yield line.encode("utf-8")

            if until and until in line.lower():
                break

Ancestors

Class variables

var required_dependencies
var optional_dependencies

Inherited members