background

At present, the Ministry of Industry and Information Technology has standardized requirements on the privacy and security issues of apps. In recent years, we can often see the news of App removal and rectification.

In overseas versions, Google Play also has frequent policy updates, such as recently requiring new apps to be in AAB format, payment library to use version 3, targetSDK to use 30, etc.

The above check items include: privacy-related sensitive apis, permissions, application security specifications, SDK versions, etc. If you only have an Apk file, then the easiest way is to use JADX decompilation, directly view the Manifest file, the code.

However, manual decompilation by JADX for static scanning is somewhat costly and inefficient. Therefore, a tool is needed to realize the above scanning operations in the tool, so that the relevant inspectors only need to focus on the detection items.

The tool here only performs static analysis for the product APK, and the following is an introduction to the relevant ideas.

Tools and Environment

  • java
  • apktool
  • apksigner
  • .

Here is a brief introduction of the main tools, ellipsis can be extended to other detection items required tools, such as Google’s non-SDK interface black gray list appCompat.

apktool

Apktool is a third-party tool to decompile Android Apk. It is possible to decompilate APK to smALI, shown here as related instructions, where D (decode) represents decompilation; The counterpart is B (building), which identifies compilation. App-release. apk is the target apk for decompilation, and -o indicates the decompilation result output path. If there is no -o parameter, it is directly in the current folder by default.

The decompilation products are

  • Androidmanifest.xml is a manifest file in an Android project.
  • Res is the resource file, layout and value are there.
  • The SMALI folder is the file that the relevant Java code has been converted to the SMALI language.

The main places we need to scan are basically in SMali. Permissions, four components, package name, VersionCode, etc. can be obtained by parsing androidmanifest.xml.

apksigner

Apksigner is a signature tool that comes with the Android SDK build tools, but in this static analysis, we use it to verify APK signatures.

apksigner verify [options] app-name.apk
Copy the code

Other tools

Of course, these are not the only two tools for static analysis. You can continue to add other tools as needed, such as appCompat, ARM-Linux-Androideabi-Readelf, and others mentioned in Google’s non-SDK interface black gray list

Train of thought

The idea of scanning is also very simple. Use apkTool to decompile APK and obtain smALI code, and scan these files one by one to see if they contain non-compliant code segments.

Java2smali syntax Plugins in AndroidStudio are recommended as Plugins in AndroidStudio

It turns your Java & Kotlin into Smali

It’s quite convenient.

Smali files at the beginning of the class name, class, the path of the package name written out, the smali files the fully qualified called com/example/myapplication Java2Smali, parent class is an android/app/Activity, The source file name is java2smali.java.

In our only method, Java2smali, we can also clearly see the start and end of the method.

Start with.method java2smali()V on line 19 and end with.end method on line 39.

In the above method, we just do one thing: create a new Intent object and pass in an Intent object.

PendingIntent was presented as an error with Implicit PendingIntent when it was launched on GooglePlay

Here is a simple analysis of how to statically scan out this problem.

You need to know why it happened. When a PendingIntent is used and the Intent uses an implicit Intent.

Then we can begin to analyze the possible scenarios.

PendingIntent.getActivity(this.0,base,PendingIntent.FLAG_UPDATE_CURRENT);

PendingIntent.getActivity(this.0.new Intent(this,MainActivity.class),PendingIntent.FLAG_UPDATE_CURRENT);

PendingIntent.getActivity(this.0.new Intent("test").setComponent(new ComponentName(this,MainActivity.class)).setPackage("test"),PendingIntent.FLAG_UPDATE_CURRENT);
Copy the code

First, the Intent is created elsewhere. The other two types create the Intent while the Intent is being created.

Write these code first, you can one by one into Smali to view.

Here you can convert all three into Smali at the same time.

When we get a Smali file, we first split the entire file with.method/.end method to get each method, and then split it again with.line to get each line of Smali code.

Line 15 represents the one that creates the Intent elsewhere.

.line 17 and.line 19 are both intents created with PendingIntent.

Let’s look at.line 17 and.line 19 first.

.line 17 is an example of an explicit Intent. It is clear that invoke-Direct calls the constructor of the Intent and passes p0 (this), And const – class v2, Lcom/example/myapplication/MainActivity;

.line 19, another example of an explicit Intent, creates an Intent object and sets v2 to const-string v2, “test”. Then call the setComponent, to create the ComponentName object, incoming p0, and const – class v3, Lcom/example/myapplication/MainActivity; . Finally, move-result-object v1 is called, and the object pointer of the last calculated result is moved into v1 register, i.e., Intent. Similarly, the final setPackage is similar.

Here, we need to determine whether the Intent is an explicit Intent. We can first determine whether it calls Landroid/content/Intent; ->setPackage(Ljava/lang/String;) Landroid/content/Intent; Or Landroid/content/Intent; ->setComponent(Landroid/content/ComponentName;) Landroid/content/Intent; . You can also check whether the Intent’s constructor parameter is passed in a const-class.

However, this detection has drawbacks, such as the Intent being passed in through a constructor, which can be difficult to locate.

In java2smali, only one Intent object is visible, even though an Intent object is already created in the test() method and is invoked explicitly. The PendingIntent constructor passed in does not determine whether the intent was explicitly called.

conclusion

This is a simple example of a static scan, and you can extend it to include V2 signature verification, a summary of SDK access, sensitive API calls, permission analysis, and more.

But static scanning has its drawbacks. Such as:

  • After the confusion, the specific source of the code cannot be determined
  • Only the existence of the code can be determined, and the specific use of the code cannot be determined

This may require compile-time detection as well as dynamic detection to continue to improve.