February  1999
"Animated Screen v2.23"
( 'Sniff the 3 levels codes'  )
Win '95 PROGRAM
Win Code Reversing
 
 
by The Snake
 
 
Code Reversing For Beginners 
 
 
 
 
Program Details
Program Name: Ascrstp.zip
Program Type: Screen Saver Utility
Program Location: Here 
Program Size: 2mb 
 
 
     
Tools Used:
 Softice V3.23 - Win'95 Debugger
W32Dasm V8.93 - Win'95 Dissembler
 
 
Rating
Easy (X)  Medium (  )  Hard (    )  Pro (    ) 
 
 

Animated Screen v2.23
( 'Sniff the 3 levels codes'  )
Written by The Snake
 
 
Introduction
 
The author of  Animated Screen V2.23 says :
 
"You can create a free screen savers to promote or increase traffic at your web site, enhance an existing product or advertise your company.Also you can start your own screen saver business,selling custom shareware screen savers, with your company listed as the author. There are no distribution fees and,
as an Animated Screen owner, you can distribute the screen savers that you create in unlimited quantities,royalty-free.
Animated Screen is best tool for creating animated .GIF images and banners. Animated Screen lets you create these files so fast so doesn't allow any other GIF animator. You can create animation for your Web site or create a
banner to join a banner exchange program like LinkExchange or SmartClicks."
 
About this protection system
 
This shareware version is for 30 days. If you want keep using it, the author is asking you to purchase a license, but it will be full functional after this 30 days, but it will add
a note in each item you create "was created by unregistered version..".

We get the registration screen each time we run this program or by choose the
Help/Registration/Registration key... from the main menu.

The program keeps its settings at the system registry file in this entries :

HKCU\Software\PySoft\Animated_screen\

Including this 2 entries :

Reg_Key     ""
Reg_Name  "sìjL;têUVö xtL;tRÂ"  ----->  Unregistered

You can't register the prog with this name, the name is allways UPPERCASE !!!

When registering, this 2 entries looks like :

Reg_Key     "þǶñþÇþÇä¼ãã"
Reg_Name  "ÕP8M¯Ï@OªVÙÒøQ¯Ï"

Now, after i've done working on this tool, i can tell that there is 3 different levels to register it, each level uses a key was generating by the program, based on the name you use to register with. 
This 3 levels give you 3 kind of "productions" provided by this professional tool :
LVL1 - for creating animated .GIF and .AVI files only. ($29)
LVL2 - for use at home. ($49)
LVL3 - for commercial use. ($99)
 
The Essay 
 
After trying to use a fake key, and getting the "Name or Registration Key are not correct"
message, i was ready now to create a dead list with W32dasm and look for the
"Name or Registration Key are..." in the Data String Reference. 

Double click on it and here is the code we're interested in :

