📄 ramdisk.bat
字号:
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
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 + -