Skip to content

Instantly share code, notes, and snippets.

@tanis2000
Forked from callowaysutton/Advanced.txt
Created June 30, 2023 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanis2000/a6788dd53848a4b23938a7d504040e4c to your computer and use it in GitHub Desktop.
Save tanis2000/a6788dd53848a4b23938a7d504040e4c to your computer and use it in GitHub Desktop.
Introduction to Hacking
HOW TO CRACK, by +ORC, A TUTORIAL
Lesson A.1: Advanced Cracking: Internet Cracking (Unix)
-------------> INTERNET CRACKING: FIREWALLS
With each new company that connects to the "Information
Superhighway" new frontiers are created for crackers to explore.
Site administrators (Siteads) have implemented various security
measures to protect their internal networks. One of these is
xinetd, covered later. A more general solution is to construct
a guarded gateway, called a [Firewall], that sits between a
site's internal network and the wild and woolly Internet where
we roam. In fact only one third of all Internet connected
machines are already behind firewalls. Most information services
have to deal with the same problem we have: getting OUT through
a local firewall or GETTING INTO a service through their
Firewall. There lays also the crack_solution.
------------> What is a Firewall?
The main purpose of a Firewall is to prevent unauthorized
access between networks. Generally this means protecting a site's
inner network from the Internet. If a site has a firewall,
decisions have been made as to what is allowed and disallowed
across the firewall. These decisions are always different and
always incomplete, given the multiplicity of Internet, there are
always loopholes where a cracker can capitalize on.
A firewall basically works by examining the IP packets that
travel between the server and the client. This provides a way to
control the information flow for each service by IP address, by
port and in each direction.
A firewall embodies a "stance". The stance of a firewall
describes the trade-off between security and ease-of-use. A
stance of the form "that which is not expressly permitted is
prohibited" requires that each new service be enabled
individually and is seldom used, coz very slow and annoying.
Conversely, the stance "that which is not expressly prohibited
is permitted" has traded a level of security for convenience. It
will be useful to guess the stance of the firewall you are
cracking when making probe decisions.
A firewall has some general responsibilities:
* First and foremost if a particular action is not allowed by
the policy of the site, the firewall must make sure that all
attempts to perform the action will fail.
* The firewall should log suspicious events
* The firewall should alert internal administration of all
cracking attempts
* Some firewall provide usage statistics as well.
------------> Types of Firewall
In order to avoid head-scratching, it's a good idea to know
the TOPOLOGY of "your" firewall -and its limitations- before
attempting to get through it. Discussed below are two popular
firewall topologies. Although other types exist, the two below
represent the basic forms; most other firewalls employ the same
concepts and thus have -luckily- the same limitations.
1) THE DUAL-HOMED GATEWAY
A dual-homed Gateway is a firewall composed of a single
system with at least two network interfaces. This system is
normally configured such that packets are not directly routed
from one network (the Internet) to the other (the internal net
you want to crack). Machines on the Internet can talk to the
gateway, as can machines on the internal network, but direct
traffic between nets is blocked.
In discussing firewalls, it's generally accepted that you
should think of the inner network as a medieval castle. The
"bastions" of a castle are the critical points where defence is
concentrated. In a dual-homed gateway topology, the dual-homed
host itself is called the [BASTION HOST].
The main disadvantage of a dual-homed gateway, from the
viewpoints of the users of the network and us crackers alike, is
the fact that it blocks direct IP traffic in both directions. Any
programs running on the inner network that require a routed path
to external machines will not function in this environment. The
services on the internal network don't have a routed path to the
clients outside. To resolve these difficulties, dual-homed
gateways run programs called [PROXIES] to forward application
packets between nets. A proxy controls the conversation between
client and server processes in a firewalled environment. Rather
than communicating directly, the client and the server both talk
to the proxy, which is usually running on the bastion host
itself. Normally the proxy is transparent to the users.
A proxy on the bastion host does not just allow free rein
for certain services. Most proxy software can be configured to
allow or deny forwarding based on source or destination addresses
or ports. Proxies may also require authentication of the
requester using encryption- or password-based systems.
The use of proxy software on the bastion host means that the
firewall administrator has to provide replacements for the
standard networking clients, a nightmare in heterogeneous
environments (sites with many different operating systems
platforms, PC, Sun, IBM, DEC, HP...) and a great burden for
administrator and users alike.
2) THE SCREENED HOST GATEWAY
A screened host gateway is a firewall consisting of at least
one router and a bastion host with a single network interface.
The router is typically configured to block (screen) all traffic
to the internal net such that the bastion host is the only
machine that can be reached from the outside. Unlike the dual-
homed gateway, a screened host gateway does not necessarily force
all traffic through the bastion host; through configuration of
the screening router, it's possible to open "holes" in the
firewall to the other machines on the internal net you want to
get into.
The bastion host in a screened host firewall is protected
from the outside net by the screening router. The router is
generally configured to only allow traffic FROM SPECIFIC PORTS
on the bastion host. Further, it may allow that traffic only FROM
SPECIFIC EXTERNAL HOSTS. For example the router may allow Usenet
news traffic to reach the bastion host ONLY if the traffic
originated from the site's news provider. This filtering can be
easily cracked: it is relying on the IP address of a remote
machine, which can be forged.
Most sites configure their router such that any connection
(or a set of allowed connections) initiated from the inside net
is allowed to pass. This is done by examining the SYN and ACK
bits of TCP packets. The "start of connection" packet will have
both bits set. If this packets source address is internal... or
seems to be internal :=) the packet is allowed to pass. This
allows users on the internal net to communicate with the internet
without a proxy service.
As mentioned, this design also allows "holes" to be opened
in the firewall for machines on the internal net. In this case
you can crack not only the bastion host, but also the inner
machine offering the service. Mostly this or these machine/s will
be far less secure than the bastion host.
New services, for instance recent WEB services, contain a
lot of back doors and bugs, that you'll find in the appropriate
usenet discussion groups, and that you could use at freedom to
crack inner machines with firewall holes. Sendmail is a good
example of how you could crack in this way, read the whole
related history... very instructive. The rule of thumb is "big
is good": the bigger the software package, the more chance that
we can find some security related bugs... and all packages are
huge nowadays, 'coz the lazy bunch of programmers uses
overbloated, buggy and fatty languages like Visual Basic or
Delphy!
Finally, remember that the logs are 'mostly) not on the bastion
host! Most administrators collect them on an internal machine not
accessible from the Internet. An automated process scan the logs
regularly and reports suspicious information.
3) OTHER FIREWALL TOPOLOGIES
The dual-homed gateway and the screened host are probably the
most popular, but by no mean the only firewall topologies. Other
configurations include the simple screening router (no bastion
host), the screened subnet (two screening routers and a bastion
host) as well as many commercial vendor solutions.
------------> Which software should we study?
Three popular unix software solutions allow clients inside a
firewall to communicate with server outside: CERN Web server in
proxy mode, SOCKS and the TIS Firewall toolkit.
1) The CERN Web server handles not only HTTP but also the other
protocols that Web clients use and makes the remote connections,
passing the information back to the client transparently. X-based
Mosaic can be configured for proxy mode simply by setting a few
environment variables.
2) The SOCKS package (available free for anonymous ftp from
ftp.nec.com in the file
/pub/security/socks.cstc/socks.cstc.4.2.tar.gz
includes a proxy server that runs on the bastion host of a
firewall. The package includes replacements for standard IP
socket calls such as connect(), getsockname(), bind(), accept(),
listen() and select(). In the package there is a library which
can be used to SOCKSify your crack probes.
3) The Firewall Toolkit
The toolkit contains many useful tools for cracking firewall and
proxy server. netacl can be used in inetd.conf to conceal
incoming requests against an access table before spawning ftpd,
httpd or other inetd-capable daemons. Mail will be stored in a
chroot()ed area of the bastion for processing (mostly by
sendmail).
The Firewall toolkit is available for free, in anonymous ftp from
ftp.tis.com in the file
/pub/firewalls/toolkit/fwtk.tar.Z
The popular PC firewall solution is the "PC Socks Pack", for MS-
Windows, available from ftp.nec.com It includes a winsock.dll
file.
The cracking attempts should concentrate on ftpd, normally
located on the bastion host. It's a huge application, necessary
to allow anonymous ftp on and from the inner net, and full of
bugs and back doors. Normally, on the bastion host, ftpd is
located in a chroot()ed area and runs as nonprivileged user. If
the protection is run from an internal machine (as opposing the
bastion host), you could take advantage of the special inner-net
privileges in hostp.equiv or .rhosts. If the internal machine
"trusts" the server machine, you'll be in pretty easily.
Another good method, that really works, is to locate your
PC physically somewhere along the route between network and
archie server and "spoof" the firewall into believing that you
are the archie server. You'll need the help of a fellow hacker
for this, though.
Remember that if you gain supervisor privileges on a machine
you can send packets from port 20, and that in a screened host
environment, unless FTP is being used in proxy mode, the access
filters allow often connections from any external host if the
source port is 20 and the destination port is greater than 1023!
remember that NCSA Mosaic uses several protocols, each on
a different port, and that -if on the firewall no proxy Web
server is operating- each protocol must be dealt with
individually, what lazy administrators seldom do.
Be careful for TRAPS: networking clients like telnet and ftp
are often viciously replaced with programs that APPEAR to execute
like their namesake, but actually email an administrator. A
fellow cracker was almost intercepted, once, by a command that
simulated network delays and spat out random error messages in
order to keep me interested long enough to catch me. Read the
(fictions) horror story from Bill Cheswick: "An evening with
Berferd in which a cracked is lured, endured and studied",
available from ftp.research.att.com in
/dist/internet_security/berferd.ps
As usual, all kind of traps can be located and uncovered by
correct zen-cracking: you must *FEEL* that some code (or that
some software behaviour) is not "genuine". Hope you believe me
and learn it before attempting this kind of cracks.
------------> How do I crack Firewalls?
Some suggestions have been given above, but teaching you how
to crack firewalls would take at least six complete tutorial
lessons for a relatively unimportant cracking sector, and you
would almost surely get snatched immediately, 'coz you would
believe you can crack it without knowing nothing at all. So, for
your sake, I'll teach you HOW TO LEARN IT, not HOW TO DO IT
(quite a fascinating difference): First Text, then the software
above. For text, start with Marcus Ranum's paper "Thinking about
Firewalls", available from ftp.tis.com in the file/pub/firewalls/firewalls.ps.Z
and do an archie search for newer literature.
Join the firewall discussion list sending a message to
majordomo@greatcircle.com, you'll get a message with
instructions, as usual, lurk only... never show yourself to the
others.
You can find for free on the web quite a lot of early
versions of proxy software. Study it, study it and then study it
again. The cracking efforts on your copies, and your machines,
before attempting anything serious, are MANDATORY if you do not
want to be immediately busted on the Internet. When you feel
ready to try serious cracking, you must OBLIGATORY start with a
small BBS which uses a firewall version you already studied very
well (sysops are not firewall administrators, and many of them
do not know nothing about the software they use). As soon as you
gain access to the bastion host, remember to subvert entirely the
firewall itself before entering the inner net.
If you feel ready and everything went well so far, if your zen-
cracking abilities are working well... then take a moment for
yourself... prepare yourself a good Martini-Wodka (you should
only use Moskovskaia), take a deep breath and by all means go
ahead! You will then be able to try your luck on the Cyberspace
and get quickly busted (if you did not follow my admonitions and
if you cannot zen-crack) or, may be, fish quite a lot of
jewels... :=)
-------------> INTERNET CRACKING: XINETD
[Xinetd] a freely available enhanced replacement for the
internet service daemon inetd, allows just those particular users
to have FTP or Telnet access, without opening up access to the
world. Xinetd can only protect the system from intrusion by
controlling INITIAL access to most system services and by logging
activities so that you can detect break-in attempts. However,
once a connection has been allowed to a service, xinetd is out
of the picture. It cannot protect against a server program that
has security problems internally. For example, the finger server
had a bug several years ago that allowed a particularly clever
person to overwrite part of its memory. This was used to gain
access to many systems. Even placing finger under the control of
xinetd wouldn't have helped.
Think of the secured firewall system as a fortress wall:
each service that is enabled for incoming connections can be
viewed as a door or window in the walls. Not all these doors have
secure and reliable locks. The more openings are available, the
more opportunities are open for us.
-------------> What xinetd does
Xinetd listens to all enabled service ports and permits only
those incoming connection request that meet authorization
criteria.
- Accept connections from only certain IP addresses
- Accept connections only from authorized users
- Reject connections outside of aithorized hours
- Log selected service when connections are accepted or
rejected, capturing following informations:
* Remote Host Address
* User ID of remote user (in some cases)
* Entry and Exit time
* Terminal type
Support login, shell, exec and finger
-------------> SERVICES TO CRACK &
UNWITTING INSIDE COMPLICES
In this order the easy services:
FTP TELNET LOGIN (rlogin) SHELL (rcmd) EXEC
In this order the more difficult ones:
MOUNT TFT FINGER NFS(Network File System)
DNS(Domain Name Service)
Remember that sendmail (SMTP), by default, accepts a message from
any incoming connection. The "sender" of such a message can
appear to have originated anywhere, therefore your claim of
identity will be accepted! Thus you can forge a message's
originator. Most of the recipients inside the protected
(firewalled) net will take your claim at face value and send you
(to the "return address" you provide) all the sensitive
information you need to crack the system. Finding unwitting
inside complices is most of the time pretty easy.
By far the best method, for entering xinetd, is to get the
real version from panos@cs.colorado.edu, modify the system files
in order to have some backdoors, and then distribute them to the
mirror servers on the WEB. Each time a new administrator will
download "your" version of xinetd, you'll have an easy access to
the "protected" system.
On the Nets, it's important to conceal your identity (they
will find you out pretty quickly if you do not). The best method
is to obtain the IP address of a legitimate workstation during
normal hours. Then, late at night, when the workstation is known
to be powered-off or disconnected from a dialup PPP link, a
different node on the network can be configured to use the
counterfeit IP address. To everyone on the network, it will
appear that the "legitimate" user is active. If you follow this
strategy, you may want to crack somehow more negligently... the
search for the cracker will go on -later- in the false confidence
that a sloppy novice (the legitimate user) is at work, this will
muddle the waters a little more.
Well, that's it for this lesson, reader. Not all lessons of my
tutorial are on the Web.
You'll obtain the missing lessons IF AND ONLY IF you mail
me back (via anon.penet.fi) with some tricks of the trade I may
not know that YOU discovered. Mostly I'll actually know them
already, but if they are really new you'll be given full credit,
and even if they are not, should I judge that you "rediscovered"
them with your work, or that you actually did good work on them,
I'll send you the remaining lessons nevertheless. Your
suggestions and critics on the whole crap I wrote are also
welcomed.
+ORC an526164@anon.penet.fi
HOW TO CRACK, by +ORC, A TUTORIAL
LESSON C (1) - How to crack, Cracking as an art
[BARCODES] [INSTANT ACCESS]
[BARCODES]
First of all, let me stress the importance of cracking in
our everyday life. Cracking it's not just about software, it's
about information, about all patterns of life. To crack is to
refuse to be controlled and used by others, to crack is to be
free. But you must also be yourself free from petty conventions
in order to crack properly.
You must learn to discerne cracking possibilities all around
yourself, and believe me, the development of this ghastly society
brings every day new codes, protections and concealing
mechanismes.
All around us grows a world of codes and secret and not so
secret patterns. Codes that are at times so familiar and common
that we do not even notice them any more... and yet they are
there to fool us, and yet they offer marvellous cracking
possibilities.
Let's take as an striking example BARCODES... those little
lines that you see on any book you buy, on any bottle you get,
on any item around you... do you know how they work? If you do
not you may be excused, but you cannot be excused if you never
had the impulse to understand them... crackers are curious by
nature... heirs of an almost extinct race of researchers that has
nothing in common with the television slaves and the publicity
and trend zombies around us. Cracker should always be capable of
going beyond the obvious, seek knowledge where others do not see
and do not venture.
[BARCODE HISTORY]
Let's begin with a little history. Universal Product Code
(UPC) was adopted for commercial use by the grocery industry in
the USA. Among the advantages were a rapid, accurate and reliable
way of entering stock information into a computer and the
possibility to sack a lot of workers and to do more profit. The
early success led to the development of the European Article
Numbering System (EAN), a symbology similar to UPC, that is
widely used in Europe and in the rest of the World. I'll teach
you to crack this one, since I do not -fortunately- live in the
States. Keep in mind, anyway, that there are different barcode
symbologies, each with its own particular pattern of bars. The
UPC/EAN code used on retail products is an all-numeric code; so
is the Interleaved 2 of 5 Code. Code 39 includes upper case
letters, digits, and a few symbols. Code 128 includes every
printable and unprintable ASCII character code. The most new one
is a 2-D code. These are special rectangular codes, called
stacked barcodes or matrix codes. They can store considerably
more information than a standard barcode. They require special
readers which cost more than a standard scanner. The practical
limit for a standard barcode depends on a number of factors, but
20 to 25 characters is an approximate maximum. For applications
that need more data, matrix codes are used. For example, the next
time you receive a package from United Parcel Service look for
a small square label with a pattern of dots and a small bullseye
in the centre. This is a MaxiCode label, and it is used by UPS
for automatic destination sortition.
The manufacturer's ID number on the barcode uniquely
identifies products. These numbers are managed by the Uniform
Code Council in Dayton, Ohio for the States and Canada and by the
EAN authority (Internationale Article Numbering Association) in
Bruxelles, for Europe and the rest of the World. The
manufacturer's ID number accounts for some digits of the code,
which leaves other digits to be assigned in any way the producer
wants. He provides retail outlets with a list of his products and
their assigned codes so that they can be entered in the cash
register system. Many codes are NOT on the products and are added
by the supermarkets on the fly, using an internal code schema
that may be non standard. Now it's enough... let's crack.
BARCODES are the only thing an automated casher needs to see
on a product to calculate its price and automatically catalogate
the sold merchandise... imagine (just imagine it :=) coz it would
be extremely illegal to act in this way) somebody would fasten
an adhesive home-made codebar label direct on the top of the
supermarket/mall/retail store label, say on a bottle of Pomerol
(that's a very good but unfortunately very expensive french
wine).
The new label would mean for the casher something like
"cheap wine from Bordeaux, France, cost so and so, everything
it's OK, do not worry"... do you think that anybody would come
to the idea that there is something wrong with the label, with
the bottle or with you? I have been codebaring for years and had
only once a problem, coz my printer was running out of ink and
the scanner in the supermarket could not read it... so what? Act
uninterested, always wear jackets of the utmost quality, shetland
pullovers and beautiful expensive shoes... (all articles that you
may codebar too, by the way), in this society appearance and look
count much more than substance and knowledge... LET'S USE THIS
TO OUR ADVANTAGE! Nobody will ever come to the idea that you may
actually really know the working of the scheme... coz codebar is
pretty complicated and not exactly exceptionally public. On the
Web there are a lot information about it, but most of them are
useless, unless you know how to search most of the time you'll
find only sentences like this one:
"The calculated check digit is the twelfth and final
digit in the U.P.C.code. It is calculated based on a
specific algorithm, and is necessary to ensure that
the number is read or key-entered correctly."
But good +ORC will now explain you everything you need to crack:
[THE 13 BAR "CODES"]
Each barcode label has 13 values, from #0 to #12 (that's the EAN
code, the UPC american one has only 12, from #0 to #11).
#0 and #1 indicate the origin of the product.
#2 to #11 give the article code
#12 (the last and 13th one) is a checksum value, that
verifies the validity of all the other numbers.
How is it calculated? #12 is calculated in 4 steps
VALUE A: You sum odd position numbers (#0+#2+#4+#6+#8+#10)
VALUE B: You sum even position numbers and multiply by 3
((#1+#3+#5+#7+#9+#11)*3)
VALUE C: You sum value A and value B
VALUE D: You mod value C (you divide by 10 and only keep
the remaining units, a very widespread checking scheme as
you'll see in the software part of this lesson)
If the result is not zero, you subtract it from 10.
Now look at a barcode label, get some books or other barcoded
items and *watch* it...
Bar codes are supposed to have "quiet zones" on either side of
the symbol. Quiet zones are blank areas, free of any printing or
marks,typically 10 times the width of the narrowest bar or space
in the bar code. Failure to allow adequate space on either side
of the symbol for quiet zones can make it impossible to read the
bar code.
On the barcode there are two "borders", left and right, and a
"middle" longer line. These three lines are longer than the
others and are used to "regulate" the scanner to whatever
dimension has been used for the barcode.
#0 dwells left of the first (left) border and has a special
meaning, the other 12 numbers are written "inside" the code and
are divided in two "groups" by the middle bar.
Each value is coded through SEVEN bars: black=1 and White=0.
These form two couples of "optic" bars of different widths.
We come now to the "magic" part: In order to bluff the
simpletons, barcode uses three different SETS of characters to
represent the values 0-9. This should make it impossible for you
to understand what's going on, as usual, in this society, slaves
should not need to worry with the real functioning of things.
Here are the graphic codes of the three graphic sets:
CODE A CODE B (XOR C) CODE C (NOT A)
0: 0001101 (13) 0100111 (39) 1110010 (114)
1: 0011001 (25) 0110011 (51) 1100110 (102)
2: 0010011 (19) 0011011 (27) 1101100 (108)
3: 0111101 (61) 0100001 (33) 1000010 (066)
4: 0100011 (35) 0011101 (29) 1011100 (092)
5: 0110001 (49) 0111001 (57) 1001110 (078)
6: 0101111 (47) 0000101 (05) 1010000 (080)
7: 0111011 (59) 0010001 (17) 1000100 (068)
8: 0110111 (55) 0001001 (09) 1001000 (072)
9: 0001011 (11) 0010111 (23) 1110100 (116)
Borders: 101
Centre: 01010
- The C graphic set is a "NOT A" graphic set.
- The B graphic set is a "XOR C" graphic set.
- each value has two couples of bars with different widths
Now watch some labels yourself... see the difference between the
numbers left and the numbers right? The first "half" of the
barcode is coded using sets A and B, the second "half" using set
C. As if that were not enough, A and B are used inside the first
"half" in a combination that varies and depends from value #0,
following 10 different patterns:
#1 #2 #3 #4 #5 #6
0 A A A A A A
1 A A B A B B
2 A A B B A B
3 A A B B B A
4 A B A A B B
5 A B B A A B
6 A B B B A A
7 A B A B A B
8 A B A B B A
9 A B B A B A
"Ah! Stupid buyer will never understand why the same values gives
different bars! Nothing is as reliable as barcodes!" :=)
Let's take as example the codebar for Martini Dry:
BARCODE: 8 0 00570 00425 7
Let's see: we have a 8 0 0 = booze
Then a 000570 as ABABBA and a 004257 as C
"Even" sum: 8+0+5+0+0+2 = 15 (even sum)
Then a 0+0+7+0+4+5= 16 and 16 *3 = 48 (odd sum)
Then a 15+48=63
63 === 3
10 - 3 = 7 = checksum
Pattern = 8 = ABABBA CCCCCC
OK, one more example: Osborne Windows programming series Volume
2 General purpose API functions (always here on my table)...
BARCODE: 9 7 80078 81991 9
Let's see: we have a 9 7 8 = book
Then a 780078 as ABBABA and a 819919 as C
"Even" sum: 9+8+5+8+8+4 = 42 (even sum)
Then a 7+1+5+2+4+4= 23 and 23 * 3 = 69 (odd sum)
Then a 42+69=111
111 === 1
10 - 1 = 9 = checksum
Pattern = 9 = ABBABA
Well... what's the point of all this?
The point, my pupils, is that who DOES NOT KNOW is taken along
on a boat ride, who KNOWS and LEARNS can use his knowledge in
order to try to beat blue and black the loathsome consumistic
oligarchy where we are compelled to live. Try it out for
yourself... if you crack correctly and wisely your supermarket,
mall and library bills will be cut to almost zero.
Write a small program to print whichever codebar you fancy
(or whichever your mall uses) in whichever size on whichever sort
of label you (or better your targets) fancy... it's quickly done
with Visualbasic or Delphy... but you'll not find much on the Web
Alternatively you could also write, as I did long ago, a short
c program in dos, using a modified upper char set... and there
you are, have labels... see the world.
A small word of caution... crack only ONE item at time and
try it out first with the SAME label for the same product... i.e.
the correct code for that item, but on your own label. If it goes
through your program works good, if not, nobody will ever be able
to harm you. Anyway it never happens anything, never: the bar
code reading equipments have great tolerance, coz the scanners
must be able to recognize barcodes that have been printed on many
different medias. You should choose labels similar to the ones
effectively used only in order not to arise human suspects, coz
for all the scanner itself cares, your label could be pink with
green stripes and with orange hand-written, numbers. Mind you,
we are still just academically imagining hypothetical situations,
coz it would be extremely illegal to act in such an inconsiderate
manner.
CRACKING POWER! It's true for barcodes, for Telecom bills,
for Compuserve accounts, for Amexco cards, for banking cheques
(do you know what MICR is? Magnetic Ink Character Recognition...
the stylized little printing on the lower left of new cheques...
there is a whole cracking school working on it), for registration
numbers... you name it, they develope it, we crack it...
Begin with barcodes: it's easy, nice and pretty useful! Live
in opulence, with the dignity and affluence that should always
distinguish real crackers. Besides... you should see the
assortment of 'Pomerols' in my "Cave-a-vin" :=)
[INSTANT ACCESS]
The (c) Instant access routines are a commercial protection
scheme used to "unlock" complete commercial applications that
have been encrypted on CD-
ROMs which are distributed (mostly) through reviews.
This is an ideal cracking target: it's commercial software,
complete, uncrippled and of (relatively) prominent quality, that
you can get in tons for the price of a coke. Obviously this kind
of protection represents an ideal subject for our lessons. This
fairly intricate protection scheme has not yet been cracked by
anybody that I am aware of, anyway not publicly, therefore it's
an ideal candidate for a "strainer" to my university. I'll teach
you here how to crack it in three lessons, C.1, C.2 and C.3. I warn
you... it's a difficult cracking session, and this protection
represents quite an intellectual challenge. But if you are
seriously interested in our trade you will enjoy these lessons
more than anything else.
This cracking is intended as an "assignment" for my +HCU
"cracking university": you'll find inside lessons C.1 and C.2 a
relatively deep "introduction" to Instant access cracking. This
will teach you a lot anyway, and spare you hours of useless
roaming around, bringing you straight to the cracking point. But
I'll release the third part of this session, with the complete
solution (lesson C.3) on the Web only in october 1996, not a day
before. All the students that would like to apply to the Higher
Cracking University, opening on the web 01/01/1997, should work
in July, August and September (three months is more than enough
time) on this assignment. They should crack completely the
instant access scheme and send me their solutions, with a good
documentation of their cracking sessions, before 30/09/1996
(WATCH IT! You can crack this scheme in -at least- three
different paths, be careful and choose the *best* one. WATCH IT!
Some of the informations) in lesson C.1 and C.2 are slightly incorrect:
check it!).
There are four possibilities:
1) The candidate has not found the crack or his solution is
not enough documented or not enough viable... the candidate
is therefore not (yet) crack-able, he will not be admitted
to the +HCU 1997 curses, better luck in 1998;
2) The cracking solution proposed by the candidate is not as
good as mine (you'll judge for yourself in october) but it
works nevertheless... he'll be admitted at the 1997
courses;
3) The cracking solution of the candidate is more or less
equal to mine, he'll be admitted, personally monitored, and
he'll get all the material he needs to crack on higher
paths;
4) The cracking solution of the candidate is better than mine,
he'll be admitted, get all the material he wishes and asked
to teach us as well as study with us: "homines, dum docent,
discunt".
[Cracking Instant access]
The user that wants to "unlock" a software application
protected with (c) Instant Access must enter first of all a
REGISTRATION number string, which through a series of
mathematical manipulations gives birth to a special "product"
code. On the basis of this "product code" the user is asked to
phone the commercial protectors (and pay) in order to get a
special "unlock code" that will allow him to decrypt the relevant
software.
This kind of "passnumber" protection routines are widely
used for software unlocking, BBS access, server access, backdoor
opening and many other protection schemes. We have already seen
password cracks in different lessons of this tutorial (in
particular Lessons 3.1 and 3.2 for DOS and Lessons 8.1, 8.2 and
9.1 for WIN) albeit on a more simplistic scale: there it did
mostly not matter very much *HOW* you passed the protection: once
passed, you could have access to the application. This is not the
case with (c) Instant Access. Face it: it's a little boring, but
important that you learn how to defeat intricate protection
routines (you'll meet them often in the next years) and I believe
that the following example will give you a "feeling" for the
right cracking approach.
In this case we must not only "crack" this protection scheme
but also study it thoroughly in order to achieve our blessed
aims. This is a very good exercise: reverse disassembling will
teach you a lot of little tricks that you'll be able to use in
your other future cracking sessions.
Instant access (c) is a exceptionally widespread protection
scheme, and it should be relatively easy for you to gather some
encrypted software that has been protected with this method...
*DO IT QUICKLY!!* After the Web publishing of this lessons (I am
sending C.1 to 8 pages and 4 usenet groups on 25/06/1996) this
protection is obviously as dead as a Dodo. The "Accessors" guys
will have to conceive something smarter if they want to keep
selling "protections" to the lamer producers of "big" software.
BTW, if you are reading this and are working for some
commercial "protection" company, consider the possibility to
double cross your masters! Deliver me anonymously all the future
projects you are working on! That will amuse me, speed up the
advent of a true altruistic society and earn you the respect of
the better part of humanity.
As I said, many "huge" application are still protected with
this "Instant access" system. I have personally bought at least
7 or 8 "second hand" CD-ROMs packed full with Microsoft, Lotus,
Norton, Symantec, you name it, applications all "protected"
through this crap. The cost of this bunch of CD-ROMs was the
equivalent of a bottle of Dry Martini, maybe less. The same
software is sold, unlocked, to zombies and lusers for ludicrous
amounts of money.
Never buy CD-ROMs magazines when they appear! Be cool! Buy
them two or three months after the publishing date! Buy
"remainders" or "second hand" CD-ROM magazines "at kilo price"...
Come to think of it, never buy *anything* when it appears or when
some (paid) advertiser tells you to... remember that "trends",
"vogues", "fashions" and "modes" are only different names for the
whips that drill and chain the dull-witted slaves of this
loathsome society: "clever crackers consider cool, crack cheap,
cheat customary culture" (a rhetorical figure: an "Alliteration".
To defend yourself learn rhetoric... it's a more powerful and
more useful weapon than Kung-fu).
The "triple" password protection routine in (c) Instant
Access is very interesting from a cracker point of view. It's a
relatively complex scheme: I'll teach you to crack it in two
phases: First of all you must find the "allowed" registration
code, the one that "ignites" the "product code". We must crack
and understand this re_code first if we want to crack the rest.
Just for the records, I am cracking here (c) Action Instant
access version 1.0 (CD-ROM found on a old copy of "Personal
Computer World" of August 1994, packed full with encrypted Lotus,
Symantec, Claris and Wordperfect applications. Just to be sure
I crosschecked my results with another CD-ROM which also has
applications protected with (c) Instant Access: Paragon
Publishing's PC OFFICE: the protection scheme remains the same).
I am focusing for this lesson on the cracking of the specific
protection for the encrypted Symantec's Norton Utilities v.8.0.
Please refer to the previous lessons for the basic
techniques used in order to find the protection routine inside
our babe... for "low" cracking purposes you -basically- type a
number (in this case, where the input gets 10 numbers, we'll use
"1212-1212-12"), do your search inside the memory (s 30:0
lffffffff "your_string") and then set memory breakpoints on all
the relevant memory locations till winice pops (I know, I know,
buddies... there are more effective ways... but hold your mouth:
for now we'll keep them among us: let's make things a little
harder for the protectionists who read this... Besides: the old
approach works here flawlessly). After getting the Registration
window on screen the Winice standard procedure is:
:task ; how
:heap IABROWSE ; where & what
:hwnd IABROWSE ; get the Winhandle
:bpx [winhandle] WM_GETTEXT ; pinpoint code
:bpx GetProcAddress ; in case of funny routines
:dex 0 ds:dx ; let's see their name
:gdt ; sniff the selectors
:s 30:0 lffffffff "Your_input_string" ; search in 4 giga data
:bpr [all memory ranges for your string that are above 80000000]
and so on. (continued in lesson C.2)
Well, that's it for this lesson, reader. Not all lessons of my
tutorial are on the Web.
You 'll obtain the missing lessons IF AND ONLY IF you mail
me back (via anon.penet.fi) with some tricks of the trade I may
not know that YOU discovered. Mostly I'll actually know them
already, but if they are really new you'll be given full credit,
and even if they are not, should I judge that you rediscovered them
with your work, or that you actually did good work on them,
I'll send you the remaining lessons nevertheless. Your
suggestions and critics on the whole crap I wrote are also
welcomed.
+ORC an526164@anon.penet.fi
HOW TO CRACK, by +ORC, A TUTORIAL
LESSON C (2) - How to crack, Cracking as an art
[INSTANT ACCESS]
cracking Instant Access (2) - strainer for the +HCU
[SEE LESSON C.1 for the first part of this cracking session]
Here follow the relevant protection routines for the first
(The "Registration") number_code of Instant Access, with my
comments: you have to investigate a little the following code.
Later, when you'll crack on your own, try to recognize the
many routines that fiddle with input BEFORE the relevant (real
protection) one. In this case, for instance, a routine checks the
correctness of the numbers of your input:
This_loop_checks_that_numbers_are_numbers:
1B0F:2B00 C45E06 LES BX,[BP+06] ; set/reset pointer
1B0F:2B03 03DF ADD BX,DI
1B0F:2B05 268A07 MOV AL,ES:[BX] ; get number
1B0F:2B08 8846FD MOV [BP-03],AL ; store
1B0F:2B0B 807EFD30 CMP BYTE PTR [BP-03],30
1B0F:2B0F 7C06 JL 2B17 ; less than zero?
1B0F:2B11 807EFD39 CMP BYTE PTR [BP-03],39
1B0F:2B15 7E05 JLE 2B1C ; between 0 & 9?
1B0F:2B17 B80100 MOV AX,0001 ; no, set flag=1
1B0F:2B1A EB02 JMP 2B1E ; keep flag
1B0F:2B1C 33C0 XOR AX,AX ; flag=0
1B0F:2B1E 0BC0 OR AX,AX ; is it zero?
1B0F:2B20 7507 JNZ 2B29 ; flag NO jumps away
1B0F:2B22 8A46FD MOV AL,[BP-03] ; Ok, get number
1B0F:2B25 8842CC MOV [BP+SI-34],AL ; Ok, store number
1B0F:2B28 46 INC SI ; inc storespace
1B0F:2B29 47 INC DI ; inc counter
1B0F:2B2A C45E06 LES BX,[BP+06] ; reset pointer
1B0F:2B2D 03DF ADD BX,DI ; point next number
1B0F:2B2F 26803F00 CMP BYTE PTR ES:[BX],00 ; input end?
1B0F:2B33 75CB JNZ 2B00 ; no:loop next num
You now obviously understand that the "real" string is
stored inside memory location [BP+SI-34]... set a memory
breakpoint on this area to get the next block of code that
fiddles with the transformed input. Notice how this routine
"normalizes" the input, strips the "-" off and puts the 10
numbers together:
user input: 1 2 1 2 1 2 1 2 1 2 End
1E7F:92E2 31 32 31 32 31 32 31 32 31 32 00 45 AF 1F 70 9B
Stack ptr: 0 1 2 3 4 5 6 7 8 9 A B C D E F
Let's now look at the "real" protection routine: the one
that checks these numbers and throw you out if they are not
"sound". Please pay attention to the following block of code:
check_if_sum_other_9_numbers_=_remainder_of_the_third_number:
:4B79 8CD0 MOV AX,SS ; we'll work inside the stack...
:4B7B 90 NOP
:4B7C 45 INC BP
:4B7D 55 PUSH BP ; save real BP
:4B7E 8BEC MOV BP,SP ; BP = stackpointer
:4B80 1E PUSH DS ; save real Datasegment
:4B81 8ED8 MOV DS,AX ; Datasegment = stacksegment
:4B83 83EC04 SUB SP,+04
:4B86 C45E06 LES BX,[BP+06] ; BX points input_start
:4B89 268A07 MOV AL,ES:[BX] ; load first number
:4B8C 98 CBW ; care only for low
:4B8D C45E06 LES BX,[BP+06] ; reset pointer
:4B90 50 PUSH AX ; save 1st number
:4B91 268A4701 MOV AL,ES:[BX+01] ; load 2nd number
:4B95 98 CBW ; only low
:4B96 8BD0 MOV DX,AX ; 2nd number in DX
:4B98 58 POP AX ; get 1st number
:4B99 03C2 ADD AX,DX ; sum with second
:4B9B C45E06 LES BX,[BP+06] ; reset pointer
:4B9E 50 PUSH AX ; save sum
:4B9F 268A4707 MOV AL,ES:[BX+07] ; load 8th number
:4BA3 98 CBW ; only low
:4BA4 8BD0 MOV DX,AX ; 8th number in DX
:4BA6 58 POP AX ; old sum is back
:4BA7 03C2 ADD AX,DX ; sum 1+2+8
:4BA9 C45E06 LES BX,[BP+06] ; reset pointer
:4BAC 50 PUSH AX ; save sum
:4BAD 268A4703 MOV AL,ES:[BX+03] ; load 4rd number
:4BB1 98 CBW ; only low
:4BB2 8BD0 MOV DX,AX ; #4 in DX
:4BB4 58 POP AX ; sum is back
:4BB5 03C2 ADD AX,DX ; sum 1+2+8+4
:4BB7 C45E06 LES BX,[BP+06] ; reset pointer
:4BBA 50 PUSH AX ; save sum
:4BBB 268A4704 MOV AL,ES:[BX+04] ; load 5th number
:4BBF 98 CBW ; only low
:4BC0 8BD0 MOV DX,AX ; #5 in DX
:4BC2 58 POP AX ; sum is back
:4BC3 03C2 ADD AX,DX ; 1+2+8+4+5
:4BC5 C45E06 LES BX,[BP+06] ; reset pointer
:4BC8 50 PUSH AX ; save sum
:4BC9 268A4705 MOV AL,ES:[BX+05] ; load 6th number
:4BCD 98 CBW ; only low
:4BCE 8BD0 MOV DX,AX ; #6 in DX
:4BD0 58 POP AX ; sum is back
:4BD1 03C2 ADD AX,DX ; 1+2+8+4+5+6
:4BD3 C45E06 LES BX,[BP+06] ; reset pointer
:4BD6 50 PUSH AX ; save sum
:4BD7 268A4706 MOV AL,ES:[BX+06] ; load 7th number
:4BDB 98 CBW ; only low
:4BDC 8BD0 MOV DX,AX ; #7 in DX
:4BDE 58 POP AX ; sum is back
:4BDF 03C2 ADD AX,DX ; 1+2+8+4+5+6+7
:4BE1 C45E06 LES BX,[BP+06] ; reset pointer
:4BE4 50 PUSH AX ; save sum
:4BE5 268A4708 MOV AL,ES:[BX+08] ; load 9th number
:4BE9 98 CBW ; only low
:4BEA 8BD0 MOV DX,AX ; #9 in DX
:4BEC 58 POP AX ; sum is back
:4BED 03C2 ADD AX,DX ; 1+2+8+4+5+6+7+9
:4BEF C45E06 LES BX,[BP+06] ; reset pointer
:4BF2 50 PUSH AX ; save sum
:4BF3 268A4709 MOV AL,ES:[BX+09] ; load 10th #
:4BF7 98 CBW ; only low
:4BF8 8BD0 MOV DX,AX ; #10 in DX
:4BFA 58 POP AX ; sum is back
:4BFB 03C2 ADD AX,DX ; 1+2+8+4+5+6+7+9+10
:4BFD 0550FE ADD AX,FE50 ; clean sum to 0-51
:4C00 BB0A00 MOV BX,000A ; BX holds 10
:4C03 99 CWD ; only AL
:4C04 F7FB IDIV BX ; remainder in DX
:4C06 C45E06 LES BX,[BP+06] ; reset pointer
:4C09 268A4702 MOV AL,ES:[BX+02] ; load now # 3
:4C0D 98 CBW ; only low
:4C0E 05D0FF ADD AX,FFD0 ; clean # 3 to 0-9
:4C11 3BD0 CMP DX,AX ; remainder = pampered #3?
:4C13 7407 JZ 4C1C ; yes, go on good guy
:4C15 33D2 XOR DX,DX ; no! beggar off! Zero DX
:4C17 33C0 XOR AX,AX ; and FLAG_AX = FALSE
:4C19 E91701 JMP 4D33 ; go to EXIT
let's_go_on_if_first_check_passed:
:4C1C C45E06 LES BX,[BP+06] ; reset pointer
:4C1F 268A4701 MOV AL,ES:[BX+01] ; now load #2 anew
:4C23 98 CBW ; only low
:4C24 05D7FF ADD AX,FFD7 ; pamper adding +3
:4C27 A38D5E MOV [5E8D],AX ; save SEC_+3
:4C2A 3D0900 CMP AX,0009 ; was it < 9? (no A-F)
:4C2D 7E05 JLE 4C34 ; ok, no 0xletter
:4C2F 832E8D5E0A SUB WORD PTR [5E8D],+0A ; 0-5 if A-F
:4C34 C45E06 LES BX,[BP+06] ; reset pointer
:4C37 268A07 MOV AL,ES:[BX] ; load 1st input number
:4C3A 98 CBW ; only low
:4C3B 05C9FF ADD AX,FFC9 ; pamper adding +7
:4C3E A38F5E MOV [5E8F],AX ; save it in FIR_+7
:4C41 0BC0 OR AX,AX ; if #1 > 7
:4C43 7D05 JGE 4C4A ; no need to add 0xA
:4C45 83068F5E0A ADD WORD PTR [5E8F],+0A ; FIR_+7 + 0xA
now_we_have_the_sliders_let's_prepare_for_loop:
:4C4A C45E0E LES BX,[BP+0E] ; Set pointer to E
:4C4D 26C747020000 MOV WORD PTR ES:[BX+02],0000 ; 0 flag
:4C53 26C7070000 MOV WORD PTR ES:[BX],0000 ; 0 flag
:4C58 C706975E0900 MOV WORD PTR [5E97],0009 ; counter=9
:4C5E E99500 JMP 4CF6 ; Jmp check_counter
loop_8_times:
:4C61 C45E06 LES BX,[BP+06] ; reset pointer
:4C64 031E975E ADD BX,[5E97] ; add running counter
:4C68 268A07 MOV AL,ES:[BX] ; load # counter+1
:4C6B 98 CBW ; only low
:4C6C 50 PUSH AX ; save 10th number
:4C6D A18D5E MOV AX,[5E8D] ; ld SEC_+3 down_slider
:4C70 BA0A00 MOV DX,000A ; BX holds 0xA
:4C73 F7EA IMUL DX ; SEC_+3 * 0xA
:4C75 03068F5E ADD AX,[5E8F] ; plus FIR_+7 up_slider
:4C79 BAA71E MOV DX,1EA7 ; fixed segment
:4C7C 8BD8 MOV BX,AX ; BX = Lkup_val=(SEC_+3*10+FIR_+7)
:4C7E 8EC2 MOV ES,DX ; ES = 1EA7
:4C80 268A870000 MOV AL,ES:[BX+0000] ; ld 1EA7:[Lkup_val]
:4C85 98 CBW ; only low: KEY_PAR
:4C86 8BD0 MOV DX,AX ; save KEY_PAR in DX
:4C88 58 POP AX ; repops 10th number
:4C89 03C2 ADD AX,DX ; RE_SULT=KEY_PAR+#10
:4C8B 05D0FF ADD AX,FFD0 ; polish RE_SULT
:4C8E 99 CWD ; only low: RE_SULT
:4C8F 8956FC MOV [BP-04],DX ; save here KEY_PAR [9548]
:4C92 8946FA MOV [BP-06],AX ; save here RE_SULT [9546]
:4C95 0BD2 OR DX,DX ; KEY_PAR < 0?
:4C97 7C0F JL 4CA8 ; yes: KEY_PAR < 0
:4C99 7F05 JG 4CA0 ; no: KEY_PAR > 0
:4C9B 3D0900 CMP AX,0009 ; KEY_PAR = 0
:4C9E 7608 JBE 4CA8 ; no pampering if RE_SULT < 9
:4CA0 836EFA0A SUB WORD PTR [BP-06],+0A ; else pamper
:4CA4 835EFC00 SBB WORD PTR [BP-04],+00 ; and SBB [9548]
:4CA8 C45E0E LES BX,[BP+0E] ; reset pointer to E
:4CAB 268B4F02 MOV CX,ES:[BX+02] ; charge CX [958C]
:4CAF 268B1F MOV BX,ES:[BX] ; charge BX slider [958A]
:4CB2 33D2 XOR DX,DX ; clear DX to zero
:4CB4 B80A00 MOV AX,000A ; 10 in AX
:4CB7 9A930D2720 CALL 2027:0D93 ; call following RO_routine
This is the only routine called from our protection, inside the
loop (therefore 8 times), disassembly from WCB. Examining this
code please remember that we entered here with following
configuration: DX=0, AX=0xA, CX=[958C] and BX=[958A]...
1.0D93 56 push si ; save si
1.0D94 96 xchg ax, si ; ax=si, si=0xA
1.0D95 92 xchg ax, dx ; dx=0xA ax=dx
1.0D96 85C0 test ax, ax ; TEST this zero
1.0D98 7402 je 0D9C ; zero only 1st time
1.0D9A F7E3 mul bx ; BX slider! 0/9/5E/3B2...
1.0D9C >E305 jcxz 0DA3 ; cx=0? don't multiply!
1.0D9E 91 xchg ax, cx ; cx !=0? cx = ax & ax = cx
1.0D9F F7E6 mul si ; ax*0xA in ax
1.0DA1 03C1 add ax, cx ; ax= ax*0xA+cx = M_ULT
1.0DA3 >96 xchg ax, si ; ax=0xA; si evtl. holds M_ULT
1.0DA4 F7E3 mul bx ; ax= bx*0xA
1.0DA6 03D6 add dx, si ; dx= dx_add
1.0DA8 5E pop si ; restore si
1.0DA9 CB retf ; back to caller with two
parameters: DX and AX
Back_to_main_protection_loop_from_RO_routine:
:4CBC C45E0E LES BX,[BP+0E] ; reset pointer
:4CBF 26895702 MOV ES:[BX+02],DX ; save R_DX par [958C]
:4CC3 268907 MOV ES:[BX],AX ; save R_AX par [958A]
:4CC6 0346FA ADD AX,[BP-06] ; add to AX RE_SULT [9546]
:4CC9 1356FC ADC DX,[BP-04] ; add to DX KEY_PAR [9548]
:4CCC C45E0E LES BX,[BP+0E] ; reset pointer
:4CCF 26895702 MOV ES:[BX+02],DX ; save R_DX+KEY_PAR [958C]
:4CD3 268907 MOV ES:[BX],AX ; save R_AX+RE_SULT [958A]
:4CD6 FF0E8D5E DEC WORD PTR [5E8D] ; down_slide SEC_+3
:4CDA 7D05 JGE 4CE1 ; no need to add
:4CDC 83068D5E0A ADD WORD PTR [5E8D],+0A ; pamper adding 10
:4CE1 FF068F5E INC WORD PTR [5E8F] ; up_slide FIR_+7
:4CE5 A18F5E MOV AX,[5E8F] ; save upslided FIR_+7 in AX
:4CE8 3D0900 CMP AX,0009 ; is it over 9?
:4CEB 7E05 JLE 4CF2 ; no, go on
:4CED 832E8F5E0A SUB WORD PTR [5E8F],+0A ; yes, pamper -10
:4CF2 FF0E975E DEC WORD PTR [5E97] ; decrease loop counter
check_loop_counter:
:4CF6 833E975E03 CMP WORD PTR [5E97],+03 ; counter = 3?
:4CFB 7C03 JL 4D00 ; finish if counter under 3
:4CFD E961FF JMP 4C61 ; not yet, loop_next_count
loop_is_ended:
:4D00 C45E06 LES BX,[BP+06] ; reset pointer to input
:4D03 268A4701 MOV AL,ES:[BX+01] ; load 2nd number (2)
:4D07 98 CBW ; only low
:4D08 05D0FF ADD AX,FFD0 ; clean it
:4D0B BA0A00 MOV DX,000A ; DX = 10
:4D0E F7EA IMUL DX ; AX = SEC_*10 = 14
:4D10 C45E06 LES BX,[BP+06] ; reset pointer
:4D13 50 PUSH AX ; save SEC_*10
:4D14 268A07 MOV AL,ES:[BX] ; load 1st number (1)
:4D17 98 CBW ; only low
:4D18 8BD0 MOV DX,AX ; save in DX
:4D1A 58 POP AX ; get SEC_*10
:4D1B 03C2 ADD AX,DX ; sum SEC_*10+1st number
:4D1D 05D0FF ADD AX,FFD0 ; clean it
:4D20 99 CWD ; only low
:4D21 C45E0A LES BX,[BP+0A] ; get pointer to [9582]
:4D24 26895702 MOV ES:[BX+02],DX ; save 1st (1) in [9584]
:4D28 268907 MOV ES:[BX],AX ; save FINAL_SUM (15) [9582]
:4D2B 33D2 XOR DX,DX ; DX = 0
:4D2D B80100 MOV AX,0001 ; FLAG TRUE !
:4D30 E9E6FE JMP 4C19 ; OK, you_are_a_nice_guy
EXIT:
:4D33 59 POP CX ; pop everything and
:4D34 59 POP CX ; return with flag
:4D35 1F POP DS ; AX=TRUE if RegNum OK
:4D36 5D POP BP ; with 1st # in [9584]
:4D37 4D DEC BP ; with FINAL_SUM in [9582]
:4D38 CB RETF
Let's translate the preceding code: first of all the pointers:
At line :4B86 we have the first of a long list of stack ptrs:
LES BX,[BP+06]
This stack pointer points to the beginning of the input string,
which, once polished from the "-", has now a length of 10 bytes,
concluded by a 00 fence. At the beginning, before the main loop,
9 out of our 10 numbers are added, all but the third one.
Notice that protection has jumped # 3 (and added # 8 out of the
line). The rest is straightforward. Now, at line :4BFD we have
our first "cleaning" instruction. You see: the numbers are
hexadecimal represented by the codes 0x30 to 0x39. If you add
FE50 to the minimum sum you can get adding 9 numbers (0x30*9 =
0x160) You get 0. The maximum you could have adding 9 numbers,
on the contrary is (0x39*9=0x201), which, added to FE50 gives
0x51. So we'll have a "magic" number between 0x0 and 0x51 instead
of a number between 0x160 and 0x201. Protection pampers this
result, and retains only the last ciffer: 0-9. Then protection
divides this number through 0xA, and what happens? DX get's the
REMAINDER of it.
If we sum the hexcodes of our (1212-1212-12) we get 0x1BE (we
sum only 9 out of then numbers: the third "1" -i.e. "31"- does
not comes into our count); 0x1BE, cleaned and pampered gives E.
Therefore (0xE/0xA = 1) We get 1 with a remainder of 4.
You may observe that of all possible answers, only sums
finishing with A, B, C, D, E or F give 1 (and rem=0,1,2,3,4 or
5). Sums finishing 0 1 2 3 4 5 6 7 8 or 9 give 0 as result and
themselves as reminder. The chance of getting a 0,1,2,3 or 4 are
therefore bigger as the chance of getting a 5, 6, 7, 8 or 9. We
are just observing... we do not know yet if this should play a
role or not.
Now this remainder is compared at :4C11 with the third number
polished from 0x30-0x39 to 0-9. This is the only protection check
for the registration number input: If your third number does not
match with the remainder of the sum of all the 9 others numbers
of your input you are immediately thrown out with FLAG AX=FALSE
(i.e. zero).
To crack the protection you now have to MODIFY your input string
accordingly. Our new input string will from now on be "1242-1212-
12": we have changed our third number (originally a "2") to a "4"
to get through this first strainer in the correct way. Only now
protection starts its mathematical part (We do not know yet why
it does it... in order to seed the random product number? To
provide a check for the registration number you'll input at the
end? We'll see).
- Protection saves the second number of your input (cleaned
with FFD7) in SEC_+3 [5E8D], pampering it if it is bigger
than 9 (i.e. if it is 0xA-0xF). Here you'll have therefore
following correspondence: 0=7 1=8 2=9 3=0 4=1 5=2 6=3 7=4
8=5 9=6. The second number of your input has got added +3.
This is value SEC_+3. In (lengthy) C it would look like
this:
If (RegString(2)is lower than 7) RegString(2) = RegString(2)+3
Else Regstring(2) = ((RegString(2)-10)+3)
- Protection saves your first number in FIR_+7 [5E8F] with a
different cleaning parameter (FFC9). The next pampering
adds 0xA if it was not 7/8/9 therefore you have here
following correspondence 7=0 8=1 9=2 0=3 1=4 2=5 3=6 4=7
5=8 6=9). This is value FIR_+7. In (lengthy) C it would
look like this:
If (RegString(1) is lower than 3) RegString(1) = RegString(1)+7
Else Regstring(1) = ((RegString(1)-10)+7)
So protection has "transformed" and stored in [5E8D] and [5E8F]
the two numbers 1 and 2. In our RegString: 1242-1212-12 the first
two numbers "12" are now stored as "94". These will be used as
"slider" parameters inside the main loop, as you will see.
Only now does protection begin its main loop, starting from the
LAST number, because the counter has been set to 9 (i.e. the
tenth number of RegString). The loop, as you'll see, handles only
the numbers from 10 to 3: it's an 8-times loop that ends without
handling the first and second number. What happens in this
loop?... Well, quite a lot: Protection begins the loop loading
the number (counter+1) from the RegString. Protection then loads
the SEC_+3 down_slider parameter (which began its life as second
number "transformed"), multiplies it with 0xA and then adds the
up_slider parameter FIR_+7 (at the beginning it was the first
number transformed).
This sum is used as "lookup pointer" to find a parameter
inside a table of parameters in memory, which are all numbers
between 0 and 9. Let's call this value Lkup_val.
Protection looks for data in 1EA7:[Lkup_val]. In our case (we
entered 1242-1212-12, therefore the first SEC_+3 value is 9 and
the first FIR_+7 value is 4): [Lkup_val] = 9*0xA+4; 0x5A+4 =
0x5E. At line :4C80 therefore AL would load the byte at 1EA7:005E
(let's call it KEY_PAR), which now would be ADDED to the #
counter+1 of this loop. In our case KEY_PAR at 1EA7:005E it's a
"7" and is added to the pampered 0x32=2, giving 9.
Let's establish first of all which KEY_PAR can possibly get
fetched: the maximum is 0x63 and the minimum is 0x0. The possible
KEY_PARs do therefore dwell in memory between 1EA7: and
1EA7:0063. Let's have a look at the relative table in memory,
where these KEY_PARs are stored ("our" first 0x5Eth byte is
underlined):
1EA7:0000 01 03 03 01 09 02 03 00-09 00 04 03 08 07 04 04
1EA7:0010 05 02 09 00 02 04 01 05-06 06 03 02 00 08 05 06
1EA7:0020 08 09 05 00 04 06 07 07-02 00 08 00 06 02 04 07
1EA7:0030 04 04 09 05 09 06 00 06-08 07 00 03 05 09 00 08
1EA7:0040 03 07 07 06 08 09 01 05-07 04 06 01 04 02 07 01
1EA7:0050 03 01 08 01 05 03 03 01-02 08 02 01 06 05 07 02
1EA7:0060 05 09 09 08 02 09 03 00-00 04 05 01 01 03 08 06
1EA7:0070 01 01 09 00 02 05 05 05-01 07 01 05 08 07 01 09
1EA7:0080 08 07 07 04 04 08 03 00-06 01 09 08 08 04 09 09
1EA7:0090 00 07 05 02 03 01 03 08-06 05 07 06 03 07 06 07
1EA7:00A0 04 02 02 05 02 04 06 02-06 09 09 01 05 02 03 04
1EA7:00B0 04 00 03 05 00 03 08 07-06 04 08 08 02 00 03 06
1EA7:00C0 09 00 00 06 09 04 07 02-00 01 01 01 01 00 01 FF
1EA7:00D0 00 FF FF FF FF 00 FF 01-00 00 00 00 00 00 00 00
An interesting table, where all the correspondences are
between 0 and 9... are we getting some "secret" number here? But,
hey, look there... funny, isn't it? Instead of only 0-0x63 bytes
we have roughly the DOUBLE here: 0-0xC8 bytes (the 01 sequence
starting at CA "feels" like a fence). We'll see later how
important this is. At the moment you should only "perceive" that
something must be going on with a table that's two time what she
should be.
As I said the result of KEY_PAR + input number is polished
(with a FFDO) and pampered (subtracting, if necessary, 0xA).
Therefore the result will be the (counter+1) input number +
KEY_PAR (let's call it RE_SULT], in our case, (at the beginning
of the loop) a 9. Now (DX=0 because of the CWD instruction) DX
will be saved in [9548] and RE_SULT in [9546].
Now Protection prepares for the RO_routine: resets its pointer
and charges CX and BX from [958C] and from [958A] respectively,
charges AX with 0xA and sets DX to zero.
The routine performs various operations on AX and DX and saves
the results in the above mentioned locations [958A] and [958C].
Now KEY_PAR and RE_SULT are added respectively to the DX and AX
value we got back from the RO_routine call, and saved once more
in the last two locations: AX+RE_SULT in [958A] and DX+KEY_PAR
in [958C]
Now the value in SEC_+3 is diminished by 1 (if it was 9 it's now
8, if it was zero it will be pampered to 9). It's a "slider"
parameter (in this case a down_slider), typically used in
relatively complicated protections to give a "random" impression
to the casual observer. The value in FIR_+7, on the contrary, is
augmented by one, from 4 to 5... up_sliding also.
Protection now handles the next number of your input for the
loop. In our case this loop uses following protection
configuration with our "sliding" parameters:
Input # pamp_2nd pamp_1st Lookup value KEY_PAR # RE_SULT
# 10 = 2, SEC_+3= 9, FIR_+7= 4, Lkup_val = 0x5E, KEY=7 +2 = 9
# 9 = 1, SEC_+3= 8, FIR_+7= 5, Lkup_val = 0x55, KEY=3 +1 = 4
# 8 = 2, SEC_+3= 7, FIR_+7= 6, Lkup_val = 0x4C, KEY=4 +2 = 6
# 7 = 1, SEC_+3= 6, FIR_+7= 7, Lkup_val = 0x43, KEY=7 +1 = 7
# 6 = 2, SEC_+3= 5, FIR_+7= 8, Lkup_val = 0x3A, KEY=0 +2 = 2
# 5 = 1, SEC_+3= 4, FIR_+7= 9, Lkup_val = 0x31, KEY=4 +1 = 5
# 4 = 2, SEC_+3= 3, FIR_+7= 0, Lkup_val = 0x1E, KEY=5 +2 = 7
# 3 = 4, SEC_+3= 2, FIR_+7= 1, Lkup_val = 0x15, KEY=2 +4 = 5
Notice how our "regular" input 21212124 has given an "irregular"
94672575.
You may legitimately ask yourself what should all this mean:
what are these RE_SULTs used for? Well they are used to slide
another parameter: this one inside the called routine... this is
what happens to AX and DX inside the routine, and the lines after
the called routine:
:4CBF 26895702 MOV ES:[BX+02],DX ; save R_DX par [958C]
:4CC3 268907 MOV ES:[BX],AX ; save R_AX par [958A]
:4CC6 0346FA ADD AX,[BP-06] ; add to AX RE_SULT [9546]
:4CC9 1356FC ADC DX,[BP-04] ; add to DX KEY_PAR [9548]
:4CCC C45E0E LES BX,[BP+0E] ; reset pointer to E
:4CCF 26895702 MOV ES:[BX+02],DX ; save R_DX+KEY_PAR [958C]
:4CD3 268907 MOV ES:[BX],AX ; save R_AX+RE_SULT [958A]
:4CC6 :4CC9 :4CCF Odd_DX :4CD3 slider_sum
RE_SULT [958A] [958C] [958C] [958A]
0 0 0 0 0
9 5A 0 0 9
4 3AC 0 0 5E
6 24F4 0 0 3B2
7 71CE 1 1 24FB
2 7220 4 E 71D0
5 7572 4 90 7225
7579
Now the loops ends, having handled the input numbers from tenth
to third. Protection loads the second number and multiplies it
by 10 (let's call this result SEC_*10), in our case 2*0xA=14.
Protection loads the first number and adds it to the
multiplication, in our case 1+0x14=0x15 (FINAL_SUM].
Now everything will be added to FFDO to "clean" it.
Pointer will now be set to the end of the input number.
DX, zeroed by CDW, will be saved as parameter in [9584] and the
cleaned and pampered sum will be saved in [9582].
FLAG is set to true and this routine is finished! No parameter
are passed and the only interesting thing is what actually
happens in the locations [9582], [9584], [958A] and [958C], i.e.:
FINAL_SUM, 0, slider_sum, odd_dx.
In the next lesson we'll crack everything, but I'll give you
already some hints here, in case you would like to go ahead on
your own: we'll see how the scheme used for the third (the
registration) number show analogies and differences with the
scheme we have studied (and cracked) here for the first number.
Our 3434-3434-3434-3434-34 input string for the registration
number will be transformed in the magic string
141593384841547431, but this will not work because the "magic"
12th number: "1" will not correspond to the remainder calculated
inside this check through the previous locations of the other
checks.
Here the things are more complicated because every little
change in your input string transforms COMPLETELY the "magic"
string... therefore in order to pass the strainer you'll have to
change 3434-3434-3434-3434-34 in (for instance) 7434-3434-3434-
3434-96. The "magic" string 219702960974498056 that this
registration input gives will go through the protection strainer.
Only then we'll be able to step over and finally crack the whole
protection... it's a pretty complicated one as I said. Now crack
it pupils... you have three months time. From this crack depends
your admission to the Uni, there will be no other admission text
till summer 1997 (it's a hell of work to prepare this crap)...
work well.
Well, that's it for this lesson, reader. Not all lessons of my
tutorial are on the Web.
You 'll obtain the missing lessons IF AND ONLY IF you mail
me back (via anon.penet.fi) some tricks of the trade I may not
know but YOU've discovered. I'll probably know most of them
already, but if they are really new you'll be given full credit,
and even if they are not, should I judge that you "rediscovered"
them with your work, or that you actually did good work on them,
I'll send you the remaining lessons nevertheless. Your
suggestions and critics on the whole crap I wrote are also
welcomed.
+ORC an526164@anon.penet.fi
HOW TO CRACK, A TUTORIAL - LESSON 1
by +ORC (the old red cracker)
-> How to crack, an approach LESSON 1
How to crack, tools and tricks of the trade LESSON 2
How to crack, hands on, paper protections LESSON 3 (1-2)
How to crack, hands on, time limits LESSON 4
How to crack, hands on, disk-CDrom access LESSON 5
How to crack, funny tricks LESSON 6 (1-2)
How to crack, intuition and luck LESSON 7
How to crack windows, an approach LESSON 8
How to crack windows, tools of the trade LESSON 9
How to crack, advanced cracking LESSON A (1-2)
How to crack, zen-cracking LESSON B
How to crack, cracking as an art LESSON C
How to crack INDEX
LESSON 1 - HOW TO CRACK, AN APPROACH
The best way to learn cracking (i.e. understanding, broadly
individuating, locating exactly and eliminating or suspending or
deferring one or more protection schemes inside a software
application you do not possess the source code of) is to begin
your tampering experiments using OLDER applications which have
OLDER protection schemes.
In this way you 'll quickly grasp the base techniques of the
trade. Do not forget that the evolution of the protection schemes
has not been a one way road... strictly speaking it's not even
an evolution: you'll eventually find some very clever new tricks,
but most of the time you 'll unearth only various trite
repetitions of past (and well known) tricks. This is no wonder:
the REAL knowledge of the "commercial" programmers themselves
(the "protectionists") is often very limited indeed: they are
inclined to use the old methods (albeit somehow changed,
sometimes even improved) instead of conceiving new methods. This
typical "commercial" degeneration happens every time people act
for money instead of doing things for the sake of it or for
pleasure. This "commercial" trend is blindly encouraged by the
stupid, money-oriented society we are coerced to live in.
So I'll begin the "hands on" part (-> starting from lesson
3), using as examples, some "old" applications and some "old"
tricks. We'll be able to come later over to the newest protection
schemes in order to understand them, and you 'll learn how to
defeat this kind of junk too. I'll also explain WHERE you can
find a lot of programs to crack for next to no money at all, and
HOW 'grossomodo', you should proceed in your work.
The applications you'll use to learn with can be divided into:
1 - Password crippled applications (the easiest to crack)
2 - applications crippled on how many times, or how many
days, you use them (fairly easy to crack)
3 - applications crippled on which date you use them before
(easy to crack)
4 - applications that have some functions present but
disabled (sometimes easy, sometimes difficoult)
5 - applications crippled on Disk access (protections schemes
that are now defined as "obsolete") and apps crippled on
CD-ROM presence (more or less the same methodes, but -
somehow- not defined as "obsolete") (vey easy to crack)
6 - CRYPTOGRAFED ADDS ON (i.e. one of the previous protection
schemes, but with some scrambled or self modifying code
(XORring and SHRLing codes) (fairly easy to crack)
7 - None of the above (sometimes difficoult to crack)
WHERE TO GET THE STUFF
The recent widespread appearance of "Demo"-CDROM on magazine
covers is a treasure for all crackers! Obviously even if they are
cheap, you should never buy such magazines immediately on their
release, coz after a short time you 'll get all the copies that
remain unsold for next to free. The demos on CD-ROMs will permit
you to gather quickly a lot of applications -old and new- that
have somehow been crippled (at times with interesting schemes).
Truly a wonderful world of cracking possibilities! Gee! For next
to no money you can secure on one CDROM the whole of LOTUS
applications (or Microsoft or Wordperfect, or you name them) on
"trial for 30 days" or "try it 20 times" editions. You'll really
enjoy to crack them and to use them subsequently for ever and
ever (and/or graciously donate them on the Web to the poor lamers
that have no money and no brain).
GAMES are definitely not to be frowned upon! They are
extraordinarily interesting from a cracker prospective coz they
are often "overprotected". With this I mean that they possess
protection schemes of a relatively HIGH level hidden inside files
that are not very large. Now, see, it is much more easy, and
simple to track down and eliminate protection schemes inside a
single 35.000 bytes long executable file than to locate them
inside a collection of many lengthy DLLs and overlaids that could
have swollen as long as 2.000.000 bytes each. The lazy bunch of
"modern" programmers relies systematically for protection schemes
on this "hide the sting in the wide desert" logic. As a matter
of fact they are no longer able to program in assembler: they
bank more and more on overbloated "fatty" monstrosities like
Visual Basic, Delphy or Visual C++. (But do not worry... I'll
nevertheless teach you how to crack -and quickly- those huge apps
too).
There is another reason for employing games instead of
applications as study material: often EXACTLY THE SAME protection
schemes that you find in a simple (and short) shareware game will
be used -without much improving- a little later in order to
"protect" some huge and extremely expensive graphic application.
For this reason in my tutorial we'll often crack games
protection schemes, even if we'll later apply what we learn
mainly in order to crack the protection schemes of commercial
applications, or to crack the access protection routines to
remote servers, or BBS, or even ATM (cash dispensers).
Here follows an example cracking session, that will show you
-I hope- the dos and donts of our art: let's crack together as
introductory example a time crippled application. We'll learn
later (-> LESSON 4) that all applications that are crippled on
time (i.e. "how many times" you use them or "how long" you use
them) rely on analogous protection schemes (albeit with a huge
palette of small variations):
1- they may have a counter which "clicks" every so often: FIND
IT AND DISABLE IT!
2- they may fetch the time_clock interrupts in your machine:
INTERCEPT THEM YOURSELF!
3- they may compare a random_seed with a variable: NOOP IT!
4- they may check randomly the date of your other, unrelated,
files on the hard disk: find this verification routine and
INVERT the JUMPS!
I wanted to start with a modern example of this "counter clicks"
protection type, just to give you a feeling for cracking, and I
have chosen a widely published demo: you should be able to find
it pretty easily. In order to show you some of the problems you
may encounter we'll crack this example "wrongly" (you'll learn
how to crack effectively in the "HANDS ON" lessons).
EXAMPLE: ARCADE POOL, Demonstration version, PC Conversion
by East Point Software Ltd, (c) Team 17 Software Ltd 1994. This
demo has been published by many magazines on their CDRom covers
throughout 1995.
What follows will be useful even if you do not have our
example; nevertheless you should get a copy of this widespread
demo in order to better grasp some of the points that follow.
This nice demo of a billiard game is time-crippled. It is
crippled on how long you use it: i.e., you can only play 2
minutes, afterwards a "nag" reminder of where and how you can buy
the real version snaps: protectionist squalor at its best.
So, how do you proceed? Where does the beginning begin?
Here is what you could (but not necessarily should) do:
Get [Soft-ice] and load it in your config.sys. See the TOOLS
OF THE TRADE lesson (-> LESSON 2) about this debugger. Version
2.6 of [Soft-Ice] has been cracked by MARQUIS DE SOIREE and can
be found on the Web for free.
- vecs s (save all the vectors before loading the babe)
- start [pooldemo.exe]
- vecs c (vector compare, save a printing of all hooked
vectors)
- enter and leave Soft-ice a few times to understand what's
going on and where in [pooldemo.exe] are we roaming around
(you should always check MORE THAN ONCE your findings when
you snoop around: nothing moves and confuses pointers in a
more frenzied way than good old "inactive" DOS).
- have a good look at the map of memory usage ("map")
- now "snap_save" the main memory regions where
[pooldemo.exe] dwells... snapping saves "photographyes" of
memory areas.
- do not do anything, let just the seconds go by.
- "snap_compare" every two or three seconds without moving
anything at all on the game board (no mouse_clicking,
NOTHING), so that the only changes are (hopefully) the
changes caused by the time counters.
- snap_compare twice in a second.
- snap_compare at second 00:59 and at second 1:01.
- snap_compare just before and just after the time limit and
the snapping of the nag screen.
- Now collect carefully your printed "snaps" data: write
clearly on the various sheets the occurrences of the snaps.
- now comes the graceful "zen-cracking" moment: Sit down with
a dry Martini and Wodka (obviously only russian Wodka will
do) and contemplate the printing of the various mutant
locations. Feel, perceive, empathize! Look closely at the
locations that have changed in the snap compares. Analyse,
interpretate, evaluate.
- Mmm! Hey! Something fishy is changing there, and there, and
there! (you are lucky, few do actually change in this case:
only two dozen)
- breakpoint on execute at the location that you believe act
as a "continuous" counter, i.e. the location that triggers
the "a second went by" event when it zeroes.
- Now set the occurrence counter of BPX in order to break at
the moment where the location "refills" and restarts from
the beginning (the equivalent of "one second" went by,
let's start anew). Use the occurrence counter in order not
to single-step through the program your life long!
- IN THIS CASE you 'll quickly locate the refill at location
3DD0. Here follows the "refill" line:
xxxx:3DCC C706F1013C00 MOV WORD PTR [01F1], 003C
The "3C" byte at xxxx:3DD0 represents a counter_byte... i.e. the
program "charges" 3C in this location and then DECs it step by
step to 3B, 3A, 39, 38 etc... till 0. When it reaches 0: bingo!
Sucker user has lost one second more of his precious two minutes.
Now, you would get a first wizard level if you searched
further on for the exact point where you get the "nag screen" in
order to eliminate the whole witless protection, but you may
think you got it already and you remember anyway that the first
principle in cracking is the following: "once you can eliminate
the effects of a protection, do not look further!"
Most of the time this is true: you do not always need to
eliminate a "whole" protection scheme (unless you are just
studying it for the joy of it). It's normally easier (and
quicker) to eliminate the "effects" of a given protection scheme.
Unfortunately this is not true in this case.
Here you believe that you have already found the way: you
got the counter that charges the reverse clock that triggers the
particular protection scheme of [pooldemo.exe]. Now you may think
that if you could modify the refill_value... say changing "3C"
to "EE" (Yeah, the maximum would be FF... but it's always good
practice to avoid such extreme values when cracking) you should
get four times more playtime for your game... more than enough
in order to make the protection scheme useless.
So you change location xxxx:3DD0 from "3C" to "EE". To work
on bytes you should use a good Hexeditor like PSEDIT (Parity
solutions, [Psedit.exe], brilliant shareware: see the "tool of
the trade" section) but you could also work with simpler
debuggers like [debug] or [symdeb] (-> see lesson 2). If you do,
remember to work on a "dead" copy of your crippled [*.exe] file,
i.e.:
ren POOLDEMO.EXE POOLDEMO.DED
symdeb POOLDEMO.DED
-s (cs+0000):0 Lffff C7 06 F1 01 C3 <- this string
corresponds to the
refill line).
cs:3E85 <- symdeb gives you two locations as answer
cs:3EEA
-e cs:3E85+4 EE <- refill changed from C3 to EE
-w
ren POOLDEMO.DED POOLDEMO.EXE
Now you run your tampered pooldemo. You think you cracked it, you
glee with satisfaction... but loo! Nothing at all has changed,
everything's as lame as before, you still have only 2 minutes
playtime. How disappointing: how comez it did'nt work?
Well, for a start you have not been attentive enough! The
search in debug gave you TWO locations, you moron, and not just
the one you just tampered with. Check and you 'll see that the
second location (cs:3EEA) is a MIRROR/CONTROL location (more on
this later). Some times there exist "double" locations... coz at
times it's quicker to use a double routine than to use a
branching if or switch structure... some times the second
locations do mirror the first ones and correct them on the fly
if need be.
So you need to modify this too... you act as said above but
this time you enter in debug a
-e cs:3EEA+4 EE
before writing back the dead file and then renaming it to exe and
then running it... and loo! Hoow sloow! THERE YOU ARE! Your
crippled POOLDEMO.EXE is now (sort of) unprotected: You think
that you can now play the stupid game up to 12 minutes real time,
even if the protection scheme (and the counter) "believes" that
it is playing only two minutes.
So you begin to play, and the seconds look veeery sloow, and
everything seems OK, but -alas- NO! At screen second 28 you get
the irritating "two minutes are over" nag screen! Obviously you
were dead wrong: the program "knows" the time directly from the
timer... you only modified the stupid counter ON THE SCREEN.
So it's back to cracking, and now you are angry, and forget
the quiet ways of the zen-analyse and begin the heavy cracking
you should reserve -if ever- for really complicated schemes. You
now start to check the hooked vectors (you did your routinely
VECS_save before loading pooldemo in [Soft-ice] and your
VECS_compare afterwards) and you see some findings that you
believe interesting:
vecs c
08 1EFD:84C6 0CD1:17AC <- the clock
09 1EFD:85EC 136A:069C <- the keyboard
22 0BCE:02B1 0BCE:017E <- the terminate
That's more like it -you think. Smack at the beginning: the
first hooked vector does it! It's good old interrupt_08: the
timer_clicker!
Some basics for those of you that do not know anything:
INT_08 controls indirectly the INT_1C timer interrupt. The 8253
clock chip generates an IRQ_0 hardware interrupt at a rate of
18.2 interrupts per second. This gives control to the ISR
(Interrupt Service Routine) that the INT_08 points to... and this
should be at 0CD1:17AC, but has been hooked here, by pooldemo,
to 1EFD:84C6.
One of the actions taken by the INT_08 ISR within the BIOS
is to issue a software interrupt call to INT_1C, just in case any
software modules within the system have established an intercept.
If no intercepts have been established, the default contents of
the INT_1C vector point to an iret instruction within the BIOS,
so that a null action results. (Iret retrieves the three words
of stack information which were automatically saved when the
interrupt call began, and uses them to restore execution control
to the appropriate point).
Normally a protectionist would intercept INT_1C, coz at
every ISR from INT_08 the CPU would fetch the contents of the
corrisponding interrupt vector and make an interrupt style call
to the code at that address (which should contain the iret at
address F000:9876 but can contain any trick they could think of).
So -you think- the protectionist hooked here INT_08 directly
(a pretty infrequently used protection scheme by the way): What
now?
A rather drastic misure would be, in such circumstances, to
disable the IRQ_0 level timer interrupt, which is controlled by
bit 0 of the mask register, at address I/O 0021h. The controllers
have IMRs (Interrupt Mask Registers) which can be used to hide
or mask specific interrupts. The IMR of the first controller is
located at port address 21h, while the IMR of the second
controller is located at port 0a1h. When bit 0 within the mask
register is set to 1, no further interrupts will be recognized
for this IRQ level. This unfortunately won't work here, but it's
an interesting technique per se, so you better learn it anyway,
just in case you should need it elsewhere:
HOW TO CRACK, A TUTORIAL - LESSON 2
by +ORC (the old red cracker)
How to crack, an approach LESSON 1
-> How to crack, tools and tricks of the trade LESSON 2
How to crack, hands on, paper protections LESSON 3 (1-2)
How to crack, hands on, time limits LESSON 4
How to crack, hands on, disk-CDrom access LESSON 5
How to crack, funny tricks LESSON 6 (1-2)
How to crack, intuition and luck LESSON 7
How to crack windows, an approach LESSON 8
How to crack windows, tools of the trade LESSON 9
How to crack, advanced cracking LESSON A (1-2)
How to crack, zen-cracking LESSON B
How to crack, cracking as an art LESSON C
How to crack INDEX
LESSON 2- How to crack, tools and tricks of the trade
LOST IN THE DARK CODEWOODS
When you break into a program you end up in portions of code
that are unfamiliar to you. It is also not uncommon for the
breakpoints to occur outside of the confines of the program you
want to crack. Getting your bearings is, in these cases, very
important.
One of the handiest utilities is the memory dump tool -it
tells you where all the device drivers and TSR are loaded, in
which memory locations the program you are cracking dwells, how
much memory is left and what the next program load point is. The
tools you use should report on the following:
- the contents of interrupt vectors
- the state of the BIOS data area, beginning at address 40:0
- internal structures within DOS, such as the MCB chain, the
SFT (System File Table) chain, the chain of installed
device drivers, the PSPs and memory allocations associated
with installed TSRs
- memory allocation statistic from XMS and EMS drivers
When seeking to understand a section of foreign code, you
must be especially careful to seek the real intent of the code.
Consider using a profiler prior to undertaking an analysis of an
unfamiliar program. This will help you by ensuring that you don't
waste time studying sections of the program that aren't even
involved in the protection scheme you are chasing down.
Using a utility that charts a program's calling hierarchy
can give you an important perspective on how your babe conducts
its internal operations.
YOUR DEBUGGER: YOUR FAVOURITE TOOL
First and foremost, your debugger must be designed for use
with resident modules (or must be itself a resident module).
Trying to crack with simplistic [debug.com] is a sure way to get
absolutely nowhere. We recommend Softice.exe from Nu-Mega
technologies (Version 2.6 [S-Ice.exe] has been cracked by MARQUIS
DE SOIREE and its vastly available on the Web). You could also
use [Periscope] or [Codeview] or Borland's Turbodebugger... all
these programs have been boldly cracked and/or distributed and
are now on the Web for free... learn how to use YAHOO and find
them. In emergency cases you could fix some quick cracking
patches using [debug] or [symdeb], but, as said above, most of
the time these older debuggers won't do. I'll nevertheless ALWAYS
give the final crack procedure for [debug.com], in order to
permit even idiots to crack their programs (altruistic, isn't
it... besides, every wizard has started with debug.com).
When you first smell a protection, it can be tempting to
immediately begin your crack using invasive types of techniques.
While there is certainly nothing wrong with this approach,
provided that you are fairly familiar with the protection scheme
used, going in too deep too soon can be a problem when you don't
have a strong hunch. Most of the time you'll end up missing
important details. So first of all sit down and ponder... that's
the zen-way, the only one that really works.
Single-stepping is expensive, not only because of the time
it requires but also because of the amount of detail with which
you must contend. Your immediate goal is to home in on the
protection scheme through a series of successively refined traps,
your broader aim is to get an overview idea of the program's
action... the wise use of breakpoints will condense these
minutiae into an understandable form.
The first step is to try to identify the section of the
program where the protection scheme is snapping.
Once you are able to isolate a certain section of a program,
breakpoints can be used to gather a trace history of the
program's execution. If your debugger sports a backtrace buffer,
logging window, or similar feature, by all means learn how to use
it. The debugger it's your best weapon, you must know all the
possibilities it offers and all the capabilities it possesses.
Having a debugger's display output echoed to a printer is another
possibility.
Using breakpoints is beneficial for two basic reasons: speed
and reduction of detail. Manual single-stepping is invaluable
when you are close to the protection scheme, but too much of it
will bore you to death.
When selecting breakpoint locations and the types of
breakpoint to use, it is important to step back once more, drink
a cool Martini-Wodka (use only Moskovskaja: non-russian Wodkas
are appalling) and ask yourself: "What is this going to tell me?"
and "What else will I need to know once the break occurs?". MOST
IMPORTANT OF ALL: "Is my current cracking approach the simplest
and most direct?", coz you do not want to waste precious cracking
time.
When devising a set of breakpoints it is wise to consider
how "a trail of bread crumbs" can be left. Not allowing for an
execution chronicle from the start can mean having to restart a
cracking session.
Setting breakpoints on certain software interrupt calls is
an excellent way to get an overview of a program's operations.
The INT_21 DOS services interrupt is probably the most universal
useful of these, with BIOS interrupts such as the INT_13 (BIOS
Disk services) and INT_16 (BIOS keyboard services) useful for
specific cracking.
When working with a debugger, evaluative breakpoints are
usually your best shot. To avoid having to deal with a plethora
of calls, you would want to have a debugger capable of being told
to "break on any INT_21 call except where AH == 2C or AH == 0B".
A real understanding of the working of a program is surely
important, but don't overdo it! To reverse-engineer even a small
program can involve many hours of analysis and documentation
work. If you'll not be able to use the zen-cracking techniques
described in this tutorial (sadly not everybody can) pace
yourself and make sure your chair is comfortable: you'll be
sitting for quite a spell.
Much of the work involved in reverse-engineering consist of
chasing down tentacles. In order to understand the operations of
one function, you must understand what happens within each of the
functions it calls- its child functions. To understand these
child functions you must study their children; and so on down the
calling hierarchy tree. Then there is the data. Tracing tentacles
based on a program's calling hierarchy is a directed process.
Each function you encounter is basically a list of other
functions you must reckon with. When it comes to analyzing a
function's interrelationship with the program's data structure,
no such list is provided. You must have instinct, feeling and
luck.
Data analysis requires more of a broad-based inquisition.
For each memory variable you are interested in, you must survey
all functions to determine which ones read and write that
variable. The use of memory conditional breakpoints and of a
disassembler that builds a cross-reference table can make this
task a lot easier. (Use Sourcer! It's a fairly good tool and
version 4.08 of [sr.exe] has been long ago cracked by me, +ORC,
and distributed on the Web).
ALL SYSTEM CALLS IN ONE LOCATION
Remember that if the program you are cracking was written
in assembler in the first place (very unlikely knowing the
laziness of to_days programmers), it is probable that system
calls are made directly from the functions which need them. But
when a program is developed in a high-level language, it is more
likely that common library functions will be used for many
operations involving system calls. When a program makes all of
its INT_21 calls from the same location, you know that this is
certainly the case.
Now, what happens sometimes is that the programmers write
the whole application in a overbloated language like C++, but are
afterwards compelled to "speed up" critical sections of the code
writing them in assembler. And loo! A section where you
repeatedly find assembler crafted patches is precisely the
section containing the protection scheme! So you could have a
program with all INT_21 calls from the same location but for one
or two calls which are coming out of the section where the morons
have "hidden" their protection strategy. By just "looking" at the
dead code of a program, you should be capable to tell wich parts
have been "added on" in a later phase. They presents themselves
as unevenness and irregularities, especially if you use an
utility that represents graphicallly the code of a program.
Protections are often added on at the end.
Should you determine that the system calls relevant to your
cracking are made from common library functions, all is not lost.
The specific function from which these library calls were made,
the function you are seeking to locate, is executing at some
point in between these calls. Break in with your debugger at the
end of the first system call, just where it is returning to the
point of call. From there, trace through the remainder of the
common library routine until it returns to its caller. In short
order, you should find yourself in the function you need to see.
The trick is to be able to identify it for what it is.
ASCIIZ IN CODE
In the interest of gaining an overall familiarity with the
program you want to crack, it can be enlightening to use a hex
dump utility to examine the message strings contained within the
program's binary modules. If the program happens to load its
message strings from separate files, your search has just been
simplified.
Your debugger's memory-dumping feature is one tool that can
be useful for this type of exploration. You could also construct
a filtering program, which would read a binary file and output
all sequences of bytes that are comprised of displayable
characters and are over a certain minimum length (the best
cracker tools are often the ones you write yourself).
When a protection scheme is marked by the issuance of a
specific message on the screen, you could go into the program and
locate the code that emits this message, and then determine what
triggers it. A good way to start the location process is to see
if a system call is used to display the string. Interrupt INT_21,
INT_10 or INT_29 are usually used to display text messages to the
console.
When the message's display is not a result of one of these
system calls, direct video writing is probably being used. If you
know the screen location used, and if that part of video memory
is not used for anything else at the time (a big if), a memory
write breakpoint could be set on the video buffer address
corresponding to the first character's position. If this won't
work, use the step-over/step-around tracing technique while
watching for the message to appear.
Now you found it: from a disassembled listing, you could
locate the address of the message string and then survey the
reminder of the file for any instructions that reference this
address. [Sourcer.exe] can generate labels for specific memory
locations and then generate a cross-reference table showing where
these labelled locations are referenced. Otherwise, load the
disassembled listing file into your editor and use its search
capabilities. Manually searching for such things in a listing
will make you old before your time.
CODE AND DATA
When stepping through code at the assembler level, watch out
for interrupt calls that are followed by data. Sometimes you will
find an interrupt call, typically within the range INT_34 to
INT_3F, where several bytes immediately following the interrupt
instruction will be data rather than code.
Be especially suspicious of this type of code-and-data
mixture when your debugger's disassembly output of the
instructions immediately following an interrupt call doesn't make
sense. Sometimes you can determine the offset of the next true
instruction by inspecting the following code and data. In other
cases, you will have to trace through the interrupt call to see
how it accesses the data following the interrupt call instruction
and how it manipulates the return address on the stack.
HOOKED VECTORS
Seeing what interrupt intercepts already exist within a
system before running the program you want to crack, as well as
what interrupt handlers are established by the target program,
can provide useful clues. For example, if a protection
establishes an INT_09 intercept just before the snapping of a
keyboard verification routine, your range of suspects has just
been narrowed significantly.
To study the interrupt vector activities of an application,
a vector dump map utility is useless. It can't be run while the
application you want to crack is running. One solution is to run
the program under a debugger and watch for system calls to INT_21
functions 25h (set interrupt vector) and 35h (get interrupt
vector), but in the event that the program reads and writes
interrupt vectors directly, this method will not give you a
complete picture. Normally you'll use a spy (trace) utility.
APPLYING A MEMORY WRITE BREAKPOINT TO A SPECIFIC VECTOR OR
TO THE ENTIRE TABLE is another way to deal with this.
Note that some sort of direct vector writing must be
occurring if a vector change is detected between system calls.
If a vector change is detected during a system call but it
isn't function 25h of INT_21, suspect that an IRQ handler may be
effecting the change.
LITTLE TRICKS OF THE TRADE: determining interrupt vector
addresses
How do you determine the interrupt vector addresses? As
example let's find the address of the INT_21 interrupt vector.
Since the interrupt vector table starts at address 0000:0000
(easy to remember, isn't it?) and there are four bytes per
vector, the basic process is to multiply the interrupt number
four times and use the result at the offset with a segment of
zero.
x21h + x21h = x42
x42h + x42h = x84
The int_21 vector is located at address 0000:0084
You could also use a calculator, for instance, the address of
INT_63 is x63*4=x18c = 0000:018C
LITTLE TRICKS OF THE TRADE: address conversion
After a painstaking cracking session, you have finally
determined that a byte of memory at address 6049:891C is the
trigger. But when you isolate the offending instruction, you find
that the address it is generating when the protection occur is
different, being 6109:7D1C instead! How can this be?
An 80x86 type CPU, when running in real or VM86 mode, uses
what is known as segment:offset type addressing. One side effect
of this addressing method is that one physical address can be
equivalent to many different segment:offset addresses.
To find the PHYSICAL ADDRESS for a given segment:offset do
the following:
- convert the segment portion of the address to a 1-based number
by multiplying it by 16 (x10)... it's easy: add 0 at the right
end of the number!...
6049 -> 60490
6109 -> 61090
now all you have to do is to add this value to the offset value
60490+891C -> 68DAC
61090+7D1C -> 68DAC
Got it?
And the other way round? If you have a physical address, say
19AC3, and you want to obtain a segment:offset address you must
first of all decide in which segment you want the address... if,
say, you choose segment 16CC, you proceed as follows:
16CC -> 16CC0
19AC3-16CC0 = 2E03 (offset)
address for 19AC3 in segment 16CC = 16CC:2E03
TOOLS OF THE TRADE
[MEMSCAN.EXE]
One of the most fascinating tools that I have ever seen is
a (very old) program: MEMSCAN.EXE.
This program was originally written in 1988 by Scott A. Mebust,
running in CGA. It's a "visual" utility: it enables you to see
graphically the 1-meg of PC memory in 8 kbyte chunks. It's a
powerful tool in order to locate quickly bit mapped graphics and
other 'objects' in memory, like program data tables, stack areas,
code areas, available RAM, etc. I used this great idea to create
(in C) my own tools: a "dead_programs scanner" and an ameliorate
version of Memscan itself. Looking at the VISUAL STRUCTURE of a
program it's a great help when you'll crack higher levels.
[TRACKMEM.COM]
A very good tool by James W.Birdsall, tracks memory usage
of programs (EMS, XMS, conventional).
[SCANCODE.COM]
"THE" scancode lister, by the code_masters from clockwork
software. The must utility for crackers that do not learn all
scancodes by heart.
[MAP.EXE]
Actually "MAP2", THE memory mapper from the code_masters at
clockwork software. It's a very good tool and an interesting one
too, coz you get it with the "Nigel" nag screens. They are not
difficult to remove (a "passletter" protection scheme, you'll
learn how to find and remove it from [Map.exe] in LESSON 3.2).
[FILEDUMP.COM] [HEXDUMP.COM] [TDUMP.EXE] [DUMP.EXE]
There are hundred of file dump utilities, coz file dumping
is one of the first exercise they learn you at C-school.
Hexdump.com is 558 bytes long, Tdump.exe 120.704, pick the one
you like better or write your own (even better). Filedump.com,
by Daniel M.O'Brien, 1046 bytes long, it's nice.
[SPRAY.COM]
That's a good crack utility indeed! This 1989 program by
Daniel M.O'Brien gives you a "post-mortem" picture of your
memory. You redirect it to <myfile> and study it at ease. It's
difficult to say how many hours of cracking it did spare me (you
should study the program, only 252 bytes long, and will have to
modify it a bit, coz it's pretty primitive, in the original
version, for instance, the redirection to the printer works only
if there is NO SPACE between "spray" and ">").
[VEXE.EXE]
A good EXE files analyzer, useful for windows programs too
(see --> LESSON 7). Some of its functions are present in
TDUMP.EXE too. This 1991 program by S.Krupa it's sometimes very
useful.
[SNOOP UTILITIES --> KGB.EXE INTMON.EXE INTRSPY.EXE etc...]
[TRACE UTILITIES --> TRACE.EXE STEPDOS.EXE etc...]
A must to study the "calling hierarchy" of an unknown
program. KGB.EXE, a 1992 program by Petr Hor k could be the best
one. I'll teach you how to crack without any of them (you do not
need them if you zen-crack), but they can nevertheless be very
useful in some situations. Stepdos.exe is a excellent program:
a pleasure to crack in order to use it for slightly different
purposes :=)
[SOURCERING UTILITIES]
SR.EXE can be used for sourcering unknown programs. It's a
fairly good sourcering tool. Version 4.08 has been long ago
cracked by me (it's a "ORIGINAL NUMBERCODE" protected program)
and distributed on the Web, so you should easily find it. This
said, you should NEVER use such a brute force approach, unless
you are really desperate: I'll teach you how to crack without
sourcering (you don't need to sourcer if you zen-crack).
[HEXEDITORS]
Every idiot has written at least one hexeditor, and you can find
very bad tools everywhere (the SIMTEL collection, on the Web,
lists at least 35 hexeditors). I suggest you write your own and
contribute to the flood, or (better) get PSEDIT.EXE, a good 1990
program by Gary C. Crider (Parity Solutions, 1903 Pavia Ct.
Arlington, TX 76006... sometimes even americans can write good
programs). If you do use it (as you should) disapt the nag screen
as small exercise in cracking.
[DEBUGGER]
Your best friend in cracking, your weapon, your hidecloak...
I suggest [Softice.exe] from Nu-Mega technologies (Version 2.6
has been cracked by MARQUIS DE SOIREE and its vastly available
on the Web). You could also use [Periscope] or [Codeview] or
Borland's Turbodebugger... all these programs have been boldly
cracked and/or distributed and are now on the Web for free...
learn how to use YAHOO and find them. It's the only tool you 'll
REALLY need, believe me. So choose wisely and learn how to use
backtrace ranges and breakpoint on user written qualifications
routines. You 'll be able to crack almost EVERYTHING using these
features in the right way.
You should get all the programs mentioned above (and more)
for free on the Web. Use them, but also modify them recklessly!
REMEMBER THAT YOU ARE (GOING TO BE) A CRACKER! The first programs
you should crack and modify are therefore your very tools! So
steal the code of the best tools you find! Snatch the best
routines and change them for the better! That's the whole point
in cracking: a mission to IMPROVE the best accomplishments of
humanity's genius :).
HOW TO CRACK, ZEN-CRACKING
You 'll learn, beginning with next lesson, how to crack
systematically the different protection schemes: paper & password
protections, time protections, access protections. At the end of
the "methodolocical" part, you'll be able to deprotect programs,
but you will still not be a cracker. In order to crack in a real
effective way you must use what I call (lacking a better
definition) "zen-cracking". I 'll give you right now an example
of this, so that you know what I'm talking about, but -unless you
are already capable- you'll have to finish the tutorial for
"normal" cracking before attempting this techniques. Let's zen-
crack together a password protection scheme (aka "paper
protection", coz you need the original manual of the program in
order to answer). This one is based on the typing, at the nag
screen, of the correct sequence of numbers. We are using as
example a game for the reasons explained in lesson 1, but you 'll
find the SAME protection scheme in the access protection
procedure of the old Tapestry networks... so do not frown upon
games protections.
INDIANAPOLIS 500, Papyrus software & Electronic Arts, 1989
It's a rather widespread program, so you should be able to find
it pretty easily. The nag screen asks for data based on the
historical performances of race cars... that means that the
answers will consist in two to three digits.
Now, the normal way to crack such a program will be
described in lesson 3.1 and embodyes following steps:
- snap save program memory areas before typing your answer
- snap compare after typing, say, "666"
- search for the sequence 36,36,36 (i.e. 666)
- breakpoint on memory range for reading
- look at the program part fetching your data
- find the snap procedure
- disable it.
The above it's a relatively quick crack, and most of the
time 'll be fairly effective, but there is a better way: the "zen
way", the only one that can really bring you to crack peculiar
protection schemes.
- Run the program and break in at the nag screen
- Answer consist of 2-3 digits? Search for "AC" (i.e. the
instruction LODSB, load digit of answer in AL) in the area 500
bytes BEFORE and 500 bytes AFTER your position. You'll get some
locations. (In the case of INDY 500 you get 6 such locations).
- "feel" the locations (that's the tricky part).
- OK, you already made it! Here is the protection strategy:
8BBF28A5 MOV DI,[BX+A528]<-- DI points to coded data area
:compare_loop
AC LODSB <-- load first digit of answer in AL
B4FF MOV AH,FF <-- load mask in AH
2A25 SUB AH,[DI] <-- sub coded data from mask and get
real answer
47 INC DI <-- ready to get next coded data
3AC4 CMP AL,AH <-- user answer = real answer ?
751A JNZ bagger_off_you_do_not_know_the_right_answer
0AC0 OR AL,AL <-- more numbers?
75F2 JNZ compare_loop
59 POP CX <-- nice guy, you may go on
...
And if the protection scheme had been more far away? And if you
cannot "feel" the right one? And if my grandma had wheels? You'll
learn it, believe me.
Now let's quickly crack this crap.
HOW TO CRACK, A TUTORIAL - LESSON 3 (1)
by +ORC (the old red cracker)
How to crack, an approach LESSON 1
How to crack, tools and tricks of the trade LESSON 2
-> How to crack, hands onn, paper protections LESSON 3 (1/2)
How to crack, hands on, time limits LESSON 4
How to crack, hands on, disk-CDrom access LESSON 5
How to crack, funny tricks LESSON 6 (1/2)
How to crack, intuition and luck LESSON 7
How to crack windows, an approach LESSON 8
How to crack windows, tools of the trade LESSON 9
How to crack, advanced cracking LESSON A (1/2)
How to crack, zen-cracking LESSON B
How to crack, cracking as an art LESSON C
How to crack INDEX
LESSON 3 (1)
HOW TO CRACK, HANDS ON - Password protected programs
SOME PROBLEMS WITH INTEL's INT
The INT instruction is the source of a great deal of the
flexibility in the PC architecture, because the ability to get
and set interrupt vectors means that system services (included
DOS itself) are infinitely extensible, replaceable and
MONITORABLE. Yet the Int instruction is also remarkably
inflexible in two key ways:
- an interrupt handler DOES NOT KNOW which interrupt number
invoked it.
- the int instruction itself expects an IMMEDIATE operand:
you cannot write MOV AX,x21, and then INT AX; you must
write INT x21.
That would be very good indeed for us cracker... unfortunately
many high level language compilers compile interrupts into PUSHF
and FAR CALL instruction sequences, rather than do an actual INT.
Another method is to PUSH the address of the handler on the stack
and do RETF to it.
Some protection schemes attempt to disguise interrupt calls,
this is particularly frequent in the disk access protection
schemes (-> see LESSON 5) that utilize INT_13 (the "disk"
interrupt).
If you are attempting to crack such programs, the usual
course of action is to search for occurrences of "CD13", which
is machine language for interrupt 13. One way or another, the
protection scheme will have to use this interrupt to check for
the special sectors of the disk. If you examine a cross section
of the program, however, you 'll find programs which do not have
"CD13" in their machine code, but which clearly are checking the
key disk for weird sectors. How comez?
There are several techniques which can be used to camouflage
the protection scheme from our nice prying eyes. I'll describe
here the three such techniques that are more frequent:
1) The following section of code is equivalent to issuing an
INT 13 command to read one sector from drive A, side 0, track
29h, sector ffh, and then checking for a status code of 10h:
cs:1000 MOV AH,02 ;read operation
cs:1002 MOV AL,01 ;1 sector to read
cs:1004 MOV CH,29 ;track 29h
cs:1006 MOV CL,FF ;sector ffh
cs:1008 MOV DX,0000 ;side 0, drive A
cs:100B XOR BX,BX ;move 0...
cs:100D MOV DS,BX ;...to DS register
cs:100F PUSHF ;pusha flags
cs:1010 PUSH CS ;pusha CX
cs:1011 CALL 1100 ;push address for next
instruction onto stack and branch
cs:1014 COMP AH,10 ;check CRC error
cs:1017 ... rest of verification code
...
...
cs:1100 PUSHF ;pusha flags
cs:1101 MOV BX,004C ;address of INT_13 vector
cs:1104 PUSH [BX+02] ;push CS of INT_13 routine
cs:1107 PUSH [BX] ;push IP of INT_13 routine
cs:1109 IRET ;pop IP,CS and flags
Notice that there is no INT 13 command in the source code, so if
you had simply used a debugger to search for "CD13" in the
machine code, you would never have found the protection routine.
2) Another technique is to put in a substitute interrupt
instruction, such as INT 10, which looks harmless enough, and
have the program change the "10" to "13 (and then back to "10")
on the fly. A search for "CD13" would turn up nothing.
3) The best camouflage method for interrupts I have ever
cracked (albeit not on a INT 13) was a jump to a section of the
PROGRAM code that reproduces in extenso the interrupt code. This
elegant (if a little overbloated) disguise mocks every call to
the replicated interrupt.
Bear all this in mind learning the following cracks.
CRACKING PASSWORD PROTECTED PROGRAMS
Refer to lesson one in order to understand why we are using
games instead of commercial applications as learn material: they
offer the same protection used by the more "serious" applications
(or BBS & servers) although inside files that are small enough
to be cracked without loosing too much time.
A whole series of programs employ copy protection schemes
based upon the possess of the original manual or instructions.
That's obviously not a very big protection -per se- coz everybody
nowadays has access to a photocopier, but it's bothering enough
to motivate our cracks and -besides- you'll find the same schemes
lurking in many other password protected programs.
Usually, at the beginning of the program, a "nag screen"
requires a word that the user can find somewhere inside the
original manual, something like: "please type in the first word
of line 3 of point 3.3.2". Often, in order to avoid mistakes, the
program indicates the first letter of the password... the user
must therefore only fill the remaining letters.
Some examples, some cracks:
HOW TO CRACK, A TUTORIAL - LESSON 3 (2)
by +ORC (the old red cracker)
How to crack, an approach LESSON 1
How to crack, tools and tricks of the trade LESSON 2
-> How to crack, hands on, paper protections LESSON 3 (1-2)
How to crack, hands on, time limits LESSON 4
How to crack, hands on, disk-Cdrom access LESSON 5
How to crack, funny tricks LESSON 6 (1-2)
How to crack, intuition and luck LESSON 7
How to crack windows, an approach LESSON 8
How to crack windows, tools of the trade LESSON 9
How to crack, advanced cracking LESSON A (1-2)
How to crack, zen-cracking LESSON B
How to crack, cracking as an art LESSON C
How to crack INDEX
LESSON 3 (2) - HOW TO CRACK, HANDS ON (3.2) Passwords, second
part, and something about passletters
You have seen in the previous lesson that the use of a password
protection, independently of the coding and hiding methods used
to store them in memory, implies the use of a comparing procedure
with the password that the user types in. You therefore have many
options to begin your cracking work:
- find the location of the user password
- find the "echo" in memory of the real password
- find the routine that compares both
- find the passwords hideout and encryption type
- find the go_ahead_nice_buyer exit or jump
- find the beggar_off_ugly_copier exit or jump
just to name the more obvious ones. In order to make things more
difficult for us crackers, the protectionists have devised many
counter-strategies, the more obvious ones being:
- keeping the various part of the store/compare/hide routines
well apart in code (no match for zen-cracking);
- filling these routines with "bogus" compares, bogus jumps
and bogus variables, in order to make things more difficult for
the crack (no match for decent crackers);
- disseminating the code with anti-debugger tricks, like INT_3
instructions or jumps in and out protected mode (no match for our
beloved [Soft-Ice]);
- trying to eliminate the need for passwords altogether
letting the user input "one letter" or "one number" or "one
image" as answer to some variable question. In this lesson I'll
teach you how to crack these "passletters" protection techniques.
Let's first resume the "uses" of a password protection:
PASSWORDS AS PERMISSION TO ACCESS
These passwords serve to acknowledge that a legitimate user is
using the program. This is the type of password that you'll find,
for example, protecting your user account on Compuserve, on
Networks or even in ATM machines used by banks or corporations.
These require a little hardwiring to crack: ATM passnumber
protection schemes rely on an answer from the central computer
(they do NOT verify only the three magnetic areas in the magnetic
strip on the card). The lines between ATM's & their hosts are
usually 'weak' in the sense that the information transmitted on
them is generally not encrypted in any way. (Some banks use
encrypted information, but this is fairly easy to crack too).
So for ATMs you should do the following 1) cross over the
dedicated line between the ATM and the host; 2) insert your
computer between the ATM and the host; 3) Listen to the "normal"
messages and DO NOT INTERFERE YET; 4) Try out some operations
with a legal card, make some mistakes, take note of the various
codes; 5) When you are ready insert a fraudulent card into the
ATM. Now the following happens:
- the ATM sends a signal to the host, saying "Hey! Can I give
this guy money, or is he broke, or is this funny card invalid?";
- the microcomputer intercepts the signal from the host,
discards it, sends on the "there's no one using the ATM" signal;
- the host gets the "no one using" signal and sends back its
"good, keep watching out if somebody comes by, and for God's sake
don't spit out any money on the street!" signal to the ATM;
- the microcomputer intercepts this signal (again), throws it
away (again), and sends the "Wow! That guy is like TOO rich! Give
him as much money as he wants. In fact, he's so loaded, give him
ALL the cash we have! He is a really valued customer." signal.
- the ATM obediently dispenses cash till the cows come home.
All this should be possible, but as a matter of fact it has
not much to do with cracking, unless there is a special software
protection on the line... so if you want to work on ATMs contact
our fellow phreakers/hackers and learn their trade... and
please remember to hack only cash dispenser that DO NOT HAVE a
control camera :=)
PASSWORDS AS REGISTRATION
This type of password is often used in shareware programs. When
you register the shareware program, you are sent a password that
you use to upgrade your shareware program to a complete and more
powerful version. This method, used frequently for commercial
applications, has recently been used quite a lot by many windows
applications that come "crippled" on the magazines cover CD-roms,
requiring you to telephone a hot line (and paying) in order to
get the "unique key" to unlock the "special protection". It's all
bullshit: we'll learn in the "how to crack windows" lessons how
easy it is to disable the various routines that verify your
entry.
PASSWORDS AS COPY PROTECTIONS
This type of password is often used for games and entertainment
software. The password query does not usually appear any more at
the start of the program, or as the program is loading. Instead,
the password query appears after one or more levels are completed
(this innovation was pioneered by "EOB I" and the "Ultima"
series) or when the user reloads a saved game or session.
DONGLE PASSWORDS
A few extremely expensive programs use a dongle (also called
an hardware key). A dongle is a small hardware device containing
a password or checksum which plugs into either a parallel or a
serial port. Some specially designed dongles even include
complete program routines. Dongles can be cracked, but the amount
of work involved is considerable and the trial and error
procedure currently used to crack them via software is extremely
tedious. It took me more than a week to crack MULTITERM,
Luxembourger dongle protected program. The quickest method to
crack dongle protected programs, involves the use of pretty
complicated hardware devices that cannot be dealt with here. I
myself have only seldom seen them, and do not like at all to
crack dongles via software, coz it requires a huge amount of zen
thinking and of luck and of time. If you want more information
on the hardware way to crack dongles, try to contact the older
ones on the appropriate web sites, they may even answer you if
you are nice, humble and really technically interested.
The obvious principle, that applies to the software password
types mentioned above is the following: The better the password
is hidden, and the better it is encrypted, the more secure the
program will be. The password may be
- encrypted and/or
- in a hooked vector and/or
- in an external file and/or
- in a SMC (Self modifying code) part
Let's finally inspect the common "ready_made" protection
schemes (used by many programmers that do not program
themselves):
* password read in
* letters added to a key to be entered
* complement of the letters formed xoring with 255
* saved key (1 char)
* saved password (256 chars)
* saved checksum (1 char), as protection, against simple
manipulations
* generating file PASSWORD.DAT with password, to be inserted
inside a different file than the one containing the calling
routine
Now the lazy programmer that wants to "protect" his program
searches first the file where the password is stored, then loads
the key, the password and the checksum. He uses a decrypt
procedure to decrypt the password and a check_checksum procedure
to check whether the password was modified. All this is obviously
crackabe in few seconds.
[PASSWORD ACCESS INSIDE THE SETUP]
Some computers have a password protected access INSIDE the
Setup (at the beginning), the protection scheme does not allow
a boot with a floppy and does not allow a setup modify. In these
cases the only possible crack is an old hack method:
* open the PC
* find on the motherboard a small jumper (bridge) with the
words "Pw"
* take it away
* PC on
* run the setup with F1 or Del (depending from the BIOS) (the
protection will not work any more)
* deactivate inside the setup the option password
* PC off
* put the small jumper (bridge) back again
* close the PC
* PC on, cracked (if you want to be nasty you could now use
the setup to set YOUR password)
If you want to know more about access refuse and access
denying, encryption and locking of the FAT tables, get from the
web, and study, the (very well written) code of a virus called
"Monkey", that does exactly this kind of devastation. Virus
studying is, in general, very useful for cracking purposes, coz
the virus'code is at times
- very well written (pure, tight assembly)
- using concealing techniques not much different from the
protection schemes (often far superior)
- using the most recent and best SMC (self modifying code)
tricks
But, and this is very important, do not believe that the
protection schemes are very complicated! Most of the time the
protection used are incredibly ordinary: as a final example of
our paper protection schemes, let's take a program released not
long ago (1994), but with a ridiculous protection scheme: TOP
(Tiger on the prowl) a simulation from HPS.
Here the cracking is straightforward:
- MAP(memory_usage) and find main_sector
- type "AAAA" as password
- (s)earch main_sector:0 lffff "AAAA"
- dump L80 "AAAA" location -40 (gives you a "wide" dump),
this gives you already the "echo" of the correct password
- breakpoint on memory read & write to "AAAA" location and
backtrace the complete main_sector
it's done! Here the code_lines that do protect TOP:
8A841C12 MOV AL,[SI+121C] move in AL first user letter
3A840812 CMP AL,[SI+1208] compare with echo
7402 JZ go_ahead_nice_buyer
EB13 JMP beggar_off_ugly_cracker
Now let's quickly crack it:
HOW TO CRACK, by +ORC, A TUTORIAL
Lesson 5.1: Disk & CD-Rom access (basics)
LESSON 5 (1) - HOW TO CRACK, HANDS ON - Disk/CDROM access (plus
bypasses "on the fly")
Somewhere I have to put the bypasses (loader programs) in this
tutorial, allow me to put them here:
Preparing a loader to bypass a protection [MARIO ANDRETTI]
At time the protectionists hook vectors in order to impose
a particular protection. In this (and similar) cases a good
crack-way is to prepare a "loader" program, that "de-hooks" the
vector used for the protection. This kind of crack can be used
also for internet cracking (on some firewall configurations, see
lesson A.2).
As example let's take "Mario andretti racing challenge", a
stupid game that uses the SAME (!) protection scheme you'll still
find to day on some access routines of military servers around
the witlessly called "free" world.
In order to crack this cram you would prepare a loader on the
following lines:
loc code instruction what's going on
-------------------------------------------------------
:0100 EB44 JMP 0146
...
:0142 0000 <- storing for offset of INT_21
:0144 5887 <- storing for segment of INT_21
:0146 FA CLI
:0147 0E PUSH CS
:0148 1F POP DS
:0149 BCB403 MOV SP,03B4
:014C FB STI
:014D 8C1EA901 MOV [01A9],DS <- save DS
:0151 8C1EAD01 MOV [01AD],DS three
:0155 8C1EB101 MOV [01B1],DS times
:0159 B82135 MOV AX,3521 <- get INT_21
:015C CD21 INT 21 in ES:BX
:015E 891E4201 MOV [0142],BX <- store offset
:0162 8C064401 MOV [0144],ES <- store segment
:0166 BA0201 MOV DX,0102
:0169 B82125 MOV AX,2521 <- set INT_21 to
:016C CD21 INT 21 DS:0102
:016E 0E PUSH CS
:016F 07 POP ES <- ES= current CS
:0170 BBB403 MOV BX,03B4
:0173 83C30F ADD BX,+0F
:0176 B104 MOV CL,04
:0178 D3EB SHR BX,CL <- BX= 3C
:017A B8004A MOV AX,4A00 <- Modify memory block
:017D CD21 INT 21 to 3C paragraphs
:017F BA9E01 MOV DX,019E <- ds:dx=program name
:0182 BBA501 MOV BX,01A5 <- es:bx = param. block
:0185 B8004B MOV AX,4B00 <- load ma.com
:0188 CD21 INT 21
:018A 2E8B164201 MOV DX,CS:[0142] <- reset old int_21
:018F 2E8E1E4401 MOV DS,CS:[0144]
:0194 B82125 MOV AX,2521
:0197 CD21 INT 21
:0199 B8004C MOV AX,4C00 <- terminate with return
:019C CD21 INT 21 code
:019E 6D612E636F6D00 "ma.com"
0000 fence
:01A7 B2015887
:01AB B2015887
:O1AF B2015887
0000 fence
let's now prepare a routine that hooks INT_21:
push all
CMP AX,2500 <- go on if INT_21 service 25
JNZ ret
CMP Word Ptr [0065], C00B <- go on if location 65 = C00B
JNZ ret
MOV Byte Ptr [0060], EB <- crack instructions
MOV Byte Ptr [0061], 3C
MOV Byte Ptr [0062], 40 <- INC AX
MOV Byte Ptr [0063], 90 <- NOP
MOV Byte Ptr [0064], 48 <- DEC AX
pop all
JMP FAR CS:[0142] <- JMP previous INT_21
From now on this loader will work every time that a program
with location [0065] containing an 0R AX,AX instruction (0BC0:
it's the case of ma.com) calls INT_21 service 25 (hook a vector),
the target program will be modified on the fly and will get, at
location [0060], the instruction JMP 3C locations ahead, despite
the fact that it has routines capable of self checking in order
to make sure it has not been modified.
The most important thing is the routine that YOU write that
will precede the call to INT_21 (or any other INT) service 25 (or
any other service) in order to crack on the fly the offending
program. I'll show you another one, this one for [Reach for the
skies] (reach.com):
push all
CMP AH,3D <- is it service 3D? (open file)
JNZ ret <- no, so ret
CMP DX,13CE <- you wanna open file at 13CE?
JNZ ret <- no, so ret
MOV AX,[BP+04] <- in this case
MOV DS,AX
CMP Byte Ptr [B6DA],74 <- old instructions
JNZ 015B
CMP Byte Ptr [B6DB],0F <- ditto
JNZ 015B
CMP Byte Ptr [B6DC],80 <- ditto, now we now where we are
JNZ 015B
MOV Byte Ptr [B6DA],EB <- crack
MOV Byte Ptr [B697],40 <- camouflaged no-opping
MOV Byte Ptr [B698],48 <- cam nop
MOV Byte Ptr [B699],90 <- cam nop
MOV Byte Ptr [B69A],40 <- cam nop
MOV Byte Ptr [B69B],48 <- cam nop
MOV DX,CS:[0165]
MOV DS,CS:[0167]
MOV AX,2521 <- set hook
INT 21
POP all
JMP FAR CS:[0165]
Here you did change the instruction 740F in the instruction EB0F,
and you did "noop" the instructions at B697-B69B. (Well, more
elegantly than "noop" them with "90" bytes, you choose a INC AX,
DEC AX, NOP, INC AX, DEC AX sequence instead! There are sound
reasons to use a sequence of "working" instructions instead of
NOPs: recent protection schemes "smell" patched nops inside the
program and trash everything if they find more than -say- three
consecutive NOPs! You should always try to choose THE LESS
INTRUSIVE and MORE "CAMOUFLAGED" solution when you crack!)
You can apply this kind of crack, on the same lines, to many
programs that perform self checking of the code and hook the
vectors.
REAL DISK ACCESS STUFF
Now we may come to the subject of this lesson:
As usual, let's begin from the beginning: history is always
the key that allows an understanding of present and future, in
cracking matters too. As the older 5 1/4 inch big black floppy
disks were still used (the 320K/8 tracks or 360K/9 tracks ones,
that were really "floppy" and have nowadays almost disappeared)
one of the more common methods to protect a program, was to
format the "master" (key) disk in a weird way. Old floppy disk
for the PC did usually store 360K at 9 sectors per track.
Some basics for those of you that do not know anything: in
order to defeat this kind of cracks you need to know two things:
the floppy disk parameter block (FDPB) and the interrupt routines
dealing with format/read disk (basically INT_13).
Most often, the protection scheme is to either format one
or more sectors or tracks with sector sizes other than the
standard 512 bytes, or to either give one of the sectors a wild
sector number like 211 or just not format a whole track of
eight/nine/15 sectors. If you, for instance, have got the same
(very old) copy of VisiCalc master I do, you'll find that sector
8 on track 39 is missing entirely. The interrogation with
assembly or with an "ad hoc" utility (I use the tools I wrote
myself, but you 'll be able to find many such utilities in public
domain, the oldest one, from 1984 (!) being the seasoned [U-ZAP]
an "Ultra utility" from the "Freesoft company") will tell you
which sector numbers were altered, their size in bytes, and if
they were formatted with a CRC error (another not so fancy
trick).
The floppy disk parameters are stored in the BIOS: interrupt
vector 1E contains the address of the floppy disk parameter
block. The FDPB's contents are the following:
Offset Function crackworthy? Example
0 Step rate & head unload no DF
1 head load time no 02
2 Motor on delay no 25
3 Number of bytes per sector yes 02
4 Last sector number yes 12
5 Gap length yes 1B
6 Data track length yes FF
7 Format gap length yes 54
8 Format byte no F6
9 Head settle time no 0F
A Motor start time no 02
0) Offset #0: the left "nybble" (single digit) of this value
is the step rate time for the disk drive head. The right
nybble is the disk head unload time. These values are best
left alone.
1) Offset #1: again, don't fool around with these values. The
left nybble is the disk head load time, and the right
nybble is the direct memory access mode select.
2) Wait time until motor is turned off. Not normally of use.
3) Bytes-per-sector value: AH-HAH! If you place a "0" in this
value, the PC expects all sectors to be 128 bytes long. A
"1" means a sector size of 256 bytes, a "2" means 512
bytes (this is the standard DOS value), and a "3" means
1024 bytes per sector.
4) Highest sector number on a track: this is used for
formatting and tells DOS how many sectors there are on each
track.
5) Gap length for diskette reads: this is what you fool around
with if you keep getting CRC errors when you try to read a
non-standard size sector. Normally, you can just leave this
alone except when formatting with a U-Format tool.
6) Data length: This contains the number of bytes in a sector
when the value in table byte #4 doesn't contain a 0, 1, 2,
or 3.
7) Number of bytes in the gap between sectors: this is also
only used when formatting special tracks.
8) Format fill byte: When formatting, this is the
initialization byte that will be placed in all new sectors.
9) Head settle time: leave this alone.
A) Motor start time: don't fool with this either.
In order to modify globally the number of tracks on a given disk
and the number of sectors per track you can always format with
the DOS command switches "/t:" and "/n:"
FORMAT /t:tracks /n:sectors
If you want to find out what the existing parameters are,
run [Debug.exe] or [Symdeb.exe] and enter the following commands:
- d 0:78 l 4 <- get FDPB address
0000:0070 22 05 00 <- debugger's likely response
- d 0:522 l a <- get 10 FDPB values
0000:520 DF 02 25 02 12 1B FF... <- see preceding table
Remember that all standard disk formats under DOS support
a sector size of 512 bytes, therefore, for one-sided 5.25 inch
floppies:
40t*8s*512b=163.840 bytes (160Kb)
40t*9s*512b=184.320 bytes (180Kb)
and for two-sided 5.25 inch floppies:
40t*8s*512b*2sides=327.680 bytes (320Kb)
40t*9s*512b*2sides=368.640 bytes (360Kb)
Beginning with DOS version 3.0 (Yeah, more and more
history!) a new floppy disk format has been supported: The IBM
AT (80286 CPU) introduced the so called "high capacity" 5.25 u-
inch floppy, capable of storing 1.2M at 15 sectors per track:
80t*15s*512b*2sides=1.228.800 bytes (1.2Mb)
Later on were introduced the to-day universally used 3.5
inch floppies, the ones inside a rigid small plastic cartridge,
and we have, similarly:
3.5-inch double sided/double density 720K
3.5-inch double sided/quad density (HD) 1440K
3.5-inch double sided/high density 2880K
[INT_13, AH=18, Set media type for format]
In order to create weird layouts, the protectionists use
interrupt 13h, service 18h, that specifies to the formatting
routines the number of tracks and sectors per track to be placed
on the media:
* Registers on entry: AH=18h; CH=N&#248; of tracks; CL= Sectors
per track; DL= Drive number (A=0; B=1;C=2... bit 7 is set
if the drive is an hard disk)
* Registers on Return: DI: Offset address of 11-byte
parameter table; ES: Segment address of 11-byte parameter
table.
[INT_13, AH=2, Read disk sectors]
In order to read them, they have to use INT_13, service 2, read
disk sectors, with following layout:
* Registers on entry: AH=2h; AL= N&#248; of sectors; BX= Offset
address of data buffer; CH=track; CL= Sector; DH= Head
(side) number; DL= Drive number; ES: Segment address of
data buffer.
* Registers on Return: AH= return code. If the carry flag is
not set, AH=0, therefore the weird sector has been read, if
on the contrary the carry flag is set, AH reports the
status byte as follows:
76543210 HEX DEC Meaning
1 80h 128 Time out - drive crazy
1 40h 064 Seek failure, could not move to track
1 20h 032 Controller kaputt
1 10h 016 Bad CRC on disk read
1 09h 009 DMA error - 64K boundary crossed
1 08h 008 DMA overrun
1 04h 004 Bad sector - sector not found
11 03h 003 Write protect!
1 02h 002 Bad sector ID (address mark
1 01h 001 Bad command
[Return code AH=9: DMA boundary error]
One of the possible errors should be explained, coz it is
used in some protection schemes: AH=9 DMA boundary error, means
that an illegal boundary was crossed when the in formation was
placed into RAM. DMA (Direct memory access) is used by the disk
service routines to place information into RAM. If a memory
offset address ending in three zeros (ES:1000, ES: 2000...) falls
in the middle of the area being overlaid by a sector, this error
will occur.
[INT_13, AH=4 Verify disk sectors]
Another possible protection interrupt is interrupt 13H,
service 4, Verify disk sectors. Disk verification takes place on
the disk and DOES NOT involve verification of the data on the
disk against data in memory! This function has no buffer
specification, does not read or write a disk: it causes the
system to read the data in the designated sector or sectors and
to check its computed cyclic redundancy check (CRC) against data
stored on the disk. See INT_13, AH=2 registers and error report.
[CRC]
The CRC is a checksum, that detects general errors. When a
sector is written to disk, an original CRC is calculated AND
WRITTEN ALONG with the sector data. The verification service
reads the sector, recalculates the CRC, and compares the
recalculated CRC with the original CRC.
We saw that some protection schemes attempt to disguise
interrupt calls. This is particularly frequent in the disk access
protection schemes that utilize INT_13 (the "disk" interrupt).
If you are attempting to crack such programs, the usual
course of action is to search for occurrences of "CD13", which
is machine language for interrupt 13. One way or another, the
protection scheme has to use this interrupt to check for the
special sectors of the disk. If you examine a cross section of
the program, however, you'll find programs which do not have
"CD13" in their machine code, but which clearly are checking the
key disk for weird sectors. How comez?
There are several techniques which can be used to camouflage
the protection scheme from our nice prying eyes. I'll describe
here the three such techniques that are more frequent:
1) The following section of code is equivalent to issuing an
INT 13 command to read one sector from drive A, side 0, track
29h, sector ffh, and then checking for a status code of 10h:
cs:1000 MOV AH,02 ;read operation
cs:1002 MOV AL,01 ;1 sector to read
cs:1004 MOV CH,29 ;track 29h
cs:1006 MOV CL,FF ;sector ffh
cs:1008 MOV DX,0000 ;side 0, drive A
cs:100B XOR BX,BX ;move 0...
cs:100D MOV DS,BX ;...to DS register
cs:100F PUSHF ;pusha flags
cs:1010 PUSH CS ;pusha CX
cs:1011 CALL 1100 ;push address for next
instruction onto stack and branch
cs:1014 COMP AH,10 ;check CRC error
cs:1017 ... rest of verification code
...
...
cs:1100 PUSHF ;pusha flags
cs:1101 MOV BX,004C ;address of INT_13 vector
cs:1104 PUSH [BX+02] ;push CS of INT_13 routine
cs:1107 PUSH [BX] ;push IP of INT_13 routine
cs:1109 IRET ;pop IP,CS and flags
Notice that there is no INT 13 command in the source code, so if
you had simply used a debugger to search for "CD13" in the
machine code, you would never have found the protection routine.
2) Another technique is to put in a substitute interrupt
instruction, such as INT 10, which looks harmless enough, and
have the program change the "10" to "13 (and then back to "10")
on the fly. A search for "CD13" would turn up nothing.
3) The best camouflage method for interrupts I have ever
cracked (albeit not on a INT 13) was a jump to a section of the
PROGRAM code that reproduces in extenso the interrupt code. This
elegant (if a little overbloated) disguise mocks every call to
the replicated interrupt.
LOADING ABSOLUTE DISK SECTORS
Old good [debug.com] has been called the "swiss army knife" of
the cracker. It allows a lot of nice things, inter alia the
loading, reading, modifying and writing of absolute sectors of
the disks. The sector count starts with the first sector of track
0, next sector is track 0, second side (if double sided), then,
back to the first side, track 1, and so on, until the end of the
disk. Up to 80h (128) sectors can be loaded at one time. To use
you must specify starting address, drive (0=A, 1=B, etc...),
starting sector and number of sectors to load.
- l 100 0 10 20
This instruction tells DEBUG to load, starting at DS:0100, from
drive A, sector 10h for 20h sectors. This allows at times the
retrieval of hidden and/or weird formatted data. If you get an
error, check the memory location for that data. Often times, part
of the data has been transferred before the error occurs, and the
remainder can be manually entered or gathered through repetitive
retries.
Bear all this in mind learning the following cracks.
Let's now crack an "oldie" primitive:
MS Flight simulator (old version 2.12, from 1985!)
This old program used -in 1985!- following beautiful protection
scheme: on the disk you had only a "stub", called FS.COM with few
bytes, which had following instructions:
loc code instruction what's going on
-------------------------------------------------------
:0100 FA CLI ;why not?
:0101 33C0 XOR AX,AX ;ax=0
:0103 8ED0 MOV SS,AX ;ss=0
:0105 BCB0C0 MOV SP,C0B0 ;SP=C0B0
:0108 8EC0 MOV ES,AX ;ES=0
:010A 26C70678003001 MOV Wptr ES:[0078],0130 ;Wp 0:78=130
:0111 268C0E7A00 MOV ES:[007A],CS ;0:7A=Segment
:0116 BB0010 MOV BX,1000 ;BX=1000
:0119 8EC3 MOV ES,BX ;ES=1000
:011B 33DB XOR BX,BX ;BX=0
:011D B80102 MOV AX,0201 ;AH=2 AL=1 sector
:0120 BA0000 MOV DX,0000 ;head=0 drive=0
:0123 B96501 MOV CX,0165 ;track=1 sector=65 (!)
:0126 CD13 INT 13 ;INT 13/AH=2
:0128 B83412 MOV AX,1234 ;AX=1234
:012B EA00000010 JMP 1000:0000 ;JMP to data we just read
:0130 CF IRET ;Pavlovian, useless ret
You see what's happening in this old protection scheme,
don't you? Herein you can watch the same snap that happens in
more recent (much more recent) protection schemes (as you'll see
in the next lesson): the protection searches for a weird
formatted sector and/or for particular data.
That should be no problem for you any more: you should just
reverse engineer everything (and that goes on pretty quickly:
just watch and break on the INT_13 calls), fetch the "weird"
data, tamper the whole crap and have your soup as you like it.
One more word about "old" protection schemes. Be careful not
to spurn them! Some of them are
--CLEVER
--STILL USED
--DIFFICULT TO CRACK... I mean, this older DOS programs had
nice protections... it's pretty annoying to crack windows
programs that require a registration number: as you saw in Lesson
3, you just type your name and a serial number of your choice in,
say "666666666", break into the program with WINICE, search the
"666666666" and search too, for good measure, your own name, set
a memory read breakpoint where the number dwells and look at the
code that manipulates your input. As [Chris] rightly pointed out,
you can even rip the code straight out of the program and create
a key generator which will produce a valid code. This code will
work for any name you typed in only in the "pure maths
manipulation" protection schemes, and will on the contrary be
specific, following the name you typed in, the "alpha-maths
manipulation" protection schemes (like MOD4WIN, see the Windows
lessons), watch in this case the "pseudo-random xoring" of the
letters that compose your name.
--STUNNING, coz new ideas have always been infrequent, and
they are getting more and more rare in this objectionable world
of lazy, incapable programmers patronizing us with ill-cooked
outrages like Windows'95... yeah, as usual there is no
"development" at all, quite the contrary, I would say. Take a
step backward, sip a good Martini-Wodka (please remember that
only Ice cubes, Dry Martini, Wodka Moskovskaja, Schweppes'
"Indian tonic" a green olive from Tuskany and a maltese lemon
zest will really be perfect) and watch from your balcony, with
unsullied eyes, your town and the people around you: slaves
everywhere, leaving home at 7.30 in the morning, stinking in a
progression of identical cars, forced to interminably watch
advertisement panels and endlessly listen to boorish publicity,
happy to go to work (if they happen to have the "luck" to work,
in this inequitable society) the whole day long in order to
produce other cars in order to buy, one day, a new car with a
different colour...
Why people don't look at the stars, love each other, feel
the winds, ban the stinking cars from the places where they live
and eat, study colours... name yourself a not-consumistic
activity? Why don't they read any poems any more? No poetry any
more, in the grey society of the publicity-spots slaves...poetry
will soon be forbidden, coz you cannot CONSUME as you read poems,
and in this farce of a society you are BOUND to consume, that's
the only thing they want you to do... you are CULTIVATED to
consume... no books worth to read any more... stupid american
conventional cram everywhere... boy, at times I'm missing some
well placed neutron bombs, the ones that would kill all these
useless zombies and leave noble books and good Wodka untouched.
It's difficult to believe in democracy any more... if I ever
did... all the useless zombie do -unfortunately- vote, and they
do vote for "smiling semblances", for "conventionally minded
idiots" that so act as if they would "really" be like what they
"look" like and could not care less about anything else than
making bucks and defend intolerant and petty patterns. The slaves
choose the people they have "seen" on TV... as if the egyptians
would VOTE for their pharaohs, exhilarated under the whips of
publicity... sorry, at times I forget that you are here for the
cracks, and could not care less about what I think...
You 'll obtain the OTHER missing lessons IF AND ONLY IF you
mail me back (via anon.penet.fi) with some tricks of the trade
I may not know that YOU discovered. Mostly I'll actually know
them already, but if they are really new you'll be given full
credit, and even if they are not, should I judge that you
"rediscovered" them with your work, or that you actually did good
work on them, I'll send you the remaining lessons nevertheless.
Your suggestions and critics on the whole crap I wrote are also
welcomed.
+ORC an526164@anon.penet.fi
HOW TO CRACK, by +ORC, A TUTORIAL
Lesson 6.1: Funny tricks (1)
LESSON 6 (1) - Funny tricks. Xoring, Junking, Sliding
EXERCISE 01: [LARRY in search of the King]
Before the next step let's resume what you have learned in
the lessons 3-5, beginning with a very simple crack exercise
(again, we'll use the protection scheme of a game, for the
reasons explained in lesson 1): SEARCH FOR THE KING (Version
1.1.). This old "Larry" protection sequence, is a "paper
protection" primitive. It's a very widespread (and therefore easy
to find) program, and one of the first programs that instead of
asking meaningful passwords (which offer us the possibility to
immediately track them down in memory) asked for a random number
that the good buyer could find on the manual, whereby the bad
cracker could not. (Here you choose -with the mouse- one number
out of 5 possible for a "gadget" choosen at random). I don't need
any more to teach you how to find the relevant section of code
(-> see lesson 3). Once you find the protection, this is what you
get:
:protection_loop
:C922 8E0614A3 MOV ES,[A314]
...
:C952 50 0E PUSH AX & CS
:C954 E81BFF CALL C872 <- call protection scheme
:C957 5B POP BX twice
:C959 8B76FA MOV SI,[BP-06] <- prepare store_room
:C95C D1E6 SHL SI,1 <- final prepare
:C95E 8942FC MOV [BP+SI-04],AX <- store AX
:C961 837EFA00 CMP Word Ptr [BP-06],+00 <- good_guy?
:C965 75BB JNZ C922 <- loop, bad guy
:C967 8E0614A3 MOV ES,[A314]
:C96B 26F606BE3501 TEST Byte Ptr ES:[35BE],01 <- bad_guy?
:C971 74AF JZ C922 <- loop, bad guy
:C973 8B46FC MOV AX,[BP-04]... <- go on good guy
Let's see now the protection scheme called from :C954
:C872 55 PUSH BP
...
:C8F7 90 NOP
:C8F8 0E PUSH CS
:C8F9 E87234 CALL FD6E <- call user input
:C8FC 5B POP BX
:C8FD 5B POP BX
:C8FE 8B5E06 MOV BX,[BP+06]
:C901 D1E3 SHL BX,1
:C903 39872266 CMP [BX+6622],AX <- right answer?
:C907 7505 JNZ C90E <- no, beggar_off
:C909 B80100 MOV AX,0001 <- yes, AX=1
:C90C EB02 JMP C910
:C90E 2BC0 SUB AX,AX <- beggar_off with AX=0
:C910 8BE5 MOV SP,BP
:C912 5D POP BP
:C913 CB RETF <- back to main
Here follow 5 questions, please answer all of them:
1) Where in memory (in which locations) are stored the "right"
passnumbers? Where in memory is the SEGMENT of this
locations stored? How does the scheme get the OFFSET?
2) Would setting NOPs instructions at :C965 and :C971 crack?
Would it be a good idea?
3) Would changing :C907 to JZ crack? Would it be a good idea?
4) Would changing :C907 to JNZ C909 crack? Would it be a good
idea?
5) Write down (and try) at least 7 OTHER different patches to
crack this scheme in spades (without using any NOP!).
Uff! By now you should be able to do the above 5 exercises in
less than 15 minutes WITHOUT USING THE DEBUGGER! Just look at the
data above and find the right answers feeling them... (you 'll
now which one are the right one checking with your debugger...
score as many points as you like for each correct answer and sip
a good Martini-Wodka... do you know that the sequence should
ALWAYS be 1) Ice cubes 2) Martini Dry 3) Wodka Moskovskaja 4)
olive 5) lemon 6) Schweppes Indian tonic?
Let's now come to the subject of this lesson:
-----> [Xoring] (Simple encryption methods)
One easy way to encrypt data is the XOR method. XOR is a bit
manipulation instruction that can be used in order to cipher and
decipher data with the same key:
Byte to encrypt key result
FF XOR A1 5E
5E XOR A1 FF
As you can see XOR offers a very easy way to encrypt or to
decrypt data, for instance using the following routine:
encrypt_decrypt:
mov bx, offset_where_encryption/decryption_starts
xor_loop:
mov ah, [bx] <- get current byte
xor ah, encrypt_value <- engage/disengage xor
mov [bx], ah <- back where you got it
inc bx <- ahead one byte
cmp bx, offset_start_+_size <- are we done?
jle xor_loop <- no, then next cycle
ret <- back where we came from
The encrypt_value can be always the same (fixed) or chosen at
random, for instance using INT_21, service 2Ch (get current time)
and choosing as encrypt_value the value reported in DL (but
remembering to discard the eventual value 0, coz otherwise it
would not xor anything at all!)
random_value:
mov ah,2Ch
int 21h
cmp dl,0
je random_value
mov encrypt_value,dl
The problem with XORing (and with many other encryption
methods), is that the part of the code that calls the encryption
routine cannot be itself encrypted. You'll somewhere have, "in
clear" the encryption key.
The protectionist do at times their best to hide the
decrypting routine, here are some common methods:
-----> JUNK FILLING, SLIDING KEYS AND MUTATING DECRYPTORS
These are the more common protection method for the small
decryption part of the program code. This methods, originally
devised to fool signature virus scanners, have been pinched from
the polymorphic virus engines of our fellows viriwriters, and are
still in use for many simple decryption protection schemes. For
parts of the following many thanks go to the [Black Baron], it's
a real pity that so many potential good crackers dedicate so much
time to useless (and pretty repetitive) virus writing instead of
helping in our work. This said, virus studying is VERY important
for crackers coz the code of the viri is
* ULTRAPROTECTED
* TIGHT AND EFFECTIVE
* CLOAKED AND CONCEALED.
Let's show as example of the abovementioned protection tactics
the following ultra-simple decryptor:
MOV SI,jumbled_data ;Point to the jumbled data
MOV CX,10 ;Ten bytes to decrypt
mn_loop: XOR BYTE PTR [SI],44 ;XOR (un_scramble!) a byte
INC SI ;Next byte
LOOP mn_loop ;Loop the 9 other bytes
This small program will XOR the ten bytes at the location pointed
to by SI with the value 44. Providing the ten bytes were XORed
with 44 prior to running this decryptor the ten bytes will be
restored to their original state.
In this very simple case the "key" is the value 44. But there are
several tricks involving keys, the simplest one being the use of
a "sliding" key: a key that will be increased, or decreased, or
multiplied, or bit-shifted, or whatever, at every pass of the
loop.
A possible protection can also create a true "Polymorph"
decryptor, a whole decryptor ROUTINE that looks completely
different on each generation. The trick is to pepper totally
random amounts of totally random instructions, including JUMPS
and CALLS, that DO NOT AFFECT the registers that are used for the
decryption. Also this kind of protection oft uses a different
main decryptor (possibly from a selection of pre-coded ones) and
oft alters on each generation also all the registers that the
decryptor uses, invariably making sure that the JUNK code that
it generates doesn't destroy any of the registers used by the
real decryptor! So, with these rules in mind, here is our simple
decryptor again:
MOV DX,10 ;Real part of the decryptor!
MOV SI,1234 ;junk
AND AX,[SI+1234] ;junk
CLD ;junk
MOV DI,jumbled_data ;Real part of the decryptor!
TEST [SI+1234],BL ;junk
OR AL,CL ;junk
mn_loop: ADD SI,SI ;junk instr, but real loop!
XOR AX,1234 ;junk
XOR BYTE PTR [DI],44 ;Real part of the decryptor!
SUB SI,123 ;junk
INC DI ;Real part of the decryptor!
TEST DX,1234 ;junk
AND AL,[BP+1234] ;junk
DEC DX ;Real part of the decryptor!
NOP ;junk
XOR AX,DX ;junk
SBB AX,[SI+1234] ;junk
AND DX,DX ;Real part of the decryptor!
JNZ mn_loop ;Real part of the decryptor!
As you should be able to see, quite a mess! But still executable
code. It is essential that any junk code generated by the
Polymorph protection is executable, as it is going to be peppered
throughout the decryptor. Note, in this example, that some of the
junk instructions use registers that are actually used in the
decryptor! This is fine, providing the values in these
registers aren't destroyed. Also note, that now we have random
registers and random instructions on each generation. So, a
Polymorph protection Engine can be summed up into three major
parts:
1 .. The random number generator.
2 .. The junk code generator.
3 .. The decryptor generator.
There are other discrete parts but these three are the ones where
most of the work goes on!
How does it all work? Well a good protection would
* choose a random selection of registers to use for the
decryptor and leave the remaining registers as "junk" registers
for the junk code generator.
* choose one of the compressed pre-coded decryptors.
* go into a loop generating the real decryptor, peppered with
junk code.
From the protectionist's point of view, the advantages of this
kind of method are mainly:
* the casual cracker will have to sweat to find the decryptor.
* the casual cracker will not be able to prepare a "patch" for
the lamers, unless he locates and patches the generators, (that
may be compressed) coz otherwise the decryptor will vary every
time.
To defeat this kind of protection you need a little "zen" feeling
and a moderate knowledge of assembler language... some of the
junk instructions "feel" quite singular when you look at them
(->see lesson B). Besides, you (now) know what may be going on
and memory breakpoints will immediately trigger on decryption...
the road is open and the rest is easy (->see lessons 3-5).
-----> Starting point number magic
For example, say the encrypted code started at address 10h, the
following could be used to index this address:
MOV SI,10h ;Start address
MOV AL,[SI] ;Index from initial address
But sometimes you'll instead find something like the following,
again based on the encrypted code starting at address 10h:
MOV DI,0BFAAh ;Indirect start address
MOV AL,[DI+4066h) ;4066h + 0BFAAh = 10010h (and FFFF = 10h)!!
The possible combinations are obviously infinite.
[BIG KEYS] (Complicated encryption methods)
Prime number factoring is the encryption used to protect
sensible data and very expensive applications. Obviously for few
digit keys the decoding is much easier than for, say, 129 or 250
digit keys. Nevertheless you can crack those huge encryption too,
using distributed processing of quadratic sieve equations (which
is far superior for cracking purpose to the sequential processing
methods) in order to break the key into prime numbers. To teach
you how to do this sort of "high" cracking is a little outside
the scope of my tutorial: you'll have to write a specific short
dedicated program, linking together more or less half a thousand
PC for a couple of hours, for a 250 bit key, this kind of things
have been done quite often on Internet, were you can also find
many sites that do untangle the mysteries (and vagaries) of such
techniques.
As References I would advocate the works of Lai Xueejia, those
swiss guys can crack *everything*. Begin with the following:
Xuejia Lai, James Massey, Sean Murphy, "Markov Ciphers and
Differential Cryptanalysis", Advances in Cryptology,
Eurocrypt 1991.
Xuejia Lai, "On the Design and Security of Block Ciphers",
Institute for Signal and Information Processing,
ETH-Zentrum, Zurich, Switzerland, 1992
Factoring and primality testing is obviously very important for
this kind of crack. The most comprehensive work I know of is:
(300 pages with lengthy bibliography!)
W. Bosma & M. van der Hulst
Primality Testing with Cyclotomy
Thesis, University of Amsterdam Press.
A very good old book you can incorporate in your probes to build
very effective crack programs (not only for BBS accesses :=) is
*the* "pomerance" catalog:
Pomerance, Selfridge, & Wagstaff Jr.
The pseudoprimes to 25*10^9
Math. Comp. Vol 35 1980 pp. 1003-1026
Anyway... make a good search with Lykos, and visit the relevant
sites... if encryption really interests you, you'll be back in
two or three (or thirty) years and you'll resume cracking with
deeper erudite knowledge.
[PATENTED PROTECTION SYSTEMS]
The study of the patented enciphering methods is also *quite*
interesting for our aims :=) Here are some interesting patents,
if you want to walk these paths get the complete texts:
[BEST] USPat 4168396 to Best discloses a microprocessor
for executing enciphered programs. Computer programs which have
been enciphered during manufacture to deter the execution of the
programs in unauthorized computers, must be decrypted before
execution. The disclosed microprocessor deciphers and executes
an enciphered program one instruction at a time, instead of on
a continuous basis, through a combination of substitutions,
transpositions, and exclusive OR additions, in which the address
of each instruction is combined with the instruction. Each unit
may use a unique set of substitutions so that a program which can
be executed on one microprocessor cannot be run on any other
microprocessor. Further, Best cannot accommodate a mixture of
encrypted and plain text programs.
[JOHNSTONE] USPat 4120030 to Johnstone describes a
computer in which the data portion of instructions are scrambled
and in which the data is of necessity stored in a separate
memory. There is no disclosure of operating with instructions
which are completely encrypted with both the operation code and
the data address portion being unreadable without a corresponding
key kernel.
[TWINPROGS] USPat 4183085 describes a technique for
protecting software by providing two separate program storages.
The first program storage is a secure storage and the second
program storage is a free storage. Security logic is provided to
check whether an output instruction has originated in the secure
store and to prevent operation of an output unit which receives
output instructions from the free storage. This makes it
difficult to produce information by loading a program into free
storage.
[AUTHENTICATOR] USPat 3996449 entitled "Operating System
Authenticator," discloses a technique for authenticating the
validity of a plain text program read into a computer, by
exclusive OR'ing the plain text of the program with a key to
generate a code word which must be a standard recognizable code
word which is successfully compared with a standard corresponding
code word stored in the computer. If there is a successful
compare, then the plain text program is considered to be
authenticated and is allowed to run, otherwise the program
is not allowed to run.
ELEMENTS OF [PGP] CRACKING
In order to try to crack PGP, you need to understand how these
public/private keys systems work. Cracking PGP seems extremely
difficult, though... I have a special dedicated "attack" computer
that runs 24 hours on 24 only to this aim and yet have only begun
to see the light at the famous other end of the tunnel. It's
hard, but good crackers never resign! We'll see... I publish here
the following only in the hope that somebody else will one day
be able to help...
In the public key cryptosystems, like PGP, each user has an
associated encryption key E=(e,n) and decryption key D=(d,n),
wherein the encryption keys for all users are available in a
public file, while the decryption keys for the users are only
known to the respective users. In order to maintain a high level
of security a user's decoding key is not determinable in a
practical manner from that user's encoding (public) key. Normally
in such systems, since
e.multidot.d.ident.1 (mod(1 cm((p-1),(q-1)))),
(where "1 cm((p-1),(q-1))" is the least common multiple of the
numbers p-1 and q-1)
d can be determined from e provided p and q are also known.
Accordingly, the security of the system is dependent upon the
ability to determine p and q which are the prime factors of n.
By selecting p and q to be large primes, the resultant composite
number n is also large, and correspondingly difficult to factor.
For example, using known computer-implemented factorization
methods, on the order of 10.sup.9 years is required to factor a
200 digit long number. Thus, as a practical matter, although a
user's encryption key E=(e,n) is public, the prime factors p and
q of n are effectively hidden from anyone due to the enormous
difficulty in factoring n. These aspects are described more fully
in the abundant publications on digital signatures and Public-Key
Cryptosystems. Most public/private systems relies on a message-
digest algorithm.
A message-digest algorithm maps a message of arbitrary length
to a "digest" of fixed length, and has three properties:
Computing the digest is easy, finding a message with a given
digest "inversion" is hard, and finding two messages with the
same digest "collision" is also hard. Message-digest algorithms
have many applications, not only digital signatures and message
authentication. RSA Data Security's MD5 message-digest algorithm,
developed by Ron Rivest, maps a message to a 128-bit message
digest. Computing the digest of a one-megabyte message takes as
little as a second. While no message-digest algorithm can yet
be secure, MD5 is believed to be at least as good as any other
that maps to a 128-bit digest.
As a final gift, I'll tell you that PGP relies on MD5 for a
secure one-way hash function. For PGP this is troublesome, to say
the least, coz an approximate relation exists between any four
consecutive additive constants. This means that one of the design
principles behind MD4 (and MD5), namely to design a collision
resistant function, is not satisfied. You can construct two
chaining variables (that only differ in the most significant bit
of every word) and a single message block that yield the same
hashcode. The attack takes a few minutes on a PC. From here you
should start, as I did.
[DOS 4GW] cracking - This is only a very provisory part of this
tutorial. DOS 4GW cracking will be much better described as soon
as [Lost soul] sends his stuff, if he ever does. For (parts of)
the following I thank [The Interrupt].
Most applications of every OS, and also of DOS 4GW, are
written in C language, coz as you'll have already learned or,
either, you'll learn, only C allows you to get the "guts" of a
program, almost approaching the effectiveness of assembler
language.
C is therefore the LANGUAGE OF CHOICE for crackers, when you
prepare your tools and do not directly use assembler routines.
Besides... you'll be able to find VERY GOOD books about C for
next to nothing in the second hand bookshops. All the lusers are
throwing money away in spades buying huge, coloured and
absolutely useless books on unproductive "bloated" languages like
Visual basic, C++ and Delphy. Good C new books are now rare
(books on assembler language have always been) and can be found
almost exclusively on the second hand market. Find them, buy
them, read them, use them for your/our aims. You can find a lot
of C tutorials and of C material on the Web, by all means DO IT!
Be a conscientious cracker... learn C! It's cheap, lean, mean and
very productive (and creative) :=)
Back to the point: most stuff is written in C and therefore
you need to find the "main" sub-routine inside the asm. With
DOS/4GW programs, search the exe file for "90 90 90 90", almost
always it'll be at the start of the compiled code. Now search for
an INT_21 executed with 4C in AH, the exec to dos code (if you
cannot "BPINT 21 AH=4C" with your tool, then search for the
sequence "b4 4c cd 21". This is the equivalent to [mov AH,4C &
int 21]: it's the most direct call, but as you'll have already
learned, there are half a dozen ways to put 4C in AX, try them
all in the order of their frequency).
A few bytes above the INT_21 service 4C, you'll find the
call to the "main" subroutine: "E8 xx xx". Now place a "CC" byte
a few bytes above the call in the exe and run the exe under a
debugger. When the computer tries to execute the instruction
you'll be throw back in the debugger coz the "CC" byte acts as
INT_01 instruction. Then proceed as usual.
[THE "STEGONATED" PASSWORD HIDEOUT]
A last, very nice trick should be explained to every wannabe
cracker, coz it would be embarrassing to search for passwords or
protection routines that (apparently) are not there. They may be
hidden INSIDE a picture (or a *.waw file for that matter). This
is steganography, a method of disguising messages within other
media.
Depending on how many shades of grey or hues of colour you want
to have, a pixel can be expressed using 8. 16, 32 or even more
bits. If the least significant bit is changed. the shade of the
pixel is altered only one-256th, one-65,OOOth or even less. No
human eye could tell the difference.
What the protectionist does, is hijack the least significant
bit in each pixel of a picture. It uses that bit to store one bit
of a protection, or of a password (or of a file, or of a secret
message). Because digitized pictures have lots of pixels, it's
possible to store lots of data in a single picture. A simple
algorithm will transfer them to the relevant parts of the program
when it needs be, and there we'll intercept them. You'll need to
learn very well the zen-cracking techniques to smell this kind
of stuff though (-> see lesson B).
Well, that's it for this lesson, reader. Not all lessons of my
tutorial are on the Web.
You 'll obtain the OTHER missing lessons IF AND ONLY IF you
mail me back (via anon.penet.fi) with some tricks of the trade
I may not know that YOU discovered. Mostly I'll actually know
them already, but if they are really new you'll be given full
credit, and even if they are not, should I judge that you
"rediscovered" them with your work, or that you actually did good
work on them, I'll send you the remaining lessons nevertheless.
Your suggestions and critics on the whole crap I wrote are also
welcomed.
an526164@anon.penet.fi (+ORC)
HOW TO CRACK, by +ORC, A TUTORIAL
Lesson 8.1: How to crack Windows, an approach
--------------------------------------------------------
SPECIAL NOTE: Please excuse the somehow "unshaven"
character of the windows lessons... I'm cracking the
newest Windows '95 applications right now, therefore
at times I had to add "on the fly" some corrections to
the older Windows 3.1 and Windows NT findings.
"homines, dum docent, discunt".
---------------------------------------------------------
-> 1st THING TO REMEMBER
The NE format does give every windows executable the equivalent
of a debug symbol table: A CRACKER BLISS!
-> UNDOCUMENTED DEBUGGING
One of the many feature of Windows based on undocumented
foundations is the "ability to debug".
A word about undocumented functions in the MS-Operating Systems:
Microsoft manipulates its rule and domination of the operating
systems in use to day (MS-DOS, Windows, Windows '95) with two
main wicked aims:
1) getting the concurrence completely bankrupt (that's the
scope of all the using of undocumented functions and
CHANGING them as soon as the concurrence uses them). The
battle against Borland was fought in this way.
2) getting all future "programmers" to use windows as a "black
box" that only Microsoft engineers (if ever) can master, so
that everybody will have to sip the ill-cooked abominations
from Microsoft without ever having a chance to alter or
ameliorate them.
Strange as it may seem, only the sublime cracker community fights
against these intolerable plans. All stupid governments and
lobbies -on the contrary- hide behind the fig-leaf of the
"market" "freedom" in order to ALLOW such heinous developments
(I'm speaking as if they were capable to opposing them even if
they wanted, which they do not. Be assured, they couldn't anyway,
"Governments" are deliberately MADE to serve Gates and all the
remaining suckers, and lobbies are the shield of feudalism. You
can forget "democracy", the only rule existing is a malevolent
oligarchy based on money, personal connections, defect of
culture, lack of knowledge and dictatorship of bad taste through
television in order to keep the slaves tamed... enough now...)
The windows situation is particularly reminiscent of the older
situation in DOS, where for years the key "load but don't
execute" function, used by debuggers, such as [DEBUG], [SYMDEB]
and [CODEVIEW], was "reserved" by Microsoft.
The windows debugging library, WINDEBUG.DLL, a number of
undocumented functions and even the interface it provides are
undocumented! The WinDebug() function is used by all available
windows debuggers, including [CVW] (CodeView for Windows), [TDW]
(TurboDebugger for Windows), [Multiscope] and [Quick C for
Windows] (the last two are GUI, not text debuggers. The use of
WinDebug() doesn't show up in MAPWIN output 'coz debuggers link
to it at run-time via the amazing GetProcAddress() function.
WinDebug() is a hacked 32-bit version, for the old Windows
3.0, of the poorly documented DOSPTrace() function from OS/2 1.x
(study these older Operating Systems! Studying the past you'll
understand EVERYTHING! Sometime I think that the only way to hack
and crack correctly is to be more a software historian than a
programmer... fac sapias et liber eris!). DOSPTrace is, in turn,
based on the ptrace() function in Unix.
Like DosPTrace(), WinDebug() takes commands such as Go,
Single-Step, Write&Read Registers, Write&Read Memory. It returns
to its caller either when the command completes or when a
breakpoint occurs (or a DLL load). These commands and
notifications appear in a large structure whose address is passed
in WinDebug().
WinDebug() was renamed CVWIN.DLL (and TDWIN.DLL) for Windows
3.1., all crackers should study it and get the maximum possible
documentation about it. As you will see in the following, it is
worth to study also TOOLHELP.DLL (what Microsoft would like you
to fiddle with) and INT_41h (the real debugging interface).
Interrupt handling under Windows
Interrupt handling under Windows can be tricky: you need to
use Toolhelp (a rather scaring lobotomy for your programs) or to
have special code for Standard vs. Enhanced modes, because the
information on the stack of an interrupt or exception handler
differs between the two windows modes. In addition, some handlers
would be installed using INT_21h, while others are set up using
DPMI services. Toolhelp has quite a bit of internal code that
"cooks" the interrupts and sends them to you in an easily
digestible form.
Remember that Windows uses GP faults as a "hacker" method
of doing ring transitions that are not allowed with legal 80x86
instructions: the virtual memory system of Enhanced mode is
implemented via the page fault.
Some tools for cracking windows (-> see lesson 9)
----------------- DEBUGGERS
CVW and TDW (you have to know the function's
segment:offset address beforehand in order
to crack a function)
WCB [Windows Codeback] by Leslie Pusztai (it's
a really cool tool!)
WDEB386 Microsoft's WDEB386 (clumsy, and requires a
second monitor)
Soft-Ice/Windows best (BY FAR!) windows debugger! NuMega is
so good I am at times really sorry to crack
their products! [WINICE] is the single,
absolutely essential debugger and snooping
utility for windows crackers. Get it!
----------------- POST MORTEM INSPECTORS
CORONER, etc. (a lot of shareware)
MS-DrWatson Old and clumsy
Borland's Winspector THE BEST! It has the BUILDSYM utility
that allows the creation of a debug
.SYM file from an .EXE without debug
information.
----------------- INSPECTORS
MS-Spy Old
Borland's WinSight (Best one, select "Other")
MicroQuill's Windows DeMystifiers (from Jeff Richter):
VOYEUR (hold SHIFT picking Message Selection), COLONEL,
MECHANIC and ECOLOGIST
----------------- SNOOPERS
[INFSPY.EXE], 231.424 bytes, version 2.05 28/8/1994 by Dean
Software Design, may be the more complete one.
[SUPERSPY.EXE], 24.576 bytes, 10,6,1994, quite handy for quick
informations.
[WINVIEW.EXE], 30.832 bytes, Version 3.00 by Scott McCraw, MS(c)
1990-1992, this is the old MS-Spy, distributed by MS
[TPWSPY.EXE], 9.472 bytes, quite primitive, but you get the
pascal source code with it.
-> INSIDE A WINDOWS '95 DEBUGGER
You can debug a program at the assembly-language level
without any debugging information. The DOS [DEBUG] program does
that, allowing breakpoints and single-stepping, all of which
implies that the hardware must be cooperating. Back in the time
of the 4-MHz Z-80s, you used a debugger that plugged interrupt
op codes into the instruction stream to generate breakpoints.
Nothing has changed. That's how you debug a program on a
80586 (=Pentium). The x86 architecture includes software
interrupts. The 1-byte op code xCC is the INT_03 instruction,
reserved for debuggers. You can put the INT_03 op code in place
of the program instruction op code where the break is to occur
and replace the original op code at the time of the interrupt.
In the 80386 and later, you can set a register flag that tells
the processor to generate a not-intrusive INT_01 instruction for
every machine instruction executed. That device supports single
stepping.
The Win32SDK (Windows '95 software developer's kit) includes
functions that allow one program to launch another program and
debug it. The SDK's debug API takes care of how the interrupts
and interrupt vectors get managed. The logical consequence of
such an approach is that fewer and fewer people will be able to
know what's going on inside an application. The bulk of the
programmers -in few years time- will not be able any more to
reverse engineer an application, unless the few that will still
understand assembler-language do offer them the tools to do it.
Microsoft -it is evident- would like the programmers to use a
"black box" approach to programming, writing nice little "hallo
world" application and leaving to the engineers in Microsoft
alone the capacity to push forward (and sell) real programs that
are not toy application.
The Win32 documentation seems vast, almost luxurious, until
you begin serious work and you discover its shortcomings, like
the fact that extended error codes are not documented, and
numerous APIs are documented either incorrectly or so poorly that
you must burn precious time testing them. What we definitely need
is to find some secret fellows inside Microsoft (like good old
Prometeus) that smuggles to the outside the real documentation
that the Microsoft engineers have reserved for themselves. If you
are reading this and do work for Microsoft, consider the
possibility of double-crossing your masters for the sake of
humanity and smuggle us the secret information.
In windows '95 a debugger program launches a program to be
debugged by calling the _CreateProcess function, specifying in
an argument that the program is to be debugged. Then the debugger
program enters a loop to run the program. At the top of the loop
the debugger calls _WaitForDebugEvent.
Each time _WaitForDebugEvent returns it sets indicators that
tell about the vent that suspended the program being debugged.
This is where the debugger traps breakpoints and single-step
exceptions. _WaitForDebugEvent fills in an event structure that
contains among other things the address that was interrupted end
the event that caused the interrupt.
The debugger calls _GetThreadContext to get the running
context of the debugged program, including the contents of the
registers. The debugger can, as the result of cracker
interaction, modify these values and the contents of the debugged
program's memory.
The debugger sets breakpoints by saving the op code at the
instruction to be intercepted and putting the INT_03 op code at
its place, it's always the same old marmalade. When the
breakpoint occurs, the debugger replaces the original op code in
the program's instruction memory, and decrements the interrupted
program counter in the saved context so that execution resumes
at the instruction that was broken.
To single-step a program, the debugger sets a bit in the
context's flags register that tells the processor to generate an
INT_01 for every instruction cycle. When that interrupt occurs,
the debugger checks to see if the interrupted address is at a new
source-code line number. If not, the debugger continues
execution. Otherwise, the debugger displays the new line in the
IDE and waits for the cracker to take an action that resumes the
program.
While the debugged program is suspended, the debugger
interacts with the cracker and provides full access to the
debugged program's context and memory. This access permits the
cracker to examine and modify part of the code.
To resume the debugged program, the debugger resets the
program's context by calling _SetThreadContext and calls
_ContinueDebugEvent. Then, the debugger returns to the top of the
loop to call _WaitForDebugEvent again.
To extract debug information from a Win32 executable file,
you must understand the format of that file (best thing to do,
to practice yourself, would be to reverse engineer small
programs). The executable file has two sections not found in
other executable files: ".stab" and ".stabstr". How nice that
they used names that suggest their purpose (nomen est omen).
You'll find them inside a table of fixed-length entries that
include entries for .text, .bss, .data and .idata. Inside these
sections the compilers put different parts of a program.
There are several different formats for encoding debug
information in an executable file. Borland's Turbo Debugger one
format. Microsoft's CodeView another. The gnu-win32 port from
Cygnus the stab format, an acronym meaning "symbol table",
although the table contains much more than just symbol
information.
The .stab section in a portable executable file is a table
of fixed-length entries that represent debugging information in
the stab format. The .stabstr section contains variable-length,
null terminated strings into which the .stab table entries point.
The documentation for the stab format is available in text
format on the Cygnus ftp site (ftp.cygnus.com//pub/gnu-win32).
Stabs contain, in a most cryptic format, the names and
characteristics of all intrinsic and user-defined types, the
memory address of every symbol in external memory and on the
stack, the program counter address of every function, the program
counter address where every brace-surrounded statement block
starts and ends, the memory address of line numbers within
source-code files, and anything else that a debugger needs. The
format is complex and cryptic because it is intended to support
any source-code language. It is the responsibility of a debugger
program to translate the stab entries into something meaningful
to the debugger in the language being debugged.
Windows '95 invokes dozens of INT_21 services from 32-bit
code, including KERNEL32.DLL and possess Krn32Mutex, which
apparently controls access to certain parts of the kernel. Some
of the functions in KERNEL32 can be blocked by the Win16Mutex,
even though Microsoft says this isn't the case.
SO, I WANNA CRACK, WHAT SHOULD I DO?
I'll show you a simple windows crack, so easy it can be done
without WINICE: let's take [WINPGP4.1.] (front-end for PGPing in
windows, by Geib - I must thank "Q" for the idea to work on this
crack).
Using WCB you'll find out quickly that the "CONGRATULATIONS
your registration number is OK" and the "SORRY, your registration
number is not correct" data blocks are at the block starting at
36.38B8 (respectively at 36.38D5 and 36.3937), that relocs to
13.081B.
Looking at 13.0000 and following code, you'll find a push
38D5 (68D538) and a push 3937 (683739) at 13.064D and 13.06AE.
The road to the crack is now open, you just need to find and
"fool" the calling routines. You'll learn the exact procedures
for this kind of WINcracks in part 2 and 3 of -> Lesson 8. Let's
now have a look at the protection scheme (disassembly from WCB):
...
13.0E88 660FBF46F8 movsx eax, word ptr [bp-08]
13.0E8D 668946F4 mov [bp-0C], eax
13.0E91 668B46F4 mov eax, [bp-0C]
13.0E95 6669C00A000300 imul eax, 0003000A
13.0E9C 668946F0 mov [bp-10], eax
13.0EA0 668B4606 mov eax, [bp+06]
13.0EA4 663B46F0 cmp eax, [bp-10]
13.0EA8 7505 jne 0EAF <- beggar_off
13.0EAA B80100 mov ax, 0001 <- flag 1 = "Right!"
13.0EAD EB04 jmp 0EB3 <- and go on
beggar_off:
13.0EAF 33C0 xor ax,ax <- flag 0 = "Nope!"
13.0EB1 EB00 jmp 0EB3 <- and go on
I want you to have a good look at this protection scheme.
IT'S THE SAME OLD SOUP! You do remember lesson 3 and the
protection schemes of the old DOS stupid games of the '80s, don't
you? IT'S THE SAME OLD SOUP! In this "up-to-date" "new" windows
application, in WINPGP version 4.1 of 1995/1996, exactly the same
kind of protection is used to "conceal" the password!
A) compare user input with memory echo
B) beggar off if not equal with AX=0
C) go on if equal with AX=1... how boring!
Besides, look at all the mov eax, and eax, moves preceding
the compare! That's a typical pattern for these "number_password"
protections! I wrote (years ago) a little crack utility that
searches for code blocks with a "66" as first instruction_byte
repeating in four or more consecutive instructions and it still
allows me to crack more than half of these windows password smuts
in less than three seconds flat. The IMUL instruction creates the
"magic" number, and if you give a closer look at the mathematical
part of the "conceal" routine, it could help you to crack
analogous schemes used in order to protect the "Instant access"
(c) & (tm) time_crippled software :=)
Now you could crack the above code in 101 different ways,
the most elegant one would probably substitute je 0EAF (or jZ
0EAF, that's the same) to the jne 0EAF at 13.0EA8. You just write
a 74 at the place of the 75, like you did for the cracks in
1978... how boring: it's really the same old soup! (But you'll
see some new tricks in the next lessons).
Well, that's it for this lesson, reader. Not all lessons of my
tutorial are on the Web.
You 'll obtain the missing lessons IF AND ONLY IF you mail
me back (via anon.penet.fi) with some tricks of the trade I may
not know that YOU discovered. Mostly I'll actually know them
already, but if they are really new you'll be given full credit,
and even if they are not, should I judge that you "rediscovered"
them with your work, or that you actually did good work on them,
I'll send you the remaining lessons nevertheless. Your
suggestions and critics on the whole crap I wrote are also
welcomed.
+ORC 526164@anon.penet.fi
HOW TO CRACK, by +ORC, A TUTORIAL
Lesson 8.2: How to crack Windows, a deeper approach
---------------------------------------------------------
SPECIAL NOTE: Please excuse the somehow "unshaven"
character of the windows lessons... I'm cracking the
newest Windows '95 applications right now, therefore
at times I had to add "on the fly" some corrections to
the older Windows 3.1 and Windows NT findings.
"homines, dum docent, discunt".
---------------------------------------------------------
-> 1st THING TO REMEMBER
If you thought that DOS was a mess, please notice that windows
3.1 is a ghastly chaos, and windows 95 a gruesome nightmare of
ill-cooked spaghetti code. Old Basic "GOTO" abominations were
quite elegant in comparison with this concoction... One thing is
sure: This OS will not last... it's way too messy organised,
impossible to consolidate, slow and neurotic (but I must warn
you... I thought exactly the same things about DOS in 1981).
The most striking thing about windows 95 is that it is neither
meat not fish: neither 16 nor 32... you could call it a "24 bit"
operating system.
We'll never damage Microsoft interests enough to compensate for
this moronic situation... where you have to wait three minutes
to get on screen a wordprocessor that older OS (and even old DOS)
kick up in 5 seconds. I decide therefore, hic et nunc, to add an
ADDENDUM to this tutorial: Addendum 1 will be dedicated to teach
everybody how to crack ALL Microsoft programs that do exist on
this planet. I'll write it this sommer and give it away between
the "allowed" lessons.
Anyway you can rely on good WINICE to crack everything, you'll
find it on the web for free, I use version 1.95, cracked by [The
Lexicon] (do not bother me for Warez, learn how to use the search
engines on the web and fish them out yourself). Learn how to use
this tool... read the whole manual! Resist the temptation to
crack immediatly everything in sight... you 'll regret pretty
soon that you did not wanted to learn how to use it properly.
A little tip: as Winice is intended more for software developers
than for crackers, we have to adapt it a little to our purposes,
in order to make it even more effective: a good idea is to have
in the *.DAT initialization file following lines:
INIT = "CODE ON; watchd es:di; watchd ds:si;"
TRA = 92
This way you'll always have the hexadecimal notation on, two very
useful watch windows for passwords deprotection and enough buffer
for your traces.
WINDOWS 3.1. basic cracking: [ALGEBRAIC PROTECTIONS]
The most used windows protections are "registration codes",
these must follow a special pattern: have a "-" or a "+" in a
predetermined position, have a particular number in particular
position... and so on.
For the program [SHEZ], for instance, the pattern is to have a
14 bytes long alphanumeric sequence containing CDCE1357 in the
first 8 bytes.
The second level of protection is to "connect" such a
pattern to the alphanumeric contents of the NAME of the user...
every user name will give a different "access key". This is the
most commonly used system.
As most of these protections have a "-" inside the answering
code, you do not need to go through the normal cracking procedure
(described in the next lesson):
* load WINICE
* hwnd [name_of_the_crackanda_module]
* choose the window Handle of the snap, i.e, the exact
"FIELD" where the code number input arrives... say 091C(2)
* BMSG 091C WM_GETTEXT
* Run anew
* Look at the memory location(s)
* Do the same for the "Username" input FIELD. (Sometimes
linked, sometimes not, does not change much, though)
* BPR (eventually with TRACE) on the memory locations (these
will be most of the time FOUR: two NUMBERCODES and two
USERNAMES). The two "mirrored" ones are the most important
for your crack. At times there will be a "5th" location,
where the algebraic play will go on...
* Look at the code that performs algebraic manipulations on
these locations and understand what it does...
* Disable the routine or jump over it, or reverse it, or
defeat it with your own code... there are thousand
possibilities...
* Reassemble everything.
Uff... quite a long cracking work just to crack some miserable
program... isn'there a quicker way? OF COURSE THERE IS! Actually
there are quite a lot of them (see also the crack of Wincat Pro
below): Look at the following code (taken from SNAP32, a screen
capture utility for Windows 95, that uses a pretty recent
protection scheme):
XOR EBX,EBX ; make sure EBX is zeroed
MOV BL, [ESI] ; load input char in BL
INC ESI ; point at the next character
MOV EDI,EBX ; save the input character in EDI
CMP EBX,+2D ; input char is a "-" ?
JZ ok_it's_a_+_or_a_-
CMP EBX,+2B ; input char is a "+" ?
JNZ Jesus_it's_neither_a_minus_nor_a_plus_let's_check_it
:ok_it's_a_+_or_a_-
XOR EBX,EBX ; EBX is zeroed
MOV BL,[ESI] ; recharge BL
INC ESI ; point to next char (do not check - or +)
:Jesus_it's_neither_a_minus_nor_a_plus_let's_check_it
XOR EBP,EBP ; zero EBP
CMP DWORD PTR [boguschecker], +01
...
even if you did not read all my precedent lessons, you do not
need much more explications... this is a part of the algebraic
check_procedure inside the SNAP32 module... you could also get
here through the usual
USER!BOZOSLIVEHERE
KERNEL!HMEMCPY
USER!GLOBALGETATOMNAME
Windows wretched and detestable APIs used for copy protections,
as usual with WINICE cracking, and as described elsewhere in my
tutorial.
The above code is the part of the routine that checks for the
presence of a "+" or a "-" inside the registration number (many
protections scheme requires them at a given position, other need
to jump over them).
Now sit down, make yourself comfortable and sip a good Martini-
Wodka (invariably very useful in order to crack... but be aware
that only Moskowskaia russian Wodka and a correct "Tumball" glass
will do, do not forget the lemon)... what does this "-" stuff
mean for us little crackers?
It means that we can search directly for the CMP EBX,+2B
sequence inside any file protected with these schemes... and
we'll land smack in the middle of the protection scheme! That's
amazing... but you will never underrate enough the commercial
programmers... the only really amazing thing is how simpleton the
protectionists are! You don't believe me? Try it... you 'll get
your crack at least 4 out of 5 times.
Yes I know, to find this code is not yet to crack it... but for
this kind of copy protection (that's the reason it is so
widespread) there is no single solution... each makes a slightly
different algebraic manipulation of the alphanumeric and of the
numeric data. It's up to you to crack the various schemes... here
you can only learn how to find them and circumvene them. I'll not
give you therefore a "debug" crack solution. You'll find it
yourself using my indications (see the crack of the Wincat Pro
program below).
WHERE ARE THE CODES? WHERE ARE THE MODIFIED FILES? WHERE DO THE
PROTECTIONS KEEP COUNT OF THE PASSING DAYS?
Most of the time the protection schemes use their own *.ini files
in the c:\WINDOWS directory for registration purposes... at time
they even use the "garbage sammler" win.ini file. Let's take as
example WINZIP (versions 5 and 5.5), a very widespread program,
you'll surely have one shareware copy of it somewhere between
your files.
In theory, winzip should be registered per post, in order to
get a "NEW" copy of it, a "registered" copy.
This scares most newby crackers, since if the copy you have
it's not full, there is no way to crack it and make it work,
unless you get the REAL stuff. The youngest among us do not
realize that the production of a real "downsized" demo copy is
a very expensive nightmare for the money-infatuated commercial
programmers, and that therefore almost nobody does it really...
nearly all "demos" and "trywares" are therefore CRIPPLED COMPLETE
PROGRAMS, and not "downsized" demos, independently of what the
programmers and the protectionists have written inside them.
Back to Winzip... all you need, to crack winzip, is to add a
few lines inside the win.ini file, under the heading [WinZip],
that has already been created with the demo version, before the
line with "version=5.0".
I will not help you any further with this... I'll leave it to
you to experiment with the correct sequences... inside win.ini
you must have following sequence (these are only template to
substitute for your tries inside WINICE... you'll get it, believe
me):
[WinZip]
name=Azert Qwerty
sn=########
version=5.5
The *important* thing is that this means that you DO NOT NEED
to have a "new registered version" shipped to you in order to
make it work, as the protectionist sellers would like you to
believe. The same applies most of the time... never believe what
you read in the read.me or in the registration files...
This brings me to a broader question: NEVER believe the
information they give you... never believe what television and/or
newspapers tell you... you can be sure that the only reason they
are notifying you something is to hinder you to read or
understand something else... this stupid_slaves_society can only
subsist if nobody thinks... if you are really interested in what
is going on, real information can be gathered, but surely not
through the "conventional" newspapers and/or news_agencies (and
definitely NEVER through television, that's really only for the
stupid slaves)... yes, some bit of information can be
(laboriously) gathered... it's a cracking work, though.
HOW TO CRACK INFORMATION [WHERE WHAT]
* INTERNET
In the middle of the hugest junk collection of the planet, some
real information can be laboriously gathered if you do learn how
to use well the search engines (or if you do build your ones...
my spiders are doing most of the work for me... get your robots
templates from "Harvest" or "Verify" and start your "spider
building" activity beginning from Martijn Koster's page). As
usual in our society, in the Internet the real point is exactly
the same point you'll have to confront all your life long: HOW
TO THROW AWAY TONS OF JUNK, HOW TO SECLUDE MYRIADS OF USELESS
INFORMATION and HOW TO FISH RARE USEFUL INFORMATION, a very
difficult art to learn per se. Internet offers some information,
though, mainly BECAUSE it's (still) unregulated. You want a
proof? You are reading it.
* SOME (RARE) NEWSPAPERS.
The newspaper of the real enemies, the economic powers that
rule this slaves world, are paradoxically most of the time the
only ones worth studying... somewhere even the real rulers have
to pass each other some bits of real information. The "Neue
Zuercher Zeitung", a newspaper of the Swiss industrials from
Zuerich, is possibly the best "not_conformist trend analyzer"
around that you can easily find (even on the web). These
swissuckers do not give a shit for ideology, nor preconcerted
petty ideas, the only thing they really want is to sell
everywhere their ubiquitous watches and their chocolates... in
order to do it, a land like Switzerland, with very high salaries
and a good (and expensive) social system, must use something
brilliant... they found it: a clear vision of the world... as a
consequence this newspaper is very often "against" the trend of
all the other medias in the world, the ones that are used only
in order to tame the slaves... If the only language you know is
english (poor guy) you could try your luck with the weekly
"Economist"... you'll have to work a lot with it, coz it has been
tailored for the "new riches" of the Tatcher disaster, but you
can (at times) fish something out of it... they do a lot of
idiotic propaganda, but are nevertheless compelled to write some
truth. American newspapers (at least the ones you can get here
in Europe) are absolute shit... one wonders where the hell do the
americans hyde the real information.
On the "non-capitalistic" side of information there is a
spanish newspaper "El Pais" that seems to know about what's going
on in South America, but it's so full of useless propaganda about
irrelevant Spanish politics that it's not really worth reading.
The monthly "Le Monde diplomatique" offers something too... this
one exaggerates a little on the pauperistic "third world" side,
but has a lot of useful information. See what you can do with all
this information (or disinformation?)
[BELIEVE THE COUNTRARY]
Another good rule of thumb in choosing your medias is the
following... if all medias around you assure, for instance, that
"the Serbians are evil"... the only logical consequence is that
the Serbians are not so evil at all and that "the Croats" or some
other Yugoslavian shits are the real culprits. This does not mean
at all that the Serbians are good, I warn you, it means only what
I say: something is surely hidden behind the concerted propaganda
you hear, the best reaction is to exaggerate in the other
direction and believe the few bit of information that do say the
countrary of the trend. This rule of thumb may be puerile, but
it works somehow most of the time... if somewhere everybody
writes that the commies are bad then THERE the commies must not
be so bad at all and, conversely, if everybody in another place
writes that the commies are all good and nice and perfect (like
the Soviet propaganda did) then THERE the commies are surely not
so good... it's a matter of perspective, much depends on where
you are, i.e. whose interests are really at stake. There is NEVER
real information in this society, only propaganda... if you still
do not believe me do yourself a little experiment... just read
the media description of a past event (say the Vietnam war) as
written AT THE MOMENT of the event and (say) as described 10
years later. You'll quickly realize how untrustworthy all
newspapers and medias are.
* SEMIOTICS You'll have to study it (as soon as you can) to
interpret what they let you believe, in order to get your
bearings. A passing knowledge of ancient RHETORIC can help quite
a lot. Rhetoric is the "Softice" debugger you need to read
through the propaganda medias: concentrate on Periphrasis,
Synecdoche, Antonomasia, Emphasis, Litotes and Hyperbole at the
beginning... you'll later crack higher with Annominatio,
Polyptoton, Isocolon and all the other lovely "figurae
sententiae".
Enough, back to software cracking.
HOW A REGISTRATION CODE WORKS [WINCAT]
Let's take as an example for the next crack, a Username-
algebraic registration code, WINCAT Pro, version 3.4., a 1994
shareware program by Mart Heubel. It's a good program, pretty
useful to catalogue the millions of files that you have on all
your cd-roms (and to find them when you need them).
The kind of protection Wincat Pro uses is the most utilized
around: the username string is manipulated with particular
algorithms, and the registration key will be made "ad hoc" and
depends on the name_string. It's a protection incredibly easy to
crack when you learn how the relevant procedures work.
[WINCAT Pro] is a good choice for cracking studies, coz you
can register "over your registration" one thousand times, and you
can herefore try for this crack different user_names to see all
the algebrical correspondences you may need to understand the
protection code.
In this program, when you select the option "register", you
get a window where you can input your name and your registration
number (that's what you would get, emailed, after registering
your copy). If you load winice and do your routinely hwnd to
individuate the nag window, and then breakpoint on the
appropriate memory ranges you'll peep in the working of the whole
bazaar (this is completely useless in order to crack these
schemes, but it'll teach you a lot for higher cracking, so you
better do it also with two or three other programs, even if it
is a little boring): a series of routines act on the input (the
name) of the user: the User_name_string (usn). First of all the
usn_length will be calculated (with a REPNZ SCASB and a following
STOSB). Then various routines store and move in memory the usn
and the registration_number (rn) and their relative lengths. In
order to compare their lengths and to check the correct
alphanumeric correspondence between usn and rn, the program first
uppercases the usn and strips all eventual spaces away.
Here the relevant code (when you see an instruction like
SUB AL,20 you should immediately realize that you are in a
uppercasing routine, which is important for us, since these are
mostly used for password comparisons)... here the relevant Winice
unassemble and my comments:
253F:00000260 AC LODSB <- get the usn chars
253F:00000261 08C0 OR AL,AL <- check if zero
253F:00000263 740F JZ 0274 <- 0: so usn finished
253F:00000265 3C61 CMP AL,61 <- x61 is "a", man
253F:00000267 72F7 JB 0260 <- not a lower, so loop
253F:00000269 3C7A CMP AL,7A <- x7A is "z", what else?
253F:0000026B 77F3 JA 0260 <- not a lower, so loop
253F:0000026D 2C20 SUB AL,20 <- upper it if it's lower
253F:0000026F 8844FF MOV [SI-01],AL<- and hyde it away
253F:00000272 EBEC JMP 0260 <- loop to next char
253F:00000274 93 XCHG AX,BX
...
The instruction MOV [SI-01],AL that you see here is important
at times, coz it points to the location of the "pre-digested"
usn, i.e. the usn formatted as it should be for the number
comparison that will happen later. In some more complicated
protection schemes the reasoning behind this formatting is the
following: "Stupid cracker will never get the relation algorhitm
usn <-> rn, coz he does not know that usn AND rn are slightly
changed before comparing, ah ah... no direct guessing is
possible". Here is only "polishing": you have to "polish" a
string before comparing it in order to concede some mistakes to
the legitimate user (too many spaces in the name, upper-lower
case mismatch, foreign accents in the name etc.) You just need
to know, for now, that this checking is usually still 5 or 6
calls ahead of the real checking (it's what we call a "green
light").
You should in general realize that the real checking of the
algebrical correspondence follows after a whole series of memory
operations, i.e.: cancelling (and erasing) the previous (if ever)
attempts; reduplicating the usn and the rn somewhere else in
memory; double checking the string lengths (and saving all these
values somewhere... be particularly attentive when you meet stack
pointers (for instance [BP+05]): most of the programs you'll find
have been written in C (what else?). C uses the stack (SS:SP) to
pass parameters or to create local variables for his procedures.
The passwords, in particular, are most of the time compared to
data contained within the stack. If inside a protection a BP
register points to the stack you have most of the time fished
something... remember it pupils: it will spare you hours of
useless cracking inside irrelevant routines. Back to our CATWIN:
another little check is about the "minimal" length allowed for
a user name, in our babe, for instance, the usn must have at
least 6 chars:
230F:00003483 3D0600 CMP AX,0006
230F:00003486 730F JAE 3497 <- go to nice_name
:too_short
230F:00003488 BF9245 MOV DI,4592 <- no good: short
After a lot of other winicing you'll finally come across
following section of the code:
2467:00000CA3 B90100 MOV CX,0001
2467:00000CA6 03F1 ADD SI,CX
2467:00000CA8 2BC1 SUB AX,CX
2467:00000CAA 7213 JB 0CBF
2467:00000CAC 40 INC AX
2467:00000CAD 368B4F04 MOV CX,SS:[BX+04] <- here
2467:00000CB1 0BC9 0R CX,CX
2467:00000CB3 7D02 JGE 0CB7
2467:00000CB5 33C9 XOR CX,CX
2467:00000CB7 3BC1 CMP AX,CX
2467:00000CB9 7606 JBE 0CC1
2467:00000CBB 8BC1 MOV AX,CX
2467:00000CBD EB02 JMP 0CC1
2467:00000CBF 33C0 XOR AX,AX
2467:00000CC1 AA STOSB <- and here
2467:00000CC2 8BC8 MOV CX,AX
2467:00000CC4 F3A4 REPZ MOVSB <- and here!
2467:00000CC6 8EDA MOV DS,DX
2467:00000CC8 FC RETF 0008
This is obviously the last part of the checking routine
(I'll not delve here with the mathematical tampering of it, if
you want to check its workings, by all means, go ahead, it's
quite interesting, albeit such study is NOT necessary to crack
these schemes). The important lines are obviously the MOV
CX,SS:[BX+04], the STOSB and the REPZ MOVSB (as usual in password
protection schemes, you do remember lesson 3, don't you?).
You should be enough crack-able :=) by now (if you have read
all the precedent lessons of my tutorial), to find out easily,
with these hints, how the working of the protection goes and
where dwells in memory the ECHO of the correct rn (passkey) that
matches the name you typed in. Remember that in these kind of
cracks the ECHO is present somewhere (90% of the cases). There
are obviously one thousand way to find such ECHOs directly,
without going through the verificayions routines... for instance
you could also find them with a couple of well placed
snap_compares, it's a "5 minutes" cracking, once you get the
working of it. I leave you to find, as interesting exercise, the
routine that checks for a "-" inside the rn, a very common
protection element.
In order to help you understand the working of the protection
code in [Wincat Pro] I'll give you another hint, though: if you
type "+ORC+ORC+ORC" as usn, you'll have to type 38108-37864 as
rn, if you usn as usn "+ORC+ORC" then the relative rn will be
14055-87593. But these are my personal cracks... I have offered
this information only to let you better explore the mathematical
tampering of this specific program... you'll better see the
snapping mechanism trying them out (going through the routines
inside Winice) alternatively with a correct and with a false
password. Do not crack Wincat with my combination! If you use a
different usn than your own name to crack a program you only show
that you are a miserable lamer... no better than the lamers that
believe to "crack" software using huge lists of serial numbers...
that is really software that they have stolen (Yeah: stolen, not
cracked). You should crack your programs, not steal them...
"Warez_kids" and "serial#_aficionados" are only useless zombies.
I bomb them as soon as I spot them. YOU ARE (gonna be) A CRACKER!
It makes a lot of a difference, believe me.
Well, that's it for this lesson, reader. Not all lessons of my
tutorial are on the Web.
You 'll obtain the missing lessons IF AND ONLY IF you mail
me back (via anon.penet.fi) with some tricks of the trade I may
not know that YOU discovered. Mostly I'll actually know them
already, but if they are really new you'll be given full credit,
and even if they are not, should I judge that you "rediscovered"
them with your work, or that you actually did good work on them,
I'll send you the remaining lessons nevertheless. Your
suggestions and critics on the whole crap I wrote are also
welcomed.
"If you give a man a crack he'll be hungry again
tomorrow, but if you teach him how to crack, he'll
never be hungry again"
an526164@anon.penet.fi
<center><h1>HOW TO CRACK, by +ORC, A TUTORIAL
Lesson 9 (1): How to crack Windows, Hands on
[Winformant][Snap32]
THE [DATA_CONSTRAINT] TRICK - [WINFORMANT 4]
I have chosen an older windows application for Win 3.1.
(WIN4MANT.EXE, 562271 bytes, Version 1.10, by Joseph B. Albanese;
you'll find it searching the web with the usual tools, see how
to do it at the end of this lesson), in order to show you how to
use a nice little trick, at times really useful in cracking
password protected programs: [data_constraint]. Inside almost all
protection routines, as you have already learned, there is a
moment when on the stack the ECHO of the real, "correct"
passnumber or password appears. The location of this ECHO varies,
but most of the time it'll be in a range of +- 0x90 bytes from
one of the locations where the user input dwells. This is due to
datadump windows constraints inside the tools used by the
protectionists... but this use is bound to diminish... especially
after this lesson :=)
[WINFORMANT CRACKING]
This application is -per se- crappy, I doubt you'll ever use
it... but its curious (and pretty rare) "deactivate" mode is
nevertheless very interesting for us: you can "unregister"
Winformant on the fly if you feel the need to.
This feature is pretty useful for scholars that like to
investigate password algorithms with valid and invalid codes
without having to reinstall every time to delete a valid code.
For your cracking exercises choose programs that have
"REVERSIBLE" protections (rare) or that can be re-registered a
billion times (more frequent). Programs that keep the valid
registration on *.ini or special files will also do the job: you
just change a couple of lines to "unregister" them.
The trick of this lesson: [data_constraint], or "password
proximity", bases on the protectionist's need to keep an eye on
the protection "working" when he assembles it. He must "see" the
relationships between USER INPUT NUMBER, USER INPUT TRANSFORMED
and the CORRECT NUMBER ANSWER (in our jargon: the "Bingo"). These
relationships must be constantly checked In order to debug the
protection code. Mostly they will dwell TOGETHER inside a small
stack area, allowing them to be "seen" in the SAME watchwindow.
Most of the time, therefore, the "ECHO" will "materialize"
shortly not very far away from one of the locations of the USER
INPUT. Let's crack:
* Fire Winice and then Winformant
* Choose HELP and then choose REGISTRATION
* Fill the registration fields with "+ORC+ORC" as "Registrant"
and "12121212" as "Activation" code (use whatever you fancy).
CTRL+D ;switch to Winice
:task ;let's see what's the name of this crap
TaskName SS:SP StackTop StackBot StackLow TaskDB hQueue Events
WINWORD 1AD7:85F2 4A52 8670 7532 1247 122F 0000
PROGMAN 1737:200A 0936 2070 1392 066F 07F7 0000
DISKOMAT *2C5F:6634 1D3C 6AC6 5192 2CB7 2C9F 0000
:hwnd DISKOMAT ;which window is getting the input?
WinHandle Hqueue QOwner Class Name Window Procedure
0EB4(0) 2C9F DISKOMAT #32769 04A7:9E6B
0F34(1) 2C9F DISKOMAT #32768 USER!BEAR306
365C(1) 2C9F DISKOMAT #32770 2C3F:0BC6
36BC(2) 2C9F DISKOMAT Button 2C3F:1CEA
3710(2) 2C9F DISKOMAT Edit 2C3F:24BE
... and many more irrelevant windows.
Let's pinpoint the code, here the relevant window is the first
"Edit" one, for obvious reasons (more on this later).
:bmsg 3710 wm_gettext ;set breakpoint
CTRL+D ;run the babe until you get:
Break Due to BMSG 3710 WM_GETTEXT C=01
Hwnd=3710 wParam=0050 lParam=2C5F629A msg=000D WM_GETTEXT
2C3F:000024BE B82F2C MOV AX,2C2F
So! Now we have "pinpointed" the babe (more on "pinpointing"
later). Let's snoop around a little: look at the stack to fetch
your babe's last call (if it does not show immediately, just keep
pinpointing, for instance on GetWindowText() or do a BPRW
diskomat (very useful), and then try and retry the stack...
should this too fail to work, search for your input in memory (in
the 30:0 lffffffff selector, as usual) and breakpoint range on
it with ReadWrite, and then stack, stack, stack... until you get
the "real" list of calls coming from your babe's protection.
:stack ; let's see
USER(19) at 073F:124C [?] through 073F:1239
CTL3D(02) at 2C3F:0D53 [?] through 2C3F:0D53
DISKOMAT(01) at 2C97:20B9 [?] through 2C97:20B9
DISKOMAT(01) at 2C97:3D94 [?] through 2C97:3D94
DISKOMAT(01) at 2C97:49E2 [?] through 2C97:4918
DISKOMAT(04) at 2C7F:EA20 [?] through 2C7F:EA20
USER(01) at 04A7:19BE [?] through USER!GETWINDOWTEXT
== CTL3D(02) at 2C3F:24BE [?] through 04A7:3A3Cæ
Beautiful stack fishing! Do immediately a BPX on babe:EA20.
2C7F:EA35 9A25ABA704 CALL USER!GETWINDOWTEXT
2C7F:EA3A 8D46AE LEA AX,[BP-52] ;load ptr "+ORC+ORC"
2C7F:EA3D 16 PUSH SS ;save pointer segment
2C7F:EA3E 50 PUSH AX ;save pointer offset
2C7F:EA3F 9A768D872C CALL 2C87:8D76; get strlen "ORC+ORC"
2C7F:EA44 83C404 ADD SP,+04
2C7F:EA47 3D2800 CMP AX,0028
2C7F:EA4A 762C JBE EA78
...
2C7F:EA97 8D46AE LEA AX,[BP-52] ;load ptr "+ORC+ORC"
2C7F:EA9A 16 PUSH SS ;various algors on input
2C7F:EA9B 50 PUSH AX ;follow here, we do not
... ;need to care
2C7F:EAB2 0F851101 JNE EBC7
2C7F:EAB6 8D8E5CFF LEA CX,[BP+FF5C] ;ptr "12121212"
2C7F:EABA 16 PUSH SS
2C7F:EABB 51 PUSH CX
2C7F:EABC 9A768D872C CALL 2C87:8D76 ;get strlen "12121212"
2C7F:EAC1 83C404 ADD SP,+04
2C7F:EAC4 50 PUSH AX
2C7F:EAC5 8D865CFF LEA AX,[BP+FF5C] ;ptr "12121212" HERE!
2C7F:EAC9 16 PUSH SS
2C7F:EACA 50 PUSH AX
...etc, various algors on input follow here
OK, it's enough: now obviously follows the code that
"algorithmize" the number string, and then, somewhere, you'll
have the hideous compare that divides good guys and bad crackers.
You could examine, and crack, and search...
BUT NOW IT'S THE "MAGIC MOMENT" OF THE ECHO! We know and *feel*
it: The echo must be somewhere... how do we find it? Searching
"12121212" in memory fishes at least 10 different locations...
:s 30:0 lffffffff '12121212'
Pattern Found at 0030:0005AD6A
.... (7 more)
Pattern Found at 0030:80509D6A
Pattern Found at 0030:8145AD6A
Should we look for all occurrences of string '12121212',
starting with the two at 80000000, dumping +-0x90 around it...
until we find the echo? We could, and it would work, but that's
not zen... that's boring! In other protections these locations
could proliferate on purpose, to deter the casual cracker. There
must be some other way... And lo and behold! YES! There is a
quicker way... THE LAST loading of the numeric input string in
the code (the one after the strlen count) is the "right" one for
our cracking purposes, coz protections follow (mostly) this
pattern (remember: we are inside a "stack-heavy" section of the
code... if you want to crack higher I suggest you read some good
literature about stack working, stack tricks and stack magics
with the Intel processors):
LOAD NAMEString - COUNT NAMEStringLen
LOAD NAMEString - TRANSFORM NAMEString
LOAD CODEString - COUNT CODEStringLen
LOAD CODEString
*ECHO must be here*
TRANSFORM CODEString
*ECHO must be here*
COMPARE TRANSFORMED_NAMEString WITH TRANSFORMED_CODEString
This means that at line
2C7F:EAC5 8D865CFF LEA AX,[BP+FF5C] ;ptr "12121212"
you'll already have your echo somewhere... just dump the memory
around the pointer [BP+FF5C]:
:d 2c5f:61e8 ;these numbers will differ in your computer
02 62 2F 06 02 00 26 2E-A3 4E A3 4E 01 00 38 30 .b/...&..N.N..80
33 37 2D 36 34 36 2D 33-38 33 36 00 01 06 02 00 37-646-3836.....
2F 06 75 62 C3 2E B7 04-F2 24 2F 06 CE 6E 2F 06 /.ub.....$/..n/.
49 00 5A 00 01 00-04 2C 2F 06 AE 24 36 62 00 00 I.Z......,/..$6b
74 62 7A 2E B7 04 36 62-01 00 C2 62 2F 2C 26 2E tbz...6b...b/,&.
03 01 BA 0F AE 24 5F 02-C9 01 5E 02 BA 01 5F 02 .....$_...^..._.
31 32 31 32 31 32 31 32-00 0C 00 BC 02 00 00 00 12121212........
00 49 00 BA 0F-AE 24 F2 24 2F 06 00 00 00 00 00 ....I....$.$/...
AF 17 00 E2 5F-7A 62 FE FF 79 1B BA 0F 00 00 00 ......._zb..y...
96 0B 01 00 02 4E 00-37 01 8A 62 D2 0F 8F 17 00 .....N..7..b....
2F 06 00 37 01-98 62 20 10 16 03 2F 06 00 00 00 /.....7..b .../.
C2 62 2B 4F 52 43 2B 4F-52 43 00 0D AE 24 2F 06 .b+ORC+ORC......
Look at this dump: everybody is there! The stack pointers points
in the middle, at string "12121212". 0x50 bytes before it you'll
find our good old ECHO (i.e. the CORRECT passnumber) and 0x50
bytes afterwards you'll see your handle: here "+ORC+ORC".
It's cracked! The code for my "+ORC+ORC" is 8037-646-3836...
Now begin your assignments: if you rally want to learn cracking:
- "Unregister" and find anew your own code for your own
handle. *DO NOT* use serial numbers with any other name
that your own handle, that's miserable stealing, not
cracking. I'll begin to punish the serial#_aficionados on
the Web, coz I like real outlaws, but I detest stupid
pickpockets.
- Study the two coding algorithms, the one for the input name
and the one for the input number, this will be very useful
for your future cracking sessions.
- Find the "Compare", i.e. the code that sets the two usual
flags "good guy, you may move on" and "bad cracker, beggar
off", and
- Create a "real" crack for this protection, that will allow
anybody you think deserves it, with any name and any
password number, to get through.
[CRACKING SNAP 32]
Snap 32 (SNAP32.EXE 356.352 bytes, 24/11/95, Version 2.54,
by Greg Kochaniak) is a "snapshot" shareware program for Windows
95, that allows users to save the screen, parts of it, or a
single window. It's a very common 'try before you buy' program,
limited to 30 days use. You'll find it everywhere on the Web. If
you do not know how to search the Web (poor guy!), learn at the
end of this lesson the correct procedure to find all the files
you need on the Net and get them automatically emailed to you
(that's something you should learn: SEARCHING! It's even more
important than cracking!).
Snap32 is not very interesting (I don't think I used it more
than a couple of times), but its protection is: in order to (try
to) deter casual crackers it does not compare strings, it
compares a "magic" sum (from Namestring) with another magic sum
(from Numberstring). And:
* SUMS magics inside the GDI, not inside its own code;
* USES a look_up table for input validation instead of
"plain" code;
* COMPARES the "magic" manipulation from input NUMBER with
the "magic" manipulation from input NAME.
The cracking procedure for most of these windows programs is
pretty simple and relatively straightforward:
1) SEE THE NAME OF YOUR BABE AND ITS QUEUE SELECTOR
:task ;This is the Winice95 command you type after firing
snap32 and getting at the "Enter License" nag window:
TaskName SS:SP StckTp StckBt StckLw TaskDB Hqueue Events
Snap32 0000:0000 006 AC000 006B0000 270E D27 0000
OK, the babe is Snap32,it's HQUEUE is 0xD27, it's TaskDB is
0x27OE, orright.
2) SEE THE MODULES OF YOUR BABE:
:map32 snap32 ;Your command
Owner Obj Name Obj# Address Size Type
SNAP32 .text 0001 0137:00401000 00043000 CODE RO
SNAP32 .rdata 0002 013F:00444000 00002E00 IDATA RO
SNAP32 .data 0003 013F:00447000 00009000 IDATA RW
SNAP32 .idata 0004 013F:00471000 00001C00 IDATA RW
SNAP32 .rsrc 0005 013F:00473000 00001600 IDATA RO
SNAP32 .reloc 0006 013F:00475000 00004C00 IDATA RO
OK, so the code is in selector 137:(as usual), and you have there
43000 bytes of code from 401000 to 401000+43000; the DATA,
ReadWrite and ReadOnly, are in selector 13F: (as usual).
3) SEE THE HANDLE OF THE PROTECTION "NAG" WINDOW
:hwnd snap32 ;Your command
Window Handle Hqueue SZ Qowner Class Name Window Procedure
0350(1) 0D27 32 SNAP32 #02071 144F:0560
0354(2) 0D27 32 SNAP32 #02071 17CF:102E
... and many more windows that we do not care of.
OK, so, for our cracking purposes, it's Handle 0x350. Most of
the times the "nag" window you want to crack will be the first
one in the hwnd listing (coz it was the last one to appear).
Watch the number in parentheses that follows the Whandle: (1) is
a mother, (2) are "children" windows. At times you'll find under
"Class Name" something like "Edit" (see before the Winformant
cracking)... SNIFF THERE! At times the "Window Procedure" code
location in a list of more than twenty, will be slightly
different for one or two windows... SNIFF THERE!
4) BREAKPOINT MESSAGE WM_GETTEXT (or any other WM_ that you can
think of in order to "pinpoint" the code of our babe).
"Pinpointing" the code is extremely important in windows
cracking... this idiotic OS moves code, data and stack out and
inside the pages all the time... so you'll keep getting on
"INVALID" sections without a correct pinpointing. Good
Pinpointing points are in general:
BMSG xxxx WM_GETTEXT (good for passwords)
BMSG xxxx WM_COMMAND (good fro OK buttons)
BPRW *your babe* TW (good for tracking)
u USER!GETWINDOWTEXT (u and then BPX inside the code)
u GETDLGITEM (for the Hwnd of an Item inside a
Dialog Box)
CSIP NOT GDI (if you have too many interferences)
u USER!SHOWWINDOW (bpx with counter occurrence to get to
the "right" window)
u GETSYSTEMTIME (for "time-crippled" software)
and many others pinpointing points you'll learn. If you are
really desperate for pinpointing, just do a BMSG xxxx WM_MOVE and
then move the nag window, this will always work. Let's go on:
:bmsg 350 wm_gettext ;Your command
OK, so the code is ready to be pinpointed.
5)RUN THE PROGRAM TO THE BREAKPOINT:
CTRL+D ;Your command to exit Winice and run
until it pops out at breakpoint
OK, now you pop out inside Winice somewhere... (look at the stack
to know where) so the code has been pinpointed.
6) SEARCH THE DATA AREA for your input string (4 Gigabytes from
30:0... remember that DATA are *always* in 30:0 to 30:FFFFFFFF
and CODE is *always* in 28:0 to 28:FFFFFFFF). In most protection
the "registration_number" string must match the "username"
string, which cannot be constrained, in order to allow users to
choose whatever stupid name they fancy. Some protections requires
fixed symbols inside the "username" string, though... in these
rare eventualities, just apply to the "username" string what
we'll do here with the "registration_number" string. The point
to remember is: begin always with the protection fumbling your
number, crack only if necessary the protection that fumbles your
name. Let's search now.
:s 30:0 lffffffff '12121212' ;Your command
Pattern Found at 0030:80308612
80000000 is good. Lower era videos, mirrors and BIOS, higher
(around C0000000) you have the OS dustbins... the point to
remember is: investigate always FIRST the 80000000 locations.
7) BREAKPOINT ON MEMORY RANGE ON THIS STRING.
By the way: prepare a watch window dex 3 es:di, you'll soon see
how useful such an automated watchwindow is in password cracking.
:bpr 30:80308612 30:80308612+8 RW ;Your command
OK Now we'll begin to dig out the relevant parts of the code.
Remember that you must breakpoint *every* copy of the string that
protection generates. A typical copy routine, very frequently
used in windows copy protection schemes, dwells inside
KERNEL!HMEMCPY (+0076):
0117:9E8E 66C1E902 SHR ECX,02
0117:9E92 F36766A5 REPZ MOVSD ;makes a copy in es:di
0117:9E96 6659 POP ECX
0117:9E98 6683E103 AND ECX,+03
0117:9E9C F367A4 REPZ MOVSB
0117:9E9F 33D2 XOR DX,DX
In fact, this piece of copying code is so often used for password
verifications that sometimes you just need to bpx on 0117:9E92
to get the correct stack sequence... but let's, for now, continue
without such little tricks: just keep on BPRring (Breakpoint on
memory range) all copies that protection makes.
8) LET THE BABE RUN, it will breakpoint on all manipulations of
your input string. One of them will lead to the magic.
8.1.) VALIDATION phase
There are many routines that check and "validate" your inputs.
The most common ones check that your numbers ARE really numbers,
i.e. in the range 0x30-0x39. Usually this is done with:
CMP EAX,+30
JB no_number
CMP EAX,+39
JA no_number
At times the protectionists use TABLES instead... The number
itself is used as a pointer to a "ready made" table where the
relevant magic can be used as a protection. Imagine that a number
4 in your input points to a code section that throws you
immediately outside the validation routine... or imagine that a
number 7, if found in your input, fetches a magic code that
removes the whole program from your harddisk (or worse): "Ah, ah!
Stupid cracker will never know that he should not have used
number 4... and definitely not number 7! Next time he'll
learn..." Yes, tables have been used for such nasty tricks.
Here the relevant code for the "validation" part of our
protection (still checking my favourite input string '12121212'):
:check_if_valid
0137:4364AE 8A16 MOV DL,[ESI] ;load license number
0137:4364B0 33C0 XOR EAX,EAX ;zero AX
0137:4364B2 668B0451 MOV AX,[ECX+2*EDX] ;look table for 84
0137:4364B6 83E008 AND EAX,+08 ;OK if AND'S TO zero
0137:4364B9 85C0 TEST EAX,EAX ;and therefore
0137:4364BB 7403 JZ 004364C0 ;go on
0137:4364BD 46 INC ESI ; ready for next number
0137:4364BE EBCD JMP 0043648D
:strip_-_&_+_signs
0137:4364C0 33DB XOR EBX,EBX ;clean BX
0137:4364C2 8A1E MOV BL,[ESI] ;load license number
0137:4364C4 46 INC ESI ;ready for next
0137:4364C5 8BFB MOV EDI,EBX ;save copy
0137:4364C7 83FB2D CMP EBX,+2D ;is it a "-"?
0137:4364CA 7405 JZ 004364D1
0137:4364CC 83FB2B CMP EBX,+2B ;is it a "+"?
8.2.) MANIPULATION (summing magic numbers)
Your wisely set breakpoints on memory range for the occurrence
of the string "12121212" will pop you out, inter alia, inside
following piece of code (note how this part of protection dwells
inside GDI, and NOT inside the code selector of snap32):
0557:11BD 33C0 XOR EAX,EAX ;zero AX
0557:11BF 66648B06 MOV AX,FS:[ESI] ;load number
0557:11C3 83C602 ADD ESI,+02 ;point to next
0557:11C6 66833C4700 CMP WORD PTR [EDI+2*EAX],+00
0557:11CB 0F8424010000 JE 000012F5
0557:11D1 668B0442 MOV AX,[EDX+2*EAX] ;load from magic table
0557:11D5 03D8 ADD EBX,EAX ;save sum in EBX
0557:11D7 49 DEC ECX ;till we are done
0557:11D8 75E5 JNZ 000011BF ;loop along
Interesting, isn't it? Protection is using this GDI routine to
create a SUM (through pointers to another table) that depends on
your very input numbers. We are now very near to the crack... can
you *feel* it? If not, prepare yourself a good Martini Vodka!
This is the correct way to do it:
* Get a "highball" glass;
* Put some ice cubes inside it (2 or 3);
* Add Martini Dry (From Martini & Rossi). Fill to 1/3;
* Add Moskowskaja Wodka (the only real Vodka). Fill to 2/3;
* Add a zest of lemon (From Malta or Southern France);
* Add a green "sound" olive (from Italy or Israel);
* Add Schweppes Indian Tonic. Fill to the brim.
Sit deeper and relax, sip slowly and *feel* where the code of the
protection scheme you are cracking "moves"... It's like a
current... a slow tide. If you still do not believe me, just try
it.
We'll now find out where protection stores the "magic" sum (and
now you'll pop out inside the very own snap32 code, this is the
"real" protection part):
8.3.) The ludicrous "HIDING" of the magic sum
0137:40437E 83C404 ADD ESP,+04
0137:404381 8B4DE8 MOV ECX,[EBP-18]
0137:404384 8945F0 MOV [EBP-10],EAX ;***HERE!***
0137:404387 68FF000000 PUSH 000000FF
0137:40438C 8D8574FBFFFF LEA EAX,[EBP+FFFFFB74] ;load string
0137:404392 50 PUSH EAX ;push it
0137:404393 E886410100 CALL 0041851E ;manipulate
0137:404398 8D8574FBFFFF LEA EAX,[EBP+FFFFFB74] ;load string
0137:40439E 50 PUSH EAX ;push it
0137:40439F E88C210300 CALL 00436530 ;manipulate
As you can see, the protection is very simple: The "magic" sum
is hidden only two lines before the further manipulations of the
input string. We have found location 137:404384, here, in the
CORRECT way, through bprring of the string that has been
manipulated in the GDI, but actually, we could have found it
quickly just checking superficially what's happening "around" all
manipulations of the input string. Do we really need to follow
all manipulations of our registration_number and eventually also
all manipulation of our username? NO, not at all: we just set a
BPR on the stack location where protection hides the sum [EBP-10]
and we'll see what happens: 90% of these protections just create
two sums, a sum from your username and a sum from your
registration_number... somewhere there will be a compare that
must use this location (or a copy of it... we'll see).
8.4.) COMPARING THE MAGICS FROM THE TWO INPUT STRING
Breakpoint on memory range on the sum location [EBP-10] that you
saw in the previous code and you'll land at this piece of code:
0137:404412 E82F050000 CALL 00404946
0137:404417 83C40C ADD ESP,+0C
0137:40441A 3B45F0 CMP EAX,[EBP-10] ;comp AX & magicsum
0137:40441D 740F JZ 0040442E
0137:40441F 68C0874400 PUSH 004487C0
0137:404424 E8149E0000 CALL 0040E23D
0137:404429 83C404 ADD ESP,+04
0137:40442C EB5B JMP 00404489
0137:40442E 893DA0714400 MOV [004471A0],EDI
0137:404434 85FF TEST EDI,EDI
That's it, you have made it! We found the compare between the
"username" magic number (for my "+ORC+ORC" string that's here
0x7C25621B) in AX (we do not need to know how this landed
there... it's irrelevant!) and the "license_number" '12121212'
(whose magic is here 0x00B8F47C) stored in [pointer-10.] How do
we find now the correct INPUT number for +ORC+ORC? Well, it's
easy... the "magic number" must be the same... therefore:
Cracked=Dec(0x7C25621B)
Cracked=2082824731
That was it. Old Snap32 has been cracked. You could now
prepare a crack in order to distribute this program around
without its simple protection. Good cracked applications should
be given free (i.e. cracked) to all the people that NEED them and
do not have the money to buy them. Don't forget that in this
intolerable society the 0,5% of the citizens own the 56% of the
industrial capital and the 63% of the propaganda machines (data
from US researchers... therefore suspect... the real situation
is probably even worser) effectively conditioning the destiny of
millions of slaves, moronized by television watching. So crack
the applications and give them to the people you care and the
peolple that need them, but for the others... just EXPLAIN
everybody how you did it... this is real help: giving knowledge,
not wares. DO NOT use my handle and my codes to crack this
program, get yours, I gave you mine only as an help for this
cracking lesson. I have showed you the way enough... THIEFS, not
crackers, use the codes that others have found. You are (gonna
be) CRACKERS! Remember it, look straight ahead, crack accurately
and keep your tommy in.
HOW TO SEARCH THE INTERNET FOR FILES WITHOUT MOVING A FINGER
It's amazing: most of the people roaming around inside Internet
DO NOT know how to use effectively the web. I'll be very
altruistic and explain how to fetch the very example of Snap32,
the babe we cracked in this lesson.
1) Choose an archie from this list (I will not explain you what
an archie is, you should know it... if you do not, be ashamed):
archie.univie.ac.at 131.130.1.23 Austria
archie.belnet.be 193.190.248.18 Belgium
archie.funet.fi 128.214.6.102 Finland
archie.univ-rennes1.fr 129.20.254.2 France
archie.th-darmstadt.de 130.83.22.1 Germany
archie.ac.il 132.65.16.8 Israel
archie.unipi.it 131.114.21.10 Italy
archie.uninett.no 128.39.2.20 Norway
2) Email a message to your archie:
To: archie.univie.ac.at (for instance)
Subject: (nothing on this field)
Body: set search sub (substrings too)
set maxhits 140 (max 140 hits)
set maxhitspm 9 (not the same file all over)
find snap32 (we want this)
3) After a while you'll get (per email) your answer: Here the
answer from the Austrian archie
Host ftp.wu-wien.ac.at (137.208.8.6)
Last updated 17:48 9 Aug 1995
Location: /pub/systems/windows.32/misc
FILE -rw-r----- 128957 bytes 15:59 16 Jun 1995 snap32.zip
Host space.mit.edu (18.75.0.10)
Last updated 00:45 4 Mar 1996
Location: /pub/mydir
FILE -rw-r--r-- 407040 bytes 11:55 28 Nov 1995 snap32.exe
4) ftpmail your file (Browsing is no good: too busy and lame).
Again, I will not explain you what an FTPMAIL server is: learn
it by yourself... choose a good one from this list (there are
many more... you'll learn):
bitftp@vm.gmd.de (Germany)
ftpmail@ieunet.ie (Ireland)
bitftp@plearn.edu.pl (Poland)
ftpmail@ftp.sun.ac.za (South Africa)
ftpmail@ftp.sunet.se (Sweden)
ftpmail@ftp.luth.se (Sweden)
ftpmail@src.doc.ic.ac.uk (United Kingdom)
To: ftpmail@ftp.sun.ac.za. (for instance)
Subject: (leave blank)
Body: open space.mit.edu (the last occurrence that
the archie sent)
cd/pub/mydir (get the correct subdir)
bin (prepare for BINARY)
get snap32.exe (I want this)
quit (bye)
5) Your FTPMAIL server will first notice you a receipt:
FTP EMAIL response...
ftpmail has received the following job from you:
reply-to +ORC
open space.mit.edu +ORC@now.here
get snap32.exe
ftpmail has queued your job as: 1834131821.5514
Your priority is 1 (0 = highest, 9 = lowest)
Requests to sunsite.doc.ic.ac.uk will be done before other jobs.
There are 14 jobs ahead of this one in the queue.
4 ftpmail handlers available.
To remove send a message to ftpmail containing just:
delete 1834131821.5514
After a while you'll get a second message, with your file
uuencoded inside... everything has been done.
YESSIR! there is absolutely no need to loose time on the WWW,
"surfing" idiotically from a junk site to the next or waiting
hours to download some slow file from an instable server! Wasting
time of your own LIFE, that you could use to read poetry, to make
love, to look at the stars, to sail slowly between the Aegean
islands or to start a nice cracking session. What's the point of
wasting your time when machines can perform all the searches you
need better, more productively and faster than you ever could...
YESSIR! You can get *everything* on the Web, and without paying
your Internet provider more than a couple of dimes... Nice, isn't
it?
By now, if you have followed all my lessons, you should be able
to crack relatively quickly "normal" applications. There are some
new projects for 1997: a cracking "university", that will allow
us to prepare for the divine war against Microsoft repulsive
dominion. If you do not have already chosen your handle (your
"cracker" name, that's it), you may consider choosing an handle
with a "+" somewhere inside it or, eventually, add a "+" to your
handle. This sign is used by me and by friends that have studied
and/or contributed. But a "+" in your handle ("official +ORC
cracker") will mean even more:
1) allows support from me personally (on a "do ut des" basis)
2) allows pupils to identify each other (good for joining
forces)
3) will open you (eventually) the doors to the "higher"
cracking university I'll set up on the Web in 1997.
(I'm not getting megalomaniac... In reality I only need a "quick"
method to know on which (anonymous) people I can count on for the
next phase).
Well, that's it for this lesson, reader. Not all lessons of my
tutorial are on the Web.
You 'll obtain the missing lessons IF AND ONLY IF you mail
me back (via anon.penet.fi) with some tricks of the trade I may
not know that YOU discovered. Mostly I'll actually know them
already, but if they are really new you'll be given full credit,
and even if they are not, should I judge that you "rediscovered"
them with your work, or that you actually did good work on them,
I'll send you the remaining lessons nevertheless. Your
suggestions and critics on the whole crap I wrote are also
welcomed.
+ORC an526164@anon.penet.fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment