胡琪

为今天工作,为明天投资,为未来孵化一些东西!

smali语法及smali代码插桩

关于smali语法部分,网上已经有一些比较好的博客,本着不重复造轮子的原则就不做过多介绍,这是个人觉得写的不错的一个:http://www.cnblogs.com/pursuitofacm/p/6736830.html ,大家可以作为smali语法的了解资料。另外学习smali语法一个很重要的方法就是先写一个简单的android工程,然后将其dex反编译为smali文件,对照着阅读。这里重点介绍下smali代码插桩以及一些插桩smali代码后容易出现的一些错误。

Smali代码插桩

所谓Smali代码插桩就是指在其他app的smali文件中插入我们自己的代码的smali代码,从而能够在App运行时调用我们的代码,这在破解App时还是挺有用的一种方式,如当我们分析某个App运行逻辑不是很容易的时候,可以通过在某些关键点插入我们的打印log的Smali代码,从而获取某些关键信息。

为了实现smali代码插桩的功能,首先需要将某个App中的dex文件反编译为smali文件,然后在需要插入我们的代码的smali文件中插入实现自己某个功能的smali代码,如打印log,然后将修改后的smali文件回编译为dex文件,接着替换原先Apk中的dex文件,替换之后要对原apk进行重新签名才能安装运行,因为apk被修改后需要重新签名。

要实现将dex文件转换为smali文件需要用到一些工具,常见的工具包括apktool,baksmali.jar/smali.jar。这里推荐大家使用baksmali.jar/smali.jar,因为apktool是对整个apk进行操作,在实际使用过程中发现apktool在反编译apk时经常会出错,而baksmali.jar/smali.jar是对dex文件进行操作,很多使用apktool出错的apk使用baksmali.jar/smali.jar反编译dex文件不会出错,另一方面是因为apktool实际上也是集合了baksmali.jar/smali.jar的一种工具而已,也就是说apktool是依赖于baksmali.jar/smali.jar,但是apktool中使用的baksmali.jar/smali.jar版本可能不是目前最新版本,因此还是推荐大家直接使用baksmali.jar/smali.jar这两个工具。

这里是官网下载地址:https://bitbucket.org/JesusFreke/smali/downloads/  。

代码插桩基本上有三个点需要注意,第一个点就是在待插桩文件的何处插入比较合适,这个就要看具体的逻辑了,第二个点就是待插入的代码的smali代码应该如何表示,这个如果你对smali语法不是很熟,可以采用先写java代码,然后反编译为smali代码的方式。第三个点是容易犯的错误,就是插桩后寄存器数量的问题,很多情况下,将我们的smali代码插桩到原smali文件后,绝大多数情况下registers的数量是会改变的,在smali代码中每个方法开头声明了registers的数量,这个数量是参数寄存器和本地寄存器总和。而在绝大多数情况下我们要插入的smali代码中是会包含本地寄存器和参数寄存器的,因此smali代码插桩后要检查插桩后的函数使用的寄存器的数量是否增加,如果增加了要修改函数开头的registers的值为相应的值。

smali插桩后常见的错误

1java.lang.VerifyError

错误场景:完成代码插桩后重新签名apk运行出现如上错误

错误原因:这个通常是因为代码插桩后寄存器问题导致的,包括插桩后寄存器数量问题和寄存器内容修改问题。举个例子来说明大家会更容易理解:

假设需要在如上代码中插入我们的smali代码,假设待插入的smali代码如下:

将这代码片段2插入到代码片段1的.line 42下面,则需要将片段一开始的.register 2修改为.register 4,因为在我们片段2中新增加了v1和v2两个本地寄存器,所以需要修改函数开头的register值为4,否则运行时会出现java.lang.verifyerror。

另外如果代码片段2中使用到了代码片段1中已经定义的寄存器,而且修改了代码片段1中寄存器的内容可能也会出现这个问题。

打赏

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注