soot基础 -- soot中基本的对象

2024-03-29 06:38
文章标签 基础 对象 基本 soot

本文主要是介绍soot基础 -- soot中基本的对象,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


  soot有着庞大的类层次结构。这篇文章将给读者介绍扩展soot时候一些非常重要的类。
  这里我们主要介绍Body,Unit,Local,Value,UnitBox以及ValueBox的概念。

关于body的介绍


  在指导手册中,说明了如何创建一个类,Body的概念被简单提到了,这里将进行更详细的介绍。
  Soot使用Body来存储一个方法的代码。在Soot中有4种类型的Body–也就是BafBody,JimpleBody,ShimpleBody以及GrimpBody–每个代表一种中间表示。
  需要注意的是,Chain是一个类似于List的数据结构,提供了常量时间访问chain中的元素,包括插入,删除。
  Body中有三类主要的Chain,分别是Units Chain, Locals Chain , Traps Chain。下面的例子说明了这些chain的角色。
考虑下面一个java方法:

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格式之后如下:

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 variables)


  这个方法的局部变量可以在这个方法的顶部看到:

    java.lang.String[] r0;int i0, i1, i2, $i3, $i4;java.io.PrintStream $r1, $r2;java.lang.Exception $r3, r4;

  Local的集合存储在localChain中,可以通过body.getLocals()获得。每个中间表示可以定义他自己的对于Local的实现;但是,它必须满足,对于每个Local r0,都有r0.getName(),r0.getType(),R0.setName(),以及r0.setType.
注意局部变量一定要有类型。

异常(Traps)


  为了支持java的异常处理,Soot的Body中定义了Traps的概念。基于的思想是在java字节码中,异常处理用一种多元组的形式(exception,start,top,handler)表示;在start 和 stop之间的语句(包括start但是不包括stop),如果异常被抛出,执行将在handler中继续进行。
在例子中,有一个异常:

catch java.lang.Exception from label0 to label1 with label2;

语句(Units)


  Body中最有趣的部分是它的units chain。这是实际包含在Body中的代码。Jimple提供了Stmt来实现Unit,Grimp提供了Inst来实现。这说明每个IR(中间代码)都有自己对于语句的定义。
  关于Jimple Stmt的一个例子是AssignStmt,表示的是分配语句。一个AssignStmt的形式如下:

x = y + z;

值(Value)


  代码(code)总是作用在数据(data)之上。为了表示数据,Soot提供了Value接口。一些类型的Value s是:

  • Local s
  • Constant s
  • Expressions(Expr)
  • ParameterRef s, CaughtExccptionRef s, 以及 ThisRef s.

      Expr 接口,有着丰富的实现;他们其中有NewExpr以及AddExpr.通常,一个Expr带有一些操作,这些操作针对一个或者多个Value s 并且返回另一个Value。
      这里是一些关于Value s的使用:
x = y + 2;

  这是一个赋值语句(AssignStmt).它的左操作数为x ,有操作数为 y + 2,一个加法表达式(AddExpr).这个加法表达式(AddExpr),包含值(Value)y 和 2作为操作数;前面一个是Local(局部变量),后面一个是Constant(常量)。
  在Jimple中,我们强制要求所有的Value(值) s 包含至多一个表达式
  在Grimp中我们取消了这个限制,产生容易阅读的但是更难分析的代码

盒子(Boxes)


  在soot中盒子是无处不在的。需要记住的主要思想是,一个盒子(Box)是一个指针(Pointer)。它提供了一个间接访问soot 对象的入口。
  一个对于Box更具有描述性的名字应该是Ref。不幸的是,Ref在soot中有不同的含义。
  在soot中有两种类型的Box - ValueBox 以及UnitBox.可以猜到,一个UnitBox包含着Unit s , 一个ValueBox包含着 Value s.在C++中,这可以表示为(Unit *)以及(Value * )。
  现在我们来分别每种类型的Box.

语句盒(UnitBox)


  一些类型的Unit(语句)将需要包含其他Unit的引用。比如说,GotoStmt 需要知道它的目标是什么。因此,Soot提供了UnitBox,一个包含一条语句Unit的盒子Box.
  考虑下面的jimple代码:

    x = 5;goto l2;y = 3;
l2: z = 9;


  每个Unit必须提供 getUnitBoxes().对于大多数UnitBox ,这返回的是一个空的列表。但是,对于GotoStmt,通过 getUnitBoxes()能够返回有一个元素的列表,包含一个Box指向 l2.
  注意SwitchStmt,通常将会返回包含多个box的列表。
  Box的概念对于修饰代码是十分重要的。比如说我们有一个语句 s:

  s: goto l2;


  以及一条在l2处的语句:

l2:  goto l3;


  很明显,s可以指向 l3 ,而不是l2,忽略 s 的实际类型;我们可以用一种统一的方式来进行处理,针对所有类型的Unit s:
- 下面这段代码将 s语句中的保存的指向信息,从l2变为了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);}
}


  其他类似的代码也可以进行这样的处理。PatchingChain是Chain的一个实现,用来调整指向Unit s的指针,s是被Chain移除的。

值的盒子(ValueBox)


  与Unit s类似,我们通常也需要指向Value的指针。这被表示为ValueBox类。对于一个Unit,我们能够得到一系列的ValueBox ,包含了在Unit中使用的值以及定义的值
  我们可以使用这些盒子来进行常数合并:如果一个AssignStmt被赋予了AddExpr(加法表达式),该AddExpr用来将两个常量值进行相加,我们可以将他们静态相加,然后将结果放入到UseBox中。
  这里有一些AddExpr s合并的例子:

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();

  这些方法都是返回ValueBox列表,分别针对在这个Unit中使用的值,定义的值,以及两者都存在的情况。对于getUseBoxes()方法,所有被使用的值被返回;包括表达式以及组成他们的部分。

public List getUnitBoxes();

  这个方法返回Unit所指向UnitBox的列表。

public List getBoxesPointingToThis();

  这个方法返回以此Unit作为目标的UnitBox列表。

public boolean fallsThrough();
public boolean branches();

  这些方法与Unit之后流的执行有关系。前一个方法在有后继Unit的情况下,返回True .后一个方法(branches())在后继有多个Unit的情况下,并且这些情况不回立即执行,返回true.

public void redirectJumpsToThisTo(Unit newLocation);

  这个方法使用 getBoxesPointingTothis 来改变所有跳转到这个Unit的情况,把他们指向新的位置 newLocation.

原文出处:
Fundamental Soot objects

这篇关于soot基础 -- soot中基本的对象的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/857880

相关文章

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

Java第二阶段---09类和对象---第三节 构造方法

第三节 构造方法 1.概念 构造方法是一种特殊的方法,主要用于创建对象以及完成对象的属性初始化操作。构造方法不能被对象调用。 2.语法 //[]中内容可有可无 访问修饰符 类名([参数列表]){ } 3.示例 public class Car {     //车特征(属性)     public String name;//车名   可以直接拿来用 说明它有初始值     pu

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

C 语言的基本数据类型

C 语言的基本数据类型 注:本文面向 C 语言初学者,如果你是熟手,那就不用看了。 有人问我,char、short、int、long、float、double 等这些关键字到底是什么意思,如果说他们是数据类型的话,那么为啥有这么多数据类型呢? 如果写了一句: int a; 那么执行的时候在内存中会有什么变化呢? 橡皮泥大家都玩过吧,一般你买橡皮泥的时候,店家会赠送一些模板。 上

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系