Skip to content

Instantly share code, notes, and snippets.

@ggtylerr
Created January 3, 2025 11:18
Show Gist options
  • Save ggtylerr/9dd93e9d999e685771b970698acd895e to your computer and use it in GitHub Desktop.
Save ggtylerr/9dd93e9d999e685771b970698acd895e to your computer and use it in GitHub Desktop.
"Vaulty" app decryption

This is a simple script to decrypt photos / videos from the android app Vaulty with its original folder structure and metadata.

You'll need to get Vaulty's database (located in /data/data/com.theronrogers.vaultyfree/databases/media.db) since that includes the data for filenames, path, and creation date. If your device isn't rooted you can use a VM with root access, then just use the cloud backup on the app to copy the files over.

To run, copy media.db to the same folder script.py is located and copy /storage/emulated/0/Documents/Vaulty/data to a new folder called input. Then just run the script using python vaultbreak.py.

import os
import sqlite3
import pathlib
import shutil
connection = sqlite3.connect("media.db")
cursor = connection.cursor()
cursor.execute("SELECT _data, path, _display_name, date_added FROM Media")
rows = cursor.fetchall()
if not os.path.exists("output"):
os.makedirs("output")
i = 0
for row in rows:
i += 1
print(f"Processing {i} out of {len(rows)} ({i/len(rows)*100:.2f}%)")
data_path = row[0].removeprefix("/storage/emulated/0/Documents/Vaulty/data/")
og_path = str(pathlib.Path(row[1]).parent).removeprefix("/")
display_name = row[2]
date_added = row[3]
input_file = os.getcwd() / pathlib.Path("input") / data_path
output_dir = os.getcwd() / pathlib.Path("output") / og_path
output_file = output_dir / display_name
if not output_dir.exists():
output_dir.mkdir(parents=True, exist_ok=True)
print(f"Copying {input_file} to {output_file}")
shutil.copy(input_file, output_file)
print("Removing high-grade encryption")
with open(output_file, "rb") as a:
if a.read(8) == b"obscured":
data = a.read()
with open(output_file, "wb") as b:
b.write(data)
print(f"Setting {output_file} access and modified times")
# date_modified is in year 56XXX for some reason so we're just using date_added for both fields.
# this is fine in most cases but date_modified is the time added to vaulty, so this might mess
# with ordering a lil bit.
os.utime(output_file, (date_added, date_added))
connection.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment