home *** CD-ROM | disk | FTP | other *** search
- Santmat's Crackme 5th August 2001
- ---------------------------------
- Solution by Alf
-
- Tools Used: Softice 3.24
- Thanks to Santmat for the crackme!!
-
- The purpose of this crackme is to make a keygen.
- At a first glance this seems simple because the name manipulation is
- very simple but there are two subtle details.The program uses the
- coordinates
- of the mouse cursor ( when you click 'Gain Access!') and the serial of
- your c: drive
- to produce the correct serial number.
-
- The important memory addresses are these:
-
- [4030d0] : name entered
- [4032d0] : serial entered
- [4036d4] : serial_length+ number produced by your windows product
- number
- [4036d8] : holds the result from name manipulation
- [4036dc] : serial of c: drive
- [4030cc] : (x*y)^0x12345 ( x,y mouse coordinates)
-
- Note: ^ indicates the xor boolean function
-
- The crackme first produces a number out of the name, more or less like
- this:
-
- result=0;
- while(*name)
- result=*name++^0x33;
-
- Then let x,y be the coordinates of the mouse cursor:
- A=result* ((x*y)^0x12345)+ SerialOfC:Drive
-
- The x*y^0x12345 is stored in location [4030cc]. At first I thought it
- was
- a constant number but when I placed a breakpoint on it I realised it
- was changing
- as the mouse moved. After that it was a piece of cake to figure out the
- x*y formula.
-
- There is also a B=(SerialLength+NumberByWindowsSerial)+((x*y)^0x12345)
- but either on purpose or by error it is not used!
-
- That is because after some calculations A is stored in EDX and B
- in ECX.
- Then A(EDX) is pushed as a parameter to wsprintf and then the function
- is called.
- The bad thing is that wsprintf alters the value of ECX and puts in
- there the address
- of the current SEH( 'structured exception handler' ). This is always
- 0x64fb80.
- Then ECX( which is not B anymore) is pushed as a parameter to another
- wsprintf.
-
- Anyway the way the number is produced by the windows serial at [4034d4]
- is the following:
-
- Every character is xored with 0x66 and added to 0x64fb00. All these
- results are added
- to produce the final result at [4036d4] . Actually the addition to
- 0x64fb00 is not really an addition. The number 0x64fbcc is a leftover in
- ECX from a previous function and is the current SEH ( just like the
- previous case ). The windows serial manipulations take place at CL but ECX
- is not cleared before that and so the rest of ECX gets carried along...
-
-
- To wrap up,each wsprintf(...,"%lu",...) just produces a string with the
- number provided in base 10. The correct serial is the concatenation of
- the two strings produced by the wsprintfs.
-
- By the way there is a softice check in the dll, called SofticeChecker
- :)
- which sets a flag at [403000]
-
- The Keygen
- ----------
- OK! Now let's make a keygen!
-
- The biggest problem to overcome is the mouse coordinates that are not
- constant.
- A windows programmer ( I am NOT one :) could make a keygen that
- automatically updates
- its output according to the current mouse coordinates and name
- specified.
-
- But I'll take another road.
- A quick and dirty solution is to drag the program window to the left
- edge of the screen
- so as to be able to press the 'Gain Access' button while the mouse
- cursor is as far left
- as possible ( x coordinate=0).
-
- This way x*y^0x12345 is always 0x12345 and the uncertainty factor is
- gone...
- I know this is not a very 'clean' way but without using windows this is
- the
- only thing I could think of :)
-
- Another problem is c: drive's serial. A windows programmer could just
- call
- GetVolumeInformationA ( which is used in the crackme, too) but I will
- just ask
- the user for the serial!
-
- So a very simple keygen in good-old ANSI/ISO C is the following:
-
- #include <stdio.h>
-
- int main(void) {
-
- char name[21];
- char serial[10];
- unsigned long serial_num;
- char *p;
- unsigned long result=0;
- /* Because x*y=0 A is initialized as 0x12345
- and B is always 0x64fb80 */
- unsigned long A=0x12345,B=0x064fb80 ;
-
-
- printf("Please enter name(20 chars max): ");
- fgets(name,21,stdin);
-
- do {
- printf("Please enter c: drive serial (without '-' ): ");
- fgets(serial,10,stdin);
- /* Make sure that the serial is acceptable */
- } while (sscanf(serial,"%x",&serial_num)!=1);
-
- p=name;
-
- /* Name Manipulation */
- while (*p && *p!='\n') { result+=*p++^0x33; }
-
- printf("%lu%lu\n",A*result+serial_num,B);
- printf("Before pressing the 'Gain Access!' button make sure your
- cursor is\n"
- "as far left as possible! Move the whole window if you must!");
- }
-
-
- .::Alf::. 6th August 2001
- email: alf82@freemail.gr
-