Skip to content

Instantly share code, notes, and snippets.

@derjanb
Last active March 14, 2024 05:50
Show Gist options
  • Star 46 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save derjanb/9f6c10168e63c3dc3cf0 to your computer and use it in GitHub Desktop.
Save derjanb/9f6c10168e63c3dc3cf0 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# Linux usage: ./extract_tampermonkey_script.py "/home/<USER>/.config/<BROWSER>/Default/Local Extension Settings/<EXTENSION_ID>"
# i.e.: ./extract_tampermonkey_script.py "/home/foo/.config/google-chrome-beta/Default/Local Extension Settings/gcalenpjmijncebpfijmoaglllgpjagf"
# Mac usage: ./extract_tampermonkey_script.py "/Users/<USER>/Library/Application Support/Google/Chrome/Default/Local Extension Settings/<EXTENSION_ID>/"
# i.e.: ./extract_tampermonkey_script.py "/Users/foo/Library/Application Support/Google/Chrome/Default/Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo/"
import leveldb
import sys
import re
import json
import codecs
pattern = re.compile("^@source(.*)$")
db = leveldb.LevelDB(sys.argv[1:][0])
for k,v in db.RangeIter():
m = pattern.match(k)
if m:
name = re.sub("[\W\b]", "_", m.groups()[0].strip())
full_name = "%s.user.js" % name
print "Writing to %s" % full_name
content = json.JSONDecoder(encoding='UTF-8').decode(v)['value']
with codecs.open(full_name, 'w', 'utf-8') as text_file:
text_file.write(content)
@derjanb
Copy link
Author

derjanb commented Jul 19, 2018

@calraith Thank you!

@ImSeaWorld
Copy link

Aight. Took me a solid day plus an hour and a half to get it working. After it's all working properly it doesn't spit out my scripts. The only solution and it doesn't work. Good fucking god.

@etaderhold
Copy link

Thanks so much for this script! I was so worried I had lost my scripts, but I was able to run this against a Time Machine backup to get them back.

@Aceralon
Copy link

Aceralon commented Aug 1, 2020

For Windows 10 user using python3 they can try wsl. https://gist.github.com/Aceralon/d94a562840b858adc8585d7e44cbaa96

@needforsuv
Copy link

https://github.com/happynear/py-leveldb-windows

for windows users. Just rename .ldb to .sst because I guess the fork doesn't work with .ldb yet (at least with 2.7 binaries)

example:
C:\Users\user>C:\Python27\python.exe C:\Users\user\Desktop\extract_tampermonkey_script.py "C:\Users\user\Desktop\dhdgffk
kebhmkfjojejmpbldmpobfkfo"
Writing to _0d456ca5_3601_4638_a417_25b70ba320ca.user.js
Writing to _2185129a_bd9d_4ed6_ae59_5e1b43dd5ecf.user.js
Writing to _5f0393a6_c0da_4069_b646_e505507724c6.user.js
Writing to _623ee855_0804_476a_922f_40b6ed938746.user.js
Writing to _66a053d9_70f0_4dc3_a490_0eb149ce9849.user.js
Writing to _6a5f7258_e74d_4383_8516_714c014c1bc1.user.js
Writing to _a1669f5f_d6f4_4f96_8e05_2c6582d8d21d.user.js
Writing to _a791fe14_381d_48a5_abe5_34c73db716b7.user.js
Writing to _bbdf06d1_0336_4dd1_acc0_9f2086548bcd.user.js
Writing to _bc2a3b39_40a2_40a5_812e_177af8f969b6.user.js
Writing to _e1af85c1_fd7a_40c2_8313_25ce1bb4c1c2.user.js
Writing to _f2e744c8_e237_45ba_ae22_bf63a1f80295.user.js

just

@ipatch
Copy link

ipatch commented Nov 27, 2020

is this suppose to work with python 3.9

@kitsune7
Copy link

@ipatch, @MrTact made a fork of this that I think should work with python 3.9.

@lamchau
Copy link

lamchau commented Apr 13, 2021

