The evolution of the Cool Edit Protection scheme Part iii


Ok, this was to be the penultimate tutorial covering both the 1.53 and
95 versions, with the last tutorial covering the 96 version.  However 
i have just found out that ther will be a 'cool edit 96 pro' which
will have multitrack capabilities and will retail at $399, big bucks.
I sincerly hope that the code has improved since the switch over to
the 32-bit versions which take about a hour to load practically run 
slower and have (nearly) doubled in size.  I feel a sense of 
greed taking over the programmer.  The program started out as a neat
project; the code was fast and compact(ish) and the retail price was
sort of acceptable, of course  +Orc would suggest otherwise (i think) 
but until I find out what he is employed as(that is, find out for sure
he is not a complete hypocrite) I suggest to you that asking 
for a small fee, and I should emphasise 'small', for a fully functional 
version of a program that has taken along time to develop is 
acceptable.  However, I have a terrible feeling that 
the developers at syntrillium now look somthing like this


		 8_--^--_8       
		8/       \8    
		8| $  $  |8  
		O|   |   |O   
		 |       |     
		 \   +   /      
		  \__#__/

.. as I'm sure that they(or he) have been making an increasing amount of 
money. Hence, thay have become overwhelmed by all that 'lovely', powerful
money and are now (i think) about to rip you of completly by selling you
a product that runs at a snails pace, just because they can't wait
for the money to start rolling in, thus don't bother to optimize or
tidy up any of the code.  This is becoming (is already) a huge problem 
as all the stupid fools with their pentium pro's don't realise that 
its crap code because they have been fooled (again) by thinking
that they need a faster computer, but what they really need is better code.
I personally think that giants like micro$oft have a thing going with intel, 



start:

Micro$oft : We will write a crap os that needs load of memory and 
            processor power, for a minimum amount of money.  Because
            we dominate the market, people will by it anyway.

Slave of Society : Oh goody a new, sparkly, trendy, os from MircoSoft
                 , Microsoft are so friendly and nice.

SLAVE of Society spends huge amount of money on Microsoft 2024, spends
2.4 days installing  5000 meg's of complete garbage.

Slave: Oh no this doen't work very well (Slave for a very brief moment
       thinks for him/herself "Microsoft are rip..ppi...g me off")

Then suddenly a blinding light :
Television RADio (and telescreen) all sing out a cool tune proclaiming
Microsoft as god, you friend, someone you can trust...

Slave: Oh no it couldn't be microsoft's fault it must be my own fault,
       lets see. The 4 page manual says minium system 386, 4 megs, oh
       whats this.. minimum system 2000Mhz 989, 512 Megs,.. Ahh it was
       my fault aftre all.  I must by a new computer.

Television, Radio again sing out another cool tune bragging about the
power of the New Intel processor.

Slave: Ah I had better get one of those, they look cool I bet the rolling 
       stones have one just like the one I'm gonna get.
Slave spends another large sum of money on a new processor 
Slave: Ah look at my new sparkly computer and os... how COOL!

Intel, Microsoft : Gotcha!!! 

	if(Mircosoft==TRUE && Intel == TRUE && Slave.free_thought==NULL)
	{
		Year++;
		Microsoft.money+=999999999999;
		Intel.money +=99999999999;
		Slave.money -=9999999;
		if(+HCU.members > HUGE_VAL)
		{
			Micro$oft.money -= 9999999; heh, heh :>
			Destroy(Microsoft);
		}
		goto start;
	}


Sorry got carried away there, hope you get the message... it's 
important.  Don't worry to much about buying software that runs well
and is not developed by a giant.. NB NEVER Never never.. buy a 
micro$oft product NEVER, but always crack them :>

ON WITH THE SHOW
================

