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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5854|回复: 138

[Android 原创] 【i春秋】-网络安全-缓存视频文件解密

    [复制链接]
发表于 2018-8-5 22:18 | 显示全部楼层
本帖最后由 BetaMao 于 2018-8-9 23:50 编辑

*注:本文不提供任何视频文件,也请大家不要传播使用盗版视频,尊重讲师劳动成果。*

由于VIP快到期了,就想把视频下载下来慢慢看,但是它只能在手机上使用官方app观看,不仅占空间而且还不敢保证到期后缓存的视频还能看,于是想把它提取出来,经查找缓存文件放在/Android/data/com.ni.ichunqiu/videocache目录下,每个视频被分片,即m3u8,且使用AES加密,当然密钥文件也在本地,但是很明显这个密钥文件本身也是被加密的,于是需要解密key->解密分段视频->合成视频这几步,其中后面两步很简单,关键就在第一步,仔细观察只能猜出密钥是base64编码存放的,看不出是什么加密,只能分析app啦。

M3U8

好像是APPLE弄出来的一种流媒体格式,索引文件为.m3u8,里面内容如下,真正的视频存储在.ts文件里,ts可以被加密,加密密钥存放在如下描述处:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:27
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="key",IV=0x99b74007b6254e4bd1c6e03631cad15b           #加密密钥位置
#EXTINF:26.250000,
585730.ts                                                                           #一个个小的碎片的位置
#EXTINF:16.875000,
585731.ts
...............
#EXT-X-ENDLIST

现在有了ts和m3u8文件啦,还需要把key解密。

直接在官方下载发现文件使用了360加固,惹不起躲得起,在豌豆荚找到旧版发现依然能用,就从旧版入手,虽然还是有壳,但是应该会好脱很多了。

  1. 下载drizzleDumper
  2. 自动脱壳:
    adb push x86/drizzleDumper /storage/sdcard/
    chmod +x drizzleDumper
    adb shell
    /storage/sdcard/drizzleDumper com.ni.ichunqiu
    exit
    adb pull xxx.dex E:\\

    很顺利的得到两个dex

分析

在使用本地缓存时应该需要读取文件,其中部分路径应该是硬编码的,使用/key.m3u8作为关键字搜索字符串直接找到了关键点:

下载加密

分析

经分析发现本类为下载处,也好,看看加密过程也就知道解密啦!
1.首先它通过video.key.get方法获取到服务端返回的key,然后调用a.getKey(key)处理它:

    public static String getKeyFromServer(String token, String url, CourseM3u8Info courseinfo) {
        InputStream httpIStream;
        URLConnection conn;
        String timestamp;
        if(url.startsWith("http://")) {
            try {
                String vid = url.substring(url.lastIndexOf("=") + 1);
                timestamp = URLEncoder.encode(new Date().getTime() + "", "UTF-8");
                HashMap v2 = new HashMap();
                v2.put("app_key", "100001");
                v2.put("ver", "1");
                v2.put("timestamp", timestamp);
                v2.put("method", "video.key.get");
                v2.put("os", "android");
                v2.put("mac", "00000");
                v2.put("from", "app.android");
                v2.put("token", token);
                v2.put("vid", vid);
                LLLLLLLLLLl.sign(v2);
                StringBuilder urlParas = new StringBuilder();
                Iterator v2_1 = v2.entrySet().iterator();
                while(v2_1.hasNext()) {
                    Object v0_4 = v2_1.next();
                    urlParas.append(((Map$Entry)v0_4).getKey()).append("=").append(((Map$Entry)v0_4).getValue()).append("&");
                }

                timestamp = String.format("%s?%s", userInfo.a().b(), urlParas.toString());
                d.LOG("newUrl =" + timestamp);
                conn = new URL(timestamp).openConnection();
                ((HttpURLConnection)conn).setConnectTimeout(5000);
                ((HttpURLConnection)conn).setRequestMethod("GET");
                if(((HttpURLConnection)conn).getResponseCode() != 200) {
                    d.LOG("请求url失败 url 是 =" + timestamp);
                    CacheFileEvent.sendTsAnalysisError(courseinfo.getChapter_id(), courseinfo.getSection_id(), 0);
                    return "";
                }

                httpIStream = ((HttpURLConnection)conn).getInputStream();
            }
            catch(Exception v0) {
                ....
            }
            try {
                timestamp = LLLLLLLLLLl.ISGetString(httpIStream, "UTF-8");  // 从服务端得到base64编码的key
                ((HttpURLConnection)conn).disconnect();
                return a.getKey(timestamp);
            }
            catch(Exception v0_1) {
                ....
            }
        }

        return null;
    }

2.a.getKey(key)做如下处理:

    public static String getKey(String key1) {  
        String v0 = null;
        if(!TextUtils.isEmpty(((CharSequence)key1))) {
            String uid = key.getUserId();                                   //为一串数字哈
            String realKey = key.rc4decrypto(key1, key.stringAppVideoKey);  //使用AppVideoKey解密key1
            if(TextUtils.isEmpty(((CharSequence)uid))) {
                return v0;
            }

            v0 = key.rc4encrypto(realKey + "____" + uid, key.stringAppVideoKey);
        }
        return v0;
    }

其中keycom.ichunqiu.libglobal.tool.f这个类,它是一个很重要的解密类,里面主要包含两个RC4加解密函数,加解密用的密钥是AppVideoKey这个字符串,它来自flytv.run.monitor.MyApplication匿名内部类的run方法:

.method public run()V
          .registers 5
00000000  const/4             v3, 0
00000002  iget-object         v0, p0, MyApplication$1->a:MyApplication
00000006  const-string        v1, "PUSH_APPID"
0000000A  const/4             v2, 0
0000000C  invoke-virtual      MyApplication->a(String, String)String, v0, v1, v2
00000012  move-result-object  v0
00000014  new-instance        v1, IChunqiuJni
00000018  invoke-direct       IChunqiuJni-><init>()V, v1
0000001E  invoke-virtual      IChunqiuJni->stringAppVideoKeyJNI()String, v1
00000024  move-result-object  v2
00000026  sput-object         v2, key->stringAppVideoKey:String
0000002A  invoke-virtual      IChunqiuJni->stringAppSecretKeyJNI()String, v1
00000030  move-result-object  v1
00000032  sput-object         v1, key->stringAppSecretKey:String
...............
.end method

看到它其实IChunqiuJni这个native层的动态库,解压文件即可得到它,用阿达打开即可得到密钥:

EXPORT Java_com_ni_ichunqiu_IChunqiuJni_stringAppSecretKeyJNI
Java_com_ni_ichunqiu_IChunqiuJni_stringAppSecretKeyJNI
; __unwind {
PUSH    {R3,LR}
LDR     R1, =(a00dfafa4ed6b64 - 0xCA4)
LDR     R2, [R0]
MOVS    R3, #0x29C
LDR     R3, [R2,R3]
ADD     R1, PC          ; "32dfafa4ed6b64f7644172c1ee9ad2f4"
BLX     R3
POP     {R3,PC}
; End of function Java_com_ni_ichunqiu_IChunqiuJni_stringAppSecretKeyJNI

3.当把密钥处理好以后,会存储在本地的/key文件下,并且更改m3u8的key uri为key

user = LLLLLLLLLLl.getRealKey(user, keyuri, this.courseinfo);
LLLLLLLLLLl.string2file(this.a.substring(0, this.a.lastIndexOf("/")) + "/key", user, false);    //存储加密后的key
sb.append(aline.replace(((CharSequence)keyuri), "key") + "\n");                                 //.M3U8文件

小结

其实内部还有很多处理与验证逻辑但是和解密key无关就省去了,通过分析发现:

key = LLLLLLLLLLl.ISGetString(httpIStream, "UTF-8");        // 1.从服务端得到base64编码的key
String uid = key.getUserId();                               // 2.得到用户id
String realKey = key.rc4decrypto(key1, key.stringAppVideoKey); // 3.使用从APP里得到的VideoKey解密服务端返回的key,里面会校验解密是否正确
localKey = key.rc4encrypto(realKey + "____" + uid, key.stringAppVideoKey);// 4.再使用VideoKey加密realKey + "____" + uid,之后存储在本地
                                                                        //也就是说本地存储的key其实适合用户绑定的

播放解密

1.根据上面分析发现key这个类很关键,加解密都在这里,于是查看交叉引用发现另一个类com.google.android.exoplayer.b\nnnn自命名,忘了原名啦调用了它,其内部就是解密代码:

   public nnnn(d arg7, byte[] key1, byte[] arg9) {      //经分析,后两个参数分别是本地存储的key和iv   
        String uid;
        String key;
        byte[] keykey;
        String keey1;
        int v0 = 0;
        super();
        if(key1 != null) {
            try {
                this.uid = key.getUserId();
                keey1 = new String(key1, "ASCII");
                key = key.rc4decrypto(keey1, key.stringAppVideoKey);            //完全的逆过程,解密key
                if(!key.contains("____")) {                                     //_____分割,第一部分为key第二部分为uid
                    goto label_117;
                }
                String[] v3 = key.split("____");
            label_62:
                uid = v3[1];
                if(!uid.equals(this.uid)) {                                     //判断uid是否相符,只有下载的人能够播放它
                    goto label_69;
                }

                keykey = this.a(v3[0]);
            }
            try {
            label_117:
                mylog.print("Aes128DataSourceKey 旧的的解析播放");
                keykey = this.a(key);   }                                       //处理解密后的key
        this.a = arg7;
        this.midKey = keykey;
        this.IV = arg9;
    }

2.转到a()函数,在其内部先尝试以此为键取,失败就去生成它:

    public byte[] a(String s) {
        byte[] v0_4;
        Object v0_2;
        try {
            v0_2 = hls.hashmap.get(s);
            if(v0_2 != null) {
                goto label_13;
            }

            if(s == null) {
                goto label_16;
            }

            String v0_3 = hls.generaKey(s);
            v0_4 = hls.hexS2bytes(v0_3);
            goto label_13;
        }
    label_16:
        v0_4 = null;
    label_13:
        return ((byte[])v0_2);
    }

3.又转到hls.generaKey(key)函数:

    public static String generaKey(String s) throws IOException, HLsParserException {
        String v2_2;
        int hex = 16;
        String v0 = null;
        int v1 = 0;
        InputStream v2 = con.context.getAssets().open("dict.png");                      //首先打开资源文件里面的一张图,可以解压apk得到
        if(s != null && !s.equals("")) {
            System.currentTimeMillis();
            new BitmapFactory$Options().inPreferredConfig = Bitmap$Config.ARGB_8888;
            Bitmap bitmap = BitmapFactory.decodeStream(v2);
            int i = 4;          
            try {
                v2_2 = s.substring(0, i);                                               //取出前缀2字节,还剩16字节,目标就在前方啊
            }
            catch(Exception v2_1) {
                v2_1.printStackTrace();
                v2_2 = v0;
            }

            if(v2_2 == null) {
                return v0;
            }

            int v5 = Integer.parseInt(v2_2, hex);                                       
            String v3_1 = hls.int2Hex(v5);
            if(bitmap == null) {
                new HLsParserException("请将工程目录下添加 dict资源");
            }

            if(s == null || (s.equals(""))) {
                new HLsParserException("请求生成原始的解密 key 不能为空!");
            }

            if(!s.contains(((CharSequence)v3_1))) {                                     //简单校验一下前缀
                return v0;
            }

            String v6 = s.replaceAll(v2_2, "");                                         //去除前缀
            if(bitmap == null) {
                return v0;
            }

            int height = bitmap.getHeight();
            int width = bitmap.getWidth();
            Object intmap = new int[height][width];
            i = 0;
        label_46:                                                                       //以RGB方式处理位图
            if(i < height) {
                int j = 0;
            label_48:
                if(j < width) {
                    int v9 = bitmap.getPixel(j, i);
                    intmap[i][j] = Color.blue(v9) / 85 + ((Color.red(v9) / 36 << 5) + (Color.green(v9) / 36 << 2));
                    ++j;
                    goto label_48;
                }

                ++i;
                goto label_46;
            }

            Object v2_4 = intmap[v5];                                                   //以前缀为下标取行
            StringBuffer v3_2 = new StringBuffer("");
            int k = 0;
        label_76:
            if(k < v6.length()) {
                String v4_1 = v6.substring(v1, v1 + 2);
                v1 += 2;
                v3_2.append(hls.int2hex(v2_4[Integer.parseInt(v4_1, hex)]));            //映射出密码
                k += 2;
                goto label_76;
            }

            System.currentTimeMillis();
            v0 = v3_2.toString();
        }

        return v0;
    }

dict

dict

小结

服务端返回的key并非最终的解密密钥,可以防止抓包获取,它其实是根据app版本生成,在本地使用VideoKey解密后得到的依然不是最终的key,还要以此为输入做一个查表映射,最终得道的才是真正的key:

data = key.rc4decrypto(localKey, key.stringAppVideoKey);    //解密本地存储的key
String[] data1 = data.split("____");                        //分割,校验uid,通过后前部用去查表
//data[1]=?uid
key = hls.hashmap.get(data[0]);            //先尝试从内存中获取
if(key==null){
    String v0_3 = hls.generaKey(s);                         //查表获取真实的key
}

解密脚本

这里的针对特定版本的app,key是不一样的,位图的话没有看,所以猜测不同的app可能不适用,这里列出最关键部分代码,可用于解密1.4版本下载的视频:

    public static void main(String[] args) throws Exception {

        String parentDirpath = "E:\\Video";//获取目录
        File parentDirFile = new File(parentDirpath);//循环获取目录下所有视频,解密
        if (parentDirFile.exists() && parentDirFile.isDirectory()) {
            File[] dirs = parentDirFile.listFiles();
            for (File file : dirs) {
                if(file.isDirectory()) {
                    String keyfile = file.getAbsolutePath() + File.separator + "key";
                    String chpier = new String(MUtils.readFile(keyfile), "UTF-8");          //读取key
                    MUtils.saveFile(MUtils.readFile(keyfile), keyfile+".bak");              //备份key
                    String key = DecryptoKey.decrypt(chpier);                               //解密key
                    MUtils.saveFile(MUtils.hexS2bytes(key), keyfile);                       //替换key
                    String fullpath = file.getAbsolutePath() + File.separator;
                    String path = file.getName();
                    String cmd = String.format("powershell ffmpeg.exe -allowed_extensions ALL -i %s.m3u8 -c copy -bsf:a aac_adtstoasc %s.mp4", path,"../"+path);
                    System.out.println(execCmd(cmd, new File(fullpath)));  //指定工作目录,执行解密合成命令
                }
            }
        }
    }

public class DecryptoKey {
    private static final String BITMAPPATH = "dict.png";                //提取出的位图位置
    public static String AppVideoKey = "";                              //so文件中拿到的app key
    public static String AppSecretKey = "";

    public static String decrypt(String chpier) throws IOException {
        String text = rc4decrypto(chpier, AppVideoKey);                 //解密key
        String keypro = text.split("____")[0];                          //取第一部分,它的长度为18字节
        //System.out.println(keypro.length());                
        return generaKey(keypro);                                       //生成解密的key
    }
    private static String generaKey(String s) throws IOException {
        String prefix;
        int hex = 16;
        String v0 = null;
        int v1 = 0;
        if (s != null && !s.equals("")) {
            System.currentTimeMillis();
            InputStream v2 = new FileInputStream(BITMAPPATH);             //读取位图
            BufferedImage bi = ImageIO.read(v2);
            int i = 4;
            try {
                prefix = s.substring(0, i);
            } catch (Exception v2_1) {
                v2_1.printStackTrace();
                prefix = v0;
            }

            if (prefix == null) {
                return v0;
            }

            int v5 = Integer.parseInt(prefix, hex);
            //String v3_1 = hls.int2Hex(v5);
            String v3_1 = Integer.toHexString(v5);
            if (!s.contains(((CharSequence) v3_1))) {                       //校验s的前缀
                return v0;
            }

            String v6 = s.replaceAll(prefix, "");                           //去前缀

            int height = bi.getHeight();
            int width = bi.getWidth();
            int[][] intmap = new int[height][width];
            for (i = 0; i < height; i++) {                                  //处理位图
                for (int j = 0; j < width; j++) {
                    int v9 = bi.getRGB(j, i);
                    int[] rgb = new int[3];
                    rgb[0] = (v9 & 0xff0000) >> 16; // r
                    rgb[1] = (v9 & 0xff00) >> 8; // g
                    rgb[2] = (v9 & 0xff); // b
                    intmap[i][j] = rgb[2] / 85 + ((rgb[0] / 36 << 5) + (rgb[1] / 36 << 2));
                }
            }

            int[] v2_4 = intmap[v5];
            StringBuffer v3_2 = new StringBuffer("");
            for (int k = 0; k < v6.length(); k += 2) {                      //映射密码
                String v4_1 = v6.substring(v1, v1 + 2);
                v1 += 2;
                String tmp = Integer.toHexString(v2_4[Integer.parseInt(v4_1, hex)]);
                System.err.println(tmp);
                v3_2.append(tmp.length()!=2?"0"+tmp:tmp);
                System.err.println(v3_2);
            }

            System.currentTimeMillis();
            v0 = v3_2.toString();
        }

        return v0;
    }

    private static String rc4decrypto(String arg13, String passwd) {    //RC4加密函数2
        int v8;
        String v0;
        int IntArrLen = 0x100;
        int v12 = 8;
        if (arg13.isEmpty()) {
            v0 = "";
        } else {
            String md5S = md5class.strToMd5(passwd);
            int len1 = md5S.length();
            byte[] v5 = MUtils.base64Decode(arg13);
            int len2 = v5.length;
            int[] v3 = new int[IntArrLen];
            int[] v7 = new int[IntArrLen];
            int i;
            for (i = 0; i <= 0xFF; ++i) {
                v8 = i % len1;
                v3[i] = md5S.substring(v8, v8 + 1).toCharArray()[0];
                v7[i] = i;
            }

            i = 0;
            len1 = 0;
            while (i < IntArrLen) {
                len1 = (len1 + v7[i] + v3[i]) % 0x100;
                v8 = v7[i];
                v7[i] = v7[len1];
                v7[len1] = v8;
                ++i;
            }

            byte[] v8_1 = new byte[len2];
            i = 0;
            len1 = 0;
            int v3_1 = 0;
            while (i < len2) {
                len1 = (len1 + 1) % 0x100;
                v3_1 = (v3_1 + v7[len1]) % 0x100;
                int v9 = v7[len1];
                v7[len1] = v7[v3_1];
                v7[v3_1] = v9;
                v8_1[i] = ((byte) (((char) (v5[i] ^ v7[(v7[len1] + v7[v3_1]) % 0x100]))));
                ++i;
            }

            v0 = new String(v8_1);
            v0 = v0.substring(0, v12)
                    .equals(md5class.strToMd5(v0.substring(v12, v0.length()).concat(md5S)).substring(0, v12))
                            ? v0.substring(v12)
                            : "";
        }

        return v0;
    }

}

结果

关于文件名

文件名信息被保存在/data/data/com.ni.ichunqiu/databases/alldata.db数据库里,写个脚本批量改就好了~下面代码大部分情况下都能用,有问题自己改吧~

package ichunqiu;

import java.io.File;
import java.sql.SQLException;
import java.util.Map;

import ichunqiu.sqliteutils.SqliteHelper;

public class Rename {
/*
cp /data/data/com.ni.ichunqiu/databases/alldata.db /sdcard/windows/Pictures/
cp -r /sdcard/Android/data/com.ni.ichunqiu/VideoCache/ /sdcard/windows/Pictures/
*/
      public static void main(String[] args) throws ClassNotFoundException, SQLException
      {
          String path = "J:\\拉拉\\31304\\";                    //我会暴露自己的用户名?
          SqliteHelper h = new SqliteHelper(path + "alldata.db");
          Map<String,String> map= h.eq("select chapter_title,course_title,section_id,section_index from course_m3u8_info"); 
            File root = new File(path);
            if (root.exists() && root.isDirectory()) {
            File[] files = root.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (files[i].getName().contains(".mp4")) {
                    int id = files[i].getName().lastIndexOf(".mp4");
                    String name = files[i].getName().substring(0, id);
                    String tmp = map.get(name);
                    if(tmp==null||tmp.isEmpty()) {
                        System.out.println("未找到相应数据");
                    }else{
                        String dirname = tmp.split("\\|")[0];
                        String title = tmp.split("\\|")[1];
                        String index = tmp.split("\\|")[2];
                        File dir = new File(path+dirname);
                        if(!dir.exists()) {
                            dir.mkdirs();
                        }
                        String newname = String.format("第%s节-%s.mp4", index,title);
                        if(!files[i].renameTo(new File(dir.getAbsolutePath()+"/"+newname)))
                            System.out.println("出错");

                        System.out.println(new File(dir.getAbsolutePath()+"/"+newname).getAbsolutePath());
                    }
                }
            }
        }
      }
}

结束

上面省去了很多细节只留下最关键的部分,其实分析是倒过来分析的,还挺有意思~(ε=ε=ε=┏(゜ロ゜;)┛

点评

今天没评分了。给hmily说一声,就说是我说的,让加个精华  发表于 2018-8-11 18:46

免费评分

参与人数 37吾爱币 +41 热心值 +34 收起 理由
Tankes + 1 我很赞同!
Braycep + 1 + 1 我很赞同!
天羽 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
仓鼠666 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
Lone2Ranger + 1 + 1 我很赞同!
Caesar + 1 + 1 谢谢@Thanks!
553429363 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
丶咖啡猫丶 + 1 + 1 谢谢@Thanks!
qq595045020 + 1 + 1 我很赞同!
下弦乀月 + 1 + 1 用心讨论,共获提升!
ainimemeda + 1 + 1 用心讨论,共获提升!
airwu + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yizhiyuji + 1 + 1 用心讨论,共获提升!
1027102633 + 1 + 1 谢谢@Thanks!
9D8147 + 1 + 1 谢谢@Thanks!
五五66 + 1 + 1 热心回复!
黑的思想 + 2 + 1 谢谢@Thanks!
wanttobeno + 2 + 1 谢谢@Thanks!
youhen233 + 1 谢谢@Thanks!
poisonbcat + 1 + 1 谢谢@Thanks!
塞北的雪 + 1 + 1 下载后可以转成普通MP4,请看我的文章 https://blog.csdn.net/sbdx/article.
老板来包辣条 + 1 + 1 用心讨论,共获提升!
god147 + 1 + 1 谢谢@Thanks!
AhKeiya + 2 + 1 谢谢@Thanks!
孟德兄 + 1 用心讨论,共获提升!
静叶流云 + 1 + 1 用心讨论,共获提升!
zlgc01 + 1 + 1 我很赞同!
smile1110 + 3 + 1 我很赞同!
windwli + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
博一笑 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
MaxMadcc + 1 + 1 谢谢@Thanks!
哎哟呵 + 1 + 1 用心讨论,共获提升!
MYxx + 1 + 1 谢谢@Thanks!
chenjingyes + 1 + 1 谢谢楼主分享 另外不用逆向app 直接搞js逆向也是可以解密的 哈哈哈!楼主.
snail_ + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
独行风云 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
赤玄 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

 楼主| 发表于 2018-8-6 09:19 | 显示全部楼层
hjclass.saver 发表于 2018-8-6 08:48
这个网站没有在线观看么?直接抓包不行么?

高级一点儿的,key值会在swf文件里面用as3处理一下

哈哈,我不懂flash,看过网页h5版的依然用的hls,还是对key加密了无法抓包解密,它是本地js解密,js被混淆过又不熟悉它就转到Android了

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2018-8-9 12:20 | 显示全部楼层
BetaMao 发表于 2018-8-6 09:19
哈哈,我不懂flash,看过网页h5版的依然用的hls,还是对key加密了无法抓包解密,它是本地js解密,js被混 ...

调试过PC网页版的,印象中好像js中的算法和楼主分析的是一样的,也有那张诡异的图片

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2018-8-5 22:34 | 显示全部楼层

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2018-8-5 22:39 | 显示全部楼层
好厉害的样子。。。。

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2018-8-5 22:45 | 显示全部楼层
技术宅都是头铁  我们为什么不找个资源看呢

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2018-8-5 22:51 | 显示全部楼层
我们为什么不找个资源看呢

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

 楼主| 发表于 2018-8-5 23:04 | 显示全部楼层
Ftimes 发表于 2018-8-5 22:45
技术宅都是头铁  我们为什么不找个资源看呢

仅用于技术分享,自己看,不盗版(认真严肃正经脸)

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2018-8-6 00:18 | 显示全部楼层
思路不错蛤,学习了

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2018-8-6 00:20 来自手机 | 显示全部楼层
66666谢谢分享

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2018-8-6 00:49 | 显示全部楼层
谢谢楼主分享  另外不用逆向app 直接搞js逆向也是可以解密的  哈哈哈!楼主可以试试!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2018-8-6 07:46 | 显示全部楼层
看不懂,还是支持一下楼主

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则


免责声明:
吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:Service@52PoJie.Cn

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

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

GMT+8, 2018-8-17 07:23

Powered by Discuz!

© 2001-2017 Comsenz Inc.

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