Hi guys.
Yesterday I downloaded a small handy cd-rom util which examins important sectors on both empty
and already recorded cd-roms. It uses standard name->serial registration validation. I quickly
found (with beloved sice) offending routine and tried to figure out serial number from it without
success. It is possible to patch program to accept serial number in format xxx-xxxxxxx (fourth
character must be "-") but author was smart enough to include well hidden CRC check and before
searching for CRC compare I decided to find correct serial number for my name. The main reason
for my decision was that I already saw this kind of serial manipulation in many schemes I've seen
till today. Of course this is not easy at all, and I hope that there is someone who can help me.
Let's see the code:

EBX=0
EDI= points to serial number entered
ESI= fourth digit of serial (ASCII hex) (If entered "2" -> esi = 32)



:0041A4C4 cmp dword ptr [0042F59C], 00000001 ;always equal
:0041A4CB jle 0041A4D9

;skipped... due to forum msg restrictions
|
:0041A4D9 mov eax, dword ptr [0042F390] ;lookup table to exclude
:0041A4DE mov al, byte ptr [eax+2*esi] ;characters from adding and
:0041A4E1 and eax, 00000004 ;to determine the end of string

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041A4D7(U)
|
:0041A4E4 test eax, eax
:0041A4E6 je 0041A4F5 ;if equal then char or end of string
;skip adding

####################### bloody magic starts here ############################################

:0041A4E8 lea eax, dword ptr [ebx+4*ebx] ;at the 1st iteration eax=0
:0041A4EB lea ebx, dword ptr [esi+2*eax-30]
;now ebx = 4th number entered
;I saw this so many times in many apps...
############################ and ends here ##################################################

:0041A4EF movzx esi, byte ptr [edi] ;get next digit in esi
:0041A4F2 inc edi ;inc pointer
:0041A4F3 jmp 0041A4C4 ;cycle till the end of serial

After this ebx holds magic number which is NEGATED and divided with constant 186A0h. REMAINDER
of this division is then compared with two bytes (4F59h) calculated from my name. If equal good
guy, otherwise...
The rest is common, name->serial combination is placed in windows registry and after restarting
the other routine fetches that from registry, does the same calculation and sets global variable
"Registered" true or false accordingly.
I wonder if this is some common mathematical manipulation on arrays I know nothing of. I've tried
to place this on paper but only to find out that the number must be very big unsigned int so
after negation and division EDX (remainder) holds the right value. It could be any int since
there is almost infinite amount of numbers that satisfy this condition.
1D5F9h div 186a0h = 1 and remainder 4F59h
669D9h div 186a0h = 4 and remainder 4F59h etc.
I suppose it is possible to write a little program which does reverse logic but it asks for
good mathematical background. I think. I finished school long time ago
If any of you guys could help...

Petroff