转载自:安全客@ACBC
https://www.anquanke.com/post/id/228981
目录
.
DEX交叉引用查询(xref)
Native调用查询(callee caller)
Native交叉引用查询
Native地址所属查询
.
.
DEX交叉引用查询
查询DEX中方法的交叉引用信息,
使用ActionXrefsData和ActionContext
# -*- coding: utf-8 -*-
from com.pnfsoftware.jeb.client.api import IClientContext
from com.pnfsoftware.jeb.core import IRuntimeProject
from com.pnfsoftware.jeb.core.actions import ActionXrefsData, Actions, ActionContext
from com.pnfsoftware.jeb.core.units import IUnit
from com.pnfsoftware.jeb.core.units.code.android import IDexUnit
from com.pnfsoftware.jeb.core.units.code.android.dex import IDexMethod, IDexClass
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
.
.
Native调用查询
查询一个函数被谁调用了,或查询它内部调用了谁,关注:
INativeCodeAnalyzer
INativeCodeModel
ICallGraphManager
ICallGraph
# -*- coding: utf-8 -*-
from com.pnfsoftware.jeb.client.api import IClientContext
from com.pnfsoftware.jeb.core import IRuntimeProject
from com.pnfsoftware.jeb.core.units import IUnit, INativeCodeUnit
from com.pnfsoftware.jeb.core.units.code.asm.analyzer import INativeCodeAnalyzer, INativeCodeModel, IReferenceManager, ICallGraphManager, ICallGraph, CallGraphVertex
from com.pnfsoftware.jeb.core.units.code.asm.items import INativeMethodItem
# callees/callers 调用与被调用信息
def Test(ctx):
assert isinstance(ctx,IClientContext)
input_path = r"D:\tmp\2\project\about_dex_diff\code\xmly\libFace3D.so"
unit = ctx.open(input_path); assert isinstance(unit,IUnit)
prj = ctx.getMainProject(); assert isinstance(prj,IRuntimeProject)
# 获取INativeCodeUnit并执行解析
nativeCodeUnit = prj.findUnit(INativeCodeUnit); assert isinstance(nativeCodeUnit,INativeCodeUnit)
bool = nativeCodeUnit.process()
# 获取INativeCodeAnalyzer,获取INativeCodeModel
nativeCodeAnalyzer = nativeCodeUnit.getCodeAnalyzer(); assert isinstance(nativeCodeAnalyzer,INativeCodeAnalyzer)
nativeCodeAnalyzer.analyze()
nativeCodeModel = nativeCodeAnalyzer.getModel(); assert isinstance(nativeCodeModel,INativeCodeModel)
# 获取ICallGraph
callGraph = nativeCodeModel.getCallGraphManager().getGlobalCallGraph(); assert isinstance(callGraph,ICallGraph)
# 函数
funcName = "libunwind::LocalAddressSpace::findFunctionName"
nativeMethodItem = nativeCodeUnit.getMethod(funcName); assert isinstance(nativeMethodItem,INativeMethodItem)
print ">>> funcAddr:",hex(nativeMethodItem.getRoutineAddress())
# callees 目标函数调用了谁
callGraphVertexList = callGraph.getCallees(nativeMethodItem,False)
for callGraphVertex in callGraphVertexList:
assert isinstance(callGraphVertex,CallGraphVertex)
print ">>> Callee:",hex(callGraphVertex.getInternalAddress().getAddress())
# callers 目标函数被谁调用
callerList = callGraph.getCallers(nativeMethodItem,False)
for caller in callerList:
print ">>> Callers:",hex(caller)
# >>> funcAddr: 0x19a1cL
# >>> Callee: 0xabfcL
# >>> Callee: 0xac08L
# >>> Callee: 0x9cc0L
# >>> Callers: 0x196b2L
.
Native交叉引用查询
查询一个Function的交叉引用情况
或查询一个Block入口指令的引用交叉引用情况
INativeCodeAnalyzer
INativeCodeModel
IReferenceManager
IReference
# -*- coding: utf-8 -*-
from com.pnfsoftware.jeb.client.api import IClientContext
from com.pnfsoftware.jeb.core import IRuntimeProject
from com.pnfsoftware.jeb.core.units import IUnit, INativeCodeUnit
from com.pnfsoftware.jeb.core.units.code import EntryPointDescription
from com.pnfsoftware.jeb.core.units.code.asm.analyzer import INativeCodeAnalyzer, INativeCodeModel, IReferenceManager, ICallGraphManager, ICallGraph, CallGraphVertex
from com.pnfsoftware.jeb.core.units.code.asm.items import INativeMethodItem
# 原生库交叉引用信息
def Test(ctx):
assert isinstance(ctx,IClientContext)
input_path = r"D:\tmp\2\project\about_dex_diff\code\xmly\libFace3D.so"
unit = ctx.open(input_path); assert isinstance(unit,IUnit)
prj = ctx.getMainProject(); assert isinstance(prj,IRuntimeProject)
# 获取INativeCodeUnit并执行解析
nativeCodeUnit = prj.findUnit(INativeCodeUnit); assert isinstance(nativeCodeUnit,INativeCodeUnit)
bool = nativeCodeUnit.process()
# 获取INativeCodeAnalyzer,获取INativeCodeModel
nativeCodeAnalyzer = nativeCodeUnit.getCodeAnalyzer(); assert isinstance(nativeCodeAnalyzer,INativeCodeAnalyzer)
nativeCodeAnalyzer.analyze()
nativeCodeModel = nativeCodeAnalyzer.getModel(); assert isinstance(nativeCodeModel,INativeCodeModel)
# 获取一个函数入口指令地址的交叉引用列表
funcName = "libunwind::LocalAddressSpace::findFunctionName"
funcAddr = nativeCodeUnit.getMethod(funcName).getRoutineAddress()
print ">>> funcAddr:",hex(funcAddr)
referenceManager = nativeCodeModel.getReferenceManager()
referenceList = referenceManager.getReferencesToTarget(funcAddr)
print ">>> funcAddr referenceList:",referenceList
# 获取一个基本块入口指令地址的交叉引用列表
referenceList = referenceManager.getReferencesToTarget(0x19A5E)
print ">>> block referenceList:",referenceList
# >>> funcAddr: 0x19a1cL
# >>> funcAddr referenceList: [196B2h]
# >>> block referenceList: [19A3Ch, 19A40h]
.
.
Native地址所属查询
获取一条指令的地址,所属Function或Block.
# -*- coding: utf-8 -*-
from com.pnfsoftware.jeb.client.api import IClientContext
from com.pnfsoftware.jeb.core import IRuntimeProject
from com.pnfsoftware.jeb.core.units import IUnit, INativeCodeUnit
from com.pnfsoftware.jeb.core.units.code import EntryPointDescription
from com.pnfsoftware.jeb.core.units.code.asm.analyzer import INativeCodeAnalyzer, INativeCodeModel, IReferenceManager, ICallGraphManager, ICallGraph, CallGraphVertex
from com.pnfsoftware.jeb.core.units.code.asm.items import INativeMethodItem
def Test(ctx):
assert isinstance(ctx,IClientContext)
input_path = r"D:\tmp\2\project\about_dex_diff\code\xmly\libFace3D.so"
unit = ctx.open(input_path); assert isinstance(unit,IUnit)
prj = ctx.getMainProject(); assert isinstance(prj,IRuntimeProject)
# 获取INativeCodeUnit并执行解析
nativeCodeUnit = prj.findUnit(INativeCodeUnit); assert isinstance(nativeCodeUnit,INativeCodeUnit)
bool = nativeCodeUnit.process()
# 获取INativeCodeAnalyzer,获取INativeCodeModel
nativeCodeAnalyzer = nativeCodeUnit.getCodeAnalyzer(); assert isinstance(nativeCodeAnalyzer,INativeCodeAnalyzer)
nativeCodeAnalyzer.analyze()
nativeCodeModel = nativeCodeAnalyzer.getModel(); assert isinstance(nativeCodeModel,INativeCodeModel)
# 返回该地址所在函数的首地址
print "-------------------"
r = nativeCodeModel.getContainedRoutineAddresses(0x19A60)
print ">>> ",hex(r[0])
# 返回该地址所在基本块
print "-------------------"
r = nativeCodeModel.getBasicBlockHeader(0x19A60)
for insn in r.getInstructions():
print ">>> ",insn.getMnemonic()
# -------------------
# >>> 0x19a1cL
# -------------------
# >>> LDR
# >>> LDR
# >>> SUBS
# >>> ITTT
# >>> ADDEQ
# >>> POPEQ
# >>> POPEQ