試題網址: http://www.shiyanbar.com/ctf/1871
0x01
首先我們得到了一個hello.dex文件,要把它反編譯為smali文件,使用工具baksmali,cmd命令: java -jar baksmali-2.0.3.jar -o class/ Hello.dex ,就在當前目錄下生成了一個文件夾,里邊有一個hello.smali 代碼如下:
.class public LHello;
.super Ljava/lang/Object;
.source "Hello.java"
# direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static main([Ljava/lang/String;)V
.registers 5
.prologue
.line 7
new-instance v0, LHello;
invoke-direct {v0}, LHello;-><init>()V
.line 8
sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; //v1存out對象的引用
const/4 v2, 0x5 //把5符號擴展32位賦值給v2
const/4 v3, 0x3 //把3符號擴展32位賦值給v3
invoke-virtual {v0, v2, v3}, LHello;->foo(II)I //調用函數foo
move-result v0 //把函數的結果賦值給v0
invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(I)V //打印輸出v0
.line 9
return-void
.end method
# virtual methods
.method public foo(II)I
.registers 5
.prologue
.line 3
add-int v0, p1, p2 // v0=p1+p2
sub-int v1, p1, p2 // v1=p1+p2
mul-int/2addr v0, v1 // v0=v0*v1
return v0
.end method。 于是便可以進行分析了.0x02
在這里首先稍微的科普一下,安卓程序都是由安卓虛擬機來運行的,Dalvik虛擬機有兩種不同的寄存器表示方法,p命名法還有v命名法,假如說一個函數fun()使用了5個寄存器,2個顯式的參數,并且這個方法是非靜態的方法,所以調用的時候會傳入一個隱式的fun對象引用,所以有三個參數,局部變量使用前2個寄存器,參數使用后3個,分別為v0,v1,v2,p0,p1,其中p0傳入對象的引用。
然后說下Dalvik字節碼的類型,方法還有字段表示方法:
1.類型:
V--void Z--boolean B--byte S--short C--char I--int F--float
D--double L--java類型 [--數組類型
其中java類型一般都是LpackageName/name/Objname 來表示具體的那個對象,如Ljava/lang/String相當于java.lang.String
2.方法:
Lpackage/name/Objname;->MethodName(III)Z
III表示三個整型參數,Z表示返回值是boolea型,
3.字段:
字段由類型、字段名、字段類型構成,字段名和字段類型之間使用:隔開
#instance fileds 實例字段
#static fields 靜態字段
一些基本語法:
.prologue 方法開始
invoke-direct 調用函數
return-void 函數返回void
.end method 函數結束
new-instance 創建實例
iput-object 對象賦值
iget-object 調用對象
所以最終返回結果 (5+3)*(5-3)=16
當然這里直接反編譯成jar然后反匯編為java代碼更容易看出來:
import java.io.PrintStream;
public class Hello
{
public static void main(String[] paramArrayOfString)
{
Hello localHello = new Hello();
System.out.println(localHello.foo(5, 3));
}
public int foo(int paramInt1, int paramInt2)
{
return (paramInt1 + paramInt2) * (paramInt1 - paramInt2);
}
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。