| Obsidian |
---
OBSIDIAN Security System v3.7.1 — Solved ✅
Key (this HWID): P87V-FAPR-0GMQ-7ES2 — and a full keygen below.
TL;DR
The "anti-debug fortress" is a distraction. The license check is a deterministic HWID-seeded PRNG, fully reconstructable offline — so I never ran it under a debugger and the entire anti-debug layer was irrelevant.
1. Recon
Strings are plaintext (no packing/VM). Key charset 0123456789ABCDEFGHJKLMNPQRSTUVWXYZ (Crockford-ish) xref'd into the main routine FUN_1400d1480, which decompiles cleanly. After the anti-debug theater it reads the license key and compares it to a locally generated one (byte-wise XOR accumulate + length check).
2. The seed (FUN_140001ce0) = HWID
serial = GetVolumeInformationA("C:\") // volume serial
fnv = FNV-1a-64 over GetComputerNameA() // computer name
cpu = cpuid(0).ebx ^ ecx ^ edx // vendor id
ram = GlobalMemoryStatusEx().ullTotalPhys
mix = (ram>>30)*0x9E3779B97F4A7C15
^ ((serial<<32)|((serial*0x45D9F3B)&0xFFFFFFFF))
^ (fnv<<16)
^ ((cpu<<8)|(cpu>>24))
seed = fmix64(mix) // murmur3 finalizer: *0xFF51AFD7ED558CCD, *0xC4CEB9FE1A85EC53
3. The keygen PRNG
M=(1<<64)-1
charset="0123456789ABCDEFGHJKLMNPQRSTUVWXYZ" # 34 chars
st=seed; out=[]; idx=0
for g in range(4):
for _ in range(4):
st=(((st>>13)^st)*0x5DEECE66D + 0xB)&M
out.append(charset[st%34])
st=((((st>>5)^seed)+idx)*0x27BB2EE687B0B0FD)&M
idx+=1
if g<3: out.append('-')
key=''.join(out) # XXXX-XXXX-XXXX-XXXX
4. Recovering the key
Read the four HWID components with the same Win32 APIs via ctypes (GetVolumeInformationA, GetComputerNameA, a tiny cpuid stub, GlobalMemoryStatusEx), reproduce the seed, run the PRNG → key. Type it into a normal run → "You have defeated OBSIDIAN."
Notes
- Anti-debug (IsDebuggerPresent / NtGlobalFlag / hw bp / RDTSC / process scan / patch detection) never matters — the algorithm is recovered statically and the key computed offline.
- It's a genuine keygen: feed any machine's (serial, computer name, cpuid vendor, total RAM) → its valid key.
--- |
2026-06-29 12:50 |
| Cortisol level low keygen |
W=[1,3,7,9,1,3,7,9,1,3]
def keygen(first10): # first10: 10 haneli string
s=sum(int(first10[i])*W[i] for i in range(10))
return first10 + str((10 - s%10) % 10)
print(keygen("1234567890")) # -> 12345678903 |
2026-06-29 10:41 |
| a Treasure |
bb{easy_r3v_challenge_s0lv3d} |
2026-06-29 10:36 |
| Vitalflea's Crackme v1.0 |
password is CrispyChicken encoded by base64 |
2022-12-29 11:03 |
| 1stCrackme |
The password is the reversed username repeated three times. |
2022-12-29 10:51 |
| Challenge #1 |
408838:"ThatWasEasy!" |
2022-12-29 10:38 |
| Challenge #2 |
password is ReallyEasyPassword |
2022-12-29 10:33 |
| Simple reverse |
1ecc7dd7b9763028e119e5046268d922 |
2022-12-29 10:23 |
| Baby Keygen 4 |
The length of the string must be 11 characters. This is determined by the call to "fun_402ce0" and the comparison with the value 11.
The first character of the string must be the letter 'A' (ASCII value 65). This is determined by the comparison with the value 65.
The fourth character of the string must be the letter 'X' (ASCII value 88). This is determined by the comparison with the value 88.
The eighth character of the string must also be the letter 'X' (ASCII value 88). This is determined by the comparison with the value 88.
Therefore, a valid input string would be a string of length 11 characters, with the first character being 'A', the fourth character being 'X', and the eighth character being 'X'. For example, "AXXXXXXXXAX" would be a valid input string. |
2022-12-28 16:29 |
| Baby Keygen 4 |
AXXXXXXXXXX valid |
2022-12-28 16:22 |