From: bbs.driverdevelop.com, Chu mad man: After my simple modification, the copyright belongs to Chu crazy man.
[Part 1] full path
The following lists all functions in the full path. For string operations, see Unicode. Lib, a library of string operations]
Pvoid
Spygetfullpath (
Pfile_object fileobject
)
//----------------------------------------------------------------------
//
// Spygetfullpath
//
// Takes a fileobject and filename and returns a canonical path,
// Nicely formatted, in fullpathname.
//
//----------------------------------------------------------------------
{
Ntstatus status = STATUS_SUCCESS;
Unicode_string filename;
Wchar namebuf [max_path];
Unicode_string volname;
Wchar volbuf [8];
Pvoid Path = NULL;
Rtlinitemptyunicodestring (& filename, namebuf, max_name_space );
Rtlinitemptyunicodestring (& volname, volbuf, 8 * sizeof (wchar ));
If (! Spygetfilename (fileobject, & filename) // 07-09-25 modify
{
Return NULL;
}
Status = spygetvolumename (fileobject, & volname );
If (! Nt_success (Status ))
{
Return NULL;
}
Path = allocstrwithunistr (& volname );
If (PATH)
{
If (filename. Buffer [0]! = L '//')
{
Appendstrwithwidestr (path, l "//");
}
Appendstrwithunistr (path, & filename );
}
Return path;
}
//
// Record: add by LWF: 07-07-25
// Purpose: Get symbolic target Unicode string
//
Pvoid
Spygetsymbolicunistr (
Punicode_string symbolic
)
{
Object_attributes attrib;
Ntstatus status;
Wchar Buf [8];
Wchar * dbuf = NULL;
Unicode_string target;
Pvoid targetret = NULL;
Ulong length;
Handle linkhandle;
Initializeobjectattributes (
& Attrib,
Symbolic,
Obj_kernel_handle | obj_case_insensitive,
Null, null );
Status = zwopensymboliclinkobject (
& Linkhandle,
Generic_read,
& Attrib );
If (! Nt_success (Status ))
{
Return NULL;
}
Rtlinitemptyunicodestring (& target, Buf, 8 * sizeof (wchar ));
Status = zwquerysymboliclinkobject (
Linkhandle,
& Target,
& Length );
If (status = status_buffer_too_small)
{
Dbuf = exallocatepool (nonpagedpool, Length + 2 );
If (null = dbuf)
{
Zwclose (linkhandle );
Return NULL;
}
Rtlinitemptyunicodestring (& target, dbuf, Length + 2 );
Status = zwquerysymboliclinkobject (
Linkhandle,
& Target,
& Length );
}
If (nt_success (Status ))
{
Targetret = allocstrwithunistr (& target );
}
If (null! = Dbuf)
{
Freestr (dbuf );
}
Zwclose (linkhandle );
Return targetret;
}
//
// Record: add by LWF: 07-07-25
// Purpose: Get dos name
//
Pvoid
Spygetsymbolictarget (
Wchar * symbolic
)
{
Pvoid sym;
Pvoid ret;
If (null = symbolic)
{
Return NULL;
}
Sym = allocstrwithwidestr (symbolic );
If (null = sym)
{
Return NULL;
}
Ret = spygetsymbolicunistr (getstrunistr (sym ));
Freestr (sym );
Return ret;
}
//
// Record: add by LWF: 07-07-24
// Purpose: Get dos name
//
Pvoid
Spyvolumenametodosname (
Wchar * Name
)
{
Wchar volsyb [] = {L "// dosdevices // X :"};
Unicode_string volname;
Wchar C;
If (null = Name)
{
Return NULL;
}
Rtlinitunicodestring (& volname, name );
For (C = L 'a'; C <('Z' + 1); ++ C)
{
Pvoid mytarget = NULL;
Volsyb [12] = C;
Mytarget = spygetsymbolictarget (volsyb );
If (mytarget! = NULL &&
Rtlcompareunicodestring (getstrunistr (mytarget), & volname, true) = 0)
{
Freestr (mytarget );
Break;
}
If (mytarget! = NULL)
{
Freestr (mytarget );
}
}
If (C = 'Z' + 1)
{
Return NULL;
}
Else
{
Return allocstrwithwidestr (& volsyb [12]);
}
}
//
// Record: add by LWF: 07-07-24
// Purpose: Get dos name
//
Pvoid
Spyqueryobjname (
Pvoid OBJ
)
{
Ntstatus status;
Uchar nibuf [1, 512];
Int Len = max_path;
Ulong ret;
Object_name_information * name_infor =
(Object_name_information *) nibuf;
Status = obquerynamestring (OBJ, name_infor, 512, & RET );
If (nt_success (Status ))
{
Return allocstrwithunistr (& name_infor-> name );
}
Else
{
Return NULL;
}
}
//
// Record: add by LWF: 07-07-24
// Purpose: Get dos name
//
Pvoid
Spygetdosname (
Pdevice_object Dev
)
{
Pvoid volname = spyqueryobjname (Dev );
Pvoid ret = NULL;
If (null = volname)
{
Return NULL;
}
Ret = spyvolumenametodosname (getstrbuf (volname ));
Freestr (volname );
Return ret;
}
//
// Record: add by LWF: 07-07-24
// Purpose: Get volume name
//
Ntstatus
Spygetvolumename (
Pfile_object fileobject,
Punicode_string volname
)
{
Ntstatus status = STATUS_SUCCESS;
Pvoid pdosname = NULL;
Pdosname = spygetdosname (fileobject-> deviceobject );
If (null = pdosname)
{
Return status_unsuccessful;
}
Rtlcopyunicodestring (volname, getstrunistr (pdosname ));
Freestr (pdosname );
Return status;
}
//
// Record: add by LWF: 07-07-23
// Purpose: Get Object Name
//
Void
Spygetobjectname (
Pvoid OBJ,
Punicode_string name
)
{
Ntstatus status;
Char nibuf [512];
Object_name_information * name_infor = (object_name_information *) nibuf;
Ulong ret;
Status = obquerynamestring (OBJ, name_infor, 512, & RET );
If (nt_success (Status ))
{
Rtlcopyunicodestring (name, & name_infor-> name );
}
Else
{
Name-> length = 0;
}
}
//
// Record: add by LWF: 07-07-23
// Purpose: Get File Name
//
Ntstatus
Spygetfilename (
In pfile_object fileobject,
Punicode_string name
)
{
Wchar * P = NULL;
Wchar Buf [max_path];
Unicode_string temp;
Int Len;
Rtlinitemptyunicodestring (& temp, Buf, max_name_space );
Spygetobjectname (pvoid) fileobject, & temp );
Kdprint ("queryfilename: [% WZ]/R/N", & temp ));
If (temp. Length = 0)
{
Return false;
}
Len = temp. Length/sizeof (wchar );
P = temp. buffer;
P = wcschr (const wchar *) (unicode_string *) (& temp)-> buffer), l '//');
If (P = NULL | + + P> = (unicode_string *) (& temp)-> buffer + Len)
{
Return false;
}
P = wcschr (p, l '//');
If (P = NULL | + + P> = (unicode_string *) (& temp)-> buffer + Len)
{
Return false;
}
P = wcschr (p, l '//');
If (P = NULL | (p + 1) >=( (unicode_string *) (& temp)-> buffer + Len)
{
Return false;
}
If (name-> maximumlength <= wcslen (p) * sizeof (wchar ))
{
Return false;
}
Name-> length = wcslen (p) * sizeof (wchar );
Wcscpy (name-> buffer, P );
Return true;
}
[Part 2] where to obtain
Because the request received during create IRP is the most authentic (not tampered with), we call the full path function when spycreate is complete to obtain the full path.
Ntstatus
Spycreate (
In pdevice_object deviceobject,
In pirp
)
{
Ntstatus status;
Kirql oldirql;
Pio_stack_location irpsp = iogetcurrentirpstacklocation (IRP );
Pfile_object fileobject;
Pvoid block;
Kevent waitevent;
Pchar pdbgstr = NULL;
If (deviceobject = gcontroldeviceobject ){
Keacquirespinlock (& gcontroldevicestatelock, & oldirql );
IRP-> iostatus. Status = STATUS_SUCCESS;
IRP-> iostatus. Information = file_opened;
Gcontroldevicestate = opened;
Kereleasespinlock (& gcontroldevicestatelock, oldirql );
G_hprocessid = psgetcurrentprocessid ();
Status = IRP-> iostatus. status;
Iocompleterequest (IRP, io_no_increment );
Return status;
}
Assert (is_filespy_device_object (deviceobject ));
Keinitializeevent (& waitevent, icationicationevent, false );
Iocopycurrentirpstacklocationtonext (IRP );
Iosetcompletionroutine (
IRP,
Spycreatecompletion,
& Waitevent,
True,
True,
True );
Status = iocalldriver (pfilespy_device_extension) deviceobject-> deviceextension)-> nlextheader. attachedtodeviceobject,
IRP );
If (status_pending = Status)
{
Ntstatus localstatus = kewaitforsingleobject (& waitevent,
Executive,
Kernelmode,
False,
Null );
Assert (STATUS_SUCCESS = localstatus );
}
Assert (kereadstateevent (& waitevent) |
! Nt_success (IRP-> iostatus. Status ));
Fileobject = irpsp-> fileobject;
Block = spygetfullpath (fileobject );
Pdbgstr = unicodetoansi (getstrunistr (Block ));
Dprintf ("[filespy. sys] majorfunction: spycreate: [% s]", pdbgstr );
Freestr (Block );
Status = IRP-> iostatus. status;
Iocompleterequest (IRP, io_no_increment );
Return status;
}
[Part 3] Chinese Printing
Write a printing function that supports Chinese Characters
Because dbuplint will be truncated when it encounters a Chinese character unicode_string, we convert it to ansi_string to print
Pchar unicodetoansi (
In punicode_string punicodestring
)
{
// Unicode_string is not empty
If (punicodestring = NULL)
{
Return NULL;
}
// String buffer is not empty
If (punicodestring-> buffer = NULL)
{
Return NULL;
}
Dbgstr. Length = 0;
Dbgstr. maximumlength = max_length;
Rtlzeromemory (dbgstr. buffer, max_length );
// Convert Buffer
Rtlunicodestringtoansistring (& dbgstr, punicodestring, false );
Return dbgstr. buffer;
}