DONGLES: The weak brothership between hard- and software |
Dongles |
|
|
|
|
|
|
by fravia+ |
fra_00E8 980216 Mad 1100 P3 PC |
The 'spaghetti' code of the dongle calling snippets is also pretty intersting... clearly someone had very funny ideas about how to use dongles here :-) |
Programmers |
|
||
|
|
|
Well no so long ago I wrote my first essay on dongle protections,I got another one in my hands and had an option the 'try' in at home ;).... Todays target also uses the dongle just for checking if it's there or not .... and is checked ever time you call a small selection of routines... (for instants the print-routine ...)
So the dongle once more missed it's target in my option (also see dong_mad.htm), I mean using the dongle for jump-information in the source or maybe even better, encryption and decryption on the fly (I think even more powerful)...
Why the simple is_dongle_there,_then_run,_else_nag routine !!!! Anyway just flip your favorite CD in your CD-ROM player (I recommend any CD from THE DOORS :))))) Come on baby fight my lighter (or what did jimmy boy sing ???)and look at my essay and see again a stupid brothership between hard- and software .... :(
|
|
|
|
Okay ... Let's look at this target, I start to install which was very slow .. I stopped the installation after the third floppy and there is an executable in the target directory .... I ran the target and yes in came alive by telling me it didn't see the dongle on the parallel port and now switched to demo-mode ....
Well as usual I run the program in both states, so I plugged this dongle to the parallel port, and no message is displayed. When the dongle is disconnected from the PC all seem to work fine but when certain functions are selected (print for example) it says it won't do that in the demo version ... when connecting the dongle straight away and hit print again, my nice Deskjet 690C starts printing away... This could mean that we might have an dongle that is providing the software jump-info (offset data I mean).
okay let's get physical .... I fired up softice and set the usual breakpoint on LPT1 (BPIO -H 378 R). This will give us an entry in the target on the follow position.
:0003.0130 8B166E09 mov dx, [096E] :0003.0134 EC in al, dx <<< point of entry :0003.0135 A27209 mov [0972], al :0003.0138 E8B505 call 06F0 :0003.013B B000 mov al, 00 :0003.013D EE out dx, al :0003.013E E87C06 call 07BD :0003.0141 B001 mov al, 01 :0003.0143 EE out dx, al :0003.0144 E87606 call 07BD :0003.0147 C606700901 mov byte ptr [0970], 01 :0003.014C E80706 call 0756 :0003.014F E80406 call 0756 :0003.0152 E8E705 call 073C
We are here right in the middle of the chat_to_dongle routine (16 bit source), since I'm a very curious and impulsive person, I like to see the call that is responsible for the execution. So I just hit on the F12-button a few times (p ret) and I come across the wonderful code (later on I'll conclude the chat_to_dongle code ...)
:0002.0034 C8020000 enter 0002, 00 :0002.0038 C646FE00 mov byte ptr [bp-02], 00 <<< reset flag dongle_there :0002.003C 6A00 push 0000 :0002.003E 6A01 push 0001 :0002.0040 8D7EFE lea di, [bp-02] :0002.0043 16 push ss :0002.0044 57 push di :0002.0045 9AFFFF0000 call 0002.005Bh :0002.004A 807EFE03 cmp byte ptr [bp-02], 03 <<<< point of entry .... :0002.004E B000 mov al, 00 :0002.0050 7501 jne 0053 :0002.0052 40 inc ax
Well well, we see a call 0002.005b which hold among other things the dongle_chat routine. After this call there's a cmp-action, which compares the location [bp-02) with 03 (and it will hold 03 if the dongle is attached to the parallel-port). If you run the target without the dongle [bp-02] will hold 00 so ... I ran the program with the dongle, on the fly I unplugged it .... press the print-button (which gives you the nag ... this to verify if the program responded) now patch the program at 0002.004A, so it compares loc. [bp-02] with 00,and press the print button .... tatatatataaaaa !!!! If you now patch it on the disk, you will see the same routine is used also for startup ... :(
So again we found a dongle-protection that will only use the dongle as reference, instead of encryption or jumping !!! I can't understand why software houses want to protect their software with this crap !!!!
Okay let's look at the dongle-chat routine .... I just picked some highlights out of this scheme and explain them ...
The follow routine (0003.0013 - 0003.0079) is used to determine on which LPT-device the dongle is plugged.
:0003.0013 A4 movsb :0003.0014 06 push es :0003.0015 1F pop ds :0003.0016 813E6E097803 cmp word ptr [096E], 0378 :0003.001C 745E je 007C :0003.001E 813E6E09BC03 cmp word ptr [096E], 03BC :0003.0024 7456 je 007C :0003.0026 813E6E097802 cmp word ptr [096E], 0278 :0003.002C 744E je 007C
Here mem.loc. DS:[096E] is check if it contains 0378 ,0278 (in other words LPT1 and LPT2). As we can see here that our target must be old or is still compatible with the good old hercules card because 03BC is used on the hercules graphic-adaptor (integrated)... (I'm not talking about the hercules 3D color-adaptor but the ancient mono-hercules). This was also seen as LPT1 (long time ago since I've last seen that).
This checking is done, so they can use the same routine at 1.)start-up to check on which port the dongle is and 2.)check the dongle later on in the program if it's still there BUT without having to check on which LPT port the dongle is ('cause the routine is very long threaded and takes time which would be bad for performance).
:0003.002E E83F07 call 0770
In this call a check is preformed to test how fast your CPU is so that they can (later on in the program, using this info to) time with a simple loop, the delay they need in between transfers to the dongle. This is stored in ds:0977 and used by a call 07BD (for me that value is 1E = pentium 200)
The timing is done by checking on 1017:006C (this is the LSB of the clock-count,see int. 1A/00) while executing a number of loops in 1/18 of a sec. Okay let's go on before we get to detailed..
:0003.0031 C7066E097803 mov word ptr [096E], 0378 :0003.0037 BE7A09 mov si, 097A :0003.003A E8E300 call 0120 :0003.003D E8A901 call 01E9 :0003.0040 3C7B cmp al, 7B :0003.0042 743E je 0082
Here we can see that the program assumes that the dongle is plugged to LPT1, before entering the actual check-routines call 0120,call 01e9. which return in case of an dongle 7B and no dongle FF. If the dongle is not found the target will try the next option (see 0003.0044 - 0003.0079)
:0003.0044 E86B06 call 06B2
Here it looks like the previous LPT-port is reset so that any printer attached will not be effected later when the program is ended.
:0003.0047 C7066E09BC03 mov word ptr [096E], 03BC :0003.004D BE7A09 mov si, 097A :0003.0050 E8CD00 call 0120 :0003.0053 E89301 call 01E9 :0003.0056 3C7B cmp al, 7B :0003.0058 7428 je 0082 :0003.005A E85506 call 06B2 :0003.005D C7066E097802 mov word ptr [096E], 0278 :0003.0063 BE7A09 mov si, 097A :0003.0066 E8B700 call 0120 :0003.0069 E87D01 call 01E9 :0003.006C 3C7B cmp al, 7B :0003.006E 7412 je 0082 :0003.0070 E83F06 call 06B2 :0003.0073 C7066E090000 mov word ptr [096E], 0000 :0003.0079 EB07 jmp 0082
If no dongle is found DS:[096E] is set with 0 so the program knows that there is no dongle present. I like to show you the timing-routine,
:0003.0770 50 push ax :0003.0771 53 push bx :0003.0772 51 push cx :0003.0773 1E push ds :0003.0774 B8FFFF mov ax, OFFSET ADDR of KERNEL.LOCALLOCK :0003.0777 8ED8 mov ds, ax :0003.0779 B9FFFF mov cx, FFFF :0003.077C A06C00 mov al, [006C] <<< get current LSB of clock :0003.077F B30A mov bl, 0A :0003.0781 90 nop :0003.0782 FECB dec bl :0003.0784 75FB jne 0781 :0003.0786 49 dec cx :0003.0787 742A je 07B3 :0003.0789 3A066C00 cmp al , [006C] <<< Has the clock changed since :0003.078D 74F0 je 077F <<< last performed loops,no then again :0003.078F B90000 mov cx, 0000 <<< {I don't understand this reset CX is left unused at this time}
:0003.0792 A06C00 mov al, [006C] | :0003.0795 B30A mov bl, 0A |This piece of code is performing :0003.0797 90 nop |the same check as the one above :0003.0798 FECB dec bl |but now the number of executions :0003.079A 75FB jne 0797 |is held in CX :0003.079C 41 inc cx | :0003.079D 3A066C00 cmp al , [006C] |And stored in DS:0977 if it's 6 or :0003.07A1 74F2 je 0795 |more !!! else DS:0977 will contain 1 :0003.07A3 80FD05 cmp ch, 05 |The slow CPUs.... :) :0003.07A6 7302 jnb 07AA | :0003.07A8 B501 mov ch, 01 | :0003.07AA 1F pop ds | :0003.07AB 882E7709 mov [0977], ch | :0003.07AF 59 pop cx :0003.07B0 5B pop bx :0003.07B1 58 pop ax :0003.07B2 C3 ret
I just commented to lines so I don't have to write down the line-numbers all the time.. (LAZY) This value stored in DS:0977 is used in the following delay-routine
:0003.07BD 51 push cx :0003.07BE 8A0E7709 mov cl , [0977] :0003.07C2 FEC9 dec cl :0003.07C4 75FC jne 07C2 :0003.07C6 59 pop cx :0003.07C7 C3 ret
I don't need to comment that I hope ..... And a example of this routine in action looks like this ....
:0003.018C E82E06 call 07BD :0003.018F 0C80 or al, 80 :0003.0191 EE out dx, al :0003.0192 E82806 call 07BD :0003.0195 24BF and al, BF :0003.0197 EE out dx, al :0003.0198 E82206 call 07BD :0003.019B 0C40 or al, 40 :0003.019D EE out dx, al
Also no comment needed ....
Okay about the dongle_chat routines, I decided not to include code, it's specific for this dongle and won't add any value for later essays or reversals. I will make a conclusion here about the chat-routine, which is more general and has value for later on.
The CALL 0120 was a very long and spaghetti like structure. Sub_routines would be called 10's of times after each other to form LONG strings of binary code which were sent to the dongle. But not once a value was read back, not at port 0379 or 037A and the semi-bi-directional way (write FFh to the IO-port 0378 (out 0378,ff) and read in right back (in al,378) so that all the low bits (read zeros) are displayed ....) So this routine is used to enable the hardware in the dongle. The Call 01E9 there was again a lot of bytes send to the dongle, after this was done the target started to read data from IO-port 0379. Testing the received value for bit 20h , which meant OR CL,CH or don't OR CL,CH. This was following by a SHL CH,1 (okay a little code).
:0003.022E EC in al, dx :0003.022F A820 test al, 20 :0003.0231 7402 je 0235 :0003.0233 0ACD or cl , ch :0003.0235 D0E5 shl ch, 01 :0003.0237 75EF jne 0228
This would give FFh in case the dongle was unplugged and 7Bh in case the dongle was connected.
|
Well today we see that in this case of a dongle protection, the dongle could also be replaced by a good serial-scheme. Because the program doesn't really need the dongle to run. The dongle here will only slow down the program (in theory) in stead of protecting it. I see it as a parasite, consuming power and time but doesn't REALLY do what it's suppose to do because the combination of the software and the dongle is again to simple....
I said in my essay also something about using the dongle as encryption-key on the fly.. Well thinking over this statement I now must concluded that in will slow down the software performance. But still it's a nice thought, though.
Anyway another dongle has revealed it's true protection capabilities and I hope they will be improved in the future, otherwise it's a dying bread of protect, I reckon (well ain't it already by the cost of it ....???)
Have a nice day and keep hunting
MaD [CPT]
btw. I want to THANK fravia , for not publishing this essay right away... (he knows why ..!!)
|