ilian / repackaging-protection

[FPS2019] Protecting Android Apps from Repackaging Using Native Code
GNU General Public License v2.0
8 stars 6 forks source link

Protecting Android Apps from Repackaging Using Native Code

This repository contains the code for the paper "Protecting Android Apps from Repackaging Using Native Code", which appeared in the conference proceedings of the 12th International Symposium on Foundations & Practice of Security.

About

The implementation aims to prevent malicious actors from repackaging Android apps by embedding integrity protections into a compiled Android application. The transformation prevents normal execution if the app has been tampered with. This protection prevents an attacker from modifying the app, and potentially bundling malware with it. To make the protection difficult to circumvent, it relies on encrypted integrity checks in native code.

System requirements

Currently, only UNIX-based systems are supposed. The following packages should be installed

Android SDK, NDK and CMake can be downloaded and installed using Android Studio

The paths to the components installed via Android Studio may be different depending on the installed version. The following paths can be adjusted as desired:

Ant targets

By default, the APK to be transformed is located at./app.apk

This can be overridden by providing the following extra argument to ant: -Dsrc-apk=custom-path>

Transform and install an APK

ant clean transform-and-install-apk

Transform APK to a new protected APK

ant clean transform-apk-to-apk

Transform APK to Jimple files

ant clean transform-apk-to-jimple

Run java tests with locally installed JVM: Compares stdout between original and transformed bytecode. Jimple files are written to ./test-out

ant clean test

Debugging native code

Native code can be debugged with gdb by setting the protected app as the debug app under Settings → System → Developer options → Select debug app. Make sure "Wait for debugger" is enabled.

The script attaches to the first pid that is hosting a JDWP transport. Make sure that no other app is hosting a JDWP transport. Running adb jdwp will list all hosting processes.

An experimental script is located at ./android-debug that attaches gdbserver to the running process. It starts jdb in the background to skip the "Waiting for debugger" dialog.

Sample gdb session:

# Break at relevant JNI function
b Java_embedded_native_orgwhispersystemslibsignalstateStorageProtosSignedPreKeyRecordStructuret90a86f5e5d244037aacabebcbb3bb6cc
c # Continue executing until we reach a breakpoint
layout reg # Show instruction pointer and surrounding instructions
ni # Execute next instruction
<enter key to repeat last entered command>
...