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

Decode and strip CBOR encoded metadata #48

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions pyevmasm/evmasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@

from future.builtins import next, bytes # type: ignore
import copy
from cbor2 import loads

DEFAULT_FORK = "london"
SOLC_METADATA_PATTERNS = [
[0xA1, 0x65, 0x62, 0x7A, 0x7A, 0x72, 0x30], # bzzr0
[0xA1, 0x65, 0x62, 0x7A, 0x7A, 0x72, 0x31], # bzzr1
[0xA2, 0x64, 0x69, 0x70, 0x66, 0x73] # ipfs
]

"""
Example use::
Expand Down Expand Up @@ -527,10 +533,12 @@ def disassemble_all(bytecode, pc=0, fork=DEFAULT_FORK):
bytecode = bytearray(bytecode)
if isinstance(bytecode, str):
bytecode = bytearray(bytecode.encode("latin-1"))

stripped_bytecode = strip_metadata(bytecode)

bytecode = iter(bytecode)
stripped_bytecode = iter(stripped_bytecode)
while True:
instr = disassemble_one(bytecode, pc=pc, fork=fork)
instr = disassemble_one(stripped_bytecode, pc=pc, fork=fork)
if not instr:
return
pc += instr.size
Expand Down Expand Up @@ -561,6 +569,53 @@ def disassemble(bytecode, pc=0, fork=DEFAULT_FORK):
"""
return "\n".join(map(str, disassemble_all(bytecode, pc=pc, fork=fork)))

""" Find start and end indices of a sublist in list

:param sublist: a sublist to look for
:type sublist: list
:param list: a list to look in
:type list: list
:return: start and end indices of a sublist in list
"""
def _find_sub_list(sublist,list):
len_sublist=len(sublist)
for index in (i for i,e in enumerate(list) if e==sublist[0]):
if list[index:index+len_sublist]==sublist:
return index,index+len_sublist-1

""" Try to decode a list of bytes as CBOR data

:param potential_cbor: a candidate list of bytes for decoding
:type potential_cbor: list
:return: True if decoding was successful | False otherwise
"""
def _try_cbor(potential_cbor):
try:
cbor = loads(bytes(potential_cbor))
if len(cbor) > 0:
print("Found CBOR encoded metadata: {}".format(cbor))
return True
else:
return False
except Exception as e:
return False

""" Try to decode and strip the solc metadata from the bytecode

:param bytecode: binary representation of an evm bytecode
:type bytecode: bytearray
:return: the stripped bytecode representation excluding the metadata part
"""
def strip_metadata(bytecode):
bytecode_array = list(bytecode)
for pattern in SOLC_METADATA_PATTERNS:
sublist_indices = _find_sub_list(pattern, bytecode_array)
if sublist_indices:
potential_cbor = bytecode_array[sublist_indices[0]:]
if _try_cbor(potential_cbor):
return bytecode_array[:sublist_indices[0]]
return bytecode_array


def assemble(asmcode, pc=0, fork=DEFAULT_FORK):
""" Assemble an EVM program
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='pyevmasm',
version='0.2.3',
version='0.2.4',
description='Ethereum Virtual Machine (EVM) assembler and disassembler',
author='Trail of Bits',
author_email='evmasm@trailofbits.com',
Expand Down