December 1998
"AI Picture Explorer V1.0"
Multiple Attacks
Win '95 PROGRAM
Win Code Reversing
 
 
by The Sandman 
 
 
Code Reversing For Beginners 
 
 
 
Program Details
Program Name: aipicx.zip
Program Type: Image File Handler
Program Location: Here 
Program Size: 711K 
 
      
Tools Used:
 Softice V3.2 - Win'95 Debugger
W32Dasm V8.93 - Disassembler
Winice.Dat - Softice settings I used
 
Rating
Easy ( X )  Medium ( )  Hard ( )  Pro (    ) 
There is a crack, a crack in everything. That's how the light gets in.
 
     
 
AI Picture Explorer V1.0
Multiple Attacks
Written by The Sandman
 
 
Introduction
 
The author of AI Picture Explorer  says:-
 
"AI Picture Explorer (AIPICX for short) is an integrated Viewer and Explorer; use both (e.g. side-by-side) or either one.  For speed, Viewer is activated to view an image; otherwise, the Explorer is presented.  Close either form (via eXit button on upper right) or minimize the Explorer separately (see Auto Minimize).  You can run multiple instances with Viewer at full screen..
 
About this protection system
 
This program *can* simply be cracked in memory using softice without having to *fully* understand how the program's protection works. However, I don't recommend this approach because you won't learn a thing by doing this. On first running, the program allows you just 15 days to evaluate this program with, or, from a cracker's point of view, you have just 15 days to figure out how to crack it before it ceases to function *grin*.

This program uses a User name and Serial code to help prevent unauthorized copies of itself being made.

Once installation is complete and the program is run two new Registry entries are created at:

HKEY_CURRENT_USER\Software\Applied Insights\AI Explorer
HKEY_USERS\.Default\Software\Applied Insights\AI Explorer

Device=0
EControls10 = 00,00,00,00,00,00,00,00,80,02,00,00,E0,01,00,00,01,00,01,00
              00,00,00,00,00,99,00,00,00,00,00,00,00,03,00,00,00
ExplorerDir = C:\WINDOWS\Crystal\
 

 
The Essay 
 
This essay is going to attempt to teach you to 'think' like a cracker, in doing this I will try and show you exactly how we can make use of the information we learn about this program using just our tools so that we can crack the hell out of this program. I will show you just how open this program really is, in fact, after looking at a dead listing of this program I was amazed to see all my usual  'attack' points almost sign posted for me!.
 
Right, so if I was a newbie and I wanted to crack this babe then where would I start?, there are so many attack points to choose from and each has their own particular merits..

First thing's first, lets fire up W32Dasm and create a 'dead listing' for this program.  This  should usually be your first approach to cracking any program (exceptions are VB & Delphi programs which won't reveal much information because of the structure of the programming language used).

Once you have your 'Dead Listing' on your screen click on the menu option 'Disassembler' and then select 'Save Disassembly Text file And Create Project File'. This will allow us to make a backup copy of our dead listing.

Many people ask me what do I look for first in a Dead Listing, the answer is I check the program's String Data References, this is by far your greatest source of 'easy' information, you can tell a great deal about what sections of code does simply by looking at the surrounding ASCII Strings peppered throughout the program. I usually look for anything that 'looks' like a 'serial code', this could be a sequence of numbers/letters or a 'pass code' of some sort..

Examples are:-

3287634346386535533987
3s87ds87sdfnpo9uty
3456-34532-25445-45
A23-sdf45-35fdsf-DL

If you see anything that resembles the above then it's well worth re-running the program and trying these out first before proceeding.. Who knows, you might get lucky..:)

Next, we continue to  examine the String Data Resources which revealed the following information about this program.:-

"99999x99999x999"                --> A possible serial code?
"and register this software."    --> Part of the nag message

"Enter EXACTLY as provided via " --> Message prompt, used in initial input Scr.

"Enter your registered name."    --> Message prompt, used in initial input Scrn.
"Enter your registration key."   --> Message prompt, used in second input screen.

"Evaluation period expired a long "          --> Part of the nag message
"for 15 days before registering."            --> Part of the nag message
"Invalid entry; please reenter."             --> Part of the nag message

"Please restart to activate registration "   --> Part of the 'Good Cracker' message.
"Please support and register this "          --> Part of the 'Good Cracker' message.
"Please support the Shareware Concept"       --> Part of the 'Good Cracker' message.

"Software\Applied Insights\AI Explorer"      --> Registry location for this program!

"Unregistered"                               --> Default  text used in About Screen.

"vcltest3.dll"                               --> Name of a support .DLL file

"You may evaluate this software"             --> Part of the nag message
 
 
OK, so we have a fair idea of what sign posts there are in this program but what do we do next and how do crackers make use of them?.

What you should not do is to go into the dead listing without first having a pre-defined idea of what to look for, because without a plan you will simply go from one section of code to another, missing in the process the logical flow of the program. It is very easy to be overwhelmed with so much code that you really do start to miss the 'clues' so vital to you if your going to solve this program.

The following plan of attacks are described in no particular order of importance, they are described here only to offer you a few possible ways we can approach this program.

  



 
1. Plan of attack - Understanding and exploiting how programs use memory flags to tell wether or not it's been registered or not.
  

 
Before going any further, let me try and explain how these 'memory flags' work.

During the normal course of any running program, the program has to have a way to temporarily store important bits of information such as in our case, wether it's been registered or not  and save it in the computer's memory. In order to do this the program will set aside small chunks of memory (ranging from 1 to several bytes) that it will treat as as 'flags'.

Flags in human terms is simply  either a YES or a NO.  The 'memory flag' used for signalling wether the program has been registered or not  will be referred from here-after as 'The Shareware Flag'.  An example of how 'Shareware Flags'  works goes like this..

When the program is first run it is ALWAYS in Shareware Mode, this is because by default, 'The Shareware Flag' within the program will more often than not contain a '0' (ZERO), which 99.9% of programs use to signify that it has not been registered.

Next, the program will then 'read' either the Registry File or some other file to see if the correct serial registration code exists.  If the checks on this registration code is found to be correct, the program will then place a value of '1' (ONE) in 'The Shareware Flag'  to signify wether or not it has been registered which in turn tells the rest of the program how to behave there-after.

Another time when the program checks to see if it should run in Shareware or Registered Mode is when you try and register it using a valid serial or password. After the program has checked the entered Serial or password the program will then update 'The Shareware Flag'  (if the Serial is correct) placing a value of 01 over the old, default value of '0'.
 
Lets re-cap, the program has set aside a few bytes (memory locations) that the rest of the program checks to see if it's been registered or not.  Depending on what's stored in this memory location will also determine how the program will behave towards the User.

Should the program show a nag screen if still in Shareware Mode or display the User's Name if in Registered Mode. Two possible outcomes, a Yes or a No.

Yes, run in Shareware Mode.
NO, User has registered me so run in Full Registered Mode.

Since 'memory flags' play such an important part in the normal running of programs there can be 100's of memory locations in use at anyone time ranging from holding Video modes to settings relating to screen positions. Because of this we have to make sure we correctly find and identify the correct 'memory flag' that the program uses to determine wether or not the program has been registered or not..

Don't worry too much if this sounds a bit technical for you at this stage, we'll try and clear this up as we go along..

OK, our task then is to locate where the program 'stores' and updates the 'Shareware Flag' but where in all this code do we start?.  More to the point, what does this 'Shareware Flag' look like!.

The 'Shareware Flag' is a memory location, so therefore the type of instruction we're looking for will have this 'part assembly' instruction in it.

[12345678]          <---The memory address shown is only an example.

The program will need to perform tests on this memory location and it will commonly use:-

cmp [12345678], 00

This instruction in human terms simply means:- Does the memory location 12345678 contain a '0' in it?.

Usually, this instruction is followed by a conditional jump, such as je 87654321 which in human terms means:- Jump if Equal to memory address 87654321.

So, the two lines together might look something like this:-

cmp     [12345678], 00        ;Still in Shareware mode?
je      87654321                  ;Display nag screen
 
OK, we now have an idea of what the 'Shareware Flag' might look like, so where do we look for it?.

Where would YOU use this kind of checking?. Well, if you've done your homework and run the program a few times then you'll notice that we get a 'Shareware nag' screen each time we close this program. Now obviously we wouldn't be pestered to register this program if we have already registered it so it's highly likely that when we try and close this program that it checks to see if it has been registered, and, on finding it is still unregistered, display's the familiar nag screen.

Notice also that this 'nag' screen is also the same screen shown when you select  the 'About' menu option. Hmm, so the programmers are making the program call the 'About' screen if it's still running in Shareware mode, that's interesting.  Can you see what I'm trying to show you?. 'Nag' screen = About Screen, same code but with a check to see if the program is running in Shareware Mode. This means that we are sure to find a 'Shareware Flag' being tested for a
value of '0' here!.

In our dead listing we found a number text strings relating to our 'nag' screen, so in this case I choose to find where the following text "for 15 days before registering."  is located within the program code.

Here's a section of code that contains this text string..

* Referenced by a (C)onditional Jump at Address: :400452BC(C)
 
:400452D3 8D45FC         lea eax, dword ptr [ebp-04]
:400452D6 E8D1E7FBFF     call 40003AAC
:400452DB 833DE48709400F cmp dword ptr [400987E4], 0000000F ;15 days left?
:400452E2 7F1C           jg 40045300               ;Jump if GREATER than 15 days!!
:400452E4 FF75FC         push [ebp-04]
:400452E7 6814540440     push 40045414             ;"You may evaluate this software"
:400452EC 683C540440     push 4004543C             ;"for 15 days before registering."

Notice that the program ALSO checks to see if you have OVER 15 days left to evaluate this software, even though it's been 'set' to just 15 days!. The programmer is checking to see if you have tampered with his program because if you have more than 15 days left then the routine that it jumps to will display the message:-

"Please support the Shareware Concept, and register this software."

Before you email me, I 'knew' that cmp dword ptr [400987E4], 0000000F  was our 'Days left' memory flag because 0Fh is 15 in decimal and that because it was used so close to the displaying of our "days remaining to evaluate this software" routines that it was too  coincidental to be anything else. Just follow the jump if greater and see that it then checks to see if you have more than 30 days left to evaluate this software.

OK, back to our original plan, to find out where the 'Shareware Flag' is being tested for a value of '0' .......

Looking at the above code snippet we see that this routine is being called by a Conditional Jump at memory location: :400452BC so lets go take a look at this section of code..
 

:400452B5 803DDC87094000  cmp byte ptr [400987DC], 00 ;'Shareware Flag'!!
:400452BC 7415            je 400452D3                 ;Jump if not *regged*
:400452BE 8D45FC          lea eax, dword ptr [ebp-04]
:400452C1 8B0DE0870940    mov ecx, dword ptr [400987E0]
:400452C7 BAF8530440      mov edx, 400453F8
:400452CC E8A3EAFBFF      call 40003D74
:400452D1 EB6C            jmp 4004533F

When I first saw this I didn't immediately know that I had found the 'Shareware Flag', but did think it looked promising.  It was only after testing this program using Softice and searching the Dead Listing for other occurrences of this memory location that I knew for certain that I had indeed, found where the program stores it's 'Registration Status'.

