Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slither printer and API for getting evm instructions for contract source #281

Merged
merged 21 commits into from
Nov 13, 2019

Conversation

rajeevgopalakrishna
Copy link
Contributor

This PR addresses #209 to add a printer evm and an API get_evm_instructions (obj) where obj can be a contract, function or a node. It uses evm-cfg-builder (https://github.com/crytic/evm_cfg_builder) to disassemble the bytecode and access evm instructions for the appropriate contract CFGs or functions as necessary.

The evm printer outputs evm assembly instructions at corresponding source lines for all the nodes in the functions of the contracts. For example:

Contract MintableTokenBounty
        Function Ownable.Ownable()
                Node: ENTRY_POINT None
                Source line 182:     function Ownable() {
                EVM Instructions:
                Node: EXPRESSION owner = msg.sender
                Source line 183:         owner = msg.sender;
                EVM Instructions:
                        0xd7: CALLER
                        0xd8: PUSH1 0x6
                        0xda: PUSH1 0x0
                        0xdc: PUSH2 0x100
                        0xdf: EXP
                        0xe0: DUP2
                        0xe1: SLOAD
                        0xe2: DUP2
                        0xe3: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
                        0xf8: MUL
                        0xf9: NOT
                        0xfa: AND
                        0xfb: SWAP1
                        0xfc: DUP4
                        0xfd: PUSH20 0xffffffffffffffffffffffffffffffffffffffff
                        0x112: AND
                        0x113: MUL
                        0x114: OR
                        0x115: SWAP1
                        0x116: SSTORE
                        0x117: POP

The API get_evm_instructions(obj) returns a list of pyevmasm (https://github.com/crytic/pyevmasm) Instructions associated with the obj. A sample script is shown below:

from slither.evm.convert import get_evm_instructions
slither = Slither(sys.argv[1])

# Get the contract evm instructions                                                                                            
contract = slither.get_contract_from_name('Test')
contract_ins = get_evm_instructions(contract)

# Get the constructor evm instructions                                                                                         
constructor = contract.constructor
constructor_ins = get_evm_instructions(constructor)

# Get the function evm instructions                                                                                            
function = contract.get_function_from_signature('foo()')
function_ins = get_evm_instructions(function)

# Get the node evm instructions                                                                                                
nodes = function.nodes
for node in nodes:
    node_ins = get_evm_instructions(node)

slither/evm/convert.py Outdated Show resolved Hide resolved
slither/evm/convert.py Outdated Show resolved Hide resolved
slither/evm/convert.py Outdated Show resolved Hide resolved
slither/printers/summary/evm.py Outdated Show resolved Hide resolved
- Removes duplicate generate_source_to_evm_ins_mapping() in evm printer (reuse from SourceToEVM module)
- Adds more comments for readability
- Adds expected output for convert_to_evm_ins
- Uses get_function_id from slither.utils.function
@rajeevgopalakrishna
Copy link
Contributor Author

Note: Travis CI fails many checks because of missing evm-cfg-builder (in the code shown below). This was not added as a forced dependency to Slither because it is required only by the evm printer (and any script APIs). The user is expected to add the dependency while using this functionality.

try:
    # Avoiding the addition of evm_cfg_builder as permanent dependency                                             
    from evm_cfg_builder.cfg import CFG
except ImportError:
    logger = logging.getLogger('Printers')
    logger.error("To use evm printer, you need to install evm-cfg-builder from ToB")
    logger.error("Documentation: https://github.com/crytic/evm_cfg_builder")
    logger.error("Installation: pip install evm-cfg-builder")
    sys.exit(-1)

slither/printers/summary/evm.py Outdated Show resolved Hide resolved
evm_info = self._extract_evm_info(self.slither)

for contract in self.slither.contracts_derived:
print('Contract {}'.format(contract.name))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use print, create a string and call self.info at the end.

See the other printers architecture

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, will do. I adopted this style from slithir printer which has prints (with empty self.info(txt)) but looks like that is a bug. Will fix that too.

slither/evm/__init__.py Outdated Show resolved Hide resolved
slither/evm/convert.py Outdated Show resolved Hide resolved
slither/evm/convert.py Outdated Show resolved Hide resolved
slither/evm/evm_cfg_builder.py Outdated Show resolved Hide resolved
slither/printers/summary/evm.py Outdated Show resolved Hide resolved
slither/printers/summary/evm.py Show resolved Hide resolved
- Replaces sys.exit with SlitherError
- Replaces prints with self.info
- Moves slither.evm to slither.analyses.evm
- Replaces class SourceToEVM static methods with functions
- Makes KEY_EVM_INS into a constant
- Adds wiki entry for evm printer
@rajeevgopalakrishna rajeevgopalakrishna changed the title [WIP] Slither printer and API for getting evm instructions for contract source Slither printer and API for getting evm instructions for contract source Oct 7, 2019
@montyly montyly merged commit fd5256b into dev Nov 13, 2019
@montyly montyly deleted the dev-evm-printer-and-api branch November 13, 2019 10:18
@montyly montyly mentioned this pull request Mar 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants