我们从Python开源项目中,提取了以下14个代码示例,用于说明如何使用idc.GetOpnd()。
def find_unusual_xors(functions): # TODO find xors in tight loops candidate_functions = [] for fva in functions: cva = fva while cva != idaapi.BADADDR and cva < idc.FindFuncEnd(fva): if idc.GetMnem(cva) == "xor": if idc.GetOpnd(cva, 0) != idc.GetOpnd(cva, 1): g_logger.debug("suspicious XOR instruction at 0x%08X in function 0x%08X: %s", cva, fva, idc.GetDisasm(cva)) ph = idc.PrevHead(cva) nh = idc.NextHead(cva) ip = idc.GetDisasm(ph) ia = idc.GetDisasm(nh) if ip and ia: g_logger.debug("Instructions: %s; %s; %s", ip, idc.GetDisasm(cva), ia) if ph or nh: if is_security_cookie(cva, ph, nh): g_logger.debug("XOR related to security cookie: %s", idc.GetDisasm(cva)) else: g_logger.debug("unusual XOR: %s", idc.GetDisasm(cva)) candidate_functions.append(fva) break cva = idc.NextHead(cva) return candidate_functions
def find_suspicous_movs(functions): candidate_functions = [] regs = ["esp", "ebp", "rsp", "rbp"] for fva in functions: for (loopStart, loopEnd) in find_tight_loops(fva): cva = loopStart while cva <= loopEnd: if idc.GetMnem(cva) == "mov": if is_list_item_in_s(regs, idc.GetOpnd(cva, 0)): cva = idc.NextHead(cva) continue # identify register dereferenced writes to memory, e.g. mov [eax], cl if idc.GetOpType(cva, 0) == OP_TYPE.BASE_INDEX.value: if idc.GetOpType(cva, 1) not in [OP_TYPE.IMMEDIATE.value, OP_TYPE.IMMEDIATE_FAR.value, OP_TYPE.IMMEDIATE_NEAR.value]: g_logger.debug("suspicious MOV instruction at 0x%08X in function 0x%08X: %s", cva, fva, idc.GetDisasm(cva)) candidate_functions.append(fva) break cva = idc.NextHead(cva) return candidate_functions
def color_head(ea): flags = idc.GetFlags(ea) if not idc.isCode(flags): return mnem = idc.GetMnem(ea) if mnem == 'call': logger.debug('call: 0x%x', ea) idc.SetColor(ea, idc.CIC_ITEM, CALL_COLOR) elif mnem == 'xor': if idc.GetOpnd(ea, 0) != idc.GetOpnd(ea, 1): logger.debug('non-zero xor: 0x%x', ea) idc.SetColor(ea, idc.CIC_ITEM, ENCRYPT_COLOR) elif mnem in ('sdit', 'sgdt', 'sldt', 'smsw', 'str', 'in', 'cpuid'): logger.debug('anti-vm: 0x%x', ea) idc.SetColor(ea, idc.CIC_ITEM, ANTIANALYSIS_COLOR) elif mnem == 'in': if idc.GetOpnd(ea, 0) in ("3", "2D"): logger.debug('anti-debug: 0x%x', ea) idc.SetColor(ea, idc.CIC_ITEM, ANTIANALYSIS_COLOR) elif mnem in ('rdtsc', 'icebp'): logger.debug('anti-debug: 0x%x', ea) idc.SetColor(ea, idc.CIC_ITEM, ANTIANALYSIS_COLOR)
def revise_syscall(rename=False): if not rename: print('Change the function name with `CGCHeler.revise_syscall(True)`.') # visit all instructions start_ea, end_ea = utils.get_seg_range('.text') eax = -1 ip = start_ea while ip < end_ea and ip != idaapi.BADADDR: if 'int' in idc.GetMnem(ip) and '80h' == idc.GetOpnd(ip, 0): if eax != -1: # fix comment and function name print('{}: {}'.format(hex(ip), syscall_table[eax])) idc.MakeComm(ip, 'CGC syscall: {}'.format(syscall_table[eax])) if rename: print('Change {} to {}'.format(idc.GetFunctionName(ip), syscall_table[eax])) idc.MakeName(idc.GetFunctionAttr(ip, idc.FUNCATTR_START), syscall_table[eax]) elif 'mov' in idc.GetMnem(ip) and 'eax' == idc.GetOpnd(ip, 0) and 5 == idc.GetOpType(ip, 1): value = idc.GetOpnd(ip, 1) if re.search('^[0-9]+$', value) != None: eax = int(value) if eax > 7 or eax < 1: eax = -1 ip = idc.NextHead(ip)
def create_call_map(self, ftype): assert_ida_available() import idc import idautils seg_mapping = {idc.SegName(x): (idc.SegStart(x), idc.SegEnd(x)) for x in idautils.Segments()} imports = seg_mapping[".idata"] if ftype == PE else seg_mapping['.plt'] start, stop = seg_mapping[".text"] current = start while current <= stop: inst = current if idc.GetMnem(inst) in ["call", "jmp"]: value = idc.GetOperandValue(inst, 0) name = idc.GetOpnd(inst, 0) if imports[0] <= value <= imports[1]: entry = self.config.call_map.add() entry.address = inst entry.name = name current = idc.NextHead(current, stop)
def get_call_name(head): instruction_type = GetInstructionType(head) if instruction_type == CALL_INSTRUCTION: opnd = idc.GetOpnd(head, 0) if opnd not in registers: opnd = opnd.replace("ds:","") return opnd else: opnd = idc.GetDisasm(head) opnd = opnd[opnd.find(";") + 1:] opnd = opnd.replace(" ", "") if opnd != None: return opnd return None
def highlight_non_zero_xor(self, ea): highlight_eas = [] if self.get_mnem(ea) == "xor": if idc.GetOpnd(ea, 0) != idc.GetOpnd(ea, 1): ph = idc.PrevHead(ea) nh = idc.NextHead(ea) ip = idc.GetDisasm(ph) ia = idc.GetDisasm(nh) if ph or nh: if not self.is_security_cookie(ea, ph, nh): highlight_eas.append(ea) MySetColor(ea, self.color) return highlight_eas
def is_security_cookie(self, va, ph, nh): # for security cookie check the xor should use ESP or EBP if idc.GetOpnd(va, 1) not in ["esp", "ebp", "rsp", "rbp"]: return False if "security" in idc.GetOpnd(ph, 1): return True elif "security" in idc.GetDisasm(nh): return True elif "security" in idc.GetDisasm(idc.NextHead(nh)): return True return False
def is_security_cookie(va, ph, nh): # for security cookie check the xor should use ESP or EBP if idc.GetOpnd(va, 1) not in ["esp", "ebp", "rsp", "rbp"]: return False if "security" in idc.GetOpnd(ph, 1): return True elif "security" in idc.GetDisasm(nh): return True elif "security" in idc.GetDisasm(idc.NextHead(nh)): return True return False
def getDispatchCode(ea): # get dispatch code out of an instruction first, second = (idc.GetOpnd(ea, 0), idc.GetOperandValue(ea, 1)) if first == 'eax': return second raise ValueError("Search resulted in address %08x, but instruction '%s' does fulfill requested constraints"% (ea, idc.GetMnem(ea)))
def FindLastAssignment(ea, register): start,end = database.guessrange(ea) while ea > start: ea = database.prev(ea) m = idc.GetMnem(ea) r = idc.GetOpnd(ea, 0) if m == 'mov' and r == register: return ea continue raise ValueError('FindLastAssignment(0x%x, %s) Found no matches'% (ea, register))
def get_args(addr): """ Retreives the passed arguments to the decryption function. We are only interested in the key and offset to the encrypted string. addr: (int) Address at which the decryption function was called. Returns: key: (int) The key used to decrypt the string. enc_str: (list) Byte array of encrypted string. ins_addr: (int) Address at which the encrypted byte array is referenced. """ found = False foundstr = False foundkey = False while not found: addr = idc.PrevHead(addr) if idc.GetMnem(addr) == "mov" and "r8d" in idc.GetOpnd(addr,0): #print "[+] Found key: 0x%08x at 0x%016x" % (idc.GetOperandValue(addr,1)& 0xffffffff, addr) key = idc.GetOperandValue(addr,1) & 0xffffffff foundkey = True if idc.GetMnem(addr) == "lea" and "rdx" in idc.GetOpnd(addr,0): #print "[+] Found str: 0x%016x at 0x%016x" % (idc.GetOperandValue(addr,1), addr) enc_str_addr = idc.GetOperandValue(addr,1) enc_str = get_encoded_string(enc_str_addr) ins_addr = addr foundstr = True if foundkey and foundstr: found = True return key, enc_str, ins_addr
def main(): base_addr = 0 ea = 0 idc.MakeFunction(ea) # heuristic while(true): mnemonic = idc.GetMnem(ea) if "LDR" in mnemonic: base_str = idc.GetOpnd(ea, 1) base_addr = int(base_str.split("=")[1], 16) break ea += 4 print("[+] rebasing to address 0x%x" % (base_addr)) idc.rebase_program(base_addr, idc.MSF_FIXONCE) idaapi.autoWait() segment_start = base_addr segment_end = idc.GetSegmentAttr(segment_start, idc.SEGATTR_END) ea = segment_start print("[+] searching and defining functions") while ea != idc.BADADDR: ea = idc.FindBinary(ea, idc.SEARCH_DOWN, "BF A9", 16) if ea != idc.BADADDR: ea = ea - 2 if (ea % 4) == 0 and idc.GetFlags(ea) < 0x200: # print("[+] defining a function at 0x%x" % (ea)) idc.MakeFunction(ea) ea = ea + 4 idc.AnalyzeArea(segment_start, segment_end) idaapi.autoWait()
def def_functions(s_start): num_added_functions = 0 s_addr = s_start s_end = idc.GetSegmentAttr(s_start, SEGATTR_END) #idc.SegEnd(segm) print "0x%08x 0x%08x" % (s_start, s_end) while (s_addr < s_end): print "Testing address 0x%08x" % s_addr #optimization assumes that function chunks are consecutive (no "function-in-function" monkey business) if (idaapi.get_func(s_addr)): next_func = idc.NextFunction(s_addr) ea = s_addr for c in idautils.Chunks(s_addr): #only use chunks in lookahead that do not jump over the next function and that are not smaller than where we are atm. if (c[1] > ea) and (c[1] <= next_func): ea = c[1] if ea == s_addr: s_addr += 2 else: s_addr = ea #s_addr += 4 continue else: #This is not a good optimization, there WILL be data refs to function start addresses sometimes. ''' if sum(1 for _ in (CodeRefsTo(s_addr, 1))) != 0: s_addr += 4 continue ''' #also add STMFD if ((idc.GetMnem(s_addr) == "STM") and ("SP!" in idc.GetOpnd(s_addr, 0)) and ("LR" in idc.GetOpnd(s_addr, 1))) or (((idc.GetMnem(s_addr) == "PUSH") or (idc.GetMnem(s_addr) == "PUSH.W") or (idc.GetMnem(s_addr) == "STR.W") ) and ("LR" in idc.GetOpnd(s_addr, 0))): print "Found function at 0x%08x" % s_addr idc.MakeFunction(s_addr) f = idaapi.get_func(s_addr) if (type(f) == type(None)): print "Failed to create function! Undefined instructions?" s_addr += 2 else: num_added_functions += 1 ea = -1 for c in idautils.Chunks(s_addr): if c[1] > ea: ea = c[1] if ea != -1: s_addr = ea #failed? else: s_addr += 2 else: s_addr += 2 print "finished segment" return num_added_functions