def Test(ctx):
    assert isinstance(ctx, IClientContext)
    input_path = r"D:\tmp\2\project\about_dex_diff\code\jsq\jsq.dex"
    class_sign = "Lcom/BestCalculatorCN/MyCalculator;"
    method_sign = "Lcom/BestCalculatorCN/MyCalculator;->b(Lcom/BestCalculatorCN/MyCalculator;Ljava/lang/String;)V"
    unit = ctx.open(input_path)
    assert isinstance(unit, IUnit)
    prj = ctx.getMainProject()
    assert isinstance(prj, IRuntimeProject)
    dexUnit = prj.findUnit(IDexUnit)
    assert isinstance(dexUnit, IDexUnit)
    clz = dexUnit.getClass(class_sign)
    assert isinstance(clz, IDexClass)
    method = dexUnit.getMethod(method_sign)
    assert isinstance(method, IDexMethod)

    # 1 查询某method交叉引用列表
    # 使用(unit,操作,地址,itemid)来创建一个context对象,提供给JEB引擎,用于后续执行
    print "------------------------------------------------"
    actionXrefsData = ActionXrefsData()
    actionContext = ActionContext(dexUnit, Actions.QUERY_XREFS,
                                  method.getItemId(), None)
    if unit.prepareExecution(actionContext, actionXrefsData):
        for xref_addr in actionXrefsData.getAddresses():
            print xref_addr

    # 2 查询整个class的交叉引用列表
    print "------------------------------------------------"
    actionXrefsData = ActionXrefsData()
    actionContext = ActionContext(dexUnit, Actions.QUERY_XREFS,
                                  clz.getItemId(), None)
    if unit.prepareExecution(actionContext, actionXrefsData):
        for idx, xref_addr in enumerate(actionXrefsData.getAddresses()):
            print idx, xref_addr
 def getMethodXrefs(self, unit, itemId):
     data = ActionXrefsData()
     # careful, with query-type actions, the data is returned after the action prep'
     if unit.prepareExecution(
             ActionContext(unit, Actions.QUERY_XREFS, itemId, None), data):
         # clean up the DEX address, extrac the method name
         return data.getAddresses()
Beispiel #3
0
    def append_cls_name(self, cls, append_str):
        p = re.compile("^.*\/([\w$-]+);$")
        # cls_name has package path
        cls_name = cls.getSignature(True)
        if cls_name.find(append_str) == -1:
            s = re.search(p, cls_name)
            if not s:
                return False

            simple_new_name = s.group(1) + '_' + append_str

            actCntx = ActionContext(self.dex, Actions.RENAME, cls.getItemId(),
                                    cls.getAddress())
            actData = ActionRenameData()
            actData.setNewName(simple_new_name)

            if self.dex.prepareExecution(actCntx, actData):
                try:
                    bRlt = self.dex.executeAction(actCntx, actData)
                    if (not bRlt):
                        print(u'executeAction fail!')
                        return False

                    else:
                        return True

                except Exception, e:
                    return self.jeb.renameClass(cls_name, simple_new_name)
            else:
                return False
Beispiel #4
0
def xrefs_for(unit, item):
    data = ActionXrefsData()
    if unit.prepareExecution(
            ActionContext(unit, Actions.QUERY_XREFS, item.itemId,
                          item.address), data):
        return data.addresses

    return []
 def setOrStoreDecryptedStr(self, unit, itemId, comment, key):
   data = ActionXrefsData()
   if unit.prepareExecution(ActionContext(unit, Actions.QUERY_XREFS, itemId, None), data):
     if data.getAddresses().size() > 1: # If the variable is called by other class(main target class)
       self.dic[key] = comment # Store the key value pair into the dictionary
     else:
       self.addComments(self.codeUnit, itemId, comment) # If the variable is not called by other class(main target class), add the decrypted string as comment directly
       return "NULL"
Beispiel #6
0
def get_xrefs_by_item(dunit, itemid, addr):
    data = ActionXrefsData()
    result = []
    if dunit.prepareExecution(ActionContext(dunit, Actions.QUERY_XREFS, itemid, addr), data): # item.getSignature()
        for xref_addr in data.getAddresses():
            # print(xref_addr)
            result.append(xref_addr)

    return result
Beispiel #7
0
 def findClassXRef(self, units, itemId, itemAddress):
     refs = []
     for unit in units:
         data = ActionXrefsData()
         if unit.prepareExecution(
                 ActionContext(unit, Actions.QUERY_XREFS, itemId,
                               itemAddress), data):
             if len(data.getAddresses()) > 0:
                 refs.append((unit, data.getAddresses()))
     return refs
 def addComments(self, unit, itemId, comment):
   data = ActionCommentData() # Create a new instance of ActionCommentData
   data.setNewComment(comment) # Add the decrypted string as comment to data
   address = unit.getAddressOfItem(itemId)
   # Set the comment
   ctx = ActionContext(unit, Actions.COMMENT, itemId, address)
   if unit.prepareExecution(ctx, data):
     r = unit.executeAction(ctx, data)
     if not r:
       print('Cannot set comment at address %s' % address)
Beispiel #9
0
 def searchOveride(self,dId, dAddr):
     actCntx = ActionContext(self.targetUnit, Actions.QUERY_OVERRIDES, dId, dAddr)
     actData = ActionOverridesData()
     if(self.targetUnit.prepareExecution(actCntx, actData)):
         try:
             bRlt = self.targetUnit.executeAction(actCntx, actData)
             if(not bRlt):
                 print('executeAction fail!')
         except Exception, e:
             print Exception, ":", e
             return []
Beispiel #10
0
    def findMethodXRef(self, units, itemId, itemAddress, refs):
        preNode = refs.getCurrentNode()
        refs.setCurrentNodeById(itemId)
        sub_address = []
        total = 0
        for unit in units:
            data = ActionXrefsData()
            if unit.prepareExecution(
                    ActionContext(unit, Actions.QUERY_XREFS, itemId,
                                  itemAddress), data):
                if len(data.getAddresses()) > 0:
                    sub_address.append((unit, data.getAddresses()))
                    total += len(data.getAddresses())
                else:
                    row_m = unit.getMethod(itemAddress)
                    impl_class = row_m.getClassType().getImplementingClass()
                    if re.search(r'(\$\d+?)+;$',
                                 impl_class.getAddress()) != None:
                        # sub_address.append((unit, impl_class.getAddress()))
                        clxXref = self.findClassXRef(units,
                                                     impl_class.getItemId(),
                                                     impl_class.getAddress())
                        sub_address.extend(clxXref)
                        for (unit, addresses) in clxXref:
                            total += len(addresses)

        refs.getCurrentNode().setXrefCount(total)
        for (unit, addresses) in sub_address:
            for xref_addr in addresses:
                indexObj = re.search(r'\+[0-9A-F]+?h$', xref_addr)
                if indexObj != None:
                    index = indexObj.group()
                    last_index = 0 - len(index)
                    method = unit.getMethod(xref_addr[0:last_index])
                    node = refs.buildNode(method.getItemId(),
                                          method.getAddress())
                    if node == None:
                        refs.setCurrentNodeById(preNode.itemId)
                        return
                    else:
                        self.findMethodXRef(units, method.getItemId(),
                                            method.getAddress(), refs)
                else:
                    method = unit.getMethod(xref_addr)
                    node = refs.buildNode(method.getItemId(),
                                          method.getAddress())
                    if node == None:
                        refs.setCurrentNodeById(preNode.itemId)
                        return
                    else:
                        self.findMethodXRef(units, method.getItemId(),
                                            method.getAddress(), refs)
        refs.setCurrentNodeById(preNode.itemId)
        return
Beispiel #11
0
 def getMethodRefs(self, unit, itemId):
   r = []
   data = ActionXrefsData()
   # careful, with query-type actions, the data is returned after the action prep'
   if unit.prepareExecution(ActionContext(unit, Actions.QUERY_XREFS, itemId, None), data):
     # clean up the DEX address, extrac the method name
     for a in data.getAddresses():
       i = a.find('->') + 2
       j = a.find('(', i)
       r.append(a[i:j])
   return r
    def comment_class(self, unit, originClazz, commentStr):
        actCtx = ActionContext(unit, Actions.COMMENT, originClazz.getItemId(),
                               originClazz.getAddress())
        actData = ActionCommentData()
        actData.setNewComment(commentStr)

        if unit.prepareExecution(actCtx, actData):
            try:
                result = unit.executeAction(actCtx, actData)
            except Exception, e:
                print(Exception, e)
 def commentClass(self, unit, clz, adr):
     ctx = ActionContext(unit, Actions.COMMENT, clz.getItemId(),
                         clz.getAddress())
     data = ActionCommentData()
     data.setNewComment(adr.replace('/', ".")[1:-1])
     if not unit.prepareExecution(ctx, data):
         return False
     try:
         return unit.executeAction(ctx, data)
     except Exception as e:
         print(Exception, e)
     return False
 def renameClass(self, unit, clz, sname):
     ctx = ActionContext(unit, Actions.RENAME, clz.getItemId(),
                         clz.getAddress())
     data = ActionRenameData()
     data.setNewName(sname)
     if not unit.prepareExecution(ctx, data):
         return False
     try:
         return unit.executeAction(ctx, data)
     except Exception as e:
         print(Exception, e)
     return False
 def getItemOriginalName(self, item):
     actCntx = ActionContext(self.focusUnit, Actions.RENAME,
                             item.getItemId(), item.getSignature())
     actData = ActionRenameData()
     originalName = ""
     if self.focusUnit.prepareExecution(actCntx, actData):
         try:
             originalName = actData.getOriginalName()
             assert (item.getName() == actData.getCurrentName())
         except Exception as e:
             print(e)
     return originalName
Beispiel #16
0
 def getItemOriginalName(self, viewName, itemId, viewAddress):
     actCntx = ActionContext(self.focusUnit, Actions.RENAME, itemId,
                             viewAddress)
     actData = ActionRenameData()
     originalName = ""
     if self.focusUnit.prepareExecution(actCntx, actData):
         try:
             originalName = actData.getOriginalName()
             assert (viewName == actData.getCurrentName())
         except Exception as e:
             print(e)
     return originalName
    def rename_class(self, unit, originClazz, sourceName, isBackup):
        actCtx = ActionContext(unit, Actions.RENAME, originClazz.getItemId(),
                               originClazz.getAddress())
        actData = ActionRenameData()
        actData.setNewName(sourceName)

        if unit.prepareExecution(actCtx, actData):
            try:
                result = unit.executeAction(actCtx, actData)
                if not result:
                    print('rename to %s failed!' % sourceName)
            except Exception, e:
                print(Exception, e)
Beispiel #18
0
    def run(self, ctx):
        unit = ctx.getActiveView().getUnit()
        print(unit.getFormatType())

        current_addr = ctx.getActiveView().getActiveFragment(
        ).getActiveAddress()
        print(current_addr)
        current_item = ctx.getActiveView().getActiveFragment().getActiveItem()
        print(current_item)

        data = ActionXrefsData()
        if unit.prepareExecution(
                ActionContext(unit, Actions.QUERY_XREFS,
                              current_item.getItemId(), current_addr), data):
            for xref_addr in data.getAddresses():
                print(xref_addr)
    def rename(self, obj, new_name):
        actCntx = ActionContext(self.unit, Actions.RENAME, obj.getItemId(), obj.getAddress())
        actData = ActionRenameData()
        actData.setNewName(new_name)

        if self.unit.prepareExecution(actCntx, actData):
            try:
                res = self.unit.executeAction(actCntx, actData)
                if not res:
                    print(u'rename failed [new_name %s]' % new_name)
                    return False

                else:
                    return True

            except Exception,e:
                print(e)
                return False
Beispiel #20
0
    def commenceRename(self, originName, newName, isClass):
        if isClass == 0:
            clz = self.targetUnit.getClass(originName)
        elif isClass == 1:
            clz = self.targetUnit.getField(originName)
        else:
            clz = self.targetUnit.getMethod(originName)
        actCntx = ActionContext(self.targetUnit, Actions.RENAME, clz.getItemId(), clz.getAddress())
        actData = ActionRenameData()
        actData.setNewName(newName)

        if (self.targetUnit.prepareExecution(actCntx, actData)):
            # 执行重命名动作
            try:
                bRlt = self.targetUnit.executeAction(actCntx, actData)
                if (not bRlt):
                    print(u'executeAction fail!')
            except Exception, e:
                print Exception, ":", e
 def rename(self, unit, origin, source, flag):
     actCtx = ActionContext(unit, Actions.RENAME, origin.getItemId(),
                            origin.getAddress())
     actData = ActionRenameData()
     if flag == 'field':
         newName = 'm%s_%d' % (source, self.count)
         self.count += 1
     else:
         newName = '%s___%s' % (source, origin.getName(True))
     actData.setNewName(newName)
     if unit.prepareExecution(actCtx, actData):
         try:
             result = unit.executeAction(actCtx, actData)
             if result:
                 print('rename to %s success!' % newName)
             else:
                 print('rename to %s failed!' % newName)
         except Exception, e:
             print(Exception, e)
