数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 5270|回复: 81

[播放] 拆个早教故事机,尝试解析加密文件

[复制链接]
发表于 2022-5-5 16:33:33 | 显示全部楼层 |阅读模式
本帖最后由 飞向狙沙 于 2022-5-5 16:47 编辑

如题,小姨子给宝宝买的早教故事机,价格未知,没屏幕,可连蓝牙,但是连蓝牙后只是普通音响,也没有可视菜单,故事挨个播放,所以为了宝宝健康,给宝宝使用的东西就应该先拆了弄懂原理才知道安全不安全。
材质不清楚,有点像TPU,微软

整体无螺丝,要么卡口要么就是防尘罩下,打开防尘罩四颗螺丝




就一个MP3主板+内存卡,屏幕都轮不着,卖资料钱了






--------------------------------------------------分割线---------------------------------------------------------------------
下面是程序部分
读卡器读出来是一对smp文件,一开始以为就像wmv之类的格式,转换软件转了下播放不了,搜了下发现这类数据值钱的小播放器经常会用这种格式,很多都是对数据简单异或处理的,就用winhex读了一下,部分如下
  1. 1A 42 86 07 1A 42 86 07 1A 42 86 07 1A 42 86 07
  2. 1A 42 86 07 1A 42 86 07 1A 42 86 07 1A 42 86 07
  3. 1A 42 86 07 1A 16 C7 40 1A 42 86 07 1A 42 86 07
复制代码
大量1A 42 86 07重复,怀疑这个就是异或的值,然后写个小程序对源文件直接处理生成mp3尝试播放,播放成功,也没什么技术含量,要是再增加一些移位交换之类的就得费点脑细胞了
解码程序放gitee了,有需要的自己克隆吧
https://gitee.com/feixiangjusha/smp-decrypt

  1. public class Main {
  2.     private final static String sourceExt = "smp";
  3.     private final static String saveExt = "mp3";

  4.     public static void main(String[] args) throws IOException {
  5.         //加密字符串
  6.         byte[] key;
  7.         //文件所在根文件夹
  8.         File root;

  9.         List<String> filePath = new LinkedList<String>();

  10.         Scanner scanner = new Scanner(System.in);
  11.         //获取文件根目录
  12.         System.out.println("请输入smp文件根目录,支持深度检索");
  13.         do {
  14.             String rootPath = scanner.nextLine();
  15.             root = new File(rootPath);
  16.             if (!root.exists() || !root.isDirectory()) {
  17.                 System.out.println("根目录错误,请重新输入");
  18.                 continue;
  19.             }
  20.             break;
  21.         } while (true);

  22.         //检索文件
  23.         System.out.println("开始检索文件");
  24.         List<File> files = deptScanFiles(root);
  25.         System.out.println("检索到" + files.size() + "个文件");
  26.         for (int i = 0; i < files.size(); i++) {
  27.             System.out.print("[" + (i + 1) + "] ");
  28.             System.out.println(files.get(i));
  29.         }
  30.         do {
  31.             System.out.println("直接回车进行下一步,或者输入文件序号查看文件hex");
  32.             String temp = "0" + scanner.nextLine().trim();
  33.             Integer tempI = Integer.valueOf(temp);
  34.             if (tempI > files.size() || tempI < 0) {
  35.                 System.out.println("输入异常,请重新输入");
  36.                 continue;
  37.             }
  38.             if (tempI.equals(0)) {
  39.                 break;
  40.             }
  41.             String savePath = saveFile2Hex(files.get(tempI - 1));
  42.             System.out.println("文件已保存到" + savePath);
  43.         } while (true);

  44.         //设置加密信息
  45.         System.out.println("请输入16进制加密信息,如:1A 2B 3C");
  46.         do {
  47.             String tempKey = scanner.nextLine().toUpperCase(Locale.ROOT);

  48.             if (tempKey == null || tempKey == "") {
  49.                 System.out.println("请输入16进制加密信息");
  50.                 continue;
  51.             }
  52.             //判断16进制
  53.             String regex = "^[A-Fa-f0-9 ]+$";
  54.             if (tempKey.matches(regex)) {
  55.                 String[] ks = tempKey.split(" ");
  56.                 key = new byte[ks.length];
  57.                 for (int i = 0; i < ks.length; i++) {
  58.                     key[i] = (byte) Integer.parseInt(ks[i], 16);
  59.                 }
  60.                 break;
  61.             } else {
  62.                 System.out.println("不是16进制,请重新输入");
  63.                 continue;
  64.             }
  65.         } while (true);


  66.         //读取smp文件字符串,对key再进行异或后保存成MP3
  67.         for (File file : files) {
  68.             byte[] bytes = readFile2Byte(file);
  69.             decrypt(bytes, key);
  70.             saveBytes2File(bytes, new File(file.getParent(), file.getName().substring(0, file.getName().indexOf(".") + 1) + saveExt).getAbsolutePath());
  71.             System.out.println(String.format("文件%s已处理", file.getAbsolutePath()));
  72.         }
  73.         System.out.println("处理完成");
  74.     }

  75.     /**
  76.      * 深度扫描smp文件
  77.      *
  78.      * @param root
  79.      * @return
  80.      */
  81.     public static List<File> deptScanFiles(File root) {
  82.         if (!root.exists()) {
  83.             return null;
  84.         }
  85.         if (root.isFile()) {
  86.             String fileExtension = getFileExtension(root);
  87.             if (sourceExt.equals(fileExtension)) {
  88.                 return new LinkedList<File>() {{
  89.                     add(root);
  90.                 }};
  91.             } else {
  92.                 return new LinkedList<File>();
  93.             }
  94.         } else if (root.isDirectory()) {
  95.             LinkedList<File> files = new LinkedList<>();
  96.             for (File file : root.listFiles()) {
  97.                 files.addAll(deptScanFiles(file));
  98.             }
  99.             return files;
  100.         } else {
  101.             return new LinkedList<File>();
  102.         }
  103.     }

  104.     /**
  105.      * 获取文件后缀
  106.      *
  107.      * @param file
  108.      * @return
  109.      */
  110.     public static String getFileExtension(File file) {
  111.         String fileName = file.getName().toLowerCase(Locale.ROOT);
  112.         if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
  113.             return fileName.substring(fileName.lastIndexOf(".") + 1);
  114.         } else {
  115.             return "";
  116.         }
  117.     }

  118.     /**
  119.      * 按照
  120.      *
  121.      * @param file
  122.      * @return
  123.      * @throws IOException
  124.      */
  125.     public static byte[] readFile2Byte(File file) throws IOException {
  126.         FileInputStream fin = new FileInputStream(file);
  127.         int len = fin.available();

  128.         byte[] temp = new byte[len];
  129.         fin.read(temp);

  130.         return temp;
  131.     }

  132.     /**
  133.      * 解密
  134.      *
  135.      * @param source
  136.      * @param keys
  137.      */
  138.     public static void decrypt(byte[] source, byte[] keys) {
  139.         int idx = 0;
  140.         for (int i = 0; i < source.length; i++) {
  141.             source[i] ^= keys[i % keys.length];
  142.         }
  143.     }

  144.     /**
  145.      * 按16进制保存文件
  146.      *
  147.      * @param file
  148.      * @return
  149.      * @throws IOException
  150.      */
  151.     public static String saveFile2Hex(File file) throws IOException {
  152.         String savePath = file.getAbsolutePath() + ".hex.txt";
  153. //        System.out.println(System.currentTimeMillis());
  154.         byte[] bytes = readFile2Byte(file);
  155.         StringWriter sw = new StringWriter();
  156.         int currentLen = 0;
  157.         for (int i = 0; i < bytes.length; i++) {
  158.             currentLen += 1;
  159.             if (bytes[i] >= 0x0) {
  160.                 sw.write(String.format("%02x", bytes[i]).toUpperCase(Locale.ROOT));
  161.             } else {
  162.                 sw.write(Integer.toHexString(bytes[i]).substring(6).toUpperCase(Locale.ROOT));
  163.             }

  164.             sw.write(" ");
  165.             if (currentLen >= 16) {
  166.                 currentLen = 0;
  167.                 sw.write("\r\n");
  168.             }
  169.         }
  170. //        System.out.println(System.currentTimeMillis());
  171.         Files.write(Paths.get(savePath), bytes);
  172. //        System.out.println(System.currentTimeMillis());
  173.         return savePath;
  174.     }

  175.     public static boolean saveBytes2File(byte[] bytes, String filePath) throws IOException {

  176. //        System.out.println(System.currentTimeMillis());
  177.         Files.write(Paths.get(filePath), bytes);
  178. //        System.out.println(System.currentTimeMillis());
  179.         return true;
  180.     }
  181. }
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 12家元 +230 收起 理由
cbh1a + 20 優秀文章
x067 + 20 原創內容
kyhwhb + 20
佳维 + 20 謝謝分享
ch104517745 + 20
myseil + 20 謝謝分享
qrut + 20
玛德陛下 + 18 謝謝分享
jf201006 + 20 優秀文章
拿糖糖换媳妇 + 20

查看全部打赏

 楼主| 发表于 2022-5-5 16:48:52 | 显示全部楼层
zzy5211250 发表于 2022-5-5 16:40
这不就是个带蓝牙的播放器板子么

是的,女人和孩子的钱好赚,要是自己买好歹买个天猫精灵或者小爱也比这值当
回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2022-5-5 16:53:15 | 显示全部楼层
音频资源就不放上来了,省的再收什么律师函,就是些童话故事、诗词成语之类的,整体还算可以吧,有谁想要的私信我给你们分享
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-5 17:04:41 | 显示全部楼层
lichengde 发表于 2022-5-5 16:55
谢谢分享确实是个播放器加兰牙的这不便宜吧

具体没问,不过估计小三位数吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-5 17:06:08 | 显示全部楼层
zpflove51 发表于 2022-5-5 16:57
家里有小度1s 和天猫精灵  最近发现天猫精灵有点智障了

我的方糖最近也有点问题,偶尔没反应,得尝试着换语调甚至换点方言才回复
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-5 17:08:26 | 显示全部楼层
zzqqzzz 发表于 2022-5-5 17:02
老哥是java专业的哇?看着代码一串串,头晕脑胀了

C# java 前端都干点,混日子,有啥项目私活老板可以给介绍介绍
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-5 17:10:39 | 显示全部楼层
hechuanhuawe 发表于 2022-5-5 17:06
这个应该是和app匹配的 ,用这个应该就能听VIP的故事了

没有vip,就是个纯播放器,有带app的得继续加钱
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-5 17:11:49 | 显示全部楼层
newboyfeng 发表于 2022-5-5 17:10
播放程序怎么搞的?

没有播放程序,smp解码后生成mp3文件
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-5 21:05:17 | 显示全部楼层
lisheng1365 发表于 2022-5-5 18:18
Gitee报 :你的访问受限!

可以了,忘了设置公开了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-5 21:06:07 | 显示全部楼层
soma 发表于 2022-5-5 19:26
仓库怎么快就不见了

可以了,忘了设置公开了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-5 21:14:14 | 显示全部楼层
chengxufan 发表于 2022-5-5 21:11
就是个播放器。不过外观还挺好看的。

是的,虽说整体硬件很拉跨但是整体做工还是可以的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-6 09:14:39 | 显示全部楼层
newboyfeng 发表于 2022-5-6 08:17
那如果想使用这个播放,还得把mp3加密?

不清楚,没试能不能直接播放MP3,更新内容还得再拆机拷文件,有那功夫还不如整个智能音箱省心
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-6 10:48:41 | 显示全部楼层
zhoudasi 发表于 2022-5-6 09:36
请教lz  1A 42 86 07   怎么就能怀疑是异或?

不是因为1A 42怀疑异或,而是很多这类播放器加密音频就是用异或简单加密,先怀疑是否异或加密,然后尝试查找用来异或的密码,文件里一般有一些连续0,加密后的连续规律字符可能就0是被异或后的值,再然后就是有网友说MP3文件开头49 44 33即ASCII的ID3,smp文件读出来开头是53 06 B5 04 1A...,前三位和49 44 33异或,结果也正是1A 42 86,也能参考这个找出密码。不过这里只针对MP3和简单异或加密方式
回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2022-5-6 17:08:49 | 显示全部楼层
zoro 发表于 2022-5-6 16:49
哎。。。。早教到底管不管用

整体来说还是有用的,君不见现在的小孩比以前的小孩懂得多多了,不过是全方位的信息接收,刻意早教谁知道能培养出来个啥呢,长大后能不能成功会不会幸福鬼知道,太内卷了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-10 11:26:21 | 显示全部楼层
st911 发表于 2022-5-10 11:07
顶大神!前几年火的神尔天才能解开不?里面也类似这样,所有故事诗词歌曲内容都在一片6G的SD卡里。 ...

不知道,可以发个文件试试
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-11 20:25:21 | 显示全部楼层
yeswei2008 发表于 2022-5-10 11:06
家里有小孩,可不可以发一份到595928088@qq.com!感谢!

已发,字数补丁
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-11 20:33:57 | 显示全部楼层
hewayking 发表于 2022-5-11 15:51
感谢大佬给孩子听

已发,字数补丁
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-18 09:33:13 | 显示全部楼层
pai 发表于 2022-5-17 09:49
。给孩子听,感谢大佬

发了,字数补丁
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-18 09:36:48 | 显示全部楼层
wooox 发表于 2022-5-18 00:01
楼主稀客,很少看到写代码的

应该也不少,只是单片机一遍往这边发,其他语言的发其他论坛或者git的多
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-18 11:23:59 | 显示全部楼层
skipperpeng 发表于 2022-5-18 11:20
超过100元的这种播放器,还是感觉被割了。凯叔讲故事,度娘资源还是不少啊。 ...

女人和孩子的东西,被割是躲不掉的,这是哪里割多少的问题
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-18 17:18 , Processed in 0.265200 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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