copy : https://blog.csdn.net/u012573920/article/details/44034397

1.Smali简介

Smali是Dalvik的寄存器语言,它与Java的关系,简单理解就是汇编之于C。假如你对汇编有足够的驾驭能力,那你可以通过修改汇编代码来改变C/C++代码的走向。当然,学过汇编的都清楚,汇编比BrainFuck还难学,更不用说去反编译修改了。

但是Smali有一点不一样,就是它很简单,只有一点点的语法,只要你会java,了解Android的相关知识,那你完全可以通过修改Smali代码来反向修改java代码,虽然绕了一点,但是在某些情况下你不得不这么做。还好,Smali很简单。

2.apktool

说了这么多,还没有说Smali哪来?没错。Smali代码是安卓APK反编译而来的,所以Smali文件和Java文件一一对应。获取Smali文件,我们需要下载一个辅助工具:ApkTool。apktool这个命令行工具如果详细使用功能参数是比较多的,但是这里我们只需要用到2个最基础的功能:

一个是反编译decode:

apktool d xxx.apk

另一个是打包build:

apktool b

这里要注意的是路径问题,apktool如果没有加入到环境变量中,记得cd到apktool的目录去使用它。另一个是打包,如果只是简单的使用参数b,那要求是要在反编译出来的项目目录下执行,而打包好的文件会保存在这个项目目录下的dist目录。

这是一个HelloWorld的应用程序反编译和打包的目录结构:

3.Smali语法

(1)数据类型

dalvik字节码有两种类型,原始类型和引用类型。对象和数组是引用类型,其它都是原始类型。

smali数据类型都是用一个字母表示,如果你熟悉Java的数据类型,你会发现表示smali数据类型的字母其实是Java基本数据类型首字母的大写,除boolean类型外,在smail中用大写的”Z”表示boolean类型。

V void,只能用于返回值类型
Z boolean
B byte
S short
C char
I int
J long (64 bits)
F float
D double (64 bits)

 对象以Lpackage/name/ObjectName;的形式表示。前面的L表示这是一个对象类型,package/name/是该对象所在的包,ObjectName是对象的名字,“;”表示对象名称的结束。相当于java中的package.name.ObjectName。

例如:Ljava/lang/String;相当于java.lang.String

数组的表示形式

[I——表示一个整型一维数组,相当于java中的int[]。对于多维数组,只要增加[就行了。[[I相当于int[][],[[[I相当于int[][][]。注意每一维的最多255个。

 对象数组的表示

[Ljava/lang/String;表示一个String对象数组。

(2)方法

方法通常必须详细的指定方法类型(?the type that contains the method) 方法名,参数类型,返回类型,所有这些信息都是为虚拟机是能够找到正确的方法并执行。

方法表示形式:Lpackage/name/ObjectName;->MethodName(III)Z

在上面的例子中,Lpackage/name/ObjectName;表示类型,MethodName是方法名。III为参数(在此是3个整型参数),Z是返回类型(bool型)。

方法的参数是一个接一个的,中间没有隔开。

一个更复杂的例子:method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;

在java中则为:String method(int, int[][], int, String, Object[])

一个比较全面的例子:

.class public interface abstract Lcom/kit/network/CachableImage;
.super Ljava/lang/Object;
.source "SourceFile" # virtual methods
.method public abstract getIsLarge()Z
.end method .method public abstract getUrl()Ljava/lang/String;
.end method .method public abstract getViewContext()Landroid/content/Context;
.end method .method public abstract setBitmap(Landroid/graphics/Bitmap;Z)V
.end method .method public abstract setIsLarge(Z)V
.end method .method public abstract setUrl(Ljava/lang/String;)V
.end method

上面的smali代码还原后的java代码为:



(3)字段

表示形式:Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;即包名,字段名和各字段类型。 eg:



这里仍然以一个默认的HelloWorld的应用程序进行解释吧。新建一个HelloWorld安卓项目,在MainActivity中只保留onCreate函数。代码如下:

package com.fusijie.helloworld;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

 

反编译后的Smali文件如下:


对比一下,可以比较清楚的看出来,smali代码其实就是对java代码一个翻译,只是没有java看起来那么简单,smali把很多应该复杂的东西还原成复杂的状态了。简单解释下这段代码。

  • 前三行指明了类名,父类名,和源文件名。
  • 类名以“L”开头相信熟悉Jni的童鞋都比较清楚。
  • “#”是smali中的注释。
  • “.method”和“.end method”类似于Java中的大括号,包含了方法的实现代码段。
  • 方法的括号后面指明了返回类型,这同样类似与Jni的调用。
  • “.locals”指明了这个方法用到的寄存器数量,当然寄存器可以重复利用,从“V0”起算。
  • “.prologue”指定了代码开始处。
  • “.line”表明这是在java源码中的第几行,其实这个值无所谓是多少,可以任意修改,主要用于调试。
  • “invoke-direct”这是对方法的调用,可以看到这里调用了是Android.app.Activity的init方法,这在java里是隐式调用的。
  • “return-void”表明了返回类型,这和java不一样,即使没有返回值,也需要这样写。
  • 接下来是onCreate方法,“.parameter”指明了参数名,但是一般没有用,需要注意的是p0代表的是this,p1开始代表函数参数,静态函数没有this,所以从p0开始就代表参数。
  • 在实现里先是调用了父类的方法,然后再调用setContentView,注意这里给了一个传参。整形的传参,这个值是先赋给寄存器v0,然后再调用的使用传递进去的。smali中都是这么使用,所有的值必须通过寄存器来中转。这点和汇编很像。

对比了Java代码和Smali代码,可以很清楚的看到,原本只有几行的代码到了Smali,内容被大大扩充了。Smali还原了Java隐藏的东西,同时显式地指定了很多细节。这还只是个最基本的HelloWorld的onCreate函数,如果有内部类,还会分文件显示。

这样看来,其实Smali只能说复杂,不能说难。如果想全面了解smali语法,这里给出几个链接,算是总结的相对好一点的(其实我都没看到有系统总结的。。。如果你有好的资料,欢迎跟帖分享)

这里顺便提供2个利器:

从上面一个例子对Smali的用途就很清楚了,没错,Smali注入。现在常见的除了测试以外的用途,Smali注入明显是带有黑客性质的,小的如破解游戏,替换游戏广告,大的甚至利用漏洞去破解密码,偷窃个人资料,财产等等。对Smali,安卓逆向分析,安卓系统安全比较清楚的,这些事其实都不算事。

[Android Security] Smali和逆向分析的更多相关文章

  1. Android应用安全防护和逆向分析 ——apk反编译

    概述 最近一直在学习Android应用安全相关和逆向分析的知识.现在移动app在安全方面是越来越重视了,特别是那些巨头企业涉及到钱的应用,那加密程度,简直是丧心病狂,密密麻麻.从这里可以看出,对于应用 ...

  2. 阿里早期Android加固代码的实现分析

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78320445 看雪上有作者(寒号鸟二代)将阿里移动早期的Android加固进行了逆 ...

  3. Android逆向分析工具表

    逆向分析工具表 工具 描述 网址 androidterm Android Terminal Emulator http://code.google.com/p/androidterm/ droidbo ...

  4. Android无需权限显示悬浮窗, 兼谈逆向分析app

    前言 最近UC浏览器中文版出了一个快速搜索的功能, 在使用其他app的时候, 如果复制了一些内容, 屏幕顶部会弹一个窗口, 提示一些操作, 点击后跳转到UC, 显示这个悬浮窗不需要申请android. ...

  5. 从Android设备中提取内核和逆向分析

    本文博客链接:http://blog.csdn.net/qq1084283172/article/details/57074695 一.手机设备环境 Model number: Nexus 5 OS ...

  6. Android开发学习之路--逆向分析反编译

      一般情况下我们想要了解别人的app怎么实现这个动画,这个效果的时候,总是会想到反编译一下,看下布局,看下代码实现.对,这对于有经验的玩家确实手到擒来了,但是初学者,根本就不知道怎么反编译,怎么看代 ...

  7. Android逆向分析(2) APK的打包与安装背后的故事

    前言 上一次我们反编译了手Q,并遇到了Apktool反编译直接crash的问题,虽然笔者很想在这次解决这个问题,但在解决途中,发现该保护依赖于很多知识,所以本次先插入一下,正所谓知其然知其所以然,授之 ...

  8. Android逆向分析(2) APK的打包与安装

    http://blog.zhaiyifan.cn/2016/02/13/android-reverse-2/ 2/18日增加对aidl和java编译的描述. 前言 上一次我们反编译了手Q,并遇到了Ap ...

  9. [Android Security] 静态分析Android程序——smali文件解析

    cp : https://blog.csdn.net/hp910315/article/details/51823236 cp : http://www.jb51.net/softjc/119036. ...

随机推荐

  1. MySQL 中国省市区SQL表数据

    MySQL 中国省市区SQL表数据   1.查省SELECT * FROM china WHERE china.Pid=02.查市SELECT * FROM chinaWHERE china.Pid= ...

  2. JAVAEE——宜立方商城13:Mycat数据库分片、主从复制、读写分离、100%Linux中成功安装Mysql的方法

    1 海量数据的存储问题 如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求.这个时候NoSQL ...

  3. spring 状态机

    前言:“状态机”见名知意,用状态去管理业务操作,打个比方:0~1岁(出生状态),1~3岁(认知状态),3~6岁(启蒙状态),6~22岁(学习状态),22~60(工作状态),60以后(退休状态),那么人 ...

  4. Bzoj2534:后缀自动机 主席树启发式合并

    国际惯例的题面:考虑我们求解出字符串uvu第一个u的右端点为i,第二个u的右端点为j,我们需要满足什么性质?显然j>i+L,因为我们选择的串不能是空串.另外考虑i和j的最长公共前缀(也就是说其p ...

  5. 菜鸟nginx源码剖析

    菜鸟nginx源码剖析 配置与部署篇(一) 手把手配置nginx "I love you" TCMalloc 对MYSQL 性能 优化的分析 菜鸟nginx源码剖析系列文章解读 A ...

  6. BZOJ4254 : Aerial Tramway

    可以修建的缆车总数不超过n,于是可以先通过$O(n^2)$的枚举求出所有可以修建的缆车. 对于一个缆车,若它仅连接i和i+1,那么它不受k的限制,把这种缆车额外取出,从大到小排序. 剩下的缆车两两之间 ...

  7. java判断集合是否重复的一种便捷方法

    内容来自其它网站,感谢原作者! import java.util.ArrayList; import java.util.HashSet; import java.util.List; /** * 通 ...

  8. 【转】InitializingBean的作用

    原文链接:http://blog.csdn.net/maclaren001/article/details/37039749 最近工作需要得到sping中的每个事物需要执行的sql,称机会简单研究了一 ...

  9. 使用 IntraWeb (7) - 主模板

    TIWLayoutMgrHTML.TIWTemplateProcessorHTML 属于页面级的模板, 如果要全站统一模板, 当然要用主模板. TIWTemplateProcessorHTML 通过其 ...

  10. 关于MongoDB时区问题

    由于MongoDb存储时间按照UTC时间存储的,其官方驱动MongoDB.driver存储时间的时候将本地时间转换为了utc时间,但它有个蛋疼的bug,读取的时候非常蛋疼的是返回的是utc使时间.一个 ...