Skip to content

Instantly share code, notes, and snippets.

@forensicmike
Last active February 14, 2022 16:05
Show Gist options
  • Select an option

  • Save forensicmike/c5dfb08383babfb623ea5a155f2bd6b3 to your computer and use it in GitHub Desktop.

Select an option

Save forensicmike/c5dfb08383babfb623ea5a155f2bd6b3 to your computer and use it in GitHub Desktop.
Jeb Android - Find Filtered Xrefs To Package
#?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