如何把java代碼轉換成smali代碼


1、概述

Smali是Android系統中Dalvik虛擬機指令語言,在apk逆向過程中有許多工具可以把smali代碼轉化成java代碼。但是在學習Smali語法的過程中,有時候需要進行java代碼和smali代碼的對照,如果可以把java代碼轉換成smali代碼,學習起來豈不是很方便。於是網上搜了一把,很失望,都是各種轉smali為java的工具。后來想了想,java變成smali不就是寫android程序—>dex—>smali的過程嘛,然而java代碼編譯完是class文件,如何變成dex文件呢?后來在一本書中找到了答案,記錄如下。

2、java代碼轉smali代碼

把java代碼轉成smali代碼共需要以下三個步驟

1、編譯java代碼為class文件

javac smaliTest.java

這個比較簡單,會生成smaliTest.class文件

2、把class文件轉成dex文件

我們知道apk包里java代碼最后生成的是class.dex文件,把class轉化成dex文件就需要用到android SDK提供的一個工具dx,該jar包位於android-sdk\build-tools\23.0.1\lib,找到該包后執行以下命令

java -jar dx.jar --dex --output=smaliTest.dex smaliTest.class

3、把dex轉化成smali文件

這時候會使用到另外一個工具baksmali,該工具位於android-sdk\platform-tools\,找到該包后執行以下命令

java -jar baksmali.jar smaliTest.dex

OK,完成,此時會生成一個out目錄,在out目錄下的smaliTest.smali就是我們要看到的smali代碼了

3、示例程序

java代碼如下:

public class smaliTest {
       public static void main(String[] args){
           System.out.println("hello smali");
       }
   }

smali代碼如下

.class LsmaliTest;
.super Ljava/lang/Object;
.source "smaliTest.java"


# direct methods
.method constructor <init>()V
    .registers 1

    .prologue
    .line 3
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

.method public static main([Ljava/lang/String;)V
    .registers 3
    .parameter

    .prologue
    .line 5
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

    const-string v1, "hello smali"

    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 6
    return-void
.end method

4、遇到的問題

我的android環境是在windows下搭建的,jdk版本是1.8,在windows下執行第二步時出現如下錯誤

UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: Exception parsing classes
        at com.android.dx.command.dexer.Main.processClass(Main.java:752)
        at com.android.dx.command.dexer.Main.processFileBytes(Main.java:718)
        at com.android.dx.command.dexer.Main.access$1200(Main.java:85)
        at com.android.dx.command.dexer.Main$FileBytesConsumer.processFileBytes(
Main.java:1645)
        at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.j
ava:170)
        at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java
:144)
        at com.android.dx.command.dexer.Main.processOne(Main.java:672)
        at com.android.dx.command.dexer.Main.processAllFiles(Main.java:574)
        at com.android.dx.command.dexer.Main.runMonoDex(Main.java:311)
        at com.android.dx.command.dexer.Main.run(Main.java:277)
        at com.android.dx.command.dexer.Main.main(Main.java:245)
        at com.android.dx.command.Main.main(Main.java:106)
Caused by: com.android.dx.cf.iface.ParseException: bad class file magic (cafebab
e) or version (0034.0000)
        at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:
472)
        at com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:4
06)
        at com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary
(DirectClassFile.java:388)
        at com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.jav
a:251)
        at com.android.dx.command.dexer.Main.parseClass(Main.java:764)
        at com.android.dx.command.dexer.Main.access$1500(Main.java:85)
        at com.android.dx.command.dexer.Main$ClassParserTask.call(Main.java:1684
)
        at com.android.dx.command.dexer.Main.processClass(Main.java:749)
        ... 11 more
1 error; aborting

原因不明,大概是jdk版本不對,然后把baksmali.jar和dx.jar兩個包拷貝到ubuntu上,執行上述三個步驟,運行成功,ubuntu上安裝的jdk版本是1.7


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM