吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 20369|回复: 474
上一主题 下一主题
收起左侧

[Android 原创] 小白获取电视直播源--2

    [复制链接]
跳转到指定楼层
楼主
qands 发表于 2024-10-6 04:53 回帖奖励
今天分析这个

对于我这个小白来说难度挺大的.我搞了好久,期间也有运气成分,才大致获取了它拿电视源的方法
他的源要解密好多次,就像玩密室逃脱一样...期间还有好多小陷阱
想想以前用OD手撕壳修复引用啥的,也没觉得有这次那么艰难啊...


但他也很简单,最终拿源如下是http的明文,你说作者包裹那么厚是干嘛呢....



现在开始分析
首先,他有壳,小白不会整,还是hook吧.

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



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


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




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


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




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

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



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


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

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


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


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


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


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

然后就发现了startcid这个方法,就是从刚刚那个d3.e.c过来的呀....还有cctv1的字样 呵呵....
把这串base64解码对比下,发现和原始的不一样,应该中途还有一次解密...
这里就不得不夸下ChatGPT,给它解密前后的代码让它分析,他竟然真找出算法来了...

[C++] 纯文本查看 复制代码
    std::vector<uint8_t> decodedBytes = Base64Decode(base64Input);
    size_t byteCount = decodedBytes.size();
    std::vector<uint8_t> resultBytes(byteCount);

    for (size_t index = 0; index < byteCount; index++) {
        int byteOffset = (byteCount + index) % 128;
        int maskValue = (byteOffset >= 128) ? 128 : 0;  // 如果 byteOffset >= 128 则掩码为 128,否则为 0
        resultBytes[index] = decodedBytes[index] ^ maskValue;  // 使用掩码值和当前字节异或
    }

    // 输出处理后的结果
    for (auto byte : resultBytes) {
        std::cout << std::hex << static_cast<int>(byte) << " ";
    }

    return 0;



看看下面解码的slb字段以及AES/CTR/NoPadding解密的内容,再用16进制编辑器看下那堆乱码,其实就是用0xa+length+content 写进去的N个需要aes解密的内容



接下来就是对这段源码进行分析,我不太看的懂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);

    [url=home.php?mod=space&uid=1892347]@Override[/url] // 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 < strArr.length) {
                String str3 = strArr[parseInt];
                String substring = str2.length() == 20 ? str2.substring(1) : str2.charAt(1) + String.format(Locale.getDefault(), "%09d", Integer.valueOf(Integer.parseInt(str2.substring(2, 3)))) + String.format(Locale.getDefault(), "%09d", Integer.valueOf(w0.c(str2.substring(3))));
                if (split.length == 1) {
                    b2 = 1;
                    format = "";
                } else {
                    b2 = 4;
                    long parseLong = Long.parseLong(split[1]);
                    long a2 = q0.a();
                    long min = Math.min(parseLong, a2 - 120000);
                    Pair pair = new Pair(Long.valueOf(min), Long.valueOf(Math.min(a2 - 30000, 3600000 + min)));
                    format = String.format(b, q0.a("yyyyMMdd'T'HHmmss.SSS'Z'").format(new Date(((Long) pair.first).longValue())), q0.a("yyyyMMdd'T'HHmmss.SSS'Z'").format(new Date(((Long) pair.second).longValue())));
                }
                String format2 = String.format(a, str3, substring, Byte.valueOf(b2), format);
                if (k0.a(format2, null, 300, 500)) {
                    return format2;
                }
                F a3 = H.a(new F(format2));
                a3.b().setInstanceFollowRedirects(false);
                String str4 = F.g;
                try {
                    a3.e = E.a;
                    D d2 = a3.d;
                    if (d2 != null) {
                        try {
                            d2.close();
                        } catch (IOException e2) {
                        }
                        a3.d = null;
                    }
                    String headerField = a3.b().getHeaderField(str4);
                    String authority = Uri.parse(headerField).getAuthority();
                    if (authority == null) {
                        return null;
                    }
                    String str5 = authority.split(":")[0];
                    e.put(F.f, str5);
                    for (String str6 : d) {
                        String replace = headerField.replace(str5, w0.a(str6));
                        HashMap hashMap = e;
                        if (k0.a(replace, hashMap, 300, 500)) {
                            return b.a(replace, hashMap);
                        }
                    }
                    return null;
                } catch (IOException e3) {
                    throw new C(e3);
                }
            }
        }
        return null;
    }
}



将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明文,何必把代码包裹的这么好折腾人啊...




image.png (65.15 KB, 下载次数: 21)

image.png

image.png (99.52 KB, 下载次数: 18)

image.png

image.png (329.23 KB, 下载次数: 9)

image.png

免费评分

