Encrypt functions in Windows executables
This is a part of my tutorial on how to protect windows executables, so is a little bit disconnected from my others posts, but in wait of my big tutorial I publish this anyway.
Something that you can apply with the others encryption tricks in PE files is the encryption of function, and decrypting at calling time.
I found this trick with the Zer0Mem0ry post originaly made to bypass memory signatures checks by encrypt functions at runtime. With random xor, so A big thanks to this good guy 😃
But wait, why use function encryption if we can just encrypt segments, In my point of view, if you make the all segments encrypted, the dissasembler will see only functions related to the decryption of the segments. So immediately you will see where the code is decrypted, I think that having a lot of functions is more efficient in this case. There is a lot of “pros and cons” about this trick and I will discuss a bit about them at the end
You can also link the decryption key to licence system, so the function is running only if the software is licenced . . .
This is, again, to make at the end of the software conception, because addresses will be modified for each little changes, so first we will setup all code stuff, with the right space in memory, and after we edit the code with right addresses
Proof Of Concept
Here is the function that we wanted to protect
As I said, its address will be hardcoded so take a DWORD
to store it (we will edit it after)
The lenght is the size of the function (hardcoded again)
I remove one byte to the encrypted buffer because for some reason that I could’nt explain, the clean decrypted full buffer in memory will make a unknow exception when the EIP
points to him. So to solve that, I just leave the 0x55
(push ebp) opcode.
If someone could explain this issue, it would be appreciated.
Here is the main function, we change the secret_function protection page status so we can write over it, and we call the decryption function before call the secret_function
, again we can make more efficient way to place the decryption function, but I leave this here
So now, we have the decrypt function, to win time, I will use XOR encryption (because it is the easiest), but you can use any encryption algorithm
I print a hexdump of the secret_function before and after xoring
After taking each byte of the function, I xor all with 0x25
as key, and I write the result at the same place
Just to show the dump function
Now all is ready to work, we have to compile it and grab the address given to us secret_function
So it will be 0x4119b0
For some’s weird reasons, Visual C++ compiler make a sub function before the call of the real function, It’s why I hardcoded the function address. Because when I took the secret_function
pointer, is pointing to the function at 0x411163
function, not the wanted one.
Time to replace the address in the executable (you can do it in the raw executable, it will limitate the chance of realloc new addresses)
To get the xored buffer quickly, I will run the stub with the original opcode in it, normaly the app will make an access violation because of wrong opcode of the function
So now we have the xored buffer, we have just to replace it in the executable. For me I will just use HxD (the best ❤), find the function patern and replace the buffer at the raw file address
And after saving, we are done, and the function is unreadable.
There is just a label pointed to the 0x4119b0 + 1
because we wrote the raw address in code, so IDA quickly made the cross-reference
But with a little bit of obfuscation and higher xor key like we said above, it’s not dificult to hide 🙂
You can improve it by adding obfuscation, or put the decryption state in the function it self, so when it’s called it’s will decrypt it self
Even better in a crackme, you can make the function decryption key a part of the user input 👌
This is a typical exemple of method you could apply with a script or a security program
So is that effective ?
Again, encrypt functions is nice to deceive static analysis in so cases, the main goal of this is to make the decryption method hidden as possible, and the link between the encrypted function and the decryption code hard to understand. Because all the encrypt is useless if we can just link the decryption to the function.
Example, If we apply this to each function of the executable, a home made script could decrypt each function if it’s the same patern again and again.
If it’s too obvious, like all sections of the executable encrypted, it loses its interest
I think it is better to make an encrypted function drown in a big program where it’s difficult to find a particular thing, then encrypt all sections and see instantly where the code is decrypted.
I will precise my point in a future big tutorial.
You have to find the good way to use this in your context.