美文网首页Android好文收录ida
简单的Android crackme IDA爆破签名验证

简单的Android crackme IDA爆破签名验证

作者: h080294 | 来源:发表于2018-05-08 19:08 被阅读74次

之前的几个小练习都是停留在smali层,今天尝试使用IDA分析修改一个so。

简单的安装体验一下,只有一个登陆页面。输入用户名和密码点击登录然后弹对应的toast。

一、首先反编译apk

代码很简单,只有一个注册按钮的点击事件,然后在里面调用了一个myJNI.check的native方法:

public class MainActivity
  extends AppCompatActivity
{
  EditText User_Name;
  EditText User_Pass;
  Context ct = this;
  myJNI mj = new myJNI();
  
  protected void onCreate(Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    setContentView(2130968603);
    this.User_Name = ((EditText)findViewById(2131427416));
    this.User_Pass = ((EditText)findViewById(2131427417));
    ((Button)findViewById(2131427418)).setOnClickListener(new View.OnClickListener()
    {
      public void onClick(View paramAnonymousView)
      {
        Toast.makeText(MainActivity.this, MainActivity.this.mj.check(MainActivity.this.ct, MainActivity.this.User_Name.getText().toString().trim(), MainActivity.this.User_Pass.getText().toString().trim()), 0).show();
      }
    });
  }
}

public class myJNI
{
  static
  {
    System.loadLibrary("JniTest");
  }
  
  public native String check(Object paramObject, String paramString1, String paramString2);
}

重新打包安装再试一下,点击登录后直接闪退了,说明在so层做了某种验证。

二、分析so

找到JniTest.so文件,丢进IDA中。先简单介绍下IDA的两个窗口
1、Exports窗口是导出表(so中能让外部调用的函数)
2、Imports窗口是导入表(so调用到外面的函数)

这里因为我们知道了在Java层调用了一个check方法,因此我们在Exports导出表窗口中搜索check,就能定位到我们需要的函数了:Java_demo2_jni_com_myapplication_myJNI_check。

点击函数后按下空格键,就能看到其流程图了。

不过我们发现有个别的地方是识别的不是很好,我们手动修复一下。


#完整的代码

text:00000EB8                 EXPORT Java_demo2_jni_com_myapplication_myJNI_check
.text:00000EB8 Java_demo2_jni_com_myapplication_myJNI_check
.text:00000EB8                                         ; DATA XREF: LOAD:000001FC↑o
.text:00000EB8
.text:00000EB8 userPassword    =  0
.text:00000EB8
.text:00000EB8 ; __unwind {
.text:00000EB8                 PUSH.W          {R4-R8,LR}
.text:00000EBC                 MOV             R4, R0
.text:00000EBE                 MOV             R7, R3
.text:00000EC0                 BL              getSignature
.text:00000EC4                 LDR             R2, [R4]
.text:00000EC6                 LDR.W           R3, [R2,#0x2A4]
.text:00000ECA                 MOVS            R2, #0
.text:00000ECC                 MOV             R1, R0
.text:00000ECE                 MOV             R0, R4
.text:00000ED0                 BLX             R3
.text:00000ED2                 LDR             R2, [R4]
.text:00000ED4                 MOV             R1, R7
.text:00000ED6                 LDR.W           R5, [R2,#0x2A4]
.text:00000EDA                 MOVS            R2, #0
.text:00000EDC                 MOV             R6, R0
.text:00000EDE                 MOV             R0, R4
.text:00000EE0                 BLX             R5
.text:00000EE2                 LDR             R3, [R4]
.text:00000EE4                 LDR             R1, [SP,#0x18+userPassword]
.text:00000EE6                 MOVS            R2, #0
.text:00000EE8                 LDR             R5, =(aJniLog - 0xEF2)
.text:00000EEA                 LDR.W           R3, [R3,#0x2A4]
.text:00000EEE                 ADD             R5, PC  ; "JNI_LOG"
.text:00000EF0                 MOV             R8, R0
.text:00000EF2                 MOV             R0, R4
.text:00000EF4                 BLX             R3
.text:00000EF6                 LDR             R2, =(aJniS - 0xF00)
.text:00000EF8                 MOV             R1, R5
.text:00000EFA                 MOV             R3, R6
.text:00000EFC                 ADD             R2, PC  ; "JNI获取到的签名是%s"
.text:00000EFE                 MOV             R7, R0
.text:00000F00                 MOVS            R0, #4
.text:00000F02                 BLX             __android_log_print
.text:00000F06                 LDR             R1, =(a308201dd308201 - 0xF0E)
.text:00000F08                 MOV             R0, R6  ; s1
.text:00000F0A                 ADD             R1, PC  ; "308201dd30820146020101300d06092a864886f"...
.text:00000F0C                 BLX             strcmp
.text:00000F10                 CBNZ            R0, loc_F2E
.text:00000F12                 LDR             R2, =(asc_23A6 - 0xF1C)
.text:00000F14                 MOV             R1, R5
.text:00000F16                 MOVS            R0, #4
.text:00000F18                 ADD             R2, PC  ; "签名一致"
.text:00000F1A                 BLX             __android_log_print
.text:00000F1E                 LDR             R1, =(aKoudai - 0xF26)
.text:00000F20                 MOV             R0, R8  ; s1
.text:00000F22                 ADD             R1, PC  ; "koudai"
.text:00000F24                 BLX             strcmp
.text:00000F28                 LDR             R5, [R4]
.text:00000F2A                 CBZ             R0, loc_F40
.text:00000F2C                 B               loc_F58
.text:00000F2E ; ---------------------------------------------------------------------------
.text:00000F2E
.text:00000F2E loc_F2E                                 ; CODE XREF: Java_demo2_jni_com_myapplication_myJNI_check+58↑j
.text:00000F2E                 LDR             R2, =(asc_23BA - 0xF38)
.text:00000F30                 MOVS            R0, #4
.text:00000F32                 MOV             R1, R5
.text:00000F34                 ADD             R2, PC  ; "签名不一致 退出程序"
.text:00000F36                 BLX             __android_log_print
.text:00000F3A                 MOVS            R0, #0  ; status
.text:00000F3C                 BLX             exit
.text:00000F40 ; ---------------------------------------------------------------------------
.text:00000F40
.text:00000F40 loc_F40                                 ; CODE XREF: Java_demo2_jni_com_myapplication_myJNI_check+72↑j
.text:00000F40                 LDR             R1, =(aBlack - 0xF48)
.text:00000F42                 MOV             R0, R7  ; s1
.text:00000F44                 ADD             R1, PC  ; "black"
.text:00000F46                 BLX             strcmp
.text:00000F4A                 CBNZ            R0, loc_F58
.text:00000F4C                 LDR             R1, =(asc_23DD - 0xF58)
.text:00000F4E                 MOV             R0, R4
.text:00000F50                 LDR.W           R3, [R5,#0x29C]
.text:00000F54                 ADD             R1, PC  ; "登陆成功"
.text:00000F56                 B               loc_F62
.text:00000F58 ; ---------------------------------------------------------------------------
.text:00000F58
.text:00000F58 loc_F58                                 ; CODE XREF: Java_demo2_jni_com_myapplication_myJNI_check+74↑j
.text:00000F58                                         ; Java_demo2_jni_com_myapplication_myJNI_check+92↑j
.text:00000F58                 LDR             R1, =(asc_23EA - 0xF64)
.text:00000F5A                 MOV             R0, R4
.text:00000F5C                 LDR.W           R3, [R5,#0x29C]
.text:00000F60                 ADD             R1, PC  ; "登陆失败"
.text:00000F62
.text:00000F62 loc_F62                                 ; CODE XREF: Java_demo2_jni_com_myapplication_myJNI_check+9E↑j
.text:00000F62                 BLX             R3
.text:00000F64                 POP.W           {R4-R8,PC}
.text:00000F64 ; End of function Java_demo2_jni_com_myapplication_myJNI_check

最终得到比较容易识别的代码。这里我们可以很明显的看到调用了一个getSignature方法,并在00000F0C位置与一个字符串做对比。接下来看00000F10位置的CBNZ操作,这里判断如果签名信息一致,则进入loc_F2E分支最后执行exit退出app。

还是简单的介绍下这个指令:

名字 功能
CBZ 比较,如果结果为零(Zero)就转移(只能跳到后面的指令)
CBNZ 比较,如果结果非零(Non Zero)就转移(只能跳到后面的指令)

看到这儿,我们就有思路了,想要要过签名验证,我们只需要把CBNZ指令改成CBZ就可以了。查看对应的16进制:

通过查找对应的指令码,我们把B9修改成B1:

然后返回到反编译页面,就能看到我们成功的把CBNZ指令改成了CBZ。这样,即便签名不一致,也不会执行退出app的逻辑

保存修改,重新打包app,这时候再次点击登录按钮,边不会出现退出app的情况了。

我们再进一步,想要输入其他任意用户名和密码也能弹出成功登录的toast。

text:00000F2A CBZ R0, loc_F40这里对用户名做了判断,如果不等于“koudai”,则跳转loc_F58分支最后展示登陆失败。同样的道理,我们把指令由CBZ改成CBNZ,让分支跳转到loc_F40。

.text:00000F4A CBNZ R0, loc_F58,这里对用户密码做了验证,如果不等于"black",则跳转loc_F58分支最后展示登陆失败。这里我们把CBNZ指令改成CBZ。最后重新打包apk,输入任意用户名和密码测试一下:

Demo apk文件
链接: https://pan.baidu.com/s/1sHUvgo3twq7uAVXfTN2I5Q
密码: e3t6


关注获取更多

相关文章

网友评论

本文标题:简单的Android crackme IDA爆破签名验证

本文链接:https://www.haomeiwen.com/subject/tbqwrftx.html