316 lines
13 KiB
Plaintext
316 lines
13 KiB
Plaintext
888 ,e,
|
|
e88'888 888,8, ,"Y88b e88'888 888 ee " 888 8e e88 888
|
|
d888 '8 888 " "8" 888 d888 '8 888 P 888 888 88b d888 888
|
|
Y888 , 888 ,ee 888 Y888 , 888 b 888 888 888 Y888 888
|
|
"88,e8' 888 "88 888 "88,e8' 888 8b 888 888 888 "88 888
|
|
, 88P
|
|
Qapla's cracking tutorial, version 0.1 rel 970209 "8",P"
|
|
|
|
|
|
1. Introduction
|
|
~~~~~~~~~~~~~~~
|
|
|
|
Welcome to my first attempt to write a Windows 95 cracking tutorial.
|
|
|
|
This file is not meant as an introduction to either SoftIce, assembler
|
|
or cracking in general. I will assume that you have installed SoftIce
|
|
2.0 or 3.0 and that you are familiar with it. Some assembler and Win32
|
|
API knowledge is also useful. If you are new to cracking, before
|
|
continuing please read some of the files on cracking already available
|
|
on the net, for example ED!SON's excellent tutorial. In his tutorial you
|
|
will find an introduction to SoftIce, how to load exports and much more.
|
|
|
|
|
|
2. The program
|
|
~~~~~~~~~~~~~~
|
|
|
|
In this tutorial, I will use a great little program that you probably
|
|
will find on the net by doing a simple search for it. The program is
|
|
called StartClean, and the version I use is 1.2. The program scans the
|
|
Windows 95 Start Menu and removes all shortcuts that don't point to
|
|
anything. This is actually a very handy utility for those with a lot
|
|
of software passing through their harddisks (like me), so this is one
|
|
of the few little utilities I actually use. Another great thing about
|
|
this program is that it is only 31kb, so it doesnt hog massive amounts
|
|
of my harddrive. You *might* find this program attached to this tutorial.
|
|
|
|
When you start the program it will fire up with a little nag-screen asking
|
|
you to register it if you use it for more than 30 days. Even if we will
|
|
defeat this protection several times in this file, I'm asking you that
|
|
if you start using the program, please register it. The author deserves
|
|
the money he is asking for it.
|
|
|
|
|
|
3. The extremly simplistic approach
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
In this section I will use a method that works with this program,
|
|
but it wont work with most other programs. I included it here to
|
|
show you that there is no need to make anything more difficult then
|
|
nessesary. (this is a good philosophy of life by the way :)
|
|
|
|
Fire up the program, and press 'Register...'
|
|
|
|
The program will show you a small dialog-box, asking you to enter your
|
|
name and secret code. Now enter your name and any code. I entered
|
|
"Qapla'97" and "115522". Press OK and it will tell you that the code was
|
|
incorrect.
|
|
|
|
Now comes the interesting part.
|
|
|
|
In the explorer press the right mouse button on the file, and select
|
|
Quick-View. A window will pop up with a lot of information about the
|
|
file. The section we are interested in is the 'Import Table'. Scroll
|
|
down until you reach this section.
|
|
|
|
You will hopefully see something like this:
|
|
|
|
Import Table
|
|
------------
|
|
|
|
COMCTL32.dll
|
|
Ordinal Function Name
|
|
------- -------------
|
|
|
|
KERNEL32.dll
|
|
Ordinal Function Name
|
|
------- -------------
|
|
|
|
026c lstrcmpiA
|
|
00d7 GetFileAttributesA
|
|
026f lstrcpyA
|
|
0045 DeleteFileA
|
|
0269 lstrcmpA
|
|
01c1 RemoveDirectoryA
|
|
. .
|
|
. .
|
|
. .
|
|
|
|
This section displays the API's the file uses. By setting a breakpoint
|
|
on any of these you will be able to intercept the program when it uses
|
|
them.
|
|
|
|
Here comes the good part. The program somewhere in the code probably
|
|
compares the code you entered with a pregenerated code, previously
|
|
calculated from the name you entered.
|
|
|
|
What does the 'lstrcmpA' function do? Lets look in the API-reference
|
|
(the file I use is called Win32.hlp from the Win95-SDK, distributed
|
|
with most real development environments, for example Borlands excellent
|
|
Delphi 2.0)
|
|
|
|
--- From Win32.hlp ---
|
|
|
|
The lstrcmp function compares two character strings. The comparison is
|
|
case sensitive.
|
|
|
|
int lstrcmp(
|
|
LPCTSTR lpString1, // address of first string
|
|
LPCTSTR lpString2 // address of second string
|
|
);
|
|
|
|
Parameters
|
|
|
|
lpString1
|
|
Points to the first null-terminated string to be compared.
|
|
|
|
lpString2
|
|
Points to the second null-terminated string to be compared.
|
|
|
|
Return Value
|
|
|
|
If the function succeeds and the string pointed to by lpString1
|
|
is less than the string pointed to by lpString2, the return value
|
|
is negative; if the string pointed to by lpString1 is greater than
|
|
the string pointed to by lpString2, it is positive. If the strings
|
|
are equal, the return value is zero.
|
|
|
|
---- End ---
|
|
|
|
|
|
So, lets try setting a breakpoint on 'lstrcmpA'
|
|
|
|
Press ^D, and when the SoftIce screen appears type 'BPX lstrcmpA',
|
|
now press ^D again and press OK once more.
|
|
|
|
blam, we were kicked back to SoftIce.
|
|
|
|
** Break due to KERNEL32!lstrcmp
|
|
|
|
Now press F12 to return to the calling function, and you should see
|
|
something like this:
|
|
.
|
|
.
|
|
.
|
|
0157:004011DD 50 PUSH EAX <- push your code on the stack
|
|
0157:004011DE 6830604000 PUSH 406030 <- push the right code on the stack
|
|
0157:004011E3 FF1520924000 CALL [KERNEL32!lstrcmp] <- compare them
|
|
0157:004011E9 85C0 TEST EAX, EAX
|
|
0157:004011EB 0F8580000000 JNZ 00401271 <- check if they were the same
|
|
.
|
|
.
|
|
|
|
At this point we have two options:
|
|
|
|
a) Patch the JNZ to NOP's - This will make the program register with
|
|
any code. This *may* introduce other
|
|
problems, most noteably it might have a
|
|
similar unpatched check in another part
|
|
of the program that you won't notice.
|
|
|
|
b) Find out the code it - This is a much better way of working as
|
|
compared your code with you dont need to change the code and the
|
|
serial you find will probably work with
|
|
the next version of the software as well,
|
|
the crack will probably stop working when
|
|
you upgrade.
|
|
|
|
Alternative (a) is left as an exercise to the reader :)
|
|
|
|
Now type 'd 406030' <- this was the address it pushed on the stack, remember?
|
|
|
|
The data-window will now display the correct code, in my case 1398-13026-
|
|
1211-249
|
|
|
|
As i said in the beginning of this section, setting a breakpoint on
|
|
string-compare API's will seldom work, as most programs use their own
|
|
routine for doing this. The next section will present another, very
|
|
similar approach to the same problem, but it will not rely on the
|
|
same API.
|
|
|
|
|
|
4. The hmemcpy-bpm approach
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
If you registered the program in the following section and wish to
|
|
'unregister' it, so you can try this approach as well, you can start
|
|
regedit, and delete the following key:
|
|
|
|
HKEY_CURRENT_USER\SOFTWARE\Start Clean\Configuration
|
|
|
|
Do a 'BC *' to clear all your existing breakpoints, and enter your name
|
|
in the registration-box once again. (be sure to use an incorrect code,
|
|
as we dont want to register it right now). Don't press OK yet.
|
|
|
|
Now enter 'BPX hmemcpy', and press OK in the dialog. We will be back in
|
|
SoftIce. Note that we are no longer in the flat addressing mode. This is
|
|
protected mode 16bit code, ie in another context. We need to get back into
|
|
the flat code before we can search all memory, but before we do that we
|
|
will press ^D once again. The program just scanned our name this time,
|
|
and we are just interested in is setting a breakpoint to trap access to
|
|
the code we entered.
|
|
|
|
We will shortly be back into softice again. Now press F12 a few times
|
|
until we reach the 32bit code. You will notice this by looking at the
|
|
addresses in the code window...
|
|
|
|
0137:9EA6 <- this is a segmented 16-bit address.
|
|
0157:004011B5 <- this is a 32-bit flat address.
|
|
|
|
When you reach this code we can scan for the text we entered in the
|
|
code-window. (you entered something unique didn't you, as we will be
|
|
searching all physical memory, and a code like 0000 will probably
|
|
be found in a lot of unrelated locations)
|
|
|
|
Enter "s 0 l ffffffff 'your_code_here'" and press enter.
|
|
|
|
Now two things can happen. either it finds your code in a low address,
|
|
(and this is what we are looking for), or it will find it somewhere
|
|
around 0x80000000 (this is Windows internal memory-space, and not what
|
|
we are looking for (Windows reserves the upper 2gig for internal use,
|
|
and non ring 0 code will only have access to memory in the lower part
|
|
of the address space))
|
|
|
|
When you found what looks like the right place in memory, (I found
|
|
it at 015f:0063f580), we will set a breakpoint for memory access there.
|
|
|
|
Use 'BPM 0063f580' (or whatever address you found).
|
|
|
|
Don't forget to 'BD hmemcpy' as well, as we will not be needing that
|
|
breakpoint any more.
|
|
|
|
Press ^D and you it will stop right in the function that compares the
|
|
two strings.
|
|
|
|
This method is usually much better than the previous, as it doesn't assume
|
|
that the program uses any specific API's. It is usually safe to set a
|
|
breakpoint on hmemcpy as almost all Win32-programs rely on this function
|
|
to retrieve information from dialogs.
|
|
|
|
|
|
5. Other ways
|
|
~~~~~~~~~~~~~
|
|
|
|
So, we have now defeated this program in two similar ways, and at this
|
|
point I am starting to realize my bad choice of program as this little
|
|
program doesn't contain any strange or non-standard things. It is rather
|
|
unusually simplistic. If you feel like making a keymaker, which is the
|
|
thing any *real* cracker would do, you can find the entrypoint to the
|
|
code-generating routine just above the call to lstrcmp.
|
|
|
|
|
|
A. Setting breakpoints
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
In ED!SON's tutorial, the author talks about the problems of setting
|
|
breakpoints, especially when Norton Commander is active. When you
|
|
try to do a BPX GETDLGITEMTEXTA, you might get the 'No LDT' error.
|
|
DOS windows, and especially Norton Commander hogs much of the CPU
|
|
and if you are running them, there is a good chance you will end up
|
|
in a VDM instead of the PROT32-mode you want to be in. SoftIce 3.0
|
|
seems to handle this much smarter, so if you are having problems
|
|
try installing the latest version of the debugger. This is an issue
|
|
of address-contexts and an extensive discussion on the topic can be
|
|
found in the documentation for SoftIce 3.0. If you are trying to set
|
|
a breakpoint in the code you are debugging and it doesnt work, try to
|
|
break on a general API, and press F12 until you reach the context you
|
|
are looking for, and then set the breakpoint.
|
|
|
|
|
|
B. Recommended reading
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The reason I wrote this tutorial is that during the last years, I have
|
|
read quite a few text on cracking by different authors. I always wanted
|
|
to make something similar to make a small contribution to this, and
|
|
hopefully make someone reach a higher level of knowledge in cracking.
|
|
|
|
I would like to recommend some of the great text on cracking already
|
|
available on the net:
|
|
|
|
* ED!SON's Cracking Tutorial - This is a great file that contains
|
|
an introduction to debugging, SoftIce
|
|
and cracking. If you havn't read it
|
|
yet, do so now. This file is *very*
|
|
recommended for everyone.
|
|
|
|
* +ORC's Cracking Tutorials - These files are split up in lessons,
|
|
each one talking about a different
|
|
approach or side of cracking. Most
|
|
of the lessons are very much worth
|
|
reading, even if I dont agree with
|
|
him in the frequent discussions about
|
|
languages like Delphi or the world in
|
|
general :) They might be a bit hard
|
|
to find as he seems to be a bit
|
|
reluctant about placing all of them
|
|
on the net.
|
|
|
|
C. Thanks
|
|
~~~~~~~~~
|
|
|
|
The author would like to thank the following persons for helping him
|
|
with debugging the text, and verifying the wannabee-cracker-author's
|
|
theory's...
|
|
|
|
[prizna], odin- and kOUGER - thanks!
|
|
|
|
|
|
D. Contacting me
|
|
~~~~~~~~~~~~~~~~
|
|
You dont, but you *might* be able to find me on US-EFnet IRC.
|
|
Check for the nick qapla, it might be me.
|
|
|
|
|
|
thank you for reading this far, I hope you enjoyed it. (c)1997, Qapla'
|