Repository navigation
Expand file tree
/
Copy pathutils.py
More file actions
116 lines (97 loc) · 3.63 KB
/
Copy pathutils.py
File metadata and controls
116 lines (97 loc) · 3.63 KB
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
import os
import subprocess
import xml.etree.ElementTree as ET
import numpy as np
import tempfile
import shutil
from dotenv import load_dotenv
load_dotenv()
apktool_jar_path = os.getenv("APKTOOL_JAR_PATH")
def decompile_apk(apk_path, output_dir):
"""
Decompile an APK file using apktool
Parameters:
apk_path (str): Path to the APK file
output_dir (str): Directory where the decompiled APK will be stored
Returns:
bool: True if decompilation was successful, False otherwise
"""
try:
os.makedirs(output_dir, exist_ok=True)
result = subprocess.run(
["java", "-jar", apktool_jar_path, "d", apk_path, "-o", output_dir, "-f"],
capture_output=True,
text=True,
check=True
)
return True
except subprocess.CalledProcessError as e:
print(f"Error decompiling APK: {e}")
print(f"Output: {e.stdout}")
print(f"Error: {e.stderr}")
return False
except Exception as e:
print(f"Unexpected error: {e}")
return False
def extract_permissions(decompiled_dir):
"""
Extract permissions from the AndroidManifest.xml file
Parameters:
decompiled_dir (str): Directory containing the decompiled APK
Returns:
list: List of Android permissions found in the manifest
"""
manifest_path = os.path.join(decompiled_dir, "AndroidManifest.xml")
permissions = []
try:
# Parse XML structure of AndroidManifest.xml
tree = ET.parse(manifest_path)
root = tree.getroot()
# Define the Android namespace
android_ns = '{http://schemas.android.com/apk/res/android}'
# Find all permission elements
for permission_elem in root.findall(".//uses-permission"):
permission_name = permission_elem.get(f'{android_ns}name')
if permission_name:
permissions.append(permission_name)
return permissions
except Exception as e:
print(f"Error extracting permissions: {e}")
return []
def permissions_to_features(permissions, all_permissions):
"""
Convert a list of permissions to a feature vector
Parameters:
permissions (list): List of permissions extracted from the APK
all_permissions (list): List of all possible permissions from the training data
Returns:
numpy.ndarray: Feature vector with 1 for permissions present, 0 for permissions absent
"""
# Create a feature vector initialized with zeros then set 1 for permissions that are present
features = np.zeros(len(all_permissions))
for i, permission in enumerate(all_permissions):
if permission in permissions:
features[i] = 1
return features
def process_apk(apk_path, all_permissions):
"""
Process an APK file to extract features for prediction
Parameters:
apk_path (str): Path to the APK file
all_permissions (list): List of all possible permissions from the training data
Returns:
numpy.ndarray: Feature vector for the APK, or None if processing failed
"""
temp_dir = tempfile.mkdtemp() # Create a temporary director to store decompiled APK
try:
if not decompile_apk(apk_path, temp_dir):
return None
permissions = extract_permissions(temp_dir)
features = permissions_to_features(permissions, all_permissions)
return features
except Exception as e:
print(f"Error processing APK: {e}")
return None
finally:
# Clean up the temporary directory
shutil.rmtree(temp_dir, ignore_errors=True)