JEB2 script 中调用 api 重命名所有派生类 V2.0

# -*- 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





class JEB2_AutoRenameDerivedClass_V2(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快捷键的功能是运行最近使用的脚本)'

    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()

    if not self.activeItem:
      print(errMsg1)
      return

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

    self.focusUnit2 = RuntimeProjectUtil.findUnitsByType(self.prj, ICodeUnit, False)[0]


    actCntx = ActionContext(self.focusUnit, Actions.QUERY_TYPE_HIER, self.activeItem.getItemId(), self.activeAddress)
    actData = ActionTypeHierarchyData()

    # 获取所有派生自该类的清单,然后逐个重命名
    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:
          cNode = actData.getBaseNode().getChildren()[0]
          if(cNode):
            print(u'派生类如下:')
            childs = cNode.getChildren()
            #print(childs)
            for n in childs:
              #print(n)
              self.nTotal += 1
              if(self.RenameClass(self.focusUnit2, n)):
                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 RenameClass(self, unit, codeNode):
    codeItem = codeNode.getObject()
    codeClass = codeItem.getImplementingClass()
    if(not codeClass):
      print(u'正在跳过 %s' % (codeItem.getAddress()))
      return False

    #print(u'正在处理 %s' % codeItem.getAddress())
    decomp = DecompilerHelper.getDecompiler(unit)
    if not decomp:
      print('There is no decompiler available for code unit %s' % unit)
      return False
    tmpUnit = decomp.decompile(codeItem.getAddress())
    #print(tmpUnit)
    doc = self.getTextDocument(tmpUnit)
    #text = self.formatTextDocument(doc)
    #print(text)

    # 从反编译得到的 Java 源文件中逐行查找 log
    pattern = re.compile('\.NetScene([^";]+)', re.I)
    lines = doc.getDocumentPart(0, 10000000).getLines()
    m = []
    for l in lines:
      #print('%s' % l.getText().toString())
      line = l.getText().toString()
      matches = pattern.findall(line)
      for match in matches:
        #print('%s\t\t\t%s' % (match, line))
        #print(line)
        if(match == 'Base'):
          continue
        m.append(match)

    # 统计词频
    if(len(m) < 1):
      print(u'正在跳过 %s' % (codeItem.getAddress()))
      return False
    
    a=collections.Counter(m)
    b=a.most_common(10)
    l = list(b);
    #print(l)

    msg = ''
    i = 0
    for s in l:
      msg = msg + 'index:' + str(i) + '\ttimes:' + str(s[1])+ '\t' + s[0] + '\n'
      i += 1

    sel = 0;
    #print(msg)

##    value = self.ctx.displayQuestionBox('sel', msg + '\n\n', str(sel))
##    if value != None:
##      sel = int(value)

    baseStr = l[sel][0]
    newClassName = "NetScene" + baseStr
    print(u'正在处理 %s\t=:>%s' % (codeItem.getAddress(), newClassName))

    # 重命名类
    actCntx = ActionContext(unit, Actions.RENAME, codeClass.getItemId(), codeClass.getAddress())
    actData = ActionRenameData()
    actData.setNewName(newClassName)

    if(unit.prepareExecution(actCntx, actData)):
      # 执行重命名动作
      try:
        bRlt = unit.executeAction(actCntx, actData)
        if(not bRlt):
          print(u'executeAction fail!')
          return False
        else:
          return True
      except Exception,e:
        print Exception,":",e
    
  ## end of RenameClass




  # 获取指定基类的所有派生类
  def GetTypeHierarchy(self, unit, c):
    #print(u'class name:%s\t\t\told name:%s\n' % (cname, oname))
    print(c)

    cType = c.getClassType()
    #print('getName:%s\tgetSignature:%s\tgetAddress:%s\tgetItemId:%d\tgetIndex:%d' % (cType.getName(True), cType.getSignature(True), cType.getAddress(), cType.getItemId(), cType.getIndex()))
    #print(cType)

    # 获取基类 c 的型层次树
    actCntx = ActionContext(unit, Actions.QUERY_TYPE_HIER, c.getItemId(), c.getAddress())
    actData = ActionTypeHierarchyData()

    if(unit.prepareExecution(actCntx, actData)):
      bNode = actData.getBaseNode()
      if(bNode):
        cNode = bNode.findNodeByObject(cType)
        if(cNode):
          print(u'派生类如下:')
          childs = cNode.getChildren()
          #print(childs)
          for n in childs:
            print(n)
            #self.processSubClass(unit, n)
            if(self.debug):
              break
  ## end of GetTypeHierarchy



  def getHierarchyFragment(self, ctx):
    views = ctx.getViews()
    for view in views:
      viewLabel = view.getLabel()
      #print('- view:%s' % view.getLabel())
      fragments = view.getFragments()
      for fragment in fragments:
        fragmentLabel = view.getFragmentLabel(fragment)
        #print(fragmentLabel)
        if(fragmentLabel == 'Hierarchy' ):
          return fragment;
    return None
  ## end of formatTextDocument



  def getTextDocument(self, srcUnit):
    formatter = srcUnit.getFormatter()
    if formatter and formatter.getDocumentPresentations():
      doc = formatter.getDocumentPresentations()[0].getDocument()
      if isinstance(doc, ITextDocument):
        return doc
    return None
  ## end of getTextDocument


  def formatTextDocument(self, doc):
    s = ''
    # retrieve the entire document -it's a source file,
    # no need to buffer individual parts. 10 MLoC is enough 
    alldoc = doc.getDocumentPart(0, 10000000)
    for line in alldoc.getLines():
      s += line.getText().toString() + '\n'
    return s
  ## end of formatTextDocument


            
  ## targetUnit.notifyListeners(JebEvent(J.UnitChange))


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值