check smali
This commit is contained in:
parent
3d7764d958
commit
4f197877ca
2 changed files with 107 additions and 1 deletions
|
|
@ -2,12 +2,16 @@ import zipfile
|
|||
import io
|
||||
import hashlib
|
||||
import json
|
||||
import sqlite3
|
||||
import tempfile
|
||||
import subprocess
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from pathlib import Path
|
||||
from getpass import getpass
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
from .androzoo import download_apk
|
||||
from .data import ApkData, load_from_directory
|
||||
from .analysis import analyze
|
||||
|
|
@ -130,7 +134,7 @@ def main():
|
|||
print(entry.to_string())
|
||||
else:
|
||||
with (args.output_dir / sha256).open("w") as file:
|
||||
file.write(entry)
|
||||
file.write(entry.to_string())
|
||||
|
||||
if apks:
|
||||
if args.json:
|
||||
|
|
@ -231,3 +235,104 @@ def collect_to_db():
|
|||
)
|
||||
args = parser.parse_args()
|
||||
load_from_directory(args.dir, args.db, args.androzoo_list)
|
||||
|
||||
|
||||
def check_smali():
|
||||
parser = ArgumentParser(
|
||||
prog="Smalli Check",
|
||||
description="Check if duplicated classes have distinct smali",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--db",
|
||||
help="Path to the database storing the results",
|
||||
type=Path,
|
||||
required=True,
|
||||
)
|
||||
key_parser = parser.add_mutually_exclusive_group(required=False)
|
||||
key_parser.add_argument(
|
||||
"--api-key-file",
|
||||
help="The path to a file containing the Androzoo API key",
|
||||
type=Path,
|
||||
)
|
||||
key_parser.add_argument(
|
||||
"--api-key", help="The Androzoo API key (Usage NOT recommanded)", type=str
|
||||
)
|
||||
SECRET_STORAGE_IMPORTED = False
|
||||
try:
|
||||
import secretstorage
|
||||
|
||||
SECRET_STORAGE_IMPORTED = True
|
||||
|
||||
key_parser.add_argument(
|
||||
"--api-key-keyring-id",
|
||||
help="The ID of the Androzoo API key in the secret service storage",
|
||||
type=str,
|
||||
)
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
args = parser.parse_args()
|
||||
|
||||
api_key = ""
|
||||
if args.api_key:
|
||||
api_key = args.api_key
|
||||
if args.api_key_file:
|
||||
with args.api_key_file.open("r") as file:
|
||||
api_key = file.read().strip()
|
||||
if SECRET_STORAGE_IMPORTED and not api_key:
|
||||
if args.api_key_keyring_id:
|
||||
key_id = args.api_key_keyring_id
|
||||
else:
|
||||
key_id = "androzoo"
|
||||
try:
|
||||
with secretstorage.dbus_init() as connection:
|
||||
collection = secretstorage.get_default_collection(connection)
|
||||
item = next(collection.search_items({"Title": key_id}))
|
||||
item.unlock()
|
||||
api_key = item.get_secret().decode("utf-8").strip()
|
||||
except:
|
||||
pass
|
||||
if not api_key:
|
||||
api_key = getpass(prompt="Androzoo API key: ").strip()
|
||||
|
||||
with sqlite3.connect(args.db) as conn:
|
||||
apks = list(
|
||||
map(
|
||||
lambda t: t[0],
|
||||
conn.execute("SELECT sha256 FROM data WHERE nb_duplicate_classes >= 1"),
|
||||
)
|
||||
)
|
||||
data = {}
|
||||
for sha256 in apks:
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
d = Path(tmpdirname)
|
||||
apk_bin = download_apk(sha256, api_key, logfile=None)
|
||||
if apk_bin is None:
|
||||
continue
|
||||
with (d / "app.apk").open("wb") as fp:
|
||||
fp.write(apk_bin)
|
||||
with zipfile.ZipFile(io.BytesIO(apk_bin)) as apk:
|
||||
json_data[sha256] = {}
|
||||
entry = analyze(apk, sha256, json_out=json_data[sha256])
|
||||
subprocess.run(["apktool", "d", "app.apk", "-o", "apktool_out"], cwd=d)
|
||||
smalli_dirs = []
|
||||
for dex in json_data[sha256]["class_dex"]:
|
||||
if dex == "classes.dex":
|
||||
smalli_dirs.append(out / "apktool_out" / "smali")
|
||||
else:
|
||||
smalli_dirs.append(
|
||||
out / "apktool_out" / "smali_" + dex.removesuffix(".dex")
|
||||
)
|
||||
dist_dup_classes = set()
|
||||
for cl in json_data[sha256]["duplicated_classes"]:
|
||||
cl_f = cl.removesuffix(";").removeprefix("L") + ".smali"
|
||||
smali = None
|
||||
for cdir in smalli_dirs:
|
||||
if (cdir / cl_f).exists():
|
||||
with (cdir / cl_f).open() as file:
|
||||
smali_new = file.read()
|
||||
if smali is None:
|
||||
smali = smali_new
|
||||
elif smali != smali_new:
|
||||
dist_dup_classes.add(cl)
|
||||
json_data[sha256]["redef_classes"] = list(dist_dup_classes)
|
||||
print(json.dumps(json_data))
|
||||
|
|
|
|||
|
|
@ -21,3 +21,4 @@ build-backend = "poetry.core.masonry.api"
|
|||
[tool.poetry.scripts]
|
||||
scan = 'android_class_shadowing_scanner.__init__:main'
|
||||
collect-scan = 'android_class_shadowing_scanner.__init__:collect_to_db'
|
||||
check-class-redef = 'android_class_shadowing_scanner.__init__:check_smali'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue