Describe the bug
When emulating a linux binary with multithread=True, calling ql.os.stop() to stop emulation didn't work as expected.
After a simple analysis, it seems that the self.threads of QlLinuxThreadManagement is always empty. No threads are added to it according to the code. As a result, when calling ql.os.stop(), no threads will be killed.
|
def stop(self): |
|
self.ql.log.debug("[Thread Manager] Stop the world.") |
|
self.ql.emu_stop() |
|
for t in self.threads: |
|
gevent.kill(t) |
|
|
A possible fix this is to add self.cur_thread into self.threads, maybe in QlLinuxThreadManagement.run() method. Or there is a better place to do it?
By the way, ql.emu_stop() is used for this purpose when multithread=False, and ql.os.stop() is used when multithread=True. Of course, calling ql.os.stop() work well in both cases. To make it consistent, maybe it's better to move ql.os.stop() into ql.stop(). Then use ql.stop() in all cases.
Sample Code
Taken from the examples/hello_x8664_linux_part_debug.py, and make minor changes. In this case, the function dump() will be called multiple times.
def dump(ql, *args, **kw):
ql.save(reg=False, cpu_context=True, snapshot="/tmp/snapshot.bin")
ql.log.info("here")
ql.os.stop()
if __name__ == "__main__":
ql = Qiling(["rootfs/x8664_linux/bin/sleep_hello"], "rootfs/x8664_linux", verbose=QL_VERBOSE.DEFAULT, multithread=True)
# load base address from profile file
X64BASE = int(ql.profile.get("OS64", "load_address"), 16)
# take a snapshot
ql.hook_address(dump, X64BASE + 0x1094)
ql.run()
Describe the bug
When emulating a linux binary with
multithread=True, callingql.os.stop()to stop emulation didn't work as expected.After a simple analysis, it seems that the
self.threadsofQlLinuxThreadManagementis always empty. No threads are added to it according to the code. As a result, when callingql.os.stop(), no threads will be killed.qiling/qiling/os/linux/thread.py
Lines 585 to 590 in 272a3da
A possible fix this is to add
self.cur_threadintoself.threads, maybe inQlLinuxThreadManagement.run()method. Or there is a better place to do it?By the way,
ql.emu_stop()is used for this purpose whenmultithread=False, andql.os.stop()is used whenmultithread=True. Of course, callingql.os.stop()work well in both cases. To make it consistent, maybe it's better to moveql.os.stop()intoql.stop(). Then useql.stop()in all cases.Sample Code
Taken from the
examples/hello_x8664_linux_part_debug.py, and make minor changes. In this case, the functiondump()will be called multiple times.