参与人数 105威望 +1 吾爱币 +116 热心值 +92 收起 理由
yiduoxiaohua + 1 谢谢@Thanks!
hshd + 1 我很赞同!
莫奇 + 1 + 1 谢谢@Thanks!
wwq0312 + 1 + 1 我很赞同!
wangyongdesign + 1 + 1 谢谢@Thanks!
m99044032 + 1 + 1 用心讨论,共获提升!
cl836 + 1 + 1 谢谢@Thanks!
yuzaizi521 + 1 + 1 谢谢@Thanks!
Fang1234yu + 1 + 1 谢谢@Thanks!
xfsan + 1 + 1 热心回复!
xiaogao66 + 1 + 1 我很赞同!
squirtlover + 1 + 1 谢谢@Thanks!
hu272501 + 1 + 1 我很赞同!
ind + 1 + 1 热心回复!
baby九叔 + 1 谢谢@Thanks!
perfectjay + 1 + 1 好一个小白,这么强
Gsn. + 1 + 1 谢谢@Thanks!
ag129 + 1 + 1 谢谢@Thanks!
应龙宇辰 + 1 + 1 热心回复!
ion2000 + 1 + 1 厉害!
eric_wapj + 1 谢谢@Thanks!
zqs123 + 1 + 1 我很赞同!
wangccyy + 1 用心讨论,共获提升!
Agolong + 1 + 1 鼓励转贴优秀软件安全工具和文档!
ErenLuo + 1 热心回复!
Augsummer + 1 + 1 谢谢@Thanks!
yefeng008 + 1 + 1 用心讨论,共获提升!
ppl121 + 1 + 1 谢谢@Thanks!
wapjluntan + 1 + 1 谢谢@Thanks!
LinkWorld + 1 我很赞同!
xxn9080856 + 1 + 1 谢谢@Thanks!
zcfrank1st + 1 + 1 我很赞同!
yx69 + 1 + 1 我很赞同!
maiwens + 1 + 1 谢谢@Thanks!
smilingk + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
zhangzhixk + 1 热心回复!
q56020676 + 1 + 1 我很赞同!
g123458 + 1 谢谢@Thanks!
kaxv + 1 + 1 我很赞同!
jnjnno + 1 + 1 我很赞同!
liu2500 + 1 + 1 我很赞同!
sanmylc + 1 + 1 我很赞同!
越难越爱 + 1 + 1 用心讨论,共获提升!
Trexrush + 1 + 1 谢谢@Thanks!
hubohang + 1 我很赞同!
hap + 1 + 1 我很赞同!
will06 + 1 + 1 热心回复!
正义天下 + 1 + 1 谢谢@Thanks!
waallen + 1 热心回复!
yaoyp2471 + 1 + 1 用心讨论,共获提升!
wang82530 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
icy0012 + 1 + 1 我很赞同!
fengshengshou + 1 + 1 我很赞同!
la2364 + 1 + 1 谢谢@Thanks!
yzq2dr + 1 我很赞同!
sherppard + 1 + 1 我很赞同!
lichen2956093 + 1 + 1 用心讨论,共获提升!
Licoo + 1 + 1 用心讨论,共获提升!
jesssy + 1 我很赞同!
diodio + 1 + 1 谢谢@Thanks!
allspark + 1 + 1 用心讨论,共获提升!
timeni + 1 + 1 用心讨论,共获提升!
yzqgeorge + 1 + 1 谢谢@Thanks!
tian073 + 1 用心讨论,共获提升!
sz232 + 1 + 1 很佩服,点赞。
yiqibufenli + 1 + 1 我很赞同!
诸葛文诚 + 1 + 1 谢谢@Thanks!
awsl52pj + 1 谢谢@Thanks!
_小白 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
wolf47211 + 1 + 1 我很赞同!
liupin924 + 1 谢谢@Thanks!
清酒半壶 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
dadao815 + 1 + 1 用心讨论,共获提升!
gaa2001 + 1 我很赞同!
XMQ + 1 我很赞同!
小火 + 1 + 1 谢谢@Thanks!
pathfinder00 + 1 + 1 用心讨论,共获提升!
JUNWO999 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
ddconstantinebb + 1 用心讨论,共获提升!
pdcba + 1 + 1 谢谢@Thanks!
adoudou + 2 + 1 谢谢@Thanks!
NPC0123 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
ggg891080 + 1 + 1 用心讨论,共获提升!
theStyx + 2 + 1 用心讨论,共获提升!
xuanle + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
无尘浪子 + 1 谢谢@Thanks!
wcu1117 + 1 用心讨论,共获提升!
海水很咸 + 1 + 1 我很赞同!
0jiao0 + 2 + 1 用心讨论,共获提升!
QaQ355 + 1 + 1 热心回复!
Zhaofeiyan + 1 + 1 用心讨论,共获提升!
distu119 + 1 + 1 我很赞同!
Mandrake + 1 + 1 谢谢@Thanks!
2022313 + 1 热心回复!
O炮酱 + 1 + 1 我很赞同!
qjlfl + 1 + 1 我很赞同!
qianxungigi + 1 + 1 谢谢@Thanks!
正己 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
25983600 + 1 + 1 我很赞同!
guiwuzhe + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

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

推荐
zj23308 发表于 2024-10-6 05:25
【代码包裹的这么好折腾人】,
这是破解和反破解的较真,
写了直直播app,然后他们就会开始收费,
但是,好多人不愿意给他们缴费,
于是诞生了一个又一个群,就是为了破解他们的链接,
最后的结局就是这样:代码包裹得一层又一层又一层的
推荐
superzengli 发表于 2024-10-6 06:02
推荐
life9999 发表于 2024-10-6 08:47
4#
黑白之道 发表于 2024-10-6 05:06
大佬好,继续虚心学习
5#
apaye 发表于 2024-10-6 06:38
这是真大佬啊,光看看都头晕
6#
GuoXin110521 发表于 2024-10-6 06:47
感谢大佬分享
7#
solos123 发表于 2024-10-6 07:08
感谢大佬分享,学习中
8#
hrxgg 发表于 2024-10-6 07:23
不可多得的精品!
9#
hbzy 发表于 2024-10-6 07:41
只能仰望大佬了
10#
yong3642270 发表于 2024-10-6 07:46
跟着大佬学习了,感谢大佬的分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-1 06:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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