用 Smali 手写一个可运行的 HelloWorld!!!

top

一、前言

Android 的 App 实际上并不是运行在 Java 虚拟机中,而是运行在 Dalvik 虚拟机中。Dalvik 虚拟机对 Java 虚拟机做了一些额外的优化,让它更适用于移动设备。而 Dalvik 也有自己独特的汇编语言,Dalvik 就是通过这些汇编的指令集,来运行我们编译好的 Apk 程序。

一般这些内容,我们正常开发 App 是接触不到的,但是如果你有反编译的需求,那你就需要花点时间研究一下它。本文不会介绍 Dalvik 的汇编指令集,它本身已经有完备的文档,没什么好说的。

本文就从逆向思维的路子,教你如何写一个可在 Dalvik 上独立运行的 Hello World 程序。

在这个过程中,我们需要了解 smali 语法,smali 是一种宽松的 Jasmin/dedexer 语法,它可以通过 baksmali 将我们已经编译好的 dex 格式的汇编语言,反汇编成 smali 文件,供我们阅读。

那么,我们的第一个 Dalvik 版本的 Hello World ,就从一个编写一个 smali 文件开始吧。

二、开始编写 Smali

既然是 smali 文件,当然是以 .smali 为文件后缀,这里先创建一个 SmaliHello.smali 文件,直接上代码,再来看每行的含义。

smali-code

第 1~3 行,实际上是声明了 smali 文件的头,每个 smali 文件都会有它们。.class 表示类名,这里定义了一个 public 的类,全类名是 com.cxmyDev.smalidemo.SmaliHelo.super 表示它的父类,这里是 Object。.source 表示它对应的 Java 文件的文件名,这只是个标记,实际上在真实反编译的场景下,如果代码被混淆了,.source 可能会没有值。

第 6 行,定义了一个 # direct methos ,它是 baksmali 为我们添加的一行注释,表示之后紧跟着这个类相对应的方法,需要注意的是,只会包含构造方法和静态方法,这里不展开讨论了。

第 7~14 行,以一个 .method 开始,.end 结尾,表示它是一个方法,而 publi constructor 表示它是一个公有的构造方法,这里其实就是 Java 类默认的构造方法,如果我们不声明构造方法,编译器会为我们创建一个�无参的构造方法,这里就是它了。没啥好说的,直接写就好了。

第 16~28 行,它也是一个方法,public static 表示它是一个公有的静态方法,方法名是 main。而之后紧跟的 ([LJava/lang/String;])V 表示它需要传递一个 String 数组,并且返回值是 void。再来看看方法内部的代码,第 17 行,.registers 表示寄存器的声明,这里声明了 3 个寄存器,供后面使用,.param 表示了方法传递的参数,参数名叫 args ,并且是一个 String 数组类型。.prologue 表示一个开场,之后跟随的才是我们业务逻辑的代码。

第 21 行,sget-object 表示创建了一个 PrintStream 对象,并存入 v0 寄存器中。

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

第 25行,invoke-virtual 表示调用了 PrintStream 中的 printIn() 方法,参数传递的是 v1 寄存器中的值,就是之前存储的 "Hello CxmyDev!"。

到这里,smali 中的代码,我们已经逐行认清楚它是干嘛的了,有些细节就不展开讲了,不了解的可以看看 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 

执行完成,如果没有报错的话,可以在当前目录下,生成一个 hello.dex 文件。如果有其它输出,应该就是报错了,查看一下报错信息解决它就好了。

得到 hello.dex 文件之后,我们还需要将它放到我们的 Android 设备上,才可以运行,这个非常简单,使用 adb push 命令即可。

最终运行这个 dex 文件,还需要使用到 dalvikvm ,使用 adb shell dalvikvm -h 命令,查看帮助文档,文档比较长,这里截取关键部分。

dalvik-help

这里我们主要是使用 -cp 指定 classpath 即可执行,它后续接收的是类的完整签名,包含包名。

然后我们就需要使用 dalvikvm -cp 命令即可执行,主要指定要执行的类,需要包含包名的全类名。

smali-run

这里,就可以输出我们之前编写的 Hello CxmyDev! 了。

下面备份一下输入的命令。

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

四、Dex 的 Java 代码

到这里就算是将清楚,从零编写一个 smali 代码,到编译成 dex 并成功执行的所有过程了。

我们再来看看,我们编辑的 smali 代码,到底用 Java 代码编写,是什么内容,可以帮助我们更好的理解它。

其实很简单,再使用 jadx 工具,对 dex 进行反编译。因为我们这里也不涉及混淆,所以代码结构非常的清晰。

java-code

这里就是初学 Java 的时候,一个标准的 Java 程序,有个 main 函数为程序的入口函数。

五、小结

本文到这里就算是完成了整个逆向的反逆向流程,相信能让你加深对反编译和 smali 的理解。

有些工具如果不方便下载(原因你懂的),可以在承香墨影公众号回复 smali工具 进行下载,可以下载到本文所有涉及到的资源文件。

更多反编译的细节,可以在承香墨影公众号回复 Android反编译,你将获得我整理好的一些关于反编译的资料。

今天在承香墨影公众号的后台,回复 成长。我会送你一些我整理的学习资料,包含:Android反编译、算法、设计模式、Web项目源码。

推荐阅读:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容