⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ramdisk.bat

📁 汇编语言开发驱动程序的开发包
💻 BAT
📖 第 1 页 / 共 2 页
字号:
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DispatchReadWrite proc uses esi edi pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP

local p:PVOID

	mov esi, pIrp
	assume esi:ptr _IRP

	mov [esi].IoStatus.Status, STATUS_UNSUCCESSFUL
	and [esi].IoStatus.Information, 0

	IoGetCurrentIrpStackLocation esi
	mov edi, eax
	assume edi:ptr IO_STACK_LOCATION

	; Check for invalid parameters.  It is an error for the starting offset
	; + length to go past the end of the buffer, or for the length to
	; not be a proper multiple of the sector size.

	; IO_STACK_LOCATION.Parameters.Read and IO_STACK_LOCATION.Parameters.Write
	; are absolutely the same, so we use Read for both

	mov eax, [edi].Parameters.Read.ByteOffset.LowPart
	add eax, [edi].Parameters.Read._Length
	mov ecx, [edi].Parameters.Read._Length
	and ecx, BYTES_PER_SECTOR - 1
	.if ( eax <= g_CreateParams.nDiskSize ) && ( ecx == 0 )

		; Get a system-space pointer to the user's buffer
		.if [esi].MdlAddress != NULL

			invoke MmGetSystemAddressForMdlSafe, [esi].MdlAddress, NormalPagePriority
			.if eax != NULL
				mov p, eax

				mov eax, [edi].Parameters.Read._Length
				mov [esi].IoStatus.Information, eax

				mov eax, g_pImage
				add eax, [edi].Parameters.Read.ByteOffset.LowPart
				.if [edi].MajorFunction == IRP_MJ_READ
					invoke memcpy, p, eax, [esi].IoStatus.Information
				.elseif [edi].MajorFunction == IRP_MJ_WRITE
					invoke memcpy, eax, p, [esi].IoStatus.Information				
				.endif

				mov [esi].IoStatus.Status, STATUS_SUCCESS
			.else
				mov [esi].IoStatus.Status, STATUS_INSUFFICIENT_RESOURCES
				invoke DbgPrint, $CTA0("RamDisk: Couldn't get the system-space virtual address\n")
        	.endif
		.endif
	.else
		mov [esi].IoStatus.Status, STATUS_INVALID_PARAMETER
		invoke DbgPrint, $CTA0("RamDisk: Invalid Read or Write request\n")
	.endif

	push [esi].IoStatus.Status

	assume edi:nothing
	assume esi:nothing

	fastcall IofCompleteRequest, esi, IO_NO_INCREMENT

	pop eax
	ret

DispatchReadWrite endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                     DispatchControl                                               
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DispatchControl proc uses esi edi pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP

local status:NTSTATUS
local dwContext:DWORD

