Update app.py
Browse files
app.py
CHANGED
@@ -2,27 +2,27 @@ import os
|
|
2 |
import subprocess
|
3 |
import tempfile
|
4 |
from androguard.misc import AnalyzeAPK
|
5 |
-
from transformers import RobertaTokenizer, RobertaForCausalLM, pipeline
|
6 |
from sentence_transformers import SentenceTransformer, util
|
7 |
import torch
|
8 |
import gradio as gr
|
9 |
|
|
|
|
|
|
|
|
|
|
|
10 |
# Inicialização do modelo all-MiniLM-L6-v2 para indexação
|
11 |
indexing_model = SentenceTransformer("all-MiniLM-L6-v2")
|
12 |
|
13 |
# Inicialização do CodeBERT para explicações gerativas
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
codebert_model.eval() # Colocar o modelo em modo de avaliação
|
18 |
-
except Exception as e:
|
19 |
-
print(f"Erro ao carregar o modelo CodeBERT: {str(e)}")
|
20 |
|
21 |
# Contexto global para armazenar dados do APK
|
22 |
apk_context = {"smali": {}, "java": {}, "info": ""}
|
23 |
|
24 |
-
|
25 |
-
# Função para verificar se o Java está instalado
|
26 |
def check_java():
|
27 |
try:
|
28 |
result = subprocess.run(["java", "-version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
@@ -32,16 +32,12 @@ def check_java():
|
|
32 |
except Exception as e:
|
33 |
raise EnvironmentError(f"Erro inesperado ao verificar a instalação do Java: {str(e)}")
|
34 |
|
35 |
-
|
36 |
-
# Instalar ferramentas como Baksmali e JADX
|
37 |
def install_tools():
|
38 |
baksmali_path = "/usr/local/bin/baksmali.jar"
|
39 |
jadx_path = "/usr/local/bin/jadx/bin/jadx"
|
40 |
|
41 |
-
# Verificar se o Java está disponível
|
42 |
check_java()
|
43 |
|
44 |
-
# Instalar o Baksmali caso não esteja presente
|
45 |
if not os.path.exists(baksmali_path):
|
46 |
print("Instalando o Baksmali...")
|
47 |
subprocess.run(
|
@@ -55,7 +51,6 @@ def install_tools():
|
|
55 |
check=True,
|
56 |
)
|
57 |
|
58 |
-
# Instalar o JADX caso não esteja presente
|
59 |
jadx_zip_path = "/usr/local/bin/jadx.zip"
|
60 |
if not os.path.exists(jadx_path):
|
61 |
print("Instalando o JADX...")
|
@@ -75,8 +70,6 @@ def install_tools():
|
|
75 |
else:
|
76 |
raise FileNotFoundError("Executável do JADX não encontrado no caminho esperado.")
|
77 |
|
78 |
-
|
79 |
-
# Função para decompilar o APK
|
80 |
def decompile_apk(apk_file):
|
81 |
if apk_file is None:
|
82 |
return "Nenhum arquivo enviado. Por favor, envie um arquivo APK."
|
@@ -84,21 +77,18 @@ def decompile_apk(apk_file):
|
|
84 |
temp_apk_path = apk_file.name
|
85 |
output_dir = tempfile.mkdtemp()
|
86 |
try:
|
87 |
-
# Decompilar usando o Baksmali
|
88 |
smali_output = os.path.join(output_dir, "smali")
|
89 |
subprocess.run(
|
90 |
["java", "-jar", "/usr/local/bin/baksmali.jar", "d", temp_apk_path, "-o", smali_output],
|
91 |
check=True,
|
92 |
)
|
93 |
|
94 |
-
# Decompilar usando o JADX
|
95 |
java_output = os.path.join(output_dir, "java")
|
96 |
subprocess.run(
|
97 |
["/usr/local/bin/jadx/bin/jadx", "-d", java_output, temp_apk_path],
|
98 |
check=True,
|
99 |
)
|
100 |
|
101 |
-
# Coletar arquivos Smali decompilados
|
102 |
smali_files = {}
|
103 |
for root, _, files in os.walk(smali_output):
|
104 |
for file in files:
|
@@ -106,7 +96,6 @@ def decompile_apk(apk_file):
|
|
106 |
with open(os.path.join(root, file), "r") as f:
|
107 |
smali_files[file] = f.read()
|
108 |
|
109 |
-
# Coletar arquivos Java decompilados
|
110 |
java_files = {}
|
111 |
for root, _, files in os.walk(java_output):
|
112 |
for file in files:
|
@@ -114,7 +103,6 @@ def decompile_apk(apk_file):
|
|
114 |
with open(os.path.join(root, file), "r") as f:
|
115 |
java_files[file] = f.read()
|
116 |
|
117 |
-
# Armazenar resultados no contexto global
|
118 |
apk_context["smali"] = smali_files
|
119 |
apk_context["java"] = java_files
|
120 |
|
@@ -123,59 +111,71 @@ def decompile_apk(apk_file):
|
|
123 |
except Exception as e:
|
124 |
return f"Erro durante a decompilação: {str(e)}"
|
125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
|
127 |
-
# Função para gerar embeddings de textos usando o modelo de indexação
|
128 |
def get_embeddings(text):
|
129 |
return indexing_model.encode(text, convert_to_tensor=True)
|
130 |
|
131 |
-
|
132 |
-
# Função para chat com APK usando CodeBERT
|
133 |
def query_apk_chat(user_message):
|
134 |
if not apk_context["smali"] and not apk_context["java"]:
|
135 |
return "Nenhum APK decompilado disponível. Por favor, envie e decompile um APK primeiro."
|
136 |
|
137 |
try:
|
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 |
return response
|
173 |
|
174 |
except Exception as e:
|
175 |
-
return f"Erro durante a
|
176 |
-
|
177 |
|
178 |
-
#
|
179 |
install_tools()
|
180 |
|
181 |
# Interfaces Gradio
|
@@ -183,17 +183,23 @@ apk_upload_interface = gr.Interface(
|
|
183 |
fn=decompile_apk,
|
184 |
inputs=gr.File(label="Enviar arquivo APK", file_types=[".apk"]),
|
185 |
outputs="text",
|
186 |
-
title="Analisador de APK",
|
187 |
-
description="Envie um arquivo APK para
|
188 |
)
|
189 |
|
190 |
chat_interface = gr.Interface(
|
191 |
fn=query_apk_chat,
|
192 |
inputs=gr.Textbox(lines=3, placeholder="Faça uma pergunta sobre o código do APK..."),
|
193 |
-
outputs=gr.Textbox(lines=
|
194 |
-
title="Chat com APK",
|
195 |
-
description="
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
)
|
197 |
|
198 |
-
|
199 |
-
iface.launch()
|
|
|
2 |
import subprocess
|
3 |
import tempfile
|
4 |
from androguard.misc import AnalyzeAPK
|
5 |
+
from transformers import BloomForCausalLM, BloomTokenizerFast, RobertaTokenizer, RobertaForCausalLM, pipeline
|
6 |
from sentence_transformers import SentenceTransformer, util
|
7 |
import torch
|
8 |
import gradio as gr
|
9 |
|
10 |
+
# Inicialização do modelo BLOOM para compreensão de linguagem natural
|
11 |
+
bloom_tokenizer = BloomTokenizerFast.from_pretrained("bigscience/bloom-560m")
|
12 |
+
bloom_model = BloomForCausalLM.from_pretrained("bigscience/bloom-560m")
|
13 |
+
bloom_model.eval()
|
14 |
+
|
15 |
# Inicialização do modelo all-MiniLM-L6-v2 para indexação
|
16 |
indexing_model = SentenceTransformer("all-MiniLM-L6-v2")
|
17 |
|
18 |
# Inicialização do CodeBERT para explicações gerativas
|
19 |
+
tokenizer = RobertaTokenizer.from_pretrained("microsoft/codebert-base")
|
20 |
+
codebert_model = RobertaForCausalLM.from_pretrained("microsoft/codebert-base", output_hidden_states=True)
|
21 |
+
codebert_model.eval()
|
|
|
|
|
|
|
22 |
|
23 |
# Contexto global para armazenar dados do APK
|
24 |
apk_context = {"smali": {}, "java": {}, "info": ""}
|
25 |
|
|
|
|
|
26 |
def check_java():
|
27 |
try:
|
28 |
result = subprocess.run(["java", "-version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
32 |
except Exception as e:
|
33 |
raise EnvironmentError(f"Erro inesperado ao verificar a instalação do Java: {str(e)}")
|
34 |
|
|
|
|
|
35 |
def install_tools():
|
36 |
baksmali_path = "/usr/local/bin/baksmali.jar"
|
37 |
jadx_path = "/usr/local/bin/jadx/bin/jadx"
|
38 |
|
|
|
39 |
check_java()
|
40 |
|
|
|
41 |
if not os.path.exists(baksmali_path):
|
42 |
print("Instalando o Baksmali...")
|
43 |
subprocess.run(
|
|
|
51 |
check=True,
|
52 |
)
|
53 |
|
|
|
54 |
jadx_zip_path = "/usr/local/bin/jadx.zip"
|
55 |
if not os.path.exists(jadx_path):
|
56 |
print("Instalando o JADX...")
|
|
|
70 |
else:
|
71 |
raise FileNotFoundError("Executável do JADX não encontrado no caminho esperado.")
|
72 |
|
|
|
|
|
73 |
def decompile_apk(apk_file):
|
74 |
if apk_file is None:
|
75 |
return "Nenhum arquivo enviado. Por favor, envie um arquivo APK."
|
|
|
77 |
temp_apk_path = apk_file.name
|
78 |
output_dir = tempfile.mkdtemp()
|
79 |
try:
|
|
|
80 |
smali_output = os.path.join(output_dir, "smali")
|
81 |
subprocess.run(
|
82 |
["java", "-jar", "/usr/local/bin/baksmali.jar", "d", temp_apk_path, "-o", smali_output],
|
83 |
check=True,
|
84 |
)
|
85 |
|
|
|
86 |
java_output = os.path.join(output_dir, "java")
|
87 |
subprocess.run(
|
88 |
["/usr/local/bin/jadx/bin/jadx", "-d", java_output, temp_apk_path],
|
89 |
check=True,
|
90 |
)
|
91 |
|
|
|
92 |
smali_files = {}
|
93 |
for root, _, files in os.walk(smali_output):
|
94 |
for file in files:
|
|
|
96 |
with open(os.path.join(root, file), "r") as f:
|
97 |
smali_files[file] = f.read()
|
98 |
|
|
|
99 |
java_files = {}
|
100 |
for root, _, files in os.walk(java_output):
|
101 |
for file in files:
|
|
|
103 |
with open(os.path.join(root, file), "r") as f:
|
104 |
java_files[file] = f.read()
|
105 |
|
|
|
106 |
apk_context["smali"] = smali_files
|
107 |
apk_context["java"] = java_files
|
108 |
|
|
|
111 |
except Exception as e:
|
112 |
return f"Erro durante a decompilação: {str(e)}"
|
113 |
|
114 |
+
def process_with_bloom(user_message):
|
115 |
+
inputs = bloom_tokenizer(user_message, return_tensors="pt", max_length=512, truncation=True)
|
116 |
+
with torch.no_grad():
|
117 |
+
outputs = bloom_model.generate(
|
118 |
+
inputs["input_ids"],
|
119 |
+
max_length=256,
|
120 |
+
num_return_sequences=1,
|
121 |
+
temperature=0.7,
|
122 |
+
top_p=0.9
|
123 |
+
)
|
124 |
+
processed_query = bloom_tokenizer.decode(outputs[0], skip_special_tokens=True)
|
125 |
+
return processed_query
|
126 |
|
|
|
127 |
def get_embeddings(text):
|
128 |
return indexing_model.encode(text, convert_to_tensor=True)
|
129 |
|
|
|
|
|
130 |
def query_apk_chat(user_message):
|
131 |
if not apk_context["smali"] and not apk_context["java"]:
|
132 |
return "Nenhum APK decompilado disponível. Por favor, envie e decompile um APK primeiro."
|
133 |
|
134 |
try:
|
135 |
+
# Processar a mensagem do usuário com BLOOM
|
136 |
+
processed_message = process_with_bloom(user_message)
|
137 |
+
|
138 |
+
# Obter embedding da query processada
|
139 |
+
query_embedding = get_embeddings(processed_message)
|
140 |
+
|
141 |
+
# Combinar Smali e Java para análise
|
142 |
+
combined_texts = [(k, v) for k, v in apk_context["smali"].items()] + [(k, v) for k, v in apk_context["java"].items()]
|
143 |
+
combined_embeddings = indexing_model.encode([v for _, v in combined_texts], convert_to_tensor=True)
|
144 |
+
|
145 |
+
# Encontrar códigos relevantes
|
146 |
+
scores = util.pytorch_cos_sim(query_embedding, combined_embeddings).squeeze(0)
|
147 |
+
top_k = min(3, len(combined_texts))
|
148 |
+
top_indices = torch.topk(scores, k=top_k).indices
|
149 |
+
|
150 |
+
response = ""
|
151 |
+
for idx in top_indices:
|
152 |
+
file_name, relevant_code = combined_texts[idx.item()]
|
153 |
+
|
154 |
+
# Gerar explicação usando CodeBERT com a query processada
|
155 |
+
explanation_prompt = f"Query processada: {processed_message}\nExplique o código:\n{relevant_code[:500]}"
|
156 |
+
inputs = tokenizer(explanation_prompt, return_tensors="pt", max_length=512, truncation=True, padding=True)
|
157 |
+
|
158 |
+
with torch.no_grad():
|
159 |
+
outputs = codebert_model.generate(
|
160 |
+
inputs["input_ids"],
|
161 |
+
max_length=1024,
|
162 |
+
num_return_sequences=1,
|
163 |
+
temperature=0.7,
|
164 |
+
top_p=0.9
|
165 |
+
)
|
166 |
+
explanation = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
167 |
+
|
168 |
+
response += f"\n\n**Arquivo:** {file_name}\n"
|
169 |
+
response += f"**Código:**\n```\n{relevant_code[:1000]}\n```\n"
|
170 |
+
response += f"**Explicação:**\n{explanation}\n"
|
171 |
+
response += "-" * 80
|
172 |
|
173 |
return response
|
174 |
|
175 |
except Exception as e:
|
176 |
+
return f"Erro durante a análise: {str(e)}"
|
|
|
177 |
|
178 |
+
# Configuração e inicialização
|
179 |
install_tools()
|
180 |
|
181 |
# Interfaces Gradio
|
|
|
183 |
fn=decompile_apk,
|
184 |
inputs=gr.File(label="Enviar arquivo APK", file_types=[".apk"]),
|
185 |
outputs="text",
|
186 |
+
title="Analisador de APK com BLOOM + CodeBERT",
|
187 |
+
description="Envie um arquivo APK para análise avançada com IA."
|
188 |
)
|
189 |
|
190 |
chat_interface = gr.Interface(
|
191 |
fn=query_apk_chat,
|
192 |
inputs=gr.Textbox(lines=3, placeholder="Faça uma pergunta sobre o código do APK..."),
|
193 |
+
outputs=gr.Textbox(lines=20, label="Análise Detalhada"),
|
194 |
+
title="Chat Avançado com APK",
|
195 |
+
description="Análise inteligente do código usando BLOOM para processamento de linguagem natural e CodeBERT para análise técnica."
|
196 |
+
)
|
197 |
+
|
198 |
+
# Interface combinada
|
199 |
+
iface = gr.TabbedInterface(
|
200 |
+
[apk_upload_interface, chat_interface],
|
201 |
+
["Enviar & Analisar", "Análise Inteligente"]
|
202 |
)
|
203 |
|
204 |
+
# Iniciar a interface
|
205 |
+
iface.launch()
|