Heaven’s gate and a chameleon code (x86/64)

A so-called heaven’s gate is not only a built-in feature of a 64-bit Windows, but also a neat reversing trick. It can be used (and is) by malware authors to temporarily switch the code execution between 32- (WOW64) and 64-bit long mode. While operating in a 64-bit long mode it executes the 64-bit instructions and this can be used to execute some funny stuff before returning to 32-bit code (f.ex. can be used to detect a debugger).

The trick is very old, many blogs describe how to mix 32- and 64-bit using it and that’s why it is just part of the topic I am going to talk about today.

A few years back I was looking at a sample that used the heaven’s gate trick, but apart from this, it also contained another trick – a chameleon code – a stream of bytes that could be executed as both 32- and 64-bit code, depending on the context. I found it to be quite cool and took a mental note of that malware family.

I recently came across a different sample from the same family and since this reminded me about that supercool trick, I thought it would be nice to write a post about it.

The sample hash is E4AB5596CB8FBE932670A6A5420E7AB9 (note it is old, from 2013).

Note: Mind you that before it reaches the heaven’s gate/chameleon code it will try to stop you by using a couple of known and lesser-known anti-reversing tricks (there is a number of them, and they are quite creative; I won’t describe it in detail not to spoil the fun in case you want to take a stab at the sample yourself).

The 32-bit code right before jumping far to 64-bit code:

heavensgate1Immediately after the far jump we land in 64-bit code.

heavensgate2Note the offsets of instructions on both screenshots.

Btw. while I am not the biggest fan of windbg for day to day work, its ability to reverse such chameleon code comes really handy.

After some more jumps and calls the code eventually ends in these places (left 32-bit, right 64-bit – 2 different VMs):

heavensgate3We can compare the opcodes and their meanings side by side:

heavensgate4They both execute in their respective modes (32- and 64).

The inability to distinguish between code and data is a well known fact. Ability to code a program that looks identically and executes on two different architectures is a completely different animal.

For what it’s worth – it was written in fasm.

“Malicious” Magic Squares

Update

Found one more 🙂

   L   I   S   T   A   S
   I   M   P   O   R   T
   S   P   U   L   E   R
   T   O   L   O   S   E
   A   R   E   S   E   S
   S   T   R   E   S   S

Old post
As a kid I loved to solve cross-words, I also published my own (together with various riddles).

I was very fond especially of magic squares e.g. a classic one:

S     A     T     O     R
A     R     E     P     O
T     E     N     E     T
O     P     E     R     A
R     O     T     A     S

and palindromes e.g.

malayalam

and anything that would be a bit unusual (e.g. 7-letter words with 4 As, partially overlapping words, etc.).

When I learned programming I wrote various cross-word generators including one for magic squares.

Finding magic squares is very easy for 3-, 4-, 5- letters. It gets a bit more challenging with 6-, but it’s still quite easy and it gets really tough with 7-, 8-, 9- letters.

Having nothing else to do, today I tried to see how my old code would perform taking a small database of malware-related keywords as a base. To my surprise, it actually found a few magic squares for 6 characters!

Here they are:

G   A   G   G   L   E
A   P   R   O   O   L
G   R   O   O   V   E
G   O   O   B   E   R
L   O   V   E   N   A
E   L   E   R   A   D

H   A   L   E   S   S
A   T   O   M   I   C
L   O   O   P   E   R
E   M   P   I   R   E
S   I   E   R   R   A
S   C   R   E   A   M

I   S   T   B   A   R
S   P   A   R   S   E
T   A   R   A   P   A
B   R   A   B   A   N
A   S   P   A   D   E
R   E   A   N   E   T

If you google these words, you will find out that all of them are actual names of a malware.

Bonus

How often do you see a code like this nowadays? Addressing via seg:ofs was a real pain in a 16-bit real-mode 😉

               xor dx,dx
               mov ax,word ptr fs:[si]
               add ax,ax
               adc dx,0
               add ax,ax
               adc dx,0
               shl dx,12
               add dx,CS:DSegm0
               mov es,dx
               mov bx,ax

              [...]