home *** CD-ROM | disk | FTP | other *** search
/ KeyGen Studio 2002 / KeyGen_Studio_2002.iso / Tutorials / CrackMesCbjNet / dux-dapope.txt < prev    next >
Encoding:
Text File  |  2001-09-21  |  18.3 KB  |  228 lines

  1. Solution for daPope's Crackme #1 by The_Dux
  2.  
  3. INTRODUCTION
  4. ============
  5.  
  6. First of all I have to thank crackmes.cjb.net for it's fantastic site that
  7. offer me a simple way to spend my spare time, and then I would like to thank
  8. daPope 'cause he indirectly taught me a new way of thinking about crackme's
  9. world.
  10.  
  11.  
  12. THE PROTECTION
  13. ==============
  14.  
  15. Let's start.
  16. At a first look the protection doesn't seem to be very hard, in fact we have
  17. only a name and a serial number to enter and then we can see if we are very
  18. strong boy or not_so_very_strong boy.
  19. As usual i have SIce loaded (who haven't?), and the program says 'you have
  20. sice loaded, please unload' that is the standard phrase for an anti-sice
  21. protection. We have to look at the code to search for a pair of byte that
  22. build one of the many protections against NuMega's debugger, but first
  23. think a bit...
  24. The most simple way of detecting SIce is trying to open the SIce main EXE
  25. so i look in the file with an hex-editor (HexWorkshop?) and found nothing.
  26. Well, it isn't so strange...
  27. Fire up W32Dasm and IDA (wow...) and try to disassemble (yeah, we can 'cause
  28. there are no rules and as we look in the PE section, there aren't any
  29. packing/compressing or other file protections).
  30. Hey, look at the W32Dasm code...
  31. It isn't reliable, but it's very strange...
  32. AH YES!!! It's a Java Crackme!!!
  33. Ok, look at the exe for some strings so we can have a start...
  34. What we found?
  35. The Java source...
  36. It isn't strange? It's all there, all the code we are looking for is
  37. standing in front of our eyes in a high level language...
  38. Really good...
  39. Open the file with Notepad or any other text editor and copy the code into
  40. another file, let's say Crackme.java (it's not a random name as you'll see).
  41. It's a strange code and I have to warn you: don't look at the 
  42. calculateSerial() routine 'cause it's only here to take us to the wrong 
  43. way (try to follow the lines of it if you can't believe, they'll lead you
  44. to a dead road).
  45. So, where can we look?
  46. First I examined the anti-SIce code that is located in the routine called
  47. checkForWinIce(). The routine do a very strange check to locate SIce. It
  48. read the autoexec.bat in search of a string with "winice.exe" in it; it's
  49. a strange protection, i've never seen such a thing, but it has a good 
  50. aspect: even if you unload SIce modifying only the autoexec.bat with a rem
  51. in front of the launch command the program still know that you have SIce
  52. in your system and it doesn't work...
  53. Ok, we have to patch this little trick: I don't touch the crackme's code
  54. 'cause there were no rules, but the ethical one it's always there... and
  55. also because to patch the exe you have to recompile the class and then
  56. modify the bytes in the file (it's a huge work and may not satisfy); so
  57. the only thing to do it's modify autoexec.bat so that there aren't more
  58. "winice.exe" string in it. Ok, done; remember the rem in front of the line
  59. to avoid errors on system startup.
  60. Now, if you know a little of Java you'll ask yourself: 'how the hell a
  61. java class can be packed into an exe file?'. The answer it's this:
  62. a little tool called Microsoft Visual J++ offer you a GUI where you can
  63. draw your application and write the code associated to each event (just
  64. like VisualBasic, except that the code isn't in Basic but in Java).
  65. Ok, let's think a bit about this: if we have the code right in front of
  66. us maybe in the exe we only have the classes packed together like an 
  67. archive. It's our lucky day, it's as I've told you...
  68. Now another problem stand in front of us: the code that we see it's there
  69. to take us to a death way or it's real code? This is a question that can
  70. be answered only extracting the real classes from the exe and then disasm
  71. them to see if the two sources match each other.
  72. If you've tryed to extract the MIDI files from Final Fantasy VII you would
  73. have thought: 'maybe the files are only stored in the exe and when one
  74. start, the other finish'.
  75. It's a complicated idea but I explain it right now:
  76. If you have, let's say, three txt files named 'one.txt', 'two.txt' and
  77. 'three.txt' and you want to put them in a file called 'archive.txt' what
  78. will you do?
  79. You simply begin to put one.txt and then two and three all one after the
  80. other...
  81. So, if we know the header of a class file we can extract it from the 
  82. exe without problem (we don't care about is size, the diasm, jad, won't
  83. look at strange code at the end, it'll simply disassemble the code and
  84. discard the garbage).
  85. Looking at other class files i noticed that the header it's this (in
  86. hexadecimal): CAFE BABE
  87. Much fantasy, huh? I don't know who select this header...
  88. Ok extract the files and notice that the last it's very big (about 20Kb).
  89. This is the core of the crackme.
  90. After disassembling it, however, we can't discover new worlds because the
  91. code is the same as the first we see...
  92. Now we have to do the hard part of the work: trying to transport ourself
  93. inside the author's mind and decyfer the source code.
  94. It's not so hard to do because crackme it's simple but we have to carefully
  95. watch at dead points, that are many: one it's the one i've told you above,
  96. another it's represented by the input boxes and the register button. They
  97. don't have functionality in this crackme, they're there only to take us
  98. to a death road.
  99. If you carefully look at the source code, you'll see that the two text boxes
  100. are used to generate the fake serial number and nothing else.
  101. We have to input the name and the serial by command line in that order...
  102. Ok, now we can declare war at the real source code. To simplify your life
  103. here is it (i've added a few comments) :
  104.  
  105.     public Crackme(String args[])  // this is like main() in C++
  106.     {
  107.         initComponents(); // Doesn't matter for us
  108.         pack();           // As above
  109.         setTitle("daPope's CrackMe #1 - Take a look att http://surf.to/daPopesTutorial");
  110.         if(!checkForWinIce()) // Interesting...
  111.         {
  112.             boolean registered = isRegistered(); // Uh, oh... what happen?
  113.             if(!registered) // Not registered it's our first state
  114.             {
  115.                 if(args.length != 2)
  116.                 {
  117.                     label3.setText((new Character('E')).toString() + (new Character('n')).toString() + (new Character('t')).toString() + (new Character('e')).toString() + (new Character('r')).toString() + (new Character(' ')).toString() + (new Character('N')).toString() + (new Character('a')).toString() + (new Character('m')).toString() + (new Character('e')).toString() + (new Character(' ')).toString() + (new Character('A')).toString() + (new Character('n')).toString() + (new Character('d')).toString() + (new Character(' ')).toString() + (new Character('S')).toString() + (new Character('e')).toString() + (new Character('r')).toString() + (new Character('i')).toString() + (new Character('a')).toString() + (new Character('l')).toString() + (new Character(' ')).toString() + (new Character('T')).toString() + (new Character('o')).toString() + (new Character(' ')).toString() + (new Character('R')).toString() + (new Character('e')).toString() + (new Character('g')).toString() + (new Character('i')).toString() + (new Character('s')).toString() + (new Character('t')).toString() + (new Character('e')).toString() + (new Character('r')).toString());
  118.                 } else
  119.                 {
  120.                     button1.setEnabled(false);
  121.                     String name = args[0];
  122.                     String serial = args[1];
  123.                     StringBuffer correct = new StringBuffer();
  124.               // From here...
  125.                     for(int i = 0; i < name.length(); i++)
  126.                     {
  127.                         char a = name.charAt(i);
  128.                         int b = Character.getNumericValue(a);
  129.                         int c = b % 10;
  130.                         Integer d = new Integer(c);
  131.                         correct.append(d.toString());
  132.                     }
  133.                     // ... to here the code is computed.
  134.  
  135.               // You can understand what will happen under
  136.                     // this line?
  137.                     if(serial.equals(correct.toString()))
  138.                     {
  139.                         registered = true;
  140.                         try
  141.                         {
  142.                             FileWriter theFile = new FileWriter("C:/Windows/systen.ini");
  143.                             theFile.write("Well done " + name + "\n\n");
  144.                             theFile.write("  You've cracked daPope's CrackMe #1");
  145.                             theFile.write("using " + correct.toString + " as serialnumber\n\n");
  146.                             theFile.flush();
  147.                         }
  148.                         catch(Exception e) { }
  149.                         textField1.setBackground(new Color(204, 204, 204));
  150.                         textField2.setBackground(new Color(204, 204, 204));
  151.                         textField1.setEditable(false);
  152.                         textField2.setEditable(false);
  153.                         label3.setText((new Character('C')).toString() + (new Character('o')).toString() + (new Character('o')).toString() + (new Character('l')).toString() + (new Character('!')).toString() + (new Character(' ')).toString() + (new Character('d')).toString() + (new Character('a')).toString() + (new Character('P')).toString() + (new Character('o')).toString() + (new Character('p')).toString() + (new Character('e')).toString() + (new Character('\'')).toString() + (new Character('s')).toString() + (new Character(' ')).toString() + (new Character('C')).toString() + (new Character('r')).toString() + (new Character('a')).toString() + (new Character('c')).toString() + (new Character('k')).toString() + (new Character('M')).toString() + (new Character('e')).toString() + (new Character(' ')).toString() + (new Character('#')).toString() + (new Character('1')).toString() + (new Character(' ')).toString() + (new Character('S')).toString() + (new Character('u')).toString() + (new Character('c')).toString() + (new Character('c')).toString() + (new Character('e')).toString() + (new Character('s')).toString() + (new Character('s')).toString() + (new Character('f')).toString() + (new Character('u')).toString() + (new Character('l')).toString() + (new Character('l')).toString() + (new Character('y')).toString() + (new Character(' ')).toString() + (new Character('R')).toString() + (new Character('e')).toString() + (new Character('g')).toString() + (new Character('i')).toString() + (new Character('s')).toString() + (new Character('t')).toString() + (new Character('e')).toString() + (new Character('r')).toString() + (new Character('e')).toString() + (new Character('d')).toString());
  154.                         setTitle((new Character('d')).toString() + (new Character('a')).toString() + (new Character('P')).toString() + (new Character('o')).toString() + (new Character('p')).toString() + (new Character('e')).toString() + (new Character('\'')).toString() + (new Character('s')).toString() + (new Character(' ')).toString() + (new Character('C')).toString() + (new Character('r')).toString() + (new Character('a')).toString() + (new Character('c')).toString() + (new Character('k')).toString() + (new Character('M')).toString() + (new Character('e')).toString() + (new Character(' ')).toString() + (new Character('#')).toString() + (new Character('1')).toString() + (new Character(' ')).toString() + (new Character('-')).toString() + (new Character(' ')).toString() + (new Character('R')).toString() + (new Character('e')).toString() + (new Character('g')).toString() + (new Character('i')).toString() + (new Character('s')).toString() + (new Character('t')).toString() + (new Character('e')).toString() + (new Character('r')).toString() + (new Character('e')).toString() + (new Character('d')).toString());
  155.                     }
  156.                     if(!registered)
  157.                         label3.setText((new Character('I')).toString() + (new Character('n')).toString() + (new Character('v')).toString() + (new Character('a')).toString() + (new Character('l')).toString() + (new Character('i')).toString() + (new Character('d')).toString() + (new Character(' ')).toString() + (new Character('S')).toString() + (new Character('e')).toString() + (new Character('r')).toString() + (new Character('i')).toString() + (new Character('a')).toString() + (new Character('l')).toString() + (new Character('.')).toString() + (new Character(' ')).toString() + (new Character('T')).toString() + (new Character('r')).toString() + (new Character('y')).toString() + (new Character(' ')).toString() + (new Character('A')).toString() + (new Character('g')).toString() + (new Character('a')).toString() + (new Character('i')).toString() + (new Character('n')).toString());
  158.                 }
  159.             } else // Already Registered
  160.             {
  161.                 button1.setEnabled(false);
  162.                 textField1.setBackground(new Color(204, 204, 204));
  163.                 textField2.setBackground(new Color(204, 204, 204));
  164.                 textField1.setEditable(false);
  165.                 textField2.setEditable(false);
  166.                 setTitle((new Character('d')).toString() + (new Character('a')).toString() + (new Character('P')).toString() + (new Character('o')).toString() + (new Character('p')).toString() + (new Character('e')).toString() + (new Character('\'')).toString() + (new Character('s')).toString() + (new Character(' ')).toString() + (new Character('C')).toString() + (new Character('r')).toString() + (new Character('a')).toString() + (new Character('c')).toString() + (new Character('k')).toString() + (new Character('M')).toString() + (new Character('e')).toString() + (new Character(' ')).toString() + (new Character('#')).toString() + (new Character('1')).toString() + (new Character(' ')).toString() + (new Character('-')).toString() + (new Character(' ')).toString() + (new Character('R')).toString() + (new Character('e')).toString() + (new Character('g')).toString() + (new Character('i')).toString() + (new Character('s')).toString() + (new Character('t')).toString() + (new Character('e')).toString() + (new Character('r')).toString() + (new Character('e')).toString() + (new Character('d')).toString());
  167.                 label3.setText((new Character('P')).toString() + (new Character('r')).toString() + (new Character('o')).toString() + (new Character('g')).toString() + (new Character('r')).toString() + (new Character('a')).toString() + (new Character('m')).toString() + (new Character(' ')).toString() + (new Character('I')).toString() + (new Character('s')).toString() + (new Character(' ')).toString() + (new Character('A')).toString() + (new Character('l')).toString() + (new Character('r')).toString() + (new Character('e')).toString() + (new Character('a')).toString() + (new Character('d')).toString() + (new Character('y')).toString() + (new Character(' ')).toString() + (new Character('R')).toString() + (new Character('e')).toString() + (new Character('g')).toString() + (new Character('i')).toString() + (new Character('s')).toString() + (new Character('t')).toString() + (new Character('e')).toString() + (new Character('r')).toString() + (new Character('e')).toString() + (new Character('d')).toString());
  168.             }
  169.         } else  // Bad boy... Unload SICE...
  170.         {
  171.             button1.setEnabled(false);
  172.             textField1.setBackground(new Color(204, 204, 204));
  173.             textField2.setBackground(new Color(204, 204, 204));
  174.             textField1.setEditable(false);
  175.             textField2.setEditable(false);
  176.             label3.setText((new Character('A')).toString() + (new Character(' ')).toString() + (new Character('C')).toString() + (new Character('e')).toString() + (new Character('r')).toString() + (new Character('t')).toString() + (new Character('a')).toString() + (new Character('i')).toString() + (new Character('n')).toString() + (new Character(' ')).toString() + (new Character('P')).toString() + (new Character('r')).toString() + (new Character('o')).toString() + (new Character('g')).toString() + (new Character('r')).toString() + (new Character('a')).toString() + (new Character('m')).toString() + (new Character(' ')).toString() + (new Character('I')).toString() + (new Character('s')).toString() + (new Character(' ')).toString() + (new Character('D')).toString() + (new Character('e')).toString() + (new Character('t')).toString() + (new Character('e')).toString() + (new Character('c')).toString() + (new Character('t')).toString() + (new Character('e')).toString() + (new Character('d')).toString() + (new Character('.')).toString() + (new Character(' ')).toString() + (new Character('U')).toString() + (new Character('n')).toString() + (new Character('l')).toString() + (new Character('o')).toString() + (new Character('a')).toString() + (new Character('d')).toString());
  177.         }
  178.     }
  179.  
  180. Ok, a big chunk of code but you can look at the for statement marked
  181. as the routine that generate the code.
  182. Here we compute the code from the name. The algo it's very simple: take
  183. a char from name, get it's numerical value (UNICODE VALUE, IT'S VERY VERY
  184. IMPORTANT), and append it to a correct string...
  185. Then we compare the serials and so on
  186. I have to underline that numerical values are UNICODE and NOT ASCII so
  187. the value of 'A' isn't 65 but 10, and also 'A' it's equal to 'a'.
  188. To compute the serial i've made a little program in VJ++ that do the work
  189. for me but you can take a piece of paper and do some maths with your 
  190. brain... it's not so hard...
  191. Then insert the code int the command line (try with mine:
  192. Name: Scully
  193. Code: 820114
  194. From the DOS prompt digit 'crkme1 Scully 820114' and the program says it's
  195. registered...
  196.  
  197. ANOTHER CONSIDERATION
  198. =====================
  199.  
  200. Have you noticed that isRegistered() function and the boolean registered?
  201. No? Really bad...
  202. Only for who of you that want to know all the protection scheme here is 
  203. the explanation of that boolean variable:
  204. Before parsing the command line the program check for a file named
  205. 'systen.ini' (note the 'n' instead of 'm') in the windows directory and
  206. read from it this string:
  207.  
  208. Well done Scully\n\n
  209. You've cracked daPope's Crackme#1using 820114 serialnumber\n\n
  210.  
  211. This string tell the program we have already registered it and we can
  212. try other crackmes...
  213. A little trick: if you don't want to pass through the command line 
  214. arguments, simply put a name and a code (not the real one, it work however)
  215. where i wrote Scully and 820114 and the crackmes it's registered.
  216.  
  217. CONCLUSIONS
  218. ===========
  219.  
  220. Well, I have finally reached the end of this solution. I hope I haven't
  221. bored you...
  222. Another thing: sorry for my english, I know it's not very good... try to
  223. fly over this little bug, it may be fixed in a future release...
  224.  
  225. By(t)e
  226. The_Dux, 16 July 2K
  227.  
  228.