这是一种非常有趣的文件格式,可能会极大地满足二进制考古学家的要求。示例文件

背景文件

此文件格式创建于90年代,用于归档客户创建的AutoCAD零部件库,例如窗,门和列。第一行是纯文本xxxx DWG library 1.0,已从示例文件中将其删除以避免任何问题。公司xxx已经消失了,但不确定是否有人仍然拥有该商标。我父亲的许多设计文件都依赖于它。

此文件格式包含一个伴随的索引/参考文件,它是一个简单的dBase III。工作平台是DOS / Windows。

发现

我花了2天的时间来尝试理解格式。虽然还不完整,但我所得到的是:


它由两部分组成:文件列表部分和blob数组部分
文件列表section是一个简单的文件名数组+一个神话般的3字节文件代码(我们称其为m1)m1指向其二进制文件2字节的位置。左1个字节似乎与文件/记录名称有关。一个4字节的int指向其相应二进制文件的位置。

文件名的长度为0x20,空格填充为0x00。
m1不是通常的位置偏移。
文件记录由0x00分隔。


blob数组节很有趣。

每个Blob均以“ AS LZW 1.0”开头(不要错过尾部空格)。

然后是2个字节的未知用法。不是随机的。示例:0x6323、0x5b23、0xfa22、0x0223。 (称为m2)解码后的二进制文件的大小。
6个字节的0x00
2个字节,用途未知。不是随机的。大多为0x9ccc(称为m3)
然后是0xaa08 + 12个字节的0x00
二进制编码的LZW旧式代码:0c00 0000 0083 0c89 0123 460d 0008 113e 08c0 ...



问题


blob数组节中的blob是否真的用LZW压缩了?我尝试使用python lzw从m2,m3位置进行解码,但都失败了。
m1是否拥有解码blob的密钥?
m2,m3的用途是什么?
是否存在一种通用的方法来解码这种文件格式? (好吧,我只有google :(和文件签名列表)010编辑器(不错的软件,谢谢@ 0xC0000022L)

更新


m1是3个字节。
感谢@ 0xC0000022L的注释。文件的第一行是:
ArchStar DWG Library 1.0(行以0x0d结尾)

尝试对blob进行尝试(切掉“ AS LWS 1.0”后),它报告

100.0%(.CEL)Autodesk FLIC图像文件(扩展名:flc,fli,cel)( 7/3)

没有任何意义。


更新21/11/13

进度python lzw似乎相对而言最近,所以我研究了上个世纪的较旧的LZW实现,因此找到了libtiff的lzw模块,它是python实现(必须在其中使用bitarray模块:版本0.35,而不是最新版本)。这个具有蛮力方法的python库(由于@Attila),blob确实可以从28h开始解码(基于:“ AS LZW”)。最重要的是,解码后的文件以AutoCAD DWG格式“ AC10”开头!但是,它仅解码了大约30%的blob。

进度2从golang尝试了lzw,其解码配置顺序:LSB和litWid:2,解码了大约3倍的数据。明天将报告更多结果。

进度3用python LibTiff LZW解码的dwg是有效的AutoCAD DWG。 AutoCAD 2014报告从golang LZW解码的那一个无效。现在,我想斑点的其余部分是矢量的图像缩略图。将解码所有50个blob并报告。

更新22/11/13

用libtiff lzw(lzw.py)解码的blob无效,尽管它们正确标头“ AC10”。

我仔细查看了pylibtiff内部的lzw.py,发现前两行:


“”“ TIFF的Lempel-Ziv-Welch算法的编码器和解码器。

该模块已过时,请使用tif_lzw扩展模块。”“”
(经验教训:阅读每一行! )


所以我修改了代码,以使用tif_lzw解码blob。没有运气。这次,我逐行仔细阅读了代码。

乍一看,该文件还有另外两个Python包装器方法Py_decode和Py_encode。然后我注意到老式LZW代码的禁用方法LZWDecodeCompat。这很有趣。因此,我修改了模块,启用了LZWDecodeCompat并将其用于Py_decode方法中。 tif_lzw.decode方法需要额外的参数大小。我自然使用m1(对于第一个Blob,我使用0x4c07)。解码后的结果具有“ AC10”标头,并已在AutoCAD(mac ver)中成功打开,但未显示任何内容。 AutoCAD表示它是Trusted DWG,其中包含1个我找不到的块。所以我花了好几个小时安装Windows和AutoCAD。答对了!有一个柱状图!仍然存在问题。例如仍然无法为tif_lzw.decode方法调用找到合适的大小。

使用m3对所有50个二进制文件进行解码:
作为尺寸参数

模板(正在进行中)

struct FILE {

    char banner[26];
    char f1[2];
    FSkip(4); //char sp[4];

    local int count = 0;
    local int pos;
    local char sp[36];
    local char SP[36];
    Memset(SP, 0, 36);

    while(true){
        pos = FTell();
        ReadBytes(sp, pos, 36);

        if(Memcmp(sp, SP, 36) == 0){
            break;
        }
        count ++;
        FSeek(pos);

        struct {
            char name[32];
            DWORD loc;
        } index;
    }


    FSkip(36); //char sp2[36];
    struct Binary(int len){
            char banner[11];
            WORD size;
            FSkip(7);//char sp[7];
            char m3[2]; // CRC16?
            char m4[2]; // always AA 08
            FSkip(16);
            char lzw[len];
    };

    local int i;

    for(i = 1; i < count; i++){
        Binary b(index[i].loc - index[i-1].loc - 40);
    }

    if(count>0){
        Binary b(FileSize() - index[i-1].loc - 40);
    }
} file;


评论

最好的方法是反转读取或写入格式的程序。有吗?

不幸的是,我没有读取/写入程序。这是我父亲12年前在中国使用的软件。

从字面上看,您拿出公司名称的观点非常糟糕。瞧,您想让我们为您提供帮助,但您会因此变得比实际情况更糟。在这种情况下(从经验上讲),每条情况信息都很重要,尤其是如果您没有能够读取/写入文件的软件。即使您已经离开第一行,然后将公司名称替换​​为字母x(原为大写/小写),也会更好。就我们所知,密钥可能是第一行的一部分。

不在Little Endian中;那么只有0x74C。您可以在指向魔术字符串的0x1B字节之前找到它-样本中的所有50个偏移量都可以。除第11和第12个字节外,所有偏移量的字符串均相同。另外,接下来的20个字节(至少)是相同的,但这也许仅仅是因为压缩数据的前x个字节是。

字节20和21的变化也很小。刚刚确认前40个数据字节是相同的。只有最后一组有所不同。除了那个之外,前52个字节都相同。接下来,我将对数据进行LZW解码,并将结果报告给我们(如果有的话)。

#1 楼

考虑更改Python脚本,以蛮力方式从各种偏移量运行LZW解压缩。

评论


蛮力确实非常有用:)(查看更新)