Before we start cracking I want to point out that if you are here to
rip out the little C program that I include at the end of my tutorials
, go away there is really no need the codes produced from the last one 
will work even for cool edit 96.  Only the codes from v1.50 will not work
on the 96 version.  
On the other hand if you are here to learn, the protection scheme 
still evolves, while retaining a backwards compatablity with passwords
from earier versions, so we still have alot to learn.
All will be explained.  Sorry to delay the start even further but this is 
an important lesson greatly emphasised by none other then +Orc himself
:- History tells all. Now that that we have (should have) all the 
previously obtained knowledge cracking these more advance schemes, will
be a considerably easier task.
I SAID GET ON WITH THE SHOW
===========================
Without any further delays :

Filename:            COOL.EXE
Type:                Segmented executable
Module description:  Cool Edit 1.53
Module name:         COOL153
Filesize:	     458,512 bytes

This is the final Windows 3.1 (16 bit) version of cool edit
and runs faster (on win 3.1) than the post version (on win 95)
Blame who you want.

The main difference between this version and previous builds is that
you can no longer use METHODS 1 and 2 from tutorial i.  This is
because there is a new string 'ifoobari' that is encrypted with
you ID as the key then using the encrypted 'ifoobari' as the key 
you password is encrypted also.  Using the encrypted 'ifoobar' as 
the key all the compare strings are encrypted(in the same manner 
as before, almost).  The encrypted PASSWORD and Compare strings 
are then compared.  
What this means is that although you can use the debugger(winice)
to get the compare strings after they have been encrypted, you
still have to find the password that, when encrypted, will give 
the same result as the encrypted compare string.....phew!! :>

In this lesson we will us a brute -force approach to get the correct
password string, in the next lesson we will 'crack' or 'decypher'
the encryption.

Ok so here is the new section of the protection scheme.

// MAIN PROTECTIO ROUTINE V1.53 //  

  3.9647  FF760E                   push    word ptr [bp+0E]
  3.964A  68F403                   push    03F4
  3.964D  8D46A6                   lea     ax, [ID STRING]
  3.9650  16                       push    ss
  3.9651  50                       push    ax
  3.9652  6A2F                     push    002F
  3.9654  9A67960000               call    USER.GETDLGITEMTEXT
  3.9659  FF760E                   push    word ptr [bp+0E]
  3.965C  68F303                   push    03F3
  3.965F  8D46DA                   lea     ax, [PASSWORD STRING]
  3.9662  16                       push    ss
  3.9663  50                       push    ax
  3.9664  6A0E                     push    000E
  3.9666  9AD68A0000               call    USER.GETDLGITEMTEXT
  3.966B  807EDA00                 cmp     byte ptr [PASSWORD STRING], 00
  3.966F  0F84E100                 je      9754
  3.9673  8D7EEA                   lea     di, ['ifoobari' STRING]
  3.9676  BE9A20                   mov     si, 209A
  3.9679  8CD0                     mov     ax, ss
  3.967B  8EC0                     mov     es, ax
  3.967D  66A5                     movsd  
  3.967F  66A5                     movsd  
  3.9681  8D7EF6                   lea     di, [NULL STRING]
  3.9684  BEE053                   mov     si, 53E0
  3.9687  66A5                     movsd  
  3.9689  66A5                     movsd  
  3.968B  8D46DA                   lea     ax, [PASSWORD STRING]
  3.968E  16                       push    ss
  3.968F  50                       push    ax
  3.9690  9A24900000               call    USER.ANSIUPPER
  3.9695  C746FE0000               mov     word ptr [bp-02], 0000
  3.969A  8D46A6                   lea     ax, [ID STRING]
  3.969D  16                       push    ss
  3.969E  50                       push    ax
  3.969F  9ADA960000               call    KERNEL.LSTRLEN
  3.96A4  0BC0                     or      ax, ax
  3.96A6  7E3B                     jle     96E3
  3.96A8  8D7EA6                   lea     di, [ID STRING]
  3.96AB  8B76FE                   mov     si, [bp-02]	// 0x0000

