Soot对象基础(Fundamental Soot Object)
来源:互联网 发布:ios小游戏源码 编辑:程序博客网 时间:2024/06/01 19:16
Soot对象基础(Fundamental Soot Object)
Soot有着庞大而复杂的类层次结构。该文档主要给读者介绍一些用于Soot扩展开发中使用的最重要的类。
关于Body类
在教程:Createing a class from scratch中,Body的概念被简要的介绍过。本节将对Body做详细的描述。
Soot使用Body来存储一个方法的代码。在Soot中,有四种不同的Body实现,分别为:BafBody,JimpleBody,ShimpleBody和GrimpBody,每一种都是一种中间表示。
另外,回顾下,一个chain是类似list的数据结构,它提供了常量时间(O(1))的对chain中元素的访问,包括插入与移除。
在Body中三个主要的chain是Units Chain,Locals Chain和Traps Chain。接下来的例子给出了这些Chain扮演的角色。
查看如下代码
public static void main(String[] argv) throws Exception
{
int x = 2, y = 6;
System.out.println("Hi!");
System.out.println(x * y + y);
try
{
int z = y * x;
}
catch (Exception e)
{
throw e;
}
}
在Jimple化后,我们可以获取到如下缩略后的Jimple代码。
public static void main(java.lang.String[]) throws java.lang.Exception
{
java.lang.String[] r0;
int i0, i1, i2, $i3, $i4;
java.io.PrintStream $r1, $r2;
java.lang.Exception $r3, r4;
r0 := @parameter0;
i0 = 2;
i1 = 6;
$r1 = java.lang.System.out;
$r1.println(``Hi!'');
$r2 = java.lang.System.out;
$i3 = i0 * i1;
$i4 = $i3 + i1;
$r2.println($i4);
label0:
i2 = i1 * i0;
label1:
goto label3;
label2:
$r3 := @caughtexception;
r4 = $r3;
throw r4;
label3:
return;
catch java.lang.Exception from label0 to label1 with label2;
}
Local变量
在该方法中的Locals是在方法的顶部:
java.lang.String[] r0;
int i0, i1, i2, $i3, $i4;
java.io.PrintStream $r1, $r2;
java.lang.Exception $r3, r4;
(备注下:带有$符号的是,Java代码中原来没有的变量)
Local的集合被存储到LocalChain中,并且可以通过body.getLocals()来访问。每个中间表示可能都定义有自己的Local实现。然而,它必须总是针对每个Local r0,可以调用r0.getName(),r0.getType(),r0.setName()和r0.setType()。注意,local变量必须是带类型的。
Traps
为了支持Java异常处理,Soot的Body定义了traps的概念。这想法来自Java的字节码,异常处理被表示为一个tuple(元组,异常,开始,结束,处理器);在start和stop 的Units(包括Start但不包括Stop),如果抛出了异常,执行将在handler处继续执行。
示例的trap如下:
catch java.lang.Exception from label0 to label1 with label2;
Units
一个Body中最有趣的部分是Units Chain。这是Body中包含的实际代码。Jimple提供了Unit的Stmt实现,而Grimpe提供了Inst实现。这反应了每个IR都有自己的语句概念。
Jimple Stmt的一个例子是AssignStmt,它表示一个Jimple赋值语句。一个AssignStmt如下:
x = y + z;
Value
代码总是作用在数据上。为了表示数据,Soot提供了Value接口。Value的一些类型包括:
- Locals(本地变量)
- Constants(常亮)
- Expressions(表达式)
- ParameterRefs(参数引用),CaughtExceptionRef(异常引用)和ThisRefs(This指针引用)
Expr接口,有着各式各样的实现,包括NewExpr和AddExpr。一般来说,一个Expr携带有针对一个或多个Value的操作,并返回另一个Value。
这里是一个使用Value的展示:
x = y + 2;
Boxes
Boxes在Soot中非常普遍。必须牢记在心的是Box指代的是指针。它提供了对Soot对象的间接访问。
对Box的更具描述性的称谓是Ref,不幸的是,Ref在Soot中有不同的含义。
在Soot中有两种不同的Box,即ValueBox和UnitBox。无需惊讶的是,一个UnitBox包含Units,而ValueBox中包含Values。在C++中,这些可以简单的用(Unit *)和(value *)来表示。
现在我们描述Box的各个类型
UnitBox
Unit中的一些类型需要包含其它Unit(s)的引用(Reference)。比如,GotoStmt需要知道它的目标在哪里。因此,Soot提供了UnitBox,一个包含Unit的Box。考虑如下Jimple代码:
x = 5;
goto l2;
y = 3;
l2: z = 9;
每个Unit必须提供一getUnitBoxes()方法。对于大多数的UnitBox,这返回一个空list。然而,在GotoStmt的场景下,getUnitBoxes()返回了一个元素的list,包含了执行l2的一个Box。
注意:一个SwitchStmt将,一般返回一个包含许多box的list。
Box的概念对于修改代码非常有用,假设有以下代码:
s: goto l2;
在l2有语句:
l2: goto l3;
显然,它可以直接指向l3而不是l2,而不需要理会s的实际类型。我们可以统一的针对所有种类的Unit做处理:
public void readjustJumps(Unit s, Unit oldU, Unit newU)
{
Iterator ubIt = s.getUnitBoxes.iterator();
while (ubIt.hasNext())
{
StmtBox tb = (StmtBox)ubIt.next();
Stmt targ = (Stmt)tb.getUnit();
if (targ == oldU)
tb.setUnit(newU);
}
}
与这类似的代码在Unit中使用,为了使能PatchingChain,一种Chain的实现,的创建,调整了指针以从Chain中移除Unit(s)。
ValueBox
类似于Unit(s),我们需要指向一个Value的指针,这是由ValueBox类来表示的。对一个Unit来说,我们总能获取到一个ValueBox的列表,包含Unit中使用和定义的value。
我们可以使用这些boxes来进行constant folding:如果一个AssignStmt评估了一个AddExpr添加了2个常量,我们可静态的将其相加,并将结果存入UseBox.
这是一个folding AddExpr的例子:
public void foldAdds(Unit u)
{
Iterator ubIt = u.getUseBoxes().iterator();
while (ubIt.hasNext())
{
ValueBox vb = (ValueBox) ubIt.next();
Value v = vb.getValue();
if (v instanceof AddExpr)
{
AddExpr ae = (AddExpr) v;
Value lo = ae.getOp1(), ro = ae.getOp2();
if (lo instanceof IntConstant && ro instanceof IntConstant)
{
IntConstant l = (IntConstant) lo,
r = (IntConstant) ro;
int sum = l.value + r.value;
vb.setValue(IntConstant.v(sum));
}
}
}
}
注意:这对任何Unit都能工作,而不需考虑类型。
Unit温故
我们现在考虑每个Unit都必须提供不同的方法:
public List getUseBoxes();
public List getDefBoxes();
public List getUseAndDefBoxes();
这些方法返回了针对在Unit中使用的,定义的,以及两者皆有的value的ValueBox的列表。对于getUseBoxes(),所有使用的值被返回;这包含了表达式也包含了它们的组成部分。
public List getUnitBoxes();
该方法返回了UnitBox的列表,表示指向的Unit(s)。
public List getBoxesPointingToThis();
该方法返回了那些将该Unit视为目标的UnitBox列表。
public boolean fallsThrough();
public boolean branches();
这些方法与该Unit的执行流程打交道。前一个方法在执行顺序能够从Unit的下一条语句执行时返回true,而后一条则是当执行可能跳转到其它的某个Unit而不是直接执行紧跟的那条时返回true。
public void redirectJumpsToThisTo(Unit newLocation);
该方法使用getBoxesPointToThis来改变使用跳转到该Unit的指针,让它们指向newLocation。(该方法可以在Soot源码中查找到。)
- Soot对象基础(Fundamental Soot Object)
- soot基础 -- soot中基本的对象
- soot
- soot基础 -- soot 中的处理阶段
- 基本的Soot对象
- 1.soot基础 -- 基本知识
- soot学习(一)
- soot基础 -- 解析java文件
- soot基础 -- 常用参数配置
- soot中存在的主要对象、soot的执行流
- soot基础 -- soot的数据结构与java语言的结构
- soot相关
- soot-1
- soot-2
- soot基础 -- 从头开始创建一个类
- 使用SOOT进行代码分析(一)
- soot数据流 -- 指向分析(points-to)
- [Soot学习笔记][7]Soot Instrument教程学习(More on profiling)
- spring boot 应用发布到 docker (完整版)
- 4.使用pnglib读写png图片
- MarkDown语法
- Docker
- 反转整数
- Soot对象基础(Fundamental Soot Object)
- 【技术分享】如何攻击Symantec Messaging Gateway:从弱口令到远程代码执行
- 欢迎使用CSDN-markdown编辑器
- Docker的使用场景
- 阿里云centos7安装yii框架
- tomcat虚拟路径设置,踩过的坑
- docker与虚拟机性能比较
- 解决VS2010链接错误:LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- 如何看待docker容器与虚拟机之间的比较