Showing posts with label Decompile APK. Show all posts
Showing posts with label Decompile APK. Show all posts

Wednesday, March 9, 2022

How to decompile and repack Android App on ChromeOS (Part 3)

(1) This continues to discuss -> How to decompile android app, previous articles are here (part 1) & (part2)


(2) Part 1 is to demo the use of ChromeOS (devloper mode on) plus the decompile tools and the process of decode and edit some resource files then rebuild the apk using apktool. And Part 2 is to use the jadx tool to decode the apk to java source file and compile it again in Android Studio.


(3) There are possibilities that the jadx tool can not decompile the complete java scources or ending with error. Even if it can be decoded, the project is maybe too complex to rebuild it in Android Studio.


(4) If we can decompile using apktool, we can edit the resource file and smali code, then repack it into apk file. However, this method is only for small modifications in code


(5) For example
cd ~/DecompileProjects # decompile the apk using apktool
apktool.bat d yourapp.apk -o yourapp_out
# edit the smali file, how ? see point(6) below
vim yourapp_out\smali_classes2\com\yourapp\MyService.smali
# build the apk using apktool
apktool b sjbot2 -o yourapp2.apk
# use jadx to decode it to gradle java source files so that you can check for any errors.
jadx --export-gradle yourapp2.apk -d yourapp2_gradle
# check the decompile java scource code before deployment
vim yourapp2_gradle\app\src\main\java\yourapp\MyService.java
# code sign and align the apk
jarsigner -verbose -sigalg SHA256withRSA -keystore my-release-key256.keystore -storepass 123456 yourapp2.apk mykey256
jarsigner -verify -verbose -certs -keystore my-release-key256.keystore yourapp2.apk
zipalign -v 4 yourapp2.apk yourapp2-aligned.apk
# install to emulator or device for testing
adb -s emulator-5556 install yourapp2-aligned.apk


(6) The problem here is how to edit the smali code, the syntax is so complex and like bytecode. So there is no easy path, and either you learn the smali language, or you can use java2smali plug-in for Android Studio to convert java code to smali code and try and error to modify it bit by bit. So using git version control and branching to keep track of your modification is very important in this case. The limitation of java2smali is that it can only be done on a complete project not a single java file, so you have to put a function that is compilable and put it in a project to compile and then convert to smali code.

Get this torrent to learn more on Reverse Engineering.

Thursday, March 3, 2022

How to decompile and repack Android App on ChromeOS (Part 2)

(1) This is the sequel to How to decompile android app (part 1)
And the demo apk can be download from here. TouchCalculator_1.0-debug.apk

(2) Part 1 is to demo the use of ChromeOS (devloper mode on) plus the decompile tools and the process of decode and edit some resource files then rebuild the apk using apktool.
If you have Windows machine, you can also download the required decompile tools as demo here.

(3) This part 2 is to continue to modify the logic in the Android App which involved the source code. I will use the JADX tools and Android Studio to edit the code.

cd ~/DecompileProjects
# Use jadx to decode the apk and export gradle project file and java source code
jadx --export-gradle TouchCalculator_1.0-debug.apk -d TouchCalculator2


(4) Then, launch Android Studio and open the project in ~/DecompileProjects/TouchCalculator2 and wait for the gradle to sync. If you try to Build -> Make Project (Ctrl F9), you will notice it has a lot of errors and these errors are mainly partial packages download from repo and many of them are not linkable. So we have to study the code, to see what are the actual code files needed for this project.

(5) Then create a new Android Studio project file with Empty Activity and with the following parameters.


(6) After creation of the new project, copy the decompiled java source code and resource files to the New Project as below:
shell script    Select all
cp ~/DecompileProjects/TouchCalculator2/app/src/main/java/com/pragmatouch/calculator/*.java ~/DecompileProjects/TouchCalculator3/app/src/main/java/com/pragmatouch/calculator/. cp ~/DecompileProjects/TouchCalculator2/app/src/main/res/drawable/k*.xml ~/DecompileProjects/TouchCalculator3/app/src/main/res/drawable/. cp ~/DecompileProjects/TouchCalculator2/app/src/main/res/drawable/stackview1.xml ~/DecompileProjects/TouchCalculator3/app/src/main/res/drawable/. cp ~/DecompileProjects/TouchCalculator2/app/src/main/res/drawable/inputview1.xml ~/DecompileProjects/TouchCalculator3/app/src/main/res/drawable/. cp ~/DecompileProjects/TouchCalculator2/app/src/main/res/drawable/appvertical1.xml ~/DecompileProjects/TouchCalculator3/app/src/main/res/drawable/. cp ~/DecompileProjects/TouchCalculator2/app/src/main/res/values/colors.xml ~/DecompileProjects/TouchCalculator3/app/src/main/res/values/. cp ~/DecompileProjects/TouchCalculator2/app/src/main/res/values/strings.xml ~/DecompileProjects/TouchCalculator3/app/src/main/res/values/. cp ~/DecompileProjects/TouchCalculator2/app/src/main/res/layout/activity_main.xml ~/DecompileProjects/TouchCalculator3/app/src/main/res/layout/ cp ~/DecompileProjects/TouchCalculator2/app/src/main/res/layout/calutor.xml ~/DecompileProjects/TouchCalculator3/app/src/main/res/layout/



(7) Then, there are several changes to the build.gradle settings. Target Sdk should be set to 30 in order to build as App Bundle format.
# Sdk should not use 32 and change to 30
   compileSdk 30
   targetSdk 30

# dependencies package change to lower version as below
   implementation 'androidx.appcompat:appcompat:1.3.0'
   implementation 'com.google.android.material:material:1.3.0'

For Release build type add
   debuggable false


(8) Then, we try to Build -> Make Project (Ctrl F9) again in the New Project and see if there are any errors to solve. For complex project, it is not possible to have a full project file to build after decompile. So there is a part 3 for this topic.

(9) In fact, the project code was from here, so I can find out the required project files easily. However, there are still some features of this app which have not been implemented yet and with the decompiled java source code, you can modify the decompiled code and rebuild it to apk and test again. ALternatively, you can copy the original source code from here and paste them to the relevant java source code files of your new project.

(10) Change the resource files as in Part 1 of this artcile and add the following lines in MainActivity.java to implement the PERCENT, SQRT and RRECIPROC functions. And then Run the app in Android Studio or rebuild the apk to test on real Android device.
diff results    Select all
# diff ./TouchCalculator2/app/src/main/java/com/pragmatouc h/calculator/MainActivity.java ./TouchCalculator3/app/src/main/java/com/pragmatouch/calculator/MainActivity.java 192a193,236 > case 16: // PERCENT > double userInputValue4 = tryParseUserInput(); > if (!Double.isNaN(userInputValue4)) { > if (Double.isNaN(this.memoryValue)) { > this.memoryValue = 0.0d; > } > this.memoryValue = (userInputValue4/100); > this.userInputText.setText(doubleToString(this.memoryValue)); > this.hasFinalResult = true; > return; > } > return; > case 17: // SQRT > // reject negative num > if (currentInputLen > 0 && currentInput.charAt(0) == '-') { > return; > } > double userInputValue5 = tryParseUserInput(); > if (!Double.isNaN(userInputValue5)) { > if (Double.isNaN(this.memoryValue)) { > this.memoryValue = 0.0d; > } > this.memoryValue = Math.sqrt(userInputValue5); > this.userInputText.setText(doubleToString(this.memoryValue)); > this.hasFinalResult = true; > return; > } > return; > case 18: // RECIPROC > // reject zero > if (currentInputLen == 1 && currentInput.charAt(0) == '0') { > return; > } > double userInputValue6 = tryParseUserInput(); > if (!Double.isNaN(userInputValue6)) { > if (Double.isNaN(this.memoryValue)) { > this.memoryValue = 0.0d; > } > this.memoryValue = (1/userInputValue6); > this.userInputText.setText(doubleToString(this.memoryValue)); > this.hasFinalResult = true; > return; > } > return; 276a321,332 > } > try { > $SwitchMap$com$pragmatouch$calculator$KeypadButton[KeypadButton.PERCENT.ordinal()] = 16; > } catch (NoSuchFieldError e16) { > } > try { > $SwitchMap$com$pragmatouch$calculator$KeypadButton[KeypadButton.SQRT.ordinal()] = 17; > } catch (NoSuchFieldError e17) { > } > try { > $SwitchMap$com$pragmatouch$calculator$KeypadButton[KeypadButton.RECIPROC.ordinal()] = 18; > } catch (NoSuchFieldError e18) {



There are still bugs here and please feel free to correct them plus any new enhancements of this calculator and Enjoy Android Studio Programming.



(11) When decompiling some apks that was compiled with old sdk or converting some old android projects to the at least using SDK 30, some conversion of libraries are needed as below:
In build.gradle, you should use androidx instead of old Android Support Libraries
     compileSdkVersion 30
    implementation 'androidx.appcompat:appcompat:1.3.0'
instead of 'com.android.support:appcompat-v7:28.0.0' or something like 'com.android.support:support-v13:26.0.2'
You also should use kotlin library if the decompiled project was converted from kotlin to Java
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

See here for reference. https://developer.android.com/jetpack/androidx

In gradle.properties, you should setup useAndroidX and enableJetifier
android.useAndroidX=true
android.enableJetifier=true

For converted/decompiled Java classes source, don't use old android support libraries, use androidx instead.
Full class-mapping here https://developer.android.com/jetpack/androidx/migrate/class-mappings
//import android.support.v4.app.NotificationCompat;
//import android.support.v7.app.AppCompatActivity;
//import android.support.v4.app.RemoteInput;
//import android.support.v4.app.Fragment;
import androidx.core.app.NotificationCompat;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.RemoteInput;
import androidx.fragment.app.Fragment;
import androidx.annotation.RequiresApi;
import android.annotation.TargetApi;
import android.annotation.SuppressLint;




(12) If you really want to support old devices and not using androidx, you should use SdkVersion 28 and compatible appcompat version as below:
      compileSdkVersion 28

    implementation 'com.android.support:appcompat-v7:28.0.0'

How to decompile and repack Android App on ChromeOS

(1) You need ChromeOS with developer mode turn on for your machine. Either use a Chromebook (after powerwash) or install a recovery image on your old pc, with developer mode on (see here How to install ChromeOS to your USB stick for your old PC)

(2) You have to install Android Studio and decompile tools on your ChromeOS machine (see here How to run Android Emulator on ChromeOS)

(3) Here is the walkthrough on how to decompile apk and change the resource file and repack and sign the apk file again. Assume you don't have the source code project file. The original demo apk can be download from here. TouchCalculator_1.0-debug.apk

(4) The problem of this TouchCalculator app has two problems on the interface: a) The memory text on the left should be smaller in size b) The key (on the right) with a comma is wrong and it should be a dot for input decimal point. Without the source project file, and in order to modify it, you have to decompile it and study the code and repack it to apk file to run.

(5) Assume, you have the ChromeOS machine and installed software and also setup the decompile tools as in Steps (1) and (2). And In Linux Terminal execute these steps:

mkdir ~/DecompileProjects
cd ~/DecompileProjects
# Then copy the download apk file to this Linux folder DecompileProjects
# Use apktool to decode the apk
apktool decode TouchCalculator_1.0-debug.apk -o TouchCalculator

# After studying the xml files in the res/layout folder
# modify the file: TouchCalculator/res/layout/activity_main.xml
# and change from 25.0sp to a smaller textSize of 12.0sp
   <TextView android:textSize="25.0sp" android:textColor="@color/lightyellow" android:gravity="right" android:id="@id/txtMemory"
#to
   <TextView android:textSize="12.0sp" android:textColor="@color/lightyellow" android:gravity="right" android:id="@id/txtMemory"

# modify the file: TouchCalculator/smali_classes3/com/pragmatouch/calculator/KeypadButton.smali

# line 453 and change the button label from "," to "•"
   const-string v3, ","
# to
   const-string v3, "\u2022"

# Use apktool to build the apk after modification of the resource files
apktool build TouchCalculator -o TouchCalculator_1.01.apk
# generate a keystore with SHA256RSA (if not yet generated) and remember the storepassword
keytool -genkey -v -keystore my-release-key256.keystore -alias mykey256 -sigalg SHA256withRSA -keyalg RSA -keysize 2048 -validity 10000 -deststoretype pkcs12
# sign the apk with self-signed certificate and enter the storepassword
jarsigner -verbose -sigalg SHA256withRSA -keystore my-release-key256.keystore TouchCalculator_1.01.apk mykey256
# verify the signature
jarsigner -verify -verbose -certs -keystore my-release-key256.keystore TouchCalculator_1.01.apk
# zipalign the apk
zipalign -v 4 TouchCalculator_1.01.apk TouchCalculator_1.01-aligned.apk

(6) Install the TouchCalculator_1.01-aligned.apk on your ChromeOS (with developer mode on) machine or your Android device (With Unknown Sources on) for testing. For ChromeOS, please uninstall the previous apk version before installation of the new one.

(7) This is just a proof of concept that using apktool can decompile then modify and repack again to an apk file. To further modify the java / smali code in the decompile source, just stay tune for my next article.