-------------------------------------------------------- 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 at: http://www.math.gatech.edu/~mladue/PenPal.java 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; } --------------------PKU#}:G ] PJ.86PmVTSB#XD )A[D2 =NG+rP(Բ(N\UptGht-YoiRQE $@; >Ğt{{}xIIyIIQʗK={+҃eAZj>-e]jO3 B*¤U`AIv&DA?_tЉYQ=\3UtS2žRԥ{F~4|Ec<Sg$5]j~HY"kW2W1 aZG Jlmtigؒ[l6v "W}D1oS]dC,K6< ic8k7K p\@fPQN@{!W x9 BT*cviqQavzKU>t)F2l 3T(y6 OѠ`֖J9Ձv0: '^T1nIXƅJNi^*`{(}:'5:E9KBDKҶvn̵x|atPv(ȮLԖ_ *U=鈴gM -9 P6`9%`K^PTAa_mZdH.ݿ@,~e@΁Xq頪 i}ueXރ+jU-+_.ݿ(,-/(Ŷ݃= }`?}5ORJ2ba(R. THE(GTD!2Q0YPt<(A#$(62$ @ bMTX*^2F)NP?ª0!1.| I z{5~m羝^\5pfpOsut:S?@d3<)% [C@Gf0Ɖ"WtHBilkPKCU#`6y0LPJ.TXT}U6fxM~av&tZ19 MQζ\IЗe3L5sv<9~ٍh_˧\lk6w#49p;Gz0m$m 5#'p>q+B޾vH'O`Q,Bx{B^/F/޽ և~*ZRoQi y;TV4vF groEUT;^ӡq1հ'e<zRe?.>ޱYt;?_ngy!V% T"%0+-)J*)AZ Yٻ3QRsB0?YE,`˵ǽL u1rSrvg;zD /JTbz@)a1}ԟo#As5I m9VKr.FNX -dM}a("aӾeA֍i@7&,`2'3g Zx.x2M~Lߓ8bQD3>l(V7kQ4n?9j#jV"bgӒ]s iM<) LaU6VxFGtCv&w,QC?FS+A(6T=NH:_-/ FllMʔS5l!6XQ.ye_%9|5|gY*QfT,?K[E\Y_Du V[JtH*+=81%anu#%y)np[8/Eѷ,Cm Ju)`khH&DėxvYV FBj gOOr Ѿr<y!Ky)ԕ;+Yf*QTPŽ[keFؐ"=[AzoNB!/PKS#A1- PJLEVELS.86GTkEf;9>T%R\SLS! h_yO^Dz>DNV)B=TPd,\ſ~wf3JKrG7ֽׯyk|rmϟNeॐ_w7~9 ^`zݷ `gq#%0ǏLecnpN7>04qϗ^l~/f1S*UHHp/%>NH=Asi'UBhJO;$2ISqihLuRU{,i?9}wpPz>*U"gl"D,6Msiii]`]a5ZdQ7Ƙ(JfAvTmؾ$pr~Xd0-zK5-y.L[v!>m\ۧ lNs֪*\Y֖ wg!y^ 'ò9d#z:DM: My 8ER nOa27Ƅ@BV(ڮQu @)s \ <^4mu֥6Ju˭,!aSYjCQd>V0b@# Y"=09.4L`R Pwh\l5.*};G%>[o?Y%U_$*I̲j0,jȍfjǤ ura:ZIQ\i6…I"טbwpL@4&g'19?*D ܲpm+c8cÃguGK4&ʨѠ;A+L* ~; X$;B}֖Ǯ77x+H9?%4C1*`B'&1q Gl$7Vc}a Tvf;Cx5?FQfr3VβEڃ[ޭGTRSrcl,LxTfHPaqe?$6'(#8=ԧ=}{GaPKU#򆄲w\PJ.ASM"p'dt5Gs{?4ǑIo8pzF?wPBiYQ8_o+Z,G$ʲ6?7Qɛx`d#:J(dL~NgrEBW+ѿCMII>ՒlhN2ͳYzdr=Yj* ݀{Wc'ryp4Aztԃ'4ZhIҌT:Yu^]2&, ']ֵP,|n*g2*z#;~w Ð<4+KRyA6{SIa)O!Z^m](z>bdF-?yV]-]\r-?n(laKiVтT9rD]b[ѩ ob^nvǞq'hC7:2ꀜFCG s ]o JyP CLBN;o>.˭!J\'7iՊY%i3XAKX=9RHO7Y%d41-ח+t)~5"!V jGndqfi\=LǮ-IxF) "+s7𧳋;vnCq:+<ϫBIiXؖP7;GuQZg+/H>>̣O4APd.WGFuG[Đ2iH>lHlcdT><`iEl0dLN晇ӄ@@S\$T2{M_`EƑ7"g2J8ل*>y?BQ級EE.APMn_ a92Uk?:q,jH* 4` "&rf`t_1XMbyv~o'1~,w@QK勵7ϧ`uCܝ]M9z4 ,lX.-77]^Ix+2!dGY(,) - Z+oC:=5ohYBKCw!&Ad H/B_4fQa MaC ̔,ȍf` 3;ȡ)w 5F r`O; xCS5M3tA-_5!OOH+Xa tղ\D8 9g"@֡`mqiyh`*k>?g q @InuAVJEwT6 RݎrkZ9MdFLФx=\Zp-YXR _#&Ě:JF^.+bVg9j ߢgUV5 te;6M5ڑL`;? !ZT^0S کL7H~I>|Jz]0Pʇ p`$m%eZQ16o`*$-AhѢ p?ІÊfިm@aXUM,Wyewg^A 0⬙k|``˰h;~!' cX s5C  , 1ANQ9c,"zuSVɒ~e4ܱO!wrriiVWG",TœŐ9%=#%-(Bx%̋`(Z$2r#XO⹢Fn`۬bBt/-j!zԘ/486|nPdfUL =o|d gTq)kȪضb2v+I _KPD嚮e/IZǒ&$*I?.V,!n끛 ^};QUۈS JEQ@*#˼H@y|e*JVd59<[`?B̀[BL|\^N9;nإةܞbڒ.O+s_-bY¥ ]{ ud`}| gOhh164/a0t]]ba.p,lp,FCM\-Rٙ[5&/"QE?CI+~@~6F0'UI#ٺUĕdȋw^R]Z=OaԮ2UAc2MJ K *ck&Dg8waf_xJaVeTin-^B1Hy.n=S0yv:z9V34~\SssM<61DLWZs.C2I߭`QY8A[+*XURՃPPcv\WU]sg0#}0&˱{T'8*.)7(de ܅(RkU-q\1"_UF\kFێ"MtO.#fuTP4q6mZ^u9VvFFۚ{rYa dש+Eygp?jSA@%U3̮Yr05KѠi%u|Yžɵ-~uA\jaw UjMNOQA mP;a.>n'2 0lAK~.3ϲhg8Ϫ4{ȶO٢):%Y Q^}NcJˏ醬hP-=ħclh& É@Gd=P/&JpK$)\X(%d,o738V4γ1.!' YUTsruLTAN"7; Ctڞ9n(=0DyYoLǃ泋GD16ԏEvx[n@av=ڮwŰr]n\VfY_^-~2' u>?'_**flSS"iyxk̬^5 ;-f.83 f+ի}@tmdԬl4NDu6\x`ZoBxC"ĬHj^KАSӐ}3d Eԥ㰧6u5`!JvT۟,\U̡.#Zy 1mw@@o9Aϱ!#ρ.5m xEuoS`]|rρؼ*(UM$^TMݲW g#Zŭg[ŗ(CBfD.oEtj'ڌ/ѷK|)E@R*>IĐ)I(^JG Ml~yA~&OF!GA *|Oߞ~ƀD*t/BE~w{MίoGs1Q{5HBeQFH"&$yV7OׇoPX-^c9QxǶ^8.Y\ᣫr> /y#KumhJSQQDϚB6͒~[<٪Ou[F{g95:?r7[B=ӱPMw9\\ p,`9VI $ܓp 0 ŋQ'jpAE@:5` :e ]l xZRသ5@ZTZ D,׀%UuyÀ%ozMz L!o Z WұyR 8nZ 5sg.zj O,g}ұgBhK 9[ӓ請W4HO874!z]t cuQcvA\nJλ=բA~ `t˜ xa'`39>L7c TGB Cjv%#UPaSpٌpp/l@OG!Q0j2<"|`*( ϱ}PZI8 9Qv># l0UTBk$DpNgSEuFͱ!0 >z_Ie*4 5 k*sK J}a1؄&_( Ƃ8@2LY:@/ s}>r%pKEƀ; j;LRKKj@7LY* p7Ez/^}e $@;d$=Pum]{({3.BGy>dPk{ BRӸ%'79G `9p$ y< /7&i$htHٹvay:B^`9]SG]%e AIhy$fxG)̜7`Z9Ɛ0w=mP:!ޮ; , 1BvDT;3΂A'^hP2ҲS٧b.̎g/#WF)1e0+`vŸ}ms'H Zr$S>G\9[O?sQW:ҏ/oW0 θ"z:{Br]W!(YX*Kbgw>W-WPKU#}:G ]  PJ.86PPKCU#`6y0L k PJ.TXTPKS#A1- PJLEVELS.86GPKU#򆄲w\ PJ.ASMPK-Pk^X&GF$Pk^X&Gv^&|&G &_ K& vv̚YYPk^X&G^&|&G &_ K& vv̚YYPk^X)yVϳV9VVTTTTTοVΛV?V(VVVTVV;V͏VcTVVV̵V̔VsVWV'TT&G^&|&G &_ K& vv̚YYPk^X&^&|&G &_ K& vv̚YYPk^X&G^&|&G &_ K& vv̚YYPk^X&G^&|&G &_ K& vv̚YYPk^X&^&|&G &_ K& vv̚YYF};v}F F u~t ~ t~tFԴFVVʉFȀ~tF۴@f3FVjvvvv̚ ~u33'vvjvF+HfN ^ QS F;v|3F3҉V‰FF+Hf^ ،FƉ^^&|&G &_ K& vv̚YYFFtM^&|&G &_ K& vv̚YYFF$FFFPFPvvĚFvvjFPvvĚ FFĊF23)FVƒ~~Ju ~v?F;v}vveYYF Ft vvLYY3^Uvvvvvvv v vvO tvvvvvvv v vv uVvvvvvvv v vv u-vvvvvvv v vv u3]UvvPjY]UPYYjY]bPvvVF<]V TTVV TTϵVϫVǧT˛TTxVWV0VVͰV̀VVV̕V]V#VG uIePYYׇeBs ?a58Q('M L5hYc]V=U .d=L)X~r>;Ztu/+`O^y:՟sA* P!er*q73Oqq*tmh\ rաIFnjIkމ5lvacwi_19tJΨKCs]d*Nu)f2,VT!tB}*P.1)؃2p /=RW/2Ya(9;k fHMդKQ3Z~wN~S1j*.J10bX44$۹ܟlq(`YγAZGܺn61z:&Hnkj-w;{Z\G˕ >q>0 }Љ]'=,=$.'Wch]OZ+D3e 崉!ƭ:ub|ʿiR>oࢰ3kaEkzքcۆGN&#S20}A,!W+Y/3ޥcܷo҆ΑȰJ?X3RJ k\1a5mܦ,SV6Ы:A}}aqS2z?;(r"lJ7|n9[hd46.ܯsxOz#im27O&D3 ^0?3'rpM> $Ӯ 9n· e%N=LQ 0R x4_nE"8|NcA )h *e8@*}"uFK=9q# ^ E$a/8$l ߊ$Ua3N|K TtW͇k4+ԶDA>ClG((35rs#׌)YĻԵX]nRqK~AYjfX | !CCb& κ>iZӻ-?PwQ.UJK}R>Qoh^0]gO1Jbst6'p?rߥ&p-9}˼/wZ˪]IZp`@d}Lcs<mƑOEKJ}[p0^ݒ_' mq:!F1!q'[t)b?r7Z٦֬ltbj(-euEww+3BUzF矢ճT{ cddaGPh,RFM64_iNo>BQF GcQбH_x9!X~} V8Dुmm^7|(8 RO'1- -J5Ad SKٗt R޿L82>18pSmY7XHx%},ަ ` kl(&֪ƫ>\ގ֑e =X2I:::0ٷy|/EzT~vlLtcrhe{Lt1Z"IqtvJTNOcFFz:D6pZ@|KecnS?:6E>p+ -jm.:[9͉>($sPf-+_, tH=wEBbM^"VE1۱AN6AE{#tvYb?,&J LخEzHD$4 1%9b`pdcۨw*v-]#.0`Yj6^ǡ)[|sT7EKҙFbÄc7jSd)%0 @P"6r370FCAH`80<Vn޺.bէýQf}WMz1_?]!;W8ܨ khon9V~ƶtJ5YK~HrlQ!Q_=OmSaYwcs]GH'r0ejrYMWG% Euiml@ޓcّGW,ڔ X2\K--/7/ƥVHIgޭTP)зR"^LDKDUWRk>ԼK] =1s/y oce)005%2\Ɨ#܏5>չvxöGvB|ֈ{{R4Fe{7{{Gxpr7A.QqbJ\CoRWU.' c[mPvA8B$ wpwj4Uu"a`Pa?pӓ=kmU%E3ohT h]~j_`\" 4wg:r`djd5붨ӚoRK-/c=}Z5w71*;hme5^mmķڵj5k7k<[W+^|19[\PW![ǬN hMcΝ;uǛmgT3oj:KHІXTi >*Qp@)&o5u6Y}r8+w:OPl 9)6uSIwO~r{{|sn'NN8prb6}nz̮;oL0JKھsgrĚxR\Y,9+(>ң]r98dY`lx[W,U ~3m9CBIdRYoaJt9{p}]!8(gу& C&foa.[Zp t~cG9ԧX~K=_R^zX]mEC[S )շEjZ*_Yu ۱ч(2MG@% vJ5e) R(f`` 1eI2Օ_x5Q3g||MS9+>}Pݞhe,n7]1=k2Kwp趇?jw`oq'M}y=A9v6^fVx<ݚm?ټ[u_jswi(TG!RM5YoDӵ,j=s|b{cG\8x !{gh_I2lJ16wrelj8sLcz22ӽ1UEZoJ^39g1q$\򩌽'G{3'bm Ƃ8T!uxC~Gx1;ҁk8'>`30IFQ̆HQt  8!O. QH:K9v^Ǽ]c#-m{\##  /z3|atʅ2+NcIqIc` kB'^g GgׂA1`ZB2CN%r_XkkZhXțC,Y^up-~]߳76eTfTzDBD唡3Ɉ᭲;q;-58!n}!vgx}J~U|o~^n5KSk{ˇFg09*0e4c᪪CZ+8LOu]]f+i7.&#Ƈ,mY:;m066o`i/=W{1ݫȶ}mJxMS5kk9Uflm=cDȩmwCC~<E?cۓߍ OkYh29b Y/G^o𹅺]#Qzj* zq,X(4 h^eܺ%yBfP+Kyi *͙K$7'^';l"_"[HԍXބ!̡Bh />1H8fS~h04еܥLQ}X8TXߕjFv#jZ ƭ&ݺc}}C'o--M獟IU_3B $|5E&8qyiA@,#^ʉ:5\çInj-l9xf?t ^ e慖{88p0imv_::U;>>49]ѯ2zdW_9Ky|l4xu^EAv?.H2"KB!#DNhSή[w]ذudrVP|wHd@ָI275.2-6glonk(?b;f{R17R!!I R5FY{ecTxr,I35t 6i}jpJDolh[LtҙI {7UsM@%& + D * ږ8ʹ@]5]ZjhFQո.1T0N0ԧ`Tzd[qpV4 @l!|Q On%}eK8<5`)jjȣ_v}xmisM;A17zŚ35M–]8z#e>WНWQ';(ѐ $p FBLK=ujbjVʎZsh^k=޶=sǾ6F S{gw[_:pc9T26P2xxTnZ ]//u/_& x"xuf4Zڮ4Sv4$ z0@D H#S4Wzhp݈k|E__:U硛C\EGm8!~"/W/'@1j3ȥ!šة/+<7GMłI}vF'QgB~ #w۽ֻM J2"9EsJc oAJ[t 0 >ei6/&. KQ+.;J&9paye^U1=S ZBzǜ{T 2A*/nWA"V%SG|uk_{HdS˩ޅ3ohrM=7[-f=s}w~Iޫ}c#ƅ)3s i Yb%28 :knw M}VK0b8x%aTXD¶_40_mM*U!ZM ه8|ssuU V 9:tuUVVGm:$:(8|O htQs3RD}jiegnaҫM"*!kpI@)K:,,J~ up&H`-Roݖ-c .l&zCc^8C| Aw>?Z? _dUԛTv:T*R* ~ /lc?{ G%jLVEsA߆<`746HE