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,有点难度的)
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() |