|
import gradio as gr |
|
import os |
|
import subprocess |
|
import tempfile |
|
import shutil |
|
import logging |
|
import re |
|
from typing import Dict, List, Optional |
|
from dataclasses import dataclass |
|
from transformers import pipeline |
|
|
|
logging.basicConfig( |
|
level=logging.INFO, |
|
format="%(asctime)s - %(levelname)s - %(message)s", |
|
handlers=[logging.StreamHandler()], |
|
) |
|
|
|
|
|
class APKError(Exception): |
|
"""Erro personalizado para problemas com APK.""" |
|
|
|
|
|
@dataclass |
|
class PointsSystem: |
|
currency_name: str |
|
modification_points: List[str] |
|
|
|
|
|
class APKAnalyzer: |
|
def __init__(self): |
|
self.smali_files = {} |
|
self.java_files = {} |
|
|
|
def analyze_apk(self, apk_file: bytes) -> Dict: |
|
"""Analisa o APK usando apktool e jadx.""" |
|
temp_dir = tempfile.mkdtemp() |
|
apk_path = os.path.join(temp_dir, "uploaded.apk") |
|
smali_dir = os.path.join(temp_dir, "smali") |
|
java_dir = os.path.join(temp_dir, "java") |
|
|
|
with open(apk_path, "wb") as f: |
|
f.write(apk_file) |
|
|
|
try: |
|
|
|
logging.info("Descompilando APK para Smali...") |
|
subprocess.run(["apktool", "d", "-o", smali_dir, apk_path], check=True) |
|
self.smali_files = self._load_files(smali_dir, ".smali") |
|
|
|
|
|
logging.info("Descompilando APK para Java...") |
|
subprocess.run(["jadx", "-d", java_dir, apk_path], check=True) |
|
self.java_files = self._load_files(java_dir, ".java") |
|
|
|
|
|
points_system = self.detect_points_system() |
|
|
|
return { |
|
"smali_count": len(self.smali_files), |
|
"java_count": len(self.java_files), |
|
"currency_name": points_system.currency_name, |
|
"modification_points": points_system.modification_points, |
|
} |
|
except Exception as e: |
|
logging.error(f"Erro ao analisar o APK: {e}") |
|
raise APKError("Erro durante a análise do APK.") |
|
finally: |
|
shutil.rmtree(temp_dir, ignore_errors=True) |
|
|
|
def _load_files(self, base_dir: str, extension: str) -> Dict[str, str]: |
|
files = {} |
|
for root, _, filenames in os.walk(base_dir): |
|
for filename in filenames: |
|
if filename.endswith(extension): |
|
with open(os.path.join(root, filename), "r", encoding="utf-8", errors="ignore") as f: |
|
files[filename] = f.read() |
|
return files |
|
|
|
def detect_points_system(self) -> PointsSystem: |
|
"""Detecta moedas ou pontos no APK.""" |
|
currency_name = None |
|
modification_points = [] |
|
|
|
patterns = [ |
|
r"(coins?|gems?|points?|credits?|gold|money|cash)", |
|
r"(score|balance|currency|wealth)", |
|
] |
|
|
|
for file_name, content in self.smali_files.items(): |
|
for pattern in patterns: |
|
match = re.search(pattern, content, re.IGNORECASE) |
|
if match: |
|
currency_name = match.group(0) |
|
modification_points.append(file_name) |
|
|
|
if not currency_name: |
|
raise APKError("Nenhum sistema de pontuação detectado.") |
|
|
|
return PointsSystem(currency_name, list(set(modification_points))) |
|
|
|
|
|
class APKModifier: |
|
def modify_apk(self, smali_files: Dict[str, str], points: int, multiplier: Optional[float]) -> bytes: |
|
"""Modifica arquivos Smali e recompila o APK.""" |
|
temp_dir = tempfile.mkdtemp() |
|
smali_dir = os.path.join(temp_dir, "smali") |
|
modified_apk_path = os.path.join(temp_dir, "modified.apk") |
|
|
|
os.makedirs(smali_dir, exist_ok=True) |
|
|
|
try: |
|
for file_name, content in smali_files.items(): |
|
|
|
content = content.replace("INITIAL_POINTS", str(points)) |
|
if multiplier: |
|
content = re.sub( |
|
r"ADD_POINTS (\d+)", |
|
lambda m: f"ADD_POINTS {int(m.group(1)) * multiplier}", |
|
content, |
|
) |
|
with open(os.path.join(smali_dir, file_name), "w", encoding="utf-8") as f: |
|
f.write(content) |
|
|
|
|
|
logging.info("Recompilando APK...") |
|
subprocess.run(["apktool", "b", smali_dir, "-o", modified_apk_path], check=True) |
|
|
|
with open(modified_apk_path, "rb") as f: |
|
return f.read() |
|
finally: |
|
shutil.rmtree(temp_dir, ignore_errors=True) |
|
|
|
|
|
def create_interface(): |
|
analyzer = APKAnalyzer() |
|
modifier = APKModifier() |
|
chat_pipeline = pipeline("text-generation", model="bigscience/bloom-560m") |
|
|
|
with gr.Blocks(title="APK Analysis & Modification Tool") as interface: |
|
gr.Markdown("## APK Analysis & Modification Tool 🚀") |
|
|
|
with gr.Tab("Analisar APK"): |
|
apk_file = gr.File(label="Envie o APK", file_types=[".apk"], type="binary") |
|
analyze_btn = gr.Button("Analisar APK") |
|
analysis_output = gr.JSON(label="Resultado da Análise") |
|
|
|
with gr.Tab("Modificar APK"): |
|
points_input = gr.Slider(0, 10000, label="Pontos Iniciais") |
|
multiplier_input = gr.Slider(1.0, 10.0, label="Multiplicador de Pontos") |
|
modify_btn = gr.Button("Modificar APK") |
|
modified_apk_output = gr.File(label="Baixar APK Modificado") |
|
|
|
analyze_btn.click( |
|
fn=analyzer.analyze_apk, inputs=apk_file, outputs=analysis_output |
|
) |
|
|
|
modify_btn.click( |
|
fn=modifier.modify_apk, |
|
inputs=[gr.State(analyzer.smali_files), points_input, multiplier_input], |
|
outputs=modified_apk_output, |
|
) |
|
|
|
return interface |
|
|
|
|
|
if __name__ == "__main__": |
|
interface = create_interface() |
|
interface.launch() |
|
|