Last active
February 14, 2022 16:05
-
-
Save forensicmike/c5dfb08383babfb623ea5a155f2bd6b3 to your computer and use it in GitHub Desktop.
Jeb Android - Find Filtered Xrefs To Package
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #?description=Find references to a specific library | |
| from com.pnfsoftware.jeb.client.api import IScript, IGraphicalClientContext | |
| from com.pnfsoftware.jeb.core.units.code import ICodeClass, ICodePackage, ICodeItem | |
| from com.pnfsoftware.jeb.core.units.code.android import IDexUnit | |
| from com.pnfsoftware.jeb.core.actions import ActionContext | |
| from com.pnfsoftware.jeb.core.actions import ActionXrefsData | |
| from com.pnfsoftware.jeb.core.actions import Actions | |
| class FindFilteredXrefsToPackage(IScript): | |
| def run(self, ctx): | |
| prj = ctx.getMainProject() | |
| # Prompt the user for a filter | |
| filter = str(ctx.displayQuestionBox("Filter results", | |
| "Please enter the filter to use on the results. For instance, if your app is com.contoso, enter contoso", | |
| "")) | |
| print '---- SCRIPT BEGIN ----' | |
| # find the first dex unit. in my test APKs, there was only 1 | |
| # but this probably should account for multiple. | |
| dex = prj.findUnit(IDexUnit) | |
| obj = ctx.getFocusedItem().getObject() | |
| if isinstance(obj, ICodeClass): | |
| print "Calling this on a class is kind of pointless :) Just use the X key" | |
| for meth in obj.getMethods(): | |
| print meth | |
| # This is the expected usage... calling it on a package. | |
| elif isinstance(obj, ICodePackage): | |
| # Iterate the children recursively | |
| # bearing in mind that a child can also be an ICodePackage | |
| for child in obj.getChildren(): | |
| self.handleObject(dex, child, filter) | |
| else: | |
| print obj.getClass() | |
| print '---- SCRIPT END ----' | |
| # Print the xrefs for the passed item. | |
| def handleObject(sender, dex, obj, filter): | |
| # If it happens to be an ICodePackage, iterate it recursively. | |
| if isinstance(obj, ICodePackage): | |
| for child in obj.getChildren(): | |
| sender.handleObject(dex, child, filter) | |
| elif (isinstance(obj, ICodeItem) | |
| and not str(obj).startswith('Type') # Must be a better way to do this but I couldn't find an easy one. | |
| and not isinstance(obj, ICodePackage)): | |
| sender.printXrefs(dex, obj.getAddress(), obj, filter) | |
| def printXrefs(sender, unit, addr, current_item, filter): | |
| any_found = False | |
| data = ActionXrefsData() | |
| if unit.prepareExecution(ActionContext(unit, Actions.QUERY_XREFS, 0 if not current_item else current_item.getItemId(), addr), data): | |
| for xref_addr in data.getAddresses(): | |
| funcname = sender.tidyAddress(xref_addr) | |
| if funcname.find(filter) >= 0: | |
| # We only want this banner if actual results were found. | |
| if any_found is False: | |
| print("** XREFs found for " + sender.tidyAddress(addr)) | |
| print("-------------------------------------") | |
| any_found = True | |
| print funcname | |
| # Finished with this section. | |
| if any_found is True: | |
| print("-------------------------------------\n") | |
| # This function cleans up an otherwise messy looking address. | |
| # For the example address: | |
| # Lcom/test/crypto/aes/AesKeyManager;->keyFactory()com/contoso/core/Factories;+16h | |
| # We will output: | |
| # com.test.crypto.aes.AesKeyManager.keyFactory | |
| def tidyAddress(sender, addr): | |
| ret = [] | |
| # This part gets the invoker's fully qualified class name. | |
| i = addr.find('L') + 1 | |
| j = addr.find(';', i) | |
| ret.append(addr[i:j]) | |
| # This part gets the invoker's method name (if any). | |
| if (addr.find('->') > 0): | |
| i = addr.find('->') + 2 | |
| j = addr.find('(', i) | |
| ret.append(addr[i:j]) | |
| # Combine them and replace / with . | |
| funcname = ''.join(ret).replace("/", ".") | |
| return funcname |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment