TORN@DO presents: cRACKER's n0TES
Tips & Tricks for cracking Serials


Memory Echo (Cruehead)
A common way to find a valid serial is to find what the legendary +ORC calls the memory echo. This is the place where our entered serial is compared to the real, valid serial (often calculated from our entered username). You can crack alot of programs, just finding the memory echo, so be suspicious when you see a code like this:


    mov bl,[esi]      ; Take one byte from the correct serial
    mov bh,[edi]      ; Take one byte from the serial entered
    cmp bl,bh         ; Compare them
    jne ...           ; If they don't match, then the serial entered is an invalid serial.
    
So, to find the memory echo here, you would, in SoftICE, write "d esi", and then you'd see the correct serial in your DataWindow. Another code snippet that does the same thing could look like this:


    mov ecx,lengthofvalidserial  ; How many bytes to compare
    repz cmpsw                   ; Cmp string at ds:esi (correct ser) with es:edi (our ser)
    je ...                       ; Jumps to the "valid serial" label if the strings match.
    
To find the memory echo for a program that uses a code like this, you would, in SoftICE, write "d esi". Just like the example above! Well, by now I hope that you understand a little bit more about what the memory echo is, and how to find it!




Message Breaks (+Greythorne)
   BMSG  <Window-Handle>    WM_GETTEXT (good for passwords)
   BMSG  <Window-Handle>    WM_COMMAND (good for OK buttons)

Important Info: Assuming you are using WM_COMMAND to try to locate the Button push, you hwnd the result and see what the hwnd of the button is e. g. 0324 and what the hwnd of the window is e. g. 0129

To find the Button, use the Window Value, not the Button Value to BMSG on (the other just won't work) so for the example here, to find our button push we would BMSG 0129 WM_COMMAND




Serial Cracking (josephCo)
Well I'll start off by explaining a little trick i use for attacking serials. I don't use any of the main API's (GetDlgItemtext(A), GetWindowText ... [if this is really one to use]), I almost always break on HMEMCPY.

When i set my breakpoint on HMEMCPY, I single step (F10) into it about 17 to 25 lines. You should find code similar to this:



    PUSH ECX
    SHR ECX,2            ; number of words to copy
    REPZ MOVSD           ; copies from DS:ESI (32-Bit) to ES:DI (32-Bit)
    POP ECX
    AND ECX,3
    REPZ MOVSB           ; same as REPZ MOVSD, but only 1 Byte
    XOR DX
    XOR AX
    
Now, this may seem a little tricky, but just stick with it. You will find that this method usually is a bit easier to break on your serial, or name.

At REPZ MOVSD, in sice, type: D DS:ESI (32 bit) or D DS:SI (16 bit). You should see your name, serial number, or whatever you typed in. Now type: D ES:EDI (32 bit) or D ES:DI (16 bit). This will show the location where you information will be copied to ie 22BF:00000000. Notice the strange segment (22BF). If you BPR on this range of memory, you MIGHT not break again at all. Now F10 untill all of your information is copied (past repz movsb). At this point you should type: PAGE 22BF:00000000 (or whatever SEG:OFFSET you have). Something like this will show up:

Linear Physical Attributes Type
80284960 01603960 PD A AU RW System

What we want to do is put a BPR (break point on range) at the address of the linear location. To do this you need to know how many bytes are in the range, and you have to use the SELECTOR 30.

Example: BPR 30:80284960 30:80284969 RW

This just set a break on the range for 9 bytes during RW (read/write) access. If you want to see how different addresses can actually be the same you can:

   D 30:80284960

Always use the selector 30, because it always exists. That's just the facts.

Basically all this does is keep the user from having to F12 out of the normal API and then searching for his serial/name. This is extremely useful for 16 bit programs, because the segment always changes. Now you can go about your merry way (F5) and repeat the process or BD <HMEMCPY> (whatever breakpoint it is) and you should break when your serial/name is read. Simple ;)




Serial # Cracking using HMEMCPY (CrackZ)
An interesting Windows-Function in cracking Serial numbers is HMEMCPY. It's called when strings (e. g. Serial-#s) are copied into memory. To use HMEMCPY, you first have to enter some details in the registration dialog and then after you had added all information, add a breakpoint to HMEMCPY (Ctrl-D, BPX HMEMCPY). Return to the program (Ctrl-D) and press the OK/Register, etc. button. You are kicked back to SoftICE, so hit F11 to return to the calling function. If there were more than just one edit box, press Ctrl+D and F11 again, until you're sure, the information from all edit boxes had been copied. Now you're looking at something like this:

   PUSH DWORD PTR [DI]
   CALL KERNEL!LOCALUNLOCK

This code is in USER, and most codes are checked from the program executable file (e. g. FILE.EXE), so let's stepping with F10 after you've disabled all breakpoints. You should step through a lot of instructions (maybe 50 or more), and you will probably go through Kernel32!_freqasm before you return to the program code. If you returned to the program code, start stepping slowly with F10 through it. If you find something interesting - maybe two serial #s are PUSHed on the stack and then a CALL is executed ... use D to view this memory location.

If you see lot's of function CALLs and conditional jumps, you might not want to loose time checking this. So let's use the info you got when you entered an invalid serial #. In this case quit SoftICE and open W32DASM. Now look for the message you got, as you entered an invalid serial#, in the string reference.. So you see where your invalid serial # message appears. You should write down this address. Then look for the message you would get when you entered a valid serial# and note the address down. So now let's go on using SoftICE and start trying to get the program registred. Back in SoftICE start stepping through the code and check if a conditional jump jumps close to your invalid serial# message and also check if it jumps to the valid serial# message. Now you should now enough to get a valid serial# - or where to patch the file.




Visual Basic Serial Cracking (CrackZ)
I'm going to highlight another way in which you can reverse VB-Serial-Protections, this approach will involve using the message box that appears when you enter an invalid code. So before pressing O.K. set a BPX rtcMsgBox in SoftICE, you'll need to have MSVBVM50.DLL exports loaded to do this. Then enter your favourite registration data and press enter. SoftICE will break at the rtcMsgBox-Function. So lets disassemble your program. Go to the code segment where the message box appears. You should easily see that our message box is referenced by a specific check. Set a breakpoint just before that compare function, note that Visual Basic functions do not differ in anyway from WIN32 API's in that they must also PUSH any parameters they use onto the stack. So you should easily reach this code (just before our critical compare), you might need to push F5 & F11 a few times. Now you should be able to snatch the good code.

Next time when you are reversing a Visual Basic target, the following functions might be worth trying:

   __vbaLenBstr (gets string length)
   __vbaStrCopy
   __vbaStrMove




Visual Basic 3 Serial Cracking (+wAj)
The explained can be used for any snippet if you have it infront of you like the one below:


       ; The_VB3_compare_snippet 
       : 8CAF     8BCA              mov cx,dx 
       : XXXX     F3A6              repz   cmpsb     ; <- cmp strings in DS:SI and ES:DI 
       : XXXX     7401              je 8CB6 
       : XXXX     9F                lahf 
       : XXXX     92                xchg ax,dx 
       : XXXX     8D5E08            lea bx, [bp+08] 
       : XXXX     E80E06            call 92CB 
    
(1). BPX on HMEMCPY. enter a character of your serial. You will break. PRET (F12) until you get to VBRUN300.DLL module. Now type BC *, and search for the hex of the snippet (8BCAF3A674019F928D5E08), and set a BPX at the location found. BD * (to avoid unecessary breaks), and enter all your serial, then BE * and press OK ... BOOM! your at the comparison.

(2). BPX on HMEMCPY. enter a character of your serial. You will break. PRET (F12) until you get to VBRUN300.DLL module. Now type BC *, and set a BPX on the offset (BPX 8CAF) of where you want the program to break. BD * (to avoid unecessary breaks), and enter all your serial, then BE * and press OK ... BOOM! your at the comparison.

Using these approaches you do not need to modify the actual file. Hence better/easier!




Visual Basic 4+5 Serial Cracking (The Sandman)
Visual Basic cracking still remains to many, a tough nut to crack because you can't just dead list it and expect to see where your going... Therefore we need to adopt new methods to circumvent this natual barrrier and one possible way is to locate routines within the VB runtime library that we can place traps (breakpoints) on with SoftICE.

In order to program Softice to quickly locate the String Compare Routine for us we place the following three lines in our WINICE.DAT file:



   AF4="^s 0 l ffffffff 56,57,8B,7C,24,10,8B,74,24,0C,8B,4C,24,14,33,C0,F3,66,A7;"

   EXP=C:\WINDOWS\SYSTEM\VB40032.DLL
   EXP=C:\WINDOWS\SYSTEM\MSVBVM50.DLL



