When it comes to writing a book, the first decision that needs to be made is whether to seek publication or to self-publish. Each option has its benefits and shortcomings, and the choice ultimately depends on individual circumstances.

Regardless of whether you choose to self-publish or seek publication through a publisher, you will need to work on a manuscript. If working with a publisher, they may assist with proofreading and editing. However, if self-publishing, you will need to handle these tasks yourself. It is recommended to read through other books in your technical field to get an idea of their layout and structure before starting your own.

Published

If you choose to seek publication, a publisher will work with you on various aspects of your book, such as the title, cover, copy editing, technical editing, and distribution. However, you may not have control over the copyright and distribution rights for your book.

If seeking publication, almost all publishers will have a mechanism to contact them and will usually require specific information for a book proposal, including the title, subtitle, author(s), market description, audience, topic, keywords, competitors, and a book outline. Some technical publishers include Apress, O’Reiley, No Starch Press, Wiley, and Packt.

Self-Published

On the other hand, if you choose to self-publish, you will be solely responsible for managing the distribution and creation of your book. However, you will retain the copyright and all distribution rights.

If self-publishing, there are several options for hiring professionals to assist with various tasks to get your book published. However, it is important to note that you can also fulfill these roles yourself.

Proofreading

Getting the book reviewed by a copy editor, proofreader, and technical editor is essential. Each of these roles fills a different purpose, but at the most fundamental level, you will need another pair of eyes to look over your book for spelling, grammar, and logical errors. Additionally, having someone review the technical content is also beneficial.

Formatting

Depending on whether you plan to release a physical copy, digital copy, or both, you may want to consider formatting your book. This involves creating chapter pages and other formatting changes to your physical copy, creating an appendix and contents page, as well as adding hyperlinks for digital copies. There are various tools and services available to assist with formatting, such as FormattedBooks or freelancers on platforms like Fiverr.

Creating a Cover

Your cover should be eye-catching and have the ability to make people stop and check it out. Similarly, you should work on the back contents of your book, including a blurb and bio for yourself if you think it’s necessary. Looking at other book covers and back material for books in your technical area for inspiration is a good starting point. You can use tools such as Canva or reach out to a freelancer on Fiverr for help.

ISBN

Depending on where you live, you may need an ISBN to publish your book. In the UK, you can obtain one from Nielson, and if distributing via Amazon, you can get one for free. However, getting an ISBN from Amazon limits your distribution solely to their platform.

Distributing

The last thing to consider when self-publishing is how you will distribute your book. Whether you plan to have a digital and paperback/hardback copy or just one or the other, there are common distributors for both options. Two of the most well-known are Kindle Direct Publishing and Ingram Spark. Ingram Spark costs a small upfront fee, but they distribute to many providers, including Amazon and Google Books, making it a better all-round option.

 

For more support on creating, publishing, and releasing your technical book checkout my Ko-Fi page below!

 

As a technical expert, you’ve spent countless hours perfecting your craft, gaining knowledge, and developing innovative ideas. Yet, to be successful, it’s not enough to be a subject matter expert. You need to be able to communicate your ideas effectively to others.

Public speaking is a crucial skill in the technical field. From presenting to a small group of colleagues to addressing hundreds of attendees at a conference, how you present your content can vary drastically. In this article, we’ll dive into key techniques to help ybou give technical talks that will engage and inform your audience.

Exercise: To practice your skills, spend 20 minutes creating a 5-minute slide pack and presentation on something that interests you. Record yourself delivering the talk alongside the slides. After this then follow the advice in this article to create a new talk on a different topic. Comparing the two talks will help you identify areas for improvement and hone your skills further.

Abstract Writing

All talks require a brief overview to give potential attendees a sense of what to expect. It’s essential to include a short sentence or paragraph detailing the talk and why people should attend. Depending on the type of talk, this abstract may vary significantly, from an email introduction to a full-blown Call For Paper (CFP) submission. It’s essential to highlight what the audience will gain from the talk, such as knowledge or a practical look at a particular topic. Both resources from Forbes (who have a great article on building a bio) and Nina Zakharenko (who has a knowledge base on creating CFPs) should start you off in the right direction. 

Exercise: Write a generic bio for yourself using the Forbes template and create an abstract for a talk you have in mind.

Knowing Your Audience

Understanding your audience is critical to delivering an effective presentation. You must tailor your content and delivery style depending on the audience. Consider why the audience is attending and what they hope to gain from the talk. Is it a conference focused on a specific topic, or are you presenting to a senior leadership team on progress? Is the talk mandatory, or have the attendees chosen to watch it? The size of the audience and their expectations also play a crucial role in how you shape your content and delivery.

Content

The content of your talk should aim to engage and inform your audience. TEDx speaker David JP Phillips recommends five techniques for more impactful slides, including having one message per slide and using size and contrast to steer focus. However, the content may be limited by the audience’s expectations or the limitations of what you’re presenting. Still, it’s best to apply these rules as much as possible to have the maximum impact.

Exercise: Create a 5 minute presentation on a topic you find interesting, based on the 5 main points of advice from David JP Phillips’ video.

Practice

Practicing is an essential part of public speaking. It’s crucial to practice your talk until you have it memorized to eliminate nerves and ensure that you’re comfortable with the content. Knowing the timing and pace of your talk helps you add or remove content to fit your timeframe and prepare for pauses and questions. Controlling the silence is equally important, as it can be used to emphasize a point or let it sink in.

Body Language

Your body language plays a crucial role in engaging and keeping your audience’s attention during both in-person and virtual talks. There is an amazing talk from students at the Stanford Graduate Business School that goes into this topic.

Facing the audience and having an open posture and utilizing gestures to emphasize your message are known to help. Disrupting the audience with questions, humor, or direct one-on-one communication can also be effective.

Exercise: Practice the gestures from the Stanford Graduate Business School video.

Engagement and Storytelling

Engaging your audience is a critical part of public speaking. While your audience attends for a specific reason, such as gaining knowledge, keeping them engaged throughout the talk is essential. Storytelling is an effective technique to help you achieve this. You can share anecdotes, personal experiences, or case studies to connect with your audience and make the content more relatable.

On The Day

Undoubtedly, one of the most intimidating aspects of delivering a speech is right before the actual presentation. Firstly, it is important to surround yourself with a group of supportive individuals, whether it’s your friends or colleagues. This will help you feel more confident and at ease. Secondly, it is crucial to remember that every member of your audience has come to see you, the subject matter expert, and learn from your presentation. Keeping this in mind will help you feel more in control and capable of delivering an engaging and informative talk.

In conclusion, delivering a technical talk is a skill that can be developed with practice and the application of key techniques. By mastering these techniques, you can engage and inform your audience, share your knowledge effectively, and make a lasting impact in your field.

Exercise: Write down one thing that you learnt from this article and tweet it to me @_JamesStevenson.

Getting Started

This article walks through the process of extracting Android applications from an un-rooted device, reverse engineering those applications, and using auxiliary tools such as automation frameworks and malware analysis tools to identify if the application’s configuration is identified as malware. During this article the following tools are showcased and used:

DROID DETECTIVE 

DroidDetective is a Python tool for analysing Android applications (APKs) for potential malware related behaviour and configurations. When provided with a path to an application (APK file) Droid Detective will make a prediction (using it’s ML model) of if the application is malicious.

 

AUTO DROID 

AutoDroid is a Python tool for programmatically scripting bulk interactions with one or more Android devices. Useful for downloading and extracting all APKs from all connected devices, testing a developed application on multiple devices at once, and more.

 

ADB 

Android Debug Bridge (adb) is a command-line interface tool for communicating with Android devices. The adb command allows for a plethora of device interaction types – including acquiring a shell, installing / uninstalling apps, and interacting with the screen and other hardware accessories. 

Structure of an Application (APK)

To get things started it’s first important to understand the structure of Android applications. Android application’s are commonly written in either Java or Kotlin. When a software engineer wants to create an APK (the Android pacKage), that contains the code and materials that are run on an Android device, they will need to compile that Java or Kotlin source code to a Dalvik executable/ bytecode. This Dalvik executable is a binary that is run on the Android device. This works where each process on the device uses its own virtual machine (VM) which segregates applications. Prior to Android API level 21 (Android 5), this would have been a Dalvik Virtual Machine, and in later versions will instead use the Android Runtime (ART). Both operate in similar fashions, where they simulate a device’s CPUs, registers, and other features while running an application’s compiled Dalvik bytecode.

Decompiling and Disassembling An APK

While it is the Dalvik bytecode that needs to be run on a device, this is not human readable and so if we are to reverse engineer an application we’ll need to decompile it back into a human readable form. This is where Jadx comes in. Using Jadx we can decompile the Dalvik bytecode back into Java. This is often called pseudo Java, as it is not a one for one representation of what the original source code would have been, and instead is the decompiler’s best guess. 

Android APK files also include a file detailing the application configuration, called AndroidManifest.xml. The Android manifest includes information such as:

  • Package name and application ID
  • Application components
  • Intent filters
  • Icons and labels information
  • Permissions
  • Device compatibility information

Retrieving an Application From A Device

Being able to retrieve applications from a device is key in identifying if one of those applications is potentially malware. Before continuing ensure that ADB is enabled on the device being tested – This can be done by going to Settings, About phone, and by tapping Build number seven times. After this go to developer settings and enable USB debugging. Now connect the device and accept any prompts that are displayed. 

Android application’s are not encrypted at rest and so if an APK’s location on a device can be identified it can be retrieved. There are two shell commands that can be used when using ADB on a device (via adb shell) to help with this. These being the pm list packages command which will list all packages on the target device, and pm path <package name> which will return the path to that package’s apk file on device. Once the path has been located the adb pull <path to apk> command can be used to retrieve the APK from a device.

Automating Retrieving and reverse engineering apks

AutoDroid wraps the ability to retrieve Android applications from a device, along with other functionality, to allow for the configurable bulk interaction with an Android device. AutoDroid is configurable with a JSON file, using the below configuration all applications from all connected devices will be extracted from the device, and their manifest files extracted and saved locally to an XML format. 

{
  "devices": ["*"],
    "apps": ["*"],
    "commands": {
      "get_app": ["!adb_connect !app_path !app_id.apk"],
      "reverse_app":["reverse: !app_id.apk;manifest"]
    }
}

Ensure all AutoDroid dependencies are installed by running the below installation command:

pip install -r REQUIREMENTS.txt

After creating a JSON config file, AutoDroid can be run by providing the path to the config file as a command line parameter:

python AutoDroid.py <JSON config path>

It would now be possible to iterate through these manifest files one by one to identify trends and malicious configurations commonly seen in malware. As, on average, most users have upwards of 80 applications on a single device this would, however, take a considerable amount of time. In the next section machine learning is used to combat this issue and automate the analysis of these APKs.  

Using machine learning to identify malware

As mentioned previously, the manual process of reviewing every single APK on an Android device can be tedious. This article pitches using machine learning to serve as a first pass to help save some of this analysis time. DroidDetective is a Python tool for analysing Android applications (APKs) for potential malicious configurations in the AndroidManifest.xml file.

Dependencies for DroidDetective are installed in the same fashion to AutoDroid. DroidDetective also requires an apk_malware.model (the pre-trained ML model) at the execution root.

pip install -r REQUIREMENTS.txt

After this DroidDetective can be run as follows

python AutoDroid.py <path to APK> <optional JSON output file>

DroidDetective works by training a Random Forest binary classifier on information derived from both known malware APKs and legitimate APKs. This tooling comes pre-trained, however, the model can be re-trained on a new dataset at any time. This model currently uses permissions from an APKs AndroidManifest.xml file as a feature set. This works by creating a dictionary of each standard Android permission and setting the feature to 1 if the permission is present in the APK. Similarly, a feature is added for the amount of permissions in use in the manifest and for the amount of unidentified permissions found in the manifest.

Putting it all together 

Using what we’ve implemented so far in this article, DroidDetective can be used alongside AutoDroid to automatically retrieve applications from a device and identify if they contain malicious configurations in their manifest file. 

For this, ensure that all requirements and required files are present, and run AutoDroid with the following configuration:

{
  "devices": ["*"],
    "apps": ["*"],
    "commands": ["!adb_connect pull !app_path !app_id.apk",
    "python DroidDetective.py !app_id.apk output.json"]
}

This will result in all APKs on the target device(s) being analysed by DroidDetective. As an optional json output file is provided all of these results are appended to output.json. An example of this ca be seen below:

{
    "com.google.android.uvexposurereporter": false,
    "com.google.android.networkstack.tethering": false,
    "com.amazon.mShop.android.shopping": false,
    "com.google.omadm.trigger": false,
...
    "com.google.android.apps.cultural": false,
    "com.android.companiondevicemanager": false,
    "com.verizon.obdm_permissions": false,
    "com.android.mms.service": false,
    "com.google.android.apps.docs.editors.sheets": false
}

 

 

Learn More On Android Internals

In 2021 I released my first book with Apress publishing, Android Software Internals Quick Reference. If you work with or find programming and Android interesting please consider picking the book up for yourself! 

 

 

 

10% off Android Malware Reverse Engineering Cheat Sheets

Free and premium resources, available on everything from Android and iOS security fundamentals, reverse engineering basics, and study guides for my Udemy courses. Use code ‘MALWARE-ARTICLE’ for 10% off on the Android Malware Reverse Engineering Cheat Sheet.

 

This article discusses topics of extremism and radicalisation. Due to this; text, themes, and content relating to far-right extremism are present in this article. Please continue with care. See the following resources if you witness or experience the effects of radicalisation: Samaritans – Call 116 123 | ACT Early | actearly.uk | Prevent advice line 0800 011 3764.  In addition to the above, this research discusses the effects of violent far-right extremism. Such research could also be applied to violent far-left extremism or violent far-centre extremism, and as such the research doesn’t exist to demonstrate that one political ideology should exist over the other. Instead it serves as an example of how violent extremism, in all of it’s forms, is important to address across all ideologies. 

 

As part of my PhD research at Bristol University I’ve developed Pinpoint, a machine learning binary classification framework, used to identify violent far-right extremism… Wait, what does that actually mean? Well, when given a string of text (like a Tweet, Facebook, or Reddit post) Pinpoint is able to instantly (or at least close to instantly) identify if that text likely contains violent-far-right extremist ideology, rhetoric, or speech.

 

 

Now, this may sound awfully Minority-Report-esk, so the first question on your mind may be “who does this actually benefit?”. As well as supporting law enforcement and social network organisations to rapidly identify violent or violence provoking speech online, it also protects end users (that’s you and I) from having to read and experience such violent and extremist content.

Much research has already been performed into classifying and identifying Islamic and other extremist ideologies online, however until recently, little research had been undertaken in far-right extremism. So why is it important to identify and limit far-right extremism? Below is an excerpt from some of my research:

On the 6th of January 2021 a mob of supporters of the 45th president of the United States, Donald Trump, stormed the United States Capitol Building in an attempt to overturn the 2020 presidential election results. Among the participants of this riot were; US Republican party officials, political donors, and far-right extremists and militias – including members of: the Proud Boys, the Oath Keepers, QAnon, the Groyper Army, and others. The events at this riot lead to the deaths of five people and the injury of approximately 140 police officers. This event is just one example of how far-right extremism has gained traction over the last decade and how radicalised online communication can lead to real world terrorism events.

In 2019 The Global Terrorism Index, published by the Institute for Economics and Peace (IEP), reported a 320% rise in the total number of far-right terrorism incidents in the West (particularly in Western Europe, North America, and Oceania). This threat is not only held within the US, but also in other western nations such as the UK. In 2020 MI5 Director, General Ken McCallum, stated that while right-wing terrorism was not at the same scale as Islamic terrorism that it was, however, growing and ~29% of late-stage terrorist attack plots in 2020 had been orchestrated by right-wing extremists .

This shows that investing in new and innovative techniques, as well as building on current methods, is critical in helping to protect the UK and it’s people against the threats of far-right extremism…

Pinpoint breaks the classification of text (social media posts specifically) down into three main categories, these being:

  • Radical Language – How a post is written, including the actual letters and words used as well as the capital letter and violent word frequency
  • Psychological Signals – The tone of the message such as anger, sadness, anxiety, power, risk, reward, and other sentiments
  • Behavioural Features – How a user interacts with others in their post such as mentions and hashtags

Pinpoint was trained from messages and posts on the Parler social media network (that were harvested from the site before it originally went offline after the January insurrection in the US). Parler is self-referred to as a freedom of speech social network and is associated with Donald Trump supporters, conservatives, conspiracy theorists, and far-right extremists. In addition to this, the Stormfront internet forum, a neo-Nazi Internet forum and the internets first major racial hate site, was also used for training the classifier. All machine learning models can be measured based off their accuracy and other measures, when using Behavioural Features alone (which the Kaggle worksheet relies on) this model has the below scores. In layman’s terms this boils down to it being good, but not perfect.

  • Accuracy: 0.7368404073424881
  • Recall: 0.6270593997684567
  • Precision: 0.7848464582288358
  • F-Measure: 0.6971362094997648

Pinpoint is available completely open source, and I’ve also created a Kaggle (a data science platform) Python workbook that will allow anyone with an account the ability to test the trained machine learning model with text of their own. This workbook can be seen below.

For more information on Pinpoint and other research in the future, sign up to my mailing list below.

 

Stay up to date with research

Receive updates on my articles, books, courses, and more by signing up to the mailing list or by receiving page notifications (configured in the bottom right).

 

 

 

Some people might remember the video chat application Houseparty. Similar to others like Zoom, Skype, and What’s App, it provided light-hearted group video chat functionality alongside games and entertainment activities. In early 2020 Houseparty, developed by Epic, was at it’s peak and was hit by an unproven social media rumour that claimed the app caused users’ other online accounts (including Netflix, eBay, Instagram and Spotify) to be hacked. Epic later offered a $1m reward to anyone who could prove it was targeted by a smear campaign (however, the bounty went unclaimed). Later in 2020 Epic withdrew Houseparty from the app store and later discontinued it completely

Back when these allegations first erupted in 2020, I took a few hours out of my “busy lockdown schedule” to take apart the application and see how it was ticking behind the scenes. This article will take us through a whistle stop tour of this analysis, breaking down some of the key functions of the app, and finally conclude with my personal opinion on if I think these allegations were true and if at all possible.

Manifest

The Android manifest is a central configuration file used on an app-by-app basis. Manifests are consistently structured across all Android applications and hold information such as the application entry points, permissions, and the services that the application uses. Android as a whole is a fairly robust operating system, meaning that if an application is acting alone and inside the confines of the Android sandbox (i.e. not using any exploits or vulnerabilities) then if something isn’t in it’s manifest file, then it won’t be able to perform that action. For example, if you want your application to take a photo and tag the location, if the camera and location permissions are not set, then the application will error when it attempts to take the picture. It it possible to dynamically declare some of these permissions in the code base, but for the most part the manifest file is used.

Permissions

So to start with, lets have a look at permissions. When it comes to permissions (and especially when looking at if an application is malicious) the goal is normally to identify elements that are out of the ordinary for the type of application being reviewed. For example, having a camera application that has the premium SMS permission would be seem a bit odd. When it comes to Houseparty, there are quite a few permissions listed, below is an excerpt of some of the most interesting:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-feature android:name="android.hardware.microphone"/>
<uses-permission android:name="com.android.vending.BILLING"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>

Some of these permissions are self explanatory, however, lets take a closer look at a few.

  • READ_PHONE_STATE  – An application with this permission can access a device’s phone number, information about ongoing calls, and cellular network information.
  • FOREGROUND_SERVICE – A fairly harmless permission, this permission allows for an application to run in the background while the application is not actively running or in the Android task stack. However, to do this, it must show a constant notification to the user. This means that unless a  notification for Houseparty is in the device notification drop-down then it isn’t running on a device (outside of one or two edge cases).
  • RECEIVE_BOOT_COMPLETED – Boot Complete is one of these edge cases. This permission means that when the device restarts, the application can be ‘woken up’ and begin running. Without this, an application would need to be restarted by either another application or by the user manually each time the device restarted.
  • WAKE_LOCK – Another fairly simple permission. This permission allows the application to stop the screen from dimming. Such functionality is usually used for call applications to force the screen to stay active while on video calls.
  • REQUEST_INSTALL_PACKAGES – This permission allows Houseparty to request to install third party applications on the device. This is, however, not as scary as it sounds as there are several safeguards in place to stop the abuse of this permission. Unless you have the  Unknown Sources option ticked in your Android settings this will fail, and even if you do, you will receive a yes/no prompt before an application is installed through this method.
  • BILLING – Another scary sounding permission, however, not as bad as it sounds. Here we can see the difference between com.android.vending (for this permission) and android.permission (for the others). This means that this permission doesn’t reside in core Android and instead in vending, which is the internal name for the Google Play Store. Instead of what it may sound like, this permission doesn’t give the application the ability to access any of your financial information, instead it allows the application to request transactions through the Play Store. This will also display a yes/no prompt when it occurs.

Services

The term ‘Services’ in Android is a general catch all term. In this context services will refer to anything that allows the application to run in the background or foreground when the application isn’t being manually and directly run, and is visible, to the user. Services, such as this, can be declared in the manifest file as well as dynamically in the codebase. Some examples of services being declared in the Houseparty manifest can be seen below:

<service android:name="com.instabug.chat.network.InstabugPushNotificationTokenService" android:permission="android.permission.BIND_JOB_SERVICE"/>
<service android:name="com.lifeonair.houseparty.core.sync.video.BackgroundVideoService" android:enabled="true" android:exported="false"/>
<service android:name="com.instabug.library.internal.video.ScreenRecordingService"/>

There are a considerable amount of services in the manifest, to many to list here, however many of these belonged to a package named InstaBug, which on their website describe themselves as:

Instabug empowers mobile teams to release with confidence through comprehensive bug and crash reports, in-app surveys, and real-time user feedback

