某海外平台短视频app逆向分析研究

查看 66|回复 9
作者:hHunter   
首先从海外平台下载此应用到测试机中然后通过mt管理器提取出他的安装包,发现安装包是apks的格式的
网上搜索了一下发现apks是某海外平台的格式,直接将apks修改后缀名为zip后解压发现如下几个apk子包体内容


Snipaste_2025-07-09_14-40-41.png (2.43 KB, 下载次数: 1)
下载附件
2025-7-9 16:49 上传

其核心代码都放在base.apk中,所以我们只要先分析里面的代码
通过jadx打开后发现其代码已经被混淆了


Snipaste_2025-07-09_14-43-43.png (38.26 KB, 下载次数: 0)
下载附件
2025-7-9 16:49 上传

于是通过jadx的反混淆功能后,也于事无补


屏幕截图 2025-07-09 161816.png (17.68 KB, 下载次数: 1)
下载附件
2025-7-9 16:50 上传

那先不管,先通过开发者工具测试 找到app的当前activity,如下图:


Snipaste_2025-07-09_16-11-06.png (96.5 KB, 下载次数: 0)
下载附件
2025-7-9 16:51 上传

大概看了一遍后也没啥用,这里知识好奇想看看启动的入口而已
然后继续回到jadx找相应的代码,根据多个小时的代码分析和测试
最终发现如下几个代码文件信息量非常大,估计可能就是播放源的操作


Snipaste_2025-07-09_16-11-40.png (100.85 KB, 下载次数: 1)
下载附件
2025-7-9 16:51 上传



Snipaste_2025-07-09_16-12-31.png (112.45 KB, 下载次数: 0)
下载附件
2025-7-9 16:51 上传

最后通过frIDA的hook这几个方法后,发现来回播放视频都会调用TXVodPlayer的startVodPlay(String str)方法,
其中str就是播放源的uri链接地址


Snipaste_2025-07-09_16-28-54.png (25.82 KB, 下载次数: 1)
下载附件
2025-7-9 16:52 上传

返回的时候调用了aVar.a(str),继续跟踪其方法


Snipaste_2025-07-09_16-31-07.png (83.36 KB, 下载次数: 1)
下载附件
2025-7-9 16:52 上传

发现a方法内部有控制其播放的操作,有此可以判定已经找到了下载源和播放视频的调用方法
最后frida去hook此调用的startVodPlay方法
[Python] 纯文本查看 复制代码    let TXVodPlayer = Java.use("com.tencent.rtmp.TXVodPlayer");
    TXVodPlayer["startVodPlay"].overload('java.lang.String').implementation = function (str) {
        console.log('startVodPlay is called' + ', ' + 'str: ' + str);
        let ret = this.startVodPlay(str);
        return ret;
    };
结果出现了加密的uri下载源


Snipaste_2025-07-09_16-34-22.png (20.37 KB, 下载次数: 1)
下载附件
2025-7-9 16:48 上传

将其下载源放入浏览器后发现没权限等提示,很恼火。
于是灵机一动通过ai写一段python读取下载源的代码并保存为mp4格式
[Python] 纯文本查看 复制代码import requests
import os
import re
from urllib.parse import urlparse
from datetime import datetime
def download_video(url, output_dir="downloads"):
    """
    下载带有签名的视频文件
   
    参数:
        url (str): 视频URL
        output_dir (str): 保存目录
    """
    # 创建保存目录
    os.makedirs(output_dir, exist_ok=True)
   
    # 从URL中提取文件名
    parsed_url = urlparse(url)
    filename = os.path.basename(parsed_url.path)
   
    # 检查URL中的Expires参数
    match = re.search(r'Expires=(\d+)', url)
    if match:
        expires_timestamp = int(match.group(1))
        expires_date = datetime.utcfromtimestamp(expires_timestamp)
        now = datetime.utcnow()
        
        # 检查链接是否过期
        if now > expires_date:
            print(f"警告: 链接已于 {expires_date} 过期!")
            return False
   
    # 设置请求头
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
        "Accept": "video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5",
        "Referer": "https://xxxxxx.com/",  # 假设来源网站
    }
   
    # 文件保存路径
    save_path = os.path.join(output_dir, filename)
   
    try:
        print(f"开始下载: {filename}")
        
        # 使用流式下载
        response = requests.get(url, headers=headers, stream=True)
        response.raise_for_status()  # 检查HTTP错误
        
        total_size = int(response.headers.get('content-length', 0))
        downloaded = 0
        
        # 写入文件
        with open(save_path, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                if chunk:  # 过滤掉保持连接的新块
                    f.write(chunk)
                    downloaded += len(chunk)
                    
                    # 显示下载进度
                    if total_size > 0:
                        percent = (downloaded / total_size) * 100
                        print(f"\r下载进度: {percent:.2f}% ({downloaded}/{total_size} bytes)", end='')
        
        print(f"\n视频已成功保存到: {save_path}")
        print(f"文件大小: {downloaded / (1024 * 1024):.2f} MB")
        
        # 验证文件完整性
        if total_size > 0 and downloaded != total_size:
            print("警告: 下载文件大小与预期不符,文件可能不完整")
            return False
        
        return save_path
        
    except Exception as e:
        print(f"下载失败: {e}")
        return False
if __name__ == "__main__":
    # 您的视频URL
    video_url = "https://xxxxx.xxxx.com/4c1b3983vodhk1310397514/4f3f05db3560136622446212854/f0.mp4?Expires=1752042081&Signature=YrMXtvSb8me66QuH05nMW48rmS6h-~P7xAQ21JlPxFGpS1FGKyFI1gzKz05--dotLXEwhPM4a920SGh2jfCXTdqswVn7KCn-LPz1u30xHX2XnqcRf5HfWkRCwfu4MTLRgZloq4oIwQsdnPGjf86t830kD6pT4KW9wJByfHRc4sFZd~aFidrSiR3gEvWJ5VgtaJ7uJjMrnCM3vwRVC~TzXQOHaZFp67q4qn0o~EKahTBxFEgKI7Vh-uxWvMUOBXhqrKUMp9zWSVF5GwdRjk6kbFBEvIUlhV527RUZzPpcM0cOwmzC8PopzOo4jS~~lxmIg~fNjPAs9sNbyhgMgExlyw__&Key-Pair-Id=K3BZ1QB768QHY7"
   
    # 下载视频
    result = download_video(video_url)
   
    if result:
        print("下载完成!")
    else:
        print("下载失败!")
运行后成功下载mp4格式视频


Snipaste_2025-07-09_16-45-59.png (20.43 KB, 下载次数: 1)
下载附件
2025-7-9 16:48 上传

至此完成此app的播放逆向分析。
最后叠甲
【宇宙免责声明】
本文内容仅供学习研究,请勿用于非法途径。

下载次数, 下载附件

fdiquan   

大佬,感觉厉害,我小白看不懂
wo54jiaobb   

大佬,感觉厉害,但小白看不懂
wanliu   

这是哪家的混淆奥,有点抽象
lijiahao123   

看不懂,感觉很厉害
hHunter
OP
  


wanliu 发表于 2025-7-10 17:55
这是哪家的混淆奥,有点抽象

我也不太清楚,反正很迷,你要是知道能告知么
xixicoco   

这个视频么有加密啊,还是比较简单了
schm168   

高手过招不留痕迹,感谢分享
Yangzaipython   

学习下思路
fangmjiu   

感谢大佬,仰望
您需要登录后才可以回帖 登录 | 立即注册

返回顶部