home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-05-25 | 56.6 KB | 1,604 lines |
- HOW TO CRACK, by +ORC, A TUTORIAL
-
- ------------------------------------------------------------------------
-
- Lesson C (3): How to crack Windows, Hands on
-
- ------------------------------------------------------------------------
-
- [INSTANT ACCESS]
-
- --------------------------------------
-
-
- --------------------------------------------------------
- LESSON C (3) - How to crack Windows, cracking as anArt:
- Web trends, Instant Access (end) and the proximity trick
- --------------------------------------------------------
-
- I. [WEB TRENDS]
-
- It's really amazing: I began this tutorial in february 1996...
- the year is not yet finished but many things have already
- changed, and how! First of all the Web proves to be even more
- significant that I would ever have thought: it's -de facto- an
- ANTI-ESTABLISHMENT and ANTI-CONSUME "permanent" tool... more than
- that: it's an EVOLVING and SHARP tool!
-
- I do not know if you will agree with me, but it seems to me that
- it is now NOT ANY MORE NECESSARY to buy any of the following
- things (and this is a quite incomplete list:
-
- 1) Newspapers Are almost all on the Web for free
- 2) Magazines Are almost all on the Web for free
- 3) Software All on the Web for free
- 4) Books on the Web (even the *images* inside the
- books you would have bought are somewhere)
- 5) Post_stamps e-mail is free and ubiquitous
- 6) Hard_disks free megabytes everywhere on the Web (for
- pages and/or software, quite a lot of
- offering (at the moment, middle november
- 1996 you can get -for free- about 80
- megabytes for each email address you have).
- Should you do not deem this space enough,
- you may multiply them -ad libitum- using one
- of the many free "alias e-mail addresses"
- generators or, as a brilliant scholar of
- mine (re)discovered, you may easily "caper"
- (the passwords of) pages established by the
- lusers.
-
- I assure you that I used to spend quite a lot of money
- buying all the preceding items. The case of the CD-ROM magazines
- (and of software in general) seems to me to be the most relevant.
- In my earlier lessons I advised you to buy CD-ROM software at
- "kilo" prices in second hand shops (obviously never when the
- magazines themselves do appear)... even this trick is now
- useless: there is NO software that you cannot find on the Web
- (I'll bet that the CD-ROM mags are not making any easy money any
- more now). This truth may be difficult to slurp until you learn
- HOW to search effectively on the Web, a very difficult art -per
- se-, that all real crackers should master. A little tip: if you
- are in a hurry do your searches using your own search engines
- instead of using only the ubiquitous AltaVista, FTP and
- Webcrawler (which you SHOULD use, of course, but not alone).
- And loo! Good old Internet, made by governments and
- universities with public money and no private partecipation
- whatsoever reveals itself to be the most striking revolution of
- the last years in spite of the continuous blah blah about free
- markets and private initiative... quite funny, isn't it?
-
- New promising patterns are emerging: it is clear (to me)
- that the future of cracking lays in JavaScript applets: Netscape
- has opened quite a Pandora Box... now everybody is scrambling to
- close it... TOO LATE! Find the relevant documentation, tutorials,
- software, tools, examples... even teachers! Everything is there
- for free on the Web! Study it, and when you are ready study it
- again... take it easy: we have a long cracking future before
- us...
-
- Here is a nice example (by LaDue) of an interesting applet:
- this one forges an e-mail from the browsers of your page sending
- it to the address contained in the string "toMe". The browser of
- your page initiates the mail by connecting (involuntarily) to
- port 25 (int mailPort=25).
-
- Now, let's just academically imagine... you would put your
- own address (faked email address but working depot when you need
- to fetch the messages, as usual) in the string "toMe"... well,
- scanning incoming mail you could get the full e-mail address,
- including the user name, of many people who have seen your page.
- See LaDue example:
-
- here.
-
- JavaScript and Java are two completely different things: The
- coincidence in the name is only a stupid marketing move from
- Netscape. JavaScript is so easy it's a shame, and this makes it
- the ideal weapon for masscracking (Java on the countrary is a
- "real" programming language). The implications of easy Javascript
- use, of internet growth and of the "on the fly" JavaScript
- workings for the drafting of much more interesting applets are
- obvious, I'll let them to the intuition (and fantasy) of my
- cleverest readers.
-
- II.[INSTANT ACCESS] End
-
- I'll admit it: I am a little deceived: the +HCU strainer
- (Instant access protection scheme) has been solved only by very
- few (pretty competent) crackers. The amount of people that has
- NOT cracked instant access (and that as relentlessy asked for
- more "clues") stood in no sound relation to the very few that
- solved it. I intended to give my complete solution in this lesson
- C3 to allow everybody to have (good) software for free... but too
- few worked hard on it to let you all lazy ones deserve a "ready-
- made" solution... I will therefore publish here one of the
- "incomplete" (albeit very good) solutions.
-
- The solution cracks the scheme but requires a little work
- of your part to accomplish it... what I mean is this: studying
- the following you'll be able to crack every Instant access
- protected code in a couple of hours, not immediatly... this is
- good, will make the lazy lurkers work (at least a little :=)
-
- Here it is (C++ code of the solution and admission letter),
- I only took off the name of the candidate:
-
- Cracking Instant Access_____________
- by xxxxxxxx
- Application for 1996 Higher Cracking University
-
- This is my solution to the strainer for admittance into your
- HCU. While I was successful in bypassing the protection (and
- hence now have a nice collection of software for free) I am the
- first to admit that my solution is not the best. However, I am
- very proud of the work I have done on this project and it is by
- far the most difficult crack I've ever done. In the past I've
- traced programs, and when they did something I did not like, I
- looked at the jumps immediately before that and reversed them.
-
- Because of idiot programming this worked about 60% of the
- time, however in many programs I was just stuck. With the hints
- you provided in your tutors I was able to actually disassemble
- the program and understand why it did things. Believe me this is
- a big jump. Anyway, here is my solution.
-
- I have dozens of handwritten notes and pages of code that
- I copied out of soft-ice, and any that are important I will type
- into this report, however most turned out to be unimportant. I
- have also created a "Magic" number generator and a reverse
- generator. I am very proud that I was able to create these,
- because the "Magic" number seemed so mysterious at first, and now
- I have complete mastery of it, a great feeling of power.
-
- I began the project by following the introductory steps in
- lessons C1 and C2. I got lost somewhere in C2, but I kept going.
- I got to the end with a vague understanding of what was happening
- and decided that I needed to understand this fully before I could
- do anything useful towards cracking it.
-
- I left my computer alone and read through the code again,
- making notes and explanations for my own use. About the third
- time through everything clicked, it was like a light bulb going
- off in my head. You mentioned that not everything in Lesson C1
- was correct.
-
- Here is a list of what I found to be incorrect.
-
- 1. The offsets in the code were not the same. (this is a good
- idea to keep people from cheating when pinpointing the correct
- code)
-
- 2. The pointers to where things are saved in memory were not the
- same.
-
- 3. You wrote that the 1st digit plus 7 was saved and then you
- wrote that the 2nd plus 3 was saved. It is the other way around!
- 1st plus 3 and 2nd plus 7. (just checking if we are paying
- attention huh?)
-
- I think that's all of the one's I found although there were
- many specific instances of each one. So here's what I did.
-
- I did a search on the 18 digit code I typed in. I found it
- at 30:8xxxxx and did a bpr on it. I let it run, and looked each
- time something accessed that area. Eventually I found code that
- checked if the digits were between 30 and 39 and copied them to
- DS:8CD8. So there lies the code with the "-" 's stripped off of
- it. I did a bpr on this area. It copied itself to DS:8CB8, and
- I bpr'ed that as well. I discovered that what was going on was,
- it copied itself, then that copy was transformed into the "Magic"
- number.
-
- So I did a little stack fishing, and found a CALL at offset
- 5C04 which copies the code from 8CB8 and converts it into the
- "Magic" number. At this point I traced into the call and got
- really fucking lost, so I stepped back had a sip of Vodka and
- thought. I don't care HOW the "magic" gets there, only that it
- is there. I figured once I figured out what "magic" I needed I
- could trace over the call that put it there, and then put in
- whatever "magic" I wanted. So I traced on to see what happened
- to the "magic" number that had been produced. I had a bpr on the
- "magic" and it stopped on the first line of code below.
-
- The code is copied from my handwritten notes, so not
- everything is accurate (I only wrote down what I thought was
- important)
-
- 2b67:2598 mov al, es:[bx] ; 12th digit of magic
- mov [bp-03], al ; ??????
- mov al, [bp-03] ; maybe an inefficient compiler
- result
- add al, d0 ; clean it
- mov [bp-04], al ; save it in [8ca6]
- les bx, bp+06
- add bx, si ; point to 12th again
- mov byte ptr es:bx, 30 ; make it a '0'
- push then more crap and then
- :253d mov al, es:bx ; 1st digit
- mov ah, 00 add ax,ffd0 ; clean it
- cwd
- add [bp-06], ax ; [8c90] is zero to start
- this loop repeats 18 times, summing up the "magic" number, with
- the 12th set to 0
-
- :256e mov [bp-07], al ; save remainder of sum/a in [8c8f]
- cmp [al, bp-05] ; is 12th (in al) save as remainder
- of sum/a ? Aha!, this is what you were talking about at the end
- of C2, where the remainder doesn't match the 12th number.
- I knew I was on the right track. I could feel it.
- I traced down farther after the remainder check (I used
- 8888-8888-8888-8888-88 as my code from then on because it passed
- this check and was easy to remember) and I found code which
- compared the value at ds:8D00 with the value at ds:8D0C and if
- it did not match jumped to beggar off.
-
- Then it checks if ds:8D06 is equal to ds:8D0E and if not
- equal jumps to beggar off. So I knew that 8D00 must equal 8D0C
- and that 8D06 must equal 8D0E.
-
- All I needed to do was figure out where these came from. I
- bpr'ed on 8D0C and found code which wrote the number to it.
-
- I did not copy the ASM down, but this is what I wrote:
- move 15th of "Magic" into AX fix it to 0-9 by +- A
- put it in SI
- mov 16th into AX
- mul si by A
- add ax to si
- mov 17th to AX
- mul si by A
- add ax to it
- put 18th in AX
- mul si by A
- add AX to it ; This is ds:8D0C !!!!
-
- So now I knew where this came from, the last 4 digits of the
- "magic" I bpr'ed on 8D0E and found out quickly that the first
- digit of the "magic" was put into ds:8D0E.
- Things were looking good. However, I was unable to figure out how
- ds:8D06 and ds:8D00 were created. I know they are related to the
- product code because they only change when it does. But they are
- put there by a MOVSW command and I cannot figure out how to
- predict where they are copied from, because it is only done once
- and it is never from the same place, so all my attempts to bpr
- on the spot they are copied from failed because it copies from
- a new spot each time.
-
- I felt dejected. I could not figure it out, even after days
- of pointless tracing.
-
- I stepped back and thought, and drank a can of Coke at 2
- a.m...
-
- (note from +ORC: Coke is dangerous for your health and your cracking
- purposes... drink only Martini-Wodka and use by all means only russian
- Wodka)
-
- ...I still had not figured out how the "magic" worked. I
- decided to do that and come back to the problem of the numbers
- generated from the Product Code.
-
- I knew the call at cs:5C04 completely generated the "magic"
- so I started there. I traced through it several times and found
- that it made a CALL 3517 three times, then looped 6 times. So it
- called 3517 a total of 18 times. I also noticed that the CALL
- changed the number, but nothing else did, it just set up the
- calls.
-
- So I traced into CALL 3517 and came up with this:
-
- mov ax,ss
- nop inc bp
- push bp
- mov bp,sp
- push ds
- mov ds,ax
- xor ax a bunch more unimportant stuff
- :356b mov al,es:[bx} ; al = 18th digit
- cbw push ax
- mov ax, A
- sub ax,[5dad] ; subtract 6 from a to get 4
- imul [5db1] pop dx ; 18th digit
- add dx,ax add dx, -30 ;clean it
- mov [5db5], dx ;save it then fix [5db5] to be
- between 0 and 9
- mov al, es:[bx] ; load 18th again
- cbw push ax
- mov ax,a
- sub ax,[5dad]
- imul [5db3]
- pop dx ; 18th digit
- add dx, ax
- add dx, -30 ;clean it
- :35bb mov [5db7], dx ;save it.
- :35d9 mov bx,[5dad]
- mov es, bp+1a
- add bx,[bp+18]
- mov al,es:[bx-1] ; al = 6th digit
- mov [5dc3], al ; save it
- mov bx,[5dad]
- mov es,[bp+1e]
- add bx,[bp+1c]
- mov al,es:[bx-1] ; 12th digit
- mov [5dc4], al ; save it more junk then
- 3605: mov bx,[5dbf] ; this is the beginning of a loop
- mov es,[bp+1a]
- add bx,[bp+18]
- mov al,es:[bx-1] ; 5th digit
- push ax ; save it
- mov ax,[5db5] ; [5db5] created above using 18th digit
- mov dx,A
- imul dx ;[5db] *A
- les bx,[bp+0c]
- add bx,ax
- add bx,[5db7] ; created using 18th
- pop ax ;5th digit
- sub al,es:[bx};subtract a value from the lookup table
- les bx add bx,[5dbf]
- mov es:[bx],al ; Put new value in 6th spot fix it
-
- so that it's between 0 and 9 by +- A
- :3656 mov bx,[5dbf]
- mov es,[bp+1e]
- add bx,[bp+1c]
- mov al,es:[bx-1] ; 11th digit
- push ax mov ax,[5db5]
- mov dx,a
- imul dx
- les bx
- add bx,ax
- add bx,[5db7]
- pop ax ;11th digit
- sub al,es:[bx] ; subtract a value from lookup
- table
- les bx, [bp+1c]
- add bx,[5db7]
- mov es:[bx],al ;put it in 12th spot fix it to be
- between 0 and 9 The loop above repeats doing the same thing,
- changing 2 numbers, but not always the same two. The next time
- through it changes 5th and 11th, after that the 4th and 10th, 3rd
- and 9th then the 2nd and 8th using this same pattern. After the
- loop it changes the 1st and 7th using the values of the original
- 6th and 12th which were saved in [5dc3] and [5dc4] using the same
- pattern. I quickly wrote a program in C which would produce this
- number, and it worked fine.
-
- I traced into the second call of 3517 and found that the
- parameters passed to it changed which values where used to create
- [5db5] and [5db7], whether they increment or decrement, whether
- you add 0 or 64 to your index for the lookup and the digits which
- are changed. All three calls to 3517 have a different
- arrangement, but the their arrangement is the same each time they
- are called. For instance, the three calls are looped over 6
- times, on each instance that the 1st call is executed it will
- change the 6th,12th,5th, 11th, etc. So I modified my C program
- to mimic the behaviour of each call and looped it six times,
- expecting this to be the "magic" number. To my surprise it was
- not right.
-
- So I followed the code until after the 3 CALL 3517's had
- been made, this was the number my generator had given me, so it
- must do something more afterwards.
-
- I found the following code, still within the cs:5c04 call
-
- :44C1 mov al,es:[bx+si-2] ; 17th digit
- add al,d0 ;clean it
- mov [5dc1], al ;save it
- les bx
- mov al,es:[bx+si-2] ; 18th digit
- add al,d0 ;clean it
- mov [5dc2],al ;save it
- mov [5dbf],0
- jmp 455f :44df
- les bx
- add bx,[5dbf]
- mov al,[5dc1] ;17th cleaned
- sub es:[bx],al ;1st digit has 17th cleaned
- subtracted from it fix it between 0 and 9
- mov al,[5dc2] ;18th cleaned 4520
- sub es:[bx],al ;7th - 18th cleaned is put in 7th
- spot fix it between 0 and 9
- :455b inc word ptr [5dbf]
- mov ax,[5dbf]
- cmp ax,[5dad] ; run six times
- jge 456b
- jmp 44df 456b: blah blah continue on.
- This loop executes six times each time incrementing the digit to
- be changed by one so that the first change changes the 1st digit,
- and the next time through the loop the 2nd then the 3rd.....till
- the sixth. The second change alters the 7th through the 12th
- digits. I added code to do this at the end of my Generator, and
- I now had a "Magic" number generator. However this did not do me
- much good in itself. The breakthrough was reversing this program
- (it wasn't hard, but getting all the bugs out was really tough)
- so that it takes a "magic" number as input and tells you what
- registration number will produce it. I have included the source
- code for both programs to prove that they are my own work. The
- coding is not the best, they are my own crude tools, and they do
- the job I need them for. But now I am home free. Even without
- knowing how the product code is manipulated to come up with
- ds:8D00 and ds:8d06 I can crack it. Here's what I did.
-
- The product code given me was 3850-0118-6260-1057-23 I
- traced to where ds:8D00 and ds:8D06 are placed they were:
- ds:8D00 = E03 ds:8D06 = 3 I knew the last 4 digits when added,
- and multiplied as explained above must be E03 so this is what I
- wrote down, using my calculator
-
- DFC + 7 =E03
-
- This is the final answer, but I need to work backwards from here
-
- 166 * A = DFC
- 15E + 8 = 166
- 23 * A = 15E
- 1E +5 = 23
- 3 * A = 1E
-
- Just working things backwards from the way the program did it I
- figured out the last 4 digits of the magic code need to be 3587
- in order for it to produce E03 as a result. I also know that the
- first digit must be equal to ds:8d06 which is 3 so I now have:
-
- 3___-____-____-__35-87
- as a "magic" number and I fill it in with 1's
-
- 3111-1111-111X-1135-87
-
- I left the 12th number as an X because I remember that the
- remainder of the sum of all the digits except the 12th must be
- equal to the 12th.
-
- 3+1+1+1+1+1+1+1+1+1+1+1+1+3+5+8+7 = 26 26/A
- 26 26/A = 3 with a remainder of 8,
-
- so the 12th digit is an 8!
-
- My "magic" number should be 3111-1111-1118-1135-87
- So I run my UNINSTAN program, which tells me that in order to get
- that "magic" I need to enter the following registration code:
- 4798-8540-6989-6899-53 I enter this in, the "Retrieve" button is
- enabled and I install Norton Utilities without a hassle! I used
- the same method to install Wine Select (I've been interested in
- wine since reading about your Pomerol), Labels Unlimited (which
- I use for what else? Barcodes!), Harvard Graphics, and Lotus Ami
- Pro, which I'm using to write this report on!
-
- Well, that's it. That is how I cracked Instant Access. As
- I mentioned above it is not the best way, but I gave everything
- I had and it's the best I could do.
-
- I have succeeded because I have beaten the protection, and
- because I taught myself a lot along the way. I'm sure you already
- have a "magic" number generator of your own, but I included mine
- so you could see it. If I just knew how the product code produces
- those 2 numbers I could create a product code to registration
- number converter, which I assume is what the operators at Instant
- Access have when you call them to buy stuff.
-
- One last note about this assignment. I know that you have
- realized that Instant Access was hard to find. I want to tell you
- how I got it, a bit a social engineering in itself. After
- searching every library and book/magazine store in the city I got
- on the Internet and asked. Nobody had it.
-
- So I found the Instant Access homepage. ...
-
- (this will not be published, coz I, +ORC, do not want to expose my
- crackers, but the way this guy got hold of the protection scheme is in
- itself worth is access to the +HCU)
-
- ...So as you can see, I have gone to great lengths for admittance
- into your University, and I hope I have earned it. I am proud to
- wear my +
-
- ...address follows
- And here are the two C++ programs:
-
- INSTANT.CPP-----------------------------------
- // Template for byte patch files
- #include
- #include
- #include
- #include
- #include
-
- void main()
- {
- char fix(char x);
-
- char *t; //*stopstring
- int save1, save2,fdbf,fdbs, i;
- static int table[208] = {1,3,3,1,9,2,3,0, 9,0,4,3,8,7,4,4,
- 5,2,9,0,2,4,1,5, 6,6,3,2,0,8,5,6,
- 8,9,5,0,4,6,7,7, 2,0,8,0,6,2,4,7,
- 4,4,9,5,9,6,0,6, 8,7,0,3,5,9,0,8,
- 3,7,7,6,8,9,1,5, 7,4,6,1,4,2,7,1,
- 3,1,8,1,5,3,3,1, 2,8,2,1,6,5,7,2,
- 5,9,9,8,2,9,3,0, 0,4,5,1,1,3,8,6,
- 1,1,9,0,2,5,5,5, 1,7,1,5,8,7,1,9,
- 8,7,7,4,4,8,3,0, 6,1,9,8,8,4,9,9,
- 0,7,5,2,3,1,3,8, 6,5,7,6,3,7,6,7,
- 4,2,2,5,2,4,6,2, 6,9,9,1,5,2,3,4,
- 4,0,3,5,0,3,8,7, 6,4,8,8,2,0,3,6,
- 9,0,0,6,9,4,7,2, 0,1,1,1,1,0,1} ;
-
-
- //_clearscreen(_GCLEARSCREEN);
- printf("Enter the 18 digit Reg code: ");
- gets(t);
-
- for (i=1; i<=6 ; i++)
- {
- save1 = t[5]; // save the sixth digit
- save2 = t[11]; // save the twelfth digit
-
- fdbf = 0xFFC+t[17]-0x1000-0x30 ; // create [5db5]
- if (fdbf < 0x0)
- fdbf += 0xA; // fix it if necessary
- else if (fdbf >= 0xA)
- fdbf -= 0xA;
- fdbs = fdbf; // and [5db7]
-
- t[5] = t[4] - table[fdbf*0xA+fdbs] ; // sixth number
- t[5] = fix(t[5]);
-
- t[11] = t[10] - table[fdbf*0xA+fdbs+0x64]; // 12th
- number
- t[11] = fix(t[11]);
-
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[4] = t[3] - table[fdbf*0xA+fdbs] ; // 5th number
- t[4] = fix(t[4]);
-
- t[10] = t[9] - table[fdbf*0xA+fdbs+0x64]; // 11th
- number
- t[10] = fix(t[10]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[3] = t[2] - table[fdbf*0xA+fdbs] ; // 4th number
- t[3] = fix(t[3]);
-
- t[9] = t[8] - table[fdbf*0xA+fdbs+0x64]; // 10th number
- t[9] = fix(t[9]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[2] = t[1] - table[fdbf*0xA+fdbs] ; // 3rd number
- t[2] = fix(t[2]);
-
- t[8] = t[7] - table[fdbf*0xA+fdbs+0x64]; // 9th number
- t[8] = fix(t[8]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[1] = t[0] - table[fdbf*0xA+fdbs] ; // 2nd number
- t[1] = fix(t[1]);
-
- t[7] = t[6] - table[fdbf*0xA+fdbs+0x64]; // 8th number
- t[7] = fix(t[7]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[0] = save1 - table[fdbf*0xA+fdbs]; // first digit
- t[0] = fix(t[0]);
- t[6] = save2 - table[fdbf*0xA+fdbs+0x64]; // 7th digit
- t[6] = fix(t[6]);
-
- //puts(t);
- // end of first call
- ////////////////////////////////////////////////
-
- save1 = t[5]; // save the sixth digit
- save2 = t[17]; // save the 18th digit
-
- fdbf = t[10]+0x4-0x30 ; // create [5db5]
- if (fdbf < 0x0)
- fdbf += 0xA; // fix it if necessary
- else if (fdbf >= 0xA)
- fdbf -= 0xA;
-
- fdbs = t[9]+0x4-0x30; // and [5db7]
- if (fdbs < 0x0)
- fdbs += 0xA; // fix it if necessary
- else if (fdbs >= 0xA)
- fdbs -= 0xA;
-
-
- t[5] = t[4] - table[fdbf*0xA+fdbs] ; // sixth number
- t[5] = fix(t[5]);
-
- t[17] = t[16] - table[fdbf*0xA+fdbs+0x64]; // 18th
- number
- t[17] = fix(t[17]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[4] = t[3] - table[fdbf*0xA+fdbs] ; // 5th number
- t[4] = fix(t[4]);
-
- t[16] = t[15] - table[fdbf*0xA+fdbs+0x64]; // 17th
- number
- t[16] = fix(t[16]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[3] = t[2] - table[fdbf*0xA+fdbs] ; // 4th number
- t[3] = fix(t[3]);
-
- t[15] = t[14] - table[fdbf*0xA+fdbs+0x64]; // 16th
- number
- t[15] = fix(t[15]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[2] = t[1] - table[fdbf*0xA+fdbs] ; // 3rd number
- t[2] = fix(t[2]);
-
- t[14] = t[13] - table[fdbf*0xA+fdbs+0x64]; // 15th
- number
- t[14] = fix(t[14]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[1] = t[0] - table[fdbf*0xA+fdbs] ; // 2nd number
- t[1] = fix(t[1]);
-
- t[13] = t[12] - table[fdbf*0xA+fdbs+0x64]; // 14th
- number
- t[13] = fix(t[13]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[0] = save1 - table[fdbf*0xA+fdbs]; // first digit
- t[0] = fix(t[0]);
- t[12] = save2 - table[fdbf*0xA+fdbs+0x64]; // 13th
- digit
- t[12] = fix(t[12]);
-
- //puts(t);
- // end of second call
- ////////////////////////////////////////////////
-
-
- save1 = t[11]; // save the 12th digit
- save2 = t[17]; // save the 18th digit
-
- fdbf = t[1]+0x4-0x30 ; // create [5db5]
- if (fdbf < 0x0)
- fdbf += 0xA; // fix it if necessary
- else if (fdbf >= 0xA)
- fdbf -= 0xA;
-
- fdbs = t[2]+0x4-0x30; // and [5db7]
- if (fdbs < 0x0)
- fdbs += 0xA; // fix it if necessary
- else if (fdbs >= 0xA)
- fdbs -= 0xA;
-
-
- t[17] = t[16] - table[fdbf*0xA+fdbs] ; // 18th number
- t[17] = fix(t[17]);
-
- t[11] = t[10] - table[fdbf*0xA+fdbs+0x64]; // 12th
- number
- t[11] = fix(t[11]);
-
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[16] = t[15] - table[fdbf*0xA+fdbs] ; // 17th number
- t[16] = fix(t[16]);
-
- t[10] = t[9] - table[fdbf*0xA+fdbs+0x64]; // 11th
- number
- t[10] = fix(t[10]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[15] = t[14] - table[fdbf*0xA+fdbs] ; // 16th number
- t[15] = fix(t[15]);
-
- t[9] = t[8] - table[fdbf*0xA+fdbs+0x64]; // 10th number
- t[9] = fix(t[9]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[14] = t[13] - table[fdbf*0xA+fdbs] ; // 15th number
- t[14] = fix(t[14]);
-
- t[8] = t[7] - table[fdbf*0xA+fdbs+0x64]; // 9th number
- t[8] = fix(t[8]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[13] = t[12] - table[fdbf*0xA+fdbs] ; // 14th number
- t[13] = fix(t[13]);
-
- t[7] = t[6] - table[fdbf*0xA+fdbs+0x64]; // 8th number
- t[7] = fix(t[7]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[12] = save2 - table[fdbf*0xA+fdbs]; // 13th digit
- t[12] = fix(t[12]);
-
- t[6] = save1 - table[fdbf*0xA+fdbs+0x64]; // 7th digit
- t[6] = fix(t[6]);
-
-
- // end of third call
- ////////////////////////////////////////////////
-
-
- } // end of for loop
-
- // Now we finish it up
- save1 = t[16] + 0xD0 - 0x100; // [5dc1]
- save2 = t[17] + 0xD0 - 0x100; // [5dc2]
-
- for (i=0; i<6; i++)
- {
- t[i] = t[i] - save1;
- t[i] = fix(t[i]);
-
- t[i+6] = t[i+6] - save2;
- t[i+6] = fix(t[i+6]);
- }
-
- printf("'Magic' code is: ");
- for (i=0; i<18 ;i++) // output the string (only first 18)
- putc(t[i], stdout);
- printf("\n\n Created by xxxxx for +Orc's HCU 1996");
-
- } // end of main()
-
- char fix(char x)
- {
- if (x < '0')
- x = x+0xA;
-
- else if (x > 0x39)
- x -= 0xA;
-
- return x;
- }
-
- ---------------------------------------------------
- UNINSTANT.CPP
-
- #include
- #include
- #include
- #include
- #include
-
- void main()
- {
- char fix(char x);
-
- char *t;
- int save1, save2,fdbf,fdbs, i,q, fdbssave,fdbfsave;
- static int table[208] = {1,3,3,1,9,2,3,0, 9,0,4,3,8,7,4,4,
- 5,2,9,0,2,4,1,5, 6,6,3,2,0,8,5,6,
- 8,9,5,0,4,6,7,7, 2,0,8,0,6,2,4,7,
- 4,4,9,5,9,6,0,6, 8,7,0,3,5,9,0,8,
- 3,7,7,6,8,9,1,5, 7,4,6,1,4,2,7,1,
- 3,1,8,1,5,3,3,1, 2,8,2,1,6,5,7,2,
- 5,9,9,8,2,9,3,0, 0,4,5,1,1,3,8,6,
- 1,1,9,0,2,5,5,5, 1,7,1,5,8,7,1,9,
- 8,7,7,4,4,8,3,0, 6,1,9,8,8,4,9,9,
- 0,7,5,2,3,1,3,8, 6,5,7,6,3,7,6,7,
- 4,2,2,5,2,4,6,2, 6,9,9,1,5,2,3,4,
- 4,0,3,5,0,3,8,7, 6,4,8,8,2,0,3,6,
- 9,0,0,6,9,4,7,2, 0,1,1,1,1,0,1} ;
-
- printf("Enter the 18 digit 'Magic' code: ");
- gets(t);
-
- save1 = t[16] + 0xD0 - 0x100; // [5dc1]
- save2 = t[17] + 0xD0 - 0x100; // [5dc2]
-
- for (i=5; i>=0 ; i--) // fix it before main loop
- {
- t[i] = t[i] +save1;
- t[i] = fix(t[i]);
-
- t[i+6] = t[i+6] + save2;
- t[i+6] = fix(t[i+6]);
- }
-
- for (i=1; i<=6 ; i++)
- {
- // begin third call
- fdbf = 0x4+t[1]-0x30 ; // create [5db5]
- if (fdbf < 0x0)
- fdbf += 0xA; // fix it if necessary
- else if (fdbf >= 0xA)
- fdbf -= 0xA;
- fdbs = 0x4+t[2]-0x30 ; // create [5db7]
- if (fdbs < 0x0)
- fdbs += 0xA; // fix it if necessary
- else if (fdbs >= 0xA)
- fdbs -= 0xA;
-
-
- save1 = t[6]; //save 7th
- save2 = t[12]; // and 13th
-
- for (q=1; q<=5; q++) // put [ ]'s where they were at end
- of loop
- {
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
- }
- fdbssave = fdbs;
- fdbfsave = fdbf;
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[6] = t[7] + table[fdbf*0xA+fdbs+0x64]; // 7th digit
- t[6] = fix(t[6]);
-
- t[12] = t[13] + table[fdbf*0xA+fdbs]; // 13th digit
- t[12] = fix(t[12]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[7] = t[8] + table[fdbf*0xA+fdbs+0x64]; // 8th digit
- t[7] = fix(t[7]);
-
- t[13] = t[14] + table[fdbf*0xA+fdbs]; // 14th digit
- t[13] = fix(t[13]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[8] = t[9] + table[fdbf*0xA+fdbs+0x64]; // 9th digit
- t[8] = fix(t[8]);
-
- t[14] = t[15] + table[fdbf*0xA+fdbs]; // 15th digit
- t[14] = fix(t[14]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
-
- t[9] = t[10] + table[fdbf*0xA+fdbs+0x64]; // 10th digit
- t[9] = fix(t[9]);
-
- t[15] = t[16] + table[fdbf*0xA+fdbs]; // 16th digit
- t[15] = fix(t[15]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[10] = t[11] + table[fdbf*0xA+fdbs+0x64]; // 11th
- digit
- t[10] = fix(t[10]);
-
- t[16] = t[17] + table[fdbf*0xA+fdbs]; // 17th digit
- t[16] = fix(t[16]);
-
- t[11] = save1 + table[fdbfsave*0xA+fdbssave+0x64]; //
- 12th digit
- t[11] = fix(t[11]);
-
- t[17] = save2 + table[fdbfsave*0xA+fdbssave]; // 18th digit
- t[17] = fix(t[17]);
-
- // end of third call
-
- // begin second call
- fdbf = 0x4+t[10]-0x30 ; // create [5db5]
- if (fdbf < 0x0)
- fdbf += 0xA; // fix it if necessary
- else if (fdbf >= 0xA)
- fdbf -= 0xA;
- fdbs = 0x4+t[9]-0x30 ; // create [5db7]
- if (fdbs < 0x0)
- fdbs += 0xA; // fix it if necessary
- else if (fdbs >= 0xA)
- fdbs -= 0xA;
-
-
- save1 = t[0]; //save first
- save2 = t[12]; // and 13th
-
- for (q=1; q<=5; q++) // put [ ]'s where they were at end
- of loop
- {
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
- }
- fdbssave = fdbs;
- fdbfsave = fdbf;
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[0] = t[1] + table[fdbf*0xA+fdbs]; // 1st digit
- t[0] = fix(t[0]);
-
- t[12] = t[13] + table[fdbf*0xA+fdbs+0x64]; // 13th digit
- t[12] = fix(t[12]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[1] = t[2] + table[fdbf*0xA+fdbs]; // 2nd digit
- t[1] = fix(t[1]);
-
- t[13] = t[14] + table[fdbf*0xA+fdbs+0x64]; // 14th digit
- t[13] = fix(t[13]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[2] = t[3] + table[fdbf*0xA+fdbs]; // 3rd digit
- t[2] = fix(t[2]);
-
- t[14] = t[15] + table[fdbf*0xA+fdbs+0x64]; // 15th digit
- t[14] = fix(t[14]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
-
- t[3] = t[4] + table[fdbf*0xA+fdbs]; // 4th digit
- t[3] = fix(t[3]);
-
- t[15] = t[16] + table[fdbf*0xA+fdbs+0x64]; // 16th digit
- t[15] = fix(t[15]);
-
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
-
- t[4] = t[5] + table[fdbf*0xA+fdbs]; // 5th digit
- t[4] = fix(t[4]);
-
- t[16] = t[17] + table[fdbf*0xA+fdbs+0x64]; // 17th digit
- t[16] = fix(t[16]);
-
- t[5] = save1 + table[fdbfsave*0xA+fdbssave]; // 6th
- digit
- t[5] = fix(t[5]);
-
- t[17] = save2 + table[fdbfsave*0xA+fdbssave+0x64]; // 18th
- digit
- t[17] = fix(t[17]);
- // end of second call
- // begin first call
- fdbf = 0xFFC+t[17]-0x1000-0x30 ; // create [5db5]
- if (fdbf < 0x0)
- fdbf += 0xA; // fix it if necessary
- else if (fdbf >= 0xA)
- fdbf -= 0xA;
- fdbs = fdbf; // and [5db7]
-
- save1 = t[0]; //save first
- save2 = t[6]; // and 7th
-
- for (q=1; q<=5; q++) // put [ ]'s where they were at end
- of loop
- {
- fdbf -= 1; // decrement
- if (fdbf == -1)
- fdbf = 9;
- fdbs -= 1;
- if (fdbs == -1)
- fdbs = 9;
- }
- fdbssave = fdbs;
- fdbfsave = fdbf;
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[0] = t[1] + table[fdbf*0xA+fdbs]; // 1st digit
- t[0] = fix(t[0]);
-
- t[6] = t[7] + table[fdbf*0xA+fdbs+0x64]; // 7th digit
- t[6] = fix(t[6]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[1] = t[2] + table[fdbf*0xA+fdbs]; // 2nd digit
- t[1] = fix(t[1]);
-
- t[7] = t[8] + table[fdbf*0xA+fdbs+0x64]; // 8th digit
- t[7] = fix(t[7]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[2] = t[3] + table[fdbf*0xA+fdbs]; // 3rd digit
- t[2] = fix(t[2]);
-
- t[8] = t[9] + table[fdbf*0xA+fdbs+0x64]; // 9th digit
- t[8] = fix(t[8]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
-
- t[3] = t[4] + table[fdbf*0xA+fdbs]; // 4th digit
- t[3] = fix(t[3]);
-
- t[9] = t[10] + table[fdbf*0xA+fdbs+0x64]; // 10th digit
- t[9] = fix(t[9]);
-
- fdbf += 1; // increment
- if (fdbf == 10)
- fdbf = 0;
- fdbs += 1;
- if (fdbs == 10)
- fdbs = 0;
-
- t[4] = t[5] + table[fdbf*0xA+fdbs]; // 5th digit
- t[4] = fix(t[4]);
-
- t[10] = t[11] + table[fdbf*0xA+fdbs+0x64]; // 11th digit
- t[10] = fix(t[10]);
-
- t[5] = save1 + table[fdbfsave*0xA+fdbssave]; // 6th
- digit
- t[5] = fix(t[5]);
-
- t[11] = save2 + table[fdbfsave*0xA+fdbssave+0x64]; // 12th
- digit
- t[11] = fix(t[11]);
- // end of first call
- } // end for loop
-
- printf("\nTo Get That 'Magic' Use: ");
- for (i=0; i<18 ;i++) // output the string (only first 18)
- putc(t[i], stdout);
- printf("\n\n Created by +xxxxx for +Orc's HCU 1996");
-
- } // end of main()
-
- char fix(char x)
- // fixes chars to between 0 and 9
- {
- if (x < '0')
- x = x+0xA;
-
- else if (x > 0x39)
- x -= 0xA;
-
- return x;
- }
-
- III. THE [DATADUMP_WINDOW] TRICK & HOW TO SEARCH THE WEB.
-
- [WINFORMANT 4 HOW TO FIND IT]
-
- I have chosen (as usual) an older windows application for
- Win 3.1. (Version 1.10, by Joseph B. Albanese), in order to
- terminate completely the "password lessons" and at the same time
- show you a nice little trick that can be very useful in cracking
- *ALL* protected programs (password protected or time protected
- or function disabled): memory windows_dumping. There is in almost
- all protection routines, as you have already learned, a moment
- when on the stack appears the ECHO of the real, "correct"
- passnumber or password, in order to compare the input of the user
- with it.
-
- The location of this ECHO varies, but it will be most of the
- time in a range of +- 0x90 bytes from the user input. This is due
- to datadump windows restraints inside the tools used by the
- protectionists I'll not delve inside here, and this use is bound
- to diminish (especially after this lesson :=).
-
- You'll find the files that I use in this lesson searching
- the web with the usual search_tools and search_strategies: These
- are names, lengths and dates of the relevant files... this will
- allow you to FTPMAIL them after having located them through an
- ARCHIE_search:
-
- CTL3D DLL 20976 17/08/93 4:36
- README WRI 2688 08/05/94 1:54
- SS3D2 VBX 88096 11/06/92 18:42
- STDLL DLL 10880 06/05/94 22:57
- THREED VBX 64432 17/07/93 0:00
- WIN4MANT EXE 562271 07/06/96 17:51
- WIN4MANT HLP 190608 08/05/94 0:36
- XLIST VBX 15248 15/02/93 0:00
-
- Please do not underestimate the importance of *EXACT NAMES*
- on the Web (be it of people, of subjects or of software)... as
- a matter of fact the Web corroborates (every day more). The old
- intuition from Persio: NOMEN ATQUE OMEN: how true! Think a moment
- about it, the importance of the NAMES on the Web is astonishing
- (and growing)!
-
- 1) It is true for http://... addresses: domains must be
- unique and registered (and the Web registration burocrats will
- get from you 100 dollars per year just to keep them registered);
-
- 2) It is true for programs (you must know BEFOREHAND the name of
- a file to find it quickly on the Web); 3) It's even true for your
- own site denomination (try searching for "Bill's" page instead
- than for "WIKKY_WAKKY's" page... that's (reversing this approach)
- one of the reason I have a "+" inside my handle, this confuses
- the search engines just enough to give me a little more anonymity
- (search for me! You'll get quite a lot of Warcraft stuff :=).
-
- Enough! If you do not know neither why all this happen nor
- how to search the Web, but are interested in these matters (as
- you should), study the web search engines themselves and read the
- relevant help files (search AltaVista and WebCrawler for
- "FTPMAIL", "WWW via e-mail", "AGORA", "search strategies" etc).
-
- It's amazing how few crackers (not to mention the lusers)
- do actually read the help files of the search engines they are
- using, which should be your bible (or the coran, or some other
- crap, for all I care about religions), your alpha and omega! The
- (growing) amount of junk on the Web makes your ability to search
- effectively the little grains of interesting truths that are
- escaping the growing heavy censorship of our enemies even more
- important.
-
- Back to our [Winformant] cracking now, and back to our
- stackdump window trick... here you are:
-
- [WINFORMANT CRACKING]
-
- This application is -per se- absolutely crap, I doubt you'll
- ever use it: this program is so primitive it must have been one
- of the first crappy visual basic experiments made by his
- programmer... but this [Winformant] program is nevertheless very
- interesting for us coz it possesses a curious (and pretty rare)
- "deactivate" mode, i.e. you can "unregister" it on the fly if you
- feel the need to... it beats me why the programmer wanted such
- a feature inside... he was just probably collecting little
- routines and mixing them without sound reasons.
-
- This feature is as rare as useless, but it is worth for
- cracking scholars that (should) investigate password algorithms
- with valid and invalid codes without having to reinstall
- everything only in order to delete previous valid codes.
-
- For your cracking exercises you should therefore choose
- programs that have "REVERSIBLE" protections (like this
- Winformant... very rare) or that can be re-registered a billion
- times (that's a more frequent protection pattern). Programs that
- keep the valid registration on *.ini or special files can also
- be useful... you just need to change a couple of lines in these
- files to restore the "unregistered" mode.
-
- The trick we'll use in this lesson: "password proximity",
- bases on the fact that the protectionists need to keep an eye on
- their protection when they "build" it and have to *see* closely
- the relationships between
-
- 1) USER INPUT PASSNUMBER (i.e. the input registration number
- that the user should have bought, but could be a fake bad guy
- input)
-
- 2) USER INPUT TRANSFORMED (i.e. the result of the working of
- the protectionist's algorithm on the user input passnumber)
- and the
-
- 3) CORRECT PASSNUMBER ANSWER (The BINGO!) i.e., the Passnumber
- calculated with some algorithm on the bases of the USER INPUT
- NAME (the name of the user, eventually transformed in USER INPUT
- TRANSFORMED).
-
- In order to clear bugs these relationships must be
- constantly checked when they prepare the protection... i.e. when
- they are writing the protection code.
-
- Most of the time all these data will therefore dwell inside
- a small stack... that means they will be "visible" in the SAME
- "watchwindow" inside the protectionist's debugger... and they use
- the same turbodebugger (or Winice) YOU are using!
-
- This means that most of the time the "ECHO" will swell not
- very far away from the USER INPUT. Therefore proceed as follows:
-
- Fire Winice
- Fire Winformant
- Choose HELP
- Choose REGISTRATION
- Fill the registration fields
- this is mine: "+ORC+ORC" as "Registrant"
- and "12121212" as "Activation" code
- CTRL+D ;switch to Winice
- task ;let's see the names
-
- :task
- TaskName SS:SP StackTop StackBot StackLow TaskDB hQueue Events
- WINWORD 1AD7:85F2 4A52 8670 7532 1247 122F 0000
- PROGMAN 1737:200A 0936 2070 1392 066F 07F7 0000
- DISKOMAT *2C5F:6634 1D3C 6AC6 5192 2CB7 2C9F 0000
-
- hwnd DISKOMAT ;which window is getting the input?
-
- :hwnd diskomat
- WinHandle Hqueue QOwner Class Name Window Procedure
- 0EB4(0) 2C9F DISKOMAT #32769 04A7:9E6B
- 0F34(1) 2C9F DISKOMAT #32768 USER!BEAR306
- 365C(1) 2C9F DISKOMAT #32770 2C3F:0BC6
- 36BC(2) 2C9F DISKOMAT Button 2C3F:1CEA
- 3710(2) 2C9F DISKOMAT Edit 2C3F:24BE
- 3758(2) 2C9F DISKOMAT Edit 2C3F:24BE
- 37A0(2) 2C9F DISKOMAT Button 2C3F:1CEA
- 37E4(2) 2C9F DISKOMAT Button 2C3F:1CEA
- ... and many more irrelevant windows.
-
- bmsg relevant_window wm_gettext ;let's pinpoint the code, here
- ;the relevant window is the first "edit" one (obviously),
- ;i.e. wHnd 3710 you could also use GetWindowsText or
- ;GetDlgItmText to locate the relevant routines
-
- :bmsg 3710 wm_gettext ;set breakpoint
- CTRL+D ;run the babe
- 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 that we have pinpointed the code... let's snoop around
- a little: first thing to do is a good stack command which, here,
- will work OK (in other cracking sessions it may not -magic
- involved- but do not worry: if it does not work immediately, just
- pinpoint a little more... for instance on GetWindowText() (always
- good) or do a BPRW diskomat (also very useful), and then try and
- retry the stack... should this too fail to work, do 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... till you get the "real" list of calls coming from your
- babe's protection (in our example the babe's name is "DISKOMAT").
-
- :stack
- 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 picture! Immediately BPX on 2C7F:EA20 (on your
- computer the segment will differ, the offset will be the SAME).
-
- 2C7F:EA20 9A25ABA704 CALL USER!GETWINDOWTEXT
- 2C7F:EA25 8E4608 MOV ES,[BP+08]
- 2C7F:EA28 26FFB42C02 PUSH WORD PTR ES:[SI+022C]
- 2C7F:EA2D 8D865CFF LEA AX,[BP+FF5C]
- 2C7F:EA31 16 PUSH SS
- 2C7F:EA32 50 PUSH AX
- 2C7F:EA33 6A50 PUSH 50
- 2C7F:EA35 9A25ABA704 CALL USER!GETWINDOWTEXT
- 2C7F:EA3A 8D46AE LEA AX,[BP-52] ;load ptr "+ORC+ORC"
- 2C7F:EA3D 16 PUSH SS ;save pointer segment
- 2C7F:EA3E 50 PUSH AX ;save pointer offset
- 2C7F:EA3F 9A768D872C CALL 2C87:8D76 ;strlen "ORC+ORC"
- 2C7F:EA44 83C404 ADD SP,+04
- 2C7F:EA47 3D2800 CMP AX,0028
- 2C7F:EA4A 762C JBE EA78
- ...
- 2C7F:EA78 8D442C LEA AX,[SI+2C]
- 2C7F:EA7B FF7608 PUSH WORD PTR [BP+08]
- 2C7F:EA7B FF7608 PUSH WORD PTR [BP+08]
- 2C7F:EA7E 50 PUSH AX
- 2C7F:EA7F 9AE002772C CALL 2C77:02E0
- 2C7F:EA84 0BC0 OR AX,AX
- 2C7F:EA86 740F JZ EA97
- 2C7F:EA88 687F2C PUSH 2C7F
- 2C7F:EA8B 68E4ED PUSH EDE4
- 2C7F:EA8E 6A00 PUSH 00
- 2C7F:EA90 6A00 PUSH 00
- 2C7F:EA92 6A00 PUSH 00
- 2C7F:EA94 E94501 JMP EBDC
- 2C7F:EA97 8D46AE LEA AX,[BP-52] ;load ptr "+ORC+ORC"
- 2C7F:EA9A 16 PUSH SS ;various algor on input
- 2C7F:EA9B 50 PUSH AX ;we do not care
- 2C7F:EA9C 8D860AFF LEA AX,[BP+FF0A]
- 2C7F:EAA0 16 PUSH SS
- 2C7F:EAA1 50 PUSH AX
- 2C7F:EAA2 6A51 PUSH 51
- 2C7F:EAA4 8D442C LEA AX,[SI+2C]
- 2C7F:EAA7 FF7608 PUSH WORD PTR [BP+08]
- 2C7F:EAAA 50 PUSH AX
- 2C7F:EAAB 9ABA00772C CALL 2C77:00BA
- 2C7F:EAB0 0BC0 OR AX,AX
- 2C7F:EAB2 0F851101 JNE EBC7
- 2C7F:EAB6 8D8E5CFF LEA CX,[BP+FF5C] ;ptr "12121212"
- 2C7F:EABA 16 PUSH SS
- 2C7F:EABB 51 PUSH CX
- 2C7F:EABC 9A768D872C CALL 2C87:8D76 ;strlen "12121212"
- 2C7F:EAC1 83C404 ADD SP,+04
- 2C7F:EAC4 50 PUSH AX
- 2C7F:EAC5 8D865CFF LEA AX,[BP+FF5C] ;ptr "12121212"
- 2C7F:EAC9 16 PUSH SS
- 2C7F:EACA 50 PUSH AX
- 2C7F:EACB 8D860AFF LEA AX,[BP+FF0A] ...etc
-
- OK, it's enough: now what obviously follows is to "algorithmize"
- this second string, and somewhere, then, you'll have a compare
- that checks and divides good guys from bad fellows.
-
- BUT NOW IT'S ALSO THE MAGIC MOMENT OF THE ECHO! We know it, we
- feel it: The echo is somewhere... what can we do to find it?
- Should we search "12121212" in memory? No, look how many
- locations we would find...
-
- :s 30:0 lffffffff '12121212'
- Pattern Found at 0030:0005AD6A
- Pattern Found at 0030:0048AD6A
- Pattern Found at 0030:007DED98
- Pattern Found at 0030:007E25F8
- Pattern Found at 0030:008E0FE1
- Pattern Found at 0030:008E1433
- Pattern Found at 0030:008E186F
- Pattern Found at 0030:008E1904
- Pattern Found at 0030:008E601A
- Pattern Found at 0030:80509D6A
- Pattern Found at 0030:8145AD6A
- Pattern Not Found
-
- And now...should we look for all occurrences of this string
- and get a memory dump of +- 0x90 around it till we find the
- echo... that's not zen... that's boring, even if we know that the
- relevant ones will ALWAYS be the ones that have MORE than
- 80000000 in their "offset", i.e., in this case, only two:
- Pattern Found at 0030:80509D6A
- Pattern Found at 0030:8145AD6A
-
- But this procedure is not always true, and in other
- protection there will be a proliferation of locations with the
- aim of deterring casual crackers... clearly the above method is
- no good... there must be some other way... YES THERE IS!
-
- THE LAST loading of the numeric input string in the code
- (the one after the strlen count) is most of the time (exspecially
- in Visual Basic and Delphy programs) the "right" one for our
- cracking purposes, coz the protections follow (most of the time)
- this pattern (remember that we are here inside a stack "heavy"
- section of the code... if you want to crack higher I suggest you
- read some good literature about stack working and stack magics
- inside the 80386/80486/80586 processors).
-
- This is the usual sequence:
-
- LOAD NAME
- COUNT NAMELENGTH
- LOAD NAME_AGAIN
- TRANSFORM NAME
- LOAD PASSCODE
- COUNT PASSCODE_LENGTH
- LOAD PASSCODE_AGAIN
- <- ECHO CHECK here
- TRANSFORM PASSCODE
- <- ECHO CHECK here
- COMPARE TRANSFORMED_NAME WITH TRANSFORMED_PASSCODE
-
- So... what does this mean? 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
-
- 2C5F:61E8
- 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 00 00 01 00-04 2C 2F 06 AE 24 36 62 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 00 0C 00 BC 02 00 00 12121212........
- 00 00 00 00 49 00 BA 0F-AE 24 F2 24 2F 06 00 00 ....I....$.$/...
- AF 17 00 00 00 00 E2 5F-7A 62 FE FF 79 1B BA 0F ......._zb..y...
- 96 0B 01 00 02 4E 00 00-37 01 8A 62 D2 0F 8F 17 .....N..7..b....
- 2F 06 00 00 00 00 37 01-98 62 20 10 16 03 2F 06 /.....7..b .../.
- C2 62 2B 4F 52 43 2B 4F-52 43 00 0D AE 24 2F 06 .b+ORC+ORC...$/.
- 2C5F:62A7
-
- and look... everybody is there! The stack pointers points in the
- middle of this dump, at the string "12121212". 0x50 bytes before
- is our good old ECHO (i.e. the CORRECT passnumber) and 0x50 bytes
- afterwards is my beautiful input name "+ORC+ORC".
-
- Therefore the "right" code for "+ORC+ORC" is 8037-646-3836.
- It cannot be so easy! You'll protest. It is: this crap protection
- is already cracked and hunderts of Visual Basic/Delphy schemes
- are absolutely identical.
-
- Now begins the hard work: if you really want to learn,
- accomplish the following tasks:
- - First of all "Unregister" and find anew your own code for
- your own handle. *DO NOT* use serial numbers with any other
- name that your own handle.
- - Study the two coding algorithms, the one for the input name
- and the one for the input passnumber, this will be useful
- for ALL your future cracking sessions.
- - Find the compare locations, i.e. the code block that sets
- the two usual flags "good guy, you may move on" and "bad
- cracker, beggar off", and create a patch crack for this
- protection, that will allow anybody, with any name and any
- password number to get through.
-
- Please accomplish all of the preceding tasks: once you do it
- you'll have FINISHED the password protection schemes part of my
- tutorial and you'll be able to pass over to the (very
- interesting) world of disabled and crippled functions (all these
- "demos" that do not save and do not print... I'll teach you how
- to do it, starting in Februar 1997).
-
- Well, that's it for this lesson, reader. Not all lessons of my
- tutorial are on the Web.
-
- You 'll obtain the missing lessons IF AND ONLY IF you mail
- me back (via anon.penet.fi) with some tricks of the trade I may
- not know that YOU discovered. Mostly I'll actually know them
- already, but if they are really new you'll be given full credit,
- and even if they are not, should I judge that you "rediscovered"
- them with your work, or that you actually did good work on them,
- I'll send you the remaining lessons nevertheless. Your
- suggestions and critics on the whole crap I wrote are also
- welcomed.
-
- "If you give a man a crack he'll be hungry again
- tomorrow, but if you teach him how to crack, he'll
- never be hungry again"
-
- +ORC 526164@anon.penet.fi
-
- E-mail +ORC
-
- +ORC an526164@anon.penet.fi
-
-