tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

script_cache.py (2440B)


      1 #!/usr/bin/env python
      2 # This Source Code Form is subject to the terms of the Mozilla Public
      3 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
      4 # You can obtain one at http://mozilla.org/MPL/2.0/.
      5 
      6 import os
      7 import struct
      8 import sys
      9 
     10 MAGIC = b"mozXDRcachev002\0"
     11 
     12 
     13 def usage():
     14    print(
     15        """Usage: script_cache.py <file.bin> ...
     16 
     17        Decodes and prints out the contents of a startup script cache file
     18        (e.g., startupCache/scriptCache.bin) in human-readable form."""
     19    )
     20 
     21    sys.exit(1)
     22 
     23 
     24 class ProcessTypes:
     25    Uninitialized = 0
     26    Parent = 1
     27    Web = 2
     28    Extension = 3
     29    Privileged = 4
     30 
     31    def __init__(self, val):
     32        self.val = val
     33 
     34    def __str__(self):
     35        res = []
     36        if self.val & (1 << self.Uninitialized):
     37            raise Exception("Uninitialized process type")
     38        if self.val & (1 << self.Parent):
     39            res.append("Parent")
     40        if self.val & (1 << self.Web):
     41            res.append("Web")
     42        if self.val & (1 << self.Extension):
     43            res.append("Extension")
     44        if self.val & (1 << self.Privileged):
     45            res.append("Privileged")
     46        return "|".join(res)
     47 
     48 
     49 class InputBuffer:
     50    def __init__(self, data):
     51        self.data = data
     52        self.offset = 0
     53 
     54    @property
     55    def remaining(self):
     56        return len(self.data) - self.offset
     57 
     58    def unpack(self, fmt):
     59        res = struct.unpack_from(fmt, self.data, self.offset)
     60        self.offset += struct.calcsize(fmt)
     61        return res
     62 
     63    def unpack_str(self):
     64        (size,) = self.unpack("<H")
     65        res = self.data[self.offset : self.offset + size].decode("utf-8")
     66        self.offset += size
     67        return res
     68 
     69 
     70 if len(sys.argv) < 2 or not os.path.exists(sys.argv[1]):
     71    usage()
     72 
     73 for filename in sys.argv[1:]:
     74    with open(filename, "rb") as f:
     75        magic = f.read(len(MAGIC))
     76        if magic != MAGIC:
     77            raise Exception("Bad magic number")
     78 
     79        (hdrSize,) = struct.unpack("<I", f.read(4))
     80 
     81        hdr = InputBuffer(f.read(hdrSize))
     82 
     83        i = 0
     84        while hdr.remaining:
     85            i += 1
     86            print(f"{i}: {hdr.unpack_str()}")
     87            print(f"  Key:       {hdr.unpack_str()}")
     88            print("  Offset:    {:>9,}".format(*hdr.unpack("<I")))
     89            print("  Size:      {:>9,}".format(*hdr.unpack("<I")))
     90            print("  Processes: {}".format(ProcessTypes(*hdr.unpack("B"))))
     91            print("")