def visit_insn(self, instruction):
        if instruction.op == idaapi.cit_block:
            while True:
                cblock = instruction.cblock
                size = cblock.size()
                if size >= 2:
                    # Find block that has "If" and "return" as last 2 statements
                    if cblock.back().op == idaapi.cit_return and \
                                    cblock.at(size - 2).op == idaapi.cit_if and not cblock.at(size - 2).cif.ielse:

                        cit_then = cblock.at(size - 2).cif.ithen

                        # Skip if only one (not "if") statement in "then" branch
                        if cit_then.cblock.size(
                        ) == 1 and cit_then.cblock.front().op != idaapi.cit_if:
                            return 0

                        # Replacing condition to opposite
                        cit_if_condition = cblock.at(size - 2).cif.expr
                        if cit_if_condition.op == idaapi.cot_lnot:
                            # Ida has following bug:
                            # when return type of call cexpr_t is not signed int, function idaapi.lnot leads to crash
                            new_if_condition = idaapi.cexpr_t(
                                cit_if_condition.x)
                        else:
                            new_if_condition = idaapi.cexpr_t(
                                idaapi.lnot(cit_if_condition))
                        new_if_condition.thisown = False
                        cblock.at(size - 2).cif.expr = new_if_condition
                        del cit_if_condition

                        # Take return from list of statements and later put it back
                        cit_return = idaapi.cinsn_t(instruction.cblock.back())
                        cit_return.thisown = False
                        instruction.cblock.pop_back()

                        # Fill main block with statements from "Then" branch
                        while cit_then.cblock:
                            instruction.cblock.push_back(
                                cit_then.cblock.front())
                            cit_then.cblock.pop_front()

                        # Put back main return if there's no another return or "GOTO" already
                        if instruction.cblock.back().op not in (
                                idaapi.cit_return, idaapi.cit_goto):
                            new_return = idaapi.cinsn_t(cit_return)
                            new_return.thisown = False
                            instruction.cblock.push_back(new_return)

                        # Put return into "Then" branch
                        cit_then.cblock.push_back(cit_return)
                        continue
                break
        return 0
Esempio n. 2
0
    def visit_insn(self, instruction):
        if instruction.op != idaapi.cit_block:
            return 0

        while True:
            cblock = instruction.cblock
            size = cblock.size()
            # Find block that has "If" and "return" as last 2 statements
            if size < 2:
                break

            if cblock.at(size - 2).op != idaapi.cit_if:
                break

            cif = cblock.at(size - 2).cif
            if cblock.back().op != idaapi.cit_return or cif.ielse:
                break

            cit_then = cif.ithen

            # Skip if only one (not "if") statement in "then" branch
            if cit_then.cblock.size(
            ) == 1 and cit_then.cblock.front().op != idaapi.cit_if:
                return 0

            inverse_if_condition(cif)

            # Take return from list of statements and later put it back
            cit_return = idaapi.cinsn_t()
            cit_return.assign(instruction.cblock.back())
            cit_return.thisown = False
            instruction.cblock.pop_back()

            # Fill main block with statements from "Then" branch
            while cit_then.cblock:
                instruction.cblock.push_back(cit_then.cblock.front())
                cit_then.cblock.pop_front()

            # Put back main return if there's no another return or "GOTO" already
            if instruction.cblock.back().op not in (idaapi.cit_return,
                                                    idaapi.cit_goto):
                new_return = idaapi.cinsn_t()
                new_return.thisown = False
                new_return.assign(cit_return)
                instruction.cblock.push_back(new_return)

            # Put return into "Then" branch
            cit_then.cblock.push_back(cit_return)
        return 0
Esempio n. 3
0
def make_block_insn(instructions, address, label_num=-1):
	block = None
	if type(instructions) is idaapi.cblock_t:
		block = instructions
	elif type(instructions) is list or type(instructions) is tuple:
		block = make_cblock(instructions)
	else:
		raise TypeError("Trying to make cblock instruicton neither of cblock_t or list|tuple")
	
	insn = idaapi.cinsn_t()
	insn.ea = address
	insn.op = idaapi.cit_block
	insn.cblock = block
	insn.label_num = label_num
	insn.thisown = False

	return insn
Esempio n. 4
0
def make_expr_instr(expr):
	new_item = idaapi.cinsn_t()
	new_item.op = idaapi.cit_expr
	new_item.cexpr = expr
	new_item.thisown = False
	return new_item