Target : SQL Navigator v3.1e1
Purpose : I usually don't write tutorials, but I have yet to see a tutorial on this one particular subject (some similar though).
Approach : Even though this is a serial protection, we are going to reverse it using a different approach (Self Modifying Code).
Tools : SoftICE, W32Dasm, Hiew & ProcDump.
OK, before we jump headfirst into this program, I just wanted
to warn you, we are going to be doing load of tracing. So this
isn't going to be a quick 30 second crack. As with all programs
we are going to reverse, lets get to know the program
first. So we start up Sqlnav3.exe, and we see a window come up saying we need to enter a reg code. Hitting cancel on that window we get another one saying this program is not authorized for this system. Hit OK, and the program exits.
Well isn't that crappy, they won't even let you get to the program. We have to fix this little error, So we open the program up in W32Dasm and find out that we don't learn much from this, so lets fire up the program in SoftICE's symbol loader and start our tracing, until we pass the call at 6ACA92. When we step over that, we get kicked out of SoftICE and those annoying nags come up. Well, what does that mean? it means that all the code for generating those windows are inside that call. So we exit out of the program and go back to the symbol loader, type : bpx 6ACA92 and press F11, so lets follow the call by pressing F8.
After following the call we begin our tracing again by pressing
F10 and just like magic, when you try to step over the call at
43675E, out you go from SoftICE and there are the nags, so lets
follow that call. After tracing through what may seem like a million
lines with F10, we come to a call at 4C7E7D, when we step over
that call up comes a nag, but when we press cancel on the first
nag, we are hammered back to SoftICE. well we are getting closer,
but we havn't reached the part of the code where the second nag
is called. So lets follow. As we continue to trace through with
F10 we notice that the call at 4343FD is creating the first nag,
but it didn't kick us out of SoftICE, so lets keep tracing down,
and we come to a JZ at 43446F that
is jumping back a couple of spaces in a continuous loop. Well, just for a laugh lets type:r fl z and invert the zero flag, and instead of jumping at that location, it will just pass the JZ by.
Goodness me, we exit out of SoftICE, and the first nag is gone,
we simulated a button press. This is the first
step in cracking the program, but we still get the second nag, well, first lets concentrate on the second nag (a hell of a lot easier than the first) so now, we reload the program in symbol loader, step through that first call that we followed at the beginning of this essay, and click through the nags. Now when we get back to SoftICE we see this :-
:006ACA92 CALL 00436728
:006ACA97 MOV EAX, DWORD PTR [006B5580]
:006ACA9C CMP BYTE PTR [EAX], 00
:006ACA9F JNE 006ACAAB
:006ACAA1 CALL 0040388C
:006ACAA6 JMP 006ACBA6
* Referenced by a (U)nconditional or (C)onditional Jump
at Address: :006ACA9F(C)
:006ACAAB MOV EAX, DWORD PTR [EDI]
At 6ACA9C the data that is located in the memory address at EAX is being compared to zero, one line below that, there is a JNZ... this means if they are the same, then don't jump. If they are different, then jump, and as before when we get to the JNZ at 6ACA9F lets type : r fl z and make it jump. Now exit out of SoftICE, and the program now loads. So basically the data at the memory address in eax (6B7F84) is being compared to 0, if they are the same, then exit, if they are different, load the program.
So lets do a bit of tracing to find where that flag is set. Back into SoftICE we go, this time lets follow the call at 6ACA92, and step through untill we get to the call at 43675E. Lets follow that one once again. And once again, we step through what seems like a million lines of code. Until we get to this bit of code :-
00698FA9 XOR EAX, EAX
Remember above we wanted the data that was at the memory address in EAX to not be equal to 0... so lets patch this in Hiew,
change 33C0 to B001 which is MOV AL, 01. Now exit hiew and run the newly patched program. We get the first nag as expected. but the second nag is gone, and the program loads up!.
Now we are going to get to the fun part. Adding our self modifying code. Why do we have to add self modifying code? well if you go to that jump that we changed the flags of in the beginning of the essay, and simply NOP it out and run the program, ouch, that severely butchered the crap out of the program. So, it only takes a little bit of logical thinking to realize that we want the JE at 43446F to be bypassed only the first time it is referenced. Every other time we want it to follow its normal routine.
The answer is self modifying code. To add our code, we need to find part of the program that isn't used by anything... just do a text search in W32Dasm for ADD [EAX], AL (which in hex is 0000x), lets just say we find what we need at 4061DD. This is where we will add our code, but first we need to make the program goto this location. So we take the JZ that we want to mess with at 43446F take note of the exact bytes, and we open the program up in Hiew, and change that to a JMP 4061DD. Once we do that, we can add our new code at 4061DD.
Since we changed the JZ to JMP we aren't going to want it to
stay that way or the program would crash, so remember the bytes
that you replaced to make the JMP 4061DD? well we need to take
those bytes 74C18945F8 and we need to put them back, how you might
ask? with a MOV DWORD PTR [addy], data and a MOV BYTE PTR [addy],
data. As you
can see this bit of data is more than eight characters long so we are going to have to make two lines. The first one needs to be:-
MOV DWORD PTR [43446F] , 4589C174 <-- Remember that the bytes need to be listed backwards.
The opcodes for that line is C7056F444430074C18945, now we need to add a second line:-
MOV BYTE PTR , 0F8
The opcodes for this line are C60573444300F8.
Now we have our self modifying code in place all we need to do is to jump to one line under our referring jump (this will simulate a bypassing of the JZ at 43446F only the first time it is referenced, every other time it will work normally. So we add this final line:-
JMP 434471 (opcodes E97EE20200).
Now it appears that we are done, right? so we load up the program and ACK we got an access violation. That simply means the program is set for read only, not read/write, so lets load this up in ProcDump's PE editor and change the CODE sections characteristics from 60000020 to C0000040, if you don't know why, read Pietrek. Now exit and try loading the program again. YES it works, no more nags and the program runs correctly, with an unlimited license at that :-).
Well what have we learned from this? One, we learned that some
programs can make you want to pull your hair out from doing so
much tracing. Two, we learned how to make a program patch itself
(in memory, not the actual .exe) this is worthwhile for cracking
several protection schemes. Three, we also learned (those of us
who are software authors) yet another *potentially* powerful protection
Greets (so many friends, please don't get mad if I left you out) :-
AB4DS, Torn@do, Kwai_Lo, Killer_3k, N0-B0dy, Azir, Darkie, Data_, Bud-, all the guys in #cracking4newbies, #shock, and #hlm2k.
Essay by Kathras.