Created
March 1, 2020 14:02
-
-
Save 0xAcid/b8d1c27776a6c9bf8b8af699e27e5441 to your computer and use it in GitHub Desktop.
IDA + QBI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pyqbdi | |
import ctypes | |
MAPPING_DIFF = 0 | |
def get_binary_mapping(lib, region): | |
mapped = region.range[0] # mapped to _init | |
binary = idaapi.get_segm_by_name(".init").start_ea | |
return mapped - binary | |
def insCB(vm, gpr, fpr, data): | |
inst = vm.getInstAnalysis() | |
binary_address = inst.address - MAPPING_DIFF | |
print("0x{:x}: {}".format(inst.address, inst.disassembly)) | |
print("coloring 0x{:x}".format(binary_address)) | |
idaapi.set_item_color(binary_address, 0xCFFFFF) | |
return pyqbdi.CONTINUE | |
if __name__ == "__main__": | |
# Chargement de la bibliothèque | |
target_path = ida_nalt.get_input_file_path() | |
target_name = ida_nalt.get_root_filename() | |
lib = ctypes.cdll.LoadLibrary(target_path) | |
# Mise en relation de l'espace mémoire avec la vue IDAPro | |
mapped_regions = pyqbdi.getCurrentProcessMaps() | |
bin_region = next(filter(lambda x: x.name == target_name and \ | |
x.permission & pyqbdi.PF_EXEC, mapped_regions)) | |
MAPPING_DIFF = get_binary_mapping(lib, bin_region) | |
# On récupère l'adresse de la fonction que l'on souhaite exécuter | |
func_addr = idaapi.get_screen_ea() + MAPPING_DIFF | |
print(hex(MAPPING_DIFF), hex(func_addr)) | |
# On crée la VM QBDI | |
vm = pyqbdi.VM() | |
vm.addInstrumentedModuleFromAddr(func_addr) | |
# On crée une stack pour le programme | |
state = vm.getGPRState() | |
stack = pyqbdi.allocateVirtualStack(state, 0x10000) | |
# On ajoute le callback qui permet de colorer les adresses | |
vm.addCodeCB(pyqbdi.PREINST, insCB, None) | |
# On initialise le contexte. On cible les fonctions sin/cos/tan, l'argument | |
# est un flottant et est donc passé dans xmm0. | |
# Cast double arg to long and set FPR | |
arg = 1.0 | |
carg = struct.pack('<d', arg) | |
fpr = vm.getFPRState() | |
fpr.xmm0 = carg | |
# on exécute la fonction | |
pyqbdi.simulateCall(state, 0x42424242) | |
success = vm.run(func_addr, 0x42424242) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment