forked from xcnkx/andro_pytool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeatures_managment.py
166 lines (134 loc) · 5.79 KB
/
features_managment.py
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
import re
import os
import lxml.etree as et
from aux_functions import *
from collections import Counter
from androguard.core.bytecodes import dvm
def opcodes_analysis(androguard_apk):
# http://blog.k3170makan.com/2014/11/automated-dex-decompilation-using.html
temp = {}
dalvik = dvm.DalvikVMFormat(androguard_apk.get_dex())
for current_class in dalvik.get_classes():
for method in current_class.get_methods():
byte_code = method.get_code()
if byte_code is not None:
byte_code = byte_code.get_bc()
for inst in byte_code.get_instructions():
inst_name = inst.get_name()
if inst_name not in temp:
temp[inst_name] = 1
else:
temp[inst_name] += 1
return temp
def get_str_opcodes(androguard_apk):
opcode_sequences = []
dalvik = dvm.DalvikVMFormat(androguard_apk.get_dex())
for current_class in dalvik.get_classes():
for method in current_class.get_methods():
byte_code = method.get_code()
if byte_code is not None:
byte_code = byte_code.get_bc()
for inst in byte_code.get_instructions():
inst_name = inst.get_name()
opcode_sequences.append(inst_name)
str_opcodes = ' '.join(opcode_sequences)
return str_opcodes
def check_for_intents(manifest, name, mode):
intent_results = []
if not os.path.isfile(manifest) or os.stat(manifest).st_size == 0:
return ['']
tree = et.parse(manifest)
root = tree.getroot()
for child in root:
child.find('application')
for x in child.iter(mode):
if any(name.endswith(t.encode('utf-8')) for t in x.attrib.values()):
for y in x:
if 'intent-filter' in y.tag:
for z in y:
if 'action' in z.tag:
intent_results.append(''.join(z.attrib.values()))
return list(set(intent_results))
def intents_analysis(manifest):
intent_results = []
tree = et.parse(manifest)
root = tree.getroot()
for child in root:
child.find('application')
for x in child.iter('activity'):
for y in x:
if 'intent-filter' in y.tag:
for z in y:
if 'action' in z.tag:
intent_results.append(''.join(z.attrib.values()))
for x in child.iter('service'):
for y in x:
if 'intent-filter' in y.tag:
for z in y:
if 'action' in z.tag:
intent_results.append(''.join(z.attrib.values()))
for x in child.iter('receiver'):
for y in x:
if 'intent-filter' in y.tag:
for z in y:
if 'action' in z.tag:
intent_results.append(''.join(z.attrib.values()))
return Counter(intent_results)
def read_smali_files(smali_list, api_packages_list, api_classes_list):
list_smali_api_calls = {}
list_smali_strings = []
for smali_file in smali_list:
with open(smali_file) as f:
content = f.readlines()
content = [x.strip() for x in content]
# SEARCHING STRINGS
splitted_string = [x.split() for x in content if 'const-string' in x]
acum = []
for elem in splitted_string:
elem = elem[2:]
acum.append(' '.join(elem).replace('\"', '').strip())
list_smali_strings.extend(acum)
# SEARCHING FOR API CALLS
content = [x for x in content if 'invoke-' in x or 'invoke-virtual' in x or 'invoke-direct' in x]
for elem in content:
# elem = elem.split('->')
elem = re.sub("\{[^]]*\}", lambda x: x.group(0).replace(',', ''),
elem) # Remove commands between brackets (invoke)
elem = re.split(', |;->', elem)
if len(elem) != 2:
# TODO CHECK IF CORRECT. Class not defined, so it must came from Object, but should be checked
try:
package = elem[1]
method = elem[2]
except IndexError:
print "Incorrect API calls transcription"
else:
package = "Object"
method = elem[1]
if package.startswith("L"):
package = package[1:]
package = package.split("/")
_class = package[-1]
del package[-1]
package = '.'.join(package)
method = method.split('(')[0]
if package in api_packages_list and _class in api_classes_list and method != '<init>':
pack_class = package + '.' + _class + '.' + method
if pack_class in list_smali_api_calls:
list_smali_api_calls[pack_class] += 1
else:
list_smali_api_calls[pack_class] = 1
return list_smali_api_calls, list_smali_strings
def read_strings_and_apicalls(analyze_apk, api_packages_list, api_classes_list):
unzip_apk(analyze_apk)
smali_files_list = list_files(analyze_apk.replace('.apk', '/'), '*.smali')
list_smali_api_calls, list_smali_strings = read_smali_files(smali_files_list, api_packages_list, api_classes_list)
return list_smali_api_calls, list_smali_strings
def read_system_commands(list_smali_strings, api_system_commands):
# System commands
list_system_commands = []
for elem in filter(None, list_smali_strings):
command_to_check_list = elem.split(' ')
if command_to_check_list[0] in api_system_commands:
list_system_commands.append(command_to_check_list[0])
return list_system_commands