Reverse Engineering
Last updated
Last updated
Hello, dear bruh. Do you know that once upon a time there were cute small Ebins walking around the planet? And with the each day passed they evolved, mastered something new... And of course... They were breeding... They were becoming more and more perfect... The Ebins developed their own languages... And even philosophy... The Ebins wrote and listened to music... And of course they danced to it... And they applauded to each other... The Ebins went so far in their brogress that they invented anime... But after... The snakes came up to something terrible...
Given PE32+ file, open it using IDA.
Look at the Strings tab, it looks like executable compiled with pyinstaller.
Using this script we can extract the pyc files and all of its dependencies.
Now, look at main.pyc which is the main code of the executable. Use pycdc to decompile the pyc to py file.
Although the pyc file has been decompiled, the code still obfuscated. Lets dive to the first obfusction
F = type(f)
C = type(f.__code__)
...
xD = F(C(1, 0, 0, 1, 6, 3, b'd\x01\x89\x00d\x02\xa0\x00\x87\x00\x87\x01f\x02d\x03d\x04\x84\x08t\x01t\x02\x88\x01\x83\x01\x83\x01D\x00\x83\x01\xa1\x01S\x00', (None, 0x2D362C9293C223BBL, '', C(1, 0, 0, 2, 10, 19, b'g\x00|\x00]&}\x01t\x00\x88\x01|\x01\x19\x00d\x00\x18\x00\x88\x00d\x01|\x01t\x01\x88\x00\xa0\x02\xa1\x00d\x02\x1b\x00\x83\x01\x16\x00d\x03\x14\x00>\x00@\x00|\x01t\x01\x88\x00\xa0\x02\xa1\x00d\x02\x1b\x00\x83\x01\x16\x00d\x03\x14\x00?\x00A\x00\x83\x01\x91\x02q\x02S\x00', (1, 255, 8, 8), ('chr', 'ceil', 'bit_length'), ('.0', 'i'), '0', '0', 11, b'', ('magic', 'self'), ()), 'str.<locals>.<listcomp>'), ('join', 'range', 'len'), ('self',), '0', '0', 4, b'\x00\x01\x04\x01', (), ('magic', 'self')), globals())
...
Actually the decompiler is not purely decompile the pyc file, there are some wrong code in the decompiled version. To defeat this, we can actually debug the python in "executable". To do that, i use pyinjector. So the idea is using pyinjector to dump the opcode then manually convert it back to python code.
run the executable (ebin.exe)
put code.py in the same directory with the executable (ebin.exe)
open process hacker
find ebin.exe -> right click -> miscellaneous -> Inject DLL
Choose PyInjector_x64.dll
import dis
dis.dis(xD)
For the xD function, it looks like string obfuscation and not related to input validation. So for the xD we can defeat it by running the xD function for all obfuscated strings. I use regex and sublime to get all the argument for xD function.
xD\((.*?)\)
import dis
print(xD(b'\xe9c\x92\xe9'))
print(xD(b'\xc7'))
print(xD(b'\xdaK\xa6'))
print(xD(b'\xd8K\xb7\xe8\xffJ'))
print(xD(b'\xda[\xb7\xf7\xfe_SI\xca'))
print(xD(b'\xda[\xb7\xf7\xf4_EM\xc3'))
print(xD(b'\xc9T\xa4\xe2\xf7J'))
print(xD(b'\xd0M\x9e\xf2\xecYT_'))
print(xD(b'\xcaC\xad\xf5\xf8'))
print(xD(b'\xd8G\xad'))
print(xD(b'\xd3N\xb7'))
print(xD(b'\xdeR\xae\xff\xceOPZ\xdfQ'))
print(xD(b'\xd8K\xb7\xe8\xffJ'))
print(xD(b'\xda[\xb7\xf7\xfe_SI\xca'))
print(xD(b'\xda[\xb7\xf7\xf4_EM\xc3'))
print(xD(b'\xc9T\xae\xf8\xe1D'))
print(xD(b'\xd0M\x9e\xf2\xecYT_'))
print(xD(b'\xcaC\xad\xf5\xf8'))
print(xD(b'\xd8G\xad'))
print(xD(b'\xd3N\xb7'))
print(xD(b'\xdeR\xae\xff\xceOPZ\xdfQ'))
print(xD(b'\xd9X\xbc\xe4\xf8`'))
print(xD(b'\xcdK\xad\xf8\xffA'))
print(xD(b'\xd1G\xb1\xfe\xf8A\x06 '))
print(xD(b'\xeeK\xb1\xe8\xe8N[~\xcaM\xb7\xf7\xf2Y'))
print(xD(b'\xdaR\xae\xe8\xfbJE'))
print(xD(b'\xdaR\xae\xe8\xfbJE'))
Now, replace all obfuscated strings with deobfuscated string.
# Source Generated with Decompyle++
# File: main.pyc (Python 3.10)
Warning: Stack history is not empty!
Warning: block stack is not empty!
import ctypes
import os
from math import ceil
def f():
pass
F = type(f)
C = type(f.__code__)
class EbinException(Exception):
pass
no_clean_pops = []
gondola = [
166,
495,
403]
ebor = b'\xe9\x9a\x00\x00\x00\xe3q\x98\x9e\tt\x89\xe6\xbe\xce\x89R\x1egb\n\na\xaa\x0c\xe1\xe2\x10\xa1\x02\xba2\xc7[\xd9W\xbcqk\x82\xf8\xda\xdb\x01\xed\x1f\xc6\xb3\xd3W\xf8\xab.\x94\xe7,)\x89\xfb\xe8\x9dA\xb7\x926c\xb3\xc5\xd5\x83\xfd#\xef\xc4\x92\x18 p\xee:\xe9\xb9\xc1x\xc3\xce\xb9\xcah}\xf5\xe3\xb8\xee\xe9-\xaf\xe0I#\x1e\x9c\x95 M\xe7h\xa5\xbb\x99*\xc9\xc3\x939\xd6\xa5\x1d\xdeT\xfd\xdcl\xfam\x04\xc4i\x96\xca?\xa0\n}\r\xa38\x98\xe5\xf9 \x8b\xc5\x1b\x15\x08\x88\xb2\x1bE\x91\xc2\x1d\xa5\xbe<\xd0\x8b\x97\x89T$\x10H\x89L$\x08UWH\x81\xecH\x01\x00\x00H\x8b\xecH\x8b\x85`\x01\x00\x00H\x83\xc0#H\x89E\x08\xb8\x01\x00\x00\x00Hk\xc0\x16H\x8b\x8d`\x01\x00\x00\x0f\xbe\x04\x01\xc1\xe0\x08H\x98H\x8b\x8d`\x01\x00\x00H\x8dD\x01\x19\xb9\x01\x00\x00\x00Hk\xc9\x15H\x8b\x95`\x01\x00\x00H\x0f\xbe\x0c\nH\x03\xc1H\x89E(\xc7ED\x00\x00\x00\x00\xeb\x08\x8bED\xff\xc0\x89EDHcEDH\x8bM\x08\x0f\xbe\x04\x01\x85\xc0t\x02\xeb\xe6\xc7Ed\x00\x00\x00\x00\xeb\x08\x8bEd\xff\xc0\x89Ed\x8b\x85h\x01\x00\x009Ed}>HcEdH\x89\x858\x01\x00\x00\x8bEd\x99\xf7}D\x8b\xc2H\x98H\x8bM\x08\x0f\xbe\x04\x01H\x8bM(H\x8b\x958\x01\x00\x00\x0f\xbe\x0c\x113\xc8\x8b\xc1HcMdH\x8bU(\x88\x04\n\xeb\xafH\x8d\xa5H\x01\x00\x00_]\xc3\xcc\xcc\xcc\xcc\xf5\xc5\xbf\xdb\xb0I\xf8\xaa\xb0\xd2 |-\x9e\x8b\x99\xb7\xee\x10\xe5\xcf;\xb0\x8f\xa2B\xf0\xfd\xd9\x10*0\xf6\x10\x99t\xb1\x83&_Wx\xd7\xcdr\'H\x0c\xc3\xf8\x98Z\xfa\xd1E\xbdnJ\xce\xc4\tC\xa8\xafo\xc7\xd2\xe2\xc7\x18\xfb\x8dt\xbae\xfd\n\xb67;$@\xb0%\x8e\x02{\x94\x98"1\xa1\x80\xc9\x1aC|\xd2\x82\xb4:\xe4\xe2L\xf3\xe0\xc3\xf6\xaa\xa2*\xad}\x9f;\x8a\xc1\xd0\xa9\xfcq\x02U\xb5\x97\x18\x9d\xa79\xc0\x17\xb0\xa4\x11^\xec[d\x13\xf86\xe5\xd0\x96{1\xbf\x83\x0b\x80\xcd\xcb\xe0\xbb\x8b=\xa4Y\x9c\xab\xb8\xb5p\xf8\x1d\xc3oo\xf5*\x9c\xbf\xd0"\xe1J\xba\xdehn\xb1\xf5D\xec_90\xbds&y\x00\xdbK\xe3Mw\x7f[:\x9a\x9f\xe6I\x13\x88*\x98\xeb\xdd\x1e\xa2]\xd6\x07q\xff\x9d\xd9\x1c\xf8\xc5\xf9Gs\xc9\x92\x88\x82\xe9]\xe6+d&p\xf4\xf3\xd6\xf3\xf8\x07\x89?>\x9a-\xa4\x13\xb7l\xd0\xa3\x98\xeaQ\x9b\x07\\\xcepo\x94\x07\xceF\x10\xa9\xb2\x89\xdcD:-I\xd4v>l\xffr\xd4\xa6\x98N\x94.D\x84\xcd\xbaI\xbc c8\xe9\xab\x18\xab\x17rg\xc5\x0fc\xcb\x9d\xe8s\xa9\xb3\xddd\x92\xbb%\x94\xdc\x19\xb3\xed\n\x82\x00\xb4J\xc3x\xe5\xb78)\xc7\x9d\x7f\xe0h\x95\x14:\x0c\x1d\xd7\xd4\xf3?V\x0e\'=\xfc\xfa2\x85\x95\xcf\xdc;\xd4\xcb\xc8\xc3\xfb\x1a\tE\x94x\x9aC@\x1d\x92\xe7\xbc\xabd!\xe98?\x04\x15\xba\x00\x14\x1f\x0f\xf9\xbb\xc0\x87\xd3FV\xd1\x8cMC\xbb\xbe\xbd\x9f}\x05\x8b\x9b\x9c=/\xee\xb6\x12\x07iL\xb8\x05\tp\x8d\xae\x97\xfcgb\xeae\xde\xa2>\x8a\x13\xc0\xf7\'\xa4\xce&\xb9\x88\xcf(.\xbbO\xdc\xae\xb27T9Y\r\x02\xec\xec\x91\xc0Z\xea\xe4{\xf9\xc6|\xe1\xd3>C\xef\n;\xd77\x0e\x9bJ?\x96\xc0\xec\xc6\xa7W\x87\x86\xda\xfd\xcf\x8c\xe3\xdc\xb3HU\x1c\x1cO\xa5~/\xad\x8c}\xc14\x96\x0e\x1c.q\xd3\x1d4\xc6\x9c\x94\xe6P\x12$\xc5\x9eL)\x82\x14\xebG72\xb6D\xe9\x1dj\xe1\xf9b\xaf;\xff\xf8\x84\x91\xa5\xbc\xb7\xce\x8erh\x1a\xa6\x03\x9de#\xdb\xa3\x9am\xe4O/\xc1V8\xfeK\xc9:\xf6\x0e#\x90\x90\xbf\x82\xc7\xc4]\x0f\x1f\x92\x03\xf4^\xd0\xa98\x98\xdd\xcb\xea\xa9B\xa7\xcd\xca\xee\xdf\xf9\xff\x9c\x87_H\xcfc \xf6\xaer\xc1l\x0b\x06\xc7\x11nL\xf7'
xD = F(C(1, 0, 0, 1, 6, 3, b'd\x01\x89\x00d\x02\xa0\x00\x87\x00\x87\x01f\x02d\x03d\x04\x84\x08t\x01t\x02\x88\x01\x83\x01\x83\x01D\x00\x83\x01\xa1\x01S\x00', (None, 0x2D362C9293C223BBL, '', C(1, 0, 0, 2, 10, 19, b'g\x00|\x00]&}\x01t\x00\x88\x01|\x01\x19\x00d\x00\x18\x00\x88\x00d\x01|\x01t\x01\x88\x00\xa0\x02\xa1\x00d\x02\x1b\x00\x83\x01\x16\x00d\x03\x14\x00>\x00@\x00|\x01t\x01\x88\x00\xa0\x02\xa1\x00d\x02\x1b\x00\x83\x01\x16\x00d\x03\x14\x00?\x00A\x00\x83\x01\x91\x02q\x02S\x00', (1, 255, 8, 8), ('chr', 'ceil', 'bit_length'), ('.0', 'i'), '0', '0', 11, b'', ('magic', 'self'), ()), 'str.<locals>.<listcomp>'), ('join', 'range', 'len'), ('self',), '0', '0', 4, b'\x00\x01\x04\x01', (), ('magic', 'self')), globals())
aggept = F(C(1, 0, 0, 1, 3, 67, b't\x00|\x00\x83\x01d\x01k\x02o\x13|\x00d\x00d\x02\x85\x02\x19\x00d\x03k\x02o\x13|\x00d\x04\x19\x00d\x05k\x02S\x00', (None, 29, 4, 'SAS{', -1, '}'), ('len',), ('a',), '0', '0', 9, b'\x00\x01', (), ()), globals())
ebonatti = b'\x8b!r\xe8\xde\xecz\xbf\x02\xa3Bw\xae\x94\xe2\xddR.\xb2\xb2\xe9w\x00\x00\x00fnk~\xb7U\x9bh\x8bDHb\xc8t*\x80J\x90\x00\xcaF\xacYO\xfa\xfc\xc5>\xe3\xf6X\xef\xad\xc5|\x04\xd5\x94l\xd0o\x1fr\xdb\xa8+\xcc\x83\xff\xaaV\x12\xaf\xd55\x86\xbfkm\xd8\xce\xf3\xf2xL1\xd3\xfea\xfb\x08\x92\xe6\x8c\xf4\x94\xd8\tb\xfb\x13}\xdf\xf8\xfc\xedQ\\4n\xc1\x86\xfc\x0f\x11\xee\x9e\xca<\x1c\xa2c\x9e3\xdeI\x11!\x99b\xb2=k\x9a\x88B\xe3j\xd5\x00\xeb\x84P"\xd5\x1d\xd8\xc9\x8e\x80u*\x80\x02\x1b\xa4\xa5\x8dp+\x80J\x90\x8f\'\xecv*\x80JW\r&\xc8t*\x80\x8d\xd5,b\xc8t*kB\x1b\r\x067\xb4\xa3\xc5.\x135\x06\xd1\tu\x0b\x0f\x94\xc1\'\x8c\xffo\xa4\xc3\xd5L\xe9\x8d0\xa1\xcdn\x93\x80\xe9\t\xfdo\xa4\xc1\xd5,\xfbK\x96-\x83\x88\x13\xa8e\xe3\xb6b\x18\x02\x1b\xc5\x02\xc9t*\x8f\xf4\x94IQ\x8dP\xa3\x05~\x91HbC1N\x19\xc9rOa\n\xf7\xca\x87aR\x00\xfa\x80\xff\xa7\xe0K\x90H\xe9]@+\x80J\x18\\c#\xe7b\r\xef\xd8Ib\xc8+wC\t\xb6}f\xdd\x8bH\x89\x8f%\xc1\xea\xf3\xd2\xb6\xe1}!`\x14\x86Fx\xe0\xe3<Y\xb47\xf7\xe8\xaa\xd42\x86\xa1`\xdcm\xec\x19\xdf\xef\x179^pe\xc0\xe2Oh\xe1/\xbc\xea\xb7\x9b\xeb.I~2\x10\xc3!5\xc0\x13G%\xba\xe0\xfd\x1e\xe5\xe6\xfe-\xed~p\xe5\x9f\xd5\xdf\xd9e\xaba\xec\xc2\xd2B\xaaQ\x15\x8b\x98\xee<\x07*\xea\xec5F\'\xb4\xa1S\x1c\xc7\t?\xf0K\xbf\x12\xd4Zq\xa3\t\x1e\x92\xd4\xbe\xc9\x0b\x87v\x86@J\x1an\xdaV\x19 w\xe1tZ\x90T4 (Qf\x9f.\xfdH\x0f\xe64\x80Su\xe5sC.C\x84\t-\xe9\x94\xa0\xce\xa0xcZ:\xa9\x96\x04\xfc\xd4\x19{\x16WQ\xc267:J\xcfX\t\xbd\x87\x94\xe1k\x020|S@\xb1x\rE\x9e\x9b\x03\x97\xd5\xf8\x90\xd8;\x9a\xd0\x82)G*t\x89\x98\xee\xb4#\xc3\xfa\x9b\xc7N\xa4\xb5=\xcau\xc7-\xa1\xd7\x19\xfd\xa1uL\x02$\xb3\xdc}\x83Da\xf7\xb1S*\xb3?1\x1f\x95?\xa2\xeaK\xe4{\x0f"j\xdb\xf0\x88\x97\xd1S\xe6A5<\n\xa5C\x984!U\xc5\x82\xc5\xd0:r\xd3\x80ur+\xe1U\xb4\xe2\x1d\xc5UA&\x0f\xc9:[\x8f\xee\x04\x00\x9a>)\x86\xe8\x94\xc91\x96\xdb\x87\xbd\xe8Un\xd2\xe1P\xaf\xd6\xac\x10\xbd\x9e\x98\xb0*z\xa4\xbfB7!@1X\xe7\xd6\xce\xd1\x9e\x05v\xfd\x8dWy\x9b(?^w:-\xa0,Ep\xa80\t\xd5\x08\x98rb\xa7O\xa0\xab/\xff\xfe\x9eu\xb24O\xb3\x06=\xdc\xb1K\xf8}\xa8e\x12.>\xe9_:q4z\x0f\xaee\xac&D\xa1\xed\xf1W\x1d\xe9\xab\x86\xc4u\x90\xe2~\xd3%A\xc4\xdb\x06]\xe6\xcec\xb4\xdex\xa3#\x81\xe8t\x99\xb8A\xa0\xfb:\xa6u2\x1e\xab\x8c\x98f\x04P\x9e)\x9c\x8a\xae\xee\xdd\x0f\xcc6\xe9n\x1eeB^e\xc5O\xc6_\x10o\xf6/I\x98R\xae7S\xf2\xf4w=p\xa0\xe8\x84#RK\xb8V]\xf5U\xc5\x95\x8b\xd5VP\xf9\xe1\xef\xde\xc0{\xee\xd3\x85\x9a\n*\xc7\x8c\x1d\x1a\xf8\xce\xa2\xcc\xe1?\x90\x7fmt\xfe\xf8\x91t\x18\x13\xbd\x1d\x0eJ\x99^\xdb\r\x88\x81\x04\xdesk\xf3\xe8\xfdAL\xeas\x13I\xee\xe3)3V`=\x9c\xfd\x81\x96D\n\x81\xe1LZgv\x1fSgH\xaei\xdbf\xb9p\x0c\xa4\xd0\x83e\x9a\xf8\xa0\x04C\xa4\xdc\xa8\x11\x0c\xe3"3\x8d.ArF\xda3c-|\xf9\xda\x96\xa4\xf0\x9e\xe7G\xa7\xb8>|\xea\x7f5\xb3\xfb\x81t\x945\xf6d8\x88\xd0\x06y\x08\xf0\xc5\xd9\x04(L\xe7\x91XL\x8cK\x8e\x03\xb0\x13\xef\xf0g\xe5\xf9\x1d\xa2.\x8b\xc3n2(\'\x94.\xcf\n\x94R7O\x9f\x19:\xda\x96\x94\x86\\\xa3\xea'
eberse_drift = F(C(1, 0, 0, 3, 6, 67, b't\x00|\x00j\x01\xa0\x02d\x01d\x02\xa1\x02\x83\x01}\x01t\x03t\x04|\x01\x83\x01\x83\x01D\x00]\x0e}\x02|\x01|\x02\x05\x00\x19\x00|\x01|\x02\x19\x00d\x03?\x007\x00\x03\x00<\x00q\x0ft\x05j\x06|\x01d\x04d\x05\x8d\x02|\x00_\x01d\x00S\x00', (None, 8, 'big', 5, 'little', ('byteorder',)), ('bytearray', 'sparde', 'to_bytes', 'range', 'len', 'int', 'from_bytes'), ('a', 'b', 'i'), '0', '0', 17, b'\x00\x01\x12\x01\x10\x01\x1a\x01', (), ()), globals())
dibide = F(C(1, 0, 0, 3, 5, 67, b't\x00|\x00j\x01\xa0\x02d\x01d\x02\xa1\x02\x83\x01}\x01t\x03t\x04|\x01\x83\x01\x83\x01D\x00]\n}\x02|\x01|\x02\x05\x00\x19\x00d\x03\x1c\x00\x03\x00<\x00q\x0ft\x05j\x06|\x01d\x02d\x04\x8d\x02|\x00_\x01d\x00S\x00', (None, 8, 'little', 2, ('byteorder',)), ('bytearray', 'spodro', 'to_bytes', 'range', 'len', 'int', 'from_bytes'), ('a', 'b', 'i'), '0', '0', 24, b'\x00\x01\x12\x01\x10\x01\x12\x01', (), ()), globals())
eggbond = b'\xa3\x98\xe7\xe9%\xd6\xad0`\xc0\x84\xcfp \x06\xe0\x10F\xbbE\xe9^\x00\x00\x00vJ\xc0\xe3\xb4\x7f\x9c\x91\xa1\x12\x91\x99\xbd\x0e\x95\x0e\x7f\xc8h\xd6\x93\r\xe8k\xc1 \x00\xeav\xb0\xc5\xd0$\x9b-\xe8\t\x1c\x89\xde\xd7(\x02\x8d1\xb8\x1en$\xfa.tU\xe5j\xd2H\x01\xdbB\x88?\xbc"\xed\xb6\x9d\xf02]u\x9a\xb1\x8a\xae^\xe8\xa4\xad\x05\n}\x05\\\xc6\xdb\xa8\x96\x9b\xcc\x05\xa9W\xd3\xd9\x10\xe9*\x85F\xf6\x84L\xde\xc6Z\xa0\xea-H\x90\x99\xbdF\x1e\xe2\xb8\x8dl\xd6\x93\r\xe8\xac\x84\x04\x91\x99\xbd\x0eRK;\xc8h\xd6\x93\xca\xad\x0f\xc1 \x91\x99\x05\n\x95\x0e\x7f\x80\x03\x16\x93Ec\xe6I!\x91\x99z\n\x94m.)\xdf\x11\xd6I\xe9k\xc1 z\x916K\xd1\xf1\xbfA-\x92\x10p\xacq\xb2\x05\x1a\xdc\xf9\xf1]\x85\xbf\x80\xe3[\x1b\x0c\xe8kJ$\x10\x9c\x04w\xa2\x90\xf4\x85,\x9e\x18\x98`j\xc1 \x18\x9d7\xe5X\xc9:\xach\xd6\x93\rc.\xa5\xa9\xd4\xddz\x8b\x11\x0e\x7f\xc8&\xd6\x93\rc\xeeE \x91\x994\x8b\xc1\x0f\x7f\xc8\xe3S\x17\r\xe8k>\xe8\x18\x1c9\x0e\x95\x0e\xfcu<\xd7\x93\r\xe8\x15\xcd\xe7\x14\xc1\xbc\x0e\x95\x0f\x7f\xc8h=\x99\xcam3\xc0 \x91\x99\xbd\x0e\x95\x8d\xc2\x90i\xd6\x93\r\xe7\xef\xc2!\x91\x996K\xd1F\xf4E\xe0\xd7\x93\rco@#\xd4\x9d\xbeK\xb1\xcf\x9f\xcb\xe3\x9b\xd7Ec\xfeI!\x91\x996\x02\x1f\r2\xcck\x9b\xb7\xcc\x01v\xca\xe1\x18\x1c\xe9\x0f\x95\x0e\xf4\x8d,\x9e\x18\x80`j\xc1 \x1a\x0c\xe9\x0f\x95\x0e\xf6\xdc\xe9]\x16Y\xe9k\xc1\xa9\xd4\x9d6K\xf1F\xf4E\xe8\xd7\x93\rco@#\xd4\x9d\xbeK\xb1\x852\xec\xe3\x83\x97\x0e9\xe0\x0b\xa3p\x86n\xee\x1eC\x1b\x80\xe3C\x13\x0c\xe8kJ,\x1b\x9a\xf0\n\x96C[A\xe5\x82\x92\r\xe8\xe0\x94\x04\xd5\x12\xf8\n\xd1\r\xbd\x89\xe3\x06\x10\xef\xf7*y\x00\x91\x99\xbdJ\xbe\xcc>C\xb8\xd9%\xc7c\xfe\x95!\x91\x99n\xe4\x1e\xc4t\t\xe1S\xcb\x0c\xe8kJe\xf5\xd16\x83\x15\x0f\x7f\xc8\xe3C\xcb\x0c\xe8kH4\x10\x128V\x94\x0e\x7fA-\xf2\x18H\xac\x94\x01\x13C \xa7\x0e\x95\x0e\x889\xe3\x14\x1aH\xac\xe0\x84DnY\x8e\xdc,\n\x7f\xc8h!b\x86*\xe2\x84Dx.C\xf1jF\xf2m\x00\xd7\x93\r\xb76\x02\xd0\xe7I!\xcb\x00\x01\xe9\xba5\x08e\xbc%-\xdf\xe1\xb9\x08f\xcc\x8a\x9f\xc9\xf4\xdd\x8aJb\xd9\xbb\x97\xe3\xba\xfez\xb7i\xa1\xae3\x0f\xe2\x1a\xf3eb#\xa0\x15\x95\x16\x8aw\x9f<\xbeJ\xadl\xcd\x18\xbcX\x00\xb0<M{DD8\x18\xdd2?X\xdd\xf4\xa9\x94#\xe2N\xa4[\xaf\x97\xb0\x83\n=\xf8\xdf+\xee\xb6)\xfbr\x99\xc1\xb36\x0b\x0b\rS\xab\xf5A\xb0\xb2\x90(\xcc\x81Q\x05z\xf9Z\xfc\xae\xf0P7\xf61\xbc\xd7\x8d\xfbQ\x06,\x85c\xcfK]4#\x87\xf7)t\xc9\x93I\xc5\xe9\xdc\x8fF\xd6dMm\x9f\x99\x99\xd7\xa7|\x7f\xe5A\x10g\x9e\xbb)\xf90{\x17\xc34{c\xe03\xfa\xfd\xb12\x97\\\xa1\xc8\xba\xf5#:\xd0\x91J\xd4\xc56)\r\x00\xa4JpGK\x7f\x85m\xf5\x10\xa5\xf6\xa3\xe4D\xf9\xeda\xf0K\xe1\x1bY\xb9oN\x1c)\xff\xdc?\x8a\xb1p\xfflBJ\xe2cwN\x94~\xf8x\xcf\xe1lm\xbfC\xb0\x9f\xcc\x99Fbpw\xad\x16\n\x1cl\x8c\xd3s\x05\x0e@Ts\xbam\x1cV\x1f"\xba\xeb\xa4\xed\xd0\x88E\xd0\xe7:\xde\xd1\xa8;\xaf\xb6\xf8\x06y\xdd\xcb*\xf7\xfd\x06ih4h\xae+O>5\xaf\x07\xc9\x87\xc7\x91\xa8pt\xf32w\xdb\xd8q\xfb2\xa0ky\x85\xc0Y\xd2\x16uC\x04l\x84\x881\xefz\x02\xa5\xda\x87A\xe5$\xb7\xf6\xb13\x02\xdd|\xe21\x9d\x8d\xe9\x85\xd3\xf7\xc1\x00\xf47\xc2E?\x01\xdb\xee\xfc\xe8\x89\xa1\xaa\xd1\x84\xd8<\x9cBV\xc0\xce\xc4,X\x13p\xc0u\xba\xc2\xf9\xab\x80\xd2'
ergipt = b'x\x81\x19\xd8\x17z\x82\xe8\x95\xfd\xef;\xdd\xb0\xb1\x9e(\xee\x8f\t\xe9=\x01\x00\x00\xdb\xf7\x18\x86\xb3\x91*S\x81\x04\x7f\xa8\x9a\xc7&\x9dN\x8e\x00\xda\xcd\xed\xd2gb\x82\x8a>\xba\x9bJ\xa57\x08,$[\xaa\xd6}\xa7^\x16\xfc`\xbd\xcc-\xce\x0b\xa3\x13d%*\xcf\x8d\x1f\x01z\xeb^\xd6I\xa9\xd6\xaa\xf0\xaf\n@\x00\x80\x92\rk\xa0\xb7\x92\x06\xc6\x1e-N\xde\x11\xf0\x0c/H\xd4\xc5\xcb}R\x01\x8bH\xba\xef\xd0B\x11\xea\xc4\x87J\xc4+g\xe3Ul\xcc\x13\x03\x1b\x0b\xf2!V\x8c?\xb7\x0b\xd7UMjU\xa8\x86b\xac\xf1\x10ubZ\x06B4v\xd0\xfdZ1\xf5\x04;\x07#v\xe6@\xd7O\x0b\x93j\x1eX\x92\x84?\x83D\x99\x18\x89\r6\xd5\xee\x8c\xba\nF\xb1\xb3Q\xfc\x85Q\x1ed\x08h\x86_\x04\xf8\x94\x18\x94?\xee]\x08h\xc8`\xa9\x05\xc6&\xce\x18\t#G\x84COV\xe8\xb6\xc8_\x94\xb3\xd5&uQ`[*\xe1\x9a\xe4\x86\x99f]\x98\xdd2\xaa0/\x15)\xfd\x8aY9&\x93P8\xfa\x96\xa87\x0f\x97\x8fb\xdf\xe5_%\x0b\xb5\xccA\xbe\xc6\x1dM\xcb\xd5\xb1\xd4Ed\xbfa\xa21\xbc2\xdf&\xa7\x1a\x1c1y\x1b\x07\xb2\xd6|\xd6\xc2\xe9\x02\xa5\xa3_\xbd@\x90+\x96\xefe\xe0\xc5a\x80\x9b\x0e\x8b^7!\xce\xe36\xd5\xc7\xc2[\xa0\xcf\x90n\x1c\xa2\xc6~\xa8\x9a\x8f\xadq\x89\xcb{\xa8\x9a\xc7&vG\x05:\xac\x19\x07$\x14\x0b\x8a\xfc\xd5\x9e\xc3)\x1e\x19\x8f\x7f\xa8\x11\x82"\xd5\xc5\x03\x17\xa9\x9a\xc7\xad\x99\xcf\x07:\x8c\x11\x82"b\x8e\x05\xbf\xe0\x11JN\x9cN\x8e\xf4\xac\x1bNc\xd9\xf6\x8a\x7f\xa8\x9a\x8fM]N\xc6\xf4%\xfa\xc6&\x9d\xc5\x8a~#\xd7\xe3%U\xc5O\xf6\xed\xbe\x7f"\x9dN\x8e7\xc3Z\xc6n\x16\xc3\xee~\xa8\x9aL"\x9c\xc5\xc3;\xabRL\xe7\x14\x0b\xca\xb8\xed\xfe\xc7&\x9dNew#\xdf\xa3\xd9]\xc7\xcb\x1b+\xe7\xa3*\x92\xc3;\x7f\xa8\x9aLc\xd9\xc5\xc3[\x9bRL\xe7\x16\x03\xca\xfcI\x85\x14\xc6\x16\x03\xca\xf4\xfd\xbe\xf4\xf7\x16\x84\x07\xf2\x9c\x9b\xc7&\x16\x1b\xca\xfcJ\x85\x86\x9e\xbdN\x8e\x7f\xec\xb1\x05g\x16\x9e\x81\xc9b\x11R\x12\x9cN\x8e\xacB\x11\r-\\\xc5\xc3{\xabSL\xef\xd5\xc5\x1b\x1f\xa9\x9a\xc7%\x99\xc4\x07:\x8c\x11\x82\x02\x16\x03\xcaL`\x11\x06\xad\xd0j\r\x9e\xb7I\'\xad\xd0j\x05*\xec\xa9\x16\xadW\xc7\x03K\xa9\x9a\xc7\xad\xc8j\r\x9d\xb7\xdb\x7f\x06\x9dN\x8e;\x83X\x86\xadMA8\xb5#\x0f\xf3\'\x9dN]\x95#P\xcc\xe7\x16\x03\x8a\xf2\xe4\x93\xc6\xadT\x06\x05\xea\xc8\x9b\xc7&\x9eJ\x04\xf6\xed\xde.\x1fb\xb1q\xf4\xed\x9e\x8f\xad\x10&\x8f\x7f\xa8\x11\x92\x02\x14Z\x0f\xf4\xed\x9e8\xe6\x16\x8e\xc6\xf4%\xf2\xc6&\x9d\xc5\xdb;!\x8eF\xcf\x0b\xb0q\x80\xe0\x17bn\x9cN\x8e \xf5Y\xb30(\xeeoc\xbb\xbbU\x01MO\x83\x93\xba\x81\xe5\x11.\xf6pc\xf7\xcf\xd6\xddI\x89\xf4\xeb\xb6\xb65\xa6\x12s\xeb\xe1+yv\x1c\xcc\xcc\xcb\xfa\xfd\x9c\xf9\xdbl\xdd\x08f\xc4X\x90\xe7\x83\x0e\r\x89\xb7\x88 \xbe\r\xeb\x0f\xaa\x97\x17\xa299>A\xc1\xb8\xa7\xea\xef\x1dj\xc1\xf7\xc2[,\xf3fh\xc0\xca#[\xae\x12[\r\xf7\xab\x8d\xbcV\x1fg\x13\x85\x0c\'\x08|\xb4\xdfj\xd4\xd9\xb5d\xaa\xec\xfd\x16\xf4\xe6Xm\xa8\xd3))\x1f\x8a((d\xd6\x9fW\xd9t\x05R\x7f\xe7\xad\xc8\xae\xd5\xc7\x0fC\x02\xcb\x03|\xdcP\x9b\xcd\x8e\xd1sa\x89\'\x97[\x00\x0fM\xf0\xcfn\xbfG\x1b\x19k\xc9\xa7W\xf6\xfa\x9c\xa6\xf2Y\xe1#wm.\xfb\x12"\xbf\xc4\x831\x80k:\x87\xcb\xbd\x94<l\x19\x084\xc8Js\xc8\xe9\x85>\x1c\xfeZ\x06 \xd2\x8a\x91\x19\x14\xa6>\xbdb\xd9^\xcc\xc6B[\x0f\x00\x84\x99\xa3\xdd1\xdf\x0b\x97\xb8\xfe\xdd\xe2\xac\xe4k\xc7\xd4\xaef`\xb7x\x06\x14\xac"\xe4+\x1e\x14\x10]\xa6\xe5\t\xa2\t'
def spawn(c, args):
Unsupported argument found for LIST_EXTEND
Unsupported opcode: LIST_TO_TUPLE
buf = ctypes.c_buffer(c)
no_clean_pops.append(buf)
addr = ctypes.addressof(buf)
olt = ctypes.c_ulong()
eval('ctypes').__dict__['windll']['kernel32']['VirtualProtect'](buf, len(c), 64, ctypes.byref(olt))
if 'brother' in globals():
globals()['brother'](addr, gondola[len(no_clean_pops) - 2])
addr += 20
# WARNING: Decompyle incomplete
brother = spawn(ebor, (ctypes.c_int64, ctypes.c_int))
def Ebin():
'''Ebin'''
_fields_ = [
('spurdo', ctypes.c_int64),
('spodro', ctypes.c_int64),
('sparde', ctypes.c_int64)]
Unsupported Node type: 26
Ebin = <NODE:26>(Ebin, 'Ebin', ctypes.Structure)
def show_wisdom():
Unsupported opcode: WITH_EXCEPT_START
with open('gondola.jpg', 'wb') as f:
f.write(b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xdb\x00C\x00\x05\x03\x04\x04\x04\x03\x05\x04\x04\x04\x05\x05\x05\x06\x07\x0c\x08\x07\x07\x07\x07\x0f\x0b\x0b\t\x0c\x11\x0f\x12\x12\x11\x0f\x11\x11\x13\x16\x1c\x17\x13\x14\x1a\x15\x11\x11\x18!\x18\x1a\x1d\x1d\x1f\x1f\x1f\x13\x17"$"\x1e$\x1c\x1e\x1f\x1e\xff\xdb\x00C\x01\x05\x05\x05\x07\x06\x07\x0e\x08\x08\x0e\x1e\x14\x11\x14\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\xff\xc2\x00\x11\x08\x01\xc2\x03 \x03\x01"\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1c\x00\x01\x00\x02\x03\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x07\x04\x06\x08\x03\x02\x01\xff\xc4\x00\x19\x01\x01\x00\x03\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x03\x04\x01\x05\xff\xda\x00\x0c\x03\x01\x00\x02\x10\x03\x10\x00\x00\x01\xb9@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0cc%Xj1\x95\xd1\xa2\xd4>|\xee\xc5\x89\r\xea\xec\xdf\xc7\x87\xe4\'-\x91\x13%\x0b3\xe7\xb5\'V\xe6\xd1\xcc\xdb\xe5\xb9\xed\xd18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe7\xce6\xddC]\x99P~\x9a\xb4-\xdag\xeb\x9b\x1a3\xf8\xf9\xf5Wpp\xfd\xd3b\xee\xcfb\xb5\x9d\x9a\xbb\x91\xd2.v\xc3\xb0y\x8e\xf7\xd7\x87e\x12\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05[\xa4gcQ\xa7\x16:o\x1e\xab\x99\x111\x12\x8c\xef\x86\x9f\xf9m\x16\x1f\xaf\x96\xc3\x92\xdd\'\xc3q\xc2\x9cp\xb2\xb11{l\xab\xe3\xee6|\xe5\xe3c\xddGF\r\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(h\x9d\x8d\x9a\xddgx\xde5\x9f=5F\xf8\xd9\x1b\xe5\x01\xb7~6h\xc5\x8f\x98\xd2\xa3\x1f\xc9\xad\x7f+\x04vH\x9c\x14P\xd3%\x96\xc5I\xc4t\x8e\x9c\x99\x82\xca\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)]BG\xd2\x8d1^\xf9\xca\xafy\xfa#/7\xa3\xaf?\xbf\xd7\x00\x00\x04M\xd1V\xc3_\x9b\xa7^~\x97\xe6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1aV\xe1\xce\\\xef\x84\xa9\x8f\xd0\x0et\x00\x00\x00\x00\x11R\xae\xf2\xd1\xdc\xf9\xd7\xa2\xb6y\xe1\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\r>\x98\x92\xfa\xa3HQ\xa4\x00\x07\x89\xec\x83\x92\xb2\xac\xa1]\xa0\x00\x04m\xb9Z\xe5\xdf\x96\xf9\x17\xe7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x0b5Mq\xa3\xcc\xfc}\xe4\xf4\x022\x00\x044\xbf\xdd\xb4\xdbu]\xf9\x8f\xa3\x1f?\xfaDKe\xdf\xfa!0\x00C\xccb\xca\x17\xb4\xc5ub\xec\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x15\x03)\xf7N\x80\xcf\xa8\x00\x06\x17y\x85|\xe8W\x16\xbc\x01(\xc0P\xbd3QBz\xc3\x0f3.\xe0\xe7@\x02r\xe8\xe7\xee\x81\xdb\xe7\x07x\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005M\xae\x8d\xe3Y\x941\xfa!\xce\x80\x07\x9f\xa4\'Ei\xc9*-\xa0\x00(\x1f\x1bv\x8c\xa7D\xb0\xcf\xa8\x00!:[\x9a\xba3V)!e@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x076\xda\x95\xedWe\x8c\xdb\x00\x01\x1d\x9f\x9be[\x9d\x8cj\xc4\x00\x00({\xe3^\xe2\x9b\xfd\x88\x97\xc7\xe8\x07$\x04M\xefG\xdc\x1aq\xeeb\xda@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x94F|D\xbe]\xa1]\xa0\x0cn\xa3\xfa"\xb8\xb75\xf9\xe1(\x80\x00\x00sL\x96\xdd\xa5\xe7\xd5\xec)\xd0\x06\x05\xc1O\xdc\x1a2nb\xea\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01H]\x9c\xc9\x19Kz\x18\xfd\x00\x00Be[\xf7\xe7\xda\xb3\x0b\xf2\x80\x00\x00\x01\t\xcf\xbd9\xcfP\xb3\xe8d\xdc\x06\x05\xc1O\xdc\x1a2nb\xea\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xb4\xae\xf2\xe1\xa9\xd12\x8b\x94\xa3Hs\xa2#\xbc\x9a\xe8\x1d7r\xd9\xe7\x07@\x00\x00\x00)\x8b\x9e\xb34v>F/H8\xc0\xb8)\xfb\x83FM\xcc]@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x19\xea\x98\xaf%\xbe=q\xef\xc2\xcd9 \xe7X\xbe\xbbe\xd9\xed\xd1\xa3(\x00\x00\x00\x005\xad\x94s,\xb7\x97\xae]\xb8\x98\xb9\xbe\xb1\x94e\xcfO\\7\xe6\xdc\xc5\xb4\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x1f\xcd\xf7\x05]U\xd9\xa36\xc0\x06?Q}![[:\xfc\xf0\x94@\x00\x00\x00\x00\nB.R/>\xaf\xc1N\x8c\x0b\x82\x9f\xb84d\xdc\xc5\xd4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x93\x9cr\xe3%3l\n\xae\x01\x075\xe3m7\xc4\xa1\xa7\x18\x00\x00\x00\x00\x00\x05\x1f\x17\xb7\xe9ti\xf5\x14i\xc0\xb8)\xfb\x83FM\xcc]@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xbe\xb0h.v+8\xc7\xe8\x07:\x04}\xbbOt\x86\xacY\x02\xca\x80\x00\x00\x00\x00\x00 \xf9\xff\x00\xa3y\xc2\xbbf\x86]\xb8\x17\x05?ph\xc9\xb9\x8b\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00sM\xd1I\xd7l\xb0\xcb\xb4\x07\xef\xe7\xc1\'zS\xf7\x06\xdf8;\xc0\x00\x00\x00\x00\x00\x077\xf4\x879\xc2y\x03&\xfc\x1br\xad\xd9\xf4e\xb8E\xd9\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\xda\xc3x\xd4)\xd1\xe83\xea\x01\x81\x9f\x81(\xdb[\xce\x99\xb9\xec\xf3\xc0\x00\x00\x00\x00\x00\x00s\x9fFs\x9c\'\x902ozy\xc7[OJ\x8d8\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)8|\xfc\x1c\xfa\xbf\x05:\x00`g\xe0J7\x06\xe7\xa6n{<\xf0\x00\x00\x00\x00\x00\x00\x1c\xe7\xd1\x9c\xe7\t\xe4\x0c\x9b\xd1\xd21VU\xd3(\xec\xcdX\xbd@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x0c\xccU\xfa\xb4e|\xf8\xd0\xd1\x9c\x95\xdd\x1bR\xfa\xc2\xcb\x07L\xf0FQ\xf2\x0f\x8a\xae\xfbDK\xca/\xc9m\x9au\xd6\xd87\xc4\xf4\xeb\xd4w\x82\xda@\x00\x00\x00\x00\x00\x00s\x8fGi\x9c\xed\\\x90\xc0\xcf\xaf\xf3\xc3\xcb\xc22\xfcH\xfd\xbb\x19+\xf2\xecv\tm\'\xceP\xbb&9\xbb\xc6u\xf4\xcf\xd73\xc9v=\x0c\xa7\xe5\xa7]\x94\xd46\xde\xbe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00??j\xc3\x16\xbe\xcd\xcd\xcf\xaf\xc3\xdc\xaa\xf0\xe0\xf0\x8f\x94%b\xac+\x1e\xec\xf4\xd6\xcfh-\xa66H\xef\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xadl\xa2\xba\xd4\xaf\';\xce\xd8]-\xe7\x0b9\xc7:\xd0\xd1!dS\x07\xf2\xbbs\xd8\xde\xd1\x9f\xdf\xcf\xd3\x9d\xc2\xf1\x93J\x1bU\xb5@_\xfa\xf0\x87x\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r/t\x14\x9e5\xea\x8c\xf9\xde7\xa6\x91\xef2\xc9t@\xaal\xac\xc5\x95\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xf1\t<4\xfdV\xda\x14n5\xf6\x84\xf9\xd3\xf7\xa2\x9c\xed;q\x16V\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xff\xc4\x001\x10\x00\x01\x04\x01\x02\x02\n\x01\x04\x02\x03\x00\x00\x00\x00\x00\x03\x01\x02\x04\x05\x06\x00 6`\x07\x10\x11\x12\x13\x14\x1504@!\x1615P"3#\x80\x90\xff\xda\x00\x08\x01\x01\x00\x01\x05\x02\xff\x00\xb7\x93\xac`\xc1\xd4\xfc\xc6\x03#\x9b*\xb7>\x97!\xbb\xef6\xeb#r>\xf3!j\x82\xd6\xfc\xa3\xf5\x0b\xfdG\xbe\xbe\x8d\xa6\xe6H\xc6U\xdfV\xd8/+H8c\x0e\xcb.\x0b]2\xda\xf2^\x88P<\xfd\xb1\x15g\x14\x8ed8\xc2\x91\xaf \x89\xa5\x8b+\xb2"\xcb\xefu\xca\x86\xd2.+\x90Jt\xaeT#\xd0c\xb4\x9ck\xeb\x14h\x809\x13\x82F\xc34$\xea{Z\xf6\x8cl\x1bw\xca\x11T\x98\x8d\xe3\xacY\xcay\xac\xd7\xc3\xa4\xae\x0f\x85\x1e\xe1\xeek4\x9f\xba~\xdb,$\x11\xc6\xef.\xa9\xdeN\xff\x00\\\xe0\xb9\xab\x8dX\xfa\x9dW)t\x8cFzp\x91PR@\xc3\x8d\x95\xa1E\x10\x04%\xd1\xe6\x04/\xf5\x18\xfa\x11\x1aVj\\\x04)\x1bX\xde\xc8\xe0\x18\x13\xad\xedG3\x0c\x9cZ\xfbNR\xcc\x95I\x94u\x18\xc2\x0e\xbc\xea\x10\x93\xa5H\xf1:\xa9)\x0f*#\xf1Y=\xcf\xd3\xd7Mkj\xb2\x04I\xa1\xb7\x82\x89<:c\x9a\xf6\xf5V\xf1g)gB(2\x03I\x08\x96\xba5\x85\xb9\xeb\xb1`\x84\xd2\x89\x02\xb8F\x8b.\xe6h\xb1\x02\xe9\xd8\xddS\x86\\Z\xb5\xcc\x93Q.\xbd\x91/\xef\x08\xc8\xb9D\xc1k\xf5bj\xc6\xfa<\xb0V\x84\x82\xea\x9f)\x02\xcc:$\x8b\x0b\x9eR\xe9+\xe4c\xd4\xd0\x95\x04\xe8\xa2\x1d\xed\xfcj\xf6\x98\xd2\xa4L\x85\x90\xd3\x0c\x1f\xa9j5\xfa\x96\xa3N\xc9jQ\xb6\x97r\xec\xe2\xc4\x17\x80\r\xac(\xe1\\\xc3\x0cp\x87\x94\xbaGN\xd9~\x9f\x1b^\x9f\x1bB\x88\x01.\xbc1\xeb\xc3\x1e\xbc1\xeb\xc3\x1e\x93\xf1\xbe\xd0JH\xf8\x8d\x90\xe7\xd5\xf2\x96G7\xd5\xef~\x83\x08\xfa\xab\x11=\x85\x1f(e\xd6\xee\xab\x83\\\x07\x05\xbfB\xd5\xaa\xe8\x98\x8d\x94y\xb5\\\x9eb4A\xb4\x99\xebw?J\x8eg\xa4_\xa7\xe7\x93\xf3\t\xbeJ\x92\xb0j8\xbfJ\xc0\r0\xb0\xab\x1f;Q\xc9\xaa\xa8\x89{c"\xear~\x13y\xdf\xe1\x87\xd3fzDc4\xe2\xf6p\xb9L\x85}\xc9\xb7\xb2\x1d\x12\xa2\xa1\x9d\xd8\xfe\xc5\xa1\x1c\x8c\xc7\xeb|\xa5\x1eOQ\xe8\xf2\xc6\xf6\x91\x9e\xc4\xbf\x18\x12i\xa6y\xfa\xceL\xcf\'\xa9\xce\xc6\xa3\x19\xbd\xeeF\xb3\x13\xad\xf5kMH\x08\xe4\x02PIOf\x8b\xda\x9b\xe5\xfeb\xf4|Q\xba\x8f\x92\xee\xecC[\x06\n\x10\xc4\xf6&\x10\x86>7\\\xb5u}W\xf5\xed\xb2\xad\xaf{\xd3\xd9\xe8\xe4\xeda\xf9/!\x92\x96\xb9\x0f\xb1.C#\xb3\x05\xaa7\x8f\xb38\xa8k\x07\x16C\x0e\xcd\xf8\xb4\xa1@\xc8\xb9+)\xb3\xf4\xca\xba\xf19\xad\xdeW\xa0\xc7\x8d\xd6\x1e\xda\xcbo\xef\xac\xaa\x03jn7\xd9v\x8c\xb1K\xe3\xc5\xe4\x9c\xf0\xc2\x95o\xec\x19\xe4\x9aj\x98B\xaf\x81\xbb%\xadK:\xc8E{]\xba\xe3\xe3U\x7f\x19\xc9\x162\x19\x12\rK{S|\xd9(\x04\xc1\xea\x9f\n\'\xb1\x9bG,[\xd4TT\xdbj\xc5t\\jO\x9a\xa3\xe4\x8e\x90\xa5\x05\xb5P\xd9\xe1\xc6\xdc\xe5F\xb7\n\x88\xb3\xee=\x9c\x8a\x1bgTU9T\x1bl>\x1e\x15\xc3|\x910\xef\xb2\xbf\xdf7\xbd"E]|Z\xd8\xde\xd1F\xb0/6\xd8|<+\x86\xf9\x1e\xf6j\xd7\xd5V\xb1\xca\x9b\xa4\x97\xc1\x0e\x0fP\xfe\xdfo\xa4(\x0e,`\x11\n-\x96\x1f\x0f\n\xe1\xbeG\xcd\xa6\xc9\x91j& \xc7\xb9XkI\xb0\xa3\xb2,On\xf8o--K\x93\xcbl\xb0\xf8xW\r\xf21\x1d\xdc\x18_\xe7l\xf7X\x1b\xc2\x06\x19\x01!\xd3{\x8b\xf9L\x8a\xb5\x94\x96{,>\x1e\x15\xc3|\x8d\x9fOP\xc0\x88\x14\x086\xaf\xe3X\xa4\x16Z]{\xdd#"\xf9\xad\x96\x1f\x0f\n\xe1\xbeF\xcb$0\xb9G\xa8\x83B\x9c\x12\x13e\xa1Q\x91\xf0\xd8\xbeV\x87\xde\xe9\x17\xf8X\xca\x8a\x0e\xbb\x0f\x87\x85p\xdf"\xdf\xcf\xf4\xda\xa8\xcd,\x93\xb5\xadjH\x8a#\xbbe0R\xc7&\xf7\xf2\x81\x10\xf45\x8fO\x03F\x92\x11k\xd4#jQXj\xfc+\x86\xf9\x17\xa4\x19\xab\xe1\x85\x9e\x18\xb6\x99\xfe\x18\xfa9\x8d\xff\x00\x17\xd0\xba\x8c\xb5\x99\x16\x9e\x00\xbd\xdd\xc6j\x7f\xe2\x16\x15\xc3|\x89dv\xc6\x81\x05\x1f \x9b\xa4\xa7\x9b\x9f_\x0c\x10b\xfd\x0c\xfb\xf9\xde\xbb\x0f\x87\x85p\xdf"g\xb2\\\n(,VE\xdb%\xea0`Ub\xf0>\x8e}\xfc\xef]\x87\xc3\xc2\xb8o\x91.\x94\x93rDDD\xdbl\xaa\xad\xa9\x8f\xe5+~\x8e\x7f\xfc\xe7]\x87\xc3\xc2\xb8o\x90\xdc\xa8\xd6\xa1R]\xd6\xd7*5\xb8\xf4\x02\xdc\xdb}.\x91\xc6\xe7W\x85\xc8\xf1uX|<+\x86\xf9\x0f6\xb2H\xb5\xf0B\xa0\x06\xdb\x17+"a\x11\xd6>?\xf4\xaf\xda\xd7R\xd4|^\xab\x0f\x87\x85p\xdf!\xe5\xa6I9N\xe1E-\xad\xc4a0\x00\xfaV!t\x9a\xfa\xa5\xecgU\x87\xc3\xc2\xb8o\x90\xc8WL\xbf\xdd\x84\t$d?R[\x1a\x0c\x97\xaaz*\xc4\xc2\x1c\xd7c\x9c\x85\x98\x11\xe3\xc7j\xc4\xd6\xc7\xda\xf5\xee\xb3\xa3\x90v\xa7\xd4\xb2\xe2\xce\xa2\x7f\xaf\xa3\x99@hy\x0b>\x92\x81\xa3\x82\xd5l]\xb6\x1f\x0f\x06\x10\xd9\x8f}K.,\xeb\xc5\xf8\xc3\x90\xbaI#<\x88\xbf\xd7\xb6\xc3\xe1\xe1\\7\xf5,\xb8\xb3\xae7xY\'!t\x87\xfc\xa6\xeb\x0f\x87\x85p\xdf\xd4\xb2\xe2\xce\xb6q\x07!g%\xf3\x17\xfb\xac>\x1e\x15\xc3\x7fR\xcb\x8b:\xd5\xec\x15\xe0\xa7B \xc6A\x91?\xbb9D\x01\xc8\xbe\xa8\x02\x17*\xa5`\xdd\x99V\xf7d\xde\\\xce0\xe3/\x98\xd9\xda\x9a|\xb8\xcdR\x18\x93S\nd\xc1R\xfdK5D\xcb:\xca!\x95<\x84m$$f\x961;"Z_\xc3\x00\xf2\xcb&<9\x9c\x1e\xc6\\U=\x88\xf6*v\xa7\xf62eF\x8c\x97\x99`B\x84\xb8\xc8\x0f\xafQ\xc85%\xb3&\xbd\x91c\xb3^\x08v=\xedby\xf1\xb9\xe2\x81{!\xe1\xc5\xed\xa5\x11\x98mZ26?N\x07G\x8d\x1e?\xd6\xbb\xc7 \xd9\xb9\xf8\xcd\xe4}:\x05\xf0\x88E\x9c\x17\x8ah\x9e\xe4sWi\x18\xc25aF\xd7\xa7\x03L\x84\xd1\xba-\x85\xe4\x15na)\x8f\x06e\\\xe7\xc7\xc9)\x8c\xd6\xb9\xafo\xf5*\xa8\x89\x90e?\xe4\xc8^"\xb0"b\xed{\x9a\xc4|\xf1v\xd5\xd0[\xd86\x16\x1b\x11\x8b\x06\x04HA\xfb\xd6\x14Us\x9f#\x0f\xab~\xa6c6\xf1t\xe0\\\t\xe5\x94\xe0(\xa5\x80\x9b\xd5\x11th\xa0*\x0e9\x80\xb8\xad\xec\xf3\xd9\x7fQ\xd2$\xb2\x0e\x14@4\x03\xdaS\x08Za\xcf2Ev!\xfeQ B\x88\x9f\xd2\x90l+.1\xba\xeb\x06\x13\x18\xb9\x8f\xa9\xed\xb1\xac;fFTa\xc2\xfd5\xcdv\xdc_\x8c\x7f\xa8\xcai\x16\xdc\t\x8c\xde\xa2\x16\x8f \x0b\xa6\xc4\xbc\x86\x1f<\xddy\xe4\xd0\xa0\xde\xca-6%\xdc\x91\x16,h\xac\xfe\xa9\xcdk\xf4\xb4\xd5*\xa7\xc6iLK\x1c?\xb0\xa6\xc7\xb2\x017\xd2r-xV\xe9\xaf\x0e\xd7Xu<\xc6Y\xff\x00\xe3\x7f\xff\xc4\x00+\x11\x00\x01\x03\x01\x06\x06\x02\x02\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x03\x11\x10\x12 12P\x04\x13!0AQ@a"B\x14`p\xff\xda\x00\x08\x01\x03\x01\x01?\x01\xfe\xf2\x1aNJ\xe7\xda\xb9S@\xb9)\xb14\x84`\x1e\x13\xe3-\xda\xe2m\xe2\xa5\x92\x86\xe8P\xba\xb6\x99\xe8S\x1dxU9\xa1\xc2\x85=\x97N\xd5\xc3\x8f)\xcdne\x19X\xdc\x97=\xc8M\xf4\xab\x199&\xc8\xcc\xac\x9ct\xae\xd5\x1b\xcbrG\xed5\xa1\xda\xba \xd8B\x7f+\xc2\x10\xf4\\\x9f\xb4\xd6\xdd\x14R\xb8\x93M\xaa\x16\x82:\xab\x8d\xf5e0\xce\xcf\xdbi\x02\xa6\x89\xa2\xe8\xa7a\xc2\xa2\x88\x8a\x1am\x107\xce\x16J\x1f\x86v\xf9\xda\x1a()\x82g\xd0Q\x03E\x1b\xef\x0c\x0f\x15n\xcf\x03?l\x04\xd1=\xd7\x8dlc\xee\x9a\xa0k\x80\x8a\x1d\x99\xa2\xe8\xa6\t\x9f^\x83\x04\x0f\xf1\x82m[,\x02\xae\xc1+\xee\x8c#\xa2i\xa8\xad\xb3\xea\xd9a\x14m\xa4\xd1=\xd7\x8dq@\xee\x94\xb6}[#\x05\xe7S\x04\xef\xfdq\xc6\xeb\xae\xb6}[$7GR\x81\x07+\x1ch*\x89\xaf`Y>\xad\x91\x8d\xba\x15\x05\x93\x9f\x1d\x98\x9dV\xaf\xc9O\x9e\xc7\x08\xab\xad=\x13\x9dx\xd7\xb3\xc3\xe5d\xfa\xb68\x07\xe3l\xce\xa3i\xda\xe1\xceb\xc9\xf5l@T\xa0()l\xce\xab\xbbPj\xb2}[\x14"\xae\xc0z\x9e\xd4z\x85\x9cF{\x17\x0f\x9d\xaf\xd2{q\xea\x16O\xa7b\xe1\xf26\xbfI\xed\xc7\xa8Y6\x9f\x9c\x1a]\x92\xe59\x7f\x1c\xa1\xc3\x8f(\x00\xd0\x8c\xad\x08\xf1\x1e\x93\xa6q\xed\xb4\xd0\xd5\t\xda\xb9\x8cr\xe5\xb7\xd20\xb4\xa3\xc3\xfa\\\x87#\x13\x82\xa7\xc7d gk\x9e\x1b\x9at\xe7\xc2$\x9f\x82\t\x0b\x9c\xf4\xd9\xfd\xa6\xc8\xd2\xaa,1\xb4\xa7\n\x1f\x8b}\xde\xd0\x95\xc1\x19\\~O1\xde\xd75\xff\x00\xe4\x7f\xff\xc4\x00)\x11\x00\x01\x03\x02\x05\x04\x02\x02\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x03\x10\x11\x12 !1P\x1302A\x04@"QB`p\xff\xda\x00\x08\x01\x02\x01\x01?\x01\xfe\xf2\\\x02\xc4\xb1iu\xd4FG!)Mxw\x17#\xac\x13\x19}J\x91\xb6\xa8\x899\xb8M\x906Mv!\xc5LPq\xd8 \xc2J\xe9\x04\xe9#i\xb6$\'\x1e\x9c\xad\x8bQ\xad":\xdb\x8a\xf9\x0ek\x05\xdc\x8c\xf2\xcap\xb1|_\x8e#\xd4\x9dV\x89\xc1\xbe\xd3\xa3\x8c\xff\x00\x14!\x8c\x1b\x80\x89\xba\x8d\xa0\x0e*W[e\x88\xe7\x89\xde\xb8\x92l\x89\xb9\xec\x03b\x81\xbf\x11+\xbdes0\xe5\x88\xfa\xe2\x1cnrF\xdb\x9a=\xb8NF\x9b\x1e\x1eWz\xc8\x05\xd3[\x84Q\xcd\xc4\x11\x16\xc88bnrF\xdbk\x92V\xfb\xc9\x17\x8f\x0b)\xd3$m\xb9\xccE\x8db\xdb\x85\x90\xdd\xd9\x1a,3J=\xd6\x1d\xb8G\x1b\x0c\x917\xdew\x8b\x8a\xc3\xb7\t%\xce\x81\x10E\x00\xb9\xed\xc3\xb7\x08\xe7\\\xab\xd2!\xef\xb3 \xb1_\x8a\x8bn\x0eSa\x91\xa2\xc2\xdd\x99\xb7\xa4;pr\x9dk\x18\xb9\xedMHv\xe0\x8e\x88\x9b\xd61a\xda\x97\xc6\x90\xed\xc1Hl\xdc\x83\xb4\xff\x00\x1aC\xb7\x056\xd5n\xfd\xb7\xf8\xd2-\xf8)\xaa\xdd\xfbo\xf1\xa4^_x\x907]F\xae\xb0Fb\x89%\x08\xdcP\x85\x08\x80\xed\x91p\x8cE`pX\xdc\x84\x8eBe\xd5\x08H\xd3\xf6\x1d\'\xea\xa1\xa4\xa1\x10\xf6\xac\x07\xd1\xb2\xe9\xb5\x18\xbfH\xb0\x85j\x07\x90\x86\xa3\xea\xe0\x0b\xa6\xd4#o\xd9\xc0\xd5\xd3o\xf9\x1f\xff\xc4\x00I\x10\x00\x01\x02\x03\x03\x07\x06\x0b\x05\x07\x02\x07\x00\x00\x00\x00\x01\x02\x03\x00\x04\x11\x12!1\x13 "AQ`q\x0502a\x91\xb2\x10\x14#@BRr\x81\x82\xb1\xd13Pb\xa1\xc1\x15$5s\x92\x93\xa2\xe1\xf04CSc\x80\x90\xf1\xff\xda\x00\x08\x01\x01\x00\x06?\x02\xff\x00\xcb\xc4\x89\xb9\x944U\x800|M+u\xedAI\xa0\x80<a\x0cu\xa1\x11F\xf9A\xc5\xf0@\xfaED\xcb\xbf\xd0\x98\xa2\xa6\x9d\xfe\x81\xf4\x8b\x7f\xb4T\x9e\xa2\x81\xf4\x8f\xe2\x9f\xe0>\x902\x99)\xa4\xd7X\xbc\xc7\xef\\\x9c\xeaW\xae\xc9\xba\x02\x19~\xcb\xa7\xd0]\xc7u\xf2\x93\x0e\xa1\xa4z\xca4\x8c\x97&2f\x97N\x91\xa8H\xfa\xc5\xa5\xcd&Q\x1b\x1a\xba\x91\x96\x99}\xd9\xb7\x0e$\xc0\xc9\xca\xb8\xa5l\xac%&\\\xb4\x98R\x80q\xb0:\xe2\xad\xbe\xe0V\xd8\xbaqU\x8aL$SnfQ\xbd\x07\x06\xb1\x08\xe4\xbePA[\x86\xe49\xaf\xdf\xba\xaaqX$T\xc5\xa5h\xcb7r\x00\xd9\xf5\x8b\x80BD)\xa2\x85\x14\xed\x06\x12\x94\xa6\xca\xbf\x17\xd7\xc1eB\xa2,\xa14\x1c\xc2\x1f\x97]\x87\x91\x81\x10\xa9i\xbb"i\xbf\xf2\x1b\xa8\xac\x9dm:\xac\x9d\xa0iH\x17\xde\xab\xe1\x08\x06\x81X\xf3\nn\xba)1\x89\x85"\xf2\x8avfx\xd3\n(u\x17\xd57B&\x14(\xb1\xa2\xbe;\xa6\xc4\xbd\xaf*\xa7m\x04\xf5B\x01\xc4\x08\xb2\xae\xd8\xaa\x94\xa5E[@I\xf0XQ5\xea\x11\xe9\xf6@Z\r\xc7\xc1m\n\t\xae1\xa4\xe9\xafP\x82\x101\xc70\xa4\xe0c\xf6s\x88*L\xc1\x14\xd2\xe8\xee\x9a\x1aZ\x89BP(\x9a\xe1\xe1\xf2\x8a\xa4\x06\xe5\x9a[\xcbV\x00\x08-)*d\xa6\xe5\'_\x87*\xe4\xf7\x8a$\xf4\x13\xb4m\xc6\to\x95TU\xaa\xa9\xbb\xe7\x17M\xcb\x9a\x7f\xbd\x91C,\xd1\xf8\xc7\xd6\x12\xb9\x991`\x9fB\xf8\xa2\xed\xa0\xec"-$\xd4xd\xbd\xa1\xbal\xcc\xdde\xc4\x80\x9ftQk\xbfd~\xed\xe4X\x18\xb8p\x86\xde\x9a\x983\nA\xe8\x91\xa2aS\x0bC-P\x1c\x00\n<!\xe9\xc995\x86\xd6\xbdf\x13\x94\x9c@\xf5\x80L!9\x15\x0b:\xc2\xaf0B2\xa8V\xdbU\x85MK\xf2\xc3\xe9CH\xa9\xb5y\x8a!m\xa8\'\xd2Z1\x82\x89\xc9\x12\xe9\x1e\x93wG\xf0\xc9\x8e\xd8ZU\xc8\x85KV\xb5\xc2\xd4\xa1d+\x04\xd7\x0f\x05\x10\xa1\x94\x84\xce\x95\xa4&X\x82\xad\xd3\x92\xf6U\xfaCs\xf3sl\xcc\x95\'\xa0iO}`6\xd2\xd9B\x06\x01$R2mQ\xf9\x83\x82A\xb8q\x819\xca,\xb92\x9cl\xd6\x82\x02P\x93,=L\x9f\xd2>\xdd_\xdb1\xf6\xea\xfe\xd9\x82C\xcb=Y3\x06^^T\xb4\xda\x8d\xea\xb5\x8c\x04v\xe7&jjTL0qI\xd7t\x01,\xca\x19B\xaf\xa2SM\xd3\x90\x1dJ\xf9\x88\xc1]\xb1\x82\xbbb\xa9E\xfd~\x0e\x82{#\xa0\x9e\xc8\xe8\'\xb2:\t\xec\x8a\x0c\xfa\x8cQ|!\x19E-\xf6E\x1d\xb5\xbavY]Xb\xe4\x9f\x99\xf3\x16f\xa5\x94S}\xe0\xe1\tq\xb5\x05!B\xa0\x8d{\xa2\x9c\x88\xf2\xce\x9a"\xa2\xe1\nS\x94\xb4\xaf1\xbbQ\xac2\xd2\x14\x03\xac\xa0%H\xad\xf7k\xdd\x05\xba\xbe\x8a\x13h\xc1~\xc1\xc8 YG\x0e\xbf3\x06\xc7\x91\x7f@\xfb\xff\x00\xd6*7=\xdb+\xb2\xe3\xba\t\xba\xb5\xdb\xf9E\xfe\x95\xfeg\\\x14\x9b\xe1-\xadUu\x9d\x15UU$m\xdc\xea\x9c\x04\x16\x93c\xc4\xd9sF\x9a\xfa\xe2\x83\x98R\xf6\x08\x1c\xb6\x1dJ\x93j\xf1[\xc5\xf4\x80\xa1\x8e\xb1\xcd=*\xb2(\xfd\xc1Gn\xe7L\xcc \x02\xa4\xa2\xe0`\xab\xd6<\xcaYN.]\r\xc9L\x84\xae\xa0\x95\xa4\x8d\xba\xa13\x92hW\x8b/\xa4=S\x01h5\x1c\xcbs\xec\x11m\xa3\\!\x89\xaa\xa2\xd2\xd3\xa5g\x00w5\xbeId\x03\xe9\xac\xc0H\xc0s\x05G\x01\x0b\x9a\x99l\x99v\xfa\xf5\xea\xf0-\x87Si\x0b\x14P\x87%\x9e\xcadk\xa0H\xc4m\x8a\x8c9\x87)\xea\xc6H*\xabC\x86\xd0\xd9]\xcc[\xcbq\x01t\xf2i>\x91\x87\'_*S\xae\x1cO2\x99\x19t\xd5\xc5\x9aB%\x94\xaa\xae\xb6\x97\xc7\xc2\xec\xbd\x13\x94\xa6\x82\x88\xad\x0c.]\xdf\xb4h\xd9<\xcc\xdc\xa2\x92\xac\xa2\xa8\xbe\xcf\xfe\xeeb\xc5*\xcb\x1a\x02\xea\x7f\xbb\xf9\x9b\xfaG\x01\x07\x95\xa6\x82\x92\x7f\xe5\x03\xaf\xaf4r\x9c\x93V\x1c\x07\xca\xd8\xf9\xd2*\x9cF#\x98qSD\xa1.\xa4\xa5&\x9a\xeb\xb9jq\x1fj\xbd\x04u\x18/8Iq\xcb\xc9\xe6\x14\xb3\x80\x15\x84N\xba\xcd%\x10o\xa9\xc7\x86{s\x0c\xd031]\x01\xabo0\xc4\xc6!\xb5a\r=Je\x10\x15N;\x95+,\xd2\x82\x96\xd06\xf6s"JQ\xb5\xb8\xb5\x1fF\x1b\x95k\x04\x8b\xce\xd3\xb7=m\x04\x02\xf2oh\xf5\xc2\xa5\x1fM\x87Z\xd1\xa6z}\xa8\x95\xfeJ>[\x92\xf4\xcb\x95\xb2\x84\x93t8\xf1\x1d#q\xe6,\x8b\xdc8B\xa6\xe6*\x1e\x98\xf4N\xa1\xcc\xa6~\xc8\xc8\xbbAZatTa\x9d_T\xd6%]\xb1gB\xcd+\xb2\xed\xc9L\xa1W\x95q`\x81\xd4!\t\xa5\r/\xcf*8\x08\\\xfb\x89\xf2l\xe1\xb2\xbc\xd3\xec\x91}\x9bI\xa0\xa9\xa8\x82\x85b\x83Jg9\xc2%\xbe.\xf1\xdc\x99\x89\x870l\xd1)*\xad9\x86d\x9a\x05jZ\xaf\x03\x18\x0cJ\xb7dk:\xd5\xc7\x9b\x9a\x97x\x8a\x95\\um\xces\x84K|]\xe3\xb9\x0f\xcd\xa56\x94\x81w\x18\\\xc2\xce\x93\xa6\xb9\xeasd~\xd7\x98:K\x1eM4\xfc\xf9\xc6\xa7\x9ah\x12\xd5\xce\x1dt\x84\xack\x19\xaep\x89o\x8b\xbcw rR\x16[e \x15_\xd2\xd7\x01\t\xc0g\xa2JQ$\xdfy\xa7\xe7\xc2\x1b\x97lQ(M\x00\xe7&\xdbm%KSD\x005\xc1F\xb4\x9b\xf3\\\xe1\x12\xdf\x17x\xee:\x97\xb0V&\'\x8dt\x96H\x04\xe1\\\xf3~\x92\xae\x10\xda\x94\xdd\x87\x9d\xd2_\xe9\xf9s\xb4\x86L\xbb\x8a-?S`\xea\xcds\x84K|]\xe3\xb8\xe8\x92h\x9c\xa4\xc1\xbe\x9e\xac\x04\xd2\xfdy\xd5\x87\x1e}\x0b[\x0c\xde\x0e\x02\xba\xb9\xf9\x05P\xd2\xfb\xfd\xe35\xce\x11-\xf1w\x8e\xe3\x95&\xb4a!+\xafTt\\\xec\x80\x8d N\xd1\x9aP\x14-+WT1x%\xdf)\x86\xde}\xaf\xe7\x8f\x91\x84P\xd7G1\xce\x11-\xf1w\x8e\xe3;4\x13iB\xe4\xf10\xb9\xe9\xa5\x05\xa9\xdcn\xc6(\x90\x00\xea\x80\xa5\xd6\xa3fk(\xd0(oH\xda\xbc(\x0f0\x9ai\xa4\x15\xac\xa6\xe08\xc6K\xd3F#\xc1E\xae\xfd\x91\x8a\xbb!\xc5\xa3\x08\x96\xf8\xbb\xc7q\x99\xe4\xc6\xcd\xee\x9bJ\xba\xeaj\x84\xa3`\xceR\xee\xb8k\x89\x99\xe2EV\xab\x14\xa6\x1f\xee\xbeb\xeahKs\x06\xd2I\xeb\xff\x00_\x05\xa5\xb6\x92c\xa2\x9e\xc8r\x91-\xf1w\x8e\xe2\xbc\xfa\x97`%\x07J\x1792\xa2\xe3\x8a8\xab=\x89$T\xdaX\x06\x82\xb4\x84\xcb\xcb\xa0!#f\xbe\xbf1\x92\xf6\x07{1\xce\x11-\xf1w\x8e\xe2\x96\xd2\x12r\xcb\x085\xd9\x8f\xe9\x08I\xceZ\xc6 G\xedg\x15m\xd5\xd4&\xa3\xa3\xe6R^\xc0\xeff9\xc2%\xbe.\xf1\xdcY\xa6\xe6\x1dR\x90\xd2\xc8H\xd8"\x83\x0c\xe6\xda\x03\xa6b^\\\xa5)R\x1b\x01Vv\xf9\x94\x97\xf2\xc7{1\xce\x11-\xf1w\x8e\xe2\x12p\x1176\xd8!\xb5\xa8\x91\\\xe2\xa3\x80\x80\xf2\x9b\x1e,\xc9\x16\xef\xf39w\x12\x82B\\\xd24\xc2\x12\xa4\xe1O\x0b\x9c"[\xe2\xef\x1d\xc4\xf14\xa08\xe4\xc8)\xa5z",\xaa\x96\xb5\xe7,\x8e\x10\xd5T\x0eT\x978y\x9c\xe5\xa4\x83\xe4To\xe1\x1f\x17\x85\xce\x11-\xf1w\x8e\xe2%\r\xa4\xd5\x84\x84\xaa\xbd\xbf\xaez9=.%\xb1\x8dH\xea\x842\xdaBR\x81@\x00\xf39\x89t\x10\x14\xe3e"\xb0\xe3:\xd0\xab\xfc.p\x89o\x8b\xbcw\x12ni@$\xda\xa5\x07f{\xf3$\xd0\xb2\x9b\x86\xdd^k8\xc3B\xc3aGDx\\\xa6\xc8\x97\tP%6\xab~\x17\xee\x1c\xca\x9bZ\x90\xab\x85A\xeb\x80\xe0\xe9/\x1c\xe2\xad\x82&\xe7J\xafR\xacY\xa7\xbf\xcdg}\xa3\xe1W\x08zMNQ\xf5.\xd0N\xd1M\xc3-Y\xae]a5\xd9\xaf\xf4\x86\xc2\xb1\xa6s\x9c!\x95\xa1 )d\x95\x1d\xb7\xf9\xac\xef\xb4s\x13\xec\xab\xbb\xb8r\xcdZ\x19L\xa5\xab=T\x84\xf0\xces\x84K|]\xe3\xe6\xb3\xbe\xd1\xcc\x93[kRJ\xdcMhz\xf7\x0eG\xd9\xfds\xdc\xe1\x12\xdf\x17x\xf9\xac\xef\xb4s9?\xf9\x89\xefn\x1b\x12\xe8I\xb4\xcao\xae\xbdy\xeep\x89o\x8b\xbc|\xd6w\xda9\x92N8\xa0\x94%i$\x9dW\xc0Z&\x99)8i\x88\xabn%~\xc9\xaf\xdf\x85\xc7\x9cCh\x18\xa9F\x82\x05\xb9\xf6M}Ck\xe5\x05Bd\xb8G\xa2\x96\xcdL\x1c\x9b\x13J^\xa1d_\xf9\xc2\xc3n.M\x9a\xd57^:\xab\x06a\xe7\x96\xeb\xc7\x15\x1c\xdcb\x85\xd1\xee\xbe\x17/),\xeb\xc6\x9e\x80\xac%\x99\xb9r\xcd\x85\x1b\x15\xb8\x91\xe6\xb3\xb5>\x91\xcc\xa3\x89\x06:\'\xb6\x0eI\xe7\x9b\x07RU\x17NLW\xda\x84\xb4\xdc\xc2\x1cB0\n\x150\x0c\xc7&\xb6\xa4ll\x9a\xc5&ef\x19]p\x1aP\x149BZ\x87k\x80EB\x92A\xeb\x8cG\xde$\xbe\xfbm\xd0WIP\x19\xe4\xcb3\x0f\x1fK\xd1\x10\x15\xe3-\xcb\xfe\x14"?\x8a\x7f\x80\xfaE\xaeP\x9dq\xef\xc3\xaa.i>\xfb\xe3\xec\x91\xfd9\x95Z\x80\x10\x12\xd2\x1cp\x9d@BrR\x194\x91P\\\x8f\xdf\x1fn]\xbf\xc2kX\x01NL\xa9Z\xcd\xa1\x01H\x91l\x90)\xa7\xa5\xf3\x83\xe2\xec4\xd5q\xb0\x90+\xe6\xc5\xe2\x0b/\xd3\xa6\x8d|a)a\xe6_O\x1aB\x90\xaeN.SZ0\x82\x89\x8eN}*\xeaM`\xa5UmCR\xa2\xe5\x03\xef\xcd\xb2\xb4\xd4G\xd9\xfeq\x8b\x9d\xb1m\x97\x9dmc\x05\x05a\x15js\xc6\x13\xea\xbb\xa5\t\xf1\x8eK\xa2u\xd9U\xf0R\xf3/\xb1\xc4V-x\xe2Q~\x0b\x14\x80\xa4\x90\xa0p#\xee\xaa\x93A\x06O\x924\xd7\x81{\xe9\xf5\x8c\xa4\xd3\x8aqg\x1b\xe2\xa8m \xe7UD\x01\xd7\x16[J\x9cV\xaa\x08.\xcc:dQ\xe8\x82\x9b\xcf\xba-N\xcc92v\r\x11\tjY\x84 \'\x0b\xaf\xf3\xfc\xa3\xf2\xa9\xb7\x89RtI\x81\x91/\xcb\x9f\xc2\xba\xd7\xb6\x10d\xe6<lkOF\x9d\xa6\n\x1d\xe4\x97\xd4\xa1\xea$\x91\x16&e_e{\x14\x98\xa2\\\x15\xeb\xcf\xbc\x085@\x04\xeb\x10\x95KN<\xda\x93\x86\x94~\xcd\x9e\xb2\xe1\xa5\xcb\xd6(??\xbaX\x94E\xc1\xe5^k\xb3W\xe7\x02\xed/H\xe7yE\x84\xc2e\xf9=\xa2\xe2\xcfT%\xceS\x9a.\xd0\xd7&\x9c x\xb4\xabM\xd0R\xa17\xf6\xfd\xccP\xe2\x12\xb4\x9cB\x85D\x0b-\xa6Y\xc1\x82\x9aM?(\x1e/0\xcb\xe3\xf1\x1aR\x029A\x80\x12\xac\x14\x9c"\xb9P8\xc6\x8b\xa9\xed\x8d\x15\x03\xc0\xe6\xa7\xd9Ww\xee\x96\xf2od\xdej\xb6k\x81\x8ax\xdc\xa7i\xfaE\x94\xb4\xc4\xc7\xe2J\xe9\xf3\xa4e\xe6$@lbRk\xf21\xf6/\x7fLh\xb0\xf1:\xae\x8b\rH-\x81\xb5\xc1O\x9c\x19\x8eUq\x13\n\xad\xc8OG\xdf\x16%\xd8m\xa1\xf8SO\xba\xf4\x92\x15\xc4A\'\x93\xa5\xaa\x7f\xed\x88\xb6d\xc2}\x85\x14\x8f\xca2\xdc\x951\x91?\xf4\xd7x\xed\x8bIT\xb3\xf7\xf4R~\xb4\x8f\xf8\x06\xff\x00\xb8>\xb1ErD\xc9#b\x0c\x7f\x07\x9b\xfe\x83\xf4\x85r\x8c\xeb.3q\xc9\xda\xec\xbc\x7f\xe9\xc3\xff\xc4\x00-\x10\x01\x00\x01\x03\x02\x04\x05\x04\x03\x01\x01\x01\x00\x00\x00\x00\x01\x11\x00!1Aa Qq\x810`\x91\xa1\xf0\x10@\xb1\xc1P\xd1\xf1\xe1\x80\x90\xff\xda\x00\x08\x01\x01\x00\x01?!\xff\x00\xd7\x8e\x01\x92\x9b\xbd\xa9\xcd\xe5\xa2=\xda\xb3le\xbfz\xcc\xd2\xb0\x84\xd3M|\xf8iP\xe3z\xf4\xd6\xcb\x17Joh* \xe6\xd8.Rc\xd2\xadvh\xdd\xb7h|X\x85#\xb7?+\xbd,a\x18\xf7\xae^)#\xd3>\xcaP\x07\xbe\xd1\xcf/\xad0YXg\xac\xe6\x91\r\x9c\x91\xfd\xd1p|\xcc\xd6! \x89\x8f\xb5`\x8d\x84\xcd\x01-\xd02~\xe9J\xd7\xb1I\x9e\xdfT\x12\x12J\x999\xc5\x89\xae\xcb\x8dbz\xb1\x9f*\xcdd\xd8\xb9\x14\xe2y\xb2Z\xb2\xee\xa6\x08E\xd8\xa7\x87\x9d\x04\xd6Ql\x89\xbf\xd0\xa0o\x91\xa8\x92\x9e`\xf0\x1c=\xed\xa2\xf7\xa7\xfbQ-\xbd\xd7\xa7\x95-z!-9W\xda;\xd5\xcd+\xbaxr\xa3\xcf\xe8T\x815\x83\xa7\x0bn6\xa0W\xfa\xd4\xa6d\x15\xd5\xc0\x17?D\xad\xac\xf3\xa4}cj\xc9\x8b\x97m\x7f)\xd9\xe4-R\x04_r\x89\xa8\x08\x9d\xaa\xf2\xcdA\x92\xa2a\xe5\x8aJ\xd9\xa9\xf4K\x0b\xcd\xc8\xad\xdaf\xa9\xf4\xa6I\xd5\xbc\xb5\x0b\xb8`\xa7\xe5\xcc[\xbc\x18\x17a\xa8Y;I^\xe1\xbf\xeb\xcao\xfb\x96\xb2D\xb1\xe9\xf52G\x94\xd5\xa1L\xe8\xcbT\xfe.\x80;\xd2\xce~\x93\xb6\x89\xb0\xf4\x90\x8a\xb4\x8e\xb5\xc4\xf5\x95i.\xb1,\xbe\xb4\n\x97\x9b\xfa\xe9d\xf7J\xfdV(*"\xdd\xd1\xb1\xbe\x13\xeb\xf1\x9b\xf9O\xa8\x1b.\x86}i1BL.\xd2k\xadIg\xf6\xecS6\xc2\xf4\xa6oI\x9bq\xbf\xa6\x13S\x03R\xd9\x97w\xf5IQ\x16\x93S\x9c4\xc1Q\x89\xe7V\x96\xb7c\x1b\xb3Oa\xa0\x18\x8eD\xc5\x12<DI\xee\xe7]\xc9\x88~\xab\xe3\x7f\xaa%\xda\x11_\xd4&\xb5\xe3w\x9fF\xca\x89\x13\x06\xf5;\x10\xac\xb30\x07\xaf\x94\xda8\xc2~ZN\x05S\xa2\xfb\x89\xf9\xa1\xd10(v\xa5jV[u~\xaa"rF1\xca\xc5\x8d\xa8\xeaE\xb7\r\xf4W\xc3\x7fU\xf0\xdf\xd5,\x04$\x17*\x1c\x19$\xa3\x96\x91\xbej\xe9\xca_\xab\x8a\xc4>\x18\x985\xb4\x95\x8d\x8cq\xbfO)\x93\x18I\xfa\x85-\xeb2\x151\xf4\xff\x00\x0f_\xe1\xeb\xfc=\x7f\x87\xa0\x08\x00\xe4q\xde:\x96m\xadB\xe9b^tw?\xaf),\x12\xe2\x88y\x1c#69\x8d\xbe\xc6C\xe5\xf1\xb7Q\x8c\x94%\x15\x8e\x0e\x1f(\xc1\xc2\xe6\x92\x0c\xaf\xad]\xa0\xcc\x1a}\x8aH\xcc\x0b\xa51G=\x82\xce\xc7\xca\r\x921Bl\x12\xd1\xbex\xa40\xbf\xb9~\xcb9\xae[\r\x91d\xe5\x10\xedH\x02\x08\xe1<\x9f;\x1c\xcf3\x0fu\x10\xbeU\xa9\x11\xf6j[\x05\x0c{U\xc8\xdfHHhi\xdb\xc9\xcc\xda\x02V\x9finDmvnP\x02\xc0X\xf0\x05\xb1oZ\xa6\x0bb\xc8\xff\x00\xb1N\x19\xec\x1f\n\xc0N\xc4Yp:\xcf\x93\x94D\xdc\x17J\xb8\xba\xd1\x18\x8f\x04\x99\x94\xff\x00\x14\x8f\xe8\x00\x84\xa5\xd515?\x8bW]\xacX\xe5\xde\x8f\x0b\xeax$T\x00\xce\x11\xcdL\x08\x14\xb9\xd4\x9eM\x0b\x88\x92\xa6\xfa\x1bE\xe7\xa9S\x0f\x0c\x13\xe0`]\x96\x8a\xe0\xf6`\xe9ng\xe8F\x97f\xa3@\xf0\x96\xdcMcDI(\x91\xf0\n\x10\xaa\xacR\x01\xa5\xd5\xd0\xfcy2w\xcf\x9bf\xc4\x17\xa4"\x0c\xb3\xff\x00|\x18!VqwJ\x9c\x96\xa2d\x1eB\xd8\xb7\xd5i\x9c%\x17.\xb8\xefX\x0e\xf0\x99\xc3\x19\xf0\x1c4C\x01\x82\xc1c;\xd9\xe4\xc9\x083\x98\xb6g\xd5A\x04\x1e\x04\xa2\xfe\xe5HS\x84\xb0\xb8\xbfG\r\xcef\xec\x93\xe153\x1dKO\x02\xe5\x058PO\xc7\x92\xd8\xd4\xafT\xd5\xb9\xa4\xf7\x8aS\xef9\x96\xf7\xff\x00\xbe\x00\x04\xb2\x91C\xe6\xefBf\x0efb\x80\x08\x088P\x08\x829*\xf4l\x80\xb8\x88\x04@\\\xf7\xf0\x1c\x0c\x05\xbb7\x9f\xd5o\x0ei\x88Ly(C\x19\xc8\x94c\xad\x9a\x00 \xf0"\x04\x87\xe3J4u\x06u\x97\x19\xde\xc9\x8cG$\xf2\xa0 \x89tY:\xf1\xfbo\xe1\xaf\x8c\xe5\xf2H\xe2\x96\x90\x96\xd8&\x94\r\xcag\x7f\x00H\xa5\xb4\xa0\xba1\x82#\xc4\x91g>\xde\n\xee\x00\x02\x84A\x1d\xf2\xd16\x94I\xc4\xcc&G\xe2\xbdiS{\xdb\xc92 #\xc5\xb5\x1eU(g\x06\xfcj\x08\x04\xb3V;\xbaEb\x0fk\xce\xde\x13\xdaKMP\x03\xacGz\xb3[t\x13\xaf\x17\xcc\xdf\xc9\\H\x196\x90\x96#i\x17\xbf\x81\x10$\x87\xec\xf7\xadP\x0b]\xb9\xad|9\xc7:6S\xbb\xaf\x17\xcc\xdf\xc9<Z`\'s\x03\xef@\x11R\x8cg\x8c\x9c\'A\xbd\x12\xee\xa1Cg\x9f\xc4s\x0c\x84^Ob\xf5\x80\xbc\x131\xc3\xf37\xf2O\x04\x90\x00\xb1\xa6]9Pmf8\xc2&\xc6d\x1b\xa3E\x06\xf3\x88\xaf\xe7\xc4\xcd\xbd6QL\xb8\x9b\x0e\xbc?3\x7f$p\x08\x137\xa2\x98\x18$%\x9b\x1e\x9cbcDVf\xe6YQ\xff\x00\x85\xbcP"\xc3W\xaap^\xe2\xd3\xaex~f\xfeH\xe3\x93\x94&\xcc\x8e\xb7\x93\xd2\x89p\x8c\xf5\xf1 )\x80\xa2\xcc\x91\x9c\x9b\x1fw\xb7\x8f\x86HXX\xa378>f\xfeH\xe0~*\x03t\xa6\xd7+\xfc\x87\xf7C\x12\xd8p\x82\x11k\xf2Q\xca\r$\x8ar<\xe3\xc7\x9d\x00\x8e\x02\x18\xe9\xc1\xf37\xf2?\r\x07\x104\xc0.\xd3R\xd94C*\xd8\x15\x08\xa0\x00\xda\x95\x1c7/0\x8c\x85"\x80\x08,x\xe7o\xf0\xa5`4\xd3p\x88\xe4%\xfe\x89\xa0\x0e\x8c\xfd\n\x80\xae7#S\xc8\xfcI@iD\xa5\xab#%\t*\x91K\xc4\n"\xe1\xba\x81r\x82\xcf\x0b\xcc\xfc[\xec[2\xa7\n\xca\xf8\xea>\x92"\xf5J\x00\x82*\x10\x00\x08\xd3\xaf\x91\xb8\x05m\x05\xa3\xa7\xbcU\xbc\xde\xbf;\xf1\xb3`C2L/b\x80M\xde\x11-V\xff\x00c\xf2\xdc\xdc\x1f3\x7f#q\xcc\x00Dj\x1e\x8ag\x05\x89\xb6\xf7\xe2\x8d\xbc\t\xa8\x948\xda\x16\x16y\xbf\xbf\xb2\xf9nn\x0f\x99\xbf\x91\xb8d\x1a\xb6\xc0\xe0\xe5D\xca\x01\x01\xc4S\xa6\xcb\xbf\xc6\x9cN\x13\x0bn\xfa\xfd\x92\x04P\t\'\xab\x83\xe6o\xe4^\x14(\tj\xd8\xd9\xcc\x92\xdb\x89\xd9\x80\x96\xa4q\t\xb2M\x03Y\xfb7\x9ahp%\xa5\xebK\x04\xa1\x1f_\x99\xbf\x91x}\xaa:\xf3#?\xe5\t\xbc2\x8e(i\x96;\x1ax\x85H0`\x8fo\xb36,\x00&\xe2\x86\xb3\xf5~\xbe\xbf3\x7f"\xf0H6\x05x\x99\x1d\xb8\xdc\xca\x85 $\xbb\xb4.+\x02=>\xcd\xc0\x0b`)\x17\xa9\xb36Z|\xb7\xd7\xe6o\xe4^\x04\x06K\xe4\xe5\xc6\x88\x9e\x83\x12\xd7\xf6\xa1.\x11\x83O\xef\xeaD\x15\xd0u\xa7\x8b\x00\x92T\xdb\xf2\xf2\x1c[\x05\xa4\xc2G\xda\xa4\xc2\x0b\x97~,eq\xbdkZ>\xe2{\xfd\xaf\xc6m\xf5\xf7\xff\x00\xc5\x0f\xc9\xbf\xc8c\xd3\xc8h\xd6\xc1\x96\x9c\xa8\x1d@\xc3\x8b\xdb?4\x0cUZ\xc4K\xd8>\xd7\xe36\xe0 `\x1eC\x19ff^\xe15\xec\xff\x00\x8e/\x99\xbf\xdbq\xf1\x9bp1Q.\x0b0N\x91\xe4;\x8d\xe7\xe3\xfc\xcd\xfe\xdb\x8f\x8c\xdb\xc8\xeb\x08\xe0\x13\xc2Z;q\xfc\xcd\xfe\xdb\x8f\x8c\xdb\x83\x18\xc5\xb8\x17\xb4+\xf6VJ|(\xca0\xf4\xfes\tt0\xee\xd3n\x99\xfc\x9b\xe2\xb1O\x8e\xc2H\x1e\xf5\x84:\xf9KBeVn\x94\x1fhZ\x92dT\xe5xR\x15\x00f\xf5*?\x86\x95pRJ\xa8\x9c\xc0T@\x10L\xa32\x8e.\xbfk\x11\x04\x91=\xb86\xd9y\x95\xfe\xfe\x9a\xd4\xa4\x02\xa7\xf6\xc9qX\x00\xc31\xcaR\xaeps\xee\t\x7f\x14\xccD$\x00\xebo\xc5\x10\xf8\xc9)\xdcY(\xd9\xc2D\xca\x87`n\xff\x00\xc8\x8d~L\x03\x1c\xe2\xb61Z\xff\x00kN\xd9\xe4@\xbe\xec\xcdm+G\x882\x060\x8c`\xf4\xac\xe4\xe8\xfd\xa8\x06Az8:\xde&\xb4Mk\xbfJ&\\1\x11\x9e\xd5\n)\x02M\x1a\xd8\xfd\xd1\xca\x05\x82\x97\x9cE]\xc8\xc4\xa5\xd9G\xb5\x06E\xfd\xca\x8f\xb6K\x05r\x171\xad"E0\xc4m{\xd6\x9d%\xfb\x1a\xd0u\x80\xc3Rh\x920S\xf0\xf7"\\*H\xfa4\xb1"n*\xf8\xdf\xea\x87i;\x9fE"t\x8a\xb3+o\x7fF\x88Qsw\xb0\x8a\x00pH\x9c\xb6\x82\x9d\x880\x94\xe8\x8b\x94\xa2D\xfe)\x99\x80\x95t\xa7^\x92\xc8\x90\xf9\xf8\xcd/5\xf2~\xf5\xbf\xe2\x0e-\xd3\xd2\x8a\x91\xd1e\xa5\xa0\x13,\x9f\xbc \xdd\xa62\xf3\x1f\xd9\xcc\xf7\xac\x92MwT\xe6~\xfd*\xc9\x91z\x84\xcd\x16\x8c\x0c\xbe\xa1u>f4\x8fJ\x04\xefL23\xeb\x02F\x9b\x88]\x89n\xf1I\x80-,\xe3ZT\xeeW$\x10\xa1\xac\x91\xef\x81\xe9FMM8.\x17\x8d^\xbf\xc4\xc8\x82I\xb2\xd0\xee\x1f\xc2\x8e\x823\x99~(\tg\x03Z\xf1\xefG\xf5\xd6\xa7\xbf2\xcc\xb6^\xbc\xa8\x958\x86\xb7\xdc\xff\x00\r\x8a\xbb\xa2vkD\xe5[984\x98W2&\xc6k\x98\xe0\x8a\xe8\xfe\xa8]\xc3Az\x96\x93\x1d\x15\xa3\x1e\xe7\xf1\xc66^.}\x13:\x98\xa0\x92c\x9d\x10\x81\xd2`\x03j\x15\xa6 \x18\xf5\x92(\x8c\x92u\xa2\x843\xc3]\x1e\xb6\x8b\x1e\x1dr\xedz\x02!vU\xbc\x82zV\xc8L\xbf\x8b\x1d\x05r\x92\x9d\xb1%rT\xc1\x91\x11\xe8\x05\x14\x10\x1bP\xae\xe6\xa7\xb44\t\xaf%}\x9f\x97\xd3\xden\xa8X\x9d\xad\xf4$X\xe2"\x05YFLt\xff\x00\xe3\x87\xff\xda\x00\x0c\x03\x01\x00\x02\x00\x03\x00\x00\x00\x10\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3.\xb4\xbb\xf2?\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcc\xde\xc3\xcf\xe1\xd2\xe7<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<w\xf65\xc9n>#\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xc5\xf9\xd2\xea\x86\xb7\xfe<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf8\x99\xcb\x8c{\xff\x00\xff\x00\xa7O<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3G\xbf\xff\x00\xff\x00\xff\x00\xff\x00\xfb\x90\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xce\x12\xff\x00\xff\x00\xfeW\xff\x00\xff\x00\xfd\xff\x00<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xbd\xdf\xff\x00\xff\x00S\xd4\xff\x00\xff\x00\xef\xd3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xc8?\xff\x00\xfeu\xf1\xaf\x7f\xfe\xf5<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf/[\xff\x00\xff\x00\x81\xcf,\xf3\xff\x00\xff\x00G\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf0\xff\x00\xff\x00\xfe\xaf<\xf3\xcb\xdf\xff\x00\xf5|\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf\x15\xff\x00\xff\x00\x05\xf3\xcf<\xf3\x9f\xff\x00[\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xd5\xef\xff\x00\x83\xcf<\xf3\xcf\x1c\xff\x00\xf5\xbc\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xc1\xbe\xfe\xe7\xfc\xf3\xcf<\xf3\xdf?[\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf,\x1d\xdf\xe6s\xcf<\xf3\xcf,\xf4\xbd|\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3/\xff\x00\xe3o<\xf3\xcf<\xf3\xc0\xff\x00[\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf\x14\xff\x00\xff\x00\\\xf3\xcf<\xf3\xcf<\xc7\xf5\xbc\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xa9\xdf\xff\x00\x13\xcf<\xf3\xcf<\xf3\xc9\x7f[\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcd\xbf\xfe\xe7\xbc\xf3\xcf<\xf3\xcf<\xaf\xf7<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xff\x00\xe9\xf3\xcf<\xf3\xcf<\xf3\xca\xbf\xb3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xc4\xbf\xfe\x9f<\xf3\xcf<\xf3\xcf<\xab\xfe\xb8\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf8\xea\x91=o\xe9\xaa\xf3\xcf<\xf3\xcf<\xf3\xcbx\xfc\xcbNg|\xf8\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xb3G?\xeds\x1c\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf.+\x9c}\xfd\xf5|\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf\x0c=\xf7<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf1\xdf\xaf\xf7\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf<\xf3\xcf\xff\xc4\x00(\x11\x01\x00\x02\x00\x05\x03\x04\x02\x03\x01\x00\x00\x00\x00\x00\x00\x01\x00\x11\x10!1AP 0Q@aq\xa1\x81\x91`p\xe1\xf0\xff\xda\x00\x08\x01\x03\x01\x01?\x10\xfes\xa7\xa1\xe4?\xef\x88no\xa8\xa0\xd1\xfa\x96\xc4b\xf5TG=8\xbdWB&\xd1\x1c\xa2i(\xbb\xc0\xd0\t\xa3\xb0\x00\x95<VC\x0bi\x80W\xd27e-3\x8c\xc1R\x85\x1a\xfa\x83p\xd3\xbb\x8a\x11!^n\xe3T\xa97\x93\xf7\x052[\xed\xfeL\x85\xb9\xc6\xd0\x14"\xd5\xa1\xc58D\x01\xb0D\x19O\x10\x03\xa1t~x\x97!\x04\x07b\xdb\xca3-\xb8\x87\xb5\xf4(\x16\xc6\x13N\x92\x10\xf0\xe0\xad\x12\xbf\xa1\x91\xb5b+ \xdd\xbfA\xb0\xf0\xf6\xb6\xe8\x01l[\xd84\xc0,\xe8\xb88P\xb6\x88 :/\xd9\x97E\r\xfa\r>\x174\xf1\xd0\xf5\x1a\xbd)VJ|F\x87\xc7\x0bO\xef\x88\x0bb\xbfR\xf4\xf6\xc7K\xe3\x84\xa4\x80\x02\x8ch\xc9\xf9\xeb\xac\\t\xbe8Gjg\r\xb5x\x0b(\x89^\xb1\xa6+/\r/\x8e\x0c.\x08\x90%C\\+\x0e\xca\xab\xda#rJ\x96\xad\xf8\xe0\xce\xc7lP-\x8c\xab\xb3\xa9\x86\x97\xc7\x06\x05\xab\\O\xc8{\x81\xa5\xf1\xc1T\x10\x80c\xa1m\xdaU\x87K\xe3\x82\xa5\xf6\xc5\xca+\x1e\xe6\x19\x1e\x08fq\xfa\x1d\xbf\xb5\x81\xbb{\xf0C3\x1f\xa1\xdb\xfbXk\xfa\xed9pwHn0\x8ek\x95\x83"n\xd0\x07$\x16\xb4\xed\xd3xDk\x942\x17-\xd96*\x81\xba\'\xe2m\xd1F\xa7\xa7"\xf3\xb0\x03#\rY\x15\xa6\xa6\xa8\xfa\x1d\x11\x80o<?\xd4\xd1X&\x8e\x1a\xc9\x01C\xd2\x87\xban\xd3v\x8b~\x9cQ\xb2\x03\x1e\xf4[m\xfe\xa2\xff\xc4\x00)\x11\x01\x00\x02\x01\x03\x04\x01\x04\x01\x05\x00\x00\x00\x00\x00\x00\x01\x00\x111\x10!P 0Aq@Qa\x81\xa1\xd1`p\x91\xb1\xf0\xff\xda\x00\x08\x01\x02\x01\x01?\x10\xfe\xb9\xc83\xd5\x8d,\x95\xbc\x9f\xb8G0Y!\x1bqx<\xc2\x12&#\x99mV\x8a\x96\xba\x01\xdd\x90\xac8\xad\xc0\x85,\x94f\x15\xef\x1e\xbf\xd1\xfe"J\x1f\xf3\xfc\xc1\x0b?\r\xf4c\x8a\x04~\xaf2\xa2\xd0\xff\x00\xdb\xb2\xd6\xe2\x95\r6\x91\xb4\xa5}\xb6\xff\x00P\xb6\xe7\xdb\x1d\xdb\x00\'\x14\x88\x14_e\x97R\xd9k\xd1\xe5\xf1 -\x8ds\xd8\xa8`\x018\x82\xaat\x05\xb5\x1c_K\xb6\xb8u\xa2\xe5\x93\xd1\xbc8"\tLZ<t8\xa7\x0fI^\x84TB\xa0\xd3h\x88\xa9\xe8V\x0f\n\xb4\\{\x9e\x8a\xd6\xcfE\x85:\x15\xf0\xaa+\xf5\xe8\xdd\x9c\x1d)e2\xe8\xd5\xf0\xbb\x8dAZ&\xdd\xd5[\xf7k\x97\xdf\tv\xc5\xbdm\xdf\xd7\xb7\xeb\x97\xdf\x08j\t\x944b\x08\x14Q\xd6\xc4\xa6\xb4\xcb\xef\x84fb\x92\x9d7\xde\xcb\xf2\xb0i\xb8\xca\xda\xbe\xbc\x1a\xd2y\xd4-\xa8%\xd9`\xd3/\xbe\r\x1a\xea\xf6\xf8;C\x0e\x99}\xf0J\x8b\x11[\xaf\xe7{CF_|\x15\xc7\xdf\xa0P\x1d\xac\x9a-\xc7\x04\xb6\x1a\xe1\xf7\xdb\xc9\xa3\xae\n\xb75\xc3\xef\xb7\x93\x802\xa8\x87\x98\xf8\x08\x83b#l\xf0\x11+v5}\xbb\x82\x0f\x11\xdc\xd4\xa3\xcc\x17\x98\x9eHO\xc8A\x1c|wZ\x85\\\xe9\x8f!\xb2\x86\x01\xf0P\xe4\x8bx\x9f]<tQ\x93L\x13\x1d\x0b\xf1U\xf1\x16\xf1\x01\xe2c\xe3\xa5\xc5<O\xb5\x02\xb6\xfe\xd1\x7f\xff\xc4\x00-\x10\x01\x01\x00\x01\x03\x02\x04\x07\x00\x03\x00\x03\x01\x00\x00\x00\x01\x11!\x001AQa\x10 `\x810@q\x91\xa1\xb1\xf0P\xc1\xf1\x80\x90\xd1\xe1\xff\xda\x00\x08\x01\x01\x00\x01?\x10\xff\x00\xcb\xc6cE)\x9c\xc0\xb3\xbe\x9d\xe6]ns-C\xa1\x96\xeb,\xac\x0fga\xb5\xf4\x9a\xeap\x82{\xe3-\x0bI`\xa1\xf8u\x1e\x88P0\xbd\xb4"\xabPxs\xe0D\xc1/Sp\xd9\x10c\xa9\xd119\xc4\x02\xec\x87\x13\xdfM\xfc+&\nV7L9\x8f\xa5\xca#\x01\xb5`T\x1b\xe9\xbb\xa3[\x11\r\xa1or6\x8b\xc2p[uDV\xd0w\x8c\xeam\xea\x83\x80\x05;\xecgma/\x93\x0f<5\xf4\x9aV\x8d"\x96lX`\xe9\xa0SA\r\x1c\x82\xd61\xcb\xbe\xbb\x1b\xd2\x0e\xb8\'\x1d\xf4Dq@\x0b\xd1j}\xb4P\x01\xb4\n!\x14\x92\xf1\xe2\xc8I\xb8\x94\xd0\n\xf0\xa4#k6{\x9aW\xd2\x917\x11\xd3\x8a\x1c\xf5\xb6\x9e\x94\xdaD\xa2\xb0V\x1fCWU\x10\x81\xa4\x05\x9dGpg\x1a\r\xe7\x9f\x03\x95\xdd\xdfP\xb7H\xe24Jv\xd1B%\x07G\x0f\xe4\xf0\x03\x93\x07GY\xfeJ\x14\xaf9\xf2G\xa7\x91\xf7\xed\x1b\xbb\x0c\xde3\x88\xa6\xb1C\x08\x13a\x8b\xb5\xb4\xc2\x17\x17\xd2\x92\x1a\xe8B\x04\x86h\xe3\x18\xdd\xa9l\x12m\n`1\xd2{\xeb\x1e1\x9d2\x0fl\xf82%L\x05\xd7\xe0?^Q\xdc\xc99\xa5*\xef\xfe\xb5\xff\x00Q\xaeo\x12\x13\x86p\\\xfd\xbc\x90T\x87p,\x88\x83\xfdkjY\xd0\x1a\xa2P7m\xbe\x93\xe1\xc8\x83\x13\x0e\xd8K~t\xe8\x91\x8e\x10\t\xac\x82F!_\xfev\xd4\x9b\x9b8-\xe6o\xa0\x82\x11\x05g\xbe\xde\t\x1cB7\x0e\x1d\xb5\xfc\x8f\xfe\xe9\tm\x14\x88\x9b\x8f\x7f\x0c\x9e2B:\xc7M{s\xc7\xd9t \x8c5\xa1\xb7\xfb\xf2Y*f\xc6$t\xa1MC\x8f\r\xa4\x1b\xec\xe1\xe94\xf9\xca.\x88.*\x16o<@\xaeJ\xb9\x0b0\x19t#\x98\xa0R\xec\x11o\xb6\x90\x8d\xb6\xa2\xe1\x1c\x1fm"\xa9^\xab\xe1!\xf2\xa5P\xaeH]\xa9\x9bt\x1c\xf7x\x9dP\xc1\xdc\x1f\xa6\xae\x8f-\x15C\x05\xddz\xae\x8b\x0e\xdc\xd5\xfb\x07\xe3A\tD\xb0\xf4[\x0f\x14\xcct\xb6x\xcb\xa3\xae.\x86t\xd4S\xc7\xfa\xfd=\'\xa1L\x11\xc9\x13Lm\x9a\xc4\xeb\t\xfa\x18\xd9\xfa\xe8\xe2\x99\xf6\x91w\xfbg3\x1a\xea/\xe2\x96Bpc\xd1N\x9a\x90\x1a\xbcC\x0b%\xb6\r;2\tK5P\xbd\xca\x9aA\xb6\x80\x0cB1w\x8ai&%0Y\x97\xb2\xe3\xb6\xfa\x97\x0c\x9f\'8#Lh/\x10\x80\r6\t!5\xbdr\x92\x0e\xbc\xb4\x92b\x81\xb7\xb6\xa4bM\xb4\x16\xc3\xed\xd5\xaa%\xb2\x04\xcc\xe5\r\xa3\xb8q\xa5B1Ad\xe1:\xc9\x9f\x06\xcc$p\x94\xcff4Y\xe9\xcb\x84\x0e\xe3\x19\\w\xbe\x93D\xc8\x84r:\x91\x99\xe88DII\x89\x087f\xa6\x01\x0c\xde\x80a\xaeh2\x84`\\ve\xed\xbe\xb2 (\xd9\xc1\xa4\xfa\x01m\xb9\xban\x1d_\x178\\\xbe\xb7\xaf\x8a\xc5\x8a\x06\x80+\x0c\x02\x80/viR\x9b\x8e\x8d\xa0\x03\xc1\x87\xdbF\xbey-+y\x8d\xbc\xd7\xbfE9\xa2\x01[\x80\xcd\x8c\x9b\xe8-\xd1\x9e\x80j\td\xf4\x9d\x0bb\x1d\x1d-\xdf\xdd\xd7\xfd\xee\x8c\x0c\\\x9a\xbb_\x0f\xe3?\xd6\xbf\xae\xff\x00Z\xfe\xbb\xfdk\xfa\xef\xf5\xa1\xa1{\x04\x0fo:\x12\x90\x89\x1eF\xf43\xa4\x91\x0e\x8d\xac\x1d\x90\x10\xe7\x90zH\x11\x00\x15^4\xc8@\xc4\xd4\x14\x99A\x15\xbd\x8d;\xfcw$t]Y\xd8,\xc9\n[\x17\x8d9\xb0\x92\x85A\xe8\x8f\xa4`\x8f\xb2($\xa6@B#\x9b\xacus\n\x9c\xe2\xf7\xbb\x1f#yNs\xb0\x1a\xfeMQ5Y 3\x0b\x01\xc5\x96-\xf4\x82\xaa\x14\x08r\x01\xbe\x07\x1a\n+\x05\xb2"\xab\x97a14\x10\x03c\xe4P\x08\x04p\x8f: \n/@H\x8a\xa02-\xc1\xd0\xd0aE\x11\xe4\xf4y\x08Pl6\xf6\x10\xea\xb3\xb6f\xb0\xe8\xda\xa8\xa0\x07\xe2\xfb\xfc\x1aYK\xd3\xe1M\xe5\x9dP\x15]\xb5\xc5\x07^\xe0\xd00f\xdd\xf9\xf4q\x8aa[\x00U\xd00\xd0\xe6)\r\x14\xd2\x04\x01\xe6]\x0c\x11\x81\xd06\xf8\x00\x10H\xdd\xa1\xff\x00$\xa0I\xe0F\x08;:\xc5\x1c\x96\xcfx\xf8&\xfa\x1b\x80BC#\x03U<m\xe8\xea\x91\xd4l\xecb;/:un\xbb\x0e\x0f\x7f\x826\xf2\xcamCwU3\xdbL\xe9\xa5\x934\xa3 \xa3\x19t\x89F\x85\x1ae8(\x99+c`\xd1\x10\x1cu:=\x1f\x82\\\xd5\xdc\xa0\x8c\xc8\x9dn\x8b\x08\xf2\xf29\xd4G\x85\xa7\xa3K\xcd\xfcFe\xc71\x814a(l\xac\x08|\x06\xc1\x1b2\xb0+\xac2\xde4\x9a/\x00$\x12S\xaf\x83\xe1b\x904L#\xa5\xbfG\x81\x00\xc9&\xe0\xf3\x9d\x05\xe2\x81\xb2;?\x00\xee&\x05\\h\x1bT\xacU\xbf\xa8\xbe\xde\x8c\x8c\xbf\xd2\xae\x9eAeM\x8c\xa9\xa7&2\x94\x1d\xda\xb88\x0f\xa7\xc1m\x0f\xe1E@\xb6\x00\xd2\xab#\xab\xfa\xe1\x14\x82c\x00o\xdf>6\xe2^\xc2\xa6I\x105M\x04X\x8c\xd0\x11\r#\x111\xc1\xf08\xdb\xc7B\xdb\x8a\x91\xb4\xb2\xa5@\x9c>\x8c[\xedP\x16\xcey1\x8fI\xa0\x00\x80@\xe8|\x03,\x85\x91k\xab\xd8\xd1\x99\x96Ve\x17yP\xdbk\xb4\xf2\xe4k\xe8\xd7\x82D\xb5\xcb\x04\x15\xe5\xd4\xb6\x18\x03+\xafL\xc7\xe0\'\xfd2\xa9\xc4\xd8p\xbdS\xd1h\xb7\xb6\x80VH\x00\x84\xb3C\x08U\x18,\x96\xb5W-\xf3\xf0\x10\x90\x83r\x1d4E\xa6\x8e\x85\xa8\xc8Q\x90\xc4w\x04\x90\x00\x80\x10\x0f)\x96(\x85\x13\xa3\xa4\x89\xf4\x11t\x00\xc9L\xae\x82 \x88\x8e\xc9\xe744\x98\x96\x02Y\x83e\xd7\xd9\xbd%\xc9\x0b,\xb3\xd1C\x10\x02\x8af\xa2\xe0Xv\xd0\x01\x06\x00 \x1f\x00\xd7\xa5CX\xe4;9XiwL\x92$ \xb0Wy\x8f<\x8d\x12\x0cyJ\x88\xdc\xe5\x0e\x9akEJZ\xe8\x8cBq\xd3\xd204\xb8\x07\x9b\rn\x01^3\xa6\x00Bfk\x17s\x8f\x81\x1a\xb2\x1d\x8b\x81}\xf8\xe7[\xb2H\x84-\x01UXR?\x04\xdf\xa8\xf0\x13\x18\x16\x00\x0b\x8d\n\xa0\x90\xe4|\xc0H\x1d\xf93\x87|\xe9_\x12{\x89\xcd\r\xf3\x9cY\x9fD\x9fU\xb6\x94dm\r\x832\x8fMB\xd3=\xd7w\xce\xc8P\x8a\x18\xef\xa7\x01cO\x04g4P\r\xc7\xc2\x17\x96hJJ-[\x19\x8bP"\xd3#\xec\xdfzg\xcd\xf8\xef\xd3\xd1F\x00-@\rI\xc2`\x18*\xdf\xe0\x0bFrUpp\xb2\xa7m\x15lk\xe0~\xb1\xf86\x00\xc7\xc39\xab\x9c4\x88\x81x\xed\xb8\xf9\xbf\x1d\xfaz$\xc7\x82\x05\x01\x04\xcad\x10\xa72h\xaf\x85\x19\x92Vp\xd5\xc7\xd3\xce\xb5\xd8\x92\xdd`\xbd\xae\x88\xb8,\xa5\x87yG\x10\xd9#w\xf8\x94\xc4&\x8e8\x82Z\xd5\x92\xeaV\x02P)\xc8\xa7>_\xc7~\x9e\x893\x19V\xf4\x90\x90\x1e\x82\x92\x83\x87S\xb5#\xfd\xbf\x7f2\x81T\x0e\xae\x83\xd0\xce\x99\xe3\x95\xd4\xb3\x86h\xa5\xb8\x10\x9b\xc5+\x9b\xbf\xc45\xde\xbdb\x80u\xd1\x01\xc8\xa3n\x1f\xa7\xcb\xf8\xef\xd3\xd1\x06M\x01\xc2\xcb\x0b/\xb6\x97\x1f?\xb8K\xe4\x14\xe3\xe9\xe7\r@a\x0b\x9d\xd9\xd2\\\xf5M.\x90\xa4\xd8mE\x83\\\xb7[\x9b\xf1v@\x11\xfa:r8\x18\x08\n\xe2\xa5)q\xbb\xa7\x7f\'\xe3\xbfOD\x18\x04\x8d6hD\xd1PC\x96t\x03\x10.\x15{\xe4\xdc8\xf3\r UX\x06\xb0\xfd\n\x00q\xf3\xb6\x0c]\xcf\x08\x01\x0c\x1f\x1b\x91\xad+(\x0b\xb0\xc1\xfb:\xa6@\x8eDp\xf9?\x1d\xfaz \xc2W\xd6\x08\xa5\x02\xdfu\xdbC\x94cQ\xa5MH\x17\x83\x0b\xe5\x9e\x81\xc1Un\xed\xf5\xd2\x06\x10\xb2Bf^\x0b\xf8>8P\x14\x15\x9a\xe2z5R\x80O\xbf\x93\xf1\xdf\xa7\xa1\xcco\xb1\x98CD\xa5\x08R\xd9\xa2\x8b\xebC\x05P!\xb1\x89\xa2a\x99\n\x0fcEp"\xf2tp\xe8 \x07\x04\xf2N\xa3iMZ%jG\x18\xd0\x00\x00\x80\x18>>\xeb\xa09\xb49\xc0\xbe\xdaZ\xab*Mp\xfd\xbc\x04\xf8\x8aK\x9e\xd8\xd7\xfd\xee\x90\xa4!\xa2\x94\xc7\xa1\xcc\xccr8\x04\x8d\xc0\xb6\r\xbe\xda/\xca\xe6>j\xf3j \xc6\x0fw@/;\xd2l^\xce2}O\xc8\xeeg\x94\xee@\x88\x0b!a\xce\xfe\x0c\x01\x80\xde\xb3m\x00\x08\x10#\x06\xa7ep!\xb3\xd0\xc6\r\xed\x03\x0eG\xb3\xc8iyEu\xaeK\xdb`\x90\x98\x9euE\x12\xe2\x80\x1b\xd1^\x93:/\xf3\xdc\xa6Q\xba\xba\xab\xd3`\xf9!.\xfe?\x8e\xfd=\x0ca\xea2&\x03\x80\x99\xa1\x9aE\xd5\r\r\xacE\x1f\x87\xcd\x98\xc7x\xae\xa1:\xfd\x94\x85U\x92\\a\x11\xdf\xe4\xc4\xbb\xf8\xfe;\xf4\xf41\x98]g\x96\x81l6\xa9\x96g@( p\x1b\x1eeh\xc9\x19\x02\x01\xa1\\s\xc1\x83\x98\n\xb4\xdew\xf9\'\xec\x02P\x0e]Q\xc8\xd1\xd9\xf1\xfcw\xe9\xe8S\x082\x08\xb0\x03\xeb\xa2\xba\x11\x0c\xd8As\x07jy\xaf9\xdeX\x19u\xca\xb1N\xaa\xa3&\x97\x10&S\x17\xe4\xb3\xa0W\x82N\x80T;\xeb&\xff\x00$\xe2x\xfe;\xf4\xf4)\x92k<,\x02\xceV\xa1\xc5Z\xb0\x94\x13\xd7ay\x9em\xf3\x0bK\x92?\x8d\x00\xe4\x9a\x10\xd1wN}\xfeL>>0$\x03\xc8\x82<:\xfe_O\x17\xe3\xbfOB\x98\xb3\x07\xa0$\xb92Cx\xd1\xc7\x9f+{C`c\x82\xc2\x86\xd97\xd0\xe6"\x06\x07\x03\x05s\xef\xf2o\x07\xb7Fa\x81ex4\x04\x16!\xba\xb3\x1c\xf2\xf1\xfcw\xe9\xe8S-\xb40Fb\x8b\xda\xfd\xfc\xc6P\xd4W\xe5\xc7%S\x9d\xb3\x8e~W\x84\xf0Q\x04o\xdd}\xfcQ\xfa\x10+\xb3C\x13\xef$ \x1b\xa21\xe1=\x07\x99p\x9aBS1H\xf5\x17@\xe3\xa2\xc6\xc8\x03\xcd\x0eB\x0f\n\x18\xd2b\x04\x1c\t\'_D\x9co\xf2\xbf\xd7\xe9\xe3*\x00\xab9\xf5i\xe7D\xd4H\x95l\xa5Sx_A\x91\xb8Q\x04\xcb\x134\x8f}![\nn\xea\x9f\x84\xf3\x7fs\xa3@$|\xc8\xbfp\x07\xb7\xca\xff\x00_\xa7\x92z\x8b@\x9c\xfd\x06\x15\x9a\x0e\xe4\xaazT=\xf5\xfc\xfe\x8f7\xe3\xbfO\x963\xfa\xfd<\x95y\xb0(\x98\xbc\xb0Nk\xe80\x04\x11\x04L8\xe9\x01\x80\x01\x808\xf3~;\xf4\xf9c?\xaf\xd3\xc9\xfe\xdfG\xa0\xeat\xd4\x00\xcb\xfa:\xb9\xd3\xbb\xe6\xfcw\xe9\xf2\xc6\x7f_\xa7\x92\xf6\xc1IJ\x9d\x80\xd4R\x98\x94}\x16\xe9T| ]\x153\xfc\xe4p\x1eA\x18T\x03(h\xb3\xe9+d\x9b\x07\'2\xe89\xf0\x8d\xc9\'\xd5\x19\x1bi\xc0\xa1L\xf9@\x85qc\xf4t\x9e\x84\x9c!\x05\x01\xde\xfbh\x89\x94\x87q\x9a\xb8^|\x8e\n\xed\xa2\xef\x15 \x03\xae\x80*K\xb8}\xc2i.\xe2\x8b\x00\xb5\x19aY\xbe\xa8\xde\xd7LkU!C\x00\xf7\xf9]\xdc\xbe%S\x13\xbf\x92\x12\xa0\x897:<xuJ\x98WD7z\xe9\xc2\x19\xcd\xd5\xdc\x1d1\x8c2\x019\xe9;\xe3If@&\xcclB\xf5\xd1\xe0\x9e\xd9\xd2*]\xdf\x1d\x1c\xe8\x02\xc4\x8a\x89H\t\xd9\x04\xd1i \xc4\tDy4y\x03\xb0\x05\xff\x00"\xee\x860[\x82ja\xd8\xd1\xc3\x15\xa0]&\x1e\xd1\x03\xaf\x1a\xe7\xa7Bs\xc1c\x99\xb9\xb6\xde\x18b\x84 \xb4\x82\x10n\xe6Y\xd1-D\x05\xcc\x9e\xe9\xed\xa1\x01\r\x12\xa3\xf6\xd4:x\xa1\x02\x16\xca\xce\x9du\x98w2W\xa1\xb9\xc5\xdbXch\x1e!U)&&\xfa\xcd1\x9c\x95\xc1"\x90\xdd\xce40\xc2\x1a\xcb"\xb0^+5\x91\xdd\x11\xe1\x15e\xbd}\x93LQ\x04\x9a\x8d\xb0\x96W\x7f\x96\x196b8q\xc6u#\x9c\xac4\xa4\x83{\x02\xa4^\xce\xab\x0e\x02\x8a\xc5\xa5<\xb4mx\x18\x8f*\x13[|\x96\xd2\xd9;7\x11\xd6\'\xbd\x89}\x87\xcb\xbc\x8b\x03\xf3\xd9\xd0Q\x892\'s:\xff\x00\x80\xd1\r]M[(\xc3\xb2\x98M\xf4\xd3 T\xd8\x1a\xe5\xdb\x00] \x90\x8a\x00\xddH\xbd\x97Y]L\xaa\x9b\x9ac7[\xb4R\x0e\x06\x82m\x9d\xfb:1v*\x96\xc8\x98O\xf1O\xa2\xcb\xc0\x1b\xab\xc6\xad\x8b\xbd,\x13\x8a\xf7`\xdc\xb8\xd34\xd8\x86\x05l\xac\xb9W\xa6u\x89\x7f\'\x19\xf5\xf3%?bA\xf7t4\xd0\xc8p\'_\xb1\xa4\xc5\x8d(\xbc\xd8\x19\xc9\\A3\xad\xe0`PB,Rn@v\xd0\x00l\x02\x8e\xe9\xe4\xb9W\xe7\xea\xca\xed\x193G\x03\x9d\x18\xb3\x12\t\x93\x0e\x04\xe2[\xa3\x91\x9a\xa8\x03\x15\x10rP\xf1\xce\xa4\xf0KY\x07\x07\xbc\xdct,\xf8J\x85\xb3\xb9\x9f\xa6\x8a\x81\x10\xd7^\x0b\x85\xfa_5uYw"\xba#\xcd\xc8\x85\xebu\xb3C\xa5\x18\x90"o\xff\x00\xe6\x8aC\xa9\xd1A\x00-e9x\xff\x00\x12?\xb2\xe9\xc2\xa0\xc6A\x1e\x8d\r\xf3\xe4\xa7\x91z_2\x04\x06\xa3/\xb1\xaeO\x92\xb8\xe5x\x07+\x1ah\xb2\x062\n\x96\xf2\x18(a4\xb0ZeV\xa2\x8f\xbc\xbf\xe1\x8aUCF\xd8\x829\r\xf4A%\x00\x9a\xa8\xa7&p\x9dx\xd2\xde|Pb\xb1\xad:0\x9a5\xd4GT\xb8p\xa78;\xeb\xb9\x04\x00\xfa\x93G wQ\xfbM \x8b\n\x81\x1fo/\xf1:\xff\x00\xc4\x92\xc6\x04t\xe3\x07a\x12\xcc\xe1\xe0\xc0\x00\x02\x95\xfa\xaez\xcd\x95\x1d;b\x95\xc5\xd93\xbe\x89\x9dT%\xe4 qRT\xeb\xa64\x86\x00A\xfa\xdc\xebjRY\x13\xb1E\xfdh\x99\x86\x98\x08*!\x16\xc0\xc1\xb3\xaa\xc77x\xc1\x1e\xcc\xc6m\x86D\xea\xccU\xae\xc70\xff\x00\x16d\xe5\xa0\x80\xf5\xce\x99\xa6\x15D\xb5v\xd2Gq\xb3\xced\xae\xf3K\xcc\x01J\xd8\x8cBf\xa8\xf2\x1b\x01\xf2\x04\xecg*(v\xac\xf8\x06\x16\xa4\x15\x9a=\xdaw\xad\xd1}\x035\xc9\x9e\xd01\r\x94\xe1\xb9\xff\x00\xa7\x0f\xff\xd9')
None(None, None, None)
# WARNING: Decompyle incomplete
def main():
secret = input("What's the Ebin's most important secret?\n")
if not aggept(secret):
raise EbinException()
gus = None.c_buffer(secret[4:-1].encode())
segred = Ebin.from_address(ctypes.addressof(gus))
ebonatto = spawn(ebonatti, (ctypes.c_int64,))
eggbonde = spawn(eggbond, (ctypes.c_int64, ctypes.c_int64))
ergipto = spawn(ergipt, (ctypes.c_int64, ctypes.c_int64))
ebonatto(ctypes.addressof(segred))
dibide(segred)
eberse_drift(segred)
brawl_stars = ctypes.c_buffer(segred.sparde.to_bytes(8, 'little') * 2)
succ = ctypes.c_uint64 * 13()
eggbonde(ctypes.addressof(brawl_stars), ctypes.addressof(succ))
ergipto(ctypes.addressof(succ), ctypes.addressof(segred))
brawl_stars = ctypes.c_buffer(segred.spurdo.to_bytes(8, 'little') * 2)
eggbonde(ctypes.addressof(brawl_stars), ctypes.addressof(succ))
ergipto(ctypes.addressof(succ), ctypes.addressof(segred) + 8)
if int(gus.value.hex(), 16) == 0x3AF9670E06B9C43175FB8D6E90E1E6225CFF6AC8D52EFFAAL:
print('Ooh I see, wise old man...')
show_wisdom()
return None
raise None()
if __name__ == '__main__':
try:
main()
finally:
pass
print('bail :---D')
os.system('calc.exe')
os.system('pause')
return None
return None
Now, continue with the actual obfuscated function that used to processed our input.
import dis
dis.dis(aggept)
dis.dis(eberse_drift)
dis.dis(dibide)
105 0 LOAD_GLOBAL 0 (len)
2 LOAD_FAST 0 (a)
4 CALL_FUNCTION 1
6 LOAD_CONST 1 (29)
8 COMPARE_OP 2 (==)
10 JUMP_IF_FALSE_OR_POP 19 (to 38)
12 LOAD_FAST 0 (a)
14 LOAD_CONST 0 (None)
16 LOAD_CONST 2 (4)
18 BUILD_SLICE 2
20 BINARY_SUBSCR
22 LOAD_CONST 3 ('SAS{')
24 COMPARE_OP 2 (==)
26 JUMP_IF_FALSE_OR_POP 19 (to 38)
28 LOAD_FAST 0 (a)
30 LOAD_CONST 4 (-1)
32 BINARY_SUBSCR
34 LOAD_CONST 5 ('}')
36 COMPARE_OP 2 (==)
>> 38 RETURN_VALUE
19 0 LOAD_GLOBAL 0 (bytearray)
2 LOAD_FAST 0 (a)
4 LOAD_ATTR 1 (sparde)
6 LOAD_METHOD 2 (to_bytes)
8 LOAD_CONST 1 (8)
10 LOAD_CONST 2 ('big')
12 CALL_METHOD 2
14 CALL_FUNCTION 1
16 STORE_FAST 1 (b)
20 18 LOAD_GLOBAL 3 (range)
20 LOAD_GLOBAL 4 (len)
22 LOAD_FAST 1 (b)
24 CALL_FUNCTION 1
26 CALL_FUNCTION 1
28 GET_ITER
>> 30 FOR_ITER 14 (to 60)
32 STORE_FAST 2 (i)
21 34 LOAD_FAST 1 (b)
36 LOAD_FAST 2 (i)
38 DUP_TOP_TWO
40 BINARY_SUBSCR
42 LOAD_FAST 1 (b)
44 LOAD_FAST 2 (i)
46 BINARY_SUBSCR
48 LOAD_CONST 3 (5)
50 BINARY_RSHIFT
52 INPLACE_ADD
54 ROT_THREE
56 STORE_SUBSCR
58 JUMP_ABSOLUTE 15 (to 30)
>> 60 LOAD_GLOBAL 5 (int)
62 LOAD_ATTR 6 (from_bytes)
64 LOAD_FAST 1 (b)
66 LOAD_CONST 4 ('little')
68 LOAD_CONST 5 (('byteorder',))
70 CALL_FUNCTION_KW 2
72 LOAD_FAST 0 (a)
74 STORE_ATTR 1 (sparde)
76 LOAD_CONST 0 (None)
78 RETURN_VALUE
26 0 LOAD_GLOBAL 0 (bytearray)
2 LOAD_FAST 0 (a)
4 LOAD_ATTR 1 (spodro)
6 LOAD_METHOD 2 (to_bytes)
8 LOAD_CONST 1 (8)
10 LOAD_CONST 2 ('little')
12 CALL_METHOD 2
14 CALL_FUNCTION 1
16 STORE_FAST 1 (b)
27 18 LOAD_GLOBAL 3 (range)
20 LOAD_GLOBAL 4 (len)
22 LOAD_FAST 1 (b)
24 CALL_FUNCTION 1
26 CALL_FUNCTION 1
28 GET_ITER
>> 30 FOR_ITER 10 (to 52)
32 STORE_FAST 2 (i)
28 34 LOAD_FAST 1 (b)
36 LOAD_FAST 2 (i)
38 DUP_TOP_TWO
40 BINARY_SUBSCR
42 LOAD_CONST 3 (2)
44 INPLACE_FLOOR_DIVIDE
46 ROT_THREE
48 STORE_SUBSCR
50 JUMP_ABSOLUTE 15 (to 30)
>> 52 LOAD_GLOBAL 5 (int)
54 LOAD_ATTR 6 (from_bytes)
56 LOAD_FAST 1 (b)
58 LOAD_CONST 2 ('little')
60 LOAD_CONST 4 (('byteorder',))
62 CALL_FUNCTION_KW 2
64 LOAD_FAST 0 (a)
66 STORE_ATTR 1 (spodro)
68 LOAD_CONST 0 (None)
70 RETURN_VALUE
Convert the opcode manually to python code, validate the code by utilizing dis function.
Function aggept
def aggept(a):
if len(a) == 29:
if a[:4] == 'SAS{':
if a[-1] == '}':
return True
return False
Function eberse_drift
def eberse_drift(a):
b = bytearray(a.sparde.to_bytes(8, 'big'))
for i in range(len(b)):
b[i] += (b[i] >> 5)
a.sparde = int.from_bytes(b, byteorder='little')
Function dibide
def dibide(a):
b = bytearray(a.spodro.to_bytes(8, 'little'))
for i in range(len(b)):
b[i] //= 2
a.spodro = int.from_bytes(b, byteorder='little')
There are 4 functions constructed with function spawn which are brother, ebonatto, eggbonde, and ergipto. Lets take a look on spawn function
def spawn(c, args):
Unsupported argument found for LIST_EXTEND
Unsupported opcode: LIST_TO_TUPLE
buf = ctypes.c_buffer(c)
no_clean_pops.append(buf)
addr = ctypes.addressof(buf)
olt = ctypes.c_ulong()
eval('ctypes').__dict__['windll']['kernel32']['VirtualProtect'](buf, len(c), 64, ctypes.byref(olt))
if 'brother' in globals():
globals()['brother'](addr, gondola[len(no_clean_pops) - 2])
addr += 20
There is one crucial variable accessed through globals function which is brother. Because if brother defined, it will call brother after calling virtualprotect. From the documentation we know that VirtualProtect will change the protection on region of memory and the memory address will be in first argument of the function call. The first argument is buf
which is the return ctypes.c_buffer from first spawn argument. So basically the buf is the address of first argument in spawn. Now, look at the initialization of brother variable we can see that the first argument of spawn function is ebor. Because the process only change the protection we can assume that the ebor value should be assembly bytecode. Lets dump the value and open it using IDA.
Function brother
def write_to_file(fn, data):
out = open("exe/" + fn, "wb")
out.write(data)
out.close()
ebor = b'\xe9\x9a\x00\x00\x00\xe3q\x98\x9e\tt\x89\xe6\xbe\xce\x89R\x1egb\n\na\xaa\x0c\xe1\xe2\x10\xa1\x02\xba2\xc7[\xd9W\xbcqk\x82\xf8\xda\xdb\x01\xed\x1f\xc6\xb3\xd3W\xf8\xab.\x94\xe7,)\x89\xfb\xe8\x9dA\xb7\x926c\xb3\xc5\xd5\x83\xfd#\xef\xc4\x92\x18 p\xee:\xe9\xb9\xc1x\xc3\xce\xb9\xcah}\xf5\xe3\xb8\xee\xe9-\xaf\xe0I#\x1e\x9c\x95 M\xe7h\xa5\xbb\x99*\xc9\xc3\x939\xd6\xa5\x1d\xdeT\xfd\xdcl\xfam\x04\xc4i\x96\xca?\xa0\n}\r\xa38\x98\xe5\xf9 \x8b\xc5\x1b\x15\x08\x88\xb2\x1bE\x91\xc2\x1d\xa5\xbe<\xd0\x8b\x97\x89T$\x10H\x89L$\x08UWH\x81\xecH\x01\x00\x00H\x8b\xecH\x8b\x85`\x01\x00\x00H\x83\xc0#H\x89E\x08\xb8\x01\x00\x00\x00Hk\xc0\x16H\x8b\x8d`\x01\x00\x00\x0f\xbe\x04\x01\xc1\xe0\x08H\x98H\x8b\x8d`\x01\x00\x00H\x8dD\x01\x19\xb9\x01\x00\x00\x00Hk\xc9\x15H\x8b\x95`\x01\x00\x00H\x0f\xbe\x0c\nH\x03\xc1H\x89E(\xc7ED\x00\x00\x00\x00\xeb\x08\x8bED\xff\xc0\x89EDHcEDH\x8bM\x08\x0f\xbe\x04\x01\x85\xc0t\x02\xeb\xe6\xc7Ed\x00\x00\x00\x00\xeb\x08\x8bEd\xff\xc0\x89Ed\x8b\x85h\x01\x00\x009Ed}>HcEdH\x89\x858\x01\x00\x00\x8bEd\x99\xf7}D\x8b\xc2H\x98H\x8bM\x08\x0f\xbe\x04\x01H\x8bM(H\x8b\x958\x01\x00\x00\x0f\xbe\x0c\x113\xc8\x8b\xc1HcMdH\x8bU(\x88\x04\n\xeb\xafH\x8d\xa5H\x01\x00\x00_]\xc3\xcc\xcc\xcc\xcc\xf5\xc5\xbf\xdb\xb0I\xf8\xaa\xb0\xd2 |-\x9e\x8b\x99\xb7\xee\x10\xe5\xcf;\xb0\x8f\xa2B\xf0\xfd\xd9\x10*0\xf6\x10\x99t\xb1\x83&_Wx\xd7\xcdr\'H\x0c\xc3\xf8\x98Z\xfa\xd1E\xbdnJ\xce\xc4\tC\xa8\xafo\xc7\xd2\xe2\xc7\x18\xfb\x8dt\xbae\xfd\n\xb67;$@\xb0%\x8e\x02{\x94\x98"1\xa1\x80\xc9\x1aC|\xd2\x82\xb4:\xe4\xe2L\xf3\xe0\xc3\xf6\xaa\xa2*\xad}\x9f;\x8a\xc1\xd0\xa9\xfcq\x02U\xb5\x97\x18\x9d\xa79\xc0\x17\xb0\xa4\x11^\xec[d\x13\xf86\xe5\xd0\x96{1\xbf\x83\x0b\x80\xcd\xcb\xe0\xbb\x8b=\xa4Y\x9c\xab\xb8\xb5p\xf8\x1d\xc3oo\xf5*\x9c\xbf\xd0"\xe1J\xba\xdehn\xb1\xf5D\xec_90\xbds&y\x00\xdbK\xe3Mw\x7f[:\x9a\x9f\xe6I\x13\x88*\x98\xeb\xdd\x1e\xa2]\xd6\x07q\xff\x9d\xd9\x1c\xf8\xc5\xf9Gs\xc9\x92\x88\x82\xe9]\xe6+d&p\xf4\xf3\xd6\xf3\xf8\x07\x89?>\x9a-\xa4\x13\xb7l\xd0\xa3\x98\xeaQ\x9b\x07\\\xcepo\x94\x07\xceF\x10\xa9\xb2\x89\xdcD:-I\xd4v>l\xffr\xd4\xa6\x98N\x94.D\x84\xcd\xbaI\xbc c8\xe9\xab\x18\xab\x17rg\xc5\x0fc\xcb\x9d\xe8s\xa9\xb3\xddd\x92\xbb%\x94\xdc\x19\xb3\xed\n\x82\x00\xb4J\xc3x\xe5\xb78)\xc7\x9d\x7f\xe0h\x95\x14:\x0c\x1d\xd7\xd4\xf3?V\x0e\'=\xfc\xfa2\x85\x95\xcf\xdc;\xd4\xcb\xc8\xc3\xfb\x1a\tE\x94x\x9aC@\x1d\x92\xe7\xbc\xabd!\xe98?\x04\x15\xba\x00\x14\x1f\x0f\xf9\xbb\xc0\x87\xd3FV\xd1\x8cMC\xbb\xbe\xbd\x9f}\x05\x8b\x9b\x9c=/\xee\xb6\x12\x07iL\xb8\x05\tp\x8d\xae\x97\xfcgb\xeae\xde\xa2>\x8a\x13\xc0\xf7\'\xa4\xce&\xb9\x88\xcf(.\xbbO\xdc\xae\xb27T9Y\r\x02\xec\xec\x91\xc0Z\xea\xe4{\xf9\xc6|\xe1\xd3>C\xef\n;\xd77\x0e\x9bJ?\x96\xc0\xec\xc6\xa7W\x87\x86\xda\xfd\xcf\x8c\xe3\xdc\xb3HU\x1c\x1cO\xa5~/\xad\x8c}\xc14\x96\x0e\x1c.q\xd3\x1d4\xc6\x9c\x94\xe6P\x12$\xc5\x9eL)\x82\x14\xebG72\xb6D\xe9\x1dj\xe1\xf9b\xaf;\xff\xf8\x84\x91\xa5\xbc\xb7\xce\x8erh\x1a\xa6\x03\x9de#\xdb\xa3\x9am\xe4O/\xc1V8\xfeK\xc9:\xf6\x0e#\x90\x90\xbf\x82\xc7\xc4]\x0f\x1f\x92\x03\xf4^\xd0\xa98\x98\xdd\xcb\xea\xa9B\xa7\xcd\xca\xee\xdf\xf9\xff\x9c\x87_H\xcfc \xf6\xaer\xc1l\x0b\x06\xc7\x11nL\xf7'
write_to_file("brother.exe", ebor)
Load as x64 file, then go to address 0x0. Go to the address of jmp instruction to view the actual code.
Press p or create function to make a function of those code.
__int64 __fastcall sub_9F(__int64 a1, unsigned int a2)
{
__int64 result; // rax
__int64 vars8; // [rsp+8h] [rbp+8h]
__int64 vars28; // [rsp+28h] [rbp+28h]
int i; // [rsp+44h] [rbp+44h]
int j; // [rsp+64h] [rbp+64h]
__int64 vars138; // [rsp+138h] [rbp+138h]
vars8 = a1 + 35;
vars28 = *(char *)(a1 + 21) + a1 + (*(char *)(a1 + 22) << 8) + 25;
for ( i = 0; *(_BYTE *)(vars8 + i); ++i )
;
for ( j = 0; ; ++j )
{
result = a2;
if ( j >= (int)a2 )
break;
vars138 = j;
*(_BYTE *)(vars28 + j) ^= *(_BYTE *)(vars8 + j % i);
}
return result;
}
Lets modified some variable to make it easier to understand. Convert the __int64 to char * also for several array variable.
__int64 __fastcall sub_9F(char *a1, unsigned int a2)
{
__int64 result; // rax
char *key; // [rsp+8h] [rbp+8h]
char *ciphertext; // [rsp+28h] [rbp+28h]
int i; // [rsp+44h] [rbp+44h]
int j; // [rsp+64h] [rbp+64h]
__int64 vars138; // [rsp+138h] [rbp+138h]
key = a1 + 35;
ciphertext = &a1[256 * a1[22] + 25 + a1[21]];
for ( i = 0; key[i]; ++i )
;
for ( j = 0; ; ++j )
{
result = a2;
if ( j >= (int)a2 )
break;
vars138 = j;
ciphertext[j] ^= key[j % i];
}
return result;
}
So basically it just do xor for two data, look at brother function call we can understand that it xor first and second argument.
globals()['brother'](addr, gondola[len(no_clean_pops) - 2])
Next, convert brother algorithm to python code
def brother(ciphertext, key):
ciphertext = list(ciphertext)
for i in range(len(ciphertext)):
ciphertext[i] ^= key[i%len(key)]
return ciphertext
We already have brother function, so lets get another function bytecode. The problem is during the competition i can't find the correct key for each function, so i choose to directly dump the bytecode from memory using python. To dump all the bytecode we need to do it sequentially like the original code.
def get_asm(func_name, size):
tmp = ctypes.cast(func_name, ctypes.c_void_p)
s = (ctypes.c_char * size).from_address(tmp.value)
return s.raw
ebonatto = spawn(ebonatti, (ctypes.c_int64,))
print(get_asm(ebonatto, len(ebonatti)))
eggbonde = spawn(eggbond, (ctypes.c_int64, ctypes.c_int64))
print(get_asm(eggbonde, len(eggbond)))
ergipto = spawn(ergipt, (ctypes.c_int64, ctypes.c_int64))
print(get_asm(ergipto, len(ergipt)))
Write to file again for all the bytecode then open each of it using IDA.
def write_to_file(fn, data):
out = open("exe/" + fn, "wb")
out.write(data)
out.close()
ebonatto = b'\xe9w\x00\x00\x00fnk~\xb7U\x9bh\x8bDHb\xc8t*\x80J\x90\x00\xcaF\xacYO\xfa\xfc\xc5>\xe3\xf6X\xef\xad\xc5|\x04\xd5\x94l\xd0o\x1fr\xdb\xa8+\xcc\x83\xff\xaaV\x12\xaf\xd55\x86\xbfkm\xd8\xce\xf3\xf2xL1\xd3\xfea\xfb\x08\x92\xe6\x8c\xf4\x94\xd8\tb\xfb\x13}\xdf\xf8\xfc\xedQ\\4n\xc1\x86\xfc\x0f\x11\xee\x9e\xca<\x1c\xa2c\x9e3\xdeI\x11!\x99b\xb2=k\x9a\x88B\xe3j\xd5H\x89L$\x08UWH\x81\xecH\x01\x00\x00H\x8b\xec\xc7E\x04\x01\x00\x00\x00\xc7E$\x02\x00\x00\x00\xc7ED\x00\x00\x00\x00\xc7Ed\x00\x00\x00\x00\xeb\x08\x8bEd\xff\xc0\x89Ed\x83}d\x19}_\x8bE\x04\x89ED\x8bE$\x89E\x04\x8bED\x8bM$\x03\xc8\x8b\xc1\x89E$\x8bEd\x99\x83\xe2\x07\x03\xc2\x83\xe0\x07+\xc2H\x98H\x8b\x8d`\x01\x00\x00\x0f\xbe\x04\x013E$\x89\x854\x01\x00\x00\x8bEd\x99\x83\xe2\x07\x03\xc2\x83\xe0\x07+\xc2H\x98H\x8b\x8d`\x01\x00\x00\x8b\x954\x01\x00\x00\x88\x14\x01\xeb\x93H\x8d\xa5H\x01\x00\x00_]\xc3\t\xb6}f\xdd\x8bH\x89\x8f%\xc1\xea\xf3\xd2\xb6\xe1}!`\x14\x86Fx\xe0\xe3<Y\xb47\xf7\xe8\xaa\xd42\x86\xa1`\xdcm\xec\x19\xdf\xef\x179^pe\xc0\xe2Oh\xe1/\xbc\xea\xb7\x9b\xeb.I~2\x10\xc3!5\xc0\x13G%\xba\xe0\xfd\x1e\xe5\xe6\xfe-\xed~p\xe5\x9f\xd5\xdf\xd9e\xaba\xec\xc2\xd2B\xaaQ\x15\x8b\x98\xee<\x07*\xea\xec5F\'\xb4\xa1S\x1c\xc7\t?\xf0K\xbf\x12\xd4Zq\xa3\t\x1e\x92\xd4\xbe\xc9\x0b\x87v\x86@J\x1an\xdaV\x19 w\xe1tZ\x90T4 (Qf\x9f.\xfdH\x0f\xe64\x80Su\xe5sC.C\x84\t-\xe9\x94\xa0\xce\xa0xcZ:\xa9\x96\x04\xfc\xd4\x19{\x16WQ\xc267:J\xcfX\t\xbd\x87\x94\xe1k\x020|S@\xb1x\rE\x9e\x9b\x03\x97\xd5\xf8\x90\xd8;\x9a\xd0\x82)G*t\x89\x98\xee\xb4#\xc3\xfa\x9b\xc7N\xa4\xb5=\xcau\xc7-\xa1\xd7\x19\xfd\xa1uL\x02$\xb3\xdc}\x83Da\xf7\xb1S*\xb3?1\x1f\x95?\xa2\xeaK\xe4{\x0f"j\xdb\xf0\x88\x97\xd1S\xe6A5<\n\xa5C\x984!U\xc5\x82\xc5\xd0:r\xd3\x80ur+\xe1U\xb4\xe2\x1d\xc5UA&\x0f\xc9:[\x8f\xee\x04\x00\x9a>)\x86\xe8\x94\xc91\x96\xdb\x87\xbd\xe8Un\xd2\xe1P\xaf\xd6\xac\x10\xbd\x9e\x98\xb0*z\xa4\xbfB7!@1X\xe7\xd6\xce\xd1\x9e\x05v\xfd\x8dWy\x9b(?^w:-\xa0,Ep\xa80\t\xd5\x08\x98rb\xa7O\xa0\xab/\xff\xfe\x9eu\xb24O\xb3\x06=\xdc\xb1K\xf8}\xa8e\x12.>\xe9_:q4z\x0f\xaee\xac&D\xa1\xed\xf1W\x1d\xe9\xab\x86\xc4u\x90\xe2~\xd3%A\xc4\xdb\x06]\xe6\xcec\xb4\xdex\xa3#\x81\xe8t\x99\xb8A\xa0\xfb:\xa6u2\x1e\xab\x8c\x98f\x04P\x9e)\x9c\x8a\xae\xee\xdd\x0f\xcc6\xe9n\x1eeB^e\xc5O\xc6_\x10o\xf6/I\x98R\xae7S\xf2\xf4w=p\xa0\xe8\x84#RK\xb8V]\xf5U\xc5\x95\x8b\xd5VP\xf9\xe1\xef\xde\xc0{\xee\xd3\x85\x9a\n*\xc7\x8c\x1d\x1a\xf8\xce\xa2\xcc\xe1?\x90\x7fmt\xfe\xf8\x91t\x18\x13\xbd\x1d\x0eJ\x99^\xdb\r\x88\x81\x04\xdesk\xf3\xe8\xfdAL\xeas\x13I\xee\xe3)3V`=\x9c\xfd\x81\x96D\n\x81\xe1LZgv\x1fSgH\xaei\xdbf\xb9p\x0c\xa4\xd0\x83e\x9a\xf8\xa0\x04C\xa4\xdc\xa8\x11\x0c\xe3"3\x8d.ArF\xda3c-|\xf9\xda\x96\xa4\xf0\x9e\xe7G\xa7\xb8>|\xea\x7f5\xb3\xfb\x81t\x945\xf6d8\x88\xd0\x06y\x08\xf0\xc5\xd9\x04(L\xe7\x91XL\x8cK\x8e\x03\xb0\x13\xef\xf0g\xe5\xf9\x1d\xa2.\x8b\xc3n2(\'\x94.\xcf\n\x94R7O\x9f\x19:\xda\x96\x94\x86\\\xa3\xea\x00\x00\x00\x00\x00\x00\x00\x00\xe9l\x86\xb7\x00\x08\x00\x80\xf0\xdb\xd0\xbb'
eggbonde = b'\xe9^\x00\x00\x00vJ\xc0\xe3\xb4\x7f\x9c\x91\xa1\x12\x91\x99\xbd\x0e\x95\x0e\x7f\xc8h\xd6\x93\r\xe8k\xc1 \x00\xeav\xb0\xc5\xd0$\x9b-\xe8\t\x1c\x89\xde\xd7(\x02\x8d1\xb8\x1en$\xfa.tU\xe5j\xd2H\x01\xdbB\x88?\xbc"\xed\xb6\x9d\xf02]u\x9a\xb1\x8a\xae^\xe8\xa4\xad\x05\n}\x05\\\xc6\xdb\xa8\x96\x9b\xcc\x05\xa9W\xd3H\x89T$\x10H\x89L$\x08UWH\x81\xech\x01\x00\x00H\x8b\xec\xc7E\x04\x00\x00\x00\x00\xc7E$\x00\x00\x00\x00\xc7ED\x00\x00\x00\x00\xc7Ed\x00\x00\x00\x00\xb8\x04\x00\x00\x00Hk\xc0\x00H\x8b\x8d\x88\x01\x00\x00\xc7\x04\x01cQ\xe1\xb7\xc7ED\x01\x00\x00\x00\xeb\x08\x8bED\xff\xc0\x89ED\x83}D\x1as%\x8bED\xff\xc8\x8b\xc0H\x8b\x8d\x88\x01\x00\x00\x8b\x04\x81\x05\xb9y7\x9e\x8bMDH\x8b\x95\x88\x01\x00\x00\x89\x04\x8a\xeb\xcd\xc7Ed\x00\x00\x00\x00\x8bEd\x89ED\xc7\x85\x84\x00\x00\x00N\x00\x00\x00\x8b\x85\x84\x00\x00\x00\x89\x85T\x01\x00\x00\x8b\x85\x84\x00\x00\x00\xff\xc8\x89\x85\x84\x00\x00\x00\x83\xbdT\x01\x00\x00\x00~\x0c\xc7\x85X\x01\x00\x00\x01\x00\x00\x00\xeb\n\xc7\x85X\x01\x00\x00\x00\x00\x00\x00\x83\xbdX\x01\x00\x00\x00\x0f\x84\x03\x01\x00\x00\x8bEDH\x8b\x8d\x88\x01\x00\x00\x8b\x04\x81\x03E\x04\x03E$\xc1\xe0\x03\x8bMDH\x8b\x95\x88\x01\x00\x00\x8b\x0c\x8a\x03M\x04\x03M$\xc1\xe9\x1d\x0b\xc1\x89\x85T\x01\x00\x00\x8bEDH\x8b\x8d\x88\x01\x00\x00\x8b\x95T\x01\x00\x00\x89\x14\x81\x8b\x85T\x01\x00\x00\x89E\x04\x8bEdH\x8b\x8d\x80\x01\x00\x00\x8b\x04\x81\x03E\x04\x03E$\x8bM$\x8bU\x04\x03\xd1\x8b\xca\x83\xe1\x1f\xd3\xe0\x8bMdH\x8b\x95\x80\x01\x00\x00\x8b\x0c\x8a\x03M\x04\x03M$\x89\x8dT\x01\x00\x00\x8bU$D\x8bE\x04D\x03\xc2A\x8b\xd0\x83\xe2\x1fA\xb8 \x00\x00\x00D+\xc2A\x8b\xd0\x0f\xb6\xca\x8b\x95T\x01\x00\x00\xd3\xea\x8b\xca\x0b\xc1\x89\x85X\x01\x00\x00\x8bEdH\x8b\x8d\x80\x01\x00\x00\x8b\x95X\x01\x00\x00\x89\x14\x81\x8b\x85X\x01\x00\x00\x89E$\x8bED\xff\xc03\xd2\xb9\x1a\x00\x00\x00\xf7\xf1\x8b\xc2\x89ED\x8bEd\xff\xc03\xd2\xb9\x04\x00\x00\x00\xf7\xf1\x8b\xc2\x89Ed\xe9\xb7\xfe\xff\xffH\x8d\xa5h\x01\x00\x00_]\xc3\xd0\xe7I!\xcb\x00\x01\xe9\xba5\x08e\xbc%-\xdf\xe1\xb9\x08f\xcc\x8a\x9f\xc9\xf4\xdd\x8aJb\xd9\xbb\x97\xe3\xba\xfez\xb7i\xa1\xae3\x0f\xe2\x1a\xf3eb#\xa0\x15\x95\x16\x8aw\x9f<\xbeJ\xadl\xcd\x18\xbcX\x00\xb0<M{DD8\x18\xdd2?X\xdd\xf4\xa9\x94#\xe2N\xa4[\xaf\x97\xb0\x83\n=\xf8\xdf+\xee\xb6)\xfbr\x99\xc1\xb36\x0b\x0b\rS\xab\xf5A\xb0\xb2\x90(\xcc\x81Q\x05z\xf9Z\xfc\xae\xf0P7\xf61\xbc\xd7\x8d\xfbQ\x06,\x85c\xcfK]4#\x87\xf7)t\xc9\x93I\xc5\xe9\xdc\x8fF\xd6dMm\x9f\x99\x99\xd7\xa7|\x7f\xe5A\x10g\x9e\xbb)\xf90{\x17\xc34{c\xe03\xfa\xfd\xb12\x97\\\xa1\xc8\xba\xf5#:\xd0\x91J\xd4\xc56)\r\x00\xa4JpGK\x7f\x85m\xf5\x10\xa5\xf6\xa3\xe4D\xf9\xeda\xf0K\xe1\x1bY\xb9oN\x1c)\xff\xdc?\x8a\xb1p\xfflBJ\xe2cwN\x94~\xf8x\xcf\xe1lm\xbfC\xb0\x9f\xcc\x99Fbpw\xad\x16\n\x1cl\x8c\xd3s\x05\x0e@Ts\xbam\x1cV\x1f"\xba\xeb\xa4\xed\xd0\x88E\xd0\xe7:\xde\xd1\xa8;\xaf\xb6\xf8\x06y\xdd\xcb*\xf7\xfd\x06ih4h\xae+O>5\xaf\x07\xc9\x87\xc7\x91\xa8pt\xf32w\xdb\xd8q\xfb2\xa0ky\x85\xc0Y\xd2\x16uC\x04l\x84\x881\xefz\x02\xa5\xda\x87A\xe5$\xb7\xf6\xb13\x02\xdd|\xe21\x9d\x8d\xe9\x85\xd3\xf7\xc1\x00\xf47\xc2E?\x01\xdb\xee\xfc\xe8\x89\xa1\xaa\xd1\x84\xd8<\x9cBV\xc0\xce\xc4,X\x13p\xc0u\xba\xc2\xf9\xab\x80\xd2\x00\x00\x00\x00\x00\x00\x00\x00\xa8l\xc7\xb7\x00\t\x00\x90p\xf2\xe1\xb9'
ergipto = b'\xe9=\x01\x00\x00\xdb\xf7\x18\x86\xb3\x91*S\x81\x04\x7f\xa8\x9a\xc7&\x9dN\x8e\x00\xda\xcd\xed\xd2gb\x82\x8a>\xba\x9bJ\xa57\x08,$[\xaa\xd6}\xa7^\x16\xfc`\xbd\xcc-\xce\x0b\xa3\x13d%*\xcf\x8d\x1f\x01z\xeb^\xd6I\xa9\xd6\xaa\xf0\xaf\n@\x00\x80\x92\rk\xa0\xb7\x92\x06\xc6\x1e-N\xde\x11\xf0\x0c/H\xd4\xc5\xcb}R\x01\x8bH\xba\xef\xd0B\x11\xea\xc4\x87J\xc4+g\xe3Ul\xcc\x13\x03\x1b\x0b\xf2!V\x8c?\xb7\x0b\xd7UMjU\xa8\x86b\xac\xf1\x10ubZ\x06B4v\xd0\xfdZ1\xf5\x04;\x07#v\xe6@\xd7O\x0b\x93j\x1eX\x92\x84?\x83D\x99\x18\x89\r6\xd5\xee\x8c\xba\nF\xb1\xb3Q\xfc\x85Q\x1ed\x08h\x86_\x04\xf8\x94\x18\x94?\xee]\x08h\xc8`\xa9\x05\xc6&\xce\x18\t#G\x84COV\xe8\xb6\xc8_\x94\xb3\xd5&uQ`[*\xe1\x9a\xe4\x86\x99f]\x98\xdd2\xaa0/\x15)\xfd\x8aY9&\x93P8\xfa\x96\xa87\x0f\x97\x8fb\xdf\xe5_%\x0b\xb5\xccA\xbe\xc6\x1dM\xcb\xd5\xb1\xd4Ed\xbfa\xa21\xbc2\xdf&\xa7\x1a\x1c1y\x1b\x07\xb2\xd6|\xd6\xc2\xe9\x02\xa5\xa3_\xbd@\x90+\x96\xefe\xe0\xc5a\x80\x9b\x0e\x8b^H\x89T$\x10H\x89L$\x08UWH\x81\xecH\x01\x00\x00H\x8b\xec\xc7E\x04\x00\x00\x00\x00\xeb\t\x8bE\x04\x83\xc0\x02\x89E\x04\x83}\x04\x04\x0f\x83W\x01\x00\x00\x8bE\x04H\x8b\x8dh\x01\x00\x00\x8b\x04\x81\x89E$\x8bE\x04\xff\xc0\x8b\xc0H\x8b\x8dh\x01\x00\x00\x8b\x04\x81\x89ED\xb8\x04\x00\x00\x00Hk\xc0\x00H\x8b\x8d`\x01\x00\x00\x8b\x04\x01\x8bM$\x03\xc8\x8b\xc1\x89E$\xb8\x04\x00\x00\x00Hk\xc0\x01H\x8b\x8d`\x01\x00\x00\x8b\x04\x01\x8bMD\x03\xc8\x8b\xc1\x89ED\xc7Ed\x00\x00\x00\x00\xeb\x08\x8bEd\xff\xc0\x89Ed\x83}d\x0c\x0f\x8d\xb5\x00\x00\x00\x8bED\x8bM$3\xc8\x8b\xc1\x8bMD\x83\xe1\x1f\xd3\xe0\x8bMD\x8bU$3\xd1\x8b\xca\x89\x8d4\x01\x00\x00\x8bUD\x83\xe2\x1fA\xb8 \x00\x00\x00D+\xc2A\x8b\xd0\x0f\xb6\xca\x8b\x954\x01\x00\x00\xd3\xea\x8b\xca\x0b\xc1\x8bM\x04\x03\xc9\x8b\xc9H\x8b\x95`\x01\x00\x00\x03\x04\x8a\x89E$\x8bE$\x8bMD3\xc8\x8b\xc1\x8bM$\x83\xe1\x1f\xd3\xe0\x8bM$\x8bUD3\xd1\x8b\xca\x89\x8d4\x01\x00\x00\x8bU$\x83\xe2\x1fA\xb8 \x00\x00\x00D+\xc2A\x8b\xd0\x0f\xb6\xca\x8b\x954\x01\x00\x00\xd3\xea\x8b\xca\x0b\xc1\x8bM\x04\x8dL\t\x01\x8b\xc9H\x8b\x95`\x01\x00\x00\x03\x04\x8a\x89ED\xe99\xff\xff\xff\x8bE\x04H\x8b\x8dh\x01\x00\x00\x8bU$\x89\x14\x81\x8bE\x04\xff\xc0\x8b\xc0H\x8b\x8dh\x01\x00\x00\x8bUD\x89\x14\x81\xe9\x96\xfe\xff\xffH\x8d\xa5H\x01\x00\x00_]\xc3\xb30(\xeeoc\xbb\xbbU\x01MO\x83\x93\xba\x81\xe5\x11.\xf6pc\xf7\xcf\xd6\xddI\x89\xf4\xeb\xb6\xb65\xa6\x12s\xeb\xe1+yv\x1c\xcc\xcc\xcb\xfa\xfd\x9c\xf9\xdbl\xdd\x08f\xc4X\x90\xe7\x83\x0e\r\x89\xb7\x88 \xbe\r\xeb\x0f\xaa\x97\x17\xa299>A\xc1\xb8\xa7\xea\xef\x1dj\xc1\xf7\xc2[,\xf3fh\xc0\xca#[\xae\x12[\r\xf7\xab\x8d\xbcV\x1fg\x13\x85\x0c\'\x08|\xb4\xdfj\xd4\xd9\xb5d\xaa\xec\xfd\x16\xf4\xe6Xm\xa8\xd3))\x1f\x8a((d\xd6\x9fW\xd9t\x05R\x7f\xe7\xad\xc8\xae\xd5\xc7\x0fC\x02\xcb\x03|\xdcP\x9b\xcd\x8e\xd1sa\x89\'\x97[\x00\x0fM\xf0\xcfn\xbfG\x1b\x19k\xc9\xa7W\xf6\xfa\x9c\xa6\xf2Y\xe1#wm.\xfb\x12"\xbf\xc4\x831\x80k:\x87\xcb\xbd\x94<l\x19\x084\xc8Js\xc8\xe9\x85>\x1c\xfeZ\x06 \xd2\x8a\x91\x19\x14\xa6>\xbdb\xd9^\xcc\xc6B[\x0f\x00\x84\x99\xa3\xdd1\xdf\x0b\x97\xb8\xfe\xdd\xe2\xac\xe4k\xc7\xd4\xaef`\xb7x\x06\x14\xac"\xe4+\x1e\x14\x10]\xa6\xe5\t\xa2\t\x00\x00\x00\x00\x00\x00\x00\x00\xa4o\xdb\xb6\x00\r\x00\x80\x90A\xce\xbb'
write_to_file("ebonatto.exe", ebonatto)
write_to_file("eggbonde.exe", eggbonde)
write_to_file("ergipto.exe", ergipto)
ebonatto function
__int64 __fastcall sub_7C(__int64 a1)
{
__int64 result; // rax
int vars4; // [rsp+4h] [rbp+4h]
int vars24; // [rsp+24h] [rbp+24h]
int vars44; // [rsp+44h] [rbp+44h]
int vars44a; // [rsp+44h] [rbp+44h]
int i; // [rsp+64h] [rbp+64h]
vars4 = 1;
vars24 = 2;
vars44 = 0;
for ( i = 0; i < 25; ++i )
{
vars44a = vars4;
vars4 = vars24;
vars24 += vars44a;
*(_BYTE *)(a1 + i % 8) ^= vars24;
result = (unsigned int)(i + 1);
}
return result;
}
Convert it to python code
def ebonatto(a1): # correct
a1 = list(long_to_bytes(a1)[::-1])
vars4 = 1
vars24 = 2
vars44 = 0
for i in range(25):
vars44a = vars4
vars4 = vars24
vars24 += vars44a
vars24 &= 0xff
a1[i%8] ^= vars24
a1 = bytes_to_long(bytes(a1)[::-1])
return a1 & (2**64 - 1)
eggbonde function
__int64 __fastcall sub_63(__int64 a1, _DWORD *a2)
{
__int64 result; // rax
unsigned int vars4; // [rsp+4h] [rbp+4h]
int vars24; // [rsp+24h] [rbp+24h]
unsigned int i; // [rsp+44h] [rbp+44h]
unsigned int vars44a; // [rsp+44h] [rbp+44h]
int vars64a; // [rsp+64h] [rbp+64h]
unsigned int vars64; // [rsp+64h] [rbp+64h]
int vars84; // [rsp+84h] [rbp+84h]
int vars154; // [rsp+154h] [rbp+154h]
unsigned int vars154a; // [rsp+154h] [rbp+154h]
int vars158; // [rsp+158h] [rbp+158h]
vars4 = 0;
vars24 = 0;
vars64a = 0;
*a2 = -1209970333;
for ( i = 1; i < 0x1A; ++i )
a2[i] = a2[i - 1] - 1640531527;
vars64 = 0;
vars44a = 0;
vars84 = 78;
while ( 1 )
{
vars154 = vars84;
result = (unsigned int)--vars84;
if ( vars154 <= 0 )
break;
vars154a = ((vars24 + vars4 + a2[vars44a]) >> 29) | (8 * (vars24 + vars4 + a2[vars44a]));
a2[vars44a] = vars154a;
vars4 = vars154a;
vars158 = __ROL4__(vars24 + vars154a + *(_DWORD *)(a1 + 4i64 * vars64), (vars24 + vars154a) & 0x1F);
*(_DWORD *)(a1 + 4i64 * vars64) = vars158;
vars24 = vars158;
vars44a = (vars44a + 1) % 0x1A;
vars64 = (vars64 + 1) % 4;
}
return result;
}
Convert it to python code
def eggbonde(a1, a2):
vars4 = 0
vars24 = 0
vars64a = 0
a2[0] = 0xB7E15163
for i in range(1, 0x1a):
a2[i] = (a2[i-1] - 0x61C88647) & (2**32 - 1)
vars64 = 0
vars44a = 0
vars84 = 78
while True:
vars84 -= 1
if vars84 <= 0:
break
vars154a = ((vars24 + vars4 + a2[vars44a]) >> 29) | (8 * (vars24 + vars4 + a2[vars44a]))
a2[vars44a] = vars154a & (2**64 - 1)
vars4 = vars154a
vars158 = rol(a1[vars64], (vars24 + vars154a) & 0x1F, 32)
a1[vars64] = vars158 & 0xff
vars24 = vars158
vars44a = (vars44a + 1) % 0x1A
vars64 = (vars64 + 1) % 4
ergipto function
__int64 __fastcall sub_142(_DWORD *a1, __int64 a2)
{
__int64 result; // rax
unsigned int i; // [rsp+4h] [rbp+4h]
int vars24; // [rsp+24h] [rbp+24h]
int vars44; // [rsp+44h] [rbp+44h]
int j; // [rsp+64h] [rbp+64h]
int vars134; // [rsp+134h] [rbp+134h]
for ( i = 0; i < 4; i += 2 )
{
vars24 = *a1 + *(_DWORD *)(a2 + 4i64 * i);
vars44 = a1[1] + *(_DWORD *)(a2 + 4i64 * (i + 1));
for ( j = 0; j < 12; ++j )
{
vars24 = a1[2 * i] + __ROL4__(vars44 ^ vars24, vars44 & 0x1F);
vars134 = vars24 ^ vars44;
vars44 = a1[2 * i + 1] + __ROL4__(vars24 ^ vars44, vars24 & 0x1F);
}
*(_DWORD *)(a2 + 4i64 * i) = vars24;
*(_DWORD *)(a2 + 4i64 * (i + 1)) = vars44;
result = i + 2;
}
return result;
}
Convert it to python code
def ergipto(a1, a2):
a2 = list(long_to_bytes(a2))
for i in range(0, 4, 2):
vars24 = a1[0] + bytes_to_long(bytes(a2[i*2:i*2+2]))
vars44 = a1[1] + bytes_to_long(bytes(a2[(i+1)*2:(i+1)*2+2]))
for j in range(12):
vars24 = a1[2*i] + rol(vars44 ^ vars24, vars44 & 0x1F, 32)
vars134 = vars24 ^ vars44
vars44 = a1[2*i + 1] + rol(vars24 ^ vars44, vars24 & 0x1F, 32)
a2[i*2] = vars24&0xff
a2[i*2+1] = (vars24 & 0xffff) >> 8
a2[(i+1)*2] = vars44&0xff
a2[(i+1)*2 + 1] = (vars44 & 0xffff) >> 8
a2 = bytes_to_long(bytes(a2))
return a2
Put it all to one file
from Crypto.Util.number import *
rol = lambda val, r_bits, max_bits: \
(val << r_bits%max_bits) & (2**max_bits-1) | \
((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
ror = lambda val, r_bits, max_bits: \
((val & (2**max_bits-1)) >> r_bits%max_bits) | \
(val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
def ebonatto(a1):
a1 = list(long_to_bytes(a1)[::-1])
vars4 = 1
vars24 = 2
vars44 = 0
for i in range(25):
vars44a = vars4
vars4 = vars24
vars24 += vars44a
vars24 &= 0xff
a1[i%8] ^= vars24
a1 = bytes_to_long(bytes(a1)[::-1])
return a1 & (2**64 - 1)
def dibide(a):
b = bytearray(a.spodro.to_bytes(8, 'little'))
for i in range(len(b)):
b[i] //= 2
a.spodro = int.from_bytes(b, byteorder='little')
def eberse_drift(a):
b = bytearray(a.sparde.to_bytes(8, 'big'))
for i in range(len(b)):
b[i] += (b[i] >> 5)
a.sparde = int.from_bytes(b, byteorder='little')
def eggbonde(a1, a2):
vars4 = 0
vars24 = 0
vars64a = 0
a2[0] = 0xB7E15163
for i in range(1, 0x1a):
a2[i] = (a2[i-1] - 0x61C88647) & (2**32 - 1)
vars64 = 0
vars44a = 0
vars84 = 78
while True:
vars84 -= 1
if vars84 <= 0:
break
vars154a = ((vars24 + vars4 + a2[vars44a]) >> 29) | (8 * (vars24 + vars4 + a2[vars44a]))
a2[vars44a] = vars154a & (2**64 - 1)
vars4 = vars154a
vars158 = rol(a1[vars64], (vars24 + vars154a) & 0x1F, 32)
a1[vars64] = vars158 & 0xff
vars24 = vars158
vars44a = (vars44a + 1) % 0x1A
vars64 = (vars64 + 1) % 4
def ergipto(a1, a2):
a2 = list(long_to_bytes(a2))
for i in range(0, 4, 2):
vars24 = a1[0] + bytes_to_long(bytes(a2[i*2:i*2+2]))
vars44 = a1[1] + bytes_to_long(bytes(a2[(i+1)*2:(i+1)*2+2]))
for j in range(12):
vars24 = a1[2*i] + rol(vars44 ^ vars24, vars44 & 0x1F, 32)
vars134 = vars24 ^ vars44
vars44 = a1[2*i + 1] + rol(vars24 ^ vars44, vars24 & 0x1F, 32)
a2[i*2] = vars24&0xff
a2[i*2+1] = (vars24 & 0xffff) >> 8
a2[(i+1)*2] = vars44&0xff
a2[(i+1)*2 + 1] = (vars44 & 0xffff) >> 8
a2 = bytes_to_long(bytes(a2))
return a2
class Ebin():
def __init__(self, val):
self.spurdo = bytes_to_long(val[:8][::-1])
self.spodro = bytes_to_long(val[8:16][::-1])
self.sparde = bytes_to_long(val[16:24][::-1])
def get_hex(self):
result = long_to_bytes(self.spurdo)[::-1] + long_to_bytes(self.spodro)[::-1] + long_to_bytes(self.sparde)[::-1]
return result.hex()
inp = b"SAS{0123456789abcdefghijklmn}"
segred = Ebin(inp[4:-1])
segred.spurdo = ebonatto(segred.spurdo)
dibide(segred)
eberse_drift(segred)
succ = [0 for i in range(0x1a)]
brawl_stars = list(segred.sparde.to_bytes(8, 'little') * 2)
eggbonde(brawl_stars, succ)
segred.spurdo = ergipto(succ, segred.spurdo)
brawl_stars = list(segred.spurdo.to_bytes(8, 'little') * 2)
eggbonde(brawl_stars, succ)
segred.spodro = ergipto(succ, segred.spodro)
print(segred.get_hex() == '0x3AF9670E06B9C43175FB8D6E90E1E6225CFF6AC8D52EFFAA')
I alsi create function that communicate through pyinjector to debug each function
ebonatto = spawn(ebonatti, (ctypes.c_int64,))
eggbonde = spawn(eggbond, (ctypes.c_int64, ctypes.c_int64))
ergipto = spawn(ergipt, (ctypes.c_int64, ctypes.c_int64))
secret = "SAS{0123456789abcdefghijklmn}"
gus = ctypes.c_buffer(secret[4:-1].encode())
segred = Ebin.from_address(ctypes.addressof(gus))
print("init",gus.value.hex())
ebonatto(ctypes.addressof(segred))
print("0",gus.value.hex())
dibide(segred)
print("1",gus.value.hex())
eberse_drift(segred)
print("2",gus.value.hex())
brawl_stars = ctypes.c_buffer(segred.sparde.to_bytes(8, 'little') * 2)
succ = (ctypes.c_uint64 * 13)()
print("3 brawl", brawl_stars.value.hex())
eggbonde(ctypes.addressof(brawl_stars), ctypes.addressof(succ))
print("3",gus.value.hex())
print("succ", list(succ))
print("3 brawl", brawl_stars.value.hex())
ergipto(ctypes.addressof(succ), ctypes.addressof(segred))
print("4",gus.value.hex())
brawl_stars = ctypes.c_buffer(segred.spurdo.to_bytes(8, 'little') * 2)
eggbonde(ctypes.addressof(brawl_stars), ctypes.addressof(succ))
print("5",gus.value)
print("5 brawl", brawl_stars.value.hex())
ergipto(ctypes.addressof(succ), ctypes.addressof(segred) + 8)
print("6",gus.value.hex())
During the competition, after recover all the code my team notice that the algorithm is RC5. After that we directly try to use rc5 to decrypt but it failed, so there is something "modified" from the RC5 algorithm. It takes long time for me to notice the different and the different is the loop, look at the code below
for ( i = 0; i < 4; i += 2 )
{
A = *S + *(_DWORD *)(data + 4i64 * i);
B = S[1] + *(_DWORD *)(data + 4i64 * (i + 1));
for ( j = 0; j < 12; ++j )
{
A = S[2 * i] + __ROL4__(B ^ A, B & 0x1F);
vars134 = A ^ B;
B = S[2 * i + 1] + __ROL4__(A ^ B, A & 0x1F);
}
*(_DWORD *)(data + 4i64 * i) = A;
*(_DWORD *)(data + 4i64 * (i + 1)) = B;
result = i + 2;
}
Line 7 and 9 in original RC5 use S[2*j] instead of S[2*i]. So the code above use value from the block loop instead the round loop.
Modifying the original rc5 then we can decrypt the ciphertext from the challenge. To get all parts of the flag we need to reverse the flow.
brawl_stars = list(segred.sparde.to_bytes(8, 'little') * 2)
eggbonde(brawl_stars, succ)
segred.spurdo = ergipto(succ, segred.spurdo)
brawl_stars = list(segred.spurdo.to_bytes(8, 'little') * 2)
eggbonde(brawl_stars, succ)
segred.spodro = ergipto(succ, segred.spodro)
Total input is 24 bytes
First encryption
Sparde is last 8 bytes (16-24), so the first encryption use the last 8 bytes as the key and it will encrypt the 0-16 bytes
Second encryption
Spurdo is first 8 bytes (0-8), so the second encryption use the first 8 bytes as the key and it will encrypt the 8-24 bytes.
We know that the second encryption use the first 8 bytes of data and it not encrypted and the end. So basically we know the key of the second encryption, after that we can get the first encryption key which is the last 8 bytes. Last, we can reverse the operation to get the rest flag.
class RC5:
def __init__(self, key, w=32, R=12, strip_extra_nulls=False):
self.w = w # block size (32, 64 or 128 bits)
self.R = R # number of rounds (0 to 255)
self.key = key # key (0 to 2040 bits)
self.strip_extra_nulls = strip_extra_nulls
self.T = 2 * (R + 1)
self.w4 = w // 4
self.w8 = w // 8
self.mod = 2 ** self.w
self.mask = self.mod - 1
self.b = len(key)
self.__keyAlign()
self.__keyExtend()
self.__shuffle()
def __lshift(self, val, n):
n %= self.w
return ((val << n) & self.mask) | ((val & self.mask) >> (self.w - n))
def __rshift(self, val, n):
n %= self.w
return ((val & self.mask) >> n) | (val << (self.w - n) & self.mask)
def __const(self): # constants generation
if self.w == 16:
return 0xB7E1, 0x9E37 # return P, Q values
elif self.w == 32:
return 0xB7E15163, 0x9E3779B9
elif self.w == 64:
return 0xB7E151628AED2A6B, 0x9E3779B97F4A7C15
def __keyAlign(self):
if self.b == 0: # key is empty
self.c = 1
elif self.b % self.w8:
self.key += b'\x00' * (self.w8 - self.b % self.w8) # fill key with \x00 bytes
self.b = len(self.key)
self.c = self.b // self.w8
else:
self.c = self.b // self.w8
L = [0] * self.c
for i in range(self.b - 1, -1, -1):
L[i // self.w8] = (L[i // self.w8] << 8) + self.key[i]
self.L = L
def __keyExtend(self):
P, Q = self.__const()
self.S = [(P + i * Q) % self.mod for i in range(self.T)]
def __shuffle(self):
i, j, A, B = 0, 0, 0, 0
for k in range(3 * max(self.c, self.T)):
A = self.S[i] = self.__lshift((self.S[i] + A + B), 3)
B = self.L[j] = self.__lshift((self.L[j] + A + B), A + B)
i = (i + 1) % self.T
j = (j + 1) % self.c
def encryptBlock(self, data):
A = int.from_bytes(data[:self.w8], byteorder='little')
B = int.from_bytes(data[self.w8:], byteorder='little')
A = (A + self.S[0]) % self.mod
B = (B + self.S[1]) % self.mod
for i in range(1, self.R + 1):
A = (self.__lshift((A ^ B), B) + self.S[2 * i]) % self.mod
B = (self.__lshift((A ^ B), A) + self.S[2 * i + 1]) % self.mod
return (A.to_bytes(self.w8, byteorder='little')
+ B.to_bytes(self.w8, byteorder='little'))
def decryptBlock(self, data, key_index):
A = int.from_bytes(data[:self.w8], byteorder='little')
B = int.from_bytes(data[self.w8:], byteorder='little')
for i in range(self.R, 0, -1):
B = self.__rshift(B - self.S[2 * key_index + 1], A) ^ A
A = self.__rshift(A - self.S[2 * key_index], B) ^ B
B = (B - self.S[1]) % self.mod
A = (A - self.S[0]) % self.mod
return (A.to_bytes(self.w8, byteorder='little')
+ B.to_bytes(self.w8, byteorder='little'))
def encryptFile(self, inpFileName, outFileName):
with open(inpFileName, 'rb') as inp, open(outFileName, 'wb') as out:
run = True
while run:
text = inp.read(self.w4)
if not text:
break
if len(text) != self.w4:
text = text.ljust(self.w4, b'\x00')
run = False
text = self.encryptBlock(text)
out.write(text)
def decryptFile(self, inpFileName, outFileName):
with open(inpFileName, 'rb') as inp, open(outFileName, 'wb') as out:
while True:
text = inp.read(self.w4)
if not text:
break
text = self.decryptBlock(text)
if self.strip_extra_nulls:
text = text.rstrip(b'\x00')
out.write(text)
def encryptBytes(self, data):
res, run = b'', True
while run:
temp = data[:self.w4]
if len(temp) != self.w4:
data = data.ljust(self.w4, b'\x00')
run = False
res += self.encryptBlock(temp)
data = data[self.w4:]
if not data:
break
return res
def decryptBytes(self, data, key_index):
res, run = b'', True
while run:
temp = data[:self.w4]
if len(temp) != self.w4:
run = False
res += self.decryptBlock(temp, key_index)
data = data[self.w4:]
if not data:
break
return res.rstrip(b'\x00')
def ebonatto(a1):
a1 = list(a1)[::-1]
vars4 = 1
vars24 = 2
vars44 = 0
for i in range(25):
vars44a = vars4
vars4 = vars24
vars24 += vars44a
vars24 &= 0xff
a1[i%8] ^= vars24
a1 = bytes(a1)[::-1]
return a1
from Crypto.Util.number import *
known_pt = b"TESTING1"
known_ct = ebonatto(known_pt)
key_ebo = []
for i in range(len(known_pt)):
key_ebo.append(known_ct[i] ^ known_pt[i])
ct_flag = 0x3AF9670E06B9C43175FB8D6E90E1E6225CFF6AC8D52EFFAA
ct_flag = long_to_bytes(ct_flag)
first_key = ct_flag[:8]
cipher = RC5(first_key*2)
block_ct = [ct_flag[8:16], ct_flag[16:24]]
for key_index in range(0, 4, 2):
block_ct[key_index // 2] = cipher.decryptBytes(block_ct[key_index // 2], key_index)
block_ct_2 = [first_key, block_ct[0]]
pt_block = []
cipher = RC5(block_ct[-1] * 2)
for key_index in range(0, 4, 2):
pt_block.append(cipher.decryptBytes(block_ct_2[key_index // 2], key_index))
fix1 = b""
for i in range(8):
fix1 += bytes([pt_block[0][::-1][i] ^ key_ebo[i]])
fix2 = b""
fix2_1 = b""
for i in range(8):
fix2 += bytes([(pt_block[1][i] * 2) & 0xff])
fix2_1 += bytes([(pt_block[1][i] * 2) + 1 & 0xff])
fix3 = b""
for i in range(8):
tmp = (block_ct[-1][i] >> 5)
fix3 += bytes([(block_ct[-1][i]-tmp) & 0xff])
flag1 = fix1[::-1] + fix2 + fix3[::-1]
flag2 = fix1[::-1] + fix2_1 + fix3[::-1]
print(flag1)
print(flag2)
# SAS{h3_1S_do1n6_l3g_3x3rC1s3}
Did little guess for the middle 8 bytes and got the flag
Flag : SAS{h3_1S_do1n6_l3g_3x3rC1s3}
The integrity of a world is at stake. A notorious hacker 3vil_Uranus has taken the FNEICS (Federal Nuclear Energy Interactive Control System). Try to understand this complicated interface faster than the 3vil_Uranus can do. Hurry up, you have very little time!
Given access to URL, we can see that the URL do validation for the input on wasm. The validation can be seen in index.js, so the next step is try to decompile the wasm file using ghidra.
Look at exports section to get all the check function.
Check1 is straight forward, so just copy the value for each index.
undefined4 export::check1(char *param1)
{
undefined4 local_4;
if (((((*param1 == -0x49) && (param1[1] == '$')) && (param1[2] == '`')) &&
((param1[3] == '\x05' && (param1[4] == '5')))) &&
((param1[5] == '1' && ((param1[6] == 'i' && (param1[7] == 'r')))))) {
local_4 = 1;
}
else {
local_4 = 0;
}
return local_4;
}
Below is the solution for check1
param1 = [0 for _ in range(8)]
param1[0] = chr(- 0x49 & 0xff)
param1[1] = '$'
param1[2] = '`'
param1[3] = '\x05'
param1[4] = '5'
param1[5] = '1'
param1[6] = 'i'
param1[7] = 'r'
inp1 = list(map(ord, param1))
print(inp1)
Check2 just use xor operation with static value as validation
undefined4 export::check2(int param1)
{
byte local_1d;
int local_1c;
byte local_18 [8];
byte local_10 [16];
local_10[0] = 5;
local_10[1] = 0xaa;
local_10[2] = 0x32;
local_10[3] = 0xad;
local_10[4] = 0xb4;
local_10[5] = 0x15;
local_10[6] = 0x20;
local_10[7] = 0x8f;
local_18[0] = 0x28;
local_18[1] = 0x19;
local_18[2] = 0xf3;
local_18[3] = 0x59;
local_18[4] = 0x7d;
local_18[5] = 0x42;
local_18[6] = 0x16;
local_18[7] = 0xcb;
local_1c = 0;
while( true ) {
if (7 < local_1c) {
return 1;
}
if ((local_10[local_1c] ^ *(param1 + local_1c)) != local_18[local_1c]) break;
local_1c = local_1c + 1;
}
return 0;
}
Below is the solution
local_10 = [0 for i in range(8)]
local_18 = [0 for i in range(8)]
local_10[0] = 5
local_10[1] = 0xaa
local_10[2] = 0x32
local_10[3] = 0xad
local_10[4] = 0xb4
local_10[5] = 0x15
local_10[6] = 0x20
local_10[7] = 0x8f
local_18[0] = 0x28
local_18[1] = 0x19
local_18[2] = 0xf3
local_18[3] = 0x59
local_18[4] = 0x7d
local_18[5] = 0x42
local_18[6] = 0x16
local_18[7] = 0xcb
inp2 = []
for i in range(8):
inp2.append(local_10[i] ^ local_18[i])
print(inp2)
For function check3, it just generate static value using unnamed_function_6 with argument 0x2e. The easy way is by leaking the value through debugger.
uint export::check3(int param1)
{
int local_18;
int local_14;
int local_c;
int local_8;
uint local_4;
local_8 = param1;
local_c = unnamed_function_6(0x2e);
for (local_18 = 0; local_18 < 4; local_18 = local_18 + 1) {
*(&local_14 + local_18) = *(local_8 + local_18);
}
local_4 = local_14 == local_c;
return local_4;
}
To call the function directly from console we can use below code (i got it from my friend, vidner).
Boolean(Module.ccall("check3", "number", ["array"], [FromHexString("01020304")]));
Set breakpoint at 0x8f70 then run the code above.
Look at stack and the target value is 1836311903 (0x6d73e55f). Put it on python script
from Crypto.Util.number import *
tmp = 1836311903
inp3 = long_to_bytes(tmp)[::-1]
inp3 = list(inp3)
print(inp3)
For the check4, we can reverse the operation to get the valid input.
uint export::check4(int param1)
{
int local_1c;
int local_18;
int local_14;
int local_10;
int local_c;
int local_8;
uint local_4;
local_c = 0xb;
local_10 = 0x69b43d76;
local_14 = 0xc945c42;
local_8 = param1;
for (local_1c = 0; local_1c < 4; local_1c = local_1c + 1) {
*(&local_18 + local_1c) = *(local_8 + local_1c);
}
local_4 = local_c * local_18 - local_10 == local_14;
return local_4;
}
Below is the solution for check4
local_c = 0xb
local_10 = 0x69b43d76
local_14 = 0xc945c42
inp4 = (local_14 + local_10) // local_c
inp4 = list(long_to_bytes(inp4))[::-1]
print(inp4)
Check5 also has reversible operation
undefined4 export::check5(int param1)
{
int local_70;
int local_6c;
ushort local_68 [4];
int local_60 [4];
int local_50 [4];
int local_40 [4];
int local_30 [4];
int local_20 [6];
int local_8;
local_8 = param1;
local_20[0] = 0x11;
local_20[1] = 0x12;
local_20[2] = 0x1a;
local_20[3] = 2;
local_30[0] = 0x10cd6;
local_30[1] = 0xd360;
local_30[2] = 0x17c87;
local_30[3] = 0x3b9e;
local_40[0] = 9;
local_40[1] = 0x20;
local_40[2] = 0x1d;
local_40[3] = 8;
local_50[0] = 0x4f0a;
local_50[1] = 0xcff8;
local_50[2] = 0x151a7;
local_50[3] = 0x1676d;
local_60[0] = 0x2f8e9e;
local_60[1] = 0x1c7f4b8;
local_60[2] = 0x232e190;
local_60[3] = 0x6cc2d;
for (local_6c = 0; local_6c < 8; local_6c = local_6c + 1) {
*(local_68 + local_6c) = *(param1 + local_6c);
}
local_70 = 0;
while( true ) {
if (3 < local_70) {
return 1;
}
if ((local_20[local_70] * local_68[local_70] + local_30[local_70]) * local_40[local_70] +
local_50[local_70] != local_60[local_70]) break;
local_70 = local_70 + 1;
}
return 0;
}
Below is the solution
local_20[0] = 0x11
local_20[1] = 0x12
local_20[2] = 0x1a
local_20[3] = 2
local_30[0] = 0x10cd6
local_30[1] = 0xd360
local_30[2] = 0x17c87
local_30[3] = 0x3b9e
local_40[0] = 9
local_40[1] = 0x20
local_40[2] = 0x1d
local_40[3] = 8
local_50[0] = 0x4f0a
local_50[1] = 0xcff8
local_50[2] = 0x151a7
local_50[3] = 0x1676d
local_60[0] = 0x2f8e9e
local_60[1] = 0x1c7f4b8
local_60[2] = 0x232e190
local_60[3] = 0x6cc2d
inp4 = []
for local_70 in range(4):
tmp = (((local_60[local_70] - local_50[local_70]) // local_40[local_70]) - local_30[local_70]) // local_20[local_70]
inp4 += list(long_to_bytes(tmp))[::-1]
print(inp4)
In last check (check6) there are so many input validation
But we can see there are pattern on the validation so we can extract constraint and solve it using z3. During the competition i can't got valid solution for the constraint and when checking it on ghidra i found something weird.
Take a look on the offset, on disassembler it shows 0x4 but on decompiler it shows 1. Besides that there are also different in size used for each index, sometime it use 4 bytes, sometimes 2 bytes, and sometimes also 1 byte. To overcome this issue we can decompile the wasm to c using wasm2c then parse the decompiled code to get valid index and valid size. So the last step is writing the solution which has been explained previously in python, below is my solution
import re
from z3 import *
from Crypto.Util.number import *
def find_constraint(data, value):
pattern = f"local_c = {value}"
found_end = -1
for i in range(len(data)):
if pattern in data[i]:
found_end = i
break
assert found_end != -1
pattern2 = "local_c == "
pattern3 = "local_c != "
found_start = -1
local_c_count = 0
for i in range(i, -1, -1):
if "local_c" in data[i]:
local_c_count += 1
if pattern2 in data[i] or pattern3 in data[i]:
found_start = i
break
assert found_start != -1
constraint_start = -1
constraint_end = -1
for i in range(found_start + 1, found_end - 1):
if "if" in data[i]:
constraint_start = i
if "{" in data[i]:
constraint_end = i + 1
break
if " == " in f[found_start]:
local_c = f[found_start].split(" == ")[-1].split(")")[0]
else:
local_c = f[found_start].split(" != ")[-1].split(")")[0]
actual_index, actual_bytes = find_index(local_c)
return local_c, actual_index, actual_bytes, ''.join(data[constraint_start:constraint_end])
def find_index(local_c):
int_local_c = int(local_c, 16)
pattern = f"case {int_local_c}"
label = -1
for i in range(len(f2)):
if pattern in f2[i]:
label = f2[i].split(" goto ")[-1][:-1]
break
pattern2 = f"{label}:;"
index_label = -1
for i in range(len(f2)):
if pattern2 in f2[i]:
index_label = i
break
pattern3 = "i32_load16_u"
pattern4 = "i32_load8_u"
pattern5 = "i32_load"
actual_index = []
actual_bytes = []
for i in range(index_label, index_label + 1000):
if pattern3 in f2[i]:
if " + " in f2[i]:
actual_index.append(f2[i].split(" + ")[-1].split("u)")[0])
else:
actual_index.append("0")
actual_bytes.append(2)
elif pattern4 in f2[i]:
if " + " in f2[i]:
actual_index.append(f2[i].split(" + ")[-1].split("u)")[0])
else:
actual_index.append("0")
actual_bytes.append(1)
elif pattern5 in f2[i]:
if " + " in f2[i]:
actual_index.append(f2[i].split(" + ")[-1].split("u)")[0])
else:
actual_index.append("0")
actual_bytes.append(4)
elif "goto" in f2[i]:
break
odd_index = []
odd_bytes = []
for i in range(0, len(actual_index), 2):
odd_index.append(actual_index[i + 1])
odd_bytes.append(actual_bytes[i + 1])
return odd_index, odd_bytes
def one_replace(data, target, value):
length = len(target)
index = data.index(target)
return data[:index] + value + data[index+length:]
def create_constraint(tmp, actual_index, actual_bytes):
arr = re.findall("\*\((.*?)\)", tmp)
counter = 0
for i in arr:
tmp_split = i.split(" ")
index = tmp_split[-1]
if actual_bytes[counter] == 2:
new_str = f"to_word({tmp_split[0]}, {actual_index[counter]})"
elif actual_bytes[counter] == 4:
new_str = f"to_dword({tmp_split[0]}, {actual_index[counter]})"
elif actual_bytes[counter] == 1:
new_str = f"to_byte({tmp_split[0]}, {actual_index[counter]})"
else:
print("whatt")
counter += 1
tmp = one_replace(tmp, f"*({i})", new_str)
return tmp.replace(" ", "")[2:-1]
def to_word(param1, off):
return Extract((off+2)*8-1,(off)*8,param1)
def to_byte(param1, off):
return Extract((off+1)*8-1,(off)*8,param1)
def to_dword(param1, off):
return Extract((off+4)*8-1,(off)*8,param1)
f = open("check.c", "r").read().split("\n")
f2 = open("decompiled.c", "r").read().split("\n")
local_c = '100'
list_constraints = []
length = 53
for i in range(length):
local_c, actual_index, actual_bytes, tmp = find_constraint(f, local_c)
list_constraints.append(create_constraint(tmp, actual_index, actual_bytes))
list_constraints = list_constraints[::-1]
param1 = BitVec("Flag", 256)
s = Solver()
fmt = "s.add({} == False)"
for i in range(length):
tmp_constraint = list_constraints[i].replace("*0x10000>>0x10", "")
tmp_constraint = tmp_constraint.replace("*0x1000000>>0x18", "")
exec(fmt.format(tmp_constraint))
print(s.check())
model = s.model()
inp6 = long_to_bytes(model[param1].as_long())[::-1]
print(list(inp6))
During the competition i can't get valid solution although all the constraints are correctly parsed and after after the competition i found that the issue is on the definition of variable param1 and conversion function (to_word, to_byte, to_dword). So by modifying the function and param1 i can get the valid solution.
Combine all solution and convert the value to hex then call it through console.
import re
from z3 import *
from Crypto.Util.number import *
param1 = [0 for _ in range(8)]
param1[0] = chr(- 0x49 & 0xff)
param1[1] = '$'
param1[2] = '`'
param1[3] = '\x05'
param1[4] = '5'
param1[5] = '1'
param1[6] = 'i'
param1[7] = 'r'
inp1 = list(map(ord, param1))
print(bytes(inp1).hex())
local_10 = [0 for i in range(8)]
local_18 = [0 for i in range(8)]
local_10[0] = 5
local_10[1] = 0xaa
local_10[2] = 0x32
local_10[3] = 0xad
local_10[4] = 0xb4
local_10[5] = 0x15
local_10[6] = 0x20
local_10[7] = 0x8f
local_18[0] = 0x28
local_18[1] = 0x19
local_18[2] = 0xf3
local_18[3] = 0x59
local_18[4] = 0x7d
local_18[5] = 0x42
local_18[6] = 0x16
local_18[7] = 0xcb
inp2 = []
for i in range(8):
inp2.append(local_10[i] ^ local_18[i])
print(bytes(inp2).hex())
tmp = 1836311903
inp3 = long_to_bytes(tmp)[::-1]
inp3 = list(inp3)
print(bytes(inp3).hex())
local_c = 0xb
local_10 = 0x69b43d76
local_14 = 0xc945c42
inp4 = (local_14 + local_10) // local_c
inp4 = list(long_to_bytes(inp4))[::-1]
print(bytes(inp4).hex())
local_20 = [0 for _ in range(4)]
local_30 = [0 for _ in range(4)]
local_40 = [0 for _ in range(4)]
local_50 = [0 for _ in range(4)]
local_60 = [0 for _ in range(4)]
local_20[0] = 0x11
local_20[1] = 0x12
local_20[2] = 0x1a
local_20[3] = 2
local_30[0] = 0x10cd6
local_30[1] = 0xd360
local_30[2] = 0x17c87
local_30[3] = 0x3b9e
local_40[0] = 9
local_40[1] = 0x20
local_40[2] = 0x1d
local_40[3] = 8
local_50[0] = 0x4f0a
local_50[1] = 0xcff8
local_50[2] = 0x151a7
local_50[3] = 0x1676d
local_60[0] = 0x2f8e9e
local_60[1] = 0x1c7f4b8
local_60[2] = 0x232e190
local_60[3] = 0x6cc2d
inp5 = []
for local_70 in range(4):
tmp = (((local_60[local_70] - local_50[local_70]) // local_40[local_70]) - local_30[local_70]) // local_20[local_70]
inp5 += list(long_to_bytes(tmp))[::-1]
print(bytes(inp5).hex())
def find_constraint(data, value):
pattern = f"local_c = {value}"
found_end = -1
for i in range(len(data)):
if pattern in data[i]:
found_end = i
break
assert found_end != -1
pattern2 = "local_c == "
pattern3 = "local_c != "
found_start = -1
local_c_count = 0
for i in range(i, -1, -1):
if "local_c" in data[i]:
local_c_count += 1
if pattern2 in data[i] or pattern3 in data[i]:
found_start = i
break
assert found_start != -1
constraint_start = -1
constraint_end = -1
for i in range(found_start + 1, found_end - 1):
if "if" in data[i]:
constraint_start = i
if "{" in data[i]:
constraint_end = i + 1
break
if " == " in f[found_start]:
local_c = f[found_start].split(" == ")[-1].split(")")[0]
else:
local_c = f[found_start].split(" != ")[-1].split(")")[0]
actual_index, actual_bytes = find_index(local_c)
return local_c, actual_index, actual_bytes, ''.join(data[constraint_start:constraint_end])
def find_index(local_c):
int_local_c = int(local_c, 16)
pattern = f"case {int_local_c}"
label = -1
for i in range(len(f2)):
if pattern in f2[i]:
label = f2[i].split(" goto ")[-1][:-1]
break
pattern2 = f"{label}:;"
index_label = -1
for i in range(len(f2)):
if pattern2 in f2[i]:
index_label = i
break
pattern3 = "i32_load16_u"
pattern4 = "i32_load8_u"
pattern5 = "i32_load"
actual_index = []
actual_bytes = []
for i in range(index_label, index_label + 1000):
if pattern3 in f2[i]:
if " + " in f2[i]:
actual_index.append(f2[i].split(" + ")[-1].split("u)")[0])
else:
actual_index.append("0")
actual_bytes.append(2)
elif pattern4 in f2[i]:
if " + " in f2[i]:
actual_index.append(f2[i].split(" + ")[-1].split("u)")[0])
else:
actual_index.append("0")
actual_bytes.append(1)
elif pattern5 in f2[i]:
if " + " in f2[i]:
actual_index.append(f2[i].split(" + ")[-1].split("u)")[0])
else:
actual_index.append("0")
actual_bytes.append(4)
elif "goto" in f2[i]:
break
odd_index = []
odd_bytes = []
for i in range(0, len(actual_index), 2):
odd_index.append(actual_index[i + 1])
odd_bytes.append(actual_bytes[i + 1])
return odd_index, odd_bytes
def one_replace(data, target, value):
length = len(target)
index = data.index(target)
return data[:index] + value + data[index+length:]
def create_constraint(tmp, actual_index, actual_bytes):
arr = re.findall("\*\((.*?)\)", tmp)
counter = 0
for i in arr:
tmp_split = i.split(" ")
index = tmp_split[-1]
if actual_bytes[counter] == 2:
new_str = f"to_word({tmp_split[0]}, {actual_index[counter]})"
elif actual_bytes[counter] == 4:
new_str = f"to_dword({tmp_split[0]}, {actual_index[counter]})"
elif actual_bytes[counter] == 1:
new_str = f"to_byte({tmp_split[0]}, {actual_index[counter]})"
else:
print("whatt")
counter += 1
tmp = one_replace(tmp, f"*({i})", new_str)
return tmp.replace(" ", "")[2:-1]
def to_word(param1, off):
return Extract((off+2)*8-1,(off)*8,param1)
def to_byte(param1, off):
return Extract((off+1)*8-1,(off)*8,param1)
def to_dword(param1, off):
return Extract((off+4)*8-1,(off)*8,param1)
f = open("check.c", "r").read().split("\n")
f2 = open("decompiled.c", "r").read().split("\n")
local_c = '100'
list_constraints = []
length = 53
for i in range(length):
local_c, actual_index, actual_bytes, tmp = find_constraint(f, local_c)
list_constraints.append(create_constraint(tmp, actual_index, actual_bytes))
list_constraints = list_constraints[::-1]
param1 = BitVec("Flag", 256)
s = Solver()
fmt = "s.add({} == False)"
for i in range(length):
tmp_constraint = list_constraints[i].replace("*0x10000>>0x10", "")
tmp_constraint = tmp_constraint.replace("*0x1000000>>0x18", "")
exec(fmt.format(tmp_constraint))
s.check()
model = s.model()
inp6 = long_to_bytes(model[param1].as_long())[::-1]
print(inp6.hex())
check1Data = FromHexString("b724600535316972")
check2Data = FromHexString("2db3c1f4c9573644")
check3Data = FromHexString("5fe5736d")
check4Data = FromHexString("28c8c00a")
check5Data = FromHexString("3e3f8bbe07b07d38")
check6Data = FromHexString("d10dcb769a39c91eb33740e9db857ec5f1c3ccc78ee9862867a2cc0decda24d0")
const strangeMiem = new Uint8Array(check1Data.length + check2Data.length + check3Data.length + check4Data.length + check5Data.length + check6Data.length);
strangeMiem.set(check1Data, 0);
strangeMiem.set(check2Data, check1Data.length);
strangeMiem.set(check3Data, check1Data.length + check2Data.length);
strangeMiem.set(check4Data, check1Data.length + check2Data.length + check3Data.length);
strangeMiem.set(check5Data, check1Data.length + check2Data.length + check3Data.length + check4Data.length);
strangeMiem.set(check6Data, check1Data.length + check2Data.length + check3Data.length + check4Data.length + check5Data.length);
alert(PerformHack(strangeMiem));
Flag: SAS{0k_u_54v3d_7h3_p14n37_n0w_u_5h0u1d_61v3_m34n1n6_70_l1f3}
Some crazy guy imagined himself to be Napoleon and attacked our network. Now all the computers in our office crash as soon as we power them on. That freaky guy demanded $10K as ransom to make our computers work again. Our IT specialists have looked at the broken computers and found a suspicious driver in it, however, we are too afraid to look at it more closely - the guy told us that he will wipe all the data in our company if we try to remove the infection without his help. The freak also offered us to remove the infection from one of the machines for free. We managed to capture the process of him interacting with the driver, however, we weren't able to make sense out of these recordings. It seems like there is nothing we can do...
TBU