قالب وردپرس درنا توس
Home / IOS Development / Get started with ProGuard | raywenderlich.com

Get started with ProGuard | raywenderlich.com



There has been a recent increase in the popularity of things of things, DIY boards and entry level devices. The consequence has been a step backwards from writing big apps in favor of less. ProGuard is here to keep apps as small as possible.

Less apps are downloaded, installed and run faster. This is important for the business. The more time offered on the table, the greater the chances are, the user will leave your app and try something else.

In this tutorial, you create a simple app that reveals details about sloths! You learn to strip down your app size using ProGuard – an appcrying and obfuscation tool. The optimizations that ProGuard performs translates to a certain level of obfuscation, which can add a minimum level of security to prevent reverse engineering or manipulation with your app.

How to debug a ProGuarded app

Note already familiar with the basics of Android development and Android Studio. If your Android development is new to you, first read our Android Android and Kotlin Android Android Training.

Get Started

Download and extract the materials for this tutorial using the Download Materials button at the top or bottom of this page. Open the launcher on Android Studio 3.1

.4 or later and build and run to see the app you're going to work with.

 Start Project

Currently, there is a simple screen that lists the six species of sloths. The app does not do very much. You will make it more exciting by adding the BubblePicker library. It presents items floating around the screen in bubbles. You will check your app size along the way. Fortunately, there is a tool for it. :]

Using APK Analyzer

APK Analyzer is a tool for inspection of the finished app and what contributes to the size. It presents a view with a breakdown of the app's file size. You can see what takes up the most space, as well as the total method and reference number.

Start the analyzer by selecting Build ▸ Analyze APK . It opens a file system dialog. If necessary, navigate to the troubleshooting folder SlothSanctuary-Starter / app / build / outputs / apk / debug . Select the app-debug.apk file and click OK to open the APK Analyzer. Select the file size of the current APK. You use this tool several times in this tutorial.

 APK Analyzer

Note : There are many other tools that engineers use to analyze apps, such as JD-GUI, APKTool and Jadx. Some of these tools help reverse engineers decompile the app back to its original code. Sometimes it's done for fun, but often reverse engineering is done for the theft of intellectual property or apploning.

Add BubblePicker Library

Open the file build.gradle for the app module and add Follow the list of addictions:

  implementation & # 39; com.github.igalata: Bubble-Picker: v0 .2.4 & # 39; 

Perform a Gradle sync then select Build ▸ Create Project . When done, run APK Analyzer again. You will notice adding add-ons to some megabytes to the APK file without writing any code! You do not want to use all parts of this library – this is where ProGuard comes in. ProGuard will do its job to remove all the code that is not available by the app.

Activating ProGuard

Activating ProGuard is easy! In the build.gradle file for the app module, replace buildTypes the code with the following:

 buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile (& # 39; proguard android.txt & # 39;), & # 39; proguard-rules.pro & # 39;
}
troubleshooting {
minifyEnabled true
proguardFiles getDefaultProguardFile (& # 39; proguard android.txt & # 39;), & # 39; proguard-rules.pro & # 39;
}
}

Setting minifyEnabled to true allows ProGuard. ProGuard looks at the recording points in your app and mapping the code that the app can reach. It removes the rest and replaces the names of classes and methods with shorter, which makes for a much smaller APK size! Please note that ProGuard results in slower construction times.

However, ProGuard confuses mistakes and removes code that it thinks you do not use even when you are . You often have to test that everything that still works with ProGuard is activated when you go. The sooner you will find problems in the building, the easier it will be to fix them. :]

Synchronize Gradle, build and run. Note that there are already compiler errors:
  Compiler notifications

Compiler errors include "Can not find referenced class org.sl4j" and "Can not find referenced class sun.misc.Unsafe ". The first way you look at solving these ProGuard issues is through online surveys.

Switch to the Bubble Picker Library's GitHub page to see if there is any documentation about using the ProGuard library. Sometimes README will receive ProGuard information, but in this case, it will not. Then select Issues .
  GitHub Area

In the search box, remove is: open add sl4j and press enter . Good luck – Issue # 61 looks like the same problem, with suggestions to add some "not warn" exceptions to ProGuard.
  GitHub Editions

Add "Not Warning" Rules

"Not Warning" Rules Tell Android Studio to ignore warnings. This can be dangerous, but if you are sure you do not use part of the code, it may be useful. They work by entering the package name. * is a wildcard – it does not include partial packages, while ** contains partial packages. ProGuard rules enter the file proguard-rules.pro .

