Text: tickle.dr Purpose: Tutorial on cracking Tickle.exe using hmemcpy and memory breakpoints Program: Tickle.exe - Keeps your ISP connection alive By: drLAN, mexelite Let's get started cracking this baby... Run the program and select: - Tickle - Register Now type in any name and code, but don't press enter yet. First pop over in to SoftICE by pressing Ctrl-D. Let's set a breakpoint on hmemcpy. This routine is often used to manipulate strings in memory. To set the breakpoint type: bpx hmemcpy. Make sure you get your name and code typed in before you set the hmemcpy breakpoint, or sICE will break for each character you type. Now toggle back to the program with Ctrl-D and press Enter or click OK. As soon as you hit Enter, sICE pops, at your hmemcpy breakpoint, because the program just used hmemcpy to read in your name. Name press Ctrl-D again so the program will read in your code. The ICE pops again, this time as the program reads your code into memory. Now let's scan memory for the reg code we entered. I entered the following: Name: drLAN Code: 006969 So my search looks like: s 0 l ffffffff '006969' sICE should find an echo of this string setting in memory. It found mine at 013F:0076177C. Your actual segment:offset will probably vary. Ok, so now we found a copy of our string in memory, now what. Well, let's set a breakpoint on this memory location. There are many ways to do this and you may need to use differemt approaches depending on the program you are working on. Some common approaches are to breakpoint on a memory location (BPM). Any reads/writes at that location will trigger the breakpoint. Another approach is to set the breakpoint on a memory range, from the first char of your reg code to the last. Or, if you know a little about the proggie you might want to break on a single byte (BPMB), a word (BPMW), or a double word (BPMD). Each of these approaches has its merrits depending on what you're looking for. I commonly use BPM and BPMB. So, based on where it found my string, here are the BPM and BPR approaches. NOTE: Only use one of the two. I used approach #1. #1: Breakpoint on memory location: bpm 013f:0076177c <== this is the one I set #2: Breakpoint on memory range: bpr 013f:0076177c 013f:00761781 RW Note the last two digits changed on the ending range. That's because it is pointing to the memory location containing the last character of our string. First character is at 013f:0076177c. String length is 6. So the last char is at 013f:0076177c+(6-1), or 013f:00761781. Sometimes the program will create another copy of the string in memory before doing its final comparison(s). Sometimes it's this second copy we need to scan for. We could single step through the program for a while, using F10. After each CALL, do the scan again to see if it has made a second copy. If so, set a memory breakpoint at that address, too. Don't clear the first one unless that memory segment is completely overwritten with something different that the code you typed. Now that we have our memory breakpoints set to pop whenever the program looks at the code we entered, let's let the baby run until it compares our code with the real code... So, press Ctrl-D again. Now you should be sitting one instruction before the good-guy/bad-guy compare routine. The code should look something like this: MOV CL,DL CMP DL,BL JNZ 78005DAC ; bad-guy, jump to sorry sucker TEST CL,CL JZ 78005DB6 ; good-guy, jump to thanks for registering Now, if you scroll up through your data window using your mouse, or change focus to that window and use Ctrl-Up Arrow, you will see the code that points these registers at memory locations for the compare routine. You should see DL being pointed to [EAX] (the good code) and BL being pointed to [ESI] (our code/the bad guy code). You can verify this with D EAX, and D ESI. If you scrool up the code you find should look like this: MOV ESI,[ESP+18] MOV EAX,[ESP+14] MOV DL,[EAX] ; points DL to the memory location of good-guy code MOV BL,[ESI] ; points BL to the memory location of bad-guy code Then we hit the code above... D ESI ; bad-guy code (the one we entered) D EAX ; good-guy code (you know what to do with this one) Beautiful, there's your good-guy code. Clear your breakpoints and register this baby!