unicorn
unicorn copied to clipboard
UC_HOOK_MEM_READ only triggered once (x86 64 emulated on mac M1)
Hello,
Description
I'm facing a strange issue where my UC_HOOK_MEM_READ is only called the first time a memory read is encountered. All subsequent reads do not trigger the callback.
Setup
- Unicorn commit d4b92485
- Host: Mac M1 running macOS 14 (Sonoma)
- Emulated code: x86 64
Unicorn has been compiled as per recommendations in the documentation. Unicorn python bindings were installed in a fresh python venv.
Test case
from unicorn import *
from unicorn.x86_const import *
# mov rax, [0x10000]
# mov [0x10000], rax
code = b"\x48\xa1\x00\x00\x01\x00\x00\x00\x00\x00\x48\xa3\x00\x00\x01\x00\x00\x00\x00\x00"*10
# callback for tracing memory access (READ ony)
def hook_mem_access(uc, access, address, size, value, user_data):
if access == UC_MEM_READ:
print(f">>> Memory is being READ at {address:#x}, data size = {size}")
else:
print(f">>> Memory is being WRITE at {address:#x}, data size = {size}")
def test_x86_64_mem_read():
print("Emulate x86 64-bit code")
try:
mu = Uc(UC_ARCH_X86, UC_MODE_64)
mu.hook_add(UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, hook_mem_access)
mu.mem_map(0x10000, 1024*8)
mu.mem_write(0x10000, b"\xaa"*8)
# write machine code to be emulated to memory
mu.mem_map(0, 0x1000)
mu.mem_write(0, code)
# emulate machine code in infinite time
mu.emu_start(0, len(code))
except UcError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_x86_64_mem_read()
Test case output
Emulate x86 64-bit code
>>> Memory is being READ at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
>>> Memory is being WRITE at 0x10000, data size = 8
As can be seen above, hook_mem_access
is only called once for READ while it is expected to be called 10 times.
Strangely, this does not affect writes.
I meet the same problem on M2 pro. I test arm64 arch
Verified the read operations are inlined. Arm64 backend tends to inline read/write operations.
See: https://github.com/unicorn-engine/unicorn/wiki/FAQ#memory-hooks-are-skipped
1200003E0: F4 03 10 32 orr w20, wzr, #0x10000
1200003E4: 60 06 7E A9 ldp x0, x1, [x19, #-0x20]
1200003E8: 00 18 54 8A and x0, x0, x20, lsr #6
1200003EC: 21 00 00 8B add x1, x1, x0
1200003F0: 20 00 40 F9 ldr x0, [x1] # <--- Optimized as a single instruction, x1 = 0x100000
Same problem here, M2 :(
I'm emulating UC_ARCH_ARM/UC_CPU_ARM_CORTEX_M4 and on Mac M1 host, and I'm not seeing UC_MEM_READ events. Is there a way to overcome this limitation, e.g. recompile the lib with the TCG inlining disabled? I'm trying to emulate peripherals and things needs to take action on read events.
you may try this, not tested full functionalities , since I only need the address and value of reads. https://github.com/saicao/unicorn/commit/026f4c447e944cd855fd0d44fea52ac31bc3a372 @keroblabs
@saicao Would you like to submit a PR for that?
From: SAI @.> Sent: Friday, April 12, 2024 11:23:13 AM To: unicorn-engine/unicorn @.> Cc: lazymio @.>; Comment @.> Subject: Re: [unicorn-engine/unicorn] UC_HOOK_MEM_READ only triggered once (x86 64 emulated on mac M1) (Issue #1908)
you may try this, not tested full functionalities , since I only need the address and value of reads. @.***https://github.com/saicao/unicorn/commit/026f4c447e944cd855fd0d44fea52ac31bc3a372 @keroblabshttps://github.com/keroblabs
― Reply to this email directly, view it on GitHubhttps://github.com/unicorn-engine/unicorn/issues/1908#issuecomment-2050896270, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AHJULO4YKUHK5KBRAGYLUUTY45HSDAVCNFSM6AAAAAA7MLCXI6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANJQHA4TMMRXGA. You are receiving this because you commented.Message ID: @.***>
@saicao Awesome! I applied the patch locally, rebuilt the lib and now all read events are coming through.
I meet the same problem,the platform is android arm64 with c code and the target arch is arm64. I try the patch of saicao ,but not solve my problem. Is anyone solve this problem? @wtdcode
I try dev branch ,but the problem is still exist.