Add the following at the end of the file proguard-rules.pro to ignore warnings for ] org.slf4j package:

  -dontwarn org.slf4j. ** 

The following warnings all refer to sun.misc.Unsafe . rx.internal is in reference to the library RxJava . Navigate to the RxJava Github page and click Issues . Replace is: open with sun.misc.Unsafe and press in . You'll see some posts about the same problem. This post states that sun.misc is never used, so it's safe to ignore. Add the following to the file proguard-rules.pro just below the line you just added:

  -dontwarn sun.misc. ** 

Select Build ▸ Create Project ]. Now it's building successfully!

Note : You can see suggestions for "- dontwarn *" float around the forum, but it's very bad practice. This does not mean warning "all". It will solve irrelevant warnings, but will also ignore critical ones where something is actually wrong.

Run APK Analyzer again. You will notice that the APK size is much smaller now. That is because ProGuard has removed all the code you do not use. Now that your project builds, you can start adding code to display bubbles.

Add BubblePicker Code

In the Res / Layout / Activity_main.xml file, replace the other TextView ( descriptionTextView ) with the following:


This adds BubblePicker to the main setup. In the MainActivity.kt file, add the following to setupBubblePicker () method:

  picker.bubbleSize = 50
picker.centerImmediately = true
picker.adapter = item: BubblePickerAdapter {

color colors = resources.obtainTypedArray (R.array.colors)
selection titles = listOf ("1", "2", "3", "4", "5", "6")

drop multiplier = 2
selection module = 8
choose addition = 1

override selection totalCount = titles.size // 1

Override fun getItem (Position: Int): PickerItem {// 2
return PickerItem (). search {
title = titles [position]

choice start = colors.getColor ((position * multiplier)% module, 0)
choice end = colors.getColor ((position * multiplier)% module + addition, 0)
gradient = BubbleGradient (start, end, BubbleGradient.VERTICAL)

textColor = ContextCompat.getColor (this @ MainActivity, android.R.color.white)
}
}

}

picker.listener = object: BubblePickerListener {// 3

override fun onBubbleSelected (item: PickerItem) {

}

override fun onBubbleDeselected (item: PickerItem) {

}

}

Note : This tutorial assumes that you are familiar with import management. If you have not installed import on airplane, import by pressing the option + return on a Mac or Alt + Enter on a PC while the cursor is over the item

Here it is which takes place in the updated method:

  1. You are parent totalCount to tell BubblePicker how many bubbles will be.
  2. ] You override getItem () to return a custom PickerItem .
  3. You set up BubblePickerListener to handle choosing a bubble.

Complete the implementation by adding this to the end of onResume :

  picker.onResume () 

Add this end to onPause :

  picker .onPause) 

Build and run the app. Uh – The app crashes with a NullPointerException ! Note that more methods in your trackpad are obfuscated – the names have been changed and decreased. This is one of the main features of ProGuard.
  Crash Error
  Sad Face
Check the output log to limit what the problem is. You can see in the Run category that it has something to do with "GL" and "onDrawFrame" in the BubblePicker library.

Note : It is always good practice to add sufficient logging to the catch tasks, nullity checks and failure states. With ProGuard, this is crucial – in case of a problem, it will help you or other developers to root the problem, especially when the method names in stacks are confused.

Reporting ProGuard Output Files [19659014] When ProGuard ends, it produces 4 output files. They are:

  • use.txt – Displays the code as ProGuard removed.
  • dump.txt – Describes the structure of the class files in APK.
  • seeds.txt – Displays the classes and members that were not confused. Good to verify that you have confused important files.
  • mapping.txt – The file that maps the obfuscated names back to the original.

You can use the mapping file to find fault with crashes.

Run APK Analyzer again, then select the file classes.dex . Your confused code crashes like org.a.d.l.a . The individual characters you see may vary from this example, but you can follow the directory path to the characters:
  Authorized Catalogs
First, it is not clear what the directories are. Click the Load Proguard mappings … button to map the obfuscated names back to the original.
  Load Proguard mapping button
Select the mapping.txt file in the troubleshoot folder and click OK .

Change Deobfuscate names button to the left of Change the ProGuard mapping … button to switch between obfuscated and deobfuscated code. You can track the problem down to the jbox2d library.
  Unobfuscated code
You must keep jbox2d so that ProGuard is not mucked with it.

