arm idapython脚本

ida在调试android-arm app时不能解析调用栈,自己实现了一个简单的arm回溯栈 ida插件,会在实战中不断增强


#PUSH {LR}
#PUSH {R3,LR}
#PUSH {R4-R7,LR}
#PUSH {R0,R1,R4-R6,LR}
#STMFD   SP!, {R3,LR}
#STMFD  SP!, {R0-R7, LR}
#STMFD   SP!, {R11,LR}
#
#SP=BEBBDBC0  BEBBDBD8 00000000
#R3=00000000
#LR=4003B0CD
#
#SP=BEBBDBB8  00000000 4003B0CD


# CallStack trace for arm x86


Rarr = ["R0","R1","R2","R3","R4","R5","R6","R7","R8","R9","R10","R11","R12"]
 
def __validate(addr):
 instr = GetDisasm(addr -1)
 if instr.find("BL") != -1:
  return True
 return False


def __getregnum(str):
 pos1 = str.find("{")
 pos2 = str.find("}")
 num = 1
 if pos1 != -1 and pos2 != -1:
  str = str[pos1+1:pos2]
  for i in str.split(','):
   if i.find("LR") != -1:
    num = num
   elif i.find("-") != -1:
    twoR = i.split("-")
    first = 0
    second = 0
    for j in range(0, Rarr.__len__()):
     index = Rarr.__len__() - j - 1
     if twoR[0].find(Rarr[index]) != -1:
      first = index
      break
    for j in range(0, Rarr.__len__()):
     index = Rarr.__len__() - j - 1
     if twoR[1].find(Rarr[index]) != -1:
      second = index
      break
    num = num + second - first + 1
   else:
    num = num + 1
  return num
 else:
  return 0


def __getsubnum(str):
 pos1 = str.find("#")
  
   
if __name__ == "__main__":
 curaddr = GetRegValue("PC")
 cursp = GetRegValue("SP")
 lastaddr = GetRegValue("LR") - 1


 # print first layer call stack
 print "%08x:%s"%(curaddr, GetFuncOffset(curaddr))


 # validate and print second layer call stack
 if -1 == GetFunctionAttr(lastaddr, FUNCATTR_START):
  AnalyzeArea(addr - 0x1000, addr)
 if __validate(lastaddr):
  print "%08x:%s"%(lastaddr, GetFuncOffset(lastaddr))
 else:
  print "error"
 
	# restore sp
 funcstart = GetFunctionAttr(curaddr, FUNCATTR_START)
 bingo = ""
 offset = 0
 if funcstart != -1:
  for i in range(funcstart, curaddr):
   instr = GetDisasm(i)
   if instr.find("LR") != -1 and (instr.find("PUSH") != -1 or instr.find("STMFD") != -1):
    offset = offset + __getregnum(instr) * 4
    break
  for i in range(funcstart, curaddr):
   instr = GetDisasm(i)
   if instr.find("SUB") != -1 and instr.find("SP") != -1:
    offset = offset + __getsubnum(instr)
 cursp = cursp + offset
	
 for layer in range(0,9):
  # get the function lastaddr belongs to
  funcstart = GetFunctionAttr(lastaddr, FUNCATTR_START)
  bingo = ""
  offset = 0
  if funcstart != -1:
   for i in range(funcstart, lastaddr):
    instr = GetDisasm(i)
    if instr.find("LR") != -1 and (instr.find("PUSH") != -1 or instr.find("STMFD") != -1):
     offset = offset + __getregnum(instr) * 4
     break
   for i in range(funcstart, lastaddr):
    instr = GetDisasm(i)
    if instr.find("SUB") != -1 and instr.find("SP") != -1:
     offset = offset + __getsubnum(instr)
  cursp = cursp + offset
 		
  lastLR = Dword(cursp - 4)
  lastaddr = lastLR - 1
  if __validate(lastaddr):
   print "%08x:%s"%(lastaddr, GetFuncOffset(lastaddr))
  else:
   print "error"
 #get the "sub sp" instruction
 
 
#1:PC   GetFuncOffset(curaddr)
#2:LR   GetFuncOffset(lastaddr)
#3:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值