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

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模块获取更便捷。

版权声明
本站“技术博客”所有内容的版权持有者为绿盟科技集团股份有限公司(“绿盟科技”)。作为分享技术资讯的平台,绿盟科技期待与广大用户互动交流,并欢迎在标明出处(绿盟科技-技术博客)及网址的情形下,全文转发。
上述情形之外的任何使用形式,均需提前向绿盟科技(010-68438880-5462)申请版权授权。如擅自使用,绿盟科技保留追责权利。同时,如因擅自使用博客内容引发法律纠纷,由使用者自行承担全部法律责任,与绿盟科技无关。

Spread the word. Share this post!

Meet The Author

C/ASM程序员