soot学习历程---(1)
今天看了soot生成手册的部分内容,简单摘录一下
Scene 表示分析所处的完整环境,可以借此设置application class(用sootclass),主类(main),point-to和call graph
SootClass 一个单独的类,被载入soot或用soot产生
SootMethod 指class的一个方法
SootField 指class的一个成员字段
Body 中间码,有四种表示
Body表示一个方法体,可以从中获得一系列Collection(soot将其称为Chain),包括本地变量声明getLocals(),构成body的statement即getUnits(),body中处理的exception即getTraps()
以下是一段 Java 代码以及其对应的 Jimple 代码:
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;
}
}
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;
}
在 Jimple 文件的最开始是 Local 的声明,它们存在 localChain 中,可以使用 body.getLocals() 获得。对于一个 local r0,可以对其 r0.getName(), r0.setName(), r0.getType(), r0.setType()。
Traps 是为了支持 Java 异常处理,由一个四元组 (exception, start, stop, handler) 来描述,其中范围包含 start 不包含 stop,在这之间的unit如果触发了异常,就跳转到handler。
catch java.lang.Exception from label0 to label1 with label2;
Unit 是表示 Body 代码的,Unit 在 Jimple 中的实现是 Stmt,在 Grimp 中的实现是 Inst
通过Unit(Jimple实现为Stmt),可以检索value的使用(getUseBoxes())和定义(getDefBoxes()),或者同时实现(getUseAndDefBoxes())
此外,还可以获得跳转到这个Unit的Unit(getBoxesPointingToThis()),以及这个Unit要跳转去的Unit--(getUnitBoxes()),借此分析控制流
Unit还提供了一些方法查询分支行为,例如fallsThrough() 和 branches()
一个单一的datum表示为Value
Value 接口是为了描述 data。Value 主要包括:Local; Constants; Expressions (Expr); ParameterRefs, CaughtExceptionRefs, ThisRefs。Expr 接口既是表达式,它接受若干个 Value 同时返回另一个 Value。例如对于 AssignStmt :
x = y + ;
y + 2 是 AddExpr,y 是 Local, 2 是Constant。对于 Jimple,强制最多有 1 个expression,Grimp 则没有此限制。
一个表达式具有多种实现,但一般可以认为是在一个或多个值上执行某些操作,并返回另一个值。
引用在soot中称作boxes,分为ValueBox and UnitBox,提供对soot对象的间接访问,不理解的话可以当做指针
对于 UnitBox,每个 Unit 必须提供 getUnitBoxes() 方法,当然对于大多数的 Unit 这个方法返回空,但是对于跳转语句,例如 GotoStmt,该方法返回目标的 lable 的 box,而对于 SwitchStmt 则返回很多 Box。Box 的概念对于用 soot 修改代码提供了很大的便利。例如有两条指令
s: goto l2;
...
...
l2: goto l3;
显然这里多用了一条指令,可以用如下程序优化
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);
}
}
对于 ValueBox,我们可以取出一个 Unit 的 ValueBox 列表,包含这个 Unit 引用、定值了哪些 Value。我们可以用 box 实现 constant folding:如果一个 AssignStmt 计算一个 AddExpr,把两个常量相加,我们可以静态的计算结果,并把结果放入 UseBox。代码如下:
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 的方法:
public List getUseBoxes();
public List getDefBoxes();
public List getUseAndDefBoxes();
public List getUnitBoxes();
这是获得被这个unit 跳转到的 UnitBox 的 List
public List getBoxesPointingToThis();
这是获得该 unit 被作为跳转对象时,所有跳转本身的 UnitBox
public boolean fallsThrough();
public boolean branches();
对于前一个方法,如果接下来会执行后面挨着的 Unit,则返回 true。后一个方法是,如果运行时会跳转到其他别的 unit,则返回 true。
public void redirectJumpsToThisTo(Unit newLocation);
该方法把所有跳转到该 unit 重定向到 newLocation。
soot学习历程---(1)的更多相关文章
- 我的Linux学习历程:那些我看过的Linux书籍们
[+]查看原图http://www.ituring.com.cn/article/119401 来北京工作已经一个多月,大都市的生活比起读大学要忙碌得多,尤其是出行,基本以小时为基本的计时单位.有时茫 ...
- StudyJams学习历程总结
Study Jams 是一个学习 Google 在线课程的活动.该活动由学员自发组建课程学习小组,旨在带领小组成员入门 Android 开发,最终将 Android App 上载至 Google Pl ...
- 大三仍是Linux系统小白的我给大家讲讲学习历程
我与Linux结缘是在大三的时候.我与Linux熟识是在偶然遇到<Linux就该这么学>的时候.因为我是电子信息工程专业,在高年级时开设了嵌入式课程,嵌入式系统是一种专用的计算机系统,作为 ...
- 登录模块的进化史,带大家回顾java学习历程(二)
接着前面的登录模块的进化史,带大家回顾java学习历程(一) 继续往下面讲 前面我们去实现登录功能,都是想着要完成这个功能,直接在处理实际业务的类中去开始写具体的代码一步步实现,也就是面向过程的编程. ...
- 来自一个电子狂的stm32学习历程
文章尾部有学习时的一些视频资料在学的可以看看那么我们就进入今天的主题我stm32的学习历程 在学习了51单片机之后,早已经对单片机这个东西甚有了解了,所有不管是从内部资源,还是一些常见应用,都可以说的 ...
- Linux学习历程——Centos 7重置root密码
一.自述 最近刚刚接触linux,因为我设置密码比较随性,把自己做系统的时候设置的root密码给forget,每当系统崩溃,重新把虚拟机备份还原后,就面临无法登陆的尴尬情况,只得重置root密码,好了 ...
- Nginx系列0:Nginx学习历程
Nginx学习历程 一.初识Nginx 1.Nginx适用于哪些场景 (1)静态资源服务 通过本地文件系统提供服务 (2)反向代理服务 Nginx的强大性能 缓存 负载均衡 (3)API服务 Open ...
- JS高级学习历程-6
PHP菜鸟学习历程-6 [闭包案例] 1 闭包创建数组 <!DOCTYPE html> <html lang="en"> <head> < ...
- Nvidia Jetson TX2开发板学习历程(1)- 详细开箱、上电过程
考试周已经结束了,开发板也已经到了.希望借着这个假期能够好好的利用这块开发板学习Linux系统以及Tensorflow的相关知识. 我打算将学习历程通过博客的方式写出来,作为自己的笔记,也可以供以后拿 ...
随机推荐
- 通过源码安装PostgresSQL
通过源码安装PostgresSQL 1.1 下载源码包环境: Centos6.8 64位 yum -y install bison flex readline-devel zlib-devel yum ...
- excel中汉字转拼音
Excel中文转拼音(完整版)打开Excel->工具->宏->Viaual Basic编辑器在弹出来的窗口中对着VBAproject点右键->插入->模块下面会出现一个名 ...
- vue学习-day01(vue指令)
目录: 1.什么是vue.js 2.为什么要学习前端的流行框架 3.框架和库的区别 4.后端MVC和前端的MVVM的区别 5.vue.js的基本代码--hollo world代 ...
- [SHOI2005]树的双中心
题目链接:Click here Solution: 首先我们要知道,选择两个点\(A,B\),必定存在一条边,割掉这条边,两个集合分别归\(A,B\)管 再结合题目,我们就得到了一个暴力的\(n^2\ ...
- yield return的使用。。。
因为要取两个集合不同的元素,所以写了个拓展方法,用到了yield这个关键字,然后就学习了一波.先上代码 public static IEnumerable<T> NoRetainAll&l ...
- kibana花式查询
在kibana提供的界面上进行操作. POST /school/student/_bulk{ "index": { "_id": 1 }}{ "nam ...
- react注
创建新项目: npm create-react-app test1 运行项目:npm start
- Python For Mac 开发环境安装 以及问题记录
Python For Mac 开发环境安装记录 把自己安装的过程记录一下,亲测可用 1.Python3环境安装(转载http://www.cnblogs.com/meng1314-shuai/p/90 ...
- class 用法 函数变量的作用域
函数变量的作用域 1. 函数体内声明的变量 2. 参数中的变量 没有赋值的 function fn(a){} 赋值的,值不是变量 function fn(a=45){} 赋的值为变量 function ...
- ffmpeg精简编译
项目上需要用到ffmpeg的接收功能,把rtp流转封装为ts吐udp组播流,不涉及编码,所以需要精简一下脚本如下: #!/bin/bash dir=$(pwd) echo $dir rm -rf $d ...