Target:      PACT software
URL:         http://www.pact.de
protection:  serial number
Description: A bunch of small win appz...
             all of them is using the same routine, except some values

Tools you will need to crack this program:  Soft-ice 3.0 or better
                                            (http://www.numega.com)
					    programming knowledge (any language
					    as long as you can code the keygen)

How to make a keygen for the programs:

   1. Start the program, choose license and enter a name (4 min-40 max)
      and a serial but DO NOT press OK yet, go into softice and set a
      breakpoint on hmemcpy (bpx hmemcpy). Now go back to the program
      and press the OK button, and bang, you are in softice.

   2. Now press F5 to goto the next hmemcpy call, and press F11 to get
      out of the second call, disable your breakpoints with 'bd *',
      now trace down until you are at a place that looks similar to this:

:0040xxxx push 0040xxxx
:0040xxxx push esi
:0040xxxx call 0040xxxx
:0040xxxx pop ecx
:0040xxxx cmp eax, FFFFFFFF
:0040xxxx pop ecx
:0040xxxx mov dword ptr [ebp-04], eax
:0040xxxx je 0040xxxx
:0040xxxx lea eax, dword ptr [ebp+FFFFFEF0]
:0040xxxx mov dword ptr [00412B54], 5DFC99F0 <-- assigns (in this case) 412B54, 5DFC99F0h
:0040xxxx push eax
:0040xxxx mov dword ptr [00412B58], 63B53E6E <-- assigns (in this case) 412B58, 63B53E6Eh
:0040xxxx mov dword ptr [00412B5C], 56EE5A45 <-- assigns (in this case) 412B5C, 56EE5A45h
:0040xxxx call 0040xxxx                      <-- the blacklist and calculation routine
:0040xxxx cmp eax, ebx
:0040xxxx pop ecx
:0040xxxx je 0040xxxx
:0040xxxx cmp eax, dword ptr [ebp-04]
:0040xxxx jne 0040xxxx
:0040xxxx cmp dword ptr [ebp+08], ebx

   3. So trace into the blacklist/calculation call, and you'll see this:

:00404910 53                      push ebx
:00404911 55                      push ebp
:00404912 56                      push esi
:00404913 57                      push edi
:00404914 8B7C2414                mov edi, dword ptr [esp+14]
:00404918 33DB                    xor ebx, ebx
:0040491A 85FF                    test edi, edi
:0040491C 0F847C020000            je 00404B9E
:00404922 6A29                    push 00000029
:00404924 57                      push edi

* Reference To: KERNEL32.IsBadReadPtr, Ord:0183h
                                  |
:00404925 FF1524454100            Call dword ptr [00414524]
:0040492B 85C0                    test eax, eax
:0040492D 0F856B020000            jne 00404B9E
:00404933 57                      push edi

* Reference To: KERNEL32.lstrlenA, Ord:02A1h
                                  |
:00404934 FF15DC444100            Call dword ptr [004144DC]
:0040493A 6A01                    push 00000001
:0040493C 89442418                mov dword ptr [esp+18], eax
:00404940 5D                      pop ebp
:00404941 3BC5                    cmp eax, ebp
:00404943 0F8655020000            jbe 00404B9E

* Reference To: KERNEL32.lstrcmpA, Ord:0295h
                                  |
:00404949 8B351C454100            mov esi, dword ptr [0041451C]

* Possible StringData Ref from Data Obj ->"John Covington"       <-- the start of the blacklist routine
                                  |
:0040494F 6880FA4000              push 0040FA80
:00404954 57                      push edi
:00404955 FFD6                    call esi
:00404957 85C0                    test eax, eax
:00404959 7502                    jne 0040495D
:0040495B 8BDD                    mov ebx, ebp

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404959(C)
|

* Possible StringData Ref from Data Obj ->"Clara Post"
                                  |
:0040495D 6874FA4000              push 0040FA74
:00404962 57                      push edi
:00404963 FFD6                    call esi
:00404965 85C0                    test eax, eax
:00404967 7502                    jne 0040496B
:00404969 8BDD                    mov ebx, ebp

snip.............

Hopefully you lands here, if not try another name ;)

:00404BAE A1542B4100              mov eax, dword ptr [00412B54] <-- gives eax the value of 412B54
:00404BB3 33C9                    xor ecx, ecx
:00404BB5 85DB                    test ebx, ebx
:00404BB7 761A                    jbe 00404BD3
:00404BB9 8B35582B4100            mov esi, dword ptr [00412B58] <-- gives esi the value of 412B58
:00404BBF 33D2                    xor edx, edx                  <-- edx=0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404BD1(C)
|
:00404BC1 0FBE2C39                movsx ebp, byte ptr [ecx+edi] <-- ebp=ascii value of current char
:00404BC5 0FAFE8                  imul ebp, eax                 <-- ebp=ebp*eax
:00404BC8 03EA                    add ebp, edx                  <-- ebp=ebp+edx
:00404BCA 41                      inc ecx                       <-- counter+1
:00404BCB 03D6                    add edx, esi                  <-- edx=edx+esi
:00404BCD 3BCB                    cmp ecx, ebx                  <-- checks if all chars of the name is processed
:00404BCF 8BC5                    mov eax, ebp                  <-- eax=ebp
:00404BD1 72EE                    jb 00404BC1                   <-- jump if not

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00404BB7(C)
|
:00404BD3 3D00CA9A3B              cmp eax, 3B9ACA00             <-- compares the value we got with 3B9ACA00h
:00404BD8 7306                    jnb 00404BE0                  <-- jump if below or equal
:00404BDA 03055C2B4100            add eax, dword ptr [00412B5C] <-- if not, add the value of 412B5C to the sum

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00404BA0(U), :00404BD8(C)
|
:00404BE0 5F                      pop edi
:00404BE1 5E                      pop esi
:00404BE2 5D                      pop ebp
:00404BE3 5B                      pop ebx
:00404BE4 C3                      ret                           <-- return...

ok, hope ya got it all,,, here's a sample piece of code for this keygen..

#include <stdio.h>

   unsigned char name[100],code_string[100];
   int i,len,flag;
   unsigned long checksum,a,b,c,eax,esi,ebp,edx;

      len=strlen(name);

      if(len>=4&&len<=0x28){
      	a=0x5dfc99f0;
      	b=0x63b53e6e;
      	c=0x56ee5a45;
      	eax=a;
      	esi=b;
         for(i=0,ebp=0,edx=0;i<len;i++){
           ebp=name[i];
           ebp*=eax;
           ebp+=edx;
           edx+=esi;
           eax=ebp;
        }
        if(eax<=0x3b9aca00){ eax+=c; }
        
        printf("%lu", eax);

else{
         printf("Name have to be at least 4 char or max 40 chars");
     }

you'll have to code the rest yourself ;)

/Klefz - klefz@cryogen.com - http://klefz.cjb.net