Jump to content
Tuts 4 You

Pyarmor CrackMe


lopeg

Recommended Posts

  • Teddy Rogers changed the title to Pyarmor CrackMe
SHADOW_UA

First of all, this crackme is version dependent, it only works with Python 3.8 x86. I don't have it installed, so I had to replace _pytransform.dll with the x64 equivalent downloaded from here to be able to run it with my x64 version of Python 3.8.

By looking in the memory of python.exe and placing hardware breakpoints on write on an encrypted code of PyArmor (that starts with \x50\x59\x41\x52\x4d...) we can find a place in _pytransform.dll where it decrypts it to the actual marshalled code object of Python. It is a function at RVA 0x254D0. Then we have to deal with the second layer of PyArmor obfuscation which decrypts opcodes at runtime and then encrypt it back with the same function. We can read about this at PyArmor website here.

Spoiler

static PyObject *
__armor_enter__(PyObject *self, PyObject *args)
{
    // Got code object
    PyFrameObject *frame = PyEval_GetFrame();
    PyCodeObject *f_code = frame->f_code;

    // Increase refcalls of this code object
    // Borrow co_names->ob_refcnt as call counter
    // Generally it will not increased  by Python Interpreter
    PyObject *refcalls = f_code->co_names;
    refcalls->ob_refcnt ++;

    // Restore byte code if it's obfuscated
    if (IS_OBFUSCATED(f_code->co_flags)) {
        restore_byte_code(f_code->co_code);
        clear_obfuscated_flag(f_code);
    }

    Py_RETURN_NONE;
}

 

This code under spoiler is taken from the link above and it tells us how PyArmor works behind the scenes. We can find this piece of code easily in _pytransform.dll by placing BP on PyEval_GetFrame() and tracing a bit. There are 3 functions in this crackme, it means we have to hit and copy decrypted opcodes to our .pyc file 3 times. Make sure that it is an actual decryption of opcodes, because as I told before it uses same function to encrypt it back (through __armor_exit__). That is pretty much enough to solve this crackme, as we can use pydisasm on our pyc file and view its bytecode/wordcode.

Spoiler

