【Android逆向】破解黑宝宝apk,绕过签名校验

android,逆向,破解,宝宝,apk,绕过,签名,校验 · 浏览次数 : 55

小编点评

The context describes the steps for modifying an APK file and installing it on a mobile device. Here's a summary: **Step 1:** * Get the source code of the APK file. **Step 2:** * Find the section in the APK file that contains the code responsible for handling login. * This might be the `loc_F2E` or `loc_F40` section. **Step 3:** * Modify the code in the chosen section to change the login behavior or restrictions. * This could involve changing the condition for launching the login activity, the username and password comparison, or other relevant logic. **Step 4:** * Save the modified APK file. **Step 5:** * Use an APK editor or a tool that allows you to modify APK files to recompile and re-sign the APK. * Ensure that you select the correct sections and file paths for modification. **Step 6:** * Install the modified APK file on the mobile device. * Launch the application and try logging in. **Step 7:** * Verify that the login is successful and the user can access the app's features. **Additional Notes:** * Be careful when modifying APK files, as changing them may break the functionality of the application. * Be aware of the legal and ethical implications of modifying APK files. * Only modify files and settings that you have permission to modify.

正文

这是52pojie的一道题,实现输入任何密码都可以登录成功

他知道你最近在学习Android逆向 他想在游戏上线前让你测试一下他新加的签名验证是否能防住别人的破解。
下面是李华编写的黑宝宝apk
链接:https://pan.baidu.com/s/1h6pX2ARE3qtiKiYbcnJ-3g 密码:duv5

1. apk拖入到jadx中, 关键逻辑

//MainActivity.java
        Button_regist.setOnClickListener(new View.OnClickListener() { // from class: demo2.jni.com.myapplication.MainActivity.1
            @Override // android.view.View.OnClickListener
            public void onClick(View view) {
                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();
            }
        });
//myJNI.java
public class myJNI {
    public native String check(Object obj, String str, String str2);

    static {
        System.loadLibrary("JniTest");
    }
}

2. 看来答案在JniTest.so中,将so拖入到idapro中,稍微整理一下代码,反汇编可得

整理步骤:
1. 入参重命名, a1 改为  JNIEnv *env 等
2. 对于显示位乱码的数据,或者展示不出来的,多半可能是中文,可以按住alt+A键打开ASCII string style窗口
然后点击set default encodings 在弹出框中选择8-bit的change 选择utf-8后点击ok回到c语言界面按f5刷新一下界面 乱码问题解决

反汇编代码

int __fastcall Java_demo2_jni_com_myapplication_myJNI_check(
        JNIEnv *env,
        jobject object,
        int context,
        int username,
        int password)
{
  void *Signature; // r0
  const char *v8; // r6
  const char *v9; // r8
  const char *v10; // r7
  int v11; // r0
  JNIEnv v12; // r5

  Signature = (void *)getSignature(env, object, context);
  v8 = (*env)->GetStringUTFChars(env, Signature, 0);
  v9 = (*env)->GetStringUTFChars(env, username, 0);
  v10 = (*env)->GetStringUTFChars(env, password, 0);
  _android_log_print(4, "JNI_LOG", aJni, v8);
  if ( !strcmp(
          v8,
          "308201dd30820146020101300d06092a864886f70d010105050030373116301406035504030c0d416e64726f6964204465627567311030"
          "0e060355040a0c07416e64726f6964310b3009060355040613025553301e170d3138303332313033303431385a170d3438303331333033"
          "303431385a30373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b30090603"
          "5504061302555330819f300d06092a864886f70d010101050003818d00308189028181008270f53e2cf8c7d7ed200863deb85a054defde"
          "773be0b848ee792839d9a81da098dd9b74bbb9679c19ea30b63fe3bb74aabb270a5c9b3359ebe3fdf278b82fe576a6677f0d77f0eb5b08"
          "8d0711b15d03cadae08b3b980f28055d0cde4bbc4a0b4b208b0f30f170b6ea77a8620269fa1d375442653663e1dd41293aa1c4910e3502"
          "03010001300d06092a864886f70d010105050003818100044b9ab7e85346a147926c2d1c6c30e8ffcce174f88acb9763cb776fb1f4dd62"
          "183c9524346738ff1aea16c5fa218c68da76d05a2422aee12fc23563b5e28925c3d96dff855a584fc1ec462aa768277bd25739085d52fe"
          "3fedfd396e38180c13fbb289786e524535933dd8a99ed3154880544f3e41f044acc43ceefbbce3af59") )
  {
    _android_log_print(4, "JNI_LOG", byte_23BA);
    exit(0);
  }
  _android_log_print(4, "JNI_LOG", byte_23A6);
  v11 = strcmp(v9, "koudai");
  v12 = *env;
  if ( !v11 || !strcmp(v10, "black") )
    return (int)v12->NewStringUTF(env, byte_23EA);
  else
    return (int)v12->NewStringUTF(env, byte_23DD);
}

