Skip to content
This repository was archived by the owner on Aug 31, 2023. It is now read-only.

Commit 6178b6c

Browse files
author
thez3ro
committed
Rewrited in python
1 parent 08045aa commit 6178b6c

24 files changed

Lines changed: 181 additions & 698 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Tools used
3939
--------------------
4040
Dex2jar : http://code.google.com/p/dex2jar/
4141

42-
JAD : http://www.varaneckas.com/jad
42+
Procyon : https://bitbucket.org/mstrobel/procyon/wiki/Java%20Decompiler
4343

4444
apk-tool : http://code.google.com/p/android-apktool/
4545

apk2java

Lines changed: 0 additions & 194 deletions
This file was deleted.

apk2java.py

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#!/usr/bin/env python2
2+
# -*- coding: utf-8 -*-
3+
#
4+
5+
import sys, os, string
6+
import urllib
7+
import zipfile
8+
from subprocess import call
9+
from optparse import OptionParser
10+
11+
apk_file=''
12+
apk_folder=''
13+
project_name=''
14+
sign_file=''
15+
home=os.path.dirname(os.path.realpath(sys.argv[0]))
16+
tmp='/tmp/apk2java/'
17+
external="https://github.com/TheZ3ro/apk2java-linux/archive/master.zip"
18+
19+
def check_home(path):
20+
return os.path.isdir(path+"/tool")
21+
22+
def getunzipped(theurl, thedir, report):
23+
print "Downloading external tool..."
24+
name = os.path.join(thedir, 'temp.zip')
25+
try:
26+
name, hdrs = urllib.urlretrieve(theurl, name, report)
27+
except IOError, e:
28+
print "Can't retrieve %r to %r: %s" % (theurl, thedir, e)
29+
return
30+
try:
31+
z = zipfile.ZipFile(name)
32+
except zipfile.error, e:
33+
print "Bad zipfile (from %r): %s" % (theurl, e)
34+
return
35+
for n in z.namelist():
36+
(dirname, filename) = os.path.split(n)
37+
if filename == '':
38+
# directory
39+
newdir = thedir + '/' + dirname
40+
if not os.path.exists(newdir):
41+
os.mkdir(newdir)
42+
else:
43+
# file
44+
fd = open(thedir+"/"+n, 'w')
45+
fd.write(z.read(n))
46+
fd.close()
47+
z.close()
48+
os.unlink(name)
49+
50+
def report(blocknr, blocksize, size):
51+
current = blocknr*blocksize
52+
sys.stdout.write("\rProgress: {0:.2f}%".format(100.0*current/size))
53+
54+
def apktool(smali):
55+
print "*********************************************"
56+
print "** Extract, fix resource files **"
57+
print "*********************************************"
58+
if apk_file != '':
59+
if smali == True:
60+
call(home+'/tool/apktool_200rc3.jar d '+apk_file+' -o '+tmp+project_name+' -f',shell=True)
61+
else:
62+
call(home+'/tool/apktool_200rc3.jar d '+apk_file+' -o '+tmp+project_name+' -sf',shell=True)
63+
os.system('mv %s %s' % (tmp+project_name+'/classes.dex', tmp+project_name+'/original/'))
64+
print 'Done'
65+
66+
def dex2jar():
67+
print "*********************************************"
68+
print "** Convert 'apk' to 'jar' **"
69+
print "*********************************************"
70+
if apk_file != '':
71+
call(home+'/tool/dex2jar-0.0.9.15/d2j-dex2jar.sh -f -o '+tmp+project_name+'.jar '+apk_file, shell=True)
72+
call(home+'/tool/dex2jar-0.0.9.15/d2j-asm-verify.sh '+tmp+project_name+'.jar',shell=True)
73+
print 'Done'
74+
75+
def procyon():
76+
print "*********************************************"
77+
print "** Decompiling class files **"
78+
print "*********************************************"
79+
if apk_file != '':
80+
call(home+'/tool/procyon-decompiler-0528.jar -jar '+tmp+project_name+'.jar -o '+tmp+project_name+'/src/',shell=True)
81+
print 'Done'
82+
83+
def apktool_build():
84+
print "*********************************************"
85+
print "** Building apk from smali **"
86+
print "*********************************************"
87+
if apk_folder != '':
88+
call(home+'/tool/apktool_200rc3.jar b '+apk_folder+' -o '+tmp+project_name+'-rebuild.apk',shell=True)
89+
global sign_file
90+
sign_file = tmp+project_name+'-rebuild.apk'
91+
print 'Done'
92+
93+
def jar2jasmin():
94+
print "*********************************************"
95+
print "** Convert 'jar' to 'jasmin' **"
96+
print "*********************************************"
97+
if apk_file != '':
98+
call(home+'/tool/dex2jar-0.0.9.15/d2j-jar2jasmin.sh -f -o '+tmp+project_name+'/jasmin '+tmp+project_name+'.jar',shell=True)
99+
print 'Done'
100+
101+
def jasmin_build():
102+
print "*********************************************"
103+
print "** Build apk from jasmin **"
104+
print "*********************************************"
105+
if apk_folder != '':
106+
call(home+'/tool/dex2jar-0.0.9.15/d2j-jasmin2jar.sh -f -o '+tmp+project_name+'-new.jar '+tmp+project_name+'/jasmin',shell=True)
107+
call(home+'/tool/dex2jar-0.0.9.15/d2j-asm-verify.sh '+tmp+project_name+'-new.jar',shell=True)
108+
call(home+'/tool/dex2jar-0.0.9.15/d2j-jar2dex.sh -f -o '+tmp+project_name+'/classes.dex '+tmp+project_name+'-new.jar',shell=True)
109+
call('zip -r '+tmp+project_name+'-new.apk -j '+tmp+project_name+'/classes.dex',shell=True)
110+
global sign_file
111+
sign_file = tmp+project_name+'-new.apk'
112+
print 'Done'
113+
114+
def sign():
115+
print "*********************************************"
116+
print "** Sign apk **"
117+
print "*********************************************"
118+
call(home+'/tool/dex2jar-0.0.9.15/d2j-apk-sign.sh -f -o '+tmp+project_name+'-signed.apk '+sign_file,shell=True)
119+
120+
def main():
121+
global apk_folder,apk_file,project_name,home
122+
usage = "usage: %prog action file [options]"
123+
parser = OptionParser(usage=usage)
124+
parser.add_option("--java",action="store_true", dest="java", default=True, help="select java source format [DEFAULT]")
125+
parser.add_option("--smali",action="store_true", dest="smali", default=False, help="select smali source format")
126+
parser.add_option("--jasmin",action="store_true", dest="jasmin", default=False, help="select jasmin source format")
127+
parser.add_option("--no-source",action="store_true", dest="nosc", default=False, help="no source code generation")
128+
(options, args) = parser.parse_args()
129+
130+
if home == "/opt/apk2java":
131+
if check_home(home) == False:
132+
getunzipped(external, home, report)
133+
else:
134+
if check_home(home) == False and check_home("/opt/apk2java") == False:
135+
getunzipped(external, "/opt/apk2java", report)
136+
home = "/opt/apk2java"
137+
138+
exit(0)
139+
140+
if (options.smali+options.jasmin+options.nosc) > 1:
141+
print "[ ERROR ] You can only select 1 source format --[smali/jasmin/java/no-source]"
142+
exit(1)
143+
if len(args)==2:
144+
if args[0] == 'd':
145+
if os.path.isfile(args[1]) and os.path.splitext(args[1])[-1].lower() == '.apk':
146+
apk_file = args[1]
147+
project_name = os.path.splitext(os.path.basename(args[1]))[0].lower()
148+
call("cp "+apk_file+" "+tmp+project_name+"-new.apk",shell=True)
149+
if options.jasmin == True:
150+
dex2jar()
151+
jar2jasmin()
152+
else:
153+
apktool(options.smali)
154+
if options.smali == False and options.nosc == False:
155+
dex2jar()
156+
procyon()
157+
else:
158+
print "[ ERROR ] You must select a valid APK file!"
159+
exit(1)
160+
elif args[0] == 'b':
161+
if os.path.isdir(args[1]):
162+
apk_folder = args[1]
163+
project_name = os.path.basename(os.path.dirname(args[1]).lower())
164+
print project_name
165+
if options.jasmin == True:
166+
jasmin_build()
167+
elif options.smali == True:
168+
apktool_build()
169+
else:
170+
print "[ ERROR ] Can't build apk with that source format. Only Jasmin or Smali supported"
171+
sign()
172+
else:
173+
parser.error("action can be only 'b' (build) or 'd' (decompile)")
174+
else:
175+
parser.print_help()
176+
177+
# Script start Here
178+
if __name__=="__main__":
179+
main()
180+

0 commit comments

Comments
 (0)