# [Ikea](https://play.camp.allesctf.net/tasks/ikea) Category: Reverse Engineering Difficulty: Medium Author: Rairosu First Blood: r3kapig People told me python is a beautiful language, but to be honest, it certainly needed some more decorations. Challenge Files:ikea.zip --- ### Zip contents main.py -> Script that calls a lot of functions through decorators insp.pyc -> Python bytecode that contains all the decorator functions ## PYC decompiler Unfortunately as of right now there doesn't seem to be any easily available Python decompiler around that is able to work with Python 3.11 bytecode. Uncompyle6 and Decompyle3 both only work with versions up to 3.8 / 3.9? Only the current main branch of [xdis](https://github.com/rocky/python-xdis) (which is used internally in both decompyle3 and uncompyle6) is able to disassemble 3.11 bytecode. #### Running xdis from git - Clone the xdis repo - cd into it - pip install -e . - pip install -r requirements-dev.txt - run ./bin/pydisasm on the insp.pyc file ## problems - the functions inside the pyc contain a lot of lambdas which makes it hard to see which decorator they belong to - some of the functions (e.g. billy) seem to be recursive - Ektrop raises an exception if all the other decorators are commented out. But `main.py` obviously works. Some other decorator is catching that exception, but we don't yet know which one. + `Ribba` and `Klippan` seem to be catching some exceptions. We figured this out by commenting them out and running `main.py`. ## Interesting development: The key might be somewhere until line 9 If we comment out the decorators till line 9, we get an exception when we run `echo bla | python main2.py`, therefore it makes sense that the lines afterwards are not necessary to understand. ## Reverse engineered functionality of ikea-named functions * `Klippan`: Checks that the first element is 0. If not, returns the rest. * `Ektrop`: Bit tricky. First element of its argument must be a callable with a single argument. Returns different stuff based on if the first element (the callable) returns a constant or something else. It always drops the second element. See below. ```python In [30]: inst.Ektorp(lambda x:x)((lambda x:32,7,12,3,78)) Out[30]: 32 In [83]: foo([lambda x:2*x, None, 7,8,9,10,11]) Out[83]: [7, 8, 9, 10, 11, 7, 8, 9, 10, 11] ``` * `Lack`: Takes the first elemnt of the argument as offset, returns `arg[offset+1:]` * `Ribba`: Prepends the length of the return value: `len(f(x), *x` * `Billy(n)`: Prepends n: `n, f(x)` * `Expedit`: Subtracts first two numbers from return value: `f(x)[1]-f(x)[0], *f(x)[2:]` and prepends to output * `Malm`: strips teh first two characters and repeats 98 times. * `Docksta`: unpacks the arguments * `Pöang`: removes first two elemnts * `Rens`: adds first two arguments * `Stockholm`: removes first two args, prepends 0 * `Färgrik`: removes first element ## Disassembled Bytecode How to read: https://stackoverflow.com/a/47529318 List of Python OPcodes: https://docs.python.org/3.11/library/dis.html#python-bytecode-instructions ``` /home/elmo/Documents/python-xdis # pydisasm version 6.1.0.dev0 # Python bytecode 3.11 (3495) # Disassembled from Python 3.11.3 (main, Jun 5 2023, 09:32:32) [GCC 13.1.1 20230429] # Timestamp in code: 1691191009 (2023-08-05 01:16:49) # Source code size mod 2**32: 777 bytes # Method Name: <module> # Filename: /inst.py # Argument count: 0 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 0 # Stack size: 1 # Flags: 0x00000000 (0x0) # First Line: 1 # Constants: # 0: <code object Ribba at 0x7f815f9c4370, file "/inst.py", line 1> # 1: <code object Billy at 0x7f815f7196f0, file "/inst.py", line 4> # 2: <code object Malm at 0x7f815f719d70, file "/inst.py", line 7> # 3: <code object Poäng at 0x7f815f719e40, file "/inst.py", line 10> # 4: <code object Lack at 0x7f815f719f10, file "/inst.py", line 13> # 5: <code object Rens at 0x7f815f719fe0, file "/inst.py", line 16> # 6: <code object Expedit at 0x7f815f71a0b0, file "/inst.py", line 19> # 7: <code object Färgrik at 0x7f815f71a180, file "/inst.py", line 22> # 8: <code object Stockholm at 0x7f815f71a250, file "/inst.py", line 25> # 9: <code object Docksta at 0x7f815f71a320, file "/inst.py", line 28> # 10: <code object Ektorp at 0x7f815f71a3f0, file "/inst.py", line 31> # 11: <code object Klippan at 0x7f815f71a4c0, file "/inst.py", line 34> # 12: None # Names: # 0: Ribba # 1: Billy # 2: Malm # 3: Poäng # 4: Lack # 5: Rens # 6: Expedit # 7: Färgrik # 8: Stockholm # 9: Docksta # 10: Ektorp # 11: Klippan 0: 0 |97 00| RESUME 0 1: 2 |64 00| LOAD_CONST (<code object Ribba at 0x7f815f9c4370, file "/inst.py", line 1>) 4 |84 00| MAKE_FUNCTION (<code object Ribba at 0x7f815f9c4370, file "/inst.py", line 1>: Neither defaults, keyword-only args, annotations, nor closures) 6 |5a 00| STORE_NAME (Ribba) 4: 8 |64 01| LOAD_CONST (<code object Billy at 0x7f815f7196f0, file "/inst.py", line 4>) 10 |84 00| MAKE_FUNCTION (<code object Billy at 0x7f815f7196f0, file "/inst.py", line 4>: Neither defaults, keyword-only args, annotations, nor closures) 12 |5a 01| STORE_NAME (Billy) 7: 14 |64 02| LOAD_CONST (<code object Malm at 0x7f815f719d70, file "/inst.py", line 7>) 16 |84 00| MAKE_FUNCTION (<code object Malm at 0x7f815f719d70, file "/inst.py", line 7>: Neither defaults, keyword-only args, annotations, nor closures) 18 |5a 02| STORE_NAME (Malm) 10: 20 |64 03| LOAD_CONST (<code object Poäng at 0x7f815f719e40, file "/inst.py", line 10>) 22 |84 00| MAKE_FUNCTION (<code object Poäng at 0x7f815f719e40, file "/inst.py", line 10>: Neither defaults, keyword-only args, annotations, nor closures) 24 |5a 03| STORE_NAME (Poäng) 13: 26 |64 04| LOAD_CONST (<code object Lack at 0x7f815f719f10, file "/inst.py", line 13>) 28 |84 00| MAKE_FUNCTION (<code object Lack at 0x7f815f719f10, file "/inst.py", line 13>: Neither defaults, keyword-only args, annotations, nor closures) 30 |5a 04| STORE_NAME (Lack) 16: 32 |64 05| LOAD_CONST (<code object Rens at 0x7f815f719fe0, file "/inst.py", line 16>) 34 |84 00| MAKE_FUNCTION (<code object Rens at 0x7f815f719fe0, file "/inst.py", line 16>: Neither defaults, keyword-only args, annotations, nor closures) 36 |5a 05| STORE_NAME (Rens) 19: 38 |64 06| LOAD_CONST (<code object Expedit at 0x7f815f71a0b0, file "/inst.py", line 19>) 40 |84 00| MAKE_FUNCTION (<code object Expedit at 0x7f815f71a0b0, file "/inst.py", line 19>: Neither defaults, keyword-only args, annotations, nor closures) 42 |5a 06| STORE_NAME (Expedit) 22: 44 |64 07| LOAD_CONST (<code object Färgrik at 0x7f815f71a180, file "/inst.py", line 22>) 46 |84 00| MAKE_FUNCTION (<code object Färgrik at 0x7f815f71a180, file "/inst.py", line 22>: Neither defaults, keyword-only args, annotations, nor closures) 48 |5a 07| STORE_NAME (Färgrik) 25: 50 |64 08| LOAD_CONST (<code object Stockholm at 0x7f815f71a250, file "/inst.py", line 25>) 52 |84 00| MAKE_FUNCTION (<code object Stockholm at 0x7f815f71a250, file "/inst.py", line 25>: Neither defaults, keyword-only args, annotations, nor closures) 54 |5a 08| STORE_NAME (Stockholm) 28: 56 |64 09| LOAD_CONST (<code object Docksta at 0x7f815f71a320, file "/inst.py", line 28>) 58 |84 00| MAKE_FUNCTION (<code object Docksta at 0x7f815f71a320, file "/inst.py", line 28>: Neither defaults, keyword-only args, annotations, nor closures) 60 |5a 09| STORE_NAME (Docksta) 31: 62 |64 0a| LOAD_CONST (<code object Ektorp at 0x7f815f71a3f0, file "/inst.py", line 31>) 64 |84 00| MAKE_FUNCTION (<code object Ektorp at 0x7f815f71a3f0, file "/inst.py", line 31>: Neither defaults, keyword-only args, annotations, nor closures) 66 |5a 0a| STORE_NAME (Ektorp) 34: 68 |64 0b| LOAD_CONST (<code object Klippan at 0x7f815f71a4c0, file "/inst.py", line 34>) 70 |84 00| MAKE_FUNCTION (<code object Klippan at 0x7f815f71a4c0, file "/inst.py", line 34>: Neither defaults, keyword-only args, annotations, nor closures) 72 |5a 0b| STORE_NAME (Klippan) 74 |64 0c| LOAD_CONST (None) 76 |53 00| RETURN_VALUE (None) # Method Name: Ribba # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 1 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f76c580, file "/inst.py", line 2> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 1: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 2: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f76c580, file "/inst.py", line 2>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f76c580, file "/inst.py", line 2>: closure) 12 |53 00| RETURN_VALUE # Method Name: Billy # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 4 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f7197c0, file "/inst.py", line 5> # Varnames: # val # Positional arguments: # val # Cell variables: # 0: val 4: 0 |87 00| <135> (val) 2 |97 00| RESUME 0 5: 4 |88 00| LOAD_CLOSURE (val) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f7197c0, file "/inst.py", line 5>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f7197c0, file "/inst.py", line 5>: closure) 12 |53 00| RETURN_VALUE # Method Name: Malm # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 7 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f8d8390, file "/inst.py", line 8> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 7: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 8: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f8d8390, file "/inst.py", line 8>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f8d8390, file "/inst.py", line 8>: closure) 12 |53 00| RETURN_VALUE # Method Name: Poäng # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 10 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f748450, file "/inst.py", line 11> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 10: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 11: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f748450, file "/inst.py", line 11>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f748450, file "/inst.py", line 11>: closure) 12 |53 00| RETURN_VALUE # Method Name: Lack # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 13 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f74c230, file "/inst.py", line 14> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 13: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 14: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f74c230, file "/inst.py", line 14>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f74c230, file "/inst.py", line 14>: closure) 12 |53 00| RETURN_VALUE # Method Name: Rens # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 16 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f76c690, file "/inst.py", line 17> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 16: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 17: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f76c690, file "/inst.py", line 17>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f76c690, file "/inst.py", line 17>: closure) 12 |53 00| RETURN_VALUE # Method Name: Expedit # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 19 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f76c9c0, file "/inst.py", line 20> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 19: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 20: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f76c9c0, file "/inst.py", line 20>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f76c9c0, file "/inst.py", line 20>: closure) 12 |53 00| RETURN_VALUE # Method Name: Färgrik # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 22 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f76c7a0, file "/inst.py", line 23> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 22: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 23: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f76c7a0, file "/inst.py", line 23>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f76c7a0, file "/inst.py", line 23>: closure) 12 |53 00| RETURN_VALUE # Method Name: Stockholm # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 25 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f76c8b0, file "/inst.py", line 26> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 25: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 26: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f76c8b0, file "/inst.py", line 26>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f76c8b0, file "/inst.py", line 26>: closure) 12 |53 00| RETURN_VALUE # Method Name: Docksta # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 28 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f8fa6b0, file "/inst.py", line 29> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 28: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 29: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f8fa6b0, file "/inst.py", line 29>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f8fa6b0, file "/inst.py", line 29>: closure) 12 |53 00| RETURN_VALUE # Method Name: Ektorp # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 31 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f8be630, file "/inst.py", line 32> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 31: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 32: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f8be630, file "/inst.py", line 32>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f8be630, file "/inst.py", line 32>: closure) 12 |53 00| RETURN_VALUE # Method Name: Klippan # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000003 (NEWLOCALS | OPTIMIZED) # First Line: 34 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f74c130, file "/inst.py", line 35> # Varnames: # f # Positional arguments: # f # Cell variables: # 0: f 34: 0 |87 00| <135> (f) 2 |97 00| RESUME 0 35: 4 |88 00| LOAD_CLOSURE (f) 6 |66 01| BUILD_TUPLE 1 8 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f74c130, file "/inst.py", line 35>) 10 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f74c130, file "/inst.py", line 35>: closure) 12 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 6 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 2 # Constants: # 0: None # Names: # 0: len # 1: tuple # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 2: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (1) 8 |74 01| LOAD_GLOBAL (NULL + len) 20 |7c 00| LOAD_FAST (s) 22 |a6 01| PRECALL 1 26 |ab 01| CALL 1 36 |66 01| BUILD_TUPLE 1 38 |74 03| LOAD_GLOBAL (NULL + tuple) 50 |7c 00| LOAD_FAST (s) 52 |a6 01| PRECALL 1 56 |ab 01| CALL 1 66 |7a 00| BINARY_OP 0 70 |a6 01| PRECALL 1 74 |ab 01| CALL 1 84 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 5 # Constants: # 0: None # 1: <code object <lambda> at 0x7f815f8faf70, file "/inst.py", line 5> # Varnames: # f # Positional arguments: # f # Free variables: # 0: val # Cell variables: # 0: f 5: 0 |95 01| COPY_FREE_VARS 1 2 |87 00| <135> (f) 4 |97 00| RESUME 0 6 |88 00| LOAD_CLOSURE (f) 8 |88 01| LOAD_CLOSURE (val) 10 |66 02| BUILD_TUPLE 2 12 |64 01| LOAD_CONST (<code object <lambda> at 0x7f815f8faf70, file "/inst.py", line 5>) 14 |84 08| MAKE_FUNCTION (<code object <lambda> at 0x7f815f8faf70, file "/inst.py", line 5>: closure) 16 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 7 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 8 # Constants: # 0: None # 1: 2 # 2: 1 # 3: 0 # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 8: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (1) 8 |7c 00| LOAD_FAST (s) 10 |64 01| LOAD_CONST (2) 12 |64 01| LOAD_CONST (2) 14 |7c 00| LOAD_FAST (s) 16 |64 02| LOAD_CONST (1) 18 |19 00| BINARY_SUBSCR 28 |7a 00| BINARY_OP 0 32 |85 02| BUILD_SLICE 2 34 |19 00| BINARY_SUBSCR 44 |7c 00| LOAD_FAST (s) 46 |64 03| LOAD_CONST (0) 48 |19 00| BINARY_SUBSCR 58 |7a 05| BINARY_OP 5 62 |7c 00| LOAD_FAST (s) 64 |64 01| LOAD_CONST (2) 66 |64 00| LOAD_CONST (None) 68 |85 02| BUILD_SLICE 2 70 |19 00| BINARY_SUBSCR 80 |7a 00| BINARY_OP 0 84 |a6 01| PRECALL 1 88 |ab 01| CALL 1 98 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 8 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 11 # Constants: # 0: None # 1: 2 # 2: 1 # 3: 0 # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 11: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (1) 8 |7c 00| LOAD_FAST (s) 10 |64 01| LOAD_CONST (2) 12 |7c 00| LOAD_FAST (s) 14 |64 02| LOAD_CONST (1) 16 |19 00| BINARY_SUBSCR 26 |7a 00| BINARY_OP 0 30 |64 01| LOAD_CONST (2) 32 |7c 00| LOAD_FAST (s) 34 |64 03| LOAD_CONST (0) 36 |19 00| BINARY_SUBSCR 46 |7a 00| BINARY_OP 0 50 |85 02| BUILD_SLICE 2 52 |19 00| BINARY_SUBSCR 62 |7c 00| LOAD_FAST (s) 64 |64 01| LOAD_CONST (2) 66 |64 01| LOAD_CONST (2) 68 |7c 00| LOAD_FAST (s) 70 |64 02| LOAD_CONST (1) 72 |19 00| BINARY_SUBSCR 82 |7a 00| BINARY_OP 0 86 |85 02| BUILD_SLICE 2 88 |19 00| BINARY_SUBSCR 98 |7a 00| BINARY_OP 0 102 |7c 00| LOAD_FAST (s) 104 |64 01| LOAD_CONST (2) 106 |7c 00| LOAD_FAST (s) 108 |64 03| LOAD_CONST (0) 110 |19 00| BINARY_SUBSCR 120 |7a 00| BINARY_OP 0 124 |64 00| LOAD_CONST (None) 126 |85 02| BUILD_SLICE 2 128 |19 00| BINARY_SUBSCR 138 |7a 00| BINARY_OP 0 142 |a6 01| PRECALL 1 146 |ab 01| CALL 1 156 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 6 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 14 # Constants: # 0: None # 1: 1 # 2: 0 # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 14: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (1) 8 |7c 00| LOAD_FAST (s) 10 |64 01| LOAD_CONST (1) 12 |7c 00| LOAD_FAST (s) 14 |64 02| LOAD_CONST (0) 16 |19 00| BINARY_SUBSCR 26 |7a 00| BINARY_OP 0 30 |64 00| LOAD_CONST (None) 32 |85 02| BUILD_SLICE 2 34 |19 00| BINARY_SUBSCR 44 |a6 01| PRECALL 1 48 |ab 01| CALL 1 58 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 6 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 17 # Constants: # 0: None # 1: 0 # 2: 1 # 3: 2 # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 17: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (1) 8 |7c 00| LOAD_FAST (s) 10 |64 01| LOAD_CONST (0) 12 |19 00| BINARY_SUBSCR 22 |7c 00| LOAD_FAST (s) 24 |64 02| LOAD_CONST (1) 26 |19 00| BINARY_SUBSCR 36 |7a 00| BINARY_OP 0 40 |66 01| BUILD_TUPLE 1 42 |7c 00| LOAD_FAST (s) 44 |64 03| LOAD_CONST (2) 46 |64 00| LOAD_CONST (None) 48 |85 02| BUILD_SLICE 2 50 |19 00| BINARY_SUBSCR 60 |7a 00| BINARY_OP 0 64 |a6 01| PRECALL 1 68 |ab 01| CALL 1 78 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 6 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 20 # Constants: # 0: None # 1: 0 # 2: 1 # 3: 2 # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 20: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (1) 8 |7c 00| LOAD_FAST (s) 10 |64 01| LOAD_CONST (0) 12 |19 00| BINARY_SUBSCR 22 |7c 00| LOAD_FAST (s) 24 |64 02| LOAD_CONST (1) 26 |19 00| BINARY_SUBSCR 36 |7a 0a| BINARY_OP 10 40 |66 01| BUILD_TUPLE 1 42 |7c 00| LOAD_FAST (s) 44 |64 03| LOAD_CONST (2) 46 |64 00| LOAD_CONST (None) 48 |85 02| BUILD_SLICE 2 50 |19 00| BINARY_SUBSCR 60 |7a 00| BINARY_OP 0 64 |a6 01| PRECALL 1 68 |ab 01| CALL 1 78 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 6 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 23 # Constants: # 0: None # 1: 0 # 2: 1 # 3: 2 # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 23: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (1) 8 |7c 00| LOAD_FAST (s) 10 |64 01| LOAD_CONST (0) 12 |19 00| BINARY_SUBSCR 22 |7c 00| LOAD_FAST (s) 24 |64 02| LOAD_CONST (1) 26 |19 00| BINARY_SUBSCR 36 |7a 05| BINARY_OP 5 40 |66 01| BUILD_TUPLE 1 42 |7c 00| LOAD_FAST (s) 44 |64 03| LOAD_CONST (2) 46 |64 00| LOAD_CONST (None) 48 |85 02| BUILD_SLICE 2 50 |19 00| BINARY_SUBSCR 60 |7a 00| BINARY_OP 0 64 |a6 01| PRECALL 1 68 |ab 01| CALL 1 78 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 6 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 26 # Constants: # 0: None # 1: 1 # 2: 0 # 3: 2 # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 26: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (1) 8 |7c 00| LOAD_FAST (s) 10 |64 01| LOAD_CONST (1) 12 |19 00| BINARY_SUBSCR 22 |7c 00| LOAD_FAST (s) 24 |64 02| LOAD_CONST (0) 26 |19 00| BINARY_SUBSCR 36 |7a 06| BINARY_OP 6 40 |66 01| BUILD_TUPLE 1 42 |7c 00| LOAD_FAST (s) 44 |64 03| LOAD_CONST (2) 46 |64 00| LOAD_CONST (None) 48 |85 02| BUILD_SLICE 2 50 |19 00| BINARY_SUBSCR 60 |7a 00| BINARY_OP 0 64 |a6 01| PRECALL 1 68 |ab 01| CALL 1 78 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 4 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 29 # Constants: # 0: None # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 29: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (1) 8 |89 01| LOAD_DEREF (1) 10 |66 01| BUILD_TUPLE 1 12 |7c 00| LOAD_FAST (s) 14 |7a 00| BINARY_OP 0 18 |a6 01| PRECALL 1 22 |ab 01| CALL 1 32 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 5 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 32 # Constants: # 0: None # 1: 1 # 2: 0 # 3: 2 # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 32: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |7c 00| LOAD_FAST (s) 6 |64 01| LOAD_CONST (1) 8 |19 00| BINARY_SUBSCR 18 |64 02| LOAD_CONST (0) 20 |6b 03| COMPARE_OP (!=) 26 |72 19| POP_JUMP_FORWARD_IF_FALSE (to 78) 28 |02 00| PUSH_NULL 30 |7c 00| LOAD_FAST (s) 32 |64 02| LOAD_CONST (0) 34 |19 00| BINARY_SUBSCR 44 |7c 00| LOAD_FAST (s) 46 |64 03| LOAD_CONST (2) 48 |64 00| LOAD_CONST (None) 50 |85 02| BUILD_SLICE 2 52 |19 00| BINARY_SUBSCR 62 |a6 01| PRECALL 1 66 |ab 01| CALL 1 76 |6e 12| JUMP_FORWARD (to 114) >> 78 |02 00| PUSH_NULL 80 |89 01| LOAD_DEREF (1) 82 |7c 00| LOAD_FAST (s) 84 |64 03| LOAD_CONST (2) 86 |64 00| LOAD_CONST (None) 88 |85 02| BUILD_SLICE 2 90 |19 00| BINARY_SUBSCR 100 |a6 01| PRECALL 1 104 |ab 01| CALL 1 >> 114 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 5 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 35 # Constants: # 0: None # 1: 0 # 2: False # 3: 1 # Varnames: # s # Positional arguments: # s # Free variables: # 0: f 35: 0 |95 01| COPY_FREE_VARS 1 2 |97 00| RESUME 0 4 |7c 00| LOAD_FAST (s) 6 |64 01| LOAD_CONST (0) 8 |19 00| BINARY_SUBSCR 18 |64 01| LOAD_CONST (0) 20 |6b 03| COMPARE_OP (!=) 26 |72 02| POP_JUMP_FORWARD_IF_FALSE (to 32) 28 |64 02| LOAD_CONST (False) 30 |6e 12| JUMP_FORWARD (to 68) >> 32 |02 00| PUSH_NULL 34 |89 01| LOAD_DEREF (1) 36 |7c 00| LOAD_FAST (s) 38 |64 03| LOAD_CONST (1) 40 |64 00| LOAD_CONST (None) 42 |85 02| BUILD_SLICE 2 44 |19 00| BINARY_SUBSCR 54 |a6 01| PRECALL 1 58 |ab 01| CALL 1 >> 68 |53 00| RETURN_VALUE # Method Name: <lambda> # Filename: /inst.py # Argument count: 1 # Position-only argument count: 0 # Keyword-only arguments: 0 # Number of locals: 1 # Stack size: 4 # Flags: 0x00000013 (NESTED | NEWLOCALS | OPTIMIZED) # First Line: 5 # Constants: # 0: None # Varnames: # s # Positional arguments: # s # Free variables: # 0: f # 1: val 5: 0 |95 02| COPY_FREE_VARS 2 2 |97 00| RESUME 0 4 |02 00| PUSH_NULL 6 |89 01| LOAD_DEREF (val) 8 |89 02| LOAD_DEREF (2) 10 |66 01| BUILD_TUPLE 1 12 |7c 00| LOAD_FAST (s) 14 |7a 00| BINARY_OP 0 18 |a6 01| PRECALL 1 22 |ab 01| CALL 1 32 |53 00| RETURN_VALUE ```` # Approach for figuring out what the decorators do WE comment out each decorator in turn. Sample script: ```python from sys import setrecursionlimit from inst import * setrecursionlimit(100000) @Ribba @Billy(16) @Expedit #@Klippan #@Billy(0) #@Billy(1) #@Billy(15) #@Malm #@Billy(185) #@Billy(198) #@Billy(214) #@Billy(67) #@Billy(52) #@Billy(212) #@Billy(83) #@Billy(22) #@Billy(93) #@Billy(13) #@Billy(225) #@Billy(85) #@Billy(197) #@Billy(225) #@Billy(53) #@Billy(34) #@Billy(121) #@Billy(101) #@Billy(107) #@Billy(114) #@Billy(101) #@Billy(116) #@Billy(116) #@Billy(101) #@Billy(98) #@Billy(97) #@Billy(102) #@Billy(111) #@Billy(107) #@Billy(110) #@Billy(105) #@Billy(104) #@Billy(116) #@Billy(116) #@Billy(110) #@Billy(97) #@Billy(99) #@Billy(121) #@Billy(108) #@Billy(108) #@Billy(97) #@Billy(101) #@Billy(114) #@Billy(105) #@Billy(0) #@Docksta #@Billy(1) #@Billy(2) #@Poäng #@Billy(1) #@Rens #@Billy(1) #@Billy(1) #@Malm #@Billy(256) #@Expedit #@Billy(1) #@Billy(1) #@Malm #@Billy(1) #@Billy(3) #@Poäng #@Billy(3) #@Billy(4) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(1) #@Billy(3) #@Poäng #@Ektorp #@Billy(2) #@Lack #@Billy(0) #@Billy(0) #@Docksta #@Billy(1) #@Billy(287) #@Poäng #@Billy(1) #@Billy(2) #@Malm #@Billy(1) #@Billy(4) #@Poäng #@Billy(256) #@Expedit #@Billy(3) #@Billy(260) #@Poäng #@Billy(256) #@Poäng #@Billy(1) #@Billy(2) #@Malm #@Billy(260) #@Billy(261) #@Poäng #@Rens #@Billy(2) #@Billy(260) #@Poäng #@Billy(256) #@Billy(257) #@Poäng #@Billy(256) #@Poäng #@Billy(259) #@Billy(287) #@Poäng #@Billy(284) #@Billy(285) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(28) #@Stockholm #@Billy(1) #@Billy(1) #@Malm #@Billy(28) #@Expedit #@Billy(1) #@Billy(31) #@Poäng #@Billy(1) #@Billy(2) #@Poäng #@Billy(1) #@Billy(287) #@Poäng #@Billy(28) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(287) #@Billy(288) #@Poäng #@Rens #@Billy(256) #@Stockholm #@Billy(1) #@Billy(287) #@Poäng #@Billy(28) #@Billy(29) #@Poäng #@Billy(28) #@Poäng #@Billy(28) #@Billy(287) #@Poäng #@Billy(257) #@Billy(258) #@Poäng #@Billy(1) #@Billy(2) #@Malm #@Billy(256) #@Expedit #@Billy(2) #@Billy(260) #@Poäng #@Billy(256) #@Poäng #@Billy(259) #@Billy(260) #@Poäng #@Billy(1) #@Billy(2) #@Poäng #@Billy(1) #@Billy(260) #@Poäng #@Billy(257) #@Billy(258) #@Poäng #@Billy(256) #@Poäng #@Billy(256) #@Billy(257) #@Poäng #@Billy(1) #@Billy(2) #@Malm #@Billy(256) #@Expedit #@Billy(2) #@Billy(259) #@Poäng #@Billy(256) #@Poäng #@Billy(1) #@Lack #@Billy(258) #@Billy(259) #@Poäng #@Billy(256) #@Billy(257) #@Poäng #@Billy(256) #@Poäng #@Billy(256) #@Billy(258) #@Poäng #@Billy(1) #@Rens #@Billy(1) #@Billy(1) #@Malm #@Billy(256) #@Expedit #@Billy(287) #@Billy(288) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(1) #@Billy(3) #@Poäng #@Ektorp #@Billy(259) #@Billy(287) #@Poäng #@Billy(31) #@Lack #@Billy(0) #@Billy(0) #@Billy(0) #@Docksta #@Billy(1) #@Billy(2) #@Poäng #@Billy(1) #@Rens #@Billy(2) #@Billy(308) #@Poäng #@Billy(1) #@Rens #@Billy(256) #@Stockholm #@Billy(1) #@Billy(2) #@Malm #@Billy(2) #@Billy(4) #@Poäng #@Billy(2) #@Billy(260) #@Poäng #@Billy(256) #@Expedit #@Billy(1) #@Billy(258) #@Poäng #@Billy(256) #@Poäng #@Billy(1) #@Billy(3) #@Malm #@Billy(261) #@Billy(262) #@Poäng #@Rens #@Billy(256) #@Stockholm #@Billy(1) #@Billy(2) #@Malm #@Billy(4) #@Billy(263) #@Poäng #@Billy(295) #@Billy(296) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(1) #@Billy(312) #@Poäng #@Färgrik #@Billy(279) #@Billy(295) #@Poäng #@Billy(274) #@Billy(275) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(1) #@Billy(276) #@Poäng #@Billy(241) #@Färgrik #@Billy(257) #@Stockholm #@Billy(16) #@Stockholm #@Billy(1) #@Billy(1) #@Malm #@Billy(16) #@Expedit #@Billy(1) #@Billy(18) #@Poäng #@Billy(16) #@Poäng #@Billy(17) #@Billy(18) #@Poäng #@Rens #@Billy(257) #@Stockholm #@Billy(16) #@Billy(17) #@Poäng #@Billy(16) #@Poäng #@Billy(16) #@Billy(294) #@Poäng #@Billy(256) #@Billy(257) #@Poäng #@Billy(256) #@Poäng #@Billy(258) #@Billy(260) #@Poäng #@Billy(256) #@Expedit #@Billy(1) #@Billy(258) #@Poäng #@Billy(256) #@Poäng #@Billy(259) #@Billy(260) #@Poäng #@Billy(1) #@Billy(2) #@Poäng #@Billy(2) #@Billy(1) #@Malm #@Rens #@Billy(256) #@Stockholm #@Billy(2) #@Billy(261) #@Poäng #@Billy(256) #@Billy(257) #@Poäng #@Billy(256) #@Poäng #@Billy(256) #@Billy(257) #@Poäng #@Billy(1) #@Billy(2) #@Malm #@Billy(256) #@Expedit #@Billy(2) #@Billy(259) #@Poäng #@Billy(256) #@Poäng #@Billy(260) #@Billy(261) #@Poäng #@Billy(1) #@Billy(2) #@Poäng #@Billy(1) #@Lack #@Billy(256) #@Billy(257) #@Poäng #@Billy(256) #@Poäng #@Billy(258) #@Billy(259) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(256) #@Expedit #@Billy(1) #@Billy(258) #@Poäng #@Billy(256) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(260) #@Billy(261) #@Poäng #@Rens #@Billy(256) #@Stockholm #@Billy(1) #@Billy(275) #@Poäng #@Billy(256) #@Billy(257) #@Poäng #@Billy(256) #@Poäng #@Billy(256) #@Billy(258) #@Poäng #@Billy(306) #@Billy(308) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(256) #@Expedit #@Billy(2) #@Billy(3) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(1) #@Billy(3) #@Poäng #@Ektorp #@Billy(292) #@Billy(308) #@Poäng #@Billy(276) #@Lack #@Billy(16) #@Docksta #@Billy(1) #@Billy(2) #@Poäng #@Billy(1) #@Billy(1) #@Malm #@Billy(2) #@Rens #@Billy(1) #@Billy(1) #@Malm #@Billy(1) #@Rens #@Poäng #@Billy(3) #@Billy(4) #@Poäng #@Expedit #@Klippan #@Billy(1) #@Billy(1) #@Billy(2) #@Poäng #@Expedit #@Billy(2) #@Billy(1) #@Malm #@Billy(1) #@Billy(4) #@Poäng #@Ektorp def checker(flag): return flag print(checker(input().strip().encode())) ```