mirror of
https://github.com/bitdefender/bddisasm.git
synced 2024-11-28 10:28:18 +00:00
139 lines
5.2 KiB
Python
139 lines
5.2 KiB
Python
|
#
|
||
|
# Copyright (c) 2024 Bitdefender
|
||
|
# SPDX-License-Identifier: Apache-2.0
|
||
|
#
|
||
|
import re
|
||
|
|
||
|
from core import objects
|
||
|
|
||
|
|
||
|
class OutputParser(object):
|
||
|
def __init__(self, data: str):
|
||
|
self._data = data
|
||
|
self._output = list()
|
||
|
|
||
|
def read(self) -> list:
|
||
|
"""
|
||
|
Return a list containing the parsed output.
|
||
|
"""
|
||
|
return self._output
|
||
|
|
||
|
|
||
|
class OutputDecode(OutputParser):
|
||
|
def __init__(self, data: str):
|
||
|
OutputParser.__init__(self, data)
|
||
|
|
||
|
self.rd(self._data)
|
||
|
|
||
|
def rd(self, data) -> type(None):
|
||
|
"""
|
||
|
Used for decoder. Example:
|
||
|
0000000000000000 00d8 ADD al, bl
|
||
|
DSIZE: 32, ASIZE: 64, VLEN: -
|
||
|
ISA Set: I86, Ins cat: ARITH, CET tracked: no
|
||
|
FLAGS access
|
||
|
CF: m, PF: m, AF: m, ZF: m, SF: m, OF: m,
|
||
|
Valid modes
|
||
|
R0: yes, R1: yes, R2: yes, R3: yes
|
||
|
Real: yes, V8086: yes, Prot: yes, Compat: yes, Long: yes
|
||
|
SMM on: yes, SMM off: yes, SGX on: yes, SGX off: yes, TSX on: yes, TSX off: yes
|
||
|
VMXRoot: yes, VMXNonRoot: yes, VMXRoot SEAM: yes, VMXNonRoot SEAM: yes, VMX off: yes
|
||
|
Valid prefixes
|
||
|
REP: no, REPcc: no, LOCK: yes
|
||
|
HLE: yes, XACQUIRE only: no, XRELEASE only: no
|
||
|
BND: no, BHINT: no, DNT: no
|
||
|
Operand: 0, Acc: RW, Type: Register, Size: 1, RawSize: 1, Encoding: M, RegType: General Purpose, RegSize: 1, RegId: 0, RegCount: 1
|
||
|
Operand: 1, Acc: R-, Type: Register, Size: 1, RawSize: 1, Encoding: R, RegType: General Purpose, RegSize: 1, RegId: 3, RegCount: 1
|
||
|
Operand: 2, Acc: -W, Type: Register, Size: 4, RawSize: 4, Encoding: S, RegType: Flags, RegSize: 4, RegId: 0, RegCount: 1
|
||
|
|
||
|
Reads the given text and parses it to obtain dictionaries.
|
||
|
"""
|
||
|
output = list()
|
||
|
ostr = list()
|
||
|
local = ""
|
||
|
for line in data.split("\n"):
|
||
|
if re.search("^[0-9A-F]{16}", line):
|
||
|
if local:
|
||
|
local = local.replace("\r", "")
|
||
|
ostr.append(local)
|
||
|
local = ""
|
||
|
local += line
|
||
|
local += "\n"
|
||
|
|
||
|
ostr.append(local)
|
||
|
|
||
|
for elem in ostr:
|
||
|
if not elem:
|
||
|
break
|
||
|
instr = objects.DecodeInstrux(elem)
|
||
|
output.append(instr)
|
||
|
|
||
|
self._output.append(output)
|
||
|
|
||
|
|
||
|
class OutputShemu(OutputParser):
|
||
|
def __init__(self, data: str):
|
||
|
OutputParser.__init__(self, data)
|
||
|
|
||
|
self.rd(self._data)
|
||
|
self.rdem(self._data)
|
||
|
|
||
|
def rd(self, data) -> type(None):
|
||
|
"""
|
||
|
Used for shemu instructions. Example:
|
||
|
IP: 0x000000000020005f 90 NOP
|
||
|
RAX = 0x0000000000000000 RCX = 0x0000000000000000 RDX = 0x0000000000000000 RBX = 0x0000000000000000
|
||
|
RSP = 0x00000000001fe000 RBP = 0x0000000000000000 RSI = 0x0000000000000000 RDI = 0x0000000000000000
|
||
|
R8 = 0x0000000000000000 R9 = 0x0000000000000000 R10 = 0x0000000000000000 R11 = 0x0000000000000000
|
||
|
R12 = 0x0000000000000000 R13 = 0x0000000000000000 R14 = 0x0000000000000000 R15 = 0x0000000000000000
|
||
|
R16 = 0x0000000000000000 R17 = 0x0000000000000000 R18 = 0x0000000000000000 R19 = 0x0000000000000000
|
||
|
R20 = 0x0000000000000000 R21 = 0x0000000000000000 R22 = 0x0000000000000000 R23 = 0x0000000000000000
|
||
|
R24 = 0x0000000000000000 R25 = 0x0000000000000000 R26 = 0x0000000000000000 R27 = 0x0000000000000000
|
||
|
R28 = 0x0000000000000000 R29 = 0x0000000000000000 R30 = 0x0000000000000000 R31 = 0x0000000000000000
|
||
|
RIP = 0x0000000000200060 RFLAGS = 0x0000000000000247 CF:1 PF:1 AF:0 ZF:1 SF:0 TF:0 IF:1 DF:0 OF
|
||
|
|
||
|
Reads the given text and parses it to obtain dictionaries.
|
||
|
"""
|
||
|
output = list()
|
||
|
ostr = list()
|
||
|
local = ""
|
||
|
for line in data.split("\n"):
|
||
|
if line.startswith("Emulation ") or "SHEMU" in line:
|
||
|
continue
|
||
|
if re.search("^PC:", line) or re.search("^IP:", line):
|
||
|
if local:
|
||
|
local = local.replace("\r", "")
|
||
|
ostr.append(local)
|
||
|
local = ""
|
||
|
local += line
|
||
|
local += "\n"
|
||
|
|
||
|
ostr.append(local)
|
||
|
|
||
|
for elem in ostr:
|
||
|
if not elem:
|
||
|
break
|
||
|
instr = objects.ShemuInstrux(elem)
|
||
|
output.append(instr)
|
||
|
|
||
|
self._output.append(output)
|
||
|
|
||
|
def rdem(self, data) -> type(None):
|
||
|
"""
|
||
|
Used for shemu result. Example:
|
||
|
Emulation terminated with status 0x0000000a, flags: 0x1000000, 1 NOPs, 0 NULLs, 62 total instructions, 61 unique instructions
|
||
|
SHEMU_FLAG_OBFUS_NEUTRAL_IMM
|
||
|
|
||
|
Reads the given text and parse it to obtain dictionaries.
|
||
|
"""
|
||
|
ems = ""
|
||
|
for line in data.split("\n"):
|
||
|
if line.startswith("Emulation ") or "SHEMU" in line:
|
||
|
line = line.replace("\r", "")
|
||
|
ems += "\n"
|
||
|
ems += line
|
||
|
|
||
|
em = objects.ShemuResult(ems)
|
||
|
|
||
|
self._output.append([em])
|