Couldn't get the macOS leveldb python package to compile, but wrote a node-based solution for anyone else who gets stuck.

@OlehSuvorovSvitla
Copy link

Hello,

My windows 10 was crashed and now I'm trying to extract Tampermonkey script from extension.
Found 000003 file (which contains them), but cannot run python script above due to errors like leveldb is missing.

Can someone please run that scripts for me?
Uploaded file to: https://1drv.ms/u/s!ApdatwDcvb1ijGud-awXAi5aIFFN?e=hYyutS (as 7z, not accepted unpacked)
Mirror: https://drive.google.com/file/d/1v73eb8TNtZ8d5OlPje2OXjS8aGI9F_FH/view (raw text)

@DonaldDuck313
Copy link

For it to work in Python 3, you need to change line 19 to m = pattern.match(str(k)) and line 24 to print("Writing to %s" % full_name)

@iamqiz
Copy link

iamqiz commented Nov 25, 2021

@OlehSuvorovSvitla
on windows, i cannt install leveldb , so i use wsl to run the python;
here is result from your file
https://1drv.ms/u/s!Aso5a3Kpi4YwgXekt87RSxpi-BTY?e=GTwciO

@OlehSuvorovSvitla
Copy link

@iamqiz oh, thank you very much for this work!

I tested extracting the 000003 file for ~500kb for me and placing it in the extension's folder - and it also worked somehow o_O
So my tampermonkey after all the restarts start to see older scripts.
Now I enabled sync of files, hopefully, it will not happen again

@ueffel
Copy link

ueffel commented Jul 7, 2022

I found myself unable to install the leveldb package via pip.

$ pip install leveldb
...
  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [1 lines of output]
      Don't know how to compile leveldb for Windows!
      [end of output]
...

So I rewrite the script in go. Maybe someone finds it useful as well:

// Windows usesage: go run main.go "C:\Users\<USER>\AppData\Local\<VENDOR>\<BROWSER>\User Data\Default\Local Extension Settings\<EXTENSION_ID>"
//            i.e.: go run main.go "C:\Users\foo\AppData\Local\Google\Chrome\User Data\Default\Local Extension Settings\dhdgffkkebhmkfjojejmpbldmpobfkfo"
//     Linux usage: go run main.go "/home/<USER>/.config/<BROWSER>/Default/Local Extension Settings/<EXTENSION_ID>"
//            i.e.: go run main.go "/home/foo/.config/google-chrome-beta/Default/Local Extension Settings/gcalenpjmijncebpfijmoaglllgpjagf"
//       Mac usage: go run main.go "/Users/<USER>/Library/Application Support/Google/Chrome/Default/Local Extension Settings/<EXTENSION_ID>/"
//            i.e.: go run main.go "/Users/foo/Library/Application Support/Google/Chrome/Default/Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo/"

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"os"
	"regexp"

	"github.com/syndtr/goleveldb/leveldb"
)

var (
	pattern = regexp.MustCompile(`^@source(.*)$`)
	replace = regexp.MustCompile("[\\W\b]")
)

func must(err error) {
	if err != nil {
		panic(err)
	}
}

func main() {
	db, err := leveldb.OpenFile(os.Args[1], nil)
	must(err)
	defer db.Close()

	iter := db.NewIterator(nil, nil)
	defer iter.Release()
	for iter.Next() {
		key, value := iter.Key(), iter.Value()
		m := pattern.FindSubmatch(key)
		if len(m) == 0 {
			continue
		}
		name := replace.ReplaceAll(bytes.TrimSpace(m[1]), []byte("_"))
		fullName := fmt.Sprint(string(name), ".user.js")
		fmt.Println("Writing to", fullName)

		content := struct{ Value string }{}
		must(json.Unmarshal(value, &content))
		must(os.WriteFile(fullName, []byte(content.Value), 0o644))
	}
	must(iter.Error())
}

@KellyEscobar
Copy link

Hello, My windows 10 was crashed.

Which of these 2 files is the correct one to use to restore all the old scripts?
"..\Local\Google\Chrome\User Data\Profile 1\Local Extension Settings\dhdgffkkebhmkfjojejmpbldmpobfkfo\002379.log (There are many ldb data files in this directory)" and "..\Local\Google\Chrome\User Data\Profile 1\Sync Extension Settings\dhdgffkkebhmkfjojejmpbldmpobfkfo\000003.log"

I tried to run Python, leveldb failed.

Could someone please help me? Thank you very much.

@ueffel
Copy link

ueffel commented Aug 18, 2022

you need the whole directory not just a single file.

@iamqiz
Copy link

iamqiz commented Aug 18, 2022

@githubabcdefg as far as i know , window cannot run above script directly, but you can run it in window WSL,
additionly, above script use python2, if you use python3, try this py3 version:
https://gist.github.com/derjanb/9f6c10168e63c3dc3cf0?permalink_comment_id=3400197#gistcomment-3400197 (from Aceralon)

usage:
python extract_tampermonkey_script.py path/to/chrome/Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo
if you use WSL in window , the window path is maped to /mnt/ directory,
you can copy the "Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo" dir to D:\dhdgffkkebhmkfjojejmpbldmpobfkfo
and run py with: python extract_tampermonkey_script.py /mnt/d/dhdgffkkebhmkfjojejmpbldmpobfkfo
and the output JavaScript file will be placed where the script.py is

@KellyEscobar
Copy link

you need the whole directory not just a single file.

Thanks nice person.

@KellyEscobar
Copy link

@githubabcdefg as far as i know , window cannot run above script directly, but you can run it in window WSL, additionly, above script use python2, if you use python3, try this py3 version: https://gist.github.com/derjanb/9f6c10168e63c3dc3cf0?permalink_comment_id=3400197#gistcomment-3400197 (from Aceralon)

usage: python extract_tampermonkey_script.py path/to/chrome/Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo if you use WSL in window , the window path is maped to /mnt/ directory, you can copy the "Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo" dir to D:\dhdgffkkebhmkfjojejmpbldmpobfkfo and run py with: python extract_tampermonkey_script.py /mnt/d/dhdgffkkebhmkfjojejmpbldmpobfkfo and the output JavaScript file will be placed where the script.py is

Since I don't have WSL installed, I'll try it out in VMware, thank you very much for your help.
Thanks again.

@KellyEscobar
Copy link

KellyEscobar commented Aug 19, 2022

@githubabcdefg as far as i know , window cannot run above script directly, but you can run it in window WSL, additionly, above script use python2, if you use python3, try this py3 version: https://gist.github.com/derjanb/9f6c10168e63c3dc3cf0?permalink_comment_id=3400197#gistcomment-3400197 (from Aceralon)

usage: python extract_tampermonkey_script.py path/to/chrome/Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo if you use WSL in window , the window path is maped to /mnt/ directory, you can copy the "Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo" dir to D:\dhdgffkkebhmkfjojejmpbldmpobfkfo and run py with: python extract_tampermonkey_script.py /mnt/d/dhdgffkkebhmkfjojejmpbldmpobfkfo and the output JavaScript file will be placed where the script.py is

I've tried different versions of Python, and it always seems to be a leveldb error.

1

2

@ueffel
Copy link

ueffel commented Aug 19, 2022

you need the leveldb module. you can install it via pip.

$ python3 -m pip install leveldb

@iamqiz
Copy link

iamqiz commented Aug 19, 2022

@KellyEscobar here is result from your file:
https://1drv.ms/u/s!Aso5a3Kpi4YwggOXvz9Uj95k_h_B?e=VpMW6v
老哥中国人?哈哈😂

@KellyEscobar
Copy link

you need the leveldb module. you can install it via pip.

$ python3 -m pip install leveldb

It's really helped. Thank you very much.

@KellyEscobar
Copy link

@KellyEscobar here is result from your file: https://1drv.ms/u/s!Aso5a3Kpi4YwggOXvz9Uj95k_h_B?e=VpMW6v 老哥中国人?哈哈😂

Thanks for your help.

@rakitanc
Copy link

@KellyEscobar here is result from your file: https://1drv.ms/u/s!Aso5a3Kpi4YwggOXvz9Uj95k_h_B?e=VpMW6v 老哥中国人?哈哈joy

Hi there hope you are doing well

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

Chrome Version 103.0.5060.114 (Official Build) (64-bit)
TM version 4.18.0
Linux OS
Screenshot from 2022-10-19 15-41-54

If anyone can help me in the situation. It would mean a world to me, I am very devastated right now to what just happened suddenly out of nowhere

@iamqiz
Copy link

iamqiz commented Oct 19, 2022

@rakitanc pack your extension directory ("/home/<USER>/.config/<BROWSER>/Default/Local Extension Settings/<EXTENSION_ID>" ) , and upload it to web cloud (google/Microsoft) ,share link to me, then i will restore it and send back to you

@rakitanc
Copy link

rakitanc commented Oct 20, 2022

@iamqiz 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

@iamqiz
Copy link

iamqiz commented Oct 20, 2022

@rakitanc happy to hear you got your script back

@EdFrees
Copy link

EdFrees commented Nov 4, 2022

I'm not sure what this is supposed to do. I ran the code, got no errors, but I don't see the extracted scripts anywhere. Could someone post a screenshot of a successful extraction?

@iamqiz
Copy link

iamqiz commented Nov 5, 2022

@EdFrees it will print "Writing to xxxx.js" and the "xxxx.js" are extracted scripts,they will be placed at python script directory

@EdFrees
Copy link

EdFrees commented Nov 5, 2022

@EdFrees it will print "Writing to xxxx.js" and the "xxxx.js" are extracted scripts,they will be placed at python script directory

Okay. I'm not seeing it Writing anything. There are no js scripts in the folder where the python script is. All it gives is a blank line in the terminal and then I can type again. No errors. There are clearly old Tampermonkey scripts in the folder because when I open some of the files in a text editor I can see parts of the scripts I wrote.

Could the problem be that there are 2 ldb files containing different scripts?

@iamqiz
Copy link

iamqiz commented Nov 6, 2022

@EdFrees i guess your tapermonkey dir is not valid leveldb database, the database dir include Manifest-* CURRENT *.ldb(or *.log) files and so on.
details about google leveldb:
https://github.com/google/leveldb/blob/main/doc/impl.md

@EdFrees
Copy link

EdFrees commented Nov 7, 2022

@iamqiz I understand. I see the files that are mentioned in the post:
000010.ldb, 000012.ldb, 000013.log, CURRENT, LOCK, LOG, LOG.old, MANIFEST-000011
After I run the script some file names are changed. 000015.log and MANIFEST-000014. The LOG is also adjusted I think.

@EdFrees
Copy link

EdFrees commented Nov 19, 2022

Could anyone please help me out trying to extract the scripts?

@optionsx
Copy link

Nice! thanks a bunch

@ziqian-L
Copy link

@iamqiz 佬,我把位于C:\Users\用户名\AppData\Local\Microsoft\Edge\User Data\Default\Extensions里的油猴插件拖出来后,油猴脚本消失了,这种情况可以恢复脚本吗?

@iamqiz
Copy link

iamqiz commented Apr 12, 2023

@ziqian-L 油猴数据位于 "C:\Users<USERNAME>\AppData\Local\Microsoft\Edge\User Data\Default\Local Extension Settings\<EXTENSION_ID> 下, 如果有CURRENT *.ldb 等文件,那么可以恢复, 我的仓库可以在线恢复,不需要自己搭python环境 ,见: https://github.com/iamqiz/github-action-for-tapermonkey

@ziqian-L
Copy link

ziqian-L commented Apr 12, 2023 via email

@iamqiz
Copy link

iamqiz commented Apr 12, 2023

@ziqian-L 😂 以后定期做好备份吧 ,设置>实用工具>压缩包|文件> 导出

@ziqian-L
Copy link

ziqian-L commented Apr 12, 2023 via email

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