:004D29DA E869F9F4FF        call 00422348                              ; we break here !
:004D29DF 8B45EC            mov eax, dword ptr [ebp-14]  ; our name
:004D29E2 8D55F0            lea edx, dword ptr [ebp-10]  ; address for real-2
:004D29E5 E8EEB6FCFF        call 0049E0D8                    ; generate real for lvl-2 :004D29EA 8B45F0            mov eax, dword ptr [ebp-10]  ; *real* code lvl-2
:004D29ED 50                push eax
:004D29EE 8D55EC            lea edx, dword ptr [ebp-14]  ; our name
:004D29F1 8B45FC            mov eax, dword ptr [ebp-04]
:004D29F4 8B80E8010000      mov eax, dword ptr [eax+000001E8]
:004D29FA E849F9F4FF        call 00422348
:004D29FF 8B55EC            mov edx, dword ptr [ebp-14]
:004D2A02 58                pop eax                                          ; *real* code lvl-2
:004D2A03 E85814F3FF        call 00403E60       ; compares *fake* and lvl-2
:004D2A08 0F84D4000000      je 004D2AE2          ; jump if equal to *real* lvl-2
:004D2A0E 8D55EC            lea edx, dword ptr [ebp-14] ; *fake* code
:004D2A11 8B45FC            mov eax, dword ptr [ebp-04]
:004D2A14 8B80E0010000      mov eax, dword ptr [eax+000001E0]
:004D2A1A E829F9F4FF        call 00422348
:004D2A1F 8B45EC            mov eax, dword ptr [ebp-14] ; our name
:004D2A22 8D55F0            lea edx, dword ptr [ebp-10] ; *real* code lvl-2
:004D2A25 E822B7FCFF        call 0049E14C                   ; generate real for lvl-3
:004D2A2A 8B45F0            mov eax, dword ptr [ebp-10] ; *real* code lvl-3
:004D2A2D 50                push eax
:004D2A2E 8D55EC            lea edx, dword ptr [ebp-14] ; our name
:004D2A31 8B45FC            mov eax, dword ptr [ebp-04]
:004D2A34 8B80E8010000      mov eax, dword ptr [eax+000001E8]
:004D2A3A E809F9F4FF        call 00422348
:004D2A3F 8B55EC            mov edx, dword ptr [ebp-14] ; *fake* code
:004D2A42 58                pop eax                                         ; *real* code lvl-3
:004D2A43 E81814F3FF        call 00403E60             ; compares *fake* and lvl-3
:004D2A48 0F8494000000      je 004D2AE2         ; jump if equal to *real* lvl-3
:004D2A4E 8D55EC            lea edx, dword ptr [ebp-14] ; *fake* code
:004D2A51 8B45FC            mov eax, dword ptr [ebp-04]
:004D2A54 8B80E0010000      mov eax, dword ptr [eax+000001E0]
:004D2A5A E8E9F8F4FF        call 00422348
:004D2A5F 8B45EC            mov eax, dword ptr [ebp-14] ; our name
:004D2A62 8D55F0            lea edx, dword ptr [ebp-10]  ; *real* code lvl-3
:004D2A65 E852B7FCFF        call 0049E1BC                  ; generate real for lvl-1
:004D2A6A 8B45F0            mov eax, dword ptr [ebp-10] ; *real* code lvl-1
:004D2A6D 50                push eax
:004D2A6E 8D55EC            lea edx, dword ptr [ebp-14]  ; our name
:004D2A71 8B45FC            mov eax, dword ptr [ebp-04]
:004D2A74 8B80E8010000      mov eax, dword ptr [eax+000001E8]
:004D2A7A E8C9F8F4FF        call 00422348
:004D2A7F 8B55EC            mov edx, dword ptr [ebp-14] ; *fake* code
:004D2A82 58                pop eax
:004D2A83 E8D813F3FF        call 00403E60              ; compares *fake* and lvl-1
:004D2A88 7458              je 004D2AE2          ; jump if equal to *real* lvl-1
:004D2A8A A110CC4E00        mov eax, dword ptr [004ECC10]
:004D2A8F 8B00              mov eax, dword ptr [eax]

---------   snip  snip  --------

:004D2AB2 8D45F8            lea eax, dword ptr [ebp-08]

* Possible StringData Ref from Code Obj ->"Name or Registration Key are not |                                       ->"correct."
                                  |
:004D2AB5 BAF02C4D00        mov edx, 004D2CF0
:004D2ABA E8AD10F3FF        call 00403B6C

We can see this large code that leads us to the "bad cracker" message, but... it
includes in it all the *good* we need. Now it's the right time to trace the code to see what's going on here.
Run Animated Screen, go into the registration screen, feel in your name and any key,
but before you click in the "ok" press the "ctrl+d" keys to fire up Softice.
The 2 bpx's i usually use, "Getwindowtexta" or "Getdlgitemtexta" didn't make any good at this time, so, we are going to use the "hmemcpy" function. Type "bpx hmemcpy" and
x to leave... click "ok" and SI breaks. Type bc * to clear the last bp, and press the
F12  7 times. We are now in the code, and going to locate a new bp in the begining of the code we have seen above.
Type "u 4d29da"this will bring this code line in top of the code screen. After you see this line and it match the line we need, set a new bp by typing "bpx 4d29da".
type x and SI break at our new break point.
From now on, keep press the F10, look at the code above that includes my "red remarks" type "d eax" or "d edx" to see how this registers get the value of the real code, fake code and your name.
If the reg code is correct, the program jumps to location 004d2ae2, this is right for all 3 keys, so they have to get checked again to decide what level this key is for, and show the appropriate message. There is no message for the highest level.

