Understanding Smali (Dalvik Bytecode) and how to start for beginners

s810car

Advance Member
199
12/09/16
100
Thread Author
Question brought up in chat today regarding how to edit smali made me think of an excellent tutorial I read a couple years back on xda. Its till around so I thought I'd share it with a couple little edits in the intro to make it more applicable to general modding rather then the specific apk it discusses. All credit goes to the OP link: [GUIDE] Smali coding guide for beginners


What is smali?
Android programmers write android apps in java. The compilers like Android Studio are then used to build apks from these codes by converting the java source code into dalvik executables (classes.dex files). The dalvik virtual machine (dalvikvm) in Android can then run these executables. So the perfect way to mod would be to edit the source code of the apk and rebuild the modded apk. This is possible for AOSP ROMs like cyanogenmod that have open source code. So anyone who knows java can download the source code of cyanogenmod, do any crazy modification they want and build CM with the new code. But unfortunately most applications/games are not open source , so thecode is not available.

But their dex (dalvik) files are available when you extract the apk and unzip the compressed data with tools like apktool. These files, like most compiled code, are mostly unreadable in their natural form. So to edit, we will need to convert this .dex files to a more understandable form. This is where smali comes in. To make it easier to understand I can represent it like this:

.dex <------------------> .smali <--------------------- java source code

