-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathunpack-apk
executable file
·145 lines (119 loc) · 3.95 KB
/
unpack-apk
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
#!/bin/bash
set -euo pipefail
# Defaults.
TP="$(dirname "$(readlink -f "$0")")"/third_party
APKTOOL="$TP"/apktool/apktool.jar
DEX2JAR="$TP"/dex2jar/d2j-dex2jar.sh
PROCYON="$TP"/procyon/procyon-decompiler.jar
VDEXEX="$TP"/vdexExtractor/bin/vdexExtractor
while getopts "a:d:p:v:" o; do
case "$o" in
a) APKTOOL="$OPTARG" ;;
d) DEX2JAR="$OPTARG" ;;
p) PROCYON="$OPTARG" ;;
v) VDEXEX="$OPTARG" ;;
esac
done
shift $((OPTIND-1))
if [[ ! -e "$APKTOOL" ]]; then
echo "apktool not found at $APKTOOL. Try make -C ${TP} or pass the path to it with -a." >&2
exit 1
fi
if [[ ! -e "$DEX2JAR" ]]; then
echo "dex2jar not found at $DEX2JAR. Try make -C ${TP} or pass the path to it with -d." >&2
exit 1
fi
if [[ ! -e "$PROCYON" ]]; then
echo "procyon-decompiler not found at $PROCYON. Try make -C ${TP} or pass the path to it with -p." >&2
exit 1
fi
if [[ ! -e "$VDEXEX" ]]; then
echo "jd-vdexExtractor not found at $VDEXEX. Try make -C ${TP} or pass the path to it with -v." >&2
exit 1
fi
apk="$(readlink -f "$1")"
framework="${2:-}"
if [[ "$framework" ]]; then
framework="$(readlink -f "$framework")"
fi
apktool() {
java -jar "$APKTOOL" "$@"
}
procyon() {
java -jar "$PROCYON" "$@"
}
outdir="${apk%.apk}"
if [[ "$outdir" == "$apk" ]]; then
outdir="${apk}.out"
fi
if [[ -e "$outdir" ]]; then
echo "Destination directory '$outdir' already exists, can't continue." >&2
exit 1
fi
# Main code starts here.
echo "Unpacking $apk to $outdir"
tmpdir="$(mktemp -d)"
trap "rm -rf '$tmpdir'" EXIT
cd "$tmpdir"
# Temporary .apk for apktool and dex2jar to work with, potentially updated with a classes.dex.
tmpapk="${tmpdir}/$(basename "$apk")"
cp -v "$apk" "$tmpapk"
# Generate classes.dex from .vdex, if necessary.
if ! zipinfo "$tmpapk" classes.dex >/dev/null 2>&1; then
apkdir="$(dirname "$apk")" # look next to original .apk
vdex="$(find "$apkdir" -type f -name '*.vdex')"
# If there is not exactly one match from find, the -f will test for "foo.vdex bar.vdex" (or "")
# and fail.
if [[ ! -f "$vdex" ]]; then
echo "Not exactly one *.vdex file found in $apkdir and APK has no classes.dex, can't continue." >&2
exit 1
fi
echo "Generating classes*.dex from $vdex"
# Extract to $tmpdir.
"$VDEXEX" -i "$vdex" -o "$tmpdir"
# vdexExtractor names the generated files foo_classes*.dex if the input file was called foo.vdex,
# and dex2jar expects classes*.dex, so remove any prefix.
for dex in *.dex; do
new="${dex##*_}"
if [[ "$new" != "$dex" ]]; then
mv -v "$dex" "$new"
fi
done
# Stuff classes*.dex back into the .apk.
for dex in *.dex; do
case "$dex" in
classes*.dex)
zip "$tmpapk" "$dex" # Tested with Info-ZIP 3.0.
rm -vf "$dex" # There is zip -m (move), but who knows which zips support that.
;;
*)
echo "Unknown file '$dex' generated by vdexExtractor (not matching classes*.dex)" >&2
exit 1
;;
esac
done
fi
tmpout="${tmpdir}/_out" # To move to $outdir.
# Add framework apks for apktool.
fwargs=() # --frame-path for apktool if necessary
if [[ "$framework" ]]; then
fwargs=(-p "${tmpdir}/_framework")
find "$framework" -name '*.apk'|while read apk; do
apktool install-framework "${fwargs[@]}" "$apk"
done
fi
# Unpack .apk with apktool.
apktool decode "${fwargs[@]}" -o "$tmpout" "$tmpapk"
# Make .jar from .apk.
if ! "$DEX2JAR" -o "$tmpout"/classes.jar "$tmpapk"; then
echo "Couldn't create classes.jar from .apk, skipping decompilation." >&2
else
# Decompile .jar.
if ! procyon "$tmpout"/classes.jar -o "$tmpout"/java; then
echo "Warning: procyon failed, adding .partial suffix to decompilation result directory." >&2
mv -v "$tmpout"/java "$tmpout"/java.partial
fi
fi
# Move.
mv -vf "$tmpout" "$outdir"
echo "Successfully unpacked $apk to $outdir"