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

  1.  
  2.                      HOW TO CRACK, by +ORC, A TUTORIAL
  3.  
  4. ---------------------------------------------------------------------------
  5.               Lesson 4 (1): Time protections - An introduction
  6. ---------------------------------------------------------------------------
  7.                 [PCFILE] [WLCHECK 16 bit] [WLCHECK 32 bit]
  8.                           A short history of time
  9.                    --------------------------------------
  10.  
  11.                                 ***********
  12.                         +HCU material FEBRUARY 1997
  13.                               LECTIO IN FIERI
  14.                                 ***********
  15.  
  16.   (Hic sunt tabulae: Best viewed with good old Courier).
  17.                 A short history of time
  18.                      (Lesson 4)
  19.             Time protections in Windows, by +ORC
  20.  
  21. For 'time protections' we intend a serie of protection schemes
  22. which are aimed to restrict the use of an application
  23. ONE
  24. -to a predetermined amount of days, say 30 days, starting with
  25. the first day of installation... 'CINDERELLA' TIME PROTECTIONS
  26. TWO
  27. -to a predetermined period of time (ending at a specific fixed
  28. date) independently from the start date... 'BEST_BEFORE' TIME
  29. PROTECTIONS
  30. THREE
  31. -to a predetermined amount of minutes and/or seconds each time
  32. you fire them... 'COUNTDOWN' TIME PROTECTIONS
  33. FOUR
  34. -to a predetermined amount of 'times' you use them, say 30
  35. times. Strictly speaking these protections are not 'time'
  36. dependent, but since their schemas are more or less on the
  37. same lines as in the cases ONE, TWO and THREE, we will examine
  38. them inside this part of my tutorial. Let's call them 'QUIVER'
  39. protections since, as with a quiver, you only have a
  40. predetermined amount of 'arrows' to shoot (and if you never
  41. went fishing with bow and arrows, on a mountain river, you do
  42. not know what's real zen... the fish springs out suddendly, but
  43. you 'knew' it, and your fingers had already reacted... a lot of
  44. broken arrows on the rocks, though :=)
  45.  
  46.      As first example I have chosen a double protected
  47. application: it has a time protection (of the 'Cinderella' type,
  48. limited to 90 days) as well as a 'quiver' protection
  49. scheme, which is the other -not time bounded- current variante
  50. of the shareware protections... i.e. you should use this program
  51. only 25 times before a protection lock.
  52. It's a relatively 'old' windows protection (april 1995). I found
  53. the program on a cheap cd-rom, which I bought (in a bunch with
  54. 9 others) a month ago: 6000 megabytes of bad protected software
  55. for the price of a good glass of wine! PCPLUS SUPER CD n°13,
  56. originally edited in July 1995. I believe it should be pretty
  57. easy to find it or to find this program on the Web if you do not
  58. already have it inside your collection of cheap CD-ROM. Another
  59. advantage of this program, from our perspective, is that the
  60. whole PCFILE.EXE represents de facto the protection scheme
  61. itself... not excessively overbloated: only 8912 bytes, when the
  62. 'real' application works inside the (huge and overbloated)
  63. pcf.dll, which will be called only if the user passes the
  64. protection. You can easily print the WHOLE disassembled listing
  65. of PCFILE.EXE (46 Wordperfect pages), that you'll quickly get
  66. through wcb (for instance). For once you'll have a COMPLETE and
  67. COMPLICATED protection scheme under your eyes.
  68.      Basically we'll study here the 'beginning' of more complex
  69. time protection schemes, the ones we'll crack with our later
  70. lessons. Some protection elements are here still 'naïv', but the
  71. protectionists have -at least- worked a little against easy
  72. cracks... which makes this protection even more interesting for
  73. us :=)
  74.      This program shows even a 'nasty' behaviour: should you use
  75. it after the locking snapped, it will obliterate the whole (main)
  76. pcf.dll from your harddisk, without any warning. This obviously
  77. does not mean anything at all here, but it's the secret to more
  78. advanced (and nastier) protection schemes, so you better have a
  79. look at it too. Nice, enough let's start now.
  80. [PCFILE] (aka the 'dll counter' method)
  81. PCFILE, version 8, (PCFILE.EXE, 8912 bytes, 17 apr 1995, Atlantic
  82. Coast software) is a database program which will be disabled
  83. after having 90 days from its first use or after having used it
  84. 25 times, whichever comes first.
  85.      We'll begin as usual: just use your wordprocessor search
  86. capacities to search inside the whole directory (and
  87. subdirectories) of PCFILE for words like 'demo' 'order' 'contact'
  88. 'expire' 'disabling' 'evaluation' and so on (alternatively, like
  89. I do, you can write your own little C utility to do it even more
  90. quickly and automatically on the whole 600 megabytes CD-ROM you
  91. have inserted on your drive :=)... You'll see immediately that
  92. only two of the PC-files can interest us: PCFILE.EXE and
  93. PCFRES.DLL. A quick 'turbodumping' of PCFILE.EXE itself will
  94. fetch all filenames and nagstrings we need to be happy from the
  95. end of the file... here they are:
  96. A)   010C      PCF.DAT
  97. B)   0114      PCF.DLL
  98. 1)   2.011C    PC-FIle demo has been disabled...
  99. 2)   2.01A2    The PC-File demo program has reached the maximum
  100.                allowable 25 sessions...
  101. 3)   2.0298    This demo version of PC-File 8 is designed...
  102. 4)   2.035A    The PC-File demo program has reached... 90 days
  103. 5)   2.0474    This is the last demo session...
  104.  
  105. When I see something like this I know that the crack is already
  106. made... it's so easy I can't understand why they don't just give
  107. their software away for free... money I suppose, people seem to
  108. be obsessed with this prepuberal problem... how stupid, besides:
  109. neminem pecunia divitem fecit.
  110. Beside, snooping inside files can be graet fun! At times you find
  111. some 'real' info inside them... Have a look at lotus Wordpro,
  112. for instance, you'll read something like: 'You idiot! Can't flow
  113. a partial paragraph!'; 'Yow! Need to SetFoundry() on this object!';
  114. 'Dude! I couldn't find myself!'; 'Ain't nothing to pop!' and many
  115. other amenities which throw a crude light on the life (and possible
  116. blunders) of commercial programmers and on the well know fact
  117. that most application are throw out FULL of bugs just in order
  118. to make money ('bugs for bucks').
  119. OK, back to our cracking: let's just search for the above NUMBERS
  120. inside the code of PCFILE:
  121. 1)   PC-File has been disabled: 011C
  122.  
  123.   1.1100 >C8040100         enter   0104, 00
  124.   1.1104  56               push    si
  125.   1.1105  C70632060000     mov     word ptr [0632], 0000
  126.   1.110B  6A00             push    0000
  127.   1.110D  B81401           mov     ax, 0114; THIS is PCF.DLL
  128.   1.1110  8946FE           mov     [bp-02], ax
  129.   1.1113  50               push    ax
  130.   1.1114  9A2E0D0212       call    1:0D2E ;what happens here?
  131.   1.1119  83C404           add     sp, 0004
  132.   1.111C  40               inc     ax
  133.   1.111D  7532             jne     1151
  134.   1.111F  1E               push    ds
  135.   1.1120  681C01           push    011C  ;HERE****
  136.   1.1123  8D86FCFE         lea     ax, [bp-0104]
  137.   1.1127  16               push    ss
  138.   1.1128  50               push    ax
  139.   1.1129  9A6E110000       call    USER._WSPRINTF
  140.  
  141. Therefore this target will be disabled after a check at the
  142. beginning of WinMain (1.1100) if ax, after having been
  143. incremented is non zero. We should have a look at the routine at
  144. 1:0D2E to see what happens... but let's first check the other
  145. nagstrings... no point in delving immediatly inside routines.
  146.  
  147. 2) The PC-File demo has reached the maximum allowable 25
  148. sessions... 01A2
  149.   1.11C9 >807EFC66                 cmp     byte ptr [bp-04], 66
  150.   1.11CD  7C0F                     jl      11DE
  151.   1.11CF  6AFF                     push    FFFF
  152.   1.11D1  9A36120000               call    USER.MESSAGEBEEP
  153.   1.11D6  6A00                     push    0000
  154.   1.11D8  1E                       push    ds
  155.   1.11D9  68A201                   push    01A2 ; HERE ****
  156.   1.11DC  EB62                     jmp     1240
  157. Therefore 25 sessions if byte ptr [bp-04] >= 66 (as you can see,
  158. the protectionists did not use anything vaguely similar to 25dec,
  159. which is 19hex).
  160.  
  161. 3)   This demo version of PC-File 8 is designed... : 0298
  162.  
  163.   1.11DE >807EFC4D         cmp     byte ptr [bp-04], 4D
  164.   1.11E2  7518             jne     11FC
  165.   1.11E4  6A00             push    0000
  166.   1.11E6  1E               push    ds
  167.   1.11E7  689802           push    0298 ;HERE ****
  168.   1.11EA  1E               push    ds
  169.   1.11EB  FF361000         push    word ptr [0010]
  170.   1.11EF  6A00             push    0000
  171.   1.11F1  9A48120000       call    USER.MESSAGEBOX
  172.   1.11F6  C70632060100     mov     word ptr [0632], 1 ;Flag 632!
  173. This 'Welcome nagged user' message appears therefore only THE
  174. FIRST time you run, when our byte ptr [bp-04] has been set to 4D.
  175. That figures: 66h - 4Dh = 19h, which are the 25 times allowed...
  176. the programmers from Atlantic Coast must have thought something
  177. like 'Stupid crackers will not fetch our nice clever protection:
  178. he'll be searching for byte 19h! Ah!' Note the flag set in
  179. location [632] if it's the first run :=)
  180.  
  181. 4)   The PC-File demo program has reached... 90 days : 035A
  182.   1.1211  833E320600               cmp     word ptr [0632], 0000
  183.   1.1216  7565                     jne     127D
  184.   1.1218  A13406                   mov     ax, [0634]
  185.   1.121B  8B163606                 mov     dx, [0636]
  186.   1.121F  2B062C06                 sub     ax, [062C]
  187.   1.1223  1B162E06                 sbb     dx, [062E]
  188.   1.1227  83FA76                   cmp     dx, 0076
  189.   1.122A  7251                     jb      127D
  190.   1.122C  7705                     ja      1233
  191.   1.122E  3D00A7                   cmp     ax, A700
  192.   1.1231  764A                     jbe     127D
  193.  
  194.   1.1233 >6AFF                     push    FFFF
  195.   1.1235  9A3C130000               call    USER.MESSAGEBEEP
  196.   1.123A  6A00                     push    0000
  197.   1.123C  1E                       push    ds
  198.   1.123D  685A03                   push    035A ; HERE!
  199.  
  200. There, location [634] in ax and location [636] in dx.
  201. ax subtracts location [62C] and dx subtracts with carry location
  202. [62E]. Is it more than 76h? (Which is 118 dec), Tell user he has
  203. reached 90 days. Is it exactly 76h? Then have a look at ax, if
  204. it is more than A700 then tell user the same.
  205.  
  206. 5)        This is the last demo session... : 0474
  207.  
  208.   1.132D >56               push    si
  209.   1.132E  9AFFFF0000       call    KERNEL._LCLOSE
  210.   1.1333  807EFC66         cmp     byte ptr [bp-04], 66
  211.   1.1337  7C19             jl      1352
  212.   1.1339  6AFF             push    FFFF
  213.   1.133B  9AFFFF0000       call    USER.MESSAGEBEEP
  214.   1.1340  6A00             push    0000
  215.   1.1342  1E               push    ds
  216.   1.1343  687404           push    0474 ;HERE****
  217.   1.1346  1E               push    ds
  218.   1.1347  FF361000         push    word ptr [0010]
  219.   1.134B  6A10             push    0010
  220.   1.134D  9AFFFF0000       call    USER.MESSAGEBOX
  221.  
  222.   1.1352 >1E               push    ds
  223.   1.1353  681401           push    0114 ;this is PCF.DLL
  224.   1.1356  6A01             push    0001
  225.   1.1358  9AFFFF0000       call    KERNEL.WINEXEC ;exec PCF.DLL
  226.  
  227.      And here, finally we have our good old [bp-04] -once more-
  228. compared to 66h. Notice that there is no Jumpequal nor
  229. jumpgreater check. This means that the program ALREADY KNOWS that
  230. the user has reached here for the first time the fatidic 66. This
  231. means (of course) that this code will be examined AFTER having
  232. incremented the counter of the protection, which must therefore
  233. happen somewhere between 1.123D and 1.132D (the end of routine
  234. 4 and the beginning of routine 5). If you have printed the whole
  235. disassembled listing of PCFILE.EXE and if you have read my other
  236. lessons about dead listing (-> 9.3 and 9.4) you do not need any
  237. more to read the following part of this lesson. Choose your
  238. armchair and sit there with a pen, your listing and a good
  239. cocktail (may I suggest a good Martini-Wodka? Don't use anything
  240. else but Moskowskaja). The moment to start 'feeling' the code has
  241. come! You can do everything alone. Write colored arrows on your
  242. listing! The first (or the fourth) simphony of Mahler on your CD!
  243. Everything will appear!
  244.      Indeed, if you prefer to follow here, behold: at 1.12B2 we
  245. have a call KERNEL._LOPEN wich opens the file PCF.DLL (0114):
  246.  
  247.   1.12AD  681401      push    0114 ;want pcf.dll
  248.   1.12B0  6A01        push    0001
  249.   1.12B2  9AFFFF0000  call    KERNEL._LOPEN ;open it
  250.  
  251. and at 1.12CD we have the exact point where, inside pcf.dll, a
  252. byte will be modified (at 10AF8):
  253.  
  254.   1.12C6  6A01                     push    0001
  255.   1.12C8  68F80A                   push    0AF8
  256.   1.12CB  6A00                     push    0000
  257.   1.12CD  9AFFFF0000               call    KERNEL._LLSEEK
  258.  
  259. The only modification takes place therefore inside PCF.DLL, a
  260. monstruosity of 1088832 bytes, where location 10af8 grows WITHOUT
  261. any change in the date of the dll. You can easily check this:
  262. *    copy pcf.dll pcf.ded
  263. *    (run pcfile a couple of time)
  264. *    fc /b pcf.dll pcf.ded
  265. fc /b is file compare /binary, good old (and quick) dos, duh?
  266. And this is what you get...
  267.  
  268.      Comparing files PCF.DLL and PCF.DED
  269.      00010AF8: 55 50
  270.  
  271. Et voila mesdames et messieurs, found the other way round, please
  272. note that this more 'practical' method can also be used *before*
  273. beginning the dead listing examination of the file (and would
  274. have given you the '0AF8' string to search for).
  275.  
  276. Well, what did we learn? A lot: an hidden counter grows in
  277. another file without leaving many traces. The 'quiver'
  278. protection snaps after growing more than 66h, having started at
  279. 4Dh. The flag for first time user is inside [0632]. [0634] and
  280. [0636] are used for the current date, [062C] and [062E] are the
  281. original date against which they are checked in a funny way.
  282.      There are two different protections, therefore we'll need
  283. two different cracks to deprotect this cram. Let's begin with the
  284. easiest one.
  285. Our FIRST crack, must destroy the counter that increases inside
  286. pcf.dll (the '25' session allowance). This will be made cracking
  287. following instruction:
  288.   1.12F3  FE46FC                   inc     byte ptr [bp-04]
  289. which is obviously the increasing instruction we are searching
  290. for (BECAUSE it's the only 'inc byte ptr' in the whole stupid
  291. program, AND because it is located short after the _LLSEEK, AND
  292. because it's incrementing nobody else than our good old [bp-
  293. 04]... what do you want more, a neon green flashing arrow light
  294. on the top of it?)
  295. We'll very simply "noop" this instruction, transforming it, for
  296. instance, in 40 90 48 (inc ax, nop, dec ax = do nothing). Well,
  297. yes, that was it for the '25 sessions' lock protection, thankyou,
  298. you may use the program a zillion times now. What now? Ah, yes,
  299. the DATE lock, let's have a look once more at it:
  300.   1.1218  A13406           mov     ax, [0634]
  301.   1.121B  8B163606         mov     dx, [0636]
  302.   1.121F  2B062C06         sub     ax, [062C]
  303.   1.1223  1B162E06         sbb     dx, [062E]
  304.   1.1227  83FA76           cmp     dx, 0076 ;118 (-90=1c)
  305.   1.122A  7251             jb      127D
  306.   1.122C  7705             ja      1233
  307.   1.122E  3D00A7           cmp     ax, A700 ;(42572)
  308.   1.1231  764A             jbe     127D
  309.  
  310.   1.1233 >6AFF             push    FFFF
  311.   1.1235  9A3C130000       call    USER.MESSAGEBEEP
  312.   1.123A  6A00             push    0000
  313.   1.123C  1E               push    ds
  314.   1.123D  685A03           push    035A ;HERE! 90 days!
  315.  
  316. Therefore, if location [636] is > than 76, the nag snaps.
  317. This 76 is calculated through what SEEMS a simple comparison
  318. between the actual date and the installation date.
  319.  
  320.   1.1218  A13406   mov     ax, [0634] ;load date ax
  321.   1.121B  8B163606 mov     dx, [0636] ;load date dx
  322.   1.121F  2B062C06 sub     ax, [062C] ;subtract first date
  323.   1.1223  1B162E06 sbb     dx, [062E] ;subtract first date
  324.   1.1227  83FA76   cmp     dx, 0076   ;allowed limit (?)
  325.   1.122A  7251     jb      127D       ;ok: you may
  326.   1.122C  7705     ja      1233       ;beggar off
  327.   1.122E  3D00A7   cmp     ax, A700   ;well, what's this
  328.   1.1231  764A    jbe     127D        ;then?
  329.  
  330.      In the reality there are various mathematical checkings
  331. going on here, as the second check on ax = A700 shows. This DOES
  332. NOT need to concern us much (we'll crack this code, later,
  333. changing the 'first time user' flag), but it's useful you have
  334. a rough understanding of what goes on inside these schemes,
  335. therefore let's delve a little inside it.
  336.      Basically, the good old dos function GetSystemDate (21/2A)
  337. works like this: On entry: ah = 2a
  338. On return:
  339. al = day of the week (0 = Sunday, 1 = Monday...)
  340. cx = year
  341. dh = month
  342. dl = day
  343. Short before the 90 days check, the protection calls two
  344. routines:
  345. 1:09B4 (GetSystemDate) and 1:0D64 (FetchInstallationCode)
  346.      The first one fetches the date (1.9D3-1.9D7) and the Time
  347. (21/2C, at 1.9E2), get's ONCE MORE the system date (1.9F7)
  348. subtracts the years against 1980 (1.A20: sub cx, 07BC) and then
  349. makes quite a lot of maniuplation of these data (around 1.C7D,
  350. where one year LESS than the current year will be stored in
  351. [SI+03], in order to calculate the total amount of days). The
  352. second one prepares the numbers for the sub ax and sbb dx of the
  353. 90 days check.
  354.      As I said all this does not need to concern you much, coz
  355. the protectionists have mad a 'protecion blunder': they have made
  356. every time snapping depending on a flag, the one in [0632].
  357.      What happens is: THE FIRST THING this program makes, smack
  358. at the beginning of WinMain, is to set to zero (FALSE) the
  359. abovementioned flag:
  360.   1.1105  C70632060000             mov     word ptr [0632], 0000
  361. Only in case of first time use, this flag will be set to TRUE at
  362.   1.11F6  C70632060100             mov     word ptr [0632], 0001
  363. knowing that, anyway, as soon as the program runs again this flag
  364. will be reset to FALSE by Winmain.
  365. And, as we saw, this flag is checked both for the 90 days snap:
  366.   1.1211  833E320600               cmp     word ptr [0632], 0000
  367. and for the 'This is your last day Cinderella' Warning:
  368.   1.1315 >833E320600               cmp     word ptr [0632], 0000
  369. A good fundamental crack will therefore be the 'automatical'
  370. setting to TRUE of this flag by our Winmain:
  371.   1.1105  C70632060100             mov     word ptr [0632], 0001
  372. Everytime the program runs it will believe that's the first time
  373. it does it.
  374. I know, theoretically, having nooped the increase inside PCF.DLL,
  375. the counter should remain always at 4D, which would set ANEW the
  376. flag to true every run... but we do not want the first 'welcome'
  377. nagscreen either, do we? Therefore:
  378. ****** Crack for PCFILE version 8, by +ORC, march 1997 ***
  379. psedit pcf.dll
  380. search         4E 49 44 4D   (4D only if you did not run it)
  381. modify in      4E 49 44 50        (second time run)
  382. psedit pcfile.exe
  383. search         83 C4 06 FE 46 FC
  384. modify in      83 C4 06 40 90 48  (nooped increase)
  385. search         C7 06 32 06 00 00
  386. modify in      C7 06 32 06 01 00  (flag always true)
  387. *********************************************
  388. As second example I have chosen a fairly interesting 'CINDERELLA'
  389. protection scheme of a Window application which can be useful for
  390. our purposes: Link Check (Version 5.1), an application written
  391. in august 1996. I'll crack here the Windows 3.1 version, for
  392. reasons explained in lesson 9.4, but you'll easily find the Win95
  393. version on the net, whose protection scheme works on the same
  394. lines.
  395. Link Check is a suite of three (3) diagnostic programs which
  396. allows the user to examine different areas of the system.
  397. 1) Link Check (WLCHECK.EXE) enables the user to view the links
  398. between an executable file and the modules it requires to run on
  399. the system.
  400. 2) Memory Check (WMCHECK.EXE) allows the user to view, load and
  401. unload modules currently in memory.
  402. 3) Function Check (WFCHECK.EXE) allows the user to view actual
  403. function calls inside modules.
  404. WLCHECK  EXE     40400 24/08/96    5:10
  405. WMCHECK  EXE     37104 18/08/96    5:10
  406. WFCHECK  EXE     45424 24/08/96    5:10
  407. WLCCOMM  DLL     46960 18/08/96    5:10
  408. KSLHOOKS DLL     29568 15/08/96    1:00
  409. The protection scheme inside this program allows a 21 days use
  410. of the program, then 'disables' it. Even in the first 21
  411. 'allowed' days there are some functions that are disabled,
  412. anyway. Another interesting feature of the protection scheme, is
  413. that once you register, an 'electronic key' will be created and
  414. sended to you in order to unlock Link Check for the full retail
  415. version (which, as usual, means that the shareware version you
  416. are using CAN be unlocked).
  417. Therefore this application:
  418. is TIME-LIMITED
  419. has been CRIPPLED
  420. has some DISABLED functions
  421. can be UNLOCKED.
  422. A wonderful world of cracking possibilities! Let's rub our hands!
  423. So much to find! So much to learn! Thanks, Karri Software Ltd!
  424. (100422.3521@compuserve.com)
  425. For these protection schemes we must use both the 'Winice' live
  426. approach and the 'dead listing' one. (both described elsewhere
  427. in my tutorial).
  428. Let's begin at the beginning, i.e. searching for strings inside
  429. the WLCHECK.EXE we'll find nothing.
  430. You'll soon realise that the protection scheme hides inside the
  431. two *.dll WLCCOMM.DLL & KSLHOOKS.DLL... the real problem, with
  432. this kind of protections, is that the 'modalities' to unlock it
  433. are not known, i.e., that you cannot just crack the unlock
  434. procedure itself, but you must reverse engineer the program long
  435. enough to find the 'switch' that fires your cracked 'unlock'
  436. procedure, in order to 'register' this program and in order to
  437. be able to use it ad libitum.
  438. What happens with time protections?
  439. The first problem for the protectionists is the tampering with
  440. the system date. Even a stupid user could set the system clock
  441. backwards in order to use a program of the CINDERELLA sort.
  442. Your target would be easily fooled by any stupid user if it did
  443. just set a variable [START_DATE] and then simply check the system
  444. time with something like
  445.      IF SystemTime > [START_DATE+30] then beggar off
  446.      ELSE OK
  447. Therefore (almost) all this program use some sort of 'diode'
  448. location. Like diodes, which let current through in only one
  449. direction, these locations can only grow... i.e, if you set the
  450. system time to 1 January 2000 and then run the program, it will
  451. throw you off, as expected, but even when you go back to your
  452. current year and date this will be 'remembered'...and the
  453. protection will NOT allow you any more to use the program even
  454. should you (theoretically) still have some free 'try me' days...
  455. your setting at year 2000 screwed up your license for ever.
  456.      IF SystemTime > [START_DATE+30] then [MARK_HERE]
  457.      ELSE continue
  458.      If [MARK_HERE] = TRUE then beggar off
  459.      ELSE OK
  460. Let's try altering the system date on our WLCHECK.EXE target...
  461. Woa! As I said... it does not work anymore.
  462.  
  463. It's fairly easy to get at this part through Winice: Just bpx
  464. WritePrivateProfileString (which is a very interesting function
  465. indeed) and then have a good look at the pointers: You'll quick
  466. find out that KSLHOOKS (Segment 0B) writes his own xCLSID value
  467. inside system.ini. The block of KSLHOOKS.DLL's code responsable
  468. for this is the following:
  469. 11.0569  9AE4013500  call    7:01E4   ;'Value' and 'SYSTEM.INI'
  470. 11.056E  83C408      add     sp, 8    ;adjusting stack
  471. 11.0571  8D843901    lea     ax, [si+0139]
  472. 11.0575  57          push    di
  473. 11.0576  50          push    ax         ;pushing 'xCLSID'
  474. 11.0577  8D46FA      lea     ax, [bp-06]
  475. 11.057A  16          push    ss
  476. 11.057B  50          push    ax         ;pushing 'Value'
  477. 11.057C  8D468A      lea     ax, [bp-76]
  478. 11.057F  16          push    ss
  479. 11.0580  50          push    ax    ;pushing '{6178-0503...}'
  480. 11.0581  8D46EE      lea     ax, [bp-12]
  481. 11.0584  16          push    ss
  482. 11.0585  50          push    ax         ;pushing 'SYSTEM.INI'
  483. 11.0586  9AFFFF0000  call    KERNEL.WRITEPRIVATEPROFILESTRING
  484. 11.058B  33C0        xor     ax, ax
  485. 11.058D  5E          pop     si
  486. 11.058E  5F          pop     di
  487. 11.058F  C9          leave
  488. 11.0590  CB          retf
  489.  
  490. The call to 7.01E4 fetches the strings 'Value' and 'SYSTEM.INI'
  491. which are 'hardwired' there byte by byte, for instance, 'INI' is
  492. fetched like this:
  493.   7.0234  26C6440749    mov     byte ptr es:[si+07], 49 ;I
  494.   7.0239  26C644084E    mov     byte ptr es:[si+08], 4E ;N
  495.   7.023E  26C6440949    mov     byte ptr es:[si+09], 49 ;I
  496.  
  497. What is really interesting in this part of the protection scheme,
  498. is that the function WritePrivateProfileString is one of the MOST
  499. COMMON functions used for this kind of protections, being the
  500. function normally used in order to 'keep track' inside an 'INI'
  501. file of the particular configuration of an application that the
  502. user has chosen... as a matter of fact this program creates an
  503. hidden WLCHECK.SWL file inside c:\windows where it writes its
  504. data, it also writes, through the above code,
  505.  
  506. [xCLSID]
  507. Value={0000006236-0017105173-6326000000}
  508. inside system.ini
  509.  
  510. and then it writes ANOTHER string inside the reg.dat 'register'
  511. of the windows directory. A short digression, about registrations
  512. in the reg.dat of the Windows directory. If you never had a look
  513. at the reg.dat file (wich you should not have only firing
  514. regedit.exe, but using the switch /v TROUGH THE COMMAND LINE
  515. run!) you are in for a big surprise. If you are used to install
  516. and de-install programs as much as I do, you'll be able to see,
  517. for instance, real BATTLES between big or widespread software
  518. packages (for instance Coreldraw and PaintShopPro) fought
  519. there... but you'll also find some cryptic messages like
  520. WB_10=VMWB20
  521.   FILTER = 000000000e
  522.   OPTION = 0000000005
  523.   TAG    = 0000001857
  524.   KEY    = 0000184F
  525. or, even more cryptic:
  526. VxDSettings = {0000006178-0419758349-4326000000}
  527. And this is actually our target, as you can see... the first
  528. thing you should know is that some protection schemes hyde the
  529. date checking part of their protection inside reg.dat.
  530. The above value is the 'ID' of our target, and the ciffer in the
  531. 'middle' varies with the date and with the passing of the time.
  532.      As we said, once the protection snaps, there is no 'normal'
  533. way to reinstall a working copy of the program, even substituting
  534. ALL the files with fresh ones and deleting the 'secret'
  535. WLCHECK.SWL will not help... in order to reinstall this program
  536. or to use it for the eternity (in 21 days chunks) you would have
  537. to do the following every time the limit snaps:
  538. A) regedit /v
  539.    delete key VxD
  540. B) edit system.ini
  541.    manually delete the block
  542. "[xCLSID]
  543.  Value={0000006236-0017105173-6326000000}"
  544. C) attrib c:\windows\wlcheck.swl -r -s -h
  545.    del c:\windows\wlcheck.swl
  546. D) reinstall everything anew and run 21 more days... clearly not
  547. a satisfactory solution, exspecially given the fact that some
  548. routines are disabled... therefore let's delve a little more
  549. inside this protection scheme... we'll find a much neater crack,
  550. you'll see... :=)
  551. Since the 'legitimate' user will get 'an electronic key' from the
  552. protectionists, there must exist, somewhere, a small menu of the
  553. kind 'Enter your electronic key, legitimate sucker'... we could
  554. find it searching with a little imagination (and/or zen) inside
  555. our listings, but in these cases, it's much more quicker a small
  556. run with WRT (Windows Resource Toolkit) by borland. Since we are
  557. already inside KSLHOOKS.DLL, let's begin with this one.
  558. Wrt loads kslhooks.dll and shows you immediatly that there are
  559. only three dialog items, the last one, tagged as 'dialog 503'
  560. represents the 'Unlock' little window: ('Please enter your key'),
  561. which has two buttons: OK (1) and Cancel (2). Let's use WRT
  562. 'ID_tagging' option: we'll immediatly fetch the ID number of the
  563. 'Please enter your key' field: 2035.
  564. 2035 dec is 7F3 hex, therefore we now just need to search 07F3
  565. inside our listing... and we land immediatly here:
  566.   6.00DE >8B760A             mov     si, [bp+0A]
  567.   6.00E1  FF760E             push    word ptr [bp+0E]
  568.   6.00E4  6A08               push    0008
  569.   6.00E6  9AFFFF0000         call    USER.GETWINDOWLONG
  570.   6.00EB  8946FC             mov     [bp-04], ax
  571.   6.00EE  8956FE             mov     [bp-02], dx
  572.   6.00F1  83FE01             cmp     si, 0001
  573.   6.00F4  7556               jne     014C
  574.   6.00F6  FF760E             push    word ptr [bp+0E]
  575.   6.00F9  68F307             push    07F3           ;HERE! ****
  576.   6.00FC  9AFFFF0000         call    USER.GETDLGITEM
  577.   6.0101  50                 push    ax
  578.   6.0102  8D4698             lea     ax, [bp-68]
  579.   6.0105  16                 push    ss
  580.   6.0106  50                 push    ax
  581.   6.0107  6A63               push    0063
  582.   6.0109  9AFFFF0000         call    USER.GETWINDOWTEXT
  583.   6.010E  8D4698             lea     ax, [bp-68]
  584.   6.0111  16                 push    ss
  585.  
  586. This block of code is part of an Exported function from
  587. kslhooks.dll: KSLHOOKPROC4 - Ord:0006h
  588. Here is the whole sequence:
  589.      :CALL_PLEASE_ENTER_ELECTROKEY
  590.      6.00DE >8B760A       mov     si, [bp+0A]
  591.      ...
  592.      6.00F9  68F307       push    07F3 ;HERE ***
  593. is called (being at 6.00DE) from
  594.      :ENTER 68
  595.      6.0082  C8680000     enter   0068, 00
  596.      ...
  597.      6.009B  7441         je      00DE  ;HERE ***
  598. which (being at 6.00082) is called from
  599.      :PUSH_82
  600.      6.000F  68FFFF          push    selector KSLHOOKPROC4
  601.      6.0012  688200          push    0082  ;HERE ***
  602.      6.0015  FF36200C        push    word ptr [0C20]
  603.      6.0019  9AFFFF0000      call    KERNEL.MAKEPROCINSTANCE
  604. Much interesting, but we are not yet there...
  605. let's see if we have other occurrences of our 7F3h instance
  606. (which, as we saw through WRT, corresponds to the 'Enter your
  607. Key' field of the 'Unlock' window). Yes, we have one more
  608. occurrence (always inside KSLHOOKS.DLL):
  609.  
  610.  4.030A >81FEF307    cmp   si, 07F3   ;HERE ***
  611.  4.030E  7515        jne   0325       ;don't care if not unlock
  612.  4.0310  FF760E      push  word ptr [bp+0E]  ;nID
  613.  4.0313  56          push  si         ;=7F3, =unlock, =hDlg
  614.  4.0314  9AFFFF0000  call  USER.ISDLGBUTTONCHECKED
  615.  4.0319  0BC0        or    ax, ax     ;mashed button?
  616.  4.031B  7408        je    0325       ;Yeah, jump...
  617.  4.031D  C45EFC      les   bx, [bp-04]
  618.  4.0320  2689B7B104  mov   es:[bx+04B1], si
  619.  4.0325 >83FE02      cmp   si, 0002   ;...here
  620.  
  621. Now, IsDlgButtonChecked is a 'typical' windows function with
  622. following structure:
  623.           UINT IsDlgButtonChecked(HWND hFlg, int nID)
  624. where the handle of the dialog box contaning the button control
  625. is specified in hDlg. The ID value of the desired button is
  626. passed in nID. For two-state buttons this function returns zero
  627. if the button is unchecked and non zero if it is checked, -1 if
  628. an error occurs.
  629. What else can we do?
  630. Let's search for the limit (21 days, that corresponds to 15h)
  631. inside our code. Well, we'll find two interesting occurrences
  632. inside the OTHER dll module: WLCCOMM.DLL:
  633.   :OCCURRENCE_1_OF_21_DAYS_LIMIT
  634.   1.3E25 >80BEFFFE15   cmp     byte ptr [bp-0101], 15 ;here***
  635.   1.3E2A  7403         je      3E2F  ;Please restart...
  636.   1.3E2C  E9B900       jmp     3EE8  ;xor ax and retf
  637. and now, look what we have immediately afterwards...
  638.   1.3E2F >FF760E       push    word ptr [bp+0E]
  639.   1.3E32  1E           push    ds
  640.   1.3E33  681306       push    0613 ;Please restart...
  641.   1.3E36  1E           push    ds
  642.   1.3E37  68EE05       push    05EE ;Retail version...
  643.   1.3E3A  6A40         push    0040
  644.   1.3E3C  9A90080000   call    USER.MESSAGEBOX
  645.   1.3E41  FF760E       push    word ptr [bp+0E]
  646.   1.3E44  6A01         push    0001
  647.   1.3E46  9AE03E0000   call    USER.ENDDIALOG
  648.   1.3E4B  E99A00       jmp     3EE8  ;xor ax and retf
  649.  
  650. Now, string 0613 is
  651. "Please restart the program for the reatil version to take
  652. effect"
  653. and string 05EE is
  654. "Retail version successfully unlocked"
  655. ...clearly we have found the part of the code where the user gets
  656. the appropriate message once he has digited the correct key
  657. inside the unlock window in KSLHOOKS.
  658. But let's use a little more our 'new' WRT approach. Examining the
  659. 'dialog' items through WRT, we'll see that inside WLCCOMM.DLL
  660. there are 'two' About Link check templates, a 'nice' one (for
  661. registered users) and a 'nag' one (for Cinderella's users).
  662. The nice one is WLCCOMM.DIALOG 130, and its second part reads
  663. 'This copy of Link check is licensed to'
  664. FIELD 1 = 603 (25bh)
  665. FIELD 2 = 604 (25Ch)
  666. The 'nag' one is WLCCOMM.DIALOG 131 and its second part reads
  667. 'UNREGISTERED Shareware notice...' with two buttons:
  668. 'How do I register' which is 601 (259h) and
  669. What do I get for it which is 602 (25ah).
  670. Well... let's have a look around our code... and here is
  671. (obviously) the relevant part of it inside WLCCOMM.DLL:
  672.  
  673.   1.3C60 >8B760E                   mov     si, [bp+0E]
  674.   1.3C63  FF7606                   push    word ptr [bp+06]
  675.   1.3C66  6AF4                     push    FFF4
  676.   1.3C68  9A8A1D0000               call    USER.GETWINDOWWORD
  677.   1.3C6D  56                       push    si
  678.   1.3C6E  685B02                   push    025B ;here***
  679.   1.3C71  9A803C0000               call    USER.GETDLGITEM
  680.   1.3C76  394606                   cmp     [bp+06], ax
  681.   1.3C79  7421                     je      3C9C
  682.   1.3C7B  56                       push    si
  683.   1.3C7C  685C02                   push    025C ;here***
  684.   1.3C7F  9ADA3C0000               call    USER.GETDLGITEM
  685.   1.3C84  394606                   cmp     [bp+06], ax
  686.   1.3C87  7413                     je      3C9C
  687.   1.3C89  FF760A                   push    word ptr [bp+0A]
  688.   1.3C8C  FF7608                   push    word ptr [bp+08]
  689.   1.3C8F  FF7606                   push    word ptr [bp+06]
  690.   1.3C92  6A01                     push    0001
  691.   1.3C94  9A08039E3D               call    KSLCONTROLCOLOR
  692.   1.3C99  E94E02                   jmp     3EEA
  693.  
  694. Whereby, here is the part for the shareware user:
  695.   1.3EA6 >81FE5902        cmp     si, 0259 ;How do I register?
  696.   1.3EAA  7513            jne     3EBF
  697.   1.3EAC  FF760E          push    word ptr [bp+0E]
  698.   1.3EAF  1E              push    ds
  699.   1.3EB0  688B06          push    068B
  700.   1.3EB3  6A01            push    0001
  701.   1.3EB5  6A00            push    0000
  702.   1.3EB7  687217          push    1772
  703.   1.3EBA  9AD43E0000      call    USER.WINHELP
  704.   1.3EBF >81FE5A02        cmp     si, 025A ;What do I get for it?
  705.   1.3EC3  7523            jne     3EE8
  706.   1.3EC5  FF760E          push    word ptr [bp+0E]
  707.   1.3EC8  1E              push    ds
  708.   1.3EC9  689706          push    0697
  709.   1.3ECC  6A01            push    0001
  710.   1.3ECE  6A00            push    0000
  711.   1.3ED0  687117          push    1771
  712.   1.3ED3  9AFFFF0000      call    USER.WINHELP
  713.   1.3ED8  EB0E            jmp     3EE8
  714.  
  715. and as you can easily see, here lays the 'working' for the two
  716. mushbuttons of the shareware version.
  717. Shareware starts at 1.3EA6 and will be called from here
  718.   1.3DB9 >81FE5802                 cmp     si, 0258
  719.   1.3DBD  7403                     je      3DC2
  720.   1.3DBF  E9E400                   jmp     3EA6
  721.  
  722. Unlocked version starts at 1.3C60 and will be called from here:
  723.  
  724.   1.3C3E  C8FE0400        enter   04FE, 00
  725.   1.3C42  57              push    di
  726.   1.3C43  56              push    si
  727.   1.3C44  1E              push    ds
  728.   1.3C45  B87938          mov     ax, selector 2:0000
  729.   1.3C48  8ED8            mov     ds, ax
  730.   1.3C4A  8B460C          mov     ax, [bp+0C]
  731.   1.3C4D  2D1900          sub     ax, 0019
  732.   1.3C50  740E            je      3C60 ;***here! UNLOCKED
  733.   1.3C52  2DF700          sub     ax, 00F7
  734.   1.3C55  7465            je      3CBC ;copyright, 1st part
  735.   1.3C57  48              dec     ax
  736.   1.3C58  7503            jne     3C5D ;(jmp 3EE8) out
  737.   1.3C5A  E94901          jmp     3DA6
  738.  
  739. Well... if [bp+0C] is 19 (dec25) then we'll jump to our unlocked
  740. routine?
  741.  
  742.                 ********************************************
  743.                 BELOW IS WORK FROM THE STUDENTS OF THE +HCU
  744.                           wlcheck for windows 3.1
  745.                 ********************************************
  746.  
  747. Well readers, this was the second +HCU lesson, as we got it at mid-February
  748. 1997. You'll see below the work of our unit on it (+gthorne wawes breaking,
  749.                     fravia+ following up and cleaning)
  750.  
  751. Starting with the nag screen, here is a silly fix for it that works on many programs
  752. that use windows resource windows (such as an about box) as the nag screen.
  753.  
  754. Load up the file with the nagscreen in it (as listed above) with WRT (I am using
  755. borland resource workshop - same program, different version) and delete it.
  756. I am serious; try it: it works!
  757.  
  758. save the .DLL and it recompiles the binary without the nagscreen.
  759. (Those borland people scare me sometimes)
  760. ---------------------------------------------------------
  761. Back to more serious work...
  762. Since we are learning methods here, this is where I get to go
  763. after individual parts of the protection and defeat them. I will
  764. work on finding the flag to register the program later, first I
  765. want to do a little digging.
  766.  
  767. Looking through our dead listing of kslhooks.dll:
  768.  
  769. Going through our lesson so far, our file included a file reference
  770. to SYSTEM.INI by means of a byte-at-a-time string creation rather
  771. than a full data statement
  772.  
  773. (Note: i do this sometimes to make it hard for simpletons to change
  774. my name in my programming
  775. ---but i at lest jumble the lines around so it isnt so obvious)
  776.  
  777. I will show you two ways of removing this particular hurdle, here is
  778. the first, and most obvious: (THE NULL TERMINATOR)
  779. ---------------------------------------------------------
  780. here is the full code from the disassembly:
  781. ---------------------------------------------------------
  782. :0007.01E3 90                     nop
  783. :0007.01E4 55                     push bp
  784. :0007.01E5 8BEC                   mov bp, sp
  785. :0007.01E7 57                     push di
  786. :0007.01E8 56                     push si
  787. :0007.01E9 8B7E06                 mov di, [bp+06]
  788. :0007.01EC 8B760A                 mov si, [bp+0A]
  789. :0007.01EF 8E4608                 mov es, [bp-08]
  790.  
  791. :0007.01F2 26C60556               mov byte ptr es:[di], 56              ;V
  792. :0007.01F6 26C6450161             mov byte ptr es:[di+01], 61   ;a
  793. :0007.01FB 26C645026C             mov byte ptr es:[di+02], 6C   ;l
  794. :0007.0200 26C6450375             mov byte ptr es:[di+03], 75   ;u
  795. :0007.0205 26C6450465             mov byte ptr es:[di+04], 65   ;e
  796. :0007.020A 26C6450500             mov byte ptr es:[di+05], 00   ; <00>    (end of string)
  797.  
  798. :0007.020F 8E460C                 mov es, [bp-0C]
  799.  
  800. :0007.0212 26C60453               mov byte ptr es:[si], 53              ;S
  801. :0007.0216 26C6440159             mov byte ptr es:[si+01], 59   ;Y
  802. :0007.021B 26C6440253             mov byte ptr es:[si+02], 53   ;S
  803. :0007.0220 26C6440354             mov byte ptr es:[si+03], 54   ;T
  804. :0007.0225 26C6440445             mov byte ptr es:[si+04], 45   ;E
  805. :0007.022A 26C644054D             mov byte ptr es:[si+05], 4D   ;M
  806. :0007.022F 26C644062E             mov byte ptr es:[si+06], 2E   ; .
  807. :0007.0234 26C6440749             mov byte ptr es:[si+07], 49   ;I
  808. :0007.0239 26C644084E             mov byte ptr es:[si+08], 4E   ;N
  809. :0007.023E 26C6440949             mov byte ptr es:[si+09], 49   ;I
  810. :0007.0243 26C6440A00             mov byte ptr es:[si+0A], 00   ;<00> (end of string)
  811.  
  812. :0007.0248 5E                     pop si
  813. :0007.0249 5F                     pop di
  814. :0007.024A C9                     leave
  815. :0007.024B CB                     retf
  816.  
  817. ---------------------------------------------------------------------------
  818.  
  819. to me this looks like an easy section to defeat - this because the full
  820. filename is here, and because it is in a standard string format
  821. terminating in hex zero (00) a.k.a.: NULL
  822.  
  823. as with programs with unencrypted passwords (yes even some programs
  824. you may use.. like X-WING have no encryption whatsoever - just try
  825. scanning FRONTEND.OVL for DANTOOINE with a hex editor, and all the
  826. passwords are sitting there for you to zero-out)
  827.  
  828. in other words, why bother disabling the function that calls this
  829. data when you can simply change each character in SYSTEM.INI to a
  830. hex zero
  831.  
  832. i did and just as i suspected, out of the three places that are
  833. causing us hassles, SYSTEM.INI, WLCHECK.SWL, and the registry (REG.DAT)
  834. I no longer have to deal with one of them
  835.  
  836. just run it, you will see: no more added line in system.ini
  837.  
  838. NOW FOR THE OTHER WAY:
  839. (This one is more useful for a cracker point of view since good
  840. protections tend to be smarter than letting you view filenames
  841. like we saw above)
  842.  
  843. This is where we go back to the WRITEPRIVATEPROFILESTRING function
  844. and check it out.
  845.  
  846. A text search of the dead listing reveals quickly:
  847.  
  848. :0011.0535 90                     nop
  849. :0011.0536 C8760000               enter 0076, 00
  850. :0011.053A 57                     push di
  851. :0011.053B 56                     push si
  852. :0011.053C 8B7606                 mov si, [bp+06]
  853. :0011.053F 33C0                   xor ax, ax
  854. :0011.0541 B93200                 mov cx, 0032
  855. :0011.0544 8D7E8A                 lea di, [bp-76]
  856. .
  857. .
  858. .
  859.  
  860. :0011.0584 16                     push ss
  861. :0011.0585 50                     push ax
  862. :0011.0586 9AFFFF0000             call KERNEL.WRITEPRIVATEPROFILESTRING
  863. :0011.058B 33C0                   xor ax, ax
  864. :0011.058D 5E                     pop si
  865. :0011.058E 5F                     pop di
  866. :0011.058F C9                     leave
  867. :0011.0590 CB                     retf
  868.  
  869. notice the end of the function and how it exits...
  870.  
  871. 5E      POP SI
  872. 5F      POP DI
  873. C9      LEAVE
  874. CB      RETF
  875.  
  876. In order to give the function a little meat to play with but still
  877. return early, lets insert this code right at the start of the function,
  878. right after push si.
  879.  
  880. :0011.0536 C8760000               enter 0076, 00
  881. :0011.053A 57                     push di
  882. :0011.053B 56                     push si
  883. :0011.053C 5E          pop si
  884. :0011.053D 5F          pop di
  885. :0011.053E C9          leave
  886. :0011.053F CB          retf
  887.  
  888. and it really works out, the function gets called, it starts, quits,
  889. and returns... veni, vidi, crakki.
  890.  
  891. a quick hex edit of the dll to alter this..
  892. searching for a good string to replace, we get 2 occurrances of:
  893.  
  894.      8b760633c0b93200
  895.  
  896. They are GETPRIVATEPROFILESTRING  and   WRITEPRIVATEPROFILESTRING  respectively.
  897. Go ahead and do the same damage that you did above to both of them. You will notice that
  898. they are very similar functions, with exactly the same method of beginning
  899. and ending.
  900.  
  901. so we can change both occurrances toto:
  902.      5e5fc9cbc0b93200
  903.  
  904. NOTE:
  905. This patch takes care of the system.ini change, so no need to do a
  906. zero-out of the file.
  907. It didnt do any good for the .swl file however, because does some
  908. other method of storing it's data.
  909. **********************************************
  910. Here is a little clue in how to find the other filenames that may be
  911. hidden in the file.
  912.  
  913. From the SYSTEM.INI example, which has a period (hex 2E) and a file
  914. extension, i knew to look for ", 2E" (COMMA SPACE 2E) in the text
  915. editor while reading kslhooks.alf
  916. i decided to give it another  whirl and see if there were any other
  917. surprises
  918.  
  919. Just looking for 2E will work, but you will find many occurrances of
  920. it in hex data, so it is best to try to differentiate it as much as
  921. possible for sanity reasons.
  922.  
  923. Apparently it bears fruit...
  924. --------------------------------------------------------------------------
  925. Here is the first block of code i landed in:
  926. --------------------------------------------------------------------------
  927. :0003.00B0 F3                     repz
  928. :0003.00B1 A5                     movsw
  929. :0003.00B2 13C9                   adc cx, cx
  930. :0003.00B4 F3                     repz
  931. :0003.00B5 A4                     movsb
  932. :0003.00B6 1F                     pop ds
  933. :0003.00B7 39460A                 cmp [bp+0A], ax       COMPARE AND JUMP...
  934. :0003.00BA 7516                   jne 00D2
  935.  
  936. :0003.00BC C646FA2E               mov byte ptr [bp-06], 2E      ; .     <----- A .SWL FILENAME EXTENSION
  937. :0003.00C0 C646FB53               mov byte ptr [bp-05], 53      ;S
  938. :0003.00C4 C646FC57               mov byte ptr [bp-04], 57      ;W
  939. :0003.00C8 C646FD4C               mov byte ptr [bp-03], 4C      ;L
  940. :0003.00CC 8846FE                 mov [bp-02], al
  941. :0003.00CF EB0E                   jmp 00DF
  942.  
  943. :0003.00D1 90                     nop
  944. :0003.00D2 8D7EFA                 lea di, [bp-06]
  945.  
  946. * Possible StringData Ref from Data Seg 013 ->".LIC"    <---- A NEW FILENAME EXTENSION ".LIC"
  947.                                   |
  948. :0003.00D5 BE1800                 mov si, 0018
  949.  
  950. --------------------------------------------------------------------------
  951. what it looks like to me is that WHEN registered, the
  952. .SWL file extension is replaced by a .LIC file extension
  953.  
  954. though changing the name of the SWL file to LIC
  955. does not seem to have any beneficial result at this time
  956.  
  957. it may once the other file checks have been disabled
  958. regardless, it is apparent that there is a file with a .LIC
  959. extension that gets created upon successfully registering
  960. this software
  961. --------------------------------------------------------------------------
  962. note that because there appears only once a .SWL reference in
  963. the KSLHOOKS.DLL, my guess is that if i hex-zero the .SWL like i
  964. did the SYSTEM.INI reference, it would not matter because the file
  965. write command and file read command apparently use the same
  966. string for their data. in other words, changing .SWL to anything,
  967. the file would just have a different name.
  968.  
  969. testing this out, i found that i was correct. hexing out .SWL with
  970. zeroes resulted in a file in my windows directory called WLCHECK
  971. with no extension, rather than .SWL (sometimes it would be nice if
  972. my theories wouldnt be quite so correct)
  973.  
  974. so we are at least in the ballpark, but no real improvements yet.
  975.  
  976. It is still going to take more looking to do anything with this yet
  977.  
  978. ----------------------------------------------------------
  979.  
  980. Now let's try for the registry...
  981. Scan the file for REG, and you will inveitable find quite a few
  982. registry commands. which are registry key edit functions.
  983.  
  984. :0011.033A C8300100               enter 0130, 00
  985. :0011.033E 57                     push di
  986. :0011.033F 56                     push si
  987.  
  988. :0011.0340 8B5E06                 mov bx, [bp+06]
  989. :0011.0343 8B4E08                 mov cx, [bp+08]
  990. :0011.0346 81C32D01               add bx, 012D
  991. :0011.034A 1E                     push ds
  992. :0011.034B 8BFB                   mov di, bx
  993. .
  994. .
  995. :0011.037D 9AFFFF0000             call SHELL.REGCREATEKEY
  996. .
  997. .
  998. and it ends JUST LIKE the previoous functions
  999. with a:
  1000.  
  1001. 5E      POP SI
  1002. 5F      POP DI
  1003. C9      LEAVE
  1004. CB      RETF
  1005.  
  1006. so we just hexedit the changes...
  1007.  
  1008. 2 occurrances of:
  1009.      010057568b5e068b
  1010.  
  1011. (regopenkey and regcreatekey respectively - feel free to
  1012. look for yourself in the dead listing)
  1013.  
  1014. it is just fine to change both to:
  1015.       010057565e5fc9cb
  1016.  
  1017. and just like in the case of the writeprivateprofilestring,
  1018. we have cracked the registry.
  1019.  
  1020. NOW -
  1021.  
  1022. 2 out of 3 of the hoops have been jumped
  1023. Now it is time to test the .SWL file and afterwards we will
  1024. deal with the NAG feature itself.
  1025.  
  1026. Here is where i get curious to see the differences in the
  1027. before and after... i want to see exactly what i have left
  1028. to conquer, and the resultant file differences in wlcheck.swl
  1029. BEFORE the 21 day date expires, and AFTER it expires.
  1030.  
  1031. I wrote a program a while back to datecrack stuff like this -
  1032. but as we already know, this program is a little smarter than
  1033. the average 'check today's date' type of protection.
  1034.  
  1035. The way my program (cdate.exe) works is relatively simple:
  1036. it alters the system date upon program  entry, and changes it
  1037. back to normal. The interesting thing about this is that it
  1038. allows future dates to be set as well as past ones since i
  1039. didnt care to put a block on WHICH dates could be set with it.
  1040.  
  1041. Note that this one works fine past midnight because it has a
  1042. calendar built in, so if you are to write one yourself
  1043. remember that when midnight comes and your calendar strangely
  1044. goes off  by a day every time you pass midnight while using a
  1045. datecracked program.
  1046.  
  1047. CDATE USAGE:
  1048. cdate  mm dd yyyy
  1049.  
  1050. So, since all that is left to crack is the swl file, i can
  1051. delete it with my handy RM command - which like all of
  1052. my little unix tools strips all attribs from the file
  1053. (ignores them really)...
  1054.  
  1055. rm c:\windows\wlcheck.swl
  1056.  
  1057. ...And i can run wlcheck.exe again (this time with false
  1058. future date)
  1059.  
  1060. cdate wlcheck 9 9 1999      (it's now 1997 so this works fine)
  1061.  
  1062. note the result: expired program!!!
  1063.  
  1064. exit wlcheck and try running it normally (no funky date this time)
  1065. guess what... STILL expired.
  1066. that means it records not only date info, but EXPIRED info as
  1067. well, exactely as +ORC said.
  1068.  
  1069. Do the little effect of RM C:\WINDOWS\WLCHECK.SWL again and run
  1070. wlcheck
  1071.  
  1072. It isn't expired now
  1073.  
  1074. That means that the ONLY recorder for 'expired software' is in that
  1075. file... doing a little dos file compare between a copy of the swl
  1076. file before, and after (the BAD one), here are my results
  1077. again i used CP.EXE to copy the swl file since it strips attribs
  1078. and i dont have to worry about them now.
  1079. -----------------------------------------------------------
  1080. C:\WLCHECK\>     FC WLCHECK.SWL WLCHECK.BAD
  1081.  
  1082. Comparing files wlcheck.swl and wlcheck.bad shows them to be quite
  1083. different (you can try this for yourself if you like)
  1084. ------------------------------------------------------------
  1085.  
  1086. There are a few ways we could go about this.
  1087. We could either try to make it so the 21 day period cannot
  1088. expire, or remove the command that records the info to the
  1089. file. In all honesty,  we will probably have to do both in
  1090. order to deprotect it completely.
  1091. **********************************************************
  1092.  
  1093. maybe we should do a little windows directory listing just
  1094. to see if there are any more surprises
  1095.  
  1096. dir /a c:\windows\wlc*
  1097.  
  1098. what do we see:
  1099. wlcheck.ini, wlcheck.ord, and wlcheck.swl
  1100.  
  1101. that is all fine, no more surprises yet (if you didnt expect
  1102. a wlcheck.ini file: WHY NOT?
  1103.  
  1104. if you edit wlcheck.ord, it is just your order blank from when
  1105. you filled out the wlcheck form nothing impressive, but at least
  1106. it has the product serial number listed at the bottom - sometimes
  1107. handy
  1108. *********************************************************
  1109. I cannot seem to find any more windows file commands, so i decided
  1110. to see if they had included in the dll their own file access commands
  1111. that means... look for int21
  1112.  
  1113. (there are a TON of int21 calls in this program! - and to think
  1114. that some people think that dos cracking is dead...)
  1115.  
  1116. these are the KSL file i/o and system functions, with direct
  1117. access to hardware through DOS.
  1118.  
  1119. upon searching for int21 calls - specifically int21 with ah=2a
  1120. b42a (mov ah, 2a) = get system date
  1121.  
  1122. I found 3 instances
  1123.  
  1124. 2 occurrances of:
  1125.  008C D89045558BEC1E8ED856 B42A
  1126.  
  1127. changed to
  1128.  00CB D89045558BEC1E8ED856 B42A
  1129.  
  1130. (CB = retf)
  1131.  
  1132. an interesting thing happens, on the first run, it works fine,
  1133. writes the .swl file, and goes on it's merry way
  1134.  
  1135. on any subsequent runs, it says expired
  1136. that tells me that the changes i made, set the date to a nothing value
  1137. in the wlcheck.swl file
  1138.  
  1139. in easier to understand lingo, i hit the nail on the head.
  1140. i found the date checker - in old int21 style.
  1141.  
  1142. if you wish to play with this more yourself, go ahead. by all means.
  1143.  
  1144. i still havent worried with the 3rd date check, which is the hex string:
  1145.   9045558BEC1E8ED856 B42A
  1146.  
  1147. About this time, I begin to think - maybe there is a better way...
  1148. (I have gotten a bit tired of playing around, and I want to fully crack it)
  1149. ----------------------------------------------------------
  1150. Now we get down to the nitty gritty.
  1151.  
  1152. The above is necessary work.. handy for other protection schemes.
  1153. It is, however, not incredibly useful here in this one. If you run wlcheck
  1154. or one of the other executables, you will notice something frustrating:
  1155. you cannot print. Only registered users get that option. That means we
  1156. either have to crack more functions, like above, or just go ahead and
  1157. register the thing and get it over with.
  1158.  
  1159. So we shall.
  1160. ------------------------------------------------------------
  1161. Time to go into the WLCCOMM.DLL...
  1162.  
  1163. remember how i said +ORC mentioned 2 occurrances of 15 that were interesting?
  1164. i search for " 15" (a space in front so it didn't get every 15 in the
  1165. wsccomm file listing)
  1166.  
  1167. i didnt find what i wanted other than the original one, so i looked for 0015
  1168. and i found one that looked promising..
  1169.  
  1170. :0001.3F5D C786E7FB1500           mov word ptr [bp-0419], 0015
  1171. :0001.3F63 B001                   mov al, 01
  1172. :0001.3F65 8886CEFB               mov [bp+FBCE], al
  1173. :0001.3F69 8886E9FB               mov [bp+FBE9], al
  1174. :0001.3F6D 8886EAFB               mov [bp+FBEA], al
  1175. :0001.3F71 C68648FC15             mov byte ptr [bp-03B8], 15
  1176.  
  1177. (I must remember to check for bgoth from now on)
  1178.  
  1179. just below all that, i saw something strange...
  1180. several 'set value to 1' - in other words, it looks like we see a bunch
  1181. of flags
  1182.  
  1183. changing the below statement to 00 returns this error: this is an old
  1184. version (and quits) - not extremely useful, but a green light shall we say.
  1185.  
  1186. :0001.3F63 B001                   mov al, 01
  1187. :0001.3F65 8886CEFB               mov [bp-0432], al
  1188. :0001.3F69 8886E9FB               mov [bp-0417], al
  1189. :0001.3F6D 8886EAFB               mov [bp-0416], al
  1190.  
  1191. going further down...
  1192. we have a comparison (in the form of an 'OR')
  1193.  
  1194. :0001.3F86 9AFFFF0000             call KSLHOOKS.Ord{0038h}
  1195.  
  1196. :0001.3F8B 8BF8                   mov di, ax    <--- backing up ax
  1197.  
  1198.   This program apparently wants to save whatever came out of the strange
  1199.    kslhooks call above before making this compare...
  1200.  
  1201. :0001.3F8D 0BF8                   or di, ax     <--- COMPARE BOTH
  1202.  
  1203.   Note the special nature of this compare.. since both values are
  1204.   the same, it is basically the same as saying if ax is zero, it
  1205.   stays zero, if it is not, it becomes a 1 since the result of any
  1206.   compare is stored in ax
  1207.  
  1208.   di still has the saved value in it however... for future use by the program
  1209.   as you will see below, it is flag containing error codes
  1210.  
  1211. :0001.3F8F 750F                   jne 3FA0      <--- FIRST JUMP IF NONZERO
  1212.  
  1213.   This smells to me like a 'beggar off jerk'...
  1214.   (i already know what i have here, do you?)
  1215.  
  1216. :0001.3F91 B80100                 mov ax, 0001  <--- SET A FLAG?!?
  1217.  
  1218.   This just gets better and better, but i still look before i try anything,
  1219.   I don't want to jump the gun and assume anything without proof...
  1220.  
  1221. :0001.3F94 C45E06                 les bx, [bp+06]
  1222. :0001.3F97 268987A400             mov es:[bx+00A4], ax
  1223.  
  1224. :0001.3F9C E9D600                 jmp 4075      <--- 2nd JMP
  1225. :0001.3F9F 90                     nop
  1226.  
  1227.   HERE is where jmp 1 takes me...
  1228.  
  1229. :0001.3FA0 8B760A                 mov si, [bp+0A]
  1230. :0001.3FA3 83FF0A                 cmp di, 000A
  1231. :0001.3FA6 7510                   jne 3FB8
  1232. :0001.3FA8 56                     push si
  1233. :0001.3FA9 1E                     push ds
  1234.  
  1235. * StringData Ref from Data Seg 002 ->"An upgrade is required.
  1236.                                         Continuing as shareware only."
  1237.                                   |
  1238. :0001.3FAA 68CF06                 push 06CF
  1239.  
  1240.   AND WOULD YOU LOOK AT THAT EVIL MESSAGE!
  1241.   it is very clear that the beggar off guess was correct...
  1242.  
  1243. just go down a few lines and you will see ALL SORTS of nasty
  1244. error messages, including the shareware expiry message we get
  1245. when we try to run after 21 days (note that it would have been
  1246. much easier had we scanned the text for keywords like shareware,
  1247. reg, exp, or others we could imagine... but that would not work
  1248. with all programs, and we are here to learn how to crack ALSO
  1249. protections that do not do us the favour of carrying their doom
  1250. inside... therefore the approach above is much more solide :-)
  1251.  
  1252. paging down a little we see this at the location JMP 2 sent us at 4075...
  1253.  
  1254. :0001.4075 1F                     pop ds
  1255. :0001.4076 5E                     pop si
  1256. :0001.4077 5F                     pop di
  1257. :0001.4078 C9                     leave
  1258. :0001.4079 CA0600                 retf 0006
  1259.  
  1260. it just quits... but if you remember up above, it set a flag before it
  1261. did so!
  1262.  
  1263. now how do we get it to ignore those nasty error messages and we ALWAYS
  1264. jump to 4075 with the flag set?
  1265.  
  1266. looking back at our decision code from above:
  1267.  
  1268. :0001.3F86 9AFFFF0000             call KSLHOOKS.Ord{0038h}
  1269.  
  1270. :0001.3F8B 8BF8                   mov di, ax
  1271. :0001.3F8D 0BF8                   or di, ax
  1272. :0001.3F8F 750F                   jne 3FA0      <---- evil jump
  1273.  
  1274. :0001.3F91 B80100                 mov ax, 0001
  1275. :0001.3F94 C45E06                 les bx, [bp+06]
  1276. :0001.3F97 268987A400             mov es:[bx+00A4], ax
  1277. :0001.3F9C E9D600                 jmp 4075      <---- good jump
  1278.  
  1279. notice the jne? there are quite a few ways of attacking this, but think
  1280. about it, there are a few things that must be done.
  1281.  
  1282. first, the jne could be changed to a je (or jz) but if we do that, we
  1283. have to WAIT 21 days to be able to use the program, or screw up the date
  1284. at install, or something dumb like that (not a good crack)
  1285.  
  1286. if AX is set to anything, it is deemed an error by the program and the error
  1287. code is saved in DI. So we need to make sure ax is zero, and it might be
  1288. smart to cover our bases and set di to zero as well (you never know if some
  1289. value had been sitting in it to be confused as an error for our crazy
  1290. program wlcheck to find and complain about)
  1291.  
  1292. so if we set both to zero, then the jne CANNOT ever jump out and we stay long
  1293. enough for us to set the AX flag and go along happily.
  1294.  
  1295. it just so happens that there is a simple way to set any variable to zero
  1296. (if you are familiar with assembly, ignore this, i am putting this in
  1297. here for those who havent become as familiar with it as the rest of us -
  1298. this is a tutorial after all isnt it?)
  1299.  
  1300. xor ax, ax                <---  sets ax to zero
  1301. xor di, di                <---  sets di to zero
  1302.  
  1303. if you are lazy like i am, you can search your dead listing for both
  1304. (the listing is so large, that you can probably find examples of many byte
  1305. values that you need)
  1306.  
  1307. it turns out that the values are:
  1308.  
  1309. 33 C0        xor ax, ax
  1310. 33 FF        xor di, di
  1311.  
  1312. and here's how our code will look:
  1313.  
  1314. :0001.3F86 9AFFFF0000             call KSLHOOKS.Ord{0038h}
  1315.  
  1316. :0001.3F8B 33C0                   xor ax, ax
  1317. :0001.3F8D 33FF                   xor di, di
  1318.  
  1319. :0001.3F8F 750F                   jne 3FA0
  1320.  
  1321. :0001.3F91 B80100                 mov ax, 0001
  1322. :0001.3F94 C45E06                 les bx, [bp+06]
  1323. :0001.3F97 268987A400             mov es:[bx+00A4], ax
  1324. :0001.3F9C E9D600                 jmp 4075
  1325.  
  1326. simply enough, now we just need to make the changes in the wlccomm.dll
  1327.  
  1328. *****************************************************
  1329.  
  1330. Crack for 16-bit wlcheck by +gthorne of the +HCU:
  1331.  
  1332. pop into your favorite hex editor and load WLCCOMM.DLL
  1333. (File Size: 46,960 bytes)
  1334.  
  1335. search for byte pattern:
  1336.   8BF80BF8750F
  1337.  
  1338. replace with:
  1339.   33C033FF750F
  1340.  
  1341. and run it...
  1342. it is registered!
  1343. ----------------------------------------------------------
  1344. Note for showoffs:
  1345.  
  1346. If you wish it to say that it is registered to you, go to
  1347. the about box, and run the "registration" part of the program
  1348. BEFORE you crack it, entering data in the order form as you
  1349. want it to be registered.
  1350.  
  1351. The target stores this info in the windows directory, in
  1352. the file: WLCHECK.ORD.
  1353. After cracking, that info is displayed proudly in the about box.
  1354. *****************************************************
  1355.  
  1356. None of the many changes listed at the beginning of this
  1357. section are necessary now, not since we have a good, clean
  1358. crack.
  1359. Don't disregard the work though, some programs I've seen are
  1360. defeatable with the kind of work done before the register flag
  1361. was found.
  1362.  
  1363. If this were a program with no flag to register, it would have
  1364. REQUIRED all that work anyway, and then some.
  1365.  
  1366. ********************************************
  1367. wlcheck for windows 95
  1368. ********************************************
  1369.  
  1370. Ok, building on my fellow +cracker's good work it was
  1371. pretty easy to defeat the Win'95 protection, which follows
  1372. the same lines as the 16 bit one above... I lost
  1373. some time on a stupid beta version of wlcheck for win 95,
  1374. that I had inside my collection though... how stupid.
  1375. This will teach me to ALWAYS work methodically.
  1376. Therefore:
  1377. FIRST OF ALL
  1378. perform an archie or ftp search for wlck95, you'll find a
  1379. whole bunch of servers carrying it, choose a ftp-server
  1380. near you and get it ftpmailed to you or download it (as
  1381. you prefer).
  1382. You'll soon find all the relevant data:
  1383. WLCHK955.ZIP 213.156 bytes
  1384.  
  1385. SECOND
  1386. You have it, unzip it and examine it:
  1387. FILE_ID  DIZ           438  23/08/96   5:10 FILE_ID.DIZ
  1388. WLCHK95  EXE        70.656  23/08/96   5:10 WLCHK95.EXE
  1389. KSLHKS95 DLL        52.224  21/08/96   1:00 KSLHKS95.DLL
  1390. WMCHK95  EXE        63.488  23/08/96   5:10 WMCHK95.EXE
  1391. WLCHK95  HLP        33.759  23/08/96   5:10 WLCHK95.HLP
  1392. WFCHK95  EXE        77.824  23/08/96   5:10 WFCHK95.EXE
  1393. WMCHK95  HLP        32.463  23/08/96   5:10 WMCHK95.HLP
  1394. WFCHK95  HLP        29.696  23/08/96   5:10 WFCHK95.HLP
  1395. README   TXT         8.689  23/08/96   5:10 README.TXT
  1396. WLCCOM95 DLL        73.216  26/03/97  20:11 WLCCOM95.DLL
  1397.  
  1398. (ignore the date of the last dll, that's just because I tampered
  1399. with it yesterday).
  1400.  
  1401. THIRD
  1402. Using what we have learned (quite a lot) let's work on
  1403. wlccom95.dll: here the relevant part of the dead listing:
  1404.  
  1405. * Referenced by a    Jump at Address:|:1C005B50(C)
  1406. |
  1407. :1C005B76 C685C3FBFFFF05          mov byte ptr [ebp+FFFFFBC3], 05
  1408. :1C005B7D C685C4FBFFFF01          mov byte ptr [ebp+FFFFFBC4], 01
  1409. :1C005B84 66C785DDFBFFFF1500      mov word ptr [ebp+FFFFFBDD], 0015
  1410. :1C005B8D C685DFFBFFFF01          mov byte ptr [ebp+FFFFFBDF], 01
  1411. :1C005B94 C685E0FBFFFF01          mov byte ptr [ebp+FFFFFBE0], 01
  1412. :1C005B9B C6853EFCFFFF15          mov byte ptr [ebp+FFFFFC3E], 15
  1413. :1C005BA2 8B450C                  mov eax, [ebp+0C]
  1414. :1C005BA5 66C780A80000000000      mov word ptr [ebx+000000A8], 0000
  1415. :1C005BAE 8D8598FAFFFF            lea eax, [ebp+FFFFFA98]
  1416. :1C005BB4 50                      push eax
  1417.  
  1418. * Reference To: kslhks95._KslHookProc1@4, Ord:0000h
  1419.                                   |
  1420. :1C005BB5 E872420000              Call 1C009E2C
  1421. :1C005BBA 66894598                mov [ebp-68], ax
  1422. :1C005BBE 0FBF4598                movsx word ptr eax, [ebp-68]
  1423. :1C005BC2 85C0                    test eax, eax
  1424. :1C005BC4 0F8516000000            jne 1C005BE0
  1425. :1C005BCA 8B450C                  mov eax, [ebp+0C]
  1426. :1C005BCD 66C780A80000000100      mov word ptr [ebx+000000A8], 0001
  1427. :1C005BD6 B801000000              mov eax, 00000001
  1428. :1C005BDB E946010000              jmp 1C005D26
  1429.  
  1430. * Referenced by a    Jump at Address: |:1C005BC4(C)
  1431. |
  1432. :1C005BE0 0FBF4598                movsx word ptr eax, [ebp-68]
  1433. :1C005BE4 83F80A                  cmp eax, 0000000A
  1434. :1C005BE7 0F8516000000            jne 1C005C03
  1435. :1C005BED 6A40                    push 00000040
  1436.  
  1437. * Possible StringData Ref from Data Obj ->"License Expired"
  1438.                                   |
  1439. :1C005BEF 6828E8001C              push 1C00E828
  1440.  
  1441. * Possible StringData Ref from Data Obj ->"An upgrade is required. Continuing "
  1442.                                         ->"as shareware only."
  1443.                                   |
  1444. :1C005BF4 6838E8001C              push 1C00E838
  1445. :1C005BF9 8B4508                  mov eax, [ebp+08]
  1446. :1C005BFC 50                      push eax
  1447.  
  1448. * Reference To: USER32.MessageBoxA, Ord:0188h
  1449.                                   |
  1450. :1C005BFD FF151C04011C            Call dword ptr [1C01041C]
  1451.  
  1452. * Referenced by a    Jump at Address:|:1C005BE7(C)
  1453. |
  1454. :1C005C03 0FBF4598                movsx word ptr eax, [ebp-68]
  1455. :1C005C07 83F807                  cmp eax, 00000007
  1456. :1C005C0A 0F8516000000            jne 1C005C26
  1457. :1C005C10 6A40                    push 00000040
  1458.  
  1459. * Possible StringData Ref from Data Obj ->"License Violated"
  1460.                                   |
  1461. :1C005C12 6870E8001C              push 1C00E870
  1462.  
  1463. * Possible StringData Ref from Data Obj ->"The license file has been changed. "
  1464.                                         ->"Continuing as shareware only."
  1465.                                   |
  1466. :1C005C17 6884E8001C              push 1C00E884
  1467. :1C005C1C 8B4508                  mov eax, [ebp+08]
  1468. :1C005C1F 50                      push eax
  1469.  
  1470. * Reference To: USER32.MessageBoxA, Ord:0188h
  1471.                                   |
  1472. :1C005C20 FF151C04011C            Call dword ptr [1C01041C]
  1473.  
  1474. * Referenced by a    Jump at Address:|:1C005C0A(C)
  1475. |
  1476. :1C005C26 0FBF4598                movsx word ptr eax, [ebp-68]
  1477. :1C005C2A 83F808                  cmp eax, 00000008
  1478. :1C005C2D 0F8516000000            jne 1C005C49
  1479. :1C005C33 6A40                    push 00000040
  1480.  
  1481. * Possible StringData Ref from Data Obj ->"License Violated"
  1482.                                   |
  1483. :1C005C35 68C8E8001C              push 1C00E8C8
  1484.  
  1485. * Possible StringData Ref from Data Obj ->"This seems to be an unlicensed "
  1486.                                         ->"copy. Continuing as shareware "
  1487.                                         ->"only."
  1488.                                   |
  1489. :1C005C3A 68DCE8001C              push 1C00E8DC
  1490. :1C005C3F 8B4508                  mov eax, [ebp+08]
  1491. :1C005C42 50                      push eax
  1492.  
  1493. * Reference To: USER32.MessageBoxA, Ord:0188h
  1494.                                   |
  1495. :1C005C43 FF151C04011C            Call dword ptr [1C01041C]
  1496.  
  1497. * Referenced by a    Jump at Address:|:1C005C2D(C)
  1498. |
  1499. :1C005C49 8D8598FAFFFF            lea eax, [ebp+FFFFFA98]
  1500. :1C005C4F 50                      push eax
  1501.  
  1502. * Reference To: kslhks95._KslHookProc2@4, Ord:0001h
  1503.                                   |
  1504. :1C005C50 E8D1410000              Call 1C009E26
  1505. :1C005C55 66894598                mov [ebp-68], ax
  1506. :1C005C59 33C0                    xor eax, eax
  1507. :1C005C5B 8A853EFCFFFF            mov al , [ebp+FFFFFC3E]
  1508. :1C005C61 83F80D                  cmp eax, 0000000D
  1509. :1C005C64 0F8536000000            jne 1C005CA0
  1510.  
  1511. * Possible StringData Ref from Data Obj ->"Link Check evaluation license "
  1512.                                         ->"has expired."
  1513.                                   |
  1514. :1C005C6A 6820E9001C              push 1C00E920
  1515. :1C005C6F 8D459C                  lea eax, [ebp-64]
  1516. :1C005C72 50                      push eax
  1517. :1C005C73 E871030000              call 1C005FE9
  1518. :1C005C78 83C408                  add esp, 00000008
  1519. :1C005C7B 6A10                    push 00000010
  1520.  
  1521. * Possible StringData Ref from Data Obj ->"License Expiry"
  1522.                                   |
  1523. :1C005C7D 684CE9001C              push 1C00E94C
  1524. :1C005C82 8D459C                  lea eax, [ebp-64]
  1525. :1C005C85 50                      push eax
  1526. :1C005C86 8B4508                  mov eax, [ebp+08]
  1527. :1C005C89 50                      push eax
  1528.  
  1529. * Reference To: USER32.MessageBoxA, Ord:0188h
  1530.                                   |
  1531. :1C005C8A FF151C04011C            Call dword ptr [1C01041C]
  1532. :1C005C90 8B450C                  mov eax, [ebp+0C]
  1533. :1C005C93 50                      push eax
  1534. :1C005C94 E857E3FFFF              call 1C003FF0
  1535. :1C005C99 33C0                    xor eax, eax
  1536. :1C005C9B E986000000              jmp 1C005D26
  1537.  
  1538. * Referenced by a    Jump at Address:|:1C005C64(C)
  1539. |
  1540. :1C005CA0 0FBF4598                movsx word ptr eax, [ebp-68]
  1541. :1C005CA4 83F804                  cmp eax, 00000004
  1542. :1C005CA7 0F8536000000            jne 1C005CE3
  1543.  
  1544. * Possible StringData Ref from Data Obj ->"This is an old version,"
  1545.                                   |
  1546. :1C005CAD 685CE9001C              push 1C00E95C
  1547. :1C005CB2 8D459C                  lea eax, [ebp-64]
  1548. :1C005CB5 50                      push eax
  1549. :1C005CB6 E82E030000              call 1C005FE9
  1550. :1C005CBB 83C408                  add esp, 00000008
  1551. :1C005CBE 6A10                    push 00000010
  1552.  
  1553. * Possible StringData Ref from Data Obj ->"License Violation"
  1554.                                   |
  1555. :1C005CC0 6874E9001C              push 1C00E974
  1556. :1C005CC5 8D459C                  lea eax, [ebp-64]
  1557. :1C005CC8 50                      push eax
  1558. :1C005CC9 8B4508                  mov eax, [ebp+08]
  1559. :1C005CCC 50                      push eax
  1560.  
  1561. * Reference To: USER32.MessageBoxA, Ord:0188h
  1562.                                   |
  1563. :1C005CCD FF151C04011C            Call dword ptr [1C01041C]
  1564. :1C005CD3 8B450C                  mov eax, [ebp+0C]
  1565. :1C005CD6 50                      push eax
  1566. :1C005CD7 E814E3FFFF              call 1C003FF0
  1567. :1C005CDC 33C0                    xor eax, eax
  1568. :1C005CDE E943000000              jmp 1C005D26
  1569.  
  1570. * Referenced by a    Jump at Address:|:1C005CA7(C)
  1571. |
  1572. :1C005CE3 0FBF4598                movsx word ptr eax, [ebp-68]
  1573. :1C005CE7 85C0                    test eax, eax
  1574. :1C005CE9 0F8D2D000000            jnl 1C005D1C
  1575.  
  1576. * Possible StringData Ref from Data Obj ->"An unexpected error has occurred."
  1577.                                   |
  1578. :1C005CEF 6888E9001C              push 1C00E988
  1579. :1C005CF4 8D459C                  lea eax, [ebp-64]
  1580. :1C005CF7 50                      push eax
  1581. :1C005CF8 E8EC020000              call 1C005FE9
  1582. :1C005CFD 83C408                  add esp, 00000008
  1583. :1C005D00 6A10                    push 00000010
  1584.  
  1585. * Possible StringData Ref from Data Obj ->"System Error"
  1586.                                   |
  1587. :1C005D02 68ACE9001C              push 1C00E9AC
  1588. :1C005D07 8D459C                  lea eax, [ebp-64]
  1589. :1C005D0A 50                      push eax
  1590. :1C005D0B 8B4508                  mov eax, [ebp+08]
  1591. :1C005D0E 50                      push eax
  1592.  
  1593. * Reference To: USER32.MessageBoxA, Ord:0188h
  1594.                                   |
  1595. :1C005D0F FF151C04011C            Call dword ptr [1C01041C]
  1596. :1C005D15 33C0                    xor eax, eax
  1597. :1C005D17 E90A000000              jmp 1C005D26
  1598.  
  1599. * Referenced by a    Jump at Address:|:1C005CE9(C)
  1600. |
  1601. :1C005D1C B801000000              mov eax, 00000001
  1602. :1C005D21 E900000000              jmp 1C005D26
  1603.  
  1604. * Referenced by a    Jump at Addresses:|:1C005BDB(U),
  1605. :1C005C9B(U), :1C005CDE(U), :1C005D17(U), :1C005D21(U)
  1606. |
  1607. :1C005D26 5F                      pop edi
  1608. :1C005D27 5E                      pop esi
  1609. :1C005D28 5B                      pop ebx
  1610. :1C005D29 C9                      leave
  1611. :1C005D2A C20800                  ret 0008
  1612. *******************************************
  1613. OK! let's crack...
  1614. Well it's all pretty obvious:
  1615. After having prepared the call with a lot of parameters
  1616.  
  1617. :1C005B76 C685C3FBFFFF05          mov byte ptr [ebp+FFFFFBC3], 05
  1618. :1C005B7D C685C4FBFFFF01          mov byte ptr [ebp+FFFFFBC4], 01
  1619. :1C005B84 66C785DDFBFFFF1500      mov word ptr [ebp+FFFFFBDD], 0015
  1620. :1C005B8D C685DFFBFFFF01          mov byte ptr [ebp+FFFFFBDF], 01
  1621. :1C005B94 C685E0FBFFFF01          mov byte ptr [ebp+FFFFFBE0], 01
  1622. :1C005B9B C6853EFCFFFF15          mov byte ptr [ebp+FFFFFC3E], 15
  1623.  
  1624. note the two x15 parameters... that will of course be the 21
  1625. days limit... well, our target calls the kslhks95._KslHookProc1@4
  1626. function with all its params and upon return the 32 bit version
  1627. uses the SAME protection scheme used in the 16 bit one: it has an
  1628. "evil" and a "good" jump:
  1629.  
  1630. * Reference To: kslhks95._KslHookProc1@4, Ord:0000h
  1631.                                   |
  1632. :1C005BB5 E872420000              Call 1C009E2C
  1633. :1C005BBA 66894598                mov [ebp-68], ax
  1634. :1C005BBE 0FBF4598                movsx word ptr eax, [ebp-68]
  1635. :1C005BC2 85C0                    test eax, eax  ;is it zero?
  1636. :1C005BC4 0F8516000000    EVIL    jne 1C005BE0  ;not 0: bagger off
  1637. :1C005BCA 8B450C                  mov eax, [ebp+0C]
  1638. :1C005BCD 66C780A80000000100      mov word ptr [ebx+000000A8], 0001 ;OK, guy
  1639. :1C005BD6 B801000000              mov eax, 00000001 ;eat another good flag
  1640. :1C005BDB E946010000      HOLY    jmp 1C005D26      ;and be happy for ever
  1641.  
  1642. if you throw another look at the listing you'll see all the nasty
  1643. messages following the evil jump
  1644. * Referenced by a    Jump at Address: |:1C005BC4(C)
  1645. |
  1646. :1C005BE0 0FBF4598                movsx word ptr eax, [ebp-68]
  1647. :1C005BE4 83F80A                  cmp eax, 0000000A
  1648.  
  1649. and the subsequent compare eax ARE intersting, they give
  1650. you an exact look upon the inner working of our target:
  1651. here
  1652. eax=A means "License expired"
  1653. eax=7 means "License violated" (changed)
  1654. eax=8 means "License violated" (unlicensed)
  1655. eax=4 means "old version" etcetera...
  1656. as a matter of fact it may well be that the crack we
  1657. made goes crazy after 21 days (it won't if you push
  1658. the date around, we checked) use... in that case it
  1659. will be only a question of "fine tuning" of this crack,
  1660. and you already know where the relevant protection scheme
  1661. dwells... We do not want to wait 21 days just to be
  1662. absolutely sure that the crack works perfectly... so it
  1663. seems, and so it should be... should it have another
  1664. check somewhere (that I do not see now), I promise you
  1665. that you'll find the crack for it in three weeks time,
  1666. but I'm pretty sure you will not need it :-)
  1667.  
  1668. Well, we learned a lot:
  1669. Time/Disabling protections may vary a lot, but even in
  1670. apparently very complicated schemes (like the wlcheck one),
  1671. wich do tamper with a lot of more or less hidden files,
  1672. there can be a very simple "hollow" point, where you
  1673. can cut mustard with a neat targeted crack... you need to
  1674. understand and to "feel" a little the program, though, and
  1675. I'm now beginning to understand what +ORC means with his
  1676. zen mystique of "feeling" the code.
  1677. So here is the simple crack for wlcheck 32 bits:
  1678.  
  1679. search for
  1680.  
  1681. :1C005BC2 85C0                    test eax, eax
  1682. :1C005BC4 0F8516000000            jne 1C005BE0
  1683. :1C005BCA 8B450C                  mov eax, [ebp+0C]
  1684. :1C005BCD 66C780A80000000100      mov word ptr [ebx+000000A8], 0001
  1685.  
  1686. 85C00F8516000000
  1687. and at the third occurrence of it
  1688. (well, if you want -instead of searching the third occurrence of that
  1689. string- to type a long string... then search directly for the whole set
  1690. 85C00F85160000008B450C66C780A80000000100) do as you like, as far as
  1691. you land where you should:
  1692.         :1C005BC2 85C0                    test eax, eax
  1693.         :1C005BC4 0F8516000000            jne 1C005BE0
  1694. it's the time to crack your target! Noop the first 8 bytes out,
  1695. that is from 85C0 until the three subsequent zeros of instruction
  1696. :1C005BC2 ... you may even use the nop=90x instruction like the
  1697. lamers if you fancy... here there is absolutely no checking-protection
  1698. that examine eventual patchings... noop as you like.
  1699. ***************************************
  1700. Thinking about it we believe that the aim of this first lesson of
  1701. the "4" series from +ORC was the following: +he found an apparently
  1702. overcomplicated protection only to show us that, hidden behind
  1703. everything, a single neat crack was needed... as the fellow +cracker
  1704. of the 16 bit version observed, +he gave us a single (but decisive)
  1705. hint: he spoke about the second occurrence of the 15x byte, which
  1706. proved decisive -as you already did read- in individuating the
  1707. "hollow" point of our target.
  1708. As this lesson 4.1 was intended as second "+HCU" lesson, we believe
  1709. (and hope) that in finding the neat cracks for the 16 and the 32 bit
  1710. versions of wlcheck (which is a damn useful program in our trade, btw)
  1711. we have accomplished our task.
  1712. Now a question arises:
  1713. Should really all time protections be variations of this scheme?
  1714. (we do not know... we are awaiting the next "4" lesson of +ORC
  1715. like everybody else). In that case there is not a single program
  1716. (now) able to elude us :-)
  1717.  
  1718. And here a last "mysterious" snippet from +ORC's original 4.1, we did not
  1719. figure out its exact meaning... should we have seeked and found and cracked
  1720. the program(s) it refers to? Who knows? Sometime +his hidden messages are
  1721. impossible to decipher :-(
  1722.  
  1723.                 ********************************************
  1724.                 ABOVE IS WORK FROM THE STUDENTS OF THE +HCU
  1725.                           wlcheck for windows 3.1
  1726.                 ********************************************
  1727.  
  1728. Another system: inside win.ini:
  1729. [License]
  1730. Installed=854824551
  1731. Expires=857416551
  1732. LastUsed=854824717
  1733. i.e. calculated in seconds,
  1734. Where 30 days allowance is 857416551 - 854824551 = 2592000
  1735. 2592000/30 = 86400 (one day)
  1736. 86400/24 = 3600 (one hour)
  1737. 3600/60 = 60 (one minute)
  1738.  
  1739. Well, that's it for this lesson, reader. Not all lessons of my
  1740. tutorial are -or will be- on the Web.
  1741. You'll obtain the missing lessons IF AND ONLY IF you mail
  1742. me back (via anon.penet.fi) with some tricks of the trade I may
  1743. not know that YOU discovered. Mostly I'll actually know them
  1744. already, but if they are really new you'll be given full credit,
  1745. and even if they are not, should I judge that you "rediscovered"
  1746. them with your work, or that you actually did good work on them,
  1747. I'll send you the remaining lessons nevertheless. Your
  1748. suggestions and critics on the whole crap I wrote are also
  1749. welcomed. Do not annoy me with requests for warez, everything is
  1750. on the Web, learn how to search, for Jimmy Olden sake.
  1751.  
  1752. "If you give a man a crack he'll be hungry again
  1753. tomorrow, but if you teach him how to crack, he'll
  1754. never be hungry again"
  1755.  
  1756.                                 E-mail +ORC
  1757.  
  1758.                         +ORC na526164@anon.penet.fi
  1759.