Although we have found where the program checks to see if it has been registered this is not the end of the story.  While we *could* simply NOP (90h) out this conditional jump and the program would now be prevented from displaying the 'You have XX days left etc" replacing this instead with routines to print our 'handle/name" instead we can't be certain that this action might cause us problems later on while the program is running.  In reality though, I happen to know it's possible to patch this program here and now at this location but as newbies you don't and the purpose of this tut is to try and show you how to always double-check your work..

Our next task is to locate where in the program's code it sets the 'Shareware Flag' to hold a value of '1', signifying that your User Name and Serial Code were found to be correct and so allow the program to run in full *registered* Mode.

From this assembly instruction cmp byte ptr [400987DC], 00  we take the '400987DC' and do a search on it, listing all occurrences throughout the whole of the program.

My searches using Ultra-Edit revealed three unique occurrences, some programs will come up with more than this but in our case there are only three.

:40045212 C605DC87094001          mov byte ptr [400987DC], 01
:400452B5 803DDC87094000          cmp byte ptr [400987DC], 00
:4004552E 803DDC87094000          cmp byte ptr [400987DC], 00

We can tell from this that the program actually checks TWICE during normal running to see if you have registered this program. We have located one such check when the program displays the 'About/Nag' screen but at this point we haven't yet found what the other check does or how it effects the program..

The important occurrence of [400987DC] is located at memory address: 40045212, do you know why?.

The answer is... because it's the ONLY place within the whole location that allows the program to run in full *regged* mode, it places that all important '1' into our  'Shareware Flag'. If we can attack this then we can forget about how many times the program checks to see if it's been registered!!!.  We must now get the program to always execute this instruction each time it is run, just as though it has found our User name & Serial Code and found them to be correct..:)

Lets go take a look at memory address: :40045212

:40045204 E84F7EFEFF      call 4002D058
:40045209 A3D4870940      mov dword ptr [400987D4], eax
:4004520E 84DB            test bl, bl
:40045210 7407            je 40045219                 ;jump if serial No is invalid.
:40045212 C605DC87094001  mov byte ptr [400987DC], 01 ;ELSE Register prog!
:40045219 B8E0870940      mov eax, 400987E0           ;Come here

Can you see that if the je (Jump if Equal) is 'set' that it will direct the program to 'skip' over the instruction that places a value of '1' into our  'Shareware Flag'!.

There are many ways to defeat this, the easiest way for newbies is to NOP (90h) out the jump completely and while very effect, it's often an easy target for programmers to check on.  One way I would use is to change the je (Jump if Equal) so that instead of jumping OVER our mov byte ptr [400987DC], 01 instruction that it instead jumps to the NEXT instruction instead!. The advantages is that it now doesn't matter if this conditional jump is 'set' or not, our all important mov byte ptr [400987DC], 01 instruction will always be executed.

To make this happen we need to change the jump's offset value, from the default value of 7 (jump seven spaces forward) to jump 0 spaces forward..

Here's what our 'revised' section of code will look like once we've 'patched' it..

:40045204 E84F7EFEFF      call 4002D058
:40045209 A3D4870940      mov dword ptr [400987D4], eax
:4004520E 84DB            test bl, bl
:40045210 7400            je 40045212                 ; jump if serial No is invalid.
:40045212 C605DC87094001  mov byte ptr [400987DC], 01 ; Register prog!

To complete this patch here's what to you need to do..

1. Load up aipicx.exe into your favourite Hex-Editor.
 
I would normally now show you what locations to patch our target program but this practice will now be discontinued.  I have shown you enough information for you to work this out for yourself and have no wish to see anyone use this essays as a quick way to steal software.. If your after knowledge and understanding then why would you want me to show you exactly where to patch this program..

 
2. If you've done your ground work at the start of this crack then you will know where this program keeps it's settings, as well as it's User registration Info..

Open up RegEdit and go here...

HKEY_CURRENT_USER\Software\Applied Insights\AI Explorer

Inside this key you will see:

SN = ""
UN= ""

