+HCU's special Project: 'Our protections'

CRYPTOGRAPHY AND MATHEMATICS OF CHAOS

by +RCG, 14 January 1998

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

```          CRYPTOGRAPHY AND MATHEMATICS OF CHAOS

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
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.

THE PROTECTION

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

'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
lenght.)

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.

VXD.VXD

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:

.code
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
ret
OpenVxD:push    L NULL
push    L FILE_FLAG_DELETE_ON_CLOSE
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

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

In C:

VxDHandle = CreateFile( VxDName, 0, 0, NULL,0,
FILE_FLAG_DELETE_ON_CLOSE,NULL );

VxdRet = DeviceIoControl(VxDHandle,1,&I_BUFFER,
sizeof(I_BUFFER),&O_BUFFER,sizeof(O_BUFFER),
&VxDBytesRet,NULL);

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 ?
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_Lenght],K_LEN-1        ;L_Len equ ??
call    UseVxD
mov     eax,vxdbytesret
cmp     eax,-1
je      No_VxD

Crippled_Function_Init:
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_Lenght],K_LEN-1        ;L_Len equ ??
Crippled_Function_End:
call    UseVxD
ret or jmp

THE VXD SOURCE

.386p
.xlist
include	vmm.inc
include vwin32.inc
.list

;============================================================================
;                         S O M E   E Q U
;============================================================================

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

VXDBODY_MAJOR_VERSION    EQU     1
VXDBODY_MINOR_VERSION    EQU     0

L_KEY                   EQU 16
ErrorCode               EQU 0FFFFFFFFh

;============================================================================
; 			  P U B L I C   D A T A
;============================================================================

VXD_LOCKED_DATA_SEG

FLAGS   dd 0
SYS_VM  dd 0
LDT     dd 0

VXD_LOCKED_DATA_ENDS

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

VXD_LOCKED_CODE_SEG

DECLARE_VIRTUAL_DEVICE VXDBODY,  \
VXDBODY_MAJOR_VERSION,   \
VXDBODY_MINOR_VERSION,   \
VXDBODY_Control, ,       \
UNDEFINED_INIT_ORDER

;=================
;M A I N   C O D E
;=================

public VXDBODY_Control
VXDBODY_Control PROC NEAR

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

VXDBODY_Control ENDP

Public VXDBODY_ioctl
BeginProc VXDBODY_ioctl

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

Function1:
call    Decrypt
jmp     RetSuccess

RetSuccess:
xor     eax, eax     ;return zero = success
mov     [esi].lpcbBytesReturned,eax
clc
ret
RetFail:
mov     eax,ErrorCode
mov     [esi].lpcbBytesReturned,eax
stc
ret

EndProc VXDBODY_ioctl

Decrypt:    pusha                       ;Save all registers
mov     edi,[esi].lpvInBuffer ;Points to our struct
mov     ecx,[edi+8]         ;C_Lenght
mov     edx,esi
mov     eax,[edi]           ;K_Lenght
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
ret

Public VXDBODY_Device_Exit
BeginProc VXDBODY_Device_Exit

clc
ret

EndProc VXDBODY_Device_Exit

VXD_LOCKED_CODE_ENDS

VXD_ICODE_SEG

BeginProc VXDBODY_Device_Init

clc
ret

EndProc VXDBODY_Device_Init

VXD_ICODE_ENDS

end

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

```

```Hi.

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
ourprot.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
```
-------------------
-------------------
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
-------------------
-------------------```

OK, now back to Our protections