小白获取电视直播源--2

查看 64|回复 10
作者:qands   
今天分析这个


image.png (65.15 KB, 下载次数: 1)
下载附件
2024-10-6 01:59 上传

对于我这个小白来说难度挺大的.我搞了好久,期间也有运气成分,才大致获取了它拿电视源的方法
他的源要解密好多次,就像玩密室逃脱一样...期间还有好多小陷阱
想想以前用OD手撕壳修复引用啥的,也没觉得有这次那么艰难啊...
但他也很简单,最终拿源如下是http的明文,你说作者包裹那么厚是干嘛呢....


image.png (211.38 KB, 下载次数: 1)
下载附件
2024-10-5 13:08 上传

现在开始分析
首先,他有壳,小白不会整,还是hook吧.
然后代{过}{滤}理抓包----有校验,不得行,不会绕,不代{过}{滤}理就不代{过}{滤}理呗, wireshark抓包也挺香
设置过滤条件,https,http,dns 出电视画面立即停止
然后过滤dns的包,再按流量排个序,大致就知道是哪个链接获取的直播源了(通讯量肯定大)


image.png (113.23 KB, 下载次数: 1)
下载附件
2024-10-5 14:12 上传

然后要通讯,总绕不过socket吧,直接hook socket.connect 找到和wireshark对应的IP域名(图是两次抓的,他域名会变,凑合着看吧)


image.png (75.04 KB, 下载次数: 0)
下载附件
2024-10-5 14:20 上传

点进去看堆栈,找到了b4.f这个方法 成功拿到源的下载地址.


image.png (121.85 KB, 下载次数: 0)
下载附件
2024-10-5 14:22 上传

但是下载下来是加密的,需要解密, hook aes试试


image.png (115.1 KB, 下载次数: 0)
下载附件
2024-10-5 14:25 上传

看大小,摘要,应该就是我们要的
打开看,有明文,有乱码,保存下来用16进制编辑器看看,我还大致分析了下他的格式,比如每个字符串前都会标明长度...然而没什么卵用....不过脑子里得记着这段乱码.


image.png (35.33 KB, 下载次数: 0)
下载附件
2024-10-6 02:28 上传

到底部看堆栈,看不到源码只能凭感觉 ,Y3.a.run像是个线程开始,然后调用X3.L.a方法


image.png (119.44 KB, 下载次数: 0)
下载附件
2024-10-6 02:18 上传

那继续hook,然后这里传递了2个参数类型,,都hook看看呗


image.png (143.91 KB, 下载次数: 0)
下载附件
2024-10-6 02:20 上传

hook出来一大堆,大致翻翻,翻出这个,比对下前面的乱码里的字符串,这应该就是操作文件后得到的内容了.
所以他部分是明文,slb字段是密文的


image.png (371.48 KB, 下载次数: 0)
下载附件
2024-10-6 02:30 上传

继续翻堆栈,发现初始堆栈都是Y3.a.run,但是X3.L的初始是U3.D.run
那hook G3.b


image.png (257.53 KB, 下载次数: 0)
下载附件
2024-10-6 02:56 上传

貌似发现了程序运行的起始位置(应该是吧)
我hook的是G3.b的初始化过程,
猜下他的过程,应该是初始化后,然后用线程去执行他.
那关键应该就是h3.g或者U3.a.N来控制线程,并执行不同的线
看下这个堆栈流程的下一个流程调用了哪些堆栈


image.png (228.72 KB, 下载次数: 0)
下载附件
2024-10-6 03:05 上传

省略中途一个看着没用的,找到了d3.e,在这里又调用了那段乱码,并且只有我看的那个台的
差不多要初始化了吧


image.png (499.88 KB, 下载次数: 0)
下载附件
2024-10-6 03:09 上传

然后额....线索断了...
没办法 瞎折腾了好久,期间 hook了文件操作得到了它动态加载的一个jar文件.
这个文件能用jadx反编译.
然后看hook的aes下面那条解密内容和堆栈,看见了这个乱码类,竟然在动态加载的jar里


image.png (200.81 KB, 下载次数: 0)
下载附件
2024-10-6 03:19 上传

吼吼 终于有源码看了,而且貌似关键的东西它放这个动态加载类里的,这里有一个不是那堆一坨abcd的东西,不分析下对不起作者


image.png (118.46 KB, 下载次数: 0)
下载附件
2024-10-6 03:30 上传

这个一看像是一个播放器的类, 查了一下java 的message,貌似是线程之间传递消息的,会不会前面消失的线索发这里来了?而且还是startup啥的
必须hook下


image.png (510.6 KB, 下载次数: 0)
下载附件
2024-10-6 03:34 上传

