I want to acknowledge my most sincere appreciation for all the guys that took their time to explain the various techniques on tool usage, standard protection schemes, not-so-standard ones, etc. etc. Thank you all people. You know who you are. Yet, one thing that some tutorials lack is that they explain the path from dowloading a program straight to the cracling procedure. What really happens while they are cracking, the dead ends, things that didn't work, etc..., is sadly neglected :-
1). Sometimes following a certain suspicious call, jump, etc, leads to nothing. Yet it is in the spirit of proper asmonauting to show that it happened, and, most important, to show WHY we followed that once-promising lead.
2). Most newbies fall in this kind of situation when attempting their first steps, and might get discouraged if they feel they're doing something completely pointless (while many times being very close to the crack site, without knowing it).
3). The useless approach for crack 'X' might be the approach that DOES work for another crack 'Y'. We can save some time by killing several cracks with one tutorial.
So, I'll try not to state only "step 1, step 2, done!" of the crack, but show you more or less, whenever possible, the kind of logic I had in mind at a certain stage, regardless of that logic being the appropriate one or not. Some of you might find this to be too long for some trivial cracks. If you really find this to be so, I'll consider adding at the bottom of each tut a more condensed, few lines version of the crack.
1). found at -- http://www.bpsoft.com,
2). protection kind -- password check
3). tools used -- NuMega SoftICE
4). level -- well, you have be a newbie if you haven't cracked this one yet...
Before we start, I want to tell you that this program surely has already been cracked and something tells me that some tuition on the course of action might be found somewhere in the web. This program is a hex-editor, a very common tool among asmonauts. There's always some crack giving a cracker a hard time to find it. No exception here. In the pursuit of displaying some original material, I unzipped some still protected material (that I keep to build a software museum one day). Since a Hex Editor is A MUST in many situations, I also unzipped a copy of an excellent Hex Editor called Hex Workshop.
When lauching this application, a screen pops telling me about this being a time-limited trial version, etc. It then ocurred to me that you, dear reader, might not have some of the material we will use for our studies. I also thought about the possibility of you needing some warm up, as I did, to refresh some assembly code ideas you might know but be not so sure about. What is better then than to try cracking the very first thing that might be interesting asmonauting territory? I decided to try some voodoo-cracking on the fly, as to show you, dear fellow newbie, not only things that work, but things that MIGHT work in different situations, but didn't in our specific case. We show how some slight change in plans can lead you to the end of your journey through the code : The crack! (or make you spend lots of extra hours barking at the wrong code).
Well, when clicking the 'HELP' then the 'ABOUT HEX WORKSHOP' in the menu, a window pops prompting you to enter something that seemingly will turn your trial version into a 'legal' one in the eyes of the program itself. Beware of such traps when you write your own protections my friend... It's an unforgiving world out there. This window that appears might be - most probably - one of 2 kinds : A 'WINDOW' in the general sense of the word, or a more especialized kind of window, called a 'DIALOG'. Dialog boxes are one of the main standards in the WINDOWS OS for use in getting some kind of input from users.
These dialogs, as commonly called, come with all sorts of more especialized 'windows' : Edit boxes (where a user types something), Check boxes (which the user can check/uncheck to select/unselect some features), Static text (Just simple unchangeable text to give messages to the user) and etc. At a first glance, this window looks pretty much like a dialog box with an edit box in it (this is where you should type your code). Since this is one area of the code which interests us a lot, it's a good idea to set some breakpoint 'near' it. Who knows what surprises we'll find there?.
You're probably already aware that WINDOWS programs have a BIG problem when trying to do anything : They use ready-made functions (existent in the WINDOWS OS itself) called API's (that's Application Programming Interface). As you write/read more and more code, you start to get acquainted with the names of these API's. A word before we move. There are mainly two kinds of programs we meet. 32 bit programs and 16 bit programs. Our target's executable file is called 'Hworks32.exe', and I think now you know what the 32 in the name means.
But how do we know if an app is 16 or 32 bit? First, WHY do we have to know it? Well, API's come in 2 flavours, 16 bit and 32 bit. Programs use API's that conform to their structure. For us to set a breakpoint on a certain API (we'll do it here), we need to know what kind we'll use. If your program is 16 bit and you use the 32 bit version of the API, SoftICE might never 'break' inside the program because it's looking for a 32 bit version of the API while the program is (or might be...) using the 16 bit version. The difference for us is this : The 32 bit version of the API's come with a letter 'A' appended to them. So, MessageBox is a 16 bit API while MessageBoxA is 32 bit. We'll be using then the 32 bit version. If you're in doubt of WHICH ONE TO USE when you start studying programs on your own, use BOTH for breakpoints.
There's an API very much used to retrieve the TEXT that as typed inside a dialog box (well, actually inside the EDIT BOX that is, by it's turn, inside the dialog). The name of this API is GetDlgItemTextA, a very sensible name. The 'Item' of the dialog is in this case an EDIT BOX. I tried first setting a breakpoint whenever such API was accessed by our program. Just load the file 'Hworks32.exe' in SoftICE and type BPX GetDlgItemTextA. Let's see... I type some random keys in the keyboard, and click the 'REGISTER'. Well, SoftICE doens't pop as expected. Instead I get another window from the program telling me I'm not playing it right. (It says 'INVALID REGISTER CODE'). What's wrong? well :-
1). Nobody said that the window WAS a dialog box, for a start...
2). The window MIGHT have been a dialog, but the program was not using this API to retrieve the text I typed.
3). etc, etc.
Everything can go wrong in this very difficult phase, when we want to get closer to the prey. Well, here your old friend asmo commits a first voodoo cracking mistake : Instead of pursuing the TEXT itself, I tried to track the CREATION of the window. 3 factors played a role here :-
1). Something veiled my mind about pursuing the TEXT. Also,
a memory lapse about other text-retrieval related API's.
2). I wanted to know more about how the window was being created. Maybe I'd even fall inside the code responsible for handling this register window itself. It has something to do with 'doing things the hard way'. My mom always advised me to take care with that.
3). It is my wife's birthday and the last thing I want to do (well, I WANT, really but I can't) is spend the whole day tracing code.
So I set another breakpoint. BPX DialogBoxA. Again nothing happened when the window was created...by 'nothing happened', my friend, I mean that SoftICE didn't pop with the program stopped at a certain breakpoint I set. I continued the window pursuit. BPX CreateWindow, BPX CreateWindowEx... nothing. Notice I even started using 16 bit API's. Complete lack of concentration...
Well, I don't want to go into details here. I DID get the handle to the window (by setting a BPX EnableWindow), but the thing was starting to take more time than I could allocate for that day... Then I remembered a certain API. GetWindowText. This API usually works with the text that is IN THE CAPTION of a window. That's the window title, the blue bar you see all the way up there in most windows. It happens that this little API retrieves the text INSIDE edit boxes because edit boxes DO NOT have caption bars. Heh... me and my memory. The text we are supposed to type is being handled by an EDIT BOX, a WINDOWS creature created mainly to do so when used inside dialogs or windows. Look at the following asmorithm :-
1). Load 'Hworks32.exe' in SoftICE
2). press 'CTRL-D' and let the program run.
3). Click 'HELP' then 'ABOUT HEX WORKSHOOP', our dear window appears
4). Press 'CTRL-D' again to access SoftICE, and set this breakpoint BPX GetWindowTextA
5). Press 'CTRL-D' yet again so we can type something in the window.
6). Type something you find sensible and easy for you to recognize. I typed 'PEPSI'.
7). Click 'REGISTER' and SoftCE will sing...
Well, you'll notice SoftICE stopped just at the beginning of the GetWindowTextA function execution... That's NOT part of our target program (It's a part of WINDOWS - the API). What we really need is the part of the program that called the GetWindowTextA function. How do we get it? Well, one option is to trace each step until a RET/RETF instruction takes us back to where the API was called from... But guess what? SoftICE has a very handy feature. By pressing 'F11', the whole API is executed and SoftICE takes us back to some point AFTER the API was called. You see the logic don't you? The API was called already, so SoftICE takes us to some code AFTER the call was executed. Well, we need to be careful here. Press 'F11' and you'll be taken to some line of code following a line saying 'CALL GetWindowTextA'.
In real life, the part of the code that verifies if your code os valid or not might be in many places. Take a look. What do you see after the API returns? Some instructions, a call, then a JMP. Any CALL we find might be the one that checks out the 'PEPSI' code I typed. The next step is to check for places that 'look like it'. Just use some logic. The first places to pay attention are the lines that contain CONDITIONAL JUMPS. These animals decide which code will follow. According to certain conditions, they will execute certain code.
If the conditions are not met (ax is not 0, or cx is not = bx, or Allah knows what...) they execute a certain other code. Lets do a first rough check to see if we find any of these conditional jumps. Notice that since our code IS NOT valid, the whole chain of possible jumps will surely take us to the 'INVALID CODE' window... Our voodoo approach will be to NOT FOLLOW the conditional jumps to see what happens... We will use the 'F10' key to execute each line of code. The 'F10' key has the advantage of executing each CALL it finds and coming back immediately, helping us stay in the track we're currently following. Tracing INSIDE each CALL may get very confusing and you'll forget very easily where the main branch of instructions is exactly.
PART 1 - these are the lines that follow our CALL GetWindowTextA :-
PUSH FF MOV ECX,[EBP+10] CALL 0044C780 ; Well, I wondered if this call was inportant, BUT since JMP 004544A2 ; THIS is a forced jump, I didn't care much. Lets' see... . . . POP EDI POP ESI POP EBP RET 000C ; Nothing much happened we continue
PART 2 - these come just after the last part. Nothing much either...
JMP 004260D1 ;What a weird jump. Heh. A needless jump to the next line? POP EDI POP ESI POP EBX LEAVE RET
PART 3 - the chase continues... Nothing interesting yet here :-
MOV DWORD PTR [EBP-18],00000001 MOV DWORD PTR [EBP-04],FFFFFFFF MOV EAX,[EBP-1E] MOV ECX,[EBP-14] POP EDI POP ESI POP EBX MOV [ECX],EAX MOV EAX,[EBP-18] MOV ECX,[EBP-0C] MOV FS:,ECX MOV ESP,EBP POP EBP RET 0004
PART 4 - You won't believe it...
MOV ECX,[EBP-0104] ADD ECX,64 CALL 00401C80 PUSH EAX LEA EAX,[EBP-24] PUSH EAX CALL 00439040 ADD ESP,08 PUSH 0047E7E8 LEA EAX,[EBP-24] PUSH EAX CALL 0043A7F0 ADD ESP,08 TEST EAX,EAX JZ 004262A8 <-- weee!
OK. You will notice that our code DOES NOT jump to this location. Press F10 if you want to confirm this fact. It didn't go there. In our language, that MIGHT be the path that leads to something different than a 'INVALID CODE' window. Let's force our program there to see what happens. Enter this : r eip (to change the pointer to the next instruction to be executed), then type 004262a8 and press 'ENTER'. We tricked the program as if it HAD jumped there. The bar that shows where we currently are might have disappeared from your screen. Press '.' then 'ENTER' to make that code location reappear. Ready? press 'CTRL-D'.
Heh. Didn't work. Well, that seemingly wasn't a very important jump. Let's continue tracing to check for more. (By the way, you might need to repeat the whole procedure again to get where we left. Do it, it's good practice). Continuing from the place where we CHANGED EIP. We won't change it now as to let the program flow normally.
LEA EAX,[EBP-24] PUSH EAX CALL 004373C0 ADD ESP,04 MOV [EBP-14],EAX JMP 004262AF MOV DWORD PTR [EBP-14],00000000 MOV DWORD PTR [EBP-14],00 JZ 00426332 <-- this time I didn't get happy so fast...
Another conditional jump. Well, my friend, here's your crack. This jump is the one that takes us to the 'Your registration code stinks' window. How do I know that? well, I pressed F10, but just before that, I wrote down the adress AFTER this JZ, in case I didn't like the results of the jump. I forced the EIP here, after the 'JZ 00426332', and pressed 'CTRL-D'. Try it. Enter your name and see how it works fine. Don't forget to buy the original if you intend to use this program. It's great and the people who constructed it deserve the money. They're fellow programmers.
Our voodoo cracking section did work after all. Let's celebrate the birthday - the asmonaut.
.....and the quick snippets courtesy of yours truly.....
:0042627B PUSH 0047F7E8 <-- StringData Reference JN11mARQ.
:00426280 LEA EAX,[EBP-24] <-- Code entered.
:00426283 PUSH EAX <-- Stack it for next function.
:00426284 CALL 0043A7F0 <-- Compare code entered with JN11mARQ.
:00426289 ADD ESP, 08 <-- Tidy stack again.
:0042628C TEST EAX,EAX <-- Check.
:0042628E JZ 004262A8 <-- Jump_JN11mARQ_isn't_a_good_code.
JN11mARQ is a registration code that was widely posted around the web for Hex Workshop and in this version the programmers have gone to great lengths to ensure losers won't be using it. Function CALL 004373C0 is the real check, first a string length check (8 being valid), then a check that the first 2 letters of your entered code were SY (and as I recall some other 2 letter combinations), numbers are not permitted, assuming you pass these checks your code will be valid.
As soon as the program accepts your code, you will be asked to enter your registration details, fill them in as you please, note also that the information will be written to the file HEXWORKS.REG and that this file will only actually be checked for its length (210 bytes). Take a look with a >bpx _lopen. I'll leave you to patch this program as you see fit, or just register it for your own evaluation use. If you patch try and locate the flag setting instruction beneath 004373C0, it looks like this :-
:0043743F REPZ CMPSB <-- Compare (E)SI:(E)DI - SY
with first 2 chars of your code.
:00437441 JZ 00437448 <-- Jump_good_code (this moves our flag EAX to 1).