This has been tested on both VB4 & VB5 programs and does work, however, if the target program uses Integer/Reals for the serial number then the program will use a different set of routines instead, bypassing our String Compare Routine altogether ...

In order to combate this I think I've found a Integer/Real routine in VB5 that we can place a BPX on that will show us the *real* numeric serial that the program expects us to use ...

The VB5 Routine looks like this:


   PUSH EBP-20
   CALL MSVBVM50._vbaR8Str    ; Convert string to Integer/Real
   FCOMP QWORD PTR [00401028] ; Our numeric compare!


Once you land on fcomp qword ptr [00401028] Type: DL 00401028 to see the *real* serial #. DL is not a typing error, DL means Display Long/real while D on it's own simply uses the current display format ... See SoftICE manual for more information on SoftICE Commands.

Okay, we now have something new for SoftICE to check on, so lets program this new Search Macro into it ...

Open up WINICE.DAT, make a backup first ... :)
Make sure you have these lines:



   EXP=C:\WINDOWS\SYSTEM\VB40032.DLL
   EXP=C:\WINDOWS\SYSTEM\MSVBVM50.DLL

   AF3="^s 0 l ffffffff FF,75,E0,E8,85,EF,FF,FF,DC,1D,28,10,40,00,DF,E0,9E,75,03;"
   AF4="^s 0 l ffffffff 56,57,8B,7C,24,10,8B,74,24,0C,8B,4C,24,14,33,C0,F3,66,A7;"



ALT-F3 Is our Integer/Real Compare search, works only in VB5
ALT-F4 Is our String Compare search, works in VB4 & VB5




Visual Basic 6 Serial Catching (widYa@cL 2011)
Here I have an alternative method that might be usefull in VB6 serial catching. ... first thing open up WINICE.DAT, make the following changes:

   F5="^x;^dd eax;"
   EXP=C:\WINDOWS\SYSTEM\MSVBVM60.DLL

Go to the registration dialog and fill in your favourite registration data. Now you should enter SoftICE (CTRL-D) and set a breakpoint on __vbaStrCat function (BPX MSVBVM60!__vbaStrCat). Now leave SoftICE (X [ENTER]) and press the OK button in your registration dialog ... #bOOm# ... we should now land here:


       :66060B5F    PUSH    EBP 
       :66060B60    MOV     EBP,ESP 
       :66060B60    MOV     EBP,ESP 
       :66060B62    PUSH    EBP 
       :66060B65    PUSH    EAX 
       :66060B66    PUSH    DWORD PTR [EBP+08] 
       :66060B69    PUSH    DWORD PTR [EBP+0C] 
       :66060B6C    CALL    [661106E8] 
       :66060B72    TEST    EAX,EAX 
       :66060B7A    MOV     EAX,[EBP+08]                     ; we're gonna see what's in EAX 
       :66060B7D    POP     EBP                              ; we're gonna sit here 
       :66060B7E    RET     0008
    
Now type the following commands:

   BC * [ENTER]
   BPX 66060B7D [ENTER]
   X [ENTER]

From here ..... Keep pressing F5 until you see a good serial form in data window in wide char format!





The cRACKER's n0tES are divided into 10 main parts:
 00. INDEX
 01. Assembly for Crackers (CoRN2)
 02. SoftICE (Boot Menu, Setup, Commands)
 03. Breakpoints & Win API Details
 04. Jump Instructions
 05. SET Instructions
 06. Tips & Tricks for Cracking
        1 Crippled Programs
        2 Dongles
        3 General
        4 InstallSHIELD Setups
        5 Key File Protections
        6 NAG Screens
        7 Runtime Limits
        8 Serials
        9 Time Limits
       10 Visual Basic 'Programs'
 07. Window Messages For Crackers
 08. Identifying Functions, Arguments, and Variables (Rhayader)
 09. Commerical Protection Systems
 10. Bitmanipulation (Cruehead)
 11. General Cracking Theory
 12. FAQ

 +A. How to contact me
 +B. What's New?



The cRACKER's n0TES are Copyright © 1998-2000 by TORN@DO of ID. All Rights Reserved. Archived and Re-hosted by Werdstaff