- Notifications
You must be signed in to change notification settings - Fork 17
Description
use this code in windows
#!/usr/bin/env python3
coding: UTF-8
import datetime
import glob
import json
import os
import subprocess
from shutil import move
from colorama import Fore
import shutil
ANDROID_SDK_DEFAULT_PATH = '/Library/Android/sdk/'
ANDROID_HOME = os.environ.get('ANDROID_HOME', ANDROID_SDK_DEFAULT_PATH)
def which_or_fail(cmd_name):
path = shutil.which(cmd_name)
if not path:
raise FileNotFoundError(f"{cmd_name} not found in PATH")
# 手动检查是否是 shim 且没有后缀,但实际是个 .cmd/.bat
if os.name == 'nt' and not os.path.splitext(path)[1]:
for ext in ('.cmd', '.bat'):
if os.path.exists(path + ext):
return path + ext
return path
def run_subprocess(cmd):
is_windows = os.name == 'nt'
# 判断是否是 .cmd/.bat 文件(Windows 下必须用 cmd.exe 调用) if is_windows and (cmd[0].endswith('.cmd') or cmd[0].endswith('.bat')): # 把原始命令拼成字符串再传给 cmd.exe /c full_cmd = ['cmd.exe', '/c'] + cmd else: full_cmd = cmd proc = subprocess.Popen( full_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) outs, errs = proc.communicate() return outs.decode('ascii', errors='ignore'), errs.decode('ascii', errors='ignore') def pull_apks(keyword):
try:
adb_path = glob.glob(ANDROID_HOME + '/platform-tools/adb')[0]
package_name = get_package_name(keyword) if not package_name: print(f"No package found matching keyword: {keyword}") return False print(f"Package found: {package_name}") apk_paths = get_apk_paths(package_name) if not apk_paths: print(f"No APK paths found for package: {package_name}") return False pull_apk_files(apk_paths) print("APKs have been pulled to the current directory.") except (IndexError, FileNotFoundError): print('adb not found.') print('Please install Android SDK Build Tools.') return False except Exception as e: print(f"An error occurred: {e}") return False def get_package_name(keyword):
adb_path = glob.glob(ANDROID_HOME + '/platform-tools/adb')[0]
list_packages_cmd = [adb_path, 'shell', 'pm', 'list', 'packages']
outs, errs = run_subprocess(list_packages_cmd)
if errs:
raise Exception(errs)
package_list = outs.strip().splitlines() package_names = [line.split(":")[1] for line in package_list if keyword in line] return package_names[0] if package_names else None def get_apk_paths(package_name):
adb_path = glob.glob(ANDROID_HOME + '/platform-tools/adb')[0]
path_cmd = [adb_path, 'shell', 'pm', 'path', package_name]
outs, errs = run_subprocess(path_cmd)
if errs:
raise Exception(errs)
apk_paths = outs.strip().splitlines() return [line.split(":")[1] for line in apk_paths] def pull_apk_files(apk_paths):
adb_path = glob.glob(ANDROID_HOME + '/platform-tools/adb')[0]
for apk_path in apk_paths:
print(f"Pulling {apk_path}...")
pull_cmd = [adb_path, 'pull', apk_path]
outs, errs = run_subprocess(pull_cmd)
if outs:
print(outs)
if errs:
raise Exception(errs)
def decode(apk_path, no_res=False, no_src=False):
apktool_cmd = [which_or_fail('apktool'), 'd', os.path.abspath(apk_path)]
if no_res:
apktool_cmd.append('-r')
if no_src:
apktool_cmd.append('-s')
try: outs, errs = run_subprocess(apktool_cmd) if outs: print(outs) if errs: errs = errs.replace('Use -f switch if you want to overwrite it.', '') raise Exception(errs) return True except FileNotFoundError: return False except Exception as e: print(str(e)) return False def build(dir_name, apk_path, aapt2=False):
apktool_cmd = [which_or_fail('apktool'), 'b', os.path.abspath(dir_name), '-o', os.path.abspath(apk_path)]
if aapt2:
apktool_cmd.append('--use-aapt2')
try:
outs, errs = run_subprocess(apktool_cmd)
is_built = False
if outs:
if "I: Built apk..." in outs:
is_built = True
print(outs)
if errs and not is_built:
raise Exception(errs)
except FileNotFoundError:
return False
except Exception as e:
print(str(e))
return False
def align(apk_path):
try:
zipalign_path = which_or_fail('zipalign')
zipalign_cmd = [zipalign_path, '-f', '-p', '4', apk_path, '/tmp/apkutil_tmp.aligned.apk']
_, errs = run_subprocess(zipalign_cmd)
if errs:
raise Exception(errs)
move('/tmp/apkutil_tmp.aligned.apk', apk_path)
return True
except FileNotFoundError:
return False
except Exception as e:
print(str(e))
return False
def sign(apk_path):
home_dir = os.environ.get('HOME', os.environ.get('USERPROFILE', ''))
try:
with open(os.path.join(home_dir, "apkutil.json")) as f:
config = json.load(f)
keystore_path = config['keystore_path'].replace('~', home_dir)
ks_key_alias = config['ks-key-alias']
ks_pass = config['ks-pass']
except:
print('Please place ~/apkutil.json containing the keystore information')
return False
try: if not os.path.isfile(apk_path): raise Exception(f"{apk_path} is not found.") apksigner_path = which_or_fail('apksigner') apksigner_cmd = [ apksigner_path, 'sign', '-ks', keystore_path, '--v2-signing-enabled', 'true', '-v', '--ks-key-alias', ks_key_alias, '--ks-pass', ks_pass, apk_path ] outs, errs = run_subprocess(apksigner_cmd) if outs: print(Fore.CYAN + outs) if errs: print(Fore.RED + errs) return False return True except FileNotFoundError: return False except Exception as e: print(str(e)) return False def get_packagename(apk_path):
try:
aapt_path = which_or_fail('aapt')
aapt_cmd = [aapt_path, 'l', '-a', apk_path]
aapt_proc = subprocess.Popen(aapt_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
grep_proc = subprocess.Popen(["findstr", "A: package"], stdin=aapt_proc.stdout)
aapt_proc.stdout.close()
outs, errs = grep_proc.communicate()
outs, errs = outs.decode('ascii'), errs.decode('ascii')
if outs:
print(outs)
if errs:
raise Exception(errs)
return True
except FileNotFoundError:
return False
except Exception as e:
print(str(e))
return False
def get_screenshot():
try:
adb_path = glob.glob(ANDROID_HOME + '/platform-tools/adb')[0]
now = datetime.datetime.now()
timestamp = now.strftime("%Y-%m-%d-%H-%M-%S")
screenshot_file = 'screenshot-' + timestamp + '.png'
screenshot_path = '/data/local/tmp/' + screenshot_file
screencap_cmd = [adb_path, 'shell', 'screencap', '-p', screenshot_path] _, errs = run_subprocess(screencap_cmd) if errs: raise Exception(errs) pull_cmd = [adb_path, 'pull', screenshot_path] _, errs = run_subprocess(pull_cmd) print(errs) rm_cmd = [adb_path, 'shell', 'rm', screenshot_path] _, errs = run_subprocess(rm_cmd) if errs: print(errs) return screenshot_file except (IndexError, FileNotFoundError): print('adb not found.') print('Please install Android SDK Build Tools.') return False def check_sensitive_files(target_path):
types = ('/*.md', '/.cpp', '**/.c', '/*.h', '/.java', '**/.kts',
'/*.bat', '/.sh', '**/.template', '/*.gradle', '/.json', '**/.yml', '**/*.txt')
allow_list = ('apktool.yml', '/assets/google-services-desktop.json',
'/assets/bin/Data/RuntimeInitializeOnLoads.json', '/assets/bin/Data/ScriptingAssemblies.json')
found_files = []
for file_type in types:
found_files.extend(glob.glob(os.path.join(target_path, file_type), recursive=True))
sensitive_files = [] for found_file in found_files: allow_flag = False for allow_file in allow_list: if found_file.endswith(allow_file): allow_flag = True break if not allow_flag: sensitive_files.append(found_file) if len(sensitive_files) == 0: print(Fore.BLUE + 'None') else: for sensitive_file in sensitive_files: print(Fore.RED + sensitive_file) print('') return sensitive_files def make_network_security_config(target_path):
xml_path = os.path.join(target_path, 'res/xml')
if not os.path.exists(xml_path):
os.makedirs(xml_path)
with open(os.path.join(target_path, 'res/xml/network_security_config.xml'), 'w') as f: f.write('<?xml version="1.0" encoding="utf-8"?>\n' + '<network-security-config>\n' + ' <base-config>\n' + ' <trust-anchors>\n' + ' <certificates src="system" />\n' + ' <certificates src="user" />\n' + ' </trust-anchors>\n' + ' </base-config>\n' + '</network-security-config>')