日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

虚拟光驱探秘

發布時間:2023/12/20 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 虚拟光驱探秘 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
現在網絡上越來越流行使用虛擬光驅,由于虛擬光驅的使用,使得越來越多的PC擁有很以前所無法想象的特殊功能,如:
1. 應用虛擬光驅能夠使沒有dvd的用戶直接使用網上可以下載的dvd鏡像來欣賞dvd的影片。
2. 通過光盤鏡像復制工具制作的光盤可以不必使用低速的刻錄設備刻錄而直接使用
3. 最實用的一點,借助虛擬光驅,可以模擬各種加密的光盤模式,即使在正版光盤不在身邊的情況下也能使用。(對熟悉網絡的人更為實用)
對于虛擬光驅工具的使用,網絡上已經有不少相關的文章了,還有不少圖文并茂的教程,在這里就不多贅述了,本文要研究的,是虛擬光驅軟件的原理和編程實現。
首先,最常用的虛擬光驅軟件是運行在windows操作系統之下的。對于微軟的操作系統來說,任何應用層上的程序是不能直接與硬件打交道的,必須要通過操作系統內核(kernel)這個中介來實現對硬件的操作。微軟為了最大限度的提供硬件層的抽象,把各種硬件設備相關的內核實現代碼用各種驅動模塊封裝了起來,并提供動態加載接口。因此對于各種設備自身的I/O處理和數據流處理,微軟只提供了一個接口框架,具體的流程是交給驅動程序自身的代碼去解決的,并依靠各個設備的I/O管理器向各個在內核中注冊的驅動發送IRP包的形式來進行統一的管理。這實際上也就意味著我們可以向系統注冊一個實際上并不存在的硬件設備來欺騙操作系統的內核,而實際上的設備操作都是由我們自己編寫的驅動模塊來進行軟件的實現。這也就是一切windows下虛擬設備存在的基礎。存儲設備驅動結構。
接下來就是如何做一個最基本的虛擬光驅并使他正常工作。眾所周知,windows使用了“消息”這一數據結構來實現應用程序之間的通信,同樣,在內核層,微軟也定義了一套IO控制碼(IOCTL)的結構來實現內核與驅動設備之間的數據流和控制流的傳遞。針對不同的設備,IO控制碼的宏定義是不同的,這樣就保證了各個設備之間的控制流不會傳錯地方。對于一個標準的CD-ROM設備,其關鍵的IOCTL的定義:
IOCTL_CDROM_GET_DRIVE_GEOMETRY :獲得光盤物理結構
IOCTL_CDROM_GET_LAST_SESSION :獲得光盤最后一個區段
IOCTL_CDROM_CHECK_VERIFY :光盤介質檢查
IOCTL_CDROM_CLOSE_DOOR :光盤入倉
IOCTL_CDROM_RAW_READ :以raw方式讀取光盤數據
IOCTL_CDROM_READ_TOC: 獲得光盤存儲內容結構
需要處理的關鍵IRP請求
IRP_MJ_READ:對設備的數據讀請求(虛擬光驅的核心)
例子:一個最簡單的虛擬光驅的驅動入口代碼:
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
……
ZwMakeTemporaryObject(dir_handle);
for (n = 0; n < n_devices; n++)
{
status=DiskCreateDevice(DriverObject, n, FILE_DEVICE_CD_ROM);
if (NT_SUCCESS(status))
{
n_created_devices++;
}
}
if (n_created_devices == 0)
{
ZwClose(dir_handle);
return status;
}
//虛擬設備例程處理
DriverObject->MajorFunction[IRP_MJ_CREATE] = DiskCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE]= DiskCreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = DiskReadWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DiskDeviceControl;

?

DriverObject->DriverUnload = DiskUnload;

return STATUS_SUCCESS;
}
//虛擬設備創建注冊函數
NTSTATUS
DiskCreateDevice (
IN PDRIVER_OBJECT DriverObject,
IN ULONG Number,
IN DEVICE_TYPE DeviceType
)
{
WCHAR device_name_buffer[MAXIMUM_FILENAME_LENGTH];
UNICODE_STRING device_name;
NTSTATUS status;
PDEVICE_OBJECT device_object;
PDEVICE_EXTENSION device_extension;
HANDLE thread_handle;
ASSERT(DriverObject != NULL);
if (DeviceType == FILE_DEVICE_CD_ROM)
{
swprintf(
device_name_buffer,
DEVICE_NAME_PREFIX L"Cd" L"%u",
Number
);
}
else
{
swprintf(
device_name_buffer,
DEVICE_NAME_PREFIX L"%u",
Number
);

RtlInitUnicodeString(&device_name, device_name_buffer);
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&device_name,
DeviceType,
0,
FALSE,
&device_object
);
if (!NT_SUCCESS(status))
{
return status;
}

device_object->Flags |= DO_DIRECT_IO;
device_extension= (PDEVICE_EXTENSION) device_object->DeviceExtension;
device_extension->media_in_device = FALSE;
if (DeviceType == FILE_DEVICE_CD_ROM)
{
device_object->Characteristics |= FILE_READ_ONLY_DEVICE;
device_extension->read_only = TRUE;
}
InitializeListHead(&device_extension->list_head);
KeInitializeSpinLock(&device_extension->list_lock);
KeInitializeEvent(
&device_extension->request_event,
SynchronizationEvent,
FALSE
);
device_extension->terminate_thread = FALSE;
status = PsCreateSystemThread(
&thread_handle,
(ACCESS_MASK) 0L,
NULL,
NULL,
NULL,
DiskThread,
device_object
);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(device_object);
return status;
}
status = ObReferenceObjectByHandle(
thread_handle,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&device_extension->thread_pointer,
NULL
);
if (!NT_SUCCESS(status))
{
ZwClose(thread_handle);
device_extension->terminate_thread = TRUE;
KeSetEvent(
&device_extension->request_event,
(KPRIORITY) 0,
FALSE
);
IoDeleteDevice(device_object);
return status;
}
ZwClose(thread_handle);
return STATUS_SUCCESS;
}
NTSTATUS
FileDiskDeviceControl (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
……
//處理IOCTL
witch (io_stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_CDROM_READ_TOC:
// IOCTL_CDROM_READ_TOC實現代碼
case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
// IOCTL_CDROM_GET_DRIVE_GEOMETRY實現代碼

}

}
對應每個控制碼,都有一個相應的實現函數,對于是實在的硬件設備而言,每個硬件都會有一套自己的控制匯編來操作硬件。對于我們的虛擬光驅而言,我們并不需要了解光驅的專用匯編指令,我們只需要用一系列的api語句來實現數據讀的功能就可以了。需要注意的是,在我們的虛擬光驅中使用的不是普通的win32 api,而是專門用于和windows內核交互的NATIVE API,即windows原生函數。
經過以上的步驟,我們已經實現了一個最基本的虛擬光驅,現在我們還需要為其添加一系列的輔助功能來實現對加密光盤的模擬。
一個能夠虛擬加密光盤的虛擬光驅實際上是由三部分組成的:一是上面所述的內核驅動,就是虛擬光驅面向內核的實現部分,二是微端口過濾驅動部分(MINIPORT),這一部分是用來欺騙內核的總線驅動ATAPI.SYS(也有部分虛擬光軀有自己的總線驅動,如daemon tools),實現光驅的總線功能操作;三是光驅文件系統過濾驅動,其目的是使一些具有特殊文件結構和光軌分布結構的加密光盤虛擬變得可能,如何才能做好這一部分,實際上是所有商業化的虛擬光驅的技術核心。
微端口過濾驅動都具有比較固定的結構,其詳細的例程在微軟的驅動開發包中都有詳細的表述,較為常用的SCSI_MINIPORT驅動有非常完整的例子,這里就不多做敘述了。
對于任何一種物理光盤保護來說,總面臨著這樣一個問題:是否能讓普通光驅讀出的數據無法完全被操作系統使用?假如能做到的話,無疑是一個非常完美的保護。但遺憾的是,目前的windows操作系統尚無法為光盤保護軟件商們制作這樣一個完美的機制,因此,也使各種對光盤的模擬的軟件能夠大行其道。這些軟件的結構中,很重要的一個組件就是文件過濾系統驅動。
光驅文件過濾系統是比較特殊的一類驅動,它對光盤的數據文件讀寫格式進行規范和定義,好比是文件系統上的一個篩子,截獲各種特殊的請求并自定義返回或者處理過程。常規的光盤采用的是ISO9660文件系統結構,微軟在操作系統內部也有直接的函數支持,因此在虛擬光驅編寫中并不要自己來處理文件系統相關的操作。而一些經過特殊加工的加密光盤采用一些比較特殊的方法人為制造可讀取的壞道,用普通的ISO文件系統讀寫函數是無法獲得加密光軌的信息的,再前期數據讀取期必須激活光驅驅動的“RAW”模式來讀取。在光盤虛擬的后期也要設計自己的讀寫函數來返回加密光軌的數據,這就是要引入光驅文件過濾系統的原因。
目前非常流行的“光盤特征識別(RMPS)”技術使一般的虛擬光驅無法實現這種特殊數據結構的讀取狀態,因此可以用來判斷是否采用了正版的光盤。基于這個原理的保護技術大同小異(包括現在的號稱最強的starforce)。現在僅就早期的一種名為“tages”的技術做一些說明:
tages中在光盤中的某些特殊區域存放著一種特殊的光軌,它由兩條光軌組成,兩條光軌有著相同的序號和盤內地址。由于光盤光頭讀取軌道的時候是采取最近最先的原則,在光頭移動距離最短的光軌是最先被使用的,所以光頭在不同的位置會讀取到2條光軌中不同的數據。tages光軌的結構。

