JEB2 script 中調用 api 重命名所有關聯函數

先將光標輸入點放到源碼文件中的函數名稱處~然後使用F2快捷鍵運行此腳本(JEB 中 F2快捷鍵的功能是運行最近使用的腳本)


因爲此腳本會取光標處的函數,然後查找與其具有相同同重載源的所有函數。。。


PS: JEB2 的腳本,讓人寫得真是費勁。。。





# -*- coding: utf-8 -*-

"""
Sample client script for PNF Software's JEB2.

More samples are available on our website and within the scripts/ folder.

Refer to SCRIPTS.TXT for more information.
"""

import string
import re,collections
from com.pnfsoftware.jeb.client.api import IScript
from com.pnfsoftware.jeb.client.api import IScript, IGraphicalClientContext
from com.pnfsoftware.jeb.core import RuntimeProjectUtil
from com.pnfsoftware.jeb.core.actions import Actions, ActionContext, ActionXrefsData
from com.pnfsoftware.jeb.core.events import JebEvent, J
from com.pnfsoftware.jeb.core.output import AbstractUnitRepresentation, UnitRepresentationAdapter
from com.pnfsoftware.jeb.core.units.code import ICodeUnit, ICodeItem
from com.pnfsoftware.jeb.core.units.code.java import IJavaSourceUnit, IJavaStaticField, IJavaNewArray, IJavaConstant, IJavaCall, IJavaField, IJavaMethod, IJavaClass
from com.pnfsoftware.jeb.core.actions import ActionTypeHierarchyData
from com.pnfsoftware.jeb.core.actions import ActionRenameData
from com.pnfsoftware.jeb.core.util import DecompilerHelper
from com.pnfsoftware.jeb.core.output.text import ITextDocument
from com.pnfsoftware.jeb.core.units.code.android import IDexUnit
from com.pnfsoftware.jeb.core.actions import ActionOverridesData
from com.pnfsoftware.jeb.core.units import UnitUtil
from com.pnfsoftware.jeb.core.units import UnitAddress






class JEB2_AutoRenameOverrideMethod(IScript):
  def run(self, ctx):
    engctx = ctx.getEnginesContext()
    if not engctx:
      print('Back-end engines not initialized')
      return

    projects = engctx.getProjects()
    if not projects:
      print('There is no opened project')
      return

    # 邏輯開始
    self.debug = 0    #0=False, 1=True
    self.ctx = ctx
    self.prj = projects[0]
    errMsg1 = u'請移動鼠標,將光標輸入點放到源碼文件中的函數名稱處~然後使用F2快捷鍵運行此腳本(JEB 中 F2快捷鍵的功能是運行最近使用的腳本)'
    errMsg2 = u'未輸入新函數名稱,腳本已退出'

    self.focusView = ctx.getFocusedView()
    if not self.focusView:
      print(errMsg1)
      return

    self.focusFragment = self.focusView.getActiveFragment()
    if not self.focusFragment:
      print(errMsg1)
      return

    self.focusUnit = self.focusFragment.getUnit()
    if not self.focusUnit:
      print(errMsg1)
      return

    self.activeAddress = self.focusFragment.getActiveAddress()
    self.activeItem = self.focusFragment.getActiveItem()

    itemStr = self.activeItem.toString()
    if(itemStr.find('cid=METHOD_NAME') < 0):
      print(errMsg1)
      return

    self.focusUnit2 = RuntimeProjectUtil.findUnitsByType(self.prj, ICodeUnit, False)[0]
##    print(self.focusUnit)
##    print(self.focusUnit2)
##    return

    # 彈出輸入框用以輸入新函數名
    newMethodName = self.ctx.displayQuestionBox('input new function name', 'input new function name\n\n', '')
    if newMethodName == None:
      print(errMsg2)
      return

    actCntx = ActionContext(self.focusUnit, Actions.QUERY_OVERRIDES, self.activeItem.getItemId(), self.activeAddress)
    actData = ActionOverridesData()

    # 獲取所有重載了此方法的函數清單,然後逐個重命名
    self.nTotal = 0
    self.nSucc = 0
    self.nFail = 0
    if(self.focusUnit.prepareExecution(actCntx, actData)):
      try:
        bRlt = self.focusUnit.executeAction(actCntx, actData)
        if(not bRlt):
          print('executeAction fail!')
        else:
          overrideAddrList = actData.getAddresses()
          self.nTotal = len(overrideAddrList)
          for addr in overrideAddrList:
            #print('renaming %s' % addr)
            if(self.RenameMeghod(addr, newMethodName)):
              self.nSucc += 1
            else:
              self.nFail += 1
            if(self.debug):
              break;
      except Exception,e:
        print Exception,":",e

    print('total:%d succ:%d fail:%d' %(self.nTotal, self.nSucc, self.nFail))
    print('Done.')
  ## end of run




  # 對指定函數進行重命名
  def RenameMeghod(self, methodAddr, newMethodName):
    m = self.GetMethodByAddress(methodAddr)
    if(not m):
      print(u'失敗 %s' % methodAddr)
      return False

    actCntx = ActionContext(self.focusUnit, Actions.RENAME, m.getItemId(), methodAddr)
    actData = ActionRenameData()
    actData.setNewName(newMethodName)

    if(self.focusUnit.prepareExecution(actCntx, actData)):
      # 執行重命名動作
      try:
        bRlt = self.focusUnit.executeAction(actCntx, actData)
        if(not bRlt):
          print(u'失敗 %s' % methodAddr)
        else:
          print('%s => %s' %(methodAddr, newMethodName))
          return True
      except Exception,e:
        print Exception,":",e
    return False
  ## end of RenameMeghod



  def GetUnitByAddress(self, addr):
    decomp = DecompilerHelper.getDecompiler(self.focusUnit2)
    if not decomp:
      print('There is no decompiler available for code unit %s' % self.focusUnit2)
      return

    tmpUnit = decomp.decompile(addr)
    self.ctx.openView(tmpUnit)
    if(self.ctx.getFocusedView().getActiveFragment().setActiveAddress(methodAddr)):
      print('setActiveAddress succ')
    return tmpUnit
  ## end of GetUnitByAddress


  def GetMethodByAddress(self, addr):
    found = 0
    self.codeUnit = RuntimeProjectUtil.findUnitsByType(self.prj, ICodeUnit, False)
    if(not self.codeUnit):
      return None
    for unit in self.codeUnit:
        classes = unit.getClasses()
        if(not classes):
          continue
        for c in classes:
          cAddr = c.getAddress()
          if(not cAddr):
            continue
          if(addr.find(cAddr) == 0):
            mlist = c.getMethods()
            if(not mlist):
              continue
            for m in mlist:
              mAddr = m.getAddress()
              if(addr == mAddr):
                #print(mAddr)
                return m
    return None

  ## end of GetMethodByAddress



就這,半玩半寫的花了一整天,哈哈~~~


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章