<DIV id=post_message_33053 align=center><DIV align=center><FONT face="Arial Black"><FONT size=4><FONT color=black>Ize from Gadgetware is a cute little program that will put a pair of eyes on your screen which will
follow your mousepointer. It has a register function where you can enter your name and a registration
number. The strategy in this case is still the same : Find out where in memory the entered information
is stored and then find out what is done with that information.
Step 1: Start Ize. Chose register and enter a name and a number. I used 'razzia' and '12345'.
Sterp 2: Enter (CTRL-D) Softice and set a breakpoint on GetDlgItemTextA.
Step 3: Leave SoftIce and press OK. This will put you back in Softice. You will be inside the GetDlgItemTextA
function. To get out of it press F11. You should see the following code :
mov esi, [esp + 0C]
push 00000064
push 0040C3A0 :<--On this memory location the NAME we entered will be stored.
mov edi, [USER32!GetDlgItemTextA] :<--Load edi with adress of GetDlgItemTextA
push 00004EE9
push esi
call edi :<-- Call GetDlgItemTextA
push 00000064 :<-- (you should be here now)
push 0040C210 :<--On this memory location the NUMBER we entered will be stored
push 00004EEA
push esi
call edi :<-- Call GetDlgItemTextA
We see that the function GetDlgItemTextA is called twice in this code fragment. The first call has
already happened. With ED 40C3A0 we can check that the name we entered is stored on that location.
To allow the program to read in the number we entered we type G and enter. Now we are inside the Get-
DlgItemTextA function again and we press f11 to get out of it. We check memory location 40C210 and
we see the number we entered is stored there.
Now we know the locations were the name and the number are stored,we note those down!
Step 4: Ok, what next? We now know where in memory the name and the number are stored. We need to find out
what the program does with those values. In order to do that we could set breakpoints on those memory
locations to see where they are read. But in this case it wont be necessary. The answer is right after the
above code :
push 0040C210 :<--save the location of the number we entered (as a parameter
call 00404490 :<-- call this unknown function
add esp, 00000004
mov edi, eax :<-- save EAX (hmmmm)
We see a function being called with the number-location as a parameter. We could trace into the function and see what it does, but that is not needed. With your experience of the Swiftsearch
example you should be able to guess what this function does. It calculates the numerical value of the registration number and puts it in EAX. To be sure we step further using F10 untill we are past the call and check the contents of EAX (with ? EAX). In my case it showed : 00003039 0000012345 "09".
Knowing that EDI contains our registration number we proceed:
push 0040C3A0 :<-- save the location of the name we entered (as a parameter for the next call)
push 00409080 :<-- save an unknown memory-location (as a parameter for the next call)
call 004043B0 :<--call to an unknown function
add esp, 00000008
cmp edi, eax :<--compare EDI (reg # we entered) with EAX (unknown, since the previous call
changed it)
jne 004018A1 :<--jump if not equal
We see that a function is called with two parameters. One of the parameters is the location of the name
we entered. The other we dont know, but we can find out with ED 409080. We see the text 'Ize'.
This function calculates the right registration number using those two parameters. If you just want to
crack this program, you can place a breakpoint right after the call and check the contents of EAX. It will
contain the right registration number. But since we want to know HOW the reg. # is calculated we will trace inside the function (using T). We will then try to find out HOW the contents of EAX got in there.
Step 5: Once inside the interesting function you will see that we are dealing with a rather long function. It wont be necessary for me to include the complete listing of this function, because we wont need all of it to make our key-gen.
But in order find out which part of the code is essential for the computation of the right registration number, you have to trace STEP by STEP and figure out what EXACTLY is going on!
Afther doing this i found out that the first part of the function computes some kind of "key". Then this
"key" is stored in memory and in that way passed on to the second part of the function.
The second part of the function then computes the right registration number, based on this "key" AND
the name we entered.
The code that is essential and that we need for our key-gen is the following:
( Note that before the following code starts, the registers that are used will have the following values:
EBX will point to the first letter of the name we entered,
EDX will be zero,
EBP will be zero,
The "key" that we talked about earlier is stored in memory location 0040B828 and will
have 0xA4CC as its initial value. )
:00404425 movsx byte ptr edi, [ebx + edx] :<-- Put first letter of the name in EDI
:00404429 lea esi, [edx+01] :<-- ESI gets the "letter-number"
:0040442C call 00404470 :<-- Call function
:00404431 imul edi, eax :<-- EDI=EDI*EAX (eax is the return value of the the previous call)
:00404434 call 00404470 :<-- Call function
:00404439 mov edx, esi
:0040443B mov ecx, FFFFFFFF
:00404440 imul edi, eax :<-- EDI=EDI*EAX (eax is the return value of the previous call)
:00404443 imul edi, esi :<-- EDI=EDI*ESI ( esi is the number of the letter position)
:00404446 add ebp, edi :<-- EBP=EBP+EDI (beware that EBP will finally contain the right reg#)
:00404448 mov edi, ebx :<--these lines compute the lenght of the name we entered
:0040444A sub eax, eax :<--these lines compute the lenght of the name we entered
:0040444C repnz :<--these lines compute the lenght of the name we entered
:0040444D scasb :<--these lines compute the lenght of the name we entered
:0040444E not ecx :<--these lines compute the lenght of the name we entered
:00404450 dec ecx :<-- ECX now contains the lenght of the name
:00404451 cmp ecx, esi
:00404453 ja 00404425 :<-- If its not the end of the name , go do the same with the next letter
:00404455 mov eax, ebp :<-- SAVE EBP TO EAX !!!!
:00404457 pop ebp
:00404458 pop edi
:00404459 pop esi
:0040445A pop ebx
:0040445B ret
_____
:00404470
:<-- Call function
:00404431 imul edi, eax :<-- EDI=EDI*EAX (eax is the return value of the the previous call)
:00404434 call 00404470 :<-- Call function
:00404439 mov edx, esi
:0040443B mov ecx, FFFFFFFF
:00404440 imul edi, eax :<-- EDI=EDI*EAX (eax is the return value of the previous call)
:00404443 imul edi, esi :<-- EDI=EDI*ESI ( esi is the number of the letter position)
:00404446 add ebp, edi :<-- EBP=EBP+EDI (beware that EBP will finally contain the right reg#)
:00404448 mov edi, ebx :<--these lines compute the lenght of the name we entered
:0040444A sub eax, eax :<--these lines compute the lenght of the name we entered
:0040444C repnz :<--these lines compute the lenght of the name we entered
:0040444D scasb :<--these lines compute the lenght of the name we entered
:0040444E not ecx :<--these lines compute the lenght of the name we entered
:00404450 dec ecx :<-- ECX now contains the lenght of the name
:00404451 cmp ecx, esi
:00404453 ja 00404425 :<-- If its not the end of the name , go do the same with the next letter
:00404455 mov eax, ebp :<-- SAVE EBP TO EAX !!!!
:00404457 pop ebp
:00404458 pop edi
:00404459 pop esi
:0040445A pop ebx
:0040445B ret
_____
:00404470 mov eax, [0040B828] :<-- Put "key" in EAX
:00404475 mul eax, eax, 015A4E35 :<-- EAX=EAX * 15A4E35
:0040447B inc eax :<-- EAX=EAX + 1
:0040447C mov [0040B828], eax :<-- Replace the "key" with the new value of EAX
:00404481 and eax, 7FFF0000 :<-- EAX=EAX && 7FFF0000
:00404486 shr eax, 10 :<-- EAX=EAX >>10
:00404489 ret
The above code consists of a loop that goes trough all the letters of the name we entered. With each
letter some value is calculated, all these values are added up together (in EBP). Then this value is stored
in EAX and the function RETurns. And that was what we were looking for, we wanted to know how EAX got its value!
Step 6: Now to make a key-gen we have to translate the above method of calculating the right reg# into a
c program. It could be done in the following way :
(Note : I am a bad c programmer
#include
#include
main()
{
char Name[100];
int NameLength,Offset;
unsigned long Letter,DummyA;
unsigned long Key = 0xa4cc;
unsigned long Number = 0;
printf("Ize 2.04 crack by razzia\n");
printf("Enter your name: ");
gets(Name);
NameLength=strlen(Name);
for (Offset=0;Offset