13 March 2017

Detecting and eliminating Chamois, a fraud botnet on Android

Posted by Security Software Engineers—Bernhard Grill, Megan Ruthven, and Xin Zhao



Google works hard to protect users across a variety of devices and environments. Part of this work involves defending users against Potentially Harmful Applications (PHAs), an effort that gives us the opportunity to observe various types of threats targeting our ecosystem. For example, our security teams recently discovered and defended users of our ads and Android systems against a new PHA family we've named Chamois.

Chamois is an Android PHA family capable of:
  • Generating invalid traffic through ad pop ups having deceptive graphics inside the ad
  • Performing artificial app promotion by automatically installing apps in the background
  • Performing telephony fraud by sending premium text messages
  • Downloading and executing additional plugins

Interference with the ads ecosystem

We detected Chamois during a routine ad traffic quality evaluation. We analyzed malicious apps based on Chamois, and found that they employed several methods to avoid detection and tried to trick users into clicking ads by displaying deceptive graphics. This sometimes resulted in downloading of other apps that commit SMS fraud. So we blocked the Chamois app family using Verify Apps and also kicked out bad actors who were trying to game our ad systems.
Our previous experience with ad fraud apps like this one enabled our teams to swiftly take action to protect both our advertisers and Android users. Because the malicious app didn't appear in the device's app list, most users wouldn't have seen or known to uninstall the unwanted app. This is why Google's Verify Apps is so valuable, as it helps users discover PHAs and delete them.

Under Chamois's hood

Chamois was one of the largest PHA families seen on Android to date and distributed through multiple channels. To the best of our knowledge Google is the first to publicly identify and track Chamois.
Chamois had a number of features that made it unusual, including:
  • Multi-staged payload: Its code is executed in 4 distinct stages using different file formats, as outlined in this diagram.

This multi-stage process makes it more complicated to immediately identify apps in this family as a PHA because the layers have to be peeled first to reach the malicious part. However, Google's pipelines weren't tricked as they are designed to tackle these scenarios properly.
  • Self-protection: Chamois tried to evade detection using obfuscation and anti-analysis techniques, but our systems were able to counter them and detect the apps accordingly.
  • Custom encrypted storage: The family uses a custom, encrypted file storage for its configuration files and additional code that required deeper analysis to understand the PHA.
  • Size: Our security teams sifted through more than 100K lines of sophisticated code written by seemingly professional developers. Due to the sheer size of the APK, it took some time to understand Chamois in detail.

Google's approach to fighting PHAs

Verify Apps protects users from known PHAs by warning them when they are downloading an app that is determined to be a PHA, and it also enables users to uninstall the app if it has already been installed. Additionally, Verify Apps monitors the state of the Android ecosystem for anomalies and investigates the ones that it finds. It also helps finding unknown PHAs through behavior analysis on devices. For example, many apps downloaded by Chamois were highly ranked by the DOI scorer. We have implemented rules in Verify Apps to protect users against Herole.
Google continues to significantly invest in its counter-abuse technologies for Android and its ad systems, and we're proud of the work that many teams do behind the scenes to fight PHAs like Chamois.

We hope this summary provides insight into the growing complexity of Android botnets. To learn more about Google's anti-PHA efforts and further ameliorate the risks they pose to users, devices, and ad systems. For more details, keep an eye open for the upcoming "Android Security 2016 Year In Review" report.

02 March 2017

Android Studio 2.3

By Jamal Eason, Product Manager, Android

Android Studio 2.3 is available to download today. The focus for this release is quality improvements across the IDE. We are grateful for all your feedback so far. We are committed to continuing to invest in making Android Studio fast & seamless for the millions of Android app developers across the world.

We are most excited about the quality improvements in Android Studio 2.3 but you will find a small set of new features in this release that integrate into each phase of your development flow. When designing your app, take advantage of the updated WebP support for your app images plus check out the updated ConstraintLayout library support and widget palette in the Layout Editor. As you are developing, Android Studio has a new App Link Assistant which helps you build and have a consolidated view of your URIs in your app. While building and deploying your app, use the updated run buttons for a more intuitive and reliable Instant Run experience. Lastly, while testing your app with the Android Emulator, you now have proper copy & paste text support.

What's new in Android Studio 2.3

For more detail about the features we added on top of the quality improvements Android Studio 2.3, check out the list of the new features below:
Build
  • Instant Run Improvements and UI Changes: As a part of our focus on quality, we have made some significant changes to Instant Run in Android Studio 2.3 to make the feature more reliable. The Run action will now always cause an application restart to reflect changes in your code that may require a restart, and the new Apply Changes action will attempt to swap the code while your app keeps running. The underlying implementation has changed significantly to improve on reliability, and we have also eliminated the startup lag for Instant Run enabled apps. Learn more.
New Instant Run Button Actions
  • Build Cache: Introduced but disabled by default in Android Studio 2.2, Build Cache is an underlying build optimization for faster builds in Android Studio. By caching exploded AARs and pre-dexed external libraries, the new build cached leads to faster clean builds. This is a user-wide build cache that is now turned on by default with Android Studio 2.3. Learn more.
Design
  • Chains and Ratios support in Constraint Layout: Android Studio 2.3 includes the stable release of ConstraintLayout With this release of ConstraintLayout, you can now chain two or more Android views bi-directionally together to form a group on one dimension. This is helpful when you want when you want to place two views close together but want to spread them across empty space. Learn more.
Constraint Layout Chains

ConstraintLayout also supports ratios, which is helpful when you want to maintain the aspect ratio of widget as the containing layout expands and contracts. Learn more about ratios. Additionally, both Chains and Ratios in ConstraintLayout can support programmatic creating with ConstraintSet APIs.

Constraint Layout Ratios

  • Layout Editor Palette: The updated widget palette in the Layout Editor allows you to search, sort and filter to find widgets for your layouts, plus gives you a preview of the widget before dragging on to the design surface. Learn more.

Layout Editor Widget Palette

  • Layout Favorites: You can now save your favorite attributes per widget in the updated Layout Editor properties panel. Simply star an attribute in the advanced panel and it will appear under the Favorites section. Learn more.

Favorites Attributes on Layout Editor Properties Panel
  • WebP Support: To help you save space in your APK, Android Studio can now generate WebP images from PNG assets in your project. The WebP lossless format is up to 25% smaller than a PNG. With Android Studio 2.3, you have a new wizard that converts PNG to lossless WebP and also allows you to inspect lossy WebP encoding as well. Right-click on any non-launcher PNG file to convert to WebP. And if you need to edit the image, you can also right-click on any WebP file in your project to convert back to PNG. Learn more.
WebP Image Conversion Wizard

  • Material Icon Wizard Update: The updated vector asset wizard supports search and filtering, plus it includes labels for each icon asset. Learn more.
Vector Asset Wizard

Develop
  • Lint Baseline: With Android Studio 2.3, you can set unresolved lint warnings as a baseline in your project. From that point forward, Lint will report only new issues. This is helpful if you have many legacy lint issues in your app, but just want to focus on fixing new issues. Learn more about Lint baseline and the new Lint checks & annotations added in this release.
Lint Baseline Support
  • App Links Assistant: Supporting Android App Links in your app is now easier with Android Studio. The new App Links Assistant allows you to easily create new intent filters for your URLs, declare your app's website association through a Digital Asset Links file, and test your Android App Links support. To access the App Link Assistant go to the following menu location: ToolsApp Link Assistant. Learn more.
App Links Assistant
  • Template Updates: By default, all templates in Android Studio 2.3 which use to contain RelativeLayout, now use ConstraintLayout. Learn more about templates and Constraint Layout. We have also added a new Bottom Navigation Activity template, which implements the Bottom Navigation Material Design guideline.

New Project Wizard Templates
  • IntelliJ Platform Update: Android Studio 2.3 includes the IntelliJ 2016.2 release, which has enhancements such as an updated inspection window and a notifications system. Learn more.
Test
  • Android Emulator Copy & Paste: Back by popular demand, we added back the Copy & Paste feature to the latest Emulator (v25.3.1). We have a shared clipboard between the Android Emulator and host operating system, which will allow you to copy text between both environments. Copy & Paste works with x86 Google API Emulator system images API Level 19 (Android 4.4 - Kitkat) and higher.

Copy & Paste support in Android Emulator

  • Android Emulator Command Line Tools: Starting with Android SDK Tools 25.3, we have moved the emulator from the SDK Tools folder into a separate emulator directory, and also deprecated and replaced the "android avd" command with a standalone avdmanager command. The previous command line parameters for emulator and "android avd" will work with the updated tools. We have also added location redirects for the emulator command. However, if you create Android Virtual Devices (AVDs) directly through the command line you should update any corresponding scripts. If you are using the Android Emulator through Android Studio 2.3, these change will not impact your workflow. Learn more.

To recap, Android Studio 2.3 includes these new features and more:

Develop
Build
Design
Test

Learn more about Android Studio 2.3 by reviewing the release notes.

Getting Started

Download
If you are using a previous version of Android Studio, you can check for updates on the Stable channel from the navigation menu (Help → Check for Update [Windows/Linux] , Android Studio → Check for Updates [OS X]). You can also download Android Studio 2.3 from the official download page. To take advantage of all the new features and improvements in Android Studio, you should also update to the Android Gradle plugin version to 2.3.0 in your current app project.
We appreciate any feedback on things you like, issues or features you would like to see. Connect with us -- the Android Studio development team -- on our Google+ page or on Twitter.

