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

注:本例中的基类 NetSceneBase,是人工分析得出来的 "假定类名"


# -*- 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 JEB2AutoRenameByStringResource(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 = False
    self.ctx = ctx
    prj = projects[0]



##    unit = ctx.getFocusedView().getActiveFragment().getUnit() # Get current Source Tab in Focus
##    print(unit)
##    print('\n')
##    stringlist = unit.getStrings()
##    for str in stringlist:
##      print(str.getValue())
##      print('\n')
##    #print(stringlist)
##    print('\n')
##    return
##    c = unit.getClassElement()  # needs >V2.1.4
##    print(c)
##    print('\n')
##    self.GetTypeHierarchy(unit, c)
##    return


##    self.codeUnit = RuntimeProjectUtil.findUnitsByType(prj, IDexUnit, False)
##    #print(self.codeUnit)
##    for unit in self.codeUnit:
##        classes = unit.getClasses()
##        for c in classes:
##          cname = c.getName(True)
##          oname = c.getName(False)
##
##          # 定位到指定的基类
##          #if cname.find('NetSceneBase') >= 0:
##          if(cname == 'NetSceneBase'):
##            self.GetTypeHierarchy(unit, c)
##            break;  # break of for c in classes:


    self.codeUnit = RuntimeProjectUtil.findUnitsByType(prj, ICodeUnit, False)
    #print(self.codeUnit)
    for unit in self.codeUnit:
        classes = unit.getClasses()
        for c in classes:
          cname = c.getName(True)
          oname = c.getName(False)

          # 定位到指定的基类
          #if cname.find('NetSceneBase') >= 0:
          if(cname == 'NetSceneBase'):
            self.GetTypeHierarchy(unit, c)
            break;  # break of for c in classes:
    print('Done.')
  ## end of run



  # 获取指定基类的所有派生类,并逐个传给processSubClass() 进行重命名操作
  # 重命名规则:在类源码查找 NetScene**** 这样的字符串,以此做为新类名
  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 processSubClass(self, unit, codeNode):
    codeItem = codeNode.getObject()
    codeClass = codeItem.getImplementingClass()
    if(not codeClass):
      print(u'正在跳过 %s' % (codeItem.getAddress()))
      return
      
    #print(u'正在处理 %s' % codeItem.getAddress())
    decomp = DecompilerHelper.getDecompiler(unit)
    if not decomp:
      print('There is no decompiler available for code unit %s' % unit)
      return
    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
    
    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!')
      except Exception,e:
        print Exception,":",e
    
  ## end of processSubClass




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




JEB2.2.5 中国版





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值