用 Smali 手寫一個可運行的 HelloWorldK时搿I∏邸!

top

一、前言

Android 的 App 實際上并不是運行在 Java 虛擬機中唱较,而是運行在 Dalvik 虛擬機中扎唾。Dalvik 虛擬機對 Java 虛擬機做了一些額外的優(yōu)化,讓它更適用于移動設備南缓。而 Dalvik 也有自己獨特的匯編語言胸遇,Dalvik 就是通過這些匯編的指令集,來運行我們編譯好的 Apk 程序汉形。

一般這些內容纸镊,我們正常開發(fā) App 是接觸不到的,但是如果你有反編譯的需求概疆,那你就需要花點時間研究一下它逗威。本文不會介紹 Dalvik 的匯編指令集,它本身已經(jīng)有完備的文檔岔冀,沒什么好說的凯旭。

本文就從逆向思維的路子,教你如何寫一個可在 Dalvik 上獨立運行的 Hello World 程序使套。

在這個過程中罐呼,我們需要了解 smali 語法,smali 是一種寬松的 Jasmin/dedexer 語法侦高,它可以通過 baksmali 將我們已經(jīng)編譯好的 dex 格式的匯編語言弄贿,反匯編成 smali 文件,供我們閱讀矫膨。

那么,我們的第一個 Dalvik 版本的 Hello World 期奔,就從一個編寫一個 smali 文件開始吧侧馅。

二、開始編寫 Smali

既然是 smali 文件呐萌,當然是以 .smali 為文件后綴馁痴,這里先創(chuàng)建一個 SmaliHello.smali 文件,直接上代碼肺孤,再來看每行的含義罗晕。

smali-code

第 1~3 行,實際上是聲明了 smali 文件的頭赠堵,每個 smali 文件都會有它們小渊。.class 表示類名,這里定義了一個 public 的類茫叭,全類名是 com.cxmyDev.smalidemo.SmaliHelo酬屉。.super 表示它的父類,這里是 Object。.source 表示它對應的 Java 文件的文件名呐萨,這只是個標記杀饵,實際上在真實反編譯的場景下,如果代碼被混淆了谬擦,.source 可能會沒有值切距。

第 6 行,定義了一個 # direct methos 惨远,它是 baksmali 為我們添加的一行注釋谜悟,表示之后緊跟著這個類相對應的方法,需要注意的是锨络,只會包含構造方法和靜態(tài)方法赌躺,這里不展開討論了。

第 7~14 行羡儿,以一個 .method 開始礼患,.end 結尾,表示它是一個方法,而 publi constructor 表示它是一個公有的構造方法光羞,這里其實就是 Java 類默認的構造方法锻离,如果我們不聲明構造方法,編譯器會為我們創(chuàng)建一個?無參的構造方法肤粱,這里就是它了。沒啥好說的厨相,直接寫就好了领曼。

第 16~28 行,它也是一個方法蛮穿,public static 表示它是一個公有的靜態(tài)方法庶骄,方法名是 main。而之后緊跟的 ([LJava/lang/String;])V 表示它需要傳遞一個 String 數(shù)組践磅,并且返回值是 void单刁。再來看看方法內部的代碼,第 17 行府适,.registers 表示寄存器的聲明羔飞,這里聲明了 3 個寄存器,供后面使用檐春,.param 表示了方法傳遞的參數(shù)逻淌,參數(shù)名叫 args ,并且是一個 String 數(shù)組類型疟暖。.prologue 表示一個開場恍风,之后跟隨的才是我們業(yè)務邏輯的代碼。

第 21 行,sget-object 表示創(chuàng)建了一個 PrintStream 對象朋贬,并存入 v0 寄存器中凯楔。

第 23 行,const-string 表示什么了一個字符串 "Hello CxmyDev!"锦募,并存入 v1 寄存器中摆屯。

第 25行,invoke-virtual 表示調用了 PrintStream 中的 printIn() 方法糠亩,參數(shù)傳遞的是 v1 寄存器中的值虐骑,就是之前存儲的 "Hello CxmyDev!"。

到這里赎线,smali 中的代碼廷没,我們已經(jīng)逐行認清楚它是干嘛的了,有些細節(jié)就不展開講了垂寥,不了解的可以看看 Dalvik 的語法和 smali 的語法颠黎,有興趣可以先看看這兩個鏈接。

Dalvik-bytecode:

https://source.android.com/devices/tech/dalvik/dalvik-bytecode

Dex 格式:

https://source.android.com/devices/tech/dalvik/dex-format

三滞项、編譯 smali

編寫完 smali 代碼之后狭归,接下來就要將它編譯成 dex 文件了,這就需要用到 smali.jar 這個工具文判。你可以在 Bitbucket 上直接下載到 jar 包过椎。

https://bitbucket.org/JesusFreke/smali/downloads/

smali.jar 最新的版本版本是 2.2.1,所以這里下載這個版本就可以了戏仓。(不方便下載的話疚宇,文末有下載方式)