– wangii
13年11月22日在12:01

#2 楼

随时编辑此社区Wiki的“答案”。

NB:仅将其写为答案,因为评论太长了。我认为,鉴于零碎的信息,除非您感到幸运,而且有人碰巧知道这种特定的文件格式,否则就没有答案。

如果我们假设文件格式确实与DWG有关,我们可以通过研究DWG的新旧规格(Google搜索OpenDesign_Specification_for_.dwg_files.pdf)并了解其使用的文件格式来学到很多东西。数据类型(请参见链接的论文的“位代码和数据定义”和“压缩”)和算法特别受关注。例如,在上述部分中,我们找到:


AutoCAD DWG文件格式使用标准循环
冗余检查的修改作为错误检测机制。由于在包含256个16位
值的表中进行查找,CRC最终以2个字节长的形式结束,并且不以任何形式的位代码形式存储。它们
也总是出现在字节边界上;它们没有嵌入到
位流中。


这是非常有价值的信息,可以帮助您确认发现。这适用于您的情况:


Autodesk还使用一种方法,将CRC的结果与“魔术数”进行异或。此方法在R13之前的文件中得到了广泛的使用。BricsCAD和其他提供SDK和库(及产品)的人声称他们也了解旧的DWG格式。 。

但是请您自己重新研究格式。

您将需要使用诸如010 Editor之类的工具来方便使用,该工具可让您创建模板并按实际方式开发了解这种文件格式。

现在,您已经说了第一行是文本,却没有给出一定的长度,反而剥夺了我们的重要信息,或者无论如何您都无法得出结论:纯文本。

例如,在文件中出现了50次AS LZW 1.0。尽管如此,我还是从头算起更多的神秘ASCII数字。可能这也包括不需要AS LZW 1.0位的一些标记。

那些小数点也从2开始。为什么?

我也无法老实说,按照您的描述。如果第一部分是文件名,并且用00分隔,那么为什么那部分出现了如此多的00?那时可能是“正常” LZW的变体。 AS LZW 1.0当然也可以代表无关的东西,例如作者的姓名缩写或名字。如果我们假设此处的信息正确,那么我们应该在此处看到有用的信息。但是它确实看起来像胡言乱语。



所以我同意,可能没有FLIC文件。不过,请记住,DWG来自同一创作者。这可能不是巧合。


有关LZW数据发现的更新。摘自Wikipedia(在此处):


这样,解码器将构建一个字典,该字典与编码器使用的字典相同,并用它来解码后续输入
值。因此,完整的字典不需要与
编码数据一起发送;仅包含
单字符字符串的初始字典就足够了(并且通常在编码器和解码器中预先定义
,而不是与编码数据一起显式发送。)


(添加了强调。)

评论


关于“ AS LZW”的要点。我以为是“ as lzw”,而不是“ A(rch)S(tar)lzw”

– wangii
13年20月20日在20:41

我认为m1,m2,m3或“ AS LZW 1.0” + 28h之前的任何内容都不是解码LZW,b / c的关键,如果这样blob不应具有完全相同的“标题” 0083 0c89 0123 460d 0008 113e 08c0

– wangii
13年11月22日在12:00