01 March 2017

Getting Santa Tracker Into Shape


Posted by Sam Stern, Developer Programs Engineer

Santa Tracker is a holiday tradition at Google.  In addition to bringing seasonal joy to millions of users around the world, it's a yearly testing ground for the latest APIs and techniques in app development.  That's why the full source of the app is released on Github every year.


In 2016, the Santa team challenged itself to introduce new content to the app while also making it smaller and more efficient than ever before.  In this post, you can read about the road to a more slimmer, faster Santa Tracker.

APK Bloat

Santa Tracker has grown over the years to include the visual and audio assets for over a dozen games and interactive scenes.  In 2015, the Santa Tracker APK size was 66.1 MB.


The Android Studio APK analyzer is a great tool to investigate what made the 2015 app so large.

Screenshot from 2017-02-01 11:59:09.png


First, while the APK size is 66.1 MB, we see that the download size is 59.5MB! The majority of that size is in the resources folder, but assets and native libraries contribute a sizable piece.


The 2016 app contains everything that was in the 2015 app while adding four completely new games.  At first, we assumed that making the app smaller while adding all of that would be impossible, but (spoiler alert!) here are the final results for 2016:

Screenshot from 2017-02-01 12:06:23.png


The download size for the app is now nearly 10MB smaller despite the addition of four new games and a visual refresh. The rest of this section will explore how we got there.

Multiple APK Support on Google Play with APK Splits

The 2015 app added the "Snowdown" game by Google's Fun Propulsion Labs team.  This game is written in C++, so it's included in Santa Tracker as a native library.  The team gave us compiled libraries for armv5, armv7, and x86 architectures.  Each version was about 3.5MB, which adds up to the 10.5MB you see in the lib entry for the 2015 APK.


Since each device is only using one of these architectures, two thirds of the native libraries could be removed to save space - the tradeoff here is that we’ll publish multiple APKs.  The Android gradle build system has native support for building an APK for each architecture (ABI) with only a few lines of configuration in the app's build.gradle file:

ext.abiList = ['armeabi', 'armeabi-v7a', 'x86']
android {
   
   // ...
   splits {
       abi {
           // Enable ABI splits
           enable true
           // Include the three architectures that we support for snowdown
           reset()
           include(*abiList)
           // Also build a "universal" APK that will run on any device
           universalApk true
       }
   }
}


Once splits are enabled, each split needs to be given a unique version code so that they can co-exist in the Play Store:

// Generate unique versionCodes for each APK variant: ZXYYSSSSS
//   Z is the Major version number
//   X is the Minor version number
//   YY is the Patch version number
//   SSSS is information about the split (default to 0000)
// Any new variations get added to the front
import com.android.build.OutputFile;
android.applicationVariants.all { variant ->
   variant.outputs.each { output ->
       // Shift abi over by 8 digits
       def abiFilter = output.getFilter(OutputFile.ABI)
       int abiVersionCode = (abiList.indexOf(abiFilter) + 1)
       // Merge all version codes
       output.versionCodeOverride = variant.mergedFlavor.versionCode + abiVersionCode
   }
}


In the most recent version of Santa Tracker, we published versions for armv5, armv7, and x86 respectively.  With this change in place, 10.5MB of native libraries was reduced to about 4MB per variant without losing any functionality.

Optimize Images

The majority of the Santa Tracker APK is image resources. Each game has hundreds of images, and each image comes in multiple sizes for different screen densities. Almost all of these images are PNGs, so in past years we ran PNGCrush on all of the files and figured our job was done.  We learned in 2016 that there have been advancements in lossless PNG compression, and Google's zopfli tool is currently the state of the art.


By running zopflipng on all PNG assets we losslessly reduced the size of most images by 10% and some by as much as 30%. This resulted in almost a 5MB size reduction across the app without sacrificing any quality. For instance this image of Santa was losslessly reduced from 10KB to only 7KB.  Don't bother trying to spot the differences, there are none!


Before (10.2KB)
After (7.4KB)
santa-before.png
santa-before-zopfli.png


Unused Resources

When working on Santa Tracker engineers are constantly refactoring the app, adding and removing pieces of logic and UI from previous years. While code review and linting help to find unused code, unused resources are much more likely to slip by unnoticed.  Plus there is no ProGuard for resources, so we can't be saved by our toolchain and unused images and other resources often sneak into the app.


Android Studio can help to find resources that are not being used and are therefore bloating the APK.  By clicking Analyze > Run Inspection by Name > Unused Resources Android Studio will identify resources that are not used by any known codepaths.  It's important to first eliminate all unused code, as resources that are "used" by dead code will not be detected as unused.


After a few cycles of analysis with Android Studio's helpful tools, we were able to find dozens of unused files and eliminate a few more MB of resources from the app.

Memory Usage

