mirror of
https://github.com/bitdefender/bddisasm.git
synced 2025-02-11 14:22:38 +00:00
157 lines
4.4 KiB
Python
157 lines
4.4 KiB
Python
#
|
|
# Copyright (c) 2020 Bitdefender
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
import os
|
|
import sys
|
|
|
|
from pybddisasm.bddisasm import *
|
|
|
|
try:
|
|
from termcolor import colored
|
|
except:
|
|
colored = None
|
|
|
|
|
|
_SPACES = [
|
|
'',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
' ',
|
|
]
|
|
|
|
|
|
def print_internal(string, foreground=None, highlight=True):
|
|
no_colors = (foreground is None) or (not highlight)
|
|
|
|
if not colored or no_colors:
|
|
sys.stdout.write(string)
|
|
else:
|
|
text = colored(string, foreground)
|
|
sys.stdout.write(text)
|
|
|
|
|
|
def print_instruction(instruction, rip, highlight=False, ext_info=False):
|
|
k = 0
|
|
|
|
print_internal('%016x ' % rip)
|
|
|
|
# prefixes
|
|
for ibyte in range(0, instruction.PrefLength):
|
|
print_internal('%02x' % instruction.InstructionBytes[ibyte])
|
|
|
|
# opcodes
|
|
k += instruction.PrefLength
|
|
for ibyte in range(k, k + instruction.OpLength):
|
|
print_internal('%02x' % instruction.InstructionBytes[ibyte], 'green', highlight)
|
|
|
|
# modrm and sib
|
|
k += instruction.OpLength
|
|
for ibyte in range(k, k + instruction.HasModRm + instruction.HasSib):
|
|
print_internal('%02x' % instruction.InstructionBytes[ibyte], 'yellow', highlight)
|
|
|
|
# displacement
|
|
k += instruction.HasModRm + instruction.HasSib
|
|
for ibyte in range(k, k + instruction.DispLength):
|
|
print_internal('%02x' % instruction.InstructionBytes[ibyte], 'blue', highlight)
|
|
|
|
# relative offset/moffset/immediates
|
|
rest = instruction.Imm1Length + instruction.Imm2Length + instruction.RelOffsLength + \
|
|
instruction.MoffsetLength + instruction.HasSseImm + instruction.AddrLength
|
|
|
|
k += instruction.DispLength
|
|
for ibyte in range(k, k + rest):
|
|
print_internal('%02x' % instruction.InstructionBytes[ibyte], 'red', highlight)
|
|
|
|
# the rest of the bytes
|
|
k += rest
|
|
for ibyte in range(k, instruction.Length):
|
|
print_internal('%02x' % instruction.InstructionBytes[ibyte])
|
|
|
|
print_internal('%s' % _SPACES[16 - instruction.Length])
|
|
print_internal('%s' % instruction.Text)
|
|
|
|
if ext_info:
|
|
print_internal('\n')
|
|
print_internal('%r' % instruction)
|
|
|
|
print_internal('\n')
|
|
|
|
|
|
def disassemble_file(filepath, offset=0, size=0, rip=0, arch=64,
|
|
highlight=True, vendor='any', ext_info=False):
|
|
if not filepath:
|
|
return
|
|
|
|
with open(filepath, 'rb') as f:
|
|
total = 0
|
|
file_size = os.path.getsize(filepath)
|
|
|
|
if not size:
|
|
size = file_size
|
|
|
|
while offset < file_size and total < size:
|
|
to_read = file_size - offset
|
|
if to_read > 15:
|
|
to_read = 15
|
|
|
|
f.seek(offset, 0)
|
|
buff = f.read(to_read)
|
|
|
|
current_rip = rip + total
|
|
|
|
instr = nd_decode_ex2(buff, arch, arch, arch, vendor, current_rip)
|
|
if instr:
|
|
print_instruction(instr, current_rip, highlight, ext_info)
|
|
offset += instr['Length']
|
|
total += instr['Length']
|
|
else:
|
|
sys.stdout.write('%016x %02x %s db 0x%02x' % (current_rip, buff[0],
|
|
_SPACES[15], buff[0]))
|
|
|
|
if str.isalpha(chr(buff[0])):
|
|
sys.stdout.write(str(buff[0]))
|
|
|
|
sys.stdout.write('\n')
|
|
|
|
offset += 1
|
|
total += 1
|
|
|
|
|
|
def disassemble_hexstring(hexstring, offset=0, size=0, rip=0, arch=64,
|
|
highlight=True, vendor='any', ext_info=False):
|
|
if not hexstring:
|
|
return
|
|
|
|
buff = bytes.fromhex(''.join(hexstring))
|
|
|
|
total = 0
|
|
if not size:
|
|
size = len(buff)
|
|
|
|
while total < size:
|
|
current_rip = rip + total
|
|
|
|
instr = nd_decode_ex2(buff[total:total+16], arch, arch, arch, vendor, current_rip)
|
|
if instr:
|
|
print_instruction(instr, current_rip, highlight, ext_info)
|
|
offset += instr['Length']
|
|
total += instr['Length']
|
|
else:
|
|
sys.stdout.write('%016x %02x %s db 0x%02x\n' % (current_rip, buff[offset],
|
|
_SPACES[15], buff[offset]))
|
|
offset += 1
|
|
total += 1
|