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.