def set_operand_value(cpu_context, ip, value, opnd, optype, width=None): """ Function to set the operand to the specified value. :param cpu_context: current context of cpu :param ip: instruction pointer :param value: value to set operand to :param opnd: value returned by idc.GetOpnd() :param optype: value returned by idc.GetOpType() :param width: byte width of the operand value being set """ if optype == idc.o_reg: # Convert the value from string to integer... if isinstance(value, str): value = utils.struct_unpack(value) cpu_context.reg_write(opnd.upper(), value) elif optype in [idc.o_phrase, idc.o_displ]: # For data written to the frame or memory, this data MUST be in string form so convert it if numpy.issubdtype(type(value), numpy.integer): value = utils.struct_pack(value, signed=(value < 0), width=width) # These need to be handled in the same way even if they don't contain the same types of data. try: offset = utils.get_stack_offset(cpu_context, ip, 0) except ValueError: # Not a stack variable, calculate the displacement and set it using .memctrlr addr = utils.calc_displacement(cpu_context, ip, 0) cpu_context.mem_write(addr, value) else: cpu_context.mem_write(offset, value) elif optype == idc.o_mem: # FS, GS are identified as memory addresses, rather use them as registers if "fs" in opnd: cpu_context.reg_write("FS", value) elif "gs" in opnd: cpu_context.reg_write("GS", value) else: if numpy.issubdtype(type(value), numpy.integer): value = utils.struct_pack(value, signed=(value < 0), width=width) cpu_context.mem_write(idc.GetOperandValue(ip, 0), value) elif optype == idc.o_imm: offset = idc.GetOperandValue(ip, 0) if idaapi.isLoaded(offset): cpu_context.mem_write(offset, value)
def add_xrefs(addr, end=idc.BADADDR): """ https://github.com/xyzz/vita-ida-physdump/blob/master/vita_phys_dump.py Searches for MOV / MOVT pair, probably separated by few instructions, and adds xrefs to things that look like addresses """ while addr < end and addr != BADADDR: addr = idc.NextHead(addr) if idc.GetMnem(addr) in ["MOV", "MOVW"]: reg = idc.GetOpnd(addr, 0) if idc.GetOpnd(addr, 1)[0] != "#": continue val = idc.GetOperandValue(addr, 1) found = False next_addr = addr for x in range(16): next_addr = idc.NextHead(next_addr) if idc.GetMnem(next_addr) in ["B", "BX"]: break # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated # if there's a function call and our register is scratch, it will probably get corrupted, bail out if idc.GetMnem(next_addr) in ["BL", "BLX"] and reg in [ "R0", "R1", "R2", "R3" ]: break # if we see a MOVT, do the match! if idc.GetMnem(next_addr) in ["MOVT", "MOVT.W"] and idc.GetOpnd( next_addr, 0) == reg: if idc.GetOpnd(next_addr, 1)[0] == "#": found = True val += idc.GetOperandValue(next_addr, 1) * (2**16) break # if we see something other than MOVT doing something to the register, bail out if idc.GetOpnd(next_addr, 0) == reg or idc.GetOpnd( next_addr, 1) == reg: break if val & 0xFFFF0000 == 0: continue if found: # pair of MOV/MOVT try: idc.OpOffEx(addr, 1, idc.REF_LOW16, val, 0, 0) idc.OpOffEx(next_addr, 1, idc.REF_HIGH16, val, 0, 0) except: print "Failed xref @ %x next_addr %x val %x" % ( addr, next_addr, val) else: # a single MOV instruction try: idc.OpOff(addr, 1, 0) except: print "Failed xref at addr %x" % (addr)
def mark_instruction(ea): ori_commt = idc.GetDisasm(ea) if '|' in ori_commt: # be handled by this python script before ori_commt = ori_commt.split('|')[-1] elif ';' in ori_commt: ori_commt = ori_commt.split(';')[-1] else: ori_commt = '' commt = '(%s, %s), (%s, %s) |%s' % (opertype[idc.GetOpType( ea, 0)], idc.GetOperandValue(ea, 0), opertype[idc.GetOpType( ea, 1)], idc.GetOperandValue(ea, 1), ori_commt) idc.MakeComm(ea, commt)
def getCallInfo(self, xref_addr, tid): result = None target = 0 callee_id = -1 for thread in self["mem_areas"][0]['threads']: if tid == thread['tid']: for call in thread['calls']: for xref in call['xrefs']: if xref['addr'] == xref_addr: target = call['target'] if len(xref["params"]): if 'count' not in xref: xref['count'] = 0 callee_id = xref['count'] xref['count'] += 1 if len(call['name']): result = call['name'].encode('ascii') elif 'real_call' in call: result = call['real_call']['name'].encode('ascii') target = call['real_call']['target'] else: result = idc.GetFunctionName(target) if len(result) == 0: opval = idc.GetOperandValue(xref_addr, 0) if len(idc.get_name(opval)) > 0: result = idc.get_name(opval) else: result = "%x" % target return result, target, callee_id return None, None, -1
def __mark_calls(self): for thread in self["mem_areas"][0]['threads']: for call in thread['calls']: if not call['returns']: continue # generate name for the function fname = idc.GetFunctionName(call['target']) if len(fname) == 0: if len(call["name"]) > 0: fname = call["name"].encode('ascii') else: fname = "0x%x" % call["target"] # name all indirect calls for xref in call['xrefs']: idc.MakeCode(xref['addr']) op = idc.GetOpType(xref['addr'],0) if op == ida_ua.o_mem: val = idc.GetOperandValue(xref['addr'], 0) vname = idc.get_name(val) if val is not None and val > 0 and len(vname) > 0 and 'dword_' in vname: idc.MakeName(val, fname) elif op == ida_ua.o_reg or op == ida_ua.o_displ: idc.MakeComm(xref['addr'], fname)
def find_WdfControlDeviceInitAllocate(): function_offset = OFFSET_WdfControlDeviceInitAllocate call_pfn = None try: for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"] + function_offset): call_pfn = xref.frm except StopIteration: # this is case 2 or 3 pass if call_pfn is None: call_pfn = find_wdf_callback_through_immediate("call", 0, function_offset) if call_pfn: idc.OpStroffEx(call_pfn, 0, (idaapi.get_struc_id("_WDFFUNCTIONS")), 0) if call_pfn is None: call_pfn = find_wdf_callback_through_immediate("mov", 1, function_offset) if call_pfn: idc.OpStroffEx(call_pfn, 1, (idaapi.get_struc_id("_WDFFUNCTIONS")), 0) lea_sddl = find_function_arg(call_pfn, "lea", "r8", 0) unicode_sddl = idc.GetOperandValue(lea_sddl, 1) idc.MakeName(unicode_sddl, 'control_device_sddl') assign_struct_to_address(unicode_sddl, "_UNICODE_STRING") print("Control Device SDDL at: ", hex(unicode_sddl))
def handle_mov(self, state): """Updates the state of the stack string finding based on a mov instruction""" op1 = tracingutils.get_opnd_replacement(state.ea, POS_FIRST) if '[' in op1: offset = tracingutils.get_operand_value_replacement( state.ea, POS_FIRST, state) self.set_stack(offset, state.ea, POS_SECOND, state) else: reg = tracingutils.get_reg_fam(op1) type_ = idc.GetOpType(state.ea, POS_SECOND) if reg: if type_ != idc.o_phrase and type_ != idc.o_displ: if type_ == idc.o_reg: reg2 = tracingutils.get_reg_fam( tracingutils.get_opnd_replacement( state.ea, POS_SECOND)) if reg2 and reg2[0] in state.regs: val = state.regs[reg2[0]][0] else: val = None else: val = idc.GetOperandValue(state.ea, POS_SECOND) if val is not None: state.regs[reg[0]] = (val, state.ea) else: offset = tracingutils.get_operand_value_replacement( state.ea, POS_SECOND, state) value = state.stack.get(offset, None) if value is not None: state.regs[reg[0]] = value else: self.clear_reg_if_needed(reg, state.regs)
def set_stack(offset, ea, pos, state): '''Sets the stack dictionary, at the given offset, to contain the value at the given position at the given ea, performing a lookup in the register dictionary if needed. Used by create_stack :param offset: offset to set on stack :param ea: instruction location :param pos: argument position :param state: the current TraceState :return: None - updates state ''' fill = False if idc.GetOpType(ea, pos) == idc.o_imm: val = idc.GetOperandValue(ea, pos) state.stack[offset] = (val, ea) fill = True else: reg = unsafe_get_reg_fam(get_opnd_replacement(ea, pos)) if reg and reg[0] in state.regs: val = state.regs[reg[0]][0] state.stack[offset] = (state.regs[reg[0]][0], ea) fill = True if fill: for i in xrange(0, get_byte_size_of_operand(ea, pos)): state.stack[offset + i] = (val & 0xff, ea) val /= 256
def find_WdfDeviceCreateDeviceInterface(): function_offset = OFFSET_WdfDeviceCreateDeviceInterface calls_to_pfn_list = [] try: for xref in idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset): call_pfnWdfDeviceCreateDeviceInterface = xref.frm calls_to_pfn_list.append(call_pfnWdfDeviceCreateDeviceInterface) except StopIteration: # this is case 2 or 3 pass if len(calls_to_pfn_list) == 0: call_pfnWdfDeviceCreateDeviceInterface = find_wdf_callback_through_immediate("call", 0, function_offset) if call_pfnWdfDeviceCreateDeviceInterface: calls_to_pfn_list.append(call_pfnWdfDeviceCreateDeviceInterface) idc.OpStroffEx(call_pfnWdfDeviceCreateDeviceInterface,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) if len(calls_to_pfn_list) == 0: call_pfnWdfDeviceCreateDeviceInterface = find_wdf_callback_through_immediate("mov", 1,function_offset) if call_pfnWdfDeviceCreateDeviceInterface: calls_to_pfn_list.append(call_pfnWdfDeviceCreateDeviceInterface) idc.OpStroffEx(call_pfnWdfDeviceCreateDeviceInterface,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) for k, pfn_call in enumerate(calls_to_pfn_list): lea_guid = find_function_arg(pfn_call, "lea", "r8", 0) interface_guid = idc.GetOperandValue(lea_guid, 1) idc.MakeName(interface_guid, '_InterfaceGUID' + str(k)) assign_struct_to_address(interface_guid, "GUID") g_vars["_InterfaceGUID" + str(k)] = interface_guid print("_InterfaceGUID: ", hex(interface_guid)) guid_bytes = idc.GetManyBytes(interface_guid, 0x10) print_guid(guid_bytes)
def patch_to_call_puts(addr): #.text:0000114D E8 DE FE FF FF call _printf count = idc.ItemSize(addr) #get value v = idc.GetOperandValue(addr, 0) #要CALL的地址 - 下一条指令地址 = E8 后面的硬编码 plt_names = idautils.Names() for address, name in plt_names: if name == '.puts': puts_addr = address elif name == '.printf': printf_addr = address op = puts_addr - (addr + count) op = op & 0xffffffff #print('op: %s' %hex(op)) idc.PatchDword(addr + 1, op) idc.MakeCode(addr) print('patch [call _printf] ok, addr: %s' % hex(addr)) return
def main(): xrefs = XrefsTo(0xF27B90) for xref in xrefs: offset = idc.GetOperandValue((xref.frm - 0xF), 0) print "%s," % (GetString(offset, -1, ASCSTR_C)) print "done"
def getMinorDispatchTableAddress(ea): """find address of last lea in function""" start = idc.GetFunctionAttr(ea, idc.FUNCATTR_START) end = idc.PrevHead(idc.GetFunctionAttr(ea, idc.FUNCATTR_END), start) res = prevMnemonic(end, 'lea', start) assert res != idc.BADADDR return idc.GetOperandValue(res, 1)
def lookForOpArgs(self, start, end): for head in idautils.Heads(start, end): try: for i in range(2): if using_ida7api: t = idc.get_operand_type(head, i) else: t = idc.GetOpType(head, i) if t == idc.o_imm: if using_ida7api: opval = idc.get_operand_value(head, i) insn = idautils.DecodeInstruction(head) opmask = OPERAND_MASK.get(insn.ops[i].dtype) if opmask: opval = opval & opmask else: opval = idc.GetOperandValue(head, i) if self.params.useXORSeed: opval = opval ^ self.params.XORSeed for h in self.params.hashTypes: hits = self.dbstore.getSymbolByTypeHash( h.hashType, opval) for sym in hits: logger.info("0x%08x: %s", head, str(sym)) self.addHit(head, sym) self.markupLine(head, sym, self.params.useDecompiler) except Exception as err: logger.exception("Exception: %s", str(err))
def get_operand_value_replacement(ea, pos, state): """ A replacement for Ida's idc.GetOperandValue that handles displacements more reasonably :param ea: memory location :param pos: argument location example: add eax, ebx eax is position 0, ebx is position 1 :param state: the current stack pointer register family (usually sp) :return: computes a numerical replacement for an operand """ if is_displ(ea, pos): bit_size = 64 if is_64_bit() else 32 stack_reg = 'rsp' if bit_size == 64 else 'esp' idaapi.decode_insn(ea) offset = idaapi.cmd.Operands[pos].addr # Convert the offset to a signed value if offset & (1 << (bit_size - 1)): offset -= (1 << bit_size) if stack_reg in get_opnd_replacement(ea, pos): offset += idc.GetSpd(ea) or 0 return offset else: return idc.GetOperandValue(ea, pos)
def norm_func1(head): inst = '' + idc.GetMnem(head) num_operands = op_count(head) for i in range(num_operands): type_op = idc.GetOpType(head, i) if type_op == idc.o_void: break elif type_op == idc.o_mem: inst += ' [MEM]' elif type_op == idc.o_imm: val = idc.GetOperandValue(head, i) #if -int(5000) <= val <= int(5000): if -int(500) <= val <= int(500): inst += ' ' + str(hex(val)) else: inst += ' HIMM' else: inst += ' ' + idc.GetOpnd(head, i) if num_operands > 1: inst += ',' if ',' in inst: inst = inst[:-1] inst = inst.replace(' ', '_') return str(inst)
def find_interesting_xors(self): next_xor = idc.FindText(idc.MinEA(), idc.SEARCH_DOWN | idc.SEARCH_NEXT, 0, 0, "xor") while next_xor != idc.BADADDR: if idc.GetOpnd(next_xor, 0) != idc.GetOpnd(next_xor, 1): entry = { "func": "", "addr": next_xor, "loop": False, "disasm": idc.GetDisasm(next_xor) } func = idaapi.get_func(next_xor) if func: entry["func"] = idaapi.get_name(idc.BADADDR, func.startEA) heads = idautils.Heads(next_xor, func.endEA) lxors = [] for head in heads: if idc.GetMnem(head).startswith('j'): jmp_addr = idc.GetOperandValue(head, 0) if jmp_addr < next_xor and jmp_addr > func.startEA: entry["loop"] = True break self._interesting_xors.append(entry) next_xor = idc.FindText(idc.NextHead(next_xor), idc.SEARCH_DOWN | idc.SEARCH_NEXT, 0, 0, "xor")
def get_operand_value_replacement(ea, pos, state): ''' A replacement for Ida's idc.GetOperandValue that handles displacements more reasonably :param ea: memory location :param pos: argument location example: add eax, ebx eax is position 0, ebx is position 1 :param state: the current stack pointer register family (usually sp) :return: computes a numerical replacement for an operand ''' if is_displ(ea, pos): idaapi.decode_insn(ea) offset = idaapi.cmd.Operands[pos].addr flipped = (offset ^ (0xffffffffffffffff if is_64_bit(ea) else 0xffffffff)) + 1 # Use reg_fam[2] here as opposed to reg_fam[0] like usual because we need to mach the reg name string if any(reg_fam[2] in get_opnd_replacement(ea, pos) for reg_fam in state.stack_pointer_reg_fams): adjustment = idc.GetSpd(ea) else: adjustment = 0 if not adjustment: adjustment = 0 if flipped < offset: return -flipped + adjustment else: return offset + adjustment else: return idc.GetOperandValue(ea, pos)
def patch_64_rsp(addr, sub_value, is_sub_rsp): count = idc.ItemSize(addr) #get value v = idc.GetOperandValue(addr, 1) #print(hex(v)) if v == -1: print('get value error') return if count == 4: #.text:000055BBF4127FD9 48 83 EC 10 sub rsp, 10h off = 0xff - v if sub_value < off: idc.PatchByte(addr + 3, v + sub_value) else: idc.PatchByte(addr + 3, 0xff) idc.MakeCode(addr) else: #.text:00007EFEA44A5310 48 81 EC 20 01 00 00 sub rsp, 120h idc.PatchDword(addr + 3, v + sub_value) idc.MakeCode(addr) if is_sub_rsp != 0: print('patch [sub rsp, %s] ok, addr: %s' % (hex(v), hex(addr))) else: print('patch [add rsp, %s] ok, addr: %s' % (hex(v), hex(addr))) return
def patch_32_esp(addr, sub_value, is_sub_esp): count = idc.ItemSize(addr) #get value v = idc.GetOperandValue(addr, 1) #print(hex(v)) if v == -1: print('get value error') return if count == 3: #.text:0804867C 83 EC 18 sub esp, 18h off = 0xff - v if sub_value < off: idc.PatchByte(addr + 2, v + sub_value) else: idc.PatchByte(addr + 2, 0xff) idc.MakeCode(addr) else: #.text:0804875B 81 EC 30 02 00 00 sub esp, 230h idc.PatchDword(addr + 2, v + sub_value) idc.MakeCode(addr) if is_sub_esp != 0: print('patch [sub esp, %s] ok, addr: %s' % (hex(v), hex(addr))) else: print('patch [add esp, %s] ok, addr: %s' % (hex(v), hex(addr))) return
def get_first_function(ea): """ see above, but returns the first pushed value """ maybe_start = idc.get_func_attr(ea, idc.FUNCATTR_START) limit = 0 if maybe_start == idc.BADADDR: limit = 10 cur_ea = ea limit_count = 0 while cur_ea != idc.BADADDR: # are we over limit or up to the func start? limit_count += 1 limit_exceeded = (limit > 0 and limit_count > limit) too_far = (maybe_start != idc.BADADDR and cur_ea < maybe_start) if limit_exceeded or too_far: LOG.error( "Failed to find string walking backwards from {:08X}".format( ea)) return None prev_ins = idautils.DecodePreviousInstruction(cur_ea) prev_ea = prev_ins.ea # did we find it? if idc.GetMnem(prev_ea) == 'push': if idc.get_operand_type(prev_ea, 0) in [idc.o_mem, idc.o_imm]: # push offset found! pushed_addr = idc.GetOperandValue(prev_ea, 0) # it's not data, then probably good if idc.isCode(idc.GetFlags(pushed_addr)): return pushed_addr cur_ea = prev_ea
def isCall(self, xref, tid): if xref in self._call_lut: return True elif idc.GetMnem(xref) == 'jmp': curf = idc.GetFunctionName(xref) if curf is not None: val = idc.GetOperandValue(xref, 0) if val is not None and val > 0: tarf = idc.GetFunctionName(val) if tarf is not None and tarf != curf: self._call_lut.add(xref) for thread in self["mem_areas"][0]['threads']: if thread['tid'] == tid: thread['calls'].append({ "execs": 1, "name": "", "target": val, "xrefs": [{ "addr": xref, "execs": 1, "params": [] }] }) return True return False
def get_goversion(): global GOVER func_goroot = find_func_by_name("runtime_schedinit") if func_goroot is None: _error("Failed to find func runtime_schedinit") return schedinit_flowchart = idaapi.FlowChart(f=func_goroot) _debug("Flowchart number of runtime_schedinit: %d" % schedinit_flowchart.size) for fc_idx in xrange(schedinit_flowchart.size): fc = schedinit_flowchart[fc_idx] _debug("Current flowchart start addr: 0x%x" % fc.startEA) # mov dword_AD744C, 7 ; dword_AD744C stores length of Go Version string if idc.GetMnem(fc.startEA) == "mov" and idc.GetOpType(fc.startEA, 0) == 2 \ and str(idc.GetOperandValue(fc.startEA, 1)) == "7": _debug("Find length of go version string @ 0x%x" % fc.startEA) possible_goversion_len_addr = idc.GetOperandValue(fc.startEA, 0) _debug("Possible go version string len addr: 0x%x" % possible_goversion_len_addr) possible_goversion_str_ptr_addr = possible_goversion_len_addr - ADDR_SZ possible_goversion_str_addr = read_mem( possible_goversion_str_ptr_addr) _debug("Possible go version string addr: 0x%x" % possible_goversion_str_addr) possible_goversion_len = read_mem(possible_goversion_len_addr) _debug("Real go version string len: %d" % possible_goversion_len) if possible_goversion_len >= 5 and possible_goversion_len < 10: if idc.MakeStr( possible_goversion_str_addr, possible_goversion_str_addr + possible_goversion_len): idaapi.autoWait() goversion_str = str( idc.GetManyBytes(possible_goversion_str_addr, possible_goversion_len)) _debug(goversion_str) if goversion_str.startswith("go"): GOVER = goversion_str[2:] _info("\nGo version: %s\n" % GOVER) else: _debug("Invalid go string") else: _debug("Failed to create go version string") else: _debug("Invalid go version len")
def handle_mov(ea, state): '''Updates the stack based on a mov instruction. Used by create_stack :param ea: instruction location :param state: the current TraceState :return: None - updates stack or regs ''' op1 = get_opnd_replacement(ea, POS_FIRST) if '[' in op1: offset = get_operand_value_replacement(ea, POS_FIRST, state) set_stack(offset, ea, POS_SECOND, state) else: reg = unsafe_get_reg_fam(op1) type_ = idc.GetOpType(ea, POS_SECOND) if reg: if type_ != idc.o_phrase and type_ != idc.o_displ: val = None if type_ == idc.o_reg: reg2 = unsafe_get_reg_fam( get_opnd_replacement(ea, POS_SECOND)) if reg2 and reg2[0] in state.regs: val = state.regs[reg2[0]][0] if reg2 in state.stack_pointer_reg_fams: state.stack_pointer_reg_fams.remove(reg2) else: if reg2 in state.stack_pointer_reg_fams: state.stack_pointer_reg_fams.append(reg2) else: val = None elif type_ == idc.o_mem: bytes = idc.GetManyBytes( idc.GetOperandValue(ea, POS_SECOND), get_byte_size_of_operand(ea, 1)) val = 0 if bytes: for x in range(len(bytes)): val += ord(bytes[x]) << x else: val = idc.GetOperandValue(ea, POS_SECOND) if val is not None: state.regs[reg[0]] = (val, ea) else: offset = get_operand_value_replacement(ea, POS_SECOND, state) value = state.stack.get(offset, None) if value is not None: state.regs[reg[0]] = value
def get_goroot(): goroot_path_str = "" ''' Get GOROOT path string ''' func_goroot = find_func_by_name("runtime_GOROOT") if func_goroot is None: _error("Failed to find func contains goroot") return goroot_path_str goroot_flowchart = idaapi.FlowChart(f=func_goroot) ret_cbs = find_ret_cb(goroot_flowchart) ''' runtime.GOROOT() normally has 2 return code blocks: 1. False return mov [rsp+28h+arg_0], rax mov [rsp+28h+arg_8], rcx mov rbp, [rsp+28h+var_8] add rsp, 28h retn 2. True return(Which we needed): mov rax, cs:runtime_internal_sys_DefaultGoroot mov rcx, cs:qword_D9AB58 mov [rsp+28h+arg_0], rax mov [rsp+28h+arg_8], rcx mov rbp, [rsp+28h+var_8] add rsp, 28h retn ''' for cb_idx in ret_cbs: if idc.GetOpType(goroot_flowchart[cb_idx].startEA, 0) == 1: # e.g.: mov rax, cs:runtime_internal_sys_DefaultGoroot ''' Op Types refer: https://www.hex-rays.com/products/ida/support/sdkdoc/ua_8hpp.html#aaf9da6ae7e8b201108fc225adf13b4d9 o_void = 0 # No Operand o_reg = 1 # General Register (al,ax,es,ds...) reg o_mem = 2 # Direct Memory Reference (DATA) addr o_phrase = 3 # Memory Ref [Base Reg + Index Reg] phrase o_displ = 4 # Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr o_imm = 5 # Immediate Value value o_far = 6 # Immediate Far Address (CODE) addr o_near = 7 # Immediate Near Address (CODE) addr ...... ''' goroot_path_str_addr = read_mem( idc.GetOperandValue(goroot_flowchart[cb_idx].startEA, 1)) goroot_path_str = idc.GetString(goroot_path_str_addr) if goroot_path_str is None or len(goroot_path_str) == 0: raise Exception("Invalid GOROOT") idc.MakeStr(goroot_path_str_addr, goroot_path_str_addr + len(goroot_path_str) + 1) idaapi.autoWait() break if len(goroot_path_str) > 0: _info("Go ROOT Path: %s\n" % goroot_path_str) return goroot_path_str.replace("\\", "/")
def ret_operand(ea, index): opType = idc.GetOpType(ea, index) if opType == 0: # o_void return "void" elif opType == 1: # o_reg return idc.GetOpnd(ea, index) elif opType == 2: # o_mem return idc.GetOperandValue(ea, index) elif opType == 3: # o_phrase [X20,X8] return idc.GetOpnd(ea, index).strip('[]').split(',') elif opType == 4: # o_displ [SP,#0x80+var_80]; [SP+0xC0+var_C0],#0x60;[X8] op = idc.GetOpnd(ea, index) ops = [] for pat in patterns: m = pat.match(op) if m: ops.append(m.groupdict()['register']) if 'offset' in m.groupdict(): ops.append(idc.GetOperandValue(ea, index)) return ops elif opType == 5: # o_imm return idc.GetOperandValue(ea, index) elif opType == 6: # o_far return idc.GetOperandValue(ea, index) elif opType == 7: # o_near return idc.GetOperandValue(ea, index) else: return idc.GetOpnd(ea, index) # funcs = Functions() # for f in funcs: # name = Name(f) # end = GetFunctionAttr(f, FUNCATTR_END) # locals = GetFunctionAttr(f, FUNCATTR_FRSIZE) # frame = GetFrame(f) # if frame is None: # continue # for struct in idautils.Structs(): # index = struct[0] # sid = struct[1] # name = struct[2] # size = idc.GetStrucSize(sid) # idc.NextNotTail(ea)
def main(): xrefs = XrefsTo(0x13070FC) for xref in xrefs: packetHeader = idc.NextNotTail(xref.frm) opCode1 = idc.GetOperandValue(packetHeader, 1) if opCode1 > 10 and opCode1 < 16655: print "%08x -> %2x" % (packetHeader, opCode1)
def get_opnd_replacement(ea, pos): """ A replacement for IDA's idc.GetOpnd that can de-alias register names""" # TODO: Support renames in other operand types if idc.GetOpType(ea, pos) == idc.o_reg: return idaapi.get_reg_name(idc.GetOperandValue(ea, pos), get_byte_size_of_operand(ea, pos)) else: return idc.GetOpnd(ea, pos)
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 run(self, arg=0): print("running") ea = idc.get_screen_ea() if idc.GetOpType(ea, 1) != 5: # Immediate return value = idc.GetOperandValue(ea, 1) & 0xffffffff ida_bytes.set_cmt(ea, windows_ioctl_decode(value), 1) return
def find_WdfDriverCreate(): function_offset = OFFSET_WdfDriverCreate # If the XREF to wdfFunctions + function_offset exists.. then we're in case 1! try: call_pfnWdfDriverCreate = idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset).next().frm except StopIteration: # this is case 2! call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("mov", 1,function_offset) if call_pfnWdfDriverCreate != None: idc.OpStroffEx(call_pfnWdfDriverCreate,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) else: call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("call", 0, function_offset) idc.OpStroffEx(call_pfnWdfDriverCreate,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0) if call_pfnWdfDriverCreate != None: # First identify the RealDriverEntry :) current_func = idaapi.get_func(call_pfnWdfDriverCreate) idc.MakeName(current_func.startEA, "_DriverEntry_") argument_DriverConfig_addr = find_function_arg_with_operand_value(call_pfnWdfDriverCreate, "mov", "rsp", 0x20, 0) register_DriverConfig = idc.GetOpnd(argument_DriverConfig_addr, 1) lea_DriverConfig_addr = find_function_arg(argument_DriverConfig_addr, "lea", register_DriverConfig, 0) # Get stack and the stack operand offset current_func = idaapi.get_func(lea_DriverConfig_addr) stack_id = idc.GetFrame(current_func) opnd = idc.GetOpnd(lea_DriverConfig_addr, 1) if "rsp" in opnd: stack_member_offset = idc.GetOperandValue(lea_DriverConfig_addr, 1) elif "rbp" in opnd: var_x = opnd.split("+")[-1][:-1] # [rbp+57h+var_80] -> var_80 members, _ = retrieve_stack_members(current_func) inverted_members = {v:k for k, v in members.items()} try: stack_member_offset = inverted_members[var_x] except KeyError as msg: print msg return else: print("+] WdfDriverCreate() Unidentified register stack layout") return #idc.SetMemberName(stack_id, stack_member_offset, "_DriverConfig") struct_id = idaapi.get_struc_id("_WDF_DRIVER_CONFIG") struct_size = idc.GetStrucSize(struct_id) # First check if we have already touch this function stack before #if function_stack_erased(current_func): # need to take care of the already defined structs # pass #else: delete_all_function_stack_members(current_func, force=True) idc.AddStrucMember(stack_id, "driver_config", stack_member_offset, idc.FF_BYTE|idc.FF_DATA, -1, struct_size) idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, struct_id, 1)