170717 逆向-Smali函数分析

来源:互联网 发布:c语言错误提示 编辑:程序博客网 时间:2024/05/16 08:30

1625-5 王子昂 总结《2017年7月17日》 【连续第288天总结】
A. Smali函数分析
B.
Smali中函数的调用:
  函数和成员变量一样也分为两种类型,分别为direct和virtual之分
  简单来说,direct method就是private函数,其余的public和protect函数都属于virtual method
  所以在调用函数时,有invoke-direct,invoke-virtual,另外还有invoke-static,invoke-super和invoke-interface等不同的指令
  当参数多于4个时,需要使用invoke-xxx/range,比较少见

  invoke-static:
    调用static函数

    invoke-static {},Lcom/aaa;->CheckSignature()Z

    {}内其实是调用方法的实例+参数列表,由于这个方法既不需参数也是static的,所以{}内为空
    

    const-string v0,"NDKLIB"    invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V

    这里调用static void System.loadLibrary(String)来加载NDK编译的so库用的方法,参数是v0即”NDKLIB”
    
  invoke-super:
    调用父类方法所使用的指令,一般用于调用onCreate,onDestroy等方法
  invoke-direct:
    调用private函数

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

    这里< init>()就是定义在TabActivity中的一个private函数
    
  invoke-virtual:
    调用public和protect函数,同样注意修改smali时不要错用invoke-direct或invoke-static

sget-object v0,Lcom/dddd;->bbb:Lcom/ccc;        invoke-virtual {v0,v1},Lcom/ccc;->Messages(Ljava/lang/Object;)V

    这里v0是bbb:Lcom/ccc,v1是传递给Messages方法的Ljava/lang/Object参数
    
  invoke-xxxxx/range:
    当方法的参数多于4个时,不能直接使用上述指令,而要在之后加上/range,它表示范围

    invoke-direct/range {v0 .. v5},Lcmb/pb/ui/PBContainerAcitivity;->h(Ljava/lang/CharSequence;Ljava/lang/String;Landroid/content/Intent;I)Z

    需要传递v0到v5一共6个参数,这时候大括号内的参数使用省略形式,并且需要连续
    
返回结果的指令:
  在JAVA代码中调用函数和返回函数结果可以用一条语句完成,而在Smali中则需要分开
  在使用上述指令以后,如果调用的函数返回非void,那么还需要使用move-result(返回基本数据类型)和move-result-
  object(返回对象)指令:
  

    const-string v0,"Eric"      invoke-static {v0},Lcmb/pbi;->t(Ljava/lang/String;)Ljava/lang/String;      move-result-object v2

    这里v2保存的就是调用t方法返回的String字符串
    
if函数分析:
  

     .method private ifRegistered()Z        .locals 2  //在这个函数中本地寄存器的个数        .prologue        const/4 v0,0x1  //v0赋值为1        .local v0,tempFlag:Z        if-eqz v0, :cond_0  //判断v0是否为0,等于0则跳到cond_0        const/4 v1,0x1  //符合条件分支        :goto_0  //标签        return v1  //返回v1的值        :cond_0  //标签        const/4 v1,0x0  //cond_0分支        goto:goto_0  //跳到goto_0执行,即返回v1的值,这里可以改成return v1,是一样的      .end method

  for函数分析:
  

     const/4 v0,0x0  //v0=0      .local v0,i:I      :goto_0      if-lt v0,v3, :cond_0  //v0小于v3则跳到cond_0并执行分支      return-void      :cond_0      iget-object v1,p0,Lcom/aaa/MainActivity;->listString:Ljava/util/List;  //引用对象      const-string v2,"Eric"      invoke-interface {v1,v2},Ljava/util/List;->add(Ljava/lang/Object;)z  //List是接口,执行接口方法add          add-int/lit8 v0,v0,0x1  //将第二个v0寄存器中的值,加上1后放入第一个寄存器中,实现自增          goto:goto_0

习题:翻译代码
  

    .locals 4      const/4 v2,0x1  //4字节常量v2=1      const/16 v1,0x10  //16字节常量v1=0x10      .local v1,"length";l  //令本地寄存器int length=v1      if-nez v1,:cond_1  //v1!=0时跳转至cond_1      :cond_0        :goto_0        return v2        :cond_1        const/4 v0,0x0  //v0=0      .local v0,"i":l  //本地寄存器int i=v0      :goto_1        if-lt v0,v1, :cond_2  //v0小于v1时跳转至cond_2      const/16 v3,0x28  //v3=0x28      if-le v1,v3, :cond_0  //v1小于等于v3时跳转至cond_0      const/4 v2,0x0  //v2=0      goto:goto_0  //跳转至goto_0      :cond_2        xor-int/lit8 v1,v1,0x3b  //v1=v1^0x3b      add-int/lit8 v0,v0,0x1  //v0=v0+1      goto:goto_1  //跳转至goto_1

 
java代码为:

v2=1;    int length=16;    int i=0;    if(length!=0)    {      for(i=0;i< length;i++)      {        length=length^0x3b;      }      if(length>0x28)        v2=0    }    return v2;

C.明日计划
ZigBee学习
安卓学习