getName方法源码
getName为被分析的方法,代码如下:
package org.example;
public class C {
public void use(){
int k = 1;
getName(1);
}
public String getName(int orderNum) {
int j = 0;
int k = orderNum +j;
if ( orderNum > j ) {
k = orderNum + j;
}
while(orderNum < j) {
orderNum ++;
k ++;
}
return "";
}
}
getName方法的CFG
%0 = 0
%1 = arg$0 + %0
%2 = %1
%5 = %2
if (arg$0 <= %0)
goto JcInstRef(index=10)
%3 = arg$0 + %0
%2 = %3
%5 = %2
goto JcInstRef(index=10)
if (arg$0 >= %0)
goto JcInstRef(index=15)
arg$0 = arg$0 + 1
%5 = %5 + 1
goto JcInstRef(index=10)
return ""
ifds分析getName方法时处理的edge(指令/三地址码)
------------>Start-Facts<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 8
startStatement: noop
facts: [[ZERO fact]]
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 8
current: noop
next: %0 = 0
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 9
current: %0 = 0
next: %1 = arg$0 + %0
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 10
current: %1 = arg$0 + %0
next: %2 = %1
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 10
current: %2 = %1
next: %5 = %2
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 11
current: %5 = %2
next: if (arg$0 <= %0)
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 11
current: if (arg$0 <= %0)
next: goto JcInstRef(index=10)
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 11
current: if (arg$0 <= %0)
next: %3 = arg$0 + %0
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 11
current: goto JcInstRef(index=10)
next: if (arg$0 >= %0)
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 12
current: %3 = arg$0 + %0
next: %2 = %3
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 14
current: if (arg$0 >= %0)
next: goto JcInstRef(index=15)
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 14
current: if (arg$0 >= %0)
next: arg$0 = arg$0 + 1
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 12
current: %2 = %3
next: %5 = %2
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 14
current: goto JcInstRef(index=15)
next: return ""
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 15
current: arg$0 = arg$0 + 1
next: %5 = %5 + 1
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 12
current: %5 = %2
next: goto JcInstRef(index=10)
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 16
current: %5 = %5 + 1
next: goto JcInstRef(index=10)
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 12
current: goto JcInstRef(index=10)
next: if (arg$0 >= %0)
------------>Normal<------------
positionMethod: (id:72)org.example.C#getName(int)
lineNumber: 16
current: goto JcInstRef(index=10)
next: if (arg$0 >= %0)
图示遍历过程
此处需要注意的是遇到条件判断语句时,由于静态分析无法判断条件是否成立,遇到条件语句时遍历path会拆分成两条。这就虽然CFG中if (arg$0 <= %0)只出现一次,ifds遍历时这条指令出现了两次的原因。上图的虚线说明,静态分析中循环语句并不会多次进入分析循环中的指令。