然后就发现了startcid这个方法,就是从刚刚那个d3.e.c过来的呀....还有cctv1的字样 呵呵....
把这串base64解码对比下,发现和原始的不一样,应该中途还有一次解密...
这里就不得不夸下ChatGPT,给它解密前后的代码让它分析,他竟然真找出算法来了...
[C++] 纯文本查看 复制代码    std::vector decodedBytes = Base64Decode(base64Input);
    size_t byteCount = decodedBytes.size();
    std::vector resultBytes(byteCount);
    for (size_t index = 0; index = 128) ? 128 : 0;  // 如果 byteOffset >= 128 则掩码为 128,否则为 0
        resultBytes[index] = decodedBytes[index] ^ maskValue;  // 使用掩码值和当前字节异或
    }
    // 输出处理后的结果
    for (auto byte : resultBytes) {
        std::cout
看看下面解码的slb字段以及AES/CTR/NoPadding解密的内容,再用16进制编辑器看下那堆乱码,其实就是用0xa+length+content 写进去的N个需要aes解密的内容


image.png (14.2 KB, 下载次数: 0)
下载附件
2024-10-6 04:11 上传

接下来就是对这段源码进行分析,我不太看的懂java,丢进ChatGPT去让它读,分析的明明白白...
中间代码分析的过程就不说了(源码,好懂)
最终找到了这串代码
[Java] 纯文本查看 复制代码import android.net.Uri;
import android.util.Pair;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
/* loaded from: classes.dex */
public final class K extends b {
    public static final String a = o0.a(f.a(97, 72, 82, 48, 99, 68, 111, 118, 76, 50, 100, 122, 98, 71, 74, 122, 90, 88, 74, 50, 76, 109, 108, 48, 100, 105, 53, 106, 98, 88, 90, 112, 90, 71, 86, 118, 76, 109, 78, 117, 76, 50, 108, 117, 90, 71, 86, 52, 76, 109, 48, 122, 100, 84, 103, 47, 89, 50, 104, 104, 98, 109, 53, 108, 98, 67, 49, 112, 90, 68, 48, 108, 99, 121, 90, 68, 98, 50, 53, 48, 90, 87, 53, 48, 97, 87, 81, 57, 74, 88, 77, 109, 98, 71, 108, 50, 90, 87, 49, 118, 90, 71, 85, 57, 74, 88, 77, 109, 99, 51, 82, 105, 83, 87, 81, 57, 78, 67, 86, 122));
    public static final String b = o0.a("JnN0YXJ0dGltZT0lcyZlbmR0aW1lPSVz");
    public static final String[] c = {f.a(121, 115, 116, 101, 110, 108, 105, 118, 101), f.a(98, 101, 115, 116, 122, 98), f.a(119, 97, 115, 117, 115, 121, 116), f.a(70, 105, 102, 97, 115, 116, 98, 76, 105, 118, 101), f.a(104, 110, 98, 98, 108, 105, 118, 101)};
    public static final String[] d = {"J4YQcw", "J4Zb7g", "J4aOlA", "J4aVuw", "J4c5Lw", "J4d6tQ", "J4e86w", "J4iH8A", "J4iH8Q", "J4kYFg"};
    public static final HashMap e = new HashMap(1);
    @Override // p000.c
    public final String a(String str) {
        byte b2;
        String format;
        String[] split = str.split(I.a)[1].split(I.b);
        String str2 = split[0];
        int parseInt = Integer.parseInt(str2.substring(0, 1));
        if (parseInt >= 0) {
            String[] strArr = c;
            if (parseInt
将string a还原下,其实就是
     a = "http://gslbserv.itv.cmvideo.cn/index.m3u8?channel-id=%s&Contentid=%s&livemode=%s&stbId=4%s";
     b = "&starttime=%ss&endtime=%s";
     c是livemode的5个对应参数字典
     d通过base64解码的4个字节是IP地址
slb解码出来的内容i://261HQ4   
i代表用哪个类去执行,这里是K这个类.
2代表是channel-id是c[2]
后面的得到contentID
最终得到链接
http://gslbserv.itv.cmvideo.cn/index.m3u8?channel-id=wasusyt&Contentid=6000000001000029752&livemode=1&stbId=4
继续 还有一系列小陷阱:
访问这个链接重定向到
http://cache.ott.wasulive.itv.cmvideo.cn:80/000000001000/6000000001000029752/index.m3u8?channel-id=wasusyt&Contentid=6000000001000029752&livemode=1&stbId=4&version=1.0&owaccmark=6000000001000029752&owchid=wasusyt&owsid=1477671728160118146&AuthInfo=PK0J3Tn6Yz04PXV3woR5G%2BZOF9YRCjgFxTMQsMRw6Hxi73CalIsyUCBTqakH8JJ3FaMlNZcUtmIsSDR4jFEC%2Fw%3D%3D
然后用d中的IP替换cache.ott.wasulive.itv.cmvideo.cn(这个域名解析出来的IP是1.1.1.1)
再将链接中的host改成cache.ott.wasulive.itv.cmvideo.cn
如果能拿到正确的文件,就开始播放
不能则循环到d中的下一个IP
至此 播放源获取完毕.....
这整个过程真够BT的.....而且最终拿源也要逐个去服务器上拿.还他娘的http明文,何必把代码包裹的这么好折腾人啊...

下载次数, 下载附件

zj23308   

【代码包裹的这么好折腾人】,
这是破解和反破解的较真,
写了直直播app,然后他们就会开始收费,
但是,好多人不愿意给他们缴费,
于是诞生了一个又一个群,就是为了破解他们的链接,
最后的结局就是这样:代码包裹得一层又一层又一层的
superzengli   

感谢分享🙏
life9999   

现在看个电视真的很麻烦了
黑白之道   

大佬好,继续虚心学习
apaye   

这是真大佬啊,光看看都头晕
GuoXin110521   

感谢大佬分享
solos123   

感谢大佬分享,学习中
hrxgg   

不可多得的精品!
hbzy   

只能仰望大佬了
您需要登录后才可以回帖 登录 | 立即注册