3.LOOP_1 >8D4404                   lea     ax, [si+04]	//lea ax, 0x0005
  3.96B1  B90800                   mov     cx, 0008
  3.96B4  99                       cwd    
  3.96B5  F7F9                     idiv    cx
  3.96B7  8D5EEA                   lea     bx, ['ifoobari' STRING]
  3.96BA  03DA                     add     bx, dx
  3.96BC  47                       inc     di
  3.96BD  8A07                     mov     al, byte ptr [bx]
  3.96BF  3245FF                   xor     al, byte ptr [ID STRING-01]
  3.96C2  8BD0                     mov     dx, ax
  3.96C4  8BC6                     mov     ax, si
  3.96C6  8BDA                     mov     bx, dx
  3.96C8  99                       cwd    
  3.96C9  F7F9                     idiv    cx
  3.96CB  8BC3                     mov     ax, bx
  3.96CD  8D5EEA                   lea     bx, ['ifoobari' STRING]
  3.96D0  03DA                     add     bx, dx
  3.96D2  0007                     add     byte ptr [bx], al
  3.96D4  8D46A6                   lea     ax, [ID STRING]
  3.96D7  16                       push    ss
  3.96D8  50                       push    ax
  3.96D9  9A9E910000               call    KERNEL.LSTRLEN
  3.96DE  46                       inc     si
  3.96DF  3BC6                     cmp     ax, si
  3.96E1  7FCB                     jg      LOOP_1

....
...
.... Load of co-processor stuff that has no relevance
....


3.LOOP_2 >8A42EA                   mov     al, byte ptr [ifoobari + SI]
  3.972C  2AE4                     sub     ah, ah
  3.972E  8A4ADA                   mov     cl, byte ptr [PASSWORD + SI]
  3.9731  2AED                     sub     ch, ch
  3.9733  03C1                     add     ax, cx
  3.9735  03C7                     add     ax, di
  3.9737  05F700                   add     ax, 00F7
  3.973A  B91A00                   mov     cx, 001A
  3.973D  99                       cwd    
  3.973E  F7F9                     idiv    cx
  3.9740  80C241                   add     dl, 41
  3.9743  8852CA                   mov     byte ptr [RESULT+ SI], dl
  3.9746  03F9                     add     di, cx
  3.9748  46                       inc     si
  3.9749  83FE08                   cmp     si, 0008
  3.974C  7CDB                     jl      LOOP_2
  3.974E  886ED2                   mov     byte ptr [bp-2E], ch
  3.9751  EB05                     jmp     9758
  3.9753  90                       nop    

  3.9754 >C646CA00                 mov     byte ptr [bp-36], 00

  3.9758 >C646D200                 mov     byte ptr [bp-2E], 00
  3.975C  8D46CA                   lea     ax, [bp-36]
  3.975F  16                       push    ss
  3.9760  50                       push    ax
  3.9761  8D46A6                   lea     ax, [ID STRING]
  3.9764  16                       push    ss
  3.9765  50                       push    ax
  3.9766  9AD68DC38A               call    ENCRYPT AND COMPARE
  3.976B  83C408                   add     sp, 0008
  3.976E  8946F4                   mov     [bp-0C], ax
  3.9771  0BC0                     or      ax, ax
  3.9773  7427                     je      979C
  3.9775  3D0300                   cmp     ax, 0003
  3.9778  7528                     jne     97A2

Ok from now on I'll assume you can reverse engineer this stuff 
yourself, which you would be able to do if you bother to go through
my other tutorials.  Ok Basicall want the above code says in C is:

	counter2 = 4;
	for(counter1=0;counterif your are as clever as you can be when you write you C code how will 
you ever debug it, as every programmer knows, debugging is twice as 
hard as programming :) (that was a quote from some book I read once, it 
was one of the few good books on C if I remember the name of it I be 
sure to give it a mention)
Anyhow I'm digressing again, (Jesus, I'll have to stay on the subject
or we'll never finish :> ) The second part of the above code is straight
forward enough and stores the new encrypted version of your PASSWORD 
in RESULT[].

As you can see from the above disassembly the encrypt and compare proceedure
is then called.  This is basically the exact same as before (see previous
lessons) except for this minor change. 

Version 1.51
		A = HOJDIVAD[counter1];
		B = 0x1A;
		A1 = (A%B);
		A1 += 0x41;
		HOJDIVAD[counter1] = A1;

Version 1.53
		
		B = 0x1A;
		A = ifoobari[counter1];
		temp2 = A;

		A = HOJDIVAD[counter1];
		temp = A;
		temp += temp2;		Adding encrypted ifoobari
		A1 = (temp%B);
		A1 += 0x41;
		HOJDIVAD[counter1] = A1;

As you can see rather than just taking a char of the compare strings and
MOD 0x1A the encrypted ifoobari string is added first.

These are the only changes made to the protection scheme.
So you program will now look like this.

#include 
#include 

void main(void)
{
	int  Length1, Length2;
	unsigned char A, B, A1;
	unsigned long C=0x0c;
	register int counter1, counter2=0;
	unsigned int temp, temp2;
	char RESULT[]	="        ";
	char HOJDIVAD[] ="HOJDIVAD";
	char HOJDIVAD2[]="HOJDIVAD";
	char LOVELOVE[] ="LOVELOVE";
	char PEACEONE[] ="PEACEONE";
	char ARTHLOVE[] ="ARTHLOVE";
	char ifoobari[] ="ifoobari";
	char ID[20];
	char UPPERID[20];
	char PASSWORD[8];

	printf("\n Enter Your Name Please => ");
	gets(ID);
	Length1 = strlen(ID);
	strcpy(UPPERID, ID);
	printf("\n Enter your Eight letter PASSWORD => ");
	gets(PASSWORD);
	strupr(PASSWORD);

	for(counter1=0;counter17)counter2=0;
	}


	for(counter1=0;counter17)counter2=0;
	}

	temp = counter2;

	for(counter1=0;counter17)counter2=0;
	}

	C = 0x0c;
	counter2 = 0;
	for(counter1=0;counter1<(Length2);counter1++)
	{
		C+= UPPERID[counter1];
		A = HOJDIVAD2[counter2];
		B = A;
		A += A;
		A += B;
		A <<= 2;
		A += B;
		A += 0x11;
		HOJDIVAD2[counter2] = A;
		A = 0x11;
		A *= LOVELOVE[counter2];
		A += 0x17;
		LOVELOVE[counter2] = A;
		A = 0x25;
		A *= ARTHLOVE[counter2];
		A += 0x11;
		ARTHLOVE[counter2] = A;
		A = 0x1F;
		A *= PEACEONE[counter2];
		A += 0x1D;
		PEACEONE[counter2] = A;
		counter2++;
		if(counter2 > 7) counter2 = 0;
	}

	for(counter1=0;counter1<(Length2);counter1++)
	{
		A = (char)C;
		HOJDIVAD2[counter2] -= A;
		LOVELOVE[counter2]	-= A;
		ARTHLOVE[counter2]	-= A;
		PEACEONE[counter2]	-= A;
		counter2++;
		if(counter2>7) counter2 = 0;
	}


	for(counter1=0;counter1<(Length2);counter1++)
	{
		A = UPPERID[counter1];
		HOJDIVAD2[counter2] ^= A;
		LOVELOVE[counter2]  ^= A;
		ARTHLOVE[counter2]  ^= A;
		PEACEONE[counter2]  ^= A;
		counter2++;
		if(counter2>7)counter2 = 0;
	}

	B = 0x1A;
	for(counter1=0;counter1<8;counter1++)
	{
		A = ifoobari[counter1];
		temp2 = A;
		A = HOJDIVAD[counter1];
		temp = A;
		temp += temp2;
		A1 = (temp%B);
		A1 += 0x41;
		HOJDIVAD[counter1] = A1;

		A = LOVELOVE[counter1];
		temp = A;
		temp += temp2;
		A1 = (temp%B);
		A1 += 0x41;
		LOVELOVE[counter1] = A1;

		A = HOJDIVAD2[counter1];
		temp = A;
		temp +=temp2;
		A1 = (temp%B);
		A1 += 0x41;
		HOJDIVAD2[counter1] = A1;

		A = ARTHLOVE[counter1];
		temp = A;
		temp +=temp2;
		A1 = (temp%B);
		A1 += 0x41;
		ARTHLOVE[counter1] = A1;

		A = PEACEONE[counter1];
		temp = A;
		temp +=temp2;
		A1 = (temp%B);
		A1 += 0x41;
		PEACEONE[counter1] = A1;

	}
	printf(	"\n    Code for 'New' version  [1.50]=> %s"
			"\n             'Full' version [1.50]=> %s"
			"\n             'Lite' version [1.50]=> %s"
			"\n             'Full' version [1.51]=> %s"
			"\n             'Lite' version [1.51]=> %s"
			"\n Typing in 'ANSWERME' in the Password box is now disabled :<"
			,HOJDIVAD, HOJDIVAD2, LOVELOVE, ARTHLOVE, PEACEONE);

}

'BUT!!...' you cry, if you were impatient enough to copy /paste this code 
without even reading it, ...this does not give us our required registration code.
So now we will modify the above code to brute force crack the password 
string.

To truly brute force a crack of eight char's requires that we try every
possible combination, using only numbers letter(upper and lower case) this
is 8 ^ 62 which is a BIG BIG number. But we know that Cool Edit only
uses the uppercase letters in the PASSWORD field, so a brute force crack
here would require 8 ^ 26 which on my DX4-100 would take anywhere from
2 weeks to 1 month to compute depending on the speed of the code.
This would be a wast of time so we look at the code again and realise that 
the whole protection scheme works in a letter by letter fashion.  Which 
means that we need only Check one letter at a time. Which gives us 
a total combination of 8 * 26 or 208 total possiblities.
A big difference from 8^26 ( approx == 302231454903700000000000) and 208
I think this was the whole idea of the protection scheme :
 Ah, the stupid cracker wont be able to use his icy debugger to crack
my password, heh, heh heh, and to try 8^26 combinations will take him 
forever , but alias a good cracker never gives in (or up).

Here is the code for you to incorporate into the above C code:

PASSWORD[] = "AAAAAAAA";
while(loop<8)
	{
			A = ifoobari[loop];
			B = PASSWORD[loop];
			temp = A;
			temp += B;
			temp += counter2;
			temp += 0x00F7;
			temp %= 0x1A;
			temp += 0x41;
			A	 = temp;
			RESULT[loop] = A;

		if(RESULT[loop] == ARTHLOVE[loop])
		{
			loop++;
			counter2 += 0x1A;
		}
		else
			PASSWORD[loop]++;
	}

There is no bounds checking in the above code so be carefull if your
input name is longer that 19 char's lengthen the appropate array and
remember to leave 1 char blank for the '\0' string terminator.
As I mentioned before we will crack this encryption code in the next lesson
so we need only one pass per Letter.
See if you can email me with the answer before I write the next tutorial.

That was the last 16bit version of cool edit, and it is really where the
evolution of the protection scheme staops as well.  The password obtained 
with this program will work for both the 95 and 96 versions. However, as I 
have gone this far and promised to really crack the alogorithm there will
be one more lesson (until Cool edit Pro comes out :> ), mainly concerned
with Cool edit 96. Cool edit 95 has almost no difference as far as the 
protection scheme goes, I think the only difference if really the complier
utilising 32-bit code: which thanks to Microsoft doesn't run much (if any) 
faster:< 

Mail me if you locate any erratum or need help etc...
Oh by the way, if the code looks a bit funny at times its because
the less then symbol is part of the html language, so just look at the
source [view source] to see the code clearly
I'll fix it later, I promise :>

Back to the mainCracking page.