As for the other services listed here, the BackgroundVideoService seems to be the main service used by the application. Earlier I mentioned that Foreground services must show a notification to the user when the activity is running. This restriction is only in place from Android 8.0 Oreo (API Level 26). In the Houseparty decompiled codebase we can see this notification being created, for this service, here:

public static void a(Context context, Notification notification) {
  hxw.a(4, "Start service to keep alive and show active party notification", (Throwable) null);
  Intent intent = new Intent(context, BackgroundVideoService.class);
  intent.setAction(b.SHOW_ACTIVE_PARTY_NOTIFICATION.name());
  intent.putExtra("ACTIVE_PARTY_NOTIFICATION", notification);
  b = true;
  if (Build.VERSION.SDK_INT >= 26) {
    context.startForegroundService(intent);
  } else {
    context.startService(intent);
  }
}

The next service, ScreenRecordingService, is for recording the screen of the device. This uses an Android system service named media_projection. Below we can see Houseparty retrieve the Media Projection system service and start an activity with it. However, as this service declaration in the manifest is part of the Instabug class, my gut instinct is that this is part of some bug reporting functionality.

if (bundle == null) {
  boolean z = true;
  this.a = getIntent().getBooleanExtra("isVideo", true);
  this.b = getIntent().getBooleanExtra("isInitial", true);
  Intent createScreenCaptureIntent = ((MediaProjectionManager) getSystemService("media_projection")).createScreenCaptureIntent();
  if (!this.a) {
    startActivityForResult(createScreenCaptureIntent, 101);
  } else if (SettingsManager.getInstance().getAutoScreenRecordingAudioCapturingState() == Feature.State.ENABLED) {
    if (ContextCompat.checkSelfPermission(this, "android.permission.RECORD_AUDIO") != 0) {
      z = false;
    }
    if (!z) {
      ActivityCompat.requestPermissions(this, new String[]{"android.permission.RECORD_AUDIO"}, 2022);
    } else {
      a();
    }
  } else {
    a();
  }
}

Misc

Before we stop talking about the Manifest there are one or two honourable mentions that are worth discussing. These being the use of the Facebook marketing and the HockeyApp providers, where on their website HockeyApp describe themselves as:

HockeyApp is the best way to collect live crash reports, get feedback from your users, distribute your betas, and analyze your test coverage.

<provider android:name="com.facebook.marketing.internal.MarketingInitProvider" android:exported="false" android:authorities="com.herzick.houseparty.MarketingInitProvider"/>
<activity android:name="net.hockeyapp.android.LoginActivity"/>

As with Instabug above, there are a considerable number of third-party libraries being used inside of the Houseparty application. This is not out of the ordinary for applications of this size, however, does pose an additional attack surface where if a vulnerable or malicious third party service is used it can provide an additional risk to the end user.

Side Loading / Hot Swapping

Earlier it was briefly mentioned how the REQUEST_INSTALL_PACKAGES permission could be used, if user consent was provided, to install third-party applications on some devices. Here we’ll be diving into other methods that the application uses for dynamically running code/ content. 

Here the term side loading is used to refer to the process of programmatically running third party code, or data, without going via the Google Play Store. Loading code in this form would mean that it typically wouldn’t be visible as part of a static code review such as this – meaning that potentially malicious code **could** be installed when then application is running.

After an initial look into the Houseparty decompiled codebase there isn’t an immediate indication that the application is doing this. However, Houseparty does have several dynamic elements, primarily it’s ability to dynamically update what games can be played in the application. While the specific games are hard coded into the app (e.g. Trivia, Heads Up, etc) the packs used in these games aren’t hard coded. Instead they are downloaded and stored in a Realm Database. I’ve only taken a look at the Heads Up game however, it seems likely that the same logic is applicable across all of their game offerings. 

It’s important to stress here that while these games are dynamically downloaded there doesn’t appear to be any code downloaded, and instead just elements that can be plugged into the game engine. As below we can see the elements for one of these ‘Heads Up Card Packs’ being updated with this data.

public static HeadsUpDeckModel buildFromParcel(Parcel parcel) {
  Builder builder = new Builder();
  String unused = builder.id = parcel.readString();
  List unused2 = builder.skus = parcel.createStringArrayList();
  String unused3 = builder.name = parcel.readString();
  String unused4 = builder.description = parcel.readString();
  String unused5 = builder.imageUrl = parcel.readString();
  boolean z = true;
  if (parcel.readInt() != 1) {
    z = false;
  }
  boolean unused6 = builder.free = z;
  List unused7 = builder.cards = parcel.createStringArrayList();
  return builder.build();
}

Conclusion

Some questions on if Houseparty was truly malicious may still stand: “well, what if they were to implement the side loading code in the future?” or “what if another one of the game packs side loads code?“. As a whole Google has very stringent rules on the side loading of code, with them stating that:

Apps or SDKs that download executable code, such as dex files or native code, from a source other than Google Play… are explicitly prohibited.

In general, Google also have fairly good automated systems for picking up these types of applications before they enter the Play Store, known as Google Play Protect, and scans over 50 billion applications, on user devices, per day.

To conclude, in my personal opinion I don’t believe Houseparty was doing anything malicious behind the scenes, however, I do recommend the advice noted by the team at NakedSecurity, across the board for all users/ applications, it’s a good read.

 

Reverse Engineering Android Malware Course

I’m in the process of developing a Udemy course on reverse engineering Android malware. Enter your email address below to receive an update and early-bird discount code once the course is live, along with updates on other resources I make available.


 

Learn More On Android Internals

In 2021 I released my first book with Apress publishing, Android Software Internals Quick Reference. If you work with or find programming and Android interesting please consider picking the book up for yourself! 

 

 

 

10% off Android Malware Reverse Engineering Cheat Sheets

Free and premium resources, available on everything from Android and iOS security fundamentals, reverse engineering basics, and study guides for my Udemy courses. Use code ‘MALWARE-ARTICLE’ for 10% off on the Android Malware Reverse Engineering Cheat Sheet.

 

This article covers the building blocks of Android malware analysis, getting you ready to go, with everything needed when it comes to reverse engineering malware on Android! 

Types of Android Malware

For Android devices running Google Play Services, and in turn using the Google Play Store, one of the biggest application security defences is the Google Play Protect utility. Google Play Protect identifies malware in two forms; on device, and off device (also known as Cloud). On device protection works by daily scanning all applications installed on Android devices, while cloud protection works by vetting and reviewing applications that are uploaded to the Google Play Store. 

As an authority on Android Malware, we’ll be using the definitions provided by Google Play Protect for Android Malware (also referred to as Potentially Harmful Applications). In addition to device malware, some antivirus providers also class personally unwanted software (POS) or Mobile Unwanted Software (MUwS) as harmful to a device. These won’t be included here as, while they pose a danger to the device ecosystem,  they do not strictly fall into the category of malware. These can include:

  • Ad fraud
  • Unauthorized Use or Imitation of System Functionality
  • Disruptive ads
  • Social Engineering
  • Data collection and restricted permissions abuse

