Exemple #1
0
def enum_func_static(instructions):

    functions = list()

    # first function of NeoContract is *usually* the Main function
    function = Function(instructions[0].offset,
                        start_instr=instructions[0],
                        name='Main')

    # parse the instructions and create Function object
    new_func = False
    for inst in instructions:
        if new_func:
            name = 'func_%x' % inst.offset
            function = Function(inst.offset, start_instr=inst, name=name)
            new_func = False

        # associate current instruction to the function
        # Worked because instruction between
        # function.start_offset and function.end_offset
        # are on the same function on Neo
        # i.e linear disassembly
        function.instructions.append(inst)

        # terminator instruction or last one
        if inst.is_halt or inst == instructions[-1]:
            function.size = inst.offset_end - function.start_offset
            function.end_offset = inst.offset_end
            function.end_instr = inst

            functions.append(function)
            new_func = True

    return functions
Exemple #2
0
def enum_func_static(instructions):

    functions = list()

    # first function is *usually* the function dispatcher
    function = Function(start_offset=0,
                        start_instr=instructions[0],
                        name='Dispatcher',
                        prefered_name='Dispatcher')
    functions.append(function)

    # parse the instructions and create Function object
    for inst in instructions:
        try:
            # PUSH4 are used to push the function signature on the stack
            if inst.name == 'PUSH4':
                index = instructions.index(inst)
                list_inst = instructions[index:index + 4]
                push4, eq, push, jumpi = list_inst[0], list_inst[1], list_inst[
                    2], list_inst[3]

                # check if this basicblock test function signature
                if eq.name == 'EQ' and push.name in [
                        'PUSH1', 'PUSH2'
                ] and jumpi.name == 'JUMPI':
                    xref = int.from_bytes(push.operand, byteorder='big')
                    sign = int.from_bytes(push4.operand, byteorder='big')
                    name = 'func_%x' % sign
                    prefered_name = find_signature(sign)

                    # find instr with offset == xref
                    begin_function = next(
                        filter(lambda i: i.offset == xref, instructions))
                    # create new function
                    function = Function(xref,
                                        start_instr=begin_function,
                                        name=name,
                                        prefered_name=prefered_name)

                    functions.append(function)
        except:
            log.info('enum_func_static Exception')
            pass
    return functions
Exemple #3
0
def enum_func(module_bytecode):
    ''' return a list of Function
        see:: octopus.core.function
    '''
    functions = list()
    analyzer = WasmModuleAnalyzer(module_bytecode)

    protos = analyzer.func_prototypes
    import_len = len(analyzer.imports_func)

    for idx, code in enumerate(analyzer.codes):
        # get corresponding function prototype
        name, param_str, return_str, _ = protos[import_len + idx]

        name = format_func_name(name, param_str, return_str)
        instructions = WasmDisassembler().disassemble(code)
        cur_function = Function(0, instructions[0], name=name)
        cur_function.instructions = instructions

        functions.append(cur_function)
    return functions
Exemple #4
0
    def extract_functions_code(self, module_bytecode):
        functions = list()
        mod_iter = iter(decode_module(module_bytecode))
        _, _ = next(mod_iter)
        sections = list(mod_iter)

        # iterate over all section
        #code_data = [cur_sec_data for cur_sec, cur_sec_data in sections if isinstance(cur_sec_data.get_decoder_meta()['types']['payload'], CodeSection)][0]
        for cur_sec, cur_sec_data in sections:
            sec = cur_sec_data.get_decoder_meta()['types']['payload']
            if isinstance(sec, CodeSection):
                code_data = cur_sec_data
                break
        if not code_data:
            raise ValueError('No functions/codes in the module')
        for idx, func in enumerate(code_data.payload.bodies):
            instructions = self.disassemble(func.code.tobytes())
            cur_function = Function(0, instructions[0])
            cur_function.instructions = instructions

            functions.append(cur_function)
        return functions