数码之家

 找回密码
 立即注册
搜索
查看: 4676|回复: 80

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

[复制链接]
发表于 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:40:24 来自手机浏览器 | 显示全部楼层
这不就是个带蓝牙的播放器板子么
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

使用道具 举报

发表于 2022-5-5 16:55:10 | 显示全部楼层
谢谢分享确实是个播放器加兰牙的这不便宜吧
回复 支持 反对

使用道具 举报

发表于 2022-5-5 16:57:55 | 显示全部楼层
家里有小度1s 和天猫精灵  最近发现天猫精灵有点智障了
回复 支持 反对

使用道具 举报

发表于 2022-5-5 16:59:55 | 显示全部楼层
为了宝宝的健康这个拆机理由可以,居然都可以解密,感觉就像二战时期破译密码
回复 支持 1 反对 0

使用道具 举报

发表于 2022-5-5 17:02:00 | 显示全部楼层
老哥是java专业的哇?看着代码一串串,头晕脑胀了
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

发表于 2022-5-5 17:05:27 | 显示全部楼层
会写代码的都是大神。。。
回复 支持 反对

使用道具 举报

发表于 2022-5-5 17:05:49 | 显示全部楼层
这类播放器其实就是个玩具。
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

发表于 2022-5-5 17:06:50 来自手机浏览器 | 显示全部楼层
这个应该是和app匹配的 ,用这个应该就能听VIP的故事了
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

发表于 2022-5-5 17:10:37 | 显示全部楼层
播放程序怎么搞的?
回复 支持 反对

使用道具 举报

 楼主| 发表于 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 17:13:20 | 显示全部楼层
高手感谢分享解析程序,设备就是成本适中的带蓝牙播放器,估计是音频资源价格贵,以前下载过网友分享过“凯叔西游记”,据说是网友自己买来的
回复 支持 反对

使用道具 举报

发表于 2022-5-5 17:16:50 | 显示全部楼层
还是女人儿童的钱好赚。
回复 支持 反对

使用道具 举报

发表于 2022-5-5 17:25:20 | 显示全部楼层
厉害了 还有一种国学教育机 买1000多到三千多不等 ,其实就是一个MP3播放器,内容是关键,机器不值钱,所以都加密
回复 支持 反对

使用道具 举报

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

本版积分规则

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

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-7 02:23 , Processed in 0.093600 second(s), 9 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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