def test_alloc_stack(emu: Emulator): emu.allocate_stack(0x1000) assert emu.sp in emu.mem.segments.stack emu.stack[0] = 0xDEAD assert emu.stack[0] == 0xDEAD
def get_emulator(arch, isa): emu = Emulator(arch) map_code_segment(emu, 'code', CODE_ADDRESS, isa) emu.mem.map(DATA_ADDRESS, DATA_SIZE, 'data', AccessType.RW) emu.mem.default_isa = isa emu.sp = STACK_ADDRESS emu.jump(CODE_ADDRESS, isa) return emu
def test_save_context(emu: Emulator): emu.regs.set(r0=1, r2=56, pc=0x1050) assert emu.regs.get('r0', 'r2', 'pc') == (1, 56, 0x1050) ctx = emu.save_context() emu.regs.set(r0=9, r2=80, pc=0x90) assert emu.regs.get('r0', 'r2', 'pc') == (9, 80, 0x90) emu.restore_context(ctx) assert emu.regs.get('r0', 'r2', 'pc') == (1, 56, 0x1050)
def test_copy(emu: Emulator): emu.mem.map(0x1000, 0x80) emu.mem.write_code(0x1000, 'NOP; NOP; NOP') emu.mem.write(0x1040, b'AAAA') emu.jump(0x1000) other = emu.copy() emu.mem.write(0x1040, b'BBBB') emu.run(3) assert emu.pc == 0x100C assert other.pc == 0x1000 assert other.mem.read(0x1040, 4) == b'AAAA'
def test_run_func_x86(): emu = Emulator(ARCH_X86) seg = emu.mem.allocate(0x20) emu.mem.write_code( seg.address, """ mov eax, [esp + 4] mov ecx, [esp + 8] add eax, ecx ret """) emu.allocate_stack() emu.stack.push(1) emu.stack.push(5) value = emu.run_function(seg.address) assert value == 6 assert emu.sp == emu.mem.segments.stack.end - 12 emu.reset_sp() emu.stack.push(8) emu.stack.push(-1) value = emu.run_function(seg.address) assert value == 7 assert emu.sp == emu.mem.segments.stack.end - 12
def test_emu_sec(sec_elf): with pytest.warns(MegastoneWarning) as records: emu = Emulator.from_execfile(sec_elf) assert len(records) == 1 assert '0x400000' in records[0].message.args[0] assert ' RX ' in records[0].message.args[0] assert emu.arch == ARCH_MIPS assert emu.pc == sec_elf.symbols['__start'] assert emu.get_curr_insn().mnemonic == 'add'
def test_from_file(arch, isa, nop): address = 0x3000 entry = isa.address_to_pointer(address + 0x10) data = nop * 30 file = FORMAT_BINARY.parse_bytes(data, arch=arch, base=address, entry=entry) emu = Emulator.from_execfile(file) assert isa.address_to_pointer(emu.pc) == entry assert emu.isa == isa assert emu.get_curr_insn().mnemonic == 'nop' assert emu.mem.read(address, len(data)) == data
from megastone import Emulator, ARCH_ARM emu = Emulator(ARCH_ARM) segment = emu.mem.allocate(0x1000, 'code') emu.mem.write_code( segment.address, """ MOV R0, 1 ADD R0, R0 ADD R0, R0 ADD R0, R0 """) emu.add_code_hook(lambda e: print(e.get_curr_insn(), e.regs.r0)) emu.run(count=4, address=segment.address)
from megastone import Emulator, ARCH_ARM64, HOOK_STOP_ONCE emu = Emulator(ARCH_ARM64) segment = emu.mem.allocate(0x1000, 'code') emu.mem.write_code( segment.address, """ start: MOV X0, 0 ADD X0, X0, 1 ADD X0, X0, 1 ADD X0, X0, 1 ADD X0, X0, 1 ADD X0, X0, 1 ADD X0, X0, 1 ADD X0, X0, 1 ADD X0, X0, 1 ADD X0, X0, 1 ADD X0, X0, 1 B start """) emu.add_breakpoint(segment.address + 0x8) emu.add_code_hook(HOOK_STOP_ONCE, segment.address + 0x10) emu.add_breakpoint(segment.address + 0x18) emu.add_code_hook(lambda e: print(e.get_curr_insn(), e.regs.x0)) emu.jump(segment.address) for _ in range(5): print(emu.run())
def test_emu(seg_elf): emu = Emulator.from_execfile(seg_elf) assert emu.arch == ARCH_MIPS assert emu.pc == seg_elf.symbols['__start'] assert emu.get_curr_insn().mnemonic == 'add'
def add_hooks(emu: Emulator, ptr, size): emu.add_read_hook(data_hook, ptr, size) emu.add_write_hook(data_hook, ptr, size)
def data_hook(emu: Emulator): print(emu.get_curr_insn(), hex(emu.curr_hook.address), emu.curr_access)
from megastone import Emulator, ARCH_ARM emu = Emulator(ARCH_ARM) code_seg = emu.mem.allocate(0x1000) data_seg = emu.mem.allocate(0x1000) data1 = data_seg.address data2 = data_seg.address + 1 data3 = data_seg.address + 2 data4 = data_seg.address + 4 data5 = data_seg.address + 8 emu.mem.write_code( code_seg.address, f""" LDR R0, ={data1} LDRB R1, [R0] STRB R1, [R0] LDR R0, ={data2} LDRB R1, [R0] STRB R1, [R0] LDR R0, ={data3} LDRH R1, [R0] STRH R1, [R0] LDR R0, ={data4} LDR R1, [R0] STR R1, [R0] LDR R0, ={data5}
def test_from_mem(): mem = BufferMemory(ARCH_ARM) mem.map(0x1000, 0x1000, 'seg') emu = Emulator.from_memory(mem) assert emu.mem.segments.seg.address == 0x1000
from megastone import Emulator, ARCH_X86, HOOK_STOP emu = Emulator(ARCH_X86) emu.allocate_stack(0x1000) start_seg = emu.mem.allocate(0x1000) func_seg = emu.mem.allocate(0x1000) emu.mem.write_code( start_seg.address, f""" push 1 push 2 call 0x{func_seg.address:X} {'nop;'*20} """) emu.mem.write_code(func_seg.address, f""" mov eax, 700 ret """) def func_hook(emu: Emulator): print(hex(emu.sp), emu.get_curr_insn() ) #since this opcode never runs, the trace func isn't called return emu.stack[1] + emu.stack[2] emu.replace_function(func_seg.address, func_hook) emu.add_code_hook(lambda e: print(hex(e.sp), e.get_curr_insn())) emu.add_code_hook(HOOK_STOP, start_seg.address + 0x10)
def trace_func(emu: ms.Emulator): try: print(emu.get_curr_insn()) except DisassemblyError: print('Invalid assembly')
def func_hook(emu: Emulator): print(hex(emu.sp), emu.get_curr_insn() ) #since this opcode never runs, the trace func isn't called return emu.stack[1] + emu.stack[2]
def emu(): return Emulator(ARCH_ARM)