这是一个粗略的实现,它扫描此模式的当前聚焦功能:
call $+5
pop <reg>
op <reg>, imm32
并将其更改为
mov <reg>, <computed imm32>
nop
nop
调整它以扫描不同范围并支持更多指令作为练习留给读者。
def simplify(tgtEA):
  ins1 = tgtEA
  if not idc.isHead(idc.GetFlags(ins1)):
    ins1 = idaapi.prev_head(ins1, limits.startEA)
  ins2 = idaapi.next_head(ins1, limits.endEA)
  if ins2 == 0xFFFFFFFF:
    return False
  ins3 = idaapi.next_head(ins2, limits.endEA)
  if ins3 == 0xFFFFFFFF:
    return False
  print "Scanning instructions at %d, %d, %d" % (ins1, ins2, ins3)
  result = ins2
  matched = False
  reg = 0
  if idc.GetMnem(ins1) == "call":
    if idc.GetOpnd(ins1, 0) == "$+5":
      if idc.GetMnem(ins2) == "pop":
        if idc.GetOpType(ins3, 0) == 1:
          reg = GetOperandValue(ins2, 0)
          if idc.GetOperandValue(ins3, 0) == reg:
            op = idc.GetMnem(ins3)
            optype = idc.GetOpType(ins3, 1)
            if op == "inc":
              matched = True
              result = result + 1
            elif op == "dec":
              matched = True
              result = result - 1
            elif op == "add":
              if optype == 5:
                # optype 5 = immediate
                matched = True
                offset = idc.GetOperandValue(ins3, 1)
                result = result + offset
  if matched:
    # patch the bytes by hand - there's no nice API to assemble("foo bar")?
    # MOV r32, imm32 = 0xB8 /rd 
    # reg is the register number acquired from IDA operand value
    # IDA uses the same register numbering as Intel
    regbyte = 0xB8 + reg;
    idaapi.patch_byte(ins1, regbyte)
    idaapi.patch_long(ins1 + 1, result)
    idaapi.patch_word(ins1 + 5, 0x9090) # NOP NOP 
    return True
  return False
# ----
curEA = ScreenEA()
tgtEA = idaapi.askaddr(curEA, "Enter target address")
#tgtEA = curEA
if tgtEA is None:
  exit
f = idaapi.get_func(tgtEA)
if not f:
  print "No function at 0x%x" % (tgtEA)
  exit
limits = idaapi.area_t()
if not idaapi.get_func_limits(f, limits):
  print "No limits in this function?!"
  exit
print "Scanning function from %x to %x" % (limits.startEA, limits.endEA)
itEA = limits.startEA
while itEA < limits.endEA:
  if simplify(itEA):
    itEA = idaapi.next_head(itEA + 7, limits.endEA)
  else:
    itEA = idaapi.next_head(itEA, limits.endEA)