[Xorolc]'s Solution for
 DnNukes Crackme v1.1

Tools Used: SoftIce, W32dasm, & UPX
Introduction: Just a few words before we get started. This solution is written assuming that you have a BASIC working knowledge of SoftIce, W32dasm, and a brain :).
Protection: Very creative!! It' a simple serial check, but it also checks that the window is a certain size.

Getting Started: Ok, lets get everything unziped and put in a working directory. First thing I notice is that the exe is rather large for a simple crackme (208kb). It must be some large algo or some boring protection that does all this crap, or is full of graphics or something. Lets check a quickview on it.......nothing. Could this be packed?? Open it up with your favorite hex editor and sure enough you see it, UPX! Well, score UPX from  http://protools.cjb.net . BTW, this is a great site to get all sorts of stuff. Ok, run UPX with the -d switch to unpack it and you'll be left with a 423kb exe WOW! Now if you do a quickview you'll see some stuff, but now that we know its not packed we can also fire up our disassembler. Why haven't we gone into the actual program yet? Well, it's a good habit to check out your target first. It'll help you out when your throwing out Keygens like mad. Ok, lets go. First thing I like to check is the Ref's. Looking at the string refs we see a few things. 1)This thing was coded with Borland Delphi. That explains a little bit about why the exe is so bloated. Borland is a pos and crams so much RTL crap in there it's a joke. The only other thing that really catches my eye are the 2 long numbers there "9877553311" & "9977553311". Well, I think we have enough info to start cracking. Lets fire up the exe. Ok, just serial so lets enter anything in like my favorite test number "14789" and click ok. No error box? So we wont be able to backtrace from that. Ok, lets start setting some breaks. My favorite 2 to start at GetWindowTextA and GetDlgItemTextA. ok, set that and hit ok. Nothing! Well, lets use our other favorite breakpoint. hmemcpy. ahh, ok F11, then F12 til we are in the crackme code. Look at the section name, CRACKME1!UPX0..mmm, that would have told us about our packer if we hadn't done our initial investigation.Well, trace out of the calls until you get to here

:004555C8 837DFC00           cmp dword ptr [ebp-04], 00000000
:004555CC 7712                    ja 004555E0

This is just a simple check to make sure you entered a serial. Now lets continue on in our trace. This will jump us to this point

:004555E0 8D55FC                  lea edx, dword ptr [ebp-04]
:004555E3 8B83C4020000      mov eax, dword ptr [ebx+000002C4]
:004555E9 E852D3FCFF         call 00422940
:004555EE 8B45FC                  mov eax, dword ptr [ebp-04]  <-- do a D eax here, what do you see?

* Possible StringData Ref from Code Obj ->"9877553311"  <-- Remember those 2 long numbers we saw, here's one of them

:004555F1 BAC8564500          mov edx, 004556C8   <--- Do a D EDX here what do you see?
:004555F6 E881E5FAFF          call 00403B7C
:004555FB 7512                       jne 0045560F

Ok, having seen this its a safe bet that a compare of some sorts is about to happen. Sure enough if we trace into the call at 004555FB we see that.  At this point we could just exit and try that code, but lets keep going. Remember the other large number? Maybe it too is used or something??? Ok the JNZ takes you here

:0045560F 8D55FC                  lea edx, dword ptr [ebp-04]
:00455612 8B83C4020000       mov eax, dword ptr [ebx+000002C4]
:00455618 E823D3FCFF         call 00422940
:0045561D 8B45FC                  mov eax, dword ptr [ebp-04]  <--- D EAX has your serial

* Possible StringData Ref from Code Obj ->"9977553311"
                                  |
:00455620 BA2C574500           mov edx, 0045572C  <--- D EDX has the other large number
:00455625 E852E5FAFF           call 00403B7C   <--- CMP EAX,EDX
:0045562A 7523                        jne 0045564F  <--- if not then jump cause we are wrong
:0045562C A110884500           mov eax, dword ptr [00458810]        <--otherwise move a value into EAX
:00455631 83783C78                cmp dword ptr [eax+3C], 00000078 <--and cmp with 0x78
:00455635 7518                         jne 0045564F <---Jump if we don't match, and at first we don't
:00455637 6A00                        push 00000000

* Possible StringData Ref from Code Obj ->"Good crackah :)"

:00455639 B938574500              mov ecx, 00455738

* Possible StringData Ref from Code Obj ->"Damn yer good ;). But if this "
                                        ->"is your first time, then I guess "
                                        ->"you changed the flag to 0 wich "
                                        ->"is wrong! Now go back and try "
                                        ->"again :).. But if ya did make "
                                        ->"it plz mail me how you did it.. "
                                        ->"DnNuke@yahoo.com"

OK, hold on just a second. Where the heck did that weird value come from that was compared to 0x78?? Well, this is where I got stuck for a little while. If you set a break on the memory access it takes a while to backtrace. But eventualy you'll see some weird calls, like IsIconic, and crap. I guess it was just ZEN-cracking that did it, but I figured that value was getting called early on, since with a break on hmemcpy we didn't see anything. I started looking for things I could change about the crackme, or my system, to get a different value. Having looked at that weird AIP IsIconic, I start thinking about that. Maybe once you entered the right serial, then minimized the window that would register, but sadly no. So I looked for other related API's and came across this little beauty.
BOOL GetWindowRect(
    HWND hWnd,    // handle of window
    LPRECT lpRect  // address of structure for window coordinates
   );
I decided to try and resize the window and then go back in and look at the strange compare, sure enough it was different. So, this must be it. once I made the window a little longer, I got the number to equal 0x78 and the serial 9977553311 worked. Now lets look a litle deeper at this though. The Code is found here.

* Reference To: user32.GetWindowRect, Ord:0000h
                                  |
:00428AC8 E8FFD7FDFF              Call 004062CC

Now going back to our look at the API we see that it returns an address to a structure for some coordinates. Well, this should then be stored in ESP, right? Take a look. D ESP look at those 4 longs. If you look at the RECT structure you see it take 4 longs. tracing through the code some more shows us what its looking for. The Length.

:00428B35 8B44240C                mov eax, dword ptr [esp+0C]
:00428B39 2B442404                 sub eax, dword ptr [esp+04]
:00428B3D 89433C                    mov dword ptr [ebx+3C], eax

if you look at the memory you'll see what i mean. Well, this has certainly been an interesting crackme. I've already given congrats to the author. Until next time,

-[Xorolc] of tNO
I can be reached on Efnet in #cracking4newbies or #tNO2000 or via email xorolc@hotmail.com