Before you start reading this article you must have some basic assembly knowledge, so if your skills are a little rusty, here are some good resources you can use to learn from:
There are plenty of articles in the Internet about what we are going to see today, but not the way i'm going to show it to you ;) but first Why the need to encrypt your application's source code? Maybe from being Reversed?! Maybe you already know about it and maybe you don't, however let me give you a little idea about what Software Reverse Engineering is, it's simply opening a program inside a tool called debugger(such as OllyDebugger, SoftICE, Immunity Debugger...) to make it's features fully working after they've been restricted only for the ones who buy it, it could be also for competitive purposes, etc...
- Introduction to Assembly Language : http://www.swansontec.com/sprogram.html
- Iczelion's Win32 Assembly Homepage : http://www.woodmann.com/RCE-CD-SITES/Iczelion/index.html
- Lord Noteworthy's Pas à Pas vers l’Assembleur : http://asm.developpez.com/cours/noteworthy/
So let's assume you have made an application and you want to protect some sensitive areas in your code (license key verification routine for example) from being reversed?, then you'll have to use an extension (example: compressor, protector, cryptor, etc...) which uses an extra protected/crypted code that jumps in a secure way to the original code, but that will only delay RE, because everything is just Crackable :) it could also be used to confuse antivirus engines from identifying malicious behaviors. So today we are going to concentrate on the code encryption part only, because there are numerous methods of Anti-RE. and we just don't want to get wasted :)
As the title says what we are going to see today is called a "Self Decryption Code" so what is this? this means the software decrypts a part of itself at runtime, which requires a decrypter stub inside the software and an encrypted code. There are many encryption methods such as XOR, RC4, Blowfish, Tea, etc..., some are static(with a static decryption key) and some are Dynamic (changes everytime) and there are many other methods..
But today we are going to see the Static Decryption method which is honestly easy to reverse. but that only depends on how you want it to be. And we want to protect that little part where the calculation and verification happens! let's see how to do that.
We will try to encrypt the following code by using the XOR encryption with a key.
We're going to encrypt the following part of our code :
00401054 5A POP EDXfirst of all let's do that mainly
00401055 B8 DEC00000 MOV EAX,0C0DE
0040105A BB A5BB0000 MOV EBX,0BBA5
0040105F 2BC3 SUB EAX,EBX
00401061 3BD0 CMP EDX,EAX
we are gonna use a 1 byte key i have chosen: 41(h)
as you might already know every instruction starts with a number that is called an OpCode that determines the nature of that instruction, example: in the x86 family 0x6A correspond to the PUSH instruction, and so on :) so what we are going to do is to encrypt each opcode with the key we've chosen:
5A xor 41 = 1B
B8 xor 41 = F9
DE xor 41 = 9F
...
3B xor 41 = 7A
D0 xor 41 = 91
which will give us the following encrypted code:
1B F9 9F 81 41 41 FA E4 FA 41 41 6A 82 7A 91
but in assembly (WinASM precisely) it has to be like this:
EncData db 01Bh, 0F9h, 09Fh, 081h, 041h, 041h, 0FAh, 0E4h, 0FAh
db 041h, 041h, 06Ah, 082h, 07Ah, 091h
now comes the implementation part, so let's make our decryption algorithm:
Decrypt: ; Start of decryption algorithm
mov edx,offset EncryptedPart ; edx is used as a pointer to the address where we will put our decrypted code
invoke VirtualProtect,edx,15,PAGE_EXECUTE_READWRITE,addr oldProt ; we use this function to give us permission to execute, read and write visit http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898%28v=vs.85%29.aspx for more..
mov esi, offset EncryptedPart ; starting address of the place where we will put our decrypted code (Code Cave)
mov edi, offset EncData ; edi = our encrypted code
mov ecx, 15 ; ecx is used here as a counter
xor eax, eax ; eax = 0
DecryptionLoop: ; start of decryption routine
mov al, byte ptr [edi] ; al = edi+1 byte
xor al,41h ; here is where the magic happens :)
mov byte ptr [esi], al ; move al to esi (remember it? it's the address)
inc esi ; increament esi (esi+1)
inc edi ; increament edi (edi+1)
loop DecryptionLoop ; until ecx = 0
jmp EncryptedPart ; jump to our encrypted routine
that was just the decryption algorithm, now we're going to set a place for the decrypted code to take action:
remember that we did not encrypt the whole code..
invoke GetDlgItemInt,hWin,1001,addr szCode,NULL
mov edx,eax
push edx
jmp Decrypt
EncryptedPart:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
jnz @WRONG
invoke SetDlgItemText,hWin,1001,addr Correct
ret
@WRONG: invoke SetDlgItemText,hWin,1001,addr Wrong
ret
in the above code we get a typed integer and had put it in edx and then jump to the decryption algorithm where those 15 NOP's (because we had encrypted 15 bytes) are going to be replaced by, and if everything goes well you will either get a Wrong or Correct message.
As a conclusion, i must say that the example given above is the most easiest thing a reverser could encounter, but there are many ways of making your decryption code much more harder and complicated, but remember that nothing is impossible especially in this domain ;) and hopefully i cover more of this in my future posts.
Hope this was a useful article. Now i will let you with your imagination.
Attachement : Exemple[Self_Decryption_Code].rar