TheZZAZZGlitch's April Fools Event 2025
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

169 lines
4.6 KiB

#!/usr/bin/env python3
class RNG:
def __init__(self):
self.rng = [0xe3, 0x34, 0xad, 0x30]
def next(self):
self.rng[0] += 1
self.rng[0] &= 0xff
self.rng[1] ^= self.rng[0]
self.rng[1] ^= self.rng[3]
self.rng[2] += self.rng[1]
self.rng[2] &= 0xff
self.rng[3] += (self.rng[2] >> 1) ^ self.rng[1]
self.rng[3] &= 0xff
return self.rng[3]
class FunnyCode:
def __init__(self):
self.code = self.gencode()
self.cache = {}
def __str__(self):
return " ".join(map(lambda x: "%02x" % x, self.code))
def gencode(self):
rng = RNG()
code = []
for x in range(0x400):
val1 = rng.next()
while val1 == 0:
val1 = rng.next()
val2 = rng.next()
while True:
val2 &= 0xf8
if val2 in [0x00, 0x08, 0xf8]:
val2 = rng.next()
continue
break
code.append(0x0e) # ld c, n8
code.append(val1)
code.append(0x09) # add hl, bc
code.append(0x15) # dec d
code.append(0xc8) # ret z
code.append(0x1d) # dec e
if x < 0x14:
code.append(0x20) # jr nz, o8
code.append(val2 & 0x7f)
elif x >= 0x400 - 0x14:
code.append(0x18) # jr o8
code.append((val2 & 0x7f) + 0x80)
else:
code.append(0x20) # jr nz, o8
code.append(val2)
return code
def runcode(self, offset, de):
key = offset << 16 | de
if key in self.cache:
return self.cache[key]
hl = 0
bc = 0
d = de >> 8
e = de & 0xff
while True:
# de = d << 8 | e
# print("0x%04x"%offset, "bc=0x%04x"%bc, "de=0x%04x"%de, "hl=0x%04x"%hl)
c = self.code[offset + 1]
bc = (bc & 0xff00) | c
hl = (hl + bc) & 0xffff
d -= 1
d &= 0xff
if d == 0: break
e -= 1
e &= 0xff
if self.code[offset + 6] == 0x20 and e == 0:
offset += 8
else:
jr = self.code[offset + 7]
if jr >= 0x80: jr -= 0x100
offset = (offset + 8) + jr
self.cache[key] = hl
return hl
class PasswordHash:
def __init__(self, password):
self.hash = self.hashpass(password)
self.valid = True
if (self.hash[0] & 0xe000) != 0:
self.valid = False
if (self.hash[0] & 0x0007) != 0:
self.valid = False
def swap(self, val):
vl = (val & 0xf0) >> 4
vh = (val & 0x0f) << 4
return vh | vl
def hashpass(self, password):
c = password[0] & 0xf
b = self.swap(password[0]) & 0x03
c = ((password[1] & 0xf) + self.swap(c)) & 0xff
b = ((self.swap(password[1]) & 0x03) + ((b << 2) & 0xff)) & 0xff
c1 = c
c = password[2] & 0xf
b = ((self.swap(password[2]) & 0x03) + ((b << 2) & 0xff)) & 0xff
c = ((password[3] & 0xf) + self.swap(c)) & 0xff
b = ((self.swap(password[3]) & 0x03) + ((b << 2) & 0xff)) & 0xff
return (password[4] << 8) | b, (c << 8) | c1
passchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?!"
def convpass(password):
return bytearray(passchars.index(x) for x in password)
if __name__ == "__main__":
wanted = [
0xadaa,
0xac39,
0x002f
]
from sys import argv
if len(argv) > 1 and argv[1] == "valid":
for x in argv[2:]:
pwd = convpass(x)
password = PasswordHash(pwd)
print(*map(hex, password.hash))
if password.valid:
print(x)
exit()
if len(argv) > 1 and argv[1] == "run":
code = FunnyCode()
for x in argv[2:]:
pwd = convpass(x)
password = PasswordHash(pwd)
result = code.runcode(*password.hash)
if result in wanted:
print(hex(result), x)
exit()
code = FunnyCode()
pwd = convpass("BEPISBEPISBEPIS")
password = PasswordHash(pwd)
print(password.hash)
if not password.valid:
print("Password invalid!")
exit(1)
print(hex(code.runcode(*password.hash)))
# val = code.runcode(0, 0)
# print(hex(val))
# if val != 0x1a51:
# exit(1)
# val = code.runcode(0x1200, 0xf814)
# print(hex(val))
# if val != 0x4031:
# exit(1)
# print("success")