Files
icicle-emu-icicle-python/tests/example.py
T
2025-10-23 11:42:32 +02:00

98 lines
2.9 KiB
Python

import icicle
import keystone
import capstone
def assemble(code: str, addr: int = 0) -> bytes:
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:
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()