Windows platform kernel-level file access

Source: Internet
Author: User

1. Background
Under the Windows platform, applications typically use API functions for file access, creating, opening, and reading and writing files. From Kernel32 's Createfile/readfile/writefile function, to local system services, to filesystem and its filterdriver, it has gone through many levels. At each level, there are security protection software, viruses or backdoor for monitoring or filtering opportunities. As a security product developer, we need to go farther than others, so we need an underlying "Windows platform kernel-level file access" approach to ensure that we can see the right clean file system.

2. Use
Direct kernel-level file access for a wide range of purposes in the area of information security. For the intruder's aspect, can let him bypass anti-virus software, IDs and other security protection system monitoring. For the detector, a clean system can be seen to detect hidden backdoors or rootkits. For the monitoring side, you can learn about the latest techniques for bypassing monitoring, and you can design updated monitoring scenarios based on them.

3. Direct access to FSD's kernel-level file access
The FSD (filesystemdriver) layer is the drive hierarchy that the file API functions last reached through the Local System service layer (native API). If we can mimic the operating system and send an IRP directly to FSD in our own driver, we can bypass those native APIs and Win32 APIs, and bypass the API hooks that are set at those levels.

3.1 file's Create and open
The file's create and open can be done by sending irp_mj_create to FSD, or by calling the Iocreatefile function. The difference between create and open is actually the value of a parameter disposition of iocreatefile/irp_mj_create. Sample code using the Iocreatefile function:

HANDLE OpenFile (wchar* name,access_mask access,ulong share)
{
return 0 for error.
HANDLE hfile;
Io_status_block IOSB;
int stat;
Object_attributes Oba;
Unicode_string Nameus;
///
if (KEGETCURRENTIRQL () >passive_level) {return 0;}
Rtlinitunicodestring (&nameus,name);
Initializeobjectattributes (&oba,&nameus,obj_kernel_handle| obj_case_insensitive,0,0);
Stat=iocreatefile (&hfile,access,&oba,&iosb,0,file_attribute_normal,share,file_open,0,0,0,0,0,0);
if (! Nt_success (stat)) {return 0;}
return hfile;
}

HANDLE createnewfile (wchar* name,access_mask access,ulong share)
{
return 0 for error.
HANDLE hfile;
Io_status_block IOSB;
int stat;
Object_attributes Oba;
Unicode_string Nameus;
///
if (KEGETCURRENTIRQL () >passive_level) {return 0;}
Rtlinitunicodestring (&nameus,name);
Initializeobjectattributes (&oba,&nameus,obj_kernel_handle| obj_case_insensitive,0,0);
Stat=iocreatefile (&hfile,access,&oba,&iosb,0,//allocationsize This set to 0 if file opened it was zero Ed.
file_attribute_normal,share,file_overwrite_if,0,0,0,0,0,0);
if (! Nt_success (stat)) {return 0;}
return hfile;
}

You can refer to the irp_mj_create description of IFSDDK document by sending Irp_mj_create to FSD in a similar way. Unlike the above method, it is necessary to create a file_object, better than the above method is that this method does not need a handle,handle is thread-dependent, FileObject is thread-independent.

3.2 Read and write of files
We read the file by sending Irp_mj_read to FSD and send Irp_mj_write to the FSD to rewrite the file.
If we are executing through a handle (such as a file opened with Iocreatefile), we first use the Obreferenceobjectbyhandle function to obtain the handle corresponding fileobject. We can only send an IRP to FileObject.

Stat=obreferenceobjectbyhandle (Handle,generic_read,*iofileobjecttype,kernelmode, (PVOID*) &fileob,0);

We then use IOALLOCATEIRP to assign an IRP. Based on the value of fileobject->deviceobject->flags, we determine what IO mode the target filesystem uses.

if (Fileob->deviceobject->flags & Do_buffered_io)
{
Irp->associatedirp.systembuffer=buffer;//buffered IO
}
else if (Fileob->deviceobject->flags & Do_direct_io)
{
MDL=IOALLOCATEMDL (buffer,count,0,0,0);
Mmbuildmdlfornonpagedpool (MDL);
Irp->mdladdress=mdl;//direct IO
}
Else
{
Irp->userbuffer=buffer;//neither I/O, use kernel buffer
}

Use different address delivery methods for each of the different IO modes. We then populate each parameter field within the IRP to send the IRP. Take read for example:

irpsp->fileobject=fileob;
irpsp->majorfunction=irp_mj_read;
irpsp->minorfunction=irp_mn_normal;//0
irpsp->parameters.read.byteoffset=offsetused;
irpsp->parameters.read.key=0;
irpsp->parameters.read.length=count;

Next to consider if the IRP is not completed in time, will asynchronously return the case, we install a completionroutine, in Completionroutine inside set an event to be activated, notify our main thread read or write operation has been completed.

Iosetcompletionroutine (irp,iocompletion,&event,1,1,1);

