# Android Reversing for Examiners

#### Preamble

This lab was created by [Mike Williamson](https://twitter.com/forensicmike1) (Magnet Forensics) and [Chris Atha](mailto:krisatha@gmail.com) (\_). It was originally designed to be delivered live as a lab. With COVID-19, the lab was reworked to be delivered virtually. This gitbook is available to all and we really hope you enjoy and have some takeaways from it.

Many of the topics and processes introduced in this lab are complex. Our objective for the live delivery component was to get as much content as possible packed inside a 90 minute lab.

To cover the inevitable explanatory shortfall, this gitbook provides a lot of accompanying documentation and guidance which you can go through at your convenience, should wish to delve deeper!

#### Video Walkthroughs

Some people learn better by seeing, so a number of walkthrough videos have been created to assist in processes not specifically covered in the lab. The videos will be referenced in the appropriate places in this documentation, but there is also a full playlist [located here](https://www.youtube.com/playlist?list=PL-MzuKIZ1eXL8fwaQb805FugeOd-vrJJa).

#### Support Frida

We wanted to include a section about how to support Frida if you find it useful! Ole Andre, the creator of Frida, pointed to this tweet and advises that the best thing you can do is [check out products](https://www.nowsecure.com/products/) offered by NowSecure! Pretty small ask for how powerful this thing is - and how much work goes into keeping the project going!

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6X1jgoTuhcabZ6ek3y%2F-M6X1rGw2Q6DBDZT5IvG%2Fimage.png?alt=media\&token=d89855bd-ad89-44ce-acb7-b74efb5318b9)

#### Legal

The opinions and information expressed in this gitbook are those of the authors.

They do not purport to reflect the opinions or views of Magnet Forensics.


# Prerequisites

Emulating Android inside a Windows VM (Android VM within a Windows VM) is difficult to achieve, and so we recommend emulating Android directly on your host machine.

For the purposes of these labs, we will be assuming that you are using a Windows host. However, there is no reason this content should not also work on other host OS'es.

At the end of the day, **any Android emulator** that allows root access can likely be made to work as a reversing sandbox. However, we are only providing an image for Android Device Emulator (ADE) and Virtualbox (VBOX).

### Which emulation environment should I choose?

It comes down to preference! Any Android emulator that allows you to act as root will suffice. Virtual Box, Android Device Emulator, Nox, Genymotion will all work.

For me, ADE is a way better emulation environment. It looks better, runs smoother, and uses less system resources. However, if you already have another emulator up and running you are welcome to use that.

### System Prerequisites

These prerequisites are required regardless of emulation environment.

* [ ] Python 3+ and pip installed, available from your PATH. (Verify this by opening a command prompt and typing python --version and pip .. you should see a version of 3 or higher.)<br>

* [ ] Install frida-tools as per [these instructions](https://frida.re/docs/installation/). We recommend using pip as in: `pip install frida-tools`

* [ ] You must have `adb` installed and in your path. If you don't, follow the instructions [here ](https://www.xda-developers.com/install-adb-windows-macos-linux/)under "Microsoft Windows ADB Setup". ( Verify this is installed by opening a command prompt and typing `adb` )<br>

* [ ] We are going to be using jadx-gui for static analysis. Jadx requires Java Runtime Environment 8. However, it has a download available that includes it. Check the releases page [here](https://github.com/skylot/jadx/releases) or download version 1.1.0 from [this link](https://github.com/skylot/jadx/releases/download/v1.1.0/jadx-gui-1.1.0-with-jre-windows.zip).

### Lab Kit

This lab kit includes: the PhotoVault APK version we used in this lab, frida scripts, and sample data.

{% file src="/files/-M6XP090JDdhFn37u093" %}
Download Lab Kit
{% endfile %}

### Video Walkthrough: Environment Setup

{% embed url="<https://www.youtube.com/watch?v=Ew3VfY07Pxk>" %}

This video covers the following topics:

* Installing frida-tools on the host machine.
* Obtaining the appropriate frida-server from the github releases page.
* Pushing frida-server to the device and making it executable.
* Running frida-server in a way that does not halt everything when you close your ADB session.

See also [\[1\] Lab setup and initial app exploration](/lab/1-lab-setup-and-initial-app-exploration) for non-video based instructions!


# Our Target: Private Photo Vault

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M1k5J2uxcVj-nrbVJOt%2F-M1k5e6lTD9ycmUfK0S7%2Fimage.png?alt=media\&token=184e3271-9a04-410d-9e72-380c9da9f5fb)

Private Photo Vault is an app that is available on the iOS and Google Play stores. On Android alone, there are over 10 M recorded installations.

The app touts the following features on their website:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M1k5J2uxcVj-nrbVJOt%2F-M1k61Tbjk_4XrGf7kWc%2Fimage.png?alt=media\&token=2c2efca1-2edc-4ce1-ae1a-3ffeab10cceb)

We will be using Private Photo Vault as our frida-ninja training ground and our objectives will be as follows:

1. Determine which functions are called to validate attempted PINs.
2. Investigate if/how PINs may be stored in the filesystem.
3. Bruteforce the user PIN using the app's functions against itself.

In this lab, we will use static analysis and dynamic binary instrumentation together to help tell a story.

The very first step is setting up our lab with some data and doing some initial exploration of how the app works. This initial stage could be very similar if you are going to tackle a different app.

See [\[1\] Lab setup and initial app exploration](/lab/1-lab-setup-and-initial-app-exploration) to begin your lab!


# \[1] Lab setup and initial app exploration

Initial exploratory steps including booting up emulator, launching our target app,

First things first, boot up your Android Emulator of choice. Please also ensure you have root and have ADB connectivity.&#x20;

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4tF4Moz8tve1utra0N%2F-M4tIV-oO-xVSUSG19W4%2FScreenshot_1586878016.png?alt=media\&token=621844b4-9891-4233-8748-c529f264703c)

### Install and configure the Photo Vault app

You only need to install Photo Vault if you are starting with your own emulator. If you've imported the lab image, you can skip to [Launch the Photo Vault App](/lab/1-lab-setup-and-initial-app-exploration#launch-the-photo-vault-app).

Steps are shown in this video:

{% embed url="<https://www.youtube.com/watch?v=U2Jls_Moqs8>" %}

The method of installing an APK varies from emulator to emulator:

* Some emulators allow you to drag-and-drop APK files directly from the host to commence installation.
* Others, you will need to use adb to push or sideload. If you push, you can open them with File Manager.
* You can also choose to download directly from the Google Play store if your emulator supports it.

Once installed, launch the app. You will be immediately be prompted to set a PIN.

Enter and confirm a PIN. Now you need to import media or use the virtual camera (if available) to capture some data for testing purposes.

Click on the Main Album and press on the plus button. If your emulator supports it, you can use the Camera app to take a photo in a virtual room.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4tIaw3-rWJItGxcMGv%2F-M4tIxvlaazITzaAlWHy%2FScreenshot_1586875567.png?alt=media\&token=767f7d23-a79f-46f9-9b14-0a5a3c78050b)

