大佬教我学逆向-第三周(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 alexkaer 发表于 2020-5-27 15:25
前两周的也分享分享, 我也想要个大佬带
可以,后面我补一个第一周第二周的 , 但是第二周的到现在都没做出来。。。 田田爱崽崽 发表于 2020-5-27 14:06
请问有xposed hook这方面的教程吗?
xposed网上很多资料了啊基础使用基本都能搜到 收藏点赞退出 学习一下了 学习,感谢楼主 感谢分享 适合新手嘛 请问有xposed hook这方面的教程吗?
键盘上的舞者 发表于 2020-5-27 13:59
适合新手嘛
我觉得是适合有点基础想要进阶的新手 ZhengY 发表于 2020-5-27 14:12
xposed网上很多资料了啊基础使用基本都能搜到
好的,谢谢指导。