Smali vs Java

The First Question which may come to your mind is:

Well The answer to is quite simple:

Smali is important because it allows developers, reverse engineers and malware analysts to:

What is Smali?

What is Baksmali?

What is Dalvik Virtual Machine (DVM)?

Connection to the Dalvik Virtual Machine with Smali

The DVM converts Smali code into a format that the device’s processor can understand through the process known as “dexing”.

Let’s take an example and try to understand

Since everybody takes example of Hello World! in this field, let’s go with that

alt text

alt text

Now let’s Understand this

Java Main Method

The next line in smali: [Ljava.lang.Object; is the name for Object[].class and .super doing function like calling/storing of it

declares that the current class extends the Java class Object.

When you create a new class in Java, it automatically extends the Java class Object. This means that your new class inherits all the methods and variables that are defined in the Object class.

A simple way to understand this concept is a family tree. In a family tree, everyone is related to each other. Similarly, in Java, all classes are related to the Object class.

For example, let’s say you have a class called Car. The Car class inherits all the methods and variables that are defined in the Object class. This means that you can use methods like toString(), equals(), and hashCode() on any Car object.

Another way to think about it is that the Object class is the parent class of all other classes in Java. When you create a new class, you are essentially saying that your new class is a child of the Object class.

The Car class inherits all the properties and methods of the Vehicle class. This means that a Car object has all the same properties and methods as a Vehicle object, such as make, model, and year.

In the same way, all Java classes extend the Object class, which means that they inherit all the properties and methods of the Object class.

declares a public static method named main that takes an array of String objects as input and returns void.

In this case/example the main method is like the front door of your house. When someone wants to enter your house, they come through the front door. Similarly, when you run a Java program, the JVM enters your program through the main method.

Another way is to think of the main method as the starting point of a race. When a race begins, all the runners start at the same starting line. Similarly, when you run a Java program, the JVM starts executing your program at the main method.

specifies that the method uses two registers. More information on Day 3 wiki

retrieves the PrintStream object associated with the standard output stream and stores it in register v0.

loads the string “Hello World!” into register v1.

calls the println method on the PrintStream object in register v0, passing the string in register v1 as an argument. This prints the string “Hello World!” to the standard output stream.

returns from the main method.

marks the end of the method.

Class Header

Okay, so we looked at a full example. Now, let’s zoom in on the very top of a smali file. Think of it like the title and introduction of a book – it tells you some important things about what you’re about to read! This top part is called the Class Header.

Imagine the Class Header is like a little information card for the class. It always has a couple of important pieces of information, and sometimes it has a few extra details.

Here are the important things you’ll find in the Class Header:

package com.example;

class ExampleClass implements MyInterface {
    // Class implementation
}

In Smali, this would be represented as:

.class public Lcom/example/ExampleClass;
.super Ljava/lang/Object;
.source "ExampleClass.java"

.implements Lcom/example/MyInterface;

Annotations

Annotations in Smali are similar to annotations in Java. They provide metadata about the class, method, or field, such as its visibility or whether it is deprecated.

They are declared using the .annotation directive, followed by the annotation’s visibility (e.g., runtime, system, build) and the annotation’s type descriptor and any associated elements. The annotation block is terminated by the .end annotation directive.

Here are some examples of annotations in Smali:

.class public Lcom/example/ExampleClass;
.super Ljava/lang/Object;

.annotation runtime Ljava/lang/Deprecated;
.end annotation

.annotation system Ldalvik/annotation/EnclosingClass;
  value = Lcom/example/OuterClass;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
  accessFlags = 0x0002
  name = "ExampleClass"
  outer = Lcom/example/OuterClass;
.end annotation

# class definition and methods go here

In this example:

public static final Parcelable.Creator<j> CREATOR = new i(0);

The equivalent Smali code with an annotation for the field’s generic signature would look like:

.field public static final CREATOR:Landroid/os/Parcelable$Creator;

  .annotation system Ldalvik/annotation/Signature;
    value = {
      "Landroid/os/Parcelable$Creator<",
      "LC1/j;",
      ">;"
    }
  .end annotation

.end field

Here, the @Signature annotation (Ldalvik/annotation/Signature;) specifies that the CREATOR field is a Parcelable.Creator parameterized with the type C1/j. This preserves the generic type information from the original Java code.

Annotation visibility:

Fields

Fields in Smali are defined using the .field directive within a class. Each field has a name, type, access modifiers and optionally an initial value. The syntax for defining a field is as follows:

.field [access_flags] field_name:field_type [= initial_value]

Where:

Example:

.field public static final myField:I = 42
.field private myString:Ljava/lang/String; = "Hello, Smali!"
.field public myBoolean:Z

here, myField is a public static final integer field i.e, it can be accessed from anywhere, is a constant and is of type integer with an initial value of 42. myString is a private field of type string with an initial value of “Hello, Smali!”. myBoolean is a public field of type boolean with no initial value specified.

*Access Modifiers: Access modifiers in Smali are used to control the visibility and accessibility of fields and methods. The common access modifiers are:

Methods

Methods in Smali are defined using the .method directive. The syntax for defining a method is as follows:

.method [access_flags] method_name([parameter_types])return_type
    .registers number_of_registers

    # method body goes here
.end method

Where:

.method public static myMethod(I)Ljava/lang/String;
    .registers 2

    const-string v0, "Hello, Smali!"

    return-object v0
.end method

In this example, myMethod is a public static method that takes an integer parameter and returns a string. The method uses two registers (v0 and v1) to store intermediate values. It creates a string “Hello, Smali!” and returns it.

Type Descriptors

Type descriptors in Smali are used to represent the types of fields, method parameters and return values. They are similar to Java type descriptors but have a specific syntax. Here are some common type descriptors:

DescriptorTypeValue Example (human-readable)Size in Bytes
VVoid-0
ZBooleantrue/false1
BByte-128 to 1271
SShort-32,768 to 32,7672
CCharacter'a', 'b', etc.2
IInteger-2,147,483,648 to 2,147,483,6474
FFloat1.4E-45 to 3.4028235E384
JLong-9,223,372,036,854,775,808 to 9,223,372,036,854,775,8078
DDouble4.9E-324 to 1.7976931348623157E3088
[Array (reference type)[I (array of integers), [Ljava/lang/String; (array of strings)-
L<class_name>;Object (reference type)Ljava/lang/String; (String object), Lcom/example/MyClass; (custom class)-

[!NOTE] Unless stated otherwise, all type descriptors are case-sensitive. For example, I is an integer, while i is not a valid type descriptor. Similarly, unless stated otherwise, all type descriptors in the above table are primitive type while L<class_name>; is not a primitive type but a reference type.

Basics →