上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
12下一页
返回列表 发新帖

记一次逆向拆包的过程(一)

[复制链接]
  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    861

    回帖

    1360

    积分

    荣誉开发者

    积分
    1360

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-11-4 23:36:30 | 显示全部楼层 | 阅读模式

    最近想做个中国移动APP的签到脚本,研究了一下签到请求发现还挺复杂,涉及各种加密、反编译,遂记录此文,以作参考。
    首先是手机抓包,大体流程就是电脑抓包软件设置好代理端口,然后手机wifi连接代理,安装好证书就可以抓包了。详细流程网上都有,可以参考下论坛的这篇文章。这里也用Charles这个工具为例进行分析,注意关掉windows代理,只打开代理端口,这样只会抓手机上的包。抓取完整的签到流程后,点击“序列”,让请求按时间排序,从后往前找响应数据,可以看出这个是关键签到请求:
    https://wx.10086.cn/qwhdhub/api/mark/do/mark
    尝试在脚本里复现这个请求,注意尽可能带上一样的header,尤其是User-Agent,cookie我们先不带上。请求发出后,被重定向到下面这个登录请求(最好去脚本管理器的background页看实际请求):
    https://wx.10086.cn/qwhdsso/login?dlwmh=true&actUrl=https%3A%2F%2Fwx.10086.cn%2Fqwhdhub%2Fqwhdmark%2F1021122301
    这说明缺少cookie,服务端认为我们需要登录,而这个登录请求在我们前面抓的包里也能找到,其响应是一个html页面。html的代码里包含了基本的登录逻辑:
    1.png
    大致分析一下,将UID加密后发出一个chinaMobileApp的post请求,猜测该请求起到关键的登录验证。在登录请求和签到请求之间的包里找一找,可以找到这个:
    2.png
    请求的响应数据包含了一个新的url,在下方就可以找到访问这个url的请求,其响应是另一个html页面。如果深入研究一下这个html,可以发现签到请求就是这个页面发出的。回到脚本的签到请求,我们可以逐个尝试一下,发现加上SESSION这个cookie以后,可以得到“今日已签”的成功响应。注意反复测试这类有cookie的请求时,最好带上anonymous: true,因为多次测试可能会改变cookie干扰结果,甚至某次失败了写入一个错误的cookie,可能导致后续一直失败无法更新cookie。
    在Charles中按ctrl+f搜索,设置如下搜索规则:
    2.1.png
    由于cookie不是凭空产生的,通常是由某些响应头的Set-Cookie字段设置,这个搜索的意思就是查找哪个请求设置了SESSION。找到2个结果,注意我们的签到请求作用域是/qwhdhub/,可以确定是这个请求设置了SESSION:
    https://wx.10086.cn/qwhdhub/qwhdmark/1021122301?XXX
    是不是很眼熟?他跟chinaMobileApp响应的那个url非常接近,对比一下发现只多了token,而这个没token的版本,正好重定向到了我们前面的登录页面。至此签到流程可以基本确定为:首先请求1021122301,该请求会设置SESSION(此时这个SESSION还是无效的),然后重定向到登录请求,登录请求的html发出chinaMobileApp,返回一个带token版的1021122301(此时SESSION正式生效),最后发出签到请求。
    显然chinaMobileApp是最关键的请求,我们在脚本里尝试复现一下,发现无需cookie也能得到正确结果(很多数据是有时效的,如果间隔时间太长需要重新抓包)。观察html代码,可以看出核心是他的data,其中openid属性明文写在前面的html代码里,mobile是对UID的加密结果,其他属性我们排除法测试一下,发现加不加没有影响。openid可以对html做正则获取,UID的加密由leadeon.encryptString这个函数完成,前后翻一翻发现,页面引入了这个js文件:
    https://app.10086.cn/appother/js/public/leadeon.js
    打开看看源码,确实可以搜索到encryptString,大胆一点,直接在脚本里引入这个js,然后模仿着写一下leadeon.encryptString,运行后报错:newSdkInterface is not defined。在leadeon.js里搜索newSdkInterface,可以大致看出,我们的加密函数在这个对象上,html里找不到该对象的定义,引入的js文件也只剩一个jquery。看起来卡住了,我们换个思路,往Charles里写入一条重写规则:
    3.png
    这里的想法是chinaMobileApp这个请求是由登录请求的html发出的,所以我们改写登录请求的响应结果,让其发出的chinaMobileApp额外带上我们需要的数据,从而暴露出加密函数源码,顺便我把UID明文也带上了。手机APP清除一下缓存,然后重新签到抓包,看看这个新的chinaMobileApp。结果发现,fn是[native code],UID倒是带上了。这个native code可能是人为改写的结果,换一种写法试试:

    Function.prototype.toString.call(newSdkInterface.encryptString)

    结果还是没变,说明一个问题:加密函数并非来自js,而是其他语言写的。这不难理解,请求是手机客户端发出的,客户端又不是js写的,关键函数可能会放到客户端内由Java实现。这又涉及客户端反编译的问题了,我这里用的安卓,关于apk反编译的教程网上很多,大致就是解压apk得到classes.dex,dex2jar反编译为jar,再用jd-gui查看源码。至于apktool,那主要是用来修改smali再重新打包回去的,由于我们的目的只是看源码,不关心打包,故可以跳过这一步。
    这里额外说一点我的经验,jd-gui的不同版本查看效果是有差异的,最新的1.6.6看有些函数会变成一堆注释,换较低的1.4.0反而能解析出来,而1.4.0看别的有更大概率变注释,也有可能两个版本都解析不出来,具体原理我也不懂,建议多下几个版本换着看。
    class.dex有80多M,dex2jar转换后却只有15K,jd-gui查看效果是这个鬼样子:
    4.png
    从包名可以看出,这个dex被加壳了。常见的脱壳方式是安装运行apk,然后从内存里dump出实际的dex。我试过在安卓模拟器里搞这些,但32位和64位的兼容问题相当麻烦,遂放弃,直接在实机上操作。这是我找到的一个工具,特点是无需root,操作简单:
    BlackDex
    中国移动的apk是64位的,要用BlackDex64打开,这个工具不是很完美,每次脱出的dex数量有限,最好多试几次得到尽可能多的dex(数字相同的就是同一个)。最终我得到了19个,可以分别用dex2jar转为jar再全拖进jd-gui里查看,不过可能会出现同一个包分散在不同文件,找起来很不方便,我写了个批处理来合并:

    rem 这里填d2j-dex2jar路径
    set DEX2JAR="D:\dex-tools\d2j-dex2jar.bat"
    rem 这里填WinRAR路径
    set WINRAR="C:\Program Files (x86)\WinRAR\WinRAR.exe"
    
    for /r %%i in (*.dex) do call %DEX2JAR% "%%i"
    if exist package rd /s /q package
    if exist package.jar del /q package.jar
    md package
    for /r %%i in (*.jar) do %WINRAR% x -o+ "%%i" package
    %WINRAR% a -afzip -df -ep1 -r -m0 package.jar package\
    rd /s /q package

    使用方法是复制到记事本,改好你自己的dex2jar和WinRAR路径,保存后修改后缀为bat,再放到与dex文件同一目录下运行即可。由于jar的本质就是zip压缩包,合并的原理即解压后合并目录,再重新压缩成一个。如果有配置好java环境,用jar命令也能做,WinRAR的好处是可以指定压缩级别,我设置为存储,这样速度最快,生成的文件也最大(其实就是没压缩)。由于我们不打算打包回去,只要jd-gui能打开就行,所以大小无所谓。如果你使用其他压缩软件,也可以尝试自己改压缩命令。
    打开合并后的jar就可以看Java源码了,有Java基础的可以自己先研究一下,篇幅所限,有关加密的分析我们就且听下文分解吧。

    已有2人评分好评 油猫币 理由
    tfsn20 + 1 + 5 学到了学到了
    陈公子的话 + 5 赞一个!

    查看全部评分 总评分:好评 +1  油猫币 +10 

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6052

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-11-4 23:51:02 | 显示全部楼层
    脱壳好像也可以试试反射大师
    在对应页面长按导出可以导出全部Class
    貌似用反射大师没碰到过导出不全的情况
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    861

    回帖

    1360

    积分

    荣誉开发者

    积分
    1360

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-11-5 20:29:30 | 显示全部楼层
    李恒道 发表于 2022-11-4 23:51
    脱壳好像也可以试试反射大师
    在对应页面长按导出可以导出全部Class
    貌似用反射大师没碰到过导出不全的情况 ...

    反射大师需要xposed框架,我手机没root,一开始用模拟器就是root比较方便,可惜兼容问题有点多。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6052

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-11-5 20:32:08 | 显示全部楼层
    cxxjackie 发表于 2022-11-5 20:29
    反射大师需要xposed框架,我手机没root,一开始用模拟器就是root比较方便,可惜兼容问题有点多。 ...

    是,而且好像反射大师还不支持安卓高版本...
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    3

    回帖

    3

    积分

    助理工程师

    积分
    3
    发表于 2022-12-14 21:46:35 | 显示全部楼层
    BlackDex能脱棒棒加固企业版?我草
    回复

    使用道具 举报

  • TA的每日心情

    2023-8-10 19:52
  • 签到天数: 9 天

    [LV.3]偶尔看看II

    3

    主题

    23

    回帖

    25

    积分

    助理工程师

    积分
    25
    发表于 2023-7-19 11:33:30 | 显示全部楼层

    BlackDex 没能脱到中国移动的壳,我用的反射大师,但包导不全,要一个个导,比较麻烦,另外想问题楼,你JAVA代码全靠分析,没做动态的HOOK? 那脑子要记多少东西啊
    回复

    使用道具 举报

  • TA的每日心情

    2023-8-10 19:52
  • 签到天数: 9 天

    [LV.3]偶尔看看II

    3

    主题

    23

    回帖

    25

    积分

    助理工程师

    积分
    25
    发表于 2023-7-19 18:32:49 | 显示全部楼层
    中国移动的脱壳JAR能分享一份吗?我的这里不知道是壳得不完整还是什么原因?里面是返回的NULL,但HOOK是有返回的值的 public class b {
        public static String a(String str, String str2) {
            return null;
        }

        public static String b(String str, String str2) {
            return null;
        }
    }
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    861

    回帖

    1360

    积分

    荣誉开发者

    积分
    1360

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2023-7-20 22:49:25 | 显示全部楼层
    sam770 发表于 2023-7-19 18:32
    中国移动的脱壳JAR能分享一份吗?我的这里不知道是壳得不完整还是什么原因?里面是返回的NULL,但HOOK是有返 ...

    你下的apk是8.0.5的吗?其他版本我没试过不知道行不行,你找找看,豌豆荚我记得可以下历史版本的。jar主要是有点大,不行我再上传一份吧。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    861

    回帖

    1360

    积分

    荣誉开发者

    积分
    1360

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2023-7-20 23:35:09 | 显示全部楼层
    sam770 发表于 2023-7-19 18:32
    中国移动的脱壳JAR能分享一份吗?我的这里不知道是壳得不完整还是什么原因?里面是返回的NULL,但HOOK是有返 ...

    传好了,找了好几个网盘,不是速度慢就是限制100M,要么不让分享jar,吐了:https://pan.quark.cn/s/32cf51a6094b
    回复

    使用道具 举报

  • TA的每日心情

    2023-8-10 19:52
  • 签到天数: 9 天

    [LV.3]偶尔看看II

    3

    主题

    23

    回帖

    25

    积分

    助理工程师

    积分
    25
    发表于 2023-7-21 08:40:13 | 显示全部楼层
    cxxjackie 发表于 2023-7-20 23:35
    传好了,找了好几个网盘,不是速度慢就是限制100M,要么不让分享jar,吐了:https://pan.quark.cn/s/32cf ...

    谢谢楼主了
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表