Android Application Hacking


NOTE: This post was initially very long, and is constantly growing. Therefore, I decided to shift the technical details to another page.

I recently decided to dive into mobile application security. During my initial learning phase, I came across a few key resources and tips that I would like to share. TLDR; the MOBISEC course and OWASP MSTG are two of the best resources I can recommend to somebody starting off.

Static analysis

To perform static analysis, you first need to decompile the APK. There are several ways to do this, I personally prefer apkx since it allows you to choose between several compilers and once you provide it with the path to a given APK file, it does everything automatically for you.

Once you have a decompiled output, you can view the files in any text editor of your choice. IDEs that are oriented towards Java, such as Android Studio and IntelliJ IDEA can help you further by providing features such as usage detection and refactoring. Refactoring is an important part of any reverse engineers methodology, as it helps you slowly gain a deeper understanding of what the app is trying to achieve.

In order to proceed with the dynamic analysis, you need information such as activity names and strings. You can also identify strings or layouts on your physical device and see if those things can be found in strings.xml or setContentView(R.layout.xyz).

Using frida for dynamic instrumentation

Frida is a popular tool used for dynamic instrumentation. You can use objection as a frida wrapper to make your experience a little better. To start working with objection, you either need to patch an APK through objection, or have frida running on your rooted android phone.

I prefer to go with the latter option, so the usual workflow for me looks as follows:

$ objection --gadget 'com.example.app' explore

# some basic commands
com.example.app on (motorola: 10) [usb] # env
com.example.app on (motorola: 10) [usb] # cd /data/app/com.example.app
com.example.app on (motorola: 10) [usb] # ls
com.example.app on (motorola: 10) [usb] # file download base.apk
com.example.app on (motorola: 10) [usb] # android keystore list

# scripts and jobs
com.example.app on (motorola: 10) [usb] # import {{script.js}}
com.example.app on (motorola: 10) [usb] # jobs list
com.example.app on (motorola: 10) [usb] # jobs kill {{UUID}}

# activities
com.example.app on (motorola: 10) [usb] # android hooking get current_activity
com.example.app on (motorola: 10) [usb] # android intent [launch_activity/launch_service] {{name}}
com.example.app on (motorola: 10) [usb] # android hooking list [activities/class_methods/classes/receivers/services]

# classes and methods
com.example.app on (motorola: 10) [usb] # android hooking search classes {{search_term}}
com.example.app on (motorola: 10) [usb] # android hooking search methods {{class_name}} {{search_term}}
com.example.app on (motorola: 10) [usb] # android hooking watch [class/class_method] {{name}} --dump-args --dump-backtrace --dump-return

# memory & heap
com.example.app on (motorola: 10) [usb] # android heap search instances {{class_name}}
com.example.app on (motorola: 10) [usb] # 

You can learn more about objection here and here.

Using jdb for debugging

First get the target app PID.

$ adb jdwp # list PIDs of debuggable apps
$ adb shell ps | grep appname # get PID of target

Then forward the app process through adb to a local tcp port and attach jdb to the local tcp port.

$ adb forward tcp:1337 jdwp:PID
$ jdb -attach localhost:1337

# Or, in case you want to suspend the app
$ { echo "suspend"; cat; } | jdb -attach localhost:1337 

Some useful jdb android commands:

> classes
> methods com.app.package.class
> stop in com.app.class.method
> locals

AndroBug is another tool that is similar to jdb.


+ MAKE NOTES for everything you come across.
+ Make sure to diff APKs for new functionalities.

Hunting ⇄ Learning ↻ Hunting => HackerOne, BugCrowd, Intigriti, YesWeHack. ↻ Learning => Vulnerable apps, disclosed reports, courses.
+ Use grep -rni, it's your best friend. - permission - android:allowBackup - activity, service, provider, receiver - debuggable


  1. Attack surface: look at the manifest for any exported activities.
  2. Storage: look into resources.asrc/res/strings.xml, /res/raw, /assets.
  3. Secrets: grep for embedded secrets and find out where and how they are being used and whether they should be disclosed or not (using the official documentation of the library, framework, etc) - keywords (firebase io, CONFIG, SECRET, API_KEY, HMAC, private, strings.xml).
  4. Cross-App Scripting: grep for instances of loadUrl and evaluateJavascript in your project directory. Check if the source of input can be controlled by you. Search for "deeplinks" and their schemas.
  5. Intent Redirection: grep for getExtras then observe how the data flows.
  6. Intent Broadcasting: grep for sendBroadcast calls, if there is no specified class or component, you might be able to intercept.
  7. Unprotected Activities: look in the manifest for exported="true" or intent-filters.
  8. Custom Permissions: look in the manifest for permission android:name="" and see if there is a typo while using it in provider android:writePermission="" (report #440749). check if defined permissions are used.
  9. Path Traversal: grep for FileWriter, dataDir, makeTempCopy, getCacheDir, fileUri, getLastPathSegment, filename and see if any files are being written with user-supplied names.
  10. Zip Path Traversal: if app processes zip files look into zip path traversal (tool: evilarc).
  11. OAuth Grants/Redirect: grep "oauth" or "redirect_uri", something like this - https://service.com/oauth/authorize/?client_id=XXXX&redirect_uri=https://www.app.com/service_success.php&response_type=token see if redirection can change.

My Bookmarks

You can find my browser bookmarks related to Android over here.