ZhengY 发表于 2020-5-27 13:20

大佬教我学逆向-第三周(Apk去除权限、签名校验)

本帖最后由 ZhengY 于 2020-5-27 19:00 编辑

#### 前言
##### 1. 为什么要写这个系列
分享新手学习逆向的过程,作为一个逆向小白,只知道要学的东西很多,却不怎么从哪儿开始学怎么学,现在在大佬的带领下在大佬的系统的教导下会节省很多摸索的时间,所以分享学习的一些东西与过程,让学习之路更平旦一点

##### 2. 学习逆向之前需要具备的能力

熟练掌握Java、基础逆向工具会使用、xposed/cydia Substrate会用、smali语法了解、C语言能看懂

上述技能应该是逆向的最基础的

##### 3. 为啥直接第三周

因为第一周的太简单(c/c++代码编译时、函数名的编译规则)、第二周又太难(一个带壳加密的apk)

第三周依大佬的话就是让找回自信的

##### 4. 第一、二周链接
https://www.52pojie.cn/thread-1188071-1-1.html
#### 要求
一个基础的逆向修改,去掉此 apk 的READ_PHONE_STATE权限

#### 技术点
-混淆代码阅读
-smali代码简单修改

#### 个人思路与做法 (针对6.0以上动态请求权限)

1. 找到请求权限位置并去除 android.permission.READ_PHONE_STATE 权限


全局搜索android.permission.READ_PHONE_STATE







定位到com.chaozhuo.texteditor.activity.TextEditorMainActivity.onCreate(Bundle bundle)方法中







Apktool解包、修改对应smali 将 "android.permission.READ_PHONE_STATE"置为空










重打包签名,然后就遇到如下的签名校验问题







首先去搜索PackageInfo.signatures 方法是否调用,没找到。
然后尝试去看onCreate方法中的逻辑,混淆后太难看不好分析放弃,
然后准备从显示的dialog方面入手,多次测试发现点击按钮后退出,
此时准备从Activity的finish()方法找到入口,还是没找到。
最后想到既然要显示dialog就从dialog的方法入手



直接通过Xposed hook show方法在其中进行异常操作




```
XposedHelpers.findAndHookMethod(Dialog.class, "show", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                  String a = (String) param.args;
                  a.toString();
                  
                }
            });
      }
```

下面是异常日志

```
java.lang.ArrayIndexOutOfBoundsException: length=0; index=1
      at com.xposed.HookUtil$2.afterHookedMethod(HookUtil.java:49)
      at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:645)
      at android.app.Dialog.show(Native Method)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:515)
      at com.chaozhuo.texteditor.widget.a.a(ARHelper.java:203)
      at com.chaozhuo.texteditor.widget.b.onPostExecute(ARHelper.java:68)
      at android.os.AsyncTask.finish(AsyncTask.java:632)
      at android.os.AsyncTask.access$600(AsyncTask.java:177)
      at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:136)
      at android.app.ActivityThread.main(ActivityThread.java:5034)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:515)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
      at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
      at dalvik.system.NativeStart.main(Native Method)


```


定位到com.chaozhuo.texteditor.widget.a.a方法



```

package com.chaozhuo.texteditor.widget;

import android.content.Context;
import android.util.Base64;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/* compiled from: ARHelper */
public final class a {

static boolean a(Context context) {
      try {
            String str;
            byte[] a = a((byte[]) a(((Object[]) b(a(a(context, a("Z2V0UGFja2FnZU1hbmFnZXI=")), a("Z2V0UGFja2FnZUluZm8="), (String) a(context, a("Z2V0UGFja2FnZU5hbWU=")), String.class, Integer.valueOf(64), Integer.TYPE), a("c2lnbmF0dXJlcw=="))), a("dG9CeXRlQXJyYXk=")));
            if (a == null) {
                str = null;
            } else {
                StringBuilder stringBuilder = new StringBuilder(a.length * 2);
                for (byte b : a) {
                  stringBuilder.append("0123456789abcdef".charAt((b >> 4) & 15));
                  stringBuilder.append("0123456789abcdef".charAt(b & 15));
                }
                str = stringBuilder.toString();
            }
            if (str.equals(a("YmUwZGQyYmM4ZmEzYjUzNDI0MWY5MWY4YjY2ZDFjNTA=")) || str.equals(a("YzY1ZmUxNmFlOWYyNDkzZDdhNTA2MWEwMTk3MTVkMWY="))) {
                return true;
            }
            return false;
      } catch (Exception e) {
            return true;
      }
    }

static final String a(String str) {
      return new String(Base64.decode(str, 0));
    }
...
}

```

一看明白了 Base64加密,先验证下 hook a(String str)方法,打印出解密前数据和解密数据


