4

I'm trying to extract data from an .ldb file. The Chrome extension OneTab glitched on me and I'm trying to recover the links it had saved. I believe I've found a solution from an old blog post, but I don't know enough about coding to figure out how to follow along.

Here is the link to the blog post: https://antimatter15.com/2015/12/recovering-deleted-data-from-leveldb/

I believe I've done everything correctly to build the Go application as he suggests. It created a file named "ldbdump" without a file extension. The next step is where I have trouble. I tried to run his Python code within Jupyter Notebook (it's the only software I have experience with for Python, and limited experience at that) but would only get errors.

The original code I'm working from can be found at the above link under the "Recovery" heading. I changed the definition of "base" from "test-stuff copy" to point to a folder with both the .ldb files I'm trying to read as well as the "ldbdump" file. I also changed the syntax of the print command at the bottom after getting errors. Everything else was left alone.

base = "D:\\Downloads\\ldb archive"

import os
from subprocess import Popen, PIPE
import json
import ast

for f in os.listdir(base):
  if f.endswith(".ldb"):
    process = Popen(["ldbdump", os.path.join(base, f)], stdout=PIPE)
    (output, err) = process.communicate()
    exit_code = process.wait()
    for line in (output.split("\n")[1:]):
      if line.strip() == "": continue
      parsed = ast.literal_eval("{" + line + "}")
      key = parsed.keys()[0]
      print(json.dumps({ "key": key.encode('string-escape'), "value": parsed[key] }))

If I understand the blog post correctly, this should print the contents of the .ldb file after converting its contents into a JSON file (though I'm not sure where that JSON file would be saved). After that, I can move on to the next step that would clean up the results to be more readable. Instead, I get an error. I can't tell what I'm doing wrong since I barely know what I'm doing in the first place. All I really understand is "file not found" at the top. It looks like this:

FileNotFoundError                         Traceback (most recent call last)
<ipython-input-2-26ff29e32d63> in <module>
      1 for f in os.listdir(base):
      2   if f.endswith(".ldb"):
----> 3     process = Popen(["ldbdump", os.path.join(base, f)], stdout=PIPE)
      4     (output, err) = process.communicate()
      5     exit_code = process.wait()

~\Anaconda3\lib\subprocess.py in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, encoding, errors, text)
    767                                 c2pread, c2pwrite,
    768                                 errread, errwrite,
--> 769                                 restore_signals, start_new_session)
    770         except:
    771             # Cleanup if the child failed starting.

~\Anaconda3\lib\subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_start_new_session)
   1170                                          env,
   1171                                          os.fspath(cwd) if cwd is not None else None,
-> 1172                                          startupinfo)
   1173             finally:
   1174                 # Child is launched. Close the parent's copy of those pipe

FileNotFoundError: [WinError 2] The system cannot find the file specified

Like I said, I'm not sure what it is I'm doing wrong. My best guesses are that I'm either not modifying the blog post's code correctly to point it to the files on my PC or that the original code incorrectly assumes something about my machine (meaning I have the wrong OS, I shouldn't be running it in a notebook, I'm missing some dependencies, etc.)

For reference, I'm using a desktop PC running Windows 10, I'm trying to run this code with Jupyter Notebook 5.7.4, I don't have any other packages imported other than the ones listed in the section of code above, and I barely know what I'm doing. I'm sorry. Please help.

ff03
  • 41
  • 1
  • 3

2 Answers2

2

in my research i added some fixes

import os
import subprocess
import json
import ast
for f in os.listdir(base):
  if f.endswith(".ldb"):
    process = subprocess.Popen(["ldbdump", os.path.join(base, f)], stdout=subprocess.PIPE, shell = True)
    (output, err) = process.communicate()
    exit_code = process.wait()
    for line in (output.split("\n")[1:]):
      if line.strip() == "": continue
      parsed = ast.literal_eval("{" + line + "}")
      key = parsed.keys()[0]
      print json.dumps({ "key": key.encode('string-escape'), "value": parsed[key] })
  • 1
    Could you please explain what fixes you implemented to solve the issue? – Teh Sep 09 '19 at 13:52
  • I'm clearly indicated library for process like subprocess.Popen and subprocess.PIPE. Also i added shell = True in function declaration. You can read more about this here: https://stackoverflow.com/questions/43143743/oserror-no-such-file-or-directory-on-using-subprocess-popen – Vjatcheslav Tkachev Sep 10 '19 at 14:13
  • 1
    Hey @VjatcheslavTkachev, could you write an explanation for the complete set up to run this script for someone who doesn't know any python? I'm really struggling and desperately need help on this. I keep getting "ldbdump: command not found", Thank you! – Jimmy Jan 30 '21 at 17:01
0

It's a little late but I encountered the same problem. The solution is actually trivial: The ldbdump file (without extension) built by Go under Windows is a proper Windows executable. Simply add an .exe extension and you can run it directly in the Windows command prompt, e.g. ldbdump 000005.ldb (the ldbdump file must have the .exe extension otherwise it's an unknown command). It will output the ldb dump as a comma-separated list of key-value pairs (plain-text). You can simply copy & paste the output into a text file or pipe the output into a file, format it whichever way you want etc.

The bottom line is: It's a normal Windows executable and you don't need python for it - use whichever tool you like to process the output or just do it manually.

Novgorod
  • 101
  • 1