// SPDX-FileCopyrightText: 2020 FXTi // SPDX-License-Identifier: LGPL-3.0-only #include "opcode.h" // The actual code of one opcode varies across the versions. // That's why I specify one opcode by its name, not its code. static inline void analysis_push(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg, ut32 type, st32 push_cnt) { op->type = type; op->stackop = RZ_ANALYSIS_STACK_INC; op->stackptr = OBJECT_SIZE_ON_STACK * push_cnt; } static inline void analysis_pop(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg, ut32 type, st32 push_cnt) { op->type = type; op->stackop = RZ_ANALYSIS_STACK_INC; op->stackptr = -(OBJECT_SIZE_ON_STACK * push_cnt); } static void analysis_BEFORE_ASYNC_WITH(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_BEGIN_FINALLY(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_BINARY_ADD(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_ADD, 1); } static void analysis_BINARY_AND(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_AND, 1); } static void analysis_BINARY_CALL(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // https://github.com/python/cpython/blob/v1.4b3/Include/opcode.h // I can not find this opcode even in v1.4 version source code. op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_BINARY_DIVIDE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_DIV, 1); } static void analysis_BINARY_FLOOR_DIVIDE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_DIV, 1); } static void analysis_BINARY_LSHIFT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_SHL, 1); } static void analysis_BINARY_MATRIX_MULTIPLY(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_BINARY_MODULO(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_MOD, 1); } static void analysis_BINARY_MULTIPLY(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_MUL, 1); } static void analysis_BINARY_OR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_OR, 1); } static void analysis_BINARY_POWER(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_BINARY_RSHIFT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_SHR, 1); } static void analysis_BINARY_SUBSCR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_BINARY_SUBTRACT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_SUB, 1); } static void analysis_BINARY_TRUE_DIVIDE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_DIV, 1); } static void analysis_BINARY_XOR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_XOR, 1); } static void analysis_BREAK_LOOP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // op->type = RZ_ANALYSIS_OP_TYPE_CJMP; // This is actually a jump, but require further analysis op->type = RZ_ANALYSIS_OP_TYPE_UNK; op->jump = -1; op->fail = -1; } static void analysis_BUILD_CLASS(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, 2); } static void analysis_BUILD_CONST_KEY_MAP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg); } static void analysis_BUILD_FUNCTION(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_NEW; } static void analysis_BUILD_LIST(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg); } static void analysis_BUILD_LIST_UNPACK(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg - 1); } static void analysis_BUILD_MAP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, 2 * oparg - 1); } static void analysis_BUILD_MAP_UNPACK(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg - 1); } static void analysis_BUILD_MAP_UNPACK_WITH_CALL(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg); } static void analysis_BUILD_SET(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg - 1); } static void analysis_BUILD_SET_UNPACK(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg - 1); } static void analysis_BUILD_SLICE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg - 1); } static void analysis_BUILD_STRING(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg - 1); } static void analysis_BUILD_TUPLE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg - 1); } static void analysis_BUILD_TUPLE_UNPACK(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg - 1); } static void analysis_BUILD_TUPLE_UNPACK_WITH_CALL(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_NEW, oparg); } static void analysis_CALL_FUNCTION(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // TODO // Get callee function from stack // Parse oparg by version info op->type = RZ_ANALYSIS_OP_TYPE_ICALL; op->jump = -1; } static void analysis_CALL_FUNCTION_EX(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_ICALL; op->jump = -1; } static void analysis_CALL_FUNCTION_KW(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_ICALL; op->jump = -1; } static void analysis_CALL_FUNCTION_VAR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_ICALL; op->jump = -1; } static void analysis_CALL_FUNCTION_VAR_KW(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_ICALL; op->jump = -1; } static void analysis_CALL_METHOD(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_ICALL; op->jump = -1; } static void analysis_DELETE_ATTR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DELETE_DEREF(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DELETE_FAST(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DELETE_GLOBAL(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DELETE_NAME(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DELETE_SLICE_0(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DELETE_SLICE_1(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DELETE_SLICE_2(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DELETE_SLICE_3(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DELETE_SUBSCR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_DUP_TOP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UPUSH, 1); } static void analysis_DUP_TOPX(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UPUSH, 1); } static void analysis_DUP_TOP_TWO(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UPUSH, 2); } static void analysis_END_ASYNC_FOR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // If TOS is StopAsyncIteration pop 7 values from the stack and restore the exception state using the second three of them. op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_END_FINALLY(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // op->type = RZ_ANALYSIS_OP_TYPE_CJMP; // This is actually a jump, but require further analysis op->type = RZ_ANALYSIS_OP_TYPE_UNK; op->jump = -1; op->fail = -1; } static void analysis_EXEC_STMT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_EXTENDED_ARG(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_FORMAT_VALUE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; if ((oparg & 0x04) == 0x04) { op->stackop = RZ_ANALYSIS_STACK_INC; op->stackptr = -OBJECT_SIZE_ON_STACK; } } static void analysis_FOR_LOOP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // https://github.com/python/cpython/blob/b2b1ed17819ecb24a78d07d3ff1e8e6bc6137721/Python/ceval.c#L1499 op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_GET_AITER(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_GET_ANEXT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_GET_AWAITABLE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_GET_ITER(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_GET_YIELD_FROM_ITER(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_IMPORT_FROM(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_IMPORT_NAME(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_IMPORT_STAR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_INPLACE_ADD(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_ADD; } static void analysis_INPLACE_AND(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_AND; } static void analysis_INPLACE_DIVIDE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_DIV; } static void analysis_INPLACE_FLOOR_DIVIDE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_DIV; } static void analysis_INPLACE_LSHIFT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_SHL; } static void analysis_INPLACE_MATRIX_MULTIPLY(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_INPLACE_MODULO(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_MOD; } static void analysis_INPLACE_MULTIPLY(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_MUL; } static void analysis_INPLACE_OR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_OR; } static void analysis_INPLACE_POWER(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_INPLACE_RSHIFT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_SHR; } static void analysis_INPLACE_SUBTRACT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_SUB; } static void analysis_INPLACE_TRUE_DIVIDE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_DIV; } static void analysis_INPLACE_XOR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_XOR; } static void analysis_LIST_APPEND(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_ASSERTION_ERROR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_ATTR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_LOAD_BUILD_CLASS(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_CLASSDEREF(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_CLOSURE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_CONST(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_DEREF(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_FAST(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_GLOBAL(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_GLOBALS(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // https://github.com/python/cpython/blob/24260ec91623c18569225229d5becb852010ae2c/Include/opcode.h#L80 // Can't find this opcode op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_LOAD_LOCAL(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_LOCALS(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_METHOD(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_LOAD_NAME(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_MAKE_CLOSURE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, oparg); } static void analysis_MAKE_FUNCTION(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, oparg); } static void analysis_MAP_ADD(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_NOP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_NOP; } static void analysis_POP_BLOCK(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_POP, 1); } static void analysis_POP_EXCEPT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_POP, 1); } static void analysis_POP_FINALLY(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // FIXME // POP_FINALLY will pop 6 elements if TOS is an exception type analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_POP, 1); } static void analysis_POP_TOP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_POP, 1); } static void analysis_PRINT_EXPR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_PRINT_ITEM(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_PRINT_ITEM_TO(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 2); } static void analysis_PRINT_NEWLINE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_PRINT_NEWLINE_TO(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_RAISE_EXCEPTION(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // https://github.com/python/cpython/blob/6c3a3aa17b028f6b93067083d32c7eaa4338757c/Include/opcode.h#L89 // Can't find this opcode op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_RAISE_VARARGS(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, oparg); } static void analysis_RERAISE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 3); } static void analysis_RESERVE_FAST(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // https://github.com/python/cpython/blob/6c3a3aa17b028f6b93067083d32c7eaa4338757c/Include/opcode.h#L134 // Can't find this opcode op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_RETURN_VALUE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_RET; op->stackop = RZ_ANALYSIS_STACK_INC; op->stackptr = -OBJECT_SIZE_ON_STACK; op->eob = true; } static void analysis_ROT_FOUR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // Lifts second, third and forth stack items one position up, moves top down to position four. op->type = RZ_ANALYSIS_OP_TYPE_XCHG; } static void analysis_ROT_THREE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // Lifts second and third stack item one position up, moves top down to position three. op->type = RZ_ANALYSIS_OP_TYPE_XCHG; } static void analysis_ROT_TWO(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // Swaps the two top-most stack items. op->type = RZ_ANALYSIS_OP_TYPE_XCHG; } static void analysis_SETUP_ANNOTATIONS(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_SET_ADD(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_SET_FUNC_ARGS(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // https://github.com/python/cpython/blob/v1.4/Python/ceval.c // Can't find this opcode op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_SET_LINENO(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_SLICE_0(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_SLICE_1(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_SLICE_2(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_SLICE_3(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 2); } static void analysis_STOP_CODE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_TRAP; } static void analysis_STORE_ANNOTATION(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_STORE_ATTR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_STORE_DEREF(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_STORE_FAST(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_STORE_GLOBAL(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_STORE_LOCALS(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_STORE_MAP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 2); } static void analysis_STORE_NAME(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_STORE_SLICE_0(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 2); } static void analysis_STORE_SLICE_1(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 3); } static void analysis_STORE_SLICE_2(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 3); } static void analysis_STORE_SLICE_3(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 4); } static void analysis_STORE_SUBSCR(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 3); } static void analysis_UNARY_CALL(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // https://github.com/python/cpython/blob/v1.4b3/Include/opcode.h // I can not find this opcode even in v1.4 version source code. op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_UNARY_CONVERT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_UNARY_INVERT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_NOT; } static void analysis_UNARY_NEGATIVE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_UNARY_NOT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_NOT; } static void analysis_UNARY_POSITIVE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_UNPACK_ARG(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, oparg - 1); } static void analysis_UNPACK_EX(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, (oparg & 0xFF) + (oparg >> 8)); } static void analysis_UNPACK_LIST(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, oparg - 1); } static void analysis_UNPACK_SEQUENCE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, oparg - 1); } static void analysis_UNPACK_TUPLE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, oparg - 1); } static void analysis_UNPACK_VARARG(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // https://github.com/python/cpython/blob/v1.4b3/Include/opcode.h // I can not find this opcode even in v1.4 version source code. op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_WITH_CLEANUP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // Need the value on stack op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_WITH_CLEANUP_FINISH(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 2); } static void analysis_WITH_CLEANUP_START(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { // Need the value on stack op->type = RZ_ANALYSIS_OP_TYPE_UNK; } static void analysis_WITH_EXCEPT_START(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_push(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_YIELD_FROM(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_YIELD_VALUE(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { analysis_pop(op, op_obj, oparg, RZ_ANALYSIS_OP_TYPE_UNK, 1); } static void analysis_FOR_ITER(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_CJMP; ut64 mid = op->jump; op->jump = op->fail; op->fail = mid; } static void analysis_SETUP_LOOP(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { ut64 mid = op->jump; op->jump = op->fail; op->fail = mid; } static void analysis_SETUP_EXCEPT(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { ut64 mid = op->jump; op->jump = op->fail; op->fail = mid; } static void analysis_SETUP_FINALLY(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { ut64 mid = op->jump; op->jump = op->fail; op->fail = mid; } static void analysis_SETUP_WITH(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_CJMP; ut64 mid = op->jump; op->jump = op->fail; op->fail = mid; } static void analysis_SETUP_ASYNC_WITH(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { op->type = RZ_ANALYSIS_OP_TYPE_CJMP; ut64 mid = op->jump; op->jump = op->fail; op->fail = mid; } static op_analysis_func op_analysis[] = { { "BEFORE_ASYNC_WITH", analysis_BEFORE_ASYNC_WITH }, { "BEGIN_FINALLY", analysis_BEGIN_FINALLY }, { "BINARY_ADD", analysis_BINARY_ADD }, { "BINARY_AND", analysis_BINARY_AND }, { "BINARY_CALL", analysis_BINARY_CALL }, { "BINARY_DIVIDE", analysis_BINARY_DIVIDE }, { "BINARY_FLOOR_DIVIDE", analysis_BINARY_FLOOR_DIVIDE }, { "BINARY_LSHIFT", analysis_BINARY_LSHIFT }, { "BINARY_MATRIX_MULTIPLY", analysis_BINARY_MATRIX_MULTIPLY }, { "BINARY_MODULO", analysis_BINARY_MODULO }, { "BINARY_MULTIPLY", analysis_BINARY_MULTIPLY }, { "BINARY_OR", analysis_BINARY_OR }, { "BINARY_POWER", analysis_BINARY_POWER }, { "BINARY_RSHIFT", analysis_BINARY_RSHIFT }, { "BINARY_SUBSCR", analysis_BINARY_SUBSCR }, { "BINARY_SUBTRACT", analysis_BINARY_SUBTRACT }, { "BINARY_TRUE_DIVIDE", analysis_BINARY_TRUE_DIVIDE }, { "BINARY_XOR", analysis_BINARY_XOR }, { "BREAK_LOOP", analysis_BREAK_LOOP }, { "BUILD_CLASS", analysis_BUILD_CLASS }, { "BUILD_CONST_KEY_MAP", analysis_BUILD_CONST_KEY_MAP }, { "BUILD_FUNCTION", analysis_BUILD_FUNCTION }, { "BUILD_LIST", analysis_BUILD_LIST }, { "BUILD_LIST_UNPACK", analysis_BUILD_LIST_UNPACK }, { "BUILD_MAP", analysis_BUILD_MAP }, { "BUILD_MAP_UNPACK", analysis_BUILD_MAP_UNPACK }, { "BUILD_MAP_UNPACK_WITH_CALL", analysis_BUILD_MAP_UNPACK_WITH_CALL }, { "BUILD_SET", analysis_BUILD_SET }, { "BUILD_SET_UNPACK", analysis_BUILD_SET_UNPACK }, { "BUILD_SLICE", analysis_BUILD_SLICE }, { "BUILD_STRING", analysis_BUILD_STRING }, { "BUILD_TUPLE", analysis_BUILD_TUPLE }, { "BUILD_TUPLE_UNPACK", analysis_BUILD_TUPLE_UNPACK }, { "BUILD_TUPLE_UNPACK_WITH_CALL", analysis_BUILD_TUPLE_UNPACK_WITH_CALL }, { "CALL_FUNCTION", analysis_CALL_FUNCTION }, { "CALL_FUNCTION_EX", analysis_CALL_FUNCTION_EX }, { "CALL_FUNCTION_KW", analysis_CALL_FUNCTION_KW }, { "CALL_FUNCTION_VAR", analysis_CALL_FUNCTION_VAR }, { "CALL_FUNCTION_VAR_KW", analysis_CALL_FUNCTION_VAR_KW }, { "CALL_METHOD", analysis_CALL_METHOD }, { "DELETE_ATTR", analysis_DELETE_ATTR }, { "DELETE_DEREF", analysis_DELETE_DEREF }, { "DELETE_FAST", analysis_DELETE_FAST }, { "DELETE_GLOBAL", analysis_DELETE_GLOBAL }, { "DELETE_NAME", analysis_DELETE_NAME }, { "DELETE_SLICE_0", analysis_DELETE_SLICE_0 }, { "DELETE_SLICE_1", analysis_DELETE_SLICE_1 }, { "DELETE_SLICE_2", analysis_DELETE_SLICE_2 }, { "DELETE_SLICE_3", analysis_DELETE_SLICE_3 }, { "DELETE_SUBSCR", analysis_DELETE_SUBSCR }, { "DUP_TOP", analysis_DUP_TOP }, { "DUP_TOPX", analysis_DUP_TOPX }, { "DUP_TOP_TWO", analysis_DUP_TOP_TWO }, { "END_ASYNC_FOR", analysis_END_ASYNC_FOR }, { "END_FINALLY", analysis_END_FINALLY }, { "EXEC_STMT", analysis_EXEC_STMT }, { "EXTENDED_ARG", analysis_EXTENDED_ARG }, { "FORMAT_VALUE", analysis_FORMAT_VALUE }, { "FOR_LOOP", analysis_FOR_LOOP }, { "GET_AITER", analysis_GET_AITER }, { "GET_ANEXT", analysis_GET_ANEXT }, { "GET_AWAITABLE", analysis_GET_AWAITABLE }, { "GET_ITER", analysis_GET_ITER }, { "GET_YIELD_FROM_ITER", analysis_GET_YIELD_FROM_ITER }, { "IMPORT_FROM", analysis_IMPORT_FROM }, { "IMPORT_NAME", analysis_IMPORT_NAME }, { "IMPORT_STAR", analysis_IMPORT_STAR }, { "INPLACE_ADD", analysis_INPLACE_ADD }, { "INPLACE_AND", analysis_INPLACE_AND }, { "INPLACE_DIVIDE", analysis_INPLACE_DIVIDE }, { "INPLACE_FLOOR_DIVIDE", analysis_INPLACE_FLOOR_DIVIDE }, { "INPLACE_LSHIFT", analysis_INPLACE_LSHIFT }, { "INPLACE_MATRIX_MULTIPLY", analysis_INPLACE_MATRIX_MULTIPLY }, { "INPLACE_MODULO", analysis_INPLACE_MODULO }, { "INPLACE_MULTIPLY", analysis_INPLACE_MULTIPLY }, { "INPLACE_OR", analysis_INPLACE_OR }, { "INPLACE_POWER", analysis_INPLACE_POWER }, { "INPLACE_RSHIFT", analysis_INPLACE_RSHIFT }, { "INPLACE_SUBTRACT", analysis_INPLACE_SUBTRACT }, { "INPLACE_TRUE_DIVIDE", analysis_INPLACE_TRUE_DIVIDE }, { "INPLACE_XOR", analysis_INPLACE_XOR }, { "LIST_APPEND", analysis_LIST_APPEND }, { "LOAD_ASSERTION_ERROR", analysis_LOAD_ASSERTION_ERROR }, { "LOAD_ATTR", analysis_LOAD_ATTR }, { "LOAD_BUILD_CLASS", analysis_LOAD_BUILD_CLASS }, { "LOAD_CLASSDEREF", analysis_LOAD_CLASSDEREF }, { "LOAD_CLOSURE", analysis_LOAD_CLOSURE }, { "LOAD_CONST", analysis_LOAD_CONST }, { "LOAD_DEREF", analysis_LOAD_DEREF }, { "LOAD_FAST", analysis_LOAD_FAST }, { "LOAD_GLOBAL", analysis_LOAD_GLOBAL }, { "LOAD_GLOBALS", analysis_LOAD_GLOBALS }, { "LOAD_LOCAL", analysis_LOAD_LOCAL }, { "LOAD_LOCALS", analysis_LOAD_LOCALS }, { "LOAD_METHOD", analysis_LOAD_METHOD }, { "LOAD_NAME", analysis_LOAD_NAME }, { "MAKE_CLOSURE", analysis_MAKE_CLOSURE }, { "MAKE_FUNCTION", analysis_MAKE_FUNCTION }, { "MAP_ADD", analysis_MAP_ADD }, { "NOP", analysis_NOP }, { "POP_BLOCK", analysis_POP_BLOCK }, { "POP_EXCEPT", analysis_POP_EXCEPT }, { "POP_FINALLY", analysis_POP_FINALLY }, { "POP_TOP", analysis_POP_TOP }, { "PRINT_EXPR", analysis_PRINT_EXPR }, { "PRINT_ITEM", analysis_PRINT_ITEM }, { "PRINT_ITEM_TO", analysis_PRINT_ITEM_TO }, { "PRINT_NEWLINE", analysis_PRINT_NEWLINE }, { "PRINT_NEWLINE_TO", analysis_PRINT_NEWLINE_TO }, { "RAISE_EXCEPTION", analysis_RAISE_EXCEPTION }, { "RAISE_VARARGS", analysis_RAISE_VARARGS }, { "RERAISE", analysis_RERAISE }, { "RESERVE_FAST", analysis_RESERVE_FAST }, { "RETURN_VALUE", analysis_RETURN_VALUE }, { "ROT_FOUR", analysis_ROT_FOUR }, { "ROT_THREE", analysis_ROT_THREE }, { "ROT_TWO", analysis_ROT_TWO }, { "SETUP_ANNOTATIONS", analysis_SETUP_ANNOTATIONS }, { "SET_ADD", analysis_SET_ADD }, { "SET_FUNC_ARGS", analysis_SET_FUNC_ARGS }, { "SET_LINENO", analysis_SET_LINENO }, { "SLICE_0", analysis_SLICE_0 }, { "SLICE_1", analysis_SLICE_1 }, { "SLICE_2", analysis_SLICE_2 }, { "SLICE_3", analysis_SLICE_3 }, { "STOP_CODE", analysis_STOP_CODE }, { "STORE_ANNOTATION", analysis_STORE_ANNOTATION }, { "STORE_ATTR", analysis_STORE_ATTR }, { "STORE_DEREF", analysis_STORE_DEREF }, { "STORE_FAST", analysis_STORE_FAST }, { "STORE_GLOBAL", analysis_STORE_GLOBAL }, { "STORE_LOCALS", analysis_STORE_LOCALS }, { "STORE_MAP", analysis_STORE_MAP }, { "STORE_NAME", analysis_STORE_NAME }, { "STORE_SLICE_0", analysis_STORE_SLICE_0 }, { "STORE_SLICE_1", analysis_STORE_SLICE_1 }, { "STORE_SLICE_2", analysis_STORE_SLICE_2 }, { "STORE_SLICE_3", analysis_STORE_SLICE_3 }, { "STORE_SUBSCR", analysis_STORE_SUBSCR }, { "UNARY_CALL", analysis_UNARY_CALL }, { "UNARY_CONVERT", analysis_UNARY_CONVERT }, { "UNARY_INVERT", analysis_UNARY_INVERT }, { "UNARY_NEGATIVE", analysis_UNARY_NEGATIVE }, { "UNARY_NOT", analysis_UNARY_NOT }, { "UNARY_POSITIVE", analysis_UNARY_POSITIVE }, { "UNPACK_ARG", analysis_UNPACK_ARG }, { "UNPACK_EX", analysis_UNPACK_EX }, { "UNPACK_LIST", analysis_UNPACK_LIST }, { "UNPACK_SEQUENCE", analysis_UNPACK_SEQUENCE }, { "UNPACK_TUPLE", analysis_UNPACK_TUPLE }, { "UNPACK_VARARG", analysis_UNPACK_VARARG }, { "WITH_CLEANUP", analysis_WITH_CLEANUP }, { "WITH_CLEANUP_FINISH", analysis_WITH_CLEANUP_FINISH }, { "WITH_CLEANUP_START", analysis_WITH_CLEANUP_START }, { "WITH_EXCEPT_START", analysis_WITH_EXCEPT_START }, { "YIELD_FROM", analysis_YIELD_FROM }, { "YIELD_VALUE", analysis_YIELD_VALUE }, // Fix jump info { "FOR_ITER", analysis_FOR_ITER }, { "SETUP_LOOP", analysis_SETUP_LOOP }, { "SETUP_EXCEPT", analysis_SETUP_EXCEPT }, { "SETUP_FINALLY", analysis_SETUP_FINALLY }, { "SETUP_WITH", analysis_SETUP_WITH }, { "SETUP_ASYNC_WITH", analysis_SETUP_ASYNC_WITH }, }; void analysis_pyc_op(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg) { size_t i; for (i = 0; i < (sizeof(op_analysis) / sizeof(op_analysis_func)); i++) { if (!strcmp(op_analysis[i].op_name, op_obj->op_name)) { op_analysis[i].func(op, op_obj, oparg); break; } } }