先來看看 smali.jar 的幫助文檔,直接使用 java -jar 命令即可赏殃。

smalijar-help

我們這里主要會用到它的 assemble 命令敷待,再來看看 assemble 的幫助文檔,使用 java -jar snali.jar a 命令即可查看嗓奢,aassemble 的縮寫。

smalijar-a-help

可以看到浑厚,使用 -o 就可以指定輸出的 dex 文件股耽,然后再指定編譯的 smali 文件即可。

java -jar smali-2.2.1.jar a -o hello.dex SmaliHello.smali 

執(zhí)行完成钳幅,如果沒有報錯的話物蝙,可以在當前目錄下,生成一個 hello.dex 文件敢艰。如果有其它輸出诬乞,應該就是報錯了,查看一下報錯信息解決它就好了。

得到 hello.dex 文件之后震嫉,我們還需要將它放到我們的 Android 設備上森瘪,才可以運行,這個非常簡單票堵,使用 adb push 命令即可扼睬。

最終運行這個 dex 文件,還需要使用到 dalvikvm 悴势,使用 adb shell dalvikvm -h 命令窗宇,查看幫助文檔,文檔比較長特纤,這里截取關鍵部分军俊。

dalvik-help

這里我們主要是使用 -cp 指定 classpath 即可執(zhí)行,它后續(xù)接收的是類的完整簽名捧存,包含包名粪躬。

然后我們就需要使用 dalvikvm -cp 命令即可執(zhí)行,主要指定要執(zhí)行的類矗蕊,需要包含包名的全類名短蜕。

smali-run

這里,就可以輸出我們之前編寫的 Hello CxmyDev! 了傻咖。

下面?zhèn)浞菀幌螺斎氲拿睢?/p>

adb shell push hello.dex /sdcard/
adb shell dalvikvm -cp /sdcard/hello.dex com.cxmydev.smalidemo.SmaliHello 

四朋魔、Dex 的 Java 代碼

到這里就算是將清楚,從零編寫一個 smali 代碼卿操,到編譯成 dex 并成功執(zhí)行的所有過程了警检。

我們再來看看,我們編輯的 smali 代碼害淤,到底用 Java 代碼編寫扇雕,是什么內容,可以幫助我們更好的理解它窥摄。

其實很簡單镶奉,再使用 jadx 工具,對 dex 進行反編譯崭放。因為我們這里也不涉及混淆哨苛,所以代碼結構非常的清晰。

java-code

這里就是初學 Java 的時候币砂,一個標準的 Java 程序建峭,有個 main 函數(shù)為程序的入口函數(shù)。

五决摧、小結

本文到這里就算是完成了整個逆向的反逆向流程亿蒸,相信能讓你加深對反編譯和 smali 的理解凑兰。

有些工具如果不方便下載(原因你懂的),可以在承香墨影公眾號回復 smali工具 進行下載边锁,可以下載到本文所有涉及到的資源文件姑食。

更多反編譯的細節(jié),可以在承香墨影公眾號回復 Android反編譯砚蓬,你將獲得我整理好的一些關于反編譯的資料矢门。

今天在承香墨影公眾號的后臺,回復 成長灰蛙。我會送你一些我整理的學習資料祟剔,包含:Android反編譯、算法摩梧、設計模式物延、Web項目源碼。

推薦閱讀:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市滨砍,隨后出現(xiàn)的幾起案子往湿,更是在濱河造成了極大的恐慌,老刑警劉巖惋戏,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件领追,死亡現(xiàn)場離奇詭異,居然都是意外死亡日川,警方通過查閱死者的電腦和手機蔓腐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門矩乐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來龄句,“玉大人回论,你說我怎么就攤上這事》中” “怎么了傀蓉?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長职抡。 經(jīng)常有香客問我葬燎,道長,這世上最難降的妖魔是什么缚甩? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任谱净,我火速辦了婚禮,結果婚禮上擅威,老公的妹妹穿的比我還像新娘壕探。我一直安慰自己,他們只是感情好郊丛,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布李请。 她就那樣靜靜地躺著,像睡著了一般厉熟。 火紅的嫁衣襯著肌膚如雪导盅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天揍瑟,我揣著相機與錄音白翻,去河邊找鬼。 笑死月培,一個胖子當著我的面吹牛嘁字,可吹牛的內容都是我干的。 我是一名探鬼主播杉畜,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼纪蜒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了此叠?” 一聲冷哼從身側響起纯续,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灭袁,沒想到半個月后猬错,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡茸歧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年倦炒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片软瞎。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡逢唤,死狀恐怖拉讯,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情鳖藕,我是刑警寧澤魔慷,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站著恩,受9級特大地震影響院尔,放射性物質發(fā)生泄漏。R本人自食惡果不足惜喉誊,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一邀摆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧伍茄,春花似錦隧熙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至沪饺,卻和暖如春躏敢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背整葡。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工件余, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遭居。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓啼器,卻偏偏與公主長得像,于是被迫代替她去往敵國和親俱萍。 傳聞我的和親對象是個殘疾皇子端壳,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內容