<div align="center"><img src="https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4tIaw3-rWJItGxcMGv%2F-M4tJ26GuliglUVParex%2FScreenshot_1586875619.png?alt=media&amp;token=2e7628f5-631c-4795-86c7-41646e0946d5" alt=""></div>

Great, you now have some test data to work with for our lab.

### Launch the Photo Vault app

To launch the app, click and hold the mouse in the bottom-center area of the emulator screen, then drag your cursor upward to reveal the app menu which includes installed applications.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4tF4Moz8tve1utra0N%2F-M4tIZ6ZHffsX9DX3DIM%2FScreenshot_1586875512.png?alt=media\&token=042f75ef-57ed-4bc5-9934-b718b59e51e4)

Find ‘Photo Vault’ on the list of installed apps and open it.&#x20;

You will now see the ‘Enter Passcode’ screen, as shown below.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M1kZp0iHaSI_Gdxo348%2F-M1k_I6rtd11HuQKqOXN%2FScreenshot_1580666492.png?alt=media\&token=1a7d24e5-dbab-4cfd-9157-33b6ba0b38f1)

So, when you open the app, the very first thing you are presented with a numeric PIN pad. The correct 4 digit numeric PIN is required to proceed.

Even without programming background, thinking about it logically we might estimate that somewhere in our app's logic, there is probably a function whose sole purpose in life is to check to see whether an inputted PIN is correct or not.


# \[1.1] Upload frida-server to the emulator or device and run using nohup

#### Upload frida-server

First, let's test to make sure that we have working connectivity over ADB (Android Debug Bridge).

{% hint style="info" %}
This lab is also covered off in the [Environment Setup video walkthrough](/setting-up/before-you-start-prerequisites#video-walkthrough-environment-setup).
{% endhint %}

Open a commandline and type `adb devices`

![If you see any other devices listed, disconnect or power them off.](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M-CYQh7eIH5vnxoBrpn%2F-M-Eq39k1jGjnpCMbA3s%2Fimage.png?alt=media\&token=84a5c30d-f3d6-4f26-9980-ab126c3ac88c)

In order for frida to work, we need it's companion `frida-server`, to be running on the device. You can download it from the frida [releases page on Github](https://github.com/frida/frida/releases) - make sure you get the one ending in "android-x86".

Push it to `/data/local/tmp` with `adb push frida-server-12.8.20-android-x86 /data/local/tmp`

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4V0jBvuHQkuQwpYbPL%2F-M4V1Nz7HdlxaSTbglgc%2Fimage.png?alt=media\&token=f9a0da87-344d-49a1-ab3b-4708135d7a04)

Obtain root with `adb root`, then connect to your device with `adb shell`. Navigate to the /data/local/tmp directory with `cd /data/local/tmp` .&#x20;

At this point I prefer to rename frida-server to something a little less annoying to type: `mv frida-server-12.8.20-android-x86 frida-server`

Make the server executable with `chmod 777 frida-server`

#### Run frida-server persistently using nohup

Start the server with `nohup ./frida-server &`

{% hint style="warning" %}
The reason we are using nohup is to keep the process running even if we close our ADB terminal. You can absolutely just run ./frida-server but then you must be mindful not to close the window.
{% endhint %}

To recap:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4V0jBvuHQkuQwpYbPL%2F-M4V8R2zDKSoEc4lcWhX%2Fimage.png?alt=media\&token=650467fd-f04e-4927-ac3f-228e98303bb0)


# \[1.2] Review files in the app data directory

In the early stages of our reversing workflow, we can look through the filesystem of this app to see if there are any leads. This could include things like shared preferences, databases, or basically anywhere within the app's sandbox.

### Shared Preferences (SharedPrefs)

If you're using the lab kit, a complete copy of the data directory has been provided under 'app\_data\_directory'. If you wanted to pull it off the device, it's located at: `/data/data/com.enchantedcloud.photovault`

A couple of artifacts of interest include the shared preferences xml (com.enchantedcloud.photovault\_preferences.xml), content shown here:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4UHpUXfy6O4JY9Bl_s%2F-M4UKwe4NU76g_Zabg6m%2Fimage.png?alt=media\&token=de9913a4-f763-4dad-849d-5b8a5e537998)

Of interest are the `pin` , `passcode_type`, and`enc_keys_pin` entries. Let's make a note of them and continue.

There's also a file called `crypto.xml` - which hits on a certain subject were interested in! So let's take a look:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VNicwZX38NlNhKlhi%2F-M6VNs9aKOEj5GcHUQj7%2Fimage.png?alt=media\&token=cf7d77b1-b6cd-4a85-95a7-83e6839a3095)

{% hint style="info" %}
It may be helpful to start a textfile in notepad++, wherein you mark down interesting or potentially significant data as you go. As you go along, you can use this as a sort of index for testing values you might retrieve during DBI.

<img src="https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VNicwZX38NlNhKlhi%2F-M6VOwzXPADYA_sDry28%2Fimage.png?alt=media&amp;token=c73279c7-0bff-4133-aaca-5baeeced67ba" alt="" data-size="original">
{% endhint %}

### Database

You might also notice `simplenosql.db` , which is stored in the `databases` folder. If you open it, there are only two tables.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VLsdH2Uf8598ppFGc%2F-M6VMKCwW9hzusj3RsZT%2Fimage.png?alt=media\&token=2628a03b-29f8-4044-9b79-ed9629809b69)

Inside the table simplenosql, there are a couple of rows:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VLsdH2Uf8598ppFGc%2F-M6VMQHtkP1pJiu0PWkS%2Fimage.png?alt=media\&token=8200199f-d595-4175-9a6a-55a01f1204d1)

Each row appears to pertain to a 'bucket', which in our case is either albums or albums\_decoy. Inside the data column is quite a bit of JSON data:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VLsdH2Uf8598ppFGc%2F-M6VMh_tocHm4yvRDCuW%2Fimage.png?alt=media\&token=866668cf-a9ef-4e40-b1bd-483c469c507a)

It appears that this may provide some intelligence as to where our encrypted media could be stored. Let's see if we can find these files in the `files/media/orig/` directory as indicated.

### Encrypted Media

As expected, we have a number of jpg files with timestamps as names. If we view them using a hex editor we can see they appear to be high entropy crypto containers.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4UHpUXfy6O4JY9Bl_s%2F-M4UMOT4GiwX_7wgH6XI%2Fimage.png?alt=media\&token=31f8c77b-7379-4cb3-88a6-fbf48ce87da4)

If we continue to look through the other encrypted media, the only obvious similarity you may note between them is that they all begin with 01 01.


# \[2] Perform static analysis to locate some functions of interest

To begin the static analysis phase, we will need a copy of our APK file to serve as our specimen. There are a number of ways to obtain this:

* Extract a sample from the device directly (see [guide here](/other-processes/extracting-apk-specimen-from-the-device))
* Work with the acquired device data.
* Note the version from your acquired content and download a website (like [APKPure](https://www.apkpure.com))

{% hint style="info" %}
In our lab, the specimen has already been obtained and can be found in the lab directory under "APKs".
{% endhint %}

Let's fire up [jadx gui](https://github.com/skylot/jadx/releases/). This is a free reverse engineering tool for Android APKs. It requires the Java Runtime Environment (JRE) 8 installed, but is also available prepackaged in a version that includes it. The releases page for jadx can be found [here](https://github.com/skylot/jadx/releases). Look for the download ending with "-with-jre-windows.zip".

Once launched, it will give you the following Open File dialog. If you downloaded the lab kit, look in the folder called 'APKs'. Double click to open the APK.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4FDHoEOszAW3TKZMP9%2F-M4FE1wYFSDV_4KZx2iK%2Fimage.png?alt=media\&token=37767bd0-81e2-4003-aafd-fda99ab37cc4)

Once loaded, you can begin browsing through the list of classes on the lefthand side. You will see lots of entries beginning with 'android', 'com.facebook' etc. A lot of these are from libraries used by the app. Rather than sifting through this list manually, we will use the clues we established in Lab 1 in order to point us in the right direction.

To open up the text search window, press CTRL+SHIFT+F or select it from the Navigation menu.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VPu8lrD-c9WBxlDyv%2F-M6VQY9W6gqKla2Zbv4Y%2Fimage.png?alt=media\&token=8e340acb-c649-4d0b-9a7f-2ee99b12046f)

The first time you open the text search, it will take some time as the app has to perform APK-wide decompilation. When finished, we are ready to start searching for our suspects.

Let's search for some values from [lab 1.2](/lab/1-lab-setup-and-initial-app-exploration/1.2-review-files-in-the-app-data-directory), starting with `pin`

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VPu8lrD-c9WBxlDyv%2F-M6VeCafe-XVTv2kE7y4%2Fimage.png?alt=media\&token=b0c5b899-2f27-404b-9c98-616f5e5da8a4)

So we do hits, but... 3k is a lot to go through and as you can see, there is significant false positives. So, what do we do? Well, in our case the key for pin is a string. In Java, strings are enclosed in double quotes. Let's modify our search to include double quotes and see how we do on results:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VPu8lrD-c9WBxlDyv%2F-M6Vez3pqVBNelfMY6k5%2Fimage.png?alt=media\&token=176f5cd2-a135-4129-8c4d-efa5f0bf8d44)

Much better. Now, instead of "android.support" (and many others) we are seeing only classes from within the "com.github.browep.privatephotovault" namespace and, if we look at the **Code** side of the view, we can see some super interesting stuff.

At this point, we have developed some leads to investigate using static analysis.

Looking at the list, in the class `CryptoUtils`, we see two calls to a function called `pinsMatch`, so let's check that out by double clicking on the result and then right clicking and choosing "go to declaration".

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VPu8lrD-c9WBxlDyv%2F-M6Vg8-HacSyiA_g6zm6%2Fimage.png?alt=media\&token=d1c5094d-c7e4-4f91-bb56-204376d6cdfa)

{% hint style="warning" %}
In this case, it turns out the target function is only a few lines away! But, **Go to declaration** is capable of looking across the whole APK and can be very useful.
{% endhint %}

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6VPu8lrD-c9WBxlDyv%2F-M6VgR2SNwCCwfPhkZed%2Fimage.png?alt=media\&token=9a8da6cd-d1e6-4ed1-a9fb-cd82dc0628a1)

Alright, so there's a couple of things happening here. However, rather than working to develop an understanding first, then testing later, let's dive in to some DBI to give us a bit of a roadmap to follow.

{% hint style="info" %}
Unlike many APKs, this one is not obfuscated. Were it obfuscated, instead of seeing `com.github.browep.privatephotovault.crypto.CryptoUtils.pinsMatch` we might see `a.b.a.c.d.d.a`.

If this happens, all is not lost, we simply have more work to do in terms of static analysis. Dealing with obfuscation is out of scope for this lab, but rest assured it's still very doable.
{% endhint %}


# \[3] Deploy method hooks using frida REPL

Alright, so - time to move on to DBI and inject Frida into our app!

#### Inject Frida

In the command prompt, navigate to the course scripts directory and type the following:

`frida -U --runtime=v8 -l privatePhotoVault.js -F`

To quickly pick apart the extra arguments we're passing:

* `-U` tells frida to look for a device connected via USB (virtually or otherwise)
* `--runtime=v8` tells frida to use a newer version of JavaScript which has a number of quality of life improvements. I generally always use it.
* `-l privatePhotoVault.js` tells frida to inject our course script with some pre-made functions useful for reversing.
* For more reading on frida command line arguments, see [frida](/frida-tool-reference/frida).

This should get you to the following terminal view (hereinafter called the [REPL](/frida-tool-reference/frida)):

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M-5XkLPBBbkgyIzx4tG%2F-M-A5kmuF55L6uCFgofl%2Fimage.png?alt=media\&token=a5020522-4223-4b21-97e1-a69eb07c405f)

If you made it here – excellent! Now, we’re ready to have some fun. If you’ve never written code before, that’s about to change! Don’t worry, we’ll take it slow!

#### Autocomplete / Intellisense

One thing Frida does that can make life a bit easier is provide a bit of good old intellisense. This means when you start typing, an autocomplete box appears which you can navigate with the up and down arrow keys.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WTh3FQ2SgA9IHFEYy%2F-M6WX99p7pWCpYEWO4zI%2Fimage.png?alt=media\&token=7a8bbdeb-bd33-49c1-8f42-11b0cd742147)

In [Lab 2](/lab/2-perform-static-analysis-to-locate-some-functions-of-interest), we identified the pinsMatch function as a candidate for method hooking, so let's start with that.

#### Get your hooks in!

To apply a method hook, we will use the traceMethod command. traceMethod is from the Raptor iOS tracing script and takes the class name as a string.

`traceMethod('com.github.browep.privatephotovault.crypto.CryptoUtils.pinsMatch')`

If successful, you should see a message from Frida saying:

`Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.pinsMatch [1 overload(s)]`

{% hint style="warning" %}
If a class has multiple implementations of the same function name (each with different parameters), these are called **overloads**. This is common when an application has been obfuscated.
{% endhint %}

Time to see if we are on the right track! Enter the PIN on the device or emulator.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WTh3FQ2SgA9IHFEYy%2F-M6WYWSKwY9Sv_3_y8KP%2Fimage.png?alt=media\&token=a4e8f9a2-5178-4ad7-b0db-261886a5acae)

Excellent, so it appears our pinsMatch function is indeed getting called twice. The parameters are the same, except for argument\[1] which is "pin" and "pin\_decoy".

Now we will head back to our static analysis tool. From here, we have some options. Since our goal is to learn, we'll do a little bit of everything!

* Continue to push through via static analysis, building our understanding up as we go. This option may appeal to those with more programming experience. \[[Lab 4a](/lab/4a-moar-static-analysis)]<br>
* Cast a wider net with method hooks, hooking additional functions of interest, or even an entire class worth of functions. \[[Lab 4b](/lab/4b-cast-a-wider-net-with-dbi)]<br>
* Go full ham and write a PIN bruteforce, because it's fun (and **relatively** easy!) \[[Lab 4c](/lab/4c-pin-bruteforce)]


