Created
December 18, 2018 00:13
-
-
Save callowaysutton/48bdf0245e17e72d41a15f9beee2e447 to your computer and use it in GitHub Desktop.
Introduction to Hacking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
[email protected], 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 [email protected], 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 [email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 [email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 [email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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ø 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ø 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 [email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | |
[email protected] (+ORC) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 [email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | |
[email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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): | |
[email protected] (Germany) | |
[email protected] (Ireland) | |
[email protected] (Poland) | |
[email protected] (South Africa) | |
[email protected] (Sweden) | |
[email protected] (Sweden) | |
[email protected] (United Kingdom) | |
To: [email protected]. (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 [email protected] | |
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 [email protected] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment