Tutorial by dihux
____________________________________
Target.: Kanal23 Trial 0.1
         By Acid_Cool_178

Remarks: http://home.no/k23
         This is where i got
         the crackme from.

Task...: Nag
         Disabled function
         Serial

TutDate: 27.sep.2002

Tools..: W32Dasm
         Hiew


Some words before be proceed with our tasks.

* Now talking in #kanal23
* Topic is 'http://home.no/k23 - Trial Crackme 0.1 is not valid anymore, 0.2 is under construction by Acid'
* Set by [AC_178] on Fri Sep 27 12:38:35

As you can see, the crackme isn't valid anymore for joining
the group. A new trial crackme is under construction. Anyway,
my intentions are NOT to join their group but learning newbies
how to crack.

To the cracking.
First I advice you to execute the crackme, and observe whatever
there is to observe. It is important that you know your target!
First the nag pops up, and then the main window appears.
Notice that the button is disabled. We have to enable it. Then
we will have to find the serial, write it in the textbox and
then 'check the serial'.

[NAG]
Load the crackme into W32Dasm. We have to find our nag, and patch
it away. Try to remember what text the nag showed to us. Open
the string references in W32Dasm and see if you can find it there.
Where is the string references? Click the button next to the printer
button and the string-ref-window should appear. But be aware, this
button isn't always enabled. If the disassembler can find strings 
in the disassembled file this button will be enabled, and if not,
then it will be disabled. You don't need great knowledge to under-
stand this. I assume that you have found the string refs by now.
See the "{-- The NAG --}"? Double click that string and we will be
taken to it.

//******************** Program Entry Point ********

:00401000 6A00                    push 00000000			 // this is the same as 'push MB_OK' in asm
:00401002 6823304000              push 00403023			 // ADDR 00403023 contains the nag caption 'kanal23 - RCE'

* Possible StringData Ref from Data Obj ->"{-- The NAG --}"      // Taken here(this is just a reference)
                                  |
:00401007 6831304000              push 00403031                  // ADDR 00403031 contains the nag message
:0040100C 6A00                    push 00000000			 // same as 'push NULL' in asm 

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:0040100E E8C7020000              Call 004012DA                  // This CALLS the messagebox

Notice that we landed right below the program entry point. This 
makes it possible remove the nag by changing the entry point to
00401013 which is the address after the call. We will not do it
like this. It will only result in bad habits, though that would
have been the best solution for this nag, optimized code ect...

If you haven't got 'Win32 Programmer's Reference' yet, go and get
it. This will help you alot while cracking, and coding. Sorry I
don't remember where I got it. 

"The MessageBox function creates, displays, and operates a message
box. The message box contains an application-defined message and
title, plus any combination of predefined icons and push buttons."

int MessageBox(
    HWND hWnd,          // handle of owner window
    LPCTSTR lpText,     // address of text in message box
    LPCTSTR lpCaption,  // address of title of message box  
    UINT uType 	        // style of message box
   );

Yeah, this is pretty straight forward. Just be aware of that the
code will come in reversed order when compiled. Like this:

push uType
push lpCation
push lpText
push hWnd
Call MessageBoxA

Take a look at nag code, it is somewhat identical to this. After 
the pushes the MessageBoxA api is ready to be called.

If you nop a push or two before a call, the app would most likely crash.

To prevent the crackme from calling the message we will have to nop the call.
What is noping?
Noping something is making it do nothing.
A NOP is an opcode, in hex it is 0x90/90h.
And NOP means no operation.

Now open the crackme in Hiew. TIP: You can drag and drop the
crackme on top of Hiew.exe or a shortcut that leads to Hiew
and it'll start with the crackme loaded in text mode. Be sure
that the crackme isn't in use, or else Hiew won't be able to write
to it. Textmode looks kinda screwed? well, we will not be doing our
work in text mode. Hit F4 and select decode mode. Now we gotta
get to our nag. Hit F5(goto) and type in ".0040100E" which is
the address of the call and hit enter. Now you should be here.
 
.00401000: 6A00                         push        000
.00401002: 6823304000                   push        000403023 ;" @0#"
.00401007: 6831304000                   push        000403031 ;" @01"
.0040100C: 6A00                         push        000
.0040100E: E8C7020000                   call        MessageBoxA ;USER32.dll
.00401013: 6A00                         push        000
.00401015: E87E020000                   call        GetModuleHandleA ;KERNEL32.

Now hit F3(edit). You will now be able to change the code.
Now write 90 five times. The lines will jump down because it can't
be two nops on one line. To update the file hit F9, and if you wanna
quit Hiew, hit F10.

Why did I make 5 nops?
90-in-hex = NOP = 1 Byte
E8C7020000 = 5 Bytes
Therefor we have to nop five times.
Or else, the code would have been totaly screwed.
The nag is now removed, unless you have done something completly wrong.





[DISABLED FUNCTION]
Now we have to enable the disabled button.
This is just as easy as removing the nag.

Take a note of the buttoncaption, 'Check the serial'.
See if you find can that in the string refs in W32Dasm. Yes, you can.
Double click the string.

:00401180 6A00                    push 00000000
:00401182 FF3554324000            push dword ptr [00403254]
:00401188 6A02                    push 00000002
:0040118A FF7508                  push [ebp+08]
:0040118D 6A19                    push 00000019 
:0040118F 68F5000000              push 000000F5
:00401194 6A37                    push 00000037
:00401196 6A14                    push 00000014
:00401198 6800008050              push 50800000 

* Possible StringData Ref from Data Obj ->"Check the serial"           // string ref
                                  |
:0040119D 6890314000              push 00403190 

* Possible StringData Ref from Data Obj ->"Button"
                                  |
:004011A2 684C324000              push 0040324C   
:004011A7 6800020000              push 00000200 

* Reference To: USER32.CreateWindowExA, Ord:0058h
 

From this we can see that the button is created with CreateWindowExA.
Lets take a look on the api in win32 programmer's reference.

====CUT====
The CreateWindowEx function creates an overlapped, pop-up, or child
window with an extended style; otherwise, this function is identical
to the CreateWindow function. For more information about creating a
window and for full descriptions of the other parameters of CreateWindowEx,
see CreateWindow. 

HWND CreateWindowEx(
    DWORD dwExStyle,	        // extended window style
    LPCTSTR lpClassName,	// pointer to registered class name
    LPCTSTR lpWindowName,	// pointer to window name
    DWORD dwStyle, 	        // window style
    int x,	                // horizontal position of window
    int y,                    	// vertical position of window
    int nWidth,	                // window width
    int nHeight,	        // window height
    HWND hWndParent,	        // handle to parent or owner window
    HMENU hMenu,	        // handle to menu, or child-window identifier
    HINSTANCE hInstance,	// handle to application instance
    LPVOID lpParam 	        // pointer to window-creation data
   );
====CUT END====

Alot of options to be pushed before calling, but the only
thing we are interested in here are the window style(dwStyle).
Why dwStyle?
dwStyle specifies the style/look of the stuff it is about to create.

As I said earlier, it will be in reversed order.

:0040117B A358324000              mov dword ptr [00403258], eax
:00401180 6A00                    push 00000000                        //LPVOID lpParam
:00401182 FF3554324000            push dword ptr [00403254]            //HINSTANCE hInstance
:00401188 6A02                    push 00000002                        //HMENU hMenu
:0040118A FF7508                  push [ebp+08]                        //HWND hWndParent
:0040118D 6A19                    push 00000019                        //int nHeight
:0040118F 68F5000000              push 000000F5                        //int nWidth
:00401194 6A37                    push 00000037                        //int y
:00401196 6A14                    push 00000014                        //int x
:00401198 6800008050              push 50800000                        //DWORD dwStyle

* Possible StringData Ref from Data Obj ->"Check the serial"           //LPCTSTR lpWindowName
                                  |
:0040119D 6890314000              push 00403190                        //LPCTSTR lpWindowName

* Possible StringData Ref from Data Obj ->"Button"
                                  |
:004011A2 684C324000              push 0040324C                        //LPCTSTR lpClassName
:004011A7 6800020000              push 00000200                        //DWORD dwExStyle

* Reference To: USER32.CreateWindowExA, Ord:0058h

:004011AC E8F3000000              Call 004012A4                        //Call CreateWindowExA

I hope you get this. The dwStyle is 50800000h as you can see.
If we dig a bit in WINDOWS.INC we can see what this actually means.

WS_POPUP                             equ 80000000h
WS_CHILD                             equ 40000000h
WS_MINIMIZE                          equ 20000000h
WS_VISIBLE                           equ 10000000h
WS_DISABLED                          equ 8000000h
WS_CLIPSIBLINGS                      equ 4000000h
WS_CLIPCHILDREN                      equ 2000000h
WS_MAXIMIZE                          equ 1000000h
WS_CAPTION                           equ 0C00000h
WS_BORDER                            equ 800000h
WS_DLGFRAME                          equ 400000h
WS_VSCROLL                           equ 200000h
WS_HSCROLL                           equ 100000h
WS_SYSMENU                           equ 80000h
WS_THICKFRAME                        equ 40000h
WS_GROUP                             equ 20000h
WS_TABSTOP                           equ 10000h
WS_MINIMIZEBOX                       equ 20000h
WS_MAXIMIZEBOX                       equ 10000h

WS_CHILD  + WS_VISIBLE + WS_BORDER = 50800000h
40000000h + 10000000h  + 800000h   = 50800000h

hmm. The button is created with WS_BORDER, WS_CHILE and WS_VISIBLE.
It shouldn't be disabled, unless there is something that disable
it after its creation. Lets take look on the code below the createwindowexa.

:004011B1 A35C324000              mov dword ptr [0040325C], eax
:004011B6 6A00                    push 00000000
:004011B8 FF355C324000            push dword ptr [0040325C]

* Reference To: USER32.EnableWindow, Ord:00B6h
                                  |
:004011BE E8F3000000              Call 004012B6 

This explains it all. If the createwindowexa succeeds the return
value is the handle to the new window. The return value is always
stored in eax.

mov   dword ptr [0040325C], eax  // this moves the return value into dword ptr [0040325C].
push  00000000                   // this is the same as push false which make the button disabled.
push  dword ptr [0040325C]       // this pushes the handle to the new 'window' which is our button.
call  EnableWindow               // Disable the button

but if this 'pushed true' the button would have been enabled(same as push 00000001).
guess what? we only need to patch address 004011B6 from 6A00 to 6A01. Then it'll
push 00000001. I assume that you know how to change data in Hiew now. Go and do it.
This is not the only way to prevent the crackme from disabling the button. If the call
never calls, the button won't be disabled. What method do you prefer? do what you like.

Finish changing?
Try it. Yeah, the button is enabled. Try checking serial. You'll get a badserial message.
Click it away, damn! The button is disabled again!!! It has to be something after the message
that disabled it.

:00401253 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"kanal23 - RCE"
                                  |
:00401255 6823304000              push 00403023

* Possible StringData Ref from Data Obj ->"Sorry, the serial didn't match."
                                  |
:0040125A 6808324000              push 00403208
:0040125F 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:00401261 E874000000              Call 004012DA
:00401266 EB00                    jmp 00401268

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040124F(U), :00401251(U), :00401266(U)
|
:00401268 6A00                    push 00000000
:0040126A FF355C324000            push dword ptr [0040325C]

* Reference To: USER32.EnableWindow, Ord:00B6h
                                  |
:00401270 E841000000              Call 004012B6

Here is the code where the badserial message is. can you see that
EnableWindow call? and those pushes before? yes it is the same as before.
After the message is displayed this code is executed. You will have to
change 00401268 from 6A00 to 6A01, then the button won't be disabled after
the messagebox. We've been through this before, if there something you
don't get, reread the whole Disabled Function section or come and ask me on efnet.




[SERIAL]
Nothing hard here either. It's always smart to locate where the serialcheck
is before doing something else. You can come close to the serialcheck by looking
in the string refs, and see if there are strings that says good or bad things, like
congratualtions,nice work,good work,bad serial,bad work, havent you got a brain ect....
Can you find something for this crackme? yes you can, 'Well done...blablabal'.
double click and you arrive here.

:00401218 6A20                    push 00000020
:0040121A 6860324000              push 00403260
:0040121F 6A01                    push 00000001
:00401221 FF7508                  push [ebp+08]

* Reference To: USER32.GetDlgItemTextA, Ord:0102h
                                  |
:00401224 E893000000              Call 004012BC

* Possible StringData Ref from Data Obj ->"kanal23"
                                  |
:00401229 6872314000              push 00403172
:0040122E 6860324000              push 00403260
s
* Reference To: KERNEL32.lstrcmpA, Ord:02D6h
                                  |
:00401233 E866000000              Call 0040129E
:00401238 0BC0                    or eax, eax
:0040123A 7517                    jne 00401253
:0040123C 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"kanal23 - RCE"
                                  |
:0040123E 6823304000              push 00403023

* Possible StringData Ref from Data Obj ->"Well done, write one tutorial "
                                        ->"and mail it to"
                                  |
:00401243 68A1314000              push 004031A1
:00401248 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:01BBh
                                  |
:0040124A E88B000000              Call 004012DA


We have now solved the crackme. Let me explain.
We don't need to trace with softice to get the serial.
The serial is hardcoded. That means that the serial is
inside the crackme, and does not rely on calculations
and stuff. First it gets the text from the textbox with
getdlgitemtexta and saves it in 00403260. Then it compares
the contents in 00403260 which is our input, with the
contents in 00403172("kanal23") which is the hardcoded serial.
this compare is done with lstrcmpA. btw, the A stands for 32bit.
----------------
The lstrcmp function compares two character strings. The comparison is case sensitive. 

int lstrcmp(
    LPCTSTR lpString1,	// address of first string 
    LPCTSTR lpString2 	// address of second string 
   );
----------------
So if 00403260(our input)=00403172("kanal23") not true then badserial message.

Serial=kanal23

That's it.


______________________
EFnet @ #New2Cracking
dihux - 2002











