+HCU's special Project: 'Our protections'

by +RCG, 14 January 1998

(with a small addition by Scut, 30 October 1998)


At this time you must be asking yourself what this title 
has in common with our reversing purposes, well: after all, 
our main purpose is "TO LEARN", don't forget it, and 
reversing is one of the main fonts of our knowledge.

BTW, this doc will teach you to protect, and I will also
attach "the oficial HCU protector program" and then we
will wait for someone able to reverse it.
Don't worry I will explain you how it works (also I will
attach the source, but this won't help you too much from
a cracking point of view).

Let me first introduce you a basical outline of Cryptography,
"if you use a non repetitive key, the decrpyt is imposible".
Think for a moment that today we are using a 128bit key and
this is impregnable, so think if we use a "infinite" key.

Next step is to create a "infinite" key absolutely randomly,
but hoW?...the answer is The Chaotic Maths.

Our problem is to create a key (always the same) with a few
information (we can't store the complete key), so we use some
functions to get it "on the fly".

The most used is x^2 (and its derivatives) because it is an easy
programmable function, lets see some examples:

1) f(x+1)=K*x^2-1
2) f(x+1)=K*x(1-x)    with 3 Period is 4
K=3,567 ==> Period is 16
K=3,57  ==> Period is very big
K=3,58  ==> Period is infinite (chaos)
At this point we have info enought to make our protection
mechanism. Think for a while and sure you will be able to
take profit of this info.


After having writting our complete program, we will
write down the offset and the lenght of our crippled
routine(s) and use 'crypto.exe'


