+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
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.
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 ?
K_Address UINT ?
C_Lenght UINT ?
C_Offset UINT ?
VxD_Block ends
xd VxD_Block ;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 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
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 Fravia'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 Fravia 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
-------------------
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