# Method Name:       check
# Filename:          <frozen challenge_2>
# Argument count:    1
# Position-only argument count: 0
# Keyword-only arguments: 0
# Number of locals:  5
# Stack size:        25
# Flags:             0x62000043 (0x40000000 | 0x20000000 | 0x2000000 | NOFREE | NEWLOCALS | OPTIMIZED)
# First Line:        5
# Constants:
#    0: None
#    1: '{'
#    2: 'utf-8'
#    3: '0'
#    4: 'x'
#    5: '5'
#    6: '='
#    7: "'"
#    8: 'S'
#    9: '@'
#   10: 'r'
#   11: 'h'
#   12: '_'
#   13: 'C'
#   14: 'n'
#   15: '}'
#   16: ''
#   17: 0
#   18: '1'
#   19: 'You found the key'
# Names:
#    0: base64
#    1: b64encode
#    2: bytes
#    3: range
#    4: len
#    5: append
#    6: print
#    7: __armor_enter__
#    8: __armor_exit__
# Varnames:
#	attempt, key, result, sucess, i
# Positional arguments:
#	attempt
# Local variables:
#    1: key
#    2: result
#    3: sucess
#    4: i
  7:           0 JUMP_ABSOLUTE            18 (to 18)
               2 NOP
               4 NOP
         >>    6 POP_BLOCK
               8 BEGIN_FINALLY
              10 NOP
              12 NOP

  8:          14 EXTENDED_ARG              2 (512)
              16 JUMP_ABSOLUTE           512 (to 512)
         >>   18 LOAD_GLOBAL               7 (__armor_enter__)
              20 CALL_FUNCTION             0
              22 POP_TOP
              24 NOP
              26 NOP

  9:          28 EXTENDED_ARG              1 (256)
              30 SETUP_FINALLY           480 (to 512)
              32 LOAD_GLOBAL               0 (base64)
              34 LOAD_METHOD               1 (b64encode)
              36 LOAD_GLOBAL               2 (bytes)
              38 LOAD_CONST                1 ('{')
              40 LOAD_CONST                2 ('utf-8')

 10:          42 CALL_FUNCTION             2
              44 CALL_METHOD               1
              46 LOAD_GLOBAL               0 (base64)
              48 LOAD_METHOD               1 (b64encode)
              50 LOAD_GLOBAL               2 (bytes)
              52 LOAD_CONST                3 ('0')
              54 LOAD_CONST                2 ('utf-8')

 11:          56 CALL_FUNCTION             2
              58 CALL_METHOD               1
              60 LOAD_GLOBAL               0 (base64)
              62 LOAD_METHOD               1 (b64encode)
              64 LOAD_GLOBAL               2 (bytes)
              66 LOAD_CONST                4 ('x')
              68 LOAD_CONST                2 ('utf-8')

 12:          70 CALL_FUNCTION             2
              72 CALL_METHOD               1
              74 LOAD_GLOBAL               0 (base64)
              76 LOAD_METHOD               1 (b64encode)
              78 LOAD_GLOBAL               2 (bytes)
              80 LOAD_CONST                3 ('0')
              82 LOAD_CONST                2 ('utf-8')

 13:          84 CALL_FUNCTION             2
              86 CALL_METHOD               1
              88 LOAD_GLOBAL               0 (base64)
              90 LOAD_METHOD               1 (b64encode)
              92 LOAD_GLOBAL               2 (bytes)
              94 LOAD_CONST                5 ('5')
              96 LOAD_CONST                2 ('utf-8')

 14:          98 CALL_FUNCTION             2
             100 CALL_METHOD               1
             102 LOAD_GLOBAL               0 (base64)
             104 LOAD_METHOD               1 (b64encode)
             106 LOAD_GLOBAL               2 (bytes)
             108 LOAD_CONST                6 ('=')
             110 LOAD_CONST                2 ('utf-8')

 15:         112 CALL_FUNCTION             2
             114 CALL_METHOD               1
             116 LOAD_GLOBAL               0 (base64)
             118 LOAD_METHOD               1 (b64encode)
             120 LOAD_GLOBAL               2 (bytes)
             122 LOAD_CONST                7 ("'")
             124 LOAD_CONST                2 ('utf-8')

 16:         126 CALL_FUNCTION             2
             128 CALL_METHOD               1
             130 LOAD_GLOBAL               0 (base64)
             132 LOAD_METHOD               1 (b64encode)
             134 LOAD_GLOBAL               2 (bytes)
             136 LOAD_CONST                8 ('S')
             138 LOAD_CONST                2 ('utf-8')

 17:         140 CALL_FUNCTION             2
             142 CALL_METHOD               1
             144 LOAD_GLOBAL               0 (base64)
             146 LOAD_METHOD               1 (b64encode)
             148 LOAD_GLOBAL               2 (bytes)
             150 LOAD_CONST                9 ('@')
             152 LOAD_CONST                2 ('utf-8')

 18:         154 CALL_FUNCTION             2
             156 CALL_METHOD               1
             158 LOAD_GLOBAL               0 (base64)
             160 LOAD_METHOD               1 (b64encode)
             162 LOAD_GLOBAL               2 (bytes)
             164 LOAD_CONST               10 ('r')
             166 LOAD_CONST                2 ('utf-8')

 19:         168 CALL_FUNCTION             2
             170 CALL_METHOD               1
             172 LOAD_GLOBAL               0 (base64)
             174 LOAD_METHOD               1 (b64encode)
             176 LOAD_GLOBAL               2 (bytes)
             178 LOAD_CONST                9 ('@')
             180 LOAD_CONST                2 ('utf-8')

 20:         182 CALL_FUNCTION             2
             184 CALL_METHOD               1
             186 LOAD_GLOBAL               0 (base64)
             188 LOAD_METHOD               1 (b64encode)
             190 LOAD_GLOBAL               2 (bytes)
             192 LOAD_CONST               11 ('h')
             194 LOAD_CONST                2 ('utf-8')

 21:         196 CALL_FUNCTION             2
             198 CALL_METHOD               1
             200 LOAD_GLOBAL               0 (base64)
             202 LOAD_METHOD               1 (b64encode)
             204 LOAD_GLOBAL               2 (bytes)
             206 LOAD_CONST               12 ('_')
             208 LOAD_CONST                2 ('utf-8')

 22:         210 CALL_FUNCTION             2
             212 CALL_METHOD               1
             214 LOAD_GLOBAL               0 (base64)
             216 LOAD_METHOD               1 (b64encode)
             218 LOAD_GLOBAL               2 (bytes)
             220 LOAD_CONST               13 ('C')
             222 LOAD_CONST                2 ('utf-8')

 23:         224 CALL_FUNCTION             2
             226 CALL_METHOD               1
             228 LOAD_GLOBAL               0 (base64)
             230 LOAD_METHOD               1 (b64encode)
             232 LOAD_GLOBAL               2 (bytes)
             234 LOAD_CONST                3 ('0')
             236 LOAD_CONST                2 ('utf-8')

 24:         238 CALL_FUNCTION             2
             240 CALL_METHOD               1
             242 LOAD_GLOBAL               0 (base64)
             244 LOAD_METHOD               1 (b64encode)
             246 LOAD_GLOBAL               2 (bytes)
             248 LOAD_CONST               14 ('n')
             250 LOAD_CONST                2 ('utf-8')

 25:         252 CALL_FUNCTION             2
             254 CALL_METHOD               1
             256 LOAD_GLOBAL               0 (base64)
             258 LOAD_METHOD               1 (b64encode)
             260 LOAD_GLOBAL               2 (bytes)
             262 LOAD_CONST               14 ('n')
             264 LOAD_CONST                2 ('utf-8')

 26:         266 CALL_FUNCTION             2
             268 CALL_METHOD               1
             270 LOAD_GLOBAL               0 (base64)
             272 LOAD_METHOD               1 (b64encode)
             274 LOAD_GLOBAL               2 (bytes)
             276 LOAD_CONST                3 ('0')
             278 LOAD_CONST                2 ('utf-8')

 27:         280 CALL_FUNCTION             2
             282 CALL_METHOD               1
             284 LOAD_GLOBAL               0 (base64)
             286 LOAD_METHOD               1 (b64encode)
             288 LOAD_GLOBAL               2 (bytes)
             290 LOAD_CONST               10 ('r')
             292 LOAD_CONST                2 ('utf-8')

  6:         294 CALL_FUNCTION             2
             296 CALL_METHOD               1

 29:         298 LOAD_GLOBAL               0 (base64)
             300 LOAD_METHOD               1 (b64encode)

 30:         302 LOAD_GLOBAL               2 (bytes)
             304 LOAD_CONST                7 ("'")

 31:         306 LOAD_CONST                2 ('utf-8')
             308 CALL_FUNCTION             2
             310 CALL_METHOD               1
             312 LOAD_GLOBAL               0 (base64)
             314 LOAD_METHOD               1 (b64encode)
             316 LOAD_GLOBAL               2 (bytes)
             318 LOAD_CONST               15 ('}')
             320 LOAD_CONST                2 ('utf-8')
             322 CALL_FUNCTION             2

 32:         324 CALL_METHOD               1
             326 BUILD_LIST               21
             328 STORE_FAST                1 (key)
             330 BUILD_LIST                0
             332 STORE_FAST                2 (result)
             334 LOAD_CONST               16 ('')
             336 STORE_FAST                3 (sucess)
             338 LOAD_GLOBAL               3 (range)
             340 LOAD_CONST               17 (0)
             342 LOAD_GLOBAL               4 (len)
             344 LOAD_FAST                 0 (attempt)
             346 CALL_FUNCTION             1
             348 CALL_FUNCTION             2
             350 GET_ITER
         >>  352 FOR_ITER                 32 (to 386)

 34:         354 STORE_FAST                4 (i)
             356 LOAD_FAST                 2 (result)
             358 LOAD_METHOD               5 (append)
             360 LOAD_GLOBAL               0 (base64)
             362 LOAD_METHOD               1 (b64encode)
             364 LOAD_GLOBAL               2 (bytes)
             366 LOAD_FAST                 0 (attempt)
             368 LOAD_FAST                 4 (i)
             370 BINARY_SUBSCR

 35:         372 LOAD_CONST                2 ('utf-8')
             374 CALL_FUNCTION             2
             376 CALL_METHOD               1
             378 CALL_METHOD               1
             380 POP_TOP
             382 EXTENDED_ARG              1 (256)
             384 JUMP_ABSOLUTE           352 (to 352)
         >>  386 LOAD_GLOBAL               3 (range)
             388 LOAD_CONST               17 (0)
             390 LOAD_GLOBAL               4 (len)
             392 LOAD_FAST                 2 (result)
             394 CALL_FUNCTION             1
             396 CALL_FUNCTION             2
             398 GET_ITER

 36:     >>  400 FOR_ITER                 70 (to 472)
             402 STORE_FAST                4 (i)
             404 LOAD_GLOBAL               4 (len)
             406 LOAD_FAST                 2 (result)
             408 CALL_FUNCTION             1
             410 LOAD_CONST               17 (0)
             412 COMPARE_OP                4 (>)
             414 EXTENDED_ARG              1 (256)
             416 POP_JUMP_IF_FALSE       400 (to 400)

 37:         418 LOAD_FAST                 4 (i)
             420 LOAD_GLOBAL               4 (len)
             422 LOAD_FAST                 1 (key)
             424 CALL_FUNCTION             1
             426 COMPARE_OP                0 (<)

 39:         428 EXTENDED_ARG              1 (256)
             430 POP_JUMP_IF_FALSE       400 (to 400)
             432 LOAD_FAST                 2 (result)
             434 LOAD_FAST                 4 (i)
             436 BINARY_SUBSCR
             438 LOAD_FAST                 1 (key)

 40:         440 LOAD_FAST                 4 (i)
             442 BINARY_SUBSCR
             444 COMPARE_OP                2 (==)
             446 EXTENDED_ARG              1 (256)
             448 POP_JUMP_IF_FALSE       460 (to 460)
             450 LOAD_FAST                 3 (sucess)
             452 LOAD_CONST               18 ('1')
             454 INPLACE_ADD
             456 STORE_FAST                3 (sucess)

 41:         458 JUMP_FORWARD              8 (to 468)
         >>  460 LOAD_FAST                 3 (sucess)
             462 LOAD_CONST                3 ('0')
             464 INPLACE_ADD
             466 STORE_FAST                3 (sucess)

 43:     >>  468 EXTENDED_ARG              1 (256)
             470 JUMP_ABSOLUTE           400 (to 400)
         >>  472 LOAD_FAST                 3 (sucess)
             474 LOAD_CONST               18 ('1')
             476 LOAD_GLOBAL               4 (len)
             478 LOAD_FAST                 1 (key)
             480 CALL_FUNCTION             1
             482 BINARY_MULTIPLY
             484 COMPARE_OP                2 (==)
             486 EXTENDED_ARG              1 (256)
             488 POP_JUMP_IF_FALSE       500 (to 500)
             490 LOAD_GLOBAL               6 (print)
             492 LOAD_CONST               19 ('You found the key')
             494 CALL_FUNCTION             1
             496 POP_TOP
             498 JUMP_FORWARD              8 (to 508)
         >>  500 LOAD_GLOBAL               6 (print)
             502 LOAD_FAST                 3 (sucess)
             504 CALL_FUNCTION             1
             506 POP_TOP
         >>  508 LOAD_CONST                0 (None)
             510 JUMP_ABSOLUTE             6 (to 6)
         >>  512 LOAD_GLOBAL               8 (__armor_exit__)
             514 CALL_FUNCTION             0
             516 POP_TOP
             518 END_FINALLY
             520 RETURN_VALUE
             522 NOP
             524 NOP
             526 NOP
             528 INPLACE_OR
             530 <210>                   195
             532 EXTENDED_ARG            238 (60928)
             534 DELETE_NAME           61070 (61070)
             536 <46>
             538 POP_JUMP_IF_FALSE        11 (to 11)
             540 STORE_ATTR              139 (139)
             542 <46>

 

Last eight "opcodes" are junk and can be safely deleted. To make .pyc file working we have to cut calls to __armor_enter__ and __armor_exit__. From this output we can assume that the key is {0x05='S@r@h_C0nn0r'}.

Attached decompiled version aswell.

challenge_decompiled.py

  • Like 1
  • Thanks 1
Link to post
On 9/13/2020 at 3:09 PM, SHADOW_UA said:

First of all, this crackme is version dependent, it only works with Python 3.8 x86. I don't have it installed, so I had to replace _pytransform.dll with the x64 equivalent downloaded from here to be able to run it with my x64 version of Python 3.8.

By looking in the memory of python.exe and placing hardware breakpoints on write on an encrypted code of PyArmor (that starts with \x50\x59\x41\x52\x4d...) we can find a place in _pytransform.dll where it decrypts it to the actual marshalled code object of Python. It is a function at RVA 0x254D0. Then we have to deal with the second layer of PyArmor obfuscation which decrypts opcodes at runtime and then encrypt it back with the same function. We can read about this at PyArmor website here.

  Hide contents


static PyObject *
__armor_enter__(PyObject *self, PyObject *args)
{
    // Got code object
    PyFrameObject *frame = PyEval_GetFrame();
    PyCodeObject *f_code = frame->f_code;

    // Increase refcalls of this code object
    // Borrow co_names->ob_refcnt as call counter
    // Generally it will not increased  by Python Interpreter
    PyObject *refcalls = f_code->co_names;
    refcalls->ob_refcnt ++;

    // Restore byte code if it's obfuscated
    if (IS_OBFUSCATED(f_code->co_flags)) {
        restore_byte_code(f_code->co_code);
        clear_obfuscated_flag(f_code);
    }

    Py_RETURN_NONE;
}

 

