import keystone
from keystone import *
import ida_bytes
import idaapi
import idc
# 来自叶谷雨的代码
def binSearch(start, end, pattern):
matches = []
addr = start
if end == 0:
end = idc.BADADDR
if end != idc.BADADDR:
end = end + 1
while True:
addr = ida_bytes.bin_search(addr, end, bytes.fromhex(pattern), None, idaapi.BIN_SEARCH_FORWARD,
idaapi.BIN_SEARCH_NOCASE)
if addr == idc.BADADDR:
break
else:
matches.append(addr)
addr = addr + 1
return matches
def getJumpAddress(addr):
A = idc.get_operand_value(addr + 8, 1)
B = idc.get_operand_value(addr + 12, 2)
C = idc.get_operand_value(addr + 20, 2)
return A - B + C
def makeInsn(addr):
if idc.create_insn(addr) == 0:
idc.del_items(addr, idc.DELIT_EXPAND)
idc.create_insn(addr)
idc.auto_wait()
def generate(code, addr):
ks = Ks(keystone.KS_ARCH_ARM64, keystone.KS_MODE_LITTLE_ENDIAN)
# 参数2是地址,很多指令是地址相关的,比如 B 指令,如果地址无关直接传 0 即可,比如 nop。
encoding, _ = ks.asm(code, addr)
return encoding
matches = binSearch(0, 0, "E0 07 BE A9 E2 7B 01 A9")
for addr in matches:
makeInsn(addr)
targetAddr = getJumpAddress(addr)
code = "B {}".format(hex(targetAddr))
bCode = generate(code, addr)
nopCode = generate("nop", 0)
ida_bytes.patch_bytes(addr, bytes(bCode))
ida_bytes.patch_bytes(addr + 4, bytes(nopCode) * 9)