Converting a .dex file to smali (called baksmaling) gives us readable code in smali (assembly) language. Now if you wonder why can't smali be converted into java source, that's because java is a very developed language and smali is more a machine code language. There are tools that can decompile the classes the smali came from (a good one is jd-gui for example), however when going from java source to smali, some information is lost (machine code is able to adjust source code very efficiently and remove/reduce a bit of the code it doesn't need), and so smali can't be used to completely reconstruct java source code.

Now how do you actually start? This next section is from the origfinal source tutorial that discusses how to mod SystemUI with APK Multi-Tool. My preference is Virtuous Ten Studio for its interface and instant help on understanding the opcode you wish to work on (you can hover over the opcode for a popup help message), but the information is the same for the how-to basics.
How to baksmali SystemUI.apk?
So let us first decode and obtain the smali code from the SystemUI.apk in your phone.

APK Multi-tool: There are many tools out there that can baksmali apks and later recompile them back after you edit the .smali files. I used APK Multi-tool for this purpose and I would say it works really well with SystemUI.apk as the tool handles system apps separately and has a comparatively more decent UI. I used Windows Version v1.0.11

(Don't forget to give thanks to the people who made these tools if these come in handy for you!)

I - Setting up APK Multi-Tool

Download and extract it
Now from your phone copy framework-res.apk from /system/framework and SystemUI.apk from /system/app and paste it in <folder to which you extracted APK-Multitool>\other. Also copy SemcGenericUxpRes.apk from /system/framework. You will need it later. SemcGenericUxpRes.apk is only for Sony stock based ROMs. For ROMs from other OEMs the corresponding file may have different name and/or location
Run Setup.bat (I think it needs to be run as administrator)
Choose option 2. And from there choose the option to install framework-res.apk and SystemUI.apk. After both are installed return to main menu
Choose option 3 to setup directories
Choose 00 to quit




Now that we have APK Multi-Tool setup for use let us do some baksmaling

II - Decompiling and Baksmaling

Run Script.bat (In case you face problems try running it as administrator. But you probably wouldn't need to unless you extracted all this somewhere in your main windows partition)
Place the apk to be modded in 'place-apk-here-for-modding' folder
Choose option 10 in APK Multi-Tool command window
When it asks for the dependee apk as input drag and drop SemcGenericUxpRes.apk you took from your phone earlier at the command input
If all goes well you would return to the main screen. Don't close the script yet. Back at the APK Multi-tool\projects folder you should find a new folder inside which you would find a folder named smali. This folder has all the required smali files


DON'T CLOSE THE SCRIPT YET
The script needs to be open from baksmaling and needs to stay till you smali it again. If you close it in between you will have to start over again

Trouble?

Try running the scripts as administrator if you get errors
Make sure you have java installed (Latest version recommended. I've used APK MultiTool with v1.6 and 1.7). Open command prompt (Type cmd in run to open command prompt) and type in java. If it says something similar to unknown command, that means you either don't have properly working java or you haven't added java to the command line path. Link is Broken. The method explained for Vista worked in my Windows 7 laptop
If you get an error similar to wrong dependee then try this. Goto %userprofile%/apktool/framework. You must already be having 1.apk there if you successfully installed framework-res.apk in step I.4 above. Just copy and paste it again in that same folder as a copy (don't overwrite the first 1.apk) and rename this copy to 2.apk and try baksmaling again


III - Coding
This is where the actual work happens. As far as I have understood each class in the java source code would make a seperate smali file. Suppose there is a PhoneStatusBar class in the actual SystemUI source code you will find a PhoneStatusBar.smali somewhere in the smali folder APK Multi-Tool just made. If there was one sub class in the PhoneStatusBar class then that would result in a PhoneStatusBar$1.smali and so on. So you need to figure out which file to edit and do it using any text editor.

IV - Smaling and Recompiling
After you finished editing all the smali files and xmls and pngs next the whole thing needs to be smalied and then recompiled into the final apk.

From the APK Multi-tool script choose option 11.
When it asks about y/n enter y
You would now find a new folder named keep in the APK Multi-Tool directory. From that folder delete everything that you changed. Obviously you won't find any smali files as they have already been smalied into dex. So if you made changes in any smali file then delete the .dex file in this folder. If you have made changes in any xml then delete the resources.arsc and also the xml file that you changed. Delete any png or any other file you have changed
Go back to the script and press any key to continue
If all goes well you would now have the modded apk waiting for you in the 'place-apk-here-for-modding' folder with its unsigned added to its file name.


Trouble?

Try running the scripts as administrator if you get errors
In the main window type in option 23 to check the log. Try to figure out what you messed up from the information in the log

Welcome to the world of smali coding!

Smali is not an easy programming language to master. You can get info about almost all smali commands here and here. These two links are excellent references for you all along the way! Here I'll go through some of the facts about smali and some of the things that I have found which might help you in writing your own smali code

Quote:

As far as I know Smali resembles java the most. And the best resource to java in android programming is nothing else than developer.android.com
Quote:

As I said earlier its not possible to reconstruct java source code from smali. But this handy tool APK_OneClick would still get you as close to the source code as possible. That said don't expect to get a compilable code out of it. Set up is pretty straight forward. Running the bat file adds few shell extensions to the right click menu including reconstructing java code. This tool has helped me a lot in understanding the code structure in SystemUI and I highly recommend using it. As a warning don't trust it completely. It did make mistakes a few times mostly when loops are involved


That said let us talk more about loops. You might have played with for, while loops, etc before. But well you won't find them in smali. Smali being more of an assembly language handles such loops using labels and goto commands.

Example 1 java code
Code:

if (flagx == 1)
flagx = 2
else
flagx = 3

When flagx variable is referenced as v0
Equivalent Example 1 smali code
Code:

const/4 v1, 0x1
if-ne v0, v1, :cond_0
const/4 v2, 0x2
move v0,v2
goto :goto_0
:cond_0
const/4 v2, 0x3
move v0,v2
:goto_0


See how much complex the so simple java code became in smali! At this rate how the hell can one figure out the smali for complex java code? Well the easiest way to do it would be starting from the opposite end.

Get Android SDK and Eclipse downloaded and set up
Write the java code which resembles what you want to do as closely as possible for a simple non-system app
Build the apk in eclipse
Decompile and Baksmali the apk and look at the smali code

Through this, if we get to know how the smali code would look, it should be easier to start off. For an example and more details on this check this post and this post

Numbers in smali are represented in hex number system and follow IEEE 754 standards. Yeah you guessed right - That's also complicated.

Suppose you want to introduce a number in your smali code. Say in example 1, you want flagx to be 330 instead of 3. The best way to find how 330 would look in smali would be to do what I said in the previous quote about starting from the opposite end. Write a java code with 330 replacing 3 and look into the baksmalied file to see how it looks.
Online Converter - This is an excellent online converter to make things easier. But even this isn't straight forward. Suppose you find a hexadecimal 0x435c in a smali file. Look for what type of variable is it stored in. And you see that that value is stored in smali in a 16 bit variable. Unfortunately the online converter takes only 32,64 and 128 bits. So type in 435c0000 in the input of the online converter. For 64 bit variables you will have to put more zeros. To find the IEEE 754 hex representation of decimal 330, type in 330 in the online converter and get its hex representation for different bit sizes

So the next part of his tute spoke on editing a specific function iun SystemUI, not relevant to this tutorial. He references some functions from it in this next part though so I'm stating this to avoid confusion, the link to original tutorial is above if really confused or just want to know
Figuring out smali


Quote:

So in the previous post I said we should call interceptOneFingerStatusBarRightTap in interceptTouchEvent method. But how does one find that out? In which function to call and where?

Well first of all look at the names of the methods and variables and try to figure out what they do. Look at the parameters in function calls. Like interceptOneFingerStatusBarRightTap requires MotionEvent as its parameter in the function call to be able to use getRawX(). So now look at all the methods in PhoneStatusBar.smali which has acces to MotionEvent. In simple cases you might then be able to figure out where to put the method call if you understand the smali code and/or through trial and error. But in more complex cases you can take the help of logcat

Send messages to logcat
So here our aim is to add the call to interceptOneFingerStatusBarRightTap to a method in PhoneStatusBar.smali that has access to MotionEvent and is called when the user touches the screen. Goto all such methods and add smali code to send messages to the logcat. The smali code would be like this

Code:

const-string v1, "Message1"

const-string v2, "Message2"

invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

Make sure the variables used doesn't interfere with the code. Let us say we want to see when interceptTouchEvent is called. Add the above code at the beginning of the definition for interceptTouchEvent method. Instead of "Message1" write "interceptTouchEvent" and instead of "Message2" write "beginning". Now if you smali+compile the code to get the unsignedSystemUI.apk and get it working in your phone, connect the phone to your PC/laptop with USB debugging and open up logcat in cmd or eclipse. Now the "interceptTouchEvent" and "beginning" would come up in the logcat the moment the beginning part of interceptTouchEvent is executed. Like this you can find out which method is called when the user touches the status bar and where in the method should the code be added so that the right tap check happens only when you want it to

In some cases you would want to see what value a certain variable holds. Suppose you want to know the value in mTouchRight at the beginning of interceptTouchEvent. The following code would do it

Code:

iget-boolean v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mTouchRight:Z

const-string v2, "mTouchRightatbegofITE"

invoke-static {v1}, Ljava/lang/String;->valueOf(Z)Ljava/lang/String;

move-result-object v3

invoke-static {v2, v3}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

The extra line is to convert the boolen value in mTouchRight to string as Log.d() needs string parameters.
Finally get rid of the log.d() commands you wouldn't require before releasing the final version!

Quote:

Starting from the Opposite End
To aid in this I'll share a simple apk source code that my friend (unfortunately he's not a member of xda) and I made with this post. Just import this project into eclipse and you should be able to build it. Suppose you want to know how much 107.0 is in hex. Just change the value at the place where it checks with getRawX in the java code to 107.0 and build the apk. Decompile/Baksmali the apk to check the corresponding smali hex value of 107.0

This is just a starter. You can probably do many things with this. Do complex codes in java in a dummy apk and see how it looks in smali and then try to implement it in the smali code of the actual apk!
Quote:

Notepad++
If you have already gotten into smali coding you might have seen that just the number of all these smali files are enough to cause headache! How do you find out all the places where interceptTouchEvent is being called? Well if you sit and open all smali files and search for the method your patience would soon abandon you (to put it in a decent way :p) Don't worry, here's notepad++ to the rescue. Here's why I recommend notepad++

The above mentioned purpose - Notepad++ has a "find in files" feature. It lets you search for "interceptTouchEvent" in every file that notepad++ can handle (of course including smali). It even lets you know which line in the file in the search result has the search string
Smali syntax highlighting - You can get proper syntax highlighted in notepad++ by importing the .xml file for smali. Google for "notepad++ smali user defined language" and find the .xml. Import it in notepad++ as a new user defined language by going to Language>Define you language.. in notepad++. I can't share the .xml file here due to some reasons.
Easy to use with multiple-tabs for multiple files
More minor reasons are there which I would let you discover for yourself
The simple apk source code file he references has an error in it when you import into android studio, I will modify it and post in this thread later tonight, but again theres a LOT of good information there, especially regarding not just how to edit, but how to get to understand what you are editing. Hope this helps someone and happy modding!
 
Top Bottom