|
An introduction to code generation routines: reversing Teleport Pro v1.29
The last beginners approach on fravia's site
|
Not Assigned
|
14th May 1998
|
by
Prophecy
|
|
|
Courtesy of Fravia's page of
reverse engineering
|
slightly edited
by fravia+ |
fra_00xx 98xxxx handle 1100 NA PC
|
Prophecy thought this as a "beginner" essay, which is true... it is nevertheless a good
essay. Yet this is THE LAST beginner essay I will ever publish on my site (unless the
techniques change radically, which I doubt :-). Yes, I will not publish any "beginner"
essays anymore. In fact I believe there is now enough material on my (and some other)
pages to help anyone to grow from beginner to intermediate... if the reader has at
least a little will, that is. Beginners have had enough. Basta, finito, pass over to the
next stage: it's about time to draw a line IMO (correct me if you reckon I'm wrong).
This essay is definitely NOT an "useless" beginner essay btw, it's an interesting article
for any beginner reversers ans protectors alike... and don't snarl at beginners (I can't
stand snotty 'elite' crackers the beginners of today are the masters of tomorrow (yet
I'm decided... I won't publish any "beginners" essay any more :-) Enjoy Prophecy's
good work!
|
|
|
There is a crack, a crack in everything
That's how the light gets in
| |
Rating
|
(x)Beginner ( )Intermediate ( )Advanced ( )Expert
|
|
This essay illustrates how a simple code generation routine based upon the
user's name works, and describes a clear approach to reversing this target.
Many of the techniques described in this essay can be used to reverse other
targets... this essay was written by a beginner, for beginners.
An introduction to code generation routines: reversing Teleport Pro v1.29
The last beginners approach on fravia's site
Written by
Prophecy
Table of contents: (use this once you've already read through the essay and you
only want to reference specific sections)
Introduction...
About the target...
Tools required...
Target's URL...
Let's get started...
Setting up SoftIce...
The main body of the essay...
The C source code for the key generator...
Credits...
Final words...
Note: I can be contacted at: prophecy_@usa.net
Introduction:
This essay is dedicated to fravia, the #cracking4newbies crew, and to those
who have contributed to fravia's academy...
I am very grateful to all the people who have written essays, and shared their
knowledge of cracking with everyone else. Now that I've gained a bit of
experience, I feel that I am now ready to contribute a small something back
to the cracking community.
The contents of this essay is aimed at beginners, and you shouldn't have much
trouble following it, just don't go too fast, and make sure you read everything!
I'm going to show you how the target generates the serial numbers so that you
can work out a serial number for your name and so that you can make a key
generator. What I hate about a lot of essays is the cracker who writes them
assumes you know the same amount as him/her, leaving beginners like me and you
confused and annoyed. Throughout this essay, I have explained everything to
the best of my ability (remember I'm only a beginner too and I can't explain
everything).
Target:
We are going to reverse Teleport Pro 1.29 (Build 622). This is a nice app which
lets you download entire web pages like the entire academy at fravia.org etc...
the shareware version, however, is crippled because it only lets you download
up to 500 threads, hence our need to crack it.
Numega SoftIce (I use v3.22)
C compiler if you want to modify my source code to make your own key generators
You can obtain the target from: http://www.tenmax.com/pro.html OR
http://www.winfiles.com/apps/98/offline.html.
History is not relevent here.
Okay! Let's get started by having a look round the target...:
Before rushing headfirst into SoftIce, let's have a little look round the
target. First of all, load it up and click on Help. Ahh, a 'register...'
option... let's check it out. Looks like a pretty standard name and serial
number protection. Okey, let's investigate: click on the 'Mail/Email/Fax'
button. First, you'll notice the company field is optional, so we can assume
that the target doesn't use that field to generate the serial number, and we can
leave that field blank. Ok, now click on 'Save to Disk' button... what does it
say? It says "Please enter a name because we need it to generate your serial
number!" (suprise, surprise). Ok, enter a small name like bob, and click 'Save
to Disk'.. what does it say now? "Our name is too short".. hmm okay, we soon
determine that the minimum length name is 5 letters long. So our snooping has
led us to these conclusions: our name must be at least 5 letters long and is
used to generate the code, and we can leave the company field blank.
Setting up SoftIce...:
Okey, if your SoftIce is already sweetly set up, you can skip this section.
When SoftIce loads with it's default values, it is in a sorry state, you
only get 25 lines of code, the Registers window isn't there, and a whole lot of
other stuff is missing too...to remedy this, I suggest you use my settings. To
use my settings open up the winice.dat file in the SoftIce directory. You
should see (round about line 20) INIT="X;". Replace that with the two INIT
lines below... if you have INIT="a whole lot of stuff like above" then chances
are it's already ok, and you don't have to replace them. You'll need to restart
your computer for the changes to take effect.
INIT="lines 60;code on;wd 13;wc 25;wr;ww 6;wl;dex 1 ss:esp;faults off;"
INIT="altkey ctrl d;watch es:di;watch eax;watch *es:di;set mouse 3;cls;X;"
So what does all this stuff do you ask? Here's a quick rundown:
lines 60 - sets SoftIce to use 60 lines
code on - displays the hexidecimal byte code next to the disassembled
listing
wd 13 - enables the data window and sets it to 13 lines
wc 25 - enables the code window and sets it to 25 lines
ww 6 - enables the watches window and sets it to 6 lines
watch bla - displays the value of bla in the watch window
set mouse 3 - puts mouse speed on full (yeeehaaaa)
cls - clears the screen
faults off - means when your computer crashes, SoftIce doesn't kick in (you
don't want faults ON because when SoftIce pops up because of a
fault it won't let you out again)
altkey ctrl d - this is the default value for switching to softice - set it
to whatever you want
dex 1 ss:esp - not quite sure :)
Note: sometimes, when you switch from SoftIce back to Windows95 it crashes, and
displays a whole bunch of vertical lines on your monitor... this is probably due
to incompatibility with your video card and can be fixed by running SoftIce in a
window. Tu run SoftIce in a window, go to the the SoftIce from the startup menu
and click 'Display Adapter Setup', then check the 'Universal driver' box. You
can then configure (in SoftIce) the number of lines by typing lines x, where x
ranges from 25-128 and width y, where y ranges from 80-160. You can set the
font by typing set font n, where n = 1, 2 or 3. If you use SoftIce in a window,
you should modify the winice.dat INIT lines with the new settings... (see the
readme.txt file in the \softice directory for more details).
One more thing that's important, is that you need to export the functions from
the standard windows functions, otherwise you won't be able to breakpoint on
anything. To make sure the functions of these libraries are exported to
softice, load up the winice.dat file and go down near the bottom of the file
until you see ;*** Examples of export symbols that can be included for Windows
95 ***. Okey, now remove the semi-colon from in front of the the kernel32.dll
and user32.dll export statements, and make sure the path points to the right
windows system directory. Now, you'll have most of the main functions available
to you, another good one to export is advapi.dll.
Okey, let's test our SoftIce setup.. hit Ctrl-D, you should see (rough sketch):
+------------------------------------------------------------------------------+
| EAX=... This is the registers window, activate it |
| EDI=... by typing wr |
+------------------------------------------------------------------------------+
| es:di=... This is the watch window, activate it by typing ww. To watch |
| something, type watch bla, eg watch eax |
+------------------------------------------------------------------------------+
| xxxx:yyyyyyyy 01 02 03 04 05 06 07 08-09 10 11 12 13 14 15 16 ...............|
| xxxx:yyyyyyyy 01 02 03 04 05 06 07 08-09 10 11 12 13 14 15 16 ...............|
| |
| This is the data window, activate it by typing wd. It is here that you can |
| see what's stored in memory. |
+------------------------------------------------------------------------------+
| 0028:C000A010 7902 JNS C000A014 (JUMP )|
| 0028:C000A012 33C0 XOR EAX,EAX |
| 0028:C000A014 83E81F SUB EAX,1F |
| |
| This is the code window, where the assembly commands the target is executing |
| are displayed. Activate this window by typing wc. |
+------------------------------------------------------------------------------+
|:< type your commands here > |
| |
| Well this is where you type your commands, simple huh? |
+------------------------------------------------------------------------------+
(I got a lot of this information from Mammon_'s excellent SoftIce tutorial,
which is availabe at http://fravia.org).
Anyway, now we're ready to rock'n'roll!
Let's break into SoftIce and see what happens...:
(Some crackers would prefer to 'dead list' the target first using w32dasm but
I'm rash, and want to get straight to the action. If I fail with SoftIce, then
I have a look round with w32dasm, but I always prefer the more eloquent solution
of a valid serial number rather than a patch that changes '74' to '75'.)
We want to work out how the target generates the serial number right? And we
know there's a good chance that our name is going to be used in the process
(unless the author is lying). It should be noted that finding the serial number
for the name you entered isn't too hard (it only took me 5 hours hehe), but
we're not interested in that, we want to get to the bottom of the code
generating routine and see how this target really works, then we can write a key
generator, and our curiousity will be appeased and the world will live happily
ever after.
Okey then, let's enter a name in the Name box, eg Prophecy, and a bogus code,
eg 666777888. Now we need to set a breakpoint in SoftIce so that we pop into
SoftIce at a point close to where the target is going to generate the code and
compare it to our bogus code. Okay, let's pop into SoftIce (Ctrl-D or whatever)
and set a breakpoint: BPX getwindowtexta. This means SoftIce will pop up
on execution of the getwindowtexta command, which is a common command a target
uses to read info supplied by a user (eg name and (bogus) serial number). Okey,
hit < F5 > to go back to the target and click OK. Bang! we're in SoftIce.
Press < F11 > to trace the call back to the target.
Now, have a careful look at the registers...:
EAX=8 (this is the length of our name)
Hrmm, so there's not much going on round here. Let's find our name in memory:
type s 0 l ffffffff "Prophecy". Right, you should see your name in the data
window like so:
013F:00FB266C 50 72 6f 70 68 65 63 79-00 00 00 00 00 00 00 00 Prophecy........
^^^^^^^^^^^^^
(these numbers will probably be different to yours)
So the address of my name is fb266c.
(there may be more than one instance of your name in memory, typing s will
display the next match in memory. If you are having trouble finding your name,
try typing a name that you KNOW won't be in memory eg PrinceCharles, then repeat
the search process).
Okey, now we want SoftIce to break whenever the target accesses the memory
containing your name, to do this, we must use the bpr (break when a range of
memory is accessed) command by typing: bpr fb266c fb266c+8 rw. Since we're
interested in seeing how the target manipulates our name to generate the serial
number, we no longer need the the breakpoint on getwindowtexta. To get rid of
it type bc 0. Now let's continue and see what happens to our name... press
< f5 > and you should see this:
(Note that throughout the assembly listing, comments that begin with '?' are
ones I'm not sure about, but which I think are a possibility).
0137:BFF7117E F2AE REPNZ SCASB ;?finds length of your name
0137:BFF71180 83C8FE OR EAX,-02 ;?
0137:BFF71183 2BC1 SUB EAX,ECX ;eax=eax-ecx
0137:BFF71185 5F POP EDI ;pops edi from the stack
0137:BFF71186 59 POP ECX ;pops ecx from the stack
0137:BFF71187 C9 LEAVE ;let's leave this call
Okey, a bit of 'zen' (intuition) tells me that this part of the code isn't very
interesting (how do I do suspect it isn't interesting? Well, after looking at
lots of lines of code, you can begin to 'feel' the code, and draw accurate
assumptions from it- you will be able to as well, just go through lots of
essays and tutorials). So lets move on: press < f10 > to step past the REPNZ
SCASB line until the OR EAX,-02 line is selected, then press < f5 > to continue:
0137:004415E8 80240800 AND BYTE PTR [ECX+EAX],00 ;?
0137:004415EC C20400 RET 0004 ;return from the call
Well this isn't very interesting either (you can always have a snoop round
yourself by press < f10 > to trace down. Anyway, don't despair, the good bit
is coming right up, let's hit < f5 > again and we end up here: ----------------+
|
(Now, if you're pretty sharp, you'll notice something I missed: hint: it's in |
one of the registers. You found it? Yep, it's that EBP register alright! |
Not convinced? Type ?ebp, and what value is it? Our bogus code... okey, so |
keep an eye on ebp.) |
|
/* start of 'dummy' code generating routine */ <-- ignore this for the moment |
|
0137:004287D0 8B01 MOV EAX,[ECX] <-----------------------+
^ This line moves the content of ECX ([ECX]) into EAX. What's [ECX]? Type d
ecx:
013F:00FB266C 50 72 6f 70 68 65 63 79-00 00 00 00 00 00 00 00 Prophecy........
Our name... hmmm, suspicious. It's important to understand how [ECX] gets
transferred to EAX: EAX consists of 8 numbers, made up of 4 bytes. A byte is
just the pairs of numbers you see in the data window, eg 50, 72 and 6f are
examples of bytes. Now, EAX must read 4 bytes from [ECX]. It reads these in
reverse order starting at 70, then 6f, 72 and finally 50, giving the new value
of EAX=706f7250 (which you can see by looking at the EAX value in the registers
window). So now EAX is equal to the first four letters of our name.
0137:004287D2 BAFFFEFE7E MOV EDX,7EFEFEFF ;edx=7efefeff
0137:004287D7 03D0 ADD EDX,EAX ;edx=edx+eax
^ EDX is now equal to (7efefeff (a possible magic number?) plus EAX).
0137:004287D9 83F0FF XOR EAX,-01
^ letters of our name get XORed with -01, result is stored in EAX.
0137:004287DC 33C2 XOR EAX,EDX
^ letters of our name get XORed with (possible magic number+EAX).
0137:004287DE 83C104 ADD ECX,04
^ ECX = ECX+4 , meaning that we have already read 4 bytes of our name, and next
time it will start reading at the 5th byte (letter) of our name.
0137:004287E1 A900010181 TEST EAX,81010100
^ finished encrypting our name?
0137:004287E6 74E8 JZ 004287D0 ;yes/no
0137:004287E8 8B41FC MOV EAX,[ECX-04]
^ Hrmm EAX has now been overwritten by the content of ECX-4... what was the
point of XORing EAX in the first place?
0137:004287EB 84C0 TEST AL,AL ;not quite sure what
0137:004287ED 7432 JZ 00428821 ;all this stuff does
0137:004287EF 84E4 TEST AH,AH ;but it basically checks
0137:004287F1 7424 JZ 00428817 ;to see how far thru the
0137:004287F3 A90000FF00 TEST EAX,00FF0000 ;encrypting of our name
0137:004287F8 7413 JZ 0042880D ;the target is.
0137:004287FA A9000000FF TEST EAX,FF000000
0137:004287FF 7402 JZ 00428803
0137:00428801 EBCD JMP 004287D0
0137:00428803 8D41FF LEA EAX,[ECX-01] ;let eax=[ecx-1]
0137:00428806 8B4C2404 MOV ECX,[ESP+04]
^ Type D esp+4 and you'll see something like:
013F:006FF488 6C 2C FB 00 bla bla bla... now doesn't that fb2c6c look familiar?
Yep, it's the location of our name (remember, stuff is read in into registers in
blocks of 4 bytes, starting from right to left).
0137:0042880A 2BC1 SUB EAX,ECX
^ This calculates the length of our name and stores the result in EAX
0137:0042880C C3 RET
etc, etc...
/* end of 'dummy' code generating routine */ <-- ignore this for the moment
Well, anyway, I'm getting pretty suspicious by now because all sorts of stuff
is happening to our name. At this point, I traced carefully through the code
for ages, noting down what was going on. This is pretty slow and hard work,
but it's good practice for a beginner like me and it also ensures I don't miss
any important points. Okey, you do the same: hit < f10 > and slowly trace the
code, you eventually hit a RET command and end up here:
0137:00422FCE 59 POP ECX ;pop ecx from the stack
0137:00422FCF EB02 JMP 00422FD3
0137:00422FD1 33C0 XOR EAX,EAX
0137:00422FD3 83F805 CMP EAX,05
^ Compares length of our code (EAX) with 5
0137:00422FD6 7304 JAE 00422FDC
^ Jump if EAX is greater than or equal to 5... remember our snooping? We
already knew our name had to be 5 or greater...
0137:00422FD8 33C0 XOR EAX,EAX ;set eax=0
0137:00422FDA EB2B JMP 00423007
0137:00422FDC BEA4E4FE5D MOV ESI,5DFEE4A4
^ move 5dfee4a4 (another possible magic number?) into ESI
0137:00422FE1 33DB XOR EBX,EBX ;set ebx=0
0137:00422FE3 85FF TEST EDI,EDI ;?did we enter a name?
^ Have you checked what EDI is? (Type D edi)... it's our name!
0137:00422FE5 7409 JZ 00422FF0 ;yes/no
0137:00422FE7 57 PUSH EDI
^ This pushes our name to a function. It is important to know how functions
work: (some) functions require parameters. For example, consider this function
here: sum(a,b). This function gets two numbers, a and b and adds them. a and b
are the parameters of the function, sum. Now in assembler this would look like:
PUSH a ;eg PUSH 30
PUSH b ;eg PUSH 12
CALL sum ;this would actually be some memory location which points to the
;function sum
Anyway, now that you've got the general idea you can see the importance of the
above PUSH EDI:
0137:00422FE8 E8C3570000 CALL 004287B0
^ This calls a function, which has our name as it's only parameter!
Okey, so this function could be important, so we want to step into it and
investigate: select the CALL 004287B0 line and hit < f8 >. Now let's see where
we end up:
0137:004287B0 8B4C2404 MOV ECX,[ESP+04]
^ set up ECX so that it points to our name
0137:004287B4 F7C103000000 TEST ECX,00000003 ;?
0137:004287BA 7414 JZ 004287D0
0137:004287BC 8A01 MOV AL,[ECX]
^ move first byte of our name into AL
0137:004287BE 41 INC ECX ;ecx=ecx+1
0137:004287BF 84C0 TEST AL,AL ;?did we enter a name
0137:004287C1 7440 JZ 00428803 ;yes/no
0137:004287C3 F7C103000000 TEST ECX,00000003 ;?finished encrypting
0137:004287C9 75F1 JNZ 004287BC ;our name yet? yes/no.
0137:004287CB 0500000000 ADD EAX,00000000 ;seems pretty pointless.
0137:004287D0 8B01 MOV EAX,[ECX]
^ Move the first 4 letters of our name into EAX
Well now, what have we here? Looks like we're back to the start of the 'dummy'
code generating routine... I call this the 'dummy' code generating routine
because it doesn't seem to have a purpose. I think that the programmer may have
put it in to send a naive cracker down the wrong track (fat chance hehe)...
anyway, maybe I missed the subtle point... let's continue:
0137:004287D2 BAFFFEFE7E MOV EDX,7EFEFEFF
0137:004287D7 03D0 ADD EDX,EAX
0137:004287D9 83F0FF XOR EAX,-01
.
.
0137:0042880C C3 RET ;let's leave the 'dummy' routine
Okay, perserverence is the key to success, so let's forge on, hit < f10 > until
you reach RET, and you end up here:
0137:00422FED 59 POP ECX ;pop ecx from the stack
0137:00422FEE EB02 JMP 00422FF2
0137:00422FF0 33C0 XOR EAX,EAX ;set eax=0
0137:00422FF2 83C0FC ADD EAX,-04
^ ?this is probably used to keep a check on how far through the 'dummy' (or even
the real code) generating routine the target is...
0137:00422FF5 3BD8 CMP EBX,EAX
^ EBX was a counter used in the 'dummy' routine. ?Compares to see if we are
finished the routine yet...
0137:00422FF7 730C JAE 00423005 ;yes/no
0137:00422FF9 33343B XOR ESI,[EDI+EBX]
^ Okey, now this looks interesting! ESI (a possible magic number remember?) is
XORed with the contents of EDI+EBX and the result is stored in ESI... now what
is [EDI+EBX]? type d edi+ebx... well, well, well, if it isn't our name. We'll
have to keep a close eye on our friend ESI... now keep tracing and you'll end up
here:
0137:00422FE3 85FF TEST EDI,EDI ;?did we enter a code?
0137:00422FE5 7409 JZ 00422FF0 ;?yes/no
0137:00422FE7 57 PUSH EDI ;push our name to the stack
0137:00422FE8 E8C3570000 CALL 004287B0
^ Well, no prizes for guess what routine this CALL is to... yep, our 'dummy'
code generating routine. Well at this stage you can just step over this
routine rather than into it, but you'll need to disable your breakpoint on
your name which can be done by typing bd 1 (otherwise you'll just pop into
the routine anyway, because our name is being accessed by it). Okey, now that
you've stepped over the routine (or you can step into it if you want, it'll just
take longer- and that's the way I did it, because I guess I wasn't thinking hard
enough, and I was just methodically stepping into all the interesting calls) you
should reenable the breakpoint on your name by typing be 1.
0137:00422FED 59 POP ECX
0137:00422FEE EB02 JMP 00422FF2
0137:00422FF0 33C0 XOR EAX,EAX ;set eax=0
0137:00422FF2 83C0FC ADD EAX,-04 ;eax=eax-4
0137:00422FF5 3BD8 CMP EBX,EAX ;finished dummy routine?
0137:00422FF7 730C JAE 00423005 ;yes/no
0137:00422FF9 33343B XOR ESI,[EDI+EBX]
^ Ok, now we end up here, which is again interesting. Typing d edi+ebx reveals
that our name has now been shifted accross one and so the contents of EDI+EBX are
the letters 2-5 inclusive or our name, namely 'roph'. So ESI is XORed with the
letters 2-5, and the result is stored in ESI... do we sense a pattern here? I
think so! The pattern seems to be that our ESI starts out as the magic number
5dfee4a4, it then gets XORed with the first 4 letters of name, and the result is
stored in the new ESI. Then the new ESI is XORed with the letters 2-5 of our
name, (and then 3-6, 4-7, 5-8...?). Anyway, for each XOR ESI, [EDI+EBX], the
'dummy' routine is called. Okey, let's confirm our theory, by continuing to
trace downwards... (remember if you see a PUSH EDI, CALL 004287B0, you don't
need to bother stepping into it, just don't forget to disable the breakpoint of
your name and reenable it after you've stepped over the call)... okey, we reach
this interesting point in the code:
0137:00422FF9 33343B XOR ESI,[EDI+EBX]
^ XOR ESI with letters 3-6 of our name, which confirms our theory doesn't it?
0137:00422FFC F6C340 TEST BL,40 ;?
0137:00422FFF 7401 JZ 00423002
0137:00423001 43 INC EBX
0137:00423002 43 INC EBX
^ this adds 1 to EBX so that at the next XOR ESI,[EDI+EBX] our name has been
shifted accross 1.
Ok, so by now things are becoming pretty obvious... keep tracing but be careful,
as we are nearing the end of our name, you don't want to miss any important
bits! Ok, now we hit yet another XOR ESI,[EDI+EBX], this time the contents of
EDI+EBX are letters 4-7 of our name. Well, let's keep tracing... hey, we've
reached new section of code:
0137:00423005 8BC6 MOV EAX,ESI
^ ESI, which by now, seems like it has a high chance of being the 'valid' code
is moved into EAX
0137:00423007 5F POP EDI ;pop edi off the stack
0137:00423008 5E POP ESI ;pop esi off the stack
0137:00423009 5B POP EBX ;pop ebx off the stack
0137:0042300A C3 RET ;let's get outta here!!
Well, we leave that routine and pop up here:
0137:00422713 3BE8 CMP EBP,EAX
^ Well, well, well what have here? Do you remember what EBP was? If you can't,
check it out now... type ?ebp, yup, it's our bogus code, and we're pretty sure
it's being compared to the 'valid' code! (Well, this programmer's efforts have
been substantially minimized by leaving an unencrypted 'bogus' code lying
around, and then comparing it with what we believe is the valid one... the
programmer should have been smarter and first of all encrypted our bogus code,
then encrypted the valid code and then compared the two encrypted codes... but
no, he was too lazy, and it cost him! < evil laughter >).
(Note that at this point, you can simply type ?eax and this would display
what we believe is our valid code (for me, I got 1139597721), and a cracker who
was just after a serial number could have quickly obtained it from here,
however, we were interested in disecting the code generating routine to bits, and
eventually writing a key generator (which is a much better and more worthwhile
exercise than quickly rushing in and finding the serial number!)
0137:00422715 59 POP ECX
0137:00422716 750F JNZ 00422727
^ if the codes don't match, then go to 'naughty cracker', otherwise continue.
Anyway, I bet your dying to see if EAX is really the valid code, so hit < F10 >
until you reach the JNZ 00422727. Okay, we want to skip the jump, so that we
can check if that EAX is the real code. How do we do this? Okay, if you notice
in the upper right part of the register window, we have a small 'z', this means
that the zero flag isn't set, (ie the two codes didn't match)... we want to
force the flag so that we fool the target into thinking the codes matched...
we do this by typing r fl z. Okey, now comes the test, let's clear all
the breakpoints we've set by typing bc * and leave SoftIce by hitting
< f5 >... and we're back in Teleport Pro and *boom* "Thankyou, your copy of
Teleport Pro is now registered blablabla". Yeehaa!
Okey, so let's recap on how the code is generated using our name:
We start off with a magic number (5DFEE4A4) and this gets XORed with the first 4
letters of our name and the result is stored in ESI. Then ESI is XORed with the
letters 2-5 of our name and a new value is stored in ESI. This process keeps
going until letters (n-4)-(n-1) have been read, where n represents the length of
your name. (Try entereing a name of different length to the one you used
through out the essay, and you'll see this is indeed the case). So now we know
exactly how the valid code is calculated based upon our name. I have written a
key generator in C for the target, and you are free to use and modify my source
code for your own key generators!
(I apologize in advance to the C gurus out there, because my code is probably
not written in the best of ways (hey, I'm only a beginner at C too), however,
I find that when you try and write efficient C, it becomes rather cryptic and
hard to follow, and because this essay is aimed at beginners, I wanted it as
easy as possible to follow...
So, without further ado, here is my C source code, fully commented so that it
may be easily understood:
--------------------------------start tprokgen.c--------------------------------
/* Your first keygen... yeehaa!
*
* This code can be used by anyone except Bill GAYtes (haha)... */
/* Note: because this proggie uses 32bit unsigned long integers, you might not
* have any luck get a DOS executable going because DOS is only 16 bit (there
* probably is a way, but I didn't find it), so you'll have to compile it to
* run under win32... good luck! */
#include <stdio.h> /* import the standard i/o library */
int main()
{ /* start of key generator */
/* Set up the variables...
* your_name is the string where your name is stored (up to 508 characters
(remember, C terminates all strings by a null character). (509 is the
minimum length string that C compilers must support.. hehe, damn I'm a geek)
* *p is a pointer to your_name
* length_of name is self explanatory, as is your_code
* buffer is where the characters making up the user's name are read into (much
like EAX, ECX etc...
* i,j,k are counter variables used in the loops */
unsigned char your_name[509], *p;
unsigned long int buffer, your_code;
int i,j,k,length_of_name;
/* Initialize the variables...
* your_code starts off as the "magic number" but quickly changes as it gets
XORed with the characters of the your name
* set initial length of name = 0
* set p to point to your_name
* the sum starts off = 0
* set up counter variables so that the code is calculated correctly (these
values become more apparent as you move further on) */
your_code=0x5dfee4a4;
length_of_name=0;
p=your_name;
buffer=0;
i=3;
j=4;
k=0;
/* Introductory blurb etc */
printf("UÄÄÄÄÄÄÄ ° ÄÄÄ Ü ÄÄÄÄÄÄÄ ° ÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
printf("_ßUU²ßUUU²ßUU²ßUU²Ü ܲU² ß²UU²ßUUU²ß 3\n");
printf("3 ß° UUU² U° UUUß²Ü UUU² UUU² UUU² 3\n");
printf("3 °UUU² °UUU UUUUU² °UUU² UUU² 3\n");
printf("3 ܲUUU²Ü ܲUUU²Ü ß²UU²Ü²UUU²Ü²UU²Ü 3\n");
printf("AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ßß² ÄÄÄÄÄÄÄÄÄÄÄÄU\n");
printf("\nKey Generator for Teleport Pro v1.29 (Build 662)");
printf("\nWritten by Prophecy [TNO]\n\n");
/* Get the name */
tryagain:
printf("Please enter your name: ");
/* Store your name in your_name */
gets(your_name);
/* Calculate the length of your name... \0 represents the NULL character which
is at the end of any C string, and hence used to find length of strings...*/
while (*p != '\0')
{
p++;
length_of_name++;
}
p=your_name; /* Set p so that it points back to the start of your_name */
/* Our name must be at least 5 characters long remember? If your name isn't at
least 5 characters long, then you get to enter your name again */
if (length_of_name 5)
{
printf("Your name must be at least 5 characters long! Try again... \n\n");
goto tryagain; /* Enter your name in again */
}
/* Ok, here starts the code generation routine... there are two while loops, an
outer one, and an inner one. The outer one checks to see if we're one away
from the end of the string, while the inner one reads in the characters of
the name so that the code can be generated. */
while (j <= length_of_name-1) /* start of outer loop */
{
while(i >= k) /* start of inner loop */
{
/* The buffer works like this: it starts off as 0, then you add to it the
first char of your name (p[0]). Then you multiply it by 0x100 which
creates space for the next char to be added into to the buffer. This
repeats 4 times until the first 4 chars (chars 1-4) have been read in
reverse order (this is how numbers are stored in registers (EAX etc)
remember?). The buffer is then XORed as described in the essay. Then k
increases by 1, and i is increased by j+4, and the chars 2-5 are read and
XORed. This keeps going until chars (n-4)-(n-1) have been read, where n
represents the length of your_name. */
buffer=(buffer*0x100LU) + p[i]; /* read in the characters of your name */
i--; /* decrease i by 1 */
} /* end of inner loop */
your_code=(your_code^buffer); /* XOR your_code with the buffer */
j++; /* increment j */
k++; /* increment k */
i=j+4; /* increase i */
buffer=0; /* reset the buffer to 0 */
} /* end of outer loop */
/* Print the code to the screen */
printf("Your code is: %u ",your_code);
return 0; /* Tells environment that the programme finished normally */
} /* end of key generator */
---------------------------------end tprokgen.c---------------------------------
Credits:
Well folks, that's about it, but of course, an essay can't be complete with all
the necessary credits...:
These people (or the stuff they've written) have helped me out a lot (in no
particular order):
natzgul, Y, cruehead, gij, corn2, niabi, aescalapius, tkc, mammon_, the
contributers to fravia's academy, the #cracking4newbies crew and probably a
whole bunch of others I missed...
These sites were also of great help:
http://fravia.org http://failure.ml.org/~mib/ http://home.cracking.ml.org
I hope that this essay has helped you and has been easy to follow... I certainly
went to great lengths to ensure it was as simple and as error-free as possible.
You should now be less afraid of SoftIce and overbloated protection schemes like
this one... if this essay has helped, then I am satisfied. Good luck with your
future cracks, and may the mighty zen force of the older ones be with you!
You can mail me here to tell me what you thought of my essay and to suggest
improvements!
Veni vidi vici.
I wont even bother explaining you
that you should BUY this target program if you intend to use it for a longer
period than the allowed one. Should you want
to STEAL this software instead, you don't need to crack its protection
scheme at all: you'll
find it on most Warez sites, complete and already regged, farewell.
You are deep inside fravia's page of reverse engineering,
choose your way out:
homepage
links
search_forms
+ORC
students' essays
academy database
reality cracking
how to search
javascript wars
tools
anonymity academy
cocktails
antismut CGI-scripts
mail_fravia+
Is reverse engineering legal?