| 95 | TIME_SLICE = 10 |
| 96 | |
| 97 | def __init__(self, ql: Qiling, os: 'QlOsWindows', cur_thread: QlWindowsThread): |
| 98 | self.ql = ql |
| 99 | |
| 100 | # main thread |
| 101 | self.cur_thread = cur_thread |
| 102 | self.threads = [self.cur_thread] |
| 103 | self.icount = 0 |
| 104 | self.thread_ret_addr = os.heap.alloc(8) |
| 105 | |
| 106 | # write nop to thread_ret_addr |
| 107 | ql.mem.write(self.thread_ret_addr, b'\x90' * 8) |
| 108 | |
| 109 | def __thread_scheduler(ql: Qiling, address: int, size: int): |
| 110 | if ql.arch.regs.arch_pc == self.thread_ret_addr: |
| 111 | self.cur_thread.stop() |
| 112 | else: |
| 113 | self.icount += 1 |
| 114 | |
| 115 | switched = self.do_schedule() |
| 116 | |
| 117 | # in case another thread was resumed, all remaining hooks should be skipped to prevent them |
| 118 | # from running with the new thread's context. |
| 119 | |
| 120 | return QL_HOOK_BLOCK if switched else 0 |
| 121 | |
| 122 | ql.hook_code(__thread_scheduler) |
| 123 | |
| 124 | def append(self, thread: QlWindowsThread): |
| 125 | self.threads.append(thread) |