📜 ⬆️ ⬇️

Reverse engineering android applications

Picture


In this article I will try to tell you about reverse-engineering applications for android. This process is somewhat different from the one for win-applications: there is no debugger and no assembler, instead LogCat and byte-code appear. As you may have guessed, we will explore the application with the aim of hacking it, or, more simply, “quack”.

BRIEFING


As a guinea pig, I chose the Multi Mount SD-Card program. Its essence is to mount the flash drive of the device while simultaneously accessing the system and the user. The fact is that by default, android does not have access to the currently mounted drive. For Eclair users, this is not so critical, but here Froyo + users pee with boiling water are not happy when the programs installed on the card crash when mounted. Actually, this program was written to solve this problem. Oh yeah, the program needs root rights.
')
First, we need a distribution package of the program, so that there is something to break. But where to get it? After all, you need to buy it. Well, or beg for someone who has already bought. Such a person became creage from the forum w3bsit3-dns.com , which was kindly shared by the purchased apk.

So, we have a distribution kit , we have already installed the program, we start ... And then bang! We see a window with an offer to buy a license. From this it follows that the test goes via the Internet, we try to disable it - it does not help. The buyer does not give the application any keys and logins, which tells us about the binding to something like hardware_id or google-account. Consequently, we have several options for hacking: either zakardkodit in the program knowingly correct verified information, or cut out of the code all areas that check the validity of the license. I chose the second option, because I like it more.

Tools


To work we need tools. I wanted to talk about them along the way, but still changed my mind and decided to write about everything in advance. Actually, today we will need the following list of tools:


Introduction


Before proceeding, I will explain a little the structure of android applications. Each application has a file with the apk extension, packed with a zip. It contains application resources, AndroidManifest.xml and classes.dex. What is the last one? This is a program bytecode compiled specifically for the dalvik virtual machine. You cannot get pure source code from java from it, but you can get dalvik opcodes - a set of commands for a virtual machine, roughly speaking, this is a local assembler. You can also turn a dex file into a jar, then decompile it and get more or less readable java code. What we are going to do now.

Decompilation


We will carry out all manipulations with apk with the help of the Apk Manger utility. This is a kind of single front-end for a set of libraries working with apk. Let me remind you that you need to have installed drivers for the device and enable USB debugging mode. Let's get started
  1. Copy multimount.apk to the apk_manager \ place-apk-here-for-modding folder and launch Script.bat. If all is well, a console with green text will appear.
  2. It is necessary to decompile apk. Select the item 9 of the same name. After that, we do not close the console.
  3. Open multimount.apk with the archiver and copy the classes.dex file to the dex2jar folder, then drag it to dex2jar.bat. Total Commander dragging does not work.
  4. Appear classes.dex.dex2jar.jar open with jd-gui. The window is not closed yet, it will be needed later.


Begin analysis


For initial information about the application, take a look at its manifest. From it you can understand that the main activations are settings. So the code offering to buy the application is somewhere there. You can also notice a strange line at the bottom:
  1. <uses-permission android:name = "com.android.vending.CHECK_LICENSE" />

What is this? As Google suggests, this line hints that LVL is used in the application, that is, the android license manager. Well, this is even good, because we have documentation. Having read that, it is important to understand that this LVL not only manages licenses, but also subjects obfuscation code, which will significantly complicate our work.

Well, okay, let's proceed directly to the analysis of the code. Switch to jd-gui, expand the tree, and see three namespaces: the first is something related to advertising, the second is a set of LVL classes, the third is what we need.
We go into it and see the effects of obfuscation. Open MultiMountSDCardConfigure, briefly review the code. A long line with some kind of hash immediately catches the eye. This is the base64 public key. And around it there are also other lines checking the license. We need to cut them.
  1. com. android . vending licensing . h localh = new com. android . vending licensing . h ( arrayOfByte, str4, str3 ) ;
  2. v localv = new v ( this , localh ) ;
  3. m localm1 = new m ( this , localv, "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg1 ..." ) ;
  4. f = localm1 ;
  5. m localm2 = f ;
  6. j localj = e ;
  7. localm2. a ( localj ) ;


Open apk_manager \ projects \ multimount.apk \ smali \ com \ rafoid \ multimountsdcard \ widget \ MultiMountSDCardConfigure.smali and see the byte code. Before reading further, I advise you to first see the list of commands. We need to find the very lines and comment them out. Here they are:
  1. ...
  2. # iput-object v1, p0, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure; -> e: Lcom / android / vending / licensing / j;
  3. # new-instance v1, Lcom / android / vending / licensing / m;
  4. # new-instance v2, Lcom / android / vending / licensing / v;
  5. # new-instance v3, Lcom / android / vending / licensing / h;
  6. # sget-object v4, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure; -> d: [B
  7. # invoke-virtual {p0}, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure; -> getPackageName () Ljava / lang / String;
  8. # move-result-object v5
  9. # invoke-direct {v3, v4, v5, v0}, Lcom / android / vending / licensing / h; -> <init> ([BLjava / lang / String; Ljava / lang / String;) V
  10. # invoke-direct {v2, p0, v3}, Lcom / android / vending / licensing / v; -> <init> (Landroid / content / Context; Lcom / android / vending / licensing / n;) V
  11. # const-string v0, "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCg ..."
  12. # invoke-direct {v1, p0, v2, v0}, Lcom / android / vending / licensing / m; -> <init> (Landroid / content / Context; Lcom / android / vending / licensing / k; Ljava / lang / String;) V
  13. # iput-object v1, p0, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure; -> f: Lcom / android / vending / licensing / m;
  14. # iget-object v0, p0, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure; -> f: Lcom / android / vending / licensing / m;
  15. # iget-object v1, p0, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure; -> e: Lcom / android / vending / licensing / j;
  16. # invoke-virtual {v0, v1}, Lcom / android / vending / licensing / m; -> a (Lcom / android / vending / licensing / j;) V
  17. ...