There are a few more things you should know about the mapping file:

  • Every time you make a release, the file mapping.txt is rewritten. That means you must save each copy with each release of your app. That way, when you receive an obfuscated stack-track for a particular app release, it will be useful.
  • You can upload the mapping.txt file to Google Play to deobfuscate your crash stack tracks.
  • Using Fabric is a Google Distribution and Crash Reporting Tool, instructions for uploading the file mapping.txt here.

Add storage rules

] Keep rules tell ProGuard not to confuse certain parts of your code. Some alternatives are:

  • team – Keep the entire class and class members.
  • keepclassmembers – Keep class members.
  • keepclasseswithmembers – Keep all classes that have a specified member.

ProGuard rules are written in a particular template format. It is best practice to use explicit keeping rules, rather than keeping the whole class. Instead of preserving the entire BubblePicker library, you only need to keep org.jbox2d and its sub packages. The format is the same as dontwarn rules.

Add following to proguard-rules.pro file immediately after dontwarn calculates:

 -hold class org.jbox2d. ** {*; }

Inside the curly bands, you told ProGuard to match any method name.

Build and run the app. When the app uploads, you should see the bubbles float around the screen.

 App with bubbles

Note : If you share the code, enter rules as you type your code and make sure to publish them on your site or the GitHub README page so that others Developers can easily use your code without any problems.

Now you should set up some real sloth data.

Adding Data to BubblePicker

There is a file included in the res folder for the project called sloths.xml . Since it is in XML format, you need a way to get the data in Kotlin objects. You will use another third party library that comes with the Retrofit package called SimpleXML .

Add this code to the list of addictions in the app module file build.gradle . You can exclude groups and modules that you are sure you do not want to use:

 implementation (& # 39; com.squareup.retrofit2: converter-simplexml: 2.0.0-beta3 & # 39;) {
exclude group: & # 39; xpp3 & # 39 ;, module: & # 39; xpp3 & # 39;
exclude group: "stax & # 39 ;, module:" stax-api & # 39;
exclude group: "stax & # 39 ;, module:" stax & # 39;
}

Synchronize Gradle, build and run the app.

You will receive some new warnings: a reference to org.codehaus.mojo.animal_sniffer.IgnoreJREquirement and many variations of warnings javax.xml.stream. ** .

 Compiler Notifications

You do not want to use Java's XML stream feature. For this training purpose, it is safe to ignore the animal_sniffer warnings. Add the following to proguard-rules.pro file:

 -dontwarn javax.xml.stream. **
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

Select Build ▸ Create Project . This time the building should be successful.

Open the file SlothViewModel.kt and replace the loadSloths () function with the following:

  private fun loadSloths (resources: Resources) {// 1
fall serializer = persist ()
drop inputStream = resources.openRawResource (R.raw.sloths) // 2
choice sloths = serializer.read (Sloths :: class.java, inputstream) // 3
sloths.list? .let {theList ->
choose folder = theList.associateBy ({it.name}, {it})
this.sloths = folder.toSortedMap ()
}
}

Here:

  1. You removed the explicit return type for the function.
  2. You opened the sloths XML file a InputStream .
  3. You obtained a list of Sloths by invoking les () .

The XML parser knows how to map the XML fields of your Kotlin objects using annotations. In the Sloths file, add this note to Sloths the constructor:

  @Root (name = "sloths", strict = false)

This tells the parser to look for the root node called "sloths".

Add comments to the list list in the constructor:

  @field: ElementList (entry = "sloth", inline = true)
@param: ElementList (entry = "sloth", inline = true)

@field and @param let the parser know to look for "sloth" items.

The same must be done for the Sloth class. In the Sloth.kt file, depending on the import layout, the following is replaced by the following:

  @Root (name = "sloth", strict = false)
Data Class Sloth Constructor (
@field: Element (name = "name")
@param: Element (name = "name")
was name: String = "",

@field: Element (name = "realName")
@param: Element (name = "realName")
was realName: String = "",

@field: Element (name = "imageResource")
@param: Element (name = "imageResource")
was imageResourceName: String = "",

@field: Element (name = "description")
@param: Element (name = "description")
was description: String = ""): Serializable

In the file MainActivity.kt you add a ViewModel variable directly above onCreate () :

  private choice viewModel: SlothViewModel of lat {
ViewModelProviders.of (this) .Go (SlothViewModel :: class.java)
}

Add a call to get the sloth data as the first line of setupBubblePicker () :

  select map = viewModel.getSloths (resources)

