📄 fileworks.bat
字号:
;@echo off
;goto make
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; FileWorks - File creation, writing, reading etc...
;
; Written by Four-F (four-f@mail.ru)
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.386
.model flat, stdcall
option casemap:none
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; I N C L U D E F I L E S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntifs.inc
include \masm32\include\w2k\ntoskrnl.inc
includelib \masm32\lib\w2k\ntoskrnl.lib
include \masm32\Macros\Strings.mac
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; R E A D O N L Y D A T A
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.const
CCOUNTED_UNICODE_STRING "\\??\\c:\\FileWorks\\test.txt", g_usFileName, 4
CCOUNTED_UNICODE_STRING "\\??\\c:\\FileWorks", g_usDirName, 4
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; CreateDirectory
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CreateDirectory proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hDirectory:HANDLE
; Remember that the Unicode format codes (%C, %S, %lc, %ls, %wc, %ws, %wZ)
; can only be used at IRQL PASSIVE_LEVEL.
invoke DbgPrint, $CTA0("\nFileWorks: Creating %ws directory\n"), g_usDirName.Buffer
; Pay attention at OBJ_KERNEL_HANDLE flag. It's applicable for all object types not only for files.
; DDK stands:
; "Driver routines that run in a process context other than that of the system process
; must set the OBJ_KERNEL_HANDLE attribute for the ObjectAttributes parameter of ZwCreateFile.
; This restricts the use of the handle returned by ZwCreateFile to processes
; running only in kernel mode. Otherwise, the handle can be accessed by the process
; in whose context the driver is running."
; But in reality even you get a handle in system process context without specifying
; OBJ_KERNEL_HANDLE you can NOT touch this object in any other process context.
; So better always specify OBJ_KERNEL_HANDLE if you plan access object by handle
; in different processes. A kernel handle doesn抰 disappear until the operating system
; shuts down and can be used without ambiguity in any process.
InitializeObjectAttributes addr oa, addr g_usDirName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
invoke ZwCreateFile, addr hDirectory, SYNCHRONIZE, addr oa, addr iosb, 0, FILE_ATTRIBUTE_NORMAL, \
0, FILE_OPEN_IF, FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
.if eax == STATUS_SUCCESS
.if iosb.Information == FILE_CREATED
invoke DbgPrint, $CTA0("FileWorks: Directory created\n")
.elseif iosb.Information == FILE_OPENED
invoke DbgPrint, $CTA0("FileWorks: Directory exists and was opened\n")
.endif
invoke ZwClose, hDirectory
.else
invoke DbgPrint, $CTA0("FileWorks: Can't create directory. Status: %08X\n"), eax
.endif
ret
CreateDirectory endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; CreateFile
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CreateFile proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
; Remember that the Unicode format codes (%C, %S, %lc, %ls, %wc, %ws, %wZ)
; can only be used at IRQL PASSIVE_LEVEL.
invoke DbgPrint, $CTA0("\nFileWorks: Creating %ws file\n"), g_usFileName.Buffer
InitializeObjectAttributes addr oa, addr g_usFileName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
; If the file already exists, fail the request and do not create or open the given file.
; If it does not, create the given file.
invoke ZwCreateFile, addr hFile, SYNCHRONIZE, addr oa, addr iosb, 0, FILE_ATTRIBUTE_NORMAL, \
0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File created\n")
invoke ZwClose, hFile
.else
invoke DbgPrint, $CTA0("FileWorks: Can't create file. Status: %08X\n"), eax
.endif
ret
CreateFile endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; WriteFile
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
WriteFile proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
invoke DbgPrint, $CTA0("\nFileWorks: Opening file for writing\n")
InitializeObjectAttributes addr oa, addr g_usFileName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
; ZwCreateFile can be used for opening existing file. FILE_OPEN should be specified.
; I use:
; - FILE_WRITE_DATA because only I want is to write data into the file;
; - SYNCHRONIZE because of FILE_SYNCHRONOUS_IO_NONALERT.
; But you can simply use less strict FILE_ALL_ACCESS.
invoke ZwCreateFile, addr hFile, FILE_WRITE_DATA + SYNCHRONIZE, addr oa, addr iosb, \
0, 0, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File openeded\n")
CTA0 "Data can be written to an open file", g_szData, 4
invoke ZwWriteFile, hFile, 0, NULL, NULL, addr iosb, \
addr g_szData, sizeof g_szData - 1, NULL, NULL
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File was written\n")
.else
invoke DbgPrint, $CTA0("FileWorks: Can't write to the file. Status: %08X\n"), eax
.endif
invoke ZwClose, hFile
.else
invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
.endif
ret
WriteFile endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; MarkAsReadOnly
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
MarkAsReadOnly proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local fbi:FILE_BASIC_INFORMATION
invoke DbgPrint, $CTA0("\nFileWorks: Opening file for changing attributes\n")
InitializeObjectAttributes addr oa, addr g_usFileName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
; ZwCreateFile can be used for opening existing file. FILE_OPEN should be specified.
; I use:
; - FILE_READ_ATTRIBUTES because I want to query file attributes;
; - FILE_WRITE_ATTRIBUTES because I want to change file attributes;
; - SYNCHRONIZE because of FILE_SYNCHRONOUS_IO_NONALERT.
; But you can simply use less strict FILE_ALL_ACCESS.
invoke ZwCreateFile, addr hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SYNCHRONIZE, \
addr oa, addr iosb, 0, 0, FILE_SHARE_READ, \
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File openeded\n")
; Protect the file from deletion.
invoke ZwQueryInformationFile, hFile, addr iosb, addr fbi, sizeof fbi, FileBasicInformation
; Undocumented ZwQueryAttributesFile does the same.
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File attributes were: %08X\n"), fbi.FileAttributes
or fbi.FileAttributes, FILE_ATTRIBUTE_READONLY
invoke ZwSetInformationFile, hFile, addr iosb, addr fbi, sizeof fbi, FileBasicInformation
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: Now file marked as read-only\n")
.else
invoke DbgPrint, $CTA0("FileWorks: Can't change file attributes. Status: %08X\n"), eax
.endif
.else
invoke DbgPrint, $CTA0("FileWorks: Can't query file attributes. Status: %08X\n"), eax
.endif
invoke ZwClose, hFile
.else
invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
.endif
ret
MarkAsReadOnly endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; ReadFile
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ReadFile proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local p:PVOID
local cb:DWORD
local fsi:FILE_STANDARD_INFORMATION
invoke DbgPrint, $CTA0("\nFileWorks: Opening file for reading\n")
InitializeObjectAttributes addr oa, addr g_usFileName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
invoke ZwOpenFile, addr hFile, FILE_READ_DATA + SYNCHRONIZE, addr oa, addr iosb, \
FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE, 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
mov eax, fsi.EndOfFile.LowPart
inc eax ; one byte more for terminating zero
mov cb, eax
invoke ExAllocatePool, PagedPool, cb
.if eax != NULL
mov p, eax
invoke RtlZeroMemory, p, cb
invoke ZwReadFile, hFile, 0, NULL, NULL, addr iosb, p, cb, 0, NULL
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File content: \=%s\=\n"), p
.else
invoke DbgPrint, $CTA0("FileWorks: Can't read from the file. Status: %08X\n"), eax
.endif
invoke ExFreePool, p
.else
invoke DbgPrint, $CTA0("FileWorks: Can't allocate memory. Status: %08X\n"), eax
.endif
.else
invoke DbgPrint, $CTA0("FileWorks: Can't query file size. Status: %08X\n"), eax
.endif
invoke ZwClose, hFile
.else
invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
.endif
ret
ReadFile endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; UnmarkAsReadOnly
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
UnmarkAsReadOnly proc
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local fbi:FILE_BASIC_INFORMATION
invoke DbgPrint, $CTA0("\nFileWorks: Opening file for changing attributes\n")
InitializeObjectAttributes addr oa, addr g_usFileName, \
OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
; ZwCreateFile can be used for opening existing file. FILE_OPEN should be specified.
; I use:
; - FILE_READ_ATTRIBUTES because I want to query file attributes;
; - FILE_WRITE_ATTRIBUTES because I want to change file attributes;
; - SYNCHRONIZE because of FILE_SYNCHRONOUS_IO_NONALERT.
; But you can simply use less strict FILE_ALL_ACCESS.
invoke ZwCreateFile, addr hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SYNCHRONIZE, \
addr oa, addr iosb, 0, 0, FILE_SHARE_READ, FILE_OPEN, \
FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File openeded\n")
; Allow delete file.
invoke ZwQueryInformationFile, hFile, addr iosb, addr fbi, sizeof fbi, FileBasicInformation
; Undocumented ZwQueryAttributesFile does the same.
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: File attributes were: %08X\n"), fbi.FileAttributes
and fbi.FileAttributes, not FILE_ATTRIBUTE_READONLY
invoke ZwSetInformationFile, hFile, addr iosb, addr fbi, sizeof fbi, FileBasicInformation
.if eax == STATUS_SUCCESS
invoke DbgPrint, $CTA0("FileWorks: Now file can be written or deleted\n")
.else
invoke DbgPrint, $CTA0("FileWorks: Can't change file attributes. Status: %08X\n"), eax
.endif
.else
invoke DbgPrint, $CTA0("FileWorks: Can't query file attributes. Status: %08X\n"), eax
.endif
invoke ZwClose, hFile
.else
invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
.endif
ret
UnmarkAsReadOnly endp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -