[Android Security] Smali和逆向分析

本文详细介绍Smali语言的基础概念,包括其与Java的关系、语法特点、数据类型、方法及字段表示等,并通过具体示例帮助读者理解Smali在Android应用反编译与重构中的作用。

copy : https://blog.youkuaiyun.com/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类型。

Vvoid,只能用于返回值类型
Zboolean
Bbyte
Sshort
Cchar
Iint
Jlong (64 bits)
Ffloat
Ddouble (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代码为:

 
 
//#注:在实际代码中我们还必须引入相关的包  
import android.content.Context;  
import android.graphics.Bitmap;  
  
public interface CachableImage {  
  
    public abstract boolean getIsLarge();  
  
    public abstract String getUrl();  
  
    public abstract Context getViewContext();  
  
    public abstract void setBitmap(Bitmap bitmap);  
  
    public abstract void setIsLarge(boolean islarge);  
  
    public abstract void setUrl(String url);  
}  

  

 
 

 (3)字段

 

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

 
 
.field private _requestLayout:Z  
  
.field public isLarge:Z  
  
.field public resize:Z  
  
.field public thumbnailSize:I  
  
.field public url:Ljava/lang/String;  

  

还原后的java代码为:
 
 
public boolean _requestLayout;  
public boolean isLarge;  
public boolean resize;  
public int thumbnailSize;  
public String url;  

  

这里仍然以一个默认的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文件如下:

 
 
.class public Lcom/fusijie/helloworld/MainActivity;  
.super Landroid/app/Activity;  
.source "MainActivity.java"  
# direct methods  
.method public constructor ()V  
  .locals 0  
  .prologue  
  .line 14  
  invoke-direct {p0}, Landroid/app/Activity;->()V  
  return-void  
.end method  
# virtual methods  
.method protected onCreate(Landroid/os/Bundle;)V  
  .locals 1  
  .parameter "savedInstanceState"  
  .prologue  
  .line 18  
  invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V  
  .line 19  
  const/high16 v0, 0x7f03  
  invoke-virtual {p0, v0}, Lcom/fusijie/helloworld/MainActivity;->setContentView(I)V  
  .line 20  
  return-void  
.end method  

 

对比一下,可以比较清楚的看出来,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,安卓逆向分析,安卓系统安全比较清楚的,这些事其实都不算事。

<think>嗯,用户问的是关于AKP逆向工程分析,零基础怎么学习。首先得弄清楚AKP是什么。可能是指Android应用程序包(APK)吧,用户可能打错了。如果是APK逆向工程的话,那确实是移动安全分析的重要部分。用户零基础,可能需要从基础开始讲起。 首先,用户需要了解APK文件的结构。APK其实是Zip压缩格式,包含资源、代码等。需要解释如何解压查看里面的内容,比如AndroidManifest.xml、classes.dex等。然后,可能需要提到反编译工具,比如apktool、dex2jar、JD-GUI这些,这些工具的使用方法应该简单介绍一下。 接下来是分析逆向后的代码,可能需要了解Smali语言,这是Dalvik的字节码,用户需要学习如何阅读修改。不过零基础的话,这部分可能会有点难度,所以需要推荐一些学习资源,比如在线教程或者书籍。 然后,动态分析也很重要,用户可能需要使用像Android Studio的模拟器,或者真机调试,配合Frida、Xposed这样的工具进行动态hook调试。这部分需要一定的编程基础,特别是JavaAndroid开发的知识,所以可能需要建议用户先学一些基础的编程。 用户零基础的话,学习路径可能需要分步骤:先学JavaAndroid开发基础,再学APK结构,然后工具使用,接着静态动态分析,最后实际案例练习。同时,法律道德问题也要提醒,避免用户进行非法的逆向工程。 可能还需要推荐一些社区资源,比如XDA论坛、GitHub上的开源项目,或者一些在线课程平台,比如Udemy、Coursera上的相关课程。另外,实践项目很重要,用户需要自己动手分析一些简单的APK,逐步提升技能。 还要考虑到用户可能遇到的问题,比如环境配置困难,工具使用复杂,这时候需要建议他们查阅官方文档,或者加入相关的论坛社群寻求帮助。另外,逆向工程需要耐心细致,错误是常有的,所以鼓励用户多练习,不要气馁。 最后,总结一下学习步骤,强调基础的重要性,逐步进阶,结合理论实践,同时注意合法性。这样用户应该能有一个清晰的学习路线图了。</think>### AKP(APK)逆向工程与分析:零基础学习指南 --- #### **1. 基本概念** - **APK 是什么?** APK(Android Package Kit)是 Android 应用的安装包文件,包含代码(`.dex` 文件)、资源(图片、布局等)、配置文件(`AndroidManifest.xml`)等。 - **逆向工程的目标** 通过反编译、调试分析 APK,了解其功能、逻辑、潜在漏洞或实现原理,常见于安全研究、漏洞挖掘、二次开发等场景。 --- #### **2. 学习路径(零基础入门)** ##### **第一步:基础准备** 1. **编程基础** - **Java/Kotlin**:Android 开发的主要语言,需掌握基本语法面向对象思想。 - **Smali 语言**:Dalvik 虚拟机的汇编语言,用于直接修改反编译后的代码([Smali 语法入门](https://blog.youkuaiyun.com/qq_33210042/article/details/120615057))。 2. **Android 开发基础** - 学习 Android 应用的组成(Activity、Service、BroadcastReceiver 等)。 - 推荐书籍:《第一行代码》(郭霖著)。 3. **工具与环境** - **Android Studio**:用于开发分析 APK。 - **Java 环境(JDK)**:运行反编译工具。 - **模拟器/真机调试**(如夜神模拟器、ADB 工具)。 --- ##### **第二步:静态分析** 1. **解包 APK** - 使用工具 **Apktool**: ```bash apktool d your_app.apk -o output_dir ``` - 得到资源文件、`AndroidManifest.xml` Smali 代码。 2. **反编译代码** - **dex2jar**:将 `.dex` 转换为 `.jar` 文件。 - **JD-GUI** 或 **Luyten**:查看 `.jar` 中的 Java 代码(可能混淆)。 3. **分析关键文件** - `AndroidManifest.xml`:查看权限、入口 Activity、服务等。 - `res/values/strings.xml`:提取硬编码的敏感信息。 --- ##### **第三步:动态分析** 1. **调试与监控** - **Frida**:动态注入工具,可 Hook 方法、修改内存数据([Frida 官方文档](https://frida.re/))。 - **Xposed**:通过模块 Hook 系统函数(需 Root)。 - **Logcat**:查看应用日志,定位关键逻辑。 2. **网络抓包** - **Charles** 或 **Wireshark**:监控应用网络请求,分析 API 接口加密方式。 --- ##### **第四步:进阶技能** 1. **对抗混淆与加固** - 学习反混淆工具(如 **deGuard**)脱壳技术(针对主流加固方案如腾讯乐固、梆梆加固)。 - 分析 Native 层代码(`.so` 文件)需掌握 **IDA Pro** 或 **Ghidra**。 2. **自动化分析** - 使用 **MobSF**(Mobile Security Framework)自动化扫描漏洞(如硬编码密钥、组件暴露)。 --- #### **3. 工具清单** | 工具名称 | 用途 | |----------------|-----------------------------| | Apktool | 解包 APK,生成 Smali 代码 | | JADX | 直接反编译 APK 为 Java 代码 | | Frida | 动态调试与 Hook | | IDA Pro/Ghidra | 分析 Native 层(.so 文件) | | Burp Suite | 抓包与网络漏洞测试 | --- #### **4. 学习资源** - **书籍** - 《Android 软件安全与逆向分析》(丰生强著) - 《Frida Android SO Reverse》 - **在线课程** - B 站:搜索“Android 逆向”系列教程(如“逆小风”)。 - Udemy:*Android Reverse Engineering 101*。 - **社区** - 看雪论坛(https://www.kanxue.com/) - GitHub 开源项目(如《Android Security》仓库)。 --- #### **5. 法律与道德** - **合法合规**:仅分析自己拥有权限的应用,避免侵犯他人知识产权。 - **测试授权**:渗透测试需获得书面授权,避免法律风险。 --- **总结**:从学习 Java Android 开发开始,逐步掌握静态/动态分析工具,通过实战项目(如破解 CTF 题目、分析开源 APK)提升技能。逆向工程需要耐心积累,建议从简单应用入手(如未加固的小工具),逐步挑战复杂目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值