Skip to content

Instantly share code, notes, and snippets.

@lamchau
Last active March 26, 2024 05:35
Show Gist options
  • Save lamchau/718aa36a6e78c2a744ff017709efcf58 to your computer and use it in GitHub Desktop.
Save lamchau/718aa36a6e78c2a744ff017709efcf58 to your computer and use it in GitHub Desktop.
[Chrome/Tampermonkey] Extract *.user.js scripts from LevelDB backup

Restoring Tampermonkey scripts

Chrome stores .user.js scripts in a .ldb, which isn't in a user accessible format to recovery. On some versions of macOS the provided python script can't compile the leveldb package. As a workaround, we can use the node level package to recover our userscripts.

Prerequisite

brew install node
npm install level

Usage

node extract.js "/Users/$(whoami)/Library/Application Support/Google/Chrome Canary/backup/Default/Default/Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo"
const fs = require('fs');
const path = require('path');
const level = require('level');
const directory = path.resolve(process.argv.length > 2
? process.argv[2]
: 'dhdgffkkebhmkfjojejmpbldmpobfkfo');
const db = level(directory);
const stream = db.createReadStream();
console.log(`Loading: ${directory}`);
const date = new Date().toISOString();
const outputDirectory = path.resolve(
path.join(
__dirname,
date.slice(0, date.indexOf('T'))
)
);
if (!fs.existsSync(outputDirectory)) {
fs.mkdirSync(outputDirectory, true);
}
console.log(`Saving to: ${outputDirectory}`);
stream.on('data', data => {
const { key, value } = data;
try {
if (value.includes('UserScript')) {
const uuid = key.slice(key.indexOf('#') + 1);
const parsed = JSON.parse(value).value;
const filename = path.join(outputDirectory, `${uuid}.user.js`);
fs.writeFile(filename, parsed, () => {
console.log(`Saved: ${path.basename(filename)}`);
});
}
} catch (err) {
}
});
@aljgom
Copy link

aljgom commented Oct 28, 2022

@rakitanc

All my userscripts over the years i gathered are gone after the abrupt PC shutdown. Please help me to restore it

Hey, were you able to figure it out?

@rakitanc
Copy link

@rakitanc

All my userscripts over the years i gathered are gone after the abrupt PC shutdown. Please help me to restore it

Hey, were you able to figure it out?

Not actually

@aljgom
Copy link

aljgom commented Oct 29, 2022

@rakitanc what did you try? Were you able to run this script? Also, did you check if in your Tampermonkey settings you have Enable Userscripts Sync checked? (If you have it checked, you might be able to restore from there too)

@rakitanc
Copy link

@rakitanc what did you try? Were you able to run this script? Also, did you check if in your Tampermonkey settings you have Enable Userscripts Sync checked? (If you have it checked, you might be able to restore from there too)

Thankyou so much brother. It's rare to find people like you nowadays who are helping this way. Because i was already sad and after not getting any help online I lost my hope actually But so happy to hear from you that finally someone came as a ray of hope

Sp just to update you with a good news..I got my scripts back by simply rebooting the PC. I just tried my luck when i didn't know what to do and Fortunately it worked.

But i would like to be in touch with you as i have one more technical issue that you might help with me. So if you don't mind can you share your Telegram, Discord or anything else so i could share it there

Looking forward to hearing from you

Thanks

@wkurten87
Copy link

wkurten87 commented Nov 15, 2022

for those that are looking for this solution in november/22 i have updated this script to work with newer versions, hope this helps somebody!

console.log(`--> LOG - INICIO --------------------`);
const fs = require('fs');
const path = require('path');

const directory = path.resolve(process.argv.length > 2
  ? process.argv[2]
  : 'bhmmomiinigofkjcapegjjndpbikblnp');

const { Level } = require('level')
const db = new Level(directory, { valueEncoding: 'json' });
console.log(`--> LOG - Tentando abrir a base`);
db.open(main);

const { EntryStream } = require('level-read-stream')
const re = new RegExp(`^@source(.*)$`);

function main(e){
	if (e){
		console.log(`--> LOG - ERROR: ${e}`);
	} else {

	console.log(`--> LOG - db status: ${db.status}`);

	console.log(`--> LOG - Loading: ${directory}`);
	const date = new Date().toISOString();
	const outputDirectory = path.resolve(
	  path.join(
		__dirname,
		date.slice(0, date.indexOf('T'))
	  )
	);

	if (!fs.existsSync(outputDirectory)) {
	  fs.mkdirSync(outputDirectory, true);
	}

	var stream = new EntryStream(db);
	stream.on('data', data => {
	  const { key, value } = data;
	  
	  try {
		console.log(`--> LOG - Saving to: ${outputDirectory}`);
		if (re.test(key)){
			console.log(`--> LOG - ACHOU! ->> key: ${key} - value ${value} `);
			
			const uuid = key.slice(key.indexOf('#') + 1);
			console.log(`--> LOG - uuid: ${uuid}`);
			
			//console.log('--> LOG - JSON Stringy' + JSON.stringify(value));
			const parsed = JSON.stringify(value);
			
			const filename = path.join(outputDirectory, `${uuid}.user.js`);
			console.log(`--> LOG - filename: ${filename}`);
			
			fs.writeFile(filename, parsed, () => {
			console.log(`--> LOG - Saved: ${path.basename(filename)}`);
			});
		}
	  } catch (err) {
			console.log(`--> LOG - ERROR: ${err}`);
	  }
	});

	console.log(`--> LOG - FIM --------------------`);
	}
}

@omicr0n
Copy link

omicr0n commented Apr 16, 2023

Updated script above works, thank you. For anyone else that plans to use it you have to run npm install level-read-stream as well before executing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment