吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2479|回复: 36
收起左侧

[原创] SMP格式音频文件解密:技术探索与应用实践

  [复制链接]
絕戀Dι宇 发表于 2024-11-5 10:50
本帖最后由 絕戀Dι宇 于 2024-11-5 23:23 编辑

在数字音频的多彩世界中,SMP格式音频文件如同一颗隐秘的珍珠,它们通常被用于特定的硬件设备,例如儿童音乐故事机。这些设备为了保护版权或出于其他原因,可能会对音频文件进行加密。然而,对于技术爱好者来说,解密这些文件并将其转换为更通用的格式,如MP3,不仅是一项挑战,也是一次充满乐趣的技术探险。

探索SMP文件的秘密
最近,我的妻子为我们的宝宝购买了一个音乐故事机,这款设备内置了许多儿童歌曲和故事,以SMP格式存储。出于对技术的好奇,我尝试将这些音频文件复制到电脑上,希望能够在其他设备上播放。然而,我很快发现这些文件无法直接播放,因为它们被加密了。在吾爱破解网站上,我找到了一些关于SMP文件解密的讨论。一位技术大咖whc2001分享了他的发现:通过异或(XOR)操作可以解密这些文件。异或加密是一种简单的加密方法,它的特点是加密和解密过程使用相同的密钥,并且加密过程是可逆的。

密钥的发现之旅
受到启发,我决定亲自尝试解密这些SMP文件。首先,我使用十六进制编辑器WinHex打开了SMP文件,寻找可能的加密模式。经过仔细观察,我发现文件头部存在大量的重复模式 9E 24 96 49。这个重复的模式可能是加密过程中使用的一个固定模式,或者是解密算法需要识别的一个标记。

WinHex

WinHex

我假设这个重复模式可能是密钥的一部分,于是编写了一个Python脚本来尝试使用这个模式作为密钥进行异或解密。在多次尝试和错误之后,我最终发现了一个有效的密钥 9E 24 96 49,它能够成功解密文件头部的数据。

解密脚本的编写
为了自动化解密过程,我编写了一个Python脚本,该脚本能够遍历指定目录中的所有SMP文件,并使用发现的密钥进行异或解密。脚本的核心是一个名为 xor_decrypt 的函数,它接受加密数据和密钥作为输入,并返回解密后的数据。脚本还包括一个 decrypt_file 函数,用于解密单个文件,并将解密后的数据写入到新文件中。

解密结果与验证
使用这个脚本,我成功解密了音乐故事机中的所有SMP3文件,并将它们转换为MP3格式。解密后的文件能够在常见的音频播放器中正常播放,这验证了我的解密方法是正确的。
image-20241105095659807.png
image.png
image-20241105103427775.png
结语
通过这次解密SMP文件的经历,我不仅解决了一个实际问题,还加深了对异或加密和解密的理解。这个过程也再次证明了,即使是对于小众格式的文件,只要我们掌握了正确的方法和工具,也能够找到解决问题的途径。这次经历也让我更加欣赏那些愿意分享知识和技术的社区成员,他们的分享使得像我这样的技术爱好者能够不断学习和进步。
附录:解密脚本示例
[Python] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import os
import re
 
def clean_filename(filename):
    # 替换文件名中的非法字符
    filename = re.sub(r'[<>:"/\\|?*]', '_', filename)  # 替换Windows系统中的非法字符
    return filename
 
def xor_decrypt(data, key):
    key_length = len(key)
    decrypted_data = bytearray()
    for i in range(0, len(data), key_length):
        data_segment = data[i:i+key_length]
        if len(data_segment) == key_length:
            for j in range(key_length):
                decrypted_data.append(data_segment[j] ^ key[j])
        else:
            for j in range(len(data_segment)):
                decrypted_data.append(data_segment[j] ^ key[j])
            for j in range(key_length - len(data_segment)):
                decrypted_data.append(key[j] ^ 0# 使用 0 作为填充
    return decrypted_data
 
def decrypt_file(input_filename, output_filename, key):
    print(f"Attempting to decrypt {input_filename} to {output_filename}")
    if not os.path.exists(os.path.dirname(output_filename)):
        print(f"Creating directory {os.path.dirname(output_filename)}")
        os.makedirs(os.path.dirname(output_filename))
    with open(input_filename, 'rb') as infile, open(output_filename, 'wb') as outfile:
        data = infile.read()
        decrypted_data = xor_decrypt(data, key)
        outfile.write(decrypted_data)
        print(f'Decrypted {input_filename} to {output_filename}')
 
def decrypt_files_in_directory(src_dir, dest_dir, key):
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)
     
    for root, dirs, files in os.walk(src_dir):
        for file in files:
            if file.endswith('.smp'):
                src_file_path = os.path.join(root, file)
                relative_path = os.path.relpath(src_file_path, src_dir)
                dest_file_path = os.path.join(dest_dir, relative_path).replace('.smp', '.mp3')
                # 清理文件名
                dest_file_name = clean_filename(os.path.basename(dest_file_path))
                dest_file_path = os.path.join(dest_dir, os.path.dirname(relative_path), dest_file_name)
                print(f"Processing file {src_file_path} to {dest_file_path}")
                decrypt_file(src_file_path, dest_file_path, key)
 
# 假设的密钥
key = [0x9E, 0x24, 0x96, 0x49]
 
# 源目录和目标目录
src_dir = "C:\\Users\\Administrator\\Desktop\\火火兔"  # 替换为你的父文件夹路径
dest_dir_suffix = '-解密'
dest_dir = src_dir + dest_dir_suffix  # 新文件夹的路径
 
# 开始解密
decrypt_files_in_directory(src_dir, dest_dir, key)

请注意,这个脚本是一个示例,实际使用时需要根据你的具体情况进行调整。希望这篇文章能够对那些对SMP文件解密感兴趣的朋友有所帮助。

免费评分

参与人数 16吾爱币 +23 热心值 +16 收起 理由
huakeha + 1 + 1 厉害,谢谢分享!
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ailyok + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
涛之雨 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Sueya34 + 1 + 1 热心回复!
201304040089 + 1 + 1 我很赞同!
allspark + 1 + 1 用心讨论,共获提升!
zhczf + 1 + 1 我很赞同!
3KING三金胖王 + 1 + 1 热心回复!
yclm233 + 1 + 1 用心讨论,共获提升!
ws001980 + 1 + 1 谢谢@Thanks!
greendays + 1 + 1 谢谢@Thanks!
myqqq + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qqycra + 1 + 1 用心讨论,共获提升!
HonDmOon + 1 + 1 用心讨论,共获提升!
驿路迷茫 + 1 + 1 谢谢@Thanks!

查看全部评分

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

 楼主| 絕戀Dι宇 发表于 2024-11-11 17:54
求大家投点热心值给我,之前有违规需要130热心值消除
qq465881818 发表于 2024-11-6 21:19
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System;
using System.IO;
using System.Text.RegularExpressions;
 
class Program
{
    static void Main(string[] args)
    {
        // 假设的密钥
        byte[] key = new byte[] { 0x9E, 0x24, 0x96, 0x49 };
 
        // 源目录和目标目录
        string srcDir = @"C:\Users\Administrator\Desktop\火火兔"; // 替换为你的父文件夹路径
        string destDirSuffix = "-解密";
        string destDir = srcDir + destDirSuffix; // 新文件夹的路径
 
        // 开始解密
        DecryptFilesInDirectory(srcDir, destDir, key);
    }
 
    static string CleanFilename(string filename)
    {
        // 替换文件名中的非法字符
        return Regex.Replace(filename, @"[<>:""/\\|?*]", "_");
    }
 
    static byte[] XorDecrypt(byte[] data, byte[] key)
    {
        int keyLength = key.Length;
        byte[] decryptedData = new byte[data.Length];
 
        for (int i = 0; i < data.Length; i++)
        {
            decryptedData[i] = (byte)(data[i] ^ key[i % keyLength]);
        }
 
        return decryptedData;
    }
 
    static void DecryptFile(string inputFilename, string outputFilename, byte[] key)
    {
        Console.WriteLine($"Attempting to decrypt {inputFilename} to {outputFilename}");
 
        // 确保输出目录存在
        string outputDir = Path.GetDirectoryName(outputFilename);
        if (!Directory.Exists(outputDir))
        {
            Console.WriteLine($"Creating directory {outputDir}");
            Directory.CreateDirectory(outputDir);
        }
 
        // 读取文件并解密
        byte[] data = File.ReadAllBytes(inputFilename);
        byte[] decryptedData = XorDecrypt(data, key);
        File.WriteAllBytes(outputFilename, decryptedData);
        Console.WriteLine($"Decrypted {inputFilename} to {outputFilename}");
    }
 
    static void DecryptFilesInDirectory(string srcDir, string destDir, byte[] key)
    {
        if (!Directory.Exists(destDir))
        {
            Directory.CreateDirectory(destDir);
        }
 
        foreach (string file in Directory.GetFiles(srcDir, "*.smp", SearchOption.AllDirectories))
        {
            string relativePath = Path.GetRelativePath(srcDir, file);
            string destFilePath = Path.Combine(destDir, relativePath).Replace(".smp", ".mp3");
 
            // 清理文件名
            string destFileName = CleanFilename(Path.GetFileName(destFilePath));
            destFilePath = Path.Combine(destDir, Path.GetDirectoryName(relativePath), destFileName);
 
            Console.WriteLine($"Processing file {file} to {destFilePath}");
            DecryptFile(file, destFilePath, key);
        }
    }
}
kof888 发表于 2024-11-5 19:09
好文章,感谢分享。
请问解密以后的文件是mp3文件吗?
qqycra 发表于 2024-11-5 20:38
楼主可以参照下精华贴的的结构
xixicoco 发表于 2024-11-5 22:11
这类念佛机啥的都是有异或加密
18c 发表于 2024-11-5 22:20
可以看结构吗?
 楼主| 絕戀Dι宇 发表于 2024-11-5 23:25
kof888 发表于 2024-11-5 19:09
好文章,感谢分享。
请问解密以后的文件是mp3文件吗?

是的,保存为mp3格式,可以播放。
 楼主| 絕戀Dι宇 发表于 2024-11-5 23:27
18c 发表于 2024-11-5 22:20
可以看结构吗?

你想看什么样的结构?
当你打开其中一个文件时,找不到密钥,不妨打开WinHex同时看多个文件,找规律,找到可疑密钥,多测试。
Atnil 发表于 2024-11-6 08:05
思路很明晰,SMP一直是用异或加密,以前是89 6B A5 22,现在是9E 24 96 49,现在的父母好卷,火火兔早教机内容都要转MP3方便随时给孩子播放
 楼主| 絕戀Dι宇 发表于 2024-11-6 11:28
sunflash 发表于 2024-11-6 10:19
感谢一下楼主,同情一下孩子

音乐故事,宝宝爱听,家长轻松,眼睛也安全。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-4-1 08:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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