From 8a12dc053cca5a6755d24a8b8dd90e9041f782e7 Mon Sep 17 00:00:00 2001 From: xwings Date: Sat, 11 Apr 2020 11:42:35 +0800 Subject: [PATCH] fix syscall location and revert windows --- .gitignore | 2 ++ qiling/os/linux/syscall.py | 6 +++++ qiling/os/posix/syscall/sched.py | 4 ++-- qiling/os/windows/clipboard.py | 10 +++++---- .../dlls/kernel32/processthreadsapi.py | 22 +++++++++---------- qiling/os/windows/dlls/kernel32/synchapi.py | 4 ++-- qiling/os/windows/structs.py | 2 +- qiling/os/windows/thread.py | 17 +++++++------- qiling/os/windows/utils.py | 2 +- tests/test_elf.py | 8 +++++++ tests/test_pe_nu.py | 2 +- 11 files changed, 49 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index 2bb66d41..f60f0e0a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,8 @@ examples/**/Windows/ # test and logs jexamples/ logs/ +test_qlog/ +qlog/ test_syscall_*.txt *.no.py .gitkeep diff --git a/qiling/os/linux/syscall.py b/qiling/os/linux/syscall.py index fab2af4f..117e7631 100644 --- a/qiling/os/linux/syscall.py +++ b/qiling/os/linux/syscall.py @@ -24,6 +24,12 @@ from qiling.os.linux.utils import * from qiling.os.utils import * from qiling.const import * +from qiling.os.posix.syscall import * + + +def ql_x8664_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, clone_child_tidptr, clone_newtls, *args, **kw): + ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, clone_newtls, clone_child_tidptr, *args, **kw) + def ql_x86_syscall_set_thread_area(ql, u_info_addr, *args, **kw): diff --git a/qiling/os/posix/syscall/sched.py b/qiling/os/posix/syscall/sched.py index 90f5b5e9..0def132c 100644 --- a/qiling/os/posix/syscall/sched.py +++ b/qiling/os/posix/syscall/sched.py @@ -34,8 +34,8 @@ from qiling.os.posix.filestruct import * from qiling.os.posix.const_mapping import * from qiling.utils import * -def ql_x8664_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, clone_child_tidptr, clone_newtls, *args, **kw): - ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, clone_newtls, clone_child_tidptr, *args, **kw) +# def ql_x8664_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, clone_child_tidptr, clone_newtls, *args, **kw): +# ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, clone_newtls, clone_child_tidptr, *args, **kw) def ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, clone_newtls, clone_child_tidptr, *args, **kw): CSIGNAL = 0x000000ff diff --git a/qiling/os/windows/clipboard.py b/qiling/os/windows/clipboard.py index 8bd9a0d5..aed4b70d 100644 --- a/qiling/os/windows/clipboard.py +++ b/qiling/os/windows/clipboard.py @@ -28,7 +28,8 @@ class Clipboard: If hWnd is null default to current thead id """ if h_wnd == 0: - hWnd = self.ql.thread_manager.cur_thread.id + # FIXME : self.ql.os this is ugly, should be self.os.thread_manager + hWnd = self.ql.os.thread_manager.cur_thread.id if self.locked_by != NOT_LOCKED and self.locked_by != h_wnd: return 0 @@ -51,7 +52,8 @@ class Clipboard: return 1 def set_data(self, fmt, data): - hWnd = self.ql.thread_manager.cur_thread.id + # FIXME : self.ql.os this is ugly, should be self.os.thread_manager + hWnd = self.ql.os.thread_manager.cur_thread.id if self.locked_by != hWnd: self.last_error = 0x58A # ERROR_CLIPBOARD_NOT_OPEN @@ -65,8 +67,8 @@ class Clipboard: def get_data(self, fmt): if fmt not in self.formats: return 0 - - hWnd = self.ql.thread_manager.cur_thread.id + # FIXME : self.ql.os this is ugly, should be self.os.thread_manager + hWnd = self.ql.os.thread_manager.cur_thread.id if self.locked_by != hWnd: self.last_error = 0x58A # ERROR_CLIPBOARD_NOT_OPEN diff --git a/qiling/os/windows/dlls/kernel32/processthreadsapi.py b/qiling/os/windows/dlls/kernel32/processthreadsapi.py index 22ff99a9..8fb377b8 100644 --- a/qiling/os/windows/dlls/kernel32/processthreadsapi.py +++ b/qiling/os/windows/dlls/kernel32/processthreadsapi.py @@ -99,9 +99,9 @@ def hook_GetStartupInfoW(self, address, params): # DWORD TlsAlloc(); @winapi(cc=STDCALL, params={}) def hook_TlsAlloc(self, address, params): - idx = self.ql.thread_manager.cur_thread.tls_index - self.ql.thread_manager.cur_thread.tls_index += 1 - self.ql.thread_manager.cur_thread.tls[idx] = 0 + idx = self.thread_manager.cur_thread.tls_index + self.thread_manager.cur_thread.tls_index += 1 + self.thread_manager.cur_thread.tls[idx] = 0 return idx @@ -113,11 +113,11 @@ def hook_TlsAlloc(self, address, params): }) def hook_TlsFree(self, address, params): idx = params['dwTlsIndex'] - if idx not in self.ql.thread_manager.cur_thread.tls: + if idx not in self.thread_manager.cur_thread.tls: self.last_error = 0x57 # (ERROR_INVALID_PARAMETER) return 0 else: - del (self.ql.thread_manager.cur_thread.tls[idx]) + del (self.thread_manager.cur_thread.tls[idx]) return 1 @@ -128,14 +128,14 @@ def hook_TlsFree(self, address, params): "dwTlsIndex": UINT}) def hook_TlsGetValue(self, address, params): idx = params['dwTlsIndex'] - if idx not in self.ql.thread_manager.cur_thread.tls: + if idx not in self.thread_manager.cur_thread.tls: self.last_error = 0x57 # (ERROR_INVALID_PARAMETER) return 0 else: # api explicity clears last error on success: # https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsgetvalue self.last_error - return self.ql.thread_manager.cur_thread.tls[idx] + return self.thread_manager.cur_thread.tls[idx] # LPVOID TlsSetValue( @@ -147,11 +147,11 @@ def hook_TlsGetValue(self, address, params): }) def hook_TlsSetValue(self, address, params): idx = params['dwTlsIndex'] - if idx not in self.ql.thread_manager.cur_thread.tls: + if idx not in self.thread_manager.cur_thread.tls: self.last_error = 0x57 # (ERROR_INVALID_PARAMETER) return 0 else: - self.ql.thread_manager.cur_thread.tls[idx] = params['lpTlsValue'] + self.thread_manager.cur_thread.tls[idx] = params['lpTlsValue'] return 1 @@ -159,7 +159,7 @@ def hook_TlsSetValue(self, address, params): # ); @winapi(cc=STDCALL, params={}) def hook_GetCurrentThreadId(self, address, params): - ret = self.ql.thread_manager.cur_thread.id + ret = self.thread_manager.cur_thread.id return ret @@ -226,7 +226,7 @@ def hook_CreateThread(self, address, params): ) # append the new thread to ThreadManager - self.ql.thread_manager.append(new_thread) + self.thread_manager.append(new_thread) # create thread handle new_handle = Handle(thread=new_thread) diff --git a/qiling/os/windows/dlls/kernel32/synchapi.py b/qiling/os/windows/dlls/kernel32/synchapi.py index ac43e3c8..6836269f 100644 --- a/qiling/os/windows/dlls/kernel32/synchapi.py +++ b/qiling/os/windows/dlls/kernel32/synchapi.py @@ -107,7 +107,7 @@ def hook_WaitForSingleObject(self, address, params): target_thread: Thread = self.handle_manager.get(hHandle).thread if not target_thread.fake: - self.ql.thread_manager.cur_thread.waitfor(target_thread) + self.thread_manager.cur_thread.waitfor(target_thread) return ret @@ -135,7 +135,7 @@ def hook_WaitForMultipleObjects(self, address, params): handle_value = self.ql.unpack(self.ql.mem.read(lpHandles + i * self.ql.pointersize, self.ql.pointersize)) if handle_value != 0: thread = self.handle_manager.get(handle_value).thread - self.ql.thread_manager.cur_thread.waitfor(thread) + self.thread_manager.cur_thread.waitfor(thread) return ret diff --git a/qiling/os/windows/structs.py b/qiling/os/windows/structs.py index 995e7540..df80868f 100644 --- a/qiling/os/windows/structs.py +++ b/qiling/os/windows/structs.py @@ -320,7 +320,7 @@ class Token: sid = Sid(ql) handle = Handle(sid=sid) - # FIXME : self.ql.os this is ugly + # FIXME : self.ql.os this is ugly, should be self.os.thread_manager self.ql.os.handle_manager.append(handle) self.struct[Token.TokenInformationClass.TokenIntegrityLevel] = self.ql.pack(handle.id) diff --git a/qiling/os/windows/thread.py b/qiling/os/windows/thread.py index 95da2bf4..4ffd5f5f 100644 --- a/qiling/os/windows/thread.py +++ b/qiling/os/windows/thread.py @@ -10,12 +10,12 @@ from qiling.os.windows.utils import * def thread_scheduler(ql, address, size): - if ql.pc == ql.thread_manager.THREAD_RET_ADDR: - ql.thread_manager.cur_thread.stop() - ql.thread_manager.do_schedule() + if ql.pc == ql.os.thread_manager.THREAD_RET_ADDR: + ql.os.thread_manager.cur_thread.stop() + ql.os.thread_manager.do_schedule() else: - ql.thread_manager.ins_count += 1 - ql.thread_manager.do_schedule() + ql.os.thread_manager.ins_count += 1 + ql.os.thread_manager.do_schedule() class Context(): @@ -156,12 +156,13 @@ class QlWindowsThread(QlThread): # create new stack stack_size = 1024 new_stack = self.ql.heap.mem_alloc(stack_size) + stack_size - + + # FIXME : self.ql.os this is ugly, should be self.os.thread_manager if self.ql.archtype == QL_X86: - self.ql.mem.write(new_stack - 4, self.ql.pack32(self.ql.thread_manager.THREAD_RET_ADDR)) + self.ql.mem.write(new_stack - 4, self.ql.pack32(self.ql.os.thread_manager.THREAD_RET_ADDR)) self.ql.mem.write(new_stack, self.ql.pack32(func_params)) elif self.ql.archtype == QL_X8664: - self.ql.mem.write(new_stack - 8, self.ql.pack64(self.ql.thread_manager.THREAD_RET_ADDR)) + self.ql.mem.write(new_stack - 8, self.ql.pack64(self.ql.os.thread_manager.THREAD_RET_ADDR)) self.ql.mem.write(new_stack, self.ql.pack64(func_params)) # set eip, ebp, esp diff --git a/qiling/os/windows/utils.py b/qiling/os/windows/utils.py index 18b0b0fe..b45f86a1 100644 --- a/qiling/os/windows/utils.py +++ b/qiling/os/windows/utils.py @@ -44,7 +44,7 @@ def setup(self): self.fiber_manager = FiberManager(self.ql) # thread manager main_thread = QlWindowsThread(self.ql) - self.ql.thread_manager = QlWindowsThreadManagement(self.ql, main_thread) + self.thread_manager = QlWindowsThreadManagement(self.ql, main_thread) # more handle manager new_handle = Handle(thread=main_thread) diff --git a/tests/test_elf.py b/tests/test_elf.py index 033afaf2..d98ca523 100644 --- a/tests/test_elf.py +++ b/tests/test_elf.py @@ -17,6 +17,14 @@ class ELFTest(unittest.TestCase): ql.multithread = True ql.run() + + def test_multithread_elf_linux_x8664(self): + ql = Qiling(["../examples/rootfs/x8664_linux/bin/x8664_multithreading"], "../examples/rootfs/x8664_linux", log_dir= "multi_log") + ql.log_split = True + ql.multithread = True + ql.run() + + def test_elf_freebsd_x8664(self): ql = Qiling(["../examples/rootfs/x8664_freebsd/bin/x8664_hello_asm"], "../examples/rootfs/x8664_freebsd", output = "disasm") ql.run() diff --git a/tests/test_pe_nu.py b/tests/test_pe_nu.py index 04f9438e..c2f00d0d 100644 --- a/tests/test_pe_nu.py +++ b/tests/test_pe_nu.py @@ -27,7 +27,7 @@ def test_pe_win_x8664_hello(): def test_pe_win_x86_hello(): ql = Qiling(["../examples/rootfs/x86_windows/bin/x86_hello.exe"], "../examples/rootfs/x86_windows", - output="default", log_dir='/var/tmp/test_qlog', append="test") + output="default", log_dir='test_qlog', append="test") ql.log_split = True ql.run() del ql