trueseeing 2.2.1__tar.gz → 2.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- trueseeing-2.2.4/Dockerfile +26 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/PKG-INFO +17 -8
- {trueseeing-2.2.1 → trueseeing-2.2.4}/README.md +11 -5
- {trueseeing-2.2.1 → trueseeing-2.2.4}/pyproject.toml +6 -2
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/__init__.py +1 -1
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/api.py +8 -4
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/__init__.py +1 -2
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/analyze.py +6 -1
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/android/asm.py +13 -5
- trueseeing-2.2.4/trueseeing/app/cmd/android/engage.py +1000 -0
- trueseeing-2.2.4/trueseeing/app/cmd/android/recon.py +316 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/android/search.py +52 -36
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/android/show.py +46 -34
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/config.py +42 -17
- trueseeing-2.2.4/trueseeing/app/cmd/info.py +64 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/scan.py +10 -4
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/search.py +1 -1
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/inspect.py +116 -49
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/scan.py +2 -8
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/shell.py +17 -1
- trueseeing-2.2.4/trueseeing/core/android/analysis/flow.py +357 -0
- trueseeing-2.2.4/trueseeing/core/android/analysis/op.py +55 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/android/asm.py +38 -10
- trueseeing-2.2.4/trueseeing/core/android/context.py +422 -0
- trueseeing-2.2.4/trueseeing/core/android/db.py +136 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/android/device.py +13 -7
- trueseeing-2.2.4/trueseeing/core/android/model.py +60 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/context.py +99 -26
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/db.py +36 -35
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/env.py +5 -1
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/model/issue.py +3 -5
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/report.py +2 -6
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/scan.py +38 -8
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/store.py +12 -14
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/tools.py +39 -20
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/ui.py +87 -12
- trueseeing-2.2.4/trueseeing/core/z.py +8 -0
- trueseeing-2.2.4/trueseeing/libs/android/frida-app.smali +16 -0
- trueseeing-2.2.4/trueseeing/libs/android/frida-scriptdir.config +7 -0
- trueseeing-2.2.4/trueseeing/libs/android/store.0.sql +10 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/store.s.sql +1 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/sig/__init__.py +1 -2
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/sig/android/crypto.py +68 -60
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/sig/android/fingerprint.py +23 -17
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/sig/android/manifest.py +8 -8
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/sig/android/privacy.py +14 -14
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/sig/android/security.py +75 -73
- trueseeing-2.2.1/Dockerfile +0 -17
- trueseeing-2.2.1/trueseeing/app/cmd/android/exploit.py +0 -445
- trueseeing-2.2.1/trueseeing/app/cmd/info.py +0 -110
- trueseeing-2.2.1/trueseeing/core/android/analysis/flow.py +0 -331
- trueseeing-2.2.1/trueseeing/core/android/analysis/smali.py +0 -147
- trueseeing-2.2.1/trueseeing/core/android/context.py +0 -152
- trueseeing-2.2.1/trueseeing/core/android/db.py +0 -188
- trueseeing-2.2.1/trueseeing/core/android/model/code.py +0 -55
- trueseeing-2.2.1/trueseeing/libs/android/store.0.sql +0 -4
- trueseeing-2.2.1/trueseeing/libs/android/store.1.sql +0 -77
- trueseeing-2.2.1/trueseeing/sig/android/__init__.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/.dockerignore +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/.github/workflows/deploy.yaml +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/.github/workflows/lint.yaml +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/.github/workflows/publish.yaml +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/.github/workflows/stale.yaml +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/.gitignore +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/COPYING +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/__init__.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/alias.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/android/__init__.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/report.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/app/cmd/show.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/__init__.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/android/analysis/__init__.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/android/store.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/android/tools.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/config.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/cvss.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/exc.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/ext.py +0 -0
- {trueseeing-2.2.1/trueseeing/core/android → trueseeing-2.2.4/trueseeing/core}/model/__init__.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/model/cmd.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/core/model/sig.py +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/LICENSE.md +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/android/abe.jar +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/android/apkeditor.jar +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/android/apksigner.jar +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/android/nsc.xml +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/files.0.sql +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/public_suffix_list.dat +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/store.0.sql +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/template/report.html +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/libs/tlds.txt +0 -0
- {trueseeing-2.2.1 → trueseeing-2.2.4}/trueseeing/py.typed +0 -0
- {trueseeing-2.2.1/trueseeing/core/model → trueseeing-2.2.4/trueseeing/sig/android}/__init__.py +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from python:3.9-alpine
|
|
2
|
+
run pip install flit
|
|
3
|
+
copy . /tmp/build/
|
|
4
|
+
run (cd /tmp/build && flit build)
|
|
5
|
+
|
|
6
|
+
from python:3.9-alpine
|
|
7
|
+
run mkdir /tmp/dist
|
|
8
|
+
# Building LIEF takes a long time so fetch from our wheel cache
|
|
9
|
+
add https://github.com/alterakey/trueseeing-lief/raw/main/dist/lief-0.14.1-cp39-cp39-musllinux_1_2_aarch64.whl /tmp/dist
|
|
10
|
+
add https://github.com/alterakey/trueseeing-lief/raw/main/dist/lief-0.14.1-cp39-cp39-musllinux_1_2_x86_64.whl /tmp/dist
|
|
11
|
+
# .. if you really prefer building it, comment above and uncomment below
|
|
12
|
+
#run (cd /tmp/dist && pip download 'lief~=0.14') || (apk add --no-cache build-base ninja cmake git ccache && git clone -b 0.14.1 https://github.com/lief-project/LIEF.git /tmp/build && (cd /tmp/build/api/python && pip install -r build-requirements.txt && pyproject-build -w && cp -a dist/*.whl /tmp/dist/))
|
|
13
|
+
|
|
14
|
+
from python:3.9-alpine
|
|
15
|
+
run apk add --no-cache openjdk17-jre-headless zip android-tools
|
|
16
|
+
run mkdir /data /ext /cache /out && ln -sfn /cache /root/.local
|
|
17
|
+
copy --from=0 /tmp/build/dist/*.whl /tmp/dist/
|
|
18
|
+
copy --from=1 /tmp/dist/*.whl /tmp/ext/
|
|
19
|
+
run pip install -f /tmp/ext/ /tmp/dist/*.whl && rm -rf /tmp/dist /tmp/ext
|
|
20
|
+
env PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
21
|
+
env TS2_IN_DOCKER=1
|
|
22
|
+
env TS2_CACHEDIR=/cache
|
|
23
|
+
env TS2_HOME=/data
|
|
24
|
+
env TS2_EXTDIR=/ext
|
|
25
|
+
workdir /out
|
|
26
|
+
entrypoint ["trueseeing"]
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: trueseeing
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.4
|
|
4
4
|
Summary: Trueseeing is a non-decompiling Android application vulnerability scanner.
|
|
5
5
|
Keywords: android,security,pentest,hacking
|
|
6
|
-
Author-email: Takahiro Yoshimura <
|
|
6
|
+
Author-email: Takahiro Yoshimura <alterakey@protonmail.com>
|
|
7
7
|
Requires-Python: >=3.9
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
Classifier: Topic :: Security
|
|
@@ -16,13 +16,16 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (G
|
|
|
16
16
|
Requires-Dist: lxml~=5.0
|
|
17
17
|
Requires-Dist: pyyaml~=6.0
|
|
18
18
|
Requires-Dist: jinja2~=3.1
|
|
19
|
-
Requires-Dist: attrs~=23.2
|
|
20
19
|
Requires-Dist: pypubsub~=4.0
|
|
21
20
|
Requires-Dist: termcolor~=2.4
|
|
22
21
|
Requires-Dist: progressbar2~=4.3
|
|
23
22
|
Requires-Dist: importlib_metadata~=7.0
|
|
24
23
|
Requires-Dist: asn1crypto~=1.5
|
|
25
24
|
Requires-Dist: zstandard~=0.22
|
|
25
|
+
Requires-Dist: aiohttp~=3.9
|
|
26
|
+
Requires-Dist: lief~=0.14
|
|
27
|
+
Requires-Dist: pyaxmlparser~=0.3
|
|
28
|
+
Requires-Dist: prompt-toolkit~=3.0
|
|
26
29
|
Requires-Dist: mypy~=1.7 ; extra == "dev"
|
|
27
30
|
Requires-Dist: pyproject-flake8~=6.1 ; extra == "dev"
|
|
28
31
|
Requires-Dist: typing_extensions~=4.1 ; extra == "dev"
|
|
@@ -43,7 +46,7 @@ trueseeing is a fast, accurate and resillient vulnerability scanner for Android
|
|
|
43
46
|
Currently we can:
|
|
44
47
|
|
|
45
48
|
* Automatically scan app for vulnerabilities, reporting in HTML/JSON/text format (see below)
|
|
46
|
-
* Manipulate app for easier analysis: e.g. enabling debug bit, enabling full backup, disabling TLS pinning, manipulating target API level, etc.
|
|
49
|
+
* Manipulate app for easier analysis: e.g. enabling debug bit, enabling full backup, disabling TLS pinning, manipulating target API level, injecting frida-gadget, etc.
|
|
47
50
|
* Examine app for general information
|
|
48
51
|
* Copy in/out app data through debug interface
|
|
49
52
|
* Search for certain calls/consts/sput/iput
|
|
@@ -81,7 +84,7 @@ Alternatively, you can install our package with pip as follows. This form of ins
|
|
|
81
84
|
You can interactively scan/analyze/patch/etc. apps -- making it the ideal choice for manual analysis:
|
|
82
85
|
|
|
83
86
|
$ trueseeing target.apk
|
|
84
|
-
[+] trueseeing 2.2.
|
|
87
|
+
[+] trueseeing 2.2.4
|
|
85
88
|
ts[target.apk]> ?
|
|
86
89
|
...
|
|
87
90
|
ts[target.apk]> i # show generic information
|
|
@@ -225,7 +228,7 @@ The following class will provide a sample command as `t`, for example:
|
|
|
225
228
|
```python
|
|
226
229
|
from typing import TYPE_CHECKING
|
|
227
230
|
from trueseeing.api import Command
|
|
228
|
-
from
|
|
231
|
+
from trueseeing.core.ui import ui
|
|
229
232
|
if TYPE_CHECKING:
|
|
230
233
|
from trueseeing.api import CommandMap, CommandPatternMap, ModifierMap, OptionMap, ConfigMap
|
|
231
234
|
|
|
@@ -314,7 +317,7 @@ class APKFileFormatHandler(FileFormatHandler):
|
|
|
314
317
|
return APKFileFormatHandler()
|
|
315
318
|
|
|
316
319
|
def get_formats(self) -> FormatMap:
|
|
317
|
-
return {
|
|
320
|
+
return {'apk2':dict(e=self._handle, r=r'\.apk$', d='sample file format')}
|
|
318
321
|
|
|
319
322
|
def get_configs(self) -> ConfigMap:
|
|
320
323
|
return dict()
|
|
@@ -337,9 +340,15 @@ But by design it works only for known types (currently, the `apk`). So if you a
|
|
|
337
340
|
context: MyAPKContext = self._helper.get_context().require_type('apk2') # type:ignore[assignment]
|
|
338
341
|
```
|
|
339
342
|
|
|
343
|
+
It is possible to define multiple formats matching the same pattern. We evaluate patterns in the order of from the most stringent (i.e. long) to the least. You use the `-F` switch to force some format to use with the target file, e.g.:
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
$ trueseeing -F apk2 target.apk
|
|
347
|
+
```
|
|
348
|
+
|
|
340
349
|
#### Package requirements
|
|
341
350
|
|
|
342
|
-
Extensions can be either: a) any package placed under `/ext` (container) or `~/.
|
|
351
|
+
Extensions can be either: a) any package placed under `/ext` (container) or `~/.trueseeing2/extensions` (pip), or b) any installed module named with the prefix of `trueseeing_ext0_`.
|
|
343
352
|
|
|
344
353
|
### Origin of Project Name?
|
|
345
354
|
|
|
@@ -12,7 +12,7 @@ trueseeing is a fast, accurate and resillient vulnerability scanner for Android
|
|
|
12
12
|
Currently we can:
|
|
13
13
|
|
|
14
14
|
* Automatically scan app for vulnerabilities, reporting in HTML/JSON/text format (see below)
|
|
15
|
-
* Manipulate app for easier analysis: e.g. enabling debug bit, enabling full backup, disabling TLS pinning, manipulating target API level, etc.
|
|
15
|
+
* Manipulate app for easier analysis: e.g. enabling debug bit, enabling full backup, disabling TLS pinning, manipulating target API level, injecting frida-gadget, etc.
|
|
16
16
|
* Examine app for general information
|
|
17
17
|
* Copy in/out app data through debug interface
|
|
18
18
|
* Search for certain calls/consts/sput/iput
|
|
@@ -50,7 +50,7 @@ Alternatively, you can install our package with pip as follows. This form of ins
|
|
|
50
50
|
You can interactively scan/analyze/patch/etc. apps -- making it the ideal choice for manual analysis:
|
|
51
51
|
|
|
52
52
|
$ trueseeing target.apk
|
|
53
|
-
[+] trueseeing 2.2.
|
|
53
|
+
[+] trueseeing 2.2.4
|
|
54
54
|
ts[target.apk]> ?
|
|
55
55
|
...
|
|
56
56
|
ts[target.apk]> i # show generic information
|
|
@@ -194,7 +194,7 @@ The following class will provide a sample command as `t`, for example:
|
|
|
194
194
|
```python
|
|
195
195
|
from typing import TYPE_CHECKING
|
|
196
196
|
from trueseeing.api import Command
|
|
197
|
-
from
|
|
197
|
+
from trueseeing.core.ui import ui
|
|
198
198
|
if TYPE_CHECKING:
|
|
199
199
|
from trueseeing.api import CommandMap, CommandPatternMap, ModifierMap, OptionMap, ConfigMap
|
|
200
200
|
|
|
@@ -283,7 +283,7 @@ class APKFileFormatHandler(FileFormatHandler):
|
|
|
283
283
|
return APKFileFormatHandler()
|
|
284
284
|
|
|
285
285
|
def get_formats(self) -> FormatMap:
|
|
286
|
-
return {
|
|
286
|
+
return {'apk2':dict(e=self._handle, r=r'\.apk$', d='sample file format')}
|
|
287
287
|
|
|
288
288
|
def get_configs(self) -> ConfigMap:
|
|
289
289
|
return dict()
|
|
@@ -306,9 +306,15 @@ But by design it works only for known types (currently, the `apk`). So if you a
|
|
|
306
306
|
context: MyAPKContext = self._helper.get_context().require_type('apk2') # type:ignore[assignment]
|
|
307
307
|
```
|
|
308
308
|
|
|
309
|
+
It is possible to define multiple formats matching the same pattern. We evaluate patterns in the order of from the most stringent (i.e. long) to the least. You use the `-F` switch to force some format to use with the target file, e.g.:
|
|
310
|
+
|
|
311
|
+
```
|
|
312
|
+
$ trueseeing -F apk2 target.apk
|
|
313
|
+
```
|
|
314
|
+
|
|
309
315
|
#### Package requirements
|
|
310
316
|
|
|
311
|
-
Extensions can be either: a) any package placed under `/ext` (container) or `~/.
|
|
317
|
+
Extensions can be either: a) any package placed under `/ext` (container) or `~/.trueseeing2/extensions` (pip), or b) any installed module named with the prefix of `trueseeing_ext0_`.
|
|
312
318
|
|
|
313
319
|
### Origin of Project Name?
|
|
314
320
|
|
|
@@ -5,7 +5,7 @@ build-backend = "flit_core.buildapi"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = 'trueseeing'
|
|
7
7
|
authors = [
|
|
8
|
-
{name='Takahiro Yoshimura', email='
|
|
8
|
+
{name='Takahiro Yoshimura', email='alterakey@protonmail.com'}
|
|
9
9
|
]
|
|
10
10
|
classifiers = [
|
|
11
11
|
"Topic :: Security",
|
|
@@ -22,13 +22,16 @@ dependencies = [
|
|
|
22
22
|
"lxml~=5.0",
|
|
23
23
|
"pyyaml~=6.0",
|
|
24
24
|
"jinja2~=3.1",
|
|
25
|
-
"attrs~=23.2",
|
|
26
25
|
"pypubsub~=4.0",
|
|
27
26
|
"termcolor~=2.4",
|
|
28
27
|
"progressbar2~=4.3",
|
|
29
28
|
"importlib_metadata~=7.0",
|
|
30
29
|
"asn1crypto~=1.5",
|
|
31
30
|
"zstandard~=0.22",
|
|
31
|
+
"aiohttp~=3.9",
|
|
32
|
+
"lief~=0.14",
|
|
33
|
+
"pyaxmlparser~=0.3",
|
|
34
|
+
"prompt-toolkit~=3.0",
|
|
32
35
|
]
|
|
33
36
|
requires-python = ">=3.9"
|
|
34
37
|
dynamic = ['version', 'description']
|
|
@@ -57,6 +60,7 @@ module = [
|
|
|
57
60
|
"jinja2",
|
|
58
61
|
"pubsub",
|
|
59
62
|
"asn1crypto.*",
|
|
63
|
+
"pyaxmlparser.*",
|
|
60
64
|
]
|
|
61
65
|
ignore_missing_imports = true
|
|
62
66
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Trueseeing is a non-decompiling Android application vulnerability scanner."""
|
|
2
|
-
__version__ = '2.2.
|
|
2
|
+
__version__ = '2.2.4'
|
|
@@ -10,9 +10,12 @@ if TYPE_CHECKING:
|
|
|
10
10
|
from trueseeing.core.android.context import APKContext
|
|
11
11
|
from trueseeing.core.model.issue import Issue, IssueConfidence
|
|
12
12
|
|
|
13
|
+
ModifierEvent = Literal['begin', 'end']
|
|
14
|
+
|
|
13
15
|
CommandEntrypoint = Callable[[deque[str]], Coroutine[Any, Any, None]]
|
|
14
16
|
CommandlineEntrypoint = Callable[[str], Coroutine[Any, Any, None]]
|
|
15
17
|
CommandPatternEntrypoints = Union[CommandEntrypoint, CommandlineEntrypoint]
|
|
18
|
+
ModifierListenerEntrypoint = Callable[[ModifierEvent, str], Coroutine[Any, Any, None]]
|
|
16
19
|
SignatureEntrypoint = Callable[[], Coroutine[Any, Any, None]]
|
|
17
20
|
FormatHandlerEntrypoint = Callable[[str], Optional[Context]]
|
|
18
21
|
ConfigGetterEntrypoint = Callable[[], Any]
|
|
@@ -34,7 +37,7 @@ if TYPE_CHECKING:
|
|
|
34
37
|
pass
|
|
35
38
|
|
|
36
39
|
class ModifierEntry(Entry):
|
|
37
|
-
|
|
40
|
+
e: Optional[ModifierListenerEntrypoint] # type: ignore[misc]
|
|
38
41
|
|
|
39
42
|
class ConfigEntry(TypedDict):
|
|
40
43
|
g: ConfigGetterEntrypoint
|
|
@@ -48,6 +51,7 @@ if TYPE_CHECKING:
|
|
|
48
51
|
|
|
49
52
|
class FormatEntry(TypedDict):
|
|
50
53
|
e: FormatHandlerEntrypoint
|
|
54
|
+
r: str
|
|
51
55
|
d: str
|
|
52
56
|
|
|
53
57
|
CommandMap = Mapping[str, CommandEntry]
|
|
@@ -71,13 +75,13 @@ if TYPE_CHECKING:
|
|
|
71
75
|
def get_context(self, typ: ContextType) -> Context: ...
|
|
72
76
|
@overload
|
|
73
77
|
@deprecated('use get_context().analyze(...)')
|
|
74
|
-
async def get_context_analyzed(self, *, level: int =
|
|
78
|
+
async def get_context_analyzed(self, *, level: int = 4) -> Context: ...
|
|
75
79
|
@overload
|
|
76
80
|
@deprecated('use get_context().require_type(...).analyze(...)')
|
|
77
|
-
async def get_context_analyzed(self, typ: Literal['apk'], *, level: int =
|
|
81
|
+
async def get_context_analyzed(self, typ: Literal['apk'], *, level: int = 4) -> APKContext: ...
|
|
78
82
|
@overload
|
|
79
83
|
@deprecated('use get_context().require_type(...).analyze(...)')
|
|
80
|
-
async def get_context_analyzed(self, typ: ContextType, *, level: int =
|
|
84
|
+
async def get_context_analyzed(self, typ: ContextType, *, level: int = 4) -> Context: ...
|
|
81
85
|
def decode_analysis_level(self, level: int) -> str: ...
|
|
82
86
|
async def run(self, s: str) -> None: ...
|
|
83
87
|
async def run_cmd(self, tokens: deque[str], line: Optional[str]) -> bool: ...
|
|
@@ -8,11 +8,10 @@ if TYPE_CHECKING:
|
|
|
8
8
|
def discover() -> Iterator[Type[Command]]:
|
|
9
9
|
from trueseeing.api import Command
|
|
10
10
|
from importlib import import_module
|
|
11
|
-
from trueseeing.core.model.cmd import CommandMixin
|
|
12
11
|
from trueseeing.core.tools import get_public_subclasses, get_missing_methods, discover_modules_under
|
|
13
12
|
|
|
14
13
|
for mod in discover_modules_under('trueseeing.app.cmd'):
|
|
15
14
|
m = import_module(mod)
|
|
16
|
-
for c in get_public_subclasses(m, Command,
|
|
15
|
+
for c in get_public_subclasses(m, Command, 'CommandMixin'): # type:ignore[type-abstract]
|
|
17
16
|
assert not get_missing_methods(c)
|
|
18
17
|
yield c
|
|
@@ -19,10 +19,12 @@ class AnalyzeCommand(CommandMixin):
|
|
|
19
19
|
|
|
20
20
|
def get_commands(self) -> CommandMap:
|
|
21
21
|
return {
|
|
22
|
-
'a':dict(e=self._analyze, n='a[a][!]', d='analyze target (aa: full
|
|
22
|
+
'a':dict(e=self._analyze, n='a[a][a][!]', d='analyze target (aa: marginal, aaa: full)'),
|
|
23
23
|
'a!':dict(e=self._analyze),
|
|
24
24
|
'aa':dict(e=self._analyze2),
|
|
25
25
|
'aa!':dict(e=self._analyze2),
|
|
26
|
+
'aaa':dict(e=self._analyze3),
|
|
27
|
+
'aaa!':dict(e=self._analyze3),
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
async def _analyze(self, args: deque[str], level: int = 2) -> None:
|
|
@@ -39,3 +41,6 @@ class AnalyzeCommand(CommandMixin):
|
|
|
39
41
|
|
|
40
42
|
async def _analyze2(self, args: deque[str]) -> None:
|
|
41
43
|
await self._analyze(args, level=3)
|
|
44
|
+
|
|
45
|
+
async def _analyze3(self, args: deque[str]) -> None:
|
|
46
|
+
await self._analyze(args, level=4)
|
|
@@ -47,16 +47,24 @@ class AssembleCommand(CommandMixin):
|
|
|
47
47
|
ui.fatal('need root path')
|
|
48
48
|
|
|
49
49
|
import os
|
|
50
|
+
import re
|
|
50
51
|
import time
|
|
51
52
|
from tempfile import TemporaryDirectory
|
|
52
53
|
from trueseeing.core.android.asm import APKAssembler
|
|
53
54
|
from trueseeing.core.android.tools import move_apk
|
|
54
55
|
|
|
55
56
|
root = args.popleft()
|
|
56
|
-
origapk =
|
|
57
|
+
origapk = re.sub(r'(\.x?apk)$', r'\1.orig', apk)
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
stem = re.sub(r'\.x?apk$', '', apk)
|
|
60
|
+
for typ in ['apk', 'xapk']:
|
|
61
|
+
print(origapk, f'{stem}.{typ}.orig')
|
|
62
|
+
if os.path.exists(f'{stem}.{typ}.orig') and not cmd.endswith('!'):
|
|
63
|
+
ui.fatal('backup file exists; force (!) to overwrite')
|
|
64
|
+
|
|
65
|
+
if apk.endswith('.xapk'):
|
|
66
|
+
ui.warn('assembling xapk is not supported; assembling as merged apk')
|
|
67
|
+
apk = apk.replace('.xapk', '.apk')
|
|
60
68
|
|
|
61
69
|
opts = self._helper.get_effective_options(self._helper.get_modifiers(args))
|
|
62
70
|
|
|
@@ -140,7 +148,7 @@ class AssembleCommand(CommandMixin):
|
|
|
140
148
|
at = time.time()
|
|
141
149
|
|
|
142
150
|
with TemporaryDirectory() as td:
|
|
143
|
-
await APKDisassembler.disassemble_to_path(apk, td, nodex=nodex)
|
|
151
|
+
await APKDisassembler.disassemble_to_path(apk, td, nodex=nodex, merge=apk.endswith('.xapk'))
|
|
144
152
|
|
|
145
153
|
if not archive:
|
|
146
154
|
with FileTransferProgressReporter('disassemble: writing').scoped() as progress:
|
|
@@ -185,7 +193,7 @@ class AssembleCommand(CommandMixin):
|
|
|
185
193
|
|
|
186
194
|
at = time.time()
|
|
187
195
|
extracted = 0
|
|
188
|
-
context = self._helper.get_context()
|
|
196
|
+
context = self._helper.get_context()
|
|
189
197
|
q = context.store().query()
|
|
190
198
|
|
|
191
199
|
if not archive:
|