# \[4a] Moar Static Analysis

Let's head back to the static analysis and see if this helps us to fill in the gaps any.

What do we know about pinsMatch? Well, it returns false when the PIN is wrong. But what else. Let's break it apart:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WeI5j8-ssA9_tJN5c%2F-M6WhVi9IQkoNYzUoInc%2Fimage.png?alt=media\&token=76c991d9-2307-4273-a0bb-212a59b31431)

So in our incorrect PIN entry, we called pinsMatch with `"1234"`, `"pin"` and a `Context`.

#### First line : String string

So our function begins with a variable `string` being declared and immediately assigned a value:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WeI5j8-ssA9_tJN5c%2F-M6WifNyT2DPNpISrnFZ%2Fimage.png?alt=media\&token=78e0b228-e9b2-4d4e-a37a-4669bf341f16)

So what's happening here? You might think to right click `PreferenceManager` or `getDefaultSharedPreferences`, but you won't have the option to "Go to declaration" - it's disabled.

In this situation, it may be worth it to search Google. You can search for the class name, method name, or both. The results should be similar. I used: `getDefaultSharedPreferences`

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WeI5j8-ssA9_tJN5c%2F-M6WiyBDe4Ac26aJ34ex%2Fimage.png?alt=media\&token=c704298b-3845-4cf7-986d-20ad3d3673fd)

Sure enough, the reason we can't view the declaration is because it's not part of our app - this is part of the Android API. The best part about that is it's well documented in the Android Developer docs. If we dig into the function, eventually we will be able to uncover a plain english explanation for what `getString` is doing.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WeI5j8-ssA9_tJN5c%2F-M6WjNEf4RYdNRhEuTs7%2Fimage.png?alt=media\&token=cd389db0-7518-4e9d-8f16-5c457327e15e)

Cool - so [earlier in Lab 1](/lab/1-lab-setup-and-initial-app-exploration/1.2-review-files-in-the-app-data-directory#shared-preferences-sharedprefs) we located a number of keys for interest, including one called `"pin"` right?

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WeI5j8-ssA9_tJN5c%2F-M6WjleJmbZ6dgvDkaZz%2Fimage.png?alt=media\&token=070a7898-87c5-4853-b1df-179ed5c3a21a)

So it would appear the value for "string" is actually going to be this hash, `2c357e386f80a13452cfec7ef58a6609034f5c08`.

#### Return statement

If you try to read this function in place, even for someone with programming knowledge this one is a bit tricky.

{% hint style="warning" %}
It's unlikely this code was written like this. Remember, decompilers **try** to recreate what it might have looked like originally, but they don't have all the information, and occasionally constructs like the above result and can be quite difficult to interpret.
{% endhint %}

One technique I would recommend when dealing with a complex function body is to break it into a few pieces in NP++ and fill in the values. So start with a copy, format it, and then fill in what you know:

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WkoTjqflH8Z6HYfMS%2F-M6WlgEsALtvtA1MxzcI%2Fimage.png?alt=media\&token=7363332d-3988-42ae-bd59-be4420b6b7e1)

A couple of things you need to know about Java to understand the above:

* when you see two vertical bars or `||` , these can be read as "OR". Its counterpart is `&&` which is read "AND".<br>
* the symbol `!` can be read as "NOT". In the case of a boolean, this means true becomes false, and false becomes true.<br>
* the word `null` means nothing - unset - no value.<br>
* The use of `?` and `:` here is a shortcut for an if / else check.\
  (expression) ? (action/value if true) : (action/value if false)

Ok, so let's fill in our known values.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WkoTjqflH8Z6HYfMS%2F-M6Wm5Byde8-vW5cBaDo%2Fimage.png?alt=media\&token=9dff245f-ac60-4a9a-8170-384c8a1c5133)

Essentially, any of the three things in the brackets evaluating to `true` will result in the function returning `false`. Confused yet? We're not done!

We now know that str is our entered PIN, str2 is either "pin" or "pin\_decoy".

The function returns boolean (true or false), takes two strings (str and str2) and a Context.

At the end of this, we've developed a pretty solid understanding, however, by casting a wider net with Frida, we can shore things up and confirm. Rather than tracing a list of functions one by one,&#x20;


# \[4b] Cast a wide net with DBI

Back in DBI land, we are ready to 'cast a wider net' by doing a less specific trace.

This time, instead of using `traceMethod`, we will instead use `traceClass`.

`Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.decrypt [2 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.encrypt [2 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.encryptPin [1 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.getBucketIdForPin [1 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.getEncryptedKeysForPin [1 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.getPinKeyForPin [1 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.padKeyForDes [1 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.patternMatches [1 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.persistPin [1 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.pinsMatch [1 overload(s)] Tracing com.github.browep.privatephotovault.crypto.CryptoUtils.setEncryptedKeysForPin [1 overload(s)]`

Perfect - looks like everything got hooked. Let's try entering a bad PIN again.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6WeI5j8-ssA9_tJN5c%2F-M6WekZ6sxAJ8f1Sd0lg%2Fimage.png?alt=media\&token=6540b2cf-7c04-4769-9566-8f52416d8c6f)

Frida has turned our app into quite the storyteller! If we peruse the list, it looks like the functions are called in this order:

* getBucketIdForPin - eventually returns null
* pinsMatch - eventually returns false
* encryptPin - returns `"7110eda4d09e062aa5e4a390b0a572ac0d2c0220"`
* pinsMatch - returns false


# \[4c] PIN bruteforce

The lab kit comes with a pre-written bruteforce and this step of the lab will cover how to run it. If you're more interested in the technical details, check out [\[4c.1\] - PIN bruteforce (in depth)](/lab/4c-pin-bruteforce/4c.1-pin-bruteforce-in-depth)

In the frida REPL, simply type bruteforcePIN() and press enter.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6XDIyqC4wWRLPmC-P7%2F-M6XEEFnx1vYN6xn4kSX%2Fimage.png?alt=media\&token=5b5ecd72-f341-46d5-96af-1ac8c12071fd)

Hey, that was pretty easy and fast right? Sadly, they aren’t all this quick.&#x20;

In fact, you may have noticed from the static analysis section that the encryptPin function simply computes SHA1 and returns the "hex string" equivalent.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M6XDIyqC4wWRLPmC-P7%2F-M6XEYMQMRyf3pP69YSc%2Fimage.png?alt=media\&token=7124b067-f10c-422a-9c78-b9ec1fd57a09)

This explains why it is so quick for us to bruteforce all 10,000 possibilities.

More secure apps tend to use much more complex and computationally expensive algorithms called Key Derivation Functions (KDF) to ensure that this type of bruteforce script would be much, much slower.


# \[4c.1] PIN bruteforce (in depth)

This page is intended to cover how the PIN bruteforce works and how it all goes together.

