The GRF is encrypted correctly (GRF Editor itself decrypts and previews the files fine with the password), the generated cps.dll matches the client, but the client never decrypts anything at runtime. I've isolated this pretty far and could use a pointer on where to look next.
Symptom
With encrypted sprites, the client window opens and then immediately shows an Error popup, followed by Gravity(tm) Error Handler (0xc0000005).
Control test (this is the important one): the exact same client executable and the exact same generated cps.dll, with a plain (unencrypted) GRF, runs fine — stays alive, no popup, no crash. So the exe/DLL pair itself is healthy; only decryption fails.
And the encryption itself is fine: opening the encrypted GRF in GRF Editor, entering the password, previews the .spr files without any issue.
Setup
- GRF Editor v1.9.1.2 (also reproduced on an older 1.5.x build)
- Clients tested (all reproduce): 2025-06-04, 2025-03-19, 2024-12-18 Ragexe
- Patcher: WARP
- Only
data\sprite encrypted for the test; everything else left plain
- Gepard disabled during these tests to rule it out
What I verified
Import rewiring looks correct. The 2025-06-04 client imports cps.dll natively:
| exe |
imports from cps.dll |
| clean 2025-06-04 |
compress, uncompress |
after Generate files |
compress, giedaoodvr |
and the generated DLL exports exactly compress + giedaoodvr. So the rename matches on both sides.
The exe patch is 20 bytes, two occurrences of uncompress → giedaoodvr, nothing else. From reading EncryptorDialog.xaml.cs that appears to be exactly what's expected (_binaryReplace for cps.dll and uncompress), so I don't think that's the problem — just noting it in case it is.
The generated cps.dll is byte-comparable to working ones. Two servers I have locally that do run fully encrypted GRFs ship a cps.dll of 175,616 bytes, PE timestamp 2024-10-31 12:54 — identical build to the one my older GRF Editor produced. The v1.9.1.2 one is 176,128 bytes / 2025-09-11.
GRF header key field (00 01 02 ... 0D) is identical between my encrypted GRF and both working servers' GRFs.
Key derivation is the same on both paths — GrfHolder.SetEncryptionKey(...) and EncryptorDialog._getKeyFromFile() both go through the same pair of functions with the same password, so I don't think there's a key mismatch.
On the "Resources weren't found in your client" error
On some of my builds Generate files throws this. On the 2025-06-04 client it does not throw — the check at EncryptorDialog.xaml.cs passes, since the renamed uncompress string is present afterwards. So that error isn't the cause here; the failure happens with a client that passes the check.
Question
Given that the encryption is valid (the editor decrypts it), the export/import names line up, and the same exe+DLL runs fine with a plain GRF — is there something else the client needs in order to actually route reads through cps.dll? Some additional client-side patch, or a client-version constraint I'm missing?
Happy to provide the executables, the generated DLL or a small encrypted GRF sample if that helps reproduce.
The GRF is encrypted correctly (GRF Editor itself decrypts and previews the files fine with the password), the generated
cps.dllmatches the client, but the client never decrypts anything at runtime. I've isolated this pretty far and could use a pointer on where to look next.Symptom
With encrypted sprites, the client window opens and then immediately shows an
Errorpopup, followed byGravity(tm) Error Handler(0xc0000005).Control test (this is the important one): the exact same client executable and the exact same generated
cps.dll, with a plain (unencrypted) GRF, runs fine — stays alive, no popup, no crash. So the exe/DLL pair itself is healthy; only decryption fails.And the encryption itself is fine: opening the encrypted GRF in GRF Editor, entering the password, previews the
.sprfiles without any issue.Setup
data\spriteencrypted for the test; everything else left plainWhat I verified
Import rewiring looks correct. The 2025-06-04 client imports
cps.dllnatively:cps.dllcompress,uncompressGenerate filescompress,giedaoodvrand the generated DLL exports exactly
compress+giedaoodvr. So the rename matches on both sides.The exe patch is 20 bytes, two occurrences of
uncompress→giedaoodvr, nothing else. From readingEncryptorDialog.xaml.csthat appears to be exactly what's expected (_binaryReplaceforcps.dllanduncompress), so I don't think that's the problem — just noting it in case it is.The generated
cps.dllis byte-comparable to working ones. Two servers I have locally that do run fully encrypted GRFs ship acps.dllof 175,616 bytes, PE timestamp 2024-10-31 12:54 — identical build to the one my older GRF Editor produced. The v1.9.1.2 one is 176,128 bytes / 2025-09-11.GRF header key field (
00 01 02 ... 0D) is identical between my encrypted GRF and both working servers' GRFs.Key derivation is the same on both paths —
GrfHolder.SetEncryptionKey(...)andEncryptorDialog._getKeyFromFile()both go through the same pair of functions with the same password, so I don't think there's a key mismatch.On the "Resources weren't found in your client" error
On some of my builds
Generate filesthrows this. On the 2025-06-04 client it does not throw — the check atEncryptorDialog.xaml.cspasses, since the renameduncompressstring is present afterwards. So that error isn't the cause here; the failure happens with a client that passes the check.Question
Given that the encryption is valid (the editor decrypts it), the export/import names line up, and the same exe+DLL runs fine with a plain GRF — is there something else the client needs in order to actually route reads through
cps.dll? Some additional client-side patch, or a client-version constraint I'm missing?Happy to provide the executables, the generated DLL or a small encrypted GRF sample if that helps reproduce.