home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / +Sandman / Htocrkc3.txt < prev    next >
Text File  |  2000-05-25  |  58KB  |  1,604 lines

  1.                      HOW TO CRACK, by +ORC, A TUTORIAL
  2.  
  3. ------------------------------------------------------------------------
  4.  
  5.                 Lesson C (3): How to crack Windows, Hands on
  6.  
  7. ------------------------------------------------------------------------
  8.  
  9.                               [INSTANT ACCESS]
  10.  
  11.                    --------------------------------------
  12.  
  13.  
  14. --------------------------------------------------------
  15. LESSON C (3) -  How to crack Windows, cracking as anArt:
  16. Web trends, Instant Access (end) and the proximity trick
  17. --------------------------------------------------------
  18.  
  19. I. [WEB TRENDS]
  20.  
  21. It's really amazing: I began this tutorial in february 1996...
  22. the year is not yet finished but many things have already
  23. changed, and how! First of all the Web proves to be even more
  24. significant that I would ever have thought: it's -de facto- an
  25. ANTI-ESTABLISHMENT and ANTI-CONSUME "permanent" tool... more than
  26. that: it's an EVOLVING and SHARP tool!
  27.  
  28. I do not know if you will agree with me, but it seems to me that
  29. it is now NOT ANY MORE NECESSARY to buy any of the following
  30. things (and this is a quite incomplete list:
  31.  
  32. 1)   Newspapers     Are almost all on the Web for free
  33. 2)   Magazines      Are almost all on the Web for free
  34. 3)   Software       All on the Web for free
  35. 4)   Books          on the Web (even the *images* inside the
  36.                     books you would have bought are somewhere)
  37. 5)   Post_stamps    e-mail is free and ubiquitous
  38. 6)   Hard_disks     free megabytes everywhere on the Web (for
  39.                     pages and/or software, quite a lot of
  40.                     offering (at the moment, middle november
  41.                     1996 you can get -for free- about 80
  42.                     megabytes for each email address you have).
  43.                     Should you do not deem this space enough,
  44.                     you may multiply them -ad libitum- using one
  45.                     of the many free "alias e-mail addresses"
  46.                     generators or, as a brilliant scholar of
  47.                     mine (re)discovered, you may easily "caper"
  48.                     (the passwords of) pages established by the
  49.                     lusers.
  50.  
  51.      I assure you that I used to spend quite a lot of money
  52. buying all the preceding items. The case of the CD-ROM magazines
  53. (and of software in general) seems to me to be the most relevant.
  54. In my earlier lessons I advised you to buy CD-ROM software at
  55. "kilo" prices in second hand shops (obviously never when the
  56. magazines themselves do appear)... even this trick is now
  57. useless: there is NO software that you cannot find on the Web
  58. (I'll bet that the CD-ROM mags are not making any easy money any
  59. more now). This truth may be difficult to slurp until you learn
  60. HOW to search effectively on the Web, a very difficult art -per
  61. se-, that all real crackers should master. A little tip: if you
  62. are in a hurry do your searches  using your own search engines
  63. instead of using only the ubiquitous AltaVista, FTP and
  64. Webcrawler (which you SHOULD use, of course, but not alone).
  65.      And loo! Good old Internet, made by governments and
  66. universities with public money and no private partecipation
  67. whatsoever reveals itself to be the most striking revolution of
  68. the last years in spite of the continuous blah blah about free
  69. markets and private initiative... quite funny, isn't it?
  70.  
  71.      New promising patterns are emerging: it is clear (to me)
  72. that the future of cracking lays in JavaScript applets: Netscape
  73. has opened quite a Pandora Box... now everybody is scrambling to
  74. close it... TOO LATE! Find the relevant documentation, tutorials,
  75. software, tools, examples... even teachers! Everything is there
  76. for free on the Web! Study it, and when you are ready study it
  77. again... take it easy: we have a long cracking future before
  78. us...
  79.  
  80.      Here is a nice example (by LaDue) of an interesting applet:
  81. this one forges an e-mail from the browsers of your page sending
  82. it to the address contained in the string "toMe". The browser of
  83. your page initiates the mail by connecting (involuntarily) to
  84. port 25 (int mailPort=25).
  85.  
  86.      Now, let's just academically imagine... you would put your
  87. own address (faked email address but working depot when you need
  88. to fetch the messages, as usual) in the string "toMe"... well,
  89. scanning incoming mail you could get the full e-mail address,
  90. including the user name, of many people who have seen your page.
  91.      See LaDue example:
  92.  
  93. here.
  94.  
  95.      JavaScript and Java are two completely different things: The
  96. coincidence in the name is only a stupid marketing move from
  97. Netscape. JavaScript is so easy it's a shame, and this makes it
  98. the ideal weapon for masscracking (Java on the countrary is a
  99. "real" programming language). The implications of easy Javascript
  100. use, of internet growth and of the "on the fly" JavaScript
  101. workings for the drafting of much more interesting applets are
  102. obvious, I'll let them to the intuition (and fantasy) of my
  103. cleverest readers.
  104.  
  105. II.[INSTANT ACCESS] End
  106.  
  107.      I'll admit it: I am a little deceived: the +HCU strainer
  108. (Instant access protection scheme) has been solved only by very
  109. few (pretty competent) crackers. The amount of people that has
  110. NOT cracked instant access (and that as relentlessy asked for
  111. more "clues") stood in no sound relation to the very few that
  112. solved it. I intended to give my complete solution in this lesson
  113. C3 to allow everybody to have (good) software for free... but too
  114. few worked hard on it to let you all lazy ones deserve a "ready-
  115. made" solution... I will therefore publish here one of the
  116. "incomplete" (albeit very good) solutions.
  117.  
  118.      The solution cracks the scheme but requires a little work
  119. of your part to accomplish it... what I mean is this: studying
  120. the following you'll be able to crack every Instant access
  121. protected code in a couple of hours, not immediatly... this is
  122. good, will make the lazy lurkers work (at least a little :=)
  123.  
  124.      Here it is (C++ code of the solution and admission letter),
  125. I only took off the name of the candidate:
  126.  
  127. Cracking Instant Access_____________
  128. by xxxxxxxx
  129. Application for 1996 Higher Cracking University
  130.  
  131.      This is my solution to the strainer for admittance into your
  132. HCU. While I was successful in bypassing the protection (and
  133. hence now have a nice collection of software for free) I am the
  134. first to admit that my solution is not the best. However, I am
  135. very proud of the work I have done on this project and it is by
  136. far the most difficult crack I've ever done. In the past I've
  137. traced programs, and when they did something I did not like, I
  138. looked at the jumps immediately before that and reversed them.
  139.  
  140.      Because of idiot programming this worked about 60% of the
  141. time, however in many programs I was just stuck. With the hints
  142. you provided in your tutors I was able to actually disassemble
  143. the program and understand why it did things. Believe me this is
  144. a big jump. Anyway, here is my solution.
  145.  
  146.      I have dozens of handwritten notes and pages of code that
  147. I copied out of soft-ice, and any that are important I will type
  148. into this report, however most turned out to be unimportant. I
  149. have also created a "Magic" number generator and a reverse
  150. generator. I am very proud that I was able to create these,
  151. because the "Magic" number seemed so mysterious at first, and now
  152. I have complete mastery of it, a great feeling of power.
  153.  
  154.      I began the project by following the introductory steps in
  155. lessons C1 and C2. I got lost somewhere in C2, but I kept going.
  156. I got to the end with a vague understanding of what was happening
  157. and decided that I needed to understand this fully before I could
  158. do anything useful towards cracking it.
  159.  
  160.      I left my computer alone and read through the code again,
  161. making notes and explanations for my own use. About the third
  162. time through everything clicked, it was like a light bulb going
  163. off in my head. You mentioned that not everything in Lesson C1
  164. was correct.
  165.  
  166.      Here is a list of what I found to be incorrect.
  167.  
  168. 1. The offsets in the code were not the same. (this is a good
  169. idea to keep people from cheating when pinpointing the correct
  170. code)
  171.  
  172. 2. The pointers to where things are saved in memory were not the
  173. same.
  174.  
  175. 3. You wrote that the 1st digit plus 7 was saved and then you
  176. wrote that the 2nd plus 3 was saved. It is the other way around!
  177. 1st plus 3 and 2nd plus 7. (just checking if we are paying
  178. attention huh?)
  179.  
  180.      I think that's all of the one's I found although there were
  181. many specific instances of each one. So here's what I did.
  182.  
  183.      I did a search on the 18 digit code I typed in. I found it
  184. at 30:8xxxxx and did a bpr on it. I let it run, and looked each
  185. time something accessed that area. Eventually I found code that
  186. checked if the digits were between 30 and 39 and copied them to
  187. DS:8CD8. So there lies the code with the "-" 's stripped off of
  188. it.  I did a bpr on this area. It copied itself to DS:8CB8, and
  189. I bpr'ed that as well. I discovered that what was going on was,
  190. it copied itself, then that copy was transformed into the "Magic"
  191. number.
  192.  
  193.      So I did a little stack fishing, and found a CALL at offset
  194. 5C04 which copies the code from 8CB8 and converts it into the
  195. "Magic" number. At this point I traced into the call and got
  196. really fucking lost, so I stepped back had a sip of Vodka and
  197. thought. I don't care HOW the "magic" gets there, only that it
  198. is there. I figured once I figured out what "magic" I needed I
  199. could trace over the call that put it there, and then put in
  200. whatever "magic" I wanted. So I traced on to see what happened
  201. to the "magic" number that had been produced. I had a bpr on the
  202. "magic" and it stopped on the first line of code below.
  203.  
  204.      The code is copied from my handwritten notes, so not
  205. everything is accurate (I only wrote down what I thought was
  206. important)
  207.  
  208. 2b67:2598 mov  al, es:[bx]    ; 12th digit of magic
  209.           mov  [bp-03], al    ; ??????
  210.           mov  al, [bp-03]    ; maybe an inefficient compiler
  211. result
  212.           add  al, d0         ; clean it
  213.           mov  [bp-04], al    ; save it in [8ca6]
  214.           les  bx, bp+06
  215.           add  bx, si         ; point to 12th again
  216.           mov  byte ptr es:bx, 30  ; make it a '0'
  217.           push then more crap and then
  218. :253d     mov  al, es:bx      ; 1st digit
  219.           mov  ah, 00         add  ax,ffd0        ; clean it
  220.           cwd
  221.           add [bp-06], ax          ; [8c90] is zero to start
  222. this loop repeats 18 times, summing up the "magic" number, with
  223. the 12th set to 0
  224.  
  225. :256e     mov  [bp-07], al    ; save remainder of sum/a in [8c8f]
  226.           cmp  [al, bp-05]    ; is 12th (in al) save as remainder
  227. of sum/a ? Aha!, this is what you were talking about at the end
  228. of C2, where the remainder doesn't match the 12th number.
  229. I knew I was on the right track. I could feel it.
  230. I traced down farther after the remainder check (I used
  231. 8888-8888-8888-8888-88 as my code from then on because it passed
  232. this check and was easy to remember) and I found code which
  233. compared the value at ds:8D00 with the value at ds:8D0C and if
  234. it did not match jumped to beggar off.
  235.  
  236.      Then it checks if ds:8D06 is equal to ds:8D0E and if not
  237. equal jumps to beggar off. So I knew that 8D00 must equal 8D0C
  238. and that 8D06 must equal 8D0E.
  239.  
  240.      All I needed to do was figure out where these came from. I
  241. bpr'ed on 8D0C and found code which wrote the number to it.
  242.  
  243.      I did not copy the ASM down, but this is what I wrote:
  244. move 15th of "Magic" into AX  fix it to 0-9 by +- A
  245. put it in SI
  246. mov 16th into AX
  247. mul si by A
  248. add ax to si
  249. mov 17th to AX
  250. mul si by A
  251. add ax to it
  252. put 18th in AX
  253. mul si by A
  254. add AX to it   ; This is ds:8D0C !!!!
  255.  
  256. So now I knew where this came from, the last 4 digits of the
  257. "magic" I bpr'ed on 8D0E and found out quickly that the first
  258. digit of the "magic" was put into ds:8D0E.
  259. Things were looking good. However, I was unable to figure out how
  260. ds:8D06 and ds:8D00 were created. I know they are related to the
  261. product code because they only change when it does. But they are
  262. put there by a MOVSW command and I cannot figure out how to
  263. predict where they are copied from, because it is only done once
  264. and it is never from the same place, so all my attempts to bpr
  265. on the spot they are copied from failed because it copies from
  266. a new spot each time.
  267.  
  268.      I felt dejected. I could not figure it out, even after days
  269. of pointless tracing.
  270.  
  271.      I stepped back and thought, and drank a can of Coke at 2
  272. a.m...
  273.  
  274. (note from +ORC: Coke is dangerous for your health and your cracking
  275. purposes... drink only Martini-Wodka and use by all means only russian
  276. Wodka)
  277.  
  278.      ...I still had not figured out how the "magic" worked. I
  279. decided to do that and come back to the problem of the numbers
  280. generated from the Product Code.
  281.  
  282.      I knew the call at cs:5C04 completely generated the "magic"
  283. so I started there.  I traced through it several times and found
  284. that it made a CALL 3517 three times, then looped 6 times. So it
  285. called 3517 a total of 18 times. I also noticed that the CALL
  286. changed the number, but nothing else did, it just set up the
  287. calls.
  288.  
  289.      So I traced into CALL 3517 and came up with this:
  290.  
  291. mov  ax,ss
  292. nop  inc  bp
  293. push bp
  294. mov  bp,sp
  295. push ds
  296. mov  ds,ax
  297. xor  ax a bunch more unimportant stuff
  298. :356b     mov  al,es:[bx}     ; al = 18th digit
  299.           cbw  push ax
  300.           mov  ax, A
  301.           sub  ax,[5dad] ; subtract 6 from a to get 4
  302.           imul [5db1]    pop  dx        ; 18th digit
  303.           add  dx,ax     add  dx, -30   ;clean it
  304.           mov  [5db5], dx     ;save it then fix [5db5] to be
  305. between 0 and 9
  306.           mov  al, es:[bx]    ; load 18th again
  307.           cbw  push      ax
  308.           mov  ax,a
  309.           sub  ax,[5dad]
  310.           imul [5db3]
  311.           pop  dx   ; 18th digit
  312.           add  dx, ax
  313.           add  dx, -30        ;clean it
  314. :35bb     mov  [5db7], dx     ;save it.
  315. :35d9     mov  bx,[5dad]
  316.           mov  es, bp+1a
  317.           add  bx,[bp+18]
  318.           mov  al,es:[bx-1]   ; al = 6th digit
  319.           mov  [5dc3], al     ; save it
  320.           mov  bx,[5dad]
  321.           mov  es,[bp+1e]
  322.           add  bx,[bp+1c]
  323.           mov  al,es:[bx-1]   ; 12th digit
  324.           mov  [5dc4], al     ; save it more junk then
  325. 3605:     mov  bx,[5dbf] ; this is the beginning of a loop
  326.           mov  es,[bp+1a]
  327.           add  bx,[bp+18]
  328.           mov  al,es:[bx-1]   ; 5th digit
  329.           push ax        ; save it
  330.           mov  ax,[5db5] ; [5db5] created above using 18th digit
  331.           mov  dx,A
  332.           imul dx        ;[5db] *A
  333.           les  bx,[bp+0c]
  334.           add  bx,ax
  335.           add  bx,[5db7] ; created using 18th
  336.           pop  ax        ;5th digit
  337.           sub  al,es:[bx};subtract a value from the lookup table
  338.           les  bx   add  bx,[5dbf]
  339.           mov  es:[bx],al     ; Put new value in 6th spot fix it
  340.  
  341. so that it's between 0 and 9 by +- A
  342. :3656     mov  bx,[5dbf]
  343.           mov  es,[bp+1e]
  344.           add  bx,[bp+1c]
  345.           mov  al,es:[bx-1]   ; 11th digit
  346.           push ax   mov  ax,[5db5]
  347.           mov  dx,a
  348.           imul dx
  349.           les  bx
  350.           add  bx,ax
  351.           add  bx,[5db7]
  352.           pop  ax        ;11th digit
  353.           sub  al,es:[bx]     ; subtract a value from lookup
  354. table
  355.           les  bx, [bp+1c]
  356.           add  bx,[5db7]
  357.           mov  es:[bx],al     ;put it in 12th spot fix it to be
  358. between 0 and 9 The loop above repeats doing the same thing,
  359. changing 2 numbers, but not always the same two. The next time
  360. through it changes 5th and 11th, after that the 4th and 10th, 3rd
  361. and 9th then the 2nd and 8th using this same pattern. After the
  362. loop it changes the 1st and 7th using the values of the original
  363. 6th and 12th which were saved in [5dc3] and [5dc4] using the same
  364. pattern. I quickly wrote a program in C which would produce this
  365. number, and it worked fine.
  366.  
  367.      I traced into the second call of 3517 and found that the
  368. parameters passed to it changed which values where used to create
  369. [5db5] and [5db7], whether they increment or decrement, whether
  370. you add 0 or 64 to your index for the lookup and the digits which
  371. are changed. All three calls to 3517 have a different
  372. arrangement, but the their arrangement is the same each time they
  373. are called. For instance, the three calls are looped over 6
  374. times, on each instance that the 1st call is executed it will
  375. change the 6th,12th,5th, 11th, etc. So I modified my C program
  376. to mimic the behaviour of each call and looped it six times,
  377. expecting this to be the "magic" number. To my surprise it was
  378. not right.
  379.  
  380.      So I followed the code until after the 3 CALL 3517's had
  381. been made, this was the number my generator had given me, so it
  382. must do something more afterwards.
  383.  
  384.      I found the following code, still within the cs:5c04 call
  385.  
  386. :44C1     mov  al,es:[bx+si-2]     ; 17th digit
  387.           add  al,d0               ;clean it
  388.           mov  [5dc1], al          ;save it
  389.           les  bx
  390.           mov  al,es:[bx+si-2]     ; 18th digit
  391.           add  al,d0               ;clean it
  392.           mov  [5dc2],al           ;save it
  393.           mov  [5dbf],0
  394.           jmp  455f :44df
  395.           les  bx
  396.           add  bx,[5dbf]
  397.           mov  al,[5dc1]           ;17th cleaned
  398.           sub  es:[bx],al          ;1st digit has 17th cleaned
  399. subtracted from it  fix it between 0 and 9
  400.           mov  al,[5dc2] ;18th cleaned 4520
  401.           sub  es:[bx],al     ;7th - 18th cleaned is put in 7th
  402. spot      fix it between 0 and 9
  403. :455b     inc  word ptr [5dbf]
  404.           mov  ax,[5dbf]
  405.           cmp  ax,[5dad] ; run six times
  406.           jge  456b
  407.           jmp  44df 456b:  blah blah continue on.
  408. This loop executes six times each time incrementing the digit to
  409. be changed by one so that the first change changes the 1st digit,
  410. and the next time through the loop the 2nd then the 3rd.....till
  411. the sixth. The second change alters the 7th through the 12th
  412. digits. I added code to do this at the end of my Generator, and
  413. I now had a "Magic" number generator. However this did not do me
  414. much good in itself. The breakthrough was reversing this program
  415. (it wasn't hard, but getting all the bugs out was really tough)
  416. so that it takes a "magic" number as input and tells you what
  417. registration number will produce it. I have included the source
  418. code for both programs to prove that they are my own work. The
  419. coding is not the best, they are my own crude tools, and they do
  420. the job I need them for. But now I am home free. Even without
  421. knowing how the product code is manipulated to come up with
  422. ds:8D00 and ds:8d06 I can crack it. Here's what I did.
  423.  
  424.      The product code given me was 3850-0118-6260-1057-23 I
  425. traced to where ds:8D00 and ds:8D06 are placed they were:
  426. ds:8D00 = E03  ds:8D06 = 3 I knew the last 4 digits when added,
  427. and multiplied as explained above must be E03 so this is what I
  428. wrote down, using my calculator
  429.  
  430.      DFC + 7 =E03
  431.  
  432. This is the final answer, but I need to work backwards from here
  433.  
  434.      166 * A = DFC
  435.      15E + 8 = 166
  436.      23 * A = 15E
  437.      1E +5 = 23
  438.      3 * A = 1E
  439.  
  440. Just working things backwards from the way the program did it I
  441. figured out the last 4 digits of the magic code need to be 3587
  442. in order for it to produce E03 as a result. I also know that the
  443. first digit must be equal to ds:8d06 which is 3 so I now have:
  444.  
  445.      3___-____-____-__35-87
  446. as a "magic" number and I fill it in with 1's
  447.  
  448.      3111-1111-111X-1135-87
  449.  
  450. I left the 12th number as an X because I remember that the
  451. remainder of the sum of all the digits except the 12th must be
  452. equal to the 12th.
  453.  
  454.      3+1+1+1+1+1+1+1+1+1+1+1+1+3+5+8+7 = 26 26/A
  455.      26 26/A = 3 with a remainder of 8,
  456.  
  457. so the 12th digit is an 8!
  458.  
  459.      My "magic" number should be 3111-1111-1118-1135-87
  460. So I run my UNINSTAN program, which tells me that in order to get
  461. that "magic" I need to enter the following registration code:
  462. 4798-8540-6989-6899-53 I enter this in, the "Retrieve" button is
  463. enabled and I install Norton Utilities without a hassle! I used
  464. the same method to install Wine Select (I've been interested in
  465. wine since reading about your Pomerol), Labels Unlimited (which
  466. I use for what else? Barcodes!), Harvard Graphics, and Lotus Ami
  467. Pro, which I'm using to write this report on!
  468.  
  469.      Well, that's it. That is how I cracked Instant Access. As
  470. I mentioned above it is not the best way, but I gave everything
  471. I had and it's the best I could do.
  472.  
  473.      I have succeeded because I have beaten the protection, and
  474. because I taught myself a lot along the way. I'm sure you already
  475. have a "magic" number generator of your own, but I included mine
  476. so you could see it. If I just knew how the product code produces
  477. those 2 numbers I could create a product code to registration
  478. number converter, which I assume is what the operators at Instant
  479. Access have when you call them to buy stuff.
  480.  
  481.      One last note about this assignment. I know that you have
  482. realized that Instant Access was hard to find. I want to tell you
  483. how I got it, a bit a social engineering in itself. After
  484. searching every library and book/magazine store in the city I got
  485. on the Internet and asked. Nobody had it.
  486.  
  487.      So I found the Instant Access homepage. ...
  488.  
  489. (this will not be published, coz I, +ORC, do not want to expose my
  490. crackers, but the way this guy got hold of the protection scheme is in
  491. itself worth is access to the +HCU)
  492.  
  493. ...So as you can see, I have gone to great lengths for admittance
  494. into your University, and I hope I have earned it. I am proud to
  495. wear my +
  496.  
  497. ...address follows
  498. And here are the two C++ programs:
  499.  
  500. INSTANT.CPP-----------------------------------
  501. // Template for byte patch files
  502. #include
  503. #include
  504. #include
  505. #include
  506. #include
  507.  
  508. void main()
  509. {
  510.      char fix(char x);
  511.  
  512.      char *t; //*stopstring
  513.      int  save1, save2,fdbf,fdbs, i;
  514.      static int table[208] = {1,3,3,1,9,2,3,0, 9,0,4,3,8,7,4,4,
  515.                5,2,9,0,2,4,1,5, 6,6,3,2,0,8,5,6,
  516.                8,9,5,0,4,6,7,7, 2,0,8,0,6,2,4,7,
  517.                4,4,9,5,9,6,0,6, 8,7,0,3,5,9,0,8,
  518.                3,7,7,6,8,9,1,5, 7,4,6,1,4,2,7,1,
  519.                3,1,8,1,5,3,3,1, 2,8,2,1,6,5,7,2,
  520.                5,9,9,8,2,9,3,0, 0,4,5,1,1,3,8,6,
  521.                1,1,9,0,2,5,5,5, 1,7,1,5,8,7,1,9,
  522.                8,7,7,4,4,8,3,0, 6,1,9,8,8,4,9,9,
  523.                0,7,5,2,3,1,3,8, 6,5,7,6,3,7,6,7,
  524.                4,2,2,5,2,4,6,2, 6,9,9,1,5,2,3,4,
  525.                4,0,3,5,0,3,8,7, 6,4,8,8,2,0,3,6,
  526.                9,0,0,6,9,4,7,2, 0,1,1,1,1,0,1} ;
  527.  
  528.  
  529.           //_clearscreen(_GCLEARSCREEN);
  530.           printf("Enter the 18 digit Reg code:  ");
  531.           gets(t);
  532.  
  533. for (i=1; i<=6 ; i++)
  534.      {
  535.           save1 = t[5];       // save the sixth digit
  536.           save2 = t[11];      // save the twelfth digit
  537.  
  538.           fdbf = 0xFFC+t[17]-0x1000-0x30 ; // create [5db5]
  539.           if (fdbf < 0x0)
  540.                fdbf += 0xA;   // fix it if necessary
  541.           else if (fdbf >= 0xA)
  542.                fdbf -= 0xA;
  543.           fdbs = fdbf;                            // and [5db7]
  544.  
  545.           t[5] = t[4] - table[fdbf*0xA+fdbs] ;  // sixth number
  546.           t[5] = fix(t[5]);
  547.  
  548.           t[11] = t[10] - table[fdbf*0xA+fdbs+0x64]; // 12th
  549. number
  550.           t[11] = fix(t[11]);
  551.  
  552.  
  553.           fdbf -= 1;          // decrement
  554.           if (fdbf == -1)
  555.                fdbf = 9;
  556.           fdbs -= 1;
  557.           if (fdbs == -1)
  558.                fdbs = 9;
  559.  
  560.           t[4] = t[3] - table[fdbf*0xA+fdbs] ;  // 5th number
  561.           t[4] = fix(t[4]);
  562.  
  563.           t[10] = t[9] - table[fdbf*0xA+fdbs+0x64]; // 11th
  564. number
  565.           t[10] = fix(t[10]);
  566.  
  567.           fdbf -= 1;          // decrement
  568.           if (fdbf == -1)
  569.                fdbf = 9;
  570.           fdbs -= 1;
  571.           if (fdbs == -1)
  572.                fdbs = 9;
  573.  
  574.           t[3] = t[2] - table[fdbf*0xA+fdbs] ;  // 4th number
  575.           t[3] = fix(t[3]);
  576.  
  577.           t[9] = t[8] - table[fdbf*0xA+fdbs+0x64]; // 10th number
  578.           t[9] = fix(t[9]);
  579.  
  580.           fdbf -= 1;          // decrement
  581.           if (fdbf == -1)
  582.                fdbf = 9;
  583.           fdbs -= 1;
  584.           if (fdbs == -1)
  585.                fdbs = 9;
  586.  
  587.           t[2] = t[1] - table[fdbf*0xA+fdbs] ;  // 3rd number
  588.           t[2] = fix(t[2]);
  589.  
  590.           t[8] = t[7] - table[fdbf*0xA+fdbs+0x64]; // 9th number
  591.           t[8] = fix(t[8]);
  592.  
  593.           fdbf -= 1;          // decrement
  594.           if (fdbf == -1)
  595.                fdbf = 9;
  596.           fdbs -= 1;
  597.           if (fdbs == -1)
  598.                fdbs = 9;
  599.  
  600.           t[1] = t[0] - table[fdbf*0xA+fdbs] ;  // 2nd number
  601.           t[1] = fix(t[1]);
  602.  
  603.           t[7] = t[6] - table[fdbf*0xA+fdbs+0x64]; // 8th number
  604.           t[7] = fix(t[7]);
  605.  
  606.           fdbf -= 1;          // decrement
  607.           if (fdbf == -1)
  608.                fdbf = 9;
  609.           fdbs -= 1;
  610.           if (fdbs == -1)
  611.                fdbs = 9;
  612.  
  613.           t[0] = save1 - table[fdbf*0xA+fdbs];    // first digit
  614.           t[0] = fix(t[0]);
  615.           t[6] = save2 - table[fdbf*0xA+fdbs+0x64]; // 7th digit
  616.           t[6] = fix(t[6]);
  617.  
  618.      //puts(t);
  619.      // end of first call
  620. ////////////////////////////////////////////////
  621.  
  622.           save1 = t[5];       // save the sixth digit
  623.           save2 = t[17];      // save the 18th digit
  624.  
  625.           fdbf = t[10]+0x4-0x30 ; // create [5db5]
  626.           if (fdbf < 0x0)
  627.                fdbf += 0xA;   // fix it if necessary
  628.           else if (fdbf >= 0xA)
  629.                fdbf -= 0xA;
  630.  
  631.           fdbs = t[9]+0x4-0x30;         // and [5db7]
  632.           if (fdbs < 0x0)
  633.                fdbs += 0xA;   // fix it if necessary
  634.           else if (fdbs >= 0xA)
  635.                fdbs -= 0xA;
  636.  
  637.  
  638.           t[5] = t[4] - table[fdbf*0xA+fdbs] ;  // sixth number
  639.           t[5] = fix(t[5]);
  640.  
  641.           t[17] = t[16] - table[fdbf*0xA+fdbs+0x64]; // 18th
  642. number
  643.           t[17] = fix(t[17]);
  644.  
  645.           fdbf += 1;          // increment
  646.           if (fdbf == 10)
  647.                fdbf = 0;
  648.           fdbs += 1;
  649.           if (fdbs == 10)
  650.                fdbs = 0;
  651.  
  652.           t[4] = t[3] - table[fdbf*0xA+fdbs] ;  // 5th number
  653.           t[4] = fix(t[4]);
  654.  
  655.           t[16] = t[15] - table[fdbf*0xA+fdbs+0x64]; // 17th
  656. number
  657.           t[16] = fix(t[16]);
  658.  
  659.           fdbf += 1;          // increment
  660.           if (fdbf == 10)
  661.                fdbf = 0;
  662.           fdbs += 1;
  663.           if (fdbs == 10)
  664.                fdbs = 0;
  665.  
  666.           t[3] = t[2] - table[fdbf*0xA+fdbs] ;  // 4th number
  667.           t[3] = fix(t[3]);
  668.  
  669.           t[15] = t[14] - table[fdbf*0xA+fdbs+0x64]; // 16th
  670. number
  671.           t[15] = fix(t[15]);
  672.  
  673.           fdbf += 1;          // increment
  674.           if (fdbf == 10)
  675.                fdbf = 0;
  676.           fdbs += 1;
  677.           if (fdbs == 10)
  678.                fdbs = 0;
  679.  
  680.           t[2] = t[1] - table[fdbf*0xA+fdbs] ;  // 3rd number
  681.           t[2] = fix(t[2]);
  682.  
  683.           t[14] = t[13] - table[fdbf*0xA+fdbs+0x64]; // 15th
  684. number
  685.           t[14] = fix(t[14]);
  686.  
  687.           fdbf += 1;          // increment
  688.           if (fdbf == 10)
  689.                fdbf = 0;
  690.           fdbs += 1;
  691.           if (fdbs == 10)
  692.                fdbs = 0;
  693.  
  694.           t[1] = t[0] - table[fdbf*0xA+fdbs] ;  // 2nd number
  695.           t[1] = fix(t[1]);
  696.  
  697.           t[13] = t[12] - table[fdbf*0xA+fdbs+0x64]; // 14th
  698. number
  699.           t[13] = fix(t[13]);
  700.  
  701.           fdbf += 1;          // increment
  702.           if (fdbf == 10)
  703.                fdbf = 0;
  704.           fdbs += 1;
  705.           if (fdbs == 10)
  706.                fdbs = 0;
  707.  
  708.           t[0] = save1 - table[fdbf*0xA+fdbs];    // first digit
  709.           t[0] = fix(t[0]);
  710.           t[12] = save2 - table[fdbf*0xA+fdbs+0x64]; // 13th
  711. digit
  712.           t[12] = fix(t[12]);
  713.  
  714.      //puts(t);
  715.      // end of second call
  716. ////////////////////////////////////////////////
  717.  
  718.  
  719.           save1 = t[11];      // save the 12th digit
  720.           save2 = t[17];      // save the 18th digit
  721.  
  722.           fdbf = t[1]+0x4-0x30 ; // create [5db5]
  723.           if (fdbf < 0x0)
  724.                fdbf += 0xA;   // fix it if necessary
  725.           else if (fdbf >= 0xA)
  726.                fdbf -= 0xA;
  727.  
  728.           fdbs = t[2]+0x4-0x30;         // and [5db7]
  729.           if (fdbs < 0x0)
  730.                fdbs += 0xA;   // fix it if necessary
  731.           else if (fdbs >= 0xA)
  732.                fdbs -= 0xA;
  733.  
  734.  
  735.           t[17] = t[16] - table[fdbf*0xA+fdbs] ;  // 18th number
  736.           t[17] = fix(t[17]);
  737.  
  738.           t[11] = t[10] - table[fdbf*0xA+fdbs+0x64]; // 12th
  739. number
  740.           t[11] = fix(t[11]);
  741.  
  742.  
  743.           fdbf += 1;          // increment
  744.           if (fdbf == 10)
  745.                fdbf = 0;
  746.           fdbs += 1;
  747.           if (fdbs == 10)
  748.                fdbs = 0;
  749.  
  750.           t[16] = t[15] - table[fdbf*0xA+fdbs] ;  // 17th number
  751.           t[16] = fix(t[16]);
  752.  
  753.           t[10] = t[9] - table[fdbf*0xA+fdbs+0x64]; // 11th
  754. number
  755.           t[10] = fix(t[10]);
  756.  
  757.           fdbf += 1;          // increment
  758.           if (fdbf == 10)
  759.                fdbf = 0;
  760.           fdbs += 1;
  761.           if (fdbs == 10)
  762.                fdbs = 0;
  763.  
  764.           t[15] = t[14] - table[fdbf*0xA+fdbs] ;  // 16th number
  765.           t[15] = fix(t[15]);
  766.  
  767.           t[9] = t[8] - table[fdbf*0xA+fdbs+0x64]; // 10th number
  768.           t[9] = fix(t[9]);
  769.  
  770.           fdbf += 1;          // increment
  771.           if (fdbf == 10)
  772.                fdbf = 0;
  773.           fdbs += 1;
  774.           if (fdbs == 10)
  775.                fdbs = 0;
  776.  
  777.           t[14] = t[13] - table[fdbf*0xA+fdbs] ;  // 15th number
  778.           t[14] = fix(t[14]);
  779.  
  780.           t[8] = t[7] - table[fdbf*0xA+fdbs+0x64]; // 9th number
  781.           t[8] = fix(t[8]);
  782.  
  783.           fdbf += 1;          // increment
  784.           if (fdbf == 10)
  785.                fdbf = 0;
  786.           fdbs += 1;
  787.           if (fdbs == 10)
  788.                fdbs = 0;
  789.  
  790.           t[13] = t[12] - table[fdbf*0xA+fdbs] ;  // 14th number
  791.           t[13] = fix(t[13]);
  792.  
  793.           t[7] = t[6] - table[fdbf*0xA+fdbs+0x64]; // 8th number
  794.           t[7] = fix(t[7]);
  795.  
  796.           fdbf += 1;          // increment
  797.           if (fdbf == 10)
  798.                fdbf = 0;
  799.           fdbs += 1;
  800.           if (fdbs == 10)
  801.                fdbs = 0;
  802.  
  803.           t[12] = save2 - table[fdbf*0xA+fdbs];   // 13th digit
  804.           t[12] = fix(t[12]);
  805.  
  806.           t[6] = save1 - table[fdbf*0xA+fdbs+0x64]; // 7th digit
  807.           t[6] = fix(t[6]);
  808.  
  809.  
  810.      // end of third call
  811. ////////////////////////////////////////////////
  812.  
  813.  
  814.      }  // end of for loop
  815.  
  816.      // Now we finish it up
  817.      save1 = t[16] + 0xD0 - 0x100;      // [5dc1]
  818.      save2 = t[17] + 0xD0 - 0x100;      // [5dc2]
  819.  
  820.      for (i=0; i<6; i++)
  821.           {
  822.                t[i] = t[i] - save1;
  823.                t[i] = fix(t[i]);
  824.  
  825.                t[i+6] = t[i+6] - save2;
  826.                t[i+6] = fix(t[i+6]);
  827.           }
  828.  
  829.      printf("'Magic' code is:  ");
  830.      for (i=0; i<18 ;i++)   // output the string (only first 18)
  831.           putc(t[i], stdout);
  832.      printf("\n\n Created by xxxxx for +Orc's HCU 1996");
  833.  
  834. }   // end of main()
  835.  
  836. char fix(char x)
  837. {
  838.      if (x < '0')
  839.           x = x+0xA;
  840.  
  841.      else if (x > 0x39)
  842.           x -= 0xA;
  843.  
  844.      return x;
  845. }
  846.  
  847. ---------------------------------------------------
  848. UNINSTANT.CPP
  849.  
  850. #include
  851. #include
  852. #include
  853. #include
  854. #include
  855.  
  856. void main()
  857. {
  858.      char fix(char x);
  859.  
  860.      char *t;
  861.      int  save1, save2,fdbf,fdbs, i,q, fdbssave,fdbfsave;
  862.      static int table[208] = {1,3,3,1,9,2,3,0, 9,0,4,3,8,7,4,4,
  863.           5,2,9,0,2,4,1,5, 6,6,3,2,0,8,5,6,
  864.           8,9,5,0,4,6,7,7, 2,0,8,0,6,2,4,7,
  865.           4,4,9,5,9,6,0,6, 8,7,0,3,5,9,0,8,
  866.           3,7,7,6,8,9,1,5, 7,4,6,1,4,2,7,1,
  867.           3,1,8,1,5,3,3,1, 2,8,2,1,6,5,7,2,
  868.           5,9,9,8,2,9,3,0, 0,4,5,1,1,3,8,6,
  869.           1,1,9,0,2,5,5,5, 1,7,1,5,8,7,1,9,
  870.           8,7,7,4,4,8,3,0, 6,1,9,8,8,4,9,9,
  871.           0,7,5,2,3,1,3,8, 6,5,7,6,3,7,6,7,
  872.           4,2,2,5,2,4,6,2, 6,9,9,1,5,2,3,4,
  873.           4,0,3,5,0,3,8,7, 6,4,8,8,2,0,3,6,
  874.           9,0,0,6,9,4,7,2, 0,1,1,1,1,0,1} ;
  875.  
  876. printf("Enter the 18 digit 'Magic' code:  ");
  877. gets(t);
  878.  
  879. save1 = t[16] + 0xD0 - 0x100;      // [5dc1]
  880. save2 = t[17] + 0xD0 - 0x100;      // [5dc2]
  881.  
  882. for (i=5; i>=0 ; i--)         // fix it before main loop
  883.      {
  884.           t[i] = t[i] +save1;
  885.           t[i] = fix(t[i]);
  886.  
  887.           t[i+6] = t[i+6] + save2;
  888.           t[i+6] = fix(t[i+6]);
  889.      }
  890.  
  891. for (i=1; i<=6 ; i++)
  892. {
  893. // begin third call
  894.      fdbf = 0x4+t[1]-0x30 ; // create [5db5]
  895.      if (fdbf < 0x0)
  896.           fdbf += 0xA;   // fix it if necessary
  897.      else if (fdbf >= 0xA)
  898.           fdbf -= 0xA;
  899.      fdbs = 0x4+t[2]-0x30 ; // create [5db7]
  900.      if (fdbs < 0x0)
  901.           fdbs += 0xA;   // fix it if necessary
  902.      else if (fdbs >= 0xA)
  903.           fdbs -= 0xA;
  904.  
  905.  
  906.      save1 = t[6];       //save 7th
  907.      save2 = t[12];       // and 13th
  908.  
  909.      for (q=1; q<=5; q++)     // put [ ]'s where they were at end
  910. of loop
  911.      {
  912.           fdbf += 1;          // increment
  913.           if (fdbf == 10)
  914.                fdbf = 0;
  915.           fdbs += 1;
  916.           if (fdbs == 10)
  917.                fdbs = 0;
  918.    }
  919.     fdbssave = fdbs;
  920.     fdbfsave = fdbf;
  921.  
  922.     fdbf -= 1;          // decrement
  923.      if (fdbf == -1)
  924.           fdbf = 9;
  925.      fdbs -= 1;
  926.      if (fdbs == -1)
  927.           fdbs = 9;
  928.  
  929.     t[6] = t[7] + table[fdbf*0xA+fdbs+0x64];      // 7th digit
  930.     t[6] = fix(t[6]);
  931.  
  932.     t[12] = t[13] + table[fdbf*0xA+fdbs];   // 13th digit
  933.     t[12] = fix(t[12]);
  934.  
  935.     fdbf -= 1;          // decrement
  936.      if (fdbf == -1)
  937.           fdbf = 9;
  938.      fdbs -= 1;
  939.      if (fdbs == -1)
  940.           fdbs = 9;
  941.  
  942.      t[7] = t[8] + table[fdbf*0xA+fdbs+0x64];      // 8th digit
  943.     t[7] = fix(t[7]);
  944.  
  945.     t[13] = t[14] + table[fdbf*0xA+fdbs];   // 14th digit
  946.     t[13] = fix(t[13]);
  947.  
  948.     fdbf -= 1;          // decrement
  949.      if (fdbf == -1)
  950.           fdbf = 9;
  951.      fdbs -= 1;
  952.      if (fdbs == -1)
  953.           fdbs = 9;
  954.  
  955.      t[8] = t[9] + table[fdbf*0xA+fdbs+0x64];      // 9th digit
  956.     t[8] = fix(t[8]);
  957.  
  958.     t[14] = t[15] + table[fdbf*0xA+fdbs];   // 15th digit
  959.     t[14] = fix(t[14]);
  960.  
  961.     fdbf -= 1;          // decrement
  962.      if (fdbf == -1)
  963.           fdbf = 9;
  964.      fdbs -= 1;
  965.      if (fdbs == -1)
  966.           fdbs = 9;
  967.  
  968.  
  969.     t[9] = t[10] + table[fdbf*0xA+fdbs+0x64];      // 10th digit
  970.     t[9] = fix(t[9]);
  971.  
  972.     t[15] = t[16] + table[fdbf*0xA+fdbs];   // 16th digit
  973.     t[15] = fix(t[15]);
  974.  
  975.     fdbf -= 1;          // decrement
  976.      if (fdbf == -1)
  977.           fdbf = 9;
  978.      fdbs -= 1;
  979.      if (fdbs == -1)
  980.           fdbs = 9;
  981.  
  982.      t[10] = t[11] + table[fdbf*0xA+fdbs+0x64];      // 11th
  983. digit
  984.     t[10] = fix(t[10]);
  985.  
  986.     t[16] = t[17] + table[fdbf*0xA+fdbs];   // 17th digit
  987.     t[16] = fix(t[16]);
  988.  
  989.     t[11] = save1 + table[fdbfsave*0xA+fdbssave+0x64];      //
  990. 12th digit
  991.     t[11] = fix(t[11]);
  992.  
  993.     t[17] = save2 + table[fdbfsave*0xA+fdbssave];   // 18th digit
  994.     t[17] = fix(t[17]);
  995.  
  996. // end of third call
  997.  
  998. // begin second call
  999.      fdbf = 0x4+t[10]-0x30 ; // create [5db5]
  1000.      if (fdbf < 0x0)
  1001.           fdbf += 0xA;   // fix it if necessary
  1002.      else if (fdbf >= 0xA)
  1003.           fdbf -= 0xA;
  1004.      fdbs = 0x4+t[9]-0x30 ; // create [5db7]
  1005.      if (fdbs < 0x0)
  1006.           fdbs += 0xA;   // fix it if necessary
  1007.      else if (fdbs >= 0xA)
  1008.           fdbs -= 0xA;
  1009.  
  1010.  
  1011.      save1 = t[0];       //save first
  1012.      save2 = t[12];       // and 13th
  1013.  
  1014.      for (q=1; q<=5; q++)     // put [ ]'s where they were at end
  1015. of loop
  1016.      {
  1017.           fdbf += 1;          // increment
  1018.           if (fdbf == 10)
  1019.                fdbf = 0;
  1020.           fdbs += 1;
  1021.           if (fdbs == 10)
  1022.                fdbs = 0;
  1023.     }
  1024.     fdbssave = fdbs;
  1025.     fdbfsave = fdbf;
  1026.  
  1027.     fdbf -= 1;          // decrement
  1028.      if (fdbf == -1)
  1029.           fdbf = 9;
  1030.      fdbs -= 1;
  1031.      if (fdbs == -1)
  1032.           fdbs = 9;
  1033.  
  1034.     t[0] = t[1] + table[fdbf*0xA+fdbs];      // 1st digit
  1035.     t[0] = fix(t[0]);
  1036.  
  1037.     t[12] = t[13] + table[fdbf*0xA+fdbs+0x64];   // 13th digit
  1038.     t[12] = fix(t[12]);
  1039.  
  1040.     fdbf -= 1;          // decrement
  1041.      if (fdbf == -1)
  1042.           fdbf = 9;
  1043.      fdbs -= 1;
  1044.      if (fdbs == -1)
  1045.           fdbs = 9;
  1046.  
  1047.      t[1] = t[2] + table[fdbf*0xA+fdbs];      // 2nd digit
  1048.     t[1] = fix(t[1]);
  1049.  
  1050.     t[13] = t[14] + table[fdbf*0xA+fdbs+0x64];   // 14th digit
  1051.     t[13] = fix(t[13]);
  1052.  
  1053.     fdbf -= 1;          // decrement
  1054.      if (fdbf == -1)
  1055.           fdbf = 9;
  1056.      fdbs -= 1;
  1057.      if (fdbs == -1)
  1058.           fdbs = 9;
  1059.  
  1060.      t[2] = t[3] + table[fdbf*0xA+fdbs];      // 3rd digit
  1061.     t[2] = fix(t[2]);
  1062.  
  1063.     t[14] = t[15] + table[fdbf*0xA+fdbs+0x64];   // 15th digit
  1064.     t[14] = fix(t[14]);
  1065.  
  1066.     fdbf -= 1;          // decrement
  1067.      if (fdbf == -1)
  1068.           fdbf = 9;
  1069.      fdbs -= 1;
  1070.      if (fdbs == -1)
  1071.           fdbs = 9;
  1072.  
  1073.  
  1074.     t[3] = t[4] + table[fdbf*0xA+fdbs];      // 4th digit
  1075.     t[3] = fix(t[3]);
  1076.  
  1077.     t[15] = t[16] + table[fdbf*0xA+fdbs+0x64];   // 16th digit
  1078.     t[15] = fix(t[15]);
  1079.  
  1080.     fdbf -= 1;          // decrement
  1081.      if (fdbf == -1)
  1082.           fdbf = 9;
  1083.      fdbs -= 1;
  1084.      if (fdbs == -1)
  1085.           fdbs = 9;
  1086.  
  1087.      t[4] = t[5] + table[fdbf*0xA+fdbs];      // 5th digit
  1088.     t[4] = fix(t[4]);
  1089.  
  1090.     t[16] = t[17] + table[fdbf*0xA+fdbs+0x64];   // 17th digit
  1091.     t[16] = fix(t[16]);
  1092.  
  1093.     t[5] = save1 + table[fdbfsave*0xA+fdbssave];      // 6th
  1094. digit
  1095.     t[5] = fix(t[5]);
  1096.  
  1097.     t[17] = save2 + table[fdbfsave*0xA+fdbssave+0x64];   // 18th
  1098. digit
  1099.     t[17] = fix(t[17]);
  1100. // end of second call
  1101. // begin first call
  1102.      fdbf = 0xFFC+t[17]-0x1000-0x30 ; // create [5db5]
  1103.      if (fdbf < 0x0)
  1104.           fdbf += 0xA;   // fix it if necessary
  1105.      else if (fdbf >= 0xA)
  1106.           fdbf -= 0xA;
  1107.      fdbs = fdbf;                            // and [5db7]
  1108.  
  1109.      save1 = t[0];       //save first
  1110.      save2 = t[6];       // and 7th
  1111.  
  1112.      for (q=1; q<=5; q++)     // put [ ]'s where they were at end
  1113. of loop
  1114.      {
  1115.           fdbf -= 1;          // decrement
  1116.           if (fdbf == -1)
  1117.                fdbf = 9;
  1118.           fdbs -= 1;
  1119.           if (fdbs == -1)
  1120.                fdbs = 9;
  1121.     }
  1122.     fdbssave = fdbs;
  1123.     fdbfsave = fdbf;
  1124.  
  1125.     fdbf += 1;          // increment
  1126.      if (fdbf == 10)
  1127.           fdbf = 0;
  1128.      fdbs += 1;
  1129.      if (fdbs == 10)
  1130.           fdbs = 0;
  1131.  
  1132.     t[0] = t[1] + table[fdbf*0xA+fdbs];      // 1st digit
  1133.     t[0] = fix(t[0]);
  1134.  
  1135.     t[6] = t[7] + table[fdbf*0xA+fdbs+0x64];   // 7th digit
  1136.     t[6] = fix(t[6]);
  1137.  
  1138.     fdbf += 1;          // increment
  1139.      if (fdbf == 10)
  1140.           fdbf = 0;
  1141.      fdbs += 1;
  1142.      if (fdbs == 10)
  1143.           fdbs = 0;
  1144.  
  1145.      t[1] = t[2] + table[fdbf*0xA+fdbs];      // 2nd digit
  1146.     t[1] = fix(t[1]);
  1147.  
  1148.     t[7] = t[8] + table[fdbf*0xA+fdbs+0x64];   // 8th digit
  1149.     t[7] = fix(t[7]);
  1150.  
  1151.     fdbf += 1;          // increment
  1152.      if (fdbf == 10)
  1153.           fdbf = 0;
  1154.      fdbs += 1;
  1155.      if (fdbs == 10)
  1156.           fdbs = 0;
  1157.  
  1158.      t[2] = t[3] + table[fdbf*0xA+fdbs];      // 3rd digit
  1159.     t[2] = fix(t[2]);
  1160.  
  1161.     t[8] = t[9] + table[fdbf*0xA+fdbs+0x64];   // 9th digit
  1162.     t[8] = fix(t[8]);
  1163.  
  1164.     fdbf += 1;          // increment
  1165.      if (fdbf == 10)
  1166.           fdbf = 0;
  1167.      fdbs += 1;
  1168.      if (fdbs == 10)
  1169.           fdbs = 0;
  1170.  
  1171.  
  1172.     t[3] = t[4] + table[fdbf*0xA+fdbs];      // 4th digit
  1173.     t[3] = fix(t[3]);
  1174.  
  1175.     t[9] = t[10] + table[fdbf*0xA+fdbs+0x64];   // 10th digit
  1176.     t[9] = fix(t[9]);
  1177.  
  1178.     fdbf += 1;          // increment
  1179.      if (fdbf == 10)
  1180.           fdbf = 0;
  1181.      fdbs += 1;
  1182.      if (fdbs == 10)
  1183.           fdbs = 0;
  1184.  
  1185.      t[4] = t[5] + table[fdbf*0xA+fdbs];      // 5th digit
  1186.     t[4] = fix(t[4]);
  1187.  
  1188.     t[10] = t[11] + table[fdbf*0xA+fdbs+0x64];   // 11th digit
  1189.     t[10] = fix(t[10]);
  1190.  
  1191.     t[5] = save1 + table[fdbfsave*0xA+fdbssave];      // 6th
  1192. digit
  1193.     t[5] = fix(t[5]);
  1194.  
  1195.     t[11] = save2 + table[fdbfsave*0xA+fdbssave+0x64];   // 12th
  1196. digit
  1197.     t[11] = fix(t[11]);
  1198. // end of first call
  1199. }  // end for loop
  1200.  
  1201. printf("\nTo Get That 'Magic' Use:  ");
  1202. for (i=0; i<18 ;i++)   // output the string (only first 18)
  1203.           putc(t[i], stdout);
  1204.      printf("\n\n Created by +xxxxx for +Orc's HCU 1996");
  1205.  
  1206. }  // end of main()
  1207.  
  1208. char fix(char x)
  1209. // fixes chars to between 0 and 9
  1210. {
  1211.      if (x < '0')
  1212.           x = x+0xA;
  1213.  
  1214.      else if (x > 0x39)
  1215.           x -= 0xA;
  1216.  
  1217.      return x;
  1218. }
  1219.  
  1220. III. THE [DATADUMP_WINDOW] TRICK & HOW TO SEARCH THE WEB.
  1221.  
  1222. [WINFORMANT 4 HOW TO FIND IT]
  1223.  
  1224.      I have chosen (as usual) an older windows application for
  1225. Win 3.1. (Version 1.10, by Joseph B. Albanese), in order to
  1226. terminate completely the "password lessons" and at the same time
  1227. show you a nice little trick that can be very useful in cracking
  1228. *ALL* protected programs (password protected or time protected
  1229. or function disabled): memory windows_dumping. There is in almost
  1230. all protection routines, as you have already learned, a moment
  1231. when on the stack appears the ECHO of the real, "correct"
  1232. passnumber or password, in order to compare the input of the user
  1233. with it.
  1234.  
  1235.      The location of this ECHO varies, but it will be most of the
  1236. time in a range of +- 0x90 bytes from the user input. This is due
  1237. to datadump windows restraints inside the tools used by the
  1238. protectionists I'll not delve inside here, and this use is bound
  1239. to diminish (especially after this lesson :=).
  1240.  
  1241.      You'll find the files that I use in this lesson searching
  1242. the web with the usual search_tools and search_strategies: These
  1243. are names, lengths and dates of the relevant files... this will
  1244. allow you to FTPMAIL them after having located them through an
  1245. ARCHIE_search:
  1246.  
  1247.           CTL3D    DLL     20976 17/08/93    4:36
  1248.           README   WRI      2688 08/05/94    1:54
  1249.           SS3D2    VBX     88096 11/06/92   18:42
  1250.           STDLL    DLL     10880 06/05/94   22:57
  1251.           THREED   VBX     64432 17/07/93    0:00
  1252.           WIN4MANT EXE    562271 07/06/96   17:51
  1253.           WIN4MANT HLP    190608 08/05/94    0:36
  1254.           XLIST    VBX     15248 15/02/93    0:00
  1255.  
  1256.       Please do not underestimate the importance of *EXACT NAMES*
  1257. on the Web (be it of people, of subjects or of software)... as
  1258. a matter of fact the Web corroborates (every day more). The old
  1259. intuition from Persio: NOMEN ATQUE OMEN: how true! Think a moment
  1260. about it, the importance of the NAMES on the Web is astonishing
  1261. (and growing)!
  1262.  
  1263.      1) It is true for http://... addresses: domains must be
  1264. unique and registered (and the Web registration burocrats will
  1265. get from you 100 dollars per year just to keep them registered);
  1266.  
  1267. 2) It is true for programs (you must know BEFOREHAND the name of
  1268. a file to find it quickly on the Web); 3) It's even true for your
  1269. own site denomination (try searching for "Bill's" page instead
  1270. than for "WIKKY_WAKKY's" page... that's (reversing this approach)
  1271. one of the reason I have a "+" inside my handle, this confuses
  1272. the search engines just enough to give me a little more anonymity
  1273. (search for me! You'll get quite a lot of Warcraft stuff :=).
  1274.  
  1275.      Enough! If you do not know neither why all this happen nor
  1276. how to search the Web, but are interested in these matters (as
  1277. you should), study the web search engines themselves and read the
  1278. relevant help files (search AltaVista and WebCrawler for
  1279. "FTPMAIL", "WWW via e-mail", "AGORA", "search strategies" etc).
  1280.  
  1281.      It's amazing how few crackers (not to mention the lusers)
  1282. do actually read the help files of the search engines they are
  1283. using, which should be your bible (or the coran, or some other
  1284. crap, for all I care about religions), your alpha and omega! The
  1285. (growing) amount of junk on the Web makes your ability to search
  1286. effectively the little grains of interesting truths that are
  1287. escaping the growing heavy censorship of our enemies even more
  1288. important.
  1289.  
  1290.      Back to our [Winformant] cracking now, and back to our
  1291. stackdump window trick... here you are:
  1292.  
  1293. [WINFORMANT CRACKING]
  1294.  
  1295.      This application is -per se- absolutely crap, I doubt you'll
  1296. ever use it: this program is so primitive it must have been one
  1297. of the first crappy visual basic experiments made by his
  1298. programmer... but this [Winformant] program is nevertheless very
  1299. interesting for us coz it possesses a curious  (and pretty rare)
  1300. "deactivate" mode, i.e. you can "unregister" it on the fly if you
  1301. feel the need to... it beats me why the programmer wanted such
  1302. a feature inside... he was just probably collecting little
  1303. routines and mixing them without sound reasons.
  1304.  
  1305.      This feature is as rare as useless, but it is worth for
  1306. cracking scholars that (should) investigate password algorithms
  1307. with valid and invalid codes without having to reinstall
  1308. everything only in order to delete previous valid codes.
  1309.  
  1310.      For your cracking exercises you should therefore choose
  1311. programs that have "REVERSIBLE" protections (like this
  1312. Winformant... very rare) or that can be re-registered a billion
  1313. times (that's a more frequent protection pattern). Programs that
  1314. keep the valid registration on *.ini or special files can also
  1315. be useful... you just need to change a couple of lines in these
  1316. files to restore the "unregistered" mode.
  1317.  
  1318.      The trick we'll use in this lesson: "password proximity",
  1319. bases on the fact that the protectionists need to keep an eye on
  1320. their protection when they "build" it and have to *see* closely
  1321. the relationships between
  1322.  
  1323. 1)   USER INPUT PASSNUMBER (i.e. the input registration number
  1324. that the user should have bought, but could be a fake bad guy
  1325. input)
  1326.  
  1327. 2)   USER INPUT TRANSFORMED (i.e. the result of the working of
  1328. the protectionist's algorithm on the user input passnumber)
  1329. and the
  1330.  
  1331. 3)   CORRECT PASSNUMBER ANSWER (The BINGO!) i.e., the Passnumber
  1332. calculated with some algorithm on the bases of the USER INPUT
  1333. NAME (the name of the user, eventually transformed in USER INPUT
  1334. TRANSFORMED).
  1335.  
  1336.      In order to clear bugs these relationships must be
  1337. constantly checked when they prepare the protection... i.e. when
  1338. they are writing the protection code.
  1339.  
  1340.      Most of the time all these data will therefore dwell inside
  1341. a small stack... that means they will be "visible" in the SAME
  1342. "watchwindow" inside the protectionist's debugger... and they use
  1343. the same turbodebugger (or Winice) YOU are using!
  1344.  
  1345.      This means that most of the time the "ECHO" will swell not
  1346. very far away from the USER INPUT. Therefore proceed as follows:
  1347.  
  1348. Fire Winice
  1349. Fire Winformant
  1350. Choose HELP
  1351. Choose REGISTRATION
  1352. Fill the registration fields
  1353.      this is mine: "+ORC+ORC" as "Registrant"
  1354.      and "12121212" as "Activation" code
  1355. CTRL+D              ;switch to Winice
  1356. task                ;let's see the names
  1357.  
  1358. :task
  1359. TaskName  SS:SP StackTop StackBot StackLow TaskDB  hQueue  Events
  1360. WINWORD   1AD7:85F2 4A52  8670      7532     1247    122F    0000
  1361. PROGMAN   1737:200A 0936  2070      1392     066F    07F7    0000
  1362. DISKOMAT *2C5F:6634 1D3C  6AC6      5192     2CB7    2C9F    0000
  1363.  
  1364. hwnd DISKOMAT       ;which window is getting the input?
  1365.  
  1366. :hwnd diskomat
  1367. WinHandle   Hqueue  QOwner    Class Name        Window Procedure
  1368. 0EB4(0)      2C9F    DISKOMAT  #32769            04A7:9E6B
  1369.  0F34(1)     2C9F    DISKOMAT  #32768            USER!BEAR306
  1370.  365C(1)     2C9F    DISKOMAT  #32770            2C3F:0BC6
  1371.   36BC(2)    2C9F    DISKOMAT  Button            2C3F:1CEA
  1372.   3710(2)    2C9F    DISKOMAT  Edit              2C3F:24BE
  1373.   3758(2)    2C9F    DISKOMAT  Edit              2C3F:24BE
  1374.   37A0(2)    2C9F    DISKOMAT  Button            2C3F:1CEA
  1375.   37E4(2)    2C9F    DISKOMAT  Button            2C3F:1CEA
  1376. ... and many more irrelevant windows.
  1377.  
  1378. bmsg relevant_window wm_gettext ;let's pinpoint the code, here
  1379.      ;the relevant window is the first "edit" one (obviously),
  1380.      ;i.e. wHnd 3710 you could also use GetWindowsText or
  1381.      ;GetDlgItmText to locate the relevant routines
  1382.  
  1383. :bmsg 3710 wm_gettext           ;set breakpoint
  1384. CTRL+D                          ;run the babe
  1385. Break Due to BMSG 3710 WM_GETTEXT C=01
  1386.   Hwnd=3710 wParam=0050 lParam=2C5F629A msg=000D WM_GETTEXT
  1387. 2C3F:000024BE B82F2C            MOV     AX,2C2F
  1388.  
  1389. So! Now that we have pinpointed the code... let's snoop around
  1390. a little: first thing to do is a good stack command which, here,
  1391. will work OK (in other cracking sessions it may not -magic
  1392. involved- but do not worry: if it does not work immediately, just
  1393. pinpoint a little more... for instance on GetWindowText() (always
  1394. good) or do a BPRW diskomat (also very useful), and then try and
  1395. retry the stack... should this too fail to work, do search for
  1396. your input in memory (in the 30:0 lffffffff selector, as usual)
  1397. and breakpoint range on it with ReadWrite, and then stack, stack,
  1398. stack... till you get the "real" list of calls coming from your
  1399. babe's protection (in our example the babe's name is "DISKOMAT").
  1400.  
  1401. :stack
  1402. USER(19) at 073F:124C [?] through 073F:1239
  1403. CTL3D(02) at 2C3F:0D53 [?] through 2C3F:0D53
  1404. DISKOMAT(01) at 2C97:20B9 [?] through 2C97:20B9
  1405. DISKOMAT(01) at 2C97:3D94 [?] through 2C97:3D94
  1406. DISKOMAT(01) at 2C97:49E2 [?] through 2C97:4918
  1407. DISKOMAT(04) at 2C7F:EA20 [?] through 2C7F:EA20
  1408. USER(01) at 04A7:19BE [?] through USER!GETWINDOWTEXT
  1409. => CTL3D(02) at 2C3F:24BE [?] through 04A7:3A3Cæ
  1410.  
  1411. Beautiful stack picture! Immediately BPX on 2C7F:EA20 (on your
  1412. computer the segment will differ, the offset will be the SAME).
  1413.  
  1414. 2C7F:EA20 9A25ABA704     CALL    USER!GETWINDOWTEXT
  1415. 2C7F:EA25 8E4608         MOV     ES,[BP+08]
  1416. 2C7F:EA28 26FFB42C02     PUSH    WORD PTR ES:[SI+022C]
  1417. 2C7F:EA2D 8D865CFF       LEA     AX,[BP+FF5C]
  1418. 2C7F:EA31 16             PUSH    SS
  1419. 2C7F:EA32 50             PUSH    AX
  1420. 2C7F:EA33 6A50           PUSH    50
  1421. 2C7F:EA35 9A25ABA704     CALL    USER!GETWINDOWTEXT
  1422. 2C7F:EA3A 8D46AE         LEA     AX,[BP-52]  ;load ptr "+ORC+ORC"
  1423. 2C7F:EA3D 16             PUSH    SS     ;save pointer segment
  1424. 2C7F:EA3E 50             PUSH    AX     ;save pointer offset
  1425. 2C7F:EA3F 9A768D872C     CALL    2C87:8D76   ;strlen "ORC+ORC"
  1426. 2C7F:EA44 83C404         ADD     SP,+04
  1427. 2C7F:EA47 3D2800         CMP     AX,0028
  1428. 2C7F:EA4A 762C           JBE     EA78
  1429. ...
  1430. 2C7F:EA78 8D442C         LEA     AX,[SI+2C]
  1431. 2C7F:EA7B FF7608         PUSH    WORD PTR [BP+08]
  1432. 2C7F:EA7B FF7608         PUSH    WORD PTR [BP+08]
  1433. 2C7F:EA7E 50             PUSH    AX
  1434. 2C7F:EA7F 9AE002772C     CALL    2C77:02E0
  1435. 2C7F:EA84 0BC0           OR      AX,AX
  1436. 2C7F:EA86 740F           JZ      EA97
  1437. 2C7F:EA88 687F2C         PUSH    2C7F
  1438. 2C7F:EA8B 68E4ED         PUSH    EDE4
  1439. 2C7F:EA8E 6A00           PUSH    00
  1440. 2C7F:EA90 6A00           PUSH    00
  1441. 2C7F:EA92 6A00           PUSH    00
  1442. 2C7F:EA94 E94501         JMP     EBDC
  1443. 2C7F:EA97 8D46AE         LEA     AX,[BP-52]  ;load ptr "+ORC+ORC"
  1444. 2C7F:EA9A 16             PUSH    SS     ;various algor on input
  1445. 2C7F:EA9B 50             PUSH    AX     ;we do not care
  1446. 2C7F:EA9C 8D860AFF       LEA     AX,[BP+FF0A]
  1447. 2C7F:EAA0 16             PUSH    SS
  1448. 2C7F:EAA1 50             PUSH    AX
  1449. 2C7F:EAA2 6A51           PUSH    51
  1450. 2C7F:EAA4 8D442C         LEA     AX,[SI+2C]
  1451. 2C7F:EAA7 FF7608         PUSH    WORD PTR [BP+08]
  1452. 2C7F:EAAA 50             PUSH    AX
  1453. 2C7F:EAAB 9ABA00772C     CALL    2C77:00BA
  1454. 2C7F:EAB0 0BC0           OR      AX,AX
  1455. 2C7F:EAB2 0F851101       JNE     EBC7
  1456. 2C7F:EAB6 8D8E5CFF       LEA     CX,[BP+FF5C]  ;ptr "12121212"
  1457. 2C7F:EABA 16             PUSH    SS
  1458. 2C7F:EABB 51             PUSH    CX
  1459. 2C7F:EABC 9A768D872C     CALL    2C87:8D76   ;strlen "12121212"
  1460. 2C7F:EAC1 83C404         ADD     SP,+04
  1461. 2C7F:EAC4 50             PUSH    AX
  1462. 2C7F:EAC5 8D865CFF       LEA     AX,[BP+FF5C]  ;ptr "12121212"
  1463. 2C7F:EAC9 16             PUSH    SS
  1464. 2C7F:EACA 50             PUSH    AX
  1465. 2C7F:EACB 8D860AFF       LEA     AX,[BP+FF0A] ...etc
  1466.  
  1467. OK, it's enough: now what obviously follows is to "algorithmize"
  1468. this second string, and somewhere, then, you'll have a compare
  1469. that checks and divides good guys from bad fellows.
  1470.  
  1471. BUT NOW IT'S ALSO THE MAGIC MOMENT OF THE ECHO! We know it, we
  1472. feel it: The echo is somewhere... what can we do to find it?
  1473. Should we search "12121212" in memory? No, look how many
  1474. locations we would find...
  1475.  
  1476. :s 30:0 lffffffff '12121212'
  1477. Pattern Found at 0030:0005AD6A
  1478. Pattern Found at 0030:0048AD6A
  1479. Pattern Found at 0030:007DED98
  1480. Pattern Found at 0030:007E25F8
  1481. Pattern Found at 0030:008E0FE1
  1482. Pattern Found at 0030:008E1433
  1483. Pattern Found at 0030:008E186F
  1484. Pattern Found at 0030:008E1904
  1485. Pattern Found at 0030:008E601A
  1486. Pattern Found at 0030:80509D6A
  1487. Pattern Found at 0030:8145AD6A
  1488. Pattern Not Found
  1489.  
  1490.      And now...should we look for all occurrences of this string
  1491. and get a memory dump of +- 0x90 around it till we find the
  1492. echo... that's not zen... that's boring, even if we know that the
  1493. relevant ones will ALWAYS be the ones that have MORE than
  1494. 80000000 in their "offset", i.e., in this case, only two:
  1495. Pattern Found at 0030:80509D6A
  1496. Pattern Found at 0030:8145AD6A
  1497.  
  1498.      But this procedure is not always true, and in other
  1499. protection there will be a proliferation of locations with the
  1500. aim of deterring casual crackers... clearly the above method is
  1501. no good... there must be some other way... YES THERE IS!
  1502.  
  1503.      THE LAST loading of the numeric input string in the code
  1504. (the one after the strlen count) is most of the time (exspecially
  1505. in Visual Basic and Delphy programs) the "right" one for our
  1506. cracking purposes, coz the protections follow (most of the time)
  1507. this pattern (remember that we are here inside a stack "heavy"
  1508. section of the code... if you want to crack higher I suggest you
  1509. read some good literature about stack working and stack magics
  1510. inside the 80386/80486/80586 processors).
  1511.  
  1512.      This is the usual sequence:
  1513.  
  1514.      LOAD NAME
  1515.      COUNT NAMELENGTH
  1516.      LOAD NAME_AGAIN
  1517.      TRANSFORM NAME
  1518.      LOAD PASSCODE
  1519.      COUNT PASSCODE_LENGTH
  1520.      LOAD PASSCODE_AGAIN
  1521.                     <- ECHO CHECK here
  1522.      TRANSFORM PASSCODE
  1523.                     <- ECHO CHECK here
  1524.      COMPARE TRANSFORMED_NAME WITH TRANSFORMED_PASSCODE
  1525.  
  1526.      So... what does this mean? This means that at line
  1527. 2C7F:EAC5 8D865CFF   LEA  AX,[BP+FF5C]  ;ptr "12121212"
  1528. you'll already have your echo somewhere... just dump the memory
  1529. around the pointer [BP+FF5C]:
  1530.  
  1531. :d 2c5f:61e8
  1532.  
  1533. 2C5F:61E8
  1534. 02 62 2F 06 02 00 26 2E-A3 4E A3 4E 01 00 38 30  .b/...&..N.N..80
  1535. 33 37 2D 36 34 36 2D 33-38 33 36 00 01 06 02 00  37-646-3836.....
  1536. 2F 06 75 62 C3 2E B7 04-F2 24 2F 06 CE 6E 2F 06  /.ub.....$/..n/.
  1537. 49 00 5A 00 00 00 01 00-04 2C 2F 06 AE 24 36 62  I.Z......,/..$6b
  1538. 74 62 7A 2E B7 04 36 62-01 00 C2 62 2F 2C 26 2E  tbz...6b...b/,&.
  1539.  
  1540. 03 01 BA 0F AE 24 5F 02-C9 01 5E 02 BA 01 5F 02  .....$_...^..._.
  1541. 31 32 31 32 31 32 31 32-00 00 0C 00 BC 02 00 00  12121212........
  1542. 00 00 00 00 49 00 BA 0F-AE 24 F2 24 2F 06 00 00  ....I....$.$/...
  1543. AF 17 00 00 00 00 E2 5F-7A 62 FE FF 79 1B BA 0F  ......._zb..y...
  1544. 96 0B 01 00 02 4E 00 00-37 01 8A 62 D2 0F 8F 17  .....N..7..b....
  1545. 2F 06 00 00 00 00 37 01-98 62 20 10 16 03 2F 06  /.....7..b .../.
  1546. C2 62 2B 4F 52 43 2B 4F-52 43 00 0D AE 24 2F 06  .b+ORC+ORC...$/.
  1547.                                           2C5F:62A7
  1548.  
  1549. and look... everybody is there! The stack pointers points in the
  1550. middle of this dump, at the string "12121212". 0x50 bytes before
  1551. is our good old ECHO (i.e. the CORRECT passnumber) and 0x50 bytes
  1552. afterwards is my beautiful input name "+ORC+ORC".
  1553.  
  1554.      Therefore the "right" code for "+ORC+ORC" is 8037-646-3836.
  1555. It cannot be so easy! You'll protest. It is: this crap protection
  1556. is already cracked and hunderts of Visual Basic/Delphy schemes
  1557. are absolutely identical.
  1558.  
  1559.      Now begins the hard work: if you really want to learn,
  1560.      accomplish the following tasks:
  1561. -    First of all "Unregister" and find anew your own code for
  1562.      your own handle. *DO NOT* use serial numbers with any other
  1563.      name that your own handle.
  1564. -    Study the two coding algorithms, the one for the input name
  1565.      and the one for the input passnumber, this will be useful
  1566.      for ALL your future cracking sessions.
  1567. -    Find the compare locations, i.e. the code block that sets
  1568.      the two usual flags "good guy, you may move on" and "bad
  1569.      cracker, beggar off", and create a patch crack for this
  1570.      protection, that will allow anybody, with any name and any
  1571.      password number to get through.
  1572.  
  1573. Please accomplish all of the preceding tasks: once you do it
  1574. you'll have FINISHED the password protection schemes part of my
  1575. tutorial and you'll be able to pass over to the (very
  1576. interesting) world of disabled and crippled functions (all these
  1577. "demos" that do not save and do not print... I'll teach you how
  1578. to do it, starting in Februar 1997).
  1579.  
  1580. Well, that's it for this lesson, reader. Not all lessons of my
  1581. tutorial are on the Web.
  1582.  
  1583.      You 'll obtain the missing lessons IF AND ONLY IF you mail
  1584. me back (via anon.penet.fi) with some tricks of the trade I may
  1585. not know that YOU discovered. Mostly I'll actually know them
  1586. already, but if they are really new you'll be given full credit,
  1587. and even if they are not, should I judge that you "rediscovered"
  1588. them with your work, or that you actually did good work on them,
  1589. I'll send you the remaining lessons nevertheless. Your
  1590. suggestions and critics on the whole crap I wrote are also
  1591. welcomed.
  1592.  
  1593.      "If you give a man a crack he'll be hungry again
  1594.      tomorrow, but if you teach him how to crack, he'll
  1595.      never be hungry again"
  1596.  
  1597.      +ORC  526164@anon.penet.fi
  1598.  
  1599.                                 E-mail +ORC
  1600.  
  1601.                         +ORC an526164@anon.penet.fi
  1602.  
  1603. 
  1604.