mirror of
https://github.com/icicle-emu/icicle-python
synced 2026-06-21 13:53:41 +00:00
98 lines
2.9 KiB
Python
98 lines
2.9 KiB
Python
import icicle
|
|
|
|
def assemble(code: str, addr: int = 0) -> bytes:
|
|
import keystone
|
|
ks = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_64)
|
|
encoding, count = ks.asm(code, addr)
|
|
if encoding is None:
|
|
raise keystone.KsError("no encoding")
|
|
return bytes(encoding)
|
|
|
|
def disassemble(code: bytes, addr: int = 0, max_count = 1000) -> str:
|
|
import capstone
|
|
result = ""
|
|
cs = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64)
|
|
count = 0
|
|
while count < max_count:
|
|
count += 1
|
|
# TODO: fix on invalid instruction
|
|
for address, size, mnemonic, op_str in cs.disasm_lite(code, addr, 1):
|
|
if len(result) > 0:
|
|
result += "\n"
|
|
result += hex(address) + "|"
|
|
result += mnemonic
|
|
if op_str:
|
|
result += " "
|
|
result += op_str
|
|
code = code[size:]
|
|
if len(code) == 0:
|
|
return result
|
|
addr += size
|
|
return result
|
|
|
|
def test_old():
|
|
buf = assemble("mov eax, ebx\nnop")
|
|
print(disassemble(buf, 0))
|
|
print(assemble("mov eax, ebx").hex())
|
|
print("Hello world!")
|
|
print(dir(icicle))
|
|
print(icicle.MemoryProtection.ReadOnly)
|
|
print(f"Architectures: {icicle.architectures()}")
|
|
vm = icicle.Icicle("x86_64")
|
|
print(vm)
|
|
|
|
for name, (offset, size) in vm.reg_list().items():
|
|
value = vm.reg_read(name.lower())
|
|
print(f"{name}[{size}] @ {offset} = {value}")
|
|
|
|
addr = 0x10000
|
|
vm.mem_map(addr, 0x1000, icicle.MemoryProtection.NoAccess)
|
|
try:
|
|
vm.mem_protect(addr, 0x2000, icicle.MemoryProtection.ExecuteRead)
|
|
except icicle.MemoryException as x:
|
|
print("MemoryException working!")
|
|
message = x.args[0]
|
|
print(message, x.code)
|
|
except Exception as x:
|
|
print(x, type(x), isinstance(x, icicle.MemoryException))
|
|
vm.mem_protect(addr, 0x1000, icicle.MemoryProtection.ExecuteRead)
|
|
vm.mem_write(addr, b"\x90\x90\x90")
|
|
data = vm.mem_read(addr, 4)
|
|
print(data, type(data))
|
|
|
|
def test_new():
|
|
print("")
|
|
vm = icicle.Icicle("x86_64", jit=False)
|
|
print(vm)
|
|
|
|
addr = 0x10000
|
|
#vm.mem_map(0, 0x1000, icicle.MemoryProtection.ReadWrite)
|
|
vm.mem_map(addr, 0x1000, icicle.MemoryProtection.ExecuteRead)
|
|
code = assemble("""
|
|
mov eax, 42
|
|
mov qword ptr [rax], 0x5
|
|
nop
|
|
""", addr)
|
|
print("code:")
|
|
print(disassemble(code, addr))
|
|
vm.mem_write(addr, code)
|
|
data = vm.mem_read(addr, len(code))
|
|
assert data == code
|
|
|
|
vm.reg_write("rip", addr)
|
|
status = vm.run_until(addr + len(code))
|
|
print(status)
|
|
if status == icicle.RunStatus.UnhandledException:
|
|
print(f"code: {vm.exception_code}, value: {hex(vm.exception_value)}")
|
|
print(f"rip: {hex(vm.reg_read('rip'))} (OK)")
|
|
else:
|
|
print(f"rax: {hex(vm.reg_read('rax'))}")
|
|
assert False, "Should be unreachable"
|
|
|
|
def main():
|
|
test_old()
|
|
test_new()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|