吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8101|回复: 104
上一主题 下一主题
收起左侧

[Web逆向] ts帧加密案例(一)

    [复制链接]
跳转到指定楼层
楼主
我是不会改名的 发表于 2023-12-31 23:28 回帖奖励

ts帧加密案例(一)

一、前言

最近比较忙,期末了,抽了点空写了下(抽了半天复习了一下,然后就考试了),写这个主要是总结一下学的知识,做个记录,预计两到三个案例,争取春节前写完。

看本文之前先学习一下下面几篇,了解一下基础知识

FLV:不许动手动脚

m3u8的ts文件的PES加解密分析以及示例

某德地图矢量瓦片逆向(快速wasm逆向),c/c++/c#可调用,执行wasm2c翻译出来的c代码一

二、配置相关环境

以win10为例

配置FFmpeg

下载FFmpeg,在这里https://github.com/BtbN/FFmpeg-Builds/releases,选择ffmpeg-master-latest-win64-gpl-shared.zip

解压(最好不要有中文),添加到环境变量

image-20231231194315450

测试环境

image-20231231194440413

配置C语言

下载wabt工具包

https://github.com/WebAssembly/wabt/releases/tag/1.0.34

添加到环境变量,略

环境测试

我用的clion,其他工具应该差不多

创建一个项目,c和c++无所谓

image-20231231195143824

在CMakeLists.txt里面添加

set(FFMPEG_DIR D:\\ffmpeg)#ffmpeg的路径
include_directories(${FFMPEG_DIR}\\include)
link_directories(${FFMPEG_DIR}\\lib)
link_libraries(avcodec  avformat avutil )

运行下面代码,输出hello 52pojie,没有报错说明没有问题了

#include <string.h>
/*
for c
#include "libavutil/log.h"
#include "libavutil/aes_ctr.h"
 */
//c++ 必须加extern "C",否则会报错
extern "C" {

#include "libavutil/log.h"
#include "libavutil/aes_ctr.h"

}

int main(void) {
    av_log_set_level(AV_LOG_INFO);
    char tmp[128] = {0};
    char plain[16] = "hello 52pojie";
    char result[128] = {0};
    int ret = 1;
    const uint8_t *iv;
    struct AVAESCTR *ae = av_aes_ctr_alloc();
    struct AVAESCTR *ad = av_aes_ctr_alloc();
    const char *key = "hello 52pojie!!!";
    if (av_aes_ctr_init(ae, (const uint8_t *) key) < 0)
    {
        av_log(NULL, AV_LOG_ERROR, "init error\n");
        goto ERROR;
    }
    if (av_aes_ctr_init(ad, (const uint8_t *) key) < 0)
    {
        av_log(NULL, AV_LOG_ERROR, "init error\n");
        goto ERROR;
    }
    av_aes_ctr_set_random_iv(ae);
    iv = av_aes_ctr_get_iv(ae);
    av_aes_ctr_set_full_iv(ad, iv);
    av_aes_ctr_crypt(ae, (uint8_t *) tmp, (uint8_t *) plain, sizeof(tmp));
    av_aes_ctr_crypt(ad, (uint8_t *) result, (uint8_t *) tmp, sizeof(tmp));
    av_log(NULL, AV_LOG_INFO, "%s", result);
    ret = 0;
    ERROR:
    av_aes_ctr_free(ae);
    av_aes_ctr_free(ad);
    return ret;
}

`

三、怎么判断是否是帧加密

ts加密通常分为整体加密,文件头加密,帧加密以及混合加密。

整体加密

整体加密顾名思义就是对文件整体加密,这是最常见的加密方式。只需要按照188字节一组,判断开头是不是0x47就知道了

文件头加密

只对文件开头一定长度加密或者插入另外文件格式的文件头,盗版网站用的比较多,毕竟白嫖图床谁不喜欢。同样的只需要按照188字节一组,判断第多少组以后是0x47,或者直接看文件头内容

帧加密

帧加密就比较麻烦了,也分为很多种。

首先在学习了参考上面文章后,可以把帧加密分为,整体pes加密,nalu头加密,nalu内容加密。

首先是pes整体加密,有代表性的就是某里系列。

利用010,并下载h264模板来分析。

image-20231231210619008

首先是未加密的ts

image-20231231211052353

然后是加密的ts

image-20231231211440889

很明显看到出来,少了很多nal单元,只有pes头,其余信息都不存在了。

然后是nal头加密,比较常见的就是v13

image-20231231211717619

可以看到能识别出nalu,但是缺少了很多,比如sps,sei,还有这个pps大的离谱了,关键帧也不见了。

最后就是nalu内容加密,直接播放视频就行,有声音花屏,也有可能音频也加密了;

image-20231231212136227

四、某网站ts加密分析

目标网站aHR0cHM6Ly90di5jY3R2LmNvbS8yMDIzLzEwLzMwL1ZJREVBSEdrWnBqMldYcm1oUWV3dzVVMDIzMTAzMC5zaHRtbD9zcG09Qzg0MTExLlBaTzIySm1qTWhKRS5TMTU0NDAuMTE=

js分析

js就不多分析了,就一个wasm加载的js文件是ob类混淆,唯一需要注意的是,流媒体播放基本都是采用多线程,worker来播放,需要手动添加断点替换js文件

image-20231231212706651

断下以后,看看堆栈,根据不同nalu类型判断是否加密,首先实现解析出nalu类型以及长度

image-20231231212846992

FFmpeg解析出pes

创建项目配置CMakeLists.txt和上面一样

首先初始化目录以及设置log,初始化上下文打开文件等

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
AVFormatContext *fmt_ctx = NULL;
const AVInputFormat *fmt = NULL;
const char *filename;
const char *audiofile;
const char *videofile ;
FILE *faudio;
FILE *fvideo;
int video_index = -1;
int audio_index = -1;
void init() {
    if (chdir("../") < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot change directory\n");
        return;
    }
    av_log_set_level(AV_LOG_INFO);
    fmt_ctx = avformat_alloc_context();
    faudio = fopen(audiofile, "wb+");//必须是wb+,否则会多出0x
    fvideo = fopen(videofile, "wb+");
}

然后打开输入流,查找相关信息

    if (avformat_open_input(&fmt_ctx, filename, fmt, NULL) < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
        goto END;
    }
    if (!find_streams()) {
        av_log(NULL, AV_LOG_ERROR, "Cannot find video stream or audio stream\n");
        goto END;
    }
bool find_streams() {
    for (int i = 0; i < fmt_ctx->nb_streams; i++) {
        if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            video_index = i;
        } else if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            audio_index = i;
        }
    }
    if (video_index == -1 || audio_index == -1) {
        printf("find video stream or audio stream failed\n");
        return false;
    }
    //av_dump_format(fmt_ctx, 0, filename, 0); //打印视频信息
    return true;
}

分离音视频流,需要注意的是这里的packet并不是完整的pes流,而是纯码流,所以pes整体加密方式这样是不行的。

int split() {
    AVPacket *packet = av_packet_alloc();
    while (av_read_frame(fmt_ctx, packet) >= 0) {
        if (packet->stream_index == video_index) {
            fwrite(packet->data, 1, packet->size, fvideo);

        } else if (packet->stream_index == audio_index) {
            fwrite(packet->data, 1, packet->size, faudio);
        }
        av_packet_unref(packet);
    }
    av_packet_free(&packet);
    return 0;
}

解析nalu单元

主要参考这个代码cgts_nal_adts_parse.c

int decode_video(AVPacket *packet) {
    AVCodecParameters *codecpar = fmt_ctx->streams[video_index]->codecpar;
    uint32_t buf_start_pos = 0;
    uint32_t nal_start_pos = 0;
    uint32_t nal_end_pos = 0;
    uint8_t nalu_type;
    uint32_t nalu_header_size=3;
    while (find_nal_unit(packet->data, packet->size, buf_start_pos, &nal_start_pos, &nal_end_pos)) {
        uint32_t len = nal_end_pos - nal_start_pos+1-nalu_header_size;
        if (codecpar->codec_id == AV_CODEC_ID_H264) {
            uint8_t *nalu_start_ptr = packet->data + nal_start_pos;
            nalu_type = find_nal_type_avc(nalu_start_ptr);
        } else if (codecpar->codec_id == AV_CODEC_ID_HEVC) {
            uint8_t *nalu_start_ptr = packet->data + nal_start_pos;
            nalu_type = find_nal_type_hevc(nalu_start_ptr);
        }
        if (nalu_type==1||nalu_type==25||nalu_type==5){
            uint8_t *nal = packet->data + nal_start_pos+nalu_header_size;
        }
        buf_start_pos = nal_end_pos + 1;
    }
    return 0;
}

和在线对比一下,部分长度多了1

image-20231231215159160

对应到ts上发现,这部分下一个文件头都是0x00,0x00,0x00,0x01开头的,修改下代码

image-20231231215320011

find_nal_unit

        if ( nalu_start_found == true && nalu_end_found == true ) {
            (* nal_start_pos) = nalu_start_pos;
            (* nal_end_pos) = nalu_end_pos;
            return true;
        }
        if ( nalu_start_found == true && nalu_end_found == true ) {
                    if (buf[nalu_end_pos] == 0x00 && buf[nalu_end_pos+1] == 0x00 && buf[nalu_end_pos+2] == 0x00 && buf[nalu_end_pos+3] == 0x01) {
                nalu_end_pos = nalu_end_pos - 1;
            }
            (* nal_start_pos) = nalu_start_pos;
            (* nal_end_pos) = nalu_end_pos;
            return true;
        }

image-20231231215555603

这次就一样了

wasm转c

wasm文件下载,大多数网站并不会直接给wasm文件地址,而是以base形式给出,直接搜索data:application/octet-stream;base64,

或者AGFzbQEAAAABm。除此之外,还有某些网站压缩了wasm,文件以br结尾。如果都不行就需要hook对应函数了。或者找到加载部分。

看了上面wasm转c转dll,案例可以知道,我们主要需要的是导入部分。

而web端导出参数,是在加载部分。开发文档介绍中

WebAssembly.Instance() 构造函数以同步方式实例化一个WebAssembly.Module 对象。然而,通常获取实例的方法是通过异步函数WebAssembly.instantiate() .

很容易就定位到,传入了两个参数,一个wasm文件,一个导入参数

image-20231231222625531

主要需要实现的是env,导入了函数,表,内存以及全局变量等

下面就讲讲如何用c去实现

首先利用wabt里面的wasm2c,将代码转换为c,wasm2c int.wasm -o out.c,然后将wbat工具包目录下的wasm-rt.h、wasm-rt-impl.c、wasm-rt-impl.h,以及转出来的文件放一起。

转出来的文件很大尽量不用动,新创建一个imp.c,方便调试需要调试对应代码,直接从out.c里面复制出来,不然直接卡死了。

然后就是在js端对所有导入函数下断点,判断是否用到或者视必须的。

#include "cctvn.c"

u32 *w2c_env_DYNAMICTOP_PTR(struct w2c_env * v) {
    return &v->DYNAMICTOP_PTR;
}

u32 *w2c_env_0x5F_table_base(struct w2c_env *v) {
    return &v->__table_base;
}

wasm_rt_memory_t *w2c_env_memory(struct w2c_env  *v) {
    return &v->memory;
}

static wasm_rt_funcref_table_t table;

wasm_rt_funcref_table_t *w2c_env_table(struct w2c_env * v) {
    return &v->table;
}

void w2c_env_0x5F_0x5FsetErrNo(struct w2c_cctv*, u32){
    return;
}

/* import: 'env' '___syscall140' */
u32 w2c_env_0x5F_0x5Fsyscall140(struct w2c_cctv*, u32, u32){
    return 0;
}

/* import: 'env' '___syscall146' */
u32 w2c_env_0x5F_0x5Fsyscall146(struct w2c_cctv*, u32, u32){
    return 31;
}

/* import: 'env' '___syscall54' */
u32 w2c_env_0x5F_0x5Fsyscall54(struct w2c_cctv*, u32, u32){
    return 0;
}

/* import: 'env' '___syscall6' */
u32 w2c_env_0x5F_0x5Fsyscall6(struct w2c_cctv*, u32, u32){
    return 0;
}

/* import: 'env' '__emscripten_fetch_free' */
void w2c_env_0x5F_emscripten_fetch_free(struct w2c_cctv*, u32){
    return;
}

/* import: 'env' '_emscripten_asm_const_ii' */
u32 w2c_env_0x5Femscripten_asm_const_ii(struct w2c_cctv* v, u32 i, u32 i1){
    u32 len=1;
    uint8_t *d;
    switch (i) {
        case 0:
        case 1:
            if (28352 == i1) {
                d = (uint8_t *) malloc(1);
                memcpy(d, "", 1);
            } else if(28384 == i1) {
                d=(uint8_t *)malloc(56);
                memcpy(d,"https://tv.cctv.com/3cba73e8-4f6c-4d45-a53f-9131c471990a",56);
            }
        case 2:
            if (28480 == i1) {
                d = (uint8_t *) malloc(5);
                memcpy(d, "blob:", 5);
            } else if(28512 == i1) {
                d=(uint8_t *)malloc(56);
                memcpy(d,"https://tv.cctv.com/3cba73e8-4f6c-4d45-a53f-9131c471990a",56);
            }
    }
    u32 ret = w2c_cctv_0x5Fmalloc(v, len);
    memcpy(v->w2c_env_memory->data + ret, d, len);
    return ret;
}

/* import: 'env' '_emscripten_get_heap_size' */
u32 w2c_env_0x5Femscripten_get_heap_size(struct w2c_cctv* v)
{
    return v->w2c_env_memory->size;
}

/* import: 'env' '_emscripten_is_main_browser_thread' */
u32 w2c_env_0x5Femscripten_is_main_browser_thread(struct w2c_cctv*){
    return 0;
}

/* import: 'env' '_emscripten_memcpy_big' */
u32 w2c_env_0x5Femscripten_memcpy_big(struct w2c_cctv* v, u32 dst, u32 src, u32 len){
    memcpy(v->w2c_env_memory->data + dst, v->w2c_env_memory->data + src, len);
}

/* import: 'env' '_emscripten_resize_heap' */
u32 w2c_env_0x5Femscripten_resize_heap(struct w2c_cctv*, u32){
    return 0;
}

/* import: 'env' '_emscripten_start_fetch' */
void w2c_env_0x5Femscripten_start_fetch(struct w2c_cctv*, u32){
    return;
}

/* import: 'env' 'abort' */
void w2c_env_abort(struct w2c_cctv*, u32){
    return;
}

/* import: 'env' 'abortOnCannotGrowMemory' */
u32 w2c_env_abortOnCannotGrowMemory(struct w2c_cctv*, u32){
    return 0;
}

/* import: 'env' 'getTempRet0' */
u32 w2c_env_getTempRet0(struct w2c_cctv*){
    return 0;
}
/* import: 'env' 'jsCall_ii' */
u32 w2c_env_jsCall_ii(struct w2c_cctv*, u32, u32){
    return 0;
}
/* import: 'env' 'jsCall_iidiiii' */
u32 w2c_env_jsCall_iidiiii(struct w2c_cctv*, u32, u32, f64, u32, u32, u32, u32){
    return 0;
}
/* import: 'env' 'jsCall_iiii' */
u32 w2c_env_jsCall_iiii(struct w2c_cctv*, u32, u32, u32, u32){
    return 0;
}
/* import: 'env' 'jsCall_jiji' */
u32 w2c_env_jsCall_jiji(struct w2c_cctv*, u32, u32, u32, u32, u32){
    return 0;
}
/* import: 'env' 'jsCall_v' */
void w2c_env_jsCall_v(struct w2c_cctv*, u32){
    return ;
}
/* import: 'env' 'jsCall_vi' */
void w2c_env_jsCall_vi(struct w2c_cctv*, u32, u32){
    return ;
}
/* import: 'env' 'jsCall_vii' */
void w2c_env_jsCall_vii(struct w2c_cctv*, u32, u32, u32){
    return ;
}
/* import: 'env' 'setTempRet0' */
void w2c_env_setTempRet0(struct w2c_cctv*, u32){
    return ;
}
void w2c_cctv_f57(w2c_cctv* instance, u32 var_p0, u32 var_p1) {

我这里把一部分w2c_env替换了,主要是懒得复制内存,web也是共享的内存。

然后就是加载wasm,到这里可能就有疑问了,转出来的c和上面案例的格式都不太一样,还多了个参数。

实际上是官方,修改了代码,加入更多特性,案例参考git

参考官方案例

.c
void wasm_init(){
    wasm_rt_init();//初始化wasm
    wasm_rt_allocate_memory(&cctv_env.memory, 256, 256, false);//分配内存
    cctv_env.DYNAMICTOP_PTR = 28144u;//设置DYNAMICTOP_PTR
    cctv_env.__table_base = 0;//设置__table_base
    wasm_rt_allocate_funcref_table(&cctv_env.table, 160, 160);//分配函数表
    wasm2c_cctv_instantiate(&cctv, &cctv_env);//注册一个wasm实例
    memcpy(cctv.w2c_env_memory->data + 28144u, data_dynamic_base, 4);//设置DYNAMICTOP_PTR的值,因为是外部导入的内存,所以需要手动设置
     //cctv.w2c_env_DYNAMICTOP_PTR = &cctv_env.DYNAMICTOP_PTR;//设置DYNAMICTOP_PTR的指针
}

.h
#include <imp.c>
w2c_cctv cctv;
w2c_env cctv_env;
static const u8 data_dynamic_base[] = {
        0x10, 0x6E, 0x50, 0x00,
};

然后就是实现调用函数

uint32_t i=1;
const char *cctva="https://tv.cctv.com";
uint8_t *decrypt( uint8_t *nal,uint32_t nal_len) {
    u32 ptr_nal = w2c_cctv_0x5Fmalloc(&cctv, nal_len+1024);
    uint32_t a=0;
    memcpy(cctv.w2c_env_memory->data + ptr_nal, nal, nal_len);
    if (i){
        memcpy(cctv.w2c_env_memory->data + ptr_nal+nal_len,cctva,strlen(cctva));
        a+=strlen(cctva);
        i=0;
    }
    uint32_t len=w2c_cctv_0x5Fvodplay(&cctv, ptr_nal, nal_len, a);
    uint8_t *out_nal = (uint8_t *) malloc(nal_len);
    memcpy(out_nal, cctv.w2c_env_memory->data + ptr_nal, len);
    w2c_cctv_0x5Ffree(&cctv, ptr_nal);
    return out_nal;
}

        printf("nalu_type:%d\tnalu_pyload_len:%d\n", nalu_type, len);
        if (nalu_type==1||nalu_type==25||nalu_type==5){
            uint8_t *nal = packet->data + nal_start_pos+nalu_header_size;
            if (len>32){
                uint8_t *out_nal = decrypt(nal,len);
                memcpy(packet->data + nal_start_pos+nalu_header_size, out_nal, len);
            }
        }

运行,查看转出的h264,然后

image-20231231225849618

image-20231231225940781

看来还是有哪里不对,那就只有尝试还原了,然后把编译出的exe拖进ida,查看对应函数,然后,就没有然后了

image-20231231230301724

分析是不可能分析的,这辈子都不可能

按下f5,

image-20231231230618415

那就只有靠猜了,利用插件查找加密函数,发现有一个tea

image-20231231230734475

然后在网页中调试,然后就发现func57是tea,func60传入了原始数据地址,解密后地址以及长度,还有个计数的感觉没啥用

image-20231231231025079

那么就可以直接写了

u64 num=0u;
uint8_t *decrypt2( uint8_t *nal,uint32_t nal_len){
    u32 in_nal = w2c_cctv_0x5Fmalloc(&cctv, nal_len+1024);
    memcpy(cctv.w2c_env_memory->data + in_nal, nal, nal_len);
    u32 out_nal = w2c_cctv_0x5Fmalloc(&cctv, nal_len+1024);
    uint32_t len=w2c_cctv_f60(&cctv,nal_len, in_nal, out_nal, num);
    num++;
    uint8_t *out_nal2 = (uint8_t *) malloc(nal_len);
    memcpy(out_nal2, cctv.w2c_env_memory->data + out_nal, len);
    w2c_cctv_0x5Ffree(&cctv, in_nal);
    w2c_cctv_0x5Ffree(&cctv, out_nal);
    return out_nal2;
}

运行

image-20231231231319522

终于可以过个跨年夜了,over!!

五、后记

有人可能会问,转出来的h264和acc怎么重新转为ts,直接用FFmpeg就行了,具体网上搜。但我个人不建议在转换为ts了,直接提取所有ts的码流,合并成mp4就行了。因为,你最后ts转mp4还是要先提取码流在合并,除非你是二进制合并。

image-20231231231840587

免费评分

参与人数 60吾爱币 +77 热心值 +53 收起 理由
modesty88 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
sansannanoda + 1 + 1 我很赞同!
frank0 + 1 beautiful
mhh + 1 + 1 用心讨论,共获提升!
linze02 + 1 + 1 用心讨论,共获提升!
baichoufeng + 1 + 1 用心讨论,共获提升!
xhx520 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
jock77 + 1 我很赞同!
xxtt + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
疯兔neo + 1 + 1 用心讨论,共获提升!
uuzone2008 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
99910369 + 1 + 1 谢谢@Thanks!
小叔sir + 1 + 1 我很赞同!
JimLewis + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Yangzaipython + 1 鼓励转贴优秀软件安全工具和文档!
wangyongdesign + 1 + 1 谢谢@Thanks!
LeonSmith123 + 1 用心讨论,共获提升!
sam喵喵 + 1 谢谢@Thanks!
wolfstudio + 1 我很赞同!
52Ender + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
zhczf + 1 + 1 我很赞同!
MYPcodcsja + 1 + 1 谢谢@Thanks!
aflysnail + 1 谢谢@Thanks!
wangguang + 2 + 1 我很赞同!
xxxlsy + 1 + 1 我很赞同!
tomhex + 1 + 1 用心讨论,共获提升!
biancaxl + 1 用心讨论,共获提升!
babyx + 1 + 1 谢谢@Thanks!
爱飞的猫 + 3 + 1 好复杂的过程,感谢分析
好孩子 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
janken + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
飞龙project + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
多德 + 1 谢谢@Thanks!
抱歉、 + 1 谢谢@Thanks!
kiopc + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
aichiyu + 1 + 1 我很赞同!
hehehero + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
杨辣子 + 1 + 1 谢谢@Thanks!
Spacecraft + 1 我很赞同!
yixi + 1 + 1 谢谢@Thanks!
chinawolf2000 + 1 + 1 热心回复!
dbgcode + 1 + 1 我很赞同!
BeyondTheDawn + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kbit + 1 + 1 谢谢@Thanks!
正己 + 10 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
lccccccc + 1 + 1 用心讨论,共获提升!
iokeyz + 3 + 1 我很赞同!
unsuns + 1 + 1 鼓励转贴优秀软件安全工具和文档!
OVVO + 2 + 1 我很赞同!
myeishare + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
mj6810 + 1 + 1 用心讨论,共获提升!
allspark + 1 + 1 用心讨论,共获提升!
Arcticlyc + 2 + 1 我很赞同!
T4DNA + 1 + 1 牛犇啊
luoziyi + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
ofo + 3 + 1 鼓励转贴优秀软件安全工具和文档!
cx冷情 + 1 + 1 谢谢@Thanks!
平淡最真 + 1 + 1 新年快乐&amp;amp;#129298;
漁滒 + 3 + 1 我很赞同!
guhuishou + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

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

推荐
sbwfnhn 发表于 2024-1-2 11:28
从2023年开始,各平台的视频加密越来越复杂,而且每隔一段时间就变换。
这么下去,没钱没技术的穷人,连个电视都看不起了,BT也不能用,以前免费装广播的年代没了
推荐
小叔sir 发表于 2024-1-10 09:14
看了大佬的帖子,好佩服啊,其实我就是那种自己网站做视频教程的小白中的小白~,也想给自己的网站视频加密~想让别人只可以在我网站看,但是不想他可以下载盗走~~无奈目前只会用ffmpeg做个简单的AES加密~但是不了解怎么样从自己把MP4剪切为ts之后,对这种自己的ts和M3U8后续的文件,如何再加密,还是怎么处理,就全然不了解了,,如果天神大哥,可以出一些后面关于加密的教程或方法就好了,谢谢大哥!
沙发
ofo 发表于 2023-12-31 23:51
3#
涛之雨 发表于 2024-1-1 00:25
(和剩下的两三个一起先预支一下精华)
4#
emptynullnill 发表于 2024-1-1 08:10
很详细。大家元旦快乐
5#
zwtstc 发表于 2024-1-1 10:28
写的不错,感谢
6#
webphp 发表于 2024-1-1 11:03
大神写得不错啊,
7#
真爱贤 发表于 2024-1-1 11:44
本来我也遇到个ts加密的网站,不知道怎么搞,看到你的分析那么复杂,我还是放弃了吧
8#
mj6810 发表于 2024-1-1 12:58
强,顶一个!
9#
tafeita 发表于 2024-1-1 13:38
精彩,学习了
10#
LuckyClover 发表于 2024-1-1 13:55
跟着大佬后面学习思路
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-4-28 18:31

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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