Santa Tracker is popular all around the world and has users on thousands of unique Android devices.  Many of these devices are a few years old and have 512MB RAM or less, so we have historically run into OutOfMemoryErrors in our games.


While the optimizations above made our PNGs smaller on disk, when loaded into a Bitmap their memory footprint is unchanged.  Since each game in Santa Tracker loads dozens of images, we quickly get into dangerous memory territory.


In 2015 six of our top ten crashes were memory related. Due to the optimizations below (and others) we moved memory crashes out of the top ten altogether.

Image Loading Backoff

When initializing a game in Santa Tracker we often load all of the Bitmaps needed for the first scene into memory so that the game can run smoothly.  The naive approach looks like this:


private LruCache<Integer, Drawable> mMemoryCache;
private BitmapFactory.Options mOptions;
public void init() {
 // Initialize the cache
 mMemoryCache = new LruCache<Integer, Drawable>(240);
 // Start with no Bitmap sampling
 mOptions = new BitmapFactory.Options();
 mOptions.inSampleSize = 1;
}
public void loadBitmap(@DrawableRes int id) {
   // Load bitmap
   Bitmap bmp = BitmapFactory.decodeResource(getResources(), id, mOptions);
   BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bmp);
   
   // Add to cache
   mMemoryCache.put(id, bitmapDrawable);
}


However the decodeResource function will throw an OutOfMemoryError if we don't have enough RAM to load the Bitmap into memory.  To combat this, we catch these errors and then try to reload all of the images with a higher sampling ratio (scaling by a factor of 2 each time):

private static final int MAX_DOWNSAMPLING_ATTEMPTS = 3;
private int mDownsamplingAttempts = 0;
private Bitmap tryLoadBitmap(@DrawableRes int id) throws Exception {
   try {
       return BitmapFactory.decodeResource(getResources(), id, mOptions);
   } catch (OutOfMemoryError oom) {
       if (mDownSamplingAttempts < MAX_DOWNSAMPLING_ATTEMPTS) {
           // Increase our sampling by a factor of 2
           mOptions.inSampleSize *= 2;
           mDownSamplingAttempts++;
       }
   }
   throw new Exception("Failed to load resource ID: " + resourceId);
}


With this technique low-memory devices will now see more pixelated graphics, but by making this tradeoff we almost completely eliminated memory errors from Bitmap loading.

Transparent Pixels

As mentioned above, an image's size on disk is not a good indicator of how much memory it will use. One glaring example is images with large transparent regions.  PNG can compress these regions to near-zero disk size but each transparent pixel still demands the same RAM.


For example in the "Dasher Dancer" game, animations were represented by a series of 1280x720 PNG frames.  Many of these frames were dominated by transparency as the animated object left the screen.  We wrote a script to trim all of the transparent space away and record an "offset" for displaying each frame so that it would still appear to be 1280x720 overall. In one test this reduced runtime RAM usage of the game by 60MB! And now that we were not wasting memory on transparent pixels, we needed less downscaling and could use higher-resolution images on low-memory devices.

Additional Explorations

In addition to the major optimizations described above, we explored a few other avenues for making the app smaller and faster with varying degrees of success.

Splash Screens

The 2015 app moved to a Material Design aesthetic where games were launched from a central list of 'cards'. We noticed that half of the games would cause the card 'ripple' effect to be janky on launch, but we couldn't find the root cause and were unable to fix the issue.


When work on the 2016 version of the app we were determined to fix the game jank launch. After hours of investigation, we realized it was only the games fixed to the landscape orientation that caused jank when launched.  The dropped frames were due to the forced orientation change. To create a smooth user experience, we introduced splash screens in between the launcher Activity and game Activities.  The splash screen would detect the current device orientation and the orientation needed to play the game being loaded and rotate itself at runtime to match.  This immediately removed any noticeable jank from game launches and made the whole app feel smoother.

SVG

When we originally took on the task of reducing the size of our resources, using SVG images seemed like an obvious optimization.  Vector images are dramatically smaller and only need to be included once to support multiple densities.  Due to the 'flat' aesthetic in Santa Tracker, we were even able to convert many of our PNGs to tiny SVGs without much quality loss. However loading these SVGs was completely impractical on slower devices, where they would be tens or hundreds of times slower than a PNG depending on the path complexity.


In the end we decided to follow the recommendation limiting vector image sizes at 200x200 dp and only used SVG for small icons in the app rather than large graphics or game assets.

Conclusions

When we started building Santa Tracker 2016 we were faced with a daunting problem: how can we make the app smaller and faster while adding exciting new content? The optimizations above were discovered by constantly challenging each other to do more with less and considering resource constraints with every change we made. In the end we were able to incrementally make the Santa Tracker app as healthy as it has ever been ... our next job will be helping Mr. Claus work off all that extra cookie weight.