def same_with(self, cfg_p): ''' 比较质心是否相同 @param cfg_p 另一个cfg对象 ''' cx_o, cy_o, cz_o, w_o = self.get_centroid() cx_p, cy_p, cz_p, w_p = cfg_p.get_centroid() def _cal(x_o, x_p): if float(x_o + x_p) == .0: return .0 return abs(x_o - x_p) / float(x_o + x_p) CDD = max([ _cal(cx_o, cx_p), _cal(cy_o, cy_p), _cal(cz_o, cz_p), _cal(w_o, w_p) ]) # print("funcname: {:>25}\taddress: {:>12}, {:>12} \t CDD: {}".format(self.funcname, # self.address, cfg_p.address, CDD)) comlog.debug("[+]cfg.same_with funcname:{}".format(self.funcname)) # if self.funcname == 'print_dot11_mode' and CDD != 0.023400936037441523: # import ipdb; ipdb.set_trace() # if CDD == 0: if CDD <= 0.01: ret = True else: ret = False comlog.debug('same_with :{}'.format(ret)) return ret
def __GetBlocksByBounds(self, start_node, node_visited): ''' 根据边界圈定基本块 ''' queue = set() queue.add(start_node) degree_node = set() blocks = [] graph = self.graph_o neighbors = self.neighbors_o tags = self.tags while len(queue) > 0: node = queue.pop() node_visited.add(node) blocks.append(node) for predecess in graph.predecessors(node): if predecess in neighbors: degree_node.add(predecess) if predecess in tags.values() and predecess not in neighbors: comlog.debug('node {} out from {}'.format(node, predecess)) return -1, [] if predecess not in neighbors and predecess not in tags.values( ): if predecess not in blocks: queue.add(predecess) for succ in graph.successors(node): if succ in neighbors: degree_node.add(succ) if succ in tags.values() and succ not in neighbors: comlog.debug('node {} out from {}'.format(node, succ)) return -1, [] if succ not in neighbors and succ not in tags.values(): if succ not in blocks: queue.add(succ) return len(degree_node), blocks
def _IDAPython_call(self, address_str): ''' 调用IDAPython @param address: ida脚本参数 函数首地址字符串 ''' self.out_json = os.path.join(self.json_dir, self.json_name) cmd = "TVHEADLESS=1 idal -A -S'{} {} {}' {} > /dev/null".format(self.script, \ address_str, self.out_json, self.filename) comlog.debug(cmd) (status, output) = commands.getstatusoutput(cmd) # output 做debug用 if status != 0: # 正常返回0 comlog.error('IDAPython call error') comlog.error('error info: {}'.format(output)) return status
def get_semidiff(self): ''' 获取语义差值 ''' difference = 0 count = 0 post_state_o = self._state_o['post_state'] post_state_p = self._state_p['post_state'] comlog.debug(post_state_o) comlog.debug(post_state_p) for reg in post_state_p['reg']: count += 1 if reg not in post_state_o['reg'] or post_state_p['reg'][ reg] != post_state_o['reg'][reg]: difference += 1 for flag in post_state_p['flag']: count += 1 if flag not in post_state_o['flag'] or post_state_p['flag'][ flag] != post_state_o['flag'][flag]: difference += 1 for mem in post_state_p['mem']: count += 1 if mem not in post_state_o['mem']: difference += 1 diffrota = difference / float(count) comlog.debug('diffrota: {}'.format(diffrota)) self._diffrota = diffrota return diffrota
def update_state_from_addrs(self, addrs, pre_state): ''' 从状态模拟器中更新post_state @param addrs 地址列表,其中元素addres为二元组, addres[0]基本块起始地址,addres[1]基本块结束地址 @param pre_state 前状态 ''' self.addrs = addrs post_state = copy.deepcopy(pre_state) self.regs = post_state['reg'].copy() self.flag = post_state['flag'].copy() if len(addrs) < 1: return state = self.__init_state(self.addrs[0][0]) for addr in self.addrs: comlog.debug('{}, {}'.format(hex(addr[0]), hex(addr[1]))) ip, state = self.__sim_block(addr[0], addr[1], state) state.ip = claripy.BVV(ip, 32) # print "last state:\n", state # update_regs(state, post_state[0]) post_state['reg'] = self.__eval_update_regs(state) post_state['flag'] = self.__eval_update_flag(state) return post_state
def __GetRelevantOriginalBlocks(self): ''' 获取原函数对应基本块 ''' # 当且仅当与边界点相通 neighbors = self.neighbors_o if len(neighbors) <= 0: return [] graph = self.graph_o node_visited = set() blocks_o = [] nodes = self.__GetFirstDegreeNeigbors(neighbors, 'O') nodes = [node for node in nodes if node not in self.tags.values()] comlog.debug('node to list...') comlog.debug(nodes) for node in nodes: if node not in node_visited: degree, blocks = self.__GetBlocksByBounds(node, node_visited) if degree == -1: continue if degree == len(neighbors): return blocks blocks_o.extend(blocks) return blocks_o
def print_reg(self, s): ''' 打印寄存器与值 ''' for reg in self.regs: comlog.debug('{}, {}'.format(reg, s.regs.get(reg.lower())))
def get_trace(self): ''' 轨迹算法主体 ''' self._match() comlog.debug('blocks_p: {}'.format(self.blocks_p)) comlog.debug('\n\ntags: {}'.format(self.tags)) traces_p = self.__LinerConnectedComponents(self.blocks_p, 'P') for trace_p in traces_p: comlog.debug('trace_p: {}'.format(trace_p)) self.neighbors_p = self.__GetFirstDegreeNeigbors(trace_p) comlog.debug('[+]neighbors in patch') comlog.debug('\t{}'.format(self.neighbors_p)) self.neighbors_o = self.__convert_node() comlog.debug('[+]neighbors in origin') comlog.debug('\t{}'.format(self.neighbors_o)) self.blocks_o = self.__GetRelevantOriginalBlocks() comlog.debug('blocks_o {}'.format(self.blocks_o)) traces_o = self.__LinerConnectedComponents(self.blocks_o, f_type='O') self.traces.append({'trace_p': trace_p, 'traces_o': traces_o}) return self.traces