smali Davlik 语法解析金山快盘代码

本文通过解析金山快盘的smali代码,介绍了Davlik虚拟机的语法,包括原始类型、对象类型和方法参数的表示。讨论了如何读懂smali代码,指出需要对应L文件来完全还原,并提到了混淆方法的拆解。文章还分享了一个学习smali的网址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

smali 逆向金山快盘的一个accout的文件安。此帖子只是要证明smali是可以读懂的。只要花点功夫

关于android逆向工程 smali Davlik 语法,很多写jni的同学都不陌生(Landroid/content/BroadcastReceiver对象

简介:

原始类型v  void  只能用于返回值类型

                               Z   boolean

                               B   byte

                               S   short

                               C   char

                                I    int

                               J    long64位)

                               F   float

                               D   double64位)

              对象类型Lpackage/name/ObjectName;  相当于java中的package.name.ObjectName;解释如下:

                                L:表示这是一个对象类型

                                 package/name:该对象所在的包

                                ;:表示对象名称的结束

 

.class publicLcn/kuaipan/android/account/AuthExpiredReceiver;

.super Landroid/content/BroadcastReceiver;

( public classAuthExpiredReceiver extends BroadcastReceiver )

 

# direct methods

.method public constructor <init>()V

   .locals 0

 

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

 

   return-void

.end method

(public AuthExpiredReceiver(){}:表示该类的不带参数缺省的构造方法)

//下面按行解毒smali的编译代码

/*

    有两种方式指定一个方法中有多少寄存器是可用的:.registers指令指定了方法中寄存器的总数.locals指令表明了方法中非参寄存器的总数,出现在方法中的第一行

方法的传参:当一个方法被调用的时候,方法的参数被置于最后N个寄存器中;例如,一个方法有2个参数,5个寄存器(v0~v4)那么,参数将置于最后2个寄存器(v3和v4)非静态方法中的第一个参数总是调用该方法的对象;说明:对于静态方法除了没有隐含的this参数外,其他都一样

寄存器的命名方式:V命名P命名第一个寄存器就是方法中的第一个参数寄存器比较:使用P命名是为了防止以后如果在方法中增加寄存器,需要对参数寄存器重新进行编号的缺点特别说明一下:Long和Double类型是64位的,需要2个寄存器例如:对于非静态方法LMyObject—— > myMethod(IJZ) V;有4个参数:LMyObject,

int,

long,

bool;

需要5个寄存器来存储参数;P0 this P1 I(int) P2,P3 J(long) P4 Z(bool)

 

*/

# virtual methods

// public voidonReceive(Context context, Intent intent)
.method publiconReceive(Landroid/content/Context;Landroid/content/Intent;)V
//locals指令表明了方法中非参寄存器的数量,4个stack
   .locals 4
 
    //第一个参数 v3
const v3,0x7f0800b6
         //第二个参数
   const/4 v2, 0x1
         //静态调用
   invoke-static {p1}, Lcn/kuaipan/android/service/ConfigFactory;->getConfig(Landroid/content/Context;)Lcn/kuaipan/android/service/Config;
         //获取结果保存v0
   move-result-object v0
         //解释上面代码     
(cn.kuaipan.android.service.Config v0= ConfigFactory. getConfig (context) )
   const-string v1, "AUTH_FAILED"
 
   invoke-virtual {v0, v1},Lcn/kuaipan/android/service/Config;->getAction(Ljava/lang/String;)Ljava/lang/String;
 
   move-result-object v0
(final string v0 = v2.getAction( v1 );)
 
   invoke-virtual {p2},Landroid/content/Intent;->getAction()Ljava/lang/String;
         ( 调用p2 intent.getAction()方法)
   move-result-object v1
         (返回结果给变量v1 )
invoke-virtual{v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
 
         (v0.equals(v1) == v2.getAction( v1 ).equals( intent.getAction() ))
         获取结果 v0
   move-result v0
         如果 v0 不等于v1 ,结束 return
   if-nez v0, :cond_0
         /*
                   if(!vo.equals(intent.getAction())) {
           return;
       }
*/
   :goto_0
   return-void
 
   :cond_0
   invoke-static {},Lcn/kuaipan/android/KuaipanApplication;->a()Lcn/kuaipan/android/KuaipanApplication;
 
   move-result-object v0
 
   invoke-virtual {v0}, Lcn/kuaipan/android/KuaipanApplication;->d()V
 
   const/16 v0, 0x3ed
 
   invoke-static {p1, v0},Lcn/kuaipan/android/notification/a;->a(Landroid/content/Context;I)V
         (静态调用 KuaipanApplication.a() return Lcn/kuaipan/android/KuaipanApplication可以看出是一个单列 通过 v0 当前栈调用 d method ,然后 Lcn/kuaipan/android/notification/a的 a方法( context , int ) 可以看出来是一个窗口调用这里认为是 Notification )    
        
 
   new-instance v0, Landroid/content/Intent;
 
   const-class v1, Lcn/kuaipan/android/home/LogoActivity;
 
   invoke-direct {v0, p1, v1},Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V
 
   const-string v1, "LogoActivity.skip_logo"
 
   invoke-virtual {v0, v1, v2},Landroid/content/Intent;->putExtra(Ljava/lang/String;Z)Landroid/content/Intent;
 
   const-string v1, "goto_login"
 
   invoke-virtual {v0, v1, v2},Landroid/content/Intent;->putExtra(Ljava/lang/String;Z)Landroid/content/Intent;
 
   const/high16 v1, 0x1000
 
   invoke-virtual {v0, v1}, Landroid/content/Intent;->setFlags(I)Landroid/content/Intent;
 
   invoke-static {p1},Lcn/kuaipan/android/utils/l;->d(Landroid/content/Context;)Z
 
   move-result v1
         (
Intent vo = newIntent(Landroid/content/Context, LogoActivity.skip_logo);
        vo.putExtra(Ljava/lang/String, Bool);
        vo.putExtra(Ljava/lang/String, Bool);
        vo.setFlags(Int);
Lcn/kuaipan/android/utils/l.d(Landroid/content/Context;)return bool;
 
)
//if 不等于 v1也就是  Lcn/kuaipan/android/utils/l.d(Landroid/content/Context;)dao cond_1
   if-eqz v1, :cond_1
        
   invoke-static {p1, v3, v2},Landroid/widget/Toast;->makeText(Landroid/content/Context;II)Landroid/widget/Toast;
 
   move-result-object v1
 
   invoke-virtual {v1}, Landroid/widget/Toast;->show()V
 
   const/high16 v1, 0x400
 
   invoke-virtual {v0, v1},Landroid/content/Intent;->addFlags(I)Landroid/content/Intent;
 
   invoke-virtual {p1, v0},Landroid/content/Context;->startActivity(Landroid/content/Intent;)V
 
   goto :goto_0
 
   :cond_1
   const-string v1, "android.intent.action.MAIN"
 
   invoke-virtual {v0, v1},Landroid/content/Intent;->setAction(Ljava/lang/String;)Landroid/content/Intent;
 
   const-string v1, "android.intent.category.LAUNCHER"
 
   invoke-virtual {v0, v1},Landroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;
 
   const/4 v1, 0x0
 
   const/high16 v2, 0x4000
 
    invoke-static{p1, v1, v0, v2},Landroid/app/PendingIntent;->getActivity(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
 
   move-result-object v0
 
   new-instance v1, Lcn/kuaipan/android/notification/a;
 
   invoke-direct {v1, p1, v3},Lcn/kuaipan/android/notification/a;-><init>(Landroid/content/Context;I)V
 
   invoke-virtual {v1, v0},Lcn/kuaipan/android/notification/a;->a(Landroid/app/PendingIntent;)Lcn/kuaipan/android/notification/a;
 
   move-result-object v0
 
   const/16 v1, 0x3e9
 
   invoke-virtual {v0, v1},Lcn/kuaipan/android/notification/a;->c(I)Lcn/kuaipan/android/notification/a;
 
   goto :goto_0
.end method
 
if (Lcn/kuaipan/android/utils/l.d(Landroid/content/Context;)) {
           Landroid/widget/Toast;->makeText(Landroid/content/Context;II)Landroid/widget/Toast)                    .show();
           i.addFlags(l);
          Landroid/content/Context.startActivity(Landroid/content/Intent;)V
} else {
 
           Landroid/content/Intent;->setAction(Ljava/lang/String;)Landroid/content/Intent;
           Landroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;
           P…….
       }


 

 

总结:需要对照此类里包含的L文件才能完全还原。混淆方法大概意思根据编码的流程大致能拆出来。还原个80%左右应该不是问题,问题是时间上是否允许,结合class。JAR文件还能解析出传递的参数。Jar里是int对应的R里的值String的值最终都是int类型

 

 

public class AuthExpiredReceiver extends BroadcastReceiver {
  public void onReceive(Context context, Intent intent) {
    Config xxx = ConfigFactory.getConfig(context);
    final String xxx 1= xxx.getAction(IAccountServiceDef.ACTION_POSTFIX_AUTH_FAILED);
    if (!xxx1.equals(intent.getAction())) {
      return;
    }
    Lcn/kuaipan/android/KuaipanApplication.getInstance().d();
    Lcn/kuaipan/android/notification/.a(Landroid/content/Context;I)V
    Intent vo = new Intent(Landroid/content/Context, LogoActivity.skip_logo);
    vo.putExtra(Ljava/lang/String, Bool);
    vo.putExtra(Ljava/lang/String, Bool);
    vo.setFlags(Int);
    if (Lcn/kuaipan/android/utils/l.d(Landroid/content/Context;) ) {
      Landroid/widget/Toast.makeText(Landroid/content/Context;II).show();
      i.addFlags(l);
      Landroid/content/Context.startActivity(Landroid/content/Intent;)
    } else {
      Landroid/content/Intent.setAction(Ljava/lang/String;);
      Landroid/content/Intent.addCategory(Ljava/lang/String;);
      P…….
    }

  }
}


配上一个 学习的网址 http://blog.youkuaiyun.com/caszhao/article/details/6028874

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值