Skip to content

Commit 086aef4

Browse files
Hamiltonian CycleHamiltonian Cycle
Hamiltonian Cycle
authored and
Hamiltonian Cycle
committed
Commit all the things!!
0 parents  commit 086aef4

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

ClassNameDeobfuscator.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import argparse
2+
import os
3+
from SmaliFile import SmaliFile
4+
5+
__author__ = 'HamiltonianPath'
6+
7+
8+
def parse_args():
9+
parser = argparse.ArgumentParser(description='Execute in the smali directory of a disassembled APK')
10+
parser.add_argument('namespace', type=str, help='base namespace to begin deobfuscating classes')
11+
parser.add_argument('-o', dest='outfile', default=None, metavar='output.txt', type=str, help='output filename to save deobfusacted class mapping')
12+
return parser.parse_args()
13+
14+
15+
class ClassNameDeobfuscator():
16+
def __init__(self, namespace, outfilepath):
17+
self.namespace = namespace
18+
self.outfilepath = outfilepath
19+
self.outfile = None
20+
if self.outfilepath:
21+
self.outfile = open(self.outfilepath, 'w')
22+
23+
def out(self, message):
24+
if self.outfile:
25+
self.outfile.write(message + '\n')
26+
else:
27+
print(message)
28+
29+
def namespace_to_path(self, namespace):
30+
return namespace.replace('.', os.path.sep)
31+
32+
def path_to_namespace(self, path):
33+
return path.replace(os.path.sep, '.')
34+
35+
def ensure_namespace_dir_exists(self, namespace_dir):
36+
return os.path.isdir(namespace_dir)
37+
38+
def parse_classname_from_source_line(self, source_line):
39+
try:
40+
return source_line.split(' ')[1].strip().strip('"')
41+
except IndexError:
42+
return 'ERROR_WHILE_DEOBFUSCATING_CLASS_NAME'
43+
44+
def deobfuscate_smali_file_class(self, namespace_path, filename):
45+
filepath = os.path.join(namespace_path, filename)
46+
smali_file = SmaliFile(filepath)
47+
for line in smali_file.raw_lines:
48+
if line.startswith('.source'):
49+
return self.parse_classname_from_source_line(line)
50+
51+
def walk_namespace_dir(self, namespace_dir):
52+
self.out(' [*] Deobfuscating class names from namespace {0}...'.format(self.path_to_namespace(namespace_dir)))
53+
for dirpath, dirnames, filenames in os.walk(namespace_dir):
54+
namespace = self.path_to_namespace(dirpath)
55+
for file in filenames:
56+
if file.endswith('smali'):
57+
obfuscated_full_namesapce = '{0}.{1}'.format(namespace, file)
58+
deobfuscated_name = self.deobfuscate_smali_file_class(dirpath, file)
59+
deobfuscated_full_namepsace = '{0}.{1}'.format(namespace, deobfuscated_name)
60+
self.out('{0} => {1}'.format(obfuscated_full_namesapce, deobfuscated_full_namepsace))
61+
62+
def execute(self):
63+
namespace_dir = self.namespace_to_path(self.namespace)
64+
if not self.ensure_namespace_dir_exists(namespace_dir):
65+
self.out(' [E] Could not find directory {0} for given namespace {1}'.format(namespace_dir, self.namespace))
66+
return
67+
68+
self.walk_namespace_dir(namespace_dir)
69+
70+
if self.outfile:
71+
self.outfile.close()
72+
73+
74+
def main():
75+
args = parse_args()
76+
deobfuscator = ClassNameDeobfuscator(args.namespace, args.outfile)
77+
deobfuscator.execute()
78+
79+
if __name__ == '__main__':
80+
main()

SmaliFile.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
__author__ = 'HamiltonianPath'
2+
3+
4+
class SmaliFile:
5+
"""A class to represent a Smali file."""
6+
7+
raw_lines = [] # A list of all lines in the Smali file.
8+
9+
def __init__(self, filepath=None):
10+
if filepath:
11+
self.readsmalifile(filepath)
12+
13+
def readsmalifile(self, filepath):
14+
f = open(filepath, 'r')
15+
self.raw_lines = f.readlines()

0 commit comments

Comments
 (0)