taintdroid源码分析 三之 解释器污点传播
来源:互联网 发布:js代码怎么用 编辑:程序博客网 时间:2024/04/28 02:10
通过研究Dalvik指令格式和类型,将可能产生信息流指令分为16大类,如表1所示。其中vx,vy,vz是寄存器,fy,fz是字段ID,T()表示污点值。
序号
指令类型
指令含义
污点传播逻辑
污点传播描述
1
Move vx,vy
移动vy的内容到vx
T(vy)→T(vx)
将T(vy)复制到T(vx)
2
Return vx
返回在vx的值
T(vx) →T(∑)
将T(vx)返回
3
Const vx, lit32
将lit32值存入vx
T(vx)→0
清空污点
4
Throw vx
将出错信息返回vx
T(vx)→T(E)
设置出错污点
5
Iput vx,vy,fz
根据fz将vx值存入实例vy的int型字段
T(vx)|T(vy)→T(fz)
将T(vx) 与T(vy)存入实例int字段
6
Iget vx,vy,fz
根据fz读取实例vy的int型字段到vx
T(fz)|T(vy)→T(vx)
将T(vy)与实例int字段相与存入T(vx)
7
Sput vx,fy
根据fy将vx存入int型字段
T(vx)→T(fy)
将T(vx)复制到T(fy)
8
Sget vx,fy
根据fy读取int型字段到vx
T(fy)→T(vx)
将T(fy)复制到T(vx)
9
Aput vx,vy,vz
将vx值存入位于vy的数组引用且索引位置为vz
T(vx)→T(vy)
将T(vx)复制数组污点
10
Aget vz,vy,vz
从位于vy的数组引用获取索引位置为vz的int型值存入vx
T(vy)→T(vx)
将数组污点复制到T(vx)
11
And vx,vy,vz
将vy|vz并存入vx
T(vy)|T(vz)→T(vx)
将T(vy)与T(vz)相与并存入T(vx)
12
Add vx,vy,vz
计算vy+vz并存入vx
T(vy)|T(vz)→T(vx)
将T(vy)与T(vz)相与并存入T(vx)
13
If-lt vx,vy,0080
如果vx<vy,跳转到目标0080
T(vx)|T(vy)→T(vy) ∪T(vx)
将T(vx)与T(vy)相与并更新各自污点
14
Int-to-long vx,vy
将vy中int值转换long并保存到vx,vx+1
T(vy)→T(vx)
将T(vy)复制到T(vx)
15
Neg vx,vy
计算vx=-vy并保存在vx
T(vy)→T(vx)
将T(vy)复制到T(vx)
16
Cmpl vx,vy,vz
比较vy和vz的值并在vz存入int型返回值
T(vy)|T(vz)→T(vz)∪T(vy) ∪T(vz)
将T(vy)与T(vz)相与更新各自污点并存入T(vz)
相对于taintdroid,其跟踪指令并没有13,15,16,所以聪明的人可能会通过这几类指令使得污点能够脱离跟踪,从而不能报告隐私泄露。
taintdroid是如何跟踪的呢,在此解释两种不同实现方式:
C 实现主要思想用C重写对栈的操作,定义如下宏:
# define GET_REGISTER_TAINT(_idx) (fp[((_idx)<<1)+1])
# define SET_REGISTER_TAINT(_idx, _val) (fp[((_idx)<<1)+1] = (u4)(_val))
# define GET_REGISTER_TAINT_WIDE(_idx) (fp[((_idx)<<1)+1])
# define SET_REGISTER_TAINT_WIDE(_idx, _val) (fp[((_idx)<<1)+1] = \
fp[((_idx)<<1)+3] = (u4)(_val))
/* Alternate interfaces to help dereference register width */
# define GET_REGISTER_TAINT_INT(_idx) GET_REGISTER_TAINT(_idx)
# define SET_REGISTER_TAINT_INT(_idx, _val) SET_REGISTER_TAINT(_idx, _val)
# define GET_REGISTER_TAINT_FLOAT(_idx) GET_REGISTER_TAINT(_idx)
# define SET_REGISTER_TAINT_FLOAT(_idx, _val) SET_REGISTER_TAINT(_idx, _val)
# define GET_REGISTER_TAINT_DOUBLE(_idx) GET_REGISTER_TAINT_WIDE(_idx)
# define SET_REGISTER_TAINT_DOUBLE(_idx, _val) SET_REGISTER_TAINT_WIDE(_idx, _val)
# define GET_REGISTER_TAINT_AS_OBJECT(_idx) GET_REGISTER_TAINT(_idx)
# define SET_REGISTER_TAINT_AS_OBJECT(_idx, _val) SET_REGISTER_TAINT(_idx, _val)
/* Object Taint interface */
# define GET_ARRAY_TAINT(_arr) ((_arr)->taint.tag)
# define SET_ARRAY_TAINT(_arr, _val) ((_arr)->taint.tag = (u4)(_val))
/* Return value taint (assumes rtaint variable is in scope */
# define GET_RETURN_TAINT() (rtaint.tag)
# define SET_RETURN_TAINT(_val) (rtaint.tag = (u4)(_val))
例如对于加法指令:
#define HANDLE_OP_X_INT_2ADDR(_opcode, _opname, _op, _chkdiv) \
HANDLE_OPCODE(_opcode /*vA, vB*/)
其实现的C 代码如下:
vdst = INST_A(inst); \
vsrc1 = INST_B(inst); \
ILOGV("|%s-int-2addr v%d,v%d", (_opname), vdst, vsrc1); \
if (_chkdiv != 0) { \
s4 firstVal, secondVal, result; \
firstVal = GET_REGISTER(vdst); \
secondVal = GET_REGISTER(vsrc1); \
if (secondVal == 0) { \
EXPORT_PC(); \
dvmThrowArithmeticException("divide by zero"); \
GOTO_exceptionThrown(); \
} \
if ((u4)firstVal == 0x80000000 && secondVal == -1) { \
if (_chkdiv == 1) \
result = firstVal; /* division */ \
else \
result = 0; /* remainder */ \
} else { \
result = firstVal _op secondVal; \
} \
SET_REGISTER(vdst, result); \
} else { \
SET_REGISTER(vdst, \
(s4) GET_REGISTER(vdst) _op (s4) GET_REGISTER(vsrc1)); \
}
为完成相应的污点操作,则可依据定义的宏进行栈中污点位置的操作如下:
SET_REGISTER_TAINT(vdst, \
(GET_REGISTER_TAINT(vdst)|GET_REGISTER_TAINT(vsrc1)) );
一目了然。
对于其用汇编语言实现,则较为复杂,难于理解一些,但如若对arm汇编比较了解,学习过编译原理的则能较好理解,毕竟汇编实现要快很多。
首先要了解的是汇编对于寄存器的分配:
在硬件上arm如下分配寄存器:
r0-r3 hold first 4 args to a method; they are not preserved across method calls
r4-r8 are available for general use
r9 is given special treatment in some situations, but not for us
r10 (sl) seems to be generally available
r11 (fp) is used by gcc (unless -fomit-frame-pointer is set)
r12 (ip) is scratch -- not preserved across method calls
r13 (sp) should be managed carefully in case a signal arrives
r14 (lr) must be preserved
r15 (pc) can be tinkered with directly
但dalvik则不这样进行分配,其如下分配和定义:
reg nick purpose
r4 rPC interpreted program counter, used for fetching instructions
r5 rFP interpreted frame pointer, used for accessing locals and args
r6 rSELF self (Thread) pointer
r7 rINST first 16-bit code unit of current instruction
r8 rIBASE interpreted instruction base pointer, used for computed goto
由此可以这样定义对栈污点的操作:
#define SET_TAINT_FP(_reg) add _reg, rFP, #4
#define SET_TAINT_CLEAR(_reg) mov _reg, #0
#define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #3]
#define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #3]
#define GET_VREG_TAINT(_reg, _vreg, _rFP) ldr _reg, [_rFP, _vreg, lsl #3]
#define SET_VREG_TAINT(_reg, _vreg, _rFP) str _reg, [_rFP, _vreg, lsl #3]
#else
#define GET_VREG(_reg, _vreg) ldr _reg, [rFP, _vreg, lsl #2]
#define SET_VREG(_reg, _vreg) str _reg, [rFP, _vreg, lsl #2]
其操作语义也比较好理解,不再多说。
由此对于加法指令:
/* binop vAA, vBB, vCC */
FETCH(r0, 1) @ r0<- CCBB
mov r9, rINST, lsr #8 @ r9<- AA
mov r3, r0, lsr #8 @ r3<- CC
and r2, r0, #255 @ r2<- BB
GET_VREG(r1, r3) @ r1<- vCC
GET_VREG(r0, r2) @ r0<- vBB
.if 0
cmp r1, #0 @ is second operand zero?
beq common_errDivideByZero
.endif
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
@ optional op; may set condition codes
add r0, r0, r1 @ r0<- op, r0-r3 changed
GET_INST_OPCODE(ip) @ extract opcode from rINST
SET_VREG(r0, r9) @ vAA<- r0
GOTO_OPCODE(ip) @ jump to next instruction
/* 11-14 instructions */
即可在Fetch之前加入污点传播指令
.LOP_ADD_INT_taint_prop
其定义为,
.LOP_ADD_INT_taint_prop:
SET_TAINT_FP(r10)
GET_VREG_TAINT(r3, r3, r10)
GET_VREG_TAINT(r2, r2, r10)
orr r2, r3, r2
SET_VREG_TAINT(r2, r9, r10)
bx lr
这些结合前面定义都比较好理解:设置污点fp,取两源数据的污点,污点相与实现传播,然后将污点保存。
这样对于其它指令也可以很好理解,至此应该就了解了全部的程序变量级别的污点传播,和方法调用的污点传播过程
方法调用污点传播再附一图如下:
- taintdroid源码分析 三之 解释器污点传播
- taintdroid源码分析之四 组件(进程)通信间污点传播
- TaintDroid剖析之IPC级污点传播
- TaintDroid剖析之File & Memiry & Socket级污点传播
- TaintDroid剖析之Native方法级污点跟踪分析
- Android动态污点分析工具TaintDroid部署指南 - FloraF
- TaintDroid剖析之DVM变量级污点跟踪(下篇)
- taintdroid源码解析一 如何为隐私数据加上污点标记
- TaintDroid实现数据流的污点追踪
- Android污点分析工具flowdroid源码简析
- Memcached源码分析之三
- ContentProvider 源码分析---之三
- TaintDroid下载与编译(三):Android源码下载和编译
- 动态污点分析浅述
- 全系统动态污点分析-概要
- 动态污点分析浅述
- Lua 简单Lua解释器源码分析
- 【Postgresql源码分析之三】同步复制源码分析
- 我的命名规则
- 二维数组+字符串split+Double包装类 例题
- 深入理解C系列:不同类型变量的变量名和内存间的关系
- 计算三角形的面积
- Makefile常见选项说明
- taintdroid源码分析 三之 解释器污点传播
- LeetCode : atoi My solution
- Android Application类以及其作用
- ACM Backward Digit Sums(挑战程序设计竞赛)
- HTML里margin-left和left的区别
- python wsgi 网络编程3 出错
- 题解053-443(V13.02版本,711题)
- cocos2dx面试题整理
- Session详解之web服务开发