Python Language
Il modulo dis
Ricerca…
Costanti nel modulo DIS
EXTENDED_ARG = 145 # All opcodes greater than this have 2 operands
HAVE_ARGUMENT = 90 # All opcodes greater than this have at least 1 operands
cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', 'is ...
# A list of comparator id's. The indecies are used as operands in some opcodes
# All opcodes in these lists have the respective types as there operands
hascompare = [107]
hasconst = [100]
hasfree = [135, 136, 137]
hasjabs = [111, 112, 113, 114, 115, 119]
hasjrel = [93, 110, 120, 121, 122, 143]
haslocal = [124, 125, 126]
hasname = [90, 91, 95, 96, 97, 98, 101, 106, 108, 109, 116]
# A map of opcodes to ids
opmap = {'BINARY_ADD': 23, 'BINARY_AND': 64, 'BINARY_DIVIDE': 21, 'BIN...
# A map of ids to opcodes
opname = ['STOP_CODE', 'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'DUP_TOP', '...
Cos'è il bytecode Python?
Python è un interprete ibrido. Quando si esegue un programma, prima lo assembla in un bytecode che può quindi essere eseguito nell'interprete Python (chiamato anche una macchina virtuale Python ). Il modulo dis
nella libreria standard può essere utilizzato per rendere leggibile il bytecode Python smontando classi, metodi, funzioni e oggetti codice.
>>> def hello():
... print "Hello, World"
...
>>> dis.dis(hello)
2 0 LOAD_CONST 1 ('Hello, World')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
L'interprete Python è basato sullo stack e utilizza un primo sistema di ultimo esaurimento.
Ogni codice operazione (opcode) nel linguaggio assembly Python (il bytecode) prende un numero fisso di elementi dallo stack e restituisce un numero fisso di elementi allo stack. Se non ci sono abbastanza elementi in pila per un opcode, l'interprete Python si bloccherà, probabilmente senza un messaggio di errore.
Disassemblare i moduli
Per disassemblare un modulo Python, prima questo deve essere trasformato in un file .pyc
(compilato con Python). Per fare questo, corri
python -m compileall <file>.py
Poi in un interprete, corri
import dis
import marshal
with open("<file>.pyc", "rb") as code_f:
code_f.read(8) # Magic number and modification time
code = marshal.load(code_f) # Returns a code object which can be disassembled
dis.dis(code) # Output the disassembly
Questo compilerà un modulo Python e produrrà le istruzioni bytecode con dis
. Il modulo non viene mai importato, quindi è sicuro da utilizzare con codice non affidabile.