GDAblog-中国首款交互式Android反编译器

GDA路径求解器

 

一、程序路径求解问题的应用方向

 

漏洞挖掘:当我们确定程序的攻击面后,需要知道攻击面上的点是否与脆弱函数存在一条可以联通的路径。

隐私泄露:对于程序中的任意敏感数据获取函数,需要知道这些数据是否被泄露出去。

恶意代码分析:对于恶意代码中的敏感函数,需要确定这些敏感函数是否被触发。

其他:闭源代码审计,程序半自动化分析等。

 

二、GDA的路径求解思路

 

一段程序可以看做是有限非线性数据流的集合,这些数据流由调用链及控制流决定流动方向。一条单一的具有方向的数据流动便构成了一条路径,反过来看,每条路径就像数据流的管道一样,也决定了数据流的流向。在一个复杂的程序中,会存在几十乃至上百万的路径,再在无数分支指令的作用下构成了一张复杂的网络。因此,这里的程序路径求解主要解决的是两个或者多个特定节点的联通性问题,进一步的可以解决联通路径的问题,所有的联通路径即是路径求解的解的集合。当然多点联通问题,实际上都可以简化为两点的联通性问题。

GDA里,主要实现两点之间的路径求解,路径的节点为低级中间表达式。此处,我将路径求解的起点称为Source,目标节点称为Target。主要通过数据流分析的方法以Source为起点结合控制流图、调用树以及对象关联进行数据传播,传播过程中要防止环流(循环),路径爆炸等问题,最后记录求解结果。在实际应用过程中,我们不必花费大量精力在所有的指令节点上(任意指令节点大家可以使用基于smali的污点传播分析来做分析),我们更关注函数调用节点。

GDA反编译器中,通过数据流联通性和任意值可达性来求解两个节点的路径集合。由于两个节点联通的路径常常太多,展示出来显得非常冗繁,因此为了降低复杂性,我将过滤掉求解结果中的非调用节点,保留关键的函数调用点,方便分析和定位。

 

三、使用方法

 

打开GDA反编译器,菜单->Path Solving, 弹出路径求解器对话框。我们可以在窗口的右边选择APIs对当前APP程序所用使用API进行实时搜索,如果搜索非APIs,取消选择即可。在搜索出来的结果中,我们可以选择我们感兴趣的结果作为Source或者Target

 

 

这里,我们选择android.database.Cursor.getString作为source,由于我们在静态分析时无法访问到api的内部逻辑,因此默认会选上Ret-Value,代表当前节点以所选择method的返回值作为路径的起点。如果我们选择非API作为source,还可以指定source的参数。

 

接下来,我们搜索一个函数作为Target这里我们以做日志记录的APIandroid.util.Log.d)为例来演示。当然我们还可以通过选择“MeetArg”来做精细化的求解(比如选择第一个参数“p0”代表来自于source的数据流必须经过p0才会存在有效解。如果不选择“MeetArg”代表任意一条穿过该函数的路径都是其中一个解)。

最后,我们点击SOLVE进行求解,求解结果以树形框的方式展示。GDA求解时,首先搜寻所有source的调用点,从每个调用点的返回值开始做路径搜索,一旦发现Target,便加入到解的集合里。通过求解的结果,我们看到source有三个调用点存在从sourcetarget的解。

 

 

默认情况下,我只将求解的SourceTarget写入到了树形框里。

如果你路径的细节感兴趣,可以右键->detail来查看路径执行情况。

 

 

同时,你点击每一个节点时,GDA会自动定位该节点在反编译(或者smali)代码中的位置。由于反编译时,难以保存原始指令的真实位置,因此在java代码中常常无法精确的定位节点位置,但在smali代码浏览模式下可以准确的定位节点的位置。