吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3191|回复: 5
收起左侧

[会员申请] 申请会员ID:hygzs【申请通过】

[复制链接]
吾爱游客  发表于 2021-12-4 10:50
申请ID:hygzs
个人邮箱:1341806518@qq.com

原创技术文章:
csdn地址:Android Xposed hook从了解到学废.004_幻叶-叶子的博客-CSDN博客
Android Xposed hook从了解到学废.004

通过xposed hook逆向直播app的sign加密



1.准备工具
下述括号内是我所有的版本或软件
1.Android Studio (3.5)
2.模拟器或者Android手机 (雷电)
3.Fiddler (4) 下载
4.jeb (2.2.7.20160815)下载
4.MT管理器.apk(注意是新版)下载
5.游拍.apk(3.5.1.56) 这里不提供地址


jeb收费,破 j 版安装也过于麻烦,所以第4个工具2选一,这里我都演示了


环境搭建请看第一篇:Android Xposed hook从了解到学废.001


2.找寻需要HOOK的类和方法
目标:进入直播间出现的弹幕和说话的sign


数据:
[JavaScript] 纯文本查看 复制代码
POST [url=http://mapi.4399youpai.com/app/android/v3.5/chat-msg.html]http://mapi.4399youpai.com/app/android/v3.5/chat-msg.html[/url] HTTP/1.1
MUDID: xiaomigofDrSauMT9BcT8MD5b0e
APIVERSION: 3.5.1.56.481
CHANNEL: xiaomi
MAUTH: a4b37556327aad56c379dd7645be14d5
DEVID: 865166028278623
User-Agent: 4399YouPai/3.5.1.56(android;vivo x9;5.1.1;1080x1920;WIFI;481;xiaomi;xxhdpi)
APKNAME: com.m4399.youpai
MAUTHCODE: 795e2e49
Content-Type: application/x-www-form-urlencoded
Content-Length: 256
Host: mapi.4399youpai.com
Connection: Keep-Alive
Accept-Encoding: gzip

is_new_version=1&sign=99257bef9ad502accda48ce50b0a3d96&msg=%E6%9D%A5%E4%BA%86&apk_version=3.5.1.56.481&nickname=2984236588&apkName=com.m4399.youpai&is_face=0&push_id=17214772&uniqueId=865166028278623&system=1&room_id=1918&channel=public%3Ayptv_172147728e28




通过Fiddler 4抓取到发送的数据为:is_new_version=1&sign=99257bef9ad502accda48ce50b0a3d96&msg=%E6%9D%A5%E4%BA%86&apk_version=3.5.1.56.481&nickname=2984236588&apkName=com.m4399.youpai&is_face=0&push_id=17214772&uniqueId=865166028278623&system=1&room_id=1918&channel=public%3Ayptv_172147728e28

查询类和方法的第一种方式 使用jeb
我们打开jeb拖入apk


这里我们抓到的提交地址是chat-msg.html,所以我们直接Ctrl+F搜索,不过不知道啥原因我的jeb有点不太配合我,没搜到(MT管理器可以,稍后再说)于是乎我直接搜索了他的提交参数"apk_version
这里有个"表明他是个常量而不是代码或者函数


发现周围用橙色突出的常量都是提交的参数名,所以确定了,这个位置就是提交弹幕的函数
使用快捷键Q键转换成java代码查看


[Java] 纯文本查看 复制代码
 private void a(String arg4, int arg5, String arg6) {
        HashMap v0 = new HashMap();
        ((Map)v0).put("msg_id", arg6);
        ((Map)v0).put("nickname", this.r.getNickName());
        ((Map)v0).put("msg", arg4);
        ((Map)v0).put("system", arg5 + "");
        ((Map)v0).put("apkName", ((Fragment)this).getActivity().getPackageName());
        ((Map)v0).put("apk_version", c.b(((Fragment)this).getActivity()));
        ((Map)v0).put("channel", this.r.getPushChannel());
        ((Map)v0).put("push_id", this.q + "");
        ((Map)v0).put("room_id", this.s);
        arg6 = LiveManager.getInstance().getIdentifiesId();
        if(TextUtils.isEmpty(((CharSequence)arg6))) {
            arg6 = e.c(((Fragment)this).getActivity());
        }
        
        ((Map)v0).put("uniqueId", arg6);
        v6 = new StringBuilder();
        v6.append(arg4);
        v6.append(this.r.getNickName());
        v6.append(arg5);
        v6.append("#4399yp*msg#");
        ((Map)v0).put("sign", i.a(v6.toString()));
        if(arg5 == 0) {
            ((b)this).loadData(LiveManager.getInstance().getApiService().sendChatMsg(((Map)v0)), this.m);
        }
    }



[Java] 纯文本查看 复制代码
        v6 = new StringBuilder();
        v6.append(arg4);
        v6.append(this.r.getNickName());
        v6.append(arg5);
        v6.append("#4399yp*msg#");
        ((Map)v0).put("sign", i.a(v6.toString()));



创建名为v6的StringBuilder对象
然后加入
arg4
this.r.getNickName()
arg5
#4399yp*msg#
转为string类型传递给i.a()我们看一下
arg4
this.r.getNickName()
arg5
都是什么

结合发出去的数据可以看出来
arg4是msg 也就是"来了"
this.r.getNickName()是nickname 也就是2984236588
arg5是system 也就是1双击i.a跳转过去看看digest和update是md5的特征
我们数一下sign:99257bef9ad502accda48ce50b0a3d96
一共32位这里又写了md5
基本可以确定是md5加密
那么我们hook他拿出他的原文看看翻到最上面这个时候我们得到了需要hook的方法和类了查询类和方法的第一种方式 使用MT管理器jeb的可以划走,这里说的是mt管理器单击APK选择查看
发现他有3个Dex
随便点一个
我们选择dex++编辑,然后全选,使用搜索功能搜索chat-msg.html搜索到一个,我们点击进去
MT管理器使用转java代码需要收费,估计看文章的没几个有会员,哈哈
(PS:哎16年买的永久会员真香哈哈哈哈哈)这里看到方法是sendChatMsg,我们出去搜索看看哪里调用了
这里一共有3个地方使用过sendChatMsg
我们倒着一个一个看吧
post过去的值都存在,所以这个可能是我们所要找的
开启会员特权给你们看一眼应该都看懂了吧,我们回去看看代码
[Asm] 纯文本查看 复制代码
    const-string p1, "#4399yp*msg#"
    invoke-virtual {p3, p1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    invoke-virtual {p3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    move-result-object p1
    .line 30
    invoke-static {p1}, Lcom/youpai/framework/util/i;->a(Ljava/lang/String;)Ljava/lang/String;
    move-result-object p1
    const-string p3, "sign"
这里代码是Smali代码,反正我是看不懂
不过能理解一丢丢,然后代码看过java的也应该能理解一点了
[Asm] 纯文本查看 复制代码
invoke-static {p1}, Lcom/youpai/framework/util/i;->a(Ljava/lang/String;)Ljava/lang/String;
    move-result-object p1
Lcom/youpai/framework/util/i;->a(Ljava/lang/String;)
传入String类型值给Lcom/youpai/framework/util/i;->a处理
那么我们过去看看哈!在第二个dex里我们就已经确定了目标开始hook3.开始编写Hook代码这里目标包名是:com.m4399.youpai
目标类是:com.youpai.framework.util.i
目标方法:a编写代码
[Java] 纯文本查看 复制代码
package com.hygzs.hook;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

public class hook implements IXposedHookLoadPackage {
    public void handleLoadPackage(LoadPackageParam loadPackageParam) throws Throwable {
        if (!loadPackageParam.packageName.equals("com.m4399.youpai"))
            return;
        XposedBridge.log("已经找到目标软件");
        XposedHelpers.findAndHookMethod("com.youpai.framework.util.i", loadPackageParam.classLoader,
                //上面看第2篇
                "a",
                //目标为isCorrectInformation
                String.class,
                //传递的1个值是string类型,所以这里直接1个String.class
                new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
                        //afterHookedMethod是在调用原方法后执行
                        XposedBridge.log("原文 = " + (String) param.args[0]);
                        //打印到xposed日志内
                        super.afterHookedMethod(param);
                        //调用
                    }
                }
        );

    }
}
这里代码和之前的没什么区别,就是改了判断的包名,类名还有方法名
我们写好后运行,然后重启模拟器或者模拟器或者vxp框架整体过程可以看前面的文章我就不赘述了现在开启fd然后抓包
抓到了新的数据sign:99257bef9ad502accda48ce50b0a3d96
看一下日志日志:来了29842365881#4399ypmsg#
我们通过工具查询md5
一模一样到此Sign算法和原文就得到了来了+nickname+system+#4399ypmsg#这里要说一下此app的通过chat-msg.html发送数据一共有2个地方,一个是弹幕,一个就是这种刚刚进入直播间的提示system是不一样的额外知识点因为我们需要不断的去看日志就很麻烦,所以这里提供xposed使用toast的方法直接贴代码详细可以看这篇文章Android逆向工程:大显神通的Xposed,如何在Xposed中弹出Toast提示
[Asm] 纯文本查看 复制代码
package com.hygzs.hook;

import android.content.Context;
import android.view.ContextThemeWrapper;
import android.widget.Toast;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

public class hook implements IXposedHookLoadPackage {
    private Context context;
    public void handleLoadPackage(LoadPackageParam loadPackageParam) throws Throwable {
        XposedHelpers.findAndHookMethod(ContextThemeWrapper.class, "attachBaseContext",Context.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                context=(Context) param.args[0];
            }
        });

        if (!loadPackageParam.packageName.equals("com.m4399.youpai"))
            return;
        XposedBridge.log("已经找到目标软件");
        XposedHelpers.findAndHookMethod("com.youpai.framework.util.i", loadPackageParam.classLoader,
                //上面看第2篇
                "a",
                //目标为isCorrectInformation
                String.class,
                //传递的1个值是string类型,所以这里直接1个String.class
                new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
                        //afterHookedMethod是在调用原方法后执行
                        XposedBridge.log("原文 = " + (String) param.args[0]);
                        Toast.makeText(context,"加密原文:"+(String) param.args[0],Toast.LENGTH_SHORT).show();
                        //打印到xposed日志内
                        super.afterHookedMethod(param);
                        //调用
                    }
                }
        );

    }
}

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2021-12-6 10:29
请在本文博客发一个文章信息确认本贴是你自己申请的,然后回复地址给我审核。
吾爱游客  发表于 2021-12-6 14:04
Hmily 发表于 2021-12-6 10:29
请在本文博客发一个文章信息确认本贴是你自己申请的,然后回复地址给我审核。

地址
emm,是这样?,不太理解如何操作
https://blog.csdn.net/qq_15781179/article/details/121745353

点我
Hmily 发表于 2021-12-6 17:09
I D:hygzs
邮箱:1341806518@qq.com

申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。
hygzs 发表于 2021-12-6 17:44
感谢Hmily大佬审核通过,本人前来报到!
hygzs 发表于 2021-12-7 11:06
Hmily 发表于 2021-12-6 17:09
I D:hygzs
邮箱:


感谢Hmily大佬审核通过,本人前来报到!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 11:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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