home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / E_bliss / dux-idcm5.txt < prev    next >
Text File  |  2000-05-25  |  21KB  |  423 lines

  1. TUTORIAL FOR IDCRACKME v.5.0 by The_Dux
  2. =======================================
  3.  
  4. INTRO:
  5. A little intro before we start.
  6. This is a very very long tutorial so be patient...
  7. The length of this is strictly realted with the type of crackme that
  8. TORN@DO wrote.
  9. I'm not a native english person so... forgive my mistakes. Thanks.
  10.  
  11. TUT:
  12. Let's start.
  13. As usual we fire up the program and see around to find some button
  14. like 'Register', etc.
  15. We didn't found anything except two buttons: one enabled (the About)
  16. and one disabled (the Request).
  17. So we can't insert our data directly to the program. We must
  18. reconstruct the registration file manually.
  19. Ok, as wrote in the Readme file this is a packed file so we can't
  20. disassemble it. Well...
  21. Now we have to choose:
  22. a) We can debug it directly with SoftIce or similar
  23. b) We can unpack it manually and try deadlisting
  24.  
  25. I prefer the first one so i've tried with SoftIce.
  26. The first problem that we encounter is that the decription routine is
  27. very long and we can only 'step into' to go on otherwise we exit from
  28. SoftIce and the program load itself without us...
  29. So we can try two things:
  30. a) We can set a breakpoint to OpenFile, CreateFile, CreateFileEx,
  31.    ReadFile and ReadFileEx to intercept the reading or
  32. b) We can try another approach that is more nice and 'aristocratic'
  33.  
  34. We try the second one, of course, because we are not novice and we
  35. crack with a little of brain, right?
  36. So, let's take a look at the main window of the program.
  37. We have a dialog, or a window, we don't say, with four main object:
  38. two pictures and two buttons.
  39. The pictures show some nice text but the button are one enabled and
  40. one disabled. This is very important and from here we can start
  41. reconstruct the missing key file. How? Be patient...
  42.  
  43. We all know that a button is enabled by a call to the EnableWindow
  44. function. Reading our Win32 API references we see that the function
  45. take two parameters: hWnd & bEnable.
  46. The first one is the handle to the window (or the button, btw) that
  47. receive our boolean value (enabled or disabled, 0 or 1) represented
  48. by bEnable.
  49. Let's think a bit...
  50. We can't enable the button from the window nor from the about box
  51. so the button is enabled ONLY when we reconstruct the key file...
  52.  
  53. Now that we reverse with word this we set a breakpoint on execution
  54. (bpx in SoftIce) at EnableWindow. Launch the program and... voilα
  55. SoftIce pop up and put ourseleves in the middle of our beloved
  56. function...
  57. Think a little again: we have two button so how much call to
  58. EnableWindow? Two!!
  59. Exit SoftIce with CTRL+D and we reenter immediately in SoftIce.
  60. Ok now F11 once to exit from EnableWindow and we fall into the
  61. crackme's code. Well.
  62. Move around the code and see the GetDlgItem function that retrieve
  63. the handle of control (our button). We also see, some lines above,
  64. a PUSH 00 that is like PUSH FALSE or PUSH DISABLED.
  65. Yes! We found where the routine where button is disabled!
  66. Now move the cursor above to see a conditional jump but there are
  67. only some pushes... like the beginning of a call. In fact this is
  68. a little call that ends some lines below the Call EnableWindow
  69. with a RET.
  70. Trace till there and see where we return. The lines that we see
  71. are few and many INT 3 are there...
  72. Let's take a look at the lines above and we see another RET
  73. instruction, after another call...
  74. Well our experience say us that this is the place where the key
  75. file is verified and then something decide how we are (good or
  76. bad crackers...).
  77. So write down the addres after the first occurrence that is in
  78. my machine 401D18.
  79. Go up to find some conditional jump that refer to this location
  80. and with a lot of surprise we find not one but many conditional
  81. jump of this type.
  82. Watching the lines above each jump we notice that we have allways
  83. a call, a stack adjustment, and a test that verify the value of
  84. eax that must be zero or non zero.
  85. Ok, now we have founded the reference to the EnableWindow that
  86. disable the button.
  87. Set a breakpoint to the first call (401BEC) and step into to see
  88. what happen.
  89. Ok, now we have to trace well the first part of this call cause
  90. as we can see we found this initial lines in each call that
  91. follow and that return the magic value in eax that decide if we
  92. are good or not so good.
  93.  
  94. Here is the code taken from W32Dasm:
  95. (Forget the addresses, they are false beacause this is a dump of
  96.  memory from SoftIce)
  97.  
  98. :00000000 83EC30                  sub esp, 00000030
  99. :00000003 33D2                    xor edx, edx
  100. :00000005 33C0                    xor eax, eax
  101. :00000007 B907000000              mov ecx, 00000007
  102. :0000000C 88542410                mov byte ptr [esp+10], dl
  103. :00000010 57                      push edi
  104. :00000011 8D7C2415                lea edi, dword ptr [esp+15]
  105. :00000015 F3                      repz
  106. :00000016 AB                      stosd
  107. :00000017 AA                      stosb
  108. :00000018 8D442405                lea eax, dword ptr [esp+05]
  109. :0000001C 88542404                mov byte ptr [esp+04], dl
  110. :00000020 8910                    mov dword ptr [eax], edx
  111. :00000022 895004                  mov dword ptr [eax+04], edx
  112. :00000025 895008                  mov dword ptr [eax+08], edx
  113. :00000028 6689500C                mov word ptr [eax+0C], dx
  114. :0000002C B801000000              mov eax, 00000001
  115. :00000031 8A8857D04000            mov cl, byte ptr [eax+0040D057]
  116. :00000037 40                      inc eax
  117. :00000038 80F133                  xor cl, 33
  118. :0000003B 83F810                  cmp eax, 00000010
  119. :0000003E 884C0412                mov byte ptr [esp+eax+12], cl
  120. :00000042 76ED                    jbe 00000031
  121. :00000044 8D442414                lea eax, dword ptr [esp+14]
  122. :00000048 8D4C2404                lea ecx, dword ptr [esp+04]
  123. :0000004C 50                      push eax
  124. :0000004D 6828D74000              push 0040D728
  125. :00000052 51                      push ecx
  126. :00000053 E858360000              call 000036B0
  127. :00000058 8D4C2410                lea ecx, dword ptr [esp+10]
  128. :0000005C 83C40C                  add esp, 0000000C
  129. :0000005F 6824D74000              push 0040D724
  130. :00000064 51                      push ecx
  131. :00000065 E826360000              call 00003690
  132. :0000006A 83C408                  add esp, 00000008
  133. :0000006D 85C0                    test eax, eax
  134. :0000006F 7413                    je 00000084
  135. :00000071 50                      push eax
  136. :00000072 E829340000              call 000034A0
  137. :00000077 83C404                  add esp, 00000004
  138. :0000007A B801000000              mov eax, 00000001
  139. :0000007F 5F                      pop edi
  140. :00000080 83C430                  add esp, 00000030
  141. :00000083 C3                      ret
  142.  
  143. :00000084 33C0                    xor eax, eax
  144. :00000086 5F                      pop edi
  145. :00000087 83C430                  add esp, 00000030
  146. :0000008A C3                      ret
  147.  
  148. Ok, it's all the call but we can slowly learn it's structure.
  149. Let's start. Where? From the beginning of course...
  150. At the address 0 (is a fake address, remember) we adjust the stack
  151. and we set some values (not so important) till 2Ch.
  152. Here we set eax to 1 and enter in a loop, repeated 16 times, in wich
  153. we get a value from somewhere, we xor it with 33h, and we put the
  154. xored value in a buffer.
  155. This loop as i said xor an array of data and put the result in
  156. another array.
  157. For educational purpose here are the crypted and the decrypted
  158. arrays:
  159.  
  160. Crypted : avtz`gargz|} (and another char that is 1Dh(can't represent))
  161. Decrypted: REGISTRATION.DAT
  162.  
  163. As you see we decrypt the buffer to get the real name of the key file.
  164. So create it! (of course in the same directory)
  165. Ok, now back on our code. We know that eax must be non-zero to
  166. fake the jz jump just after our breakpoint.
  167. We see two RET and after each one eax is filled with different
  168. values: 1 for the first RET (at 7Ah) and 0 for the second RET (84h).
  169. The only way to go to 84h is with the jump at 6Fh that verify the
  170. return value of the above call. We can go through this call and so
  171. on and so on... or we can simply guess what this call do.
  172. Really I don't know what this call do but i believe that return
  173. the handle of file (with a call to OpenFile maybe) and if eax is
  174. zero (that is the error code of OpenFile for failed operation) it
  175. jump and return a zero that say we are bad crackers.
  176. So try it! It's as I said... No matter how the check is done
  177. (not because we are lamers but because we can't trace through these
  178. calls or our key file never watch the sun light!!).
  179. We have reversed almost 50% of the protection, I think, because
  180. all the others calls begin as this.
  181. Ok now we come back and set another breakpoint to the next call
  182. (that now is executed because we have the REGISTRATION.DAT).
  183.  
  184. Well, well, we are still in the night because we have just created
  185. the file... NO!
  186. Now we go to the next call and see some operations (at the end)
  187. that substract 400h (1024d) to a value stored in ebx. Now that we
  188. are here we can choose:
  189. a) trace the call to find where value ebx is computed
  190. b) think a little as TORN@DO and guess what's this
  191.  
  192. We try... b!
  193. Ok, now the program know that the key file exist what more?
  194. We can check many things but one is the more probable (watching
  195. that 400h or 1024d also): the length of our file.
  196. Yes, is as said and the length must be 1024 bytes.
  197. Try yourself if you don't believe me. I don't have time (and
  198. space) to explain those little particulars.
  199. so we return with the correct value in eax and set a breakpoint
  200. on next call.
  201.  
  202. Go inside, jump the known part, and pay attention to what happens
  203. here is that movsx, mov and cmp loop. With the call above we read
  204. the entire file (important: the entire file) and we put it onto
  205. a buffer pointed by the stack (esp). After little tricks i've founded
  206. that the file is stored starting from address [esp+3C].
  207. I've simply putted a 01h byte at the beginning and at the end of our
  208. key file and searched for it near the pointer to [esp+eax+38] readed
  209. onto the code.
  210. This call is the most important part of key file because here we can
  211. reconstruct our key file with our name...
  212. I have to say that our name is crippled with a simple algorithm that
  213. xor every char of our name with the length of name.
  214. As we see after some other calls depending on the name we change a
  215. handful of byte, but later...
  216. So insert our name (crippled of course!!).
  217. This time i've crippled a name, Scully, that is the name I usually
  218. use to find the serial number.
  219. So we can write at the offset 99 of the key-file the crippled name.
  220. A little things: the 99 is computed as I said above basing on the
  221. beginning of file situated at [esp+3C] and the lines that move our
  222. name to a buffer. I can't explain i've said but it isn't so hard.
  223.  
  224. My cryppled name is Uesjj (plus the 7Fh char that i can't represent).
  225.  
  226. The only limit to the name is the length: it must be greater than 3
  227. and lesser than 55 chars.
  228.  
  229. Now we go further and set a breakpoint on next call.
  230. The address is 401E90 and I have to say that the last known call
  231. (the one that is repeated every call) read from file and place
  232. start the buffer at esp+38.
  233. In this call we do a simply check to verify the header of the key
  234. file that is 9 bytes long.
  235.  
  236. The header is already stored in the exe (decrypted of course!) and
  237. is compared with a routine of three line.
  238. If you don't find it by yourself here is what it is:
  239. 06h 0Ah 15h 07h 13h 10h 0Ah 72h 0Ch
  240.  
  241. As you can see it's a sequence of nine byte.
  242.  
  243. We are done with this call too so set a breakpoint on the next.
  244. This call is another check to verify the integrity of our key file.
  245. We have 7 bytes that are readed from the buffer (that is always
  246. where we put the content of the registration file), xored with some
  247. values and then compared with other values.
  248. To simplify the tedious job here are the bytes to put at offset 0Ah:
  249. 07h 20h 34h 3Eh 09h 07h 0Ah
  250.  
  251. Note: The first 07h is taken from the last reading operation of the
  252. call. THEY AREN'T IN SEQUENCE AS IN REG FILE.
  253.  
  254. Ok, next call and set the new breakpoint.
  255. In this call we get some other bytes (4) just after the 0Ah of the
  256. above call.
  257. The byte are compare directly with cmp or tested if they must be zero.
  258. Here are they (to put after the last 0Ah, offset 11h):
  259. 08 00 00 05
  260.  
  261. Now we are ready to set the next breakpoint.
  262. In this call what we have? The same things as in the above one...
  263. We have some value that must be equal to our values xor dummy val.
  264. So here are they: (they are 17 starting from offset 15h)
  265. 08 05 00 12h 0Ah 12h 03 12h 02 2Ch 43h 08 02 2Ah 0Ah 44h 54h
  266.  
  267. And now what we do? We set a breakpoint on next call...
  268. This call is a bit obscure but we resolve it in a while. With this
  269. call the crackme check a date stored in the key file with the
  270. current date. The key file date must be greater or equal to the
  271. current one.
  272. We simply store a 07CFh word in our file at the offset 52h and we
  273. pass this check.
  274. Now we have to look at another value that here appear as unused but
  275. in the last call we find some references to this. We can modify it if
  276. we want but, you are warned, we have to do more complex math later so
  277. believe me, leave 0 this byte that is at the offset 50h.
  278.  
  279. Well... slowly but calm we are here...what more? some more calls...
  280. we are about in the middle of the check routine so we must take a
  281. rest here...
  282.  
  283. Good rest? well... let's start again with the famous breakpoint on
  284. next call.
  285. At the beginning of this tute we see the crackme like a heavy slope,
  286. now we are in a descent...
  287. This call tell us nothing... It simply compares two byte of our code
  288. and verify that they are lesser than two values. Ok leave these byte
  289. null (0 - at offset 55h & 56h) and go on with next call.
  290.  
  291. Set The Breakpoint.
  292. Now a call that will relax ourself and free our mind...
  293. We trace till we reach the usual set of known code and then we see a
  294. routine, repeated 88 times that compare some value with some other
  295. situated at offset 0D0h of our key file.
  296.  
  297. What are these bytes? They are a joke...
  298. Here are they: (all uppercase)
  299.  
  300. SUPPORT THE SOFTWARE AUTHORS BY BUYING THE PROGRAMS IF YOU USE THEM
  301. AFTER CRACKING THEM!
  302.  
  303. Nice isn't it?
  304. Write this words on the file starting from 0D0h and go on.
  305.  
  306. Set The Breakpoint.
  307. In this call, with a little different routine to the above one we
  308. do the same thing: we compare another handful of bytes.
  309. They are (starting from offset 150h):
  310.  
  311. 6;9>>2TJR255<5>=92:8><=
  312.  
  313. Set The Breakpoint.
  314. Now begin the part that is a little harder than the previous one.
  315. We start generating checksum...
  316. Ok, don't be demoralized, it's only math...
  317. Well, we begin with a little look around the code:
  318. We see a loop repeated 100 times and a division by 0Ah
  319. Now I try explain you what happen:
  320. Here we compute a checksum (only a sum) of the first 100 bytes.
  321. After this we xor it with 7CFh (1999, nice!) and we divide by 0Ah.
  322. The result of division must be equal to a byte stored in the key file
  323. at the offset 3B0h.
  324. We have to do all this maths? Nope, the computer do it for us...
  325. We only wait at the line with cmp ecx, eax and write down what we
  326. have in eax (the byte of checksum just computed).
  327. Now we open the key file and we write this byte to the 3B0h offset.
  328. Done.
  329. Note: in this call we have a handful of value taken here and there
  330. from the key file. Believe me, leave it to zero...
  331.  
  332. Set The Breakpoint.
  333. Another call very similar to the above one.
  334. We find some more maths... leave the computer alone to do that
  335. (hey, it's it job and it do it very quickly...). We wait at the
  336. usual cmp reg32, reg32 and write down the addresses.
  337. What more? NOTHING.
  338. The call that follow do the same job and we have to wait at the
  339. cmp reg32, reg32 instruction to find the correct values...
  340.  
  341. Another things: the last call verify that the last byte of the key
  342. file is 52h. Don't miss it!
  343.  
  344. FINAL NOTES:
  345. We have successfully rebuild the missing key file... what more?
  346. A key-gen... Wait, it's a bit longer...
  347. For those of you that wasn't able to follow me here is the dump of
  348. my REGISTRATION.DAT (Pay attention: don't modify any byte because
  349. the final checksum may change!):
  350.  
  351. Taken from HexWorkshop v.2.54
  352. 00000000 060A 1507 1310 0A72 0C00 0720 343E 0907 .......r... 4>..
  353. 00000010 0A08 0000 0508 0500 120A 1203 1202 2C43 ..............,C
  354. 00000020 0802 2A0A 4454 2101 5269 3A00 0000 0000 ..*.DT!.Ri:.....
  355. 00000030 0000 0000 0000 0000 0000 0000 0000 0000 ................
  356. 00000040 0000 0000 0000 0000 0000 0000 0000 0000 ................
  357. 00000050 0000 07CF 0000 0000 0000 0000 0000 0000 ................
  358. 00000060 0000 0000 0000 0000 0000 0000 0000 0000 ................
  359. 00000070 0000 0000 0000 0000 0000 0000 0000 0000 ................
  360. 00000080 0000 0000 0000 0000 0000 0000 0000 0000 ................
  361. 00000090 0000 0000 0000 0000 0055 6573 6A6A 7F00 .........Uesjj..
  362. 000000A0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  363. 000000B0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  364. 000000C0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  365. 000000D0 5355 5050 4F52 5420 5448 4520 534F 4654 SUPPORT THE SOFT
  366. 000000E0 5741 5245 2041 5554 484F 5253 2042 5920 WARE AUTHORS BY
  367. 000000F0 4255 5949 4E47 2054 4845 2050 524F 4752 BUYING THE PROGR
  368. 00000100 414D 5320 4946 2059 4F55 2055 5345 2054 AMS IF YOU USE T
  369. 00000110 4845 4D20 4146 5445 5220 4352 4143 4B49 HEM AFTER CRACKI
  370. 00000120 4E47 2054 4845 4D21 0000 0000 0000 0000 NG THEM!........
  371. 00000130 0000 0000 0000 0000 0000 0000 0000 0000 ................
  372. 00000140 0000 0000 0000 0000 0000 0000 0000 0000 ................
  373. 00000150 363B 393E 3E32 544A 5232 3535 3C35 3E3D 6;9>>2TJR255<5>=
  374. 00000160 3932 3A38 3E3C 3D00 0000 0000 0000 0000 92:8><=.........
  375. 00000170 0000 0000 0000 0000 0000 0000 0000 0000 ................
  376. 00000180 0000 0000 0000 0000 0000 0000 0000 0000 ................
  377. 00000190 0000 0000 0000 0000 0000 0000 0000 0000 ................
  378. 000001A0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  379. 000001B0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  380. 000001C0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  381. 000001D0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  382. 000001E0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  383. 000001F0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  384. 00000200 0000 0000 0000 0000 0000 0000 0000 0000 ................
  385. 00000210 0000 0000 0000 0000 0000 0000 0000 0000 ................
  386. 00000220 0000 0000 0000 0000 0000 0000 0000 0000 ................
  387. 00000230 0000 0000 0000 0000 0000 0000 0000 0000 ................
  388. 00000240 0000 0000 0000 0000 0000 0000 0000 0000 ................
  389. 00000250 0000 0000 0000 0000 0000 0000 0000 0000 ................
  390. 00000260 0000 0000 0000 0000 0000 0000 0000 0000 ................
  391. 00000270 0000 0000 0000 0000 0000 0000 0000 0000 ................
  392. 00000280 0000 0000 0000 0000 0000 0000 0000 0000 ................
  393. 00000290 0000 0000 0000 0000 0000 0000 0000 0000 ................
  394. 000002A0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  395. 000002B0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  396. 000002C0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  397. 000002D0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  398. 000002E0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  399. 000002F0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  400. 00000300 0000 0000 0000 0000 0000 0000 0000 0000 ................
  401. 00000310 0000 0000 0000 0000 0000 0000 0000 0000 ................
  402. 00000320 0000 0000 0000 0000 0000 0000 0000 0000 ................
  403. 00000330 0000 0000 0000 0000 0000 0000 0000 0000 ................
  404. 00000340 0000 0000 0000 0000 0000 0000 0000 0000 ................
  405. 00000350 0000 0000 0000 0000 0000 0000 0000 0000 ................
  406. 00000360 0000 0000 0000 0000 0000 0000 0000 0000 ................
  407. 00000370 0000 0000 0000 0000 0000 0000 0000 0000 ................
  408. 00000380 0000 0000 0000 0000 0000 0000 0000 0000 ................
  409. 00000390 0000 0000 0000 0000 0000 0000 0000 0000 ................
  410. 000003A0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  411. 000003B0 6272 0400 120F 0000 0000 0000 0000 0000 br..............
  412. 000003C0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  413. 000003D0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  414. 000003E0 0000 0000 0000 0000 0000 0000 0000 0000 ................
  415. 000003F0 0000 0000 0000 0000 0000 0000 0000 0052 ...............R
  416.  
  417. Ok, I have finished my very very long tutorial.
  418. In the words above I don't say a little things:
  419. the objective. Mine is... I can't tell you. If you follow my
  420. tutorial step by step and call by call you see a little nice
  421. joke from TORN@DO with the main icon. Really cool!
  422.  
  423. The_Dux, 12 July 1999.