```
05-14 09:28:50.124 2054-2095/? E/@@@@: widget
    widget a : param - Z2V0UGFja2FnZU1hbmFnZXI= rst : getPackageManager
    widget a : param - Z2V0UGFja2FnZU5hbWU= rst : getPackageName
    widget a : param - Z2V0UGFja2FnZUluZm8= rst : getPackageInfo
    widget a : param - c2lnbmF0dXJlcw== rst : signatures
05-14 09:28:50.134 2054-2095/? E/@@@@: widget a : param - dG9CeXRlQXJyYXk= rst : toByteArray
    widget a : param - YmUwZGQyYmM4ZmEzYjUzNDI0MWY5MWY4YjY2ZDFjNTA= rst : be0dd2bc8fa3b534241f91f8b66d1c50
    widget a : param - YzY1ZmUxNmFlOWYyNDkzZDdhNTA2MWEwMTk3MTVkMWY= rst : c65fe16ae9f2493d7a5061a019715d1f
05-14 09:28:50.274 2054-2054/? E/@@@@: widget a : param - YW5kcm9pZC5hcHAuQWxlcnREaWFsb2ckQnVpbGRlcg== rst : android.app.AlertDialog$Builder
    widget a : param - c2V0VGl0bGU= rst : setTitle
    widget a : param - c2V0TWVzc2FnZQ== rst : setMessage
    widget a : param - 5qOA5rWL5Yiw5oKo5omA5L2/55So55qE6L2v5Lu25LiN5piv5Yek5Yew5bel5L2c5a6k55qE5a6Y5pa55q2j54mI6L2v5Lu277yM5pyJ5Y+v6IO96KKr5qSN5YWl5LqG5oG25oSP5Luj56CB77yM5L615a6z5oKo55qE6K6+5aSH5oiW6ICF6ZqQ56eB77yM5bu66K6u5oKo5Y675Yek5Yew5bel5L2c5a6k55qE5a6Y572R5LiL6L295q2j54mI6L2v5Lu277yM5bm25Zyo6K665Z2b5Li+5oql5q2k54mI5pys44CCd3d3LnBob2VuaXhzdHVkaW8ub3Jn rst : 检测到您所使用的软件不是凤凰工作室的官方正版软件,有可能被植入了恶意代码,侵害您的设备或者隐私,建议您去凤凰工作室的官网下载正版软件,并在论坛举报此版本。www.phoenixstudio.org
    widget a : param - c2V0UG9zaXRpdmVCdXR0b24= rst : setPositiveButton
    widget a : param - c2V0T25EaXNtaXNzTGlzdGVuZXI= rst : setOnDismissListener
    widget a : param - Y3JlYXRl rst : create
    widget a : param - Z2V0V2luZG93 rst : getWindow
    widget a : param - c2V0QmFja2dyb3VuZERyYXdhYmxlUmVzb3VyY2U= rst : setBackgroundDrawableResource
    widget a : param - c2hvdw== rst : show
```

ok 确实是Base64加密导致直接全局搜索不到



修改:以下就是验证签名的地方,只需要修改让永远返回true就可以了

```
      if (str.equals(a("YmUwZGQyYmM4ZmEzYjUzNDI0MWY5MWY4YjY2ZDFjNTA=")) || str.equals(a("YzY1ZmUxNmFlOWYyNDkzZDdhNTA2MWEwMTk3MTVkMWY="))) {
                return true;
            }

```

#### 原Apk文件

链接: https://pan.baidu.com/s/1Ao28Zzveqa20Xci4HXZN8w 提取码: kvc7

ZhengY 发表于 2020-5-27 15:44

alexkaer 发表于 2020-5-27 15:25
前两周的也分享分享, 我也想要个大佬带

可以,后面我补一个第一周第二周的 , 但是第二周的到现在都没做出来。。。

ZhengY 发表于 2020-5-27 14:12

田田爱崽崽 发表于 2020-5-27 14:06
请问有xposed hook这方面的教程吗?

xposed网上很多资料了啊基础使用基本都能搜到

老婆是加藤惠 发表于 2020-5-27 13:23

收藏点赞退出

第一品霄 发表于 2020-5-27 13:26

学习一下了

飞天蜗牛 发表于 2020-5-27 13:33

学习,感谢楼主

Black_山猫 发表于 2020-5-27 13:37

感谢分享

键盘上的舞者 发表于 2020-5-27 13:59

适合新手嘛

田田爱崽崽 发表于 2020-5-27 14:06

请问有xposed hook这方面的教程吗?

ZhengY 发表于 2020-5-27 14:11

键盘上的舞者 发表于 2020-5-27 13:59
适合新手嘛

我觉得是适合有点基础想要进阶的新手

田田爱崽崽 发表于 2020-5-27 14:27

ZhengY 发表于 2020-5-27 14:12
xposed网上很多资料了啊基础使用基本都能搜到

好的,谢谢指导。
页: [1] 2 3 4
查看完整版本: 大佬教我学逆向-第三周(Apk去除权限、签名校验)