Tuesday, 15 March 2016

Protecting your E2B USB drive from being cloned

I added this section to the E2B 'Passwords and Security' page today because I was asked how to protect an E2B USB drive from being cloned:

Someone could make a byte-for-byte copy of your E2B USB drive. Each USB drive should have a unique device serial number, however we cannot read this using grub4dos (and also many USB drives do not have unique serial numbers!).

RMPrepUSB - Drive Info - 0 will reveal the USB drive Model Name, Firmware Revision and Serial Number, if available >>>

Drive 4  SanDisk Extreme  F/W Rev.=0001 Serial No.= [ bytes = 00 00 00 00 00 00 00 00 ]
Reported size 64,023,257,088 bytes (59.6263GiB)  Last LBA 125,045,423
RMPrepUSB Max 64,009,128,960 bytes (59.6131GiB)  Last LBA 125,017,829

We can check the USB drives Model Name however by searching the BIOS for these strings using some grub4dos code the MyE2B.cfg file.

Note: We are relying on the fact that the BIOS will have performed an Inquiry command on the USB drive during POST and that the returned values are still in the BIOS memory area. This may not work on all systems, but it seems to work on the ones I have.

Here is an example (this will halt if you try to test it under a VM - only test on a real system)

call /%grub%/SearchBS.g4b 0x680+0x180 "sandisk extreme" > nul
if not "%GOTSTR%"=="1" halt

set GOTSTR=

The other thing we can check is the exact size of the drive. This often varies even for the same model of drive:

debug 1
echo xxxxxxxxxxxxxxxxxxxxxxxxx > (md)0x300+1
write 0x60000 0x42 > nul
# set buffer to 0 in case bios call fails
write 0x60010 0 > nul
# get number of sectors from INT 13h AH=48 into memory at DS:SI+10h  - edx=80h is hard disk 0, 81h would be hard disk 1
/%grub%/bios int=0x13 eax=0x4800 edx=0x80 ds=0x6000 esi=0x0 > nul
read 0x60010 > nul
set /a END=%@retval%-1 > nul
echo DRIVE END %END%
if not %END%==125045423 halt

Change the size in bold to match what your drive returns.
The size returned is not affected by how you partition the drive or how you format it.

You can add these lines to your \_ISO\MyE2B.cfg file to protect it.

Instead of using halt (which will power off the system), you can use reboot or just show a warning - e.g. 
if not %END%==125045423 pause WARNING: THIS E2B DRIVE HAS BEEN CLONED!

A version of this is also in E2B v1.78 Sample mnu Files folder as CloneProtect.mnu - it can be added to the \_ISO\MAINMENU\$$$$CONFIG folder, or you can add the lines into your \_ISO\MyE2B.cfg file.

Check if your device is Removable or not under grub4dos

I would really like to be able to tell if the USB boot device was a Removable type of  Fixed Media type because it changes the way E2B will work (e.g. when booting Windows Install ISOs).

If I know the Vendor ID string that is returned by the Inquiry command (use RMPrepUSB - Drive Info to see the Vendor ID name) , then we may be able to get the RMB bit from the Inquiry command data still left in the BIOS.

The Inquiry command returns these bytes according to the SCSI specification:


Byte 1 will either be 0 (for fixed disk) or 0x80 (for a Removable Media device).
Byte 1 is 7 bytes before the Vendor ID, so we can use this code in a grub4dos batch file.
According to the spec the code below needs to use - 7  not - 6 to adjust the address (I don't know why the EeePC BIOS has a missing byte!)

This worked on my Asus EeePC, but the USB drive Inquiry Data could not be found on my Asus Z87 mainboard, so this code will probably not work on lots of systems and only if one USB device is present - it is just for interest only!

!BAT
set DEVID=Sandisk
# uncomment line below to ask user for DEVID
# set /p DEVID=Enter Device Vendor ID (e.g. Sandisk) : 
cat --locatei=%DEVID% --number=1 (md)0x680+0x180 > nul
set /A loc=%?% + 0xd0000 - 6 > nul
read %loc% > nul
set /A RMB=%@retval% & 0xff > nul
set RMBOK=
if %RMB%==0 echo Device%DEVID%  has Fixed Media && set RMBOK=1
if %RMB%==0x80 echo Device %DEVID% has Removable Media && set RMBOK=1
if not exist RMBOK echo ERROR: Cannot get RMB bit for %DEVID% from BIOS!
pause

Interesting, but I cannot think of a way to obtain the boot device Device Vendor ID using grub4dos...

The actual location of the Inquiry buffer will probably be the same for any device as long as we always boot on the same system, but that does not really help much if we want to use the USB drive on different systems.