The requirements of our bruteforcing function can be summed up as: iterate every possible combinations of PINs, starting with 0000 and working our way up to 9999, and invoke the `pinsMatch` function on each combination until we get a `true` result.

```
function bruteforcePIN() {
	Java.perform(() => {
		var CryptoUtils = Java.use('com.github.browep.privatephotovault.crypto.CryptoUtils');
		var StringUtils = Java.use('org.apache.commons.lang.StringUtils');
		var context = getApplicationContext();
		for (var i = 0; i < 10000; i++) {
			if (i % 1000 == 0) {
				console.log('Tried', i, 'PINs');
			}
			var currentPin = StringUtils.leftPad(i.toString(), 4, '0');
			if (CryptoUtils.pinsMatch(currentPin, 'pin', context)) {
				console.log('found it!', currentPin);
				break;
			}
		}
	});
}
```

### Line 2 - Java.perform

```
	Java.perform(() => {
		// do stuff
	});
```

Wrapping code in a Java.perform are a necessary evil whenever we use frida on Android. You can bank on needing to wrap just about every call you make inside of one.&#x20;

![The good news is, frida will let you know quite definitively if you forget.](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4FjGW-VjCqLtbKVlo-%2F-M4FkCbKeIRNAdbwo3LJ%2Fimage.png?alt=media\&token=94345962-8387-4424-a59e-a0f8a0f80e0f)

### Lines 3 and 4 - Java.use

```
var CryptoUtils = Java.use('com.github.browep.privatephotovault.crypto.CryptoUtils');
var StringUtils = Java.use('org.apache.commons.lang.StringUtils');
```

Java.use statements are necessary whenever you want to interact with Java classes. This goes for both classes that are part of the target app, and also classes that are part of the standard libraries. Java.use provides a wrapper with which you can do fun things with like invoking functions!

In this case, we are obtaining two wrappers: CryptoUtils, and StringUtils. If you consider the namespaces, you may note that StringUtils is not part of the "privatephotovault" but rather part of the Apache Commons library.

### Line 5 - getApplicationContext()

```
var context = getApplicationContext();
```

At the risk of delving too far into the programming concepts, I want to explain the purpose of this call very simply to start: we need a Context to pass to our `pinsMatch` function (argument 3). That's it. That's the only reason!

