承接上一篇文章,简略了解了APK的解包重打包流程,这一篇不介绍Smali的详细语法,只是简略介绍下如何对解包后的Smali代码进行修正/刺进代码,以到达测验(修正)代码的意图.
本教程纯学习意图,绝无唆使念头!!
Smali
根据百度百科解释:Smali,Baksmali分别是指安卓系统里的Java虚拟机(Dalvik)所运用的一种.dex格式文件的汇编器,反汇编器.其语法是一种宽松式的Jasmin/dedexer语法,而且它实现了.dex格式所有功用(注解,调试信息,线路信息等).也便是说解包后的Smali文件,用文本翻开后看到的代码指令,便是虚拟机履行的详细的指令.
测验项目
很简略,便是屏幕中间显现一个Text: 用上一篇文章的解包办法对APK进行解包,查看到Smali代码如下:
其中,.param
,.line
都是用作调试信息,能够删去.
修正
可见,在show办法中,我直接传入了false
使得运行时显现了’Hello Android‘.现在对Smali进行修正,使其显现Hello World.
修正show办法
在show办法中,true
时显现’Hello World’,false
时显现’Hello Android’,那么咱们能够把true
和false
的逻辑转换一下,就能够使得传入false
时显现’Hello World’了.修正后的show办法如下:
这儿我把if-eqz
改成了if-nez
,表明假如参数是true
(if not equal zero),就跳转到:cond_5
处,不然履行下一行代码.那么咱们传入的false
明显为0,所以不进行跳转,直接履行下一行,返回’Hello World’
修正入参
有时一个办法或许很多当地调用,修正办法的影响会很大,那么咱们能够直接修正调用时的入参,传入true
:
这儿把0修正成了1,也便是把false
修正成了true
,那么就能够根据show办法逻辑返回’Hello World’了
修正show办法返回值
这种办法便是把输入false
时的’Hello Android’改成’Hello World’,不推荐.
直接赋值’Hello World’
这种办法不进行show办法调用了,能够删去这一行,把v3寄存器直接赋予一个字符串常量’Hello World’:
这儿我把办法2中的那4行全删了,添加了这一行.当然关于这种办法,想输出什么就输出什么字符串.
这4种办法效果相同,如下:
刺进
上一步是对代码的修正,这一步介绍下代码的刺进.
刺进指令
平常要对apk进行调试时,最希望刺进的便是Log了,这儿咱们试着在show办法中刺进一个Log看看.在show办法最初刺进指令:
从头打包装置,翻开应用后能够看到如下日志输出:
这儿有一点需求留意:在这show办法中,我不仅刺进了日志输出指令,还把.locals 1
改成了.locals 2
,.locals
表明本地寄存器的数量,不包括参数寄存器数量.在之前,只需求运用寄存器v0,所以这儿只需求1个本地寄存器.而现在不仅需求运用v0,还用到了v1,那么就需求两个本地寄存器,所以改成了2.当然假如需求运用v2,或许v3,防止程序运行时出错,这儿数值就需求改成3,4.不然或许会报以下错误:
详细还得看寄存器数量的计算规矩,总寄存器数量=参数寄存器数量+本地寄存器数量.假如要运用的寄存器大于这个值,运行就会出错.
刺进Smali文件
有时或许需求刺进一段代码或一段逻辑,那么能够将这段代码独自编译成Smali后,直接放入smali_classes文件夹下,在再需求刺进的当地进行调用即可.如下,在show办法中刺进仓库调用的打印逻辑
运用java2Smali插件将文件转换成Smali指令的文件后,再将此Smali文件放到smali_classes文件下(放哪都行),留意这儿需求翻开此文件,修正包名,最好全局查找,将全部包名替换成现在放入的包名.然后开端刺进代码:
很简略,刺进一行stati调用的代码即可,从头打包,翻开项目后查看日志:
就能够把当前办法的调用仓库打印出来了
刺进办法
能够把上一步生成的Smali指令的办法直接复制到需求刺进的文件的当地,然后在这个文件中待刺进的办法中调用这个新刺进的办法即可,这儿也需求留意修正包名.
结束
到此,Smali的增修正(删没细讲,在’直接赋值’的办法中一笔带过了,由于上层语言中,一条代码,对应的汇编指令会有多条,所以删去需谨慎)办法就讲完了,在其他便是靠我们自行学习对Smali指令的进一步了解和熟悉了.
坑
- 假如需求添加本地寄存器的运用,最好修正
.locals
的数值 - 刺进文件,刺进函数,以及对函数的调用时,需留意对包名的修正
- 在运用
long
和double
类型的变量时,需求运用两个寄存器.比如赋值时运用的是v1,那么运用时需求用到v1,v2.这个能够自行先写Java代码,再转换成Smali指令仔细看看.