8.5. DONGLES
hashed inside the dongle, being transformed into a 16-bit number. The algorithm was secret, so it was not
possible to write a driver replacement or to remake the dongle hardware that would emulate it perfectly.
However, it is always possible to intercept all accesses to it and to find what constants the hash function
results are compared to.
But we need to say that it is possible to build a robust software copy protection scheme based on secret
cryptographic hash-function: let it encrypt/decrypt the data files your software uses.
But let’s get back to the code.
Codes 51/52/53 are used for LPT printer port selection. 3x/4x are used for “family” selection (that’s how
Sentinel Pro dongles are differentiated from each other: more than one dongle can be connected to a LPT
port).
The only non-2-character string passed to the hashing function is ”0123456789”.
Then, the result is compared against the set of valid results.
If it is correct, 0xC or 0xB is to be written into the global variablectl_model.
Another text string that gets passed is ”PRESS ANY KEY TO CONTINUE: ”, but the result is not checked.
Hard to say why, probably by mistake^14.
Let’s see where the value from the global variablectl_modeis used.
One such place is:
.text:0000D708 prep_sys proc near ; CODE XREF: init_sys+46Ap
.text:0000D708
.text:0000D708 var_14 = dword ptr -14h
.text:0000D708 var_10 = byte ptr -10h
.text:0000D708 var_8 = dword ptr -8
.text:0000D708 var_2 = word ptr -2
.text:0000D708
.text:0000D708 push ebp
.text:0000D709 mov eax, ds:net_env
.text:0000D70E mov ebp, esp
.text:0000D710 sub esp, 1Ch
.text:0000D713 test eax, eax
.text:0000D715 jnz short loc_D734
.text:0000D717 mov al, ds:ctl_model
.text:0000D71C test al, al
.text:0000D71E jnz short loc_D77E
.text:0000D720 mov [ebp+var8], offset aIeCvulnvvOkgT ; "Ie-cvulnvV\\bOKG]T_"
.text:0000D727 mov edx, 7
.text:0000D72C jmp loc_D7E7
...
.text:0000D7E7 loc_D7E7: ; CODE XREF: prep_sys+24j
.text:0000D7E7 ; prep_sys+33j
.text:0000D7E7 push edx
.text:0000D7E8 mov edx, [ebp+var_8]
.text:0000D7EB push 20h
.text:0000D7ED push edx
.text:0000D7EE push 16h
.text:0000D7F0 call err_warn
.text:0000D7F5 push offset station_sem
.text:0000D7FA call ClosSem
.text:0000D7FF call startup_err
If it is 0, an encrypted error message is passed to a decryption routine and printed.
The error string decryption routine seems a simplexoring:
.text:0000A43C err_warn proc near ; CODE XREF: prep_sys+E8p
.text:0000A43C ; prep_sys2+2Fp ...
.text:0000A43C
.text:0000A43C var_55 = byte ptr -55h
.text:0000A43C var_54 = byte ptr -54h
.text:0000A43C arg_0 = dword ptr 8
(^14) What a strange feeling: to find bugs in such ancient software.