lopeg Posted September 12, 2020 Posted September 12, 2020 (edited) View File Not easy but not hard CrackMe Try to find the key Hint : The key countains - Specials - Caps - Non caps - Numbers Enter the key and you will see the results. Good luck. Submitter lopeg Submitted 09/12/2020 Category CrackMe Edited September 13, 2020 by lopeg
SHADOW_UA Posted September 13, 2020 Posted September 13, 2020 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 2 1
AboSaad Posted September 15, 2020 Posted September 15, 2020 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
SHADOW_UA Posted September 16, 2020 Posted September 16, 2020 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. 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now