# Arithmetic Obfuscation

Because of the design of the Java bytecode, arithmetic operations are (usually) exactly translated in their dedicated bytecode.

For instance, if we consider the following Java code:

```
int doAdd(int a, int b) {
return a + b;
}
```

Once compiled, it generates the following instructions:

```
int doAdd(int, int) {
Code:
0: iload_1
1: iload_2
2: iadd
3: ireturn
}
```

Moreover, the Java arithmetic opcodes are strongly typed:

`iadd`

for integer number addition.`ladd`

for long number addition.`fadd`

for floating numbers addition.`dadd`

for double numbers addition.

It means that decompilers can reliably determine the type of the arithmetic operands and efficiently decompile arithmetic expressions.

In addition, decompilers are doing simplifications on the top of these expressions (like constant propagation).

Similarly to the Arithmetic Obfuscation in O-MVLL, this pass transforms arithmetic operations into Mixed Boolean-Arithmetic expressions (MBA).

## When to use it?

You should use this protection when arithmetic operations matter in the logic of your class. This is particularly true for:

- Cryptography algorithms (known or custom).
- Encoding algorithms.
- Bitwise manipulations.

## How to use it?

Within the dProtect configuration file, we can enable this protection with:

```
-obfuscate-arithmetic <class specifier>
```

In addition, this `-obfuscate-arithmetic`

option accepts the following modifiers:

```
-obfuscate-arithmetic,low <class specifier>
-obfuscate-arithmetic,medium <class specifier>
-obfuscate-arithmetic,high <class specifier>
```

`low, medium, and high`

define the number of transformations applied to a single operation:

```
[->] Operation: X ^ Y [<-]
low : (X | Y) - (X & Y)
medium : (((Y + X) - (Y & X)) ^ ((Y | X) - (Y + X))) + 2*(((Y + X) - (Y & X)) & ((Y | X) - (Y + X)))
high : <not printable>
```

Level | Number of Iterations |
---|---|

`low` | 1 |

`medium` | 2 |

`high` | 3 |

In the future, `-obfuscate-arithmetic`

might also accept other modifiers to disable/enable this obfuscation
on categories of instructions:

```
-obfuscate-arithmetic,skiparray <class specifier>
-obfuscate-arithmetic,skipfloat <class specifier>
```

Nevertheless, the support of these extra modifiers will require some changes in the design of the pass.

## Implementation

To transform arithmetic operations into Mixed Boolean-Arithmetic expressions (MBA), the pass implements the
`proguard.obfuscate.util.ReplacementSequences`

interface which provides the API to define rewriting rules:

```
import proguard.obfuscate.util.ReplacementSequences;
public class MBAObfuscationAdd implements ReplacementSequences {
...
@Override
public Instruction[][][] getSequences() {
return new Instruction[][][]
{
// X + Y --> (X & Y) + (X | Y)
{
// Sequence of instructions to match
____.iload(X) // |
.iload(Y) // |
.iadd() // | X + Y
.__(), // |
// Transformation
____.iload(X) // | First term
.iload(Y) // |
.iand() // | X & Y
.iload(X) // | Second term
.iload(Y) // |
.ior() // | X | Y
.iadd() // | Addition of the previous terms
.__(), // | (X & Y) + (X | Y)
```

Given the different rewriting classes associated with arithmetic operations, they are successively
applied on the class pool using the Proguard `MultiMemberVisitor`

visitor:

```
programClassPool.accept(
new AllClassVisitor(
new MBAObfuscationFilter(
new AllMethodVisitor(
new MultiMemberVisitor(
new InstructionSequenceObfuscator(new MBAObfuscationAdd(...)),
new InstructionSequenceObfuscator(new MBAObfuscationXor(...)),
new InstructionSequenceObfuscator(new MBAObfuscationAnd(...)),
new InstructionSequenceObfuscator(new MBAObfuscationOr (...)),
new InstructionSequenceObfuscator(new MBAObfuscationSub(...))
)))));
```

`MBANormalizer`

visitor.## Limitations

Classical arithmetic operations on **integers** and **longs** are **supported** by the pass. Nevertheless,
the pass **does not (yet) support** expressions with inner operations in the **left and right operands**:

```
int A = B + C; // Supported
int A = (B >> 3) + (C << 4); // /!\ Addition not supported
int A = (B & 0xFF) + (C | 1); // /!\ Addition not supported
```

In addition, the operations on **floats** and **doubles** are **not yet supported** but following the existing
rules on integers/long, it should not be complicated to support.

For array operations (e.g. `table[i] + table[y]`

), there is early support but it is far from being complete.