Skip to content

Instantly share code, notes, and snippets.

@AltoRetrato
Last active May 24, 2024 13:45
Show Gist options
  • Save AltoRetrato/05f6957756931b12dc7ff8a87c2fe835 to your computer and use it in GitHub Desktop.
Save AltoRetrato/05f6957756931b12dc7ff8a87c2fe835 to your computer and use it in GitHub Desktop.
This Python script tests the CryptProtectData() Windows function. It might help test and solve issues that can affect many Windows programs.
# crypt32_test.py
#
# 2024-05-24 - 1st version published as a gist at
# https://gist.github.com/AltoRetrato/05f6957756931b12dc7ff8a87c2fe835
# TL;DR: This script helps you test the CryptProtectData() Windows function
# to possibly find and solve issues that can affect many programs.
# ----------------------------------------------------------------------------
# Is Google Chrome pausing sync each time you (re)start the browser?
#
# Does Steam always ask for login even when selecting
# "Remember my password on this device"?
#
# I investigated these and other issues in Chromium Embedded Framework (CEF)
# apps on my PC by starting those apps with the command-line argument
# --enable-logging
#
# One thing they all had in common (Chrome, Steam, Evernote, ...) was an error
# similar to "Failed to encrypt: Access is denied. (0x5)" appearing in the log.
#
# After some debugging, I found that the Windows function CryptProtectData()
# was returning error code 5 (access denied) instead of 0 (no error) on my PC.
# So I wrote this script to reproduce the issue faster and test on other PCs,
# where it worked fine. I just converted this C++ code to Python:
# https://learn.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata#examples
#
# Using Process Monitor, I captured events while running the Python script
# and found that lsass.exe encountered an "ACCESS DENIED" error
# when trying to access %APPDATA%\Microsoft\Protect\CREDHIST.
#
# SOLUTION / CONCLUSION
# =====================
#
# Though CREDHIST file permissions were correct, I noticed that the file
# was set to "read-only". Removing the "read-only" attribute solved the issue!
# You can check and change it from a command prompt using the "attrib" command,
# or by right-clicking the file in Windows Explorer and selecting "Properties".
#
# As for what changed the attribute, I have no idea.
#
# From a quick web search, this doesn't seem to be a common issue.
# Still, I think the process I used to find and fix the issue might help
# other users to find other issues as well.
#
# Some possibly related Chromium issues:
# Logout and Sync Pause Issue
# https://issues.chromium.org/issues/40281493
#
# Chrome Sync is paused after closing and opening Chrome
# https://issues.chromium.org/issues/40936509
#
# Google not saving my passwords, or prompting me to save pw even though I have the option selected
# https://issues.chromium.org/issues/337476657
import ctypes
from ctypes import POINTER, byref, c_void_p, c_wchar_p, c_char_p, c_ulong, c_int, c_char
# Define required structures
class DATA_BLOB(ctypes.Structure):
_fields_ = [("cbData", c_ulong),
("pbData", POINTER(c_char))]
# Load CryptProtectData from Crypt32
crypt32 = ctypes.WinDLL('Crypt32.dll')
CryptProtectData = crypt32.CryptProtectData
CryptProtectData.argtypes = [POINTER(DATA_BLOB), c_wchar_p, c_void_p, c_void_p, c_void_p, c_ulong, POINTER(DATA_BLOB)]
CryptProtectData.restype = c_int
# Initialize variables
pbDataInput = b"Hello world of data protection."
cbDataInput = len(pbDataInput) + 1
# Initialize the DataIn structure
DataIn = DATA_BLOB()
DataIn.pbData = ctypes.cast(pbDataInput, POINTER(c_char))
DataIn.cbData = cbDataInput
# Call CryptProtectData
DataOut = DATA_BLOB()
if CryptProtectData(byref(DataIn), None, None, None, None, 0, byref(DataOut)):
print("The encryption phase worked.")
# Free memory allocated by CryptProtectData
ctypes.windll.kernel32.LocalFree(DataOut.pbData)
else:
print("Encryption error using CryptProtectData.")
print(f"Error number {ctypes.GetLastError()}.")
input("[ENTER] to terminate.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment