📄 fileworks.bat
字号:
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; AppendFile
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
AppendFile proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
invoke DbgPrint, $CTA0("\nFileWorks: Opening file to append data\n")
InitializeObjectAttributes addr oa, addr g_usFileName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
; If only the FILE_APPEND_DATA and SYNCHRONIZE flags are set, the caller can write
; only to the end of the file, and any offset information on writes to the file is ignored.
; However, the file will automatically be extended as necessary
; for this type of write operation.
invoke ZwOpenFile, addr hFile, FILE_APPEND_DATA + SYNCHRONIZE, addr oa, addr iosb, \
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File openeded\n")
CTA0 " using ZwWriteFile", g_szDataToAppend, 4
; If the call to ZwOpenFile set only the DesiredAccess flag FILE_APPEND_DATA,
; ByteOffset is ignored. Data in the given Buffer, for Length bytes,
; is written starting at the current end of file.
invoke ZwWriteFile, hFile, 0, NULL, NULL, addr iosb, \
addr g_szDataToAppend, sizeof g_szDataToAppend - 1, NULL, NULL
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: Data appended to the file\n")
.else
invoke DbgPrint, $CTA0("FileWorks: Can't append data to file. Status: %08X\n"), eax
.endif
invoke ZwClose, hFile
.else
invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
.endif
ret
AppendFile endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; TruncateFile
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
TruncateFile proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local fsi:FILE_STANDARD_INFORMATION
local feofi:FILE_END_OF_FILE_INFORMATION
invoke DbgPrint, $CTA0("\nFileWorks: Opening file to truncate\n")
InitializeObjectAttributes addr oa, addr g_usFileName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
; Or just use FILE_GENERIC_WRITE
invoke ZwOpenFile, addr hFile, FILE_WRITE_DATA + SYNCHRONIZE, addr oa, addr iosb, \
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File openeded\n")
invoke ZwQueryInformationFile, hFile, addr iosb, \
addr fsi, sizeof fsi, FileStandardInformation
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: EOF was: %08X\n"), fsi.EndOfFile.LowPart
and feofi.EndOfFile.HighPart, 0
mov eax, fsi.EndOfFile.LowPart
shr eax, 1 ; truncate to half size
mov feofi.EndOfFile.LowPart, eax
invoke ZwSetInformationFile, hFile, addr iosb, \
addr feofi, sizeof feofi, FileEndOfFileInformation
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File truncated to its half size\n")
.else
invoke DbgPrint, $CTA0("FileWorks: Can't truncate file. Status: %08X\n"), eax
.endif
.else
invoke DbgPrint, $CTA0("FileWorks: Can't query file info. Status: %08X\n"), eax
.endif
invoke ZwClose, hFile
.else
invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
.endif
ret
TruncateFile endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DeleteFile
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DeleteFile proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local fdi:FILE_DISPOSITION_INFORMATION
invoke DbgPrint, $CTA0("\nFileWorks: Opening file for deletion\n")
InitializeObjectAttributes addr oa, addr g_usFileName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
invoke ZwCreateFile, addr hFile, DELETE + SYNCHRONIZE, addr oa, addr iosb, \
0, 0, FILE_SHARE_DELETE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File openeded\n")
mov fdi.DeleteFile, TRUE
invoke ZwSetInformationFile, hFile, addr iosb, addr fdi, sizeof fdi, FileDispositionInformation
.if eax == STATUS_SUCCESS
; The file has been marked for deletion. Do nothing with the file handle except closing it.
invoke DbgPrint, $CTA0("FileWorks: File has been marked for deletion\n")
invoke DbgPrint, $CTA0("FileWorks: It should be deleted when the last open handle is closed\n")
.else
invoke DbgPrint, $CTA0("FileWorks: Can't mark file for deletion. Status: %08X\n"), eax
.endif
invoke ZwClose, hFile
.else
invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
.endif
ret
DeleteFile endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DeleteDirectory
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DeleteDirectory proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hDirectory:HANDLE
InitializeObjectAttributes addr oa, addr g_usDirName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
; The DDK stands that ZwDeleteFile exist only on Windows XP and later
; but it's not true.
invoke ZwDeleteFile, addr oa
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("\nFileWorks: Directory deleted\n")
.else
invoke DbgPrint, $CTA0("\nFileWorks: Can't delete directory. Status: %08X\n"), eax
.endif
ret
DeleteDirectory endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; EnumerateFiles
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
EnumerateFiles proc uses esi
local status:NTSTATUS
local oa:OBJECT_ATTRIBUTES
local hSystemRootDirectory:HANDLE
local hDriversDirectory:HANDLE
local as:ANSI_STRING
local us:UNICODE_STRING
local iosb:IO_STATUS_BLOCK
local tf:TIME_FIELDS
local cb:DWORD
local pfdi:PFILE_DIRECTORY_INFORMATION
invoke DbgPrint, $CTA0("\nFileWorks: Opening directory to enumerate files\n")
InitializeObjectAttributes addr oa, $CCOUNTED_UNICODE_STRING("\\SystemRoot"), \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
invoke ZwOpenFile, addr hSystemRootDirectory, FILE_LIST_DIRECTORY + SYNCHRONIZE, addr oa, \
addr iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE, \
FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT
.if eax == STATUS_SUCCESS
; Specify pathname relative to the directory file represented by the hSystemRootDirectory.
InitializeObjectAttributes addr oa, $CCOUNTED_UNICODE_STRING("system32\\drivers"), \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, hSystemRootDirectory, NULL
invoke ZwOpenFile, addr hDriversDirectory, FILE_LIST_DIRECTORY + SYNCHRONIZE, addr oa, \
addr iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE, \
FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT
.if eax == STATUS_SUCCESS
; 256 bites is enough to hold file name
mov cb, sizeof FILE_DIRECTORY_INFORMATION + 256
invoke ExAllocatePool, PagedPool, cb
.if eax != NULL
mov pfdi, eax
mov esi, eax
assume esi:ptr FILE_DIRECTORY_INFORMATION
invoke DbgPrint, \
$CTA0("\nFileWorks: ---------- Starting enumerate files ----------\n")
; DDK stands ZwQueryDirectoryFile is available on Windows XP and later
; but it's not true.
; Let's enumerate all files which name starts whith 'c' for example.
invoke ZwQueryDirectoryFile, hDriversDirectory, NULL, NULL, NULL, addr iosb, \
esi, cb, FileDirectoryInformation, \
TRUE, $CCOUNTED_UNICODE_STRING("c*"), TRUE
.while eax != STATUS_NO_MORE_FILES
.if ( eax == STATUS_SUCCESS )
; Fill UNICODE_STRING manually instead of calling RtlInitUnicodeString
; because of FILE_DIRECTORY_INFORMATION.FileName is not null-terminated
mov eax, [esi].FileNameLength
mov us._Length, ax
mov us.MaximumLength, ax
lea eax, [esi].FileName
mov us.Buffer, eax
invoke RtlUnicodeStringToAnsiString, addr as, addr us, TRUE
.if eax == STATUS_SUCCESS
invoke RtlTimeToTimeFields, addr [esi].CreationTime, addr tf
movzx eax, tf.Day
movzx ecx, tf.Month
movzx edx, tf.Year
; Who knows, may be sometime driver files grow bigger then 4Gb :-(((
; But in our days we can be shure that LowPart is enough
invoke DbgPrint, $CTA0(" %s size=%d created on %d.%02d.%04d\n"), \
as.Buffer, [esi].EndOfFile.LowPart, eax, ecx, edx
invoke RtlFreeAnsiString, addr as
.endif
.endif
; Continue scanning
invoke ZwQueryDirectoryFile, hDriversDirectory, NULL, NULL, NULL, addr iosb, \
esi, cb, FileDirectoryInformation, \
TRUE, NULL, FALSE
.endw
invoke DbgPrint, \
$CTA0("FileWorks: ------------------------------------------------\n")
assume esi:nothing
invoke ExFreePool, pfdi
.endif
invoke ZwClose, hDriversDirectory
.else
invoke DbgPrint, $CTA0("FileWorks: Can't open drivers directory. Status: %08X\n"), eax
.endif
invoke ZwClose, hSystemRootDirectory
.else
invoke DbgPrint, $CTA0("FileWorks: Can't open system root directory. Status: %08X\n"), eax
.endif
ret
EnumerateFiles endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DriverEntry
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
invoke DbgPrint, $CTA0("\nFileWorks: Entering DriverEntry\n")
invoke CreateDirectory
invoke CreateFile
invoke WriteFile
invoke MarkAsReadOnly
invoke ReadFile
invoke UnmarkAsReadOnly
invoke AppendFile
invoke ReadFile
invoke TruncateFile
invoke ReadFile
invoke DeleteFile
invoke DeleteDirectory
invoke EnumerateFiles
invoke DbgPrint, $CTA0("\nFileWorks: Leaving DriverEntry\n\n")
mov eax, STATUS_DEVICE_CONFIGURATION_ERROR
ret
DriverEntry endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
end DriverEntry
:make
set drv=FileWorks
\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj
del %drv%.obj
echo.
pause
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -