android 逆向工程-语言篇 Smali(三)
Android逆向工程篇:
- android 逆向工程-工具篇 drozer(一)
- android 逆向工程-工具篇 apktool(二)
- android 逆向工程-语言篇 Smali(三)
- android 逆向工程-分析篇 漏洞与风险(四)
- android 逆向工程-工具篇 dex2jar jd-gui(五)
- android 逆向工程-开发篇 apk加固(六)
- android 逆向工程-工具篇 IDA pro入门(七)
- android 逆向工程-技术篇 Android studio动态调试(八)
- android 逆向工程-工具篇 jadx(九)
数据类型
- B---byte
- C---char
- D---double
- F---float
- I---int
- J---long
- S---short
- V---void
- Z---boolean
- [XXX---array
- Lxxx/yyy---object
基本语法
.field private isFlag:z | 定义变量 |
.method | 方法 |
.parameter | 方法参数 |
.prologue | 方法开始 |
.line 12 | 此方法位于第12行 |
invoke-super | 调用父函数 |
const/high16 v0, 0x7fo3 | 把0x7fo3赋值给v0 |
invoke-direct | 调用函数 |
return-void | 函数返回void |
.end method | 函数结束 |
new-instance | 创建实例 |
iput-object | 对象赋值 |
iget-object | 调用对象 |
invoke-static | 调用静态函数 |
条件跳转分支:
if-eq vA, vB, :cond_** | 如果vA等于vB则跳转到:cond_** |
if-ne vA, vB, :cond_** | 如果vA不等于vB则跳转到:cond_** |
if-lt vA, vB, :cond_** | 如果vA小于vB则跳转到:cond_** |
if-ge vA, vB, :cond_** | 如果vA大于等于vB则跳转到:cond_** |
if-gt vA, vB, :cond_** | 如果vA大于vB则跳转到:cond_** |
if-le vA, vB, :cond_** | 如果vA小于等于vB则跳转到:cond_** |
if-eqz vA, :cond_** | 如果vA等于0则跳转到:cond_** |
if-nez vA, :cond_** | 如果vA不等于0则跳转到:cond_** |
if-ltz vA, :cond_** | 如果vA小于0则跳转到:cond_** |
if-gez vA, :cond_** | 如果vA大于等于0则跳转到:cond_** |
if-gtz vA, :cond_** | 如果vA大于0则跳转到:cond_** |
if-lez vA, :cond_** | 如果vA小于等于0则跳转到:cond_** |
smali文件格式
.class < 访问权限> [ 修饰关键字] < 类名>
.super < 父类名>
.source <源文件名>
MainActivity.smali展示
.class public Lcom/droider/crackme0502/MainActivity; //指令指定了当前类的类名。
.super Landroid/app/Activity; //指令指定了当前类的父类。
.source "MainActivity.java" //指令指定了当前类的源文件名。
smali文件中字段的声明使用“.field”指令。字段有静态字段与实例字段两种。静态字段的声明格式如下:
.field < 访问权限> static [ 修饰关键字] < 字段名>:< 字段类型>
实例字段的声明与静态字段类似,只是少了static关键字,它的格式如下:
.field < 访问权限> [ 修饰关键字] < 字段名>:< 字段类型>
比如以下的实例字段声明。
.field private btnAnno:Landroid/widget/Button; //私有字段
smali 文件中方法的声明使用“.method ”指令,方法有直接方法与虚方法两种。
.method <访问权限> [ 修饰关键字] < 方法原型>
<.locals> //指定了使用的局部变量的个数
[.parameter] //指定了方法的参数
[.prologue] //指定了代码的开始处,混淆过的代码可能去掉了该指令
[.line] //指定了该处指令在源代码中的行号
<代码体>
.end method
虚方法的声明与直接方法相同,只是起始处的注释为“virtual methods”,如果一个类实现了接口,会在smali 文件中使用“.implements ”指令指出,相应的格式声明如下:
.implements < 接口名> //接口关键字
如果一个类使用了注解,会在 smali 文件中使用“.annotation ”指令指出,注解的格式声明如下:
.annotation [ 注解属性] < 注解类名>
[ 注解字段 = 值]
.end annotation
注解的作用范围可以是类、方法或字段。如果注解的作用范围是类,“.annotation ”指令会直接定义在smali 文件中,如果是方法或字段,“.annotation ”指令则会包含在方法或字段定义中。例如:
.field public sayWhat:Ljava/lang/String; //String 类型 它使用了 com.droider.anno.MyAnnoField 注解,注解字段info 值为“Hello my friend”
.annotation runtime Lcom/droider/anno/MyAnnoField;
info = "Hello my friend"
.end annotation
.end field