nsv2042 commited on
Commit
f49bd67
1 Parent(s): a1b79b1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +158 -121
app.py CHANGED
@@ -1,121 +1,158 @@
1
- import gradio as gr
2
- import tempfile
3
- import os
4
- import subprocess
5
- from androguard.misc import AnalyzeAPK
6
- from transformers import pipeline, Conversation
7
- from sentence_transformers import SentenceTransformer, util
8
- import json
9
-
10
- # Global storage
11
- apk_context = {"smali": {}, "java": {}, "info": ""}
12
-
13
- # Step 1: Decompile APK
14
- def decompile_apk(apk_file):
15
- if apk_file is None:
16
- return "No file uploaded. Please upload an APK file."
17
-
18
- temp_apk_path = None
19
- output_dir = tempfile.mkdtemp()
20
- try:
21
- with tempfile.NamedTemporaryFile(delete=False, suffix=".apk") as temp_apk:
22
- temp_apk.write(apk_file.read())
23
- temp_apk_path = temp_apk.name
24
-
25
- # Decompile APK to Smali
26
- smali_output = os.path.join(output_dir, "smali")
27
- subprocess.run(["baksmali", "d", temp_apk_path, "-o", smali_output], check=True)
28
-
29
- # Decompile APK to Java
30
- java_output = os.path.join(output_dir, "java")
31
- subprocess.run(["jadx", "-d", java_output, temp_apk_path], check=True)
32
-
33
- # Load Smali and Java content
34
- smali_files = {}
35
- for root, _, files in os.walk(smali_output):
36
- for file in files:
37
- if file.endswith(".smali"):
38
- with open(os.path.join(root, file), "r") as f:
39
- smali_files[file] = f.read()
40
-
41
- java_files = {}
42
- for root, _, files in os.walk(java_output):
43
- for file in files:
44
- if file.endswith(".java"):
45
- with open(os.path.join(root, file), "r") as f:
46
- java_files[file] = f.read()
47
-
48
- # Save to global context
49
- apk_context["smali"] = smali_files
50
- apk_context["java"] = java_files
51
-
52
- return f"Decompilation successful. Extracted {len(smali_files)} Smali files and {len(java_files)} Java files."
53
-
54
- except Exception as e:
55
- return f"Error during decompilation: {str(e)}"
56
- finally:
57
- if temp_apk_path and os.path.exists(temp_apk_path):
58
- os.unlink(temp_apk_path)
59
-
60
- # Step 2: Build Searchable Database
61
- def build_search_index():
62
- smali_texts = [f"{k}\n{v}" for k, v in apk_context["smali"].items()]
63
- java_texts = [f"{k}\n{v}" for k, v in apk_context["java"].items()]
64
-
65
- # Use SentenceTransformer for embeddings
66
- model = SentenceTransformer('all-MiniLM-L6-v2')
67
-
68
- smali_embeddings = model.encode(smali_texts, convert_to_tensor=True)
69
- java_embeddings = model.encode(java_texts, convert_to_tensor=True)
70
-
71
- return model, smali_texts, smali_embeddings, java_texts, java_embeddings
72
-
73
- # Step 3: Query Chatbot
74
- def query_apk_chat(user_message):
75
- if not apk_context["smali"] and not apk_context["java"]:
76
- return "No decompiled APK available. Please upload and decompile an APK first."
77
-
78
- try:
79
- # Build the search index
80
- model, smali_texts, smali_embeddings, java_texts, java_embeddings = build_search_index()
81
-
82
- # Encode user message
83
- query_embedding = model.encode(user_message, convert_to_tensor=True)
84
-
85
- # Search Smali and Java
86
- smali_scores = util.pytorch_cos_sim(query_embedding, smali_embeddings).squeeze(0)
87
- java_scores = util.pytorch_cos_sim(query_embedding, java_embeddings).squeeze(0)
88
-
89
- # Get top matches
90
- smali_result = smali_texts[smali_scores.argmax().item()]
91
- java_result = java_texts[java_scores.argmax().item()]
92
-
93
- # Combine results into a response
94
- response = f"**Relevant Smali Code:**\n\n{smali_result[:1000]}\n\n"
95
- response += f"**Relevant Java Code:**\n\n{java_result[:1000]}"
96
-
97
- return response
98
-
99
- except Exception as e:
100
- return f"Error during search: {str(e)}"
101
-
102
- # Gradio Interface
103
- apk_upload_interface = gr.Interface(
104
- fn=decompile_apk,
105
- inputs=gr.File(label="Upload APK File", file_types=['.apk']),
106
- outputs="text",
107
- title="APK Analyzer with Full Source Access",
108
- description="Upload an APK to decompile it into Smali and Java source code."
109
- )
110
-
111
- chat_interface = gr.Interface(
112
- fn=query_apk_chat,
113
- inputs="text",
114
- outputs="text",
115
- title="APK Chatbot",
116
- description="Ask questions about the APK's source code in Smali or Java."
117
- )
118
-
119
- # Combine interfaces into tabs
120
- iface = gr.TabbedInterface([apk_upload_interface, chat_interface], ["Upload & Decompile", "Chat with Source"])
121
- iface.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import tempfile
3
+ import subprocess
4
+ from androguard.misc import AnalyzeAPK
5
+ from transformers import pipeline, Conversation
6
+ from sentence_transformers import SentenceTransformer, util
7
+ import gradio as gr
8
+
9
+ # Global storage for APK data
10
+ apk_context = {"smali": {}, "java": {}, "info": ""}
11
+
12
+ # Function to install Baksmali and JADX
13
+ def install_tools():
14
+ baksmali_path = "/usr/local/bin/baksmali.jar"
15
+ jadx_path = "/usr/local/bin/jadx"
16
+
17
+ # Install Baksmali if not present
18
+ if not os.path.exists(baksmali_path):
19
+ print("Installing Baksmali...")
20
+ subprocess.run(
21
+ [
22
+ "curl",
23
+ "-L",
24
+ "-o",
25
+ baksmali_path,
26
+ "https://bitbucket.org/JesusFreke/smali/downloads/baksmali-2.5.2.jar"
27
+ ],
28
+ check=True
29
+ )
30
+
31
+ # Install JADX if not present
32
+ if not os.path.exists(jadx_path):
33
+ print("Installing JADX...")
34
+ subprocess.run(
35
+ [
36
+ "curl",
37
+ "-L",
38
+ "-o",
39
+ "/usr/local/bin/jadx.zip",
40
+ "https://github.com/skylot/jadx/releases/download/v1.4.7/jadx-1.4.7.zip"
41
+ ],
42
+ check=True
43
+ )
44
+ subprocess.run(["unzip", "-o", "/usr/local/bin/jadx.zip", "-d", "/usr/local/bin"], check=True)
45
+ subprocess.run(["chmod", "+x", "/usr/local/bin/jadx/bin/jadx"], check=True)
46
+
47
+ # Install tools at the start of the app
48
+ install_tools()
49
+
50
+ # Step 1: Decompile APK
51
+ def decompile_apk(apk_file):
52
+ if apk_file is None:
53
+ return "No file uploaded. Please upload an APK file."
54
+
55
+ temp_apk_path = None
56
+ output_dir = tempfile.mkdtemp()
57
+ try:
58
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".apk") as temp_apk:
59
+ temp_apk.write(apk_file.read())
60
+ temp_apk_path = temp_apk.name
61
+
62
+ # Decompile APK to Smali
63
+ smali_output = os.path.join(output_dir, "smali")
64
+ subprocess.run(["java", "-jar", "/usr/local/bin/baksmali.jar", "d", temp_apk_path, "-o", smali_output], check=True)
65
+
66
+ # Decompile APK to Java
67
+ java_output = os.path.join(output_dir, "java")
68
+ subprocess.run(["/usr/local/bin/jadx/bin/jadx", "-d", java_output, temp_apk_path], check=True)
69
+
70
+ # Load Smali and Java content
71
+ smali_files = {}
72
+ for root, _, files in os.walk(smali_output):
73
+ for file in files:
74
+ if file.endswith(".smali"):
75
+ with open(os.path.join(root, file), "r") as f:
76
+ smali_files[file] = f.read()
77
+
78
+ java_files = {}
79
+ for root, _, files in os.walk(java_output):
80
+ for file in files:
81
+ if file.endswith(".java"):
82
+ with open(os.path.join(root, file), "r") as f:
83
+ java_files[file] = f.read()
84
+
85
+ # Save to global context
86
+ apk_context["smali"] = smali_files
87
+ apk_context["java"] = java_files
88
+
89
+ return f"Decompilation successful. Extracted {len(smali_files)} Smali files and {len(java_files)} Java files."
90
+
91
+ except Exception as e:
92
+ return f"Error during decompilation: {str(e)}"
93
+ finally:
94
+ if temp_apk_path and os.path.exists(temp_apk_path):
95
+ os.unlink(temp_apk_path)
96
+
97
+ # Step 2: Build Searchable Database
98
+ def build_search_index():
99
+ smali_texts = [f"{k}\n{v}" for k, v in apk_context["smali"].items()]
100
+ java_texts = [f"{k}\n{v}" for k, v in apk_context["java"].items()]
101
+
102
+ # Use SentenceTransformer for embeddings
103
+ model = SentenceTransformer('all-MiniLM-L6-v2')
104
+
105
+ smali_embeddings = model.encode(smali_texts, convert_to_tensor=True)
106
+ java_embeddings = model.encode(java_texts, convert_to_tensor=True)
107
+
108
+ return model, smali_texts, smali_embeddings, java_texts, java_embeddings
109
+
110
+ # Step 3: Query Chatbot
111
+ def query_apk_chat(user_message):
112
+ if not apk_context["smali"] and not apk_context["java"]:
113
+ return "No decompiled APK available. Please upload and decompile an APK first."
114
+
115
+ try:
116
+ # Build the search index
117
+ model, smali_texts, smali_embeddings, java_texts, java_embeddings = build_search_index()
118
+
119
+ # Encode user message
120
+ query_embedding = model.encode(user_message, convert_to_tensor=True)
121
+
122
+ # Search Smali and Java
123
+ smali_scores = util.pytorch_cos_sim(query_embedding, smali_embeddings).squeeze(0)
124
+ java_scores = util.pytorch_cos_sim(query_embedding, java_embeddings).squeeze(0)
125
+
126
+ # Get top matches
127
+ smali_result = smali_texts[smali_scores.argmax().item()]
128
+ java_result = java_texts[java_scores.argmax().item()]
129
+
130
+ # Combine results into a response
131
+ response = f"**Relevant Smali Code:**\n\n{smali_result[:1000]}\n\n"
132
+ response += f"**Relevant Java Code:**\n\n{java_result[:1000]}"
133
+
134
+ return response
135
+
136
+ except Exception as e:
137
+ return f"Error during search: {str(e)}"
138
+
139
+ # Gradio Interface
140
+ apk_upload_interface = gr.Interface(
141
+ fn=decompile_apk,
142
+ inputs=gr.File(label="Upload APK File", file_types=['.apk']),
143
+ outputs="text",
144
+ title="APK Analyzer with Full Source Access",
145
+ description="Upload an APK to decompile it into Smali and Java source code."
146
+ )
147
+
148
+ chat_interface = gr.Interface(
149
+ fn=query_apk_chat,
150
+ inputs="text",
151
+ outputs="text",
152
+ title="APK Chatbot",
153
+ description="Ask questions about the APK's source code in Smali or Java."
154
+ )
155
+
156
+ # Combine interfaces into tabs
157
+ iface = gr.TabbedInterface([apk_upload_interface, chat_interface], ["Upload & Decompile", "Chat with Source"])
158
+ iface.launch()