-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapkextractor_sync.sh
executable file
·226 lines (186 loc) · 7.24 KB
/
apkextractor_sync.sh
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#!/bin/bash
# apkextractor_sync.sh - Combines APK extraction and synchronization to the server
# pass appID as an argument, ie: ./apkextractor_sync.sh com.gemwallet.android [user@server]
set -e
# Initialize the bundletoolPath variable
bundletoolPath=""
# Function to check if a command exists and print status
check_command() {
if command -v $1 &> /dev/null || alias | grep -q "$1"; then
echo -e "$1 - \033[1;32m☑ installed\033[0m"
else
echo -e "$1 - \033[1;31m[x] not installed\033[0m"
MISSING_DEPENDENCIES=true
fi
}
is_app_installed() {
local package_name="$1"
if adb shell pm list packages | grep -q "^package:$package_name$"; then
return 0 # App is installed
else
return 1 # App is not installed
fi
}
get_version_code() {
local apk_path="$1"
aapt dump badging "$apk_path" | grep versionCode | awk '{print $3}' | sed "s/versionCode='//" | sed "s/'//"
}
get_full_apk_name() {
local package_name="$1"
local apk_path=$(adb shell pm path "$package_name" | grep "base.apk" | cut -d':' -f2 | tr -d '\r')
if [ -z "$apk_path" ]; then
echo "Error: Could not find base.apk for $package_name" >&2
return 1
fi
local apk_name=$(adb shell ls -l "$apk_path" | awk '{print $NF}')
echo "$apk_name"
}
# Function to determine naming convention
determine_naming_convention() {
local dir="$1"
local app_id="$2"
if ssh $sshCredentials "ls $dir/${app_id}_v* 2>/dev/null"; then
echo "convention1"
elif ssh $sshCredentials "ls $dir/${app_id}-* 2>/dev/null"; then
echo "convention2"
else
echo "convention1" # Default to convention1 if no existing files
fi
}
if [ -z "$1" ]; then
echo -e "\033[1;31mError: No bundle ID provided. Usage: $0 <bundleId> [user@server]\033[0m]"
exit 1
fi
bundleId="$1"
echo "bundleId=\"$bundleId\""
# Check if the app is installed before proceeding
if ! is_app_installed "$bundleId"; then
echo -e "\033[1;31mError: The app '$bundleId' is not installed on the connected device.\033[0m"
exit 1
fi
# Get the full APK name including version
full_apk_name=$(get_full_apk_name "$bundleId")
if [ $? -ne 0 ]; then
echo "Failed to get full APK name. Exiting."
exit 1
fi
echo "Full APK name: $full_apk_name"
# Show and execute the command to get apk paths
echo "Retrieving APK paths for bundle ID: $bundleId"
apks=$(adb shell pm path $bundleId)
# Check if bundletool is installed
check_bundletool() {
echo "Checking for bundletool in /usr/local/lib and /usr/share/java..."
if [ -f "/usr/local/lib/bundletool.jar" ]; then
bundletoolPath="/usr/local/lib/bundletool.jar"
echo -e "bundletool - \033[1;32m☑ installed\033[0m"
echo "Bundletool location: /usr/local/lib/bundletool.jar"
elif [ -f "/usr/share/java/bundletool.jar" ]; then
bundletoolPath="/usr/share/java/bundletool.jar"
echo -e "bundletool - \033[1;32m☑ installed\033[0m"
echo "Bundletool location: /usr/share/java/bundletool.jar"
else
echo "Checking for bundletool alias in ~/.bashrc..."
if grep -q "alias bundletool=" ~/.bashrc; then
bundletoolPath=$(grep "alias bundletool=" ~/.bashrc | sed -e "s/alias bundletool=\'//" -e "s/\'$//")
echo -e "bundletool - \033[1;32m☑ installed\033[0m"
echo "Bundletool alias found in ~/.bashrc"
echo "Bundletool location: $bundletoolPath"
else
echo -e "bundletool - \033[1;31m[x] not installed\033[0m"
echo "Please ensure bundletool is installed and available in your PATH."
MISSING_DEPENDENCIES=true
fi
fi
}
MISSING_DEPENDENCIES=false
# Check if adb is installed
check_command "adb"
# Check if java is installed
check_command "java"
# Check if aapt is installed
check_command "aapt"
# Check if bundletool is installed
check_bundletool
if [ "$MISSING_DEPENDENCIES" = true ]; then
echo -e "\033[1;31mPlease install the missing dependencies before running the script.\033[0m"
exit 1
fi
# Check if a phone is connected
connected_devices=$(adb devices | grep -w "device")
if [ -z "$connected_devices" ]; then
echo -e "\033[1;31m▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮ No phone is connected. Exiting program ▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮\033[0m"
exit 1
else
echo -e "\033[1;32mDevice connected successfully.\033[0m"
echo "Device information:"
adb devices
echo "Model: $(adb shell getprop ro.product.model)"
echo "Manufacturer: $(adb shell getprop ro.product.manufacturer)"
echo "Android Version: $(adb shell getprop ro.build.version.release)"
echo "SDK Version: $(adb shell getprop ro.build.version.sdk)"
fi
# Get the bundle ID from the command line argument
if [ -z "$1" ]; then
echo -e "\033[1;31mError: No bundle ID provided. Usage: $0 <bundleId> [user@server]\033[0m"
exit 1
fi
bundleId="$1"
echo "bundleId=\"$bundleId\""
# Show and execute the command to get APK paths
echo "Retrieving APK paths for bundle ID: $bundleId"
apks=$(adb shell pm path $bundleId)
# Debug: Print the paths retrieved
echo "APK paths retrieved:"
echo "$apks"
# Determine if the app uses single or split APKS by checking for patterns
if echo "$apks" | grep -qE "split_|config."; then
echo -e "\033[1;33m▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮ $bundleId - uses split APKs ▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮\033[0m"
else
echo -e "\033[1;33m▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮ $bundleId - uses single APK ▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮\033[0m"
fi
# Make official directory
mkdir -p $bundleId/official_apks
mkdir -p $bundleId/official
# Show and execute the command to pull the APKs
echo "Pulling APKs..."
for apk in $apks; do
apkPath=$(echo $apk | awk '{print $NF}' FS=':' | tr -d '\r\n')
echo "Pulling $apkPath"
adb pull "$apkPath" "$apkPath" $bundleId/official_apks/
done
# List the contents of the official directory
echo "Contents of the official directory:"
ls -l $bundleId/official
# Check if the user provided SSH credentials for syncing to the server
if [ ! -z "$2" ]; then
sshCredentials="$2"
echo -e "\033[1;33m▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮ Uploading files to server ▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮\033[0m"
ssh $sshCredentials "mkdir -p /var/shared/apk/$bundleId"
versionCode=$(get_version_code "$bundleId/official_apks/base.apk")
# Determine naming convention
namingConvention=$(determine_naming_convention "/var/shared/apk/$bundleId" "$bundleId")
# Create the version-specific directory
ssh $sshCredentials "mkdir -p /var/shared/apk/$bundleId/$versionCode"
# Upload and rename APKs
for apk in $bundleId/official_apks/*.apk; do
apkName=$(basename "$apk")
if [ "$apkName" = "base.apk" ]; then
if [ "$namingConvention" = "convention1" ]; then
newName="${bundleId}_v${versionCode}.apk"
else
newName="${bundleId}-${versionCode}.apk"
fi
else
newName="$apkName"
fi
scp "$apk" "$sshCredentials:/var/shared/apk/$bundleId/$versionCode/$newName"
# Extract APK contents
extractDir=$(echo "$apkName" | sed 's/\.apk$//' | sed 's/split_config\.//')
ssh $sshCredentials "mkdir -p /var/shared/apk/$bundleId/$versionCode/$extractDir && unzip -q /var/shared/apk/$bundleId/$versionCode/$newName -d /var/shared/apk/$bundleId/$versionCode/$extractDir"
done
echo "APK files have been uploaded, renamed, and extracted on the server."
else
echo "Skipping server synchronization."
exit 0
fi