A DREADed Guide to Cracking Written by MisterE 13th March 1999
.----------------------------------------------------------------------------------------------. | Introduction | `----------------------------------------------------------------------------------------------' Hi, Here's another essay from me and all the people that helped me by writing pieces of this guide and supporting me with info. You wouldn't be reading this essay without the help of BaneOldMan, Rhytm and {_Suby_}. I started this Guide in December 1998, quite some time back. But after some time I joined DREAD (Dutch Reverse Engineers And Deciperians), so now this is a DREADed Guide. In this Guide, I'll try to explain to you how most protections work and -moreover- how to defeat them. The protection schemes will NOT be explained in a target specific way; rather, in a general fashion, so be prepared for some theory :) I've tried to keep this Guide as readable as possible, starting from newbie level to more advanced level, sometimes you might see some intermediate cracker tips. Those tips are NOT meant for newbies, but for crackers who have some experience in cracking. I've included those tips so both newbie and more advanced crackers will have fun in reading this Guide. I've included some reference material and an index at the end of this Guide to keep it as readable as possible. Well, won't bother you with a longer Introduction, here we go :) MisterE PS: If YOU also want to write a piece for the Guide, contact me!! PSS: Expect updates for this Guide, as new pieces will be added. .----------------------------------------------------------------------------------------------. | Serials | | Written by MisterE | `----------------------------------------------------------------------------------------------' Windows32bitDisassembler (W32dasm): String Fishing Most people who want to learn about cracking, start with W32dasm, because it's easy to understand. Just open the program you want to crack and go to 'Refs - String Data References'. See if you can find a string that has something to do with the registration of the target. Look for strings like: 'Thank You (for registering)', 'Wrong Serial', 'Invalid Serial', etc. You found such string? Cool! Now double-click on the string to go to the location where that string is mentioned (do another double-click on the string to go to the next location). Take a good look at the code now..........Do you see some conditonal jump to the string? Go to the location of the jump that points at the string. It is very likely that this jump determines if the serial number you entered is either right or wrong. You can create a patch for this target. You can patch this by toggling the jump. Say turn a JumpifZero (JZ) into a JumpifNotZero (JNZ). See the part about Patching for that. SoftIce: Getting Started Most of the time, when I want to crack a serial protection, I just set some breakpoint on GetWindowText(A) and GetDlgItemText(A). The A on the end means that the API is 32-bit. Short Intermezzo about APIs and dlls I just mentioned an API. I'll give you some more info about this. You probably seen all those weird .dll (dynamic-linked libraries) files in your windows directory. These dll files contain APIs or Application Programming Interface. Now what does this all mean? To start with the APIs: an API is something like a procedure or function as you know them in pascal or C. You call the API (or function) and gives it some parameters for input, in pascal you would have: Function CombineStrings(string1, string2 : string):string; In windows 32Bit assembly it would look like this: push string2 push string1 call CombineStrings (the API returns a pointer to the output string in EAX) This is just some fictional API. Notice that the parameters string1 and string2 are pushed in reverse order on the stack. You can probably guess what a dll is now: it's a library that contains APIs. End Intermezzo You press F12 (trace until you get out of a call) a few times so you get into the main program. How do you know you are out of a call? Well, that's in the caption of the code window, press 'wc' a few times to see what the code window is. If there's no caption, you aren't in a call anymore. Now look for a TEST or a CMP mnemonic (that's how these instructions are called, impress your friends with it :) You spotted such mnemonic??? Great! You've got a big chance that you landed right in the protection scheme, and -maybe- even discovered the Registered/Unregistered jump. Now trace (F9) until you reached this TEST ecx, ebx (or some other register, that doesn't matter). Take a look at the register (using 'd ebx' or 'd ecx') and write down the serial. BUT we are not always that fortunate that we get the serial at once...so read on! Note: Hmemcpy might break if GetWindowText(A) or GetDlgItemtext(A) doesn't work. See this for more API's. Combining the power of Windows32bitDisassembler and SoftIce I like W32Dasm very much! With some brain you can (sometimes) even get a serial without SoftIce. Open the Refs - String Data references, and take a look at the strings in the program. Some programs have their serial number hardcoded (written in plain text) in the program, bah, no honour to get from that program. Now, say the program has a better protection :) Say you even find a string that says you failed the serial test, or something like 'Thank you!'. That's what we want to hear! Now take a look at the address of this string (by double clicking on the string). Scroll a bit up and LOOK, examine the code, it won't take you long. You probably see something like 'Referenced by a conditional jump at 44E7C3'. Scroll up to this address and write down this address. You could Patch the jump. But there are some warnings. Now you don't want a lousy patch! You want a SERIAL. I'll tell you how to. Fire the target and place a breakpoint on Hmemcpy. Press a button or something and you'll get kicked into SoftIce. Place a breakpoint at the address you wrote down and disable the breakpoint on Hmemcpy. Go to the registration screen and enter some name/serial and the program should break. Look into some register to find out what your serial is. Why did I tell you to place a breakpoint on hmemcpy? Well, if you didn't place this breakpoint and just set a breakpoint at the address, SoftIce wouldn't break. That's because SoftIce has to know on which program it should break on. Intermediate tip: type 'addr' to see which program SoftIce is hooking on, you can also type 'addr name_program' to tell SoftIce which program it should break on. Softice: 'break on memory access' approach Ok, we got better protection scheme! Time for the 'break on memory access' approach. Say you got a program to break and you're in SoftIce. Do a search on the serial that you entered by typing 's 0 l ffffffff 'my_serial'' If SoftIce finds your serial before 80000000h then you got a good chance finding a serial. Why did I say 'before 80000000h'? Because above 80000000h you only have useless copies of your serial (well, most of the time). Now put a breakpoint on this memory location. Do this by typing 'bpm address' or 'bpr starting_address ending_address RW'. The RW means that SoftIce has to break when a program reads or writes to that address. Now continue running the program. The program should break. Take a look at the code and follow it. Look for CoMPare functions, procedures that check if you entered a correct serial (no ascii codes above 7Ah, etc). If you spot such procedures, you just have to trace to look what the program is doing, use your brain to figure out what the program is doing. If you didn't spot these procedures, well guess you have to do some more tracing, but most of the times you do get the serial comparison routine. Other Serial Protections Well, not all programs are as easy as I described above -Sigh-. But you'll feel great when you've cracked this little bastard. Maybe you couldn't find the right API to break. Ok, then check out this list. Or you got lost in the dark codewoods, which is a common problem. Well, also this time you might want to try another approach, using other API's to break on, OR if you think you are near the serial, trace a little more. Or some might encounter weird 'FSTP' etc. mnemonics. Then you got a program that uses the 80-bit FPU registers to generate/check it's serial. Go here to learn more about them. And if this doesn't solve your problem -Sigh- go to #cracking4newbies on EFNet, they'll help you if you ask nicely enough. .----------------------------------------------------------------------------------------------. | Patching | | Written by MisterE | `----------------------------------------------------------------------------------------------' A warning before we start I'll say it to you right now: I hate patching. There are numerous reasons why you should not patch, though there are situations when you can't do anything else. Like when you want to remove that nag-screen from some program that doesn't let you enter a name/serial. If you can enter a serial or register the program without patching, do it!! If you want to patch you might encounter problems like programs that do some CRC checks or check multiple times. Another common problem is that newbies patch some jump just before the call to a MessageBoxA. The programs tells you it's register, but meanwhile you only thing you patched was that the program displays the 'regged' message instead of the 'unregged' message. MAJOR TIP: There's nothing worse than patching a file, and finding out that the program is still unregistered. You probably missed some other check, or simply patched the wrong code. Therefore TEST your solution before doing ANYTHING else. You can do this by breaking at the location of the jump and then reverse the zero flag by typing 'r fl z'. Finding the offset of the code you want to patch Anyway, if you're still interested in patching i'll tell you how to patch. To patch you need two things: you need to know the location (offset) of the code you want to patch and you'll need a hexeditor. Say you discoved some JumpifZero using SoftIce and you want it to change to JumpifNotZero. First we need to know what the location of that offset. Say softice tells you that the JZ is located at 4206DEh. From this location we have to get the file offset, meaning the location of the JZ in the file, this is NOT the same as the address you got from SoftIce. You can find the file offset by opening w32dasm and searching for the address SoftIce gave you. If you look at the bottom of the w32dasm window, you'll see something like: Code Data @:4206DE Offset 0003F3B4. The last offset is the one we need to know. Intermediate way of finding the offset Another way to get is the file offset using SoftIce and w32dasm is that you use SoftIce to find the location of the JZ. Then right-click on the address of the jump in the code window and click on 'diplay'. Now take a look at the title of the data window. The title should say something like Program_name!.text+000006DE. The offset of this program is at .text+6DE. Now we have to figure out where .text starts. When you open this program with w32dasm you'll see something like: Object1: .text RVA: 1000 Offset: 1000. So this JZ is located at 1000+6DE = 16DEh. This last method of getting the file offset might be more difficult, but i think it will work for programs that change their imagebase (imagebases for normal programs are around 00400000h, though DLLs are more likely to have image bases around 00680000h). Let's Patch! In both SoftIce and w32dasm you can see what the opcode for JZ is: 74h. if you don't know what the opcode for JNZ is, you could look up the opcodes reference (opcodes.hlp), which can be found on most good reverse engineering sites. At this time we're ready to patch. Start an hexeditor and open your target. Search for the file offset we found. Now change the 74h (JZ) to 75h (JNZ). Save the file and you patched the program!!! Let's hope the program doesn't have any other check apart from the one you just patched. Spreading the Patch You might want to write a patcher so you can spread your patch to other people. There are several utilities that can create a patch for you. Personally I don't like those utilities, even though some of them are real masterpieces. I like to do my cracks myself, easiest way is to learn some programming language. Believe it or not, but that was one of the reasons for me to learn pascal. I've also written a tutorial for writing a pascal patcher, contact me to get it. Problems Sometimes problems arise. The program is giving some weird error after you patched it, or simply remains unregistered. Serveral things can cause this. Maybe the target is doing a CRC check, you missed a check, or you just patched the program this way, it shows the registered window instead of the unregged one. Well, i can't help you with this, mind you: i have warned you before ;) .----------------------------------------------------------------------------------------------. | Nag Screens by Suby | | Edited by MisterE | `----------------------------------------------------------------------------------------------' A nag screen is a window that pops up and doesn't disappear until you click one particular button. There are a lot of ways to create this nag-window, so there are also lot of approaches to crack them. First we need to find where this nag-screen is located. Very Easy Nags (MessageBoxes) These are the simplest types of nag-screens, you can recognize them easily, because they are formed by a little window, with text and a windows icon and only one button. You can check if a MessageBox is causing you troubles, simply by putting a breakpoint on MessageBox(A). If SoftIce breaks, you can start removing the nag. You can Nop (Nop means 'Do Nothing') out the call to MessageBoxA, remember you also have to nop out all the pushes before the call as well!! Though there are also other API's to generate windows. Universal approach to get rid of those nags This is a universal approach to get rid of the nags, and works for 99% of the nags. Load the program and when our target's nag is shown, go to SoftICE and type 'task' to see a list of names of currently active programs. Then type 'hwnd program_name' to get a list of all the window handles (objects) of this program. Look for a Window Handle that has a class name like 'Button'. Remember the Window Handle and put a breakpoint on it by typing 'bmsg Window_handle wm_command'. This means that SoftIce has to break when the window gets a 'wm_command' message. Knowledge of Windows32BitAssembly would help you some more here, but what you actually have done is saying to SoftIce: Break if the user presses a button. Notice there are also other wm_commands that will work for you, that will work for you, consult your win32 API reference to get more detail about them. Sometimes it is better to only use a 'bmsg Window_handle' because it is more general and simpler. Now try to exit Softice, press on the OK button and you should be kicked back into SoftIce, if not you might have entered the wrong Window Handle. Then press f12 a lot of times to get out of all those calls. Now you might see the main nag call. You should patch it, by for example, just nop the call out. Then re-run the program to see if it works, if not, use the backup of the program you made ;). Hard Nags Now I've got to tell that I rarely found programs protected with a hard-to-crack nag (like Paint Shop Pro). For these nags the universal approach and other ones failed, because there is no easy way to get rid of the nag without crashing the program. In this cases you have to forge some clever approach, like emulating the user's click, check out Bb's essay for this. Intermediate: String fishing using a hex-editor and W32dasm by BaneOldMan Here's a way to find strings that you can't find using W32dasm, but that you can find using a hex-editor. This can be very useful for nags, here is an example how to do it. Say we've found that string using a hex editor at offset B1602. Then open w32dasm to get the info where the DATA segment offset is located, you can find this info at the first page of the deadlisting. Say it is located at AC400. Now we subtract the DATA segment offset from the string offset (B1602-AC400=5202) and add this to 004C0000. But why 4C0000? Well, that's because the image base starts at 00400000h (get this info using w32dasm) for most programs, and in our example object DATA is located at the RVA(relative virtual address) C0000. So: 00400000 + 000C0000 = 004C0000 and at the end we add 5202 to this to get 004C5202. This is the address where our string is located. This tip is very useful when you can't find the string with W32dasm, but can with a hex editor. This is very handy to find out where that naggy message/error) gets pushed onto the stack. It's easy to find it now(in this example it will be push 004C5202). What you do with this info is up to you. .----------------------------------------------------------------------------------------------. | Keyfiles | | Written by MisterE | `----------------------------------------------------------------------------------------------' A keyfile is a registration file. The program looks if this file exists and if the characteristics of the file match with a good keyfile. If the keyfile is 'good' then the program is registered. NOTE: keyfiles are NOT .ini and .cfg files that have entries like: Name=MisterE; Serial=123454. Arriving at the protection scheme As you might have guessed, keyfiles are my favorite protection scheme, they really give you some things to think about. Keyfile protections can vary from very easy to very hard. But, before saying how you should crack such protection, i'll tell you how to discover you're dealing with a keyfile protection. Most of the time I open w32dasm and look for string like 'program.key' or 'program.lic'. If I don't find such string, and if I am still convinced it's a keyfile one, then I use Filemon. Get an old version of filemon at Fravia's Site. You might also want to take a look at his essay about this great tool. Now fire up Filemon and your program. You see the program looking for some kinda file that seems to be missing? Well, big chance that it's a keyfile. Most program's use the CreateFileA API, though there are other API's. At this time you might want to look up the CreateFileA Api. If you look the API up you'll read that the last parameter that get's pushed before the call is the filename of the file your program tries to open. So you put a breakpoint on this API (SI) and fire your target. SoftIce should break, now get out of this call and take a look at the file parameter. If it isn't the right filename, then continue running the program till you have the right filename. OK, you're at the protection scheme now! Some common keyfile checks Well, we reached the protection scheme. By now you should have created a yet unregistered keyfile with your favorite hexeditor. Most of the time the program uses the ReadFile API (other) to read some Data from the keyfile. This time it is quite important that you look up your win32.hlp. In case you're too lazy to look this one up, I've printed this one: BOOL ReadFile( HANDLE hFile, // handle of file to read LPVOID lpBuffer, // address of buffer that receives data DWORD nNumberOfBytesToRead, // number of bytes to read LPDWORD lpNumberOfBytesRead, // address of number of bytes read LPOVERLAPPED lpOverlapped // address of structure for data ); OK, take a look at the nNumberOfBytesToRead. This means that the program wants to read a certain number of bytes from the fileammount of bytes. If ReadFile fails it returns 0 in EAX. Well, this is the first common check. From now you can encounter quite a few different protections. Some programs only check if keyfile contains the name of the program. Another check, very common in the past when MS-DOS ruled the world, is that it only checks if some bytes match. Other programs do a CRC check. In other words, at this time you can encounter quite a few types of protection schemes (CRC, serial are common). So the rest is up to you. Good luck!! .----------------------------------------------------------------------------------------------. | Visual Basic Cracking | | Written by Rhytm | `----------------------------------------------------------------------------------------------' Introduction Welcome, first a few words before we start learning how to reverse engineer Visual Basic programs. I wrote this tutorial to help newbies learn how to reverse engineer Visual Basic programs. This tutorial should only be used for educational purposes only, and NOT for people who are only interested in spreading quick & dirty cracks on the internet. Use the software you crack for your own goods and let other people learn the art of reversing themselves instead of doing a 2 second search on the internet. I would like to thank all my friends in #Dread and #Cracking4Newbies for all the help I got with all my reverse engineering problems. I want to thank Edison for his tutorial that gave me the courage to crack my first program. Other thanks go to Fravia+ and all the people on his site. Special thanks go to Razzia, lots of the info I used in this essay comes from his fabulous essay. Requirements There are a couple of basic tools you'll need to follow this complete essay. If you haven't got them yet, download them somewhere from the web or just buy them. These are the tools I've used in this tutorial: W32Dasm 8.93, SoftICE 3.24, SmartCheck 6.0, Visual Basic 3 Decompiler, Visual Basic 3 Decompiler Addon, Visual Basic 4 Decompiler, Visual Basic 4 Decompiler Addon. I added a list with the complete listing of all the Visual Basic 5.0 runtime library functions. You can read it in the other API's section. Visual Basic Programs I hope you all now that Visual Basic programs don't call Windows APIs directly. They call a large runtime library with the most common Visual Basic functions. Q: Does a Visual Basic Program NEVER use any of the standard Windows APIs? A: In general no, in all the VB programs that I've cracked, I only had one case of a program that called GetDlgItem. If you're not sure just look at the string data reference in Win32Dasm BUT the Visual Basic runtime library does call the Windows API calls. Every Visual Basic program needs this library else it won't work, in most cases you can find this file in your windows\system directory. Every version has it's own runtime library (I'll discuss version 3 and higher in this essay). This is also the weak spot of Visual Basic programs, if we know the functions inside the runtime library and if we have the code calling the function, all we have to do is break at the function and we're at the place we want to be... Hehe, but we're going too fast now. Let us first take a look at the different approaches. Approaches There are several approaches to cracking Basic programs. You can base your decision on the most appropriate approach to use by checking the version it's written in, and the method used to compile it. Q: How do I know which version my Visual Basic program was made in? A: Download a program like Quickview and quickview the executable, or use a filemonitor to see which version of the runtime library the program is using. Most of the time the programs documentation already gives you this information. As said before every program uses it's own runtime-library, here is a list with the different runtime libraries: Visual Basic 3.0 Vbrun300.dll 16-Bit Visual Basic 4.0 Vb40016.dll 16-Bit OR Vb40032.dll 32-Bit Visual Basic 5.0 Msvbvm50.dll 32-Bit Visual Basic 6.0 Msvbvm60.dll 32-Bit Case1: Visual Basic 3 Programs These programs are very easy to reverse, just use a vb3 decompiler (don't forget to install the additional ocx controls). When you've decompiled the target you've got the source-code of the program. You'll need a little bit of Visual Basic knowledge but with some brains you should have no problems reverse engineering the program. Hint: When you've decompiled your program and the protection-routine calls many subroutines, think about giving the variables easy to recognize names. Case2: Visual Basic 4 Programs These programs require a better look, first try to decompile your program. If you're lucky (chances are about fifty-fifty) you get the source and can start searching for the protection routine. Otherwise you'll have to use SoftICE and W32Dasm to reverse the program. Chapter 3 deals with this approach. Q: Does Decompiling only work with 16Bit Visual Basic programs? A: No, it works as good as with 32Bit Visual Basic programs, just try it out. An even better method is to examine it with SmartCheck, more about Smartcheck in Chapter 3. Case3: Visual Basic 5 and Visual Basic 6 programs The approach for these programs is the same. You can't decompile Vb5 programs yet, although the author of the Vb3 and Vb4 decompiler hopes to release a Vb5 Decompiler soon. Your approach will depend on several things; I would like to mention one important thing. When someone writes a Visual Basic program he can choose two methods for compiling his program. Compile it to P-Code or to Native Code. It's easy to find out which way the program has been compiled. First try to load the target into Smartcheck. Are you getting an error ?? Then it's P-Code. If there's P-Code involved try to get your serial with the help of SoftICE and W32Dasm. Using Numega's Smartcheck Well, this tool is as good as a decompiler, maybe better because it only shows you the routines you're looking for. An important thing is to configure Smartcheck. (I assume you're using Smartcheck v6.0). The most important setting can only be changed once a program is loaded. Choose for Program - settings - Error detection - Advanced. Uncheck 'suppress system API and OLE calls' You also might want to go to Program - settings - Reporting and set SmartCheck to report some more events. Well, it's time to load your first target in Smartcheck. The approach is very simple. Click the play button. Navigate to the registration part, enter a name and serial, and click the button. Go back to Smartcheck and go to the right event-handler. Collapse it and you'll see your name and code being saved in a String. Take a good look, sometimes the serial is right in front of you. If not, choose View Show All Events. Now things are going cool . You'll see all the API calls and all calls to the VB runtime library. Take a good look again, study this information and 9 out of 10 times you can reverse the program this way. Q: Why is the ExitProc suddenly called ?? A: ExitProc = Exit Procedure. Something went wrong, the serial you typed wasn't correct, most of the time this call is made AFTER the final compare. But sometimes the program checks the length of your serial before it compares the codes or it does some other compare before the final compare. If you're lucky, you can retrieve the proper length of the serial with the info Smartcheck gives you. But some times the help of SoftICE can come out very useful. Using SoftICE and W32Dasm So you failed to crack your program with the help of Smartcheck.. Well then the programmer must be a clever person.. SoftICE will help you here. You CAN'T use a normal approach such as you do with C++ programs. The VB runtime library uses it own calls. I've listed most of them in Appendix A. There's one function that still is in use :) It's the hmemcpy function. Just try it out on a program. The only bad thing about this call is that it'll take you quite some time to get to the code you're program uses (in other words: get out of the runtime library). When you finally get out of all those dlls you can study the assembly and find the info you were looking for. Note: If you study the Vb functions and start using them instead of the hmemcpy function you won't have to step that much (still quite much). You can discover which APIs the program is using by taking a look at the import table with W32Dasm. Most API's have pretty clear names.. You can reach Rhytm at Rhytm@newmail.net. .----------------------------------------------------------------------------------------------. | Greyed targets and CrippleWare by BaneOldMan | | Edited by MisterE | `----------------------------------------------------------------------------------------------' This part is about grey targets or crippleware: programs that you must send money to the programmer so he will send you back the FULL version. Cracking such program can be very difficult, if not impossible. But, lucky us, most of them have usual 'weak spots' on which we can attack the target. We will give some useful tips on how to tackle the targets, but most is up to you. Find out if the target is missing a feature The first step is to find out if this function/code has really been removed. Enabling some function is much easier that writing a missing function!! Look in the dead listing for unused or unreferenced pieces of code that have something to do with the missing function. Like looking for calls to CreateFileA when dealing with a saved-disabled-program. It's very hard to say where you should start ungreying menuitem. Most of the time you see A LOT of calls to some routine that displays a messagebox telling you that 'this option is not available in the unregistered version'. Uncrippling Now...when you start uncrippling, you should use some Resource Editor like Borland Resource Workshop, Resource Studio32 or another Resource Editor to find the ID of the missing function. Try to locate the function using a dead listing. Look if you can see any conditional jump pointing at the function, or one that jumps over the function. Also look for calls to EnableWindow using a dead listing. One of the parameters of this function indicates if a menu should be enabled or disabled. To help you a bit I've printed some info about this API and an example on how to patch it below: The EnableWindow function enables or disables mouse and keyboard input to the specified window or control. When input is disabled, the window does not receive input such as mouse clicks and key presses. When input is enabled, the window receives all input. BOOL EnableWindow( HWND hWnd, // Identifies the window to be enabled or disabled. BOOL bEnable // flag for enabling or disabling input. TRUE means enable, FALSE means disable ); Study this call well, it'll be your best shot against this type of software. Below is the example code of a hypothetical program with its feature disabled: push 00000000 ; <-- disable flag push 0000031A ; <-- handle of the window (editbox, checkbox) call EnableWindow This code could be patched to push a 1 (enable flag) instead of a 0 (disable flag), or alternatively you can jump over the code if the window starts out enabled. A program can also enable/disable windows using the SendMessage API function by sending the window message WM_ENABLE: push 00000000 ; <-- lParam: not used push 00000000 ; <-- wParam: disable flag push 0000000A ; <-- WM_ENABLE push 0000031A ; <-- handle of the window (editbox, checkbox) call SendMessageA That's all the info we've got for you, it might not be enough, but it will surely help you on your way to enabling menuitems! .----------------------------------------------------------------------------------------------. | CD-Checks | | Written by MisterE | `----------------------------------------------------------------------------------------------' Well, these are most of the time easy to crack. Most CD-check follow a pattern...and that's BAD. Because that will only make things easier for us :). Usually, the check goes like this: 1) Look/check for CD-ROM drives. Programs do this using the some variable to keep track of the drive they're currently checking and the GetDriveTypeA API. Most of the time you can find this variable using w32dasm, just take a look at the string references, look for something like '%s:\' or 'xrom', then patch this variable this way it says 'c:\' or 'c'. Now the game will check if this drive is a CD-ROM using GetDriveTypeA. This API needs a drive letter as input and will then return some value representing to it's type. Take a look at the table below. Note: ofcourse there are other API's for all these checks. Value Meaning 0 The drive type cannot be determined. 1 The root directory does not exist. 2 The drive can be removed from the drive. 3 The disk cannot be removed from the drive. 4 The drive is a remote (network) drive. 5 The drive is a CD-ROM drive. 6 The drive is a RAM disk. As you can see is the return value 5 important for us. Now make a copy of some cd to your harddisk. Now place a breakpoint on GetDriveTypeA and run the game. You should get kicked back into SoftIce. You probably see a CMP eax, 5 after the call, followed by a jump. Patch the CMP so that it says 'CMP 5, 5' or change the jump. 2) The game takes a look if the label of the CD/HD matches using the GetVolumeInformationA API. Simply place a breakpoint on this API and patch the check. Note: this API also returns more information about the drive. Interesting for us might be the volume serial number and the maximum filename length on the drive. I haven't seen any checks for this, but there might be in the future. 3) Now we have to do a check if some files are on the CD/HD like movies, music tracks, etc. The program can check this using the CreateFileA API, but also -which is more common- GetLogicalDriveStings. Create these files or patch the program into thinking they're there. Though the game can also check the files on their contents and since we don't want a 100Mb on our HD using the ReadFile API. Just patch it. 4) As we all know CD's have zero bytes free on them, or at least, most CD's. Patch this simple check using a breakpoint on the GetDiskFreeSpace API. This API also returns more information like the number of free clusters. This information is used to check if the drive is write-protected. Also patch this check. Well we're done. Hope you removed all the checks. Though there are more possible checks, like checking the cluster size of the drive the game is on. But i've never seen a program doing these checks. Oh yeah, on note: you can also use w32dasm to crack these checks, might even be easier than SoftIce. .----------------------------------------------------------------------------------------------. | Last Words And Greetz | `----------------------------------------------------------------------------------------------' Well, I hope you enjoy reading this Guide as much as I enjoyed working on it. Still this Guide isn't complete and I always welcome help from you to write a piece. I will continue to work on this guide to keep it as up-to-date as possible. If you have had problems cracking a program you can always mail me here at MisterE@freemail.nl. Greetz in no particular order greetz go to: BaneOldMan, Rhytm, {_Suby_} (for helping me with this Guide, and being nice friends), Iczelion (Your win32asm tutorials RuLe!), Knotty Dread, Gattman, Ikke (for amazing me every time ;), Douby, Noos, VisionZ, G0rgon, Anarchriz, Elmopio, Lowton, Rdm_Task, Decoder|Z, Merkuur, H3llsp4wn, Fravia, Sandman, DEZM, [Kwai_Lo], Prophecy, Bisoux, [Six6Six] and all my friends on #Cracking4Newbies, #win32asm, #iNSiDE99 and #DREAD What now follows is reference material. I've included it to get the Guide as complete as possible. .----------------------------------------------------------------------------------------------. | Tools | `----------------------------------------------------------------------------------------------' This section is about tools that are usefull to us reverse engineers. SoftIce Guess i don't have to tell you about SoftIce, it's the most powerful debugger around. If you still haven't got it, download it now!! Windows32bitDisassembler Well, you should also be familiar with this tool. It is one of the best disassemblers. Only IDA beats this guy disassembling. But w32dasm has a windows gui, so it looks much nicer and is easier to use. Visit the Win32Dasm WEB Page at http://www.expage.com/page/w32dasm. InteractiveDisAssembler IDA beats w32asm at disassembling and has more features, though it lacks a nice windows gui. But good news has arrived, the people at DataRescue are busy working on a windows version of IDA. Can't wait to see it working. FileMonitor This is a great tool from NtInternals (www.ntinternals.com). It monitors which files want to read from other files. This is particularly handy when you want check if a program uses a keyfile to see if it's registered. It might also be handy for programs that store their registration information in .ini or .cfg files. No reverse engineer should be without this tool. Note: this program has a very nice keyfile protection. RegistryMoninor This is also a great tool from NtInternals (www.ntinternals.com). Regmon monitors which programs are accessing the registry. Use regmon for all kinds of protection. Like most products from NtInternals, this program uses a keyfile. HexWorkShop This is imho the best Hexeditor around, it's simple to use. You will need this tools alot!!! Get it at www.bpsoft.com. HIEW (Hacker's view) This is also an hexeditor. Some people like it more than HexWorkShop because it also show all the mnemonics. You can easily change mnemonic with this tool, without knowing the right opcodes for them. I dislike it because it hasn't got a nice Win GUI...but if you think appearance isn't important, then get it!! Do a simple search on the Internet to find it. .----------------------------------------------------------------------------------------------. | API's that might help you breaking into SoftIce | `----------------------------------------------------------------------------------------------' Here's a list of API's that might help you break into SoftIce, though if none of these API's work, you should open the target with Quickview or W32Dasm to get a list of the imports (the API's that this program uses) of this program. Take a look in the list if you see some API that might be usefull for cracking your target, then take a look in your win32.hlp for a description. Note: there are some variants on these API's, for example, try typing 'exp RegOpenKey' in SoftIce. API's that are used to get text from the screen GetDlgItemText(A) - Retrieves the title or text associated with a control in a dialog box. GetWindowText(A) - Copies the text of the specified window's title bar into a buffer. GetDlgItemInt - Translates the text of a specified control in a dialog box into an integer value. Hmemcpy - Makes a copy of data that it reads from a textbox, 16-bit BozosLiveHere - 32-bit version of Hmemcpy GetKeyState - Function retrieves the status of the specified virtual key. The status specifies whether the key is up, down, or toggled. API's that protection scheme's might use LstrlenA - Returns the length of the specified string. LstrcpyA - Function copies a string to a buffer. API's that keyfiles protections use CreateFileA - The CreateFile function creates or opens files and returns a handle that can be used to access the file. _lopen - 16-bit version of CreatefileA ReadFile - The ReadFile function reads data from a file. _lread - 16-bit version of ReadFile SetFilePointer - Function moves the file pointer of an open file. API's that CD protections use GetDriveTypeA - Function determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive. GetLogicalDrives - Function returns a bitmask representing the currently available disk drives. FindFirstFileA - Function searches a directory for a file whose name matches the specified filename. FindFirstFile examines subdirectory names as well as filenames. FindNextFileA - Function continues a file search from a previous call to the FindFirstFile function. GetVolumeInformationA - Function returns information about a file system and volume whose root directory is specified. GetLogicalDriveStrings - Function fills a buffer with strings that specify valid drives in the system. GetDiskFreeSpace - Function retrieves information about the specified disk, including the amount of free space on the disk. GetFileAttributesA - Function returns attributes for a specified file or directory. API's that are used to read/write from plain text files (INI, CFG) GetPrivateProfileString(A) - Retrieves a string from the specified section in an initialization file. GetPrivateProfileInt(A) - Retrieves an integer associated with a key in the specified section of the given initialization file. WritePrivateProfileString(A) - Copies a string into the specified section of the specified initialization file. WriteProfileString - Copies a string into the specified section of the WIN.INI file. API's that programs use to access the registry RegCreateKey(A) - Function creates the specified key. RegDeleteKey(A) - Function deletes a key and all its descendents. RegQueryValue(A) - Function retrieves the value associated with the unnamed value for a specified key in the registry RegCloseKey(A) - Function releases the handle of the specified key. RegOpenKey(A) - Function opens the specified key. API's that have something to do with time GetSystemTime - Function retrieves the current system date and time. The system time is expressed in Coordinated Universal Time (UTC). GetLocalTime - Function retrieves the current local date and time. SystemTimeToFileTime - function converts a system time to a file time. API's that put a nag-screen on the screen MessageBox(A) - Function creates, displays, and operates a message box. MessageBoxExA - Function creates, displays, and operates a message box. MessageBeep - Function plays a waveform sound. SetRect - Function sets the coordinates of the specified rectangle. EnableWindow - Function enables or disables mouse and keyboard input to the specified window or control. UpdateWindow - Function updates the client area of the specified window. CreateWindow - Function creates an overlapped, pop-up, or child window. CreateWindowExA - Function creates an overlapped, pop-up, or child window with an extended style; otherwise, this function is identical to the CreateWindow function. DialogBoxParamA - Display a DialogBox on the screen. ShowWindow - Function sets the specified window's show state. SendMessage - Function sends the specified message to a window or windows. wsprintf - Function formats and stores a series of characters and values in a buffer. Visual Basic APIs Here you find a list with APIs that VB uses. There are quite a lot...too many if you should ask me. For that reason I haven't included all of them. Sometimes you'll see some dots after an API, that means you have to go to SoftIce and type 'exp API' to see which variants of that API are available. Compare APIs __vbaStrCmp - Very important, compares two strings. __vbaStrTextCmp - Very important, compares two strings. __vbaVarCmpEq - Compare Equal __vbaVarCmpGe - Compare Greater/Equal __vbaVarCmpGt - Compare Greater Then __vbaVarCmpLe - Compare Lower Equal __vbaVarCmpLt - Compare Lower Then __vbaVarCmpNe - Compare Not Equal __vbaVarTextCmp... __vbaVarTextTst... __vbaVarTst... Other APIs that are common __vbaFreeStr - Very usefull __vbaFreeVar __vbaVarCopy __vbaVarMove __vbaVargVarCopy __vbaVargVarMove __vbaCopyBytes __vbaLenBstr... - Returns the length of a string __vbaLenVar... rtcBeep - Beep. rtcMsgBox - Puts a MessageBoxA on the screen rtc... - Some of them are very usefull for VB time-protections .----------------------------------------------------------------------------------------------. | Index | `----------------------------------------------------------------------------------------------' Introduction Serials Windows32BitDisassembler: String Fishing SoftIce: Getting Started Short Intermezzo about APIs and dlls Combining the power of Windows32BitDisassembler and SoftIce SoftIce: The 'Break on Memory Access' Approach Other Serial Protections Patching A warning before we start Finding the offset of the code you want to patch Intermediate way of finding the serial Let's Patch! Spreading the Patch Problems Nags Very Easy Nags (MessageBoxes) Universal approach to get rid of those nags Hard Nags Intermediate: String fishing using a hex-editor and W32dasm Keyfiles Arriving at the protection scheme Some common keyfile checks Visual Basic Cracking Introduction Requirements Visual Basic Programs Approaches Case1: Visual Basic 3 Programs Case2: Visual Basic 4 Programs Case3: Visual Basic 5 and Visual Basic 6 programs Using Numega's Smartcheck Using SoftICE and W32Dasm Greyed targets and CrippleWare Find out if the target is missing a feature Uncrippling CD-Checks Last Words And Greetz Tools API's that might help you breaking into SoftIce API's that are used to get text from the screen API's that protection scheme's might use API's that keyfiles protections use API's that CD protections use API's that are used to read/write from plain text files (INI, CFG) API's that programs use to access the registry API's that have something to do with time API's that put a nag-screen on the screen Visual Basic APIs Compare APIs Other APIs that are common Index Copyright (c) 1999 MisterE. All rights reserved.