Target: CrackMe [id:12] Author: tC... Cracker: The AntiXryst [CrossOver] Rating: Not as easy as apple pie, but not hard at all. Better luck next time, tC... ! Used tools: WDASM 8.93, Hex Workshop Greetings to: Me, myself and I and everybody else I injured during my sadomasochistic games ;-) Hi there! Without explicit trying to be arrogant, I want to tell you that many people tried to crack this little nonsensical crackme and did fail. Now I want to show you that cracking Delphi programs is not that hard and complicated at all as you maybe have heard or experienced. You should know how programs written in Delphi are organized and why they are so huge even if they do not consist of anything but a small window with "Hello world!". Maybe as you already know, the tradition of Borland is to break with Microsoft's concepts and traditions and to reach the "aim" by completely different methods. In the case of the most popular programming languages coming from Inprise/Borland - Delphi and C++Builder - that's the same dilemma. Common standards like the usage of MFC and program data including window design stored in the resource section of an executable are simply ignored. Other commonly used strategies, e.g. for window creation, are replaced by own routines being absolutely incompatible to Microsoft standards. And exactly these routines make your (and mine, too) Delphi programs being huge harddisk and memory wasters. So, what exactly does a Delphi-born little suckin' motherfucker consist of? Answer: The whole VCL (Visual Components Library, not to mix up with Virus Creation Lab) is linked into the poor executable becoming an overweight monster. It usually goes from the code start up to somewhere $0043xxxx, sometimes up to $0044xxxx. Form data is, as I experienced this weird shit, sometimes stored in the code section of the executable or completely incompatible to Microsoft standards in a separate resource section (.rsrc). Although this VCL enables you a more or less easy and totally object- oriented GUI handling, it sometimes lacks in performance and sometimes doesn't let you "play" with particular window settings without using plain Win32 API. Another thing is that the whole handling of window messages is also done by the VCL. That's why sometimes the search for a special routine in SoftICE leads to long debugging orgies and head ache. Sometimes SoftICE ignores message breakpoints to controls placed on the window, this appears even without special debugging-preventive measures and can also be found in this crackme. Please do not fear that you will have to trace through the whole VCL in order to find some relevant routines, I found a very easy way to find the entry point of handling functions (in Delphi known as event routines). For this you just need a simple hex editor like Hex Workshop. Depending on how the programmer of a particular application called his window, you will often find an ASCII string of someting like "TForm1". So have I in this little funny crackme. A couple of lines above this string you'll find the names of handler functions, in our case I recognized them by names "Register1Click" and "Exit2Click" - these routines are handlers for clicks on the menu bar entries. Now, before "Register1Click" you'll see 6 Bytes: 00 14 62 44 00 0E. What do they stand for? 00 14 62 44 is the Little Endian notation for $00446214 - THIS IS OUR ROUTINE!!!! Just read these numbers from right to left... The other 2 bytes, hmmm, I don't know what they do exactly stand for - the zero as a separator between the procedure entry and its name, $0E maybe for the length of the procedure name. If you think this search is a bit too complicated, well, I plan to code a small handy tool which will work same as EXE2DPR (in pity I just have a very old trial version that doesn't work with Delphi 4 written code). After a disassembly in WDASM you should set a breakpoint to the address shown above. You may wonder why there is no cross reference to this address - my answer: because it is called via CALL [EAX]. If you launch the crackme from the integrated debugger, you should enter someting into the edit box, I entered "fuck Jesus"... If you now click on the menu item "Register", WDASM will stop at our breakpoint. Now, what did I say? This IS REALLY our routine! Now, the step of analyzing has to be done. I will NOT explain every single detail, I'll just show you what part of code does what in a syntactical mix of Pascal and ASM register calling... Code snippet $0044623F-$00446244: --------------------------------- [$004488D4]:=Length(Key); if Length(Key)=0 then Exit; Code snippet $00446258-$0044628E: --------------------------------- var index:Cardinal; for index:=1 to Length(Key) do [$00448874+index]:=Ord(Key[index]); Procedure $004461F0 (called from $00446290): -------------------------------------------- - performs a call to subroutine at $004461C0 - both routines do mutilate our entered key string - what the functions together do: var index:Cardinal; for index:=1 to Length(Key) do Key[index]:=Chr(((Ord(Key[index]) xor 3)*2)+8-index); In addition to that, a truncation is performed to 8 bit, if the value in Key[index] is greater than 256 (via MOVZX EBX, BL). Code snippet $00446295-$004462C8: --------------------------------- If you look at the index counter (in EDI), you'll see that our string must be $12 (decimal 18) chars long. Now, continue the run with F9 and enter the next time someting 18 chars long, like "Marilyn Manson 123". The mutilated string is stored, as far as I remember, at $004488C0 in this way (again Little Endian): D8 E7 CA A3 <--- 1st byte of manipulated string 46 DB F6 E1 DC D7 C2 9B 5C 3F D4 D3 00 00 56 59 <---------- read direction This code snippet does move the byte pairs and then does swap the bytes in the pairs. It works like that (symbolical example): A1 A2 | B1 B2 G2 G1 | I2 I1 C1 C2 | D1 D2 E2 E1 | H2 H1 E1 E2 | F1 F2 ------> C2 C1 | F2 F1 G1 G2 | H1 H2 A2 A1 | D2 D1 00 00 | I1 I2 00 00 | B2 B1 OK, you know now how it works. In $00C2D58 (look in $004488D8 what points to our string) you'll find the result of this byte shake: 3F 5C 59 56 D7 DC D3 D4 DB 46 9B C2 E7 D8 E1 F6 00 00 A3 CA <---------- read direction Code snippet $004462CA-$004462D9: --------------------------------- A compare of our poor little twisted and horribly mutilated key with constant values in $00446338 is performed via built-in Delphi routines. OK - thus the 18 constant values in the same form as above must con- tain the "real" unlock code. These are the constant values: C9 C4 D9 3A 7D DE BF BA D9 E2 CF 44 DD D2 49 EA 00 00 8F DE <---------- read direction Now it's up to you either to write a short decryption routine or to de-cipher these constants by the help of a calculator (calc.exe in scientific view is pretty good). OK OK OK, you're too lazy, me too, here's the unlock string: Good work Cracker! Just test it (do not forget the big "G" and the exclamation mark !!!). What does this crackme say? Yeah, I did it! ----------------------------------------------------------------------- I hope you have learned a little bit from this. Look out for my cracks: tutorials or source codes are included in most cases! Sincerely yours, The AntiXryst [CrossOver] Visit the newcoming cracking group I am the CoLeader of: http://crossover.tsx.org