Loading sign.shdeleted 100755 → 0 +0 −38 Original line number Diff line number Diff line #!/bin/bash root_dir=$(dirname "$(readlink -f "$0")") input_apk=$1 cert=$2 ks_pass=$3 ks_alias=$4 if [ "$#" -ne 4 ]; then echo "Usage: $0 <input_apk_file> <ks_file> <ks_pass> <ks_alias>" exit 1 fi if [[ "$cert" != *.jks ]]; then echo ">> [$(date)] Error: Certificate file must have the extension .jks." exit 1 else echo ">> [$(date)] Patching apk." certdigest=$(openssl x509 -sha256 -fingerprint -noout -in $cert -passin pass:$ks_pass) fingerprint=$(echo $certdigest | awk -F'=' '{print $2}' | sed 's/://g' | tr '[:upper:]' '[:lower:]') python3 ${root_dir}/trichrome_patch.py $fingerprint $input_apk fi output_apk="${input_apk%.apk}_signed.apk" if [ -f "$input_apk.patched" ]; then echo ">> [$(date)] Zipaligning apk." zipalign -p -f 4 "$input_apk.patched" $output_apk rm "$input_apk.patched" else cp -r $input_apk $output_apk fi if [ -f "$output_apk" ]; then echo ">> [$(date)] Signing apk." apksigner sign --ks $cert --ks-pass pass:$ks_pass --ks-key-alias $ks_alias $output_apk fi trichrome_patch.py +53 −16 Original line number Diff line number Diff line Loading @@ -2,36 +2,67 @@ import os import sys import subprocess import zipfile if len(sys.argv) < 3: print("Usage: python " + sys.argv[0] + ".py certdigest <input_apks>") def main(): if len(sys.argv) != 5: print("Usage: {} <input_apk_file> <ks_file> <ks_pass> <ks_alias>".format(sys.argv[0])) sys.exit(1) certdigest = sys.argv[1] input_apks = sys.argv[2:] input_apk = sys.argv[1] cert = sys.argv[2] ks_pass = sys.argv[3] ks_alias = sys.argv[4] def patch_apk(infilename, new_certdigest): # Default for chromium apks root_dir = os.path.dirname(os.path.realpath(__file__)) if not cert.endswith(".jks"): print(">> [{}] Error: Certificate file must have the extension .jks.".format(get_current_time())) sys.exit(1) else: print(">> [{}] Patching apk.".format(get_current_time())) certdigest = get_certificate_fingerprint(cert, ks_pass) fingerprint = certdigest.replace(':', '').lower() patch_apk(root_dir, fingerprint, input_apk) output_apk = "{}_signed.apk".format(os.path.splitext(input_apk)[0]) if os.path.exists("{}_patched".format(input_apk)): print(">> [{}] Zipaligning apk.".format(get_current_time())) zipalign_apk("{}_patched".format(input_apk), output_apk) os.remove("{}_patched".format(input_apk)) else: subprocess.run(["cp", input_apk, output_apk]) if os.path.exists(output_apk): print(">> [{}] Signing apk.".format(get_current_time())) sign_apk(cert, ks_pass, ks_alias, output_apk) def get_current_time(): return subprocess.check_output("date", shell=True).decode().strip() def get_certificate_fingerprint(cert, ks_pass): certdigest = subprocess.check_output("openssl x509 -sha256 -fingerprint -noout -in {} -passin pass:{}".format(cert, ks_pass), shell=True).decode().strip() return certdigest.split('=')[1].replace(':', '').lower() def patch_apk(root_dir, new_certdigest, input_apk): orig_certdigest = "32a2fc74d731105859e5a85df16d95f102d85b22099b8064c5d8915c61dad1e0" # Check if the original and new certificate digests are the same if orig_certdigest == new_certdigest: return delete_apk = False with zipfile.ZipFile(infilename, 'r') as zin: # Initialize the output ZIP file outfilename = infilename + ".patched" with zipfile.ZipFile(input_apk, 'r') as zin: outfilename = "{}_patched".format(input_apk) with zipfile.ZipFile(outfilename, 'w') as zout: for info in zin.infolist(): data = zin.read(info.filename) if info.filename == 'AndroidManifest.xml': if new_certdigest.encode('utf-16-le') in data: delete_apk = True # Check if the original certdigest is found if orig_certdigest.encode('utf-16-le') in data: elif orig_certdigest.encode('utf-16-le') in data: data = data.replace(orig_certdigest.encode('utf-16-le'), new_certdigest.encode('utf-16-le')) else: delete_apk = True Loading @@ -40,5 +71,11 @@ def patch_apk(infilename, new_certdigest): if delete_apk and os.path.exists(outfilename): os.remove(outfilename) for apk in input_apks: patch_apk(apk, certdigest) def zipalign_apk(input_apk, output_apk): subprocess.run(["zipalign", "-f", "-p", "-z", "4", input_apk, output_apk]) def sign_apk(cert, ks_pass, ks_alias, output_apk): subprocess.run(["apksigner", "sign", "--ks", cert, "--ks-pass", "pass:{}".format(ks_pass), "--ks-key-alias", ks_alias, output_apk]) if __name__ == "__main__": main() Loading
sign.shdeleted 100755 → 0 +0 −38 Original line number Diff line number Diff line #!/bin/bash root_dir=$(dirname "$(readlink -f "$0")") input_apk=$1 cert=$2 ks_pass=$3 ks_alias=$4 if [ "$#" -ne 4 ]; then echo "Usage: $0 <input_apk_file> <ks_file> <ks_pass> <ks_alias>" exit 1 fi if [[ "$cert" != *.jks ]]; then echo ">> [$(date)] Error: Certificate file must have the extension .jks." exit 1 else echo ">> [$(date)] Patching apk." certdigest=$(openssl x509 -sha256 -fingerprint -noout -in $cert -passin pass:$ks_pass) fingerprint=$(echo $certdigest | awk -F'=' '{print $2}' | sed 's/://g' | tr '[:upper:]' '[:lower:]') python3 ${root_dir}/trichrome_patch.py $fingerprint $input_apk fi output_apk="${input_apk%.apk}_signed.apk" if [ -f "$input_apk.patched" ]; then echo ">> [$(date)] Zipaligning apk." zipalign -p -f 4 "$input_apk.patched" $output_apk rm "$input_apk.patched" else cp -r $input_apk $output_apk fi if [ -f "$output_apk" ]; then echo ">> [$(date)] Signing apk." apksigner sign --ks $cert --ks-pass pass:$ks_pass --ks-key-alias $ks_alias $output_apk fi
trichrome_patch.py +53 −16 Original line number Diff line number Diff line Loading @@ -2,36 +2,67 @@ import os import sys import subprocess import zipfile if len(sys.argv) < 3: print("Usage: python " + sys.argv[0] + ".py certdigest <input_apks>") def main(): if len(sys.argv) != 5: print("Usage: {} <input_apk_file> <ks_file> <ks_pass> <ks_alias>".format(sys.argv[0])) sys.exit(1) certdigest = sys.argv[1] input_apks = sys.argv[2:] input_apk = sys.argv[1] cert = sys.argv[2] ks_pass = sys.argv[3] ks_alias = sys.argv[4] def patch_apk(infilename, new_certdigest): # Default for chromium apks root_dir = os.path.dirname(os.path.realpath(__file__)) if not cert.endswith(".jks"): print(">> [{}] Error: Certificate file must have the extension .jks.".format(get_current_time())) sys.exit(1) else: print(">> [{}] Patching apk.".format(get_current_time())) certdigest = get_certificate_fingerprint(cert, ks_pass) fingerprint = certdigest.replace(':', '').lower() patch_apk(root_dir, fingerprint, input_apk) output_apk = "{}_signed.apk".format(os.path.splitext(input_apk)[0]) if os.path.exists("{}_patched".format(input_apk)): print(">> [{}] Zipaligning apk.".format(get_current_time())) zipalign_apk("{}_patched".format(input_apk), output_apk) os.remove("{}_patched".format(input_apk)) else: subprocess.run(["cp", input_apk, output_apk]) if os.path.exists(output_apk): print(">> [{}] Signing apk.".format(get_current_time())) sign_apk(cert, ks_pass, ks_alias, output_apk) def get_current_time(): return subprocess.check_output("date", shell=True).decode().strip() def get_certificate_fingerprint(cert, ks_pass): certdigest = subprocess.check_output("openssl x509 -sha256 -fingerprint -noout -in {} -passin pass:{}".format(cert, ks_pass), shell=True).decode().strip() return certdigest.split('=')[1].replace(':', '').lower() def patch_apk(root_dir, new_certdigest, input_apk): orig_certdigest = "32a2fc74d731105859e5a85df16d95f102d85b22099b8064c5d8915c61dad1e0" # Check if the original and new certificate digests are the same if orig_certdigest == new_certdigest: return delete_apk = False with zipfile.ZipFile(infilename, 'r') as zin: # Initialize the output ZIP file outfilename = infilename + ".patched" with zipfile.ZipFile(input_apk, 'r') as zin: outfilename = "{}_patched".format(input_apk) with zipfile.ZipFile(outfilename, 'w') as zout: for info in zin.infolist(): data = zin.read(info.filename) if info.filename == 'AndroidManifest.xml': if new_certdigest.encode('utf-16-le') in data: delete_apk = True # Check if the original certdigest is found if orig_certdigest.encode('utf-16-le') in data: elif orig_certdigest.encode('utf-16-le') in data: data = data.replace(orig_certdigest.encode('utf-16-le'), new_certdigest.encode('utf-16-le')) else: delete_apk = True Loading @@ -40,5 +71,11 @@ def patch_apk(infilename, new_certdigest): if delete_apk and os.path.exists(outfilename): os.remove(outfilename) for apk in input_apks: patch_apk(apk, certdigest) def zipalign_apk(input_apk, output_apk): subprocess.run(["zipalign", "-f", "-p", "-z", "4", input_apk, output_apk]) def sign_apk(cert, ks_pass, ks_alias, output_apk): subprocess.run(["apksigner", "sign", "--ks", cert, "--ks-pass", "pass:{}".format(ks_pass), "--ks-key-alias", ks_alias, output_apk]) if __name__ == "__main__": main()