We’re seeing new Waled malware today, and the custom packer it’s using has changed again. In fact it’s using a decryption trick to hide its code that I thought was worth sharing.
The decryption code starts off by changing the access to itself by calling VirtualProtect, to allow it read-write access instead of just read access:
VirtualProtect takes four arguments – the address on which to change the protection, the length to apply this change, the new access protection, and an address to store the old access protection. In this case the address to change is shortly before the range of bytes to be decrypted, the size (
0x6D9) incorporates the bytes that are going to be decrypted, the new access protection is
0x40 (PAGE_EXECUTE_READWRITE), and the old memory protection is stored at a later offset (
Then immediately after this we have the decryption loop itself:
Before the loop it get a length to decrypt (
0x125), a decryption key from a later offset (
0x4EDFC4), and a pointer to the earliest address to be decrypted (here halfway through the operator which completes the decryption loop). The decryption loop itself then xors with the key it just picked up, adds a fixed key byte (
0xB5), decrypts the length counter, and repeats.
What’s interesting here is the decryption key byte – the offset it gets picked up from falls isn’t in the file’s initialised data as it falls between sections. This is something we’ve seen used recently in the context of jumping to an offset that’s between sections (see my blog on cliff-jumping code), but unless the decryption key is zero there must have been some earlier code that stored something else there.
And so indeed there is – when VirtualProtect changes the access protection to a piece of memory, it makes a note of the original memory protection. Usually this isn’t a value you care about very much, but in this case it stored that value at the same uninitialised address from which the decryption key is later obtained.
So when VirtualProtect changes the access protection to
0x40 (PAGE_EXECUTE_READWRITE) it stores the old value of
0x20 (PAGE_EXECUTE_READ) at an offset that lies between sections, and then picks this value up again to use it as a key in decrypting the rest of the Waled custom packer.
We’re detecting these new files as Mal/WaledPak-A, and the pages they’re being seen on (detected as Mal/WaledJs-A) are still touting love-based ecards and Valentine’s Day “devkits” – I’d expect to see a couple more changes to the packer before February 14th.