吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 10393|回复: 70
收起左侧

[原创] 解包“微软纸牌集合”资源文件

  [复制链接]
bihaiorg 发表于 2020-8-19 18:49
本帖最后由 bihaiorg 于 2020-8-19 18:53 编辑

成功反编译“微软纸牌集合”资源文件
一天时间,终于成功反编译了“微软纸牌集合(Microsoft Solitaire Collection)”的资源文件,以及图片集索引逆向转为跨平台json/atlas/texturePacker文件格式,可以直接用于跨平台软件制作,包括网页版,只是作为研究而已,没什么实际意义。至此,微软全平台游戏终于全部解包完毕,包括solitaire, minesweeper等等,还是很有借鉴意义。
3.jpg
2.jpg
1.jpg

文件格式说明
微软纸牌采用BR****I算法的zip压缩文件格式作为资源文件包,图集atlasIndex索引是加密(或者说是编译)的二进制文件,不知道是不是笔者孤陋寡闻,没有找到相关资料,只好用ultralEdit/vb6/vscode分析了一天,终于凑合转为JSON文件格式,好看好用多了:)。
zip文件格式应该不用多说,但是用普通的解压缩软件解不开这些.archive文件,只好又写了一个专用的解包工具,牵扯版权就不发了。
atlasIndex文件格式比较复杂,主要如下:

1、文件头8字节
[Visual Basic] 纯文本查看 复制代码
'atlas.atlasindex文件格式说明
'atlas.atlasindex file format specification
'Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
'00000000   68 2E 00 00 B4 30 00 00  00 00 00 00 00 00 00 00   h.  ?
Type TAtlasHeader
    lOffsetTable As Long '&h2e68
    lOffsetNamelist As Long '&h30b4
End Type 'TAtlasHeader

第一个长整数&h2e68是索引表的偏移量位置,第二个整数&h30b4是名称列表。
2、&h70偏移开始表结构的索引,各种跳转,实在是一言难尽啊,抽空整理一下VB6源代码,估计感兴趣的也不多。以上抛砖引玉,主要还是知识浅薄,孤陋寡闻,不知道是不是已经有人做了,纯粹业余兴趣,如果侵犯版权或者有其他错误请批评指正。

免费评分

参与人数 18吾爱币 +20 热心值 +18 收起 理由
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
hefengrili + 1 热心回复!
新的心跳 + 1 + 1 我很赞同!
liyqckli + 1 + 1 我很赞同!
duanjj6688 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
前笨笨 + 1 + 1 热心回复!
gzsklsskszngc + 2 + 1 我很赞同!
smile5 + 1 用心讨论,共获提升!
七月风 + 1 用心讨论,共获提升!
shuilinlin + 1 + 1 我很赞同!
o97 + 1 + 1 热心回复!
_知鱼之乐 + 1 + 1 我很赞同!
fanlanv + 1 + 1 我很赞同!
Youmdzz2333 + 1 + 1 我很赞同!
zerzul + 1 + 1 热心回复!
弘文发 + 1 热心回复!
三笙三世 + 1 我很赞同!
610100 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

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

 楼主| bihaiorg 发表于 2020-8-20 15:09
解析atlasIndex文件的源代码其实不复杂,只不过很难看,大体像这样:
(VB6伪代码,抱歉乱糟糟还没注释;))
[Visual Basic] 纯文本查看 复制代码
Option Explicit
'atlas.atlasindex文件格式说明
'atlas.atlasindex file format specification
'Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
'00000000   68 2E 00 00 B4 30 00 00  00 00 00 00 00 00 00 00   h.  ?
Type TAtlasHeader
    lOffsetTable As Long '&h2e68
    lOffsetNamelist As Long '&h30b4
End Type 'TAtlasHeader

Type TAtlasOffset
    lOffset As Long
    lNameIndex As Long '&h14
    lType As Long '&hc
End Type
Sub ParseAtlasIndexFile(Optional sFile As String)
    If sFile = "" Then
      sFile = "atlas.atlasindex"
    End If
    Dim TAH As TAtlasHeader
    Dim f As Integer
    f = FreeFile
    Open sFile For Binary As f
        Get #f, , TAH
        If TAH.lOffsetNamelist = 0 Then
            Close f
            GoTo exitIt
        End If
        Seek #f, TAH.lOffsetTable + 1
        Dim lNumItems As Long
        Get #f, , lNumItems
        Dim alItems() As Long
        Dim i As Long
        If lNumItems > 0 Then
            ReDim alItems(lNumItems - 1)
            For i = 0 To lNumItems - 1
                Get f, TAH.lOffsetTable + 1 + 4 + i * 8 + 4, alItems(i)
            Next
            Dim asItems() As String
            ReDim asItems(lNumItems - 1)
            Dim abTmp() As Byte
            For i = 1 To lNumItems - 1
                ReDim abTmp((alItems(i) - alItems(i - 1)) - 1)
                Get f, alItems(i - 1) + 1, abTmp
                asItems(i - 1) = StrConv(TrimByteArray(abTmp), vbUnicode)
            Next
            ReDim abTmp((LOF(f) - alItems(i - 1)) - 1)
            Get f, alItems(i - 1) + 1, abTmp
            asItems(i - 1) = StrConv(TrimByteArray(abTmp), vbUnicode)
            'parse the listindexes:
            Seek #f, &H70 + 1
            Dim lPnt As Long
            Get #f, , lPnt
            Dim lNodes As Long
            Dim p As Dictionary
            Set p = JSON.parse("{}")
            If lPnt Then
                Get #f, lPnt + 1 + 4, lNodes
                If lNodes Then
                    'parse the listOffsets:
                    Dim atTao() As TAtlasOffset
                    ReDim atTao(lNodes - 1)
                    Seek #f, &H80 + 1 + 8
                    Dim Itm As Dictionary
                    Dim dItm As Dictionary
                    'Itm.Add i + 1
                    Set Itm = Nothing
                    Set Itm = New Dictionary
                    'Itm.Add "data"
                    p.Add "data", Itm
                    p.Add "Number of Images", lNodes
                    Dim lSeekNodes As Long
                    lSeekNodes = Seek(f)
                    Dim lNodeItems As Long
                    For i = 0 To lNodes - 1
                        Get #f, lSeekNodes + i * 12, atTao(i)
                        Debug.Print asItems(atTao(i).lNameIndex); " ";
                        Seek #f, atTao(i).lOffset + 1 + 4
                        Get #f, , lNodeItems
                        Dim j As Integer
                        Dim sTmp As String
                        Set dItm = Nothing
                        Set dItm = New Dictionary
                        Seek #f, atTao(i).lOffset + 1 + 4 + 4 + 4
                        Dim lSeek As Long
                        Dim lNameIndex As Long
                        Dim lType As Long
                        For j = 0 To lNodeItems - 1
                            Get #f, , lNameIndex
                            sTmp = asItems(lNameIndex)
                            Get #f, , lType
                            Get #f, , lPnt
                            lSeek = Seek(f)
                            If lType = &H4 Then
                              'is long
                              Get #f, lPnt + 1, lPnt
                              dItm.Add sTmp, lPnt
                            ElseIf lType = &HA Then
                              'is string
                              ReDim abTmp(128)
                              Get #f, lPnt + 1, abTmp
                              dItm.Add sTmp, StrConv(TrimByteArray(abTmp), vbUnicode)
                            ElseIf lType = &H9 Then
'                              Stop
                              Dim iTmp As Integer
                              Get #f, lPnt + 1, iTmp
                              dItm.Add sTmp, iTmp
                            Else
                              Get #f, lPnt + 1, lPnt
                              dItm.Add sTmp, lPnt
                            End If
                            Seek (f), lSeek
                        Next
                        Itm.Add asItems(atTao(i).lNameIndex), dItm
                    Next
                    debug.print JSON.toString(p)
                End If
            End If
        End If
        Seek #f, TAH.lOffsetNamelist + 1
    Close f
End Sub
 楼主| bihaiorg 发表于 2020-8-20 11:29
谢谢大家关注和回复!
关于逆向,纯粹个人兴趣,目前仅限于素材资源解包解密,水平有限,不敢班门弄斧。
再就是需要运气,不敢高调,大多数时候需要攒够人品,才能偶尔成功。
希望抛砖引玉,引起大家对编程和逆向、安全防护的兴趣,激励学习提高,如果能够起到一点帮助作用,就算有所的,没白费功夫。
微软的软件质量很高,值得学习借鉴,目的还是为了提高知识水平和解决问题的能力,同时开拓视野、明白人外有人天外有天,谦虚本分,更容易进步。
至于源代码,主要因为是vb6写的,没啥移植性,就暂时不发了,也许后面用.net重写一遍,就可以堂而皇之开源了。
至于格式说明和伪代码,抽空整理一下,尽快发,多谢支持!
木得感情 发表于 2020-8-19 19:14
三笙三世 发表于 2020-8-19 19:16
大佬牛逼
hysh 发表于 2020-8-19 19:22
想法不错
旋风中的小聪明 发表于 2020-8-19 19:22
哎,是经典没错了
Windows10 发表于 2020-8-19 19:34
VB6源代码期待一下
三分米信息技术 发表于 2020-8-19 20:13
寂寞的高手
 楼主| bihaiorg 发表于 2020-8-19 20:24

现在已经是很认真的游戏了
 楼主| bihaiorg 发表于 2020-8-19 20:26

寂寞确实寂寞,高手不敢当,小学生而已
三分米信息技术 发表于 2020-8-19 20:35
bihaiorg 发表于 2020-8-19 20:26
寂寞确实寂寞,高手不敢当,小学生而已

惭愧惭愧
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-27 02:31

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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