this is a basic example of smali code with some comments. view it with ultraedit and syntax highlighting to get the full effect. this file is also included and updated in lesson 0 of the way of the android cracker.
for reference of dalvik opcodes, visit Dalvik opcodes.
update: if you like this, you may also want to see some example structures.
update #2: threw in a little bit about primitives and arrays.
for reference of dalvik opcodes, visit Dalvik opcodes.
update: if you like this, you may also want to see some example structures.
update #2: threw in a little bit about primitives and arrays.
# class name, also determines file path when dumped .class public Lcom/packageName/example; # inherits from Object (could be activity, view, etc.) # note class structure is L; .super Ljava/lang/Object; # original java file name .source "example.java" # these are class instance variables .field private someString:Ljava/lang/String; # finals are not actually used directly, because references # to them are replaced by the value itself # primitive cheat sheet: # V - void, B - byte, S - short, C - char, I - int # J - long (uses two registers), F - float, D - double .field public final someInt:I # the :I means integer .field public final someBool:Z # the :Z means boolean # Do you see how to make arrays? .field public final someCharArray:[C .field private someStringArray:[Ljava/lang/String; # this is the <init> of the constructor # it calls the <init> of it's super, which in this case # is Ljava/lang/Object; as you can see at the top # the parameter list reads: ZLjava/lang/String;I # Z - boolean # Ljava/lang/String; - java String object # (semi-colon after non-primitive data types) # I - integer # (no semi-colon) # also notice this constructor returns V, which means void .method public constructor <init>(ZLjava/lang/String;I)V # declare how many variable spaces we will need # we can have: v0, v1, v2, v3, v4 and v5 as variables. # smali/baksmali by default uses .registers # but you can change this by using --use-locals # apktool uses --use-locals and --sequential-labels .locals 6 # these are not always present and are usuaully taken # out by optimization/obfuscation but they tell us # the names of Z, Ljava/lang/String; and I before # when it was in Java .parameter "someBool" .parameter "someInt" .parameter "exampleString" # the .prologue and .line directives can be mostly ignored # sometimes line numbers are useful for debugging errors .prologue .line 10 # p0 means parameter 0 # p0, in this case, is like "this" from a java class. # we are calling the constructor of our mother class. # what would p1 be? invoke-direct {p0}, Ljava/lang/Object;-><init>()V # store string in v0 const-string v0, "i will not fear. fear is the mind-killer." # store 0xF hex value in v0 (or 15 in base 10) # this destroys previous value string in v0 # variables do not have types they are just registers # for storing any type of value. # hexadecimal is base 15 is used in all machine languages # you normally use base 10 # read up on it: # http://en.wikipedia.org/wiki/Hexadecimal const/4 v0, 0xF # create instance of StringBuilder in v1 new-instance v1, Ljava/lang/StringBuilder; # initialize StringBuilder with v2 # notice it returns V, or void const-string v2, "the spice must flow" invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V # append p1, which is our first paramater and is boolean # therefore we use append(Z) # notice how append returns a StringBuilder invoke-virtual {v1, p1}, Ljava/lang/StringBuilder;->append(Z)Ljava/lang/StringBuilder; # use move-result-object to store previous result in v1 move-result-object v1 # non-objects use move-result or move-result-wide # append v2 to our StringBuilder # notice how this append takes a string and not Z const-string v2, "some random string" invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v1 # call toString() on our StringBuilder # if you use Java you know that most objects have toString() invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; move-result-object v1 # send our new string to the log. # this can be used to debug and can be picked up with ddms, logcat # or log collector. as an exercise look up what the d() function does # in the android developer documentation. const-string v0, "Tag" invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I move-result v0 # get the current time in milliseconds # J denotes a float or wide return value invoke-static {}, Ljava/lang/System;->currentTimeMillis()J move-result-wide v2 # note!! since it is a wide value, it takes up v2 AND v3 # so we must use v4 next # try to reuse variables if possible. const-wide/16 v4, 0x300 # this takes up v4 and v5 div-long/2addr v2, v4 # divide v2 by v4 long-to-int v2, v2 # convert v2 to an integer # since i wrote this in my head, there was no Java # compiler to add the .line's in the right places # but normally they would relate to actual Java lines # these are often removed with proguard optimization .line 12 # store p1 as an instance variable (someBool) for this class # in java this may look like this.someBool = p1; iput-boolean p1, p0, Lcom/packageName/example;->someBool:Z .line 14 # do the same for p3 and someInt iput p3, p0, Lcom/packageName/example;->someInt:I # get the value from p0.someInt iget v0, p0, Lcom/packageName/example;->someInt:I # now we will invoke a static method. # {} means empty parameters then the full package name followed by -> # then the method and it's return value. everything must be there. invoke-static {}, Lcom/packageName/example;->someMethod()Ljava/lang/String; # for different types of invoke-*, try this: # http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html # invoke-virtual and direct take the class instance as a first parameter. .line 16 return-void # meditate on the void. .end method # try and figure this one out .method public static someMethod()Ljava/lang/String; # could i have used fewer variables? .locals 4 new-instance v0, Ljava/lang/Long; invoke-static {}, Ljava/lang/System;->currentTimeMillis()J move-result-wide v1 invoke-direct {v0, v1, v2}, Ljava/lang/Long;-><init>(J)V invoke-static {v0}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String; move-result-object v1 # notice use of return-object and not just return return-object v1 .end method
I can't believe there are no more comments here. VERY helpful. I'm trying to dig into smali files and it's sometimes frustrating. Digging the Dune references there also ;)
ReplyDeleteSince you are already doing this:
what does if-eqz v4, :cond_2 mean?
I'm trying to translate it in my mind to java:
if (v4==0)
(whatever is after the :cond_2 tag)
else
(whatever set of instructions follows)
Am I correct?
Yes, if v4 is equal to zero go to the line where :cond_2 is placed and continue on from there,
Deleteotherwise just continue on at the next line.
if you want to write if(v4==0) in smali
Deleteif-nez v0, :cond_0
//This block execute when Value in v0 is Zero
:cond_0
//This block execute when Value in v0 is One
Your thinking of if(v4!=0)
DeleteFor if-nez
It should be if-eqz
i'm glad you find it helpful and you enjoy dune :D.
ReplyDeleteyou are correct. it helps to mentally read it as "if equals zero v4 jump to label :cond_2". this goto-style branching is typical of lower level languages.
Thanks for the quick reply
ReplyDeleteI was figuring it out myself in the meantime. In this case v4 is a Z (boolean as I learned today :), so I'm assuming it could be read as if (!v4), which would make sense in the context of the rest of the code.
I will go over your lessons 0 and 1. I'll probably come with a few more questions after that if you don't mind.
Thanks a LOT! This is really helpful!
ReplyDeleteOMG!!!! Thank u for this great work. The comment is really helpful to me. Great Job. Thank you
ReplyDeleteI'm working on project which is based on baksmali but outputs java-code instead of smali-code, because it's much easier than smali and there is no application around which produces compileable java-code(dex2jar is very buggy).
ReplyDeleteI already got simple classes and method-definitions converted but now I'm about to convert variables.
So I need to know how this works exactly :)
One problem I have is the number behind "const/" which always differs. what does it mean?
Maybe you can contact me via email so I don't have to go offtopic in the comments.
Hi, have you finished the project, coz I badly need that now, not only me so many developers are waiting forward for suc sort of project which could directly convert to java files and you are absolutely right about dex2jar, but there are no further improvements or later versions released in that. So looking eagerly forward for your project.
Deletehi, did you manage to find the meaning of the numbers behind the "const/" ?
DeleteIt refers to the number of bits for the literal. const/4 would be 4 bits sign extended to 32 bits. See http://source.android.com/tech/dalvik/dalvik-bytecode.html for more information.
Deleteconst/4
Deletemeans that reister size is 4 bytes
Hi, lohan+
ReplyDeleteI'm writing a tutorial on android malware analysis here:
http://code.google.com/p/amatutor
I hope it can use your code in example.smali, example-structures.java, and example-structure.smali to introduce smali syntax and dalvik opcode to readers. Because current version is writen by Chinese, I hope I can delete some comments and explain it in Chinese.
I will add your name and the refer URLs near these code.
Can I use it like that? Hope for your confirm email, my address is iClaudXiao@gmail.com
Thank u very much.
Claud Xiao
Hi there can u please help me in writing coding in smali format to add an edittext...??
ReplyDeletehow important is ".line"?
ReplyDelete# .line directives can be mostly ignored
# sometimes line numbers are useful for debugging errors
.line 10
based on your comment .line it's used mostly for error debug?
or some code it's called through that ".line"?
thanks!
No code is called. It's just debugging information. It shows up in error logs and stack dumps
ReplyDeleteThis is great helpful!Thank you!
ReplyDeleteThanks for the interesting info.
ReplyDeleteA small correction: it should be "15 in base 10" on line 68 ;)
wonderful. thank you very much.
DeleteIn line 68 and line 72, don't you mean 16? :)
ReplyDeleteI made the same mistake originally. You'll notice the comment above yours corrected it. Intuitively, the maximum value of a single digit in base 10 can only be 9. 0x9 = 9, 0xA = 10, 0xB = 11, 0xC = 12, 0xD = 13, 0xE = 14, 0xF = 15
ReplyDeleteDo you know if its possible to link in libraries that weren't included in the original build?
ReplyDeleteex. if you add a log statement and Landroid/util/Log results in a ClassDefNotFound
Explanations through your comments were really helpful...thanks
ReplyDeleteAnonymous, short answer: go ahead, shouldn't be a problem.
ReplyDeletelong answer: you will only get ClassDefNotFound if the class is not available to the class loader. if you're referring to java's adding of "import" statements, those are not really present in the bytecode, so i'm guessing they're just there to help the compiler know what you're referring to. if you're on a normal android system Landroid/util/Log will be there.
Thanks for sharing this.
ReplyDeletepicreel
dude you are awesome i need to contact you
ReplyDeleteYou just did! :D
DeleteDude, you just made things A LOT less of a headache! I can't thank you enough for this!
ReplyDeleteHelped me alot here but sadly im still stuck not sure what the goto or cond tags are for i see in a comment they mean to like jump somewhere
ReplyDeleteI am just a begineer. and i am trying to edit an app that send "call me back" message to a phoe number that i entered but it don't list my contact list. A problem of that app is i need to remember phone number that i want message to. So what i want to know is how to list phone contact list and use it in .smali file. thank you.
ReplyDeleteThis very very helpfull, thanks brothers, i am newbe and wanted to learn
ReplyDeleteThis very very helpfull, thanks brothers, i am newbe and wanted to learn
ReplyDeleteHi sir how can I create an int array in smali?
ReplyDeleteIn java I do this COLOR_ARRAY = new int[]{Color.rgb(int, int, int), Color.rgb(int, int, int), Color.rgb(int, int, int), Color.rgb(int, int, int)}
How to do this in smali?
best way is to actually learn how to convert arbitrary java to smali.
Delete1.) write the code in java and compile using javac. this will create .class files.
2.) compile .class files using dx (part of android sdk) into a .dex file
3.) baksmali the dex file to get the smali
4.) automate this using aliases and functions in bash
Hello. I want to make this method return a "false" value.
ReplyDelete.method public isLocked()Z
.locals 1
iget-boolean v0, p0, Lahc;->isLocked:z
return v0
.end method
replace "iget-boolean ..." with "const/4 v0"
Deletebetter would be to find where isLocked is set and fix it so it's set to true. you don't know where else that field is getting checked. may be through reflection and not obvious with static analysis.
What is the use of smali? Pls explain briefly...
ReplyDeletesmali is how the bytecode of dalvik executables can be represented. it's good because it's easy to modify and read. most of the time you don't use it directly. you only "use" it when you need to read and modify it. though it's entirely possible to write programs purely in smali and compile them to dalvik executables using smali. you can also write java, convert to java class files (javac), then convert to dalvik (dx) then convert back to smali.
DeleteAs the job seekers does not only rely on the employment news, they also expect information related to the exam as well as the sarkari results which we find here very apt.
ReplyDeleteThat was a wonderful article. Smali material on the internet is very scarce and this article is a perfect place to get started. Btw, I had a question (though I will follow-up with more questions): When I try to print the byte array using toString() function, I get an overflow error on logcat. Is there a way to get around and print the byte array contents? Any short cuts, hacks? Thanks in advance.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeletewhen i try crack app after change smali code and building and singing i installed it the app open for 2 or 3 second then automatically close can u tell me why
ReplyDeletethis is very very very helpful!!!
ReplyDeletethx a lot!!
Get everything about lucky patcher application here
ReplyDeletelucky patcher
Nice
ReplyDeleteI really like you post good blog,Thanks for your sharing.
ReplyDeleteพี่มากพระโขนง
wow, great work. thanks for info
ReplyDeleteI do not understand the code. Many people who write code is very good at it. I do not write it. สมัครบาคาร่า
ReplyDeleteปรับรูปหน้าเรียว
ReplyDeleteฉีดหน้าเรียว ลดริ้วรอย เป็น
ต้องการ
หน้าเรียวทำเป็น
ยังไง
หลายคน
อาจจะ
กำเนิด
ปัญหา
นี้
และก็
การฉีดลดหน้าเรียวด้วยโบท็อกก็เป็นขั้นตอนการ
รักษาที่ทำเป็น
ง่าย โดยไม่ต้องผ่าตัด
สารารถยนต์
ช่วยลดลางเลือน
ริ้วรอยแล้วก็
ร่องลึกได้ภายในช่วงเวลา
เร็วทันใจ
ได้ผล
การดูแลและรักษา
ที่น่าพอใจ
ละสร้างความเชื่อมั่น
ให้กับผู้มีปัญหาได้อย่างดีเยี่ยม
สารที่ฉีดลดหน้าเรียว
ยังเป็นสารจากธรรมชาติที่เป็นโปรตีนบริสุทธิ์สกัดจากแบคทีเรียที่มีคุณประโยชน์
ประเภทหนึ่ง
ซึ่งจะช่วยเหมือน
กล้าม
โบท็อก หน้าเรียว
ฉีดโบท็อก ที่ไหนดี
โบท็อก กังนัม