Now, after we found how to sniff the codes, we want to learn something out of this prog, and not just sniff the codes. So, why not to have a look how the routine that compare the codes work :

:00403E60 53                push ebx
:00403E61 56                push esi
:00403E62 57                push edi
:00403E63 89C6              mov esi, eax         ; esi=*real* code address
:00403E65 89D7              mov edi, edx                  ; edi=*fake* code address
:00403E67 39D0              cmp eax, edx                  ; address are equal ?
:00403E69 0F848F000000      je 00403EFE                    ; if yes, jump
:00403E6F 85F6              test esi, esi                ; *real* code empty ?
:00403E71 7468              je 00403EDB                    ; if yes, jump
:00403E73 85FF              test edi, edi                ; *fake* code empty ?
:00403E75 746B              je 00403EE2                    ; if yes, jump
:00403E77 8B46FC            mov eax, dword ptr [esi-04]; eax=*real* length
:00403E7A 8B57FC            mov edx, dword ptr [edi-04]; edx=*fake* length
:00403E7D 29D0              sub eax, edx
:00403E7F 7702              ja 00403E83      ; jump if *real* length greather
:00403E81 01C2              add edx, eax                              ; edx=*real* length

:00403E83 52                push edx
:00403E84 C1EA02            shr edx, 02      ; edx=how many loops need to do ?
:00403E87 7426              je 00403EAF      ;   edx=0 ? no more loops, jump

:00403E89 8B0E              mov ecx, dword ptr [esi] ; 4 bytes of *real*
:00403E8B 8B1F              mov ebx, dword ptr [edi] ; 4 bytes of *fake*
:00403E8D 39D9              cmp ecx, ebx             ; is this 4 bytes equal ?
:00403E8F 7558              jne 00403EE9             ; if not, jump
:00403E91 4A                dec edx                       ; edx = edx - 1
:00403E92 7415              je 00403EA9               ;   edx=0 ? no more loops, jump
:00403E94 8B4E04            mov ecx, dword ptr [esi+04] ; 4 bytes of *real*
:00403E97 8B5F04            mov ebx, dword ptr [edi+04] ; 4 bytes of *fake*
:00403E9A 39D9              cmp ecx, ebx             ; is this 4 bytes equal ?
:00403E9C 754B              jne 00403EE9             ; if not, jump
:00403E9E 83C608            add esi, 00000008   ; *real* +8 bytes  
:00403EA1 83C708            add edi, 00000008   ; *fake* +8 bytes
:00403EA4 4A                dec edx           ; edx = edx - 1   
:00403EA5 75E2              jne 00403E89             ;   edx=0 ?  jump
:00403EA7 EB06              jmp 00403EAF

:00403EA9 83C604            add esi, 00000004
:00403EAC 83C704            add edi, 00000004

From here, if the code length is not multiples of 4, let say 7 and after the first 4 checked, the program gets here and the last 3 bytes will be checked one-by-one.....

 
The Patches 
  
Nothing is needed.
 

REMEMBER, i'm doing my cracks as a hobby and challenge, so please, if you like
this utility and want to keep using it, support the author and pay for it.
 
 
 
Final Notes
 
Try to register with an empty name, and try to sniff the real code, is the code based on the name we entered ? Not is this case !!

Usually, after registering, the registration option/screen get disabled. Here, because
of the 3 levels, it kept enabled to let the user upgrade, but why after the highest level
it is not disabled, who will want to degrade it ? Maybe, it is for us, crackers, to keep play without need to touch the registry file :)

My thanks and gratitude goes to:-
 
The Sandman for all what he is doing for us, newbies.
 
Rhayader for helping me with Reverse Code Engineering and
useful tips
 



Essay by:            The snake
Page Created: 4th February 1999