Cracking

 

Audio Notes Recorder v3.4

 

********  by Soldat ********

 

 

August 2002

 

 

GENERAL

 

This tutorial  will  try  to explain some basic tehniques for cracking  ,so it is  recommended  to beginners  ,of  course  everyone can read it

 

TOOLS  Used :

 

OS  Win 98

SOFT-ICE  4.05

IDA 4.21

Hiew  6.81  ( or another hex editor )

 

 

Warning   :  you can use IDA 4.20 if don’t have 4.21  I don’t  know  is there carck for it  ,if you have trouble with this mail me 

(soldatsoldat@hotmail.com )  I’ll  send you the crack

image001.gif
image002.gif
 

 


ABOUT PROGRAM

 

URL: http://www.xemico.com   

 

Audio Notes Recorder is easy to use voice notes application. It works in systray, has two operating modes (Analog and Digital), three microphone modes (Normal, Spy, Voice Operated Recording), export to WAV/MP3/EXE option, direct message sending as email attachment, and of course - very posh design with various skins.

 

There are several  protections that limit using demo version of this program

 

1. Time limitation   ( the first and most important)

2. In digital mode you can save just 3 messages per cassette

3. In digital mode you can save just 30 second of your voice per message

4. In Analog mode you can save onlly  one minute of sound per cassette

 

CRACKING 

 

PART 1

 

     Fire IDA and chose ANR.exe  (Audio Notes Recorder v3.4)  ,  waite  for several minutes and when disassembling is over open

string window (SHIFT+F12) , look  for a while and you will see 4 very useful words like this:

 

Unregistered

Unregistered

    …….

Unregistered

 

Select first ,double click on it and you will see something like this:

 

:0052B857 aUnregistered   db 'Unregistered',0     ; DATA XREF: sub_430508+742

 

double click on  sub_430508+742 and you will find  yourself in following part of the code :

 

.text:00430C1E                 add     esp, 0Ch

.text:00430C21                 test    al, al

image003.gifimage004.gif.text:00430C23                 jz      short loc_430C41 

.text:00430C25                 mov     ecx, [ebp+arg_0]                                                                                                

.text:00430C28                 mov     byte ptr [ecx+624h], 1                                                                                        

.text:00430C2F                 lea     edx, [ebp+var_48]                                                                                                

.text:00430C32                 mov     eax, [ebp+arg_0]                                                                                                

.text:00430C35                 add     eax, 5F8h                                                                                                            

.text:00430C3A                 call    @System@AnsiString@$basg$qqrrx17System@AnsiString System::AnsiString::operator=(System::AnsiString &)

image005.gifimage006.gif.text:00430C3F                 jmp     short loc_430C8A 

.text:00430C41 ; ---------------------------------------------------------------------------

.text:00430C41

.text:00430C41 loc_430C41:                             ; CODE XREF: sub_430508+71Bj

image007.gif.text:00430C41                 mov     [ebp+var_D4], 164h 

.text:00430C4A                 mov     edx, offset aUnregistered ; "Unregistered"

.text:00430C4F                 lea     eax, [ebp+var_74]

.text:00430C52                 call    sub_5263B4

.text:00430C57                 inc     [ebp+var_C8]

.text:00430C5D                 lea     edx, [ebp+var_74]

.text:00430C60                 mov     eax, [ebp+arg_0]                                                                              (doesn’t matter)

.text:00430C63                 add     eax, 5F8h

 

 

We will put two nop ( 90h ) on  00430C23  it  means  that program in no case jump to Unregistered  

fire  Hiew  select our program  select our code   00430C23  ( F5 and input data ,enter )   then  F3 , F2  input nop once ,enter ,nop again  enter ,Esc then F9 ,F10   and this jump is killed

 

Now back in IDA  select second Unregistrered ,repeat like in previous  and you‘ll get something like this:

 

 :00431132                 add     esp, 0Ch

.text:00431135                 test    al, al

image008.gifimage009.gifimage010.gif.text:00431137                 jz      short loc_431155      

.text:00431139                 lea     edx, [ebp+var_7C]

.text:0043113C                 mov     eax, [ebp+arg_0]

.text:0043113F                 add     eax, 5F8h

.text:00431144                 call    @System@AnsiString@$basg$qqrrx17System@AnsiString ; System::AnsiString::operator=(System::AnsiString &)

.text:00431149                 mov     ecx, [ebp+arg_0]

