舍得英语魔法学苑

 找回密码
 注册
查看: 5261|回复: 13

SMPAK文件格式精美图解及一个SMPAK解包的Python小脚本。

  [复制链接]
  • TA的每日心情
    奋斗
    2012-11-12 10:34
  • 签到天数: 23 天

    [LV.4]偶尔看看III

    ifree128 发表于 2012-6-5 19:40:13 | 显示全部楼层 |阅读模式

    解包的Python脚本:
    1. #!/usr/bin/python

    2. import struct
    3. import zlib

    4. class smPackage:
    5.     headerMap = {"sign" : (0, 8, "8s"),
    6.                  "version" : (8, 10, "2s"),
    7.                  "locked" : (10, 12, "H"),
    8.                  "entry_offset" : (12, 16, "I"),
    9.                  "name_offset" : (16, 20, "I")}
    10.     def __init__(self, path):
    11.         self.data = {}
    12.         try:
    13.             self.stream = open(path, "rb")
    14.             header_data = self.stream.read(20)
    15.             if header_data[:8] == "-SMArch-":
    16.                 for tag, (start, end, t) in self.headerMap.items():
    17.                     self.data[tag], = struct.unpack(t, header_data[start:end])
    18.                 self.__read_entries()
    19.                 self.__read_entry_name()
    20.         except IOError:
    21.             print "IOError"
    22.             pass
    23.     def __read_entries(self):
    24.         entry_offset = self.data["entry_offset"]
    25.         self.stream.seek(entry_offset)
    26.         self.entry_count, = struct.unpack("I", self.stream.read(4))
    27.         self.entries = []
    28.         for i in range(self.entry_count):
    29.             entry = {}
    30.             entry["name_offset"], = struct.unpack("I", self.stream.read(4))
    31.             entry["name_len"], = struct.unpack("H", self.stream.read(2))
    32.             entry["mode"], = struct.unpack("H", self.stream.read(2))
    33.             entry["data_offset"], = struct.unpack("I", self.stream.read(4))
    34.             entry["data_size"], = struct.unpack("I", self.stream.read(4))
    35.             self.entries.append(entry)
    36.     def __read_entry_name(self):
    37.         self.files = {}
    38.         self.stream.seek(self.data["name_offset"])
    39.         name_chunk_size, = struct.unpack("I", self.stream.read(4))
    40.         self.stream.seek(-name_chunk_size, 2)
    41.         name_chunk_begin = self.stream.tell()
    42.         for entry in self.entries:
    43.             self.stream.seek(name_chunk_begin + entry["name_offset"])
    44.             entry_name = self.stream.read(entry["name_len"])
    45.             entry["name"] = entry_name
    46.             self.files[entry_name] = entry
    47.     def read_file(self, name):
    48.         if self.files.has_key(name):
    49.             entry = self.files[name]
    50.             self.stream.seek(entry["data_offset"])
    51.             data = self.stream.read(entry["data_size"])
    52.             if entry["mode"] == 1:
    53.                 data = zlib.decompress(data, -15)
    54.             return data
    55.     def unpack(self):
    56.         for entry in self.entries:
    57.             print entry["name"]
    58.             filename = entry["name"].replace("/", "_")
    59.             f = open(filename, "wb")
    60.             f.write(self.read_file(entry["name"]))
    61.             f.close()
    62.     def __getitem__(self, key): return self.data[key]
    63.     def __setitem__(self, key, item): self.data[key] = item

    64. if __name__ == "__main__":
    65.     smpak = smPackage("d:\\EEBasic\\course.smpak")
    66.     smpak.unpack()



    复制代码

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x

    评分

    1

    查看全部评分

  • TA的每日心情
    开心
    2013-3-28 19:15
  • 签到天数: 41 天

    [LV.5]常住居民I

    xsqxsy 发表于 2012-6-6 12:19:41 | 显示全部楼层
    向高手敬礼!
  • TA的每日心情

    2017-4-4 10:43
  • 签到天数: 571 天

    [LV.9]以坛为家II

    yltsw 发表于 2012-6-6 17:28:48 | 显示全部楼层
    谢谢分享!!
  • TA的每日心情
    擦汗
    2015-12-3 21:34
  • 签到天数: 440 天

    [LV.9]以坛为家II

    败亦枭雄 发表于 2012-6-7 02:35:09 | 显示全部楼层
    感谢楼主分享。
  • TA的每日心情
    开心
    2012-10-16 10:38
  • 签到天数: 14 天

    [LV.3]偶尔看看II

    lzc0103792 发表于 2012-7-20 19:48:20 | 显示全部楼层
    楼主很认真{:soso_e179:}
  • TA的每日心情
    难过
    2013-9-18 12:04
  • 签到天数: 39 天

    [LV.5]常住居民I

    znhbj 发表于 2012-7-21 01:50:12 | 显示全部楼层
    确实下工夫了,辛苦了!{:soso_e100:}
  • TA的每日心情
    奋斗
    2013-8-28 15:45
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    メ無止境か 发表于 2012-7-21 18:22:15 | 显示全部楼层
    厉害!辛苦楼主了1!!!
  • TA的每日心情
    奋斗
    2012-11-30 09:11
  • 签到天数: 64 天

    [LV.6]常住居民II

    QinRay 发表于 2012-8-6 04:22:04 | 显示全部楼层
    很强大! 谢谢分享!
  • TA的每日心情
    开心
    2017-5-24 17:24
  • 签到天数: 108 天

    [LV.6]常住居民II

    Fellow 发表于 2012-8-6 04:53:09 | 显示全部楼层
    强!还要多多向你学习!!
  • TA的每日心情
    开心
    2014-2-23 15:34
  • 签到天数: 168 天

    [LV.7]常住居民III

    plucaozi 发表于 2012-8-6 05:33:37 | 显示全部楼层
    我是外行,没看懂这些东东,不过还是要向楼主献上崇高的敬意!
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    小黑屋|手机版|Archiver|官方微博|官方QQ群|舍得英语魔法学苑 ( 冀ICP备11024081号-1 )

    GMT+8, 2017-8-24 18:45 , Processed in 0.287011 second(s), 21 queries .

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

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