def decrypt_aes_string(index): index ^= 0xAA addr = idaapi.get_dword(0x81A5140 + (index << 2)) if index % 2 == 1: string = '' i = 0 while True: ch = idaapi.get_byte(addr + i) if ch < 0x20 or ch > 0x7e: break string += chr(ch) i += 1 decr_string = '' for i in range(len(string) >> 1): arg2, arg3 = ord(string[2 * i]), ord(string[2 * i + 1]) eax = (16 * (arg2 - 1)) | (arg3 - 1) & 0xF eax &= 0xFF decr_string += chr(eax) return decr_string else: key = bytes(idaapi.get_byte(addr + i) for i in range(16)) size = idaapi.get_dword(addr + 16) cipher = bytes(idaapi.get_byte(addr + 20 + i) for i in range(size)) decryptor = AES.new(key, AES.MODE_ECB) decrypted_data = decryptor.decrypt(cipher) return str(decrypted_data)
def decrypt_xor_string(index): addr = idaapi.get_dword(0x81A51C0 + ((index ^ 0xAA) << 2)) key = bytes(idaapi.get_byte(addr + i) for i in range(4)) size = idaapi.get_dword(addr + 4) cipher = bytes(idaapi.get_byte(addr + 8 + i) for i in range(size)) plain = ''.join(chr(cipher[i] ^ key[i % 4]) for i in range(size)) return plain
def is_sead_safestringbase_null_char(c, cfunc): # type: (...) -> bool c = unwrap_cast(c) if c.op == hr.cot_var and cfunc: return "zero_" in cfunc.get_lvars()[c.v.idx].name if c.op != hr.cot_obj: return c.is_zero_const() return idaapi.get_byte(c.obj_ea) == 0
def make_cstrings(): """Highlight a range and turn it into c-style strings NOTE: read_selection appears to be a fickle bitch. You absolutely have to select more than one line at a time in order for it to work as expected. """ # TODO check to verify that each byte is valid ascii selected = get_selected_bytes() if selected: curr_start = selected[1] curr_length = 0 for ea in range(selected[1], selected[2]): if not cool_to_clobber(ea): print "[-] Error: Something that we shouldn't clobber at 0x%x" % ea break curr_byte = idaapi.get_byte(ea) curr_length += 1 if curr_byte == 0: if curr_length > 1: idaapi.doASCI(curr_start, curr_length) curr_length = 0 curr_start = ea + 1 else: curr_length = 0 curr_start = ea + 1 else: print "[-] Error: EA is not currently a selection endpoint %x" % idc.ScreenEA( )
def process_instruction(self, packet, addr): """Architecture specific instruction processing""" # Call the generic part with the architecture specific operand # handling # (instruction, i_mnemonic, operands, operand_strings, data) = self.process_instruction_generic(addr) if i_mnemonic is None: return None if idaapi.get_byte(addr) == 0xf0: prefix = 'lock ' else: prefix = '' packet.add_instruction(instruction, addr, prefix+i_mnemonic, operand_strings, operands, data) return instruction
def get_str(x): res = bytearray() while True: c = idaapi.get_byte(x) if c == 0: break res.append(c) x += 1 return res
def get_strlen(self, addr): strlen = 0 while get_byte(addr + strlen) != 0x0 and strlen < 50: strlen += 1 #assume no names will ever be longer than 50 bytes if strlen == 50: return None return strlen
def decrypt(ea, key): # Virtual address to IMAGE_IMPORT_DESCRIPTOR->FirstThunk va_iat = 0 # Virtual address to IMAGE_IMPORT_DESCRIPTOR->OriginalFirstThunk va_int = 0 tmp_ea = ea # Back-tracing to locate the IMAGE_IMPORT_DESCRIPTOR from import address table passed from the callback for xref in idautils.XrefsTo(ea, 0): if XrefTypeName(xref.type) == 'Data_Offset': va_iat = xref.frm - 0x10 if va_iat != 0: print "Import Name Table->%08x" % (idaapi.get_long(va_iat) + IMG_BASE) va_int = idaapi.get_long(va_iat) + IMG_BASE else: return if va_int != 0: va_itd = idaapi.get_long(va_int) # Enumerate array of IMAGE_THUNK_DATA while va_itd != 0: va_itd = va_itd + IMG_BASE if va_itd > IMG_BASE and va_itd <= IMG_END: print "Image thunk data->%08x" % va_itd va_ibn = va_itd + 2 ch = idaapi.get_byte(va_ibn) str = '' while ch != 0 and ch != 255: str += chr(ch ^ key) va_ibn += 1 ch = idaapi.get_byte(va_ibn) # Save the decoded import name print "IMAGE_IMPORT_BY_NAME->Name (%08x): %s" % (va_itd + 2, str) idc.MakeName(tmp_ea, str) tmp_ea += 4 # Next IMAGE_THUNK_DATA va_int += 4 va_itd = idaapi.get_long(va_int) else: return
def decrypt(ea, key): # Virtual address to IMAGE_IMPORT_DESCRIPTOR->FirstThunk va_iat = 0 # Virtual address to IMAGE_IMPORT_DESCRIPTOR->OriginalFirstThunk va_int = 0 tmp_ea = ea # Back-tracing to locate the IMAGE_IMPORT_DESCRIPTOR from import address table passed from the callback for xref in idautils.XrefsTo(ea, 0): if XrefTypeName(xref.type) == 'Data_Offset': va_iat = xref.frm - 0x10 if va_iat != 0: print "Import Name Table->%08x" % (idaapi.get_long(va_iat) + IMG_BASE) va_int = idaapi.get_long(va_iat) + IMG_BASE else: return if va_int != 0: va_itd = idaapi.get_long(va_int) # Enumerate array of IMAGE_THUNK_DATA while va_itd != 0: va_itd = va_itd + IMG_BASE if va_itd > IMG_BASE and va_itd <= IMG_END: print "Image thunk data->%08x" % va_itd va_ibn = va_itd + 2 ch = idaapi.get_byte(va_ibn) str = '' while ch != 0 and ch != 255: str += chr(ch ^ key) va_ibn += 1 ch = idaapi.get_byte(va_ibn) # Save the decoded import name print "IMAGE_IMPORT_BY_NAME->Name (%08x): %s" % (va_itd+2, str) idc.MakeName(tmp_ea, str) tmp_ea += 4 # Next IMAGE_THUNK_DATA va_int += 4 va_itd = idaapi.get_long(va_int) else: return
def get_loaded_bytes(start_addr, size, fill_with="\x00"): data = "" cur_ea = start_addr while cur_ea < (start_addr+size): if idaapi.is_loaded(cur_ea): data += chr(idaapi.get_byte(cur_ea)) else: data += fill_with cur_ea += 1 return bytes(data, 'latin1')
def get_string_table_start_address(self, address): string_table_start_address = address # find current string start address while idaapi.get_byte(string_table_start_address - 1) != 0: string_table_start_address -= 1 while self.get_prev_ascii_string_address(string_table_start_address): string_table_start_address = self.get_prev_ascii_string_address(string_table_start_address) return string_table_start_address
def Dump_Memory(start_addr, end_addr): print '[*]begin to dump memory' handle_f = open('d:/dump.so', 'wb') for byte_addr in range(start_addr, end_addr): byte_value = idaapi.get_byte(byte_addr) handle_f.write(struct.pack('B', byte_value)) handle_f.close() print '[-]dump memory save to d:/dump.so' print '[*]script finish'
def get_next_ascii_string_address(address): """ :param address: must be current ascii string start address. :return: """ next_string_start_address = address # find current string end address while idaapi.get_byte(next_string_start_address) != 0: next_string_start_address += 1 # string table interval should less than 5 bytes. # TODO: need handle short string. if idc.Dword(next_string_start_address + 1) == 0: return None while idaapi.get_byte(next_string_start_address) == 0: next_string_start_address += 1 return next_string_start_address
def main(ea_start, ea_end, save_file): print '[*]begin to dump segment' handle_f = open(save_file, 'wb') for byte_addr in range(ea_start, ea_end): byte_value = idaapi.get_byte(byte_addr) handle_f.write(struct.pack('B', byte_value)) handle_f.close() print '[*]script by freakish, enjoy~~' print '[*]script finish'
def hook_skip_calls(emu, addr, size, user_data): # Need to skip return instructions too: when we emulate an area not # recognized as a function, the emulation will not stop at the retn and the # execution will continue at someplace we don't want to exec. # # Skip 0xCC (INT3 breakpoints) to not stop the execution. mnem = GetMnem(addr) if mnem == "call" or idaapi.get_byte(addr) == 0xCC or "ret" in mnem: emu.reg_write(UC_X86_REG_RIP, addr + size) elif "j" in mnem: if hex(int(GetOpnd(addr, 0)[4:], 16)) > next_call: emu.reg_write(UC_X86_REG_RIP, addr + size) return
def followAddress(self, address): b = idaapi.get_byte(address) if (b == 0xE8): callOffset = ida_bytes.get_dword(address + 1) if (callOffset > 2147483647): callOffset -= 4294967296 address = address + 5 + callOffset return address, False elif (b == 0xE9): # Lazy and none of my signatures use this yet... return address, "JMP Instruction signatures not supported yet" else: return address, False
def activate(self, ctx): info = idaapi.get_inf_structure() selection = idaapi.read_selection() start = selection[1] end = selection[2] if selection[0] == False: start = idaapi.get_screen_ea() if start == idaapi.BADADDR: print 'Easy Nop :: Screen EA == idaapi.BADADDR' return 0 end = start + idaapi.get_item_size(start) else: end += idaapi.get_item_size(end) if start == idaapi.BADADDR: print 'Easy Nop :: Selection EA == idaapi.BADADDR' return 0 if start == end: print 'Easy Nop :: Nothing to nop' return 0 for x in range(start, end): # Maybe theres a smarter way to get the nop value for different archs e.g. Assemble('nop') -> 0x90 idaapi.patch_byte(x, 0x90) for x in range(start + 1, end): idaapi.hide_item(x) # Must do this else it bugs out on 2x 1 byte instructions being nopped idaapi.hide_item(start) idaapi.unhide_item(start) # Search for hidden nops and add to count while idaapi.get_byte(end) == 0x90 and idaapi.is_hidden_item( end) == True: end += 1 count = end - start if count > 1: idaapi.set_cmt(start, "truncated nops (%d)" % (count), False) print end print start return 1
def xor_s(addr, key): ret = [] while True: c = idaapi.get_byte(addr) addr += 1 if c == 0: print str(ret) ret_s = [] for x in ret: ret_s.append(chr(x)) print ''.join(ret_s) return ret.append(c ^ key) return
def xor_mem(addr, key, n): ret = [] for i in range(n): c = idaapi.get_byte(addr) addr += 1 ret.append(c ^ key) print str(ret) ret_s = [] for x in ret: if x == 0: ret_s.append('\\0') else: ret_s.append(chr(x)) print ''.join(ret_s) return
def dynamic_breakpoint(targe_type): has_linker = False module_base = idc.GetFirstModule() while module_base != None: module_name = idc.GetModuleName(module_base) if module_name.find('linker') >= 0: has_linker = True break module_base = idc.GetNextModule(module_base) if has_linker == False: print '[*]unable to find linker module base' return module_size = idc.GetModuleSize(module_base) print '[*]found linker base=>0x%08X, Size=0x%08X' % (module_base, module_size) print("\t[-]begin to search DT_INIT") init_func_ea = 0 init_array_ea = 0 # bytecode=b'\x53\x1e\x73\xb5\x03\x33\x06\x46\x0d\x46\x14\x46\x24\xd8\x13\x48\x78\x44\x01\x68\x01\x29' bytecode = [ 0x14, 0x49, 0x04, 0x20, 0x23, 0x46, 0x14, 0x4A, 0x79, 0x44, 0x7A, 0x44 ] findcode = True for ea_offset in range(module_base, module_base + module_size): findcode = True for i in xrange(len(bytecode)): if idaapi.get_byte(ea_offset + i) != bytecode[i]: findcode = False break if (findcode == True): init_func_ea = ea_offset + 0x1A init_array_ea = ea_offset + 0x30 break if (findcode == False): print("can't find bytecode") return print "\t[-]found INIT=>0x%08X INIT_ARRAY=>0x%08X" % (init_func_ea, init_array_ea) print("\t[-]try set breakpoint there") if targe_type == 12: idc.AddBpt(init_func_ea) if targe_type == 25: idc.AddBpt(init_array_ea) print("[*]script finish")
def activate(self, ctx): t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t( ), idaapi.get_current_viewer() if idaapi.read_selection(view, t0, t1): start, end = t0.place(view).toea(), t1.place(view).toea() end += idaapi.get_item_size(end) else: start = idaapi.get_screen_ea() if start == idaapi.BADADDR: print('Easy Nop :: Screen EA == idaapi.BADADDR') return 0 end = start + idaapi.get_item_size(start) if start == idaapi.BADADDR: print('Easy Nop :: Selection EA == idaapi.BADADDR') return 0 if start == end: print('Easy Nop :: Nothing to nop') return 0 for x in range(start, end): # Maybe theres a smarter way to get the nop value for different archs e.g. Assemble('nop') -> 0x90 idaapi.patch_byte(x, 0x90) for x in range(start + 1, end): idaapi.hide_item(x) # Must do this else it bugs out on 2x 1 byte instructions being nopped idaapi.hide_item(start) idaapi.unhide_item(start) # Search for hidden nops and add to count while idaapi.get_byte(end) == 0x90 and idaapi.is_hidden_item( end) == True: end += 1 count = end - start if count > 1: idaapi.set_cmt(start, "truncated nops (%d)" % (count), False) print(end) print(start) return 1
def get_prev_ascii_string_address(address): """ :param address: must be current ascii string start address. :return: """ prev_string_start_address = address # string table interval should less than 5 bytes. if idc.Dword(address - 5) == 0: return None else: prev_string_start_address -= 5 # TODO: Need handle short string. while idaapi.get_byte(prev_string_start_address) != 0: prev_string_start_address -= 1 return prev_string_start_address + 1
def process_instruction(self, packet, addr): """Architecture specific instruction processing""" # Call the generic part with the architecture specific operand # handling # (instruction, i_mnemonic, operands, operand_strings, data) = self.process_instruction_generic(addr) if i_mnemonic is None: return None if idaapi.get_byte(addr) == 0xf0: prefix = 'lock ' else: prefix = '' packet.add_instruction(instruction, addr, prefix + i_mnemonic, operand_strings, operands, data) return instruction
def ev_ana_insn(self, insn): b1 = idaapi.get_byte(insn.ea) if b1 >= 0x70 and b1 <= 0x7F: d1 = idaapi.get_byte(insn.ea + 1) b2 = idaapi.get_byte(insn.ea + 2) d2 = idaapi.get_byte(insn.ea + 3) if b2 == b1 ^ 0x01 and d1 - 2 == d2: idaapi.put_byte(insn.ea, 0xEB) idaapi.put_word(insn.ea + 2, 0x9090) elif b1 == 0x0F: b1_1 = idaapi.get_byte(insn.ea + 1) d1 = idaapi.get_long(insn.ea + 2) b2 = idaapi.get_byte(insn.ea + 6) b2_1 = idaapi.get_byte(insn.ea + 7) d2 = idaapi.get_long(insn.ea + 8) if b2 == 0x0F and b1_1 ^ 0x01 == b2_1 and d1 - 6 == d2: idaapi.put_byte(insn.ea, 0xE9) idaapi.put_long(insn.ea + 1, d1 + 1) idaapi.put_byte(insn.ea + 5, 0x90) idaapi.put_word(insn.ea + 6, 0x9090) idaapi.put_long(insn.ea + 8, 0x90909090) return False
def selfmod_decoder(rip_address): if ((rip_address > 0x400935) and (rip_address <= 0x40103D)): idaapi.patch_byte(rip_address, idaapi.get_byte(rip_address) ^ (rip_address & 0xFF)) return
def repeating_key_xor(start_address, buffer_len, key): for i in xrange(buffer_len): c = idaapi.get_byte(start_address + i) ^ ord(key[(i % len(key))]) idaapi.patch_byte(start_address + i, c) return
import idaapi def derive_key(xs, ys): return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys)) def repeating_key_xor(start_address, buffer_len, key): for i in xrange(buffer_len): c = idaapi.get_byte(start_address + i) ^ ord(key[(i % len(key))]) idaapi.patch_byte(start_address + i, c) return def selfmod_decoder(rip_address): if ((rip_address > 0x400935) and (rip_address <= 0x40103D)): idaapi.patch_byte(rip_address, idaapi.get_byte(rip_address) ^ (rip_address & 0xFF)) return routine_1_address = 0x400E0E candidate_plaintext = [0x55, 0x48, 0x89, 0xE5] key1 = ''.join([chr(idaapi.get_byte(routine_1_address + i) ^ candidate_plaintext[i]) for i in xrange(len(candidate_plaintext))]) print "[+] Key1: [%s]" % key1 # Step 1 repeating_key_xor(routine_1_address, 0x9E, key1) # Step 2 routine_2_address = 0x400936 repeating_key_xor(routine_2_address, 0xEC, key1) # Step 3 to be applied manually (or as a per-instruction SIGTRAP hook)
def create_func_signature(start, length): """Return function signature in mega format.""" if length < MIN_SIG_LENGTH: return ea = start end = start + length sig = "" publics = [] refs = {} v = [False for _ in range(length)] while (ea - start < length): flags = idaapi.getFlags(ea) if idaapi.has_name(flags): publics.append(ea) ref = idaapi.get_first_dref_from(ea) if ref != idaapi.BADADDR: ref_loc = ea set_v_bytes(v, ref_loc - start) refs[ref_loc] = ref # Check if there is a second data location ref'd ref = idaapi.get_next_dref_from(ea, ref) if ref != idaapi.BADADDR: ref_loc = ea set_v_bytes(v, ref_loc - start) refs[ref_loc] = ref else: # Code ref? ref = idaapi.get_first_fcref_from(ea) if ref != idaapi.BADADDR: if not start <= ref < end: ref_loc = ea set_v_bytes(v, ref_loc - start) refs[ref_loc] = ref # Check for r13 and rtoc disasm = idaapi.generate_disasm_line(ea) if "%r13" in disasm or "%rtoc" in disasm: ref_loc = ea set_v_bytes(v, ref_loc - start) ea = idaapi.next_not_tail(ea) line = "" for i in range(length): if v[i]: line += ".." else: line += "{:02X}".format(idaapi.get_byte(start + i)) # Write publics found = False for public in sorted(publics): name = idaapi.get_true_name(idaapi.BADADDR, public) if name: found = True if is_skipped(name): idaapi.warning("Rename the function {} ({})!".format( name, "it is on the skip list")) return else: line += " :{:04X} {}".format(public - start, name) if not found: idaapi.warning("The function has autogenerated name, rename it first!") # Write refs for ref_loc, ref in sorted(refs.items()): name = idaapi.get_true_name(idaapi.BADADDR, ref) if name: if not is_skipped(name) and ref_loc != idaapi.BADADDR: line += " ^{:04X} {}".format(ref_loc - start, name) return line
else : print "Certs processing fail!" # TODO: Parse rights of the keys # TODO: Parse ASN1 from digests # Processing Images i = 0 while i < 4 : print "images type %s " % type (certppa.images) if certppa.images[i].image_offset != 0 : print "Found PPA image at %x offset " % certppa.images[i].image_offset if certisw.images[i].image_offset != 0 : print "Found ISW image at %x offset " % certisw.images[i].image_offset i += 1 # image start at certppa mark address + certppa.images[i].image_offset # Script body start = idc.MinEA() stop = idc.MaxEA() version_addr = idaapi.find_binary(start, stop, "43 65 72 74 49 53 57 00", 0, 0) + 0x79e # "CertISW" string version_minor = idaapi.get_byte(version_addr) version_major = idaapi.get_byte(version_addr + 1) print "MBM loader Major Version: %x " % version_major print "MBM loader Minor Version: %x " % version_minor parse_structures()
def process_instruction_generic(self, addr): """Architecture agnostic instruction parsing.""" # Retrieve the instruction mnemonic # i_mnemonic = self.get_mnemonic(addr) if not i_mnemonic: return None, None, None, None, None # Set the current location to the instruction to disassemble # #idaapi.jumpto(addr) #idaapi.ua_ana0(addr) # Up to IDA 5.7 it was called ua_code... if hasattr(idaapi, 'ua_code'): # Gergely told me of using ua_code() and idaapi.cvar.cmd # instead of jumpto() and get_current_instruction(). The latter # where always making IDA to reposition the cursor and refresh # the GUI, which was quite painful # idaapi.ua_code(addr) # Retrieve the current instruction's structure and # set its type ida_instruction = idaapi.cvar.cmd else: # now it's called decode_insn() idaapi.decode_insn(addr) # Retrieve the current instruction's structure and # set its type ida_instruction = idaapi.cmd instruction = Instruction( ida_instruction.itype, ida_instruction.size, ida_instruction.ip) self.current_instruction_type = instruction.itype # Try to process as many operands as IDA supports # # Up to IDA 5.7 it was called ua_code... so we use it to check for 5.7 if hasattr(idaapi, 'ua_code'): operands = self.operands_parser( addr, [( idaapi.get_instruction_operand(ida_instruction, idx), idx ) for idx in range(6)] ) else: operands = self.operands_parser( addr, [( ida_instruction.Operands[idx], idx ) for idx in range(6)] ) # Retrieve the operand strings # operand_strings = [ idc.GetOpnd(addr, idx) for idx in range(len(operands))] # Get the instruction data # data = ''.join( [chr(idaapi.get_byte(addr+i)) for i in range(idc.ItemSize(addr))]) # Return the mnemonic and the operand AST # return instruction, i_mnemonic, operands, operand_strings, data
for func_addr in idautils.Functions(0, 0xffffffff): # Signature is based on the beginning of the decryption function: # 53 push ebx # 8B DA mov ebx, edx # 56 push esi # 33 F6 xor esi, esi # 57 push edi # 8B F9 mov edi, ecx # 39 34 DD C4 DE 06+ cmp dword_1006DEC4[ebx*8], esi if idaapi.get_many_bytes(func_addr, 12) == "538BDA5633F6578BF93934DD".decode('hex'): decoding_func = idaapi.get_func(func_addr) break for addr in idautils.Heads(decoding_func.startEA, decoding_func.endEA): if chr(idaapi.get_byte(addr)) == "\x8A": # 8A 89 B0 D5 04 10 mov cl, key[ecx] # ^ key offset key_offset = struct.unpack("<I", idaapi.get_many_bytes(addr + 2, 4))[0] elif idaapi.get_many_bytes(addr, 1) == "\x6B": # 6B C2 33 imul eax, edx, 51 # ^ key length key_len = idaapi.get_byte(addr + 2) elif idaapi.get_many_bytes(addr, 3) == "\x8B\x04\xDD": # 8B 04 DD C0 DE 06 10 mov eax, packed_strings_list[ebx*8] # ^ address of string list struct_base = struct.unpack("<I", idaapi.get_many_bytes(addr + 3, 4))[0] print "[*] Decoding function : 0x{:08x}".format(int(decoding_func.startEA)) print "[*] Encoded string list base : 0x{:08x}".format(struct_base)
def decoder(self,from_loc,to_loc,key): self.GlobalCounter += 1 for loc in range(from_loc, to_loc+1): temp = idc.Byte(loc) ^ key idc.PatchByte(loc,temp) SetColor(loc, CIC_ITEM, 0x208020) next_inst = from_loc ready = False xor_check = False jmp_dword = False idc.MakeUnkn(from_loc,1) idc.MakeCode(from_loc) while next_inst <= to_loc: #idc.MakeCode(next_inst) idaapi.decode_insn(next_inst) inst = idc.GetDisasm(next_inst) print "inst %s next_inst %x" % (inst, next_inst) opndValue = idc.GetOperandValue(next_inst,1) if ready and xor_check and jmp_dword: self.flag.append(format(key,'x')) print '[{0:d}] decoder(0x{1:x},0x{2:x},0x{3:x})'.format(self.GlobalCounter,from_loc,to_loc,key) if self.GlobalCounter >= 10: print ''.join([chr(int(i,16)) for i in self.flag]).strip() return self.decoder(from_loc,to_loc,key) elif "xor" in inst: #key = hex(opndValue) #print idaapi.cmd.Operands[1].value xor_check = True key = idc.GetOperandValue(next_inst,1) print key elif "mov" in inst or format(idaapi.get_byte(next_inst),'x') == "BA": print idaapi.cmd.Operands[1].value to_loc = idaapi.cmd.Operands[1].value elif format(idaapi.get_byte(next_inst),'x') == "81" or "cmp" in inst: print idaapi.cmd.Operands[1].value from_loc = idaapi.cmd.Operands[1].value ready = True elif format(idaapi.get_byte(next_inst),'x') == "e9" or "jmp" in inst: print 'jmp_dword hitted' jmp_dword = True if idaapi.cmd.Operands[0].type == o_near and "dword" in GetOpnd(next_inst,0): offset = int(idaapi.tag_remove(idaapi.ua_outop2(next_inst, 0))[24:-1],16) address = GetOperandValue(next_inst,0) dword_adr = address - offset idc.MakeUnkn(dword_adr,DOUNK_SIMPLE) idc.MakeCode(address) next_inst = idc.NextHead(next_inst) #next_inst += idaapi.decode_insn(next_inst) print "out of loop"
def _addBytesToSig(self, sigIndex, ea, size): for i in range(0, size): b = idaapi.get_byte(ea + i) self.Sigs[sigIndex].sig.append('%02X' % b)
import idaapi from idaapi import Choose2 start_ea = 0x7C19 for ix in xrange(0xCF): print ix byte_to_decr = idaapi.get_byte(start_ea + ix) to_rotate = (0xCF - ix) % 8 byte_decr = (byte_to_decr >> to_rotate) | (byte_to_decr << (8 - to_rotate)) idaapi.patch_byte(start_ea + ix, byte_decr)
def get_byte(self, addr): return idaapi.get_byte(addr)
anim = sark.structure.get_struct('AnimationFrame') end_of_frame = sark.structure.get_struct("EndOfAnimFrame") play_sound = sark.structure.get_struct("PartialFuncPlaySound") func_with_count = sark.structure.get_struct("PartialFuncWithCount") partial_func_param1 = sark.structure.get_struct("PartialFuncParam1Func") set_image_width = sark.structure.get_struct("PartialFuncSetImageWidth") dataseg = sark.Segment(name='dataseg').ea # anim_offset = idaapi.get_word(sark.Line(ea=dataseg + idautils.cpu.di + 2).ea) current_position = sark.Line().ea # current_byte = idaapi.get_byte(current_position) done = False print("running") while not done: current_byte = idaapi.get_byte(current_position) if current_byte == 0xff: print("applying EndOfAnimFrame") idaapi.doStruct(current_position, 2, end_of_frame) next_byte = idaapi.get_byte(current_position + 1) if next_byte == 0xff: done = True current_position += 2 elif current_byte < 0x80: # print(current_byte) print("applying AnimationFrame") test = idaapi.doStruct(current_position, 6, anim) # print(test) current_position += 6 # print(hex(current_position-dataseg)) elif current_byte == 0x92:
def repeating_key_xor(start_address, buffer_len, key): for i in xrange(buffer_len): c = idaapi.get_byte(start_address + i) ^ ord(key[(i % len(key))]) idaapi.patch_byte(start_address + i, c) return def selfmod_decoder(rip_address): if ((rip_address > 0x400935) and (rip_address <= 0x40103D)): idaapi.patch_byte(rip_address, idaapi.get_byte(rip_address) ^ (rip_address & 0xFF)) return routine_1_address = 0x400E0E candidate_plaintext = [0x55, 0x48, 0x89, 0xE5] key1 = ''.join([ chr(idaapi.get_byte(routine_1_address + i) ^ candidate_plaintext[i]) for i in xrange(len(candidate_plaintext)) ]) print "[+] Key1: [%s]" % key1 # Step 1 repeating_key_xor(routine_1_address, 0x9E, key1) # Step 2 routine_2_address = 0x400936 repeating_key_xor(routine_2_address, 0xEC, key1) # Step 3 to be applied manually (or as a per-instruction SIGTRAP hook)