Skip to content

bug fix in windows #19

@krysof

Description

@krysof

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>') 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions