gaulthiergain-tools/srcs/binarytool/scripts/uk_sharing_class.py
Gaulthier Gain 4039686867 Main update
2022-09-09 11:43:03 +02:00

186 lines
No EOL
5.8 KiB
Python
Executable file

import re
import os
import hashlib
from collections import defaultdict
from binascii import hexlify
DIFF_FOLDER="diff" + os.sep
PAGE_FOLDER="pages" + os.sep
PAGE_VMA_FOLDER="pages_vma" + os.sep
DBG_EXTENSION = ".dbg"
PAGE_SIZE = 4096
SIZE = "size"
ALIGN = "_local_align"
ASLR_PLT = "_aslr_plt"
ASLR_DCE = "_aslr_dce"
ASLR_DEFAULT = "_aslr_default"
class Unikernel:
def __init__(self, shortname, name):
self.shortname = self.filter_name(shortname)
self.name = name
self.type_unikernel = self.process_name(shortname)
self.segments = list()
self.sections = list()
self.byte_array = None
self.map_addr_section = dict()
self.map_symbols = defaultdict(list)
self.dump = None
def filter_name(self, name):
return name.strip(DBG_EXTENSION)
def process_name(self, shortname):
if ALIGN in shortname:
return ALIGN
elif SIZE in shortname:
return SIZE
elif ASLR_PLT in shortname:
return ASLR_PLT
elif ASLR_DEFAULT in shortname:
return ASLR_DEFAULT
elif ASLR_DCE in shortname:
return ASLR_DCE
else:
return ""
class Segment:
def __init__(self, address, offset, size):
self.address = address
self.offset = offset
self.size = size
class Section:
def __init__(self, name, start, offset, size, alignment):
self.name = name
self.start = start
self.start_align = self.round_mult()
self.offset = offset
self.size = size
self.alignment = alignment
self.end = start+size
self.pages = list()
self.data = None
def round_mult(self, base=PAGE_SIZE):
if self.start % PAGE_SIZE != 0:
return base * round(self.start / base)
return self.start
class Symbol:
def __init__(self, address, name, info):
self.address = address
self.name = name
self.info = info
class Page:
def __init__(self, name, number, start, size, uk_name, sect_name, content):
self.name = name
self.number = number
self.start = start
self.size = size
self.end = self.start+self.size
self.uk_name = uk_name
self.sect_name = sect_name
self.content = self.process_content(content)
self.instructions = list()
self.instructions_string = ""
self.others = defaultdict(list)
self.zeroes = self.count_zeroes()
self.hash = hashlib.sha256(self.content).hexdigest()
def warning_symbol(self, map_symbols, addr):
if len(map_symbols[addr]) > 1:
#print("[WARNING] several symbols for {:02x}".format(addr))
for t in map_symbols[addr]:
#print("\t-{} {} 0x{:02x}".format(t.name, t.info, t.address))
if t.name not in self.others[t.address]:
self.others[t.address].append(t.name)
return " + " + str(len(map_symbols[addr])) + "others "
return ""
def disassemble_bytes(self):
str_ascii = ""
for i, b in enumerate(self.content):
if i == 0:
self.instructions_string +="0x{:02x}".format(self.start) + ": "
if i > 0 and i % 4 == 0:
self.instructions_string += " "
if i > 0 and i % 16 == 0:
self.instructions_string += str_ascii
self.instructions_string += "\n" + "0x{:02x}".format(self.start + i) + ": "
str_ascii = ""
fb = "{:02x}".format(b)
self.instructions_string += fb
if int(fb, 16) > 20 and int(fb, 16) < 126:
ascii_str = "%s" % bytearray.fromhex(fb).decode()
else:
ascii_str = "."
str_ascii += ascii_str
def instructions_to_string(self, map_symbols):
for ins in self.instructions:
function_call = ""
# FUNCTION NAME
if ins.address in map_symbols:
ret = self.warning_symbol(map_symbols, ins.address)
self.instructions_string += "\n[== " + map_symbols[ins.address][0].name + ret + " ==]\n"
#FUNCTION CALL
regex = r"0x[a-f0-9]*"
matches = re.finditer(regex, ins.op_str)
for _, z in enumerate(matches, start=1):
addr = int(z.group(),16)
if addr in map_symbols:
ret = self.warning_symbol(map_symbols, addr)
function_call = "(" + map_symbols[addr][0].name + ret + ")"
self.instructions_string += "{: <32} 0x{:02x} {: <10} {: <10}{}\n".format(ins.bytes, ins.address, ins.mnemonic, ins.op_str, function_call)
for k,values in self.others.items():
self.instructions_string += "\n0x{:02x}: [".format(k)
for v in values:
self.instructions_string += "" + v + ","
self.instructions_string +=("]")
def process_content(self, content):
# ALIGN if necessary
if len(content) % PAGE_SIZE != 0:
byte_array = bytearray([0] * PAGE_SIZE)
byte_array[0:len(content)] = content
return byte_array
return content
def count_zeroes(self):
zeroes = 0
for c in self.content:
if c == 0:
zeroes += 1
return zeroes
class Instruction:
def __init__(self, address, mnemonic, op_str, _bytes):
self.address = address
self.mnemonic = mnemonic
self.op_str = op_str
self.bytes = self.cut(hexlify(_bytes).decode())
def cut(self, line, n=2):
return ' '.join([line[i:i+n] for i in range(0, len(line), n)])
class Dump:
def __init__(self, shortname, name, content):
self.shortname = shortname
self.name = name
self.content = content
self.pages = list()