

 .---.        .---.                                                                 .----------.
 |    \      /    |    .-.                                                          |          |
 |  |\ \    / /|  |    | |    .--------.   .-----------.  .---------.  .-------.    |  .-------'
 |  | \ \  / / |  |    `-'    | .------'   `----. .----'  | .-------'  | ,---. |    |  | 
 |  |  \ \/ /  |  |    .-.    | |               | |       | |          | |   | |    |  `----.
 |  |   \__/   |  |    | |    \ \               | |       | `----.     | `---' |    |  ,----'
 |  |          |  |    | |     \ `-----.        | |       | ,----'     |  .---'     |  |
 |  |          |  |    | |      `----. |        | |       | |          | , \        |  |
 |  |          |  |    | |           | |        | |       | |          | |\ \       |  |
 |  |          |  |    | |           | |        | |       | |          | | \ \      |  '-------.
 |  |          |  |    | |    .------' |        | |       | '------.   | |  \ \     |          |
 `--'          `--'    `-'    `--------'        `-'       `--------'   `-'   `-'    `----------'


                                  .----------------------. 
                      .-----------|   Proudly Presents   |-----------.
       .--------------+----------------------------------------------+--------------.
       |                            A cracking tutor for:                           |
       |                               xReminder v1.02                              |
       `----------------------------------------------------------------------------'




This program used a protection scheme unknown to me, and so it deserved a cracking tutor.
The program just needs a serial number.  This time is takes more work to calculate the serial
than finding the protection scheme. If you like maths you should certainly download the program 
and start cracking right now.

Programs I have used:

