腾讯手机管家加密相册打不开的照片 视频 大部分正常 小部分打不开 也解密不了 没什么 怎么恢复正常

【i春秋】-网络安全-缓存视频文件解密 - 『移动安全区』
- 吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn
后使用快捷导航没有帐号?
只需一步,快速开始
请完成以下验证码
请完成以下验证码
查看: 6602|回复: 163
【i春秋】-网络安全-缓存视频文件解密
阅读权限10
本帖最后由 BetaMao 于
19:42 编辑
注:本文不提供任何视频文件,也请大家不要传播使用盗版视频,尊重讲师劳动成果。
关于最新版和相关文件
小声BB:我也不知道为啥这篇没啥技术含量的帖子被加精了,反正受宠若惊,而且还有小伙伴感兴趣,我就把相关文件直接传出来大家可以直接下载分析
密码:80o4:旧版.zip就是本篇下面记载的,新版.zip是本小节记载的,new.zip是用来解新版的视频的,解密旧版视频的代码在本篇文章的最下面。
今天没事又看了看新版,试了下发现新版也可以自动脱,dump出好几个dex,经过分析就两个有用,因为过程差不多我就不详细记了,就说下解密大体流程:
查看文件发现下载的m3u8和key都被加密了,并且key的长度是95字节,m3u8的长度不固定无填充。
经过找关键点与交叉引用发现m3u8文件用rc4decrypt这个函数解密即可得到明文,解密密钥硬编码的,为ded2899ead484e8c43b5df69d0fa995d
本地的key经过多次加密,第一次用rc4decrypt函数以videokey为密钥就可以解密得到key2,其中videokey在jni.so文件中,经过分析为了兼容以前的版本它实际上不会变化一直是d8d8df96a3e。
key2同样是用rc4decrypt解密,只是这次的密钥不同了,随key2变化,我下载了三个文件都是用同一类型的密钥,我就假设这个版本都是用这种类型的密钥了:aadskjldbla + "_" + userId + "_" + sectionId,这三个值都可以从数据库获得。
如上,具体可以看解密代码,解密代码打包为new.zip了,代码写的很丑请见谅,有兴趣可以完善啊~
手动割,以下为原文
由于VIP快到期了,就想把视频下载下来慢慢看,但是它只能在手机上使用官方app观看,不仅占空间而且还不敢保证到期后缓存的视频还能看,于是想把它提取出来,经查找缓存文件放在/Android/data/com.ni.ichunqiu/videocache目录下,每个视频被分片,即m3u8,且使用AES加密,当然密钥文件也在本地,但是很明显这个密钥文件本身也是被加密的,于是需要解密key-&解密分段视频-&合成视频这几步,其中后面两步很简单,关键就在第一步,仔细观察只能猜出密钥是base64编码存放的,看不出是什么加密,只能分析app啦。
好像是APPLE弄出来的一种流媒体格式,索引文件为.m3u8,里面内容如下,真正的视频存储在.ts文件里,ts可以被加密,加密密钥存放在如下描述处:
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:27
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="key",IV=0x99be4bd1c6e03631cad15b& && && && && && && && &#加密密钥位置
#EXTINF:26.250000,
585730.ts& && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && && &&&#一个个小的碎片的位置
#EXTINF:16.875000,
...............
#EXT-X-ENDLIST
现在有了ts和m3u8文件啦,还需要把key解密。
直接在官方下载发现文件使用了360加固,惹不起躲得起,在豌豆荚找到旧版发现依然能用,就从旧版入手,虽然还是有壳,但是应该会好脱很多了。
自动脱壳:
adb push x86/drizzleDumper /storage/sdcard/
chmod +x drizzleDumper
/storage/sdcard/drizzleDumper com.ni.ichunqiu
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 httpIS
& && &&&URLC
& && &&&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) {
& && && && && & ....
& && && && &}
2.a.getKey(key)做如下处理:
& & public static String getKey(String key1) {&&
& && &&&String v0 =
& && &&&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;
其中key是com.ichunqiu.libglobal.tool.f这个类,它是一个很重要的解密类,里面主要包含两个RC4加解密函数,加解密用的密钥是AppVideoKey这个字符串,它来自flytv.run.monitor.MyApplication匿名内部类的run方法:
.method public run()V
& && && & .registers 5
&&const/4& && && && & v3, 0
&&iget-object& && && &v0, p0, MyApplication$1-&a:MyApplication
&&const-string& && &&&v1, "PUSH_APPID"
0000000A&&const/4& && && && & v2, 0
0000000C&&invoke-virtual& && &MyApplication-&a(String, String)String, v0, v1, v2
&&move-result-object&&v0
&&new-instance& && &&&v1, IChunqiuJni
&&invoke-direct& && & IChunqiuJni-&&init&()V, v1
0000001E&&invoke-virtual& && &IChunqiuJni-&stringAppVideoKeyJNI()String, v1
&&move-result-object&&v2
&&sput-object& && && &v2, key-&stringAppVideoKey:String
0000002A&&invoke-virtual& && &IChunqiuJni-&stringAppSecretKeyJNI()String, v1
&&move-result-object&&v1
&&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& && && & ; "32dfafa4ed6b64fee9ad2f4"
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& &
& && &&&byte[]
& && &&&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 =
& && &&&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 =
& & 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 =
& && &&&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;
QQ截图19.png (291.93 KB, 下载次数: 0)
22:09 上传
服务端返回的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.
& && && && && && && && && && && && && & 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 {
& && && && && & S
& && && && && & int hex = 16;
& && && && && & String v0 =
& && && && && & 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 & i++) {& && && && && && && && && && && & //处理位图
& && && && && && && && && && &&&for (int j = 0; j & 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.
& && && && && && && && &int[] v3 = new int[IntArrLen];
& && && && && && && && &int[] v7 = new int[IntArrLen];
& && && && && && && && &
& && && && && && && && &for (i = 0; i &= 0xFF; ++i) {
& && && && && && && && && && &&&v8 = i % len1;
& && && && && && && && && && &&&v3[i] = md5S.substring(v8, v8 + 1).toCharArray()[0];
& && && && && && && && && && &&&v7[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数据库里,写个脚本批量改就好了~下面代码大部分情况下都能用,有问题自己改吧~
import java.io.F
import java.sql.SQLE
import java.util.M
import ichunqiu.sqliteutils.SqliteH
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. 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说一声,就说是我说的,让加个精华&
吾爱币 +42
热心值 +35
谢谢@Thanks!
我很赞同!
我很赞同!
欢迎分析讨论交流,吾爱破解论坛有你更精彩!
鼓励转贴优秀软件安全工具和文档!
我很赞同!
谢谢@Thanks!
鼓励转贴优秀软件安全工具和文档!
谢谢@Thanks!
我很赞同!
用心讨论,共获提升!
用心讨论,共获提升!
感谢发布原创作品,吾爱破解论坛因你更精彩!
用心讨论,共获提升!
谢谢@Thanks!
谢谢@Thanks!
热心回复!
谢谢@Thanks!
谢谢@Thanks!
谢谢@Thanks!
谢谢@Thanks!
下载后可以转成普通MP4,请看我的文章 https://blog.csdn.net/sbdx/article.
用心讨论,共获提升!
谢谢@Thanks!
谢谢@Thanks!
用心讨论,共获提升!
用心讨论,共获提升!
我很赞同!
我很赞同!
欢迎分析讨论交流,吾爱破解论坛有你更精彩!
感谢发布原创作品,吾爱破解论坛因你更精彩!
谢谢@Thanks!
用心讨论,共获提升!
谢谢@Thanks!
谢谢楼主分享
另外不用逆向app 直接搞js逆向也是可以解密的
哈哈哈!楼主.
欢迎分析讨论交流,吾爱破解论坛有你更精彩!
感谢发布原创作品,吾爱破解论坛因你更精彩!
谢谢@Thanks!
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
这个网站没有在线观看么?直接抓包不行么?
高级一点儿的,key值会在swf文件里面用as3处理一下
哈哈,我不懂flash,看过网页h5版的依然用的hls,还是对key加密了无法抓包解密,它是本地js解密,js被混淆过又不熟悉它就转到Android了
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
老哥,我也下了些视频,但是无法去加固,也就拿不到appkey,那你这方法还能用么?
不不,加固没有影响到so文件,我发现之前看错了,看了好几个版本的key都是一样的:d8d8df96a3e,晚上我再发一下稍微详细点的代码~
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
这个可以学习下&&谢谢分享
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限25
好厉害的样子。。。。
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
技术宅都是头铁&&我们为什么不找个资源看呢
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
我们为什么不找个资源看呢
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
技术宅都是头铁&&我们为什么不找个资源看呢
仅用于技术分享,自己看,不盗版(认真严肃正经脸)
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
思路不错蛤,学习了
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
66666谢谢分享
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
谢谢楼主分享&&另外不用逆向app 直接搞js逆向也是可以解密的&&哈哈哈!楼主可以试试!
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
看不懂,还是支持一下楼主
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
免责声明:吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。
( 京ICP备号 | 京公网安备 87号 )
Powered by Discuz!
Comsenz Inc.}

我要回帖

更多关于 腾讯手机管家加密相册打不开 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信