Replace the line that reads valtitler = listOf ("1", "2", "3", "4", "5", "6") with the following:

  selection titles = map.toList ()

And finally, replace title = the line with this:

  title = titles [position] .first

Build and run the app. Notice NoSuchMethodException crash.

 Crash Error

You know it must be the code you just added. To do similar troubleshooting to what you did earlier, you can limit the problem down to the Parameter object in SimpleXML. This time you will look into the issue. SimpleXML works by loading XML devices presented by driving and instilling Kotlin colleagues. Kotlin can only do this by using introspection and reflection .

Introspection and Reflection

Sloths hang out in trees for hours and hours that do not seem to do very much. This is probably because they are keen to inspect and reflect on life. In Kotlin, introspection and reflection characteristics of the language that inspect objects and call methods dynamically at runtime.

ProGuard looks at the static version of your app but does not run your app so it's impossible to know which methods can be accessed by introspection and reflection. Remember, ProGuard takes long class names and replaces them with smaller names. If something tries to refer a name while driving with a constant string, the name will be changed. You can often tell that this happens with NoSuchMethodException .

You must tell ProGuard to keep the paragraphs using reflection like @param the code you added. You use implements keywords to keep all classes that stretch or implement Parameter . Add the following to the end of the ProGuard rule file:

 -hold class * implements org.simpleframework.xml.core.Parameter {public *; }

While you're in it, go ahead and add some more functionality to the app. In the MainActivity.kt file, add this to the onBubbleSelected () method for BubblePickerListener :

  selection showDetailsIntent = Intent (picker.context, SlothDetailActivity :: class.java)
fall pet = map [item.title]
showDetailsIntent.putExtra (SLOTH_KEY, pet)
startActivity (showDetailsIntent)

item.isSelected = false

Build and run the app.
  Final Project
Touch a bubble to reveal more information about each species.
  Details view

Congratulations!
  Happy Face
You can stop here, but if you're interested in how the app size can be reduced further, keep reading.

Enabling Advanced Optimization

ProGuard provides an advanced optimization profile. It is not used by default because it can lead to furthering and runtime errors. You enable the advanced optimizations by replacing the default proguard-android.txt file with proguard-android-optimize.txt .

I build.gradle appmodulfil, replace the line proguardFiles in the troubleshooting section with the following:

 proguardFiles getDefaultProguardFile (& # 39; proguard android optimize.txt & # 39;) ,
& # 39; Proguard-rules.pro & # 39;

Synchronize Gradle, build and run the app. Construction time will be much longer because ProGuard performs more analysis and optimization within and across methods.

Your app should crash with the following errors:
  Crash Error Message
Here is the symbol @ referred to an annotated class – in this case, classes marked with org.simpleframework.xml. * . Add a rule at the end of the ProGuard rule file to keep the methods marked with org.simpleframework.xml. * :

  -clerk class member class * {@ org.simpleframework.xml. * *; }

This time the error mentions a constructor instead of a missing class, and therefore uses this code keepclassmembers to hold class members only.

Build and run the app. You should see your app over and over again.

Note : This may be a good time to stop and check the APK analyzer again to see how the size is doing.

You have set up a fancy ProGuard optimized app for your Sloth Sanctuary. Sleuth Zoo is very competitive – they have taken all your ideas and make money on them. How bad You think that when you release your app, they will analyze APK and steal your "secret sauce". Since ProGuard performs confusion, this is another place where it can help you.

Understanding of obfuscation

Sloths hiding on top of trees to prevent predators from finding them from below. Many have a symbiotic relationship with green algae. It grows on the back so that they mix with the green leaves. These tricks and other flying predators. Sloths confuses oneself, something that really comes down to fooling and hiding.

Obfuscation is not encryption. Casting ProGuard on your release can deter the informal attacker to continue. However, it is not a substitute for proper security measures. You should never store sensitive API keys, tokens or passwords anywhere in APK. Instead, the items sent to the app are encrypted by authentication.

That said, it is often used to hide or hide proprietary logic or a secret algorithm. Sometimes developers use manual obfuscation. Some examples are string divide, dummy code, hide the names of methods, or use reflection to muddy application flow. You will add some reflection code that confuses your secret bubble gradient formula. From now on, it is not impossible for an attacker to find the numbers used to make the degree.

In APK Analyzer, select the file classes.dex . Navigate to com raywenderlich android slothsanctuary . Right-click MainActivity $ b and select Show bytecode . The entirety e f and g


Source link