| 36 | # create a new thread with context |
| 37 | @classmethod |
| 38 | def create(cls, ql: Qiling, stack_size: int, func_addr: int, func_params: int, status: THREAD_STATUS) -> 'QlWindowsThread': |
| 39 | os = cast('QlOsWindows', ql.os) |
| 40 | |
| 41 | thread = cls(ql, status) |
| 42 | |
| 43 | # create new stack |
| 44 | new_stack = os.heap.alloc(stack_size) + stack_size |
| 45 | |
| 46 | asize = ql.arch.pointersize |
| 47 | context = ql.arch.regs.save() |
| 48 | |
| 49 | # set return address |
| 50 | ql.mem.write_ptr(new_stack - asize, os.thread_manager.thread_ret_addr) |
| 51 | |
| 52 | # set parameters |
| 53 | if ql.arch.type == QL_ARCH.X86: |
| 54 | ql.mem.write_ptr(new_stack, func_params) |
| 55 | elif ql.arch.type == QL_ARCH.X8664: |
| 56 | context["rcx"] = func_params |
| 57 | |
| 58 | # set eip/rip, ebp/rbp, esp/rsp |
| 59 | if ql.arch.type == QL_ARCH.X86: |
| 60 | context["eip"] = func_addr |
| 61 | context["ebp"] = new_stack - asize |
| 62 | context["esp"] = new_stack - asize |
| 63 | |
| 64 | elif ql.arch.type == QL_ARCH.X8664: |
| 65 | context["rip"] = func_addr |
| 66 | context["rbp"] = new_stack - asize |
| 67 | context["rsp"] = new_stack - asize |
| 68 | |
| 69 | thread.saved_context = context |
| 70 | |
| 71 | return thread |
| 72 | |
| 73 | def suspend(self) -> None: |
| 74 | self.saved_context = self.ql.arch.regs.save() |