(please read challenge3.txt before)
Just for reminding, the sensible area is:

:00456D23 8D55C0                  lea edx, dword ptr [ebp-40]
:00456D26 52                      push edx
:00456D27 53                      push ebx
:00456D28 8B0B                    mov ecx, dword ptr [ebx]
:00456D2A FF5108                  call [ecx+08] --->        adr:459AC1
:00456D2D 8D45C0                  lea eax, dword ptr [ebp-40]
:00456D30 50                      push eax
:00456D31 E8363D0100              call 0046AA6C  ----> FIRST NICE_BUYER TEST
:00456D36 85C0                    test eax, eax
:00456D38 741B                    je 00456D55    ----> get out!
:00456D3A 8D55BC                  lea edx, dword ptr [ebp-44]
:00456D3D 52                      push edx
:00456D3E 6A00                    push 00000000
:00456D40 6A00                    push 00000000
:00456D42 53                      push ebx
:00456D43 8B0B                    mov ecx, dword ptr [ebx]
:00456D45 FF5110                  call [ecx+10]        -----> 459C3A
:00456D48 8D45BC                  lea eax, dword ptr [ebp-44]
:00456D4B 50                      push eax
:00456D4C E81B3D0100              call 0046AA6C  ----> SECOND ONE.
:00456D51 85C0                    test eax, eax
:00456D53 7504                    jne 00456D59   ----> nice buyer!

I think huge asm dumps are just boring, so i'll try to sumarize what i've
understand from the encryption:
The important calls are 459AC1 and  459C3A. They finally set the flag that will 
be compared with 489990. If it's ok the value is 15A4. if not it'll be its 
opposite: FFFFEA5C.
Seems that you've got two "chances" to trigger the ok box. The algos differ in 
that in each case the working area width vary. It can be 9 or D, and the 
"congruence" can be 1 or 3. For the moment i've just looked at the first case.

A) First call:
crashThe call 459AC1 checks the key. Here's how: the characters (uppercased) 
must be alphanumeric, values 1 and 0 are excluded, 1 is set to L (have you 
noticed that everything es when you put "1" in the key field ?). A rather 
"cryptic" routine (46ABE9) does the following:
 1- give the position of each char in the string 
"ABCDEFHIKLMNOPQRSTUVWXYZ23456789". Only the 5 less significant bits of this 
position will be used. The program constructs a new key with these five bits by 
putting them aside. If the previous was L bytes long, the new one will be 
int(L*5/8)+1 bytes. I'll give an example: supposing your key is "23456",
2-->1A (the position in the string) --> 11010
3-->1B --> 11011
4-->1C --> 11100
5-->1D --> 11101
6-->1E --> 11110

2- Juxtaposing all this stuff beginning from the right gives the new pattern:
1 1110 1110 1111 0011 0111 1010
1   E    E    F    3    7    A
In memory there will be: 7A F3 EE 01 + some constant bytes. the 9 bytes 
beginning with the new key are xored alltogether (459B50), and the result must give 
0 (:459B76 call 401268 is the comparing routine). That triggers the first "nice 
buyer flag". This appears quite easy to bruteforce; i hadn't seen the rest....

B) Second call:
The routine in 459C3A first uses the pack, name, id fields to construct some kind 
of 6 bytes long checksum: all bytes at the same position in each string are 
xored together and the result is put in this 6 bytes area beginning at adr.(the 
position from adr is evaluated modulo 6).Example for the following values : (adr 
is initialized to 00 00 00 00 00 00)
pack: 212
name: abc def
id  : 12345678

[adr]= [adr] xor 2 xor a xor 1
[adr+1]=[adr+1] xor 1 xor b xor 2
  ..... etc, then for the 7th: 
[adr]=[adr] xor f xor 7 (no more chars in pack)

Finally you've got this 6 bytes large area which will be matched against 
another, triggering the second ok flag. And that's where i'm stuck, because the 
second one is not always the same even if you don't touch anything in the 4 
fields. I came to the conclusion that one of the two calls: 46A4E0 or 46A77F 
obviously affects this area (its adress is pushed but not used) if some 
condition is met. Actually these 2 calls are doing something on the transformed 
key, but these routines are such a mess (recursivity involved...) 
Unfortunately that's all for now :-(
