def findOEP(code_object):
    '''
    Finds the original entry point of a code object obfuscated by PjOrion.
    DO NOT call this for a non obfsucated code object.
    
    :param code_object: the code object
    :type code_object: code    
    :returns: the entrypoint
    :rtype: int
    '''
    disassembler = Disassembler(code_object)
    ins = disassembler.disasAt(0)

    try:
        assert utils.insMnemonic(ins) == 'SETUP_EXCEPT'
        except_handler = 0 + ins.arg + ins.size

        assert disassembler.disasAt(3).opkode == -1
        assert utils.insMnemonic(
            disassembler.disasAt(except_handler)) == 'POP_TOP'
        assert utils.insMnemonic(disassembler.disasAt(except_handler +
                                                      1)) == 'POP_TOP'
        assert utils.insMnemonic(disassembler.disasAt(except_handler +
                                                      2)) == 'POP_TOP'
        return except_handler + 3
    except:
        return -1
def buildBasicBlocks(leaders, code_object, entry_addr):
    i = 0
    bb_list = []
    disassembler = Disassembler(code_object)

    while i < len(leaders):
        leader1, leader2 = leaders[i], leaders[i + 1]
        addr1, addr2 = leader1.addr, leader2.addr
        bb = BasicBlock()
        bb_list.append(bb)
        bb.addr = addr1
        offset = 0
        if addr1 == entry_addr:
            bb.isEntry = True

        if leader1.type == 'S' and leader2.type == 'E':
            while addr1 + offset <= addr2:
                ins = disassembler.disasAt(addr1 + offset)
                bb.addInstruction(ins)
                offset += ins.size
            i += 2

        elif leader1.type == 'S' and leader2.type == 'S':
            while addr1 + offset < addr2:
                ins = disassembler.disasAt(addr1 + offset)
                bb.addInstruction(ins)
                offset += ins.size
            i += 1

    return bb_list
def buildBasicBlocks(leaders, code_object, entry_addr):
    i = 0
    bb_list = []
    disassembler = Disassembler(code_object)

    while i < len(leaders):
        leader1, leader2 = leaders[i], leaders[i+1]
        addr1, addr2 = leader1.addr, leader2.addr
        bb = BasicBlock()
        bb_list.append(bb)
        bb.addr = addr1
        offset = 0
        if addr1 == entry_addr:
            bb.isEntry = True

        if leader1.type == 'S' and leader2.type == 'E':
            while addr1 + offset <= addr2:
                ins = disassembler.disasAt(addr1  + offset)
                bb.addInstruction(ins)
                offset += ins.size
            i += 2

        elif leader1.type == 'S' and leader2.type == 'S':
            while addr1 + offset < addr2:
                ins = disassembler.disasAt(addr1  + offset)
                bb.addInstruction(ins)
                offset += ins.size
            i += 1

    return bb_list
def findLeaders(code_object, oep):
    Leader = collections.namedtuple('leader', ['type', 'addr'])

    leader_set = set()
    leader_set.add(Leader('S', oep))

    # Queue to contain list of addresses to be analyzed by linear sweep disassembly algorithm
    analysis_Q = queue.Queue()
    analysis_Q.put(oep)

    analyzed_addresses = set()

    disassembler = Disassembler(code_object)

    while not analysis_Q.empty():
        addr = analysis_Q.get()

        while True:
            ins = disassembler.disasAt(addr)
            analyzed_addresses.add(addr)

            # If current instruction is a return, stop disassembling further
            # current address is an end leader
            if utils.isRetIns(ins):
                leader_set.add(Leader('E', addr))
                break

            # If current instruction is braching, stop disassembling further
            # the current instr is an end leader, branch target is start leader
            if utils.isBranchIns(ins):
                leader_set.add(Leader('E', addr))
                for target in getInsCrossRef(ins, addr):
                    leader_set.add(Leader('S', target))
                    if target not in analyzed_addresses:
                        analysis_Q.put(target)
                break

            # Current instruction is not branching
            else:
                # Get cross refs
                cross_refs = getInsCrossRef(ins, addr)
                addr = cross_refs[0]  # The immediate next instruction

                # Some non branching instructions like SETUP_LOOP,
                # SETUP_EXCEPT can have more than 1 cross references
                if len(cross_refs) == 2:
                    leader_set.add(Leader('S', cross_refs[1]))

                    if cross_refs[1] not in analyzed_addresses:
                        analysis_Q.put(cross_refs[1])

    return sorted(leader_set, cmp=_leaderSortFunc)
def findLeaders(code_object, oep):
    Leader = collections.namedtuple('leader', ['type', 'addr'])

    leader_set = set()
    leader_set.add(Leader('S', oep))

    # Queue to contain list of addresses to be analyzed by linear sweep disassembly algorithm
    analysis_Q = Queue.Queue()
    analysis_Q.put(oep)

    analyzed_addresses = set()

    disassembler = Disassembler(code_object)

    while not analysis_Q.empty():
        addr = analysis_Q.get()

        while True:
            ins = disassembler.disasAt(addr)
            analyzed_addresses.add(addr)

            # If current instruction is a return, stop disassembling further
            # current address is an end leader
            if utils.isRetIns(ins):
                leader_set.add(Leader('E', addr))
                break

            # If current instruction is braching, stop disassembling further
            # the current instr is an end leader, branch target is start leader
            if utils.isBranchIns(ins):
                leader_set.add(Leader('E', addr))
                for target in getInsCrossRef(ins, addr):
                    leader_set.add(Leader('S', target))
                    if target not in analyzed_addresses:
                        analysis_Q.put(target)
                break

            # Current instruction is not branching
            else:
                # Get cross refs
                cross_refs = getInsCrossRef(ins, addr)
                addr = cross_refs[0] # The immediate next instruction

                # Some non branching instructions like SETUP_LOOP,
                # SETUP_EXCEPT can have more than 1 cross references
                if len(cross_refs) == 2:
                    leader_set.add(Leader('S', cross_refs[1]))

                    if cross_refs[1] not in analyzed_addresses:
                        analysis_Q.put(cross_refs[1])

    return sorted(leader_set, cmp = _leaderSortFunc)
def findOEP(code_object):
    '''
    Finds the original entry point of a code object obfuscated by PjOrion.
    DO NOT call this for a non obfsucated code object.
    
    :param code_object: the code object
    :type code_object: code    
    :returns: the entrypoint
    :rtype: int
    '''    
    disassembler = Disassembler(code_object)
    ins = disassembler.disasAt(0)

    try:
        assert utils.insMnemonic(ins) == 'SETUP_EXCEPT'
        except_handler = 0 + ins.arg + ins.size

        assert disassembler.disasAt(3).opkode == -1
        assert utils.insMnemonic(disassembler.disasAt(except_handler)) == 'POP_TOP'
        assert utils.insMnemonic(disassembler.disasAt(except_handler + 1)) == 'POP_TOP'
        assert utils.insMnemonic(disassembler.disasAt(except_handler + 2)) == 'POP_TOP'
        return except_handler + 3
    except:
        return -1