- SoftIce V3.2
- W32dasm V8.9
- xReminder v1.02 (http://www.geocities.com/SiliconValley/Hills/7349/)
- not necessary, but might come in handy: Base Calculator 
  http://biosys12.ee.unsw.edu.au/personal/software/basecalc/


.-----------------------------------------------------------------------------------------------.
`-----------------------------------------------------------------------------------------------'


Fire w32dasm and take a look at Refs - String data references. You should notice:

"String Resource ID=59148: "This is not a valid registration. You may have used an inval"

Double click on this string and you ge transported to 4023BF. Now take a look at the code:

.-----------------------------------------------------------------------------------------------.
|                                    Part of the code                                           |
`-----------------------------------------------------------------------------------------------'
:004023A8 8BC8                    mov ecx, eax
:004023AA E8E1A60000              call 0040CA90
:004023AF 3D0BE70000              cmp eax, 0000E70B  <--------- important call
:004023B4 7443                    je 004023F9        <--------- if eax = E70B, register
:004023B6 8D4C2404                lea ecx, dword ptr [esp+04]
:004023BA E8A23C0200              call 00426061


* Possible Reference to String Resource ID=59148: "This is not a valid registration. You may have
                                                                                   used an inval"
                                  |
:004023BF 680CE70000              push 0000E70C
:004023C4 8D4C2408                lea ecx, dword ptr [esp+08]

..........

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004023B4(C)
|
:004023F9 8BCE                    mov ecx, esi       <--------- go on registering
:004023FB E8894F0200              call 00427389

.-----------------------------------------------------------------------------------------------.
`-----------------------------------------------------------------------------------------------'

I have already explained this part of the code. You shouldn't have problems with this. The fun
is just beginning.......

Now follow the important call. And scroll a little downwards. You MIGHT notice this: 


:0040CAE6 83F813                  cmp eax, 00000013  <------ check is s/n is 13h(19d) char long
:0040CAE9 740C                    je 0040CAF7        <------ if so, go on
:0040CAEB 33C0                    xor eax, eax               if not, unregister
:0040CAED 5F                      pop edi
:0040CAEE 5E                      pop esi
:0040CAEF 5D                      pop ebp
:0040CAF0 5B                      pop ebx
:0040CAF1 83C414                  add esp, 00000014
:0040CAF4 C20800                  ret 0008           


As I said 'You MIGHT notice this' I won't blame you for not seeing this. I overlooked this part
myself. If you overlook this part you might go tracing. This is a boring job. Anyway, you are
reading this tutorial so you won't overlook this part. 

Now start xReminder, go to the registration screen and place a breakpoint at 
GetWindowTextA(SoftIce).

Enter a s/n (1234567890123456789) and press enter. You get kicked into SoftIce. Press F12 to get 
into prot32. Now place a breakpoint just before the 'important call'. BPX 4023A8
Disable the breakpoint at GetWindowTextA and continue the program. Place another BPX at 40CAE6 
Press CTRL-D or F5 again and you should arrive 40CEA6. EAX should be 13h. Continue and arrive at
40CAEF7. Now here is a big block of code. You might want to take some time to explore this 
important part of the protection scheme. Just trace a few times through it to look what kind of
protection this is. Notice this part:



:0040CB2C 8BD0                    mov edx, eax                 <------- put 1st 4 char of sn in
:0040CB2E 880D3ABC4400            mov byte ptr [0044BC3A], cl                                EDX
:0040CB34 81E257494E2D            and edx, 2D4E4957            <------- 2D4E4957 = -NIW 
:0040CB3A 3BD0                    cmp edx, eax                 <------- compare edx, eax 
:0040CB3C 7404                    je 0040CB42                  <------- must be the same to
:0040CB3E 8B5C2410                mov ebx, dword ptr [esp+10]                            register

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB3C(C)
|
:0040CB42 C744241401000000        mov [esp+14], 00000001


Take a look at the 'and edx, 2D4E4957' The first 4 characters of your s/n get 'and-ed' with -NIW
2D4E4957 AND 2D4E4957 returns 2D4E4957. So the first 4 characters of our serial should be -NIW
IN REVERSED ORDER. If you type '? edx' at 40CB2E you should get '4321' as answer. So -NIW should
also be reversed: WIN- Now we know the serial looks like this: WIN-123456789012345

I would advice you to do some more tracing, get a hand of the protection. Take a look at the end
of the protection scheme:



:0040CC12 8BD3                    mov edx, ebx                     <----- ebx +EFFFFF01 must be 0
:0040CC14 8D8301FFFFEF            lea eax, dword ptr [ebx+EFFFFF01] <---- eax must be zero
:0040CC1A 81E2FF000010            and edx, 100000FF
:0040CC20 5F                      pop edi
:0040CC21 81EAFF000010            sub edx, 100000FF
:0040CC27 5E                      pop esi
:0040CC28 F7DA                    neg edx
:0040CC2A 1BD2                    sbb edx, edx
:0040CC2C 5D                      pop ebp
:0040CC2D F7D2                    not edx
:0040CC2F 23D3                    and edx, ebx
:0040CC31 5B                      pop ebx
:0040CC32 F7D8                    neg eax                         <------ eax must be 0
:0040CC34 1BC0                    sbb eax, eax                    <------ eax must be 0
:0040CC36 891524BC4400            mov dword ptr [0044BC24], edx
:0040CC3C F7D8                    neg eax                         <------ neg eax must be 0
:0040CC3E 050BE70000              add eax, 0000E70B               <------ ?register?
:0040CC43 83C414                  add esp, 00000014
:0040CC46 C20800                  ret 0008                        <------ EAX must be E70B to
                                                                          register.


This is the last part of the big block, an end. Notice that at 40CC3E EAX+E70B must be zero. So 
EAX must also be zero. Now do some arithmetic yourself. At 40CC12 EBX + EFFFFF01 must be zero =>
ebx = 0 - EFFFFF01 => ebx = 100000FF. EBX must be 100000FF to register, so take anther look at
the code, only this part of the code modifies EBX:

:0040CB51 8A8728BC4400            mov al, byte ptr [edi+0044BC28] <------ load char from s/n
:0040CB57 3C2D                    cmp al, 2D                      <------ is char 2d(-)?
:0040CB59 8844242C                mov byte ptr [esp+2C], al
:0040CB5D 7428                    je 0040CB87                     <------ if so, jump 



* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB5D(C)
|
:0040CB87 8BC6                    mov eax, esi                    <------ arrive here from jump
:0040CB89 83C9FF                  or ecx, FFFFFFFF
:0040CB8C 83E800                  sub eax, 00000000
:0040CB8F 7414                    je 0040CBA5                     <------ jump 1
:0040CB91 48                      dec eax
:0040CB92 740A                    je 0040CB9E                     <------ jump 2
:0040CB94 48                      dec eax
:0040CB95 7513                    jne 0040CBAA                    <------ jump 3
:0040CB97 B958000000              mov ecx, 00000058
:0040CB9C EB0C                    jmp 0040CBAA                    <------ jump 4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB92(C)
|
:0040CB9E B956000000              mov ecx, 00000056
:0040CBA3 EB05                    jmp 0040CBAA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB8F(C)
|
:0040CBA5 B94B000000              mov ecx, 0000004B


* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040CB95(C), :0040CB9C(U), :0040CBA3(U)
|                                                                     ,-- jumps arrive here
:0040CBAA 8B44B414                mov eax, dword ptr [esp+4*esi+14] <---- put value in EAX 
:0040CBAE 33D2                    xor edx, edx
:0040CBB0 F7F1                    div ecx                         <------ IMPORTANT
:0040CBB2 85D2                    test edx, edx
:0040CBB4 750C                    jne 0040CBC2                    <------ EDX must be zero
:0040CBB6 8D4E02                  lea ecx, dword ptr [esi+02]
:0040CBB9 B801000000              mov eax, 00000001
:0040CBBE D3E0                    shl eax, cl
:0040CBC0 0BD8                    or ebx, eax                     <------ modify ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CBB4(C)
|
:0040CBC2 46                      inc esi                         <------ ESI counts 2d(-) in s/n
:0040CBC3 83FE04                  cmp esi, 00000004                              exept the WIN-
:0040CBC6 7412                    je 0040CBDA                                                 /\
:0040CBC8 C744B41401000000        mov [esp+4*esi+14], 00000001                                ||




As I said before, you might want to trace through the code. We now know the programs checks if 
there are - (that is 2D hexadecimal) in the serial. Now let me tell you something about the DIV
function: EAX gets DIVided by ECX, in other words: EAX tells how many times ECX goes into EAX.
The MODulo gets stored in EDX, in other words: the rest of the division gets stored in EDX.
This might be a bit confusing so i'll give you an example in *!DECIMAL!*:

 mov eax, 100
 mov ecx, 15
 div ecx
 
The result: eax = 6, edx = 10, ecx = 15
In a formula: EAX(before) = (EAX(after) * ecx) + EDX

Enough explaination of the div(?) Let's go on. EDX must be zero to modify EBX. Now lets take a 
look how [esp+4*esi+14] gets calculated:

:0040CB51 8A8728BC4400            mov al, byte ptr [edi+0044BC28]   <----- put char of s/n in AL
:0040CB57 3C2D                    cmp al, 2D                        <----- check if al = 2d(-)
:0040CB59 8844242C                mov byte ptr [esp+2C], al         <----- store eax
:0040CB5D 7428                    je 0040CB87                       <----- jump if eax = 2d
:0040CB5F 8B44242C                mov eax, dword ptr [esp+2C]       <----- retrieve eax
:0040CB63 8B4CB414                mov ecx, dword ptr [esp+4*esi+14] <----- restore [esp+4*esi+14] 
:0040CB67 25FF000000              and eax, 000000FF                 <----- not important
:0040CB6C 03E8                    add ebp, eax                      <----- add eax to ebp
:0040CB6E 81F900040000            cmp ecx, 00000400                 <----- check if ecx > 400h
:0040CB74 7309                    jnb 0040CB7F                      <----- if ecx >= jump
:0040CB76 0FAFC8                  imul ecx, eax                     <----- if not imul
:0040CB79 894CB414                mov dword ptr [esp+4*esi+14], ecx <----- store ecx
:0040CB7D EB51                    jmp 0040CBD0                      <----- jump

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CBB4(C)
|
:0040CBC2 46                      inc esi
:0040CBC3 83FE04                  cmp esi, 00000004
:0040CBC6 7412                    je 0040CBDA
:0040CBC8 C744B41401000000        mov [esp+4*esi+14], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB74(C)
|
:0040CB7F 03C8                    add ecx, eax                      <----- add eax to ecx
:0040CB81 894CB414                mov dword ptr [esp+4*esi+14], ecx <----- store ecx
:0040CB85 EB49                    jmp 0040CBD0                      <----- jump
 
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040CB7D(U), :0040CB85(U)
|
:0040CBD0 47                      inc edi                           <----- increase counter
:0040CBD1 83FF13                  cmp edi, 00000013                        /location in s/n
:0040CBD4 0F8277FFFFFF            jb 0040CB51                       <----- if edi < 13h jump
 
Well, that should be enough explaination. By now you should have an idea of how to register the 
program. The serial must start with WIN- and you will probably need some 2d(-). To modify EBX
[esp+4*esi+14] must go EXACLY(EDX must be zero) into x times into ECX.

Now lets modify that EBX register to register the program, use a serial like this: 
WIN-123-456-789-012
Here is a part of the code(again), i wrote the values next to the code for the 1st, 2nd, 3rd
and 4th time:
                                                        1st time | 2nd time | 3rd time  | 4th t 
:0040CB51      mov al, byte ptr [edi+0044BC28]   <----- al = 31h | al = 32h | al = 33h  | al = 2d
:0040CB57      cmp al, 2D                        <----- compare
:0040CB59      mov byte ptr [esp+2C], al         <----- store    
:0040CB5D      je 0040CB87                       <----- no jump  | no jump  | no jump   | JUMP!!
:0040CB5F      mov eax, dword ptr [esp+2C]       <----- retrieve
:0040CB63      mov ecx, dword ptr [esp+4*esi+14] <----- ecx = 1h | ecx = 31h| ecx = 32h
:0040CB67      and eax, 000000FF                 <----- not important       
:0040CB6C      add ebp, eax                      <----- ebp = 31h| ebp = 63h| ebp = 96h
:0040CB6E      cmp ecx, 00000400                 <----- compare
:0040CB74      jnb 0040CB7F                      <----- no jump  | no jump  | JUMP!!
:0040CB76      imul ecx, eax                     <----- ecx = 31h| ecx = 992h 
:0040CB79      mov dword ptr [esp+4*esi+14], ecx <----- store
:0040CB7D      jmp 0040CBD0                      <----- jump

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB74(C)
|
:0040CB7F      add ecx, eax                      <-----------------------   | ecx = 992 + 33=9C5h
:0040CB81      mov dword ptr [esp+4*esi+14], ecx <----- store ecx
:0040CB85      jmp 0040CBD0                      <----- jump




Now follow that JUMP!!!





* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB5D(C)
|                                                                  ,----- ESI = 0 because this
:0040CB87 8BC6                    mov eax, esi                    <------ is the first 2d(-)
:0040CB89 83C9FF                  or ecx, FFFFFFFF                <------ ecx = FFFFFFFF
:0040CB8C 83E800                  sub eax, 00000000               <------ eax = 0 
:0040CB8F 7414                    je 0040CBA5                     <------ JUMP!!

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB8F(C)
|
:0040CBA5 B94B000000              mov ecx, 0000004B               <------ ecx = 4Bh


* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040CB95(C), :0040CB9C(U), :0040CBA3(U)
|                                                                     
:0040CBAA 8B44B414                mov eax, dword ptr [esp+4*esi+14] <---- eax = 9C5h
:0040CBAE 33D2                    xor edx, edx
:0040CBB0 F7F1                    div ecx                         <------ Divide
:0040CBB2 85D2                    test edx, edx                           eax = 21h, edx = 1Ah
:0040CBB4 750C                    jne 0040CBC2                    <------ EDX not zero :( Jump
:0040CBB6 8D4E02                  lea ecx, dword ptr [esi+02]
:0040CBB9 B801000000              mov eax, 00000001
:0040CBBE D3E0                    shl eax, cl
:0040CBC0 0BD8                    or ebx, eax                     <------ modify ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CBB4(C)
|
:0040CBC2 46                      inc esi                         <------ ESI = 1h
:0040CBC3 83FE04                  cmp esi, 00000004               <------ compare      
:0040CBC6 7412                    je 0040CBDA                     <------ no jump   
:0040CBC8 C744B41401000000        mov [esp+4*esi+14], 00000001    <------ [esp+4*esi+14] = 1h


Bah, we didn't register, because we used the wrong serial. Let me tell you again (SHORT) how the 
calculation goes and how we should register:

(1st digit * 2nd digit) + 3rd digit digit = x * 4B

Now THAT was REALLY SHORT, now we only have to figure out 4 variables. This can easily done by
guessing. X must be a value bigger then 930h because (30 * 30) + 30h = 930h
Lets say x = 22h. Then:

 (1st * 2nd) + 3rd = 9F6h        ; what could those digits be?
 (32  * 32 ) + 32  = 9F6h!!!!!!  ; OK, we got them!!!!

You might say that this is a hell of a work, and yes i agree with you. But I have done this with
the '? 32 *32+32' command in SoftIce. 

Now go figure out the other parts of the s/n yourself, I have put the answers at the bottom of
this text file. I have put the other calculation problems hereunder to help you a bit.
Also mind this part:

:0040CB87 8BC6                    mov eax, esi            <---- esi counts 2d(-)
:0040CB89 83C9FF                  or ecx, FFFFFFFF
:0040CB8C 83E800                  sub eax, 00000000
:0040CB8F 7414                    je 0040CBA5             <---- 1st time
:0040CB91 48                      dec eax
:0040CB92 740A                    je 0040CB9E             <---- 2nd time
:0040CB94 48                      dec eax
:0040CB95 7513                    jne 0040CBAA            <---- 3th time
:0040CB97 B958000000              mov ecx, 00000058       <---- 3th time
:0040CB9C EB0C                    jmp 0040CBAA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB92(C)
|
:0040CB9E B956000000              mov ecx, 00000056       <---- 2nd time
:0040CBA3 EB05                    jmp 0040CBAA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CB8F(C)
|
:0040CBA5 B94B000000              mov ecx, 0000004B       <---- 1st time


Well, here are all the arithmetic problems:

WIN-123-456-789-012   ( 1st digit *  2nd digit) +  3rd digit digit = x * 4Bh
WIN-123-456-789-012   ( 4th digit *  5th digit) +  6th digit digit = x * 56h
WIN-123-456-789-012   ( 7th digit *  8th digit) +  9th digit digit = x * 58h
WIN-123-456-789-012   (10th digit * 11th digit) + 12rd digit digit = x * 55h




I hope you got through this tutor, it was a pretty tough one. Anyway you should have registered
it by now. I hope you enjoyed reading this tutor, if you do: let me know. Thanks. 

Next tutor will cover patching in Pascal. 


.-----------------------------------------------------------------------------------------------.
`-----------------------------------------------------------------------------------------------'


Well, I hope you learned SOMETHING from this tutor.

If you have any comments, questions, need help or whatever, mail me at MisterE@freemail.nl

OR

look for me at EFNET => #cracking4newbies or #cracking


.-----------------------------------------------------------------------------------------------.
|                                        GREETZ                                                 |
`-----------------------------------------------------------------------------------------------'

Still the same greetz:

Greetz go to: everyone on #cracking4newbies - #tno - #inside98

.-----------------------------------------------------------------------------------------------.
`-----------------------------------------------------------------------------------------------'

























The answer: WIN-222-440-060-277
 