August 18th 2000 A CRACKING TUTORIAL ON XARA3D v4.0 ,by Mikl0 This tutorial is divided in * * parts: 1. Introduction 2. Disclaimer 3. Brief info about Xara3D4 4. Cracking the time-trial protection 5. Cracking the compare-code protection (* Full Cracking! *) 6. Some extra info for nosy people 1. Introduction I welcome you my fellow crackers! This is a tutorial on cracking Xara3D v4.0. A few days ago I bought a magazine about "earning money with a webpage". This magazine learned me how I could make some money with a webpage. First I had to design and setup a webpage (of course). But this was a thing that I had already done even before cracking my first program. Building a webpage is not something I really like to do. But the magazine said it would be nice to make some 3D logo's and put it on the site. Disigning 3D logo's was a thing that I had never tried. Luckily there was a CD-rom included with a "FULL VERSION!" of Xara3D v2.0. And there was also a version 4.0 of Xara. included. But, of course, this was only a evaluation version. I was able to use this version for only 15 days. And then the cracking started......... 2. Disclaimer This tutorial is for educational purposes only. Some of the information in this tutorial can be used in a illegal way. But the author will, in no way, hold any responsibility for the illegal actions you take. 3. Brief info about Xara3D4 Xara3D4 is a nice program for designing 3D text images. You can make a 3D image in just a few seconds. And that with only a few clicks! I really like this program. You can view my first 3D logo's created with Xara3D on my webpage: go.to/Mikl0.(Please don't complain about my site. It may be a bit ugly. But that is because I never update it. I never update it because no one will ever bump on my little site. This site was just a store place for my cracking stuff. Here you will find some more tutorials written by me). Anyway I really like this program and I think I am going to order this program(what you also should do if you're planning to use this program for long term). I got this evaluation version from my CD-rom but you can also download this version from their webpage: http://www.xara.com/xara3d/ 4. Cracking the time-trial protection When cracking a program, it is always a good idea to explore the program first. Try making some images, read the help files, search for important strings etc, etc. So when I first started the program I noticed the NAG-screen with the text "You have 15 days remaining...blah blah blah". The NAG-screen had also two buttons. Of course there was a [Purchase] and a [Continue] button. After clicking the [Continue] button a few times(for exploring the program) I finally clicked the [Purchase] button. When exploring the [Purchase] window I noticed the "Key " string. This key is different on each pc. This key was created by doing some calculations on the setup of your harddisk. I know this by reading the help files. And on this window there is one text area for inputting your Unlock Code with an [Unlock] button under it. By reading the help files I know this Unlock Code is created from the key above. And the Unlock code should be 7 letters, all in uppercase. So I 'guessed' one...I guessed wrong(what do you think?), too bad. The program shows me an error message("You entered an invalid unlock code"). Now I fired up W32dasm(my disassembler) and disassembled Xara3D4 with it. At this point I should first search for the error string but no String Data References were available. And there also wasnt a disassembling of the file. Maybe the program is packed. So what now? Here I decided to explore the program with SoftICE(my windows debugger). Using SoftICE requires some good thinking... So first some theory: When starting the program it tells me that I have 15 days left for trying. When I change the date on my computer one day forward it tells me that I have 14 days left for trying. So the program is counting your days till evaluating. Now I changed my date 15 days forward. This way the program knows he must stop letting me use this program for trying. How does it know when one day is passed? How does it know when to stop letting me use the program? When searching my Win API help files for appropriate API's I found "GetLocalTime" and "GetSystemTime". These API's we can use in SoftICE. Cause the program uses one of these API's to get the date on your computer. And from this date he can count how much days you already tried the program and how much days are left till evaluating. Isn't it logical? So I set the date on the original time so I have 15 days left. Now I first tried the GetLocalTime API. I jumped into SoftICE with Control-D and put a breakpoint on GetLocalTime. "bpx " is the syntax for this. I won't go much into details for using SoftICE in this tutorial. There are many good resources for this. After putting the breakpoint I returned to the program with Crtl-D. Now I started X3D.exe again and, as expected, I was returned into SoftICE in no time. This is due to the fact that windows has called the "GetLocalTime" API function call. As I don't wanted to be in the API function call(because it's not ME that wants to get the actual date) I pressed F11 a few times till I was in X3D.exe's code. I can see this at the bottom of SoftICE. Then I was here: 0157:00480519 FF1500A24B00 CALL [KERNEL32!GetLocalTime] <--We broke here 0157:0048051F 8D45E0 LEA EAX,[EBP-20] <--We are here after F11-ing 0157:00480522 50 PUSH EAX 0157:00480523 FF15F8A14B00 CALL [KERNEL32!GetSystemTime] 0157:00480529 668B45EA MOV AX,[EBP-16] 0157:0048052D 663B05C2B05200 CMP AX,[0052B0C2] 0157:00480534 753B JNZ 00480571 0157:00480536 668B45E8 MOV AX,[EBP-18] 0157:0048053A 663B05C0B05200 CMP AX,[0052B0C0] 0157:00480541 752E JNZ 00480571 0157:00480543 668B45E6 MOV AX,[EBP-1A] 0157:00480547 663B05BEB05200 CMP AX,[0052B0BE] 0157:0048054E 7521 JNZ 00480571 When I first broke into SoftICE I was in the CALL to "GetLocalTime". So I kept pressing F11 until I was out of the call. Now I was in the code of X3D and just under the CALL to "GetLocalTime" function. I saw that it also uses the "GetSystemTime" API so I would also break in SoftICE when I put a breakpoint on this API. I suddenly remembered that I had 15 days to try the nice program. And after those 15 days the program would be evaluated. So it was most certainly that the program would, somewhere in the code, compare to . Since I know that SoftICE gives me the code in assembler(and assembler uses hex digits) I am looking for an asm instruction like: CMP , 0F My_used_days will most certainly be put in a register. And since we are looking in hex we aren't looking for the 15 but for: 0F(this is 15 in hex). Now I kept pressing F10 in SoftICE. This will execute the instructions one by one. Pressing and pressing until I reach something like: CMP , 0F. I pressed about 150 times. This seems much but your CPU executes thousands of instruction in just about milliseconds. And then I saw, again as expected, this piece of code: 0157:0041F29C 83FA0F CMP EDX,0F <--This was as suspected 0157:0041F29F C644241300 MOV BYTE PTR [ESP+13],00 0157:0041F2A4 7C05 JL 0041F2AB <--After a compare comes a jump The "CMP EDX,0F" was expected. This instruction compares the days I used the program to 15. I checked this in SoftICE. I did "? EDX" on the commandline to see what was in the register EDX. And since I was only testing the program on the first day, EDX was equal to 0(zero). That is the number of used days. And then I did "? 0F" to see what 0F means. And the outcome was this: :? 0F 0000000F 0000000015 "¤" First SoftICE shows the digit in hex(0F) and then in decimal(15) and then in ASCII(¤). Two instructions after the compare comes the jump. JL means "Jump If Less". So in human readable words the instructions do this: compare the number of days used to 15(the number of days I may try the program) jump if less to ... Where will it jump to if it is less? Well, since I may keep using the program if my number of days used is less than 15, it is not hard to guess that it will jump to the instructions that will continue the program. And that is what I was planning to do. Make the program NOT evaluating! Not even if the 15 days are over. So this crack is ease as hell. Just change the "Jump If Less" to "Always Jump!!!". In assembler that is the "JMP" instruction. So now I knew WHAT I had to patch to WHAT. But WHERE did I had to patch? In order to know this I right-clicked on the JL-address. And chose "Display". Now on top of the data window it show me the address of the JL-address(this is also the address to patch). I did all this in SoftICE. The address was: "TEXT+1E2A4". But what is TEXT? This is the address of the text code. I could find this address when I disassembled the program. This is what is had: Disassembly of File: x3d.w32 Code Offset = 00001000, Code Size = 000B2000 Data Offset = 000E5000, Data Size = 00009000 Number of Objects = 44799 (dec), Imagebase = 8BFFFFF5h Object01: .text RVA: 00001000 Offset: 00001000 Size: 000B2000 Flags: 60000020 <--Look here! Object02: WCODE RVA: 000B3000 Offset: 000B3000 Size: 00007000 Flags: E0000020 Object03: .rdata RVA: 000BA000 Offset: 000BA000 Size: 0002B000 Flags: 40000040 Object04: .data RVA: 000E5000 Offset: 000E5000 Size: 00009000 Flags: C0000040 Object05: .rsrc RVA: 0012E000 Offset: 000EE000 Size: 0002F000 Flags: 40000040 I wanted to know the code offset address of text. And I could see here that that was: 1000. So adding 1000 and 1E2A4 I get: 1F2A4(the address to patch!). Now I fired up Hiew(my hex-editor) and loaded X3D.exe. Now I pressed F4 and chose "Decode". And then I pressed F5 and entered the address 1F2A4. here I saw the same code as in SoftICE. The JL instruction. To edit this jump I pressed F3. Now I can patch this jump in hex-code. The JL instruction in hex is: 7C. I wanted to edit to the JMP instruction. And that in hex is: EB. So I entered EB and pressed F9 to save it. What will the program do now? It will still check to <15> because I never changed this instruction. But I patched the jump after it so it will ALWAYS jump!!!. Now I checked this by editing the actual date on my computer. I changed the date one year further. And now I started X3D.exe again. And still the NAG was shown. But now with the text: "You have -350 days remaining...blah blah blah". And I could still keep using the program. Even after one year!!! So the program was cracked... But the NAG was still shown and the background still had the X3D logo and couldn't be changed. So I was still using the program in evaluation period. All this wouldn't happen if the program was only registered... wanna know more? .....read further..... 5. Cracking the compare-code protection (* Full Cracking! *) You noticed it. In the last section I only cracked the time-trial protection. This way the program is cracked and can still be used after trying for 15 days. But the program still remains in evaluation period. So the NAG still will be shown.... To make the program registered we have to crack the compare-code routine(which is a bit harder) That is the routine the program takes when you enter an Unlock Code. So I am gonna take some more action...!!! For cracking this protection I first copied the patched exe to another filename. This way I can use the unpatched X3D.exe. I started X3d.exe again and pressed the [Purchase] button. Here I entered my dummy code of 7 chars I entered: "MIKLORZ". But before entering I put a breakpoint "GetwindowTextA" in SoftICE. This breakpoint is used to get text from a dialogbox. Now I pressed the [Unlock] button and got kicked back into SoftICE. I pressed F11 to get to the caller, which of course is, X3D.exe. Who else? I was here in SoftICE: 0157:004A01F8 FF15B8A44B00 CALL [USER32!GetWindowTextA] 0157:004A01FE 8B4D10 MOV ECX,[EBP+10] <-- Move what is returned to: ECX 0157:004A0201 6AFF PUSH FF 0157:004A0203 E81697FFFF CALL 0049991E 0157:004A0208 EB0B JMP 004A0215 I was at the "MOV ECX,[EBP+10]". This instruction moves something to the register ECX. What does it move to ECX? This instruction is just after the CALL to GetWindowTextA so it most likely moves the string that is returned from the API, which is my dummy code(MIKLORZ). To check this I pressed F10 one time to let ECX get the returning. And then entered "d ecx" on the commandline of SoftICE. This dumps the data at the address that the ECX register holds. I saw this in the data window: 015F:0078F64C FC E1 EE 00 FC E1 EE 00-8C 01 A4 01 CC 2F 02 00 .C.........../.. <-address of ECX 015F:0078F65C 30 B3 02 00 00 00 00 00-6F 2B 78 86 88 86 58 25 0.......o+x...X% 015F:0078F66C BF 17 01 00 16 87 3F 3B-8C 01 A4 01 30 B3 02 00 ......?;....0... 015F:0078F67C D4 B2 02 00 00 00 00 00-00 00 00 00 A8 86 58 25 ..............X% 015F:0078F68C BF 17 01 00 16 87 3F 3B-8C 01 A4 01 D4 B2 02 00 ......?;........ 015F:0078F69C 00 00 58 4E 26 87 40 23-D7 17 01 00 00 00 C1 A6 ..XN&.@#........ 015F:0078F6AC F8 00 22 01 10 57 4D 00-01 00 00 00 00 00 00 00 .."..WM......... 015F:0078F6BC 00 00 00 00 00 00 00 00-01 00 00 00 00 00 00 00 ................ 015F:0078F64C is the address that holds the data. And then comes the hex(16 bytes) and then SoftICE gives me this in ASCII(that is on each line). But I didn't see my dummy code anywhere? Why not? This is because ECX did NOT hold the offset address of my dummy code. But ECX POINTS to the address of my dummy code. To check this I did: "d 00EEE1FC" (see the first 4 bytes at the address. But the bytes are in reversed order. Always remember that the CPU saves date in reverse bytes!) So "d 00EEE1FC" gives me: 015F:00EEE1FC 4D 49 4B 4C 4F 52 5A 00-53 65 72 69 66 00 2E 00 MIKLORZ.Serif... 015F:00EEE20C 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 015F:00EEE21C 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 015F:00EEE22C 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 015F:00EEE23C 00 00 00 00 90 E2 EE 00-17 00 00 00 40 00 00 00 ............@... 015F:00EEE24C 58 61 72 61 33 44 34 20-2D 20 4B 65 79 20 4E 48 Xara3D4 - Key NH 015F:00EEE25C 52 46 44 43 44 46 42 00-00 00 00 00 00 00 00 00 RFDCDFB......... 015F:00EEE26C 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ Yes! So ECX did hold the offset address of my dummy code address? Do you follow me? I know it may be a bit complicated but that is just how assembler works. Data addressing in asm is one of the hardest thing to get used to. But it is needed. So after dumping the address that ECX pointed to I get my dummy code. I also noticed my key under it. The mine was "NHRFDCDFB". This is not on all computers the same(the help files told me). Now I don't want to trace all the way down so it is a good idea to set a breakpoint on memory on the dummy string. I did it with this: bpr EEE1FC EEE1FC+6 RW. This is a breakpoint on memory FROM the address EEE1FC TO EEE1FC(my code is 7 bytes long) on READ and WRITE access. So SoftICE would break whenever something was read from or written to one of the bytes of my dummy code. After setting the breakpoint I pressed F5 to let the program continue. I was kicked back into SoftICE immediately. At this piece of code: 0157:BFF7117E F2AE REPNZ SCASB <-- Here was the cursor! 0157:BFF71180 83C8FE OR EAX,-02 0157:BFF71183 2BC1 SUB EAX,ECX 0157:BFF71185 5F POP EDI 0157:BFF71186 59 POP ECX 0157:BFF71187 C9 LEAVE 0157:BFF71188 C20400 RET 0004 SoftICE broke at this point so something was done with my dummy code. This is a little function to get the length of a string. The API: lstrlen. To make sure I got out of the code by pressing F11 a few times. I did see the lstrlen API. Of course the program check if the code is 7 chars long. It was said in the help files. It also had to be in UPPERCASE. Let's check by pressing F5. And again I was back into SoftICE: 0157:0041F6C5 0F85FF010000 JNZ 0041F8CA -= Here I was =- 0157:0041F6CB 0FBE10 MOVSX EDX,BYTE PTR [EAX]<--Move first byte of string in EDX 0157:0041F6CE 52 PUSH EDX <--Save EDX for later use 0157:0041F6CF E814CD0500 CALL 0047C3E8 <--Call routing to check letter 0157:0041F6D4 83C404 ADD ESP,04 <--Restore stack(not important now) 0157:0041F6D7 85C0 TEST EAX,EAX <--Test something 0157:0041F6D9 0F84EB010000 JZ 0041F8CA <--Jump if EAX is zero 0157:0041F6DF 8B842444010000 MOV EAX,[ESP+00000144] 0157:0041F6E6 0FBE4801 MOVSX ECX,BYTE PTR [EAX+01] 0157:0041F6EA 51 PUSH ECX 0157:0041F6EB E8F8CC0500 CALL 0047C3E8 0157:0041F6F0 83C404 ADD ESP,04 0157:0041F6F3 85C0 TEST EAX,EAX 0157:0041F6F5 0F84CF010000 JZ 0041F8CA 0157:0041F6FB 8B942444010000 MOV EDX,[ESP+00000144] 0157:0041F702 0FBE4202 MOVSX EAX,BYTE PTR [EDX+02] 0157:0041F706 50 PUSH EAX 0157:0041F707 E8DCCC0500 CALL 0047C3E8 0157:0041F70C 83C404 ADD ESP,04 0157:0041F70F 85C0 TEST EAX,EAX 0157:0041F711 0F84B3010000 JZ 0041F8CA 0157:0041F717 8B8C2444010000 MOV ECX,[ESP+00000144] 0157:0041F71E 0FBE5103 MOVSX EDX,BYTE PTR [ECX+03] Next piece of code. Short analyzis: EAX points to the dummy string then move first byte of dummy string(in my case the letter "M") to EDX then push EDX for later use then call a routine to make sure that the char is a letter and that it is in UPPERCASE! then check it if it is NOT, then jump to error messages if it is, then do the same with next letter and so on... I hope this is clear for you all. My dummy code was 7 chars and it were all in uppercase so I know my dummy code passes this one. So I kept pressing F10 till all the letters were checked. And here I was: 0157:0041F787 8BC5 MOV EAX,EBP 0157:0041F789 8BCD MOV ECX,EBP 0157:0041F78B D1E8 SHR EAX,1 0157:0041F78D 2555555555 AND EAX,55555555 0157:0041F792 81E155555555 AND ECX,55555555 0157:0041F798 8D0C48 LEA ECX,[ECX*2+EAX] 0157:0041F79B 8B842444010000 MOV EAX,[ESP+00000144] 0157:0041F7A2 69C915DE7856 IMUL ECX,ECX,5678DE15 0157:0041F7A8 8A5801 MOV BL,[EAX+01] 0157:0041F7AB 8A5003 MOV DL,[EAX+03] 0157:0041F7AE 885C2432 MOV [ESP+32],BL 0157:0041F7B2 8A18 MOV BL,[EAX] 0157:0041F7B4 885C2430 MOV [ESP+30],BL 0157:0041F7B8 8A5805 MOV BL,[EAX+05] 0157:0041F7BB 885C2431 MOV [ESP+31],BL 0157:0041F7BF 8A5802 MOV BL,[EAX+02] 0157:0041F7C2 885C2433 MOV [ESP+33],BL 0157:0041F7C6 8A5806 MOV BL,[EAX+06] 0157:0041F7C9 0FBE4004 MOVSX EAX,BYTE PTR [EAX+04] 0157:0041F7CD 0FBEF3 MOVSX ESI,BL 0157:0041F7D0 8D0440 LEA EAX,[EAX*2+EAX] 0157:0041F7D3 0FBED2 MOVSX EDX,DL 0157:0041F7D6 8D04C6 LEA EAX,[EAX*8+ESI] 0157:0041F7D9 0FBE742433 MOVSX ESI,BYTE PTR [ESP+33] 0157:0041F7DE 8D0440 LEA EAX,[EAX*2+EAX] 0157:0041F7E1 8D04C6 LEA EAX,[EAX*8+ESI] 0157:0041F7E4 0FBE742431 MOVSX ESI,BYTE PTR [ESP+31] 0157:0041F7E9 8D0440 LEA EAX,[EAX*2+EAX] 0157:0041F7EC 8D04C6 LEA EAX,[EAX*8+ESI] 0157:0041F7EF 0FBE742430 MOVSX ESI,BYTE PTR [ESP+30] 0157:0041F7F4 8D0440 LEA EAX,[EAX*2+EAX] 0157:0041F7F7 8D04C6 LEA EAX,[EAX*8+ESI] 0157:0041F7FA 0FBE742432 MOVSX ESI,BYTE PTR [ESP+32] 0157:0041F7FF 8D0440 LEA EAX,[EAX*2+EAX] 0157:0041F802 8D04C6 LEA EAX,[EAX*8+ESI] 0157:0041F805 8D0440 LEA EAX,[EAX*2+EAX] 0157:0041F808 8D84C267216BFB LEA EAX,[EAX*8+EDX+FB6B2167] 0157:0041F80F 3BC1 CMP EAX,ECX 0157:0041F811 0F85B3000000 JNZ 0041F8CA This is understandable? Maybe not for some people but it is for me. This is a calculation of the dummy code. And the last two lines compares the result to another code and then jumps if they are not equal. The result is in EAX. And EAX is compared to ECX. Where did ECX come from? Well, it is most likely calculated from the key that was given before. If you are not sure if what I say is true then you just have to believe me. It is really true. At this point we can crack the program by patching the jump again. This jump would jump if the two results aren't the same so I simply changed the "CMP EAX,ECX" to "CMP EAX,EAX". Now it would compare the register EAX with itself so I will always give a good result! And the crack was done. Now I could enter any dummy code and the program remains registered! The AG was even removed and the background didn't had the X3D4 logo anymore! So I was happy and the job was done. 6. Some extra info for nosy people The crack was fun and I am done! Yes, now the program is and remains registered. But this doen't mean that I must stop exploring the program. It's always fun to play some more with the program. Maybe I will discover other fun things that I can do with the program. But before I can explore the program again I have to Unregister the program. This can be done by removing a key in the windows register. It is the regedit.exe in the windows directory. And the key that should be removed is: [HKEY_CURRENT_USER\Software\Xara] After removing this key in regedit.exe Xara3D4 is unregistered again(what a shame huh?). I did this and started to write generic patchers for Xara. The generic patchers aren't meant for stupid people who just want a registered copy of xara without paying for it(however, this is possible). But I wrote these patchers for educational purposes only. And because I just love programming. I coded a patcher in pascal and I coded one in c. Both are available in the same directory that this tutor is in. The source code for these patchers are both very simple. I also put some comments in the source so anyone can understand how the patchers work. I thank you for reading this tutorial and I hope you learned something from it, Mikl0