TypeDescription
TrojanUsed in combination with other malware categories, a Trojan will usually appear as something it is not. For example a legitimate game, application, or useful piece of software. While it may appear to be benign it will then perform undesirable actions against the user.
SpywareSpyware is any form of application or software that transmits personal or personally identifiable information to a third party without adequate control, notice, or consent - this can include contact information, photos or other files, messages from email, call logs or sms, web history and bookmarks and information from the device '/data/' directory. This can also include actions such as recording video, audio, calls, and acquiring application data.
StalkerwareA subset of this type of malware and is often seen used as a commercial/ spyware-as-a-service, where the data is often sent to a third party that is not the PHD provider. Legitimate versions of such software can be used by parents to track their children, however, a persistent notification should be displayed at all times.
SpamApplications that send unsolicited messages to the user's contacts, the user themselves, or others without adequate consent from the user.
Rooting - An application or code that roots the target device without consent from the user and in turn executes some form of further malicious code onto the device.
RansomwareDefined as an application or code that gains partial or full control over a device and in turn offers to relinquish that control for a performed action such as payment. This can include encrypting device data or enabling device admin controls to lock the user out of the device.
Elevated privilege abuseSimilar to rooting, this is where an application or code compromises system integrity by breaking the app sandbox, gaining elevated privileges, or changing or disabling access to core security-related functions. This can include everything from disabling SELinux, abusing features so that the application cannot be uninstalled, abusing permission or authentication models.
PhishingSimilar to a Trojan, this is where an application or code masquerades as a legitimate piece of software and requests user authentication credentials or other personal and private information. This data is then sent to a malicious third party.
Non-Android threatThis malware category applies to Android applications and code that do not provide a direct threat to the device ecosystem or user, and instead leverage the device to target other platforms - such as connected devices or devices on the same network.
Hostile downloadersThis category covers applications and code that are utilised to download other malware. Google Play Protect has a collection of rules it uses for identifying if a given piece of downloader software if classed as hostile, these being:
There is reason to believe it was created to spread PHAs and it has downloaded PHAs or contains code that could download and install apps; or
At least 5% of apps downloaded by it are PHAs with a minimum threshold of 500 observed app downloads (25 observed PHA downloads).
They don't drive downloads without user interaction
All PHA downloads are initiated by consenting users.
Denial of service (DoS)An application or code that performs a denial of service (DoS) / distributed DoS attack against a third party system or resource.
Billing fraudBilling fraud summarises several types of an application or code that leads to the user being charged for a service in an intentionally deceptive way. This is commonly broken down into: SMS, Call, and Toll fraud.
BackdoorA backdoor will often allow for a malicious actor to gain unwanted, unauthorised, and potentially harmful remote control of the target device.

Android Applications 101

Android application’s are commonly written in either Java or Kotlin. When a software engineer wants to create an APK (the Android pacKage), that contains the code and materials that are run on an Android device, they will need to compile that Java or Kotlin source code to a Dalvik executable/ bytecode. This Dalvik executable is a binary that is run on the Android device. This works where each process on the device uses its own virtual machine (VM) which segregates applications. Prior to Android API level 21 (Android 5), this would have been a Dalvik Virtual Machine, and in later versions will instead use the Android Runtime (ART). Both operate in similar fashions, where they simulate a device’s CPUs, registers, and other features while running an application’s compiled Dalvik bytecode.

Decompiling and Disassembling An APK

While it is the Dalvik bytecode that needs to be run on a device, this is not human readable and so if we are to reverse engineer an application we’ll need to decompile it back into a human readable form. This is where Jadx comes in. Using Jadx we can decompile the Dalvik bytecode back into Java. This is often called pseudo Java, as it is not a one for one representation of what the original source code would have been, and instead is the decompiler’s best guess.  

Android application architecture

An Android application (APK) is an archive-like file format, that contains several other files and folders. This including:

  • assets— A directory for application assets. This is for arbitrary storage; anything provided by the application creator can be stored here.
  • res— A directory with all resources that are not compiled into arsc (icons, images, etc.).
  • lib— A directory for native libraries used by the application. Contains multiple directories for each supported CPU architecture that the application has been compiled for.
  • META-INF— A directory for APK metadata – including signatures.
  • xml— The application manifest in a binary XML formatted file that contains application metadata — for example, its name, version, permissions, etc.
  • dex— The classes.dex file contains the compiled application code in the Dex file format. There can be additional .dex files (named classes2.dex, etc.) when the application uses multidex.
  • arsc— This file contains precompiled resources—such as strings, colours, or styles.

Android Manifest File

Android APK files also include a file detailing the application configuration – AndroidManifest.xml. The Android manifest includes information such as:

  • Package name and application ID
  • Application components
  • Intent filters
  • Icons and labels information
  • Permissions
  • Device compatibility information

Building and Reverse Engineering an ordinary application

First things first, especially if you’re new to Android as a whole, my recommendation would be to build a simple Android application. As an example open up Android Studio and create one of the following simple applications. This will give you a better understanding of Java, how Android applications are written, and some experience using a device/ emulator when running an application.

  • A simple note-taking application
  • A quote of the day application
  • A simple password manager
  • An Android file explorer

After compiling the created application to an APK, your next step will be to decompile that application to pseudo-Java, using Jadx. This will provide you with an understanding of how code goes from source code, to Dalvik assembly, then back to decompiled pseudo Java.

Reverse Engineering Android Malware

Kicking things off, it’s important to bear in mind that any malware analysis should be performed on a segregated system, such as a VM, with minimal connection to the outside world. 

All of the malware samples used today can be found on the Android Malware GiHub repository by Ashishb.

Malicious Skype Application

In the rouge_skype folder you can find a file named skype.apk. If loaded onto a device this application would present itself as a regular, if old, Skype application.  That being the case, we can use some tools to identify a more nefarious purpose. 

Virus Total

Before this, however, we can upload the APK onto Virus Total (a tool for analysing and sharing suspicious files, domains, IPs and URLs). With an immediate look, we can see that we’re not the first people to be looking at this APK, with the first submission of the file to Virus Total (VT) being back in 2015. Straight off the bat, VT gives us a clear indication that this APK is potentially (and probably)malicious

Reverse Engineering

The next step is to disassemble this APK and begin diving into it’s contents. Using APKTool, the contents of the APK archive can be identified (for information on these files see the Android Application Architecture section above).

Entering the assets folder of the application we can see several obfuscated file names. Using the file command it can be identified that one of these files, a , is actually a jar file. As an APK is simply an instance of a Jar (Java Archive) file, with some additional Android files dotted in there, this can be reverse engineered with ease.

Using APKTool a second time, this time on the Jar file, it can be seen that the jar file is successfully de-bundled into it’s core components, and the internals of a second APK can be seen. This is a good indication that the original Skype application was patched in some way and is dynamically loading the jar file inside of the assets directory at runtime. 

Further analysis could be performed on both this APK and the jar file, including reviewing the manifest file, reviewing interesting functions, and identifying the link between the two files. 

 

Dendroid

The next malware sample we’ll be reviewing can be found in the dendroid folder in the GitHub repository. Dendroid malware was quite sophisticated in it’s time, being first identified in 2014 by Symantec. Falling into several of the above categories, Dendroid was capable of deleting call logs, opening web pages, dialling numbers, recording calls, SMS interception, uploading files, opening applications, and performing denial of service attacks.

APKLab

Instead of manually reviewing the file structure and disassembled SMALI of this application, we’ll be using APKLab (A Mobile Threat Intelligence Platform by Avast), as an example of automated reverse engineering tooling (if you do not have access to APKLab, you can use other automated tooling such as Quark).

Using APKLab, this APK can be uploaded and an analysis performed on it. Some key information that APKLab provides, includes:

  • Suspicious permissions
  • URL strings
  • Generated files
  • Emulator check for known build properties
  • A network dump
  • Entrypoints
  • More…

 

