Chromium资源文件.pak解包方法(python)

本文介绍如何使用Python解包Chromium的资源.pak文件,虽然通常不需要解包,但通过提供的unpack.py脚本,可以将其中的png图片资源导出。由于.pak文件不包含资源类型信息,所以默认导出为png格式。若要确定资源类型,需依赖文件头来分辨。
部署运行你感兴趣的模型镜像

import collections
import struct
import sys
def ReadFile(filename, encoding):
  mode = 'rb' if encoding == 0 else 'rU'
  with open(filename, mode) as f:
    data = f.read()
  if encoding not in (0, 1):
    data = data.decode(encoding)
  return data

PACK_FILE_VERSION = 4
HEADER_LENGTH = 2 * 4 + 1  # Two uint32s. (file version, number of entries) and
                           # one uint8 (encoding of text resources)
def UnpackDataPack(input_file):
  """Reads a data pack file and returns a dictionary."""
  data = ReadFile(input_file, 0)
  original_data = data

  # Read the header.
  version, num_entries, encoding = struct.unpack("<IIB", data[:HEADER_LENGTH])
  if version != PACK_FILE_VERSION:
    print "Wrong file version in ", input_file
    raise WrongFileVersion

  resources = {}
  if num_entries == 0:
    return DataPackContents(resources, encoding)

  # Read the index and data.
  data = data[HEADER_LENGTH:]
  kIndexEntrySize = 2 + 4  # Each entry is a uint16 and a uint32.
  for _ in range(num_entries):
    id, offset = struct.unpack("<HI", data[:kIndexEntrySize])
    data = data[kIndexEntrySize:]
    next_id, next_offset = struct.unpack("<HI", data[:kIndexEntrySize])
    resources[id] = original_data[offset:next_offset]
    of = open('{0}.png'.format(id),'wb')
    of.write(original_data[offset:next_offset])
    of.close()
def main():
  if len(sys.argv) > 1:
    UnpackDataPack(sys.argv[1])


if __name__ == '__main__':
  main()




chromium资源文件在linux下以pak格式文件打包,文件格式很简单,并没有压缩。一般没有解包的必要,因为编译时会自动根据源文件变化而自动生成。资源内容只在运行时由chromium根据资源ID获取,所以在.pak文件中只存储了资源的ID,并没有存储资源文件类型,所以只能默认解包成png格式了。

#python unpack.py chrome_100_percent.pak
就可以解包chrome_100_percent.pak中的png图片资源了。

如果非要获取资源文件类型的话,只能从内容判断了,根据不同文件的文件头可以大致分辨类型:


import collections
import struct
import sys
def ReadFile(filename, encoding):
  mode = 'rb' if encoding == 0 else 'rU'
  with open(filename, mode) as f:
    data = f.read()
  if encoding not in (0, 1):
    data = data.decode(encoding)
  return data

PACK_FILE_VERSION = 4
HEADER_LENGTH = 2 * 4 + 1  # Two uint32s. (file version, number of entries) and
                           # one uint8 (encoding of text resources)
def UnpackDataPack(input_file):
  """Reads a data pack file and returns a dictionary."""
  data = ReadFile(input_file, 0)
  original_data = data

  # Read the header.
  version, num_entries, encoding = struct.unpack("<IIB", data[:HEADER_LENGTH])
  if version != PACK_FILE_VERSION:
    print "Wrong file version in ", input_file
    raise WrongFileVersion

  resources = {}
  if num_entries == 0:
    return DataPackContents(resources, encoding)

  # Read the index and data.
  data = data[HEADER_LENGTH:]
  kIndexEntrySize = 2 + 4  # Each entry is a uint16 and a uint32.
  for _ in range(num_entries):
    id, offset = struct.unpack("<HI", data[:kIndexEntrySize])
    data = data[kIndexEntrySize:]
    next_id, next_offset = struct.unpack("<HI", data[:kIndexEntrySize])
    resources[id] = original_data[offset:next_offset]
    filetype = 'bin'
    fileheader = ''.join(original_data[offset:offset+1])
    print ord(fileheader[0])
    if fileheader == '<':
      filetype = 'html'
    if fileheader == '\x89':
      filetype = 'png'
    elif fileheader == '/':
      filetype = 'js'
    of = open('{0}.{1}'.format(id,filetype),'wb')
    of.write(original_data[offset:next_offset])
    of.close()
def main():
  if len(sys.argv) > 1:
    UnpackDataPack(sys.argv[1])


if __name__ == '__main__':
  main()

这里直接判断每个文件内容的前一个字节,如果是‘<'则应该是html文件,如果是'/'应该是js文件,如果是PNG文件头’\x89PNG',则应该就是png文件了。

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值