idapython初探

# PREFACE:确实不熟,但是确实该学学一些自动化东西,反正萌新么记录一下
# 11.12:发现这个 https://bbs.kanxue.com/thread-225920.htm
  • 批量获取函数 Xref
"""
arg: addr : hex
ret: XrefList : list
"""
def XrefList(addr):
    x_list = []
    for x_addr in XrefsTo(addr, flags=0):
        x_list.append(hex(addr.frm))
    return x_list
  • 返回函数参数(todo,有点难度的)
n
import ida_bytes
import ida_idp
import ida_search
import ida_ua
import idc
def find_function_arg(addr):
    while True:
        # 使用 idc.prev_head 而不是 ida_bytes.prev_head
        addr = idc.prev_head(addr, ida_ida.cvar.inf.min_ea)
        # 使用 idc.get_mnem 而不是 GetMnem
        if idc.get_mnem(addr) == "mov" and "esi" in idc.get_operand_value(addr, 0):
            # 使用 idc.get_operand_value 而不是 GetOperandValue
            print("We found it at 0x%x" % idc.get_operand_value(addr, 1))
            break
# 替换为你的目标地址
find_function_arg(0x5D2966)
  • 从地址返回指令
"""
arg: addr : hex
ret: [addr, mnemonic, op_str]
"""
def get_asm_from_addr(addr):
    md = Cs(CS_ARCH_X86, CS_MODE_32)
    # 创建一个 insn_t 对象来存储解码的指令
    insn = ida_ua.insn_t()
    ida_ua.decode_insn(insn, addr)
    insn_bytes = ida_bytes.get_bytes(addr, insn.size)
    # 打印指令的助记符和操作数
    x = []
    for i in md.disasm(insn_bytes, addr):
        x.append(hex(i.address))
        x.append(i.mnemonic)
        x.append(i.op_str)
    return x
  • 找到特定的十六进制(全段查找)
"""
arg: hex_of_pattern : str
ret: void
"""
def find_pattern(bytes_to_find): # 例如 "FF E0"
    for seg_ea in idautils.Segments():
        seg_end = idc.get_segm_end(seg_ea)
        ea = seg_ea
        while (ea <= seg_end):
            ea = idaapi.find_binary(ea, seg_end, bytes_to_find, 16, idaapi.SEARCH_DOWN)
            if ea != idaapi.BADADDR:
                # 这里填写需要的处理逻辑,ea 即找到的地址
                print(hex(ea))
            ea = idc.next_head(ea)
  • 查找特定的汇编地址(全段查找)
"""
arg: assembly_code : str
ret: void
"""
from keystone import *
def find_pattern(assembly_code):
    ks = Ks(KS_ARCH_X86, KS_MODE_64)
    new_bytes , _= ks.asm(assembly_code)
    new_bytes = [hex(new_bytes[i])[2:] for i in range(0, len(new_bytes), 1)]
    new_bytes = ' '.join(new_bytes)
    for seg_ea in idautils.Segments():
        seg_end = idc.get_segm_end(seg_ea)
        ea = seg_ea
        while (ea <= seg_end):
            ea = idaapi.find_binary(ea, seg_end, new_bytes , 16, idaapi.SEARCH_DOWN)
            if ea != idaapi.BADADDR:
                # 这里填写需要的处理逻辑,ea 即找到的地址
                print(hex(ea))
            ea = idc.next_head(ea)
  • 查找某条地址的上一条汇编地址信息
"""
arg: addr : str
ret: addr : hex
	, len_of_opcode : int
"""
def find_prev_addr(addr):
	prev_inst_addr = ida_bytes.prev_head(address, ida_ida.cvar.inf.min_ea)
    prev_inst_size = ida_bytes.get_item_size(prev_inst_addr)
    return prev_inst_addr, prev_inst_size
  • patch 脚本
"""
arg: addr : str
	 assembly_code : str
ret: void
"""
def patch_addr(addr, assembly_code)
	new_bytes , _= ks.asm(assembly_code)
	new_bytes = [(new_bytes[i]) for i in range(0, len(new_bytes), 1)]
	for i in range(prev_inst_addr, prev_inst_addr + len(new_bytes), 1):
        patch_byte(i, new_bytes[j])
        j += 1
  • 批量 hook
class MyDbgHook(idaapi.DBG_Hooks):
    def dbg_bpt(self, tid, ea):
        if ea in addresses_to_hook:
            # 设置处理逻辑
            rax_value = ida_dbg.get_reg_val("RAX")
            print("Breakpoint at 0x%X, RAX = 0x%X" % (ea, rax_value))
            ida_dbg.continue_process()
        return 0
# 实例化并注册我们的调试器 hook
debug_hook = MyDbgHook()
debug_hook.hook()
# 为列表中的每个地址设置断点
for address in addresses_to_hook:
    idc.add_bpt(address, 0, idc.BPT_SOFT)
# 启动或继续调试过程
ida_dbg.run_requests()