We zamenchivaem, save. It seems like everything can be used. It remains only to compile and install.

Compile and install


For this, we will use the already familiar Apk Manager.
  1. If you have not yet closed the console window, switch to it and select item 14. The script itself compiles, signs and installs apk on the device.
  2. We start the application and see that now we are not offered to buy anything, but the window with the verification process hangs and does not close.


Again analysis


Now we need to detect and delete the code that shows the dialogue we do not need. Switch to jd-gui and find the following lines a little higher:
  1. rogressDialog localProgressDialog = ProgressDialog.show (this, str1, str2, 1, 0);
  2. b = localProgressDialog;

Now you need to find them in MultiMountSDCardConfigure.smali. Here they are:
  1. ...
  2. # invoke-static {p0, v0, v1, v6, v7}, Landroid / app / ProgressDialog; -> show (Landroid / content / Context; Ljava / lang / CharSequence; Ljava / lang / CharSequence; ZZ) Landroid / app / ProgressDialog;
  3. # move-result-object v0
  4. # iput-object v0, p0, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardConfigure; -> b: Landroid / app / ProgressDialog;
  5. ...

We comment, save, compile, install, run. Hooray! Everything is working. But after a short test, we understand that not everything works, namely the auto-mount function. Switch to jd-gui, open MultiMountSDCardWidget $ UpdateService and see the following curve code:
  1. if (MultiMountSDCardWidget.b.booleanValue ());
  2. int j;
  3. for (int i = 0;; j = 1)
  4. {
  5. Boolean localBoolean = Boolean.valueOf (i);
  6. RemoteViews localRemoteViews = MultiMountSDCardWidget.a (this, localBoolean);
  7. Class localClass = MultiMountSDCardWidget.a;
  8. ComponentName localComponentName = new ComponentName (this, localClass);
  9. AppWidgetManager.getInstance (this) .updateAppWidget (localComponentName, localRemoteViews);
  10. return;
  11. }

This service is responsible for auto-mounting. At the very beginning, we see some kind of check, as a result of which this mount is performed. The code checks the variable b from the main activation, the very variable whose declaration we comment, deleting the dialog. We will do the same with this check - we comment it to hell.
This time, open MultiMountSDCardWidget $ UpdateService.smali and fill in the following lines:
  1. ...
  2. .method public onStart (Landroid / content / Intent; I) V
  3. .locals 3
  4. # sget-object v0, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardWidget; -> b: Ljava / lang / Boolean;
  5. # invoke-virtual {v0}, Ljava / lang / Boolean; -> booleanValue () Z
  6. # move-result v0
  7. # if-eqz v0,: cond_0
  8. const / 4 v0, 0x0
  9. : goto_0
  10. invoke-static {v0}, Ljava / lang / Boolean; -> valueOf (Z) Ljava / lang / Boolean;
  11. move-result-object v0
  12. invoke-static {p0, v0}, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardWidget; -> a (Landroid / content / Context; Ljava / lang / Boolean;) Landroid / widget / RemoteViews;
  13. move-result-object v0
  14. new-instance v1, Landroid / content / ComponentName;
  15. sget-object v2, Lcom / rafoid / multimountsdcard / widget / MultiMountSDCardWidget; -> a: Ljava / lang / Class;
  16. invoke-direct {v1, p0, v2}, Landroid / content / ComponentName; -> <init> (Landroid / content / Context; Ljava / lang / Class;) V
  17. invoke-static {p0}, Landroid / appwidget / AppWidgetManager; -> getInstance (Landroid / content / Context;) Landroid / appwidget / AppWidgetManager;
  18. move-result-object v2
  19. invoke-virtual {v2, v1, v0}, Landroid / appwidget / AppWidgetManager; -> updateAppWidget (Landroid / content / ComponentName; Landroid / widget / RemoteViews;) V
  20. return-void
  21. #: cond_0
  22. const / 4 v0, 0x1
  23. goto: goto_0
  24. .end method
  25. ...

We start and we are glad that we saved as much as 30 rubles on the purchase of this most useful program.

Notes


The process is described entirely for Windows, but can easily be repeated on Linux, since all the necessary libraries are cross-platform.
After writing this article, I came across this hacking method, but, as far as I understand, it is relevant for earlier versions of LVL.

All information is presented for informational purposes only. And also for developers to improve software protection.

Source: https://habr.com/ru/post/111513/


All Articles