Пример #1
0
def _set_end(block):
	target = None

	if block.warp is not None:
		target = _get_target(block.warp, allow_end=True)

	block.warp = nodes.EndWarp()

	setattr(block.warp, "_target", target)
Пример #2
0
def _establish_warps(state, instructions):
    state.blocks[0].warpins_count = 1

    for block in state.blocks[:-1]:
        state.block = block

        end_addr = block.last_address + 1
        start_addr = max(block.last_address - 1, block.first_address)

        warp = instructions[start_addr:end_addr]

        block.warp, shift = _build_warp(state, block.last_address, warp)

        setattr(block, "_last_body_addr", block.last_address - shift)
        setattr(block.warp, "_addr", block.last_address - shift + 1)

    last_block = state.blocks[-1]
    last_block.warp = nodes.EndWarp()

    setattr(last_block, "_last_body_addr", last_block.last_address)
    setattr(last_block.warp, "_addr", last_block.last_address)
Пример #3
0
def _establish_warps(state, instructions):
    state.blocks[0].warpins_count = 1

    enumerated_blocks = enumerate(state.blocks[:-1])
    for i, block in enumerated_blocks:
        if state.blocks.__contains__(block) is None:
            continue

        state.block = block

        end_addr = block.last_address + 1
        start_addr = max(block.last_address - 1, block.first_address)

        # Catch certain double unconditional jumps caused by logical primitives in expressions:
        if start_addr == (end_addr - 1) \
                and end_addr + 1 < len(instructions) \
                and instructions[start_addr].opcode == ins.JMP.opcode \
                and instructions[end_addr].opcode == ins.JMP.opcode \
                and instructions[start_addr].A == instructions[end_addr].A \
                and instructions[start_addr].CD == 0:

            end_instruction_destination = end_addr + instructions[
                end_addr].CD + 1
            target_instruction_A = instructions[start_addr].A
            exit_instruction_found = False

            # When two consecutive jumps are found with the same A operand, lookahead for the end jump.
            following_destination = -1
            for j in range(end_addr + 1, len(instructions) - 1):
                following_instruction = instructions[j]
                if following_instruction.opcode == ins.JMP.opcode:
                    if following_instruction.A == target_instruction_A:
                        following_destination = get_jump_destination(
                            j, following_instruction)
                        exit_instruction_found = True
                        break

            # If we find the exit jump and we're not skipping it (if true then break else),
            #  form the original two jumps into a fake conditional warp.
            if exit_instruction_found \
                    and end_instruction_destination <= following_destination:
                fixed_instruction = ins.ISF()
                fixed_instruction.CD = ins.SLOT_FALSE

                instructions[start_addr] = fixed_instruction
                state.blocks.pop(state.blocks.index(block) + 1)

                block.last_address += 1
                start_addr = max(block.last_address - 1, block.first_address)
                end_addr = block.last_address + 1

        warp = instructions[start_addr:end_addr]

        block.warp, shift = _build_warp(state, block.last_address, warp)

        setattr(block, "_last_body_addr", block.last_address - shift)
        setattr(block.warp, "_addr", block.last_address - shift + 1)

    last_block = state.blocks[-1]
    last_block.warp = nodes.EndWarp()

    setattr(last_block, "_last_body_addr", last_block.last_address)
    setattr(last_block.warp, "_addr", last_block.last_address)