autosignck(1.案例分析)

来源:互联网 发布:形状与抗弯曲能力数据 编辑:程序博客网 时间:2024/06/05 18:57

转自:
http://www.wjdiankong.cn/android%E9%80%86%E5%90%91%E4%B9%8B%E6%97%85-%E5%B8%A6%E4%BD%A0%E7%88%86%E7%A0%B4%E4%B8%80%E6%AC%BE%E5%BA%94%E7%94%A8%E7%9A%84%E7%AD%BE%E5%90%8D%E9%AA%8C%E8%AF%81%E9%97%AE%E9%A2%98/

一、前言

签名校验一般的两种方式:

第一种:签名校验不通过直接退出程序,也就是你会发现回编译二次打包运行失败的现象

第二种:签名校验不通过不触发程序指定逻辑,导致没有错误信息,也进不了应用的现象

第一种,比较好解决,因为这种签名校验的一般都在应用的入口处,所以直接在入口处加一些日志,通过打印日志就可以看到,入口一般是Application的onCreate方法和attachBaseContext方法。学到一个快速定位签名校验的方法的技巧:
全局搜索signatures字符串,因为我们知道如果要做签名验证,必须调用系统的一个api方法:getPackageManager().getPackageInfo(getPackageName(), 64).signatures,所以在用Jadx工具反编译apk之后,全局搜signatures字符串可以立马定位到签名校验的方法。

二、案例分析

我们下载游戏之后,可以利用apktool进行反编译,然后回编译重签名,安装运行:

游戏可以运行成功,但是卡在这里,进不了游戏了,这时候我们就猜想他可能有签名验证逻辑,可能放在本地,也有可能放在服务端,我们利用上面说到的那个技巧:在Jadx中全局搜”signatures”字符串内容:

这里写图片描述

推断有很多校验,发现卡在进度条,猜想和网络请求有关,所以通过Fiddler抓包分析请求信息:

这里写图片描述

游戏打开就这些请求,但是作为一个游戏不可能就这点请求的,这个也是卡住的原因,我们可以这么做,用一个正常的游戏在抓包看看情况:

这里写图片描述

这个是没有二次打包签名的请求信息,和上面二次打包签名之后的请求相比较,多了很多请求,可以发现有一个get_user_info这个接口比较特殊,所以我们可以去Jadx全局搜这个请求接口:

这里写图片描述

这里看到定义了url的地方,然后在全局Find Usage的地方:

这里写图片描述

点进去看方法调用:

public static void a(f fVar){    b.a(d.s,new HashMap(),new com.wepie,snake.module.b.b(fVar));}

继续查看这个方法的调用地方:

这里写图片描述

这里有四个地方调用这个方法,但是可以依次排除,最终定位到是com.wepie.snake.module.home.b.d.e()方法,那么下面来看一下如何进行排除的,可以从下往上排除,看最下面一个方法:

这里写图片描述
然后进入调用了b.a方法的l.a方法中查看逻辑:
这里写图片描述
这里其实是个请求,请求接口是d.r的值:

这里写图片描述

注意
1.由usage(get_user_info)知道public static final string s=(a+”user_api/get_user_info”);
2.由usage(s)知道b.a(d.s,new HashMap(),new com.wepie.snake.module.b.b(fvar));
3.由usage(b.a)知道四个方法;
4.查看其中一个com.wepie.snake.module.home.user.a.e():void 进入该方法看到其中的l.a();方法中查看逻辑:
使用了b.a(d.r,hashMap,new n(avar));
这里其实是个请求,请求接口是d.r的值:
public static final String r=(a+”user_api/update_user_info”);
另外,为什么查找全局变量时,不能直接使用“需要付款”,而是反编译后文件中的id或者valus文件中的对应“需要付款”的name值,难道是因为反编译后不存在“需要付款”字符,而是对应的资源id或者资源idname。另外同名的可以用type区分。估计反编译后的代码逻辑中字符串是使用资源id嵌入的,所以不能直接搜索。

看到是这个接口信息,但是我们在用Fiddler抓包的时候并没有看到这个请求,所以这个地方可以过滤了,其他三个地方的分析结果类似。所以通过这种方式定位到了方法调用的地方:

这里写图片描述

注意
好像并没有明显看到调用了d.a(s,,)啊!难道这就是排除法的原因?!

我们在查找这个e方法调用的地方:

这里写图片描述

在这里被调用了,通过调用结果发现,有第一个判断(判断没过停下了):

这里写图片描述

这里有一个字符串比较相等的逻辑,很有可能是比较签名信息的,可以查看h.a这个方法:

这里写图片描述

这里貌似有一个字符串的构造算法,我们为了看到最终的字符串内容,可以新建一个简单的Java项目,然后把这个方法打印一下看看结果:

这里写图片描述

看到这个最终生成的字符串内容是:678a930b9829b54a44f92a840916f7d1,然后再看一下equals的o.a的方法:

这里写图片描述

这个方法是获取应用签名信息的,然后用MD5计算结果。所以到这里我们就知道校验签名逻辑是,获取应用的签名信息,然后MD5一下,和”678a930b9829b54a44f92a840916f7d1“字符串进行比较。那么我们二次签名之后,这个判断肯定就是false了,所以后续的逻辑就不走了,没有后面的请求,发现卡在开始界面了。

那么问题找到了,改起来就比较简单了,直接反编译游戏,然后找到这个 com.wepie.snake.helper.f.o.a()方法对应的smali代码:

这里写图片描述

把这个方法直接返回”678a930b9829b54a44f92a840916f7d1“字符串即可。有的同学说这个怎么改?是手动编写samli代码吗?肯定不是的,咋们可以先写一个简单的返回这个字符串的方法,然后反编译得到这段smali代码就可以了,可千万别自己手动的去编写,除非你有这个耐心和毅力,反正我没有。替换完成之后,咋们就回编译,二次签名运行安装游戏,可惜的是还是卡住了,所以还得回去看代码:
这里写图片描述
这里写图片描述

咋们修改了一次签名校验方法,进入了第一层签名判断,继续往下看代码:

这里写图片描述

这里又有一个判断,点进去查看逻辑:

这里写图片描述

果然,这里又有了一次签名校验方法,所以还得手动的修改,修改方法和上面类似,把这个p方法改一下即可:

这里写图片描述

修改成功之后,再次回编译重签名安装运行,可惜的是还是卡住了,进不了游戏,这时候我们在次抓包看看:

这里写图片描述

这次比之前多了一个config_v3_android请求,但是还是没有get_user_info的请求!所以还得去看代码逻辑,不过从请求结果来看,我们之前的两次签名校验修改已经有效果了,继续看下面的代码:

这里写图片描述

这里可以看到,有一个设置进度条的逻辑,而且有一个tag=999的日志,貌似是取配置信息的进度条,那么我们可以查看这个日志信息:

这里写图片描述

看到了这个日志信息之后,发现有开始取config到获取成功config了,但是后面就没有日志了,所以这里猜想应该是在本地解析这个配置信息的时候还有判断,咋们全局搜一个字符串信息”getConfigAndroid“:

这里写图片描述
注意:
咋们全局搜一个字符串信息”getConfigAndroid“ 为什么log信息没有对应资源id或者name就可以直接搜索?!

第一条信息就是我们想要的,点击进入:

这里写图片描述

果然这里还有一个判断,进入查看:

这里写图片描述

又是一次签名校验的逻辑,好吧,还得再一次改这个com.wepie.snake.helper.b.a.i()方法了:

这里写图片描述

修改成功之后,再次回编译二次签名安装运行即可,这次终于运行成功,进入游戏界面了。