破译未知的图形格式

逆向工程 二元分析 文件格式 二元诊断 图形
2021-06-13 11:19:41

为了我自己的娱乐,我丢弃了我拥有的旧任天堂 DS 视频游戏的文件(该公司早已破产/关闭)并试图提取资产。我已经恢复了游戏文本、视频和声音,但是一个名为 的 58 MB 文件graph.dat,其中包含游戏的图形(可能)让我很难过。

重要的是,游戏的文本以开发人员似乎为游戏创建的自定义格式存储,因此我强烈怀疑graph.dat也包含自定义图形格式。

我能够通过读取保留在单独文件graph.dti. 元数据文件包含 1910 条记录,由 44 个中间数据块分隔。每条记录都列出了 中的一组连续地址graph.dat,一旦从该文件中分块,就会产生三个二进制数据 blob。

每条记录中的第一个 blob,我昵称为“Huey”,可能是某种标题。它总是 32 字节或 512 字节长。

第二个 blob 'Dewey' 的长度可变,大小从 704 字节到 49 KB 不等。我怀疑它包含实际的图像数据。

第三个 blob 'Louie' 的大小始终为 1536 字节。

我怀疑 'Huey' 可能是调色板数据,而 'Louie' 是某种颜色索引,但我不能确定。

有没有人有任何想法?将“杜威”放入 GIMP 的原始数据导入中是非常失败的。

从文件链接到四个不同图像的样本(我假设)。文件名由我的解包工具提供,并且不存在于原始元数据中。我还有 1,906 个这些是从哪里来的,所以问问你是否需要它们。

1个回答

我不确定“louie”文件的用途,但这个 python 脚本应该有助于重建图像:

import png

# simple scale from [0,0x1f] to [0,0xff]
def scale_up(n):
  return (n<<3)|n

def make_pal(n):
  val = (n[1]<<8)|n[0]
  return [scale_up((val>>0)&0x1f), scale_up((val>>5)&0x1f), scale_up((val>>10)&0x1f)]

w=256
h=192

image_base='img_159_9_0'

pixel_data_file=f'{image_base}_dewey.bin'
palette_file=f'{image_base}_huey.bin'

with open(palette_file, 'rb') as f:
  pal_bytes = f.read()

real_pal=[]
for i in range(0,256):
  m = make_pal(pal_bytes[i*2:i*2+2])
  real_pal.append(m)


with open(pixel_data_file, 'rb') as f:
  pixel_bytes = f.read()

tile_w = 8
tile_h = 8
image_tile_h = h/tile_h
image_tile_w = w/tile_w

# if any pixel/channel is not written, the png writer will complain about -1
rows_dat = [[-1 for n in range(w*3)] for m in range(h)]
for i in range(w*h):
  tile_i = int(i / (tile_w*tile_h))
  tile_x = int(tile_i % image_tile_w)
  tile_y = int(tile_i / image_tile_w)
  small_i = int(i % (tile_w*tile_h))
  small_x = int(small_i % tile_w)
  small_y = int(small_i / tile_w)
  rows_dat[tile_y*tile_h + small_y][3*(tile_x*tile_w + small_x)] = real_pal[pixel_bytes[i]][0]
  rows_dat[tile_y*tile_h + small_y][3*(tile_x*tile_w + small_x)+1] = real_pal[pixel_bytes[i]][1]
  rows_dat[tile_y*tile_h + small_y][3*(tile_x*tile_w + small_x)+2] = real_pal[pixel_bytes[i]][2]

with open(f'{image_base}.png', 'wb') as of:
  writer = png.Writer(width=w, height=h, greyscale=False)
  writer.write(of, rows_dat)

在您的示例数据中,它看起来像是img_159_9_0_dewey.bin在开头填充了 64 个字节的0x00's。我不确定这是否是转储时的错误,但删除它会有所帮助

您提供的所有图像似乎都是 256x192(我让它们旋转,平铺逻辑更清晰而不旋转 - 您可以在之后执行此操作),由 8x8 像素平铺组成。像素数据(存储在 中dewey)索引到存储为 u16le(存储在 中huey的 RGB555 值调色板中您没有提供任何内容,但我猜 32 字节huey文件只是 16 种颜色的调色板 - 相应的像素数据可能由紧密打包的 4 位索引组成。