Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python callbacks suppress KeyboardInterrupt exceptions #2129

Open
DavidBuchanan314 opened this issue Mar 11, 2025 · 3 comments
Open

Python callbacks suppress KeyboardInterrupt exceptions #2129

DavidBuchanan314 opened this issue Mar 11, 2025 · 3 comments

Comments

@DavidBuchanan314
Copy link

DavidBuchanan314 commented Mar 11, 2025

from unicorn import *
from unicorn.x86_const import *

def instruction_callback(uc, a, b, c):
	print("hello, callback")
	#raise Exception("this works as expected")
	raise KeyboardInterrupt("this gets ignored")

mu = Uc(UC_ARCH_X86, UC_MODE_32)
mu.mem_map(0x1000, 0x1000)
mu.mem_write(0x1000, b"\xeb\xfe") # infinite loop
mu.hook_add(UC_HOOK_CODE, instruction_callback)
mu.emu_start(0x1000, -1, count=5)
print("ended without errors (unexpected!)")

Here's a simple example program.

If the commented line is uncommented, the program works as I'd expect/like - emu_start() raises an exception and the final print() does not execute.

But as written (i.e. with the callback raising a KeyboardInterrupt exception), it goes like this:

hello, callback
Exception ignored on calling ctypes callback function: <bound method Uc._hookcode_cb of <unicorn.unicorn.Uc object at 0xffff42acbf50>>
Traceback (most recent call last):
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 392, in wrapper
    return func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 663, in _hookcode_cb
    cb(self, address, size, data)
  File "/home/david/re/TDS864A/TDS684A/unicorn_hook_poc.py", line 7, in instruction_callback
    raise KeyboardInterrupt("this gets ignored")
KeyboardInterrupt: this gets ignored
hello, callback
Exception ignored on calling ctypes callback function: <bound method Uc._hookcode_cb of <unicorn.unicorn.Uc object at 0xffff42acbf50>>
Traceback (most recent call last):
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 392, in wrapper
    return func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 663, in _hookcode_cb
    cb(self, address, size, data)
  File "/home/david/re/TDS864A/TDS684A/unicorn_hook_poc.py", line 7, in instruction_callback
    raise KeyboardInterrupt("this gets ignored")
KeyboardInterrupt: this gets ignored
hello, callback
Exception ignored on calling ctypes callback function: <bound method Uc._hookcode_cb of <unicorn.unicorn.Uc object at 0xffff42acbf50>>
Traceback (most recent call last):
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 392, in wrapper
    return func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 663, in _hookcode_cb
    cb(self, address, size, data)
  File "/home/david/re/TDS864A/TDS684A/unicorn_hook_poc.py", line 7, in instruction_callback
    raise KeyboardInterrupt("this gets ignored")
KeyboardInterrupt: this gets ignored
hello, callback
Exception ignored on calling ctypes callback function: <bound method Uc._hookcode_cb of <unicorn.unicorn.Uc object at 0xffff42acbf50>>
Traceback (most recent call last):
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 392, in wrapper
    return func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 663, in _hookcode_cb
    cb(self, address, size, data)
  File "/home/david/re/TDS864A/TDS684A/unicorn_hook_poc.py", line 7, in instruction_callback
    raise KeyboardInterrupt("this gets ignored")
KeyboardInterrupt: this gets ignored
hello, callback
Exception ignored on calling ctypes callback function: <bound method Uc._hookcode_cb of <unicorn.unicorn.Uc object at 0xffff42acbf50>>
Traceback (most recent call last):
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 392, in wrapper
    return func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/david/.local/lib/python3.12/site-packages/unicorn/unicorn.py", line 663, in _hookcode_cb
    cb(self, address, size, data)
  File "/home/david/re/TDS864A/TDS684A/unicorn_hook_poc.py", line 7, in instruction_callback
    raise KeyboardInterrupt("this gets ignored")
KeyboardInterrupt: this gets ignored
ended without errors (unexpected!)

I can't really figure out why this is happening. It's unfortunate because in real-world code it results in a program that can't easily be killed via ctrl+C.

@DavidBuchanan314
Copy link
Author

I think this is where the "exception ignored" message is coming from https://github.com/python/cpython/blob/8b1edae93a05cc90c5b8c5c935f3753aca938ccf/Modules/_ctypes/callbacks.c#L212-L217

@DavidBuchanan314
Copy link
Author

I'm still not quite sure what's going on, but I have a workaround, which is to catch the KeyboardInterrupt exception in the wrapper and re-raise it as a regular Exception:

from unicorn import *
from unicorn.x86_const import *
from functools import wraps

def my_wrapper(f):
	@wraps(f)
	def wrapper(*args, **kwds):
		try:
			return f(*args, **kwds)
		except KeyboardInterrupt:
			raise Exception("KeyboardInterrupt raised in callback")
	return wrapper

@my_wrapper
def instruction_callback(uc, a, b, c):
	print("hello, callback")
	#raise Exception("this works as expected")
	raise KeyboardInterrupt("this gets ignored")

mu = Uc(UC_ARCH_X86, UC_MODE_32)
mu.mem_map(0x1000, 0x1000)
mu.mem_write(0x1000, b"\xeb\xfe") # infinite loop
mu.hook_add(UC_HOOK_CODE, instruction_callback)
mu.emu_start(0x1000, -1, count=5)
print("ended without errors (unexpected!)")

@wtdcode
Copy link
Member

wtdcode commented Mar 12, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants