Android逆向工程:详细讲解smali语法,手把手带你分析语句!

最近开始了Android逆向工程和反编译的学习和实战,众所周知Android逆向工程首当其冲的拦路虎就是smali语法。反编译还是比较简单,毕竟目前有很多优秀的反编译软件,都可以轻松的把APK给反编译掉,但是反编译后出现的smali文件却不是这么的轻松,毕竟一大堆的代码让你看的懵逼,不熟悉smali语法的人绝对撑不过三秒钟就会关掉页面!

可能你会去网上查smali语法的相关知识,然而看了规则你回来试着分析一个smali文件依旧一头雾水,感觉无法下手。那么今天我就带大家来细致的分析一篇smali文件,真正的手把手带你,争取分析的时候你能轻松应对大多数的smali文件的分析工作。

关于什么是smali语法已经它的背景我就不做出介绍了,有兴趣的同学可以自行搜索,这里主要带大家去分析一篇smali文件。本文适合小白类型的同学阅读观看,资深玩家亦可阅读,指出文中错误本人感激不尽!

鉴于大家初次接触smali语法,所以我这里选择了一篇逻辑中等,代码适中的smali文件,这是从我自己项目中选择的一篇,我不会上来给大家一大堆的语法知识,相信你也看不清楚,我推崇实践中学习,所以我这里亲自分析了四百多行的smali文件,每一行代码我都标注了相应的语法解析,看完后相信你就对smali语法理解的差不多了。

废话少说,这里我先贴上源码:

package com.shanzha.changmodel.clearfile;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.shanzha.changmodel.Adapter.HiddenAdapter;
import com.shanzha.changmodel.MainActivity;
import com.shanzha.changmodel.been.AppTape;
import com.shanzha.changmodel.been.PackageModel;
import com.shanzha.changmodel.parsenter.PackageParsenter;
import com.shanzha.changmodel.parsenter.RootCmd;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 王将 on 2018/8/8.
 */

public abstract class AppActivity extends Activity implements View.OnClickListener,TextWatcher {

    public ProgressDialog progressDialog;
    public RecyclerView recyclerView;
    public HiddenAdapter hiddenAdapter;
    public View.OnClickListener onClickListener;
    public int id;

    public ImageView search;
    public EditText input;

    public LocalReceiver localReceiver;
    public IntentFilter intentFilter;
    public LocalBroadcastManager localBroadcastManager;

    public Context context;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        onClickListener=this;
        context=this;

        localBroadcastManager=LocalBroadcastManager.getInstance(this);

        intentFilter=new IntentFilter();
        intentFilter.addAction("com.shanzha.changmodel.UPDATEUI");
        localReceiver=new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);

        Intent intent=getIntent();
        id=intent.getIntExtra("count",0);

        PackageModel.getPackageModel().setActivity(this);

        if (!MainActivity.GET_DATA_FINISH){
            progressDialog=new ProgressDialog(this);
            progressDialog.setTitle("正在获取中");
            progressDialog.setMessage("请稍等...");
            progressDialog.setCancelable(false);
            progressDialog.show();
        }else {
            if (recyclerView!=null){
                addAdapter();
            }

        }
    }

    public void addAdapter(){
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        hiddenAdapter=new HiddenAdapter(PackageParsenter.getPackageInfos(),onClickListener,id);
        recyclerView.setAdapter(hiddenAdapter);
    }

    class LocalReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("com.shanzha.changmodel.UPDATEUI")){
                if (progressDialog!=null){
                    progressDialog.dismiss();
                }

                recyclerView.setLayoutManager(new LinearLayoutManager(context));
                recyclerView.setItemAnimator(new DefaultItemAnimator());

                hiddenAdapter=new HiddenAdapter(PackageParsenter.getPackageInfos(),onClickListener,id);
                recyclerView.setAdapter(hiddenAdapter);

                Toast.makeText(getApplicationContext(),"获取完成",Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        PackageParsenter.cancelState();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        if (input.getText().toString().isEmpty()){
            hiddenAdapter=new HiddenAdapter(PackageParsenter.getPackageInfos(),this,id);
            recyclerView.setAdapter(hiddenAdapter);
        }
    }

    class DEleteApk extends AsyncTask {

        @Override
        protected void onPreExecute() {
            progressDialog=new ProgressDialog(context);
            progressDialog.setTitle("正在卸载中");
            progressDialog.setMessage("请稍后...");
            progressDialog.setCancelable(true);
            progressDialog.show();
        }

        @Override
        protected Object doInBackground(Object[] objects) {
            boolean isDo=false;
            List waitingUninstalls=new ArrayList<>();

            for (AppTape appTape:PackageModel.getPackageModel().getAppTapes()){
                if (appTape.getIsUninstall()==1){
                    isDo=true;
                    waitingUninstalls.add(appTape);
                }
            }

            if (waitingUninstalls.size()>0){
                for (AppTape appTape:waitingUninstalls){
                    RootCmd.unInstallApk(appTape.getAppPackage());
                }
            }

            return isDo;
        }

        @Override
        protected void onPostExecute(Object o) {
            progressDialog.dismiss();
            input.setText(null);

            if ((boolean) o){
                hiddenAdapter=new HiddenAdapter(PackageParsenter.getPackageInfos(),onClickListener,id);
                recyclerView.setAdapter(hiddenAdapter);
                Toast.makeText(context,"卸载完成",Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(context,"你还没有勾选一个应用",Toast.LENGTH_SHORT).show();
            }

        }
    }
}

这是我们一会要分析的smali文件的java源码。从代码中我们可以看出,这是一个抽象类的活动,这个活动中还包含有两个内部类,主要是进行线程操作,同时它还存在多个方法,以及逻辑判断。

那么下面我们就来看看它的smali文件代码是什么样子:

.class public abstract Lcom/shanzha/changmodel/clearfile/AppActivity;#展示该类所处路径,以及该类是一个抽象类
.super Landroid/app/Activity;#继承自Activity类
.source "AppActivity.java"#该类的名字叫做AppActivity.java

# interfaces
.implements Landroid/view/View$OnClickListener;#该类继承了OnClickListener接口
.implements Landroid/text/TextWatcher;#该类继承了TextWatcher接口


# annotations
.annotation system Ldalvik/annotation/MemberClasses;#注解类为MemberClasses,这里定义的是该类中的内部类
    value = {
        Lcom/shanzha/changmodel/clearfile/ityAppActiv$DEleteApk;,#这里定义为AppActiv类中的内部类DEleteApk类
        Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;#这里定义的为AppActiv类中的内部类LocalReceiver类
    }
.end annotation#结束注解


# instance fields
.field public context:Landroid/content/Context;#定义一个名字为context的公众变量,类型为Context

.field public hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;#定义一个名字为hiddenAdapter的公众变量,类型为HiddenAdapter

.field public id:I#定义一个名字为id的公众变量,类型为Int

.field public input:Landroid/widget/EditText;#定义一个名字为input的公众变量,类型为EditText

.field public intentFilter:Landroid/content/IntentFilter;#定义一个名字为intentFilter的公众变量,类型为IntentFilter

.field public localBroadcastManager:Landroid/support/v4/content/LocalBroadcastManager;#定义一个名字为intentFilter的公众变量,类型为LocalBroadcastManager

.field public localReceiver:Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;#定义一个名字为localReceiver的公众变量,类型为AppActivity类中的内部类LocalReceiver

.field public onClickListener:Landroid/view/View$OnClickListener;#定义一个名字为onClickListener的公众变量,类型为View类中的内部类nClickListener

.field public progressDialog:Landroid/app/ProgressDialog;#定义一个名字为progressDialog的公众变量,类型为ProgressDialog

.field public recyclerView:Landroid/support/v7/widget/RecyclerView;#定义一个名字为recyclerView的公众变量,类型为RecyclerView

.field public search:Landroid/widget/ImageView;#定义一个名字为search的公众变量,类型为ImageView


# direct methods
.method public constructor ()V  #无参构造函数
    .registers 1

    .prologue
    .line 40
    invoke-direct {p0}, Landroid/app/Activity;->()V

    return-void
.end method


# virtual methods
.method public addAdapter()V#公众方法,方法名为addAdapter(),无返回值,void型
    .registers 5#会使用到五个寄存器

    .prologue
    .line 91#源文件第91行代码

    #从v0寄存器中获取AppActivity类中的recyclerView变量,变量类型是RecyclerView
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    #创建一个对象,放入v1寄存器,类型是LinearLayoutManager
    new-instance v1, Landroid/support/v7/widget/LinearLayoutManager;

    #调用LinearLayoutManager类的构造方法,无返回参数,类型是void
    invoke-direct {v1, p0}, Landroid/support/v7/widget/LinearLayoutManager;->(Landroid/content/Context;)V

    #调用RecyclerView类中的setLayoutManager方法,传入的参数类型是RecyclerView类的内部类LayoutManager类型,无返回值,方法类型是void型
    invoke-virtual {v0, v1}, Landroid/support/v7/widget/RecyclerView;->setLayoutManager(Landroid/support/v7/widget/RecyclerView$LayoutManager;)V

    .line 92#源文件第92行

    #从v0寄存器中获取AppActivity类中的recyclerView变量,变量类型是RecyclerView
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    #创建一个对象,放入v1寄存器,类型是DefaultItemAnimator
    new-instance v1, Landroid/support/v7/widget/DefaultItemAnimator;

    #调用DefaultItemAnimator类的构造方法,无返回参数,类型是void型
    invoke-direct {v1}, Landroid/support/v7/widget/DefaultItemAnimator;->()V

    #调用RecyclerView类中的setItemAnimator方法,传入的参数类型是RecyclerView类的内部类ItemAnimator类型,无返回值,方法类型为void型
    invoke-virtual {v0, v1}, Landroid/support/v7/widget/RecyclerView;->setItemAnimator(Landroid/support/v7/widget/RecyclerView$ItemAnimator;)V

    .line 94#源文件第94行

    #创建一个对象放入v0寄存器,类型是HiddenAdapter类
    new-instance v0, Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    #调用位于PackageParsenter类中的getPackageInfos方法,方法是静态方法,返回类型是List,无传入参数
    invoke-static {}, Lcom/shanzha/changmodel/parsenter/PackageParsenter;->getPackageInfos()Ljava/util/List;

    #转换返回值类型,这里转换的是getPackageInfos方法的返回类型
    move-result-object v1

    #从v2寄存器中获取AppActivity类中的onClickListener变量,类型为View类中的内部类OnClickListener类
    iget-object v2, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->onClickListener:Landroid/view/View$OnClickListener;

    #从v3寄存器中获取AppActivity类中的id变量,类型为Int型
    iget v3, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->id:I

    #调用HiddenAdapter类中的构造方法,传入的参数类型分别是List,OnClickListener,和Int,无返回值,方法类型为void
    invoke-direct {v0, v1, v2, v3}, Lcom/shanzha/changmodel/Adapter/HiddenAdapter;->(Ljava/util/List;Landroid/view/View$OnClickListener;I)V

    #把AppActivity类中的hiddenAdapter变量存入v0寄存器,变量类型为HiddenAdapter
    iput-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    .line 95#源文件中第95行

    #从v0寄存器中获取AppActivity中的recyclerView变量,类型为RecyclerView
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    #从v1寄存器中获取AppActivity中的hiddenAdapter变量,变量类型为HiddenAdapter
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    #调用RecyclerView类中的setAdapter方法,传入参数类型为RecyclerView类中的内部类Adapter,无返回值,方法类型是void
    invoke-virtual {v0, v1}, Landroid/support/v7/widget/RecyclerView;->setAdapter(Landroid/support/v7/widget/RecyclerView$Adapter;)V

    .line 96#源文件第96行

    #该方法无返回值,类型为void,该方法指的是addAdapter方法
    return-void

.end method#该方法结束

.method public afterTextChanged(Landroid/text/Editable;)V#公众方法,方法名为afterTextChanged,传入参数类型为Editable,无返回值,方法类型为void
    .registers 5#会使用到五个寄存器
    .param p1, "s"    # Landroid/text/Editable;

    .prologue
    .line 138#源文件第138行

    #从v0寄存器中获取AppActivity类中input变量值,类型为EditText
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->input:Landroid/widget/EditText;

    #调用EditText类中的getText方法,返回值类型为Editable
    invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable;

    #转换返回值类型,这里转换的是getText方法的返回值
    move-result-object v0

    #调用Object类中的toString方法,返回值类型为String
    invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String;

    #转换返回值类型,这里转换的是toString方法的返回值
    move-result-object v0

    #调用String类中的isEmpty方法,返回值类型是Boolean型
    invoke-virtual {v0}, Ljava/lang/String;->isEmpty()Z

    #转换返回值类型,这里转换的是isEmpty方法的返回值
    move-result v0

    #如果v0寄存器中的数值等于0,则跳转到cond_24分支,这里的0代表为false的意思
    if-eqz v0, :cond_24

    .line 139#源文件中第139行

    #创建一个对象存入v0寄存器,类型为HiddenAdapter
    new-instance v0, Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    #调用PackageParsenter类中的静态方法getPackageInfos,返回值类型为List
    invoke-static {}, Lcom/shanzha/changmodel/parsenter/PackageParsenter;->getPackageInfos()Ljava/util/List;

    #转换返回值类型,这里转换的是getPackageInfos方法的返回值
    move-result-object v1

    #从v2寄存器中获取AppActivity类中的id变量,类型为Int
    iget v2, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->id:I

    #调用HiddenAdapter类的构造方法,传入的参数类型依次为List,OnClickListener,Int,无返回值,方法类型为void
    invoke-direct {v0, v1, p0, v2}, Lcom/shanzha/changmodel/Adapter/HiddenAdapter;->(Ljava/util/List;Landroid/view/View$OnClickListener;I)V

    #把AppActivity类中的hiddenAdapter变量值存入v0寄存器,类型为HiddenAdapter
    iput-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    .line 140#源文件第140行

    #从v0寄存器中获取AppActivity类中的recyclerView变量值,类型是RecyclerView
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    #从v1寄存器中获取AppActivity类中的hiddenAdapter变量值,类型是HiddenAdapter
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    #调用RecyclerView类的setAdapter方法,传入参数类型是RecyclerView类中的内部类Adapter,无返回值,方法类型是void
    invoke-virtual {v0, v1}, Landroid/support/v7/widget/RecyclerView;->setAdapter(Landroid/support/v7/widget/RecyclerView$Adapter;)V

    .line 142#源文件第142行

    #cond_24分支处。与上面if判断代码相对应,如果不符合条件,程序将会跳到这里
    :cond_24

    #该方法无返回值,类型为void,该方法指的是afterTextChanged方法
    return-void
.end method#该方法结束

.method public beforeTextChanged(Ljava/lang/CharSequence;III)V
    .registers 5#使用的5个寄存器
    .param p1, "s"    # Ljava/lang/CharSequence;#方法的参数,变量s,类型为CharSequence
    .param p2, "start"    # I  #方法的参数,变量start,类型为Int
    .param p3, "count"    # I  #方法的参数,变量count,类型为Int
    .param p4, "after"    # I  #方法的参数,变量after,类型为Int

    .prologue
    .line 129#源文件中第129行

    #该方法无返回值,类型为void,该方法指的是beforeTextChanged方法
    return-void
.end method#该方法结束。

.method public onCreate(Landroid/os/Bundle;)V#公众方法,方法名为onCreate,传入的参数类型为Bundle,无返回值,方法类型为void
    .registers 7#使用到7个寄存器
    .param p1, "savedInstanceState"    # Landroid/os/Bundle;#方法的参数,变量savedInstanceState,类型为Bundle
        .annotation build Landroid/support/annotation/Nullable;#该参数存在注解,注解类为Nullable类
        .end annotation#结束注解
    .end param#参数描述结束

    .prologue
    const/4 v4, 0x0#把值0x0赋值到v4寄存器中

    .line 59#源文件中第59行

    #调用父类中的方法onCreate,传入参数类型为Bundle,无返回值,方法类型为void
    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

    .line 61#源文件中第61行

    #把AppActivity类中的onClickListener变量值放入p0寄存器中,类型为View类中的内部类OnClickListener
    iput-object p0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->onClickListener:Landroid/view/View$OnClickListener;

    .line 62#源文件中第62行

    #把AppActivity类中的context变量值放入p0寄存器中,类型为Context
    iput-object p0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->context:Landroid/content/Context;

    .line 64#源文件中第64行

    #调用LocalBroadcastManager类中的静态方法getInstance,传入参数类型为Context,返回值类型为LocalBroadcastManager
    invoke-static {p0}, Landroid/support/v4/content/LocalBroadcastManager;->getInstance(Landroid/content/Context;)Landroid/support/v4/content/LocalBroadcastManager;

    #转换返回值类型,这里转换的是getInstance方法的返回值
    move-result-object v1

    #把AppActivity类中的localBroadcastManager变量放入v1寄存器中,类型为LocalBroadcastManager
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localBroadcastManager:Landroid/support/v4/content/LocalBroadcastManager;

    .line 66#源文件中第66行

    #创建一个IntentFilter类的对象,并存入v1寄存器
    new-instance v1, Landroid/content/IntentFilter;

    #调用IntentFilter类的构造方法,无返回值,方法类型为void
    invoke-direct {v1}, Landroid/content/IntentFilter;->()V

    #把AppActivity类中的intentFilter变量值存入v1寄存器,类型为IntentFilter
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->intentFilter:Landroid/content/IntentFilter;

    .line 67#源文件中第67行

    #从v1寄存器中获取AppActivity类中的intentFilter变量值,类型为IntentFilter
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->intentFilter:Landroid/content/IntentFilter;

    #把"com.shanzha.changmodel.UPDATEUI"字符串赋值到v2寄存器中
    const-string v2, "com.shanzha.changmodel.UPDATEUI"

    #调用IntentFilter类中的addAction方法,传入的参数类型为String,无返回值,方法类型为void
    invoke-virtual {v1, v2}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V

    .line 68#源文件中第68行

    #创建一个AppActivity类中的内部类LocalReceiver对象
    new-instance v1, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    #调用AppActivity类中的内部类LocalReceiver类的构造方法,无返回值,方法类型为void
    invoke-direct {v1, p0}, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->(Lcom/shanzha/changmodel/clearfile/AppActivity;)V

    #把AppActivity类中的localReceiver变量值放入v1寄存器中,类型为AppActivity类中的内部类LocalReceiver
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localReceiver:Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    .line 69#源文件第69行

    #从v1寄存器中获取AppActivity类中的localBroadcastManager变量,类型为LocalBroadcastManager
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localBroadcastManager:Landroid/support/v4/content/LocalBroadcastManager;

    #从v2寄存器中获取AppActivity类中的localReceiver变量,类型为AppActivity类中的内部类LocalReceiver
    iget-object v2, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localReceiver:Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    #从v3寄存器中获取AppActivity类中的intentFilter变量值,类型为IntentFilter
    iget-object v3, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->intentFilter:Landroid/content/IntentFilter;

    #调用LocalBroadcastManager类中的registerReceiver方法,传入参数类型依次是BroadcastReceiver,IntentFilter,无返回值,方法类型为void
    invoke-virtual {v1, v2, v3}, Landroid/support/v4/content/LocalBroadcastManager;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)V

    .line 71#源文件第71行

    #调用AppActivity类中的getIntent方法,返回值类型为Intent
    invoke-virtual {p0}, Lcom/shanzha/changmodel/clearfile/AppActivity;->getIntent()Landroid/content/Intent;

    #转换返回值类型,这里转换的是getIntent方法的返回值
    move-result-object v0

    .line 72#源文件第72行

    #本地寄存器v0储存变量intent,类型为Intent
    .local v0, "intent":Landroid/content/Intent;

    #将字符串"count"赋值到v1寄存器
    const-string v1, "count"

    #调用Intent类中的getIntExtra方法,传入的参数分别是v1,v4寄存器中的值,v0为调用该方法的实例,传入参数类型分别为String,Int,返回值类型为Int
    invoke-virtual {v0, v1, v4}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I

    #转换返回值类型,这里转换的是getIntExtra方法的返回值
    move-result v1

    #将AppActivity类中的id变量放入v1寄存器中,类型为Int
    iput v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->id:I

    .line 74#源文件第74行

    #调用PackageModel类中的静态方法getPackageModel,返回值类型为PackageModel
    invoke-static {}, Lcom/shanzha/changmodel/been/PackageModel;->getPackageModel()Lcom/shanzha/changmodel/been/PackageModel;

    #转换返回值类型,这里转换的是getIntExtra方法的返回值
    move-result-object v1

    #调用PackageModel中的setActivity方法,调用方法的实例为v1寄存器中的值,参数为p0寄存器中的数值,参数类型为Activity,无返回值,方法类型为void
    invoke-virtual {v1, p0}, Lcom/shanzha/changmodel/been/PackageModel;->setActivity(Landroid/app/Activity;)V

    .line 76#源文件中第76行

    #获取MainActivity类中GET_DATA_FINISH变量值,并把它放入v1寄存器中
    sget-boolean v1, Lcom/shanzha/changmodel/MainActivity;->GET_DATA_FINISH:Z

    #如果v1寄存器中的值为0,这里表示为false,则跳到cond_63分支处
    if-nez v1, :cond_63

    .line 77#源文件中第77行

    #创建一个ProgressDialog类的实例对象
    new-instance v1, Landroid/app/ProgressDialog;

    #调用ProgressDialog类的构造函数
    invoke-direct {v1, p0}, Landroid/app/ProgressDialog;->(Landroid/content/Context;)V

    #把AppActivity类中的progressDialog变量值放入到v1寄存器中
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    .line 78#源文件第78行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #将字符串"\u6b63\u5728\u83b7\u53d6\u4e2d"赋值到v2寄存器中
    const-string v2, "\u6b63\u5728\u83b7\u53d6\u4e2d"

    #调用ProgressDialog类中的setTitle方法,调用该方法的实例为v1寄存器中的值,参数为v2寄存器中的值,参数类型为CharSequence,无返回值,方法类型为void
    invoke-virtual {v1, v2}, Landroid/app/ProgressDialog;->setTitle(Ljava/lang/CharSequence;)V

    .line 79#源文件第79行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #将字符串"\u8bf7\u7a0d\u7b49..."赋值到v2寄存器中
    const-string v2, "\u8bf7\u7a0d\u7b49..."

    #调用ProgressDialog类中的setTitle方法,调用该方法的实例为v1寄存器中的值,参数为v2寄存器中的值,参数类型为CharSequence,无返回值,方法类型为void
    invoke-virtual {v1, v2}, Landroid/app/ProgressDialog;->setMessage(Ljava/lang/CharSequence;)V

    .line 80#源文件第80行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #调用ProgressDialog类的setCancelable方法,调用该方法的实例为v1寄存器中的值,参数为v4寄存器中的值,参数类型为boolean型,无返回值,方法类型为void
    invoke-virtual {v1, v4}, Landroid/app/ProgressDialog;->setCancelable(Z)V

    .line 81#源文件第81行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #调用ProgressDialog类的show方法
    invoke-virtual {v1}, Landroid/app/ProgressDialog;->show()V

    .line 88#源文件第88行

    #cond_62分支入口,下面的if判断中如果条件为false,则程序会跳到这里
    :cond_62

    #goto_62分支入口
    :goto_62

    #该方法无返回值,类型为void,该方法指的是onCreate方法
    return-void

    .line 83#源文件第83行

    #cond_63分支入口,上面的if判断中如果条件为false,则程序会跳到这里,即执行else代码块,
    :cond_63

    #从v1寄存器中获取AppActivity类中的recyclerView变量值,类型为RecyclerView
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    #如果v1寄存器中的值为0,这里表示为false,则跳到cond_62分支处
    if-eqz v1, :cond_62

    .line 84#源文件中第84行

    #调用AppActivity类中的addAdapter方法,无返回值,方法类型为void
    invoke-virtual {p0}, Lcom/shanzha/changmodel/clearfile/AppActivity;->addAdapter()V

    #回去:goto_62分支处
    goto :goto_62
.end method#方法结束

.method protected onDestroy()V#受保护方法,无返回值,方法类型void
    .registers 3#使用三个寄存器

    .prologue
    .line 120#源文件中第120行

    #调用父类中的onDestroy方法
    invoke-super {p0}, Landroid/app/Activity;->onDestroy()V

    .line 122#源文件第122行

    #调用PackageParsenter类中的静态方法cancelState
    invoke-static {}, Lcom/shanzha/changmodel/parsenter/PackageParsenter;->cancelState()V

    .line 123#源文件中123行

    #从v0寄存器中获取AppActivity类中localBroadcastManager的变量值
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localBroadcastManager:Landroid/support/v4/content/LocalBroadcastManager;

    #从v1寄存器中获取AppActivity类中localReceiver的变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localReceiver:Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    #调用LocalBroadcastManager类中的unregisterReceiver方法,调用方法的实例为v0寄存器中的值,参数为v1寄存器中的值,参数类型为BroadcastReceiver,无返回值,方法类型为void
    invoke-virtual {v0, v1}, Landroid/support/v4/content/LocalBroadcastManager;->unregisterReceiver(Landroid/content/BroadcastReceiver;)V

    .line 124#源文件第124行

    #该方法无返回值,类型为void,该方法指的是beforeTextChanged方法
    return-void
.end method#方法结束

.method public onTextChanged(Ljava/lang/CharSequence;III)V#公众方法,方法名为onTextChanged,有五个参数,无返回值,方法类型为void
    .registers 5#使用到五个寄存器
    .param p1, "s"    # Ljava/lang/CharSequence;#名为s的参数变量,类型为CharSequence
    .param p2, "start"    # I#名为start的参数变量,类型为Int
    .param p3, "before"    # I#名为before的参数变量,类型为Int
    .param p4, "count"    # #名为count的参数变量,类型为Int

    .prologue
    .line 134#源文件第134行

    #该方法无返回值,类型为void,该方法指的是beforeTextChanged方法
    return-void
.end method#方法结束

转成smali文件后代码量就大了很多,这里有四百多行的代码,我为里面的每一步代码都写上了细致的解析,相信你可以看的懂,在分析这篇smali文件的时候,你可以配合它的java源文件一同分析,这样会让你理解的更加深刻。你可以把它复制下来放到你的编译器中进行查看,这样学习起来比较方便。

下面我就带领大家一步一步的来正确解析smali文件。这里顺便一提,在实际的Android逆向分析中,我们并没有必要把整篇的smali文件从头到尾解析一遍,我们往往只需要看其中某一处的关键函数或者关键的逻辑代码,毕竟进行逆向分析我们的目的就是找出软件的漏洞所在,或者进行相关的破解工作,一小段的关键性代码就足够了。就这篇smali文件来说,整篇几百行的代码,分析完超级累人,更别提上千行上万行逻辑更加复杂的smali文件!这里只是为了大家能够更加明白理解快速掌握smali语法,所以我把通篇的smali文件解析了下来。

针对上面还有一处未涉及到的smali语法,那就是switch多分支选择,那个大家可以自行搜索查看学习,网上也比较详细。

好,下面我们就一步一步的来解析。

我们从头往下看,做上面总共有三句代码:

.class public abstract Lcom/shanzha/changmodel/clearfile/AppActivity;#展示该类所处路径,以及该类是一个抽象类
.super Landroid/app/Activity;#继承自Activity类
.source "AppActivity.java"#该类的名字叫做AppActivity.java

我这里给出的解析也比较详细,相信你能看得懂。

学习smali语法的时候可以看关键字进行猜测联想。比如.class,class是类,我们又看到后面是路径,所以这句就是说明一下该类所处的路径,我们看到还有两个关键字,分别是public,和abstract,我们就可以知道这个类是一个公众的抽象类。

下面.super,我们知道使用super的关键字用来访问父类的相关方法,和继承有关,那么这里就代表的是继承关系,我们看到后面也是一个类的路径,对比我们的java源码可知,这里描述的就是该类的父类,也就是它的继承关系。

.source后面没有出现路径,直接是该类的名字,也就是说这里描述的是该类的名称。

接着下面的smali代码:

# interfaces
.implements Landroid/view/View$OnClickListener;#该类继承了OnClickListener接口
.implements Landroid/text/TextWatcher;#该类继承了TextWatcher接口


# annotations
.annotation system Ldalvik/annotation/MemberClasses;#注解类为MemberClasses,这里定义的是该类中的内部类
    value = {
        Lcom/shanzha/changmodel/clearfile/ityAppActiv$DEleteApk;,#这里定义为AppActiv类中的内部类DEleteApk类
        Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;#这里定义的为AppActiv类中的内部类LocalReceiver类
    }
.end annotation#结束注解

我们可以看到第一行#后面的interfaces接口关键字,我们便可以猜测这里和接口有关,往下看我们就看到可implements关键字,我们知道使用implements关键字用来继承某一个接口,又看到后面的路径,对比我们的java源码便很容易明白,这里是描述该类继承的接口的地方!

下面.annotations字段,这里描述的是注解类,我们仔细看后面的注解类名称为:MemberClasses,翻译就是成员类的意思,猜测这里应该是和内部的成员类有关,我们下面看到它的value字段,分别描述了该类的两个内部类,对比java源码可知,这里描述的是该类中的内部成员类。提一句,我们碰到xxxclass$xxxclass就要明白这里代表的是类中的内部成员类,$前面的class为外部类,$后面的类为它的内部类。

接着看下面的smali代码:

# instance fields
.field public context:Landroid/content/Context;#定义一个名字为context的公众变量,类型为Context

.field public hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;#定义一个名字为hiddenAdapter的公众变量,类型为HiddenAdapter

.field public id:I#定义一个名字为id的公众变量,类型为Int

.field public input:Landroid/widget/EditText;#定义一个名字为input的公众变量,类型为EditText

.field public intentFilter:Landroid/content/IntentFilter;#定义一个名字为intentFilter的公众变量,类型为IntentFilter

.field public localBroadcastManager:Landroid/support/v4/content/LocalBroadcastManager;#定义一个名字为intentFilter的公众变量,类型为LocalBroadcastManager

.field public localReceiver:Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;#定义一个名字为localReceiver的公众变量,类型为AppActivity类中的内部类LocalReceiver

.field public onClickListener:Landroid/view/View$OnClickListener;#定义一个名字为onClickListener的公众变量,类型为View类中的内部类nClickListener

.field public progressDialog:Landroid/app/ProgressDialog;#定义一个名字为progressDialog的公众变量,类型为ProgressDialog

.field public recyclerView:Landroid/support/v7/widget/RecyclerView;#定义一个名字为recyclerView的公众变量,类型为RecyclerView

.field public search:Landroid/widget/ImageView;#定义一个名字为search的公众变量,类型为ImageView

这一块代码描述则是类中的成员变量,:前面的是变量名,:后面的是该变量的类型。我已经注释的很清楚了,相信你很快就明白。

下面就是描述该类中的定义方法,这里我挑其中一个最重要也最特别的方法来给大家讲解,剩余的方法大家可以自行分析理解。

onCreate()的smali代码:

.method public onCreate(Landroid/os/Bundle;)V#公众方法,方法名为onCreate,传入的参数类型为Bundle,无返回值,方法类型为void
    .registers 7#使用到7个寄存器
    .param p1, "savedInstanceState"    # Landroid/os/Bundle;#方法的参数,变量savedInstanceState,类型为Bundle
        .annotation build Landroid/support/annotation/Nullable;#该参数存在注解,注解类为Nullable类
        .end annotation#结束注解
    .end param#参数描述结束

    .prologue
    const/4 v4, 0x0#把值0x0赋值到v4寄存器中

    .line 59#源文件中第59行

    #调用父类中的方法onCreate,传入参数类型为Bundle,无返回值,方法类型为void
    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

    .line 61#源文件中第61行

    #把AppActivity类中的onClickListener变量值放入p0寄存器中,类型为View类中的内部类OnClickListener
    iput-object p0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->onClickListener:Landroid/view/View$OnClickListener;

    .line 62#源文件中第62行

    #把AppActivity类中的context变量值放入p0寄存器中,类型为Context
    iput-object p0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->context:Landroid/content/Context;

    .line 64#源文件中第64行

    #调用LocalBroadcastManager类中的静态方法getInstance,传入参数类型为Context,返回值类型为LocalBroadcastManager
    invoke-static {p0}, Landroid/support/v4/content/LocalBroadcastManager;->getInstance(Landroid/content/Context;)Landroid/support/v4/content/LocalBroadcastManager;

    #转换返回值类型,这里转换的是getInstance方法的返回值
    move-result-object v1

    #把AppActivity类中的localBroadcastManager变量放入v1寄存器中,类型为LocalBroadcastManager
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localBroadcastManager:Landroid/support/v4/content/LocalBroadcastManager;

    .line 66#源文件中第66行

    #创建一个IntentFilter类的对象,并存入v1寄存器
    new-instance v1, Landroid/content/IntentFilter;

    #调用IntentFilter类的构造方法,无返回值,方法类型为void
    invoke-direct {v1}, Landroid/content/IntentFilter;->()V

    #把AppActivity类中的intentFilter变量值存入v1寄存器,类型为IntentFilter
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->intentFilter:Landroid/content/IntentFilter;

    .line 67#源文件中第67行

    #从v1寄存器中获取AppActivity类中的intentFilter变量值,类型为IntentFilter
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->intentFilter:Landroid/content/IntentFilter;

    #把"com.shanzha.changmodel.UPDATEUI"字符串赋值到v2寄存器中
    const-string v2, "com.shanzha.changmodel.UPDATEUI"

    #调用IntentFilter类中的addAction方法,传入的参数类型为String,无返回值,方法类型为void
    invoke-virtual {v1, v2}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V

    .line 68#源文件中第68行

    #创建一个AppActivity类中的内部类LocalReceiver对象
    new-instance v1, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    #调用AppActivity类中的内部类LocalReceiver类的构造方法,无返回值,方法类型为void
    invoke-direct {v1, p0}, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->(Lcom/shanzha/changmodel/clearfile/AppActivity;)V

    #把AppActivity类中的localReceiver变量值放入v1寄存器中,类型为AppActivity类中的内部类LocalReceiver
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localReceiver:Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    .line 69#源文件第69行

    #从v1寄存器中获取AppActivity类中的localBroadcastManager变量,类型为LocalBroadcastManager
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localBroadcastManager:Landroid/support/v4/content/LocalBroadcastManager;

    #从v2寄存器中获取AppActivity类中的localReceiver变量,类型为AppActivity类中的内部类LocalReceiver
    iget-object v2, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localReceiver:Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    #从v3寄存器中获取AppActivity类中的intentFilter变量值,类型为IntentFilter
    iget-object v3, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->intentFilter:Landroid/content/IntentFilter;

    #调用LocalBroadcastManager类中的registerReceiver方法,传入参数类型依次是BroadcastReceiver,IntentFilter,无返回值,方法类型为void
    invoke-virtual {v1, v2, v3}, Landroid/support/v4/content/LocalBroadcastManager;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)V

    .line 71#源文件第71行

    #调用AppActivity类中的getIntent方法,返回值类型为Intent
    invoke-virtual {p0}, Lcom/shanzha/changmodel/clearfile/AppActivity;->getIntent()Landroid/content/Intent;

    #转换返回值类型,这里转换的是getIntent方法的返回值
    move-result-object v0

    .line 72#源文件第72行

    #本地寄存器v0储存变量intent,类型为Intent
    .local v0, "intent":Landroid/content/Intent;

    #将字符串"count"赋值到v1寄存器
    const-string v1, "count"

    #调用Intent类中的getIntExtra方法,传入的参数分别是v1,v4寄存器中的值,v0为调用该方法的实例,传入参数类型分别为String,Int,返回值类型为Int
    invoke-virtual {v0, v1, v4}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I

    #转换返回值类型,这里转换的是getIntExtra方法的返回值
    move-result v1

    #将AppActivity类中的id变量放入v1寄存器中,类型为Int
    iput v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->id:I

    .line 74#源文件第74行

    #调用PackageModel类中的静态方法getPackageModel,返回值类型为PackageModel
    invoke-static {}, Lcom/shanzha/changmodel/been/PackageModel;->getPackageModel()Lcom/shanzha/changmodel/been/PackageModel;

    #转换返回值类型,这里转换的是getIntExtra方法的返回值
    move-result-object v1

    #调用PackageModel中的setActivity方法,调用方法的实例为v1寄存器中的值,参数为p0寄存器中的数值,参数类型为Activity,无返回值,方法类型为void
    invoke-virtual {v1, p0}, Lcom/shanzha/changmodel/been/PackageModel;->setActivity(Landroid/app/Activity;)V

    .line 76#源文件中第76行

    #获取MainActivity类中GET_DATA_FINISH变量值,并把它放入v1寄存器中
    sget-boolean v1, Lcom/shanzha/changmodel/MainActivity;->GET_DATA_FINISH:Z

    #如果v1寄存器中的值为0,这里表示为false,则跳到cond_63分支处
    if-nez v1, :cond_63

    .line 77#源文件中第77行

    #创建一个ProgressDialog类的实例对象
    new-instance v1, Landroid/app/ProgressDialog;

    #调用ProgressDialog类的构造函数
    invoke-direct {v1, p0}, Landroid/app/ProgressDialog;->(Landroid/content/Context;)V

    #把AppActivity类中的progressDialog变量值放入到v1寄存器中
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    .line 78#源文件第78行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #将字符串"\u6b63\u5728\u83b7\u53d6\u4e2d"赋值到v2寄存器中
    const-string v2, "\u6b63\u5728\u83b7\u53d6\u4e2d"

    #调用ProgressDialog类中的setTitle方法,调用该方法的实例为v1寄存器中的值,参数为v2寄存器中的值,参数类型为CharSequence,无返回值,方法类型为void
    invoke-virtual {v1, v2}, Landroid/app/ProgressDialog;->setTitle(Ljava/lang/CharSequence;)V

    .line 79#源文件第79行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #将字符串"\u8bf7\u7a0d\u7b49..."赋值到v2寄存器中
    const-string v2, "\u8bf7\u7a0d\u7b49..."

    #调用ProgressDialog类中的setTitle方法,调用该方法的实例为v1寄存器中的值,参数为v2寄存器中的值,参数类型为CharSequence,无返回值,方法类型为void
    invoke-virtual {v1, v2}, Landroid/app/ProgressDialog;->setMessage(Ljava/lang/CharSequence;)V

    .line 80#源文件第80行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #调用ProgressDialog类的setCancelable方法,调用该方法的实例为v1寄存器中的值,参数为v4寄存器中的值,参数类型为boolean型,无返回值,方法类型为void
    invoke-virtual {v1, v4}, Landroid/app/ProgressDialog;->setCancelable(Z)V

    .line 81#源文件第81行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #调用ProgressDialog类的show方法
    invoke-virtual {v1}, Landroid/app/ProgressDialog;->show()V

    .line 88#源文件第88行

    #cond_62分支入口,下面的if判断中如果条件为false,则程序会跳到这里
    :cond_62

    #goto_62分支入口
    :goto_62

    #该方法无返回值,类型为void,该方法指的是onCreate方法
    return-void

    .line 83#源文件第83行

    #cond_63分支入口,上面的if判断中如果条件为false,则程序会跳到这里,即执行else代码块,
    :cond_63

    #从v1寄存器中获取AppActivity类中的recyclerView变量值,类型为RecyclerView
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    #如果v1寄存器中的值为0,这里表示为false,则跳到cond_62分支处
    if-eqz v1, :cond_62

    .line 84#源文件中第84行

    #调用AppActivity类中的addAdapter方法,无返回值,方法类型为void
    invoke-virtual {p0}, Lcom/shanzha/changmodel/clearfile/AppActivity;->addAdapter()V

    #回去:goto_62分支处
    goto :goto_62
.end method#方法结束

 这个方法的smali代码是最长的也是最难分析的,下面我一一给大家讲解。

首先是描述函数相关信息的代码:

.method public onCreate(Landroid/os/Bundle;)V#公众方法,方法名为onCreate,传入的参数类型为Bundle,无返回值,方法类型为void

.method代表的是这个是一个函数,后面public表示该方法是公众方法,后面onCreate是方法的名字,后面括号中是参数类型,这里参数类型为Bundle型。然后最后的V表示该方法类型为void型。 

下面.registers 7表示这个方法会使用到7个寄存器,registers翻译一下就是寄存器的意思。

.param p1, "savedInstanceState"    # Landroid/os/Bundle;#方法的参数,变量savedInstanceState,类型为Bundle
        .annotation build Landroid/support/annotation/Nullable;#该参数存在注解,注解类为Nullable类
        .end annotation#结束注解
    .end param#参数描述结束

上面的代码就是针对传入参数的描述,.parm代表参数的意思。我们这里可以看出,传入的一个参数变量名是 savedInstanceState,类型是Bundle。下面是重点,这里我们又碰见了.annotation注解描述。上面描述的是该类中的内部类信息,这里有所不同,这里描述的是该参数存在注解,注解类为Nullable。我们可以去看一下java源码,看看到底是不是这样子。

public void onCreate(@Nullable Bundle savedInstanceState)

java源码中可以很清楚的看到,这里确实存在着注解,类型为Nullable。下面 .end annotation和.end param我们很容易就会猜到,这里是结束注解和结束参数描述的意思。

.line 59#源文件中第59行

    #调用父类中的方法onCreate,传入参数类型为Bundle,无返回值,方法类型为void
    invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

上面的smali代码中,.line代表的是行数,也就是说下面的描述的逻辑操作位于源文件中的哪一行。invoke-super这里是调用父类中方法的指令,存在super关键字;后面 Landroid/app/Activity代表的是具体方法位于哪一个类,\rightarrow箭头代表的调用哪一个方法,后面onCreate就是具体方法的名字,所以这里的指令为调用父类Activity中onCreate()方法。

我们可以去看一下Java源码,在第59行:

super.onCreate(savedInstanceState);

确实是调用了父类的onCreate()方法!

接着继续分析:

 .line 61#源文件中第61行

    #把AppActivity类中的onClickListener变量值放入p0寄存器中,类型为View类中的内部类OnClickListener
    iput-object p0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->onClickListener:Landroid/view/View$OnClickListener;

    .line 62#源文件中第62行

    #把AppActivity类中的context变量值放入p0寄存器中,类型为Context
    iput-object p0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->context:Landroid/content/Context;

    .line 64#源文件中第64行

    #调用LocalBroadcastManager类中的静态方法getInstance,传入参数类型为Context,返回值类型为LocalBroadcastManager
    invoke-static {p0}, Landroid/support/v4/content/LocalBroadcastManager;->getInstance(Landroid/content/Context;)Landroid/support/v4/content/LocalBroadcastManager;

    #转换返回值类型,这里转换的是getInstance方法的返回值
    move-result-object v1

    #把AppActivity类中的localBroadcastManager变量放入v1寄存器中,类型为LocalBroadcastManager
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localBroadcastManager:Landroid/support/v4/content/LocalBroadcastManager;

 首先描述第61行的操作。iput-object代表的是放入对象的指令,put放入,object意思为对象,这个不难理解。后面p0代表的是寄存器,代表的是参数寄存器,这里p0代表的是this,后面则描述的是具体哪一个类,箭头代表具体哪一个变量,我们很容易就看出是AppActivity中的onClickListener变量。这里的意思就是说用p0寄存器中的值为onClickListener变量赋值,同时再把onClickListener变量放入p0寄存器中。

你先别晕,这里两个p0代表的含义不同。第一个p0代表的是寄存器,第二个p0代表的是this关键字,操作就是把第二个p0为onClickListener变量赋值,然后放入第一个p0寄存器中。如果你还不是很明白,那么就去对比一下java源码第61行:

 onClickListener=this;

看到没有 ,这里说白了进行的操作就是onClickListener=this!

接着第62行的操作,同理我就不多说了,这里进行的操作是context=this。

接着我们看第64行的描述。invoke-static指令表示要调用一个静态方法,static即是静态关键字。后面描述的照样,调用的静态方法具体为哪一个类中的哪一个静态方法。所以这里表示的指令为调用LocalBroadcastManager类中的静态方法getInstance。

move-result-object v1指令表示进行数据转换,每当调用一个有返回值的方法后,都要进行数据转换的处理。下面执行iput-object指令把获取到的localBroadcastManager实例放到储存器中。对比Java中的源码即为:

localBroadcastManager=LocalBroadcastManager.getInstance(this);

继续分析:

.line 66#源文件中第66行

    #创建一个IntentFilter类的对象,并存入v1寄存器
    new-instance v1, Landroid/content/IntentFilter;

    #调用IntentFilter类的构造方法,无返回值,方法类型为void
    invoke-direct {v1}, Landroid/content/IntentFilter;->()V

    #把AppActivity类中的intentFilter变量值存入v1寄存器,类型为IntentFilter
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->intentFilter:Landroid/content/IntentFilter;

    .line 67#源文件中第67行

    #从v1寄存器中获取AppActivity类中的intentFilter变量值,类型为IntentFilter
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->intentFilter:Landroid/content/IntentFilter;

    #把"com.shanzha.changmodel.UPDATEUI"字符串赋值到v2寄存器中
    const-string v2, "com.shanzha.changmodel.UPDATEUI"

    #调用IntentFilter类中的addAction方法,传入的参数类型为String,无返回值,方法类型为void
    invoke-virtual {v1, v2}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V

 第66行代码的描述。new-instance是创建实例的指令,后面描述的是具体创建哪一个类的实例,v1表示创建完成放入v1寄存器中。invoke-direct也是调用方法的指令,()V代表的是构造函数,所以这里指令为调用IntentFilter类的构造方法。下面就是对创建出来的IntentFilter类实例存入寄存器中。对比Java代码就是:

intentFilter=new IntentFilter();

下面第67行代码的描述。首先从寄存器中拿到实例,然后 const-string  V2代表是把一段字符串赋值到V2寄存器中,后面是具体要操作的字符串,然后invoke-virtual调用方法,v1寄存器中的值就是具体执行方法的实例,这里为IntentFilter类实例,v2寄存器中的值就是需要传入方法的参数,这里为字符串"com.shanzha.changmodel.UPDATEUI",调用的方法为addAction(String)。我们对应一下java中的源码就是:

 intentFilter.addAction("com.shanzha.changmodel.UPDATEUI");

 继续分析:

.line 68#源文件中第68行

    #创建一个AppActivity类中的内部类LocalReceiver对象
    new-instance v1, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    #调用AppActivity类中的内部类LocalReceiver类的构造方法,无返回值,方法类型为void
    invoke-direct {v1, p0}, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->(Lcom/shanzha/changmodel/clearfile/AppActivity;)V

    #把AppActivity类中的localReceiver变量值放入v1寄存器中,类型为AppActivity类中的内部类LocalReceiver
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localReceiver:Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    .line 69#源文件第69行

    #从v1寄存器中获取AppActivity类中的localBroadcastManager变量,类型为LocalBroadcastManager
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localBroadcastManager:Landroid/support/v4/content/LocalBroadcastManager;

    #从v2寄存器中获取AppActivity类中的localReceiver变量,类型为AppActivity类中的内部类LocalReceiver
    iget-object v2, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->localReceiver:Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;

    #从v3寄存器中获取AppActivity类中的intentFilter变量值,类型为IntentFilter
    iget-object v3, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->intentFilter:Landroid/content/IntentFilter;

    #调用LocalBroadcastManager类中的registerReceiver方法,传入参数类型依次是BroadcastReceiver,IntentFilter,无返回值,方法类型为void
    invoke-virtual {v1, v2, v3}, Landroid/support/v4/content/LocalBroadcastManager;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)V

这里你就可以自己看懂了,我就不多讲解,别忘了对比一下Java 源码,这样会让你更加印象深刻。

下面:

  .line 72#源文件第72行

    #本地寄存器v0储存变量intent,类型为Intent
    .local v0, "intent":Landroid/content/Intent;

    #将字符串"count"赋值到v1寄存器
    const-string v1, "count"

    #调用Intent类中的getIntExtra方法,传入的参数分别是v1,v4寄存器中的值,v0为调用该方法的实例,传入参数类型分别为String,Int,返回值类型为Int
    invoke-virtual {v0, v1, v4}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I

    #转换返回值类型,这里转换的是getIntExtra方法的返回值
    move-result v1

    #将AppActivity类中的id变量放入v1寄存器中,类型为Int
    iput v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->id:I

 .local表示的是本地寄存器,这里表示是从本地寄存器中取出名字为intent的变量值放入v0寄存器中,类型为Intent。然后把字符串放入寄存器v1中,下面就开始调用方法,传入参数值v1和v4寄存器中的值。下面对返回值进行数据转换,给id变量赋值,并把id变量放入v1寄存器中。对比java源码就是:

id=intent.getIntExtra("count",0);

下面就是进行逻辑if判断了:

.line 76#源文件中第76行

    #获取MainActivity类中GET_DATA_FINISH变量值,并把它放入v1寄存器中
    sget-boolean v1, Lcom/shanzha/changmodel/MainActivity;->GET_DATA_FINISH:Z

    #如果v1寄存器中的值为0,这里表示为false,则跳到cond_63分支处
    if-nez v1, :cond_63

    .line 77#源文件中第77行

    #创建一个ProgressDialog类的实例对象
    new-instance v1, Landroid/app/ProgressDialog;

    #调用ProgressDialog类的构造函数
    invoke-direct {v1, p0}, Landroid/app/ProgressDialog;->(Landroid/content/Context;)V

    #把AppActivity类中的progressDialog变量值放入到v1寄存器中
    iput-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    .line 78#源文件第78行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #将字符串"\u6b63\u5728\u83b7\u53d6\u4e2d"赋值到v2寄存器中
    const-string v2, "\u6b63\u5728\u83b7\u53d6\u4e2d"

    #调用ProgressDialog类中的setTitle方法,调用该方法的实例为v1寄存器中的值,参数为v2寄存器中的值,参数类型为CharSequence,无返回值,方法类型为void
    invoke-virtual {v1, v2}, Landroid/app/ProgressDialog;->setTitle(Ljava/lang/CharSequence;)V

    .line 79#源文件第79行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #将字符串"\u8bf7\u7a0d\u7b49..."赋值到v2寄存器中
    const-string v2, "\u8bf7\u7a0d\u7b49..."

    #调用ProgressDialog类中的setTitle方法,调用该方法的实例为v1寄存器中的值,参数为v2寄存器中的值,参数类型为CharSequence,无返回值,方法类型为void
    invoke-virtual {v1, v2}, Landroid/app/ProgressDialog;->setMessage(Ljava/lang/CharSequence;)V

    .line 80#源文件第80行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #调用ProgressDialog类的setCancelable方法,调用该方法的实例为v1寄存器中的值,参数为v4寄存器中的值,参数类型为boolean型,无返回值,方法类型为void
    invoke-virtual {v1, v4}, Landroid/app/ProgressDialog;->setCancelable(Z)V

    .line 81#源文件第81行

    #从v1寄存器中取出AppActivity类中progressDialog变量值
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    #调用ProgressDialog类的show方法
    invoke-virtual {v1}, Landroid/app/ProgressDialog;->show()V

    .line 88#源文件第88行

    #cond_62分支入口,下面的if判断中如果条件为false,则程序会跳到这里
    :cond_62

    #goto_62分支入口
    :goto_62

    #该方法无返回值,类型为void,该方法指的是onCreate方法
    return-void

    .line 83#源文件第83行

    #cond_63分支入口,上面的if判断中如果条件为false,则程序会跳到这里,即执行else代码块,
    :cond_63

    #从v1寄存器中获取AppActivity类中的recyclerView变量值,类型为RecyclerView
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    #如果v1寄存器中的值为0,这里表示为false,则跳到cond_62分支处
    if-eqz v1, :cond_62

    .line 84#源文件中第84行

    #调用AppActivity类中的addAdapter方法,无返回值,方法类型为void
    invoke-virtual {p0}, Lcom/shanzha/changmodel/clearfile/AppActivity;->addAdapter()V

    #回去:goto_62分支处
    goto :goto_62

 讲解这段smali代码的时候我们先贴上具体的java源码,以防止小伙伴晕向。

对应的java源码为:

 if (!MainActivity.GET_DATA_FINISH){
            progressDialog=new ProgressDialog(this);
            progressDialog.setTitle("正在获取中");
            progressDialog.setMessage("请稍等...");
            progressDialog.setCancelable(false);
            progressDialog.show();
        }else {
            if (recyclerView!=null){
                addAdapter();
            }

        }

好,我们下面开始讲解。首先执行了 sget-boolean指令,也是一个取值操作,后面是具体取值对象的描述

sget-boolean v1, Lcom/shanzha/changmodel/MainActivity;->GET_DATA_FINISH:Z

取值对象为MainActivity中的 GET_DATA_FINISH变量,后面的Z表示这个变量为boolean型。对应的java源码就是MainActivity.GET_DATA_FINISH。

下面if-nez v1, :cond_63指令,表示如果v1寄存器中的值为0,那么就跳到cond_63分支。这里为0就是代表条件为false,那么cond_63分支又是什么鬼?!这里cond_63代表的是一个跳入的接口,你可以把它想象为switch中的case分支,这里的cond_63分支的入口在这里:

 #cond_63分支入口,上面的if判断中如果条件为false,则程序会跳到这里,即执行else代码块,
    :cond_63

    #从v1寄存器中获取AppActivity类中的recyclerView变量值,类型为RecyclerView
    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    #如果v1寄存器中的值为0,这里表示为false,则跳到cond_62分支处
    if-eqz v1, :cond_62

    .line 84#源文件中第84行

    #调用AppActivity类中的addAdapter方法,无返回值,方法类型为void
    invoke-virtual {p0}, Lcom/shanzha/changmodel/clearfile/AppActivity;->addAdapter()V

 也就是说,如果上面程序决定跳到cond_63分支,那么程序就会在代码中寻找这个分支的接口,也就是:cond_63。找到后后执行这个接口下面的逻辑。这下讲解你是否明白了?

这个所谓了cond_63接口说白了就是else的代码体,我们对比java源码,发现确实是这样,:cond_63下面的逻辑操作正是else代码中的逻辑。具体else代码中的逻辑这里不做主要分析,这里主要关注的是if判断。

下面我们就先分析一下else干了什么,首先从寄存器v1中获取recyclerView变量值,接下来又是一个逻辑判断,这里判断如果为false跳入的接口为cond_62。我们找cond_62的接口:

#cond_62分支入口,下面的if判断中如果条件为false,则程序会跳到这里
    :cond_62

    #goto_62分支入口
    :goto_62

    #该方法无返回值,类型为void,该方法指的是onCreate方法
    return-void

我们发现这里同时也是goto_62分支的入口 ,即:goto_62,我们可以看到,goto_62分支入口下面的操作就是return了,也就意味着结束这个方法,那么又是在哪里声明了这个接口呢?答案是在这里:

#回去:goto_62分支处
    goto :goto_62

goto指令的意思就是程序跳转到后面声明的分支处,这里就是使程序跳转到goto_62的分支处,也就是结束了这个方法的调用。这句跳转语句位于分支cond_63下面,也就是说执行完cond_63的操作后,该方法就会结束。同时在cond_ 63里面还会有一个判断进行cond_62分支的跳转,刚才我们已经看到了,cond_62分支入口下就是return的操作,也就是执行了方法结束。

我们这里对比java源码:

else {
            if (recyclerView!=null){
                addAdapter();
            }

        }

 发现逻辑确实如此,如果上面的if条件为false就会执行else,进入else后再进行第二个if判断,如果也是false,那么就会跳入cond_62分支,执行该方法结束,为true就会执行下面的逻辑操作。

到此关于整篇的smali文件我已经带领大家分析完毕,剩余的部分小伙伴可以自行分析,顺便强化理解。

这里你可能还会问,为什么没有看到内部类的smali代码?这是因为在解析成smali文件的时候,是把内部类分开来解析的,所以这里贴上内部类的smali代码,你在学习完上面的smali语法后,可以试着把内部类的smali文件给解析一下,以便使自己掌握的更加牢固!

AppActivity$DEleteApk的smali代码:

.class Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;
.super Landroid/os/AsyncTask;
.source "AppActivity.java"


# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Lcom/shanzha/changmodel/clearfile/AppActivity;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = "DEleteApk"
.end annotation


# instance fields
.field final synthetic this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;


# direct methods
.method constructor (Lcom/shanzha/changmodel/clearfile/AppActivity;)V
    .registers 2
    .param p1, "this$0"    # Lcom/shanzha/changmodel/clearfile/AppActivity;

    .prologue
    .line 144
    iput-object p1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    invoke-direct {p0}, Landroid/os/AsyncTask;->()V

    return-void
.end method


