forked from ckh08045/AutoPercenty
77 lines
2.9 KiB
Python
77 lines
2.9 KiB
Python
'''
|
|
Proof of concept way to get cookies from chrome on Windows.. even when they're locked.
|
|
Does not require admin rights.
|
|
|
|
Includes a pure-python version of release_file_lock from:
|
|
https://github.com/thewh1teagle/rookie/blob/02995bbbb692f775e12368e7fb2b728775c88ddd/rookie-rs/src/winapi.rs#L63
|
|
|
|
(C) - MIT License 2023 - Charles Machalow
|
|
'''
|
|
import os
|
|
from ctypes import windll, byref, create_unicode_buffer, pointer, WINFUNCTYPE
|
|
from ctypes.wintypes import DWORD, WCHAR, UINT
|
|
import browser_cookie3 # pip install browser-cookie3
|
|
import backoff # pip install backoff
|
|
|
|
ERROR_SUCCESS = 0
|
|
ERROR_MORE_DATA = 234
|
|
RmForceShutdown = 1
|
|
|
|
cookies_path = os.path.expandvars(r"%LOCALAPPDATA%\Google\Chrome\User Data\Default\Network\Cookies")
|
|
|
|
rstrtmgr = windll.LoadLibrary("Rstrtmgr")
|
|
|
|
@WINFUNCTYPE(None, UINT)
|
|
def callback(percent_complete: UINT) -> None:
|
|
print(f"Unlocking file status: {percent_complete}% done")
|
|
|
|
def unlock_cookies():
|
|
session_handle = DWORD(0)
|
|
session_flags = DWORD(0)
|
|
session_key = (WCHAR * 256)()
|
|
|
|
result = DWORD(rstrtmgr.RmStartSession(byref(session_handle), session_flags, session_key)).value
|
|
|
|
if result != ERROR_SUCCESS:
|
|
raise RuntimeError(f"RmStartSession returned non-zero result: {result}")
|
|
|
|
try:
|
|
result = DWORD(rstrtmgr.RmRegisterResources(session_handle, 1, byref(pointer(create_unicode_buffer(cookies_path))), 0, None, 0, None)).value
|
|
|
|
if result != ERROR_SUCCESS:
|
|
raise RuntimeError(f"RmRegisterResources returned non-zero result: {result}")
|
|
|
|
proc_info_needed = DWORD(0)
|
|
proc_info = DWORD(0)
|
|
reboot_reasons = DWORD(0)
|
|
|
|
result = DWORD(rstrtmgr.RmGetList(session_handle, byref(proc_info_needed), byref(proc_info), None, byref(reboot_reasons))).value
|
|
|
|
if result not in (ERROR_SUCCESS, ERROR_MORE_DATA):
|
|
raise RuntimeError(f"RmGetList returned non-successful result: {result}")
|
|
|
|
if proc_info_needed.value:
|
|
result = DWORD(rstrtmgr.RmShutdown(session_handle, RmForceShutdown, callback)).value
|
|
|
|
if result != ERROR_SUCCESS:
|
|
raise RuntimeError(f"RmShutdown returned non-successful result: {result}")
|
|
else:
|
|
print("File is not locked")
|
|
finally:
|
|
result = DWORD(rstrtmgr.RmEndSession(session_handle)).value
|
|
|
|
if result != ERROR_SUCCESS:
|
|
raise RuntimeError(f"RmEndSession returned non-successful result: {result}")
|
|
|
|
|
|
# Use backoff here since there is a race condition between unlocking the file and reading it.
|
|
# Technically we're killing a process within chrome that holds the lock. Chrome can/will restart it,
|
|
# .. so we have to fetch cookies before it re-locks the file. Generally on my system we get them
|
|
# .... though one time we didn't. I think it has to do with opening a new tab.. idk. Maybe not necessary?
|
|
|
|
|
|
@backoff.on_exception(backoff.constant, PermissionError, max_tries=5)
|
|
|
|
def fetch_cookies(domain_name):
|
|
unlock_cookies()
|
|
return browser_cookie3.chrome(domain_name=domain_name) |