【问题标题】:Raw floating point encoding原始浮点编码
【发布时间】:2012-03-13 07:26:34
【问题描述】:

更新 最初的问题不再是这个问题的合适问题,所以我将不理会这个问题,以展示我尝试/学到的内容以及背景。很明显,这不仅仅是“Base64 变体”,而且涉及更多。

背景: 我在 python 3.x 中编程主要是为了与开源程序 Blender 一起使用。我是新手/业余级别的程序员,但我对大概念理解得相当好 我已阅读与我的问题相关的这些文章。

问题: 我有一个二进制文件,其中包含对应于每个顶点(浮点数)的 x、y、z 坐标的 3d 网格数据(浮点数列表和整数列表)以及构成网格面的顶点索引(整数) .该文件以一种xml'ish的感觉组织......

<SomeFieldLabel and header like info>**thensomedatabetween**</SomeFieldLabel>

这是“顶点”字段中的示例

<Vertices vertex_count="42816" base64_encoded_bytes="513792" check_value="4133547451">685506bytes of b64 encoded data
</Vertices>
  1. Vertices”和“/Vertices”之间有685506字节的数据
  2. 这些字节只包含 a-a、A-Z、0-9 和 +,这是 base64 的标准
  3. 当我抓取这些字节并在 python 中使用标准 base64decode 时,我得到了 513792 个字节
  4. 如果可以相信 vertex_count="42816",则每个顶点应该需要 42816*12 个字节来表示 x,y,z。 42816*12 = 513792。非常好。
  5. 现在,如果我尝试将解码后的字节解压缩为 32 位浮点数,我会得到垃圾......所以有些东西是 ammis。

我在想某处有一个额外的加密步骤。也许有翻译表、旋转密码或某种流密码?奇怪的是字节数是正确的,但结果却不应该限制可能性。有任何想法吗?下面是两个文件扩展名更改为 *.mesh 的示例文件。我不想公开这种文件格式,只想为 Blender 编写一个导入器,以便我可以使用模型。

这里有两个示例文件。我已经从 Vertices 和 Facets 字段中提取了原始二进制文件(不是 b64 解码的),并从公司提供的此类文件的“查看器”中提供了边界框信息。
示例文件 1

示例文件 2

关于 Vertices 字段的说明

  • 标头指定vertex_count
  • 标头指定 base64_encoded_bytes,即在 base64 编码发生之前的字节数
  • 标头指定了一个“check_value”,其意义尚未确定
  • 字段中的数据只包含标准的base64字符
  • 在标准 base64 解码后,输出数据具有...长度 = vertex_count*12 = base64_encoded_bytes。 b64 输出中偶尔会多出 4 个字节? -编码/解码字节的比例是4/3,这也是典型的base64

关于 Facets 字段的说明

  • 标头指定了 facet_count
  • 标头 base64_encoded_bytes 是发生 base64 编码之前的字节数

  • base64_encoded_bytes/facet_count 的比率似乎变化很大 少量。从 1.1 到大约 1.2。我们预计比率为 12,如果他们 被编码为对应于顶点索引的 3x4 字节整数。 所以要么这个字段被压缩,要么模型被保存 triangle strips,或两者兼有:-/

更多窥探
我打开了公司提供的 viewer.exe(在十六进制编辑器中)来查看这些文件(也是我获得边界框信息的地方)。这里有一些我觉得很有趣的sn-ps,可以进一步搜索。

f_LicenseClient...Ì.@......m_wApplicationID......@......f_bSiteEncryptionActive......@......f_bSaveXXXXXXInternalEncrypted......@. .....f_bLoadXXXXXXInternalEncrypted...¼!@......f_strSiteKey....í†......

在 LoadXXXXXXInternalEncrypted 和 SaveXXXXXXInternalEncrypted 中,我用 XX 屏蔽了公司名称。看起来除了简单的 base64 表变体之外,我们肯定还有一些加密。

SaveEncryptedModelToStream........Self...pUx....Model...^ÃC....Stream....

在我看来,这就像一个关于如何保存加密模型的函数定义。

DefaultEncryptionMethod¼!@........ÿ.......€...€ÿÿ.DefaultEncryptionKey€–†....ÿ...ÿ.......€ ....ÿÿ.DefaultIncludeModelData –†..ÿ...ÿ.......€...€ÿÿ.DefaultVersion.@

啊……现在这很有趣。默认加密密钥。请注意,每个描述符之间有 27 个字节,它们总是以“ÿÿ”结尾。这是 24 个字节,不包括“ÿÿ”。对我来说,这是一个 192 位的密钥……但谁知道是否所有 24 个字节都对应于密钥?有什么想法吗?

80 96 86 00 18 00 00 FF 18 00 00 FF 01 00 00 00 00 00 00 80 01 00 00 00

代码片段
为了节省此线程中的空间,我将此脚本放在我的下拉框中以供下载。它读取字段,从顶点和面字段中提取基本信息,并打印出一堆东西。您可以取消注释末尾,使其将数据块保存到单独的文件中,以便于分析。
basic_mesh_read.py

这是我用来在标准 base64 库上尝试所有“合理”变体的代码。 try_all_b64_tables.py

【问题讨论】:

  • 您确定编码值是 32 位浮点数吗?如果是这样,它们是用LSB 还是MSB 表示的?
  • 我不完全确定,但考虑到字节与顶点的比率,我相当有信心。至于 LSB 或 MSB,这些对我来说是新术语,所以我正在调查。看起来这与字节顺序相同,但 Wiki 文章说它不是。所以,我需要多考虑一下这个问题。我试过拆开小端和大端。
  • 它没有加密。加密文本看起来像随机字节,我看到很多重复。
  • 你有什么方法可以得到一些已知的纯文本吗?如果您知道其中一个顶点的实际值,您的工作会容易得多。
  • check_value 看起来确实很可疑。我尝试用它对数据进行异或运算,但它仍然会产生无意义的值。所以这可能涉及更多的事情。

标签: python reverse-engineering 3d-model


【解决方案1】:

我不确定您为什么认为结果不是浮点数。您提供的“解密数据”中的顶点数据包含前 4 个字节“f2 01 31 41”。给定一个 LSB 字节顺序,它对应于位模式“413101f2”,它是浮点值 11.062973 的 IEEE 754 表示。该文件中的所有 4 字节值都在同一范围内,所以我假设它们都是浮点值。

【讨论】:

  • 没错,“解密数据”是4byte浮点数。此特定数据由第 3 方应用程序解密。因此,原始文件中的数据来自原始浮点数 -> 加密 -> base64encoded。我的目标是反过来。加密 -> 我目前无法做到的原始浮点数。当我第一次写这个线程时,我只是认为它是 Base64 的变体,但更多的调查得出结论,它也是加密的。为混乱道歉。
  • 也许“加密数据”实际上只是 binary 中的浮点流?
猜你喜欢
  • 2015-10-17
  • 2014-12-01
  • 2015-06-14
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 2015-03-23
  • 2010-10-03
  • 1970-01-01
相关资源
最近更新 更多