NTSTATUS
IoCompletion (
In Pdevice_object DeviceObject,
In Pirp IRP,
In PVOID Context
)
{
KeSetEvent ((prkevent) Context, io_disk_increment, 0);
return status_more_processing_required;
}

The IRP can now be sent. If special measures are not taken, the IRP sending target is fileobject corresponding to the DeviceObject. After sending, wait for the IRP to complete and release the resource, returned.

Stat=iocalldriver (FILEOB->DEVICEOBJECT,IRP);
if (stat==status_pending) {
KeWaitForSingleObject (&event, executive,kernelmode,0,0);
stat=irp->iostatus.status;
}
if (! Nt_success (STAT))
{
IOFREEIRP (IRP);
if (MDL) {iofreemdl (MDL);} If Do_direct_io
return-1;
}
Stat=irp->iostatus.information;//bytes Read
IOFREEIRP (IRP);
if (MDL) {iofreemdl (MDL);} If Do_direct_io
return stat;

Delete of 3.3 files
Delete actually sends the Irp_mj_set_information IRP to the FSD and irpsp-> Parameters.SetFile.FileInformationClass is set to Filedispositioninformation, with a file_disposition_ The information structure fills buffer to perform.

Fdi. Deletefile=true;

irpsp->majorfunction=irp_mj_set_information;
irpsp->parameters.setfile.length = sizeof (file_disposition_information);
Irpsp->parameters.setfile.fileinformationclass = filedispositioninformation;
Irpsp->parameters.setfile.deletehandle = (HANDLE) HANDLE;

Rename of 3.4 files
Similar to Delete,rename is the IRP that sends Irp_mj_set_information to FSD, putting irpsp-> The Parameters.SetFile.FileInformationClass is set to Filerenameinformation and the buffer is filled with file_rename_information structure.

Fri. Replaceifexists=true;
Fri. Rootdirectory=0;//set Fri. FileName to full path name.
Fri. Filenamelength=wcslen (filename) * *;
wcscpy (Fri. Filename,filename);//if the RootDirectory member is NULL, and the file was being moved to a different directory, this Membe R Specifies the full pathname to is assigned to the file.

irpsp->majorfunction=irp_mj_set_information;
irpsp->parameters.setfile.length = sizeof (file_file_rename_information);
Irpsp->parameters.setfile.fileinformationclass = filerenameinformation;


So we can directly access the file system by sending an IRP in the driver, bypassing the native API and the Win32 API hierarchy.


4. Bypass file system filter drivers and hooks

With the third part of the content, we can now send the request operation file directly to FSD. But this is not enough because there are a lot of anti-virus software or monitoring tools using FSD Filter driver or fsd hook method to monitor the file operation. In today's article I'm going to talk about some of the original things, and provide a way to bypass the FSD Filter driver/fsd Hook.

4.1 Dealing with file system filter drivers

File system filtering drives attach on top of normal file systems, monitoring and filtering our file access. The file system driver stack is made up of this series of attach-up filtering drives. We can use the Iogetrelateddeviceobject function to obtain a fileobject corresponding to the lowest level of the function driven object (FDO). But this bypasses the filter drive, but also bypasses the normal fsd such as Ntfs/fastfat, because the normal FSD is also a filter driver. The underlying fdo of the disk file object is Ftdisk.sys, which has been too low to handle the IRP request we delivered.
In fact, the normal FSD information is stored in a VPB structure, and we can use Iogetbasefilesystemdeviceobject, an undisclosed kernel function, to get it. It is the target of the IRP we sent.

4.2 FSD hooks to replace Dispatchroutine

This is a common type of FSD hook. We need to get the original dispatchroutine and send our IRP to the original dispatchroutine. Here's a thought: we can read the original FSD-driven. Init segment or. Text segment, find its driverentry function, and certainly set its own DriverObject dispatchroutine in its driverentry function. In this function we can find the address of the dispatchroutine we want. This value can be searched only by using the method of the signature search.

4.3 fsd hooks against the inline hook dispatchroutine function itself

This kind of hook method is vicious, but not very common in security products, generally used in Trojans and rootkits, such as I wrote a rootkit. Instead of changing the function pointer of the dispatchroutine inside the driverobject, it jumps to the function with jmp written to the assembly instruction at the beginning of the function. The basic idea to deal with it is to read the files that exist on the disk of FSD, load a clean backup into memory, and see how many bytes we want to call the beginning of the dispatchroutine and whether this clean backup is consistent. If it is inconsistent, especially if there is a JMP,RET,INT3 class of assembly instructions, it is possible that an inline Hook exists. (but take full account of the relocation situation.) If there is an inline Hook, we copy the clean function at the beginning to cover the infected function header. Then, when the IRP is sent, it is not monitored or tampered with by the inline hook.

Http://www.cnblogs.com/lzjsky/archive/2010/11/19/1881599.html

Windows platform kernel-level file access

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.