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