This is a small and basic program that reads for a file
named key.dat a 128bit value and uses it to XOR the
offset of the filtoxor.exe 'lenght' bytes.
(I have programmed crypto to 128bit key but at the
EQU section you can change the value and to use any

BTW, look at this:

	Let's encrypt 28h twice (with 07h and 0Dh)

	28h xored with 07h is 2Fh
	2Fh xored with 0Dh is 22h
	07h xored with 0Dh is 0Ah 

	22h xored with 0Ah is 28h

What this can useful for?...this is a way to avoid
public keys for our program, at the instalation time,
we can xor the previous xored crippled routine with
a random value (the free space of your HD, the lenght
of the swp file,some arbitrary bytes of any file or
the time stamp of something, it is your decision)
I have not implemented it in my little example.


This is the most important part of the protection.
You know a VxD runs at privilege level 0 so it can
do all we want, we will use this fact to write (decrypt)
at code areas of our program.

So we must initialize the VxD and later use it, how?

In Assembler:

UseVxD: push    L NULL
        push    offset VxdBytesRet      ;lp to bytes returned
        push    L FALSE                 ;size of output buffer
        push    L NULL                  ;lp to output data
        push    L FALSE                 ;size of input buffer
        push    L offset xd           	lp to input data
        push    L 1                     ;Control code 1 (VxD check it
        push    [VxDHandle]
        call    DeviceIoControl
OpenVxD:push    L NULL
        push    L FALSE
        push    L NULL
        push    L FALSE
        push    L FALSE               
        push    offset VxDName
        call    CreateFileA
        cmp     eax,-1
        je      VxDErr
        mov     VxDHandle,eax
VxDErr:	ret

VxDHandle	dd 0
VxDName 	db '\\.\vxd.vxd',0
VxdBytesRet	dd 0

In C:

	VxDHandle = CreateFile( VxDName, 0, 0, NULL,0,
	VxdRet = DeviceIoControl(VxDHandle,1,&I_BUFFER,

BOOL DeviceIoControl(
HANDLE hDevice,	// handle to device of interest
DWORD dwIoControlCode, //control code of operation to perform
LPVOID lpInBuffer, // pointer to buffer to supply input data
DWORD nInBufferSize, // size of input buffer
LPVOID lpOutBuffer, // pointer to buffer to receive output data
DWORD nOutBufferSize, // size of output buffer
LPDWORD lpBytesReturned, // pointer to variable to receive output byte count
LPOVERLAPPED lpOverlapped // pointer to overlapped structure
   		      // for asynchronous operation

So we must create a struct to pass to the VxD with:

VxD_Block struct
        K_Lenght      UINT ?
        K_Address     UINT ?
        C_Lenght      UINT ?
        C_Offset      UINT ?
VxD_Block ends

xd	VxD_Block 	;Create a structure

Now, we will create a VxD with only one function, maybe in
a future we can add some other functions (like snap Winie while
our program runs, BTW it is very very easy :-(  
See the example:

        lea     esi,Crippled_Function_Init
        mov     [xd.C_Offset],esi
        lea     edi,Crippled_Function_End
        sub     edi,esi
        mov     [xd.C_Lenght],edi
        lea     esi,Key_Data
        mov     [xd.K_Address],esi
        mov     [xd.K_Lenght],K_LEN-1        ;L_Len equ ??
        call    UseVxD
        mov     eax,vxdbytesret
        cmp     eax,-1
        je      No_VxD 
	push    L MB_ICONEXCLAMATION    ;Lets disorder a little
        push    offset szTitleName	;Don't be obvious
        push    L 0			;use junk code also
        call    MessageBeep		;You saw like +Zer0       	
        push    offset Congtext 	;found my key easily :-(  
        push    [hwnd]         
        call    MessageBoxA		;End of our crippled function
	lea     esi,Crippled_Function_Init	;Encrpyt it again
        mov     [xd.C_Offset],esi
        lea     edi,Crippled_Function_End
        sub     edi,esi
        mov     [xd.C_Lenght],edi
        lea     esi,Key_Data
        mov     [xd.K_Address],esi
        mov     [xd.K_Lenght],K_LEN-1        ;L_Len equ ??
  	call    UseVxD
	ret or jmp 


	include	vmm.inc
	include vwin32.inc

;                         S O M E   E Q U 

VXDBODYName              EQU     <'VXDBODY VXD      '> ;Must be 16 chars
VXDBODYRev               EQU     00H


L_KEY                   EQU 16
ErrorCode               EQU 0FFFFFFFFh

; 			  P U B L I C   D A T A


FLAGS   dd 0
SYS_VM  dd 0
LDT     dd 0


;D E V I C E   D E C L A R A T I O N


        VXDBODY_Control, ,       \

;M A I N   C O D E

public VXDBODY_Control

        Control_Dispatch SYS_DYNAMIC_DEVICE_INIT,       VXDBODY_Device_Init
        Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT,       VXDBODY_Device_Exit
        Control_Dispatch W32_DEVICEIOCONTROL,           VXDBODY_ioctl


Public VXDBODY_ioctl
BeginProc VXDBODY_ioctl

	mov	ecx,[esi].dwIoControlCode	; get ioctl code
        cmp     ecx,1
        je      Function1
        jmp     RetSuccess

        call    Decrypt
        jmp     RetSuccess

        xor     eax, eax     ;return zero = success
        mov     [esi].lpcbBytesReturned,eax
        mov     eax,ErrorCode
        mov     [esi].lpcbBytesReturned,eax

EndProc VXDBODY_ioctl

Decrypt:    pusha                       ;Save all registers
            mov     edi,[esi].lpvInBuffer ;Points to our struct
            mov     ecx,[edi+8]         ;C_Lenght
            mov     esi,[edi+4]         ;K_Address
            mov     edx,esi
            mov     eax,[edi]           ;K_Lenght
            add     edx,eax             ;edx=end of key
            mov     ebx,edi
            mov     edi,[edi+12]        ;C_Offset
Bucle:      mov     al,[edi]
            xor     al,[esi]
            mov     [edi],al
            inc     edi
            dec     ecx
            test    ecx,ecx
            je      EndBucle
            inc     esi
            cmp     esi,edx
            jbe     Bucle
            mov     esi,[ebx+4]         ;Restore Key
            jmp     Bucle
EndBucle:   popa

Public VXDBODY_Device_Exit
BeginProc VXDBODY_Device_Exit


EndProc VXDBODY_Device_Exit



BeginProc VXDBODY_Device_Init


EndProc VXDBODY_Device_Init



That's all!!! shareware writers you better begin
to use these kind of protections, yes I also hate 
lamers, use my VxD freely (soon I will add new 
options, so remember to visit Reverser's Page frequently).

Next step is to create your own VxD, I will teach you
(at least a little.)

On May I promised to develop our own VxD, now we have
the first, but this wouldn't be posible without the
help (and the friendship) of Reverser and specially of
Mammon, thanks to both, friends.

+rcg 1998 


I just want to make a short statement of the cryptographic point of
view of this essay.
I want to make clear, that I think the vxd and external callable en-
cryption/decryption functions are quite useable, but from cryptographic
point of view weak.

Cryptographic weakness is not always practical weakness, a
cryptographic system is weak if it is possible to derive the cleartext or 
the key in a "natural" (angemessender) time.

So, first, there is Shannons theorem of cryptography/complexity, which 
clearly states, that there is a perfect cryptosystem, but only one where
are as much different keys possible as different messages are possible.

So the perfect cryptosystem already exists, but the key is as long as
the cleartext, and this in unpracticable, although it was already used in 
WWII for example. The basic idea is to create a cryptographic safe
(random) stream of data to combine the cleartext with from the short 
key (in the essay 128b).

This was meant in short phrase "if you use a non repetitive 
key, the decrpyt is imposible" in the essay.

Now, although everything mentioned to this point is true, the next step 
is not clear, and is just one (not very good) way to go. The author, 
RCG says we have to switch to chaos math just because it is
statistically random (appear random).
But even this "chaos" math is predictable. There are, (also mentioned
in the essay) weird attractors, which produce nearly unpredictable (random)
combinatinos, but there are also very stable points, that produce
always the same or cycling data, the data is not cryptographic random anymore.
Although maybe there may be a safe part of cryptographic random derived 
from the key i think most of the data is not random enough.

Because the whole security of this protection relies on the randomness
of the data stream created, I don't think we (the protectionists) should 
create our "own" algorithms, but trust into already existing ones, 
analyzed for years by non-govermental cryptographic experts, easier to 
implement (or readily available at source level), faster, safer and
more secure to use.

Also, even if the protection is unsafe it is unfair to provide a
crackme-like challenge based on cryptographic routines without
supplying a few valid keys, which is the reality situation authors fear.

In my opinion a protection should always rely on mathematics, never on 
anti-debugging, cracker-harassing or code-messing tricks, but the last 
hole, even in our "perfect" protection will never be solved: the user,
which gives away the valid key.

cu, scut (scut@nb.in-berlin.de)

- elitec - a generation ahead -

Back to Our protections
No, no, no! I want to go FURTHER and download the whole lot by +RCG
redourprot.zip (36.611 bytes. Don't forget to pkunzip -d for recursives subdirectories)
Well, in that case you'll have to wait until I'm sure that +RCG wants me to publish this zipped file... in the meantime here is what you would have found inside ourprot.zip

dirssing C:\PRIVATE\mypa\cafe\rcg32\OurProt.ZIP begin
OURPROT  ZIP        36.611  12/01/98  18:38 OurProt.ZIP
Directory of C:\PRIVATE\mypa\cafe\rcg32
TEMP           <DIR>        13/01/98   9:23 TEMP
CRYPTO1  TXT        17.185  12/01/98  12:47 CRYPTO1.TXT
         3 file(s)         53.796 bytes

Directory of C:\PRIVATE\mypa\cafe\rcg32\TEMP
TASM           <DIR>        13/01/98   9:23 TASM
DDK95          <DIR>        13/01/98   9:23 DDK95
         0 file(s)              0 bytes

Directory of C:\PRIVATE\mypa\cafe\rcg32\TEMP\DDK95
VXDBODY        <DIR>        13/01/98   9:23 VXDBODY
         0 file(s)              0 bytes

Directory of C:\PRIVATE\mypa\cafe\rcg32\TEMP\DDK95\VXDBODY
MAKEFILE               381  12/01/98  12:53 MAKEFILE
DO       BAT            56  12/01/98  12:52 DO.BAT
VXD      ASM         3.152  12/01/98  12:51 VXD.ASM
VXD      DEF         1.174  12/01/98  12:52 VXD.DEF
VXD      VXD         4.657  12/01/98  12:53 VXD.VXD
         5 file(s)          9.420 bytes

Directory of C:\PRIVATE\mypa\cafe\rcg32\TEMP\TASM
CRIPPLED       <DIR>        13/01/98   9:23 CRIPPLED
CRYPTO         <DIR>        13/01/98   9:23 CRYPTO
         0 file(s)              0 bytes

Directory of C:\PRIVATE\mypa\cafe\rcg32\TEMP\TASM\CRIPPLED
HEAVY    RES           728  09/01/98  17:45 HEAVY.RES
EXTRN    INC         2.113  12/01/98   3:49 EXTRN.INC
HEAVY    ASM         9.505  12/01/98   4:54 HEAVY.ASM
HEAVY    DEF           235  20/12/97  11:52 HEAVY.DEF
HEAVY    EXE         8.192  12/01/98   4:55 HEAVY.EXE
DO       BAT            31  12/01/98   4:49 DO.BAT
KEY      DAT            16  12/01/98   4:01 KEY.DAT
MAKEFILE               584  12/01/98   2:48 MAKEFILE
VXD      VXD         4.657  12/01/98  12:53 VXD.VXD
WIN32    INC        16.032  12/01/98   3:44 WIN32.INC
        10 file(s)         42.093 bytes

Directory of C:\PRIVATE\mypa\cafe\rcg32\TEMP\TASM\CRYPTO
MAKEFILE               650  06/06/98  15:44 MAKEFILE
CRYPTO   DEF           235  20/12/97  11:52 CRYPTO.DEF
CRYPTO   EXE         8.192  08/01/98  12:07 CRYPTO.EXE
CRYPTO   RES           332  08/06/98   0:06 CRYPTO.RES
DO       BAT            34  08/01/98  12:02 DO.BAT
EXTRN    INC         2.293  07/06/98  16:21 EXTRN.INC
KEY      DAT            16  07/06/98  16:42 KEY.DAT
CRYPTO   ASM        10.420  08/01/98  12:09 CRYPTO.ASM
WIN32    INC        15.855  16/03/97  23:41 WIN32.INC
         9 file(s)         38.027 bytes

Total files listed:
        27 file(s)        143.336 bytes
        20 dir(s)   1.461.321.728 bytes free
dirssing C:\PRIVATE\mypa\cafe\rcg32\OurProt.ZIP end

OK, now back to Our protections