commit a3fe883d769cbf20a6607c94c82b8d42fc22b86b Author: mid-kid Date: Sun Feb 26 00:07:38 2023 +0100 Publish TheZZAAZZGlitch's Fools 2022 event notes (a bit late) diff --git a/braille.txt b/braille.txt new file mode 100644 index 0000000..862d956 --- /dev/null +++ b/braille.txt @@ -0,0 +1,38 @@ +ster +disa +less +hope +lettuce + +once entered walk twenty steps total +finally you will become femboy +go to hole in the fence five times + +east east north north - done +east north south south - done +north south east east - done +north east south east - done + +braille in Tiny Cavner in Southern Glitchland + +YEET: +SLIDE FREELY EVERYWHERE + +eastern camp: + cracker cavern + +southern camp: + femboy prime + fun value resetter + +northern camp: + fun value checker + casino + altering cave + +northern retreat: + trendy phrase + +western camp: + balls guy + western relic diff --git a/calc_hash.py b/calc_hash.py new file mode 100644 index 0000000..d18e590 --- /dev/null +++ b/calc_hash.py @@ -0,0 +1,211 @@ +#!/usr/bin/python3 + +charmap = { + ' ': 0x00, + '0': 0xA1, + '1': 0xA2, + '2': 0xA3, + '3': 0xA4, + '4': 0xA5, + '5': 0xA6, + '6': 0xA7, + '7': 0xA8, + '8': 0xA9, + '9': 0xAA, + '!': 0xAB, + '?': 0xAC, + '.': 0xAD, + '-': 0xAE, + '…': 0xB0, + '“': 0xB1, + '”': 0xB2, + '‘': 0xB3, + '’': 0xB4, + '♂': 0xB5, + '♀': 0xB6, + ',': 0xB8, + '/': 0xBA, + 'A': 0xBB, + 'B': 0xBC, + 'C': 0xBD, + 'D': 0xBE, + 'E': 0xBF, + 'F': 0xC0, + 'G': 0xC1, + 'H': 0xC2, + 'I': 0xC3, + 'J': 0xC4, + 'K': 0xC5, + 'L': 0xC6, + 'M': 0xC7, + 'N': 0xC8, + 'O': 0xC9, + 'P': 0xCA, + 'Q': 0xCB, + 'R': 0xCC, + 'S': 0xCD, + 'T': 0xCE, + 'U': 0xCF, + 'V': 0xD0, + 'W': 0xD1, + 'X': 0xD2, + 'Y': 0xD3, + 'Z': 0xD4, + 'a': 0xD5, + 'b': 0xD6, + 'c': 0xD7, + 'd': 0xD8, + 'e': 0xD9, + 'f': 0xDA, + 'g': 0xDB, + 'h': 0xDC, + 'i': 0xDD, + 'j': 0xDE, + 'k': 0xDF, + 'l': 0xE0, + 'm': 0xE1, + 'n': 0xE2, + 'o': 0xE3, + 'p': 0xE4, + 'q': 0xE5, + 'r': 0xE6, + 's': 0xE7, + 't': 0xE8, + 'u': 0xE9, + 'v': 0xEA, + 'w': 0xEB, + 'x': 0xEC, + 'y': 0xED, + 'z': 0xEE, + '$': 0xFF, +} +chars = [ + ' ', + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '!', + '?', + '.', + '-', + '…', + '“', + '”', + '‘', + '’', + '♂', + '♀', + ',', + '/', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + '$', +] + +round1 = ([73, 97, 13, 41, 67, 101, 89, 139, 71, 83], [6969, 6367, 5099, 4591, 4421, 4831, 3581, 5039, 5279, 4079, 4021]) +round2 = ([59, 181, 127, 163, 103, 163, 149, 193, 211, 151], [1337, 3701, 4603, 4663, 4703, 4219, 6481, 6983, 5407, 5297, 5099]) +def one_round(string, coeffs, addends): + assert(len(coeffs) == 10) + assert(len(string) == 10) + + var32769 = addends[0] + for c,n,x in zip(string,coeffs,addends[1:]): + var32769 = (var32769 + charmap[c]) % 65536 + var32769 = (var32769 * n) % 65536 + var32769 = (var32769 + x) % 65536 + return var32769 + +def get_hash_for(string): + var32771 = one_round(string, *round1) + var32769 = one_round(string, *round2) + return hex(var32771),hex(var32769) + +all = len(chars) ** 10 +for x in range(all): + s = "" + while x: + s += chars[x % len(chars)] + x //= len(chars) + while len(s) < 10: + s += "$" + + hash = get_hash_for(s) + if hash == (0xB0EF, 0xD4B9): + print(s) + +final = 0x828E - round1[1][-1] +for x in range(10): + for i, c in reversed(charmap.items()): + if c == 0: + continue + if c % round1[0][-x] == 0: + c //= round1[0][-x] + print(c) + break + else: + print("nope") + exit() + c -= round1[1][-1 - x] + +# 0123456789 = +print(get_hash_for("0123456789")) +print(get_hash_for("$$$$$$$$$$")) +print(get_hash_for("ABABABABAB")) +print(get_hash_for("6969696969")) diff --git a/calc_hash_fast.py b/calc_hash_fast.py new file mode 100644 index 0000000..f7bcdef --- /dev/null +++ b/calc_hash_fast.py @@ -0,0 +1,236 @@ +#!/usr/bin/python3 + +charmap = { + ' ': 0x00, + '0': 0xA1, + '1': 0xA2, + '2': 0xA3, + '3': 0xA4, + '4': 0xA5, + '5': 0xA6, + '6': 0xA7, + '7': 0xA8, + '8': 0xA9, + '9': 0xAA, + '!': 0xAB, + '?': 0xAC, + '.': 0xAD, + '-': 0xAE, + '…': 0xB0, + '“': 0xB1, + '”': 0xB2, + '‘': 0xB3, + '’': 0xB4, + '♂': 0xB5, + '♀': 0xB6, + ',': 0xB8, + '/': 0xBA, + 'A': 0xBB, + 'B': 0xBC, + 'C': 0xBD, + 'D': 0xBE, + 'E': 0xBF, + 'F': 0xC0, + 'G': 0xC1, + 'H': 0xC2, + 'I': 0xC3, + 'J': 0xC4, + 'K': 0xC5, + 'L': 0xC6, + 'M': 0xC7, + 'N': 0xC8, + 'O': 0xC9, + 'P': 0xCA, + 'Q': 0xCB, + 'R': 0xCC, + 'S': 0xCD, + 'T': 0xCE, + 'U': 0xCF, + 'V': 0xD0, + 'W': 0xD1, + 'X': 0xD2, + 'Y': 0xD3, + 'Z': 0xD4, + 'a': 0xD5, + 'b': 0xD6, + 'c': 0xD7, + 'd': 0xD8, + 'e': 0xD9, + 'f': 0xDA, + 'g': 0xDB, + 'h': 0xDC, + 'i': 0xDD, + 'j': 0xDE, + 'k': 0xDF, + 'l': 0xE0, + 'm': 0xE1, + 'n': 0xE2, + 'o': 0xE3, + 'p': 0xE4, + 'q': 0xE5, + 'r': 0xE6, + 's': 0xE7, + 't': 0xE8, + 'u': 0xE9, + 'v': 0xEA, + 'w': 0xEB, + 'x': 0xEC, + 'y': 0xED, + 'z': 0xEE, + '$': 0xFF, +} + +chars = [ + ' ', + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '!', + '?', + '.', + '-', + '…', + '“', + '”', + '‘', + '’', + '♂', + '♀', + ',', + '/', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + '$', +] +# Script vars are u16 + + +def one_round(string, starting_val, coeffs, addends): + assert(len(coeffs) == 10) + assert(len(string) == 10) + + var32769 = starting_val + for c,n,x in zip(string,coeffs,addends): + var32769 = (var32769 + charmap[c]) % 65536 + var32769 = (var32769 * n) % 65536 + var32769 = (var32769 + x) % 65536 + return var32769 + +round1 = (6969, [73, 97, 13, 41, 67, 101, 89, 139, 71, 83], [6367, 5099, 4591, 4421, 4831, 3581, 5039, 5279, 4079, 4021]) +round2 = (1337, [59, 181, 127, 163, 103, 163, 149, 193, 211, 151], [3701, 4603, 4663, 4703, 4219, 6481, 6983, 5407, 5297, 5099]) +def get_hash_for(string): + var32771 = one_round(string, *round1) + var32769 = one_round(string, *round2) + return hex(var32771),hex(var32769) + +def get_unk_coeffs(round): + constant = one_round(" ", *round) + coeffs = [] + for c in round[1]: + for i in range(len(coeffs)): + coeffs[i] = (coeffs[i] * c) % 65536 + coeffs.append(c) + return constant,coeffs + + +simple_round1 = get_unk_coeffs(round1) +simple_round2 = get_unk_coeffs(round2) +print(simple_round1) +print(simple_round2) + +def simple_round(string, starting_val, coeffs): + return (starting_val + sum([ (charmap[char] * coeff) % 65536 for (char,coeff) in zip(string,coeffs) ])) % 65536 + +def simple_hash(string): + var32771 = simple_round(string, *simple_round1) + var32769 = simple_round(string, *simple_round2) + return hex(var32771),hex(var32769) + + +# all = len(chars) ** 10 +# for x in range(all): + # s = "" + # while x: + # s += chars[x % len(chars)] + # x //= len(chars) + # while len(s) < 10: + # s += "$" + + # hash = simple_hash(s) + # if hash == 0xB0EF: + # print(s) + +print(get_hash_for("0123456789"), simple_hash("0123456789")) +print(get_hash_for("$$$$$$$$$$"), simple_hash("$$$$$$$$$$")) +print(get_hash_for("ABABABABAB"), simple_hash("ABABABABAB")) +print(get_hash_for("6969696969"), simple_hash("6969696969")) + + +def print_simple(starting_val, coeffs, target): + print(coeffs, hex((target - starting_val) % 65536)) + +print_simple(*simple_round1, 45295) +print_simple(*simple_round2, 54457) + +for char in charmap: + print("0x%04X" % ((charmap[char] * 39437) & 0xffff)) + +# a1 * x1 + a2 * x2 + C = <> +# (a1 + a2) * (x1 + x2) + C diff --git a/cave3.txt b/cave3.txt new file mode 100644 index 0000000..ba25e32 --- /dev/null +++ b/cave3.txt @@ -0,0 +1,10 @@ + +"0123456789" = 0AEE 828E +" " = 78D3 FC47 +"ABABABABAB" = 5266 9722 +"6969696969" = 9B24 F0E0 + +32769 32771 +D4B9 B0EF + +Password: "…n….," diff --git a/cave4.txt b/cave4.txt new file mode 100644 index 0000000..b98a4c4 --- /dev/null +++ b/cave4.txt @@ -0,0 +1,9 @@ +Request cert: +07000000686f6c6465723d41656c6974612f747970653d73696c766572ffc04600000000 +Response: +4954496e702b6863537766503243357276544179796e3355496a5a3974584d3368664d634470346b677672515438724d755645367954686652556a397a2b516d45564353564d4a6a393070526f464a355959525257413d3dff + +Verify cert: +080000004954496e702b6863537766503243357276544179796e3355496a5a3974584d3368664d634470346b677672515438724d755645367954686652556a397a2b516d45564353564d4a6a393070526f464a355959525257413d3dff0000000217018037121200c71d020213006587010217018000001200da75030213008c8701021200db75030213008d8701021601800000160280a3001701800000180280010021028000000605898701021701805f121200c81d02021300b287010217018000001200da7503021300d98701021200db7503021300da870102160180000016028067001701800000180280010021028000000605d68701021701807b101200c91d +Response: +53000000617574686f726974793d437261636b6572466f75722f73657269616c3d343636343135342f686f6c6465723d41656c6974612f747970653d73696c766572ff diff --git a/cave5.txt b/cave5.txt new file mode 100644 index 0000000..8f05710 --- /dev/null +++ b/cave5.txt @@ -0,0 +1,28 @@ +02018213: lock +02018214: faceplayer +02018215: checkflag 1070 +02018218: goto_if 1, loc_0201825b +0201821e: loadword 0, 0x02018265 +02018224: callstd 4 +02018226: waitmessage +02018227: closemessage +02018228: delay 60 +0201822b: playse 209 +0201822e: delay 20 +02018231: setvar 32781, 3 +02018236: playse 107 +02018239: callnative 0x080b0535 +0201823e: delay 150 +02018241: callnative 0x080b058d +02018246: waitstate +02018247: delay 10 +0201824a: message 0x02018321 +0201824f: setflag 1070 +02018252: playfanfare 389 +02018255: waitfanfare +02018256: call 0x0203e14c + loc_0201825b: +0201825b: loadword 0, 0x0201835a +02018261: callstd 4 +02018263: release +02018264: end diff --git a/client.py b/client.py new file mode 100755 index 0000000..f4b4e23 --- /dev/null +++ b/client.py @@ -0,0 +1,463 @@ +#!/usr/bin/env python3 + +import json +from urllib.request import Request, urlopen +from base64 import b64encode, b64decode +from binascii import hexlify, unhexlify +from random import randrange +from os.path import isfile, isdir +from os import mkdir +from time import time + +charmap = { + ' ': 0x00, + 'é': 0x1B, + '0': 0xA1, + '1': 0xA2, + '2': 0xA3, + '3': 0xA4, + '4': 0xA5, + '5': 0xA6, + '6': 0xA7, + '7': 0xA8, + '8': 0xA9, + '9': 0xAA, + '!': 0xAB, + '?': 0xAC, + '.': 0xAD, + '-': 0xAE, + '…': 0xB0, + '“': 0xB1, + '”': 0xB2, + '‘': 0xB3, + '’': 0xB4, + '♂': 0xB5, + '♀': 0xB6, + ',': 0xB8, + '/': 0xBA, + 'A': 0xBB, + 'B': 0xBC, + 'C': 0xBD, + 'D': 0xBE, + 'E': 0xBF, + 'F': 0xC0, + 'G': 0xC1, + 'H': 0xC2, + 'I': 0xC3, + 'J': 0xC4, + 'K': 0xC5, + 'L': 0xC6, + 'M': 0xC7, + 'N': 0xC8, + 'O': 0xC9, + 'P': 0xCA, + 'Q': 0xCB, + 'R': 0xCC, + 'S': 0xCD, + 'T': 0xCE, + 'U': 0xCF, + 'V': 0xD0, + 'W': 0xD1, + 'X': 0xD2, + 'Y': 0xD3, + 'Z': 0xD4, + 'a': 0xD5, + 'b': 0xD6, + 'c': 0xD7, + 'd': 0xD8, + 'e': 0xD9, + 'f': 0xDA, + 'g': 0xDB, + 'h': 0xDC, + 'i': 0xDD, + 'j': 0xDE, + 'k': 0xDF, + 'l': 0xE0, + 'm': 0xE1, + 'n': 0xE2, + 'o': 0xE3, + 'p': 0xE4, + 'q': 0xE5, + 'r': 0xE6, + 's': 0xE7, + 't': 0xE8, + 'u': 0xE9, + 'v': 0xEA, + 'w': 0xEB, + 'x': 0xEC, + 'y': 0xED, + 'z': 0xEE, + '$': 0xFF, +} +charmap_rev = {} +for x, y in charmap.items(): + charmap_rev[y] = x +def translate(str): + d = bytearray() + for x in str: + d.append(charmap[x]) + d.append(0xff) + return d +def translate_rev(bytes): + s = "" + for c in bytes: + if c == 0xff: + break + s += charmap_rev[c] + return s + +class BitstreamReader(): + def __init__(self, bytes, bytesize=8): + self.bytes = bytes + self.bytesize = bytesize + self.pos = 0 + self.bits = 0 + self.value = 0 + + def remaining(self): + if self.pos < len(self.bytes): + return True + if self.bits > 0: + return True + return False + + def read(self, count): + while self.bits < count: + if self.pos >= len(self.bytes): + break + self.value |= (self.bytes[self.pos] & ((1 << self.bytesize) - 1)) << self.bits + self.bits += self.bytesize + self.pos += 1 + + ret = self.value & ((1 << count) - 1) + self.value >>= count + self.bits -= count + return ret + +def bitpack(code, origbits, destbits): + newcode = [] + reader = BitstreamReader(code, origbits) + while reader.remaining(): + newcode.append(reader.read(destbits)) + return newcode + +def ror(val, bits): + return val >> bits | ((val << (32 - bits)) & (2 ** 32 - 1)) + +class Client: + def __init__(self, user, pwd): + self.token = None + self.uid = None + self.login(user, pwd) + + def makereq(self, endpoint, *args, **kwargs): + req = Request("https://fools2022.online/%s" % endpoint, *args, **kwargs) + req.add_header("User-Agent", "fools2022-client/1.1.0") + req.add_header("Content-Type", "application/x-www-form-urlencoded") + req.add_header("Accept-Encoding", "identity") + if self.token: + req.add_header("X-Foolssessiontoken", self.token) + return req + + def makepkt(self, cmd, data): + data = bitpack(data, 8, 32) + rnd = randrange(256) + + pkt = [rnd << 8 | cmd] + data + + magic = 0xf0dbeb15 + for x in pkt: + magic = ror(magic, 5) + magic ^= x + magic += x * 2 + pkt[0] = (magic & (2**16-1)) << 16 | pkt[0] + pkt = b64encode(bytes(bitpack(pkt, 32, 8))) + return self.makereq("packet/%s" % self.uid, data=pkt) + + def login(self, user, pwd): + data = {"u": user, "p": pwd} + data = json.dumps(data).encode() + req = self.makereq("login", data=data) + res = json.loads(urlopen(req).read().decode()) + self.token = res["data"]["session"] + self.uid = res["data"]["uid"] + + def getmap(self, mapid, pos=(0,0)): + data = [mapid >> 0, mapid >> 8, pos[0], pos[1]] + req = self.makepkt(0x01, data) + rev = b64decode(urlopen(req).read().decode()) + print(hexlify(rev).decode()) + return rev + + def trendset(self, text): + data = bytearray() + for i, x in enumerate(text): + data.append(x) + data.append(0xff) + req = self.makepkt(0x04, data) + rev = b64decode(urlopen(req).read().decode()).decode() + print(rev) + + def cave3(self, text): + data = bytearray(unhexlify("ffffffffffffffffffff")) + for i, x in enumerate(text): + data[i] = x + req = self.makepkt(0x06, data) + print(urlopen(req).read().decode()) + + def cave4gen(self, text): + data = bytearray() + for i, x in enumerate(text): + data.append(ord(x)) + data.append(0xff) + req = self.makepkt(0x07, data) + rev = b64decode(urlopen(req).read().decode())[:-1].decode() + print(rev) + + def cave4chk(self, cert): + data = cert.encode() + b"\xff" + req = self.makepkt(0x08, data) + rev = b64decode(urlopen(req).read().decode()) + print(rev) + rev = rev[4:-1] + for x in range(0, len(rev), 16): + print(rev[x:x+16]) + + def lotto(self): + data = b"" + req = self.makepkt(0x05, data) + rev = b64decode(urlopen(req).read().decode()) + print(hexlify(rev).decode()) + + def complete(self): + data = bytearray(unhexlify("ef7fffff7fe0ffff000000000000000000000000000000000000000000000000")) + data = bytearray(unhexlify("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) + req = self.makepkt(0x02, data) + rev = b64decode(urlopen(req).read().decode()).decode() + print(rev) + +maps = [ + 0x0000, + 0x0100, + 0x0110, + 0x0210, + 0x0327, + 0x0364, + 0x043A, + 0x0523, + 0x0565, + 0x0566, + 0x062F, + 0x0667, + 0x0668, + 0x0669, + 0x066A, + 0x0734, + 0x0824, + 0x0932, + 0x096B, + 0x098A, + 0x0A32, + 0x0B2D, + 0x0C2C, + 0x0D3E, + 0x0E3C, + 0x0E6C, + 0x0F3B, + 0x103B, + 0x106D, + 0x113D, + 0x116E, + 0x123D, + 0x1321, + 0x1337, + 0x1432, + 0x146F, + 0x152D, + 0x1631, + 0x1639, + 0x1670, + 0x1671, + 0x1672, + 0x1720, + 0x1730, + 0x1731, + 0x1732, + 0x182A, + 0x1927, + 0x1A3C, + 0x1A73, + 0x1B37, + 0x1C2C, + 0x1D3B, + 0x1E33, + 0x1E92, + 0x1F3A, + 0x1F79, + 0x1F7A, + 0x2001, + 0x202F, + 0x207B, + 0x2125, + 0x2174, + 0x223A, + 0x2275, + 0x2276, + 0x2277, + 0x232D, + 0x2435, + 0x2478, + 0x2536, + 0x2632, + 0x2725, + 0x2731, + 0x2791, + 0x2833, + 0x2939, + 0x2B29, + 0x2B7C, + 0x2B7D, + 0x2B7E, + 0x2C29, + 0x2D27, + 0x2E2B, + 0x2F38, + 0x2F7F, + 0x2F80, + 0x2F81, + 0x302C, + 0x3120, + 0x318B, + 0x318C, + 0x318D, + 0x318E, + 0x318F, + 0x3190, + 0x3191, + 0x323F, + 0x3336, + 0x3420, + 0x3482, + 0x353C, + 0x3621, + 0x3724, + 0x3828, + 0x3920, + 0x3A3E, + 0x3B22, + 0x3B30, + 0x3B31, + 0x3B32, + 0x3C36, + 0x3D20, + 0x3D83, + 0x3E31, + 0x3E90, + 0x3F3D, + 0x4026, + 0x412E, + 0x423A, + 0x432A, + 0x4384, + 0x4430, + 0x4528, + 0x4530, + 0x4585, + 0x472B, + 0x4786, + 0x4787, + 0x4788, + 0x482B, + 0x4889, + 0x4933, + 0x4A34, + 0x4B3A, + 0x4C21, + 0x4C93, + 0x4D3A, + 0x4E22, + 0x4F21, + 0x506F, + 0x5133, + 0x5134, + 0x5135, + 0x5136, + 0x5137, + 0x5160, + 0x5211, +] +maps_skip = [ + # YEET maps (not always accessible) + 0x5133, + 0x5134, + 0x5135, + 0x5136, + 0x5137, + 0x5160 +] + +if __name__ == "__main__": + from time import sleep + from sys import argv + + c = Client(open(".user").read().strip(), open(".pass").read().strip()) + sleep(1) + if argv[1] == "map": + c.getmap(int(argv[2], 0)) + if argv[1] == "maps": + fun_map = c.getmap(0x1670) + fun_value = int(translate_rev(fun_map[0x25b:0x260])) + print("Fun value:", fun_value) + fdir = "maps_%03d" % fun_value + if not isdir(fdir): + mkdir(fdir) + sleep(1) + + # fdir = "maps" + # for x in range(0x10000): + for x in maps: + fname = "%s/%04X.map" % (fdir, x) + if isfile(fname): + continue + if x in maps_skip: + continue + print("Getting map %s..." % fname) + m = c.getmap(x) + open(fname, "wb").write(m) + sleep(1) + if argv[1] == "trend": + c.trendset(translate(argv[2])) + if argv[1] == "cave3": + c.cave3(translate(argv[2])) + if argv[1] == "cave4gen": + c.cave4gen(argv[2]) + if argv[1] == "cave4chk": + c.cave4chk(argv[2]) + if argv[1] == "complete": + c.getmap(int(argv[2], 0)) + sleep(1) + c.complete() + if argv[1] == "lotto": + c.lotto() + if argv[1] == "yeet": + game_corner_map = c.getmap(0x1A73) + sleep(1) + yeet_map_id = game_corner_map[0x8B0] << 0 + yeet_map_id |= game_corner_map[0x8B1] << 8 + yeet_map = c.getmap(yeet_map_id) + game_corner_map_fname = "maps_changing/1A73_%04X.map" % yeet_map_id + if not isfile(game_corner_map_fname): + open(game_corner_map_fname, "wb").write(game_corner_map) + yeet_map_fname = "maps/%04X.map" % yeet_map_id + if not isfile(yeet_map_fname): + open(yeet_map_fname, "wb").write(yeet_map) + sleep(1) + results_map = c.getmap(0x5160) + results_map_fname = "maps_changing/5160_%d.map" % time() + open(results_map_fname, "wb").write(results_map) + if argv[1] == "funroll": + fun_map = c.getmap(0x472b, (15, 10)) + if argv[1] == "funcheck": + fun_map = c.getmap(0x1670) + fun_value = int(translate_rev(fun_map[0x25b:0x260])) + print(fun_value) diff --git a/definitely-not-suspicious.mp4 b/definitely-not-suspicious.mp4 new file mode 100644 index 0000000..adcb793 Binary files /dev/null and b/definitely-not-suspicious.mp4 differ diff --git a/definitely-not-suspicious.png b/definitely-not-suspicious.png new file mode 100644 index 0000000..bcf9d5f Binary files /dev/null and b/definitely-not-suspicious.png differ diff --git a/disasm_script.py b/disasm_script.py new file mode 100644 index 0000000..b453362 --- /dev/null +++ b/disasm_script.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 + +file = open("cave5.map", "rb").read() + +def read_byte(): + global offset + val = file[offset + 0] + offset += 1 + return val + +def read_half(): + global offset + val = file[offset + 0] << 0 + val |= file[offset + 1] << 8 + offset += 2 + return val + +def read_word(): + global offset + val = file[offset + 0] << 0 + val |= file[offset + 1] << 8 + val |= file[offset + 2] << 16 + val |= file[offset + 3] << 24 + offset += 4 + return val + +def dump_loadword(): + dest = read_byte() + value = read_word() + print("loadword %d, 0x%08x" % (dest, value)) + +def dump_callstd(): + func = read_byte() + print("callstd %d" % func) + +def dump_call(): + dest = read_word() + print("call 0x%08x" % dest) + +def dump_callnative(): + dest = read_word() + print("callnative 0x%08x" % dest) + +def dump_compare_var_to_value(): + var = read_half() + value = read_half() + print("compare_var_to_value %d, %d" % (var, value)) + +def dump_goto_if(): + cond = read_byte() + dest = read_word() + print("goto_if %d, 0x%08x" % (cond, dest)) + +def dump_playse(): + song = read_half() + print("playse %d" % song) + +def dump_setvar(): + var = read_half() + val = read_half() + print("setvar %d, %d" % (var, val)) + +def dump_loadbytefromptr(): + var = read_byte() + source = read_word() + print("loadbytefromptr %d, 0x%08x" % (var, source)) + +def dump_setptrbyte(): + var = read_byte() + dest = read_word() + print("setptrbyte %d, 0x%08x" % (var, dest)) + +def dump_addvar(): + var = read_half() + val = read_half() + print("addvar %d, %d" % (var, val)) + +def dump_subvar(): + var = read_half() + val = read_half() + print("subvar %d, %d" % (var, val)) + +def dump_copyvar(): + var = read_half() + val = read_half() + print("copyvar %d, %d" % (var, val)) + +def dump_checkflag(): + flag = read_half() + print("checkflag %d" % flag) + +def dump_delay(): + frames = read_half() + print("delay %d" % frames) + +def dump_message(): + text = read_word() + print("message 0x%08x" % text) + +def dump_setflag(): + flag = read_half() + print("setflag %d" % flag) + +def dump_playfanfare(): + song = read_half() + print("playfanfare %d" % song) + +cmds = { + 0x02: "end", + 0x03: "return", + 0x04: dump_call, + 0x06: dump_goto_if, + 0x09: dump_callstd, + 0x0f: dump_loadword, + 0x12: dump_loadbytefromptr, + 0x13: dump_setptrbyte, + 0x16: dump_setvar, + 0x17: dump_addvar, + 0x18: dump_subvar, + 0x19: dump_copyvar, + 0x21: dump_compare_var_to_value, + 0x23: dump_callnative, + 0x27: "waitstate", + 0x28: dump_delay, + 0x29: dump_setflag, + 0x2b: dump_checkflag, + 0x2f: dump_playse, + 0x31: dump_playfanfare, + 0x32: "waitfanfare", + 0x5a: "faceplayer", + 0x66: "waitmessage", + 0x67: dump_message, + 0x68: "closemessage", + 0x6a: "lock", + 0x6c: "release" +} + +def dump(): + global offset + while True: + cmd = file[offset] + if cmd not in cmds: + print("Unknown cmd: %02x" % cmd) + return + print("%08x: " % (offset - base_rel + base), end="") + offset += 1 + ex = cmds[cmd] + if isinstance(ex, str): + print(ex) + else: + ex() + if cmd == 0x02 or cmd == 0x03: + return + +base = 0x02018213 +base_rel = 0x213 +offset = (0x02018213 - base) + base_rel +dump() diff --git a/dumpallfun.sh b/dumpallfun.sh new file mode 100755 index 0000000..598109b --- /dev/null +++ b/dumpallfun.sh @@ -0,0 +1,7 @@ +#!/bin/sh +while sleep 1; do + while sleep 1; do + ./client.py maps && break + done + ./client.py funroll +done diff --git a/forward.py b/forward.py new file mode 100644 index 0000000..f968f32 --- /dev/null +++ b/forward.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 + +from urllib.request import urlopen, build_opener, install_opener, Request, BaseHandler +from http.server import BaseHTTPRequestHandler, HTTPServer +from base64 import b64decode, b64encode +from binascii import hexlify, unhexlify + +host = "localhost" +port = 80 + +class HTTPErrorIgnore(BaseHandler): + def http_response(self, request, response): + return response +install_opener(build_opener(HTTPErrorIgnore)) + +class Server(BaseHTTPRequestHandler): + def do_GET(self): + print(self.path) + print(self.headers) + self.send_response(200) + self.end_headers() + + def do_POST(self): + path = self.path + if path.startswith("////////"): + path = path[8:] + + print(path) + print(self.headers) + body = self.rfile.read(int(self.headers.get("Content-Length"))) + if path != "/login": + data = bytearray(b64decode(body)) + # if data[0] == 4: + # text = unhexlify("C8BFD0BFCC00C1C9C8C8BB00C1C3D0BF00D3C9CF00CFCAFF") + # for i, x in enumerate(text): + # data[4+i] = x + + # new = bytearray(unhexlify("02fad7c9ef7ffff76fa0ffff000000000000000000000000000000000000000000000000")) + # new[1] = data[1] + # new[2] = data[2] + # new[3] = data[3] + # data = new + + # data[4] = 0x00 + # data[5] = 0x00 + # data[6] = 0x00 + # data[7] = 0x00 + print(hexlify(data).decode()) + body = b64encode(data) + print(body) + + print("====") + r = Request("https://fools2022.online" + path, data=body) + for header in self.headers: + r.add_header(header, self.headers.get(header)) + req = urlopen(r) + res = req.read() + # print(req.code) + print(req.headers) + print(res) + print() + + self.send_response(req.code) + for header in req.headers: + if header == "Transfer-Encoding": + continue + self.send_header(header, req.headers.get(header)) + self.end_headers() + self.wfile.write(res) + +if __name__ == "__main__": + server = HTTPServer((host, port), Server) + server.serve_forever() diff --git a/gbasio.txt b/gbasio.txt new file mode 100644 index 0000000..c9cf857 --- /dev/null +++ b/gbasio.txt @@ -0,0 +1,3 @@ +Port: + Clock: 49420 + Data: 54970 diff --git a/gold.cert b/gold.cert new file mode 100644 index 0000000..d03a785 --- /dev/null +++ b/gold.cert @@ -0,0 +1 @@ +!2'\K.k02(pt@Q6vc&I@$PByLƇYbrZO=EDh)ԡ \ No newline at end of file diff --git a/map.py b/map.py new file mode 100755 index 0000000..2a1d2a8 --- /dev/null +++ b/map.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 + +from client import translate_rev +from struct import unpack_from + +class Map: + def __init__(self, fname): + self.map = open(fname, "rb").read() + self.baseaddr = 0x02018000 + + def getoffs(self, pos): + return unpack_from("