Skip to content

Commit 599495c

Browse files
committed
analyze_crypted_code: Add support for Python 3.10 and older
1 parent c1bf702 commit 599495c

1 file changed

Lines changed: 10 additions & 5 deletions

File tree

analyze_crypted_code.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,23 @@ def display_code(code_obj):
6161
def get_crypto_info(all_data: bytes, code_obj) -> dict:
6262
"""Returns a dictionary with information about the ciphered region in the code object."""
6363

64-
# NOTES:
64+
# NOTES (Python 3.11+):
6565
# 1. co_code is sanitized before being given out to a script (invalid opcodes are zeroed), so it's useless for us
6666
# 2. Using _co_code_adaptive only works because we disable specialization in our custom Python build
67-
code: bytes = code_obj._co_code_adaptive
67+
if sys.version_info.major > 3 or sys.version_info.minor > 10:
68+
code: bytes = code_obj._co_code_adaptive
69+
else:
70+
code = code_obj.co_code
6871
code_offset_in_data = all_data.index(code)
6972

70-
if code[8] != opcode.opmap["LOAD_CONST"] or code[12] != opcode.opmap["CALL_FUNCTION_EX"]:
73+
case1 = code[8] == opcode.opmap["LOAD_CONST"] and code[12] == opcode.opmap["CALL_FUNCTION_EX"]
74+
case2 = code[14] == opcode.opmap["LOAD_CONST"] and code[16] == opcode.opmap["CALL_FUNCTION"]
75+
if not case1 and not case2:
7176
print("Method does not seem to be encrypted")
7277
return {}
7378

74-
# Get the LOAD_CONST bytes that can be seen above at offset 8.
75-
crypto_info = code_obj.co_consts[code[9]]
79+
# Get the constant that is loaded by LOAD_CONST at offset 8 or 14.
80+
crypto_info = code_obj.co_consts[code[(8 if case1 else 14) + 1]]
7681

7782
if not isinstance(crypto_info, bytes):
7883
raise Exception(f"Expected LOAD_CONST to load bytes, got {type(crypto_info)}")

0 commit comments

Comments
 (0)