Last active
October 26, 2021 15:13
-
-
Save elfsternberg/7e4c01c92a1ac05e36278d055e2a5e4c to your computer and use it in GitHub Desktop.
A primitive "dump the current OneTab collection kept in my Chrome Browser" script.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from subprocess import Popen, PIPE | |
import binascii | |
import json | |
import ast | |
# An extremely primitive dump of the | |
# [OneTab](https://www.one-tab.com/) local database. | |
# Logic is derived from [Recovering data from | |
# LevelDB](https://antimatter15.com/2015/12/recovering-deleted-data-from-leveldb/) | |
onetab = os.path.expanduser("~/.config/google-chrome/Default/Local Extension Settings/chphlpgkkbolifaimnlloiipkdnihall/000005.ldb") | |
# This script assumes you have `ldbdump` available and installed. If | |
# not, you can follow the instruction at the "Recovering data from | |
# LevelDB" blogpost above to find and install it. | |
process = Popen(["ldbdump", onetab], stdout=PIPE) | |
(output, err) = process.communicate() | |
exit_code = process.wait() | |
items = [] | |
for line in (output.split("\n")[1:]): | |
if line.strip() == "": continue | |
parsed = ast.literal_eval("{" + line + "}") | |
key = parsed.keys()[0] | |
halves = key.encode('string_escape').split("\\x", 1) | |
# Kevin Kwok (antimatter15, see above) asserts that this is the | |
# vector clock of leveldb, and that the *last* entry is the one | |
# visible in your browser's OneTab entry. | |
litkey = ast.literal_eval("'\\x" + halves[1].replace("\\\\u00", "\\x") + "'") | |
if len(litkey) == 8: | |
time = int(binascii.hexlify(litkey[1:][::-1]), 16) | |
items.append((time, halves[0], parsed[key])) | |
found = None | |
for i in sorted(items, key = lambda k: k[0]): | |
if (len(i) > 2) and (i[1] == "state"): | |
found = i[2] | |
# OneTab stringifies its JSON payload, and LevelDB stringifies | |
# *that*, so we end up with having to do two loads, and then | |
# a pretty-print dump. | |
if found: | |
print(json.dumps(json.loads(json.loads(found)), indent=4)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment