Python3利用opcode模块获取指令信息

admin 2023年5月19日18:50:22评论26 views字数 5098阅读16分59秒阅读模式

创建: 2023-05-19 10:39

import opcode

exinfo  = 
(
'hasconst',
'hasname',
'haslocal',
'hasfree',
'hasjrel',
'hasjabs',
'hascompare',
)

def getex ( op ) :
    if op >= opcode.HAVE_ARGUMENT :
        for ex in exinfo :
            if op in getattr( opcode, ex ) :
                return ex
    return None

def get_stack_effect ( op ) :
    if op < opcode.HAVE_ARGUMENT :
        se  = '%d' % opcode.stack_effect( op )
    else :
        if op in opcode.hasjrel or op in opcode.hasjabs :
            se  = '%d %d' % 
            (
            opcode.stack_effect( op, 0, jump=True ),
            opcode.stack_effect( op, 0, jump=False )
            )
        else :
            se  = '%d' % opcode.stack_effect( op, 0 )
    return se

for k, v in opcode.opmap.items() :
    ex  = getex( v )
    se  = get_stack_effect( v )
    if ex is None :
        print( '0x%02x (%3d) %s (%s)' % ( v, v, k, se ) )
    else :
        print( '0x%02x (%3d) %s (%s) (%s)' % ( v, v, k, ex, se ) )

以Python 3.9为例,执行上述代码,输出如下

0x01 (  1) POP_TOP (-1)
0x02 (  2) ROT_TWO (0)
0x03 (  3) ROT_THREE (0)
0x04 (  4) DUP_TOP (1)
0x05 (  5) DUP_TOP_TWO (2)
0x06 (  6) ROT_FOUR (0)
0x09 (  9) NOP (0)
0x0a ( 10) UNARY_POSITIVE (0)
0x0b ( 11) UNARY_NEGATIVE (0)
0x0c ( 12) UNARY_NOT (0)
0x0f ( 15) UNARY_INVERT (0)
0x10 ( 16) BINARY_MATRIX_MULTIPLY (-1)
0x11 ( 17) INPLACE_MATRIX_MULTIPLY (-1)
0x13 ( 19) BINARY_POWER (-1)
0x14 ( 20) BINARY_MULTIPLY (-1)
0x16 ( 22) BINARY_MODULO (-1)
0x17 ( 23) BINARY_ADD (-1)
0x18 ( 24) BINARY_SUBTRACT (-1)
0x19 ( 25) BINARY_SUBSCR (-1)
0x1a ( 26) BINARY_FLOOR_DIVIDE (-1)
0x1b ( 27) BINARY_TRUE_DIVIDE (-1)
0x1c ( 28) INPLACE_FLOOR_DIVIDE (-1)
0x1d ( 29) INPLACE_TRUE_DIVIDE (-1)
0x30 ( 48) RERAISE (-3)
0x31 ( 49) WITH_EXCEPT_START (1)
0x32 ( 50) GET_AITER (0)
0x33 ( 51) GET_ANEXT (1)
0x34 ( 52) BEFORE_ASYNC_WITH (1)
0x36 ( 54) END_ASYNC_FOR (-7)
0x37 ( 55) INPLACE_ADD (-1)
0x38 ( 56) INPLACE_SUBTRACT (-1)
0x39 ( 57) INPLACE_MULTIPLY (-1)
0x3b ( 59) INPLACE_MODULO (-1)
0x3c ( 60) STORE_SUBSCR (-3)
0x3d ( 61) DELETE_SUBSCR (-2)
0x3e ( 62) BINARY_LSHIFT (-1)
0x3f ( 63) BINARY_RSHIFT (-1)
0x40 ( 64) BINARY_AND (-1)
0x41 ( 65) BINARY_XOR (-1)
0x42 ( 66) BINARY_OR (-1)
0x43 ( 67) INPLACE_POWER (-1)
0x44 ( 68) GET_ITER (0)
0x45 ( 69) GET_YIELD_FROM_ITER (0)
0x46 ( 70) PRINT_EXPR (-1)
0x47 ( 71) LOAD_BUILD_CLASS (1)
0x48 ( 72) YIELD_FROM (-1)
0x49 ( 73) GET_AWAITABLE (0)
0x4a ( 74) LOAD_ASSERTION_ERROR (1)
0x4b ( 75) INPLACE_LSHIFT (-1)
0x4c ( 76) INPLACE_RSHIFT (-1)
0x4d ( 77) INPLACE_AND (-1)
0x4e ( 78) INPLACE_XOR (-1)
0x4f ( 79) INPLACE_OR (-1)
0x52 ( 82) LIST_TO_TUPLE (0)
0x53 ( 83) RETURN_VALUE (-1)
0x54 ( 84) IMPORT_STAR (-1)
0x55 ( 85) SETUP_ANNOTATIONS (0)
0x56 ( 86) YIELD_VALUE (0)
0x57 ( 87) POP_BLOCK (0)
0x59 ( 89) POP_EXCEPT (-3)
0x5a ( 90) STORE_NAME (hasname) (-1)
0x5b ( 91) DELETE_NAME (hasname) (0)
0x5c ( 92) UNPACK_SEQUENCE (-1)
0x5d ( 93) FOR_ITER (hasjrel) (-1 1)
0x5e ( 94) UNPACK_EX (0)
0x5f ( 95) STORE_ATTR (hasname) (-2)
0x60 ( 96) DELETE_ATTR (hasname) (-1)
0x61 ( 97) STORE_GLOBAL (hasname) (-1)
0x62 ( 98) DELETE_GLOBAL (hasname) (0)
0x64 (100) LOAD_CONST (hasconst) (1)
0x65 (101) LOAD_NAME (hasname) (1)
0x66 (102) BUILD_TUPLE (1)
0x67 (103) BUILD_LIST (1)
0x68 (104) BUILD_SET (1)
0x69 (105) BUILD_MAP (1)
0x6a (106) LOAD_ATTR (hasname) (0)
0x6b (107) COMPARE_OP (hascompare) (-1)
0x6c (108) IMPORT_NAME (hasname) (-1)
0x6d (109) IMPORT_FROM (hasname) (1)
0x6e (110) JUMP_FORWARD (hasjrel) (0 0)
0x6f (111) JUMP_IF_FALSE_OR_POP (hasjabs) (0 -1)
0x70 (112) JUMP_IF_TRUE_OR_POP (hasjabs) (0 -1)
0x71 (113) JUMP_ABSOLUTE (hasjabs) (0 0)
0x72 (114) POP_JUMP_IF_FALSE (hasjabs) (-1 -1)
0x73 (115) POP_JUMP_IF_TRUE (hasjabs) (-1 -1)
0x74 (116) LOAD_GLOBAL (hasname) (1)
0x75 (117) IS_OP (-1)
0x76 (118) CONTAINS_OP (-1)
0x79 (121) JUMP_IF_NOT_EXC_MATCH (hasjabs) (-2 -2)
0x7a (122) SETUP_FINALLY (hasjrel) (6 0)
0x7c (124) LOAD_FAST (haslocal) (1)
0x7d (125) STORE_FAST (haslocal) (-1)
0x7e (126) DELETE_FAST (haslocal) (0)
0x82 (130) RAISE_VARARGS (0)
0x83 (131) CALL_FUNCTION (0)
0x84 (132) MAKE_FUNCTION (-1)
0x85 (133) BUILD_SLICE (-1)
0x87 (135) LOAD_CLOSURE (hasfree) (1)
0x88 (136) LOAD_DEREF (hasfree) (1)
0x89 (137) STORE_DEREF (hasfree) (-1)
0x8a (138) DELETE_DEREF (hasfree) (0)
0x8d (141) CALL_FUNCTION_KW (-1)
0x8e (142) CALL_FUNCTION_EX (-1)
0x8f (143) SETUP_WITH (hasjrel) (6 1)
0x91 (145) LIST_APPEND (-1)
0x92 (146) SET_ADD (-1)
0x93 (147) MAP_ADD (-2)
0x94 (148) LOAD_CLASSDEREF (hasfree) (1)
0x90 (144) EXTENDED_ARG (0)
0x9a (154) SETUP_ASYNC_WITH (hasjrel) (5 0)
0x9b (155) FORMAT_VALUE (0)
0x9c (156) BUILD_CONST_KEY_MAP (0)
0x9d (157) BUILD_STRING (1)
0xa0 (160) LOAD_METHOD (hasname) (1)
0xa1 (161) CALL_METHOD (-1)
0xa2 (162) LIST_EXTEND (-1)
0xa3 (163) SET_UPDATE (-1)
0xa4 (164) DICT_MERGE (-1)
0xa5 (165) DICT_UPDATE (-1)

部分指令第4列出现hasconst、hasname这类信息,编写反汇编器、反编译器时需要

hasconst    co_consts[] // oparg是co_consts[]的索引
hasname     co_names[]  // oparg是co_names[]的索引
haslocal    co_varnames[]
hasfree     co_cellvars[]+co_freevars[]
hasjrel     相对跳转    // oparg是相对偏移
hasjabs     绝对跳转    // oparg是绝对地址
hascompare  比较指令

所有指令最后一列反映该指令对数据栈的影响,编写反编译器时需要。1表示有一个压栈动作,-1表示有一个弹栈动作。若是跳转类指令,第1个数字对应跳转时栈变化,第2个数字对应未跳转时栈变化。也可从解释器源码ceval.c、compile.c获取栈变化信息,只不过利用opcode模块获取更便捷。

原文始发于微信公众号(青衣十三楼飞花堂):Python3利用opcode模块获取指令信息

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年5月19日18:50:22
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Python3利用opcode模块获取指令信息https://cn-sec.com/archives/1746954.html

发表评论

匿名网友 填写信息