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

  1.  
  2.  
  3. HOW TO CRACK, by +ORC, A TUTORIAL
  4.  
  5.  
  6.  
  7.  
  8.  
  9. ------------------------------------------------------------------------
  10. Lesson 9 (4): How to crack Windows, Hands on
  11.  
  12.  
  13.  
  14.  
  15.  
  16. ------------------------------------------------------------------------
  17. [WEBEXPRESS] [REDIRECTION]
  18.  
  19.  
  20.  
  21.  
  22. á 'Dead listing' approach - second part
  23.  
  24.  
  25.  
  26.  
  27.  
  28. ------------------------------------------------------------------------
  29.  
  30.  
  31.  
  32.  
  33.                           ***********
  34.                   +HCU material FEBRUARY 1997
  35.                         LECTIO IN FIERI
  36.                           ***********                  
  37.   (Hic sunt tabulae: Best viewed with good old Courier 10)
  38.  
  39. First of all I'll give you a fundamental advice: don't stroll too
  40. much inside the dark codewoods without taking a due amount of
  41. notes: our paths are narrow, and wind in and out among
  42. codetrunks.
  43.      Everything may seem 'obvious' to you when you are
  44. continuously cracking a given target, but after a break, or
  45. having cracked something else, you'll notice, as soon as you
  46. begin working anew on the original target, that many 'obvious'
  47. things are not so evident any more, and that you'll probably have
  48. to follow once more quite a lot of previous steps.
  49.      Therefore heed my advice! NEVER WORK without taking notes,
  50. and never leave a crack without 'assembling' these notes in a
  51. short review where you'll synthesize 1) the paths you have
  52. followed in order to find the protection scheme, 2) a short
  53. description of the protection scheme itself and/or 3) the
  54. eventual new tricks you'll have found.
  55. Beginning with this lesson we will slowly drift towards 'higher'
  56. cracking, i.e., simply put, beginning from now I will give as
  57. acquired the minimum skills and knowledge you do need in order
  58. to crack (at least at this elementary level). Should you not feel
  59. able to follow a lesson, just re-read the 'basic' ones and
  60. practices on those lines until you do.
  61.      To day we'll work on WEBEXPRESS, an 'html page designer'
  62. program whose 'triple' protection scheme (nagscreens and time
  63. protection and disabled functions) has some interest for us.
  64.      I am using here version 1.0 of Webexpress for Win 3.1 by
  65. Microvision Development (at http://www.mvd.com). There is now a
  66. new beta version 2.0 out, but I reckon more useful to crack the
  67. older 16 bit Windows 3.1 application (august 1996) because this
  68. crack can be followed both by Windows 95 and by Windows 3.1 users
  69. (which -notwithstanding Microsoft's efforts- are still the
  70. majority). Besides, the Windows95 version's protection scheme and
  71. the beta one seem both to be more or less the same: you should
  72. be able to apply the following approaches, cracking the newer
  73. versions, without many problems (I did'nt check very thoroughly,
  74. though).
  75.      I am using version 1.0 of Webexpress, with following files:
  76. WEBEX.EXE      1.309.200 12 august 1996 Main program
  77. WEBEX.DWR      120.885   12 august 1996 ASCII  & resources
  78. (As usual you'll be able to fetch the whole application on the
  79. Web searching the archies).
  80. First of all let's fire Webexpress snapping the nagscreens (use
  81. snap32, cracked elsewhere in my tutorial, or PaintShopPro,
  82. cracked elsewhere in my tutorial, in order to get the printed
  83. snaps). This gives us a rough idea of our target's protection
  84. schema:
  85. This application is
  86. 1)  4 TIMES NAGSCREENED
  87.  
  88.  
  89.      1) Evaluation copy 'smallscreen' at the beginning
  90.      2) Evaluation copy Webexpress is NOT Freeware. This copy...
  91.      3) Evaluation copy 'smallscreen' at the end
  92.      4) To register Webexpress, enter your registration name...
  93. 2)  TIME-LIMITED (30 days)
  94. 3)  CRIPPLED (Prints 'Printed with an evaluation copy...' after
  95. 30 days).
  96.      Gosh, quite a lot of annoyances... that's NICE for us little
  97. crackers! (That's actually the real reason I have chosen this
  98. crap). There is obviously a lot to learn for us inside its
  99. protection scheme... wipe your hands, prepare your cocktail (may
  100. I suggest a good Martini-Wodka? Remember: put in your glass
  101. always the ice cubes first, then the Martini dry and then the
  102. Moskowskaja)... at work!
  103. We proceed first with a little reverse engineering, using our
  104. 'dead listing' approach (see lesson - 9.3) and loading Webex.exe
  105. inside W32dasm in order to get the disassembled listing of the
  106. program. A word of caution: I am using only for teaching purposes
  107. version 5 of W32dasm, because this is the disassembler that the
  108. masses will use (watch carefully the file lengths after you
  109. searched w32dasm through the archies, before ftpmailing it, else
  110. you'll fish only the shareware and incomplete versions of it) but
  111. I originally used WCB, a much older, DOS based, Windozes
  112. disassembler, which has, as you will see, some advantages vis-a-
  113. vis of W32dasm. Remember that you DO NOT NEED to run windows in
  114. order to crack windows programs... cracking has not much to do
  115. with a particular OS... since you learn (here) how to 'interact'
  116. with an application at a 'fundamental', machine language, level,
  117. you'll be ALWAYS able to apply 'DOS cracks' or 'Windows cracks'
  118. or 'Unix cracks' to whatever OS the idiots will fancy in 5 years
  119. time... you are learning a technique that will NEVER BE OBSOLETE,
  120. believe me.
  121. Well firing w32dasm (which, I insist, is not a very good
  122. disassembler) you'll be able to save the webex.alf listing
  123. (which is 16 million bytes long, BTW, a real tribute to the
  124. 'overbloatility' of C++ in general and Windows programming in
  125. particular). Now load this *.alf inside a wordprocessor (you
  126. would be well advised to use a fast and good wordprocessor, i.e.
  127. not Microsoft's one, when you deal with such monstrosities, once
  128. more there is no reason to work inside Windoze).
  129. Ok, let's start with the cracking! Alas! Searching our nagging
  130. ASCII strings inside the listing, we do NOT find any trace of the
  131. two main nagscreens of Webexpress (Evaluation copy... &  To
  132. register Webexpress...). These ASCII data are indeed NOT in the
  133. main *.exe module, but inside WEBEX.DWR, a file containing the
  134. resources for Webex (which seems compiled with Borland C++ 4,5
  135. btw). What now? Should we switch to Winice in order to find our
  136. protection scheme then? Has our dead listing approach failed?
  137. Well... let's examine a little more our listings... let's forget
  138. the ASCII strings -for the moment- and let's start with the
  139. easiest possible search in such cases: Since the limit of allowed
  140. days is 30 (which corresponds to 1Ex, duh) we could/should have
  141. somewhere an instruction like (we are here in a 16 bit
  142. application, not 32 one) mov ax,001E (B81E00)... would not we?
  143. Well, er... yes, quite. If you think this string of bytes is TOO
  144. SHORT and that you'll find much too many mov ax,001E inside a
  145. 1309200 bytes long file you are dead right... we would indeed
  146. find quite a lot of occurrences where 1E does not represent the
  147. 30 days limit at all, but only a parameter for a subsequent
  148. call:... let's conclude by saying that with overbloated programs
  149. -i.e. all Windows programs- there is no point in searching 'too
  150. short' shortcuts.
  151.      Our search for 'mov ax, 001E'... would fail for sure... But
  152. wait! Couldn't we narrow the search a little more?
  153. Yes, hey, we can! But we'll need both a little experience and a
  154. little feeling: You see: the normal code for such a protection
  155. inside Borland C++ would consist in a COUPLE of instructions:
  156. E81E00    mov ax,001E
  157. 2B06xxxx  sub ax,[gone_days]
  158. and since the code for 'sub ax,[whatever]' is 2B06xxxx, we now
  159. have a more 'robust' sequence of bytes for our search:
  160.                         E8 1E 00 2B 06
  161. Obviously we CANNOT search two consecutive instructions inside
  162. our disassembled listing using our wordprocessor search
  163. facilities, we will therefore have to search the above sequence
  164. inside Hexworkshop (a fairly good hexeditor that we cracked with
  165. - lesson 9.3 if you are using windoze, but you could anytime use
  166. old good (and powerful) PSEDIT). Let's do it... ahh! Things look
  167. muuuch better: splendid! There is only a single occurrence, at
  168. bytes 84565-84569 of our hexfile. Ok, done. Struck and destroyed.
  169. It's easy now to fetch this part of the code from our
  170. disassembled listing (we'll obviously have to translate the
  171. address 84565-84569 using the tables at the beginning of our
  172. Wdasm disassembly: here the relevant part:
  173. ...
  174. CSEG053 Off:83400 Size:1FFC Flags:0x1D10-CODE,MOVEABLE ; *53*
  175. ... and since 84565-83400 gives us 1165 bytes, the same address
  176. inside our listing will be :0053.1165... here it is!
  177. :THE_BINGO_QUICK_CRACK
  178. :0053.1162 8956EA        mov [bp-16], dx
  179. :0053.1165 B81E00        mov ax, 001E   ;load 30 *** BINGO!
  180. :0053.1168 2B066A46      sub ax, [466A] ;subtract gone_days
  181. :0053.116C 50            push ax
  182.  
  183. Well, this shows us immediately the importance of location
  184. [466A], which is the memory location where the day_counter
  185. "grows".
  186.      OK, bingo! This search has worked here without flaw or
  187. error... nevertheless beware! The abovementioned 'zen' method is
  188. NOT correct, coz it would in many cases NOT work (even if it
  189. actually worked here). Much too many protection schemes would
  190. have either
  191. a) a different (masked or concealed) initial value for ax instead
  192. of the exact one (here 1E): The protectionists could have a 'mov
  193. ax, 1F' (which is 31) and a 'dec ax' following it (which gives
  194. back our 30 days limit), or a zillion other possibilities in
  195. order to 'conceal' (more or less slightly :=) the purposes of the
  196. main comparison inside the code;
  197. b) another, completely different, assembler construction... say
  198. different instructions instead of sub ax,[gone_days], or
  199. c) junk between 'real' instructions (see elsewhere in my tutorial
  200. the 'junking' techniques for protection schemes).
  201. Therefore the abovementioned approach (unless you 'feel' the
  202. code) could make you waste too much time and would often miss the
  203. mustard... even if, interestingly enough, we ARE as a matter of
  204. fact landed smack in the middle of our protection using the
  205. simple trick above... but since you are here to learn the solid
  206. basic ways of cracking first (and you are not yet ready to feel
  207. the code, even if I believe you will, once you understand my
  208. 'zen' lessons at the end of this tutorial) here is a more 'sound'
  209. approach to this sort of cracking:
  210.      Looking at all the many data strings inside Webex.exe, as
  211. said above, we have NOT found the text of the nagscreens (which
  212. is located inside the resource file Webex.dwr), but we can
  213. nevertheless find ONE very interesting stringdata reference (did
  214. they forgot it?)... just have a look at the "string data
  215. references" inside W32dasm once you load webex.exe...
  216. HERE!:    "Printed with an evaluation copy"
  217. Ahha! Protectionist's squalor... how awful! This is a nagstring
  218. that should be WRITTEN inside any text printed with our copy of
  219. the application, should a user deem necessary to use it for more
  220. than the allowed 30 days... you remember our PaintShopPro
  221. cracking (- lessons 9.2 and 9.3) don't you? PaintShop had a
  222. counter as well, but there was no 'punishment' should you
  223. heedlessly 'overuse' the program. These 'MicroVision development'
  224. guys have purposely added a protection which cripples the program
  225. if you do not register it after 30 days! Buu! Buu!
  226.      Now please examine code segment 109.1A06... (using W32dasm)
  227. there you'll find a whole series of code protection strings.
  228. Let's now have a look at the part of the code that pushes
  229. "Printed with an evaluation copy", it's segment 82... as you will
  230. see, even coming from this direction we land immediately inside
  231. the protection scheme. As I said elsewhere... protection schemes
  232. inside the code of an application are like tarantulas on a
  233. wedding suit, it's impossible not to see them from pretty far
  234. away.
  235.  
  236. :COMPARE_VALUES_ADD_FB_AND_PRINT_NAGSTRING... NAGSTRING_ROUTINE
  237. :82.0B5F 8CD0        mov ax, ss    ;start of routine
  238. :82.0B61 90          nop
  239. :82.0B62 45          inc bp
  240. :82.0B63 55          push bp
  241. :82.0B64 8BEC        mov bp, sp
  242. :82.0B66 1E          push ds
  243. :82.0B67 8ED8        mov ds, ax
  244. :82.0B69 B8D400      mov ax, D4      ;parameter D4 for the next
  245. :82.0B6C 9AFFFF0000  call 0001.517Fh ;(and only) ubiquitous call
  246. :82.0B71 8C5EFC      mov [bp-04], ds
  247. :82.0B74 C746FAC319  mov word ptr [bp-06], 19C3 ;fix XX start
  248. :82.0B79 8D468E      lea ax, [bp-72]  ;ax = [bp-72]
  249. :82.0B7C 8C56F4      mov [bp-0C], ss  ;save ss
  250. :82.0B7F 8946F2      mov [bp-0E], ax  ;[bp-0E] = [bp-72]
  251. :82.0B82 EB14        jmp 0B98         ;begin loop
  252.  
  253. :82.0B84 C45EFA     les bx, [bp-06]  ;loop from B9F,begin=[19C3]
  254. :82.0B87 268A07     mov al , es:[bx] ;load in al es:[19C3](XX)
  255. :82.0B8A 04FB       add al, FB       ;add FB
  256. :82.0B8C C45EF2     les bx, [bp-0E]  ;load [bp-72] in bx
  257. :82.0B8F 268807     mov es:[bx], al  ;save XXX at es:[bp-72]
  258. :82.0B92 FF46FA     inc word ptr [bp06] ;next value loc gets+FB
  259. :82.0B95 FF46F2     inc word ptr [bp0E] ;next save location
  260. :82.0B98 C45EFA     les bx, [bp-06]  ;we begin/began at19C3
  261. :82.0B9B 26803F00   cmp byte ptr es:[bx], 0 ;are we done?
  262. :82.0B9F 75E3       jne 0B84           ;not yet, so loop up
  263. :82.0BA1 C45EF2     es bx, [bp-0E]
  264. :82.0BA4 26C60700   mov byte ptr es:[bx], 00
  265. :82.0BA8 16         push ss
  266. :82.0BA9 8D468E     lea ax, [bp-72]   ;prepare for the call
  267. :82.0BAC 50         push ax           ;passing all...
  268. :82.0BAD 1E         push ds           ;...these params...
  269.  
  270. * StringData Ref from Data Seg 109 -Printed with EvaluationCopy
  271.                      |
  272. :82.0BAE 68061A     push 1A06         ;push and be betrayed
  273. :82.0BB1 9AFFFF0000 call USER.LSTRCMP ;AhHa!
  274.  
  275. A very interesting block of code! You can easily see that here
  276. we have a reference to an obvious protection and at the end we
  277. have a call to USER.LSTRCMP, which is a case sensitive comparison
  278. of two null terminated strings, wildly used by windows
  279. protectionists (sic!).
  280.      As 'usual' (you remember our crack of Hexworkshop in -
  281. lesson 9.2, don't you?) we must search the 'caller' of this block
  282. of code, i.e., where, inside webex.exe, dwells one of the
  283. following calling strings
  284. Either         call 0B5F
  285. or             jmp, je, jz... you name it, 0B5F
  286. or             call 0082.0B5F
  287. Since the only common denominator of the above strings is a
  288. '0B5F' inside them, let's search first of all for 0B5F
  289. occurrences inside our 'protection' segment 82 (we should look
  290. further for the eventual call 0082.0B5F inside the other segments
  291. only if we do not fetch anything inside 82).
  292. And look! We land, almost immediately (remember that protection
  293. routines are most of the time 'compacted' inside one -or at most
  294. two- segments of wincode):
  295. :BE_NAGGED_INFIDEL
  296. :0082.0C8F 90        nop
  297. :0082.0C90 0E        push cs    ;prepare for call
  298. :0082.0C91 E86202    call 0EF6  ;call DECIDING_ROUTINE and...
  299. :0082.0C94 0BC0      or ax, ax  ;...check flag ax. IS it 0?
  300. :0082.0C96 7506      jne 0C9E   ;call compare if ax=1
  301. :0082.0C98 B80100    mov ax, 1  ;AX now 1 if it was zero...
  302. :0082.0C9B E9EE01    jmp 0E8C   ;...and do NOT call NAGSTRING
  303. :compare_howbadareyou
  304. :0082.0C9E 833E6E4602 cmp word ptr [466E], 2 ;is it 2?
  305. :0082.0CA3 7D02      jge 0CA7   ;[466E] = 2 call NAGSTRING!
  306. :0082.0CA5 EBF1      jmp 0C98   ;[466E]  10?
  307. :82.07EE 7E08          jle 07F8               ;if yes, Jesus,
  308. :82.07F0 C7066E460300  mov word ptr [466E], 3 ;flag 3=VERY BAD
  309. :82.07F6 EB15          jmp popout
  310.  
  311. :82.07F8 833E684605   cmp word ptr [4668], 5 ;is 4668  10?
  312. :82.0814 7E1E         jle 0834        ;yes, then...
  313. :82.0816 6A00         push 0          ;...let's...
  314. :82.0818 1E           push ds         ;...prepare
  315. * StringData Ref from Data Seg 109 -"CODE"
  316.                           |
  317. :82.0819 686D19      push 196D        ;...and
  318. :82.081C 1E          push ds          ;...then
  319. * StringData Ref from Data Seg 109 -"WB_10"
  320.                          |
  321. :82.081D 685119       push 1951
  322. :82.0820 9AFFFF0000   call 0069.09F4h ;...fire this routine
  323. :82.0825 83C40A       add sp, 000A
  324. :82.0828 0BC0         or ax, ax       ;and if not zero...
  325. :82.082A 7508         jne 0834        ;...then check can use
  326. :82.082C C7066E460300 mov word ptr [466E], 3 ;flag=3=VERY BAD
  327. :82.0832 EB15         jmp popout
  328.  
  329. :OK_4668_IS_MORE_THAN_10_THEREFORE_CAN_USE_OR_ALMOST:
  330. :82.0834 833E6A460A    cmp word ptr [466A], A ;is [466A]  10?
  331. :82.0839 7E08          jle 0843           ;can use if [466A] = 4.1-4.4: protection schemes based on time), this
  332. is done in a very rich number of ways, a double counter being one
  333. of the most common.
  334. OK, let's resume our findings:
  335. 1) We found our good old location [466A] compared to 1E (i.e.
  336. 30), which is very interesting to say the least.
  337. 2) We know now the meaning of location [466E], which may be
  338. either: 3=VERY BAD, DISABLING, or 2=TIME IS OVER or 1=TIME IS
  339. ALMOST OVER or 0=OK GO ON USING OUR CRAP
  340. So we'll 'name' this [466E] HOWBADAREYOU.
  341. Since we know that its value depends on the TWO parameters in
  342. [466A] and [4668], let's search for them. If we start with [466A]
  343. We land immediately to our 'first' block of code (the one found
  344. at the beginning of this lesson, the one inside segment 53,
  345. which seems to be an 'initialisation' segment):
  346. :FIRST_NEW_OCCURRENCE_OF_gone_days
  347. :0053.1162 8956EA       mov [bp-16], dx
  348. :0053.1165 B81E00       mov ax, 001E      ;load 30 ****
  349. :0053.1168 2B066A46     sub ax, [466A] ;subtract gone_days
  350. :0053.116C 50           push ax
  351. And we'll therefore 'name' [466A] GONEDAYS
  352. Let's do our first 'HANDS ON' checking.
  353. Pick up WEBEXP.EXE with hexworkshop (we cracked it in lesson -
  354. 9.3) and substitute (for instance)
  355. :0053.1165 B81E00       mov ax, 001E
  356. with
  357. :0053.1165 B81E1E       mov ax, 1E1E
  358. This should allow for more than 21 years of undisturbed use of
  359. this program (1E1E=7710 days) and if we run the program now we'll
  360. see that the 'Evaluation days remaining' of the nagscreen are
  361. indeed 7710. This crack will not work (alone), though, because
  362. there are, as we saw, other 'crosschecking' locations in play.
  363. Let's therefore gather a little more facts about these locations
  364. inside our code.
  365. :ANOTHER_OCCURRENCE_OF_[466A]_gone_days
  366. :0082.074E E843FC        call 0394     ;SHELL calls
  367. :0082.0751 83C406        add sp, 0006
  368. :0082.0754 A36846        mov [4668], ax  ;UPDATE [4668]
  369. :0082.0757 6A03          push 0003
  370. :0082.0759 6A00          push 0000
  371. :0082.075B 6A00          push 0000
  372. :0082.075D 0E            push cs
  373. :0082.075E E833FC        call 0394     ;SHELL calls
  374. :0082.0761 83C406        add sp, 0006
  375. :0082.0764 A36C46        mov [466C], ax ;save ax here
  376. :0082.0767 8B46FA        mov ax, [bp-06] ;get param
  377. :0082.076A 2B066046      sub ax, [4660]  ;sub ax with [4660]
  378. :0082.076E A36A46        mov [466A_GONEDAYS], ax ;UPDATE
  379. GONEDAYS!
  380. :0082.0771 8B46FC        mov ax, [bp-04]
  381. :0082.0774 8B56FA        mov dx, [bp-06]
  382. :0082.0777 3B066646      cmp ax, [4666]
  383. :0082.077B 7506          jne 0783
  384. :0082.077D 3B166446      cmp dx, [4664]
  385. :0082.0781 742F          je 07B2
  386. :0082.0783 FF066846      inc word ptr [4668] ;INCREASE [4668]!!
  387.  
  388. ****************** THE WHAT_THE_CUCKOO_PROBLEM ***************
  389. We better -first of all- have a closer look at this 'double' call
  390. 394 for learning purposes, coz here hides a very common 'mistake'
  391. of Wdasm: a problem that you may not be aware of: DISASSEMBLER
  392. OFTEN MISS THE BEGINNING OF THE ROUTINES.
  393. Look! Our listing does not seem to report any :0082.0394 routine
  394. at all!
  395. :WHAT_THE_CUCKOO?_NO_ROUTINE_AT_82.0394?
  396. :0082.038A 91                 xchg ax,cx
  397. :0082.038B 029B02AF           add bl , [bp+di-50FE]
  398. :0082.038F 02A502D2           add ah, [di-2DFE]
  399. :0082.0393 028CD090           add cl , [si-6F30]
  400. :0082.0397 45                 inc bp
  401. :0082.0398 55                 push bp
  402. ... But since missing the start of routines is a 'routinely'
  403. mistake for all disassemblers we can repair 'by hand' this piece
  404. of code, which in reality should read, once you rearrange the
  405. same bytes:
  406. :EVERYTHING_OK_AT_394
  407.  82.0394 8CD0                 mov     ax, ss
  408.  82.0396  90                   nop
  409.  82.0397  45                   inc     bp
  410.  82.0398  55                   push    bp
  411.  82.0399  8BEC                 mov     bp, sp
  412.  82.039B  1E                   push    ds
  413. The above listing comes from WCB, which is a much older
  414. disassembler than W32dasm, but which DOES NOT miss the beginning
  415. of the routines.
  416.  
  417. ... For now, just remember -always- that 8CD090 is a common start
  418. for routines and that you should -never- completely trust your
  419. disassembler (or you debugger, or anybody for that matter) Work
  420. always cum grano salis!
  421. ******************************************************
  422. What IS interesting in the ANOTHER_OCCURRENCE routine above is
  423. that we have our GONEDAYS correlated to an increase of [4668],
  424. a parameter whose meaning we do not yet know. Let's also notice
  425. that location [4660] is a 'gone days' basher, i.e. a location
  426. that 'remembers' how much must be 'diminished' from GONEDAYS,
  427. let's call it [4660_BASHER]. And now we would search for these
  428. locations and so on and so on, sinking deeper and deeper in our
  429. shadowy codewoods, always (well, almost always :=) knowing what
  430. we are doing.
  431.      We could continue like this in order to completely reverse
  432. engineering this application. But all these paths have been
  433. showed for your 'homework', and you should -obviously- use the
  434. help of Winice for such examinations. I wanted with all this
  435. cracking WITHOUT Winice (once more) just show you the untarnished
  436. POWER of the dead listing approach. Now let's go on to the real
  437. crack, which we'll do still only looking at our listings, without
  438. even a glimpse at Winice (no debugger in my hands, ladies and
  439. gentlemen! Only three or four sheets of printed paper).
  440.      As we saw before, clearly the protection scheme acts inside
  441. the call to 0EF6 at the beginning of the BE_NAGGED_INFIDEL?
  442. routine... what happens to our beloved flag ax, then, inside the
  443. 82.OEF6 'deciding' routine?
  444.      Routines inside routines... like the Russian Mathrioskas
  445. dolls... this kind of fishing is part of the sublime art of
  446. reverse engineering a program, a sport that requires some
  447. feeling, some luck and some experience.
  448. Let's have a close look at this routine.
  449. :DECIDING_IF_BE_NAGGED_INFIDEL... DECIDING_ROUTINE!
  450. :0082.0EF6 8CD0               mov ax, ss
  451. :0082.0EF8 90                 nop
  452. :0082.0EF9 45                 inc bp
  453. :0082.0EFA 55                 push bp
  454. :0082.0EFB 8BEC               mov bp, sp
  455. :0082.0EFD 1E                 push ds
  456. :0082.0EFE 8ED8               mov ds, ax
  457. :0082.0F00 33C0               xor ax, ax
  458. :0082.0F02 9AFFFF0000         call 0001.517Fh ;call ubiquitous
  459. :0082.0F07 A19846             mov ax, [4698]  ;HERE!!***
  460. :0082.0F0A EB00               jmp 0F0C        ;therefore
  461. :0082.0F0C 1F                 pop ds          ;everything
  462. :0082.0F0D 5D                 pop bp          ;depends
  463. :0082.0F0E 4D                 dec bp          ;from location
  464. :0082.0F0F CB                 retf            ;[4698]!
  465.  
  466. Here we call once more this ubiquitous 1.517Fh routine, which
  467. -being at segment one- is probably one of the main display
  468. routines... we do not have necessarily to care... let's just
  469. check that 1.517F does not modify our TREASURE, i.e. location
  470. [4698], which is the location moved in AX. How will we check it?
  471. It's easy: just search for [4698] inside the listing...
  472.      Whoa! No problem! The first occurrence of [4698] found is
  473. already inside our 'protection segment' 82... and it's a most
  474. interesting piece of code indeed from our cracking perspective...
  475. :82.01FB 9AFFFF0000    call USER.LSTRCMPI    ;call LSTRCMPI
  476. :82.0200 0BC0          or ax, ax             ;same strings?
  477. :82.0202 750B          jne 020F              ;no, so go flag1
  478. :82.0204 C70698460000  mov word ptr [4698], 0 ;flag0=samestrings
  479. :82.020A B80100        mov ax, 1              ;ax = 1
  480. :82.020D EB0A          jmp 0219               ;continue
  481. :82.020F C70698460100  mov word ptr [4698], 1
  482. ;flag1=stringsdiffer
  483. :82.0215 33C0          xor ax, ax             ;ax = zero
  484. :82.0217 EBF4          jmp 020D               ;goto continue
  485.  
  486. I assume you all know that the function
  487.           int lstrcmpi (LPCSTR lpszStr1, LPCSTR lpszStr2)
  488. makes a non case sensitive comparison of two null terminated
  489. strings... a zero return value indicates that the two strings
  490. where identical. A negative value means that string1 < string2 and a positive one means that string1> string2.
  491. OK, it's MADE! The above piece of code represents obviously the
  492. final comparison between the user input and the registration key
  493. (what else?).
  494. THEREFORE the crack can be made with a very simple modification
  495. of the DECIDING ROUTINE... we must ensure that location [4698]
  496. is always flagged TRUE (i.e. zero) and therefore we modify
  497. :0082.0F07 A19846                 mov ax, [4698]
  498. with
  499. :0082.0F07 B80000                 mov ax, 0
  500. That's all we need to crack completely this program.
  501. No more nagscreens, (all three fetch the value of 4698 with a
  502. call to the same routine 82.EF6, all three will not snap any more
  503. now) should we really use this program, and we have made the
  504. first steps towards higher cracking. A word about it: higher
  505. cracking is something more than just defeating a protection, it's
  506. understanding what's going on in ANY part of a program we may
  507. wish to modify. Say you hate (just kidding) Microsoft enough to
  508. distribute cracked copies of their (awful slow) proggies where
  509. there is NO Microsoft logo whatsoever, or that you fancy a pink
  510. wordprocessor... go ahead and crack all the applications you use!
  511. And then distribute everything on the web for free!
  512. BTW, you should NOT believe that the two approaches I have shown
  513. you ('live' cracking through Winice, i.e. examining the
  514. protection scheme when it snaps, and the examining of the 'dead'
  515. listing as we are doing here) are the only methods to crack such
  516. protection... many more possibilities are open... just to give
  517. you an example, the (very old) utilities that show the 'imported'
  518. API functions of a program from its *.DLL and from KERNEL, USER
  519. and SHELL are a formidable cracking tool for windows programs...
  520. if you for instance search for KEYBOARD, you'll find the
  521. following occurrences...
  522. 59.1354  9AFFFF0000               call    KEYBOARD.ANSITOOEM
  523. 79.1F7A  9AFFFF0000               call    KEYBOARD.OEMTOANSI
  524. 79.1FCB  9AFFFF0000               call    KEYBOARD.ANSITOOEM
  525. 82.13DA  9AFFFF0000               call    KEYBOARD.ANSITOOEM
  526. 82.1550  9AFFFF0000               call    KEYBOARD.ANSITOOEM
  527. 82.1588  9AFFFF0000               call    KEYBOARD.ANSITOOEM
  528. 82.1599  9AFFFF0000               call    KEYBOARD.ANSITOOEM
  529. 82.15D7  9AFFFF0000               call    KEYBOARD.ANSITOOEM
  530. 82.1629  9AFFFF0000               call    KEYBOARD.OEMTOANSI
  531. 82.16D5  9AFFFF0000               call    KEYBOARD.OEMTOANSI
  532. 83.063A  9AFFFF0000               call    KEYBOARD.ANSITOOEM
  533. 83.06B2  9AFFFF0000               call    KEYBOARD.OEMTOANSI
  534. 102.0721 9AFFFF0000               call    KEYBOARD.ANSITOOEMBUFF
  535. 102.074C 9AFFFF0000               call    KEYBOARD.OEMTOANSIBUFF
  536. ...and even lower beings would notice that segment 82 has SEVEN
  537. occurrences of KEYBOARD out of 14 and would smell a  rat...
  538. KEYBOARD.DRV is a windows device driver, i.e. a DLL with another
  539. name, which is extensively used by the USER module. I hope you
  540. will not ask for the 'meaning' of the various KEYBOARD
  541. functions... you should know them by heart!  Suffice to say that
  542. all ANSI APIs have MUCH to do with protection schemes, and than
  543. therefore the calls to KEYBOARD 5,6,134 and 135 are INDEED
  544. important from our point of view. Applications use the
  545. AnsiToOem(const char_huge* hpszWinString, const char_huge*
  546. hpszOEMString) function to convert a string stored in the windows
  547. character set into one stored in the specified OEM character set
  548. (in WinNT/32 there is a macro that calls the CharToOem()
  549. function)... As a matter of fact the USER.LSTRCMPI API from
  550. 82.01FB uses -in our case- these Keyboard functions. Are we
  551. finished with 'alternative' cracking approaches? Nooo! There are
  552. zillion cracking ways... say you use WRT (WIndows Resources
  553. Toolkit, a BEAUTIFUL Borland utility which is of UTMOST interest
  554. in our trade)... there you'll immediately find out that the Menu
  555. option 'Register' corresponds to 164. Decimal 164 is A4h... have
  556. a search for it... you'll land to 82.1575!
  557.      As you have seen, we could have located the protection
  558. segment of our target using a completely different approach...
  559. but let's go back to our VERY POWERFUL dead listing... just a
  560. moment! A cool breeze outside my windows... say, do you know the
  561. names of the winds? Boreas (Aquila), Notus (Auster), Eurus and
  562. Zephyrus (Favonius) are the basic North, south, east and west
  563. ones... you may add Thrascias (NNW), Libs (WSW), Corus (Caurus
  564. or Argestes) (NW), Volturnus (SE), Africus (Afer ventus) (SW)...
  565. you did read Milton's Paradise, didn't you... how can you hope
  566. to crack if you did not? Back to our target, now. Let's have a
  567. look at the protection scheme itself... let's see how the
  568. comparison between user input and serial number is made.
  569. Here the relevant part of the routine:
  570. :CHECK_IF_USER_CHEATS
  571. :0082...01A2-01B2...               ;prepare for REGNAME
  572. :0082.01B3 E84AFE        call 0000 ;call SHELL.REGOPENKEYetc
  573. :0082.01B6 0BC0          or ax, ax
  574. :0082.01B8 7455          je 020F   ;you are BAD, beggar off
  575. :0082.01BA 1E            push ds
  576. :0082.01BB 687046        push 4670
  577. :0082.01BE 9AFFFF0000    call 1.4590h
  578. :0082.01C3 83C404        add sp, 4
  579. :0082.01C6 3D0400        cmp ax, 4
  580. :0082.01C9 7244          jb 020F   ;you are BAD, beggar off
  581. :0082...01CB-01DC...               ;prepare for REGKEY
  582. :0082.01DD E820FE        call 0000 ;call SHELL.REGOPENKEYetc
  583. :0082.01E0 0BC0          or ax, ax
  584. :0082.01E2 742B          je 020F   ;you are BAD, beggar off
  585. :0082.01E4 1E            push ds
  586. :0082.01E5 687046        push 4670
  587. :0082.01E8 16            push ss
  588. :0082.01E9 8D46AE        lea ax, [bp-52] ;USER INPUT LOCATION
  589. :0082.01EC 50            push ax
  590. :0082.01ED 0E            push cs
  591. :0082.01EE E8E7FE        call 00D8  ;call loadchars and...
  592. :0082.01F1 16            push ss    ;...ansilower and magic
  593. :0082.01F2 8D46D6        lea ax, [bp-2A]     ;MAGIC LOCATION
  594. :0082.01F5 50            push ax
  595. :0082.01F6 16            push ss
  596. :0082.01F7 8D46AE        lea ax, [bp-52]     ;USER INPUT
  597. :0082.01FA 50            push ax
  598. :0082.01FB 9AFFFF0000    call USER.LSTRCMPI  ;check strings
  599. :0082.0200 0BC0          or ax, ax           ;strings differ?
  600.  
  601. :0082.0202 750B          jne 020F   ;you are BAD, beggar off
  602. :0082.0204 C70698460000  mov word ptr [4698], 0 ;good guy!
  603. :0082.020A B80100        mov ax, 0001        ;flag ax=1,OK
  604. :0082.020D EB0A          jmp 0219            ;continue
  605. :0082.020F C70698460100  mov word ptr [4698], 1 ;beggar off!
  606. :0082.0215 33C0          xor ax, ax          ;flag ax=0
  607. :0082.0217 EBF4          jmp 020D            ;NO GOOD, continue
  608. ...
  609. :retf
  610.  
  611. The above block of code makes EVIDENT how such a protection
  612. scheme works:
  613. 1)   first of all it performs the 'usual' checks on the entered
  614. strings (something must be written there, chars must make sense,
  615. minimum length, etc)
  616. 2)   after the usual checks the loadchars and trasformchars
  617. routines are fired.
  618.      If you look at the listing, routine 82.00D8 calls among
  619. other things the LPSTR AnsiLower(LPSTR lpszString) function which
  620. under Windows NT/32 does not exist any more and has been
  621. substituted with a macro (Yes, a macro! This should make you
  622. shiver thinking at what for a monstrosity is this Windows OS
  623. swelling towards) that calls the CharLower() function.
  624. 3)   as soon as we have in memory our magic string, made
  625. transforming the user name input, we can compare it with the
  626. numbers inside the second inputted string. Should magic number
  627. and magic string differ you beggar off.
  628. Let's crack once more this program, this time we'll crack it
  629. here, i.e. we'll seek a correct registration 'result'
  630. substituting instruction
  631.  
  632. :0082.020F C70698460100   mov word ptr [4698], 1 ;beggar off!
  633. with instruction
  634. :0082.020F C70698460000   mov word ptr [4698], 0 ;OK, nice sucker
  635.  
  636. [REDIRECTION] (First elements of)
  637. The above crack solves location [4698], but that is not enough:
  638. WE MUST ALSO MODIFY THE AX FLAG... remember: each routine jumps
  639. back with a flag (mostly in ax) upon which the calling routine
  640. reacts... therefore we must also modify following piece of code:
  641. :0082.0215 33C0           xor ax, ax       ;flag ax=0
  642. in order to substitute it with
  643. :0082.0215 B80100         mov ax,1         ;flag ax=1
  644. But, alas, this crack is a 3 bytes instructions! The original
  645. instruction was only two bytes long! How should we crack?
  646. Independently from the fact that actually there are 2 bytes
  647. instructions that do indeed perform the abovementioned flagging,
  648. I'll teach you here, a simple 'redirection', a method that you'll
  649. use a lot for higher cracking when we will 'patch'
  650. applications... Yeah! Time to leave the ONE BYTE FOR ONE
  651. BYTE petty and miserable cracking, time to insert whole new
  652. PIECES OF OUR code inside the applications we crack... what about
  653. having -somewhere inside a cracked Word for Windows- the string
  654. 'Warning: Microsoft can damage your health'? :=)
  655.      You'll learn pretty complicate 'patching' redirection
  656. techniques in my +HCU, for now, let's just understand the
  657. fundament of this method here: the very short block of code we
  658. need to crack inside our target was originally this one:
  659. :0082.0204 C70698460000   mov word ptr [4698], 0 ;good guy!
  660. :0082.020A B80100         mov ax, 0001         ;flag ax=1, OK
  661. :0082.020D EB0A           jmp 0219             ;continue
  662. :0082.020F C70698460100   mov word ptr [4698], 1 ;beggar off!
  663. :0082.0215 33C0           xor ax, ax           ;flag ax=0
  664. :0082.0217 EBF4           jmp 020D             ;NO GOOD, continue
  665.      What about cracking the LAST instruction? Let's see... the
  666. code jumps back FF-F4 bytes (218-(FF-F4))=20d i.e. back to
  667. :0082.020d which is 'continue' (in this case after having being
  668. badflagged).
  669.      Well, what if we redirect this to :0082.020A? Then having
  670. already cracked instruction 20F in order to have our necessary
  671. 0 inside [4698], we would now 'redirect' a correct 1 inside ax
  672. AFTER having already had the bad guy 0 there at line 215.
  673. Therefore, let's 'redirect' this jump:
  674. :0082.0217 EBF4           jmp 020D            ;NO GOOD, continue
  675. with
  676. :0082.0217 EBF1           jmp 020A            ;get_da_good_flag
  677.      But Hey! Just a moment... What's the point of having loaded
  678. OURSELF a zero inside [4698] in the first time? WE DO NOT NEED
  679. IT! Let's use for the same aim the stupid protection itself...
  680. let's redirect FURTHER, DEEPER, BETTER.
  681.      There is -indeed- a final cracking solution for this program
  682. (and a much more ELEGANT one: I still grudge the criticisms I
  683. suffered on the ground I used simple and 'unelegant' cracks in
  684. this tutorial). Let's redirect 82.217 to instruction 82.204 and
  685. let's merryly forget the whole previous cracking of instruction
  686. 82.020F... I mean... who cares if the protection, there, loads
  687. one in the [4698] and flags to 0 our sad ax? As soon as our last
  688. redirection snaps, the OTHER PART of the same protection scheme,
  689. the 'good guy' one, will snap and 'cover' the badflagged [4698]
  690. with TRUE zeros and will flag to 1 our beloved, but unfortunately
  691. zeroed, ax.
  692.      Therefore forget ALL the previous cracks, this is the last
  693. but not least one (I mean, do not forget them... just fetch a new
  694. original nagged copy of webex.exe and start anew) and crack with
  695. that unnatural elegance that should always characterize all
  696. crackers from my school... solid crackers, old red's ones.
  697.      I'll leave to you the obvious disassembly solution: if EBF4
  698. jumps to 020D and EBF1 jumps to 020A, what will land our cracked
  699. copies to 0204? Ebbene? :=)
  700.      Now, you see, we have gone a long way cracking our silly
  701. Webexpress... as you saw, we could have cracked this target in
  702. quite a lot of different ways, but eventually the best (and less
  703. intrusive) crack required indeed a slight knowledge of the
  704. working of this program. Once more we worked on a 'dead'
  705. application... and once more we have demonstrated that Winice,
  706. though a splendid tool, is NOT the 'only' or 'absolute' cracking
  707. tool... Often a good disassembler, a wordprocessor and a
  708. hexeditor (and a good cocktail) are more than enough to crack
  709. every single application you can think of.
  710.      I will tell you something you may already have supposed: in
  711. order to prepare this lesson I originally cracked this Windows'
  712. application without EVER FIRING WINDOWS... using WCB (100.294
  713. bytes which -unlike W32dasm, did not miss any routine), List
  714. (26.507 bytes... a quick 'lister' which is a *.com... not even
  715. an *.exe!) and PSEDIT (which is a very powerful, 65.862 bytes
  716. long hexeditor), all DOS quick application (to work REALLY you
  717. cannot use windoze)... but many of my readers will probably have
  718. to crack inside Microsoft's slow abomination... using W32dasm,
  719. Word and Hexworkshop and wasting time... after all... why not?
  720. The results will be the same, it's only a matter of -good or bad-
  721. taste.
  722.      Now that you (begin to) understand re-direction cracking,
  723. you are ready to step over to 'real' higher cracks: what we call
  724. 'crackpatching'.
  725.  
  726. Well, that's it for this lesson, reader. Not all lessons of my
  727. tutorial are -or will be- on the Web.
  728.      You'll obtain the missing lessons IF AND ONLY IF you mail
  729. me back (via anon.penet.fi) with some tricks of the trade I may
  730. not know that YOU discovered. Mostly I'll actually know them
  731. already, but if they are really new you'll be given full credit,
  732. and even if they are not, should I judge that you "rediscovered"
  733. them with your work, or that you actually did good work on them,
  734. I'll send you the remaining lessons nevertheless. Your
  735. suggestions and critics on the whole crap I wrote are also
  736. welcomed. Do not annoy me with requests for warez, everything is
  737. on the Web, learn how to search, for goddess sake.
  738.  
  739.      "If you give a man a crack he'll be hungry again
  740.      tomorrow, but if you teach him how to crack, he'll
  741.      never be hungry again"
  742.  
  743.  
  744.  
  745.  
  746.  
  747. á
  748.  
  749.  
  750.  
  751. E-mail +ORC
  752.  
  753.  
  754.  
  755.  
  756. +ORC na526164@anon.penet.fi
  757.  
  758.  
  759.