How To Crack
How To Crack
--------------------------------------------------------------
---------------------------------------------------------------------------
Lesson 1: an approach
---------------------------------------------------------------------------
[Pooldemo.exe]
--------------------------------------
In this way you 'll quickly grasp the base techniques of the
has not been a one way road... strictly speaking it's not even
but most of the time you 'll unearth only various trite
So I'll begin the "hands on" part (-> starting from lesson
defeat this kind of junk too. I'll also explain WHERE you can
maybe you have tried it with mixed success. If you are here to
get aimed in the right direction, to get off to a good start with
the cracking tricks and procedures, then you have come for the
right reason. I can't promise you'll get what you want, but I'll
on the elementary side for you. (If you want to review a few
basics and have no where else pressing to go, then by all means
stay).
* Some intuition
(easy to crack)
crippled on
release you 'll get all the copies that remain unsold for next
them, to use them for ever and ever and/or graciously donate them
on the Web to the poor lamers that have no money and no brain.
too).
schemes that you find in a simple (and short) shareware game will
-I hope- the dos and donts of our art: let's crack together as
time (i.e. "how many times" you use them or "how long" you use
by East Point Software Ltd, (c) Team 17 Software Ltd 1994. This
throughout 1995.
crippled on how long you use it: i.e., you can only play 2
minutes, afterwards a "nag" reminder of where and how you can buy
- start [pooldemo.exe]
vectors)
(you should always check MORE THAN ONCE your findings when
memory areas.
- snap_compare just before and just after the time limit and
interpretate, evaluate.
Sucker user has lost one second more of his precious two minutes.
further on for the exact point where you get the "nag screen" in
think you got it already and you remember anyway that the first
Here you believe that you have already found the way: you
got the counter that charges the reverse clock that triggers the
to "EE" (Yeah, the maximum would be FF... but it's always good
get four times more playtime for your game... more than enough
the trade" section) but you could also work with simpler
debuggers like [debug] or [symdeb] (-> see lesson 2). If you do,
i.e.:
symdeb POOLDEMO.DED
corresponds to the
refill line).
cs:3EEA
-e cs:3E85+4 EE
-w
Now you run your tampered pooldemo. You think you cracked it, you
Well, for a start you have not been attentive enough! The
search in debug gave you TWO locations, you moron, and not just
the one you just tampered with. Check and you 'll see that the
locations do mirror the first ones and correct them on the fly
if need be.
So you need to modify this too... you act as said above but
-e cs:3EEA+4 EE
before writing back the dead file and then renaming it to exe and
then running it... and loo! Hoow sloow! THERE YOU ARE! Your
that you can now play the stupid game up to 12 minutes real time,
So you begin to play, and the seconds look veeery sloow, and
everything seems OK, but -alas- NO! At screen second 28 you get
the irritating "two minutes are over" nag screen! Obviously you
were dead wrong: the program "knows" the time directly from the
So it's back to cracking, and now you are angry, and forget
the quiet ways of the zen-analyze and begin the heavy cracking
you should reserve -if ever- for really complicated schemes. You
now start to check the hooked vectors (you did your routinely
believe interesting:
vecs c
first hooked vector does it! It's good old interrupt_08: the
timer_clicker!
(Interrupt Service Routine) that the INT_08 points to... and this
to 1EFD:84C6.
One of the actions taken by the INT_08 ISR within the BIOS
every ISR from INT_08 the CPU would fetch the contents of the
address F000:9876 but can contain any trick they could think of).
now?
to
* prompt $t and hit ENTER a few times, see how the dos_clock
* enter DEBUG.COM
-a
in al,21
or al,1
out 21,al
ret
RETURN
-q
into AL, you set the mask bit in the bit 0 position (which
register.
When you are ready to activate IRQ_0 events again, reenter DEBUG,
run the following and then reset the clock you stopped with DOS
TIME command:
-a
in al,21
and al,fe
out 21,al
ret
RETURN twice
- g 100
-q
will not operate correctly: once you access the diskette drive,
-------------------------------------------------------
address at 20h (or 0a0h), from which the instructions are given.
the EoI command (20h) is written to either port 20h or port 0a0h.
After the EoI follow the usual pushes, then some CALLS then
a call that issues some OUT 40,AL that look like timer refreshing
CALL, one more conditional CALL and then a "mysterious" call FAR
final CALL... then the routine pops all registers and irets away.
find the one that's only called at the awakening of the time
limit protection).
You work, and work, and work... and eventually find nothing
the range DS:0 DS:FFFF you 'll notice that one of them changes
How long will it tick along? Well, we saw above that the "charge"
CS:0A90 7C07
JL okay_play_a_little_more
CS:0A92 E834FD
CALL beggar_off_time_is_up
BINGO!: FOUND!
------------------------------------------------
symdeb pooldemo.ded
- s cs:0 Lffff 81 3E 20 A7 20 1C
xxxx:yyyy
- w
- q
-------------------------------------------------
as you will see in the hands on part, there are always MANY ways
have found this protection the other way round: set a trace on
memory range for the program, restricting the trace to the first
can always try the other blocks). Breakpoint at the nag screen,
...
JL 0A99
...
JL 0A99
...
...
JL 0A99
... there it is, found the other way round. (But this apparently
and nag screen, therefore the somehow more complicated, but more
are seldom difficult to find (and those that are really worth
understand our zen ways, and do not care at all for a well done
job. That means, among other things, that the hard disk of the
user will be cluttered with files that the main program module
This was in reality no less than the complete beta version of the
You 'll obtain the missing lessons IF AND ONLY IF you mail
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,
welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
[INDY.EXE]
--------------------------------------
important.
tells you where all the device drivers and TSR are loaded, in
which memory locations the program you are cracking dwells, how
much memory is left and what the next program load point is. The
unfamiliar program. This will help you by ensuring that you don't
DE SOIREE and its vastly available on the Web). You could also
are now on the Web for free... learn how to use YAHOO and find
them. In emergency cases you could fix some quick crack using
older debuggers won't do. I'll nevertheless ALWAYS give the final
to crack programs.
provided that you are fairly familiar with the protection scheme
used, going in too deep too soon can be a problem when you don't
it. The debugger it's your best weapon, you must know all the
possibility.
when you are close to the protection scheme, but too much of it
are appalling) and ask yourself: "What is this going to tell me?"
and "What else will I need to know once the break occurs?". MOST
and most direct?", coz you do not want to waste precious cracking
time.
how "a trail of bread crumbs" can be left. Not allowing for an
cracking session.
specific cracking.
one function, you must understand what happens within each of the
child functions you must study their children; and so on down the
luck.
For each memory variable you are interested in, you must survey
task a lot easier. (Use Sourcer! It's a fairly good tool and
directly from the functions which need them. But when a program
calls from the same location, you know that this is certainly the
case.
calls from the same location but for one or two calls which are
coming out of the section where the morons have "hidden" their
cracking are made from common library functions, all is not lost.
The specific function from which these library calls were made,
order, you should find yourself in the function you need to see.
ASCIIZ IN CODE
message strings from separate files, your search has just been
simplified.
specific message on the screen, you could go into the program and
locate the code that emits this message, and then determine what
console.
know the screen location used, and if that part of video memory
is not used for anything else at the time (a big if), a memory
the address of the message string and then survey the reminder
searching for such things in a listing will make you old before
your time.
for interrupt calls that are followed by data. Sometimes you will
sense. Sometimes you can determine the offset of the next true
cases, you will have to trace through the interrupt call to see
HOOKED VECTORS
the program under a debugger and watch for system calls to INT_21
vector), but in the event that the program reads and writes
utility.
(easy to remember, isn't it?) and there are four bytes per
four times and use the result at the offset (on segment zero).
INT_63 is 63h*4=18ch
-> 0000:018C
trigger. But when you isolate the offending instruction, you find
the following:
now all you have to do is to add this value to the offset value
And the other way round? If you have a physical address, say
first of all decide in which segment you want the address... if,
16CC
-> 16CC0
Before starting this section, for those of you that do not know
anything, here is the ARCHIE way you get all the program that do
1) (address) archie@archie.univ-rennes1.fr
I use this french archie, but you can get a worldwide list using
2) (text)
<- (100-1000)
find stepdos
Wait two hours, get your post and ftp the file you wanted (and
YES!, you 'll find also EVERYTHING else for free on the Web).
You could, instead of using archie, also learn how to use YAHOO.
[MEMSCAN.EXE]
code areas, available RAM, etc. I used this great idea to create
[TRACKMEM.COM]
[SCANCODE.COM]
software. The must utility for crackers that do not learn all
scancodes by heart.
[MAP.EXE]
too, coz you get it with the "Nigel" nag screens. They are not
[SPRAY.COM]
should study the program, only 252 bytes long, and will have to
[VEXE.EXE]
useful.
the best one, and comes with source code(!). I'll teach you how
to crack without any of them (you do not need them if you zen-
purposes :=)
[SOURCERING UTILITIES]
fairly good sourcering tool. Version 4.08 has been cracked (it's
Web, so you should easily find it. This said, you should NEVER
use such a brute force approach, unless you are really desperate:
I'll teach you how to crack without sourcering (you don't need
[HEXEDITORS]
Every idiot has written at least one hexeditor, and you can find
programs). If you do use it (as you should) disapt the nag screen
[DEBUGGER]
cracked and/or distributed and are now on the Web for free...
learn how to use ARCHIE and YAHOO in order to find them. Your
debugger is the only tool you 'll REALLY need, believe me. So
choose your weapon wisely and learn how to use backtrace ranges
You should get all the programs mentioned above (all the
programs that EXIST for that matter) for free on the Web. Use
them, but also modify them recklessly! REMEMBER THAT YOU ARE
(GOING TO BE) A CRACKER! The first programs you should crack and
modify are therefore your very tools! So steal the code of the
best tools you find! Snatch the best routines and change them for
you know what I'm talking about, but -unless you are already
for the reasons explained in lesson 1, but you 'll find the SAME
pretty easily. The nag screen asks for data based on the
- disable it.
the time fairly effective, but there is a better way: the "zen
way", the only one that can really enable you to crack high
protection schemes.
bytes BEFORE and 500 bytes AFTER your position. You'll get some
locations. (In the case of INDY 500 you get 6 such locations).
8BBF28A5
:compare_loop
AC
LODSB
2A25 SUB AH,[DI] <-- sub coded data from mask and get
real answer
47
INC DI
0AC0 OR AL,AL
59
POP CX
...
And if the protection scheme had been more far away? And if you
cannot "feel" the right one? And if my grandma had wheels? You'll
------------------------------------------------
symdeb indy.ded
- s (cs+0000):0 Lffff B4 FF 2A 25 47 3A C4 75 1A
xxxx:yyyy
- s (cs+1000):0 Lffff B4 FF 2A 25 47 3A C4 75 1A
- w
- q
-------------------------------------------------
WHY WE CRACK
much for money and -as you can see- I am giving away the basis
of what I know for free with this tutorial. The programs we crack
money, he does not deserve anything. It's the mind challenge that
counts, NEVER the profit! (Even if you can make good use of the
personal profit).
information, data that you would like to snoop but that somebody
its awfully egoistic way of life and its dirty "profit" values,
but you'll never be able to crack in the "right" way. You must
coz in order to be emphatic with the code you must be free from
you better take a good look around you... you'll find plenty of
crackle programs in the right way... Hope all this did not sound
too cretin.
You 'll obtain the missing lessons IF AND ONLY IF you mail
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,
welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
--------------------------------------
invoked it.
you cannot write MOV AX,x21, and then INT AX; you must
instructions which look harmless and modifying them "on the fly"
language" code. You can find a lot of good, well explained code
for free: viruses are one of the best sources for good "tight and
tricky" assembler code. You can find the source code of almost
all viruses on the web: oddly all the would be hackers seem to
it out and study it: the more you know, the better you crack.
The string instructions are quite powerful (and play a great role
that:
ES:DI
repeated.
JZ ero
JNZ ero
JA bove
JL ess
JB elow
JC arry
aesthetic choice
(or BBS & servers) although inside files that are small enough
That's obviously not a very big protection -per se- coz everybody
to motivate our cracks and -besides- you'll find the same schemes
requires a word that the user can find somewhere inside the
---------------------------------------------------
by Dr Ezra SIDRAN
European Union:
Rainbird Software
United States:
Firebird Software
---------------------------------------------------
schemes used to day (January 1996) are directly derived from one
of the 12 primitives.
asking your answer, only the use of CTRL+C will bring you out of
newer schemes let you in for only 3 attempts or even only one,
first of all, to find out where are stored the letters that you
type in. So examine your memory map, find out where the program
vecs 34-3D
vec 3E
is hooked at xxxx:00CA
search for some words used in the nag_screen and then let's dump
the area where we find them (in UMS that will be at 3E_hook
address + 7656) and loo! You'll see the content of the nag screen
(that's a very old protection scheme indeed). You could now, for
for server and BBS, for that matter) have quite a lot of weak
points. The most obvious one (you 'll find out the other when
you'll high crack) is that they MUST compare the password of the
password, you just need to "ear" the echo of the original one in
the memory locations used for the compare, or, and that's more
where the password is stored (and you 'll find these with your
ES:0F8E (here you 'll see a copy of the password that the
program is asking)
ES:0F5C (here you 'll see a copy of the password that the user
types in)
in extenso).
MOV
CX,FFFF
Charge MAX in CX
REPNZ
SCASB
NOT
CX
MOV
DI,SI
LDS
SI,[BP+0A]
REPZ
CMPSB
level... you look at the code that follows the CMPSB searching
out of the CMPSB check at the first different char, OR at the end
MOV AL,[SI-01]
CBW
Well let's now look for the next JZ near (it's a "74" code)
CS:IP 740D
JZ location no_good
CS:IP 7590
a JZ... now you will always pass, no matter what you write,
------------------------------------------------
symdeb ums.ded
- s (cs+0000):0 Lffff 74 0D 1E B8 C2 3F
(nothing)
- s (cs+1000):0 Lffff 74 0D 1E B8 C2 3F
(nothing)
- s (cs+2000):0 lffff 74 0D 1E B8 C2 3F
xxxx:yyyy
- e xxxx:yyyy 75
- e xxxx:yyyy+17 74
- w
- q
-------------------------------------------------
modified them there, but I'm teaching also pupils who may not
have [Soft-ice].
that's good practice! If you do not find your string in the first
sector you must search for it in the next sectors, till you find
it, coz in many programs there may be MORE THAN ONE repetitions
protection schemes.
--------------------------------------------------------
--------------------------------------------------------
interesting indeed).
The snap_comparisons of the main memory area -as you type the
What now?
Moskovskaja 'll do) and meditate. Get the memory map of the
compares. Sit down, sip Martini Wodka, relax. You know that the
code for A is x41, for B x42, for C x43 and so on... and in the
snap_compares, that you made between letters, you 'll have only
You 'll soon enough find out that for LIGHTSPEED absolute
-----------------------------------------------------
F858
F859...
41 3E first_ready_letter your_1st_letter
your_2nd_one...
-----------------------------------------------------
Inspecting the same prints, you 'll find out that absolute
LAST character you typed in. The relative code line is:
and this means that the code of the letter you just typed in will
be now copied in BX=F85A. What else can you do? Time to use a
is the typical "IF the user hits ENTER then" instruction, coz
CS:0073 3D0D00
CMP AX,000D
And now the way is open to the crack. But YOU DO NOT NEED ALL
THIS! Since the password protection schemes are -as I told you-
all more or less the same, I would suggest that you use first of
memory map to see where the program dwells) search the "F3A6"
pgsg:C6F9
pgsg:E5CA
pgsg:E63E
pgsg:EAB0
There you are! Only four... have a short look at each of them:
you 'll see that the second one (pgsg:E5CA) is the "good" one.
B9FFFF MOV
F2AE
REPNZ
SCASB
password)
F7D1
NOT
CX
2BF9
SUB
DI,CX
F3A6
REPZ
CMPSB
at CX=0 or at char_differs
See how easy? They all use the same old tricks the lazy
lowercased.
locations, in order to stop the program "in the snap area" and
Now you can find out the segment:offset used by the snap and only
NOT CX instruction).
Now run the program and breakpoint in: have a dump of the
ES:DI and see the original password. How nice! We have now the
are the password stored? From which locations do they come from?
you to see them. Here the passwords are encoded (albeit in a very
sg:0118 8C 91 9D 95 9B 8D 00 B8 EC 94 9B 8D 8F 8B 9B
sg:0128 94 9B 8D 00 AE EC 9C 9B 8A 9B 86 00 A9 EC 91
Let's now leave the "hidden" passwords and proceed with our
cracking... let's follow the snap procedure after the REPZ CMPSB
F3A6
REPZ
CMPSB
7405
1BC0
SBB AX,AX
:preserved_AX=0000
8BF3
MOV SI,BX
8BFA
MOV DI,DX
5D
POP BP
CB
RETF
....
0BC0
OR AX,AX
7509
JNZ 0276
the fly INSIDE [Soft-Ice] and it did work!), the "74" with a
"75" also. And then you would like to change the JNZ instruction
work! (You will not even find the second JNZ in the program
fly", as needs arise, by the program. The code you modify while
"dead" program.
overlay message and the program pops out with instability! You
cannot easily modify the JNZ instruction either, coz the part
after the RETF will be compiled "on the fly" by lightspeed, and
do encrypt it twice... and then you must hack all night long...
very annoying.
Wodka and meditate: loo! The only thing that happens after the
that's what the two SBB instructions do) if the snap went out
with a non-zero flag... i.e. if you did not know the password.
So let's nop the 5 bytes of the two SBB instructions, or, more
elegantly, let's have a INC AX, DEC AX, NOP, INC AX, DEC AX
with the second JNZ either... the program will work as if you got
the previous type of crack -seen for UMS- when you crack computer
accesses: hereby the legitimate user will not have any suspects
'coz the system will not shut him out... everybody will access:
the good guys and the bad ones... that's nice isn't it?).
------------------------------------------------
symdeb lightspd.ded
- s (cs+0000):0 Lffff 2B F9 F3 A6 74
xxxx:yyyy
- s (cs+1000):0 Lffff 2B F9 F3 A6 74
- s (cs+2000):0 lffff 2B F9 F3 A6 74
- w
- q
-------------------------------------------------
When you break in, at the nag screen, you are in the middle of
the BIOS procedures, coz the program expects your input (your
password, that's is). You 'll quickly find out (MAP MEMORY
breakpoints on memory write you 'll find out that the memory area
xxxx:1180 to xxxx:11C0
where xxxx represents the second of the memory segments where the
procedure):
CODE.
It's already done! Now it's your intuition that should work a
-9 xxxx:0185 7425
-8 xxxx:0187 2D1103
SUB AX,0311
-7 xxxx:018A 7430
-6 xxxx:018C 2DFD04
SUB AX,04FD
-5 xxxx:018F 7443
JZ next_trace, taken
-4 xxxx:01D4 E85500
CALL funny_procedure
-3 xxxx:022C 803E8F8C11
-2 xxxx:0231 750E
-1 xxxx:0233 9A0A0AC33E
CALL procedure_that_sniffs
our_memory_area
:funny_procedure
803E8F8C11
750E
JNZ compare_byte
9A0A0AC333
CALL procedure_that_sniffs
0AC0
OR AL,AL
7405
J2 compare_byte
C6068F8C2A
:compare_byte
803E8F8C2A
7504
JNZ after_ret
B001
MOV AL,01
C3
RET
MOV 2A and CMP 2A, coz there would be no sense in comparing the
"2A" in order to JNZ to after_ret if you just had the 2A set with
the precedent MOV instruction... but the first JNZ jumps to the
compare WITHOUT putting the "2A" inside. And "2A" is nothing else
explained):
- else ret_ahead_nice_buyer
------------------------------------------------
symdeb general.ded
- s (cs+0000):0 Lffff 8C 11 75 0E
xxxx:yyyy
- e xxxx:yyyy+2 EB [SPACE] 09
- w
- q
-------------------------------------------------
And in this way you changed the JNZ to the cmp "*" instruction
You 'll obtain the missing lessons IF AND ONLY IF you mail
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,
welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
--------------------------------------
You have seen in the previous lesson that the use of a password
with the password that the user types in. You therefore have many
just to name the more obvious ones. In order to make things more
instructions or jumps in and out protected mode (no match for our
beloved [Soft-Ice]);
using the program. This is the type of password that you'll find,
(they do NOT verify only the three magnetic areas in the magnetic
strip on the card). The lines between ATM's & their hosts are
dedicated line between the ATM and the host; 2) insert your
computer between the ATM and the host; 3) Listen to the "normal"
with a legal card, make some mistakes, take note of the various
codes; 5) When you are ready insert a fraudulent card into the
- the ATM sends a signal to the host, saying "Hey! Can I give
discards it, sends on the "there's no one using the ATM" signal;
- the host gets the "no one using" signal and sends back its
"good, keep watching out if somebody comes by, and for God's sake
don't spit out any money on the street!" signal to the ATM;
away (again), and sends the "Wow! That guy is like TOO rich! Give
- the ATM obediently dispenses cash till the cows come home.
PASSWORDS AS REGISTRATION
you register the shareware program, you are sent a password that
get the "unique key" to unlock the "special protection". It's all
entry.
software. The password query does not usually appear any more at
the password query appears after one or more levels are completed
DONGLE PASSWORDS
myself have only seldom seen them, and do not like at all to
ones on the appropriate web sites, they may even answer you if
- encrypted and/or
themselves):
* password read in
manipulations
routine
searches first the file where the password is stored, then loads
Setup (at the beginning), the protection scheme does not allow
a boot with a floppy and does not allow a setup modify. In these
* open the PC
words "Pw"
* take it away
* PC on
* run the setup with F1 or Del (depending from the BIOS) (the
* PC off
* close the PC
* PC on, cracked (if you want to be nasty you could now use
denying, encryption and locking of the FAT tables, get from the
web, and study, the (very well written) code of a virus called
- using the most recent and best SMC (self modifying code)
tricks
7402
JZ go_ahead_nice_buyer
EB13
JMP beggar_off_ugly_cracker
------------------------------------------------
symdeb top.ded
- s (cs+0000):0 Lffff 8A 84 1C 12 3A 84
xxxx:yyyy
- w
- q
-------------------------------------------------
And you changed the MOV AL, [SI+121C] instruction in a MOV AL,
the characters you typed in... no wonder that the ECHO does
are stored: we saw in the first part of our "passwords hands on"
mean? Well, this could mean quite many things... the most
Now you 'll quickly find out that the routine determining
Now, every time this random triggers, you get a different number
The random seed routine, evidently, comes back with the random
seed in AX... what we now need is to zero it: the user will
always have to choose the same plane: "plane 0", and he will have
given the correct answer. Note how elegant all this is: we do not
with the actual choosing of the planes... the random seed may
---------------------------------------------------
symdeb start.ded
xxxx:yyyy
-w
-q
----------------------------------------------------
58
POP AX
31C0
XOR AX,AX
beginning this was a smart idea: "the cracker won't find the
correct password, 'coz it's not there, ah!". We'll now therefore
[POPULOUS.EXE]
stored. Set a breakpoint memory read & write on this area, and
40
INC AX
7509
JNZ beggar_off_ugly_copier
<- beggar_off
I don't think that you need much more now... how do you prefer
[BP+0C], AX and three NOPS (=6 bytes) after the IMUL instruction?
---------------------------------------------------
symdeb populous.ded
- s cs:O lffff F7 AE 4E FF
xxxx:yyyy
- w
- q
----------------------------------------------------
Now you are almost ready with this course... let's crack a
very useful for our purposes (you'll use it later to crack a lot
But, Hey! Do not forget that you would have never done it without
[MAP.EXE]
Let's now go over to one of the best TOOLS for mapping your
in Lesson 2, and you should learn how to crack it, coz it comes
amount of time before asking the user to press a key which varies
the loading of the nag screen. You 'll quickly find the relative
B95000
MOV CX,0050
2EFF366601
PUSH CS:[0166]
07
POP ES
AC
LODSB
...
You could already eliminate the delay and you could already force
the protection... but we crack deep!: let's do the job and track
91
XCHG AX,CX
6792
XCHG AX,DX
28939193
SUB [BP+DI+9391],DL
2394AA94
AND DX,[SI+94AA]
7416
JZ ret
E882F3
CALL 8870
2E3B064B88
CMP AX,CS:[884B]
7307
C3
RET
...
E86700
CALL delay_user
BE9195
MOV SI,9591
2E8B3E255C
MOV DI,CS:[5C25]
83EF16
SUB DI,+16
2E8A263D01
MOV AH,CS:[013D]
50
PUSH AH
E892C7
B42C
MOV AH,2C
CD21
INT 21
80E60F
AND DH,0F
80C641
ADD DH,41
58
POP AX
8AC6
MOV AL,DH
83EF04
SUB DI,+4
AB
STOSW
E85A00
CALL INT_16_AH=01
B400
MOV AH,00
CD16
INT 16
24DF
AND AL,DF
3AC6
CMP AL,DH
<- pass_compare
75F3
E807F3
go_ahead
are somehow like little snakes moving under a cover: you cannot
easily say what's exactly going on yet, but you could bet that
your LODSB routine call: you find two JUMPS there: a JZ ret, that
leaves a lot of pusha and popa aside, and a JAE after RET, that
does not take the previous ret. If you did smell something here
you are thoroughly right: The first JZ triggers the NIGEL screen
protection, and the second JAE does THE SAME THING (as usual,
of the code in order to change it, you won't have any luck: it's
find out the LODSW routine; find out the real area; dump that
memory region; find out a search sequence for the "dead" code...
------------------------------------------------
symdeb map.ded
- s (cs+0000):0 Lffff 74 16 50 53 51 52 57
xxxx:yyyy
- e xxxx:yyyy EB
- w
- q
-------------------------------------------------
You 'll obtain the missing lessons IF AND ONLY IF you mail
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,
welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
--------------------------------------
vector used for the protection. This kind of crack can be used
lesson A.2).
stupid game that uses the SAME (!) protection scheme you'll still
following lines:
loc code
instruction
what's going on
-------------------------------------------------------
:0100 EB44
JMP 0146
...
:0142 0000
:0144 5887
:0146 FA
CLI
:0147 0E
PUSH CS
:0148 1F
POP DS
:0149 BCB403
MOV SP,03B4
:014C FB
STI
:014D 8C1EA901
MOV [01A9],DS
<- save DS
:0151 8C1EAD01
MOV [01AD],DS
three
:0155 8C1EB101
MOV [01B1],DS
times
:0159 B82135
MOV AX,3521
:015C CD21
INT 21
in ES:BX
:015E 891E4201
MOV [0142],BX
:0162 8C064401
MOV [0144],ES
:0166 BA0201
MOV DX,0102
:0169 B82125
MOV AX,2521
:016C CD21
INT 21
DS:0102
:016E 0E
PUSH CS
:016F 07
POP ES
:0170 BBB403
MOV BX,03B4
:0173 83C30F
ADD BX,+0F
:0176 B104
MOV CL,04
:0178 D3EB
SHR BX,CL
<- BX= 3C
:017A B8004A
MOV AX,4A00
:017D CD21
INT 21
to 3C paragraphs
:017F BA9E01
MOV DX,019E
:0182 BBA501
MOV BX,01A5
:0185 B8004B
MOV AX,4B00
:0188 CD21
INT 21
:018A 2E8B164201
:018F 2E8E1E4401
MOV DS,CS:[0144]
:0194 B82125
MOV AX,2521
:0197 CD21
INT 21
:0199 B8004C
MOV AX,4C00
:019C CD21
INT 21
code
0000
fence
:01A7 B2015887
:01AB B2015887
:O1AF B2015887
0000
fence
push all
JNZ ret
JNZ ret
pop all
From now on this loader will work every time that a program
the target program will be modified on the fly and will get, at
The most important thing is the routine that YOU write that
will precede the call to INT_21 (or any other INT) service 25 (or
program. I'll show you another one, this one for [Reach for the
skies] (reach.com):
push all
CMP AH,3D
JNZ ret
JNZ ret
MOV DS,AX
JNZ 015B
JNZ 015B
CMP Byte Ptr [B6DC],80 <- ditto, now we now where we are
JNZ 015B
nop
nop
nop
nop
MOV DX,CS:[0165]
MOV DS,CS:[0167]
INT 21
POP all
Here you did change the instruction 740F in the instruction EB0F,
elegantly than "noop" them with "90" bytes, you choose a INC AX,
DEC AX, NOP, INC AX, DEC AX sequence instead! There are sound
program and trash everything if they find more than -say- three
You can apply this kind of crack, on the same lines, to many
programs that perform self checking of the code and hook the
vectors.
cracking matters too. As the older 5 1/4 inch big black floppy
disks were still used (the 320K/8 tracks or 360K/9 tracks ones,
format the "master" (key) disk in a weird way. Old floppy disk
order to defeat this kind of cracks you need to know two things:
the floppy disk parameter block (FDPB) and the interrupt routines
(very old) copy of VisiCalc master I do, you'll find that sector
myself, but you 'll be able to find many such utilities in public
domain, the oldest one, from 1984 (!) being the seasoned [U-ZAP]
trick).
Offset Function
crackworthy?
Example
no
DF
no
02
2 Motor on delay
no
25
yes
02
yes
12
5 Gap length
yes
1B
yes
FF
yes
54
8 Format byte
no
F6
no
0F
no
02
is the step rate time for the disk drive head. The right
nybble is the disk head unload time. These values are best
left alone.
1) Offset #1: again, don't fool around with these values. The
left nybble is the disk head load time, and the right
formatting and tells DOS how many sectors there are on each
track.
5) Gap length for diskette reads: this is what you fool around
with if you keep getting CRC errors when you try to read a
or 3.
and the number of sectors per track you can always format with
- d 0:78 l 4
0000:0070
22 05 00
- d 0:522 l a
floppies:
history!) a new floppy disk format has been supported: The IBM
720K
2880K
on the media:
table.
data buffer.
not set, AH=0, therefore the weird sector has been read, if
Meaning
80h 128
40h 064
20h 032
Controller kaputt
10h 016
09h 009
08h 008
DMA overrun
1 04h 004
11 03h 003
Write protect!
1 02h 002
1 01h 001
Bad command
placed into RAM. DMA (Direct memory access) is used by the disk
will occur.
the disk and DOES NOT involve verification of the data on the
stored on the disk. See INT_13, AH=2 registers and error report.
[CRC]
"CD13" in their machine code, but which clearly are checking the
the protection scheme from our nice prying eyes. I'll describe
29h, sector ffh, and then checking for a status code of 10h:
;read operation
;1 sector to read
;track 29h
;sector ffh
;move 0...
;...to DS register
cs:100F PUSHF
;pusha flags
cs:1010 PUSH CS
;pusha CX
...
...
cs:1100 PUSHF
;pusha flags
cs:1109 IRET
machine code, you would never have found the protection routine.
have the program change the "10" to "13 (and then back to "10")
Old good [debug.com] has been called the "swiss army knife" of
the disks. The sector count starts with the first sector of track
back to the first side, track 1, and so on, until the end of the
- l 100 0 10 20
drive A, sector 10h for 20h sectors. This allows at times the
error, check the memory location for that data. Often times, part
of the data has been transferred before the error occurs, and the
retries.
scheme: on the disk you had only a "stub", called FS.COM with few
loc code
instruction
what's going on
-------------------------------------------------------
:0100 FA
CLI
;why not?
:0101 33C0
XOR AX,AX
;ax=0
:0103 8ED0
MOV SS,AX
;ss=0
:0105 BCB0C0
MOV SP,C0B0
;SP=C0B0
:0108 8EC0
MOV ES,AX
;ES=0
:0111 268C0E7A00
:0116 BB0010
MOV BX,1000
;BX=1000
:0119 8EC3
MOV ES,BX
;ES=1000
:011B 33DB
XOR BX,BX
;BX=0
:011D B80102
MOV AX,0201
:0120 BA0000
MOV DX,0000
;head=0 drive=0
:0123 B96501
MOV CX,0165
:0126 CD13
INT 13
;INT 13/AH=2
:0128 B83412
MOV AX,1234
;AX=1234
:012B EA00000010
JMP 1000:0000
:0130 CF
IRET
don't you? Herein you can watch the same snap that happens in
more recent (much more recent) protection schemes (as you'll see
That should be no problem for you any more: you should just
just watch and break on the INT_13 calls), fetch the "weird"
data, tamper the whole crap and have your soup as you like it.
-- CLEVER
-- STILL USED
3, you just type your name and a serial number of your choice in,
say "666666666", break into the program with WINICE, search the
"666666666" and search too, for good measure, your own name, set
a memory read breakpoint where the number dwells and look at the
you can even rip the code straight out of the program and create
a key generator which will produce a valid code. This code will
work for any name you typed in only in the "pure maths
they are getting more and more rare in this objectionable world
zest will really be perfect) and watch from your balcony, with
unsullied eyes, your town and the people around you: slaves
produce other cars in order to buy, one day, a new car with a
different colour...
Why people don't look at the stars, love each other, feel
the winds, ban the stinking cars from the places where they live
activity? Why don't they read any poems any more? No poetry any
will soon be forbidden, coz you cannot CONSUME as you read poems,
the only thing they want you to do... you are CULTIVATED to
well placed neutron bombs, the ones that would kill all these
useless zombies and leave noble books and good Wodka untouched.
"look" like and could not care less about anything else than
making bucks and defend intolerant and petty patterns. The slaves
publicity... sorry, at times I forget that you are here for the
You 'll obtain the OTHER missing lessons IF AND ONLY IF you
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
Your suggestions and critics on the whole crap I wrote are also
welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
Before the next step let's resume what you have learned in
that the good buyer could find on the manual, whereby the bad
cracker could not. (Here you choose -with the mouse- one number
any more to teach you how to find the relevant section of code
(-> see lesson 3). Once you find the protection, this is what you
get:
:protection_loop
:C922 8E0614A3
MOV
ES,[A314]
...
:C952 50 0E
PUSH AX & CS
:C954 E81BFF
CALL C872
:C957 5B
POP
BX twice
:C959 8B76FA
MOV
:C95C D1E6
SHL
SI,1
:C95E 8942FC
MOV
:C961 837EFA00
CMP
:C965 75BB
JNZ
C922
:C967 8E0614A3
MOV
ES,[A314]
:C971 74AF
JZ C922
:C973 8B46FC
MOV
:C872 55
PUSH BP
...
:C8F7 90
NOP
:C8F8 0E
PUSH CS
:C8F9 E87234
:C8FC 5B
POP
BX
:C8FD 5B
POP
BX
:C8FE 8B5E06
MOV
BX,[BP+06]
:C901 D1E3
SHL
BX,1
:C903 39872266
CMP
:C907 7505
JNZ
C90E
:C909 B80100
MOV
:C90C EB02
JMP
C910
:C90E 2BC0
SUB
AX,AX
:C910 8BE5
MOV
SP,BP
:C912 5D
POP
BP
:C913 CB
RETF
idea?
less than 15 minutes WITHOUT USING THE DEBUGGER! Just look at the
data above and find the right answers feeling them... (you 'll
now which one are the right one checking with your debugger...
score as many points as you like for each correct answer and sip
One easy way to encrypt data is the XOR method. XOR is a bit
Byte to encrypt
key
result
FF
XOR
A1
5E
5E
XOR
A1
FF
encrypt_decrypt:
xor_loop:
mov [bx], ah
inc bx
jle xor_loop
ret
random, for instance using INT_21, service 2Ch (get current time)
random_value:
mov ah,2Ch
int 21h
cmp dl,0
je random_value
mov encrypt_value,dl
methods), is that the part of the code that calls the encryption
These are the more common protection method for the small
* ULTRAPROTECTED
MOV
SI,jumbled_data
MOV
CX,10
mn_loop: XOR
INC
SI
;Next byte
LOOP
mn_loop
This small program will XOR the ten bytes at the location pointed
to by SI with the value 44. Providing the ten bytes were XORed
In this very simple case the "key" is the value 44. But there are
several tricks involving keys, the simplest one being the use of
loop.
and CALLS, that DO NOT AFFECT the registers that are used for the
oft alters on each generation also all the registers that the
decryptor uses, invariably making sure that the JUNK code that
real decryptor! So, with these rules in mind, here is our simple
decryptor again:
MOV
DX,10
MOV
SI,1234
;junk
AND
AX,[SI+1234]
;junk
CLD
;junk
MOV
TEST
[SI+1234],BL
;junk
OR
AL,CL
;junk
mn_loop: ADD
SI,SI
XOR
AX,1234
;junk
XOR
SUB
SI,123
;junk
INC
DI
TEST
DX,1234
;junk
AND
AL,[BP+1234]
;junk
DEC
DX
NOP
;junk
XOR
AX,DX
;junk
SBB
AX,[SI+1234]
;junk
AND
DX,DX
JNZ
mn_loop
parts:
There are other discrete parts but these three are the ones where
junk code.
time.
(->see lesson B). Besides, you (now) know what may be going on
the road is open and the rest is easy (->see lessons 3-5).
For example, say the encrypted code started at address 10h, the
MOV SI,10h
;Start address
MOV AL,[SI]
MOV DI,0BFAAh
digit keys the decoding is much easier than for, say, 129 or 250
digit keys. Nevertheless you can crack those huge encryption too,
PC for a couple of hours, for a 250 bit key, this kind of things
have been done quite often on Internet, were you can also find
techniques.
Eurocrypt 1991.
A very good old book you can incorporate in your probes to build
very effective crack programs (not only for BBS accesses :=) is
Anyway... make a good search with Lykos, and visit the relevant
two or three (or thirty) years and you'll resume cracking with
interesting for our aims :=) Here are some interesting patents,
which are completely encrypted with both the operation code and
key kernel.
storage.
[AUTHENTICATOR]
that runs 24 hours on 24 only to this aim and yet have only begun
to see the light at the famous other end of the tunnel. It's
hard, but good crackers never resign! We'll see... I publish here
the following only in the hope that somebody else will one day
be able to help...
public file, while the decryption keys for the users are only
digest algorithm.
As a final gift, I'll tell you that PGP relies on MD5 for a
of every word) and a single message block that yield the same
hashcode. The attack takes a few minutes on a PC. From here you
as [Lost soul] sends his stuff, if he ever does. For (parts of)
language.
next to nothing in the second hand bookshops. All the lusers are
Visual basic, C++ and Delphy. Good C new books are now rare
them, read them, use them for your/our aims. You can find a lot
you need to find the "main" sub-routine inside the asm. With
DOS/4GW programs, search the exe file for "90 90 90 90", almost
always it'll be at the start of the compiled code. Now search for
an INT_21 executed with 4C in AH, the exec to dos code (if you
cannot "BPINT 21 AH=4C" with your tool, then search for the
int 21]: it's the most direct call, but as you'll have already
learned, there are half a dozen ways to put 4C in AX, try them
A few bytes above the INT_21 service 4C, you'll find the
call to the "main" subroutine: "E8 xx xx". Now place a "CC" byte
a few bytes above the call in the exe and run the exe under a
you'll be throw back in the debugger coz the "CC" byte acts as
hidden INSIDE a picture (or a *.waw file for that matter). This
media.
bit in each pixel of a picture. It uses that bit to store one bit
when it needs be, and there we'll intercept them. You'll need to
You 'll obtain the OTHER missing lessons IF AND ONLY IF you
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
Your suggestions and critics on the whole crap I wrote are also
welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
[WINPGP.EXE]
--------------------------------------
--------------------------------------------------------
---------------------------------------------------------
ameliorate them.
situation in DOS, where for years the key "load but don't
Windows] (the last two are GUI, not text debuggers. The use of
in WinDebug().
3.1., all crackers should study it and get the maximum possible
have special code for Standard vs. Enhanced modes, because the
digestible form.
of doing ring transitions that are not allowed with legal 80x86
-----------------
DEBUGGERS
to crack a function)
WCB
WDEB386
second monitor)
CORONER, etc.
(a lot of shareware)
MS-DrWatson
Borland's Winspector
information.
-----------------
INSPECTORS
MS-Spy
Old
Borland's WinSight
-----------------
SNOOPERS
informations.
reserved for debuggers. You can put the INT_03 op code in place
In the 80386 and later, you can set a register flag that tells
stepping.
debug it. The SDK's debug API takes care of how the interrupts
programmers -in few years time- will not be able any more to
alone the capacity to push forward (and sell) real programs that
you begin serious work and you discover its shortcomings, like
the fact that extended error codes are not documented, and
you must burn precious time testing them. What we definitely need
program enters a loop to run the program. At the top of the loop
tell about the vent that suspended the program being debugged.
contains among other things the address that was interrupted end
program's memory.
its place, it's always the same old marmalade. When the
IDE and waits for the cracker to take an action that resumes the
program.
you must understand the format of that file (best thing to do,
they used names that suggest their purpose (nomen est omen).
include entries for .text, .bss, .data and .idata. Inside these
information.
null terminated strings into which the .stab table entries point.
windows, by Geib - I must thank "Q" for the idea to work on this
crack).
13.081B.
The road to the crack is now open, you just need to find and
...
13.0E88 660FBF46F8
movsx
13.0E8D 668946F4
mov
[bp-0C], eax
13.0E91 668B46F4
mov
eax, [bp-0C]
eax, 0003000A
13.0E9C 668946F0
mov
[bp-10], eax
13.0EA0 668B4606
mov
eax, [bp+06]
13.0EA4 663B46F0
cmp
eax, [bp-10]
13.0EA8 7505
jne
0EAF
<- beggar_off
13.0EAA B80100
mov
13.0EAD EB04
jmp
0EB3
<- and go on
beggar_off:
13.0EAF 33C0
xor
ax,ax
13.0EB1 EB00
jmp
0EB3
<- and go on
IT'S THE SAME OLD SOUP! You do remember lesson 3 and the
protection schemes of the old DOS stupid games of the '80s, don't
you? IT'S THE SAME OLD SOUP! In this "up-to-date" "new" windows
Besides, look at all the mov eax, and eax, moves preceding
in less than three seconds flat. The IMUL instruction creates the
Now you could crack the above code in 101 different ways,
0EAF, that's the same) to the jne 0EAF at 13.0EA8. You just write
a 74 at the place of the 75, like you did for the cracks in
1978... how boring: it's really the same old soup! (But you'll
You 'll obtain the missing lessons IF AND ONLY IF you mail
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,
welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
--------------------------------------
---------------------------------------------------------
If you thought that DOS was a mess, please notice that windows
sure: This OS will not last... it's way too messy organised,
meat not fish: neither 16 nor 32... you could call it a "24 bit"
operating system.
this planet. I'll write it this sommer and give it away between
find it on the web for free, I use version 1.95, cracked by [The
Lexicon] (do not bother me for Warez, learn how to use the search
engines on the web and fish them out yourself). Learn how to use
soon that you did not wanted to learn how to use it properly.
TRA = 92
This way you'll always have the hexadecimal notation on, two very
first 8 bytes.
every user name will give a different "access key". This is the
* load WINICE
* hwnd [name_of_the_crackanda_module]
* Run anew
possibilities...
* Reassemble everything.
there are quite a lot of them (see also the crack of Wincat Pro
protection scheme):
INC ESI
JZ ok_it's_a_+_or_a_-
JNZ Jesus_it's_neither_a_minus_nor_a_plus_let's_check_it
:ok_it's_a_+_or_a_-
INC ESI
:Jesus_it's_neither_a_minus_nor_a_plus_let's_check_it
...
even if you did not read all my precedent lessons, you do not
USER!BOZOSLIVEHERE
KERNEL!HMEMCPY
USER!GLOBALGETATOMNAME
tutorial.
The above code is the part of the routine that checks for the
Now sit down, make yourself comfortable and sip a good Martini-
will do, do not forget the lemon)... what does this "-" stuff
protectionists are! You don't believe me? Try it... you 'll get
Yes I know, to find this code is not yet to crack it... but for
you can only learn how to find them and circumvene them. I'll not
program below).
WHERE ARE THE CODES? WHERE ARE THE MODIFIED FILES? WHERE DO THE
Most of the time the protection schemes use their own *.ini files
they even use the "garbage sammler" win.ini file. Let's take as
your files.
This scares most newby crackers, since if the copy you have
unless you get the REAL stuff. The youngest among us do not
few lines inside the win.ini file, under the heading [WinZip],
that has already been created with the demo version, before the
I will not help you any further with this... I'll leave it to
substitute for your tries inside WINICE... you'll get it, believe
me):
[WinZip]
name=Azert Qwerty
sn=########
version=5.5
The *important* thing is that this means that you DO NOT NEED
believe. The same applies most of the time... never believe what
newspapers tell you... you can be sure that the only reason they
* INTERNET
to use well the search engines (or if you do build your ones...
my spiders are doing most of the work for me... get your robots
the same point you'll have to confront all your life long: HOW
rule this slaves world, are paradoxically most of the time the
only ones worth studying... somewhere even the real rulers have
around that you can easily find (even on the web). These
all the other medias in the world, the ones that are used only
english (poor guy) you could try your luck with the weekly
"Economist"... you'll have to work a lot with it, coz it has been
tailored for the "new riches" of the Tatcher disaster, but you
truth. American newspapers (at least the ones you can get here
in Europe) are absolute shit... one wonders where the hell do the
spanish newspaper "El Pais" that seems to know about what's going
but has a lot of useful information. See what you can do with all
the Serbians are not so evil at all and that "the Croats" or some
other Yugoslavian shits are the real culprits. This does not mean
at all that the Serbians are good, I warn you, it means only what
direction and believe the few bit of information that do say the
writes that the commies are bad then THERE the commies must not
writes that the commies are all good and nice and perfect (like
the Soviet propaganda did) then THERE the commies are surely not
you are, i.e. whose interests are really at stake. There is NEVER
sententiae".
algorithms, and the registration key will be made "ad hoc" and
can register "over your registration" one thousand times, and you
can herefore try for this crack different user_names to see all
protection code.
get a window where you can input your name and your registration
schemes, but it'll teach you a lot for higher cracking, so you
STOSB). Then various routines store and move in memory the usn
253F:00000260 AC
LODSB
253F:00000261 08C0
OR AL,AL
253F:00000263 740F
JZ 0274
253F:00000265 3C61
CMP AL,61
253F:00000267 72F7
JB 0260
253F:00000269 3C7A
CMP AL,7A
253F:0000026B 77F3
JA 0260
253F:0000026D 2C20
SUB AL,20
253F:00000272 EBEC
JMP 0260
253F:00000274 93
XCHG AX,BX
...
usn <-> rn, coz he does not know that usn AND rn are slightly
case mismatch, foreign accents in the name etc.) You just need
light").
memory; double checking the string lengths (and saving all these
register points to the stack you have most of the time fished
a user name, in our babe, for instance, the usn must have at
least 6 chars:
230F:00003486 730F
JAE 3497
<- go to nice_name
:too_short
2467:00000CA6 03F1
ADD SI,CX
2467:00000CA8 2BC1
SUB AX,CX
2467:00000CAA 7213
JB 0CBF
2467:00000CAC 40
INC AX
2467:00000CB1 0BC9
0R CX,CX
2467:00000CB3 7D02
JGE 0CB7
2467:00000CB5 33C9
XOR CX,CX
2467:00000CB7 3BC1
CMP AX,CX
2467:00000CB9 7606
JBE 0CC1
2467:00000CBB 8BC1
MOV AX,CX
2467:00000CBD EB02
JMP 0CC1
2467:00000CBF 33C0
XOR AX,AX
2467:00000CC1 AA
STOSB
2467:00000CC2 8BC8
MOV CX,AX
2467:00000CC4 F3A4
REPZ MOVSB
2467:00000CC6 8EDA
MOV DS,DX
2467:00000CC8 FC
RETF 0008
CX,SS:[BX+04], the STOSB and the REPZ MOVSB (as usual in password
You should be enough crack-able :=) by now (if you have read
with these hints, how the working of the protection goes and
matches the name you typed in. Remember that in these kind of
routine that checks for a "-" inside the rn, a very common
protection element.
code in [Wincat Pro] I'll give you another hint, though: if you
different usn than your own name to crack a program you only show
that you are a miserable lamer... no better than the lamers that
that is really software that they have stolen (Yeah: stolen, not
I bomb them as soon as I spot them. YOU ARE (gonna be) A CRACKER!
You 'll obtain the missing lessons IF AND ONLY IF you mail
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,
welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
[Winformant][Snap32]
--------------------------------------
THE [DATA_CONSTRAINT] TRICK - [WINFORMANT 4] I have chosen an older windows application for Win 3.1. (WIN4MANT.EXE, 562271 bytes, Version 1.10, by Joseph B. Albanese; you'll find it searching the web with the usual tools, see how to do it at the end of this lesson), in order to show you how to use a nice little trick, at times really useful in cracking password protected programs: [data_constraint]. Inside almost all protection routines, as you have already learned, there is a moment when on the stack the ECHO of the real, "correct" passnumber or password appears. The location of this ECHO varies, but most of the time it'll be in a range of +- 0x90 bytes from one of the locations where the user input dwells. This is due to datadump windows constraints inside the tools used by the protectionists... but this use is bound to diminish... especially after this lesson :=)
[WINFORMANT CRACKING] This application is -per se- crappy, I doubt you'll ever use it... but its curious (and pretty rare) "deactivate" mode is nevertheless very interesting for us: you can "unregister" Winformant on the fly if you feel the need to.
This feature is pretty useful for scholars that like to investigate password algorithms with valid and invalid codes without having to reinstall every time to delete a valid code. For your cracking exercises choose programs that have "REVERSIBLE" protections (rare) or that can be re-registered a billion times (more frequent). Programs that keep the valid registration on *.ini or special files will also do the job: you just change a couple of lines to "unregister" them. The trick of this lesson: [data_constraint], or "password proximity", bases on the protectionist's need to keep an eye on the protection "working" when he assembles it. He must "see" the relationships between USER INPUT NUMBER, USER INPUT TRANSFORMED and the CORRECT NUMBER ANSWER (in our jargon: the "Bingo"). These relationships must be constantly checked In order to debug the protection code. Mostly they will dwell TOGETHER inside a small stack area, allowing them to be "seen" in the SAME watchwindow. Most of the time, therefore, the "ECHO" will "materialize" shortly not very far away from one of the locations of the USER INPUT. Let's crack:
* Fire Winice and then Winformant * Choose HELP and then choose REGISTRATION * Fill the registration fields with "+ORC+ORC" as "Registrant" and "12121212" as "Activation" code (use whatever you fancy). CTRL+D ;switch to Winice
:task
TaskName SS:SP StackTop StackBot StackLow TaskDB hQueue Events WINWORD 1AD7:85F2 4A52 8670 PROGMAN 1737:200A 0936 2070 DISKOMAT *2C5F:6634 1D3C 6AC6 7532 1392 5192 1247 122F 0000 066F 07F7 0000 2CB7 2C9F 0000
:hwnd DISKOMAT
;which window is getting the input? Window Procedure 04A7:9E6B USER!BEAR306 2C3F:0BC6 2C3F:1CEA 2C3F:24BE
WinHandle Hqueue QOwner Class Name 0EB4(0) 0F34(1) 365C(1) 2C9F DISKOMAT #32769 2C9F DISKOMAT #32768 2C9F DISKOMAT #32770
36BC(2) 2C9F DISKOMAT Button 3710(2) 2C9F DISKOMAT Edit ... and many more irrelevant windows.
Let's pinpoint the code, here the relevant window is the first "Edit" one, for obvious reasons (more on this later). :bmsg 3710 wm_gettext CTRL+D ;set breakpoint
Break Due to BMSG 3710 WM_GETTEXT C=01 Hwnd=3710 wParam=0050 lParam=2C5F629A msg=000D WM_GETTEXT 2C3F:000024BE B82F2C MOV AX,2C2F
So! Now we have "pinpointed" the babe (more on "pinpointing" later). Let's snoop around a little: look at the stack to fetch your babe's last call (if it does not show immediately, just keep
pinpointing, for instance on GetWindowText() or do a BPRW diskomat (very useful), and then try and retry the stack... should this too fail to work, search for your input in memory (in the 30:0 lffffffff selector, as usual) and breakpoint range on it with ReadWrite, and then stack, stack, stack... until you get the "real" list of calls coming from your babe's protection. :stack ; let's see
USER(19) at 073F:124C [?] through 073F:1239 CTL3D(02) at 2C3F:0D53 [?] through 2C3F:0D53 DISKOMAT(01) at 2C97:20B9 [?] through 2C97:20B9 DISKOMAT(01) at 2C97:3D94 [?] through 2C97:3D94 DISKOMAT(01) at 2C97:49E2 [?] through 2C97:4918 DISKOMAT(04) at 2C7F:EA20 [?] through 2C7F:EA20 USER(01) at 04A7:19BE [?] through USER!GETWINDOWTEXT == CTL3D(02) at 2C3F:24BE [?] through 04A7:3A3C
Beautiful stack fishing! Do immediately a BPX on babe:EA20. 2C7F:EA35 9A25ABA704 CALL USER!GETWINDOWTEXT 2C7F:EA3A 8D46AE 2C7F:EA3D 16 2C7F:EA3E 50 LEA AX,[BP-52] ;load ptr "+ORC+ORC"
2C7F:EA3F 9A768D872C CALL 2C87:8D76; get strlen "ORC+ORC" 2C7F:EA44 83C404 2C7F:EA47 3D2800 2C7F:EA4A 762C ADD SP,+04 CMP AX,0028 JBE EA78
... 2C7F:EA97 8D46AE 2C7F:EA9A 16 2C7F:EA9B 50 ... LEA AX,[BP-52] PUSH SS PUSH AX ;load ptr "+ORC+ORC"
PUSH SS PUSH CX
2C7F:EABC 9A768D872C CALL 2C87:8D76 ;get strlen "12121212" 2C7F:EAC1 83C404 2C7F:EAC4 50 ADD SP,+04 PUSH AX LEA AX,[BP+FF5C] ;ptr "12121212" HERE!
PUSH SS PUSH AX
OK, it's enough: now obviously follows the code that "algorithmize" the number string, and then, somewhere, you'll have the hideous compare that divides good guys and bad crackers. You could examine, and crack, and search... BUT NOW IT'S THE "MAGIC MOMENT" OF THE ECHO! We know and *feel* it: The echo must be somewhere... how do we find it? Searching "12121212" in memory fishes at least 10 different locations... :s 30:0 lffffffff '12121212'
Pattern Found at 0030:0005AD6A .... (7 more) Pattern Found at 0030:80509D6A Pattern Found at 0030:8145AD6A Should we look for all occurrences of string '12121212', starting with the two at 80000000, dumping +-0x90 around it... until we find the echo? We could, and it would work, but that's not zen... that's boring! In other protections these locations could proliferate on purpose, to deter the casual cracker. There must be some other way... And lo and behold! YES! There is a quicker way... THE LAST loading of the numeric input string in the code (the one after the strlen count) is the "right" one for our cracking purposes, coz protections follow (mostly) this pattern (remember: we are inside a "stack-heavy" section of the code... if you want to crack higher I suggest you read some good literature about stack working, stack tricks and stack magics with the Intel processors): LOAD NAMEString - COUNT NAMEStringLen LOAD NAMEString - TRANSFORM NAMEString LOAD CODEString - COUNT CODEStringLen LOAD CODEString *ECHO must be here* TRANSFORM CODEString *ECHO must be here* COMPARE TRANSFORMED_NAMEString WITH TRANSFORMED_CODEString
This means that at line 2C7F:EAC5 8D865CFF LEA AX,[BP+FF5C] ;ptr "12121212" you'll already have your echo somewhere... just dump the memory around the pointer [BP+FF5C]: :d 2c5f:61e8 ;these numbers will differ in your computer 02 62 2F 06 02 00 26 2E-A3 4E A3 4E 01 00 38 30 .b/...&..N.N..80 33 37 2D 36 34 36 2D 33-38 33 36 00 01 06 02 00 37-646-3836..... 2F 06 75 62 C3 2E B7 04-F2 24 2F 06 CE 6E 2F 06 /.ub.....$/..n/. 49 00 5A 00 01 00-04 2C 2F 06 AE 24 36 62 00 00 I.Z......,/..$6b 74 62 7A 2E B7 04 36 62-01 00 C2 62 2F 2C 26 2E tbz...6b...b/,&. 03 01 BA 0F AE 24 5F 02-C9 01 5E 02 BA 01 5F 02 .....$_...^..._. 31 32 31 32 31 32 31 32-00 0C 00 BC 02 00 00 00 12121212........ 00 49 00 BA 0F-AE 24 F2 24 2F 06 00 00 00 00 00 ....I....$.$/... AF 17 00 E2 5F-7A 62 FE FF 79 1B BA 0F 00 00 00 ......._zb..y... 96 0B 01 00 02 4E 00-37 01 8A 62 D2 0F 8F 17 00 .....N..7..b.... 2F 06 00 37 01-98 62 20 10 16 03 2F 06 00 00 00 /.....7..b .../. C2 62 2B 4F 52 43 2B 4F-52 43 00 0D AE 24 2F 06 .b+ORC+ORC......
Look at this dump: everybody is there! The stack pointers points in the middle, at string "12121212". 0x50 bytes before it you'll find our good old ECHO (i.e. the CORRECT passnumber) and 0x50 bytes afterwards you'll see your handle: here "+ORC+ORC". It's cracked! The code for my "+ORC+ORC" is 8037-646-3836... Now begin your assignments: if you rally want to learn cracking:
- "Unregister" and find anew your own code for your own handle. *DO NOT* use serial numbers with any other name that your own handle, that's miserable stealing, not cracking. I'll begin to punish the serial#_aficionados on the Web, coz I like real outlaws, but I detest stupid pickpockets. - Study the two coding algorithms, the one for the input name and the one for the input number, this will be very useful for your future cracking sessions. - Find the "Compare", i.e. the code that sets the two usual flags "good guy, you may move on" and "bad cracker, beggar off", and - Create a "real" crack for this protection, that will allow anybody you think deserves it, with any name and any password number, to get through.
[CRACKING SNAP 32] Snap 32 (SNAP32.EXE 356.352 bytes, 24/11/95, Version 2.54, by Greg Kochaniak) is a "snapshot" shareware program for Windows 95, that allows users to save the screen, parts of it, or a single window. It's a very common 'try before you buy' program, limited to 30 days use. You'll find it everywhere on the Web. If you do not know how to search the Web (poor guy!), learn at the end of this lesson the correct procedure to find all the files you need on the Net and get them automatically emailed to you
(that's something you should learn: SEARCHING! It's even more important than cracking!). Snap32 is not very interesting (I don't think I used it more than a couple of times), but its protection is: in order to (try to) deter casual crackers it does not compare strings, it compares a "magic" sum (from Namestring) with another magic sum (from Numberstring). And: * SUMS magics inside the GDI, not inside its own code; * USES a look_up table for input validation instead of "plain" code; * COMPARES the "magic" manipulation from input NUMBER with the "magic" manipulation from input NAME.
The cracking procedure for most of these windows programs is pretty simple and relatively straightforward:
1) SEE THE NAME OF YOUR BABE AND ITS QUEUE SELECTOR :task ;This is the Winice95 command you type after firing
TaskName SS:SP
OK, the babe is Snap32,it's HQUEUE is 0xD27, it's TaskDB is 0x27OE, orright.
2) SEE THE MODULES OF YOUR BABE: :map32 snap32 Owner ;Your command Size Type
SNAP32 .text
SNAP32 .rdata 0002 013F:00444000 00002E00 IDATA RO SNAP32 .data 0003 013F:00447000 00009000 IDATA RW
SNAP32 .idata 0004 013F:00471000 00001C00 IDATA RW SNAP32 .rsrc 0005 013F:00473000 00001600 IDATA RO
OK, so the code is in selector 137:(as usual), and you have there 43000 bytes of code from 401000 to 401000+43000; the DATA, ReadWrite and ReadOnly, are in selector 13F: (as usual).
3) SEE THE HANDLE OF THE PROTECTION "NAG" WINDOW :hwnd snap32 ;Your command
Window Handle Hqueue SZ Qowner Class Name Window Procedure 0350(1) 0354(2) 0D27 32 SNAP32 #02071 0D27 32 SNAP32 #02071 144F:0560 17CF:102E
OK, so, for our cracking purposes, it's Handle 0x350. Most of the times the "nag" window you want to crack will be the first one in the hwnd listing (coz it was the last one to appear).
Watch the number in parentheses that follows the Whandle: (1) is a mother, (2) are "children" windows. At times you'll find under "Class Name" something like "Edit" (see before the Winformant cracking)... SNIFF THERE! At times the "Window Procedure" code location in a list of more than twenty, will be slightly different for one or two windows... SNIFF THERE!
4) BREAKPOINT MESSAGE WM_GETTEXT (or any other WM_ that you can think of in order to "pinpoint" the code of our babe). "Pinpointing" the code is extremely important in windows cracking... this idiotic OS moves code, data and stack out and inside the pages all the time... so you'll keep getting on "INVALID" sections without a correct pinpointing. Good Pinpointing points are in general: BMSG xxxx WM_GETTEXT (good for passwords) BMSG xxxx WM_COMMAND (good fro OK buttons) BPRW *your babe* TW (good for tracking) u USER!GETWINDOWTEXT (u and then BPX inside the code) u GETDLGITEM (for the Hwnd of an Item inside a
Dialog Box) CSIP NOT GDI (if you have too many interferences) (bpx with counter occurrence to get to
u USER!SHOWWINDOW
really desperate for pinpointing, just do a BMSG xxxx WM_MOVE and then move the nag window, this will always work. Let's go on:
;Your command
5)RUN THE PROGRAM TO THE BREAKPOINT: CTRL+D ;Your command to exit Winice and run until it pops out at breakpoint OK, now you pop out inside Winice somewhere... (look at the stack to know where) so the code has been pinpointed.
6) SEARCH THE DATA AREA for your input string (4 Gigabytes from 30:0... remember that DATA are *always* in 30:0 to 30:FFFFFFFF and CODE is *always* in 28:0 to 28:FFFFFFFF). In most protection the "registration_number" string must match the "username" string, which cannot be constrained, in order to allow users to choose whatever stupid name they fancy. Some protections requires fixed symbols inside the "username" string, though... in these rare eventualities, just apply to the "username" string what we'll do here with the "registration_number" string. The point to remember is: begin always with the protection fumbling your number, crack only if necessary the protection that fumbles your name. Let's search now.
80000000 is good. Lower era videos, mirrors and BIOS, higher (around C0000000) you have the OS dustbins... the point to remember is: investigate always FIRST the 80000000 locations.
7) BREAKPOINT ON MEMORY RANGE ON THIS STRING. By the way: prepare a watch window dex 3 es:di, you'll soon see how useful such an automated watchwindow is in password cracking.
OK Now we'll begin to dig out the relevant parts of the code. Remember that you must breakpoint *every* copy of the string that protection generates. A typical copy routine, very frequently used in windows copy protection schemes, dwells inside KERNEL!HMEMCPY (+0076):
0117:9E8E 66C1E902 0117:9E92 F36766A5 0117:9E96 6659 0117:9E98 6683E103 0117:9E9C F367A4 0117:9E9F 33D2
SHR
AND
In fact, this piece of copying code is so often used for password verifications that sometimes you just need to bpx on 0117:9E92 to get the correct stack sequence... but let's, for now, continue without such little tricks: just keep on BPRring (Breakpoint on memory range) all copies that protection makes.
8) LET THE BABE RUN, it will breakpoint on all manipulations of your input string. One of them will lead to the magic. 8.1.) VALIDATION phase
There are many routines that check and "validate" your inputs. The most common ones check that your numbers ARE really numbers, i.e. in the range 0x30-0x39. Usually this is done with: CMP EAX,+30 JB no_number CMP EAX,+39 JA no_number At times the protectionists use TABLES instead... The number itself is used as a pointer to a "ready made" table where the relevant magic can be used as a protection. Imagine that a number 4 in your input points to a code section that throws you immediately outside the validation routine... or imagine that a number 7, if found in your input, fetches a magic code that removes the whole program from your harddisk (or worse): "Ah, ah! Stupid cracker will never know that he should not have used
number 4... and definitely not number 7! Next time he'll learn..." Yes, tables have been used for such nasty tricks. Here the relevant code for the "validation" part of our protection (still checking my favourite input string '12121212'): :check_if_valid 0137:4364AE 8A16 0137:4364B0 33C0 MOV XOR DL,[ESI] ;load license number EAX,EAX ;zero AX AX,[ECX+2*EDX] ;look table for 84 EAX,+08 ;OK if AND'S TO zero
0137:4364B2 668B0451 MOV 0137:4364B6 83E008 0137:4364B9 85C0 0137:4364BB 7403 0137:4364BD 46 0137:4364BE EBCD :strip_-_&_+_signs 0137:4364C0 33DB 0137:4364C2 8A1E 0137:4364C4 46 0137:4364C5 8BFB 0137:4364C7 83FB2D 0137:4364CA 7405 0137:4364CC 83FB2B XOR MOV INC ESI AND
TEST EAX,EAX ;and therefore JZ INC JMP 004364C0 ;go on ESI ; ready for next number
0043648D
EBX,EBX ;clean BX BL,[ESI] ;load license number ;ready for next EDI,EBX ;save copy EBX,+2D ;is it a "-"?
MOV CMP JZ
CMP
8.2.)
Your wisely set breakpoints on memory range for the occurrence of the string "12121212" will pop you out, inter alia, inside
following piece of code (note how this part of protection dwells inside GDI, and NOT inside the code selector of snap32): 0557:11BD 33C0 0557:11BF 66648B06 0557:11C3 83C602 XOR EAX,EAX ;zero AX
0557:11C6 66833C4700 CMP WORD PTR [EDI+2*EAX],+00 0557:11CB 0F8424010000 JE 000012F5 0557:11D1 668B0442 0557:11D5 03D8 0557:11D7 49 0557:11D8 75E5 MOV AX,[EDX+2*EAX] ;load from magic table ADD EBX,EAX DEC ECX ;save sum in EBX ;till we are done ;loop along
JNZ 000011BF
Interesting, isn't it? Protection is using this GDI routine to create a SUM (through pointers to another table) that depends on your very input numbers. We are now very near to the crack... can you *feel* it? If not, prepare yourself a good Martini Vodka! This is the correct way to do it: * Get a "highball" glass; * Put some ice cubes inside it (2 or 3); * Add Martini Dry (From Martini & Rossi). Fill to 1/3; * Add Moskowskaja Wodka (the only real Vodka). Fill to 2/3; * Add a zest of lemon (From Malta or Southern France); * Add a green "sound" olive (from Italy or Israel); * Add Schweppes Indian Tonic. Fill to the brim. Sit deeper and relax, sip slowly and *feel* where the code of the
protection scheme you are cracking "moves"... It's like a current... a slow tide. If you still do not believe me, just try it.
We'll now find out where protection stores the "magic" sum (and now you'll pop out inside the very own snap32 code, this is the "real" protection part):
8.3.)
The ludicrous "HIDING" of the magic sum ADD MOV MOV ESP,+04 ECX,[EBP-18] [EBP-10],EAX ;***HERE!***
0137:404387 68FF000000 PUSH 000000FF 0137:40438C 8D8574FBFFFF LEA 0137:404392 50 PUSH EAX EAX,[EBP+FFFFFB74] ;load string ;push it ;manipulate
0137:404393 E886410100 CALL 0041851E 0137:404398 8D8574FBFFFF LEA 0137:40439E 50 PUSH EAX
As you can see, the protection is very simple: The "magic" sum is hidden only two lines before the further manipulations of the input string. We have found location 137:404384, here, in the CORRECT way, through bprring of the string that has been manipulated in the GDI, but actually, we could have found it
quickly just checking superficially what's happening "around" all manipulations of the input string. Do we really need to follow all manipulations of our registration_number and eventually also all manipulation of our username? NO, not at all: we just set a BPR on the stack location where protection hides the sum [EBP-10] and we'll see what happens: 90% of these protections just create two sums, a sum from your username and a sum from your registration_number... somewhere there will be a compare that must use this location (or a copy of it... we'll see).
8.4.) COMPARING THE MAGICS FROM THE TWO INPUT STRING Breakpoint on memory range on the sum location [EBP-10] that you saw in the previous code and you'll land at this piece of code: 0137:404412 E82F050000 CALL 00404946 0137:404417 83C40C 0137:40441A 3B45F0 0137:40441D 740F ADD ESP,+0C CMP EAX,[EBP-10] ;comp AX & magicsum JZ 0040442E
0137:40441F 68C0874400 PUSH 004487C0 0137:404424 E8149E0000 CALL 0040E23D 0137:404429 83C404 0137:40442C EB5B ADD ESP,+04 JMP 00404489
That's it, you have made it! We found the compare between the
"username" magic number (for my "+ORC+ORC" string that's here 0x7C25621B) in AX (we do not need to know how this landed there... it's irrelevant!) and the "license_number" '12121212' (whose magic is here 0x00B8F47C) stored in [pointer-10.] How do we find now the correct INPUT number for +ORC+ORC? Well, it's easy... the "magic number" must be the same... therefore:
Cracked=Dec(0x7C25621B) Cracked=2082824731
That was it. Old Snap32 has been cracked. You could now prepare a crack in order to distribute this program around without its simple protection. Good cracked applications should be given free (i.e. cracked) to all the people that NEED them and do not have the money to buy them. Don't forget that in this intolerable society the 0,5% of the citizens own the 56% of the industrial capital and the 63% of the propaganda machines (data from US researchers... therefore suspect... the real situation is probably even worser) effectively conditioning the destiny of millions of slaves, moronized by television watching. So crack the applications and give them to the people you care and the peolple that need them, but for the others... just EXPLAIN everybody how you did it... this is real help: giving knowledge, not wares. DO NOT use my handle and my codes to crack this program, get yours, I gave you mine only as an help for this
cracking lesson. I have showed you the way enough... THIEFS, not crackers, use the codes that others have found. You are (gonna be) CRACKERS! Remember it, look straight ahead, crack accurately and keep your tommy in.
HOW TO SEARCH THE INTERNET FOR FILES WITHOUT MOVING A FINGER It's amazing: most of the people roaming around inside Internet DO NOT know how to use effectively the web. I'll be very altruistic and explain how to fetch the very example of Snap32, the babe we cracked in this lesson.
1) Choose an archie from this list (I will not explain you what an archie is, you should know it... if you do not, be ashamed): archie.univie.ac.at archie.belnet.be archie.funet.fi 131.130.1.23 193.190.248.18 128.214.6.102 Austria Belgium Finland France Germany
archie.univ-rennes1.fr 129.20.254.2 archie.th-darmstadt.de 130.83.22.1 archie.ac.il archie.unipi.it archie.uninett.no 132.65.16.8 131.114.21.10 128.39.2.20 Israel
Italy Norway
2) Email a message to your archie: To: archie.univie.ac.at (for instance) (nothing on this field)
Subject:
Body:
(substrings too) (max 140 hits) (not the same file all over)
3) After a while you'll get (per email) your answer: Here the answer from the Austrian archie
Host ftp.wu-wien.ac.at (137.208.8.6) Last updated 17:48 9 Aug 1995 Location: /pub/systems/windows.32/misc FILE -rw-r----- 128957 bytes 15:59 16 Jun 1995 snap32.zip Host space.mit.edu (18.75.0.10) Last updated 00:45 4 Mar 1996 Location: /pub/mydir FILE -rw-r--r-- 407040 bytes 11:55 28 Nov 1995 snap32.exe
4) ftpmail your file (Browsing is no good: too busy and lame). Again, I will not explain you what an FTPMAIL server is: learn it by yourself... choose a good one from this list (there are many more... you'll learn): bitftp@vm.gmd.de ftpmail@ieunet.ie bitftp@plearn.edu.pl ftpmail@ftp.sun.ac.za (Germany) (Ireland) (Poland) (South Africa)
To:
ftpmail@ftp.sun.ac.za. (for instance) (leave blank) open space.mit.edu (the last occurrence that
Subject: Body:
the archie sent) cd/pub/mydir bin get snap32.exe quit (bye) (get the correct subdir) (prepare for BINARY) (I want this)
FTP EMAIL response... ftpmail has received the following job from you: reply-to +ORC open space.mit.edu +ORC@now.here get snap32.exe ftpmail has queued your job as: 1834131821.5514 Your priority is 1 (0 = highest, 9 = lowest) Requests to sunsite.doc.ic.ac.uk will be done before other jobs. There are 14 jobs ahead of this one in the queue. 4 ftpmail handlers available.
After a while you'll get a second message, with your file uuencoded inside... everything has been done. YESSIR! there is absolutely no need to loose time on the WWW, "surfing" idiotically from a junk site to the next or waiting hours to download some slow file from an instable server! Wasting time of your own LIFE, that you could use to read poetry, to make love, to look at the stars, to sail slowly between the Aegean islands or to start a nice cracking session. What's the point of wasting your time when machines can perform all the searches you need better, more productively and faster than you ever could... YESSIR! You can get *everything* on the Web, and without paying your Internet provider more than a couple of dimes... Nice, isn't it?
By now, if you have followed all my lessons, you should be able to crack relatively quickly "normal" applications. There are some new projects for 1997: a cracking "university", that will allow us to prepare for the divine war against Microsoft repulsive dominion. If you do not have already chosen your handle (your "cracker" name, that's it), you may consider choosing an handle with a "+" somewhere inside it or, eventually, add a "+" to your handle. This sign is used by me and by friends that have studied
and/or contributed. But a "+" in your handle ("official +ORC cracker") will mean even more: 1) allows support from me personally (on a "do ut des" basis) 2) allows pupils to identify each other (good for joining forces) 3) will open you (eventually) the doors to the "higher" cracking university I'll set up on the Web in 1997. (I'm not getting megalomaniac... In reality I only need a "quick" method to know on which (anonymous) people I can count on for the next phase).
Well, that's it for this lesson, reader. Not all lessons of my tutorial are on the Web. You 'll obtain the missing lessons IF AND ONLY IF you mail me back (via anon.penet.fi) with some tricks of the trade I may not know that YOU discovered. Mostly I'll actually know them already, but if they are really new you'll be given full credit, and even if they are not, should I judge that you "rediscovered" them with your work, or that you actually did good work on them, I'll send you the remaining lessons nevertheless. Your suggestions and critics on the whole crap I wrote are also welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
site's internal network and the wild and woolly Internet where
have to deal with the same problem we have: getting OUT through
------------>
What is a Firewall?
travel between the server and the client. This provides a way to
the policy of the site, the firewall must make sure that all
cracking attempts
------------>
Types of Firewall
represent the basic forms; most other firewalls employ the same
from one network (the Internet) to the other (the internal net
than communicating directly, the client and the server both talk
A proxy on the bastion host does not just allow free rein
The use of proxy software on the bastion host means that the
platforms, PC, Sun, IBM, DEC, HP...) and a great burden for
to the internal net such that the bastion host is the only
machine that can be reached from the outside. Unlike the dual-
get into.
on the bastion host. Further, it may allow that traffic only FROM
SPECIFIC EXTERNAL HOSTS. For example the router may allow Usenet
you can crack not only the bastion host, but also the inner
lot of back doors and bugs, that you'll find in the appropriate
example of how you could crack in this way, read the whole
is good": the bigger the software package, the more chance that
we can find some security related bugs... and all packages are
Delphy!
Finally, remember that the logs are 'mostly) not on the bastion
The dual-homed gateway and the screened host are probably the
1) The CERN Web server handles not only HTTP but also the other
protocols that Web clients use and makes the remote connections,
environment variables.
/pub/security/socks.cstc/socks.cstc.4.2.tar.gz
The toolkit contains many useful tools for cracking firewall and
sendmail).
/pub/firewalls/toolkit/fwtk.tar.Z
The popular PC firewall solution is the "PC Socks Pack", for MS-
file.
to allow anonymous ftp on and from the inner net, and full of
archie server and "spoof" the firewall into believing that you
are the archie server. You'll need the help of a fellow hacker
you can send packets from port 20, and that in a screened host
/dist/internet_security/berferd.ps
correct zen-cracking: you must *FEEL* that some code (or that
------------>
Some suggestions have been given above, but teaching you how
believe you can crack it without knowing nothing at all. So, for
your sake, I'll teach you HOW TO LEARN IT, not HOW TO DO IT
above. For text, start with Marcus Ranum's paper "Thinking about
others.
You can find for free on the web quite a lot of early
small BBS which uses a firewall version you already studied very
do not know nothing about the software they use). As soon as you
If you feel ready and everything went well so far, if your zen-
ahead! You will then be able to try your luck on the Cyberspace
and get quickly busted (if you did not follow my admonitions and
jewels... :=)
------------->
viewed as a door or window in the walls. Not all these doors have
secure and reliable locks. The more openings are available, the
------------->
criteria.
* Terminal type
------------->
MOUNT
(firewalled) net will take your claim at face value and send you
will find you out pretty quickly if you do not). The best method
You 'll obtain the missing lessons IF AND ONLY IF you mail
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,
welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
--------------------------------------
[BARCODES] First of all, let me stress the importance of cracking in our everyday life. Cracking it's not just about software, it's about information, about all patterns of life. To crack is to refuse to be controlled and used by others, to crack is to be free. But you must also be yourself free from petty conventions in order to crack properly. You must learn to discerne cracking possibilities all around yourself, and believe me, the development of this ghastly society brings every day new codes, protections and concealing mechanismes.
All around us grows a world of codes and secret and not so secret patterns. Codes that are at times so familiar and common that we do not even notice them any more... and yet they are there to fool us, and yet they offer marvellous cracking possibilities. Let's take as an striking example BARCODES... those little lines that you see on any book you buy, on any bottle you get, on any item around you... do you know how they work? If you do not you may be excused, but you cannot be excused if you never had the impulse to understand them... crackers are curious by nature... heirs of an almost extinct race of researchers that has nothing in common with the television slaves and the publicity and trend zombies around us. Cracker should always be capable of going beyond the obvious, seek knowledge where others do not see and do not venture.
[BARCODE HISTORY] Let's begin with a little history. Universal Product Code (UPC) was adopted for commercial use by the grocery industry in the USA. Among the advantages were a rapid, accurate and reliable way of entering stock information into a computer and the possibility to sack a lot of workers and to do more profit. The early success led to the development of the European Article Numbering System (EAN), a symbology similar to UPC, that is widely used in Europe and in the rest of the World. I'll teach
you to crack this one, since I do not -fortunately- live in the States. Keep in mind, anyway, that there are different barcode symbologies, each with its own particular pattern of bars. The UPC/EAN code used on retail products is an all-numeric code; so is the Interleaved 2 of 5 Code. Code 39 includes upper case letters, digits, and a few symbols. Code 128 includes every printable and unprintable ASCII character code. The most new one is a 2-D code. These are special rectangular codes, called stacked barcodes or matrix codes. They can store considerably more information than a standard barcode. They require special readers which cost more than a standard scanner. The practical limit for a standard barcode depends on a number of factors, but 20 to 25 characters is an approximate maximum. For applications that need more data, matrix codes are used. For example, the next time you receive a package from United Parcel Service look for a small square label with a pattern of dots and a small bullseye in the centre. This is a MaxiCode label, and it is used by UPS for automatic destination sortition. The manufacturer's ID number on the barcode uniquely identifies products. These numbers are managed by the Uniform Code Council in Dayton, Ohio for the States and Canada and by the EAN authority (Internationale Article Numbering Association) in Bruxelles, for Europe and the rest of the World. The manufacturer's ID number accounts for some digits of the code, which leaves other digits to be assigned in any way the producer
wants. He provides retail outlets with a list of his products and their assigned codes so that they can be entered in the cash register system. Many codes are NOT on the products and are added by the supermarkets on the fly, using an internal code schema that may be non standard. Now it's enough... let's crack. BARCODES are the only thing an automated casher needs to see on a product to calculate its price and automatically catalogate the sold merchandise... imagine (just imagine it :=) coz it would be extremely illegal to act in this way) somebody would fasten an adhesive home-made codebar label direct on the top of the supermarket/mall/retail store label, say on a bottle of Pomerol (that's a very good but unfortunately very expensive french wine). The new label would mean for the casher something like "cheap wine from Bordeaux, France, cost so and so, everything it's OK, do not worry"... do you think that anybody would come to the idea that there is something wrong with the label, with the bottle or with you? I have been codebaring for years and had only once a problem, coz my printer was running out of ink and the scanner in the supermarket could not read it... so what? Act uninterested, always wear jackets of the utmost quality, shetland pullovers and beautiful expensive shoes... (all articles that you may codebar too, by the way), in this society appearance and look count much more than substance and knowledge... LET'S USE THIS TO OUR ADVANTAGE! Nobody will ever come to the idea that you may
actually really know the working of the scheme... coz codebar is pretty complicated and not exactly exceptionally public. On the Web there are a lot information about it, but most of them are useless, unless you know how to search most of the time you'll find only sentences like this one: "The calculated check digit is the twelfth and final digit in the U.P.C.code. It is calculated based on a specific algorithm, and is necessary to ensure that the number is read or key-entered correctly."
But good +ORC will now explain you everything you need to crack:
[THE 13 BAR "CODES"] Each barcode label has 13 values, from #0 to #12 (that's the EAN code, the UPC american one has only 12, from #0 to #11). #0 and #1 indicate the origin of the product. #2 to #11 give the article code #12 (the last and 13th one) is a checksum value, that verifies the validity of all the other numbers. How is it calculated? #12 is calculated in 4 steps VALUE A: You sum odd position numbers (#0+#2+#4+#6+#8+#10) VALUE B: You sum even position numbers and multiply by 3 ((#1+#3+#5+#7+#9+#11)*3) VALUE C: You sum value A and value B VALUE D: You mod value C (you divide by 10 and only keep
the remaining units, a very widespread checking scheme as you'll see in the software part of this lesson) If the result is not zero, you subtract it from 10. Now look at a barcode label, get some books or other barcoded items and *watch* it... Bar codes are supposed to have "quiet zones" on either side of the symbol. Quiet zones are blank areas, free of any printing or marks,typically 10 times the width of the narrowest bar or space in the bar code. Failure to allow adequate space on either side of the symbol for quiet zones can make it impossible to read the bar code. On the barcode there are two "borders", left and right, and a "middle" longer line. These three lines are longer than the others and are used to "regulate" the scanner to whatever dimension has been used for the barcode. #0 dwells left of the first (left) border and has a special meaning, the other 12 numbers are written "inside" the code and are divided in two "groups" by the middle bar. Each value is coded through SEVEN bars: black=1 and White=0. These form two couples of "optic" bars of different widths. We come now to the "magic" part: In order to bluff the simpletons, barcode uses three different SETS of characters to represent the values 0-9. This should make it impossible for you to understand what's going on, as usual, in this society, slaves should not need to worry with the real functioning of things.
CODE A
CODE B (XOR C) CODE C (NOT A) 0100111 (39) 1110010 (114) 0110011 (51) 1100110 (102) 0011011 (27) 1101100 (108) 0100001 (33) 1000010 (066) 0011101 (29) 1011100 (092) 0111001 (57) 1001110 (078) 0000101 (05) 1010000 (080) 0010001 (17) 1000100 (068) 0001001 (09) 1001000 (072) 0010111 (23) 1110100 (116)
0: 0001101 (13) 1: 0011001 (25) 2: 0010011 (19) 3: 0111101 (61) 4: 0100011 (35) 5: 0110001 (49) 6: 0101111 (47) 7: 0111011 (59) 8: 0110111 (55) 9: 0001011 (11)
Borders: Centre:
101 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 1 2 3 4 5 6 7 8 9 A A A A A A A A B A B B A A B B A B A A B B B A A B A A B B A B B A A B A B B B A A A B A B A B A B A B B A 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
OK, one more example: Osborne Windows programming series Volume 2 General purpose API functions (always here on my table)... BARCODE: 9 7 80078 81991 9 Let's see: we have a 9 7 8 = book Then a 780078 as ABBABA and a 819919 as C "Even" sum: 9+8+5+8+8+4 = 42 (even sum) Then a 7+1+5+2+4+4= 23 and 23 * 3 = 69 (odd sum) Then a 42+69=111 111 === 1 10 - 1 = 9 = checksum Pattern = 9 = ABBABA
Well... what's the point of all this? The point, my pupils, is that who DOES NOT KNOW is taken along on a boat ride, who KNOWS and LEARNS can use his knowledge in order to try to beat blue and black the loathsome consumistic oligarchy where we are compelled to live. Try it out for yourself... if you crack correctly and wisely your supermarket, mall and library bills will be cut to almost zero. Write a small program to print whichever codebar you fancy (or whichever your mall uses) in whichever size on whichever sort of label you (or better your targets) fancy... it's quickly done
with Visualbasic or Delphy... but you'll not find much on the Web Alternatively you could also write, as I did long ago, a short c program in dos, using a modified upper char set... and there you are, have labels... see the world. A small word of caution... crack only ONE item at time and try it out first with the SAME label for the same product... i.e. the correct code for that item, but on your own label. If it goes through your program works good, if not, nobody will ever be able to harm you. Anyway it never happens anything, never: the bar code reading equipments have great tolerance, coz the scanners must be able to recognize barcodes that have been printed on many different medias. You should choose labels similar to the ones effectively used only in order not to arise human suspects, coz for all the scanner itself cares, your label could be pink with green stripes and with orange hand-written, numbers. Mind you, we are still just academically imagining hypothetical situations, coz it would be extremely illegal to act in such an inconsiderate manner. CRACKING POWER! It's true for barcodes, for Telecom bills, for Compuserve accounts, for Amexco cards, for banking cheques (do you know what MICR is? Magnetic Ink Character Recognition... the stylized little printing on the lower left of new cheques... there is a whole cracking school working on it), for registration numbers... you name it, they develope it, we crack it... Begin with barcodes: it's easy, nice and pretty useful! Live
in opulence, with the dignity and affluence that should always distinguish real crackers. Besides... you should see the assortment of 'Pomerols' in my "Cave-a-vin" :=)
[INSTANT ACCESS] The (c) Instant access routines are a commercial protection scheme used to "unlock" complete commercial applications that have been encrypted on CDROMs which are distributed (mostly) through reviews. This is an ideal cracking target: it's commercial software, complete, uncrippled and of (relatively) prominent quality, that you can get in tons for the price of a coke. Obviously this kind of protection represents an ideal subject for our lessons. This fairly intricate protection scheme has not yet been cracked by anybody that I am aware of, anyway not publicly, therefore it's an ideal candidate for a "strainer" to my university. I'll teach you here how to crack it in three lessons, C.1, C.2 and C.3. I warn you... it's a difficult cracking session, and this protection represents quite an intellectual challenge. But if you are seriously interested in our trade you will enjoy these lessons more than anything else. This cracking is intended as an "assignment" for my +HCU "cracking university": you'll find inside lessons C.1 and C.2 a relatively deep "introduction" to Instant access cracking. This will teach you a lot anyway, and spare you hours of useless
roaming around, bringing you straight to the cracking point. But I'll release the third part of this session, with the complete solution (lesson C.3) on the Web only in october 1996, not a day before. All the students that would like to apply to the Higher Cracking University, opening on the web 01/01/1997, should work in July, August and September (three months is more than enough time) on this assignment. They should crack completely the instant access scheme and send me their solutions, with a good documentation of their cracking sessions, before 30/09/1996 (WATCH IT! You can crack this scheme in -at least- three different paths, be careful and choose the *best* one. WATCH IT! Some of the informations) in lesson C.1 and C.2 are slightly incorrect: check it!). There are four possibilities: 1) The candidate has not found the crack or his solution is not enough documented or not enough viable... the candidate is therefore not (yet) crack-able, he will not be admitted to the +HCU 1997 curses, better luck in 1998; 2) The cracking solution proposed by the candidate is not as good as mine (you'll judge for yourself in october) but it works nevertheless... he'll be admitted at the 1997 courses; 3) The cracking solution of the candidate is more or less equal to mine, he'll be admitted, personally monitored, and he'll get all the material he needs to crack on higher
paths; 4) The cracking solution of the candidate is better than mine, he'll be admitted, get all the material he wishes and asked to teach us as well as study with us: "homines, dum docent, discunt".
[Cracking Instant access] The user that wants to "unlock" a software application protected with (c) Instant Access must enter first of all a REGISTRATION number string, which through a series of mathematical manipulations gives birth to a special "product" code. On the basis of this "product code" the user is asked to phone the commercial protectors (and pay) in order to get a special "unlock code" that will allow him to decrypt the relevant software. This kind of "passnumber" protection routines are widely used for software unlocking, BBS access, server access, backdoor opening and many other protection schemes. We have already seen password cracks in different lessons of this tutorial (in particular Lessons 3.1 and 3.2 for DOS and Lessons 8.1, 8.2 and 9.1 for WIN) albeit on a more simplistic scale: there it did mostly not matter very much *HOW* you passed the protection: once passed, you could have access to the application. This is not the case with (c) Instant Access. Face it: it's a little boring, but important that you learn how to defeat intricate protection
routines (you'll meet them often in the next years) and I believe that the following example will give you a "feeling" for the right cracking approach. In this case we must not only "crack" this protection scheme but also study it thoroughly in order to achieve our blessed aims. This is a very good exercise: reverse disassembling will teach you a lot of little tricks that you'll be able to use in your other future cracking sessions. Instant access (c) is a exceptionally widespread protection scheme, and it should be relatively easy for you to gather some encrypted software that has been protected with this method... *DO IT QUICKLY!!* After the Web publishing of this lessons (I am sending C.1 to 8 pages and 4 usenet groups on 25/06/1996) this protection is obviously as dead as a Dodo. The "Accessors" guys will have to conceive something smarter if they want to keep selling "protections" to the lamer producers of "big" software. BTW, if you are reading this and are working for some commercial "protection" company, consider the possibility to double cross your masters! Deliver me anonymously all the future projects you are working on! That will amuse me, speed up the advent of a true altruistic society and earn you the respect of the better part of humanity. As I said, many "huge" application are still protected with this "Instant access" system. I have personally bought at least 7 or 8 "second hand" CD-ROMs packed full with Microsoft, Lotus,
Norton, Symantec, you name it, applications all "protected" through this crap. The cost of this bunch of CD-ROMs was the equivalent of a bottle of Dry Martini, maybe less. The same software is sold, unlocked, to zombies and lusers for ludicrous amounts of money. Never buy CD-ROMs magazines when they appear! Be cool! Buy them two or three months after the publishing date! Buy "remainders" or "second hand" CD-ROM magazines "at kilo price"... Come to think of it, never buy *anything* when it appears or when some (paid) advertiser tells you to... remember that "trends", "vogues", "fashions" and "modes" are only different names for the whips that drill and chain the dull-witted slaves of this loathsome society: "clever crackers consider cool, crack cheap, cheat customary culture" (a rhetorical figure: an "Alliteration". To defend yourself learn rhetoric... it's a more powerful and more useful weapon than Kung-fu). The "triple" password protection routine in (c) Instant Access is very interesting from a cracker point of view. It's a relatively complex scheme: I'll teach you to crack it in two phases: First of all you must find the "allowed" registration code, the one that "ignites" the "product code". We must crack and understand this re_code first if we want to crack the rest. Just for the records, I am cracking here (c) Action Instant access version 1.0 (CD-ROM found on a old copy of "Personal Computer World" of August 1994, packed full with encrypted Lotus,
Symantec, Claris and Wordperfect applications. Just to be sure I crosschecked my results with another CD-ROM which also has applications protected with (c) Instant Access: Paragon Publishing's PC OFFICE: the protection scheme remains the same). I am focusing for this lesson on the cracking of the specific protection for the encrypted Symantec's Norton Utilities v.8.0. Please refer to the previous lessons for the basic techniques used in order to find the protection routine inside our babe... for "low" cracking purposes you -basically- type a number (in this case, where the input gets 10 numbers, we'll use "1212-1212-12"), do your search inside the memory (s 30:0 lffffffff "your_string") and then set memory breakpoints on all the relevant memory locations till winice pops (I know, I know, buddies... there are more effective ways... but hold your mouth: for now we'll keep them among us: let's make things a little harder for the protectionists who read this... Besides: the old approach works here flawlessly). After getting the Registration window on screen the Winice standard procedure is: :task :heap IABROWSE :hwnd IABROWSE ; how ; where & what ; get the Winhandle
:bpx [winhandle] WM_GETTEXT ; pinpoint code :bpx GetProcAddress :dex 0 ds:dx :gdt ; ; in case of funny routines let's see their name
:s 30:0 lffffffff "Your_input_string" ; search in 4 giga data :bpr [all memory ranges for your string that are above 80000000] and so on. (continued in lesson C.2)
Well, that's it for this lesson, reader. Not all lessons of my tutorial are on the Web. You 'll obtain the missing lessons IF AND ONLY IF you mail me back (via anon.penet.fi) with some tricks of the trade I may not know that YOU discovered. Mostly I'll actually know them already, but if they are really new you'll be given full credit, and even if they are not, should I judge that you rediscovered them with your work, or that you actually did good work on them, I'll send you the remaining lessons nevertheless. Your suggestions and critics on the whole crap I wrote are also welcomed.
E-mail +ORC
---------------------------------------------------------------------------
---------------------------------------------------------------------------
[INSTANT ACCESS]
--------------------------------------
[SEE LESSON C.1 for the first part of this cracking session] Here follow the relevant protection routines for the first (The "Registration") number_code of Instant Access, with my comments: you have to investigate a little the following code. Later, when you'll crack on your own, try to recognize the many routines that fiddle with input BEFORE the relevant (real protection) one. In this case, for instance, a routine checks the correctness of the numbers of your input:
This_loop_checks_that_numbers_are_numbers: 1B0F:2B00 C45E06 LES BX,[BP+06] ; set/reset pointer 1B0F:2B03 03DF ADD BX,DI
1B0F:2B05 268A07 MOV AL,ES:[BX] ; get number 1B0F:2B08 8846FD MOV [BP-03],AL ; store 1B0F:2B0B 807EFD30 CMP BYTE PTR [BP-03],30 1B0F:2B0F 7C06 JL 2B17 ; less than zero?
1B0F:2B15 7E05
JLE 2B1C
1B0F:2B17 B80100 MOV AX,0001 1B0F:2B1A EB02 1B0F:2B1C 33C0 1B0F:2B1E 0BC0 1B0F:2B20 7507 JMP 2B1E XOR AX,AX OR AX,AX
JNZ 2B29
1B0F:2B22 8A46FD MOV AL,[BP-03] ; Ok, get number 1B0F:2B25 8842CC MOV [BP+SI-34],AL ; Ok, store number 1B0F:2B28 46 1B0F:2B29 47 INC SI INC DI ; inc storespace ; inc counter
1B0F:2B2A C45E06 LES BX,[BP+06] ; reset pointer 1B0F:2B2D 03DF ADD BX,DI ; point next number
1B0F:2B2F 26803F00 CMP BYTE PTR ES:[BX],00 ; input end? 1B0F:2B33 75CB JNZ 2B00 ; no:loop next num
You now obviously understand that the "real" string is stored inside memory location [BP+SI-34]... set a memory breakpoint on this area to get the next block of code that fiddles with the transformed input. Notice how this routine "normalizes" the input, strips the "-" off and puts the 10 numbers together: user input: 1 2 1 2 1 2 1 2 1 2 End 1E7F:92E2 31 32 31 32 31 32 31 32 31 32 00 45 AF 1F 70 9B Stack ptr: 0 1 2 3 4 5 6 7 8 9 A B C D E F Let's now look at the "real" protection routine: the one
that checks these numbers and throw you out if they are not "sound". Please pay attention to the following block of code:
check_if_sum_other_9_numbers_=_remainder_of_the_third_number: :4B79 8CD0 :4B7B 90 :4B7C 45 :4B7D 55 :4B7E 8BEC :4B80 1E :4B81 8ED8 :4B83 83EC04 :4B86 C45E06 :4B89 268A07 :4B8C 98 MOV AX,SS ; we'll work inside the stack... NOP INC BP PUSH BP ; save real BP MOV BP,SP ; BP = stackpointer PUSH DS ; save real Datasegment MOV DS,AX ; Datasegment = stacksegment SUB SP,+04 LES BX,[BP+06] ; BX points input_start MOV AL,ES:[BX] ; load first number ; care only for low
CBW
PUSH AX
:4B91 268A4701 MOV AL,ES:[BX+01] ; load 2nd number :4B95 98 :4B96 8BD0 :4B98 58 :4B99 03C2 :4B9B C45E06 :4B9E 50 CBW ; only low ; 2nd number in DX
ADD AX,DX
PUSH AX
CBW
ADD AX,DX
:4BAD 268A4703 MOV AL,ES:[BX+03] ; load 4rd number :4BB1 98 :4BB2 8BD0 :4BB4 58 :4BB5 03C2 :4BB7 C45E06 :4BBA 50 CBW ; only low ; #4 in DX
ADD AX,DX
:4BBB 268A4704 MOV AL,ES:[BX+04] ; load 5th number :4BBF 98 :4BC0 8BD0 :4BC2 58 :4BC3 03C2 :4BC5 C45E06 :4BC8 50 CBW ; only low ; #5 in DX
ADD AX,DX
PUSH AX
:4BC9 268A4705 MOV AL,ES:[BX+05] ; load 6th number :4BCD 98 :4BCE 8BD0 :4BD0 58 :4BD1 03C2 CBW ; only low ; #6 in DX
ADD AX,DX
PUSH AX
:4BD7 268A4706 MOV AL,ES:[BX+06] ; load 7th number :4BDB 98 :4BDC 8BD0 :4BDE 58 :4BDF 03C2 :4BE1 C45E06 :4BE4 50 CBW ; only low ; #7 in DX
ADD AX,DX
PUSH AX
:4BE5 268A4708 MOV AL,ES:[BX+08] ; load 9th number :4BE9 98 :4BEA 8BD0 :4BEC 58 :4BED 03C2 :4BEF C45E06 :4BF2 50 CBW ; only low ; #9 in DX
ADD AX,DX
:4BF3 268A4709 MOV AL,ES:[BX+09] ; load 10th # :4BF7 98 :4BF8 8BD0 :4BFA 58 :4BFB 03C2 :4BFD 0550FE :4C00 BB0A00 :4C03 99 :4C04 F7FB CBW ; only low ; #10 in DX
ADD AX,DX
ADD AX,FE50 ; clean sum to 0-51 MOV BX,000A ; BX holds 10 ; only AL ; remainder in DX
CWD IDIV BX
:4C06 C45E06
:4C09 268A4702 MOV AL,ES:[BX+02] ; load now # 3 :4C0D 98 :4C0E 05D0FF :4C11 3BD0 :4C13 7407 :4C15 33D2 :4C17 33C0 :4C19 E91701 CBW ; only low
ADD AX,FFD0 ; clean # 3 to 0-9 CMP DX,AX ; remainder = pampered #3? JZ 4C1C ; yes, go on good guy
XOR DX,DX ; no! beggar off! Zero DX XOR AX,AX ; JMP 4D33 and FLAG_AX = FALSE ; go to EXIT
:4C1F 268A4701 MOV AL,ES:[BX+01] ; now load #2 anew :4C23 98 CBW ; only low
ADD AX,FFD7 ; pamper adding +3 MOV [5E8D],AX ; save SEC_+3 CMP AX,0009 ; was it < 9? (no A-F) JLE 4C34 ; ok, no 0xletter
:4C2F 832E8D5E0A SUB WORD PTR [5E8D],+0A ; 0-5 if A-F :4C34 C45E06 :4C37 268A07 :4C3A 98 :4C3B 05C9FF :4C3E A38F5E :4C41 0BC0 :4C43 7D05 LES BX,[BP+06] ; reset pointer MOV AL,ES:[BX] ; load 1st input number CBW ; only low
ADD AX,FFC9 ; pamper adding +7 MOV [5E8F],AX ; save it in FIR_+7 OR AX,AX ; if #1 > 7 ; no need to add 0xA
JGE 4C4A
:4C45 83068F5E0A ADD WORD PTR [5E8F],+0A ; FIR_+7 + 0xA now_we_have_the_sliders_let's_prepare_for_loop: :4C4A C45E0E LES BX,[BP+0E] ; Set pointer to E
:4C4D 26C747020000 MOV WORD PTR ES:[BX+02],0000 ; 0 flag :4C53 26C7070000 MOV WORD PTR ES:[BX],0000 ; 0 flag :4C58 C706975E0900 MOV WORD PTR [5E97],0009 :4C5E E99500 loop_8_times: :4C61 C45E06 LES BX,[BP+06] ; reset pointer JMP 4CF6 ; Jmp check_counter ; counter=9
:4C64 031E975E ADD BX,[5E97] ; add running counter :4C68 268A07 :4C6B 98 :4C6C 50 MOV AL,ES:[BX] ; load # counter+1 ; only low ; save 10th number
CBW PUSH AX
MOV AX,[5E8D] ; ld SEC_+3 down_slider MOV DX,000A ; BX holds 0xA IMUL DX ; SEC_+3 * 0xA
:4C75 03068F5E ADD AX,[5E8F] ; plus FIR_+7 up_slider :4C79 BAA71E :4C7C 8BD8 :4C7E 8EC2 MOV DX,1EA7 ; fixed segment MOV BX,AX ; BX = Lkup_val=(SEC_+3*10+FIR_+7) MOV ES,DX ; ES = 1EA7
:4C80 268A870000 MOV AL,ES:[BX+0000] ; ld 1EA7:[Lkup_val] :4C85 98 :4C86 8BD0 :4C88 58 :4C89 03C2 CBW ; only low: KEY_PAR ; save KEY_PAR in DX
ADD AX,DX
:4C8B 05D0FF :4C8E 99 :4C8F 8956FC :4C92 8946FA :4C95 0BD2 :4C97 7C0F :4C99 7F05 :4C9B 3D0900 :4C9E 7608
CWD
MOV [BP-04],DX ; save here KEY_PAR [9548] MOV [BP-06],AX ; save here RE_SULT [9546] OR JL JG DX,DX 4CA8 4CA0 ; KEY_PAR < 0? ; yes: KEY_PAR < 0 ; no: KEY_PAR > 0
:4CA0 836EFA0A SUB WORD PTR [BP-06],+0A ; else pamper :4CA4 835EFC00 SBB WORD PTR [BP-04],+00 ; and SBB [9548] :4CA8 C45E0E LES BX,[BP+0E] ; reset pointer to E
:4CAB 268B4F02 MOV CX,ES:[BX+02] ; charge CX [958C] :4CAF 268B1F :4CB2 33D2 :4CB4 B80A00 MOV BX,ES:[BX] ; charge BX slider [958A] XOR DX,DX ; clear DX to zero
MOV AX,000A ; 10 in AX
This is the only routine called from our protection, inside the loop (therefore 8 times), disassembly from WCB. Examining this code please remember that we entered here with following configuration: DX=0, AX=0xA, CX=[958C] and BX=[958A]... 1.0D93 56 1.0D94 96 1.0D95 92 push si ; save si
1.0D96 85C0 test ax, ax ; TEST this zero 1.0D98 7402 je 0D9C ; zero only 1st time ; BX slider! 0/9/5E/3B2...
1.0D9C >E305 jcxz 0DA3 ; cx=0? don't multiply! 1.0D9E 91 xchg ax, cx ; cx !=0? cx = ax & ax = cx ; ax*0xA in ax
1.0DA1 03C1 add ax, cx ; ax= ax*0xA+cx = M_ULT 1.0DA3 >96 xchg ax, si ; ax=0xA; si evtl. holds M_ULT ; ax= bx*0xA
1.0DA6 03D6 add dx, si ; dx= dx_add 1.0DA8 5E 1.0DA9 CB pop si retf ; restore si ; back to caller with two parameters: DX and AX Back_to_main_protection_loop_from_RO_routine: :4CBC C45E0E LES BX,[BP+0E] ; reset pointer
:4CBF 26895702 MOV ES:[BX+02],DX ; save R_DX par [958C] :4CC3 268907 :4CC6 0346FA :4CC9 1356FC :4CCC C45E0E MOV ES:[BX],AX ; save R_AX par [958A]
ADD AX,[BP-06] ; add to AX RE_SULT [9546] ADC DX,[BP-04] ; add to DX KEY_PAR [9548] LES BX,[BP+0E] ; reset pointer
:4CCF 26895702 MOV ES:[BX+02],DX ; save R_DX+KEY_PAR [958C] :4CD3 268907 MOV ES:[BX],AX ; save R_AX+RE_SULT [958A]
:4CD6 FF0E8D5E DEC WORD PTR [5E8D] ; down_slide SEC_+3 :4CDA 7D05 JGE 4CE1 ; no need to add
:4CE1 FF068F5E INC WORD PTR [5E8F] ; up_slide FIR_+7 :4CE5 A18F5E :4CE8 3D0900 :4CEB 7E05 MOV AX,[5E8F] ; save upslided FIR_+7 in AX CMP AX,0009 ; is it over 9? JLE 4CF2 ; no, go on
:4CED 832E8F5E0A SUB WORD PTR [5E8F],+0A ; yes, pamper -10 :4CF2 FF0E975E DEC WORD PTR [5E97] ; decrease loop counter check_loop_counter: :4CF6 833E975E03 CMP WORD PTR [5E97],+03 ; counter = 3? :4CFB 7C03 :4CFD E961FF loop_is_ended: :4D00 C45E06 LES BX,[BP+06] ; reset pointer to input JL 4D00 ; finish if counter under 3 ; not yet, loop_next_count
JMP 4C61
:4D03 268A4701 MOV AL,ES:[BX+01] ; load 2nd number (2) :4D07 98 CBW ; only low
PUSH AX
:4D14 268A07 :4D17 98 :4D18 8BD0 :4D1A 58 :4D1B 03C2 :4D1D 05D0FF
CBW
ADD AX,DX
:4D20 99
CWD
; only low
:4D21 C45E0A
:4D24 26895702 MOV ES:[BX+02],DX ; save 1st (1) in [9584] :4D28 268907 :4D2B 33D2 :4D2D B80100 :4D30 E9E6FE EXIT: :4D33 59 :4D34 59 :4D35 1F :4D36 5D :4D37 4D :4D38 CB POP CX POP CX POP DS POP BP DEC BP RETF ; pop everything and ; return with flag ; AX=TRUE if RegNum OK ; with 1st # in [9584] MOV ES:[BX],AX ; save FINAL_SUM (15) [9582] XOR DX,DX ; DX = 0
Let's translate the preceding code: first of all the pointers: At line :4B86 we have the first of a long list of stack ptrs: LES BX,[BP+06] This stack pointer points to the beginning of the input string, which, once polished from the "-", has now a length of 10 bytes, concluded by a 00 fence. At the beginning, before the main loop, 9 out of our 10 numbers are added, all but the third one. Notice that protection has jumped # 3 (and added # 8 out of the line). The rest is straightforward. Now, at line :4BFD we have our first "cleaning" instruction. You see: the numbers are
hexadecimal represented by the codes 0x30 to 0x39. If you add FE50 to the minimum sum you can get adding 9 numbers (0x30*9 = 0x160) You get 0. The maximum you could have adding 9 numbers, on the contrary is (0x39*9=0x201), which, added to FE50 gives 0x51. So we'll have a "magic" number between 0x0 and 0x51 instead of a number between 0x160 and 0x201. Protection pampers this result, and retains only the last ciffer: 0-9. Then protection divides this number through 0xA, and what happens? DX get's the REMAINDER of it. If we sum the hexcodes of our (1212-1212-12) we get 0x1BE (we sum only 9 out of then numbers: the third "1" -i.e. "31"- does not comes into our count); 0x1BE, cleaned and pampered gives E. Therefore (0xE/0xA = 1) We get 1 with a remainder of 4. You may observe that of all possible answers, only sums finishing with A, B, C, D, E or F give 1 (and rem=0,1,2,3,4 or 5). Sums finishing 0 1 2 3 4 5 6 7 8 or 9 give 0 as result and themselves as reminder. The chance of getting a 0,1,2,3 or 4 are therefore bigger as the chance of getting a 5, 6, 7, 8 or 9. We are just observing... we do not know yet if this should play a role or not. Now this remainder is compared at :4C11 with the third number polished from 0x30-0x39 to 0-9. This is the only protection check for the registration number input: If your third number does not match with the remainder of the sum of all the 9 others numbers of your input you are immediately thrown out with FLAG AX=FALSE
(i.e. zero). To crack the protection you now have to MODIFY your input string accordingly. Our new input string will from now on be "1242-121212": we have changed our third number (originally a "2") to a "4" to get through this first strainer in the correct way. Only now protection starts its mathematical part (We do not know yet why it does it... in order to seed the random product number? To provide a check for the registration number you'll input at the end? We'll see). - Protection saves the second number of your input (cleaned with FFD7) in SEC_+3 [5E8D], pampering it if it is bigger than 9 (i.e. if it is 0xA-0xF). Here you'll have therefore following correspondence: 0=7 1=8 2=9 3=0 4=1 5=2 6=3 7=4 8=5 9=6. The second number of your input has got added +3. This is value SEC_+3. In (lengthy) C it would look like this: If (RegString(2)is lower than 7) RegString(2) = RegString(2)+3 Else Regstring(2) = ((RegString(2)-10)+3) - Protection saves your first number in FIR_+7 [5E8F] with a different cleaning parameter (FFC9). The next pampering adds 0xA if it was not 7/8/9 therefore you have here following correspondence 7=0 8=1 9=2 0=3 1=4 2=5 3=6 4=7 5=8 6=9). This is value FIR_+7. In (lengthy) C it would look like this: If (RegString(1) is lower than 3) RegString(1) = RegString(1)+7
Else Regstring(1) = ((RegString(1)-10)+7) So protection has "transformed" and stored in [5E8D] and [5E8F] the two numbers 1 and 2. In our RegString: 1242-1212-12 the first two numbers "12" are now stored as "94". These will be used as "slider" parameters inside the main loop, as you will see. Only now does protection begin its main loop, starting from the LAST number, because the counter has been set to 9 (i.e. the tenth number of RegString). The loop, as you'll see, handles only the numbers from 10 to 3: it's an 8-times loop that ends without handling the first and second number. What happens in this loop?... Well, quite a lot: Protection begins the loop loading the number (counter+1) from the RegString. Protection then loads the SEC_+3 down_slider parameter (which began its life as second number "transformed"), multiplies it with 0xA and then adds the up_slider parameter FIR_+7 (at the beginning it was the first number transformed). This sum is used as "lookup pointer" to find a parameter inside a table of parameters in memory, which are all numbers between 0 and 9. Let's call this value Lkup_val. Protection looks for data in 1EA7:[Lkup_val]. In our case (we entered 1242-1212-12, therefore the first SEC_+3 value is 9 and the first FIR_+7 value is 4): [Lkup_val] = 9*0xA+4; 0x5A+4 = 0x5E. At line :4C80 therefore AL would load the byte at 1EA7:005E (let's call it KEY_PAR), which now would be ADDED to the # counter+1 of this loop. In our case KEY_PAR at 1EA7:005E it's a
"7" and is added to the pampered 0x32=2, giving 9. Let's establish first of all which KEY_PAR can possibly get fetched: the maximum is 0x63 and the minimum is 0x0. The possible KEY_PARs do therefore dwell in memory between 1EA7: and 1EA7:0063. Let's have a look at the relative table in memory, where these KEY_PARs are stored ("our" first 0x5Eth byte is underlined): 1EA7:0000 01 03 03 01 09 02 03 00-09 00 04 03 08 07 04 04 1EA7:0010 05 02 09 00 02 04 01 05-06 06 03 02 00 08 05 06 1EA7:0020 08 09 05 00 04 06 07 07-02 00 08 00 06 02 04 07 1EA7:0030 04 04 09 05 09 06 00 06-08 07 00 03 05 09 00 08 1EA7:0040 03 07 07 06 08 09 01 05-07 04 06 01 04 02 07 01 1EA7:0050 03 01 08 01 05 03 03 01-02 08 02 01 06 05 07 02 1EA7:0060 05 09 09 08 02 09 03 00-00 04 05 01 01 03 08 06 1EA7:0070 01 01 09 00 02 05 05 05-01 07 01 05 08 07 01 09 1EA7:0080 08 07 07 04 04 08 03 00-06 01 09 08 08 04 09 09 1EA7:0090 00 07 05 02 03 01 03 08-06 05 07 06 03 07 06 07 1EA7:00A0 04 02 02 05 02 04 06 02-06 09 09 01 05 02 03 04 1EA7:00B0 04 00 03 05 00 03 08 07-06 04 08 08 02 00 03 06 1EA7:00C0 09 00 00 06 09 04 07 02-00 01 01 01 01 00 01 FF 1EA7:00D0 00 FF FF FF FF 00 FF 01-00 00 00 00 00 00 00 00
An interesting table, where all the correspondences are between 0 and 9... are we getting some "secret" number here? But, hey, look there... funny, isn't it? Instead of only 0-0x63 bytes
we have roughly the DOUBLE here: 0-0xC8 bytes (the 01 sequence starting at CA "feels" like a fence). We'll see later how important this is. At the moment you should only "perceive" that something must be going on with a table that's two time what she should be. As I said the result of KEY_PAR + input number is polished (with a FFDO) and pampered (subtracting, if necessary, 0xA). Therefore the result will be the (counter+1) input number + KEY_PAR (let's call it RE_SULT], in our case, (at the beginning of the loop) a 9. Now (DX=0 because of the CWD instruction) DX will be saved in [9548] and RE_SULT in [9546]. Now Protection prepares for the RO_routine: resets its pointer and charges CX and BX from [958C] and from [958A] respectively, charges AX with 0xA and sets DX to zero. The routine performs various operations on AX and DX and saves the results in the above mentioned locations [958A] and [958C]. Now KEY_PAR and RE_SULT are added respectively to the DX and AX value we got back from the RO_routine call, and saved once more in the last two locations: AX+RE_SULT in [958A] and DX+KEY_PAR in [958C] Now the value in SEC_+3 is diminished by 1 (if it was 9 it's now 8, if it was zero it will be pampered to 9). It's a "slider" parameter (in this case a down_slider), typically used in relatively complicated protections to give a "random" impression to the casual observer. The value in FIR_+7, on the contrary, is
augmented by one, from 4 to 5... up_sliding also. Protection now handles the next number of your input for the loop. In our case this loop uses following protection configuration with our "sliding" parameters: Input # pamp_2nd pamp_1st Lookup value KEY_PAR # RE_SULT # 10 = 2, SEC_+3= 9, FIR_+7= 4, Lkup_val = 0x5E, KEY=7 +2 = 9 # 9 = 1, SEC_+3= 8, FIR_+7= 5, Lkup_val = 0x55, KEY=3 +1 = 4 # 8 = 2, SEC_+3= 7, FIR_+7= 6, Lkup_val = 0x4C, KEY=4 +2 = 6 # 7 = 1, SEC_+3= 6, FIR_+7= 7, Lkup_val = 0x43, KEY=7 +1 = 7 # 6 = 2, SEC_+3= 5, FIR_+7= 8, Lkup_val = 0x3A, KEY=0 +2 = 2 # 5 = 1, SEC_+3= 4, FIR_+7= 9, Lkup_val = 0x31, KEY=4 +1 = 5 # 4 = 2, SEC_+3= 3, FIR_+7= 0, Lkup_val = 0x1E, KEY=5 +2 = 7 # 3 = 4, SEC_+3= 2, FIR_+7= 1, Lkup_val = 0x15, KEY=2 +4 = 5 Notice how our "regular" input 21212124 has given an "irregular" 94672575. You may legitimately ask yourself what should all this mean: what are these RE_SULTs used for? Well they are used to slide another parameter: this one inside the called routine... this is what happens to AX and DX inside the routine, and the lines after the called routine: :4CBF 26895702 MOV ES:[BX+02],DX ; save R_DX par [958C] :4CC3 268907 :4CC6 0346FA :4CC9 1356FC :4CCC C45E0E MOV ES:[BX],AX ; save R_AX par [958A]
ADD AX,[BP-06] ; add to AX RE_SULT [9546] ADC DX,[BP-04] ; add to DX KEY_PAR [9548] LES BX,[BP+0E] ; reset pointer to E
:4CCF 26895702 MOV ES:[BX+02],DX ; save R_DX+KEY_PAR [958C] :4CD3 268907 MOV ES:[BX],AX ; save R_AX+RE_SULT [958A]
:4CC6
RE_SULT [958A] [958C] [958C] 0 9 4 6 7 2 5 0 5A 3AC 24F4 71CE 7220 7572 0 0 0 0 1 4 4 0 0 0 0 1 E 90 7579 0 9 5E 3B2 24FB 71D0 7225
Now the loops ends, having handled the input numbers from tenth to third. Protection loads the second number and multiplies it by 10 (let's call this result SEC_*10), in our case 2*0xA=14. Protection loads the first number and adds it to the multiplication, in our case 1+0x14=0x15 (FINAL_SUM]. Now everything will be added to FFDO to "clean" it. Pointer will now be set to the end of the input number. DX, zeroed by CDW, will be saved as parameter in [9584] and the cleaned and pampered sum will be saved in [9582]. FLAG is set to true and this routine is finished! No parameter are passed and the only interesting thing is what actually
happens in the locations [9582], [9584], [958A] and [958C], i.e.: FINAL_SUM, 0, slider_sum, odd_dx. In the next lesson we'll crack everything, but I'll give you already some hints here, in case you would like to go ahead on your own: we'll see how the scheme used for the third (the registration) number show analogies and differences with the scheme we have studied (and cracked) here for the first number. Our 3434-3434-3434-3434-34 input string for the registration number will be transformed in the magic string 141593384841547431, but this will not work because the "magic" 12th number: "1" will not correspond to the remainder calculated inside this check through the previous locations of the other checks. Here the things are more complicated because every little change in your input string transforms COMPLETELY the "magic" string... therefore in order to pass the strainer you'll have to change 3434-3434-3434-3434-34 in (for instance) 7434-3434-34343434-96. The "magic" string 219702960974498056 that this registration input gives will go through the protection strainer. Only then we'll be able to step over and finally crack the whole protection... it's a pretty complicated one as I said. Now crack it pupils... you have three months time. From this crack depends your admission to the Uni, there will be no other admission text till summer 1997 (it's a hell of work to prepare this crap)... work well.
Well, that's it for this lesson, reader. Not all lessons of my tutorial are on the Web. You 'll obtain the missing lessons IF AND ONLY IF you mail me back (via anon.penet.fi) some tricks of the trade I may not know but YOU've discovered. I'll probably know most of them already, but if they are really new you'll be given full credit, and even if they are not, should I judge that you "rediscovered" them with your work, or that you actually did good work on them, I'll send you the remaining lessons nevertheless. Your suggestions and critics on the whole crap I wrote are also welcomed.
E-mail +ORC
+ORC an526164@anon.penet.fi