컴파일된 pyc가 포함된 zip파일에서 python 코드 디컴파일
문제 출처 :
Hack.lu 2013 [ What's wrong with this?]
- zip file : library.zip
- pyc file : __main__hello__.pyc
- >>> import zipimport
- >>>
- >>> importer = zipimport.zipimporter('library.zip')
- >>> code = importer.get_code('__main__hello__')
- >>>
- >>> print dir(code)
- ['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__','__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars','co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize','co_varnames']
- >>> print code.co_names # 사용된 오브젝트 이름
- ('sys', 'hashlib', 'sha256', 'dis', 'multiprocessing', 'UserList', 'encrypt_string', 'rot_chr', 'SECRET', 'argv')
- >>>
- >>> import dis
- >>> dis.dis(code)# 파이썬 바이너리 코드를 disassemble함
- 1 0 LOAD_CONST 0 (-1)
- 3 LOAD_CONST 1 (None)
- 6 IMPORT_NAME 0 (sys)
- 9 STORE_NAME 0 (sys)
- 2 12 LOAD_CONST 0 (-1)
- 15 LOAD_CONST 2 (('sha256',))
- 18 IMPORT_NAME 1 (hashlib)
- 21 IMPORT_FROM 2 (sha256)
- 24 STORE_NAME 2 (sha256)
- 27 ROT_TWO
- 3 28 LOAD_CONST 0 (-1)
- 31 LOAD_CONST 1 (None)
- 34 IMPORT_NAME 3 (dis)
- 37 STORE_NAME 3 (dis)
- 40 LOAD_CONST 0 (-1)
- 43 LOAD_CONST 1 (None)
- 46 IMPORT_NAME 4 (multiprocessing)
- 49 STORE_NAME 4 (multiprocessing)
- 52 LOAD_CONST 0 (-1)
- 55 LOAD_CONST 1 (None)
- 58 IMPORT_NAME 5 (UserList)
- 61 STORE_NAME 5 (UserList)
- 5 64 LOAD_CONST 3 (<code object encrypt_string at 0x7fa62ded7cb0, file "chall.py", line 5>) # 첫번째 함수
- 67 MAKE_FUNCTION 0
- 70 STORE_NAME 6 (encrypt_string)
- 16 73 LOAD_CONST 4 (<code object rot_chr at 0x7fa62dedcb30, file "chall.py", line 16>) # 두번째 함수
- 76 MAKE_FUNCTION 0
- 79 STORE_NAME 7 (rot_chr)
- 19 82 LOAD_CONST 5 ('w*0;CNU[\\gwPWk}3:PWk"#&:ABu/:Hi,M')
- 85 STORE_NAME 8 (SECRET)
- 20 88 LOAD_NAME 6 (encrypt_string)
- 91 LOAD_NAME 0 (sys)
- 94 LOAD_ATTR 9 (argv)
- 97 LOAD_CONST 6 (1)
- 100 BINARY_SUBSCR
- 101 CALL_FUNCTION 1
- 104 LOAD_NAME 8 (SECRET)
- 107 COMPARE_OP 2 (==)
- 110 POP_JUMP_IF_FALSE 121
- 21 113 LOAD_CONST 7 ('Yup')
- 116 PRINT_ITEM
- 117 PRINT_NEWLINE
- 118 JUMP_FORWARD 5 (to 126)
- 23 >> 121 LOAD_CONST 8 ('Nope')
- 124 PRINT_ITEM
- 125 PRINT_NEWLINE
- >> 126 LOAD_CONST 1 (None)
- 129 RETURN_VALUE
- >>> print code.co_consts
- (-1, None, ('sha256',), <code object encrypt_string at 0x7fa62ded7cb0, file "chall.py", line 5>, <code object rot_chr at 0x7fa62dedcb30, file"chall.py", line 16>, 'w*0;CNU[\\gwPWk}3:PWk"#&:ABu/:Hi,M', 1, 'Yup', 'Nope')
- >>> print code.co_consts[3]
- <code object encrypt_string at 0x7fa62ded7cb0, file "chall.py", line 5>
- >>>
- >>> dir(code.co_consts[3])
- ['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__','__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars','co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize','co_varnames']
- >>>
- >>> print code.co_consts[3].co_code
- g}xct|▒E]U\}}|dkrD|jt|d▒▒q|jt|t||d▒▒▒qXdj|▒T
- >>> dis.dis(code.co_consts[3].co_code)
- 0 BUILD_LIST 0
- 3 STORE_FAST 1 (1) # '1' = new_str = []
- 6 SETUP_LOOP 99 (to 108) # for
- 9 LOAD_GLOBAL 0 (0) # 'global_0' = parameter : s
- 12 LOAD_FAST 0 (0) # '0' = s
- 15 CALL_FUNCTION 1 # enumerate(s)
- 18 GET_ITER
- >> 19 FOR_ITER 85 (to 107)
- 22 UNPACK_SEQUENCE 2 # (index, c)
- 25 STORE_FAST 2 (2) # '2' = index
- 28 STORE_FAST 3 (3) # '3' = c
- 31 LOAD_FAST 2 (2) # index
- 34 LOAD_CONST 1 (1) # 'const_1' = 0
- 37 COMPARE_OP 2 (==) # ( '2' == '1' ) <-> ( index == 1 )
- 40 POP_JUMP_IF_FALSE 68
- 43 LOAD_FAST 1 (1) # '1' (new_str)
- 46 LOAD_ATTR 1 (1) # '1'.'1' (new_str.append)
- 49 LOAD_GLOBAL 2 (2) # 'global_2' = 'rot_chr'
- 52 LOAD_FAST 3 (3) # 'c'
- 55 LOAD_CONST 2 (2) # 'const_2' = 10
- 58 CALL_FUNCTION 2 # rot_chr(c, 10)
- 61 CALL_FUNCTION 1 # new_str.append(rot_chr(c, 10))
- 64 POP_TOP
- 65 JUMP_ABSOLUTE 19
- >> 68 LOAD_FAST 1 (1) # '1' (new_str)
- 71 LOAD_ATTR 1 (1) # '1'.'1' (new_str.append)
- 74 LOAD_GLOBAL 2 (2) # 'global_2' = 'rot_chr'
- 77 LOAD_FAST 3 (3) # 'c'
- 80 LOAD_GLOBAL 3 (3) # 'global_3' = 'ord'
- 83 LOAD_FAST 1 (1) # '1' (new_str)
- 86 LOAD_FAST 2 (2) # '2' = index
- 89 LOAD_CONST 3 (3) # 'const_2' = 1
- 92 BINARY_SUBTRACT # '2' - 'const_2' <-> index - 1
- 93 BINARY_SUBSCR # new_str[index - 1]
- 94 CALL_FUNCTION 1 # ord(new_str[index - 1])
- 97 CALL_FUNCTION 2 # rot_chr(c, ord(new_str[index - 1]))
- 100 CALL_FUNCTION 1 # new_str.append(rot_chr(c, ord(new_str[index - 1])))
- 103 POP_TOP
- 104 JUMP_ABSOLUTE 19
- >> 107 POP_BLOCK
- >> 108 LOAD_CONST 4 (4)
- 111 LOAD_ATTR 4 (4)
- 114 LOAD_FAST 1 (1)
- 117 CALL_FUNCTION 1
- 120 RETURN_VALUE
<code object encrypt_string at 0x7fa62ded7cb0, file "chall.py", line 5> 디컴파일 결과
- def encrypt_string(s):
- new_str = []
- for (index, c) in enumerate(s):
- if (index == 0):
- new_str.append(rot_chr(c,10))
- else:
- new_str.append(rot_chr(c,ord(new_str[index - 1])))
- return ''.join(new_str)
전체 소스 디컴파일 결과
- import sys
- import dis
- import multiprocessing
- import UserList
- def encrypt_string(s):
- new_str = []
- for (index, c) in enumerate(s):
- if (index == 0):
- new_str.append(rot_chr(c,10))
- else:
- new_str.append(rot_chr(c,ord(new_str[index - 1])))
- return ''.join(new_str)
- def rot_chr(c, amount):
- return chr((((ord(c) - 33) + amount) % 94) + 33)
- SECRET = 'w*0;CNU[\\gwPWk}3:PWk"#&:ABu/:Hi,M'
- if encrypt_string(sys.argv[1]) == SECRET:
- print
- print >>'Yup'
- else:
- print
- print >>'Nope'
** key : modified_in7erpreters_are_3vil!!! **
Reference :
- http://docs.python.org/2/library/dis.html#python-bytecode-instructions
- http://pymotw.com/2/dis/
- http://stackoverflow.com/questions/16219245/how-do-you-remove-the-nth-index-of-a-nested-list
- http://stackoverflow.com/questions/13905741/accessing-class-variables-from-a-list-comprehension-in-the-class-definition
댓글 없음:
댓글 쓰기