Spaces:
Running
Running
File size: 7,318 Bytes
3ef37b3 12102c5 92387b0 6ad15e8 21fd4fa 12102c5 5a1e926 eb7e9a5 7ff86f3 eb7e9a5 5a1e926 22c90ec 5a1e926 6ad15e8 5a1e926 6ad15e8 5a1e926 6ad15e8 5a1e926 6ad15e8 5a1e926 12102c5 5a1e926 12102c5 5a1e926 21fd4fa 5a1e926 21fd4fa 5a1e926 5717f28 5a1e926 6ad15e8 5a1e926 101246c 5a1e926 eb7e9a5 5a1e926 4c53a66 5a1e926 4c53a66 5a1e926 eb7e9a5 5a1e926 12102c5 5a1e926 12102c5 5a1e926 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
import streamlit as st
import os
import subprocess
import shutil
import zipfile
import requests
# Function to debug APK file
def debug_apk(input_path, output_dir):
# Run apk-mitm command
command = f"apk-mitm {input_path} -o {output_dir}"
result = subprocess.run(command, shell=True, capture_output=True, text=True)
if result.returncode == 0:
# Extract the patched file name from stdout
output_file_name = result.stdout.split("Patched file: ")[-1].strip()
output_path = os.path.join(output_dir, output_file_name)
return output_path
else:
st.error(f"Error debugging APK: {result.stderr}")
return None
# Function to process XAPK file
def process_xapk(xapk_path):
"""
Process XAPK file: rename to ZIP, extract contents, merge with APKEditor.jar, and sign the APK.
Args:
xapk_path (str): Path to the XAPK file
Returns:
str: Path to the signed APK if successful, None if failed
"""
try:
# Get the directory and filename without extension
folder = os.path.dirname(xapk_path)
name_without_ext = os.path.splitext(os.path.basename(xapk_path))[0]
# Create paths for zip and extraction
zip_path = os.path.join(folder, f"{name_without_ext}.zip")
extract_dir = os.path.join(folder, name_without_ext)
# Rename XAPK to ZIP and extract contents
shutil.move(xapk_path, zip_path)
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(extract_dir)
# Remove the ZIP file after extraction
os.remove(zip_path)
# Run APKEditor.jar command to merge the extracted files
command = f'java -jar APKEditor.jar m -i "{extract_dir}"'
result = subprocess.run(command, shell=True, capture_output=True, text=True)
if result.returncode == 0:
# Define the path for the merged APK
merged_apk_path = os.path.join(folder, f"{name_without_ext}_merged.apk")
st.write(f"Merged APK created at: {merged_apk_path}")
# Proceed to sign the merged APK
signed_apk_path = process_sign(merged_apk_path)
return signed_apk_path
else:
st.error(f"Error merging APK: {result.stderr}")
return None
except Exception as e:
st.error(f"Error processing XAPK: {str(e)}")
# Clean up in case of error
shutil.rmtree(extract_dir, ignore_errors=True)
return None
# Function to sign APK file
def process_sign(apk_path):
"""
Sign the APK file using uber-apk-signer.
Args:
apk_path (str): Path to the APK file to be signed.
Returns:
str: Path to the signed APK if successful, None if failed.
"""
folder = os.path.dirname(apk_path)
command = f"java -jar uber-apk-signer.jar --apks {apk_path}"
result = subprocess.run(command, shell=True, capture_output=True, text=True)
if result.returncode == 0:
# Extract the path of the signed APK from the output directory
signed_apk_path = apk_path.replace('.apk', '-aligned-debugSigned.apk')
# Check if the signed APK exists at the expected path
if os.path.exists(signed_apk_path):
st.write("APK signing successful!")
return signed_apk_path
else:
st.error("APK signing completed, but the signed file could not be found.")
return None
else:
# Display the error message in a more user-friendly way
st.error(f"Error signing APK: {result.stderr}")
return None
# Streamlit app interface
st.title("APK File Processor")
# File upload
uploaded_file = st.file_uploader("Upload APK file", type=['apk', 'xapk', 'apks'])
# URL upload
url_input = st.text_input("Or enter APK URL")
# Radio buttons to select the processing type
processing_option = st.radio("Choose the processing type:", ('Process XAPK', 'Sign APK', 'Debug APK'))
if uploaded_file is not None or url_input:
# Create directories if they don't exist
upload_dir = "uploads"
if not os.path.exists(upload_dir):
os.makedirs(upload_dir)
if uploaded_file is not None:
# Save uploaded file
input_path = os.path.join(upload_dir, uploaded_file.name)
# Write the uploaded file to the filesystem
with open(input_path, "wb") as f:
f.write(uploaded_file.read())
# Now that the file is saved, rename it if it contains spaces
if " " in uploaded_file.name:
new_name = uploaded_file.name.replace(" ", "_") # Replace spaces with underscores
new_input_path = os.path.join(upload_dir, new_name)
# Only rename if the new name is different
if new_input_path != input_path:
os.rename(input_path, new_input_path)
input_path = new_input_path # Update input_path to new name
elif url_input:
# Download APK from URL
st.write("Downloading APK from URL...")
response = requests.get(url_input)
if response.status_code == 200:
input_path = os.path.join(upload_dir, os.path.basename(url_input))
with open(input_path, "wb") as f:
f.write(response.content)
else:
st.error("Failed to download APK from URL. Please check the URL and try again.")
st.stop()
# Define output directory for the processed APK
output_dir = upload_dir
# Execute the process based on user choice
if processing_option == 'Process XAPK' and input_path.endswith('.xapk'):
st.write("Processing XAPK...")
output_path = process_xapk(input_path)
elif processing_option == 'Sign APK' and input_path.endswith('.apk'):
st.write("Signing APK...")
output_path = process_sign(input_path)
elif processing_option == 'Debug APK' and input_path.endswith('.apk'):
st.write("Debugging APK...")
output_path = debug_apk(input_path, output_dir)
else:
st.error("The selected process is not compatible with the uploaded file type. Please ensure the file type matches your selection.")
output_path = None
# Handle the result of processing
if output_path:
st.success("APK processed successfully!")
st.write("Output path:")
st.text(output_path)
# Provide download link for the processed APK file
if os.path.exists(output_path):
with open(output_path, "rb") as f:
file_data = f.read()
st.download_button(
label="Download Processed APK",
data=file_data,
file_name=os.path.basename(output_path),
mime="application/vnd.android.package-archive"
)
else:
st.error("Processed APK file not found. Please try again.")
else:
st.error("Failed to process APK. Please try again.")
# Clean up the uploaded and processed files
def cleanup_files():
shutil.rmtree(upload_dir, ignore_errors=True)
# Cleanup is done after download button appears to ensure the file is available for download
cleanup_files()
|