Beispiel #22
0
    def run(self, ctx):
        unit = ctx.getFocusedUnit()
        assert unit, 'Need a focused unit fragment'
        print(unit.getFormatType())

        current_addr = ctx.getFocusedAddress()
        print(current_addr)

        current_item = ctx.getFocusedItem()
        print(current_item)

        data = ActionXrefsData()
        if unit.prepareExecution(
                ActionContext(
                    unit, Actions.QUERY_XREFS,
                    0 if not current_item else current_item.getItemId(),
                    current_addr), data):
            for xref_addr in data.getAddresses():
                print(xref_addr)
Beispiel #23
0
    def commenceRename(self, codeUnit, ClassName, newName):
        clz = codeUnit.getClass(ClassName)
        #clz = codeUnit.getMethod(ClassName)
        print("[+] Change class name from [ %s ] to [ %s ] " %
              (ClassName, newName))
        #print(clz)

        actCntx = ActionContext(codeUnit, Actions.RENAME, clz.getItemId(),
                                clz.getAddress())
        actData = ActionRenameData()
        actData.setNewName(newName)

        if (codeUnit.prepareExecution(actCntx, actData)):
            try:
                bRlt = codeUnit.executeAction(actCntx, actData)
                if (not bRlt):
                    print(u'executeAction fail!')
            except Exception, e:
                print Exception, ":", e
    def rename_class(self, unit, originClazz, sourceName):
        actCtx = ActionContext(unit, Actions.RENAME, originClazz.getItemId(),
                               originClazz.getAddress())
        actData = ActionRenameData()
        actData.setNewName(sourceName)

        if unit.prepareExecution(actCtx, actData):
            try:
                originalName = actData.getOriginalName()
                if len(
                        originalName
                ) > 10:  # Skip for general cases: already have meaningful class name
                    return sourceName
                result = unit.executeAction(actCtx, actData)
                if result:
                    print('rename %s to %s success!' %
                          (originalName, originClazz.getAddress()))
                else:
                    print('rename to %s failed!' % sourceName)
            except Exception, e:
                print(Exception, e)
    def renameItembySig(self, codeType, signature, newName):
        x = None
        for cu in self.codeUnits:
            if codeType == "Field":
                x = cu.getField(signature)
            elif codeType == "Method":
                x = cu.getMethod(signature)
            elif codeType == "Class":
                x = cu.getClass(signature)
            else:
                raise Exception("execute renameItembySig with unknown codeType!")
            if x:
                break

        if not x:
            return

        itemId = x.getItemId()
        itemAddress = x.getAddress()
        itemSig = x.getSignature()

        actCntx = ActionContext(cu, Actions.RENAME, itemId, itemAddress)
        actData = ActionRenameData()

        if cu.prepareExecution(actCntx, actData):
            try:
                originalName = actData.getOriginalName()
                getCurrentName = actData.getCurrentName()

                if newName == getCurrentName:
                    return newName
                actData.setNewName(newName)
                bRlt = cu.executeAction(actCntx, actData)
                if not bRlt:
                    print(u'Failure Action %s' % itemAddress)
                else:
                    pass
            except Exception as e:
                print(e)
        return newName
    def RenameItem(self, unit, itemId, itemAddress, prefix=""):
        actCntx = ActionContext(unit, Actions.RENAME, itemId, itemAddress)
        actData = ActionRenameData()

        if unit.prepareExecution(actCntx, actData):
            try:
                getCurrentName = actData.getCurrentName()

                if "_" in getCurrentName: return getCurrentName

                originalName = actData.getOriginalName()

                if prefix: prefix += "_"
                newName = prefix + self.methodNameTransform(originalName)

                if not newName or newName == getCurrentName:
                    return getCurrentName

                actData.setNewName(newName)
                bRlt = unit.executeAction(actCntx, actData)

            except Exception as e:
                print(e)
Beispiel #27
0
    def clusterUnit(self, codeUnit, basePackage=''):
        #print(codeUnit)
        typeToInternalMethods = {}
        typeToExternalMethods = {}
        # method -> list of called methods
        methodToMethods = {}
        # reverse map: method -> list of methods callers
        xmethodToMethods = {}
        methodToType = {}

        for classObject in codeUnit.getClasses():
            if (classObject.getGenericFlags() & ICodeItem.FLAG_INNER) != 0:
                #print('Inner class, skipping: %s' % classObject)
                continue

            pname = classObject.getPackage().getSignature(True)
            pname = pname[1:-1].replace('/', '.') + '.'
            if not pname.startswith(basePackage):
                #print('Class not in target package, skipping: %s' % classObject)
                continue

            typeIndex = classObject.getClassType().getIndex()
            typeToInternalMethods[typeIndex] = []
            methodObjects = classObject.getMethods()
            if not methodObjects:
                continue

            print('Processing: %s (type: %d)' % (classObject, typeIndex))
            for methodObject in methodObjects:
                methodIndex = methodObject.getIndex()
                typeToInternalMethods[typeIndex].append(methodIndex)

                methodToType[methodIndex] = typeIndex

                #print(methodObject)
                instructions = methodObject.getInstructions()
                if not instructions:
                    continue

                print('  %s' % methodObject)
                for insn in instructions:
                    s = insn.format(None)
                    refMethodIndex = self.extractMethodIndex(s)
                    if refMethodIndex >= 0:
                        print('    %d -> %d' % (methodIndex, refMethodIndex))
                        if methodIndex not in methodToMethods:
                            methodToMethods[methodIndex] = []
                        methodToMethods[methodIndex].append(refMethodIndex)
                        #if refMethodIndex not in xmethodToMethods:
                        #  xmethodToMethods[refMethodIndex] = []
                        #xmethodToMethods[refMethodIndex].append(methodIndex)

        # derive type-to-type connections
        # map: edge(couple=src,dst) TO weight(int)
        edgemap = {}
        vertices = set()
        for methodIndex in methodToMethods:
            typeIndex = methodToType[methodIndex]
            for targetMethodIndex in methodToMethods[methodIndex]:
                targetTypeIndex = methodToType.get(targetMethodIndex, -1)
                if targetTypeIndex >= 0 and targetTypeIndex != typeIndex:
                    #print ('%d -> %d' % (typeIndex, targetTypeIndex))
                    edge = (typeIndex, targetTypeIndex)
                    vertices.add(typeIndex)
                    vertices.add(targetTypeIndex)
                    if edge not in edgemap:
                        edgemap[edge] = 0
                    edgemap[edge] += 1

        types = codeUnit.getTypes()

        # graph definition (graphviz)
        gd = 'digraph {\n'
        for typeIndex in vertices:
            gd += '  %d [label="%s"]\n' % (typeIndex,
                                           self.getTypeLabel(types[typeIndex]))
        gd += '\n'
        for edge, weight in edgemap.items():
            gd += '  %d -> %d [weight=%d]\n' % (edge[0], edge[1], weight)
        gd += '}'
        with open(os.path.join(self.outputDir, 'graph.dot'), 'w') as f:
            f.write(gd)

        # graph definition (custom, for igraph)
        gd = '# vertices (%d)\n' % len(vertices)
        for typeIndex in vertices:
            gd += 'v,%d\n' % typeIndex
        gd += '# edges (%d)\n' % len(edgemap)
        for edge, weight in edgemap.items():
            gd += 'e,%d,%d,%d\n' % (edge[0], edge[1], weight)
        fileGraph = os.path.join(self.outputDir, 'graph.txt')
        with open(fileGraph, 'w') as f:
            f.write(gd)

        # clustering (external)
        fileClusteringScript = os.path.join(self.outputDir, 'cluster.py')
        fileClusters = os.path.join(self.outputDir, 'graph-clusters.txt')
        task = ClusterTask(fileClusteringScript, fileGraph, fileClusters)
        if isinstance(self.ctx, IGraphicalClientContext):
            self.ctx.executeAsync('Clustering...', task)
        else:
            task.run()

        # reading clusters
        clusters = self.readClusters(fileClusters)
        print('Clusters(types): %s' % clusters)

        # refactoring
        for i, cluster in enumerate(clusters):
            pname = basePackage + 'cluster%03d' % i

            # create a package clusterX
            data = ActionCreatePackageData()
            data.setFqname(pname)
            codeUnit.executeAction(
                ActionContext(codeUnit, Actions.CREATE_PACKAGE, 0, None), data)

            # move related classes to the virtual package
            for typeIndex in cluster:
                t = types[typeIndex]
                c = t.getImplementingClass()
                itemId = c.getItemId()

                data = ActionMoveToPackageData()
                data.setDstPackageFqname(pname)
                codeUnit.executeAction(
                    ActionContext(codeUnit, Actions.MOVE_TO_PACKAGE, itemId,
                                  None), data)