If you've been cracking for a while then you'll know that programmers in general, like to use the same abbreviations over and over again in their work, more so in the System registry Files, so...  SN = Serial Number and UN = User Name..

With our patch in place, we know that the program will now display our User Name in the 'About' screen and although at this stage you don't know it yet, it will not display the serial number.

 Therefore edit:-

SN and place some numbers in it.
UN and place your Name/handle in it..

Example:-

SN = "12345678"
UN = "The Sandman".

Close RegEdit and run the program.. Program now registered..  *SEE FINAL NOTES*
 
 
 


2. Plan of attack - Understanding and exploiting how conditional jumps operate.
  



Conditional  jumps are by far, the newbies number one choice to search for a program's weakness by, this is because a conditional jump has only two possible actions associated with it. They will either tell the computer to go and execute the program's code somewhere else (perhaps display the 'beggar off Cracker message) or they can be ignored (perhaps to allow the program to be registered), just as though they never existed.

Newbies will more often than not, prefer to NOP (90h) out a conditional jump or change it into a unconditional jump (jump regardless) and this will often work, until that is, programmers in mass decide to incorporate code routines into their programs  to detect such tampering from crackers.

Many programs, and this includes AI Picture Explorer uses text strings that can be clearly seen in dead listings created by W32Dasm.  If we've examined the registration procedure with this program then we know that it asks the User for their User Name and when it rejects this we are given the message "Invalid entry; please reenter."

OK, so lets examine this section of code a little more closely... Fortunately, there is only one occurrence of this error message..:)

* Referenced by a (C)onditional Jump at Addresses:
:40080811(C), :4008086C(C), :400808D1(C), :40080924(C)
 
:40080993 FF45E8            inc [ebp-18]
:40080996 6A00              push 00000000
:40080998 668B0DEC0A0840    mov cx, word ptr [40080AEC]
:4008099F B201              mov dl, 01
:400809A1 B8F80A0840        mov eax, 40080AF8 ;->"Invalid entry; please reenter."
:400809A6 E871DFFBFF        call 4003E91C
:400809AB 807DEF00          cmp byte ptr [ebp-11], 00
:400809AF 0F85D2FEFFFF      jne 40080887
:400809B5 E9FAFDFFFF        jmp 400807B4
 
Cracker's commonly call any routine that displays an invalid serial/password message as 'The beggar off cracker' routine or 'Bad cracker' routine.

The important information above are those four memory address where this routine gets executed. :40080811, :4008086C, :400808D1, :40080924

So we now must examine these address in turn and find out what 'triggers' the program to forcing us to come here each time we try and register this program..

The first 'trigger' we find to our 'Beggar off cracker' routine looks like this...

:400807F2 B8280A0840      mov eax, 40080A28
:400807F7 E828E2FBFF      call 4003EA24
:400807FC 84C0            test al, al
:400807FE 0F84B6010000    je 400809BA
:40080804 A1948D0940      mov eax, dword ptr [40098D94]
:40080809 E81A35F8FF      call 40003D28
:4008080E 83F80C          cmp eax, 0000000C ;Name must >=11 characters
:40080811 0F8C7C010000    jl 40080993       ;Jump if less than 11 characters.

So all we need to do to avoid this from happening is to enter 11 or more characters for our User Name.  There's no need to patch this conditional jump.
 
 

Next, our second 'trigger' to our 'Beggar off cracker' routine looks like this...

:4008085D 83E607         and esi, 00000007
:40080860 8D4631         lea eax, dword ptr [esi+31]
:40080863 33DB           xor ebx, ebx
:40080865 8A5DA7         mov bl, byte ptr [ebp-59]
:40080868 3A441DA7       cmp al, byte ptr [ebp+ebx-59] ;al holds a checksum
                                                       ;for the User Name
                                                       ;which is then
                                                       ;compared against
                                                       ;the byte stored at
                                                       ;[ebp+ebx-59]
 
:4008086C 0F8521010000   jne 40080993                  ;If al<>checksum then jump

Here we would need to disable the jne 40080993 jump so that it never sends us to the 'beggar off cracker' routine. We could, if we wish, simply NOP (90h) it out easily enough.
 
 

Next, our third 'trigger' to our 'beggar off cracker' routine looks like this...
 

:400808C9 E85A34F8FF     call 40003D28
:400808CE 83F804         cmp eax, 00000004 ;Is serial >=4 numbers
:400808D1 0F8CBC000000   jl 40080993       ;Jump if less than 4 characters.

Again,  all we need to do to avoid this from happening is to enter 4 or more numbers for our Serial Number.  There's no need to patch this conditional jump.
 
 
 

 
Our fourth and final 'trigger' to our 'Beggar off cracker' routine looks like this...

:4008091D 8A55A7        mov dl, byte ptr [ebp-59]
:40080920 3A4415A7      cmp al, byte ptr [ebp+ebx-59]  ;al holds a checksum
                                                       ;for the Serial No
                                                       ;which is then
                                                       ;compared against
                                                       ;the byte stored at
                                                       ;[ebp+ebx-59]
:40080924 756D          jne 40080993                   ;If al<>checksum then jump
 
Here again we would need to disable the jne 40080993 jump so that it never sends us to the 'beggar off cracker' routine. We could, if we wish, simply use two NOP's (90h) to accomplish this.
 

Unlike the first method described above, this method would require no editing of the System Registry File because we would be using the program itself to do the inserting of our User details into the Registry File..
 
I would normally now show you what locations to patch our target program but this practice will now be discontinued.  I have shown you enough information for you to work this out for yourself and have no wish to see anyone use this essays as a quick way to steal software.. If your after knowledge and understanding then why would you want me to show you exactly where to patch this program..

 



 
3. Plan of attack - Understanding how the program validates the User Name & Serial Numbers when you try and register it..
 


 
While working on this program and trying to figure out why this program ignores User Names if they don't end with a number I discovered the following...

The program will ignore any User Name if it is less than 12 characters in length. Further more, the program expects you to tag a digit at the end of the User Name. This numeric value will be from 0 to 9.

Example: The Sandman_6
 

You can test this out yourself.  Enter a User Name (must be 12 characters or more) and experiment adding a digit [0-9] at the end of this User Name.  After a few tries the program WILL accept your User Name.

Next, the serial number also works in a similar manner, only this time the serial number must be four numbers or more in length.  It must also end with a Capital Letter, ranging from [A to Z] but 'Y' seems to be quite common.

Example:  1234Y

Interestingly, the program will insert a further letter in front of your serial number when it places this in your System registry file. So if you used the serial number 1234Y to register this program then in your System Registry file you will see:  n1234Y

The program will only display the first 11 characters of your User Name in the About Screen, regardless of how many letters you original used to register this program.
 

 Job Done.
 
The Crack
     
See Above.
 
Final Notes 
    

Interesting note about this program and you won't realize this UNLESS you've studied it properly, is that this program runs as a fully registered program UNTIL you either Select the 'About' screen or choose to close the program down.  Only then does it check to see if you've registered it!.
 

My thanks and gratitude goes to:-
 
Fravia+ for providing possibly the greatest source of Reverse Engineering
knowledge on the Web.
 
+ORC for showing me the light at the end of the tunnel.
 
Ob Duh 
 
Do I really have to remind you all that by buying and NOT stealing the software you use will ensure that these software houses will be encouraged to producing even *better* software for us to use and enjoy.

Ripping off software through serials and cracks is for lamers..
 
If your looking for cracks or serial numbers from these pages then your wasting your time, try searching elsewhere on the Web under Warze, Cracks etc.
 


 
 
 Next   Return to Essay Index   Previous 
 

Essay by:          The Sandman
Page Created: 13th December 1998