Fix ADD LOCK
	mov esi, pIrp
	assume esi:ptr _IRP

	mov [esi].IoStatus.Status, STATUS_UNSUCCESSFUL
	and [esi].IoStatus.Information, 0

	IoGetCurrentIrpStackLocation esi
	mov edi, eax
	assume edi:ptr IO_STACK_LOCATION

	.if [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_REMOVE

		; Remove the drive letter associated with the ram disk.
		; This prevents new references to it from being established,
		; in preperation for deletion.

		invoke IsRamDiskOpened
		.if eax == FALSE
			; Delete the symbolic link created by the constructor
			invoke DeleteSymbolicLink
			mov [esi].IoStatus.Status, STATUS_SUCCESS
		.else
			mov [esi].IoStatus.Status, STATUS_DEVICE_BUSY
		.endif


	.elseif ([edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_MEDIA_TYPES) || ([edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY)
		.if [edi].Parameters.DeviceIoControl.OutputBufferLength >= sizeof DISK_GEOMETRY

			; request information about the disk geometry

			mov edi, [esi].AssociatedIrp.SystemBuffer
			assume edi:ptr DISK_GEOMETRY

			mov [edi].MediaType, RemovableMedia
			mov eax, g_CreateParams.nDiskSize
			shr eax, 0Fh			; / BYTES_PER_SECTOR * SECTORS_PER_TRACK * TRACKS_PER_CYLINDER = 512*32*2
			mov [edi].Cylinders.LowPart, eax
			and [edi].Cylinders.HighPart, 0
			mov [edi].TracksPerCylinder, TRACKS_PER_CYLINDER
			mov [edi].SectorsPerTrack, SECTORS_PER_TRACK
			mov [edi].BytesPerSector, BYTES_PER_SECTOR

			mov [esi].IoStatus.Status, STATUS_SUCCESS
			mov [esi].IoStatus.Information, sizeof DISK_GEOMETRY

			assume edi:nothing
		.else
			mov [esi].IoStatus.Status, STATUS_BUFFER_TOO_SMALL
		.endif

	assume edi:ptr IO_STACK_LOCATION
	.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_LENGTH_INFO
		.if [edi].Parameters.DeviceIoControl.OutputBufferLength >= sizeof GET_LENGTH_INFORMATION

			; request information about the disk length

			mov edi, [esi].AssociatedIrp.SystemBuffer
			assume edi:ptr GET_LENGTH_INFORMATION

			mov eax, g_CreateParams.nDiskSize
			and [edi]._Length.HighPart, 0
			mov [edi]._Length.LowPart, eax

			mov [esi].IoStatus.Status, STATUS_SUCCESS
			mov [esi].IoStatus.Information, sizeof GET_LENGTH_INFORMATION

			assume edi:nothing
		.else
			mov [esi].IoStatus.Status, STATUS_BUFFER_TOO_SMALL
		.endif
		

	assume edi:ptr IO_STACK_LOCATION
	.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_PARTITION_INFO
		.if [edi].Parameters.DeviceIoControl.OutputBufferLength >= sizeof PARTITION_INFORMATION

			mov edi, [esi].AssociatedIrp.SystemBuffer
			assume edi:ptr PARTITION_INFORMATION

			; The offset in bytes on drive where the partition begins
			and [edi].StartingOffset.LowPart, 0
			and [edi].StartingOffset.HighPart, 0

			; The length in bytes of the partition
			mov eax, g_CreateParams.nDiskSize
			mov [edi].PartitionLength.LowPart, eax
			and [edi].PartitionLength.HighPart, 0

			; The number of hidden sectors
			mov [edi].HiddenSectors, 1

			; Specifies the number of the partition
			or [edi].PartitionNumber, -1

			; Indicates the system-defined MBR partition type
			mov eax, g_pImage
			mov al, (BOOT_SECTOR PTR [eax]).FileSystemType[4]
			.if al == '2'
				; a partition with 12-bit FAT entries
				mov [edi].PartitionType, PARTITION_FAT_12
			.else
				; a partition with 16-bit FAT entries
				mov [edi].PartitionType, PARTITION_FAT_16
			.endif

			; FALSE indicates that this partition is not bootable
			and [edi].BootIndicator, FALSE

			; TRUE indicates that the system recognized the type of the partition
			mov [edi].RecognizedPartition, TRUE

			; FALSE indicates that the partition information has not changed
			and [edi].RewritePartition, FALSE

			mov [esi].IoStatus.Status, STATUS_SUCCESS
			mov [esi].IoStatus.Information, sizeof PARTITION_INFORMATION

			assume edi:nothing
		.else
			mov [esi].IoStatus.Status, STATUS_BUFFER_TOO_SMALL
		.endif



	assume edi:ptr IO_STACK_LOCATION
	.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_PARTITION_INFO_EX	; xp+
		.if [edi].Parameters.DeviceIoControl.OutputBufferLength >= sizeof PARTITION_INFORMATION_EX

    
			mov edi, [esi].AssociatedIrp.SystemBuffer
			assume edi:ptr PARTITION_INFORMATION_EX

			; AT-style master boot record

			mov [edi].PartitionStyle, PARTITION_STYLE_MBR

			; The offset in bytes on drive where the partition begins

			and [edi].StartingOffset.LowPart, 0
			and [edi].StartingOffset.HighPart, 0

			; The length in bytes of the partition

			mov eax, g_CreateParams.nDiskSize
			mov [edi].PartitionLength.LowPart, eax
			and [edi].PartitionLength.HighPart, 0

			; Specifies the number of the partition

			or [edi].PartitionNumber, -1

			; FALSE indicates that the partition information has not changed

			and [edi].RewritePartition, FALSE

			; Indicates the system-defined MBR partition type

			mov eax, g_pImage
			mov al, (BOOT_SECTOR PTR [eax]).FileSystemType[4]
			.if al == '2'
				; a partition with 12-bit FAT entries
				mov [edi].Mbr.PartitionType, PARTITION_FAT_12
			.else
				; a partition with 16-bit FAT entries
				mov [edi].Mbr.PartitionType, PARTITION_FAT_16
			.endif


			; FALSE indicates that this partition is not bootable

			and [edi].Mbr.BootIndicator, FALSE

			; TRUE indicates that the system recognized the type of the partition

			mov [edi].Mbr.RecognizedPartition, TRUE

			; The number of hidden sectors

			mov [edi].Mbr.HiddenSectors, 1

			mov [esi].IoStatus.Status, STATUS_SUCCESS
			mov [esi].IoStatus.Information, sizeof PARTITION_INFORMATION_EX

			assume edi:nothing
		.else
			mov [esi].IoStatus.Status, STATUS_BUFFER_TOO_SMALL
		.endif


	assume edi:ptr IO_STACK_LOCATION
	.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_VERIFY
		.if [edi].Parameters.DeviceIoControl.InputBufferLength >= sizeof VERIFY_INFORMATION

			; IOCTL_DISK_VERIFY is the same as IRP_MJ_READ
			; but no data is being transfered.

			mov edi, [esi].AssociatedIrp.SystemBuffer
			assume edi:ptr VERIFY_INFORMATION
			mov eax, [edi].StartingOffset.LowPart
			add eax, [edi]._Length
			mov ecx, [edi]._Length
			assume edi:nothing
			and ecx, BYTES_PER_SECTOR - 1
			.if ( eax <= g_CreateParams.nDiskSize ) && ( ecx == 0 )
				mov [esi].IoStatus.Status, STATUS_SUCCESS
			.else
				mov [esi].IoStatus.Status, STATUS_INVALID_PARAMETER
        	.endif
		.else
			mov [esi].IoStatus.Status, STATUS_BUFFER_TOO_SMALL
		.endif


	assume edi:ptr IO_STACK_LOCATION
	.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
 		.if [edi].Parameters.DeviceIoControl.OutputBufferLength < sizeof MOUNTDEV_NAME

			mov [esi].IoStatus.Status, STATUS_BUFFER_TOO_SMALL
			mov [esi].IoStatus.Information, sizeof MOUNTDEV_NAME

		.else

			mov ecx, [esi].AssociatedIrp.SystemBuffer
			assume ecx:ptr MOUNTDEV_NAME
			movzx eax, g_usDeviceName._Length
			mov [ecx].NameLength, ax

			inc eax
			inc eax		; + sizeof WORD

			; The buffer must fit sizeof WORD + MOUNTDEV_NAME.NameLength
	 		.if [edi].Parameters.DeviceIoControl.OutputBufferLength < eax

				mov [esi].IoStatus.Status, STATUS_BUFFER_OVERFLOW
				mov [esi].IoStatus.Information, sizeof MOUNTDEV_NAME
			
	 		.else

				movzx eax, [ecx].NameLength
	 			invoke memcpy, addr [ecx]._Name, g_usDeviceName.Buffer, eax

				mov [esi].IoStatus.Status, STATUS_SUCCESS
				
				movzx eax, g_usDeviceName._Length
				inc eax
				inc eax		; + sizeof WORD
				mov [esi].IoStatus.Information, eax
				
	 		.endif
			assume ecx:nothing
		.endif
		

	assume edi:ptr IO_STACK_LOCATION
	.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_CHECK_VERIFY

		mov [esi].IoStatus.Status, STATUS_SUCCESS
		and [esi].IoStatus.Information, 0


	.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_IS_WRITABLE

		mov [esi].IoStatus.Status, STATUS_SUCCESS
		and [esi].IoStatus.Information, 0


	.else
		mov [esi].IoStatus.Status, STATUS_INVALID_DEVICE_REQUEST
	.endif

	push [esi].IoStatus.Status

	assume edi:nothing
	assume esi:nothing
	
	fastcall IofCompleteRequest, esi, IO_NO_INCREMENT

	pop eax
	ret

DispatchControl endp


;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                       RemoveRamDisk                                               
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

RemoveRamDisk proc uses esi pDeviceObject:PDEVICE_OBJECT

local status:NTSTATUS

	mov status, STATUS_UNSUCCESSFUL

	.if g_fRamDiskCreated == TRUE

		invoke IsRamDiskOpened
		.if eax == FALSE

			.if g_pImage != NULL
	
				invoke ExFreePool, g_pImage

				and g_pImage, NULL

				; Normaly the symbolic link should have been deleted.
				invoke DeleteSymbolicLink
				invoke IoDeleteDevice, pDeviceObject

				and g_fRamDiskCreated, FALSE

				mov status, STATUS_SUCCESS

			.else
				invoke DbgPrint, $CTA0("RamDisk: BAD. Disk image pointer = NULL\n")
			.endif
		.else
			invoke DbgPrint, $CTA0("RamDisk: An attempt to remove opened RamDisk\n")
		.endif
	.else
		invoke DbgPrint, $CTA0("RamDisk: BAD. Disk doesn't exist\n")
	.endif

	mov eax, status
	ret

RemoveRamDisk endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                       DriverUnload                                                
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DriverUnload proc pDriverObject:PDRIVER_OBJECT

	mov eax, pDriverObject
	invoke RemoveRamDisk, (DRIVER_OBJECT PTR [eax]).DeviceObject
	ret

DriverUnload endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                              D I S C A R D A B L E   C O D E                                      
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.code INIT

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                       DriverEntry                                                 
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING

local status:NTSTATUS

	mov status, STATUS_DEVICE_CONFIGURATION_ERROR

	; Explicity initialize global variables
	xor eax, eax
	and g_fRamDiskCreated,		eax
	and g_fSymbolicLinkCreated,	eax
	and g_pImage,				eax
	and g_nOpenCount,			eax

	invoke QueryRamDiskParamsFromRegistry, pusRegistryPath
	.if eax == STATUS_SUCCESS
	
		invoke CreateRamDisk, pDriverObject
		.if eax == STATUS_SUCCESS
			mov g_fRamDiskCreated, TRUE

			mov eax, pDriverObject
			assume eax:ptr DRIVER_OBJECT
			mov [eax].MajorFunction[IRP_MJ_CREATE*(sizeof PVOID)],			offset DispatchCreate
			mov [eax].MajorFunction[IRP_MJ_CLOSE*(sizeof PVOID)],			offset DispatchClose
			mov [eax].MajorFunction[IRP_MJ_READ*(sizeof PVOID)],			offset DispatchReadWrite
			mov [eax].MajorFunction[IRP_MJ_WRITE*(sizeof PVOID)],			offset DispatchReadWrite
			mov [eax].MajorFunction[IRP_MJ_DEVICE_CONTROL*(sizeof PVOID)],	offset DispatchControl
			mov [eax].DriverUnload,											offset DriverUnload
			assume eax:nothing

			mov status, STATUS_SUCCESS

		.endif
	.else
		invoke DbgPrint, $CTA0("RamDisk: Couldn't get RamDisk parameters from the registry.\n")
	.endif

	mov eax, status
	ret

DriverEntry endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                                                                                   
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

end DriverEntry

:make

set drv=RamDisk

\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native /ignore:4078 %drv%.obj

del %drv%.obj
move %drv%.sys ..

echo.
pause

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -