#### Topic: Not so random random()

Suppose that you wrote a polymorphic engine and implemented as many different encryption operations as you can, when your virus reaches the AV lab and tested with some kind of automation to check what it is fit for. And finally a record in the av database which will cover all possible outputs of the PE without even touching the PE code. What about the following trick - one could skew the probabilities for different PE features. Instead of choosing randomly between, say, ADD, SUB, XOR, one could make the following - choose ADD or SUB with probability close to 0.5, with 1/1000 choose XOR. This will increase the chances that AVer would miss some features of the PE (*because it is very rare at occurence*). This could be done with simple wrapper for random:

```
int prandom(int count, ...)
{
uint32_t a[count], i, r, m, s, w;
va_list ap;
va_start(ap, count);
for (s = 0, i = 0; i < count; i++) {
a[i] = va_arg(ap, uint32_t);
s += a[i];
}
r = random();
m = RAND_MAX / s;
for (w = 0, i = 0; i < count; i++)
if (r < (w += a[i] * m))
return i;
va_end(ap);
return count - 1;
}
```

So, the recurrent calls to prandom(5, 5, 10, 15, 20, 50) would produce something like:

4 1 4 4 4 4 1 4 3 4 2 4 3 2 4 3 3 4 0 1 ...

With probabilities (on a large series) are very close to the specified weights.

0.049480 0.100040 0.150120 0.201060 0.499300