Created
December 3, 2011 21:32
-
-
Save pao/1428218 to your computer and use it in GitHub Desktop.
Brute-force script to decode the Artificial Heart Level 4 easter-egg image
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from base64 import b64decode | |
import struct | |
from zlib import crc32 | |
b64alphabet = [] | |
b64alphabet.extend([chr(x) for x in range(ord('A'),ord('Z')+1)]) | |
b64alphabet.extend([chr(x) for x in range(ord('a'),ord('z')+1)]) | |
b64alphabet.extend([chr(x) for x in range(ord('0'),ord('9')+1)]) | |
b64alphabet.extend(['+', '/']) | |
with open('joco.b64', 'rb') as f: | |
src = f.read() | |
subst1 = '' | |
# http://libpng.org/pub/png/spec/iso/index-object.html#5Chunk-layout | |
def check_chunk(name, startfrom): | |
start = picstr.find(name, startfrom) | |
if start < 0: | |
return (True, -1) | |
size = struct.unpack("!I", picstr[start-4:start])[0] | |
end = start + 4 + size | |
newcrc = crc32(picstr[start:end]) | |
oldcrc = struct.unpack("!i", picstr[end:(end+4)])[0] | |
return (newcrc == oldcrc, end) | |
for subst in (''.join([x,y]) for x in b64alphabet for y in b64alphabet): | |
picstr = b64decode(src.replace('code', subst).replace('python', 'hon')) | |
next = 0 | |
# The string "code" appears by itself in the first four IDAT chunks, | |
# so we check those only on this first run to reduce the search space | |
for i in range(0,4): | |
(valid, next) = check_chunk('IDAT', next) | |
if not valid: | |
break | |
if valid: | |
subst1 = subst | |
break | |
if len(subst1) != 2: | |
print "'code' couldn't be solved!" | |
exit() | |
print "'code' was '%s'"%(subst1,) | |
for subst in (''.join([x,y,z]) for x in b64alphabet for y in b64alphabet for z in b64alphabet): | |
picstr = b64decode(src.replace('code', subst1).replace('python', subst)) | |
next = 0 | |
# This time through, check all the IDAT chunks | |
while next >= 0: | |
(valid, next) = check_chunk('IDAT', next) | |
if not valid: | |
break | |
if valid: | |
# And also check the IEND chunk (just to be sure) | |
(valid, next) = check_chunk('IEND', 0) | |
if valid: | |
subst2 = subst | |
with open('joco_correct.png', 'wb') as out: | |
out.write(picstr) | |
break | |
print "'code' was '%s', 'python' was '%s'"%(subst1, subst2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wow, very nicely done. I'm sure glad you're not my nemesis. Unless, of course, you are.