Skip to content

Instantly share code, notes, and snippets.

@MikuAuahDark
Created June 8, 2021 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MikuAuahDark/fc9dc2357d408ec231ba133945102621 to your computer and use it in GitHub Desktop.
Save MikuAuahDark/fc9dc2357d408ec231ba133945102621 to your computer and use it in GitHub Desktop.
LuaJIT FFI to test Crypt(Un)protectData Function to Diagnose Genshin Impact Logged Out Problem
local ffi = require("ffi")
local Crypt32 = ffi.load("Crypt32")
local TEST_TEXT = [[
struct DATA_BLOB {
uint32_t size;
void *data;
};
uint32_t GetLastError();
void *__stdcall LocalFree(void*);
bool __stdcall CryptProtectData(struct DATA_BLOB*, const wchar_t*, struct DATA_BLOB*, void*, void*, uint32_t, struct DATA_BLOB*);
bool __stdcall CryptUnprotectData(struct DATA_BLOB*, wchar_t*, struct DATA_BLOB*, void*, void*, uint32_t, struct DATA_BLOB*);
]]
ffi.cdef(TEST_TEXT)
local f = io.open("testcrypt-data.txt", "rb")
local s = ffi.new("struct DATA_BLOB[2]")
local function toHex(s)
return string.format("%02X", s:byte())
end
local function encryptText()
s[0].size = #TEST_TEXT
s[0].data = ffi.cast("void*", TEST_TEXT)
if not Crypt32.CryptProtectData(s, nil, nil, nil, nil, 0, s+1) then
error("CryptProtectData error "..ffi.C.GetLastError())
end
local str = ffi.string(s[1].data, s[1].size)
assert(ffi.C.LocalFree(s[1].data) == nil)
return str
end
if not f then
local enc = encryptText()
f = assert(io.open("testcrypt-data.txt", "wb+"))
f:write(enc)
f:flush()
f:seek("set", 0)
end
local encrypted = f:read("*a")
s[0].data = ffi.cast("void*", encrypted)
s[0].size = #encrypted
if not Crypt32.CryptUnprotectData(s, nil, nil, nil, nil, 0, s+1) then
error("CryptUnprotectData error "..ffi.C.GetLastError())
end
local decrypted = ffi.string(s[1].data, s[1].size)
assert(ffi.C.LocalFree(s[1].data) == nil)
if decrypted ~= TEST_TEXT then
print("Text mismatch")
print("Actual text")
print(string.gsub(TEST_TEXT, ".", toHex), "\n")
print("Encrypted text from file")
print(string.gsub(encrypted, ".", toHex), "\n")
print("Decrypted text from file")
print(string.gsub(decrypted, ".", toHex), "\n")
print("Re-encrypted text for now")
print(string.gsub(encryptText(), ".", toHex), "\n")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment