********************************************************************************************************************************************************************************************************* Teleport Pro V1.29.1590 ********************************************************************************************************************************************************************************************************* Author: Tennyson Maxwell Protection: Name / Company / Serial - CRC Check URL: http://tenmax.com/pro12.exe Tools: SoftICE 4.05 W32Dasm V8.93 Hex-Editor ---> Intro... Hi and welcome to my next Tutorial !!! This time we're going to crack "Teleport Pro V1.92.1590". It has an very easy Algo and some CRC Check to prevent modifying the file :) Ok, i'm only gonna "Sniff the Serial" today, i leave the CRC Check up to you, hehe its a very simple one but i don't want to explain it sorry =/ Ask me if you really want to know the CRC Check ;) ---> Let's Begin... Ok, open up the program and then select "Help / Register...", you will see a window with 3 edit boxes. One for the Name, one for the Company and one for the Serial :) Now enter some "Fake" info in it, ive used: Name: CoDe_InSiDe Company: KnOwLeDgE Serial: 1234567890 When your ready we press (CTRL+D) to get into SoftICE to set our breakpoint. But what breakpoint could we use ??? GetDlgItemTextA... GetWindowTextA... etc... hmm, you know what, we're going to use hmemcpy (because it almost always breaks), so in SoftICE we type "bpx hmemcpy" followed by (ENTER) then leave SoftICE (CTRL+D) and click on "Ok" and SoftICE will popup. Ok, now we're at the beginning of the hmemcpy code, now type "BC *" to clear the breakpoint and press (F12) 11 times till you see this: --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :00426905 8B87DD000000 mov eax, dword ptr [edi+000000DD] <--- WE LAND HERE AFTER THE BREAK !!! :0042690B 33DB xor ebx, ebx <--- XOR EBX which is now 00 :0042690D 6A0A push 0000000A :0042690F 53 push ebx :00426910 50 push eax :00426911 E85E690000 call 0042D274 <--- In this CALL it puts your "Fake" Serial in EAX in Decimal Format :00426916 8B0DF8204800 mov ecx, dword ptr [004820F8] :0042691C 83C40C add esp, 0000000C :0042691F 8945E8 mov dword ptr [ebp-18], eax <--- Save "Fake" Serial in Memory :00426922 3899DB040000 cmp byte ptr [ecx+000004DB], bl :00426928 0F8412020000 je 00426B40 :0042692E 3BC3 cmp eax, ebx <--- Compare EBX (00000000) with EAX ("Fake" Serial) * Possible StringData Ref from Data Obj ->"User" | :00426930 BE00DA4700 mov esi, 0047DA00 :00426935 0F8406010000 je 00426A41 <--- If EAX is equal to EBX we jump and that means we haven't entered a Serial, or our Serial consists of 00000000, else continue :0042693B FFB7D5000000 push dword ptr [edi+000000D5] <--- Push the offset to our Name :00426941 E896090000 call 004272DC <--- Here's the Algo !!! :00426946 3945E8 cmp dword ptr [ebp-18], eax <--- Compare EAX ("Real" Serial) with our "Fake" Serial in Memory :00426949 59 pop ecx :0042694A 753A jne 00426986 <--- If not equal we jump and get the Bad Guy message ,else we get the Good Guy message :) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Ok well, first it puts our "Fake" Serial into the Register EAX (In Decimal Format), so if your out of that CALL and then do a "? EAX" you'll see your "Fake" Serial in SoftICE :) Then it Compares that value (Your "Fake" Serial) to the value 00000000, to see if we really entered something or to see if we entered only 0's :) If so we jump and fail, if not we continue to the Algo, let's see what the Algo is so enter the CALL 004272DC and you'll see this: --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :004272DC 57 push edi :004272DD 8B7C2408 mov edi, dword ptr [esp+08] <--- Move the offset to our Name in EDI :004272E1 85FF test edi, edi <--- Test if EDI is 00 :004272E3 7409 je 004272EE <--- If so we jump and XOR's EAX and we fail, else we continue :004272E5 57 push edi :004272E6 E855560000 call 0042C940 <--- In here it gets the length of our Name :004272EB 59 pop ecx :004272EC EB02 jmp 004272F0 <--- Jump to the Compare * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004272E3(C) | :004272EE 33C0 xor eax, eax <--- XOR EAX which is now 00 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004272EC(U) | :004272F0 83F805 cmp eax, 00000005 <--- Compare EAX with 05 :004272F3 7304 jnb 004272F9 <--- If below we continue and then it XOR's EAX and we fail, else jump and continue to the Algo :004272F5 33C0 xor eax, eax <--- XOR EAX which is now 00 :004272F7 5F pop edi :004272F8 C3 ret --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- In this piece of Code it takes the length of our Name and Compares it with 05, if less then 5 Characters entered as Name we fail, else we continue to the Algo. So trace a little further till it jumps after the "cmp eax, 00000005" (or do everything again if you entered less then 5 Characters for your Name) and then you'll see this: --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :004272F9 53 push ebx :004272FA 56 push esi :004272FB BEA4E4FE5D mov esi, 5DFEE4A4 <--- Hmm... Move Magic Value in ESI :) :00427300 33DB xor ebx, ebx <--- XOR EBX which is now 00 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00427322(U) | :00427302 85FF test edi, edi <--- Test if EDI is 00 (EDI holds the offset to our Name) :00427304 7409 je 0042730F <--- If so we jump to the "xor eax, eax", else continue :00427306 57 push edi :00427307 E834560000 call 0042C940 <--- In here it gets the length of our Name :0042730C 59 pop ecx :0042730D EB02 jmp 00427311 <--- Jump and skip one instruction * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00427304(C) | :0042730F 33C0 xor eax, eax <--- XOR EAX which is now 00 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0042730D(U) | :00427311 83C0FC add eax, FFFFFFFC <--- ADD EAX FFFFFFFC (-04), so it subs 04 from the length of your Name :00427314 3BD8 cmp ebx, eax <--- Compare EAX (Length of your Name) with EBX (00000000) :00427316 730C jnb 00427324 <--- If below we continue to make our Serial, else we jump to the end :00427318 33343B xor esi, dword ptr [ebx+edi] <--- XOR [EBX+EDI] (is 1st four Chars) with ESI (5DFEE4A4) :0042731B F6C340 test bl, 40 <--- Test if BL is less then 40 :0042731E 7401 je 00427321 <--- If so we jump and skip one instruction, else continue :00427320 43 inc ebx <--- EBX +1 * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0042731E(C) | :00427321 43 inc ebx <--- EBX +1 :00427322 EBDE jmp 00427302 <--- Repeat loop * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00427316(C) | :00427324 8BC6 mov eax, esi <--- Move our "Real" Serial in EAX :00427326 5E pop esi :00427327 5B pop ebx :00427328 5F pop edi :00427329 C3 ret --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Very small Algo :) Ok, so it takes the length of your Name and subtracts 04 from it why?... Because as you see it XOR's a Dword (4 bytes) with ESI (Our Magic Value), if it didn't subtract 04 from the length then you would get a XOR with 00 and they didn't want that :) So it goes like this: CoDe_InSiDe" Lenght of my Name "0B" (11 Decimal) Length - 04 = "07" (7 Decimal) Then it Compares EBX (00 at the beginning) with our "New" Length (07) If below we continue to make the "Real" Serial, else we jump to the end and move ESI (Our "Real" Serial) in EAX Then it XOR's the first 4 bytes of our Name with the Magic Value in ESI (65446F43 XOR 5DFEE4A4) Then it Test's if BL is less then 40 If so we jump and increase EBX by 1, else we increase EBX by 2 Repeat loop ... Compare EBX (01 now) with our "New" Length (07) If below we continue to make the "Real" Serial, else we jump to the end and move ESI (Our "Real" Serial) in EAX Then it XOR's with ESI with 4 bytes of our Name (now it begins at the next Char of our Name because of "inc EBX") Then it Test's if BL is less then 40 If so we jump and increase EBX by 1, else we increase EBX by 2 And so on... Till the "Compare ebx, eax" is the same and then we jump and move the final result from ESI in EAX Then we get back to the main Code and then it does "cmp dword ptr [ebp-18], eax", Compare EAX ("Real" Serial) with our "Fake" Serial in Memory. If equal we continue and get the Good Guy message, else we get the Bad Guy message :) Do a "? EAX" to see your Serial in Decimal Format. Ok, that's it... As you can see it hasn't calculated our "Company" like so much other Program's won't :) So finally i got this Serial for my Name: Name: CoDe_InSiDe Company: KnOwLeDgE <--- Not necessary can be left blank Serial: 1050509777 I hope you learned something from this tutorial, as it wasn't very hard to understand i hope :) If you have any questions or just something to say send it to: Email: code.inside@home.nl ---> Greetings... Everyone from TrickSoft (www.TrickSoft.net) Everyone from Cracking4Newbies (www.Cracking4Newbies.com) Everyone from Keygenning4Newbies (Keygenning4Newbies.cjb.net) And You... Don't trust the Outside, trust the InSiDe !!! Cya... CoDe_InSiDe