當你的U盤,移動硬盤遺失了,被盜了,或者是遺忘在公共場所,裏面的資料就會完全被別人窺探,如果涉及一些隱私,機密,那後果是很嚴重的。本課題就是在這樣一個情況下產生的。這裏剖析的只是一個最初的演示原型,詳細設計,以及一些細節可以參考源代碼。源代碼在WinXP,VC6.0編譯通過。
1、訪問註冊表讀取計算機上的移動存儲設備
在註冊表
1.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Disk\Enum
下面可以看到計算機當前的狀態,這裏可以看到所有的存儲設備的情況,包括計算機的硬盤,通過情況下,名稱爲0的是計算機硬盤,所以在列出的選擇設備時,會把名稱爲0的屏蔽,不然太危險,一旦造成系統的破壞,後果會很麻煩。對註冊表的讀寫:
01.
HKEY
hkey;
02.
char
sz[256];
03.
DWORD
dwtype,sl
= 256;
04.
for
(
int
i=1;i<8;i++)
05.
{
06.
if
(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet
07.
\\Services\\Disk\\Enum",\
08.
NULL,
KEY_ALL_ACCESS, &hkey)==ERROR_SUCCESS)
09.
{
10.
CString
id;
11.
id.Format(
"%d"
,i);
12.
if
(RegQueryValueEx(hkey,id,NULL,&dwtype,(
LPBYTE
)sz,&sl)==ERROR_SUCCESS)
13.
{
14.
CString
str=(CString)sz;
15.
m_select.AddString(sz);
16.
}
17.
}
18.
}
19.
RegCloseKey(hkey);
2、對磁盤的扇區的操作
Windows 操作系統在很大程度上採取了訪問安全保護機制(例如,在Windows操作系統下不能直接訪問物理內存、不能使用各種DOS、BIOS中斷等等),其實Windows在採取“實保護”措施的同時也提供了另外的一種有別於在DOS下訪問硬件設備的方法,即把所有的硬件設備全部看做“文件”,並允許按照對文件的讀寫方式來對其進行數據存取訪問。對於磁盤扇區的讀寫,可以通過C++的CreateFile()函數來實現。由MSDN可查詢到該函數原型:
1.
HANDLE
CreateFile(
2.
LPCTSTR
lpFileName,
3.
DWORD
dwDesiredAccess,
4.
DWORD
dwShareMode,
5.
LPSECURITY_ATTRIBUTES
lpSecurityAttributes,
6.
DWORD
dwCreationDisposition,
7.
DWORD
dwFlagsAndAttributes,
8.
HANDLE
hTemplateFile
);
由於訪問的是事實上已經存在的磁盤扇區,因此只能以OPEN_EXISTING標誌設置dwCreationDisposition參數指出將要打開已經存在的文件(設備)。至於其他參數的使用與操作普通文件時的用法相同。
使用的時候,如果需要定位到某一個具體的扇區,可以使用SetFilePointer()函數:
1.
DWORD
SetFilePointer(
HANDLE
hFile,
LONG
lDistanceToMove,
PLONG
lpDistanceToMoveHigh,
DWORD
dwMoveMethod);
在定位到要訪問的扇區開始位置後就可以通過ReadFile()或WriteFile()函數實施相應的讀寫訪問了,具體操作與文件讀寫並沒有什麼太大的差別。最後,在完成訪問操作後以CloseHandle()關閉文件句柄釋放資源,從而完成一次完整的磁盤扇區數據訪問操作。
01.
int
ReadDisk(CString
driver,unsigned
char
*Buf,
long
addr)
02.
{
03.
HANDLE
hDevice;
04.
BOOL
bResult;
05.
DWORD
bytesread;
06.
07.
hDevice=CreateFile(driver,GENERIC_READ|GENERIC_WRITE,
08.
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
09.
if
(hDevice==INVALID_HANDLE_VALUE)
10.
{
11.
AfxMessageBox(
"Error!"
);
12.
return
0;
13.
}
14.
if
(addr!=0)
15.
{
16.
SetFilePointer(hDevice,512*addr,NULL,NULL);
17.
}
18.
19.
bResult=ReadFile(hDevice,Buf,512,&bytesread,NULL);
20.
if
((bResult==FALSE)||(bytesread<512))
21.
{
22.
AfxMessageBox(
"Error!"
);
23.
return
0;
24.
}
25.
CloseHandle(hDevice);
26.
return
1;
27.
}
3、用RC4加密算法對磁盤加密。
1.
/*
RC4加密,KEY是密鑰,此處Key[]="MobileStorageSecurity",後期可以用戶輸入的密碼作爲密鑰 */
2.
RC4_KEY
rc4_key;
3.
build_rc4_key(Key,
strlen
((
char
*)Key),&rc4_key);
4.
rc4_handler(MBRBuf,
strlen
((
char
*)MBRBuf),&rc4_key);
4、U盤插入計算機時的自動感知
1.
LRESULT
CRawDiskDlg::WindowProc(
UINT
message,
WPARAM
wParam,
LPARAM
lParam)
2.
{
3.
if
(
WM_DEVICECHANGE == message && FALSE == bCopy )
4.
{
5.
//刷新設備列表
6.
}
7.
return
CDialog::WindowProc(message,
wParam, lParam);
8.
}
後期改進
1.這樣就必須要求在電腦上有這個程序,所以在後期採用同樣的原理,將這個程序放在U盤裏,在加密的時候實現對自身的屏蔽,這樣大大提高程序的易用性。
2.可以讓用戶輸入密碼,將密碼作爲密鑰去加密和解密。
3.這個只是對一個磁盤最初的512字節加密,後期可以通過對扇區的定位和計算,對目錄表及數據加密。