It means Work backwards from the result
So far in Data Flow Analysis we have learned where the data comes from and what path it takes
Backward Slicing
is exactly the opposite
Here we start from a significant point and work backwards to understand what caused that result
For example, suppose we have this code:
C++
int process(int a, int b)
{
int x = a + b;
int y = x * 2;
int junk = 500;
junk ^= 123;
return y;
}
If our goal is to return y, we start at y
We ask:
Where did y
come from?
Answer:
y = x * 2
So now we need to figure out where x came from
x = a + b
So a and b affect the output
Now if we look at junk we see that it has no path to y or output
So we can ignore it completely for now in this analysis
The Backward Slice path looks like this:
Return y
↑
y = x * 2
↑
x = a + b
↑ ↑
a b
This method is especially useful when you are dealing with a very large and busy function
Because you do not have to analyze everything from the beginning to the end of the function. First, you specify what you are looking for
For example:
The result of a condition
The output value
An important address
A value written to memory
Or an important function
Then you start from that point and go back
Suppose you see this in the disassembler:
cmp eax, 1
jne failed
The important question is not where jne goes
First, you should Ask:
Where did the EAX value come from before this comparison?
There may have been a few statements:
call check_value
Now you need to go back and see what check_value returns
Or maybe EAX came from a long calculation
In this case, Backward Slicing helps to check only the statements that actually affect the final value of EAX
This is very important in obfuscated programs because there may be a hundred extra statements around an important condition
But maybe only ten statements actually affect the result of that condition. The goal of Backward Slicing is to find exactly that statement
An important point is that you should not only look for direct dependencies
For example:
A affects B
B affects C
C affects the result
So A is also part of the Slice even if it is not directly connected to the result
Exercise:
Check this function:
C
int verify(int input)
{
int a = input * 2;
int b = a + 15;
int temp = 100;
temp += 50;
int result = b ^ 0x33;
return result;
}
Start from return result and work backwards to determine which variables really affect the output
Then draw the path on paper
input
↓
a
↓
b
↓
result
↓
return
temp
Check it out, you'll see that there are a few operations that are performed but have no effect on the output, and this is exactly where Backward Slicing helps us get straight to the point in the middle of a lot of code
@reverseengine