.text:0043114C                 mov     byte ptr [ecx+624h], 1

image011.gifimage012.gif.text:00431153                 jmp     short loc_43119D   

.text:00431155 ; ---------------------------------------------------------------------------

.text:00431155

.text:00431155 loc_431155:                             ; CODE XREF: sub_430508+C2Fj

image013.gif.text:00431155                 mov     [ebp+var_D4], 248h

.text:0043115E                 mov     edx, offset aUnregistered_0 ; "Unregistered"

.text:00431163                 lea     eax, [ebp+var_C0]

.text:00431169                 call    sub_5263B4

        

                                                                                                                                                         ( doesn’t matter )

 

We need to put again two nop on 00431137  to avoid jump on Unregistered

do like in previous case with Hiew

 

Now select 3rd Unregistred  you will get following  :

 

 

                 mov     eax, [ecx]

.text:00441431                 cmp     dword ptr [eax+34h], 78h

image014.gifimage015.gif.text:00441435                 jnz     short loc_441459

.text:00441437                 mov     edx, 5Eh

.text:0044143C                 mov     eax, [ebx+2D4h]

.text:00441442                 call    @Controls@TControl@SetHeight$qqri ; Controls::TControl::SetHeight(int)

.text:00441447                 mov     edx, 58h

.text:0044144C                 mov     eax, [ebx+2D4h]

.text:00441452                 call    @Controls@TControl@SetWidth$qqri ; Controls::TControl::SetWidth(int)

image016.gifimage017.gif.text:00441457                 jmp     short loc_441479

.text:00441459 ; ---------------------------------------------------------------------------

.text:00441459

.text:00441459 loc_441459:                             ; CODE XREF: _TAboutForm_FormShow+3Dj

image018.gif.text:00441459                 mov     edx, 5Ch

.text:0044145E                 mov     eax, [ebx+2D4h]

.text:00441464                 call    @Controls@TControl@SetHeight$qqri ; Controls::TControl::SetHeight(int)

.text:00441469                 mov     edx, 56h

.text:0044146E                 mov     eax, [ebx+2D4h]

.text:00441474                 call    @Controls@TControl@SetWidth$qqri ; Controls::TControl::SetWidth(int)

image019.gif.text:00441479

.text:00441479 loc_441479:                             ; CODE XREF: _TAboutForm_FormShow+5Fj

.text:00441479                 mov     [ebp+var_1C], 8

.text:0044147F                 mov     edx, offset aUnregistered_1 ; "Unregistered"

.text:00441484                 lea     eax, [ebp+var_4]

.text:00441487                 call    sub_5263B4

 

 

 


Now we have to change  00441435 to jump because if we put nop it will go on Unregistered ,we don’t want this so put jump instead

jnz ,procedure similar with Hiew

 

Select 4 th  Unregistered ,looks like this :

 

.text:00443B06                 call    @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)

.text:00443B0B                 pop     ecx

.text:00443B0C                 test    cl, cl

.text:00443B0E                 jz      loc_443BD8   

.text:00443B14                 mov     [ebp+var_4C], 74h

.text:00443B1A                 xor     eax, eax

.text:00443B1C                 mov     [ebp+var_30], eax

.text:00443B1F                 lea     edx, [ebp+var_30]

.text:00443B22                 inc     [ebp+var_40]

.text:00443B25                 mov     ecx, [ebp+var_60]

.text:00443B28                 mov     eax, [ecx+2D0h]

.text:00443B2E                 call    @TControl@GetText$qqrv ; TControl::GetText(void)

.text:00443B33                 lea     edx, [ebp+var_30]

.text:00443B36                 mov     ecx, off_551ABC

.text:00443B3C                 mov     eax, [ecx]

.text:00443B3E                 add     eax, 5F8h

.text:00443B43                 call    @System@AnsiString@$basg$qqrrx17System@AnsiString ; System::AnsiString::operator=(System::AnsiString &)

.text:00443B48                 dec     [ebp+var_40]

.text:00443B4B                 lea     eax, [ebp+var_30]

.text:00443B4E                 mov     edx, 2

.text:00443B53                 call    @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)

.text:00443B58                 mov     ecx, off_551ABC

.text:00443B5E                 mov     eax, [ecx]

.text:00443B60                 mov     byte ptr [eax+624h], 1

.text:00443B67                 mov     edx, [ebp+var_60]

.text:00443B6A                 mov     eax, [edx+2D0h]

.text:00443B70                 xor     edx, edx

.text:00443B72                 mov     ecx, [eax]

.text:00443B74                 call    dword ptr [ecx+5Ch]

.text:00443B77                 mov     eax, off_551AD4

.text:00443B7C                 mov     edx, [eax]

.text:00443B7E                 mov     eax, [edx+330h]

.text:00443B84                 mov     dl, 1

.text:00443B86                 mov     ecx, [eax]

.text:00443B88                 call    dword ptr [ecx+5Ch]

.text:00443B8B                 mov     eax, off_551AD4

.text:00443B90                 mov     edx, [eax]

.text:00443B92                 mov     eax, [edx+338h]

.text:00443B98                 mov     dl, 1

.text:00443B9A                 mov     ecx, [eax]

.text:00443B9C                 call    dword ptr [ecx+5Ch]

.text:00443B9F                 mov     eax, off_551AD4

.text:00443BA4                 mov     edx, [eax]

.text:00443BA6                 mov     eax, [edx+334h]

.text:00443BAC                 mov     dl, 1

.text:00443BAE                 mov     ecx, [eax]

.text:00443BB0                 call    dword ptr [ecx+5Ch]

.text:00443BB3                 mov     eax, [ebp+var_60]

.text:00443BB6                 mov     eax, [eax+2D4h]

.text:00443BBC                 xor     edx, edx

.text:00443BBE                 mov     ecx, [eax]

.text:00443BC0                 call    dword ptr [ecx+5Ch]

.text:00443BC3                 mov     eax, [ebp+var_60]

.text:00443BC6                 mov     dl, 1

.text:00443BC8                 mov     eax, [eax+2E8h]

.text:00443BCE                 call    unknown_libname_429

.text:00443BD3                 jmp     loc_443C8A  

.text:00443BD8 ; ---------------------------------------------------------------------------

.text:00443BD8

.text:00443BD8 loc_443BD8:                             ; CODE XREF: _TRegisterForm_RegButtonClick+26Aj

.text:00443BD8                 mov     [ebp+var_4C], 80h

.text:00443BDE                 mov     edx, offset aUnregistered_2 ; "Unregistered"

.text:00443BE3                 lea     eax, [ebp+var_34]

.text:00443BE6                 call    sub_5263B4

.text:00443BEB                 inc     [ebp+var_40]

.text:00443BEE                 mov     eax, off_551ABC

.text:00443BF3                 lea     edx, [ebp+var_34]

                                                                                                                                                                        (doesn’t matter)

 

We have to change 00443B0E   to nop to avoid jum on Unregistered ( put 6 nop because this is six byte instruction ) .Do this with Hiew of course

 

There is one more thing  in the third Unregistered you will se one Registered to :  ( after double clicking on Unregistered ) select this and you will find somethig like this

 

.text:004414B0                 call    @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)

.text:004414B5                 pop     ecx

.text:004414B6                 test    cl, cl

.text:004414B8                 jz      short loc_4414D6

.text:004414BA                 xor     edx, edx

.text:004414BC                 mov     eax, [ebx+2F4h]

.text:004414C2                 call    @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool)

.text:004414C7                 mov     dl, 1

.text:004414C9                 mov     eax, [ebx+2F0h]

.text:004414CF                 call    @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool)

.text:004414D4                 jmp     short loc_441538

.text:004414D6 ; ---------------------------------------------------------------------------

.text:004414D6

.text:004414D6 loc_4414D6:                             ; CODE XREF: _TAboutForm_FormShow+C0j

.text:004414D6                 mov     [ebp+var_1C], 14h

.text:004414DC                 xor     ecx, ecx

.text:004414DE                 mov     eax, off_551ABC

.text:004414E3                 mov     [ebp+var_8], ecx

.text:004414E6                 lea     ecx, [ebp+var_8]

.text:004414E9                 inc     [ebp+var_10]

.text:004414EC                 mov     edx, [eax]

.text:004414EE                 mov     eax, offset aRegisteredTo ; "Registered to "

.text:004414F3                 add     edx, 5F8h

.text:004414F9                 call    @System@$badd$qqrpxcrx17System@AnsiString ; System::operator+(char *,System::AnsiString &)

.text:004414FE                 lea     edx, [ebp+var_8]