*Ok, that makes sense, but what is a Context?* Essentially, every single Android app is going to have Application Context. [This article on mindorks.com](https://blog.mindorks.com/understanding-context-in-android-application-330913e32514) provides a decent explanation.

One last thing -- the getApplicationContext function is actually defined earlier in our `privatePhotoVault.js` script.

```
function getApplicationContext() {
	const ActivityThread = Java.use("android.app.ActivityThread");
	const currentApplication = ActivityThread.currentApplication();

	var ret = currentApplication.getApplicationContext();
	return ret;
}
```

As you can see, it is doing more of the same of what we've done earlier in the script. We're getting a wrapper to `android.app.ActivityThread`, then invoking two functions and ultimately returning our Application Context.

### Line 6 - For loop

```
for (var i = 0; i < 10000; i++) {
    // Loop stuff...
}
```

Now we finally get to the good stuff! This loop starts at 0, and works its way up to 9999, and incrementing by one at a time.

### Lines 7-9 - Update Progress

```
if (i % 1000 == 0) {
    console.log('Tried', i, 'PINs');
}
```

This section isn't necessary -- it's just for information. Every 1000 entries, we want to let the console know how many tries we've done.

{% hint style="info" %}
If you're wondering what the % operator is, it's called [modulo](https://en.wikipedia.org/wiki/Modulo_operation). Essentially, what if anything left over after dividing by a number.
{% endhint %}

### Line 10 - Preparing our PIN attempt

```
var currentPin = StringUtils.leftPad(i.toString(), 4, '0');
```

We're tantalizingly close to trying our PIN now! We have one final step: currently, our loop is counting from 0 to 9999, but the passcode we need to try is "0000", "0001", etc.


# Ready for more?

We hope you've enjoyed the content in this lab!

If you're interested in more content, please reach out and let us know! Contact links are on the top of the page.


# Installation & Common Flags

The frida-tools suite comes from this repo:

{% embed url="<https://github.com/frida/frida-tools>" %}

Assuming you have Python 3+ installed, you can install frida-tools with the following command:

```
pip install frida-tools
```

Once installed, you now have ready access to the frida tools suite.

These include:

| Tool Name   | Description                                                       | More Info                                        |
| ----------- | ----------------------------------------------------------------- | ------------------------------------------------ |
| frida-ps    | List running processes                                            | [frida-ps](/frida-tool-reference/frida-ps)       |
| frida-trace | Seek out and trace functions en masse based on keyword searching. | [frida-trace](/frida-tool-reference/frida-trace) |
| frida       | Frida REPL (Read-Eval-Print-Loop)                                 | [frida](/frida-tool-reference/frida)             |


# frida

Launching the REPL is accomplished from the commandline. Once frida has been installed, you can verify whether or not it is functioning by typing frida with no arguments.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M-5VLS3zSlV6ouz1bbn%2F-M-5XayfU8GuJtokHL1x%2Fimage.png?alt=media\&token=df4538f5-dd55-4ffc-8e8d-ed5e76c5c861)

### Spawning vs. attaching

Frida has the ability to either spawn a new process (using the specified app identifier) or attach to one that's already running. Which one you choose will be dependent on the app you are reversing and what particular task you are pursuing.

{% tabs %}
{% tab title="Spawning" %}
To spawn a new process, we use the CLI argument `-f <app id>`, for example: `frida -f com.app.name`

When spawning a new process, frida immediately will pause execution of the app. The intent here is to give you a chance to apply method hooks before anything happens in the application. You can type %resume to continue execution, but be warned that apps will generally force close if execution halts for more than a few seconds.

{% hint style="info" %}
You can turn off the pausing behaviour using the `--no-pause` CLI flag.
{% endhint %}
{% endtab %}

{% tab title="Attaching" %}
To attach to an existing app, you can either:

* Attach to an app using its pid. To find this, use [frida-ps](/frida-tool-reference/frida-ps).
* Attach to an app using its application identifier. To find this, use [frida-ps](/frida-tool-reference/frida-ps).
* Attach to the frontmost (focused) application, with CLI flag `-F`
  {% endtab %}
  {% endtabs %}

### Loading a script locally

If you have a .js file which you would like to inject, such as the [raptor tracing or enum scripts](/whats-next/recommended-toolkits-and-scripts#raptor-scripts), the way to do this regardless of which platform you are on is by appending the CLI argument `-l <script name>`

### Recommended Scripts

For almost every app, I recommend creating a "base script" that works for you. For me, I generally start with the Raptor tracing scripts. (See: <https://github.com/0xdea/frida-scripts> )


# frida-ps

Frida-ps, included with the standard frida tools suite, is a helpful way of listing running apps on your target device. Out of the box, an iPhone will have hundreds of running processes at first boot. Thankfully, frida-ps provides several command line options to make this process easier.

{% hint style="info" %}
Remember to utilize the`-U` flag to tell Frida you want to see apps on the device connected via USB / emulator. If you don't, you'll instead see processes running on your host machine.
{% endhint %}

Examples:

{% tabs %}
{% tab title="List running apps (-a)" %}

```
C:\>frida-ps -U -a
  PID  Name                      Identifier
-----  ------------------------  ---------------------------------------
 1797  AnalyticsService          org.android_x86.analytics
 1411  Android Keyboard (AOSP)   com.android.inputmethod.latin
 6765  Android Setup             com.google.android.setupwizard
 1285  Android System            android
20054  Blocked Numbers Storage   com.android.providers.blockednumber
20054  Contacts Storage          com.android.providers.contacts
19534  Download Manager          com.android.providers.downloads
 5617  ES File Explorer          com.estrongs.android.pop
 5438  External Storage          com.android.externalstorage
 5399  Files                     com.android.documentsui
 1285  Fused Location            com.android.location.fused
 5102  Gallery                   com.android.gallery3d
 1792  Google App                com.google.android.googlequicksearchbox
15496  Google Partner Setup      com.google.android.partnersetup
 6219  Google Play Store         com.android.vending
 1874  Google Play services      com.google.android.gms
 6274  Google Services Framew…   com.google.android.gsf
20089  MTP Host                  com.android.mtp
19534  Media Storage             com.android.providers.media
 1510  Mobile Data               com.android.phone
 1510  Mobile Network Configur…  com.android.providers.telephony
 5477  Package installer         com.google.android.packageinstaller
 6551  Photo Vault               com.enchantedcloud.photovault
 1832  Quickstep                 com.android.launcher3
 1285  Settings Storage          com.android.providers.settings
 1422  System UI                 com.android.systemui
 3360  Terminal Emulator         com.termoneplus
20054  User Dictionary           com.android.providers.userdictionary 
```

{% endtab %}

{% tab title="List all installed apps (-a -i)" %}

```
C:\>frida-ps -U -a -i
  PID  Name                         Identifier
-----  ---------------------------  ----------------------------------------------------
 1797  AnalyticsService             org.android_x86.analytics
 1411  Android Keyboard (AOSP)      com.android.inputmethod.latin
 6765  Android Setup                com.google.android.setupwizard
 1285  Android System               android
20054  Blocked Numbers Storage      com.android.providers.blockednumber
20054  Contacts Storage             com.android.providers.contacts
19534  Download Manager             com.android.providers.downloads
 5617  ES File Explorer             com.estrongs.android.pop
 5438  External Storage             com.android.externalstorage
 5399  Files                        com.android.documentsui
 1285  Fused Location               com.android.location.fused
 5102  Gallery                      com.android.gallery3d
 1792  Google App                   com.google.android.googlequicksearchbox
15496  Google Partner Setup         com.google.android.partnersetup
 6219  Google Play Store            com.android.vending
 1874  Google Play services         com.google.android.gms
 6274  Google Services Framew…      com.google.android.gsf
20089  MTP Host                     com.android.mtp
19534  Media Storage                com.android.providers.media
 1510  Mobile Data                  com.android.phone
 1510  Mobile Network Configur…     com.android.providers.telephony
 5477  Package installer            com.google.android.packageinstaller
 6551  Photo Vault                  com.enchantedcloud.photovault
 1832  Quickstep                    com.android.launcher3
 1285  Settings Storage             com.android.providers.settings
 1422  System UI                    com.android.systemui
 3360  Terminal Emulator            com.termoneplus
20054  User Dictionary              com.android.providers.userdictionary
    -  Android Easter Egg           com.android.egg
    -  Android Services Library     com.google.android.ext.services
    -  Android Setup                com.google.android.apps.restore
    -  Android Shared Library       com.google.android.ext.shared
    -  Android System WebView       com.google.android.webview
    -  Basic Daydreams              com.android.dreams.basic
    -  Bluetooth                    com.android.bluetooth
    -  Bluetooth MIDI Service       com.android.bluetoothmidiservice
    -  Bookmark Provider            com.android.bookmarkprovider
    -  BusyBox Free                 stericson.busybox
    -  Calculator                   com.android.calculator2
    -  Calendar                     com.android.calendar
    -  Calendar Storage             com.android.providers.calendar
    -  Calibration                  org.zeroxlab.util.tscal
    -  Call Log Backup/Restore      com.android.calllogbackup
    -  Camera                       com.android.camera2
    -  CaptivePortalLogin           com.android.captiveportallogin
    -  CarrierDefaultApp            com.android.carrierdefaultapp
    -  Cell Broadcasts              com.android.cellbroadcastreceiver
    -  Certificate Installer        com.android.certinstaller
    -  Chrome                       com.android.chrome
    -  Clock                        com.android.deskclock
    -  Companion Device Mana…       com.android.companiondevicemanager
    -  Contacts                     com.android.contacts
    -  Corner display cutout        com.android.internal.display.cutout.emulation.corner
    -  Dark                         com.android.systemui.theme.dark
    -  Default Print Service        com.android.bips
    -  Dev Tools                    com.android.development
    -  Double display cutout        com.android.internal.display.cutout.emulation.double
    -  Downloads                    com.android.providers.downloads.ui
    -  Emergency information        com.android.emergency
    -  Gmail                        com.google.android.gm
    -  Google Account Manager       com.google.android.gsf.login
    -  Google Backup Transport      com.google.android.backuptransport
    -  Google Calendar Sync         com.google.android.syncadapters.calendar
    -  Google Contacts Sync         com.google.android.syncadapters.contacts
    -  Google One Time Init         com.google.android.onetimeinitializer
    -  HTML Viewer                  com.android.htmlviewer
    -  Input Devices                com.android.inputdevices
    -  Intent Filter Verification…  com.android.statementservice
    -  Key Chain                    com.android.keychain
    -  Live Wallpaper Picker        com.android.wallpaper.livepicker
    -  Market Feedback Agent        com.google.android.feedback
    -  MmsService                   com.android.mms.service
    -  Music                        org.lineageos.eleven
    -  NotePad                      com.example.android.notepad
    -  PacProcessor                 com.android.pacprocessor
    -  Package Access Helper        com.android.defcontainer
    -  Phone                        com.android.dialer
    -  Print Service Recommen…      com.google.android.printservice.recommendation
    -  Print Spooler                com.android.printspooler
    -  ProxyHandler                 com.android.proxyhandler
    -  RSS Reader                   com.example.android.rssreader
    -  Settings                     com.android.settings
    -  Settings Suggestions         com.android.settings.intelligence
    -  Shell                        com.android.shell
    -  Sim App Dialog               com.android.simappdialog
    -  Simple message receiver      com.android.basicsmsreceiver
    -  Storage Manager              com.android.storagemanager
    -  SuperSU                      eu.chainfire.supersu
    -  System Tracing               com.android.traceur
    -  Tall display cutout          com.android.internal.display.cutout.emulation.tall
    -  Taskbar                      com.farmerbb.taskbar.androidx86
    -  VpnDialogs                   com.android.vpndialogs
    -  Work profile setup           com.android.managedprovisioning
    -  com.android.backupcon…       com.android.backupconfirm
    -  com.android.carrierconfig    com.android.carrierconfig
    -  com.android.cts.ctsshim      com.android.cts.ctsshim
    -  com.android.cts.priv.cts…    com.android.cts.priv.ctsshim
    -  com.android.providers.p…     com.android.providers.partnerbookmarks
    -  com.android.sharedstor…      com.android.sharedstoragebackup
    -  com.android.wallpaperb…      com.android.wallpaperbackup
    -  com.android.wallpapercr…     com.android.wallpapercropper
    -  com.android.wallpaperpi…     com.android.wallpaperpicker
    -  com.google.android.gms…      com.google.android.gms.setup      
```

{% endtab %}

{% tab title="List all running processes" %}

```
C:\>frida-ps -U
  PID  Name
-----  --------------------------------------------------
 3678  adbd
 1130  android.hardware.audio@2.0-service
 1131  android.hardware.bluetooth@1.0-service.btlinux
 1132  android.hardware.camera.provider@2.4-service
 1133  android.hardware.cas@1.0-service
 1134  android.hardware.configstore@1.1-service
 1135  android.hardware.dumpstate@1.0-service
 1136  android.hardware.light@2.0-service
 1137  android.hardware.memtrack@1.0-service
 1138  android.hardware.power@1.0-service
 1139  android.hardware.usb@1.0-service
 1140  android.hardware.wifi@1.0-service
 1128  android.hidl.allocator@1.0-service
20054  android.process.acore
19534  android.process.media
 1141  audioserver
 1148  cameraserver
 6622  com.android.chrome:sandboxed_process0
 5399  com.android.documentsui
 5438  com.android.externalstorage
 5102  com.android.gallery3d
 1411  com.android.inputmethod.latin
 1832  com.android.launcher3
20089  com.android.mtp
 1510  com.android.phone
 1422  com.android.systemui
 6219  com.android.vending
 6551  com.enchantedcloud.photovault
 5617  com.estrongs.android.pop
 1874  com.google.android.gms
 1768  com.google.android.gms.persistent
 6835  com.google.android.gms.unstable
 1792  com.google.android.googlequicksearchbox:interactor
18157  com.google.android.googlequicksearchbox:search
 5477  com.google.android.packageinstaller
15496  com.google.android.partnersetup
 6765  com.google.android.setupwizard
 6274  com.google.process.gservices
 3360  com.termoneplus
 1149  drmserver
11689  frida-helper-32
11670  frida-server
 1162  gatekeeperd
 1129  healthd
 1059  hwservicemanager
 1150  incidentd
    1  init
 1044  init
 1045  init
 1151  installd
 1189  ip6tables-restore
 1188  iptables-restore
 1152  keystore
 6024  libestool2.so
 1142  lmkd
11672  logcat
 1057  logd
 1181  mdnsd
 1160  media.codec
 1154  media.extractor
 1155  media.metrics
 1153  mediadrmserver
 1156  mediaserver
 1124  netd
 1797  org.android_x86.analytics
 1163  perfprofd
 1161  rild
 1058  servicemanager
 1145  sh
 3388  sh
 3424  sh
11667  sh
 1157  statsd
 1158  storaged
 1147  su
 3405  su
 3406  su
 3411  su
 3418  su
 1143  surfaceflinger
 1285  system_server
 1144  thermalserviced
 1164  tombstoned
 1046  ueventd
 1102  v86d
 1060  vndservicemanager
 1117  vold
 1458  webview_zygote
 1159  wificond
 1406  wpa_supplicant
 1126  zygote
 1125  zygote64
```

{% endtab %}
{% endtabs %}

Locating an app with frida-ps

### Locate a specific app using frida-ps

If you are finding yourself needing to know an app's identifier, frida-ps can be a good way to find it. It will also get us the application's current Process ID (PID) if it's running.

On your host machine, open a Command Prompt.&#x20;

Type `frida-ps -U -a`. These switches will limit our list greatly and make it easier to spot our target.

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M4FI5aDqC-YLcnhKFgQ%2F-M4FIt4F3xQcQ8TksJGP%2Fimage.png?alt=media\&token=084d1de5-83b7-4a4c-94f1-396e30d3dd25)

{% hint style="info" %}
For more info on frida-ps, see [frida-ps](/frida-tool-reference/frida-ps).
{% endhint %}

In the case of Photo Vault, the bundle identifier is `com.enchantedcloud.photovault`. You may optionally note down the PID (Process ID) however, the application identifier is primarily what we are after since we may re-launch the app several times throughout the lab (resulting in a different PID).

Great, now we’ve established our application identifier, and can see that it is running. We also know that since frida-ps gave us the data we needed, we indeed have connectivity between the host machine and frida-server on the device (or emulator).


# frida-trace


# Extracting an APK specimen from the device

This method ensures you are getting the same version of the APK as what your target device has on it. It could be particularly useful if dealing with an APK that isn't available on the Google Play store (or websites like APKPure or APK4Fun). A good example would be a corporate app that has been sideloaded.

A video containing the same steps as below has been created:

{% embed url="<https://youtu.be/_NIc-8Loerk>" %}

Before you begin, it is helpful to establish the application identifier, for instance `com.enchantedcloud.photovault`

Continuing with the photovault example:

1. Open an adb shell (as root if possible).<br>

2. Navigate to the app's installation directory by typing `cd /data/app/` and then `ls`

3. Confirm the folder exists beginning with *com.enchantedcloud*, then access the folder by typing `cd com.ench` and pressing \[TAB].<br>

4. In this directory you will find a file base.apk. We want to retrieve this off the emulator. You can either copy it's full path, or make your life easier by first copying the apk to an easier path. (e.g. copy the APK to /data/local/tmp by typing `cp base.apk /data/local/tmp`) <br>

5. Open another command window in your working directory. Finally, pull the APK to the host system with: `adb pull /data/local/tmp/base.apk`


# Troubleshooting frida connectivity

### Steps to verify frida-server is running

`adb shell`

`ps -A | grep frida`

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M-5XkLPBBbkgyIzx4tG%2F-M-A5cO6DcKmwnEO6_5H%2Fimage.png?alt=media\&token=0439421e-c09b-4a88-8919-9c16d4ac7146)

Great! The server is running. Now we can verify connectivity. Leave your adb shell and go back to your emulator.

### How to start frida-server if it is not running

See [\[1.1\] Upload frida-server to the emulator or device and run using nohup](/lab/1-lab-setup-and-initial-app-exploration/1.1-upload-frida-server-to-the-emulator-or-device-and-run-using-nohup#run-frida-server-persistently-using-nohup)


# Recommended Toolkits and Scripts

#### Raptor Scripts

![](https://488119401-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lzm4AJhr7K-rQNi6wbH%2F-M1k6VXyJh5qg_hSuSfZ%2F-M1k7ZMpFN6hRmbtpuvd%2Fimage.png?alt=media\&token=d0860d45-0631-40f9-86a5-4e1fb37512e5)

The [Raptor scripts](https://github.com/0xdea/frida-scripts) by 0xdea ([Marco Ivaldi](https://0xdeadbeef.info/)) are an excellent starting point for a base script. The 'trace' line of scripts provide prebuilt method hooking functions which greatly simplify the hooking process. There are both Android and iOS variants available. If you browse to the bottom of any of these scripts, you will see some commented out examples of how to use these scripts, included here for quick reference:

{% tabs %}
{% tab title="android\_trace.js" %}

```javascript
// usage examples
setTimeout(function() { // avoid java.lang.ClassNotFoundException

	Java.perform(function() {

		// trace("com.target.utils.CryptoUtils.decrypt");
		// trace("com.target.utils.CryptoUtils");
		// trace("CryptoUtils");
		// trace(/crypto/i);
		// trace("exports:*!open*");

	});   
}, 0);
```

{% endtab %}

{% tab title="android\_enum.js" %}

```javascript
// usage examples
setTimeout(function() { // avoid java.lang.ClassNotFoundException

	Java.perform(function() {

		// enumerate all classes
		/*
		var a = enumAllClasses();
		a.forEach(function(s) { 
			console.log(s); 
		});
		*/

		// find classes that match a pattern
		/*
		var a = findClasses(/password/i);
		a.forEach(function(s) { 
			console.log(s); 
		});
		*/

		// enumerate all methods in a class
		/*
		var a = enumMethods("com.target.app.PasswordManager")
		a.forEach(function(s) { 
			console.log(s); 
		});
		*/

	});
}, 0);
```

{% endtab %}

{% tab title="ios\_trace.js" %}

```javascript
// usage examples
if (ObjC.available) {

	// trace("-[CredManager setPassword:]");
	// trace("*[CredManager *]");
	// trace("*[* *Password:*]");
	// trace("exports:libSystem.B.dylib!CCCrypt");
	// trace("exports:libSystem.B.dylib!open");
	// trace("exports:*!open*");
	
} else {
 	send("error: Objective-C Runtime is not available!");
}
```

{% endtab %}

{% tab title="ios\_enum.js" %}

```javascript
// usage examples
if (ObjC.available) {

	// enumerate all classes
	/*
	var a = enumAllClasses();
	a.forEach(function(s) { 
		console.log(s); 
	});
	*/

	// find classes that match a pattern
	/*
	var a = findClasses(/password/i);
	a.forEach(function(s) { 
		console.log(s); 
	});
	*/

	// enumerate all methods in a class
	/*
	var a = enumMethods("PasswordManager")
	a.forEach(function(s) { 
		console.log(s); 
	});
	*/

	// enumerate all methods
	/*
	var d = enumAllMethods();
	for (k in d) {
		console.log(k);
		d[k].forEach(function(s) {
			console.log("\t" + s);
		});
	}
	*/

	// find methods that match a pattern
	/*
	var d = findMethods(/password/i);
	for (k in d) {
		console.log(k);
		d[k].forEach(function(s) {
			console.log("\t" + s);
		});
	}
	*/

} else {
 	send("error: Objective-C Runtime is not available!");
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Once one of these scripts is [loaded into a REPL session](/frida-tool-reference/frida#loading-a-script-locally), you can access the`trace` methods directly from the REPL. Alternatively, you may add them directly to the raptor script. Remember, making changes to a script while it is loaded will cause Frida to reload that script.
{% endhint %}

#### frida-awesome

Another great resource for scripts is "[frida-awesome](https://github.com/dweinstein/awesome-frida)", a repo maintained by [David Weinstein](https://twitter.com/insitusec) at NowSecure containing a large number of links that include:  talks, papers, videos, blog posts,


# Additional Resources / Questions

Learning Frida is all about finding stuff online!

We could not possibly cover all there is to know in the span of 90 minutes. Instead, our goal is to empower you and provide concrete examples of situations where as a forensic examiner, you might consider RE to help explain or validate some tricky data.

We recommend following [@fridadotre](https://twitter.com/fridadotre) on Twitter as you will be more likely to see when new versions are released.

The release notes often provide working examples you may be able to use in your own reverse engineering.&#x20;

It might seem obvious, but it's worth reiterating -- one of the best resources out there is the Frida website itself. For instance, check out this page on the [JavaScript API](https://frida.re/docs/javascript-api/) or this page with a bunch of [Android examples](https://frida.re/docs/examples/android/).

### Updates from June 9th Q\&A

On June 9th, we hosted a followup Q\&A and discussed a number of other interesting resources which are listed below.

* Azeria labs\
  <https://azeria-labs.com>
* OWASP Mobile Security Testing Guide\
  <https://owasp.org/www-project-mobile-security-testing-guide>
* CrackMes RE test apps\
  <https://crackmes.one>
* Flare-VM\
  <https://github.com/fireeye/flare-vm>
* Daily CTF Challenge from NW3C\
  <https://nw3.ctfd.io>
* iOS RE Repo\
  <https://github.com/iosre>
* Exploit Writing Tutorial\
  <https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-1-stack-based-overflows>

## Frida Telegram Group

Another great way to get in touch with a room full of reverse engineering folks is to [join the Frida telegram group](https://telegram.me/fridadotre).

## Android

Maddie Stone has an [Android application reverse engineering course](https://maddiestone.github.io/AndroidAppRE/) which focuses on reversing potentially malicious applications.&#x20;

## iOS

This lab is all about Android, but in the event you wanted to try your hand at frida on iOS, you can do that! Checkm8/checkra1n has really made this a lot more accessible than it used to be.&#x20;

There are definitely nuances that make it distinct than Android. Generally speaking, static analysis can also be more tricky!

Part 1: IOS Encryption Libraries - <https://8ksec.io/advanced-frida-usage-part-1-ios-encryption-libraries-8ksec-blogs/>&#x20;

Part 2: Analyzing Signal And Telegram Messages On IOS - <https://8ksec.io/advanced-frida-usage-part-2-analyzing-signal-and-telegram-messages-on-ios/>&#x20;

Part 3: Inspecting XPC Calls - <https://8ksec.io/advanced-frida-usage-part-3-inspecting-ios-xpc-calls/>&#x20;

Part 4: Sniffing Location Data From Locationd In IOS - <https://8ksec.io/advanced-frida-usage-part-4-sniffing-location-data-from-locationd-in-ios/>&#x20;

Part 5: Advanced Root Detection & Bypass Techniques - <https://8ksec.io/advanced-root-detection-bypass-techniques/>

Part 6: Utilizing Writers - <https://8ksec.io/advanced-frida-usage-part-6-utilising-writers/>&#x20;

<br>

One great way to get started is with Ivan Rodriguez's [free course](https://github.com/ivRodriguezCA/RE-iOS-Apps) available for those interested in pursuing iOS RE.

##


# Contact Us

Have a question? Feel free to reach out to us!

Mike can be reached [@forensicmike1](https://twitter.com/forensicmike1) on Twitter, DM's are open!

Chris can be reached via email [here](mailto:krisatha@gmail.com).