By now, you have an entry level understanding into the internals of Android applications, Android malware types, and several areas and variables to look out for during Android malware analysis. See below for additional resources on the topic!

 

Reverse Engineering Android Malware Course

I’m in the process of developing a Udemy course on reverse engineering Android malware. Enter your email address below to receive an update and early-bird discount code once the course is live, along with subscribing to my mailing list.

 

 

Introduction To Reverse Engineering Course

I’ve released an Android reverse engineering course inspired by my interest in game design. This course walks through the fundamentals of reverse engineering and uses Android games as a fun and practical starting point.

 

10% off Android Malware Reverse Engineering Cheat Sheets

Free and premium resources, available on everything from Android and iOS security fundamentals, reverse engineering basics, and study guides for my Udemy courses. Use code ‘MALWARE-ARTICLE’ for 10% off on the Android Malware Reverse Engineering Cheat Sheet.

Continue reading “Android Malware Reverse Engineering”

 

Let’s start things off with a question; what does the TV show Black Mirror, the series Person of Interest, and Android Google Play devices all have in common? Well it’s not the fact that they all involve technology, nor is it the fact that they all include mobile devices, instead it’s the fact that they all include elements of using machine learning and AI to detect malicious activity. In the case of Android Google Play devices this is via the Safety Net APIs  – and it’s this we’ll be talking about today. By the end of this article we’ll have answered the bellow, by reverse engineering the Android SafetyNet Attestation API and framework.

How do app developers identify if a device an application is running on is legitimate?

Google Play Safety Net Attestation API

What is SafetyNet?

Google SafetyNet (also known as SNet) is a suite and umbrella of functionality available on Android devices that have Google Play Services available. Google Play Services comes with most Android devices and allows devices to have applications such as the Google Play Store installed on them. Some devices, such as a selection of Huawei devices, do not have Google Play Services available, and so SNet is not available on these devices. 

The SNet umbrella is broken down into the following:

SNet Safe Browsing API

The SNet Browsing API provides services to application developers, running application’s on device’s with Google Play Services, the ability to check a given URL for if it has been identified as a known threat by Google. For example a web browsing application could use this API to identify if the URL a user was visiting was malicious and in turn the URL could be blocked.

SNet Verify Apps API

The SNet Browsing API provides services to application developers, running application’s on device’s with Google Play Services, the ability to check if there are any malicious or harmful applications running on the same devices as the application. For example a banking application could use this API to ensure it is not used on the same device as malware.

SNet reCAPTCHA API

This API extends the Google reCAPTCHA framework and allows application developers to use reCAPTCHA checks inside of their application. For example these reCAPTCHA checks could be used to validate user requests or form submissions.

SNet Attestation API

The SNet attestation API is one of the most interesting of these APIs and the one that we’ll be focusing on moving forward. The Attestation API is an anti-abuse API that allows application developers to assess the Android device their application is running  on – in turn being able to identify if the application the device is running on is rooted or compromised in some way. As an example, banking applications can use this API to ensure they’re not running on a rooted device.

Rooting and Root Detection

Both Android and other mobile operating systems have a concept of privileged control on a device. Here, when talking about privileged control, it refers to providing a user with extensive controls over the device, which the manufacturer did not intend for the end-user to have and can normally allow for actions such as breaking application sandboxing, accessing and modifying system actions, and accessing the underlying kernel. For Android this is commonly referred to as rooting. From the above it can been seen why some applications would not want to run on rooted devices, including user security, intellectual property controls, and it leading to future exploitation or control of an application. Below can be seen a sample of application’s on Android that implement root detection – this comes in many forms; from instructing the user the device is rooted, closing the application completely, or silently logging that the device is rooted.

One of the most common root detection mechanisms in place in Android applications is the Google Play SNet API. Later on this article will dive into the internals on how the SNet API operates, however, for now the below demonstrates a sample wrapper application (an application that’s sole purpose is to call the API and display the results to the screen) using the API on both a standard and rooted Android device. 

How Developers get Attestation data from SNet

Now that we can see that applications using the SNet API are magically able to identify if a device is rooted or not, the next question is, how? The process for a developer is a fairly simple one. At first Google Play Services periodically runs on the device and downloads a jar file (Java archive), this code is then dynamically run and aggregates an assortment of data (Described later) on the device. This information is then sent to an unknown Google server for analysis. After this point third party applications running on the device can then call the API and will receive several variables in response.

The variables received by the application from the API include:

  • ctsProfileMatch: The strictest identifier on the device’s integrity.  If false then the device has failed Android compatibility testing and is not a Google-certified Android device.
  • basicIntegrity: The more lenient identifier of device integrity. If false then it is likely that the device has been tampered with in some way.

There are also several optional variables that can be returned:

  • error: Error information relating to the current API request.
  • advice: Recommendations for fixing the device state.
  • evaluationType: How the device evaluation was performed, i.e. is it backed by hardware?

Taking apart the mystery Jar file

As previously mentioned, Google Play Services periodically aggregates data from an Android device and sends it to a server for analysis. While the decision making, on if a device is tampered with or not, is performed on the server the data aggregation occurs on the device. This means that by reverse engineering the Jar file that is downloaded by SNet a picture can be put together of what data goes into identifying the integrity of a device. 

Timeframe of SNet Attestation versions

There have been many versions of SNet over the years, and with each new version comes new forms of data aggregation that occur on the device. Below shows an incomplete timeframe of SNet versions (put together in part by the research from Collin Mulliner & John Kozyrakis) up to 2019, however, there have been many more versions both between these dates and after. 

SNet Attestation Modules

The data aggregation performed by the SNet Jar file is broken down into several categories based on their functionality. From this point I’ll walk through a handful of the modules available in SNet version 10000700. 

Device State Checker

DeviceStateChecker.java | SNet Version: 10000700

Including variables: the verify boot state, verifying mode, security patch level, and if OEM unlock is supported on the device.

Settings Finder

SettingsFinder.java | SNet Version: 10000700

Including variables: if ADB is enabled, the device fingerprint status, the lock screen timeout, lock screen type, if non-market apps are enabled, notification visibility at lock screen, Android smart lock, and the storage encryption status.

SD Card Analyzer

SdCardAnalyzer.java | SNet Version: 10000700

Process: this module saves a JPG file to the external storage of the device and periodically checks in on it. If the image has been altered, removed, or changed in any way it’s reported as a indicator or compromise. 

Rooting File Finder 

RootingFileFinder.java | SNet Version: 10000700

Process: this module looks for the presence of several files and file paths on the device, including: “/system/bin”, “/dev/block/loop”, “/system/xbin”, “/bin”, “/xbin”, “/proc/self/mountinfo”, and more. 

Preferred Package Finder

PreferredPackageFinder.java | SNet Version: 10000700

Process:  this module aggregates the set default installer and web browser on the device (i.e. Google Play Store and Chrome).

Captive Portal Detector

CaptivePortalDetector.java | SNet Version: 10000700

Process: this module sends a request to a hardcoded Google server and saved the IP address, response body, and response code. Presumably this is compared with the known response by the integrity check on the server to identify if a captive portal or man-in-the-middle was present on the device.

Wrap-Up

In addition to the above sampled aggregated variables, there are many more that SNet aggregates and sends to the Google server for integrity reviews. In late 2019 the version of SNet I reviewed included approximately 55 variables that it was aggregating. 

In past research I’ve previously developed a tool called Tamper, which seeks to replicate some of the key functionality of SNet. I may write a follow on article on this process, however, for now you can see it’s development over on GitHub.

 

 

Develop Your Reverse Engineering Skills

I’ve released an Android reverse engineering course inspired by my interest in game design. This course walks through the fundamentals of reverse engineering and uses Android games as a fun and practical starting point.

Learn More On Android Internals

In 2021 I released my first book with Apress publishing, Android Software Internals Quick Reference. If you work with or find programming and Android interesting please consider picking the book up for yourself! 

 

 

 

ANDROID CHEAT SHEETS AND STUDY GUIDES

Free and premium resources, available on everything from Android and iOS security fundamentals, reverse engineering basics, and study guides for my Udemy courses.

 

The most common tools used for obfuscation in Android include ProGuard, DexGuard and R8. For most of this article the terms R8, DexGuard, and ProGuard will be used interchangeably as functionality is loosely the same between them, however, the main differences will be detailed below. ProGuard analyses and optimizes the Java bytecode rather than the direct Java/Kotlin code base. ProGuard implements a collection of techniques, these being:

  • Shrinking – Identifies and removes dead code that is not reachable or is unused. Including classes, fields, methods, and attributes.
  • Optimizer – Performs optimization on code and code flow where performance changes can be made.
  • Obfuscator – Renaming aspects of the codebase (i.e., classes, fields, and methods) to names that are deliberately obscure and meaningless.
  • Preverifier – Performs preverification checks on the bytecode, where if the checks are successful, the classfiles are annotated with preverification information. This is required for Java Micro Edition and for Java 6 and higher.

R8 and ProGuard

When enabled, in  Android Gradle plugin 3.4.0 and above ProGuard is no-longer used by default for obfuscation, optimization, and other tasks. Instead, R8 is used. R8 provides a similar suite of functionality to ProGuard (and DexGuard, it’s premium alternative), however, is being actively developed by the team at Android. By default, when compiling a release build of an Android application R8 will automatically perform these functions (as described above) on the codebase. Neither R8 nor ProGuard are categorically better than one another, instead they each come with their own benefits and drawbacks. Some reasons for why R8 was adopted in the Android Gradle plugin include: 

  • With ProGuard, the compiled Java bytecode is taken and converted into optimized Java bytecode and then further converted into optimized Dalvik bytecode. The process for R8 skips a step, taking the Java bytecode straight to optimized Dalvik bytecode – in turn saving time during the building process.   
  • It’s estimated that ProGuard reduces a shrunken application’s size by ~8.5%, while R8 reduces it by ~10%.
  • R8 comes with more widespread Kotlin support and optimizations.

Enabling Obfuscation 

Depending on the version of the Android Gradle plugin being used, the below will either enable ProGuard by default or R8. Edit the ‘buildTypes’ tag in the ‘gradle.build’ file to ‘minifyEnabled true’. To enable obfuscation on a debug build, switch out ‘release’ for ‘debug’. An example of using obfuscation on a release build can be seen below:

buildTypes {

    release {

        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 
        proguardFile 'proguard-project.txt' 

    }

}

For the above, if using an older version of the Android Gradle Plugin, and you wish to enable ProGuard over R8, you may need to manually disable R8 in your ‘gradle.properties’, as below:

android.enableR8=false 
android.enableR8.libraries=false

For steps including how to enable ProGuard on the newest versions of the Android Gradle Plugin see their official documentation

The Mapping File

After following the above when making a release build, using Gradle, the Java bytecode will have been analysed by ProGuard. ProGuard will provide a log file of the stages undergone. This is saved at the following relative path to the application project root.

Mapping file relative location:

app/build/outputs/mapping/release/mapping.txt

This file shows the changes that ProGuard has implemented. An example of part of this file is below. In this example it can be seen that the
function ‘showString’ in ‘MainActivity’ has been allow-listed while the other function in ‘MainActivity’ named ‘loadMe’ has not and is now renamed to ‘n’.

Example of mapping file:

com.example.java_dexloadable.MainActivity -> com.example.java_dexloadable.MainActivity:
java.lang.String loadMe() -> n
1:1:java.lang.String com.example.java_dexloadable.StringsClass.stringGetter(int):0:0 -> showString
1:1:void showString(android.content.Context,int):0 -> showString
2:2:void showString(android.content.Context,int):0:0 ->showString

If a function or class is not in this mapping, then it has been shrunken out (meaning that it wasn’t being used in the code), or it has not been
obfuscated (due to being allow-listed).

The ProGuard Allow-List

By default, ProGuard will shrink, optimize, and obfuscate everything in the Java bytecode. This can be controlled by editing the ProGuard
file located at ‘app\proguard-rules.pro’, in the root of an application directory. This file can be renamed and moved and is specified in the
‘gradle.build’ file.

The following example rule allow-lists the ‘showString’ function in the class ‘com.example.java_dexloadable.MainActivity’. Here you need
to specify the access level of the class and function (‘public’, ‘private’, ‘package-private’, etc.) as well as the parameters for the function:

-keep class com.example.java_dexloadable.MainActivity {
    public showString(android.content.Context, int);
}

The following example is the same; however, in this example all functions in the ‘MainActivity’ are allow-listed:

-keep class com.example.java_dexloadable.MainActivity {
    public *;
}

Entry Points

ProGuard automatically allow-lists (also known as white-lists) entry points to an application (e.g., an activity with the MAIN or LAUNCHER category). It’s important to bear in mind that entry points used as part of reflection will not be automatically allow-listed, and so if using refection, these entry points will have to be manually allow-listed. This, however, will minimize the effectiveness of obfuscation as the frequency of plain text components will be higher. The entry points that are automatically added to an allowlist by ProGuard typically include classes with main methods, applets, MIDlets, activities, etc. This also includes classes that have calls to native C code.

The Different Types of Keep

In the preceding two examples, the ‘keep’ keyword is used. There are, however, several different types of keep keyword.

  • No Rule – Shrinks Classes, Shrinks Members, Obfuscates Classes, Obfuscates Members
  • -keep – None
  • -keepclassmembers – Shrinks Classes, Obfuscates Classes
  • -keepnames – Shrinks Classes, Shrinks Members

Example Rules

In the following example, the Java Package Name is ‘java_dexloadable’, and all rules have been added to the ‘Proguard-rules.pro’ file.

Keeps (allow-lists) all methods in the ‘MainActivity’ class:

-keep class com.example.java_dexloadable.MainActivity {
    public *;
}

Keeps (allow-lists) the ‘showString’ function in the ‘MainActivity’ class as well as the ‘MainActivity’ class itself:

-keep class com.example.java_dexloadable.MainActivity {
    public showString(android.content.Context, int);
}

Keeps (allow-lists) everything under the top-level package (shouldn’t be used):

-keep class com.example.java_dexloadable.** { *; }

Keeps (allow-lists) the function stringGetter but not the class StringsClass itself:

-keepclassmembers class com.example.java_dexloadable.
StringsClass {
    public stringGetter(int);
}

Repackage whole package into a single root:

-repackageclasses

Doesn’t perform the ProGuard shrink step:

--dontshrink

 

Read More

This article was derived from a chapter in my book Android Software Internals Quick Reference. If you found it interesting please consider picking the book up for yourself! 

 

 

 

Adverts





 

During this article we’re going to take a whistle stop tour of Android reverse engineering to get you to the stage of being able to take apart and review a simple Android game, as soon as possible. 

What  you’ll need to get started

For this walkthrough the only tooling you’ll need is an APK (Android PacKage) decompiler, called Jadx. Jadx can be installed onto Windows, Linux, and MacOS by following the instructions on their website. Using Jadx is as simple as running:

jadx-gui <path to the APK file>

How to reverse engineer an application

Android application’s are commonly written in either Java or Kotlin. When a software engineer wants to create an APK (the Android pacKage), that contains the code and materials that are run on an Android device, they will need to compile that Java or Kotlin source code to a Dalvik executable/ bytecode. This Dalvik executable is a binary that is run on the Android device. This works where each process on the device uses its own virtual machine (VM) which segregates applications. Prior to Android API level 21 (Android 5), this would have been a Dalvik Virtual Machine, and in later versions will instead use the Android Runtime (ART). Both operate in similar fashions, where they simulate a device’s CPUs, registers, and other features while running an application’s compiled Dalvik bytecode.

While it is the Dalvik bytecode that needs to be run on a device, this is not human readable and so if we are to reverse engineer an application or game we’ll need to decompile it back into a human readable form. This is where Jadx comes in. Using Jadx we can decompile the Dalvik bytecode back into Java. This is often called pseudo Java, as it is not a one for one representation of what the original source code would have been, and instead is the decompiler’s best guess. 

Decompiling and Disassembling An APK

Reverse Engineering Android Games

There are several reasons why you might want to start taking apart Android games and applications – the obvious being curiosity and the ability to alter key traits in games such as health, score, and more. For the purpose of today we’re going to download and reverse engineer an MIT licensed game, ‘Original 2048’. You can download the APK of this game from APKPure or APKMirror (However, please be warned that these are external websites and I do not control the content on them – ensure to download the APK safely). 

Now that we’ve downloaded the 2048 game APK we can open it in Jadx, with the command above. In the panel on the left hand side of Jadx-gui you will be able to see all of the resources bundled into the APK, including decompiled source code, assets, images, and more. The source code is most probably obfuscated, this means that at compile time the name of the classes, functions, variables, and so on were all altered and modified to obscure the program if a malicious actor was to reverse engineer it (i.e. the class called ‘update’ could be renamed to ‘ca’). While this is the case we can find look at the entry point for the decompiled source code – this can be seen in the source code drop down at the below path:

com.androbaby.original2048

The next steps are up to you, look at what images are used in the game, review the configuration via the AndroidManifest.xml file, or take it a step further and reverse engineer the .dex file located in the applications assets folder. 

 

Learn More

This article is inspired by my Udemy course on reverse engineering Android games. If you’re interested in Android, gaming, and learning more about reverse engineering then consider checking it out!

Adverts





 

Reflection is one of the many aces up the sleeve when it comes to taking apart Android applications and getting them running in a state that
suits you. To put it simply reflection is an API that can be used to access, examine, and modify objects at runtime – this includes fields, methods,
classes, and interfaces. 

Some examples of components reflection can be used on when working from Java (or Kotlin) include:

  • Classes – A class is a blueprint/template where when used individual objects can be created from them.
  • Methods – A method is a segment of code, with a specific purpose, which is run when called and can be part of a class or standalone.
  • Constructors – A constructor is a special type of method that is used as part of the initialization of an object (e.g., a class) to set variables and call methods.
  • Interfaces – An interface is an abstract class that contains a collection of methods with empty bodies.

Class Loading

Java Class Loaders are a component of the Java Runtime Environment (JRE) which load Java classes into a Java Virtual Machine (JVM)/Dalvik Virtual Machine (DVM)/Android Runtime (ART). Not all classes are loaded simultaneously, nor with the same ClassLoader. The context method
getClassLoader() can be used to get the current class loader. There are several types of class loading in Android, these being:

  • PathClassLoader – This is used by the Android system for its system and application class loader(s).
  • DexClassLoader – This loads file types containing a .dex file (e.g., .jar and .apk or .dex file directly). These .dex files (Dalvik executable) contain Dalvik bytecode.
  • URLClassLoader – This is used to retrieve classes or resources via URL paths. Paths ending with / are assumed to be directories, while otherwise they are assumed to be .jar files.

Below shows how to retrieve the current application context class loader:

ClassLoader loader = getApplicationContext().getClassLoader();

Below shows how a new class loaded can be created:

dexLoader = new DexClassLoader(filePath, dexCacheDirectory.getAbsolutePath(), null, loader);
//After creating a dex class loader, choose the class to load, as a string:
loadedClass = dexLoader.loadClass("me.jamesstevenson.dexloadable.MainActivity"); //alter path for your use case
//At this stage the uninitialized class can be used as normal. The following shows how to safely
initialize this class:
initialisedClass = loadedClass != null ? loadedClass.newInstance() : null;
method = loadedClass != null ? loadedClass.getMethod("loadMeAndIllTakeContext", Context.class) : null;
Object methodResponse = method != null ? method.
invoke(initialisedClass, getApplicationContext()) : null;

Reflection Examples

The two supporting classes for these reflection examples can be found on GitHub under DeviceData.Java and Loadable.Java.

Initializing a class:

try {
    Object initialisedDeviceData= DeviceData.class.
    newInstance();
    initialisedDeviceData.getClass().getDeclaredMethod("setDeviceInfo").invoke(initialisedDeviceData);
    String model = (String) initialisedDeviceData.getClass().
    getDeclaredField("model").get(initialisedDeviceData);
    Log.v(TAG, model);
} catch (...) {
    // Todo catch all exceptions
}

Retrieving class methods:

Static method example:
try {
    Method getDeviceName = Loadable.class.getDeclaredMethod("getDeviceName");
    getDeviceName.setAccessible(true);
    Log.v(TAG,(String) getDeviceName.invoke(Loadable.class));
} catch (...) {
    // Todo catch all exceptions
}

Retrieve all methods for a class:

getMethods() example:
    for (Method method : Loadable.class.getMethods()){
    Log.v(TAG, method.getName());
}

The following is an example of constructing a class with a private constructor:

try {
    Constructor<?> constructor = Loadable.class.getDeclaredConstructor(Context.class, long.class);
    constructor.setAccessible(true);
    Object instance = constructor.newInstance(getApplicationContext(), (Object) 12); // constructor takes a context and an id.
    Field uniqueIdField = instance.getClass().getDeclaredField("uniqueId");
    uniqueIdField.setAccessible(true);
    long uniqueId = (long) uniqueIdField.get(instance);
    Log.v(TAG, ""+uniqueId);
} catch (...) {
    // Todo catch all exceptions
}

Instance class example:

try {
    // The loadable class has a static method that can be used to construct it in this example
    Object instance = Loadable.class.getDeclaredMethod("construct", Context.class).invoke(Loadable.class, getApplicationContext());
    // Retrieve the field device data which is the class we're looking to get the data of.
    Field devicdDataField = instance.getClass().getDeclaredField("deviceData");
    devicdDataField.setAccessible(true);
    Object initialisedDeviceData = devicdDataField.get(instance);
    // After accessing the value from the field we're looking to access the fields of, we can use the same type of reflection again after getting it's class
    Field modelField = initialisedDeviceData.getClass().getDeclaredField("device");
    modelField.setAccessible(true);
    String model = (String) modelField.get(initialisedDeviceData);
    Log.v(TAG,model);
}  catch (...) {
    // Todo catch all exceptions
}

 

 

Read More

This article was derived from a chapter in my book Android Software Internals Quick Reference. If you found it interesting please consider picking the book up for yourself! 

 

 

 

Adverts