.text:00441501                 mov     eax, [ebx+2F4h]

 

                                                                                                                                                                              ( doesn’t matter )

 

In this case we need to chage jz on address 004414B8  to jump because we want to jump on Registered 

This last thing is for every case  ,  this will work without this but  because ‘about’ in program to have clear situation  ( if one looks in our program he can’t say it is not registered )

 

OK  now you can run our sweet  program and you will see that time limitation is broken  but still  there is limitation under 2. 3. 4.

Now  it goes harder  part of  cracking.

 

PART 2

 

Close IDA  we don’t need it anymore we’re gonna use now SOFT-ICE  and intuition

When 30 seconds passes window pops-up to warn us we are not pleasant  anymore , OK press CTR+D and SOFT-ICE  will pop-up.

Put breakpoint on Showwindow (bpx Showwindow) exit SOFT-ICE  and  try to save your 3 rd message in digital mode . SOFT-ICE  will break ,we hit API  Showwindow (Because program wants to say us :get out of here ) press F12 until you reach the code of our program .

 Now let’s think for a while , this API  is called because program wants to pop-up message , so it is to assume that whenever

program wanna show something ( i.e at the beginning )  he calls  the same procedure but with different parameters (that is the sense of calls), so we have to find where is the beginning of our procedure responsible for message about limitation ,because if we change something  in general procedure for showing window we will screw up something and program will not work    

OK when we reached  the code with F12 after pop-up trace for a while with F10 in SOFT-ICE   .You will see that every time you reach ret from current call the next ret is not so far ,so go on untill you reach the code where is departure from this .You will see something like this :

.text:004DA6F6                 mov     fs:[edx], esp

.text:004DA6F9                 mov     eax, [ebp+var_4]

.text:004DA6FC                 call    unknown_libname_770

.text:004DA701                 xor     edx, edx                                                                      land here                        

.text:004DA703                 push    ebp

.text:004DA704                 push    offset loc_4DA7BB

.text:004DA709                 push    dword ptr fs:[edx]

 

trace F10  for  a  while and you will find yourself in the loop  :

 

.text:004DA731                 mov     eax, [ebx]

.text:004DA733                 call    (some call)

.text:004DA738                 mov     eax, [ebx]

.text:004DA73A                 cmp     byte ptr [eax+8Ch], 0

.text:004DA741                 jz      short loc_4DA752

.text:004DA743                 mov     eax, [ebp+var_4]

.text:004DA746                 mov     dword ptr [eax+234h], 2

.text:004DA750                 jmp     short loc_4DA766

.text:004DA752                 mov     eax, [ebp+var_4]

.text:004DA755                 cmp     dword ptr [eax+234h], 0

.text:004DA75C                 jz      short loc_4DA766

.text:004DA75E                 mov     eax, [ebp+var_4]

.text:004DA761                 call     (some call)

.text:004DA766                 mov     eax, [ebp+var_4]

.text:004DA769                 mov     eax, [eax+234h]

.text:004DA76F                 test    eax, eax

.text:004DA771                 jz      short loc_4DA731

 

If you continue with tracing you will see how program draws letters so it means we are on the right place ,this call is our call ,scroll-up until you reach the beginning of it something like this :

 

.text:004DA5EC                 push    ebp                                                                                  This is the beginning of  our call

.text:004DA5ED                 mov     ebp, esp

.text:004DA5EF                 add     esp, 0FFFFFFE0h

.text:004DA5F2                 push    ebx

.text:004DA5F3                 push    esi

.text:004DA5F4                 xor     edx, edx

.text:004DA5F6                 mov     [ebp+var_20], edx

.text:004DA5F9                 mov     [ebp+var_4], eax

.text:004DA5FC                 mov     ebx, offset dword_5524B0

.text:004DA601                 xor     eax, eax

 

The end of this call  is something like  :

 

.text:004DA7A2                 mov     [ebp+hWnd], eax

.text:004DA7A5                 xor     eax, eax

.text:004DA7A7                 pop     edx

.text:004DA7A8                 pop     ecx

.text:004DA7A9                 pop     ecx

.text:004DA7AA                 mov     fs:[eax], edx

.text:004DA7AD                 push    offset loc_4DA7C2

.text:004DA7B2                 mov     eax, [ebp+var_4]

.text:004DA7B5                 call    sub_4DA534

.text:004DA7BA                 retn                                                                                                    The end of our call

 

 

  Put breakpoint on ret on our call    004DA7BA   ,why this ,because we want to see what part of the program code is responsible for this message about  limitation

OK  press now F5 in SOFT-ICE   ,message is here but calm ,nothing happens ,what is with our bpx on the end of our call ,did we make mistake ,no we didn’t

Close message window ,and SOFT-ICE will pop up ,it means that we have the following situation

 

        

start of call                                                      

                                                                          

                                                                                 

                                                                            

                                                                                              Waiting for us to close the window

                                                                                                    and cotinue with execution

                                                                                                                                 

 

                                                                                                                                                         

end of call                                                                

 

 

So we needn’t anymore bpx on API  Showwindow because we know this call ,so clear it ,but put the bpx on  the beginning (004DA5EC) of the call

just to se how is going all stuff .Trace for a while after ret following the logic from the beginning until you reach next :

 

.text:0041584D                 mov     edx, [eax]

.text:0041584F                 call    dword ptr [edx+0D8h]

.text:00415855                 cmp     byte ptr [edi+2F4h], 1                                              land here

.text:0041585C                 jnz     short loc_41586B

.text:0041585E                 mov     dl, 1

.text:00415860                 mov     eax, [ebx+4B8h]

 

Scroll-up little untill you reach something like this :

 

.text:00415764                 cmp     dword ptr [ebx+5B8h], 1

.text:0041576B                 jnz     loc_415989

.text:00415771                 test    al, al

.text:00415773                 jz      loc_415989    

.text:00415779                 mov     byte ptr [ebx+59Ah], 1

.text:00415780                 mov     word ptr [esi+10h], 1D0h

 

 

                                                                                                                                                        (overrides critical call)

 

You see, jz on 00415773  will override the call we just returned ,if it is active ,so put bpx on it, put new cassette in our recorder and you will see that this jz is active first tree times and after that it is inactive ,yes that’s it ,we just have to rename it in jmp and there is no limitation in numbers of messages per cassete anymore ,do it with Hiew

 

There is still time limitation per message wait for 30 second ,after that time SOFT-ICE will pop-up ,because we left the bpx on the beginning of critical call ,OK do F5 ,window with message is here ,close it and as in previous SOFT-ICE pops-up,trace for a while until you reach following

 

.text:00409214                 mov     edx, [eax]

.text:00409216                 call    dword ptr [edx+0D8h]

.text:0040921C                 cmp     byte ptr [edi+2F4h], 1                                                             land here

.text:00409223                 jnz     short loc_409232

.text:00409225                 mov     dl, 1

.text:00409227                 mov     eax, [ebx+4B8h]

 

Scroll up for a while until you reach next :

 

 

.text:0040912A                 test    al, al

.text:0040912C                 jz      loc_4092F8         

.text:00409132                 mov     edx, ebx

.text:00409134                 mov     eax, ebx

 

                                                                                                                                 (overrides critical call)

 

See when this jz is active it overrides our critical section we returned  ,you can put bpx on it ,start recording and watch what is going on

but SOFT-ICE  will break  again and again ,if you look at secondes on the recorder’s display you will see that they’re counted up ,and this jz is active until  counter reachs 30 and then he becomes inactive (jz)  and goes on critical call ,then on our call etc…

yes that’s it put jmp instead jz on   0040912C  and say bye ,bye to the time limitation for digital mode .

 

But there is still limitation for analog mode ,let’s kill it .

 

You remember our bpx on critical call stays , now you put analog cassette and wait for SOFT-ICE’s break  ,after it close window and trace for a while until you reach next :

 

.text:00408FDE                 mov     eax, edi

.text:00408FE0                 mov     edx, [eax]

.text:00408FE2                 call    dword ptr [edx+0D8h]

.text:00408FE8                 cmp     byte ptr [edi+2F4h], 1                                                        lend here

.text:00408FEF                 jnz     short loc_408FFE

 

Scroll-up and you will see the next  :

 

.text:00408EF6                 test    al, al

.text:00408EF8                 jz      loc_4090C4

.text:00408EFE                 mov     edx, ebx

.text:00408F00                 mov     eax, ebx

                                                                                                                                             (overrides crirical call)

 

Again jz (00408EF8) is active in first 60 second after that becomes inactive ,please put jmp instead jz and that’s it.We broke the last limitation enjoy

 

If you have any trouble with this mail me ,I hope this was useful to one who read above.Best wishes in cracking and keep cracking