Module refinery.units.formats.office.xlm
Expand source code Browse git
from __future__ import annotations
from refinery.lib.excel.common import rc2ref
from refinery.lib.scripts.xlm import XlmEngine, XlmView
from refinery.lib.scripts.xlm.trace import visible_steps
from refinery.lib.types import Param
from refinery.units.formats import Arg, Unit
class xlm(Unit):
"""
Deobfuscates Excel v4.0 (XLM) macros from XLS, XLSM, and XLSB documents.
The program is emulated and every cell that contains a command or doesn't reduce to a value is
listed in the order it ran. The unit emits one chunk per cell whose data is the formula of the
cell and whose meta variables hold the cell address, its emulation method, call depth, and the
sheet name. A meta variable "severity" encodes the likely relevance of the cell data.
"""
@classmethod
def handles(cls, data) -> bool | None:
from refinery.lib.id import Fmt, get_microsoft_format, get_office_xml_type
if get_microsoft_format(data) == Fmt.XLS:
return True
if get_office_xml_type(data) == Fmt.XLSX:
return True
def __init__(
self,
filter: Param[int, Arg.Counts('-f', help=(
'Filter amount of details shown. Specify once to remove jump commands and twice to '
'restrict to the most relevant commands.'))] = 0,
cell: Param[str, Arg.String('-c', metavar='CELL', help=(
'Optionally start interpretation from a specific cell address.'))] = '',
day: Param[int, Arg.Number('-d', help=(
'The day of month the DAY command answers instead of searching the date it reads; '
'the default {default} leaves the day to that search.'))] = -1,
timeout: Param[int, Arg.Number('-t', help=(
'Stop emulation after N seconds; the default {default} means no limit.'))] = 0,
):
super().__init__(filter=filter, day=day, cell=cell, timeout=timeout)
def process(self, data: bytearray):
view = XlmView(data)
engine = XlmEngine(view, self.args.day, self.args.timeout)
for step in visible_steps(engine.run(self.args.cell), self.args.filter):
meta = {
'cell': rc2ref(step.row, step.col),
'depth': step.indent,
'severity': step.severity,
'sheet': step.sheet,
'status': step.status.name,
}
yield self.labelled(step.text.encode(self.codec), **meta)
Classes
class xlm (filter=0, cell='', day=-1, timeout=0)-
Deobfuscates Excel v4.0 (XLM) macros from XLS, XLSM, and XLSB documents.
The program is emulated and every cell that contains a command or doesn't reduce to a value is listed in the order it ran. The unit emits one chunk per cell whose data is the formula of the cell and whose meta variables hold the cell address, its emulation method, call depth, and the sheet name. A meta variable "severity" encodes the likely relevance of the cell data.
Expand source code Browse git
class xlm(Unit): """ Deobfuscates Excel v4.0 (XLM) macros from XLS, XLSM, and XLSB documents. The program is emulated and every cell that contains a command or doesn't reduce to a value is listed in the order it ran. The unit emits one chunk per cell whose data is the formula of the cell and whose meta variables hold the cell address, its emulation method, call depth, and the sheet name. A meta variable "severity" encodes the likely relevance of the cell data. """ @classmethod def handles(cls, data) -> bool | None: from refinery.lib.id import Fmt, get_microsoft_format, get_office_xml_type if get_microsoft_format(data) == Fmt.XLS: return True if get_office_xml_type(data) == Fmt.XLSX: return True def __init__( self, filter: Param[int, Arg.Counts('-f', help=( 'Filter amount of details shown. Specify once to remove jump commands and twice to ' 'restrict to the most relevant commands.'))] = 0, cell: Param[str, Arg.String('-c', metavar='CELL', help=( 'Optionally start interpretation from a specific cell address.'))] = '', day: Param[int, Arg.Number('-d', help=( 'The day of month the DAY command answers instead of searching the date it reads; ' 'the default {default} leaves the day to that search.'))] = -1, timeout: Param[int, Arg.Number('-t', help=( 'Stop emulation after N seconds; the default {default} means no limit.'))] = 0, ): super().__init__(filter=filter, day=day, cell=cell, timeout=timeout) def process(self, data: bytearray): view = XlmView(data) engine = XlmEngine(view, self.args.day, self.args.timeout) for step in visible_steps(engine.run(self.args.cell), self.args.filter): meta = { 'cell': rc2ref(step.row, step.col), 'depth': step.indent, 'severity': step.severity, 'sheet': step.sheet, 'status': step.status.name, } yield self.labelled(step.text.encode(self.codec), **meta)Ancestors
Subclasses
Class variables
var reverse-
The type of the None singleton.
Inherited members