Thinking Like a Cracker
A
lesson for the Beginner
Writtenby
The _RudeBoy_ [PC]
This essay is aimed towards beginning crackers, and helping them to think like a
cracker. I can't count how many times I have been asked by a beginning cracker about why
they can patch a program so that it says that it's been registered, but then when they
restart the application it no longer says that it's registered. The solution is usually
quite simple, but requires you to "think like a cracker".
W32Dasm 8.9 (or whatever version you prefer)
Hex Workshop (or your favorite
hex editor)
PolyView 3.00 beta 9
http://www.polybytes.com/betafiles/pvbeta.exe
Before we get started with cracking our target, PolyView 3.00 beta
9, we need
a lesson in thinking like a cracker/programmer. Programmers are taught
that
whenever you have a task that is going to be done more that once, you should
create a function to do that task, and just call the function when you
need to
perform the task. Now, most programs that use a name/serial # combination
check the code at least twice, once when you enter the code, and once when
the
program starts up. Because of this the programmer will usually call
a function
to test your reg code. And usually, this function will be called
every time the
code is checked. At this point you should probably see where I am
going with
this. If you patch the function that is called to test the reg code,
it will
show up as valid whenever the program does it's check.
Now, for an example of this technique, on to PolyView 3.00 beta 9.
When you run the program you should notice on the menubar the "Registration"
section,
and under that, "License Information". It has a place to enter a
name and a license
code. Enter whatever you like for these values and press "OK".
If you have not
entered an integer into the license code box, you will receive an error
saying "Please
enter a positive integer", otherwise you will receive the error "Registration
Unsuccessful".
Fire up W32Dasm, and load PolyView.exe. When this is done go to the
string references
and look for "Registration Unsuccessful". When you find it in the
list, notice that
just above it is the string "Registration successful", and then double
click on
"Registration Unsuccessful". You should see this section of code:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004400C9(C)
|
* Possible Reference to String Resource ID=00141: "Unregistered"
|
:0044016C 688D000000
push 0000008D
:00440171 8BCF
mov ecx, edi
:00440173 E8D9070600
call 004A0951
:00440178 53
push ebx
:00440179 53
push ebx
* Possible StringData Ref from Data Obj ->"Registration unsuccessful. please
"
->"verify that you have entered the "
->"information exactly as shown on "
->"your registration letter."
|
:0044017A 684C364F00
push 004F364C
:0044017F 899E70010000
mov dword ptr [esi+00000170], ebx
:00440185 E8D88A0600
call 004A8C62
You should notice first that this section of code was referenced by a
conditional jump at 004400C9. Scroll up in w32dasm until you get
to that location, you should see this code:
:004400B7 50
push eax
:004400B8 51
push ecx
:004400B9 898670010000
mov dword ptr [esi+00000170], eax
:004400BF E8DCF0FEFF
call 0042F1A0 ;IsValidCode()
:004400C4 83C408
add esp, 00000008
:004400C7 85C0
test eax, eax ;The infamous test
:004400C9 0F849D000000
je 0044016C ;je Bad_Guy
Here is where we apply what we learned earlier. If you were to simply
NOP out the je 044016C the program would say that it is registered when
you enter in your code. However, When you restart the program, it
would
still say "Unregistered". Remember what I said about programmers
writing
one function, and calling it many times to see if the code is valid?
That
is what this author has done, the call to 0042F1A0 is the program calling
that function. In w32dasm, goto code location 0042F1A0, and you will
see
this:
* Referenced by a CALL at Addresses:
|:0040423B , :004046B8 , :004055FA
, :0042DDBE , :0042DE36
|:004395C4 , :0043CE1A , :0043D6B0
, :0043E35A , :00440025
|:004400BF , :004419BC , :0044234D
, :00452FF9 , :004531CB
|:004B9033
|
:0042F1A0 64A100000000
mov eax, dword ptr fs:[00000000]
Every one of those addresses is a place where this program calls the
IsValidCode() routine to see if the program is registered. Now, the
question remains.how do you patch this program so that it is
registered. Look again to the section of code that calls the
IsValidCode() routine, specifically at the jump to Bad_Guy. It will
jump if eax = 0. So, the easiest way to patch this program is to
write
over the mov eax, dword ptr fs:[00000000] in the called function with:
push 00000001
pop eax
ret
(In hex that would be 6A0158C3)
The function now always returns 1 in eax, and the program thinks that
it has been registered.
The techniques employed here do not only apply to cracking programs with
name/reg code routines. Do not limit yourself by thinking "Inside the Box",
these techniques can be used with many other types of protections as well.
(for example, many times a date check and a nag screen are done by
one function
I wont even bother explaining you that you should BUY this target
program if you intend to use it for a longer period than the allowed one.
Should you want to STEAL this software instead, you don't need to crack
its protection scheme at all: you'll find it on most Warez sites, complete
and already regged, farewell.
[Back]