Welcome to Cracking Tutorial #48! A nice rainy day today, good time to finish this tutor :) OK, let's go! You'll need the following tools: (I use these tools, I assume you'll use 'em, but it doesn't mean that you'll need to use all those tools, so be sure to get them handy for the examples in this tutorial!) SoftICE 4.01 W32Dasm 8.93 Hacker's View 6.20 SmartCheck 6.03 TASM 5.00 Windows Commander 4.01 (I use it coz of easier to multitask) Don't ask me where to download all these tools since you had a chance to get them when you used my older tutorials. Here is a good site where you can grab tools from: http://protools.cjb.net/ or ask any crackers to get you these tools! Are you ready?! OK! ;) tARGET pROGRAM : JPEG Optimizer 3.07 pROTECTION : Registration Code that is hard-coded uRL : http://www.xat.com/ pROGRAM sIZE : 385 KB tOOLS uSED : - W32Dasm 8.93 - SoftICE 4.01 (Optional) dESCRIPTION : JPEG Optimizer is designed to create the smallest possible JPEG image files savings of up to 50 % in the file size are possible, which can considerably decrease Web Page download times and save on disc space. cOMPILED bY : Borland C++ rEGISTRATION fEE : $29 Hi Again! I hope you will enjoy my second TuT and helps you learn more! Install the program. Live Approach: Run it! at the main window caption we see the #1 magic word "UNREGISTERED" . Now, Go Help/Register and put a fake registration code. I entred: 11223344, DO NOT PRESS ANYTHING YET, Press CTRL-D, Type bpx GetDlgItemTextA to break when that function is called . CTRL-D again or F5 to return in JO. Click on " Register ". and we get the message "Icorrect registration code", Hmmm! Nothing's happened, ok anyway So CTRL-D again, this time type bpx GetWindowTextA. F5, Click on "Register!" Nothing's happened too, seems like the program doesn't use those API's Call, Hmmmm Let's think a little bit, so if we break at HMemCpy, it goes to take a lot of time to crack it, about 19 times pressing F12 and several F10 hits, so do BC* under SoftICE to clear all breakpoints then X. Dead Listing Approach: So let's change our approch to dead listing. Launch W32Dasm, and disassemble the program , and search for the message "Icorrect registration code",we didn't find it :( so do another search for all the strings linked to the registration, and we found ... " - Unregistered" one reference, so Dblclick on it: * Possible StringData Ref from Data Obj ->" - Unregistered" <--- We land here. | :00404759 BABF864700 mov edx, 004786BF :0040475E 8D8568FFFFFF lea eax, dword ptr [ebp+FFFFFF68] :00404764 E8DB460400 call 00448E44 :00404769 FF8548FFFFFF inc dword ptr [ebp+FFFFFF48] :0040476F 33C0 xor eax, eax :00404771 898564FFFFFF mov dword ptr [ebp+FFFFFF64], eax :00404777 8D9568FFFFFF lea edx, dword ptr [ebp+FFFFFF68] :0040477D FF8548FFFFFF inc dword ptr [ebp+FFFFFF48] :00404783 8D8D64FFFFFF lea ecx, dword ptr [ebp+FFFFFF64] :00404789 58 pop eax :0040478A E86C490400 call 004490FB As always, we must look before that Ref for CCJ (Call+Compare+Jump) , so scroll up a little bit, to understand what is done before, and * Referenced by a (U)nconditional or (C)onditional Jump at Address: <-- we are here |:00404712(U) | :00404719 51 push ecx :0040471A E8C5570200 call 00429EE4 C <-- Call :0040471F 59 pop ecx :00404720 84C0 test al, al C <-- Test :00404722 0F85E8010000 jne 00404910 J <-- Jump if not equal jump :00404728 66C7853CFFFFFFA001 mov word ptr [ebp+FFFFFF3C], 01A0 :00404731 33C0 xor eax, eax :00404733 89856CFFFFFF mov dword ptr [ebp+FFFFFF6C], eax :00404739 8D956CFFFFFF lea edx, dword ptr [ebp+FFFFFF6C] :0040473F FF8548FFFFFF inc dword ptr [ebp+FFFFFF48] :00404745 8B3D98434800 mov edi, dword ptr [00484398] :0040474B 8BC7 mov eax, edi :0040474D E85ADC0300 call 004423AC :00404752 8D956CFFFFFF lea edx, dword ptr [ebp+FFFFFF6C] :00404758 52 push edx As crackers, we draw the conclusion that the call in 40471A is the one we after, let's verify that by executing it. * Referenced by a CALL at Addresses: |:0040471A , :00429355 <-- This procedure is called twice | :00429EE4 55 push ebp <-- We land here :00429EE5 8BEC mov ebp, esp :00429EE7 83C4F8 add esp, FFFFFFF8 :00429EEA 53 push ebx :00429EEB 8B4508 mov eax, dword ptr [ebp+08] <-- Put serial in EAX :00429EEE 8D5DF8 lea ebx, dword ptr [ebp-08] <-- Prepare the place for Duplication :00429EF1 8A10 mov dl, byte ptr [eax] ŽŽ\ :00429EF3 8813 mov byte ptr [ebx], dl \ :00429EF5 8A4801 mov cl, byte ptr [eax+01] \ :00429EF8 884B01 mov byte ptr [ebx+01], cl \ :00429EFB 8A5002 mov dl, byte ptr [eax+02] \ :00429EFE 885302 mov byte ptr [ebx+02], dl \ Duplicates our :00429F01 8A4803 mov cl, byte ptr [eax+03] / serial into EBX :00429F04 884B03 mov byte ptr [ebx+03], cl / :00429F07 8A5004 mov dl, byte ptr [eax+04] / :00429F0A 885304 mov byte ptr [ebx+04], dl / :00429F0D 8A4005 mov al, byte ptr [eax+05] / :00429F10 884305 mov byte ptr [ebx+05], al ŽŽ/ :00429F13 0FBE0B movsx ecx, byte ptr [ebx] <-- Put our 1st char in ECX :00429F16 51 push ecx <-- Save our 1st char :00429F17 E86C590400 call 0046F888 <-- Upcasing our 1st char (Seems like to be a Letter) :00429F1C 59 pop ecx <-- Restore our 1st Letter :00429F1D 83F841 cmp eax, 00000041 (1) <-- Compare it with 1st Lettre of the real serial :00429F20 7547 jne 00429F69 <-- If not equal then jump to Unregistered :00429F22 0FBE4301 movsx eax, byte ptr [ebx+01] <-- Put our 2nd char in EAX :00429F26 50 push eax <-- Save our 2nd char :00429F27 E85C590400 call 0046F888 <-- Upcasing our 2nd char (Seems like to be a Letter) :00429F2C 59 pop ecx <-- Restore our 2nd Letter :00429F2D 83F859 cmp eax, 00000059 (2) <-- Compare it with 2nd lettre of the real serial :00429F30 7537 jne 00429F69 <-- If not equal then jump to Unregistered :00429F32 0FBE5302 movsx edx, byte ptr [ebx+02] <-- Put our 3rd char in EDX :00429F36 83FA38 cmp edx, 00000038 (3) <-- Compare it with 3rd char of the real serial (Seems like to be a Number) :00429F39 752E jne 00429F69 <-- If not equal then jump to Unregistered :00429F3B 0FBE4B03 movsx ecx, byte ptr [ebx+03] <-- Put our 4th char in ECX :00429F3F 83F931 cmp ecx, 00000031 (4) <-- Compare it with 4th char of the real serial (Seems like to be a Number) :00429F42 7525 jne 00429F69 <-- If not equal then jump to Unregistered :00429F44 0FBE4304 movsx eax, byte ptr [ebx+04] <-- Put our 5th char in EAX :00429F48 83F832 cmp eax, 00000032 (5) <-- Compare it with 5th char of the real serial (Seems like to be a Number) :00429F4B 751C jne 00429F69 <-- If not equal then jump to Unregistered :00429F4D 0FBE5305 movsx edx, byte ptr [ebx+05] <-- Put our 6th char in EDX :00429F51 83FA34 cmp edx, 00000034 (6) <-- Compare it with 6th char of the real serial (Seems like to be a Number) :00429F54 7513 jne 00429F69 <-- If not equal then jump to Unregistered :00429F56 C705284B48001443FC69 mov dword ptr [00484B28], 69FC4314 :00429F60 E8B7AAFDFF call 00404A1C :00429F65 B001 mov al, 01 :00429F67 EB1B jmp 00429F84 Pkew! so : 1st : the serial must be six chars 2nd : the 1st and the 2nd char must be letters, and the others numbers. so here it: (1) (2) (3) (4) (5) (6) Hex 41 59 38 31 32 34 Dec A Y 8 1 2 4 Look like there is one universal serial,If we enter it and go to About, it says the #2 magic word "REGISTERED". I'll let you to do a keygen! ok! and if you do so, please send it to me!. For the final touch! here is freeware called Ascii Table it can help you a lot, the url : http://users.southeast.net/~rhwarner/software/software.html Ending: ŽŽŽŽŽŽ Well, that's that. I hope you could follow it all, For any comments or if there's anything that I didn't explain too well then don't hesitate to mail me at: tBS@iquebec.com. Face of the Day: ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ (ε©’) ˆύ‹ύˆ \^/ When I was in military. Greetingz to: tKC , NETRUNNER , MinIfoo , apoKalipse , wAvEr , Ivanopulo , rEd , schUmU , TeeJi , and all the crackers around the world Special Greetingz to: DaVinci , Nitallica , LagPRO , Socko , Fli7e , DnNuke , and all the GfXs around the world Extra Greetingz to : CoOkIeE , Marta , CeLLuLaiR and all the ATGIHL around the world I would like to thankx tKC for his kindness and all the members of CiA How To Code A KeyGen A Lesson For Newbies By: Cardenal Mendoza Introduction ------------------------------------------------------------------- This time I will teach you how to code a very simple keygen. The essay I wrote is one year old, so it is time for a new, is it? OK, this time you will need SoftIce (of course!), W32dasm or IDA for making a dead listing, and a c++ compiler. I will use Borland Turbo C++ 3 :-) I know it is pretty old, but I have buyed a legal (!) copy of it for 15 $. And for our purpose it will be enough. Oh, of course you need GIF Movie Gear 2.63, our target. You can download it at www.gamani.com. If you use only SoftIce and not W32dasm you should have pen and paper, too. Don't ask me where to get these tools, ask you local software dealer ;-) I will assume that you know how to use SoftIce, W32dasm and your compiler. If not, go out and by a good book. Finding The Reg Routine ------------------------------------------------------------------- When you run the target, a silly nag pops up, probably a bug. So let us do a bit of debugging. Fire up SoftIce and run the target. Click a little bit around, and search some dialog where you can enter your name and a serial. Try to search under the menu, ;-) Type in your name and a dummy serial. Of course your serial is not the right one. If it is, wow, that is what I call zen cracking ;-) Lets try the default breakpoints. I think GetWindowTextA and GetDlgItemTextA will do good. With this two breakpoints, try to reg again. And, what a surprise, SoftIce pops up. Wait for the second call to GetWindowTextA and disable all breakpoints. Now you should see something like this: 0xxx:0042C33F lea ecx, [esp+78] ; ecx = our fake serial 0xxx:0042C343 lea edx, [esp+14] ; edx = our name 0xxx:0042C347 push ecx ; push our fake serial 0xxx:0042C348 push edx ; push our name 0xxx:0042C349 call 0042C0C0 ; call the reg routine 0xxx:0042C34E add esp, 8 ; add 8 to esp 0xxx:0042C351 test eax, eax ; is eax == 0? 0xxx:0042C353 jz 0042C3FF ; if yes, jmp bad_boy :-( I think this should be all clear. If not you should learn assembly. So we found our routine. Getting One Valid Serial ------------------------------------------------------------------- Before we code the keygen, we should fish one valid serial out of SoftIce. Step into the call and further. Always look what the code does. At first it compares the first char of our serial with 'm' if it is not equal, it jumps to the end of the routine. But before we follow this jump, because our serial probably starts not ith a 'm', look a little bit further. The code after it compares the second char with 'v', the third with 'g' and the fourth with '2'. If they aren't equal, our serial is wrong. OK, type in a new serial which starts with 'mvg2'. Step again in the call. You should pass all the compares without problems. No we get to this piece of code: 0xxx:0042C0F0 mov ebx, 004462A8 ; ebx = ptr to a serial 0xxx:0042C0F5 mov edx, dword ptr [ebx] ; edx = a serial 0xxx:0042C0F7 or ecx, FFFFFFFF ; 0xxx:0042C0FA mov edi, edx ; edi = a serial 0xxx:0042C0FC xor eax, eax ; eax = 0 0xxx:0042C0FE repnz 0xxx:0042C0FF scasb ; load serial 0xxx:0042C100 not ecx 0xxx:0042C102 dec ecx 0xxx:0042C103 mov edi, edx ; the serial 0xxx:0042C105 mov esi, ebp ; our fake serial 0xxx:0042C107 xor eax, eax ; eax = 0 0xxx:0042C109 repz ; while byte ptr!= 0 0xxx:0042C10A cmpsb ; cmp edi, esi 0xxx:0042C10B je 0042C172 ; jmp bad_boy if equal 0xxx:0042C10D add ebx, 00000004 ; ebx += 4 0xxx:0042C110 cmp ebx, 0044635C ; ebx==offset last serial 0xxx:0042C116 jl 0042C0F5 ; if not jmp 0042C0F5 So what does this code do? It is easy, it just compares our serial with some other serials. So this serials are the right? Of course not, havn't you read my comments? ;-) They are all not legal ones. The programmer have searched the web for such cracker serials and if a serial is equal to one of them, it is always wrong. Instead of searching the net for cracks for their own programme, they should have coded a better protection! But they are so lazy. Therefore it would be senseless to publish a single serial, because next version it would be black-listed, but we are going to do a keygen :-) Just go on stepping. Now your fourth char is compared with 's'. Why? If it has a 's' as the fourth char it is a serial for the site license of the application. Of course we want to have that ;-) So replace the fourth char of your serial with a 's' and step again until you get to this point. Now the programme changes the pointer to our serial. It is esp, it skipps the first 7 ( or 6 if you have no site license ) chars. Ok, then a call follows. Overstep it, it only moves the serial in [eax]. But what does this mean? It simply means, that the 5th, 6th and 7th char could be anything you want. So we can give our serial a signature. I use eVC because it is my group, but you can use any 3 chars you want, of course you could use numbers, too. So after the call there is someting moved to edx. Guess what it is, it is our name! So we are near the bitchs nest! 0xxx:0042C12F mov edi, edx ; edi = our name 0xxx:0042C131 xor ecx, ecx ; ecx = 0 0xxx:0042C133 mov dl, byte ptr [edx] ; dl = name[0] 0xxx:0042C135 mov esi, 000006FE ; esi = 1790 0xxx:0042C13A test dl, dl ; dl == 0 0xxx:0042C13C je 0042C164 ; jmp to the cmp 0xxx:0042C13E movsx edx, dl ; edx = name[0] 0xxx:0042C141 inc ecx ; ecx = 1 0xxx:0042C142 imul edx, ecx ; edx *= ecx 0xxx:0042C145 add esi, edx ; esi = edx 0xxx:0042C147 cmp esi, 00000DFD ; esi <= 3581? 0xxx:0042C14D jle 0042C155 ; if not 0xxx:0042C14F sub esi, 00000DFD ; esi -= 3581 0xxx:0042C155 cmp ecx, 0000000A ; ecx == 10? 0xxx:0042C158 jle 0042C15C ; if yes 0xxx:0042C15A xor ecx, ecx ; ecx = 0 0xxx:0042C15C mov dl, byte ptr [edi+01] ; dl = next char 0xxx:0042C15F inc edi ; edi += 1 0xxx:0042C160 test dl, dl ; dl == 0? 0xxx:0042C162 jne 0042C13E ; if not loop 0xxx:0042C164 cmp esi, eax ; esi == eax? 0xxx:0042C166 jne 0042C172 ; if not jmp bad_boy I think with my comments this loop is easy to understand, too. At the point 0042C164 do a '? esi' and you see the second part of your serial. So, if you understand the loop completly, we could make the keygen, right?? Coding The Keygen ------------------------------------------------------------------- We will use C++, of course asm is better and normally I code my keygen's in w32 asm, but it is not so easy to understand, and since this text is for newbies... So how is a keygen build up? First we must show a logo. I think this is easy, is it? Then we must get the username, I will use gets() for this purpose. Then we will calculate the second part of the serial and print it our, with a 'mvg2seVC' in front of it. See my source code and mail me if you couldn't understand all: #include #include #include int main() { char n[255]; long ebx = 0, ecx = 0, edx = 0, esi = 0x6FE; cout << " *KeyGen*" << endl; cout << " By Cardenal Mendoza" << endl; cout << " ----------------------" << endl; cout << " !rEAD tHE .nFO!" << endl << endl; cout << "Please enter your name: "; gets( n ); if( strlen(n)==0 ) { cout << "You should enter a name!"; return 0; } for( int i = 0; i < strlen(n); i++) { ecx++; edx = n[i]; ebx = ecx; ebx *= edx; esi += ebx; if( esi > 0xDFD ) esi -= 0xDFD; if( ecx > 0xA ) ecx = 0; } cout << "Your serial is : mvg2seVC" << esi; cout << endl << endl << "Another KeyGen coded by Cardenal Mendoza..."; return 0; } This source code is really easy and not optimized. But you should understand it. In the appendix I will give you a optimized version. Outro ------------------------------------------------------------------- Ok, this is it for this time. I hope you learned something. If you want another tutor mail me. Of course you can also mail me flames, criticism, or any other things. But please no spam and mail bombs. I will trace you, trust me ;-) :13/10/99 Cardenal Mendoza [EVC]: Appendix ------------------------------------------------------------------- #include #include #include int main() { char n[255]; long ecx = 0, esi = 0x6FE; cout << " *KeyGen*" << endl; cout << " By Cardenal Mendoza" << endl; cout << " ----------------------" << endl; cout << " !rEAD tHE .nFO!" << endl << endl; cout << "Please enter your name: "; gets( n ); if( strlen(n)==0 ) { cout << "You should enter a name!"; return 0; } for( int i = 0; i < strlen(n); i++) { ecx++; esi += ecx*n[i]; if( esi > 0xDFD ) esi -= 0xDFD; if( ecx > 0xA ) ecx = 0; } cout << "Your serial is : mvg2eVC" << esi; cout << endl << endl << "Another KeyGen coded by Cardenal Mendoza..."; return 0; } ********************** ## Manual Unpacking ## <<<<<<< UsiNG >>>>>>>> ~~~ ProcDump32 1.5 ~~~ ********************** Name: PowerStrip Version: 2.51.02 but crack works with other versions... Availability: CD Pro No 49 of the PC-TEAM magazine (a french mag) or on the web,but that will not be probably the version 2.51.02 http://www.entechtaiwan.com/ps.htm Target: Pstrip.exe (468Ko) Protections: Compressed with ASPACK 10.08.03 Nagscreen Tools: Procdump 1.5 (Http://Procdump32.cjb.net) Softice 4.0 (Http://Crackfr.cjb.net) Hexa Editor (Hview etc...) Brain if available... PowerStrip is a small shareware which proposes advanced adjustments of your zindoze. The version that we're going to crack is found in PC-TEAM 's CD No 49 , a French Magazine. You may find more recent versions on Web,but steps are EXACTLY the same ones...I Have tested this crack with versions 2.51.04,2.51.06 and 2.51.07.... The principal protection of the software comes from his format .It was compressed with Aspack (10.08.03). This trick compresses the exe from 50 to 70%... And of course, an exe which was compressed (with aspack or other) is not possible to pach: it is necessary already to unpack it.That's we will see in this tutor. I mean that, Procdump 1.5 is completely able to unpack exes compressed with Aspack. But I find always more interressant to unpack it manually. Step 1 We start already by copying ' Pstrip.exe',which is in the Windows's directory,in the root of our hard disk : that will prevent a mistake on the original exe . Take Symbol loader (delivred with softice) and open Powerstrip. Normally softice give you the hand: except that here, the prog runs directly... We don't care, take Procdump 1.5 and click on ' PE Editor'.Open our exe, and click on ' Sections'. Procdump indicates to you the sections of your proggy. Make a Right-Button click on your mouse on section ' CODE' and choose the option ' Edit section' . In the box ' Section characteristics',Procdump indicates to you: C0000040. Replace this value by E0000020. To record your change, leave ' PE Editor'. Take again Symbol loader and open PowerStrip: this time, Softice takes the hand well. Step 2 Now that our debugger gave us the hand, we can trace the routine of unpacking. Press on the key F10,we arrive quickly at this first loop: 015f:005b72f2 or ecx,ecx ------ beginning of the loop 015f:005b72f4 jz 005b7312 015f:005b72f6 js 005b7312 015f:005b72f8 lodsb 015f:005b72f9 cmp al,e8 015f:005b72fb jz 005b7305 015f:005b72fd cmp al,e9 015f:005b72ff jz 005b7305 015f:005b7301 inc ebx 015f:005b7302 dec ecx 015f:005b7303 jmp 005b72f2 ----end of loop The loop starts at 5b72f2 and finishes at 5b7303 (jmp 5b72f2). If you trace this mini loop with the F10 key you will quickly see that the trace is quite long . To trace over this routine, put a Breakpoint at the address 5b7312. Under softice,enter BPX 5b7312. Why do we put a breakpoint at this address and not to another? Because this address corresponds to the first conditional jump of the loop (in 5b72f4, jz 5b7312).The second conditional jump (in 5b72fb,jz 5b7305) is not interressant : at the end, there is a jmp 5b72f2, the beginning of our mini loop...We deduce that the mini loop ends in 5b7312 .Run the whole with the key F5,and softice stops again in 5b7312. While continuing to trace the proggy with the F10 key , we arrive at this: 015f:005b734a cmp dword ptr [esi],00 015f:005b734d jz 005b7299 015f:005b7353 mov ebx,[ebp+00444adf] When you arrive at the address 5b734a, a comparison is made,followed by a conditional jump. As previously you will be taken in a loop. Put a breakpoint after the conditional jump: under softice, type BPX 5b7353 .And start again the whole with F5 and softice is blocked in 5b7353. We continue the trace with F10 and we arrive at this (Caution! The trace is long to arrive there!): 015f:005b7520 add dword ptr [ebp+00445172],04 015f:005b7527 jmp 005b7493 ------------- and we go up ... 015f:005b752c xor eax,eax 015f:005b752e mov [esi],eax 015f:005b7530 mov [esi+0c],eax 015f:005b7533 mov [esi+10],eax 015f:005b7536 add esi,14 015f:005b7539 mov edx,[ebp+004450ac] 015f:005b753f jmp 5b73fc 015f:005b7544 mov eax,[ebp+00444aef] 015f:005b754a push eax 015f:005b754b add eax,[ebp+004450ac] 015f:005b7551 pop ebx 015f:005b7552 or ebx,ebx 015f:005b7554 mov [esp+1c],eax 015f:005b7558 popad 015f:005b7559 jnz 005b7563 015f:005b755b mov eax,00000001--------- hum... 015f:005b7560 ret 000c 015f:005b7563 push eax----------------- entry point... 015f:005b7564 ret If you trace the proggy correctly, you arrive at the address 005b7527 jmp 005b7493. If you to carry out this jump, you will be taken in a loop again(to change...). Personally, the first time that I have traced a proggy compressed with aspack 10.08.03, there was a trick wich rang me a bell: in 5b755b there is a register (eax) that the prog puts has 1. Generally,coders is useful (it 's not always true) of this register to put ' flags' to announce that a routine is finished. Moreover this setting is followed by a push eax (5b7563) and a ret...Put a breakpoint at the address 5b7563: under softice,type BPX 5b7563.Run the proggy with F5. Softice is blocked in 5b7563. Under softice type ? EAX .Softice indicates to you 4D1F5C .It's the entry point of our program once this one is unpacked. Write this value in a corner, we will need it. Step 3 Now it will be necessary to make a DUMP of our proggy .Before executing the ret to the address 5b7564, type A 5b7564. You are in ASM editor of softice,in 5b7564 .Type ' jmp eip' and enter. Escape to come out of ASM editor . The prog will make an infinity loop at the address 5b7564, before executing. Run again the whole with F5. Launch Procdump 1.5. It must indicate to you all proggyz running at this time. In the window of procdump, we locate our prog easily : pstrip.exe .Before Dumping,change an option of procdump: in ' option', choose ' Rebuild Import Table' .To dump the prog, make a right click above your proggy and choose the option ' Dump (Full) '. Give a name to your exe (Dump.exe for me) .Now,you must have an exe of 1674 KB... Now, it is necessary to put the right entry point of your new exe .With procdump,go in the option ' PE Editor' and open the dump that you have made .Procdump indicates to you that ' Image Base' 00400000. A few moments ago (Step 2), we had noted that the entry point was 4D1F5C. Thus your entry point is equal to : 4D1F5C-400000=D1F5C. In the box ' Entry point' of procdump, enter D1F5C. To check that your exe unpacked is valid, launch it . He should be run without problem... Step 4 The other protection of the software is a nagscreen which is posted at all loadings .In more ,it is not really easy to crack it : breakpoints on current APIs , like DialogBoxParamA,MessageBoxA and others, do not have any effect... I have used the breakpoint which give the hand to softice when the button of the mouse is activated. Launch your exe and before to click on ' ok' when the nag is posted, launch softice with Hotkeys: CTRL D .We will see all programs which run under zindows: under softice,type TASK. We locate easily our exe (' dump.exe' for me) .Now ,type HWND DUMP. This order will post you all APIs that the prog uses at this moment. CAUTION! Screen below will be inevitably different on your computer : addresses on the left, will change from a config to an other. Personnaly, in typing HWND DUMP,i obtain this : Window Handle hQueue SZ QOwner Class Name Window Procedure 0270(1) 3967 32 Dump TPSSplash 13ff:00000298 02A0(2) 3967 32 Dump Button 13ff:00000A72 029C(2) 3967 32 Dump Button 13ff:00000A5C 0298(2) 3967 32 Dump Button 13ff:00000A46 0294(2) 3967 32 Dump TGroupBox 13ff:00000A30 0288(2) 3967 32 Dump TGroupBox 13ff:000009D8 0290(3) 3967 32 Dump Edit 13ff:00000A1A 028C(3) 3967 32 Dump Edit 13ff:00000A1A 0284(2) 3967 32 Dump TGroupBox 13ff:000009C2 0278(2) 3967 32 Dump TRadioGroup 13ff:00000980 0280(3) 3967 32 Dump Button 13ff:000009AC 027C(3) 3967 32 Dump Button 13ff:00000996 0274(2) 3967 32 Dump Button 13ff:0000096a We search a class having as name ' Button', beacause we want to block the software when there is an activity on the mouse (like a click on button ' ok' or other). Softice indicates several class having this name ' button'. Take one but ,probably, it will be necessary that you make several tests before finding the right BP. I took the window procedure which has a window handle equal to 280(3).To place your breakpoint , type: BMSG 280 0202 .The number 280 corresponds to the window handle of the button and 0202 is the breakpoint's name (WM_LbuttonUp). If you put the right breakpoint, when you click above ' ok' ,softice must take the hand .But at this time, you are not in the principal code of the proggy.We are at the beginning of API. To go back in the code of our proggy, we need to go up using F12. Caution! To come out of the nag, it is necessary to support 64 TIMES on F12! If you make the operation well, you arrive at this: 015f:004a8856 cmp byte ptr [eax+00000530],0 ------ user registered ? 015f:004a885d jnz 004a8904 ------------ Year! we jump... | ---- cut ------ | 015f:004a88c7 mov eax,[004d8b00] 015f:004a88cc call 0042522c------- Nagscreen! 015f:004a88d1 cmp eax,02--------- YoU ArE HeRe WitH SoFTiCe! While supporting 64 times on F12,we arrive at the address 4a88d1. Before this address you have the call which starts the nag: call 0042522c. While going up a little in the code,we see that at the address 4a8856 ,there is a comparison followed by a conditional jump ... And if we replace the jnz 004a8904 by a jz 004a8904, to force the proggy to jump on the top of the nag... Take your editor hexa, and edit the dump.exe .Go to the offset a7e5e and put 84 at the place of 85. Launch your crack: it works, nag is not posted... It should be noted that this technique to unpack Aspack 10.08.03 is valid for others proggyz compressed with this shit.... Just memory address change.A+++++++++++ For the remarKs,critiKs,contaKts : Samsoul99@hotmail.com a crACk By TaMaMBoLo From [ (/ $$-SaMSoUL CRaCKinG CReW-$$ \) ] How to write an automatik script for ProcDUMP 1.5? Tools : ProcDump 1.5 (Http://Procdump32.cjb.net) :Softice 4.1 (Http://Crackfr.cjb.net) :STne PE Encrypter 1.13 (Http://Protools.com) In this tutor we will see a simple manner to write a script for Procdump. For this example, I have choose a compressor that procdump didn't Know: STNE PE Encrypter 1.13 (Stone). It is completely possible to restore a exe packed with STNE,juste by changing some options of procdump. But it is more interressant of to make a special script ... Step 1 As I did not find a prog crypted with STNE 1.13, I took ' Notepad.exe' (in the Windows repertory ) and I have packed it . I am sure that everyone has the same prog (under zin98) Note the entry point of notepad.exe: 4010cc.When notepad.exe is packed,You have an exe from 61Ko instead of the 56 ko. Take Symbol loader and open the notepad .While tracing the prog with the F10 key, we arrive quickly at this: 015f:0040e090 pop ebx ---- we recover 015f:0040e091 pop ecx ---- all 015f:0040e092 pop edx ---- registers 015f:0040e093 pop esi 015f:0040e094 pop edi 015f:0040e095 pop ebp 015f:0040e096 jmp eax ---- and we jump towards the unpacked prog... While tracing the proggy with F10 we arrive at the address 40e096: jmp eax .And eax=4010cc who is the original entry point of the prog (unpacked). we deduce easily that the unpacking is finished . Step 2 Before executing the jmp eax in 40e096, type under softice A 40e096 . You are in ASM editor of SoftIcE. Type: jmp eip .Now the proggy makes an infinity loop in 40e096. Take procdump 1.5 . In the principal screen you have all the proggyz which turn at this time. Our notepad.exe is easily located. Make a right-click above and choose the option ' Dump (Full) '.Give a name for our safeguard, dump.exe for me. we had noted at the beginning of the article that our original entry point was 4010cc.Go in the option ' PE Editor' of Procdump .Open your dump.exe. Procdump indicates to you : 'Image 'Base' = 00400000. To give the good entry point,make 4010cc-400000=10cc=Entry point... In the box ' Entry point' of the PE Editor ,type 10cc . To validate changement,leave procdump. While launching our dump.exe with the good point of entr‚e,notepad is well open without package... Step 3 Before writing script some comments on the orders used: LOOK: it is with this order that procdump reference the signature of the cryptor or of ~~~~~ the compressor .This command search a hexadecimal chain in the exe . If the chain is found, that means it is the good script. BP: with this command,you put a breakpoint (even principle that Softice) ~~~ on the current memory address. This order is preceded by LOOK. STEP: it is with this instruction that you will finish your script. STEP starts ~~~~~ a step by step analysis of the code, which explains sometimes the slowness of the dump. The first order that we will use is the order LOOK, used to locate the signature of the cryptor. Do you remember the jmp eax in 40e096 (see Step 2) ? I think it's a good signature... Why? Because just after this jmp eax we jump towards the prog unpacked. By putting a BP on this address,Procdump will deduce from it that the next memory address will be the original entry point . jmp eax=FF,E0 into hexadecimal . The first line of code in the file script.ini will be: L1=LOOK FF,E0 (L1 for line 1 ). Then,it is appropriate to put a breakpoint on this address: L2=BP. The prog is unpacked at this time. We can launch the step by step analysis : L3=STEP. It is important to note that you can also define the default options which will be used with this script: it's the options OPTL1,OPTL2,OPTL3,OPTL4,et OPTL5. I can not to explain this options in detail, coze it's not very clear for myself. Final script is : CAUTION! REMOVE ALL THE COMMENTS SO THAT SCRIPT RUN! (-----blablabla...) ------------------------------cut here------------------------------------------ P1D=STNPE Encrypter 1.xx --------give a name and a No to our new script [ STNPE Encrypter 1.xx ] L1=LOOK FF,E0---------------------Look the signature of STNPE L2=BP-----------------------------Put a breakpoint so good signature L3=STEP---------------------------step by step analysis OPTL1=00000000--------------------here some options put by default for this script OPTL2=01010001 OPTL3=01010001 OPTL4=00030000 OPTL5=00000000 ------------------------------cut here------------------------------------------ Once this put in script.ini, you can unpack all the progs compressed with STNPE Encrypter 1.13 If you want other informations on the writing of the scripts, read the councils of the author (G-RoM), in the txts files included with Procdump 1.5. My mail : Samsoul99@hotmail.com TaMaMBoLo How to write an automatik script for Procdump? Tools: Procdump 1.5 (http://Procdump32.cjb.net) : Softice 4.1 (http://crackfr.cjb.net) : PECompact 0.975b (http://Protools.cjb.net or http://Pecompact.cjb.net) : Brain/Ganja (yup! if u like it!) Today we will see how to write a script for ProDUMP.If you already read my tutorials for Procdump (PCSHRINK 0.71 Beta...), the technique employed to write this script is similar. I already traced, with Softice, the routine of unpacking from PECompact to see how this latter worked... So I located in this same routine, the places where I could use the Breakpoints for Procdump. Step 1 Take Symbol loader and open PECompact. Trace the proggy by pressing F10. Quickly, we arrive at this: un-assembling 1 15f:0040aab1 repz movsd 15f:0040aab3 pop EDI 15f:0040aab4 jmp EDI We are at the beginning of the routine . Consequently, jmp EDI (40aab4) will not make a jump towards the unpacked prog . It is necessary to continue the unpacking of the proggy. But we note the address where is jmp EDI coze we will need it... While continuing the trace with the F10 key, we arrive at this: un-assembling 2 15f:0040c57f call 40c617 15f:0040c584 xchg eax,ecx 15f:0040c585 pop esi 15f:0040c586 pop EDI 15f:0040c587 repz movsb 15f:0040c589 jmp 40c6f8 After the call 40c617 (in 40c57f), the routine will make a jump to another place of the code. This call 40c617 makes a handling of bytes (move some bytes of the proggy to another place of the code): the unpacking started... We note also this place of the code. We still did not see something which resembled our point of entered (400000...). We continue the trace and we fall on that: un-assembling 3 15f:0040c6f8 pop edi 15f:0040c6f9 lea esi,[ebp+004075ed] 15f:0040c6ff mov eax,[ebp+0040728b] 15f:0040c705 add [ebp+004074ae],eax 15f:0040c70b push edi ----------- beginning of the loop 15f:0040c70c lodsd 15f:0040c70d or eax,eax --------- loop end ? 15f:0040c70f jz 0040c72e --------- Year! we jump to 40c72e ------ cuted! ------- 15f:0040c72a pop esi 15f:0040c72b pop edi 15f:0040c72c jmp 0040c70b ---- return to beginning of loop While arriving at this part of the code, you will be taken in a loop. It starts in 40c70b and finishes in 40c72c. Like this loop is rather long, put a breakpoint in 40c7Ÿ (which corresponds to the end of the loop, see comments): under softice, type BPX 40c7Ÿ and start again with F5. Softice is blocked well in 40c7Ÿ. we continue has unpacking the proggy while continuing the trace with F10. And finally, we arrive at this: un-assembling 4 15f:0040c72e pop eax 15f:0040c72f lea esi,[ebp+0040766d] 15f:0040c735 lodsd---------- loop beginning 15f:0040c736 or eax,eax 15f:0040c738 jz 0040c779 ----- go to unpacking end... 15f:0040c73a add eax,[ebp+0040728b] --------- cuted! ------------ 15f:0040c776 pop edi 15f:0040c777 jmp 0040c735----- end of loop 15f:0040c779 call 0040c848 ----- decrunching end! 15f:0040c77e call 0040c7be ----- idem 15f:0040c783 jae 40c7b6 -------- go to Entry point... --------- cuted! ------------ 15f:0040c7b6 popad ------ recover register 15f:0040c7b7 popfd ------ idem 15f:0040c7b8 push 00401867 ------ ENTRY POINT! 15f:0040c7bd ret By tracing the proggy with the key F10, we still find oneself in a loop which starts in 40c735 and finishes in 40c777. In 40c738, there is a conditional jump: it is this jump which marks the end of the loop (when the loop is finished, we jump in 40c7b6). To avoid tracing all the loop, under softice you type: BPX 40c779 and start again with F5. 40c779 corresponds to the address of the jz 40c779... And while arriving in 40c779, we fall on two calls (call 40c848 and call 40c7be) followed by a conditional jump. This conditional jump is carried out and send us in 40c7b6. And at this place of the code, we recover the registers piled up in the pile, and we notice Push 401867 followed by a Ret: do not seek further, here it is your original entry point ... How I know that? I have quite simply continued the trace of the prog after this push and this ret, who brought me into 401867, where I could note some calls with various APIs like GetModuleHandleA. This last API is always present at the beginning of the proggys turning under Zindaube... We can deduce easily that Push 401867 is well the original entry point... To check it ,we will to dump our proggy. BEFORE carrying out Push 401867, type under Softice: A 40c7b8. We are in the ASM editor of Softice, at the address memory corresponding to Push 401867. Type in ASM editor of softice, JMP EIP ,and escape to leave. Normally your Push 401867 has to leave its place to a JMP 40c7b8... Take procdump 1.5. Start by changing an option in Procdump: choose in ' Options', ' Rebuild New Import Table'. We easily locate our proggy in the principal screen of Procdump. Make a right-click above and choose the option ' Dump (Full) '. Give a name for our dump (dump.exe for example). But like our proggy is unpacked, it is necessary to give him the original entry point which was 401867,I recall. Always with Procdump, go in ' PE Editor' and open our ' dump.exe'. Procdump indicates to you ' Image Base ' : 400000. Therefore our entry point is equal to: 401867-400000=1867. In the box ' Entry Point' of Procdump enter 1867. To check your dump, launch it: it should run without problem... Now you have got an exe from 57Ko instead of the original 17Ko... Step 2 We will write the script, to automate all that with Procdump... If you remember the routine of decrunching , it several should be posed Breakpoints for that Procdump can unpacked PECompact. Indeed, if you make one ' LOOK' on last hexa chain of the routine from unpacking (on the popfd and the push 00401867, in 40c7b7 (see last desassembling)), Procdump will not find this chain beacause PECompact unpacks the proggyz gradually: it is the same technique as for PCSHRINK 0.71 beta script ... Some recalls on the various orders which I have used for this script: LOOK: it is with this order that procdump reference the signature of the cryptor or of ~~~~~ the compressor .This command search a hexadecimal chain in the exe . If the chain is found, that means it is the good script. BP: with this command,you put a breakpoint (even principle that Softice) ~~~ on the current memory address. This order is preceded by LOOK.You'll understand in few minutes. STEP: it is with this instruction that you will finish your script. STEP starts ~~~~~ a step by step analysis of the code, which explains sometimes the slowness of the dump. WALK: this command executes an instruction (in the proggy that you dump). ~~~~~ When we trace the unpacking routine of PECompact, we arrive in 0040aab4 jmp EDI. (see No1 desassembling) . I think it's a good place to make a first Breakpoint with Procdump .We will make a ' LOOK' on the chain which interress us. We will take pop EDI who precedes jmp EDI , to be sure that Procdump finds the good hexa chain . In hexa, pop EDI and jmp edi= 5F,FF,E7. So, the beginning of the script is : L1=LOOK 5F,FF,E7 ---- Seeks the chains hexa 5F,FF,E7 L2=WALK ------------- carries out an instruction L3=WALK ------------- idem L4=BP --------------- Put a breakpoint I used the order ' WALK' to execute two instructions. Indeed, as we took one instruction in more (pop EDI), we must execute 2 walks to be themselves after jmp EDI and to put our breakpoint at the good place. I mentioned above that at this time,the proggy is not unpacked yet. It should be necessary to put others breakpoints. Step 3 For the second breakpoint, the second desassembling will be useful for us (see step 1). It is important to put our breakpoint after the call 40c617 (in 40c57f) because this call unpacks or moves some bytes. I chose to put my second breakpoint on the repz movsb (in 40c587) and on the jmp 40c6f8 (in 40c589). This instructions are equal in hexa to F3,A4,E9. The continuation of script is thus: L5=LOOK F3,A4,E9 ------ Seeks in hexa F3,A4,E9 L6=WALK --------------- Carries out an instruction L7=WALK --------------- idem L8=BP ----------------- Met a breakpoint I don't return on the 'walks', if you don't understand, return to the school... If you read my tutorial on PCSHRINK 0.71, you think that we did not make yet the ' LOOK' on the last instruction of the unpacking routine (0040c7b8 push 00401867), to find our original entry point. But Procdump is incredible : it's not necessary to make another 'LOOK' or 'BP'.... To recover the original entry point, just launch the step by step analysis (STEP) after the second BP... Final script is : --------------------------------------- cut here------------------------ CAUTION! REMOVE ALL THE COMMENTS SO THAT SCRIPT RUN! (-----blablabla...) P1E=PECompact 0.975 b--- give a name and a number (P1E) to script [P1E=PECompact 0.975 b]----- name of script L1=LOOK 5F,FF,E7 ------ seek in hexa 5F,FF,E7 L2=WALK --------------- execute one instruction L3=WALK --------------- idem L4=BP ----------------- Put a breakpoint L5=LOOK F3,A4,E9 ------ seek in hexa F3,A4,E9 L6=WALK --------------- Execute one instruction L7=WALK --------------- idem L8=BP ----------------- Put breakpoint L9=STEP --------------- step by step analysis OPTL2=01010001----------- options put OPTL3=01010001----------- by default for OPTL4=00030000----------- this script ('Rebuild New OPTL5=00000000----------- Import Table' ,etc... --------------------------------------- cut here------------------------ It is to be added in ' script.ini' in the directory of Procdump 1.5. Now, you can unpack PECompact itself : it goes very well! It should be noted that this software is updated regularly but scripts are not completely the same ones for various versions. For example here the script of the version 0.971 b: --------------------------------------- cut here------------------------ P1F=PECompact 0.971 b [P1F=PECompact 0.971 b] L1=LOOK 5A,FF,E2 L2=WALK L3=WALK L4=BP L5=LOOK F3,A4,E9 L6=WALK L7=WALK L8=BP L9=STEP OPTL2=01010001 OPTL3=01010001 OPTL4=00030000 OPTL5=00000000 I have well used the same technique as for the script of the version 0.975 B... If you have any questions, remarKs or criticiKs,or just contaKts, you can send me a mail : Samsoul99@Hotmail.com I profit from this moment to thank people who, as me, come from the ' OLd SChoOL': Xor,Syntax ERRoR,Virus,Dr Felix,AcE,Syndrome, the fanzines Disc Full, Micro Mag & Press Fire,DraPeAu NOiR, without forgetting my two friends FoRcE ONe and ANtoinE... Amstrad CPC was a very cool word, especially the environment! It was 11 years ago... CpC RuLLLEEEEEZZZZZZZZZZZ! TaMaMBoLo/SamSouL CRackIng CReW We really hope you've enjoyed this tutorial too much as we did! Don't miss Tutor #49 soon! ;) And as I said last time: Without knowledge, there's no power! ;) Credits go to: DnNuke for Splash Logo. TaMaMBoLo for providing 3 tuts in this version. Cardenal Mendoza for providing a tut in this version. tBS for providing a tut in this version. tKC/CiA (hey it's me!) for coding this version :) All the crackers (non-members of CiA) are welcome to send tutors for the next tutorials see below for my email address! And all the tutors can be found at http://www.msjessca.da.ru! Greetz goto all my friends! You can find me on IRC or email me at tkc@reaper.org Coded by The Keyboard Caper - tKC The Founder of PhRoZeN CReW/Crackers in Action '99 Compiled on 21 October 1999 Cracking Tutorial #48 is dedicated to Jenny...