def get_op(ea, op, stkvars=None): '''ea_t -> int -> opt:{int : tinfo_t} -> op_ret''' cmd = idautils.DecodeInstruction(ea) cmd.Operands = get_operands(cmd) # for mips_op_hack op = mips_op_hack(cmd, op) opd = cmd[op] if opd.type == idaapi.o_reg: # gpr, XXX sorta MIPS-specific return op_ret(op_ty.reg, regs.gpr(opd.reg), 0) elif opd.type == idaapi.o_idpspec1: # fpr, XXX sorta MIPS-specific return op_ret(op_ty.reg, regs.fpr(opd.reg), 0) elif opd.type in [idaapi.o_near, idaapi.o_mem]: return op_ret(op_ty.name, idc.Name(opd.addr), 0) elif idc.isStkvar1(idc.GetFlags(ea)): # IDA seems to set this flag even for operands beyond the second, # i.e. both of these are true for isStkvar1: # .text:10003A84 sd $a1, 0x2E0+var_58($sp) # .text:10003A68 addiu $a1, $sp, 0x2E0+var_2D8 try: func = idaapi.get_func(ea) off = idaapi.calc_stkvar_struc_offset(func, ea, op) (name, ti) = stkvars[off] return op_ret_for_ti(ti, name, off, off) except KeyError: raise OperandUnresolvableError('unable to get operand %u at %s' % (op, idc.atoa(ea))) elif opd.type in [idaapi.o_imm, idaapi.o_displ]: return cpu_ida.ida_current_cpu().data.get_op_addrmode(ea, op, cmd) else: raise OperandUnresolvableError('unable to get operand %u at %s' % (op, idc.atoa(ea)))
def dlls_setup(base_address): """Find the pattern for loading dynamically DLLs by using LoadLibrary API, set the name for the retrieved dll. Args: base_address -- the address for Oski procsSetup function """ """LoadLibrary pattern mov eax, aBcryptdll push eax ; lpLibFileName call LoadLibraryA mov [ebp+hModule], eax """ pattern = ['mov', 'push', 'call', 'mov'] dism_addr_list = list(FuncItems(base_address)) pFunc = idaapi.get_func(base_address) pFrame = ida_frame.get_frame(base_address) counter_dlls = 0 for i in range(0, len(dism_addr_list) - len(pattern)): if check_pattern(dism_addr_list[i:i + len(pattern)], pattern): if "LoadLibrary" in print_operand(dism_addr_list[i + 2], 0): dll_string_addr = list(DataRefsFrom(dism_addr_list[i]))[0] dll_name = get_cmt(dll_string_addr, 0) # rename stack variable inst = DecodeInstruction(dism_addr_list[i + 3]) offset = (idaapi.calc_stkvar_struc_offset(pFunc, inst, 0)) name = sanitize_string(dll_name, 'dll') ida_struct.set_member_name(pFrame, offset, 'h%s' % name) counter_dlls += 1 print("%s dynamic dlls" % counter_dlls)
def get_operand_stack_variable_name(self, address, op, idx): """Return the name of any variable referenced from this operand.""" if op.addr>2**31: addr = -(2**32-op.addr) else: addr = op.addr try: # In IDA 5.7 get_stkvar takes 2 arguments var = idaapi.get_stkvar(op, addr) except TypeError: # In earlier versions it takes 3... var = idaapi.get_stkvar(op, addr, None) if var: if isinstance(var, (tuple, list)): # get the member_t # In IDA 5.7 this returns a tuple: (member_t, actval) # so we need to get the actual object from the first # item. In previous version that was what was returned var = var[0] func = idaapi.get_func(address) stackvar_offset = idaapi.calc_stkvar_struc_offset( func, address, idx) stackvar_start_offset = var.soff stackvar_offset_delta = stackvar_offset-stackvar_start_offset delta_str = '' if stackvar_offset_delta != 0: delta_str = '+0x%x' % stackvar_offset_delta disp_str = '' # 4 is the value of the stack pointer register SP/ESP in x86. This # should not break other archs but needs to be here or otherwise would # need to override the whole method in metapc... # if op.reg == 4: difference_orig_sp_and_current = idaapi.get_spd(func, address) disp_str = ida_hexify( -difference_orig_sp_and_current-idc.GetFrameRegsSize(address) ) + '+' name = self.get_stack_var_name(var) if name: return disp_str + name + delta_str return None
def get_operand_stack_variable_name(self, address, op, idx): """Return the name of any variable referenced from this operand.""" if op.addr > 2**31: addr = -(2**32 - op.addr) else: addr = op.addr try: # In IDA 5.7 get_stkvar takes 2 arguments var = idaapi.get_stkvar(op, addr) except TypeError: # In earlier versions it takes 3... var = idaapi.get_stkvar(op, addr, None) if var: if isinstance(var, (tuple, list)): # get the member_t # In IDA 5.7 this returns a tuple: (member_t, actval) # so we need to get the actual object from the first # item. In previous version that was what was returned var = var[0] func = idaapi.get_func(address) stackvar_offset = idaapi.calc_stkvar_struc_offset( func, address, idx) stackvar_start_offset = var.soff stackvar_offset_delta = stackvar_offset - stackvar_start_offset delta_str = '' if stackvar_offset_delta != 0: delta_str = '+0x%x' % stackvar_offset_delta disp_str = '' # 4 is the value of the stack pointer register SP/ESP in x86. This # should not break other archs but needs to be here or otherwise would # need to override the whole method in metapc... # if op.reg == 4: difference_orig_sp_and_current = idaapi.get_spd(func, address) disp_str = ida_hexify(-difference_orig_sp_and_current - idc.GetFrameRegsSize(address)) + '+' name = self.get_stack_var_name(var) if name: return disp_str + name + delta_str return None