|
32 | 32 | class Qiling(QlCoreHooks, QlCoreStructs): |
33 | 33 | def __init__( |
34 | 34 | self, |
35 | | - argv: Sequence[str] = None, |
| 35 | + argv: Sequence[str] = [], |
36 | 36 | rootfs: str = r'.', |
37 | 37 | env: MutableMapping[AnyStr, AnyStr] = {}, |
38 | | - code: bytes = None, |
| 38 | + code: Optional[bytes] = None, |
39 | 39 | ostype: Union[str, QL_OS] = None, |
40 | 40 | archtype: Union[str, QL_ARCH] = None, |
41 | 41 | verbose: QL_VERBOSE = QL_VERBOSE.DEFAULT, |
@@ -90,18 +90,26 @@ def __init__( |
90 | 90 | ############## |
91 | 91 | # argv setup # |
92 | 92 | ############## |
93 | | - if argv is None: |
94 | | - argv = ['qilingcode'] |
| 93 | + if argv: |
| 94 | + if code: |
| 95 | + raise AttributeError('argv and code are mutually execlusive') |
95 | 96 |
|
96 | | - elif not os.path.exists(argv[0]): |
97 | | - raise QlErrorFileNotFound(f'Target binary not found: "{argv[0]}"') |
| 97 | + target = argv[0] |
| 98 | + |
| 99 | + if not os.path.isfile(target): |
| 100 | + raise QlErrorFileNotFound(f'Target binary not found: "{target}"') |
| 101 | + else: |
| 102 | + # an empty argv list means we are going to execute a shellcode. to keep |
| 103 | + # the 'path' api compatible, we insert a dummy placeholder |
| 104 | + |
| 105 | + argv = [''] |
98 | 106 |
|
99 | 107 | self._argv = argv |
100 | 108 |
|
101 | 109 | ################ |
102 | 110 | # rootfs setup # |
103 | 111 | ################ |
104 | | - if not os.path.exists(rootfs): |
| 112 | + if not os.path.isdir(rootfs): |
105 | 113 | raise QlErrorFileNotFound(f'Target rootfs not found: "{rootfs}"') |
106 | 114 |
|
107 | 115 | self._rootfs = rootfs |
@@ -697,11 +705,11 @@ def restore(self, saved_states: Mapping[str, Any] = {}, *, snapshot: Optional[st |
697 | 705 |
|
698 | 706 | # Map "ql_path" to any objects which implements QlFsMappedObject. |
699 | 707 | def add_fs_mapper(self, ql_path: Union["PathLike", str], real_dest): |
700 | | - self.os.fs_mapper.add_fs_mapping(ql_path, real_dest) |
| 708 | + self.os.fs_mapper.add_mapping(ql_path, real_dest) |
701 | 709 |
|
702 | 710 | # Remove "ql_path" mapping. |
703 | 711 | def remove_fs_mapper(self, ql_path: Union["PathLike", str]): |
704 | | - self.os.fs_mapper.remove_fs_mapping(ql_path) |
| 712 | + self.os.fs_mapper.remove_mapping(ql_path) |
705 | 713 |
|
706 | 714 | # push to stack bottom, and update stack register |
707 | 715 | def stack_push(self, data): |
@@ -757,14 +765,16 @@ def emu_start(self, begin: int, end: int, timeout: int = 0, count: int = 0): |
757 | 765 | if getattr(self.arch, '_init_thumb', False): |
758 | 766 | begin |= 0b1 |
759 | 767 |
|
760 | | - self._state = QL_STATE.STARTED |
761 | | - |
762 | 768 | # reset exception status before emulation starts |
763 | 769 | self._internal_exception = None |
764 | 770 |
|
| 771 | + self._state = QL_STATE.STARTED |
| 772 | + |
765 | 773 | # effectively start the emulation. this returns only after uc.emu_stop is called |
766 | 774 | self.uc.emu_start(begin, end, timeout, count) |
767 | 775 |
|
| 776 | + self._state = QL_STATE.STOPPED |
| 777 | + |
768 | 778 | # if an exception was raised during emulation, propagate it up |
769 | 779 | if self.internal_exception is not None: |
770 | 780 | raise self.internal_exception |
0 commit comments