# virtual methods
.method protected doInBackground([Ljava/lang/Object;)Ljava/lang/Object;
    .registers 8
    .param p1, "objects"    # [Ljava/lang/Object;

    .prologue
    .line 157
    const/4 v1, 0x0

    .line 158
    .local v1, "isDo":Z
    new-instance v2, Ljava/util/ArrayList;

    invoke-direct {v2}, Ljava/util/ArrayList;->()V

    .line 160
    .local v2, "waitingUninstalls":Ljava/util/List;, "Ljava/util/List;"
    invoke-static {}, Lcom/shanzha/changmodel/been/PackageModel;->getPackageModel()Lcom/shanzha/changmodel/been/PackageModel;

    move-result-object v3

    invoke-virtual {v3}, Lcom/shanzha/changmodel/been/PackageModel;->getAppTapes()Ljava/util/List;

    move-result-object v3

    invoke-interface {v3}, Ljava/util/List;->iterator()Ljava/util/Iterator;

    move-result-object v3

    :cond_12
    :goto_12
    invoke-interface {v3}, Ljava/util/Iterator;->hasNext()Z

    move-result v4

    if-eqz v4, :cond_2a

    invoke-interface {v3}, Ljava/util/Iterator;->next()Ljava/lang/Object;

    move-result-object v0

    check-cast v0, Lcom/shanzha/changmodel/been/AppTape;

    .line 161
    .local v0, "appTape":Lcom/shanzha/changmodel/been/AppTape;
    invoke-virtual {v0}, Lcom/shanzha/changmodel/been/AppTape;->getIsUninstall()I

    move-result v4

    const/4 v5, 0x1

    if-ne v4, v5, :cond_12

    .line 162
    const/4 v1, 0x1

    .line 163
    invoke-interface {v2, v0}, Ljava/util/List;->add(Ljava/lang/Object;)Z

    goto :goto_12

    .line 167
    .end local v0    # "appTape":Lcom/shanzha/changmodel/been/AppTape;
    :cond_2a
    invoke-interface {v2}, Ljava/util/List;->size()I

    move-result v3

    if-lez v3, :cond_48

    .line 168
    invoke-interface {v2}, Ljava/util/List;->iterator()Ljava/util/Iterator;

    move-result-object v3

    :goto_34
    invoke-interface {v3}, Ljava/util/Iterator;->hasNext()Z

    move-result v4

    if-eqz v4, :cond_48

    invoke-interface {v3}, Ljava/util/Iterator;->next()Ljava/lang/Object;

    move-result-object v0

    check-cast v0, Lcom/shanzha/changmodel/been/AppTape;

    .line 169
    .restart local v0    # "appTape":Lcom/shanzha/changmodel/been/AppTape;
    invoke-virtual {v0}, Lcom/shanzha/changmodel/been/AppTape;->getAppPackage()Ljava/lang/String;

    move-result-object v4

    invoke-static {v4}, Lcom/shanzha/changmodel/parsenter/RootCmd;->unInstallApk(Ljava/lang/String;)V

    goto :goto_34

    .line 173
    .end local v0    # "appTape":Lcom/shanzha/changmodel/been/AppTape;
    :cond_48
    invoke-static {v1}, Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;

    move-result-object v3

    return-object v3
.end method

.method protected onPostExecute(Ljava/lang/Object;)V
    .registers 8
    .param p1, "o"    # Ljava/lang/Object;

    .prologue
    const/4 v5, 0x0

    .line 178
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    invoke-virtual {v0}, Landroid/app/ProgressDialog;->dismiss()V

    .line 179
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->input:Landroid/widget/EditText;

    const/4 v1, 0x0

    invoke-virtual {v0, v1}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V

    .line 181
    check-cast p1, Ljava/lang/Boolean;

    .end local p1    # "o":Ljava/lang/Object;
    invoke-virtual {p1}, Ljava/lang/Boolean;->booleanValue()Z

    move-result v0

    if-eqz v0, :cond_46

    .line 182
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    new-instance v1, Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    invoke-static {}, Lcom/shanzha/changmodel/parsenter/PackageParsenter;->getPackageInfos()Ljava/util/List;

    move-result-object v2

    iget-object v3, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v3, v3, Lcom/shanzha/changmodel/clearfile/AppActivity;->onClickListener:Landroid/view/View$OnClickListener;

    iget-object v4, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget v4, v4, Lcom/shanzha/changmodel/clearfile/AppActivity;->id:I

    invoke-direct {v1, v2, v3, v4}, Lcom/shanzha/changmodel/Adapter/HiddenAdapter;->(Ljava/util/List;Landroid/view/View$OnClickListener;I)V

    iput-object v1, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    .line 183
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v1, v1, Lcom/shanzha/changmodel/clearfile/AppActivity;->hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    invoke-virtual {v0, v1}, Landroid/support/v7/widget/RecyclerView;->setAdapter(Landroid/support/v7/widget/RecyclerView$Adapter;)V

    .line 184
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->context:Landroid/content/Context;

    const-string v1, "\u5378\u8f7d\u5b8c\u6210"

    invoke-static {v0, v1, v5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object v0

    invoke-virtual {v0}, Landroid/widget/Toast;->show()V

    .line 189
    :goto_45
    return-void

    .line 186
    :cond_46
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->context:Landroid/content/Context;

    const-string v1, "\u4f60\u8fd8\u6ca1\u6709\u52fe\u9009\u4e00\u4e2a\u5e94\u7528"

    invoke-static {v0, v1, v5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object v0

    invoke-virtual {v0}, Landroid/widget/Toast;->show()V

    goto :goto_45
.end method

.method protected onPreExecute()V
    .registers 4

    .prologue
    .line 148
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    new-instance v1, Landroid/app/ProgressDialog;

    iget-object v2, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v2, v2, Lcom/shanzha/changmodel/clearfile/AppActivity;->context:Landroid/content/Context;

    invoke-direct {v1, v2}, Landroid/app/ProgressDialog;->(Landroid/content/Context;)V

    iput-object v1, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    .line 149
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    const-string v1, "\u6b63\u5728\u5378\u8f7d\u4e2d"

    invoke-virtual {v0, v1}, Landroid/app/ProgressDialog;->setTitle(Ljava/lang/CharSequence;)V

    .line 150
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    const-string v1, "\u8bf7\u7a0d\u540e..."

    invoke-virtual {v0, v1}, Landroid/app/ProgressDialog;->setMessage(Ljava/lang/CharSequence;)V

    .line 151
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    const/4 v1, 0x1

    invoke-virtual {v0, v1}, Landroid/app/ProgressDialog;->setCancelable(Z)V

    .line 152
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$DEleteApk;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    invoke-virtual {v0}, Landroid/app/ProgressDialog;->show()V

    .line 153
    return-void
.end method

AppActivity$LocalReceiver的smali代码: 

.class Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;
.super Landroid/content/BroadcastReceiver;
.source "AppActivity.java"


# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Lcom/shanzha/changmodel/clearfile/AppActivity;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = "LocalReceiver"
.end annotation


# instance fields
.field final synthetic this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;


# direct methods
.method constructor (Lcom/shanzha/changmodel/clearfile/AppActivity;)V
    .registers 2
    .param p1, "this$0"    # Lcom/shanzha/changmodel/clearfile/AppActivity;

    .prologue
    .line 98
    iput-object p1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    invoke-direct {p0}, Landroid/content/BroadcastReceiver;->()V

    return-void
.end method


# virtual methods
.method public onReceive(Landroid/content/Context;Landroid/content/Intent;)V
    .registers 8
    .param p1, "context"    # Landroid/content/Context;
    .param p2, "intent"    # Landroid/content/Intent;

    .prologue
    .line 102
    invoke-virtual {p2}, Landroid/content/Intent;->getAction()Ljava/lang/String;

    move-result-object v0

    const-string v1, "com.shanzha.changmodel.UPDATEUI"

    invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v0

    if-eqz v0, :cond_61

    .line 103
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    if-eqz v0, :cond_19

    .line 104
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->progressDialog:Landroid/app/ProgressDialog;

    invoke-virtual {v0}, Landroid/app/ProgressDialog;->dismiss()V

    .line 107
    :cond_19
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    new-instance v1, Landroid/support/v7/widget/LinearLayoutManager;

    invoke-direct {v1, p1}, Landroid/support/v7/widget/LinearLayoutManager;->(Landroid/content/Context;)V

    invoke-virtual {v0, v1}, Landroid/support/v7/widget/RecyclerView;->setLayoutManager(Landroid/support/v7/widget/RecyclerView$LayoutManager;)V

    .line 108
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    new-instance v1, Landroid/support/v7/widget/DefaultItemAnimator;

    invoke-direct {v1}, Landroid/support/v7/widget/DefaultItemAnimator;->()V

    invoke-virtual {v0, v1}, Landroid/support/v7/widget/RecyclerView;->setItemAnimator(Landroid/support/v7/widget/RecyclerView$ItemAnimator;)V

    .line 110
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    new-instance v1, Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    invoke-static {}, Lcom/shanzha/changmodel/parsenter/PackageParsenter;->getPackageInfos()Ljava/util/List;

    move-result-object v2

    iget-object v3, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v3, v3, Lcom/shanzha/changmodel/clearfile/AppActivity;->onClickListener:Landroid/view/View$OnClickListener;

    iget-object v4, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget v4, v4, Lcom/shanzha/changmodel/clearfile/AppActivity;->id:I

    invoke-direct {v1, v2, v3, v4}, Lcom/shanzha/changmodel/Adapter/HiddenAdapter;->(Ljava/util/List;Landroid/view/View$OnClickListener;I)V

    iput-object v1, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    .line 111
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v0, v0, Lcom/shanzha/changmodel/clearfile/AppActivity;->recyclerView:Landroid/support/v7/widget/RecyclerView;

    iget-object v1, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    iget-object v1, v1, Lcom/shanzha/changmodel/clearfile/AppActivity;->hiddenAdapter:Lcom/shanzha/changmodel/Adapter/HiddenAdapter;

    invoke-virtual {v0, v1}, Landroid/support/v7/widget/RecyclerView;->setAdapter(Landroid/support/v7/widget/RecyclerView$Adapter;)V

    .line 113
    iget-object v0, p0, Lcom/shanzha/changmodel/clearfile/AppActivity$LocalReceiver;->this$0:Lcom/shanzha/changmodel/clearfile/AppActivity;

    invoke-virtual {v0}, Lcom/shanzha/changmodel/clearfile/AppActivity;->getApplicationContext()Landroid/content/Context;

    move-result-object v0

    const-string v1, "\u83b7\u53d6\u5b8c\u6210"

    const/4 v2, 0x0

    invoke-static {v0, v1, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object v0

    invoke-virtual {v0}, Landroid/widget/Toast;->show()V

    .line 115
    :cond_61
    return-void
.end method

以上两篇smali文件分别属于两个内部类,希望你可以加油把他们都给解析掉!(我是因为解析了上面四百多行累坏了,解析不动了,,,,)。

好了本文到此结束,希望大家可以迅速的掌握住smali语法,后面我还会继续带大家进行相关的Android逆向工程的知识,赶紧跟上别掉队!

对以上smali语法有疑问有不解的小伙伴可以评论留言,我会为你们一一解决的。

你可能感兴趣的:(Android逆向工程:详细讲解smali语法,手把手带你分析语句!)