KTX to PNG in Python for iOS snapshots
iOS上的应用快照以KTX文件格式存储,这一点由于Geraldine Blay(@i_am_the_gia)和Alex Brignoni(@AlexisBrignoni)在此处和此处的研究而变得相当知名。他们甚至提出了一种收集并将其转换为PNG格式的方法。然而,该解决方案仅适用于macOS,因此有了这项研究。
KTX
KTX是一种用于存储纹理的文件格式,通常被OpenGL程序使用。KTX文件格式的详细信息可在此处获取。由于它主要用于游戏,而不是用于读取/分发独立纹理,因此没有太多独立的实用程序可以处理KTX文件。也没有现成的Python库来读取它!创建该格式的Khronos小组分发了libktx,但它仅支持C++。即便如此,它也无法读取iOS创建的ktx文件(原因如下所述)。我能找到的少数Windows应用程序(如PicoPixel)无法将Apple创建的KTX文件识别为有效文件。
那么这里有什么不同?在十六进制编辑器中快速浏览文件显示,纹理数据以LZFSE压缩形式存储,目前只有macOS/iOS可以读取。
现在使用pyliblzfse,我可以解压缩数据,并重新创建一个包含原始纹理数据的新KTX文件。即便如此,除了macOS的Finder/Quickview和Preview之外,其他KTX查看器也无法渲染它。因此,我尝试了几种不同的方法来获取数据。
尝试1 - 渲染和导出
纹理与2D图像不同,因此没有从纹理到图像格式的直接转换。根据现有的研究,似乎最简单的方法是使用OpenGL渲染从KTX文件中提取的纹理数据,然后使用OpenGL保存渲染图像的2D图像。互联网上也有一些示例代码,但为了使其工作,需要了解如何使用OpenGL渲染纹理,这对我来说学习曲线太陡峭了。
在花了几个小时尝试在Python中实现这一点后,我最终放弃了,因为Python不是主要进行OpenGL开发的平台,因此支持很少甚至没有,而且库依赖于平台。我勉强在Linux中正确安装了一个库,但每一步都遇到了比我想调试的更多的错误,最终我放弃了。
尝试2 - 将纹理数据转换为RAW图像数据
读取KTX文件头,对于所有iOS生成的KTX文件,头中的glInternalFormat值字段为0x93B0(如上图所示)。该值是COMPRESSED_RGBA_ASTC_4x4的枚举值。所以现在我们知道了格式是ASTC,即自适应可扩展纹理压缩,一种用于存储纹理数据的有损压缩格式,并使用4x4像素的块大小。这简化了我们的任务,现在需要找到一种将ASTC数据转换为原始图像数据的方法。一番搜索后,我找到了python库astc_decomp,它正是做这个的。所以我现在需要将各个部分组合如下:
- 读取KTX文件并解析格式以获取LZFSE压缩数据,以及宽度和高度参数
- 解压缩LZFSE以获取ASTC数据
- 将ASTC转换为RAW图像流
- 使用PIL库将RAW图像保存为PNG
将所有这些结合起来,我们能够创建一个可以将KTX文件转换为PNG文件的Python脚本。在此获取:
https://github.com/ydkhatri/MacForensics/tree/master/IOS_KTX_TO_PNG
如果你需要在没有Python的Windows上执行此操作,那里还有一个Windows编译的可执行文件。Alex Brignoni有帮助地向我发送了多个图像的KTX文件样本。该代码也适用于并非真正KTX的KTX文件,即它们具有.ktx扩展名但头是'AAPL'。然而,格式类似,我的代码也会解析它们。如果你遇到无法工作的文件,请发送给我,我可以查看一下。
需要注意的是,并非所有KTX文件都使用COMPRESSED_RGBA_ASTC_4x4格式,只有iOS创建的文件才使用。因此,你可能会遇到许多部署或随应用程序分发的KTX文件无法用此工具解析,因为它只处理ASTC 4x4格式。
享受吧!
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)
公众号二维码

公众号二维码

