Files
dobin-avred/model/model_code.py
T
2023-06-22 22:38:58 +02:00

135 lines
3.9 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from typing import List, Set, Dict, Tuple, Optional
from intervaltree import Interval, IntervalTree
from enum import Enum
import logging
@dataclass
class Section:
name: str
addr: int
size: int
virtaddr: int
scan: bool = True
class SectionsBag:
def __init__(self):
self.sections: List[Section] = []
self.sectionsIntervalTree = IntervalTree()
def addSection(self, section: Section):
self.sections.append(section)
interval: Interval = Interval(section.addr, section.addr + section.size, section)
self.sectionsIntervalTree.add(interval)
def removeSectionByName(self, sectionName: str):
new = []
for section in self.sections:
if section.name != sectionName:
new.append(section)
self.sections = new
def getSectionByName(self, sectionName: str) -> Section:
return next((sec for sec in self.sections if sectionName in sec.name ), None)
def getSectionByAddr(self, address: int) -> Section:
for section in self.sections:
if address >= section.addr and address <= section.addr + section.size:
return section
return None
def getSectionNameByAddr(self, address: int) -> Section:
for section in self.sections:
if address >= section.addr and address <= section.addr + section.size:
return section.name
return "<unknown>"
def getSectionsForRange(self, start: int, end: int) -> List[Section]:
res = self.sectionsIntervalTree.overlap(start, end)
res = [r[2] for r in res]
return res
def printSections(self):
for section in self.sections:
print(f"Section {section.name}\t addr: {hex(section.addr)} size: {section.size} ")
gpRegisters = [
'eax','ebx','ecx','edx','esi','edi', # make sure we also check 32 bit
'ebp', 'esp',
'al','bl','cl','dl', # and these.. argh
'ah','bh','ch','dh', # and these.. argh
'rax','rbx','rcx','rdx','rsi','rdi',
'r8','r9','r10','r11','r12','r13','r14','r15'
'rbp', 'rsp',
]
class AsmInstruction():
def __init__(self, fileOffset, rva, esil, type, disasm, size, rawBytes):
self.offset = fileOffset # offset in file
self.rva = rva
self.esil = esil
self.type = type
self.disasm = disasm
self.size = size
self.rawBytes = rawBytes
# ESIL
self.esilComponents = esil.split(",") if esil else []
# Registers touched
self.esilTouchedRegisters = []
for a in self.esilComponents:
if a in gpRegisters:
self.esilTouchedRegisters.append(a)
def registersTouch(self, asmInstruction: AsmInstruction):
return any(element in self.esilTouchedRegisters for element in asmInstruction.esilTouchedRegisters)
def __str__(self):
s = "Offset: {} RVA: {} type: {} disasm: {} size: {} esil: {} bytes: {}".format(
self.offset,
self.rva,
self.type,
self.disasm,
self.size,
self.esil,
self.rawBytes
)
return s
class UiDisasmLine():
def __init__(self, fileOffset, rva, isPart, text, textHtml):
self.offset = fileOffset # offset in file
self.rva = rva # relative offset (usually created by external disasm tool)
self.isPart = isPart # is this part of the data, or supplemental?
self.text = text # the actual disassembled data
self.textHtml = textHtml # the actual disassembled data, colored
def __str__(self):
s = "Offset: {} RVA: {} isPart: {} Text: {}".format(
self.offset,
self.rva,
self.isPart,
self.text
)
return s
class SectionType(Enum):
UNKNOWN = 'u'
CODE = 'c'
DATA = 'd'