smali/baksmali 수준의 코드 수정

smali/baksmali는 An assembler/disassembler for Android's dex format의 약자이다.
DEX 바이너리를 사람이 읽을 수 있도록 쉽게 표현한 것이다.

Dex (Dalvik Executable)

Toast Smali Code 추가 방법

HelloWorld.java

Toast toast = Toast.makeText(getApplicationContext(), "Toast Test");
toast.show();

HelloWorld.Smali

invoke-virtual {p0}, Lcom/test/helloworld/HelloWorldActivity;->getApplicationContext()Landroid/content/Context;
move-result-object v1
const-string v2, "Toast Test"
const/4 v3, 0x0
invoke-static {v1, v2, v3}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V

smali code를 설명하면 다음과 같다. 우선 line 1은 자신의 activity 이름과 맞춰서 변경을 해야 한다.

문법 정리

java 코드

package com.atest;

import android.app.Activity;
import android.os.Bundle;

public class AtestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

smali 코드

.class public Lcom/atest/AtestActivity;
.super Landroid/app/Activity;
.source "AtestActivity.java"

# direct methods
.method public constructor <init>()V
    .locals 0

    .prologue
    .line 7
    invoke-direct {p0}, Landroid/app/Activity;-><init>()V

    return-void
.end method

# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
    .locals 1
    .parameter "savedInstanceState"

    .prologue
    .line 11
    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

    .line 12
    const/high16 v0, 0x7f03

    invoke-virtual {p0, v0}, Lcom/atest/AtestActivity;->setContentView(I)V

    .line 13
    return-void
.end method

class -> super
Object는 L이라 이름 붙음
.source는 파일 명이다.

Class Body는 .method로 시작해서 .end method로 끝난다.
invoke-virtual {v1}, Landroid/widget/Toast;->show()V에서 V는 마지막 return type void를 의미한다.
.locals는 method 내부에서 사용하는 resiter의 수를 의미한다. (v0,v1,v2..vn)
.parameter는 매개변ㅅ로 받아온 변수명이다.

.prologue로 body가 시작하는데 사용되는 opcode들은 
(http://netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html)에서 자세하게 확인할 수 있다.

.line xx는 java소스의 라인을 가리키므로 디버깅시 확인할 수 있다.

주로 함수 호출시 invoke-kind가 사용되는데 virtual, static, super등이 있다.
p0은 클래스 인스턴스를 가리키고 이후 value가 매개변수에 해당된다. 
메소드 명 뒤 괄호 안에 매개변수의 type을 지정하는데, primitive type의 경우 약어를 넣고 그 외의 type은 패키지명을 포함하여 지정한다.

관련 사이트

Smali: https://github.com/JesusFreke/smali
Smali TypesMethods and Fields: https://github.com/JesusFreke/smali/wiki/TypesMethodsAndFields

Dalvik bytecode format: https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html
APKTool을 통한 Smali 분석: http://strawberryit.tistory.com/142


  1. 스말리 2017.11.30 18:42

    토스트 스말리코드에 invoke nvoke라고 오타났네요

+ Recent posts