After some cleanup I managed to get the unique code verification blocks, and narrowed them down to 35. This excludes various junk instructions inserted and different registers/memory locations. Below is the code I used to find the unique instances.
for (int i = 0; i < m.size(); i++) {
Vertex n = (Vertex) m.keySet().toArray()[i];
int size = m.get(n).size();
for (int j = 0; j < size; j++) {
Vertex v = m.get(n).get(j);
if(!v.isLoop)
continue;
long hash = 0;
MessageDigest md5 = MessageDigest.getInstance("MD5");
for (int k = 0; k < v.insns.size(); k++) {
Instruction in = v.insns.get(k);
if(in.bytes.length == 2 && in.bytes[0] == (byte)0xEB && in.bytes[1] == (byte)0x0)
continue;
md5.update(in.opMnemonic.getBytes());
}
hash = ByteBuffer.wrap(md5.digest()).getInt();
if(occurrences.putIfAbsent(hash, v.insns) == null)
{
System.out.println("added");
}
else
{
System.out.println("not added");
}
}
}
However, those 35 unique instances are variations of two operations, xor and add. So xor and add mutated to 35 unique blocks of code, multiplied a bunch of times to 22718.