3. 这里可以看到,首先做了一个签名校验,那么只要我们重打包,必然运行失败,然后做了账号密码的校验

这里留的题目是输入任何密码都可以登录成功,那么我们可以看看汇编代码的条件处
.text:00000EB8
.text:00000EB8                               ; =============== S U B R O U T I N E =======================================
.text:00000EB8
.text:00000EB8
.text:00000EB8                               ; int __fastcall Java_demo2_jni_com_myapplication_myJNI_check(int *, int, int, int, int)
.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                               arg_0=  0
.text:00000EB8
.text:00000EB8                               ; __unwind {
.text:00000EB8 2D E9 F0 41                   PUSH.W          {R4-R8,LR}
.text:00000EBC 04 46                         MOV             R4, R0
.text:00000EBE 1F 46                         MOV             R7, R3
.text:00000EC0 FF F7 5C FF                   BL              getSignature
.text:00000EC0
.text:00000EC4 22 68                         LDR             R2, [R4]
.text:00000EC6 D2 F8 A4 32                   LDR.W           R3, [R2,#0x2A4]
.text:00000ECA 00 22                         MOVS            R2, #0
.text:00000ECC 01 46                         MOV             R1, R0
.text:00000ECE 20 46                         MOV             R0, R4
.text:00000ED0 98 47                         BLX             R3
.text:00000ED0
.text:00000ED2 22 68                         LDR             R2, [R4]
.text:00000ED4 39 46                         MOV             R1, R7
.text:00000ED6 D2 F8 A4 52                   LDR.W           R5, [R2,#0x2A4]
.text:00000EDA 00 22                         MOVS            R2, #0
.text:00000EDC 06 46                         MOV             R6, R0
.text:00000EDE 20 46                         MOV             R0, R4
.text:00000EE0 A8 47                         BLX             R5
.text:00000EE0
.text:00000EE2 23 68                         LDR             R3, [R4]
.text:00000EE4 06 99                         LDR             R1, [SP,#0x18+arg_0]
.text:00000EE6 00 22                         MOVS            R2, #0
.text:00000EE8 1F 4D                         LDR             R5, =(aJniLog - 0xEF2)  ; "JNI_LOG"
.text:00000EEA D3 F8 A4 32                   LDR.W           R3, [R3,#0x2A4]
.text:00000EEE 7D 44                         ADD             R5, PC                  ; "JNI_LOG"
.text:00000EF0 80 46                         MOV             R8, R0
.text:00000EF2 20 46                         MOV             R0, R4
.text:00000EF4 98 47                         BLX             R3
.text:00000EF4
.text:00000EF6 1D 4A                         LDR             R2, =(aJni - 0xF00)     ; "JNI"
.text:00000EF8 29 46                         MOV             R1, R5                  ; tag
.text:00000EFA 33 46                         MOV             R3, R6
.text:00000EFC 7A 44                         ADD             R2, PC                  ; "JNI" ; fmt
.text:00000EFE 07 46                         MOV             R7, R0
.text:00000F00 04 20                         MOVS            R0, #4                  ; prio
.text:00000F02 FF F7 CC EE                   BLX             __android_log_print
.text:00000F02
.text:00000F06 1A 49                         LDR             R1, =(a308201dd308201 - 0xF0E) ; "308201dd30820146020101300d06092a864886f"...
.text:00000F08 30 46                         MOV             R0, R6                  ; char *
.text:00000F0A 79 44                         ADD             R1, PC                  ; "308201dd30820146020101300d06092a864886f"...
.text:00000F0C FF F7 CC EE                   BLX             strcmp
.text:00000F0C
.text:00000F10 68 B9                         CBNZ             R0, loc_F2E
.text:00000F10
.text:00000F12 18 4A                         LDR             R2, =(byte_23A6 - 0xF1C)
.text:00000F14 29 46                         MOV             R1, R5                  ; tag
.text:00000F16 04 20                         MOVS            R0, #4                  ; prio
.text:00000F18 7A 44                         ADD             R2, PC                  ; byte_23A6 ; fmt
.text:00000F1A FF F7 C0 EE                   BLX             __android_log_print
.text:00000F1A
.text:00000F1E 16 49                         LDR             R1, =(aKoudai - 0xF26)  ; "koudai"
.text:00000F20 40 46                         MOV             R0, R8                  ; char *
.text:00000F22 79 44                         ADD             R1, PC                  ; "koudai"
.text:00000F24 FF F7 C0 EE                   BLX             strcmp
.text:00000F24
.text:00000F28 25 68                         LDR             R5, [R4]
.text:00000F2A 48 B1                         CBZ            R0, loc_F40
.text:00000F2A
.text:00000F2C 14 E0                         B               loc_F58
.text:00000F2C
.text:00000F2E                               ; ---------------------------------------------------------------------------
.text:00000F2E
.text:00000F2E                               loc_F2E                                 ; CODE XREF: Java_demo2_jni_com_myapplication_myJNI_check+58↑j
.text:00000F2E 13 4A                         LDR             R2, =(byte_23BA - 0xF38)
.text:00000F30 04 20                         MOVS            R0, #4                  ; prio
.text:00000F32 29 46                         MOV             R1, R5                  ; tag
.text:00000F34 7A 44                         ADD             R2, PC                  ; byte_23BA ; fmt
.text:00000F36 FF F7 B2 EE                   BLX             __android_log_print
.text:00000F36
.text:00000F3A 00 20                         MOVS            R0, #0                  ; int
.text:00000F3C FF F7 BA EE                   BLX             exit
.text:00000F3C
.text:00000F40                               ; ---------------------------------------------------------------------------
.text:00000F40
.text:00000F40                               loc_F40                                 ; CODE XREF: Java_demo2_jni_com_myapplication_myJNI_check+72↑j
.text:00000F40 0F 49                         LDR             R1, =(aBlack - 0xF48)   ; "black"
.text:00000F42 38 46                         MOV             R0, R7                  ; char *
.text:00000F44 79 44                         ADD             R1, PC                  ; "black"
.text:00000F46 FF F7 B0 EE                   BLX             strcmp
.text:00000F46
.text:00000F4A 28 B9                         CBNZ             R0, loc_F58
.text:00000F4A
.text:00000F4C 0D 49                         LDR             R1, =(unk_23DD - 0xF58)
.text:00000F4E 20 46                         MOV             R0, R4
.text:00000F50 D5 F8 9C 32                   LDR.W           R3, [R5,#0x29C]
.text:00000F54 79 44                         ADD             R1, PC                  ; unk_23DD
.text:00000F56 04 E0                         B               loc_F62
.text:00000F56
.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 0B 49                         LDR             R1, =(unk_23EA - 0xF64)
.text:00000F5A 20 46                         MOV             R0, R4
.text:00000F5C D5 F8 9C 32                   LDR.W           R3, [R5,#0x29C]
.text:00000F60 79 44                         ADD             R1, PC                  ; unk_23EA
.text:00000F60
.text:00000F62
.text:00000F62                               loc_F62                                 ; CODE XREF: Java_demo2_jni_com_myapplication_myJNI_check+9E↑j
.text:00000F62 98 47                         BLX             R3
.text:00000F62
.text:00000F64 BD E8 F0 81                   POP.W           {R4-R8,PC}
.text:00000F64
.text:00000F64                               ; End of function Java_demo2_jni_com_myapplication_myJNI_check

要修改的行

[1] 对应着签名条件的跳转
.text:00000F10 68 B9                         CBNZ             R0, loc_F2E
[2] 对应着username判断条件的跳转
.text:00000F2A 48 B1                         CBZ            R0, loc_F40
[3] 对应着password判断条件的跳转
.text:00000F4A 28 B9                         CBNZ             R0, loc_F58

查汇编与机器码对应关系可知
B9 对应 CBNZ
B1 对应 CBZ

那么只要把它们反过来就可以了

鼠标点住那行命令 View->Open subviews->Hex dump打开16进制编辑 ,
选中要改的机器码,按F2, 修改完毕后再按F2,表示修改完毕

4. 保存so的修改 : Edit -> Patch Program -> apply patch into file 进行保存

5. 对apk进行重打包,重签名,安装到手机,输入任何内容,显示登陆成功

与【Android逆向】破解黑宝宝apk,绕过签名校验相似的内容:

【Android逆向】破解黑宝宝apk,绕过签名校验

这是52pojie的一道题,实现输入任何密码都可以登录成功 他知道你最近在学习Android逆向 他想在游戏上线前让你测试一下他新加的签名验证是否能防住别人的破解。 下面是李华编写的黑宝宝apk 链接:https://pan.baidu.com/s/1h6pX2ARE3qtiKiYbcnJ-3g 密

【Android逆向】破解看雪 test1.apk

1. 获取apk,并安装至手机 apk 获取地址: https://www.kanxue.com/work-task_read-800624.htm adb install -t test1.apk # 这个apk必须加-t ,否则会报错 2. 只有一个输入框,随便输入内容,提示壮士继续加油 3.

【Android逆向】破解看雪test3.apk方案一

1. test3.apk 安装到手机 2. 发现其实际逻辑和之前的test2.apk基本一致,逆向so查看到加入了一些检查逻辑 代码: jstring __fastcall fuck(JNIEnv *env, jclass jcls, jstring str_) { ...... if ( !str

【Android逆向】破解看雪test3.apk方案二

方案二就是要hook那三个条件,不让追加字符串变成false v20 = "REAL"; clazz = _JNIEnv::FindClass(env, "android/os/Build"); fieldID = _JNIEnv::GetStaticFieldID(env, clazz, "FIN

【Android逆向】破解看雪9月算法破解第一题

1. 安装apk到手机 2. 随意输入账号和密码,点击register,报错crackme1:ERROR 3. 将apk拖入到jadx中进行观察 public native String register(String str); static { System.loadLibrary("nativ

【Android逆向】破解看雪9月算法破解第二题

1. apk安装到手机,一样的界面,随便输入一样的报错 2. apk拖入到jadx重看看 public native String sha1(String str); static { System.loadLibrary("native-lib"); } /* JADX INFO: Access

【Android逆向】破解看雪9月算法破解第三题

这题的目标是算法还原,并写出注册机 1. 9月份算法第一题.apk 安装到手机 2. 随意输入账号密码,提示错误 3. apk拖入到jadx中 public native boolean register(String str, String str2); static { System.loadL

【Android逆向】frida 破解 jwxdxnx02.apk

apk 路径: https://pan.baidu.com/s/1cUInoi 密码:07p9 这题比较简单,主要是用于练习frida 1. 安装apk到手机 需要输入账号密码 2. 使用jdax 查看apk package hfdcxy.com.myapplication; import andr

[Android逆向]Exposed 破解 jwxdxnx02.apk

使用exposed 遇到了一些坑,这里记录一下 源码: package com.example.exposedlesson01; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.X

[Android 逆向]frida 破解 切水果大战原版.apk

1. 手机安装该apk,运行,点击右上角礼物 提示 支付失败,请稍后重试 2. apk拖入到jadx中,待加载完毕后,搜素失败,找到疑似目标类MymmPay的关键方法payResultFalse 4. adb logcat 或者androidstudio 查看该进程的日志,发现以下日志 com.mf