對于這種的加密光盤格式,由于其生產過程中加密光軌的分布位置各不相同,所以就形成了所謂的“光盤指紋”。因為,從本質上來說,啟動加密過的執行文件,進行正版序列號的輸入工作,實際上就是輸入加密光軌的位置并讓加密系統進行驗證的過程。
對于某種特殊的加密如starforce,它甚至接管了ide總線驅動,它由它自己的總線驅動來實現對光盤數據的讀取,并在讀取過程中記錄讀取加密光軌的各種運行時刻參數(如讀取一個光軌經歷的時間等,starforce的新版本甚至精確到了毫秒級別),以此來作為是否正版光盤的認證。其實我個人認為starforce在光盤文件格式上并沒有與其他保護系統有何種優越性,事實上它只在阻止調試者對受保護的程序進行調試方面做的非常成功(使用了偽代碼,內存保護,進程保護,調試監控,禁止下斷點,有些時候這樣的保護使正版都無法通過檢測),對于使用其保護的光盤復制并且模擬仍然是可能的。
對于這些加密光盤,可以在驅動中層結構中使用一些特殊的軟件層驅動來過濾這些特殊光軌的I/O請求,并返回讀取正版光盤時的系統變量和參數來對這個光盤進行模擬,也就是文件系統過濾驅動。
較為成功的文件過濾系統是Alochol 120%的rmps文件系統,其原理實際上就是對光盤某些區域的讀取的實地情況進行類似“錄像”的操作,并記錄進文件,在模擬時進行回放。事實上,Alochol這種技術是相當成功的,starforce目前只能用使用自己的總線驅動并且在運行時封閉scsi總線的方法來規避Alochol的模擬。
文件過濾系統的技術難點在于原始光盤讀取數據的采集,一旦其能夠完整的采集到原始光盤的讀寫狀態紀錄,那么模擬將會是非常容易的。

附錄:
一些文件過濾系統驅動的例子可以在網上找到,如:
ext2 IFS:
http://uranus.it.swin.edu.au/~jn/linux/ext2ifs.htm
ext2 FSD:
http://ext2fsd.sourceforge.net/projects/projects.htm#insider

總結

以上是生活随笔為你收集整理的虚拟光驱探秘的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。