This code under spoiler is taken from the link above and it tells us how PyArmor works behind the scenes. We can find this piece of code easily in _pytransform.dll by placing BP on PyEval_GetFrame() and tracing a bit. There are 3 functions in this crackme, it means we have to hit and copy decrypted opcodes to our .pyc file 3 times. Make sure that it is an actual decryption of opcodes, because as I told before it uses same function to encrypt it back (through __armor_exit__). That is pretty much enough to solve this crackme, as we can use pydisasm on our pyc file and view its bytecode/wordcode.

  Hide contents


# Method Name:       check
# Filename:          <frozen challenge_2>
# Argument count:    1
# Position-only argument count: 0
# Keyword-only arguments: 0
# Number of locals:  5
# Stack size:        25
# Flags:             0x62000043 (0x40000000 | 0x20000000 | 0x2000000 | NOFREE | NEWLOCALS | OPTIMIZED)
# First Line:        5
# Constants:
#    0: None
#    1: '{'
#    2: 'utf-8'
#    3: '0'
#    4: 'x'
#    5: '5'
#    6: '='
#    7: "'"
#    8: 'S'
#    9: '@'
#   10: 'r'
#   11: 'h'
#   12: '_'
#   13: 'C'
#   14: 'n'
#   15: '}'
#   16: ''
#   17: 0
#   18: '1'
#   19: 'You found the key'
# Names:
#    0: base64
#    1: b64encode
#    2: bytes
#    3: range
#    4: len
#    5: append
#    6: print
#    7: __armor_enter__
#    8: __armor_exit__
# Varnames:
#	attempt, key, result, sucess, i
# Positional arguments:
#	attempt
# Local variables:
#    1: key
#    2: result
#    3: sucess
#    4: i
  7:           0 JUMP_ABSOLUTE            18 (to 18)
               2 NOP
               4 NOP
         >>    6 POP_BLOCK
               8 BEGIN_FINALLY
              10 NOP
              12 NOP

  8:          14 EXTENDED_ARG              2 (512)
              16 JUMP_ABSOLUTE           512 (to 512)
         >>   18 LOAD_GLOBAL               7 (__armor_enter__)
              20 CALL_FUNCTION             0
              22 POP_TOP
              24 NOP
              26 NOP

  9:          28 EXTENDED_ARG              1 (256)
              30 SETUP_FINALLY           480 (to 512)
              32 LOAD_GLOBAL               0 (base64)
              34 LOAD_METHOD               1 (b64encode)
              36 LOAD_GLOBAL               2 (bytes)
              38 LOAD_CONST                1 ('{')
              40 LOAD_CONST                2 ('utf-8')

 10:          42 CALL_FUNCTION             2
              44 CALL_METHOD               1
              46 LOAD_GLOBAL               0 (base64)
              48 LOAD_METHOD               1 (b64encode)
              50 LOAD_GLOBAL               2 (bytes)
              52 LOAD_CONST                3 ('0')
              54 LOAD_CONST                2 ('utf-8')

 11:          56 CALL_FUNCTION             2
              58 CALL_METHOD               1
              60 LOAD_GLOBAL               0 (base64)
              62 LOAD_METHOD               1 (b64encode)
              64 LOAD_GLOBAL               2 (bytes)
              66 LOAD_CONST                4 ('x')
              68 LOAD_CONST                2 ('utf-8')

 12:          70 CALL_FUNCTION             2
              72 CALL_METHOD               1
              74 LOAD_GLOBAL               0 (base64)
              76 LOAD_METHOD               1 (b64encode)
              78 LOAD_GLOBAL               2 (bytes)
              80 LOAD_CONST                3 ('0')
              82 LOAD_CONST                2 ('utf-8')

 13:          84 CALL_FUNCTION             2
              86 CALL_METHOD               1
              88 LOAD_GLOBAL               0 (base64)
              90 LOAD_METHOD               1 (b64encode)
              92 LOAD_GLOBAL               2 (bytes)
              94 LOAD_CONST                5 ('5')
              96 LOAD_CONST                2 ('utf-8')

 14:          98 CALL_FUNCTION             2
             100 CALL_METHOD               1
             102 LOAD_GLOBAL               0 (base64)
             104 LOAD_METHOD               1 (b64encode)
             106 LOAD_GLOBAL               2 (bytes)
             108 LOAD_CONST                6 ('=')
             110 LOAD_CONST                2 ('utf-8')

 15:         112 CALL_FUNCTION             2
             114 CALL_METHOD               1
             116 LOAD_GLOBAL               0 (base64)
             118 LOAD_METHOD               1 (b64encode)
             120 LOAD_GLOBAL               2 (bytes)
             122 LOAD_CONST                7 ("'")
             124 LOAD_CONST                2 ('utf-8')

 16:         126 CALL_FUNCTION             2
             128 CALL_METHOD               1
             130 LOAD_GLOBAL               0 (base64)
             132 LOAD_METHOD               1 (b64encode)
             134 LOAD_GLOBAL               2 (bytes)
             136 LOAD_CONST                8 ('S')
             138 LOAD_CONST                2 ('utf-8')

 17:         140 CALL_FUNCTION             2
             142 CALL_METHOD               1
             144 LOAD_GLOBAL               0 (base64)
             146 LOAD_METHOD               1 (b64encode)
             148 LOAD_GLOBAL               2 (bytes)
             150 LOAD_CONST                9 ('@')
             152 LOAD_CONST                2 ('utf-8')

 18:         154 CALL_FUNCTION             2
             156 CALL_METHOD               1
             158 LOAD_GLOBAL               0 (base64)
             160 LOAD_METHOD               1 (b64encode)
             162 LOAD_GLOBAL               2 (bytes)
             164 LOAD_CONST               10 ('r')
             166 LOAD_CONST                2 ('utf-8')

 19:         168 CALL_FUNCTION             2
             170 CALL_METHOD               1
             172 LOAD_GLOBAL               0 (base64)
             174 LOAD_METHOD               1 (b64encode)
             176 LOAD_GLOBAL               2 (bytes)
             178 LOAD_CONST                9 ('@')
             180 LOAD_CONST                2 ('utf-8')

 20:         182 CALL_FUNCTION             2
             184 CALL_METHOD               1
             186 LOAD_GLOBAL               0 (base64)
             188 LOAD_METHOD               1 (b64encode)
             190 LOAD_GLOBAL               2 (bytes)
             192 LOAD_CONST               11 ('h')
             194 LOAD_CONST                2 ('utf-8')

 21:         196 CALL_FUNCTION             2
             198 CALL_METHOD               1
             200 LOAD_GLOBAL               0 (base64)
             202 LOAD_METHOD               1 (b64encode)
             204 LOAD_GLOBAL               2 (bytes)
             206 LOAD_CONST               12 ('_')
             208 LOAD_CONST                2 ('utf-8')

 22:         210 CALL_FUNCTION             2
             212 CALL_METHOD               1
             214 LOAD_GLOBAL               0 (base64)
             216 LOAD_METHOD               1 (b64encode)
             218 LOAD_GLOBAL               2 (bytes)
             220 LOAD_CONST               13 ('C')
             222 LOAD_CONST                2 ('utf-8')

 23:         224 CALL_FUNCTION             2
             226 CALL_METHOD               1
             228 LOAD_GLOBAL               0 (base64)
             230 LOAD_METHOD               1 (b64encode)
             232 LOAD_GLOBAL               2 (bytes)
             234 LOAD_CONST                3 ('0')
             236 LOAD_CONST                2 ('utf-8')

 24:         238 CALL_FUNCTION             2
             240 CALL_METHOD               1
             242 LOAD_GLOBAL               0 (base64)
             244 LOAD_METHOD               1 (b64encode)
             246 LOAD_GLOBAL               2 (bytes)
             248 LOAD_CONST               14 ('n')
             250 LOAD_CONST                2 ('utf-8')

 25:         252 CALL_FUNCTION             2
             254 CALL_METHOD               1
             256 LOAD_GLOBAL               0 (base64)
             258 LOAD_METHOD               1 (b64encode)
             260 LOAD_GLOBAL               2 (bytes)
             262 LOAD_CONST               14 ('n')
             264 LOAD_CONST                2 ('utf-8')

 26:         266 CALL_FUNCTION             2
             268 CALL_METHOD               1
             270 LOAD_GLOBAL               0 (base64)
             272 LOAD_METHOD               1 (b64encode)
             274 LOAD_GLOBAL               2 (bytes)
             276 LOAD_CONST                3 ('0')
             278 LOAD_CONST                2 ('utf-8')

 27:         280 CALL_FUNCTION             2
             282 CALL_METHOD               1
             284 LOAD_GLOBAL               0 (base64)
             286 LOAD_METHOD               1 (b64encode)
             288 LOAD_GLOBAL               2 (bytes)
             290 LOAD_CONST               10 ('r')
             292 LOAD_CONST                2 ('utf-8')

  6:         294 CALL_FUNCTION             2
             296 CALL_METHOD               1

 29:         298 LOAD_GLOBAL               0 (base64)
             300 LOAD_METHOD               1 (b64encode)

 30:         302 LOAD_GLOBAL               2 (bytes)
             304 LOAD_CONST                7 ("'")

 31:         306 LOAD_CONST                2 ('utf-8')
             308 CALL_FUNCTION             2
             310 CALL_METHOD               1
             312 LOAD_GLOBAL               0 (base64)
             314 LOAD_METHOD               1 (b64encode)
             316 LOAD_GLOBAL               2 (bytes)
             318 LOAD_CONST               15 ('}')
             320 LOAD_CONST                2 ('utf-8')
             322 CALL_FUNCTION             2

 32:         324 CALL_METHOD               1
             326 BUILD_LIST               21
             328 STORE_FAST                1 (key)
             330 BUILD_LIST                0
             332 STORE_FAST                2 (result)
             334 LOAD_CONST               16 ('')
             336 STORE_FAST                3 (sucess)
             338 LOAD_GLOBAL               3 (range)
             340 LOAD_CONST               17 (0)
             342 LOAD_GLOBAL               4 (len)
             344 LOAD_FAST                 0 (attempt)
             346 CALL_FUNCTION             1
             348 CALL_FUNCTION             2
             350 GET_ITER
         >>  352 FOR_ITER                 32 (to 386)

 34:         354 STORE_FAST                4 (i)
             356 LOAD_FAST                 2 (result)
             358 LOAD_METHOD               5 (append)
             360 LOAD_GLOBAL               0 (base64)
             362 LOAD_METHOD               1 (b64encode)
             364 LOAD_GLOBAL               2 (bytes)
             366 LOAD_FAST                 0 (attempt)
             368 LOAD_FAST                 4 (i)
             370 BINARY_SUBSCR

 35:         372 LOAD_CONST                2 ('utf-8')
             374 CALL_FUNCTION             2
             376 CALL_METHOD               1
             378 CALL_METHOD               1
             380 POP_TOP
             382 EXTENDED_ARG              1 (256)
             384 JUMP_ABSOLUTE           352 (to 352)
         >>  386 LOAD_GLOBAL               3 (range)
             388 LOAD_CONST               17 (0)
             390 LOAD_GLOBAL               4 (len)
             392 LOAD_FAST                 2 (result)
             394 CALL_FUNCTION             1
             396 CALL_FUNCTION             2
             398 GET_ITER

 36:     >>  400 FOR_ITER                 70 (to 472)
             402 STORE_FAST                4 (i)
             404 LOAD_GLOBAL               4 (len)
             406 LOAD_FAST                 2 (result)
             408 CALL_FUNCTION             1
             410 LOAD_CONST               17 (0)
             412 COMPARE_OP                4 (>)
             414 EXTENDED_ARG              1 (256)
             416 POP_JUMP_IF_FALSE       400 (to 400)

 37:         418 LOAD_FAST                 4 (i)
             420 LOAD_GLOBAL               4 (len)
             422 LOAD_FAST                 1 (key)
             424 CALL_FUNCTION             1
             426 COMPARE_OP                0 (<)

 39:         428 EXTENDED_ARG              1 (256)
             430 POP_JUMP_IF_FALSE       400 (to 400)
             432 LOAD_FAST                 2 (result)
             434 LOAD_FAST                 4 (i)
             436 BINARY_SUBSCR
             438 LOAD_FAST                 1 (key)

 40:         440 LOAD_FAST                 4 (i)
             442 BINARY_SUBSCR
             444 COMPARE_OP                2 (==)
             446 EXTENDED_ARG              1 (256)
             448 POP_JUMP_IF_FALSE       460 (to 460)
             450 LOAD_FAST                 3 (sucess)
             452 LOAD_CONST               18 ('1')
             454 INPLACE_ADD
             456 STORE_FAST                3 (sucess)

 41:         458 JUMP_FORWARD              8 (to 468)
         >>  460 LOAD_FAST                 3 (sucess)
             462 LOAD_CONST                3 ('0')
             464 INPLACE_ADD
             466 STORE_FAST                3 (sucess)

 43:     >>  468 EXTENDED_ARG              1 (256)
             470 JUMP_ABSOLUTE           400 (to 400)
         >>  472 LOAD_FAST                 3 (sucess)
             474 LOAD_CONST               18 ('1')
             476 LOAD_GLOBAL               4 (len)
             478 LOAD_FAST                 1 (key)
             480 CALL_FUNCTION             1
             482 BINARY_MULTIPLY
             484 COMPARE_OP                2 (==)
             486 EXTENDED_ARG              1 (256)
             488 POP_JUMP_IF_FALSE       500 (to 500)
             490 LOAD_GLOBAL               6 (print)
             492 LOAD_CONST               19 ('You found the key')
             494 CALL_FUNCTION             1
             496 POP_TOP
             498 JUMP_FORWARD              8 (to 508)
         >>  500 LOAD_GLOBAL               6 (print)
             502 LOAD_FAST                 3 (sucess)
             504 CALL_FUNCTION             1
             506 POP_TOP
         >>  508 LOAD_CONST                0 (None)
             510 JUMP_ABSOLUTE             6 (to 6)
         >>  512 LOAD_GLOBAL               8 (__armor_exit__)
             514 CALL_FUNCTION             0
             516 POP_TOP
             518 END_FINALLY
             520 RETURN_VALUE
             522 NOP
             524 NOP
             526 NOP
             528 INPLACE_OR
             530 <210>                   195
             532 EXTENDED_ARG            238 (60928)
             534 DELETE_NAME           61070 (61070)
             536 <46>
             538 POP_JUMP_IF_FALSE        11 (to 11)
             540 STORE_ATTR              139 (139)
             542 <46>

 

Last eight "opcodes" are junk and can be safely deleted. To make .pyc file working we have to cut calls to __armor_enter__ and __armor_exit__. From this output we can assume that the key is {0x05='S@r@h_C0nn0r'}.

Attached decompiled version aswell.

challenge_decompiled.py 1.59 kB · 5 downloads

i learn somethings from you but i get few questions :
how did you edit _pytransform.dll and how did you get this output and decompiled it i mean the steps You taked if you can answer, Thank You anyway 

Link to post
SHADOW_UA
21 hours ago, AboSaad said:

i learn somethings from you but i get few questions :
how did you edit _pytransform.dll and how did you get this output and decompiled it i mean the steps You taked if you can answer, Thank You anyway 

You have to place license data and transform key inside _pytransform.dll to be able to use dll that was downloaded from server. Check this source code file, specifically _patch_extension method. To decompile pyc file, you have to deal with some anti-decompiling features that PyArmor has. For example, uncompyle6 does not work on the piece of code with several "NOP" in a row. Check this opcodes reference, you can easily edit pyc file using your favourite hex editor.

  • Like 1
Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...