NtCreateFile返回大目录的否定 [英] NtCreateFile Returning Large Neg for Directory

查看:90
本文介绍了NtCreateFile返回大目录的否定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目的是创建一个目录。以下是全球定价:



  typedef  NTSTATUS( __ stdcall  * NTDLLptr)(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES * ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength);

typedef VOID( __ stdcall * my_RtlInitUnicodeString)(
IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString);
// static my_RtlInitUnicodeString rtlInitUnicodeString; //更新:这里没什么区别!


NTDLLptr foundNTDLL = NULL; // 在此处返回变量
// RtlInitUnicodeStringPtr pRtlInitUnicodeString; // for NTcreatefile fileObject
UNICODE_STRING fn;
OBJECT_ATTRIBUTES fileObject;
IO_STATUS_BLOCK ioStatus;
NTSTATUS状态;





加载库的函数调用:



 NTDLLptr DynamicLoader(HWND hwnd, bool  progInit)
{
HMODULE hdlNtCreateFile = LoadLibraryW(L NtDll.dll);
foundNTDLL =(NTDLLptr)GetProcAddress(hdlNtCreateFile,createFnString);
if (foundNTDLL)
{
if (progInit)
{
memset(& ioStatus, 0 sizeof (ioStatus));
memset(& fileObject, 0 sizeof (fileObject));
fileObject.Length = sizeof (fileObject);
fileObject.Attributes = OBJ_CASE_INSENSITIVE;
}
else
{
my_RtlInitUnicodeString RtlInitUnicodeString =(my_RtlInitUnicodeString)GetProcAddress(hdlNtCreateFile,initUnicodeFnString);
RtlInitUnicodeString(& fn,tempDest);
fileObject.ObjectName =& fn; // Ntdll.dll
}
返回 foundNTDLL;
}
else
{
FreeLibrary(hdlNtCreateFile);
return foundNTDLL;
}

}





电话是在初始时发出的:

  if (!DynamicLoader(hwnd, true ))DisplayError( hwnd,L  已删除长路径功能。使用短路径功能......,错误代码, 0 ); 
...
if (foundNTDLL)FreeLibrary((HMODULE)hdlNtCreateFile);
/ pre>
tempDest是一个calloc ' d wchar_t包含路径名。 NTcreatefile调用在这里进行:
< pre lang =c ++> if(DynamicLoader(hwnd,false))
{

NTSTATUS ntStatus;
ntStatus = foundNTDLL(& hdlNTOut,FILE_LIST_DIRECTORY | FILE_TRAVERSE,& fileObject,& ioStatus,NULL,FILE_ATTRIBUTE_NORMAL,0,FILE_CREATE,FILE_DIRECTORY_FILE,NULL,0);

if(!NT_SUCCESS(ntStatus))
....
free(tempDest);
if(foundNTDLL)FreeLibrary((HMODULE)hdlNtCreateFile);





但是hdlNTOut是0.这里有通话结束后的汽车:



& fileObject 0x3d91cdcc  struct  _OBJECT_ATTRIBUTES fileObject {Length =  24  RootDirectory = 0x00000000 ObjectName = 0x3d91cdec ...} _OBJECT_ATTRIBUTES * 
长度 24 unsigned long
RootDirectory 0x00000000 void *
ObjectName 0x3d91cdec struct _UNICODE_STRING fn {Length = 60 MaximumLength = 62 Buffer = 0x41300098 \\?\ C:\ My path} _UNICODE_STRING *
长度 60 无符号
Maxi mumLength 62 无符号
缓冲区0x41300098 \\?\ C:\ My path wchar_t *
92 L ' \'wchar_t
属性64 unsigned long
SecurityDescriptor 0x00000000 void *
SecurityQualityOfService 0x00000000 void *
& hdlNTOut 0x00494320 void * hdlNTOut void * *
& ioStatus 0x3d91cbb0 struct _IO_STATUS_BLOCK ioStatus {Status = 0 Pointer = 0x00000000 Information = 0} _IO_STATUS_BLOCK *
Status 0 long
指针0x00000000 void *
信息0 unsigned long
foundNTDLL 0x776e00f4 _NtCreateFile @ 44 long(void * *,unsigned long,_ OBJECT_ATTRIBUTES *,_IO_STATUS_BLOCK *,_ LARGE_INTEGER *,unsigned long,unsigned long, unsigned long,unsigned long,void *,unsigned long)*
ntStatus -1073741773 long




路径末尾的反斜杠获得相同的输出。 ObjectName.Buffer中的L \是唯一看起来不正确的东西。所有这些都是在没有调用Initializeobjectattributes的情况下完成的,但还是错过了其他的东西?

感谢阅读。 :)

解决方案

问题是不完整的,因为它没有明确说明tempDest的初始化,尽管'\\?\ C:\ myPath'看起来在输出中没问题。

对于普通的CreateDirectoryW函数,填充tempDest的驱动常量有效:



 const wchar_t * driveIDBaseW = L\\\\?\\C:\\; 





但这会产生STATUS_OBJECT_NAME_INVALID错误。但是,用通配符的第二个反斜杠代替NtCreateFile:

 const wchar_t * driveIDBaseWNT = L\\ ?? \\C:\\ ; 



感谢指点,我已经学到了一点点,虽然在通过旧的OSR驱动程序线程进行研究之后有点cross cross。 :)


The aim is to create a directory. Here are the global decls:

typedef NTSTATUS (__stdcall *NTDLLptr)(
    PHANDLE FileHandle, 
    ACCESS_MASK DesiredAccess, 
    OBJECT_ATTRIBUTES *ObjectAttributes, 
    PIO_STATUS_BLOCK IoStatusBlock, 
    PLARGE_INTEGER AllocationSize,
    ULONG FileAttributes, 
    ULONG ShareAccess, 
    ULONG CreateDisposition, 
    ULONG CreateOptions, 
    PVOID EaBuffer, 
    ULONG EaLength );

typedef VOID (__stdcall *my_RtlInitUnicodeString) (
    IN OUT PUNICODE_STRING  DestinationString,
    IN PCWSTR  SourceString );
//static my_RtlInitUnicodeString rtlInitUnicodeString; //Update: Makes no difference here!


NTDLLptr foundNTDLL = NULL; //returns variable here
//RtlInitUnicodeStringPtr pRtlInitUnicodeString; //for NTcreatefile fileObject
UNICODE_STRING fn;
OBJECT_ATTRIBUTES fileObject;
IO_STATUS_BLOCK ioStatus;
NTSTATUS status;



The function call to load the libs:

NTDLLptr DynamicLoader (HWND hwnd,  bool progInit)
{
	HMODULE hdlNtCreateFile = LoadLibraryW(L"NtDll.dll");
	foundNTDLL = (NTDLLptr) GetProcAddress (hdlNtCreateFile, createFnString);
	if (foundNTDLL)
		{
			if (progInit)
			{
			memset(&ioStatus, 0, sizeof(ioStatus));
			memset(&fileObject, 0, sizeof(fileObject));
			fileObject.Length = sizeof(fileObject);
			fileObject.Attributes = OBJ_CASE_INSENSITIVE;
			}
			else
			{
			my_RtlInitUnicodeString RtlInitUnicodeString = (my_RtlInitUnicodeString) GetProcAddress(hdlNtCreateFile, initUnicodeFnString);
			RtlInitUnicodeString(&fn, tempDest);
			fileObject.ObjectName = &fn; //Ntdll.dll
			}
			return foundNTDLL;
		}
	else
		{
		FreeLibrary (hdlNtCreateFile);
		return foundNTDLL;
		}

}



The call is made at init:

if (!DynamicLoader (hwnd, true)) DisplayError (hwnd, L"The long path function has been removed. Using short path functions...", errorcode, 0);
...
if (foundNTDLL) FreeLibrary ((HMODULE)hdlNtCreateFile);
/pre>
"tempDest" is a calloc'd wchar_t containing the path name. The NTcreatefile call is made here:
<pre lang="c++">	if (DynamicLoader (hwnd,  false))
	{

	NTSTATUS ntStatus;
	ntStatus = foundNTDLL (&hdlNTOut, FILE_LIST_DIRECTORY | FILE_TRAVERSE, &fileObject, &ioStatus, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_DIRECTORY_FILE, NULL, 0);

	if (!NT_SUCCESS(ntStatus))
....
free(tempDest);
if (foundNTDLL) FreeLibrary ((HMODULE)hdlNtCreateFile);



But hdlNTOut is 0. Here are the autos just after the call:

&fileObject	0x3d91cdcc struct _OBJECT_ATTRIBUTES fileObject {Length=24 RootDirectory=0x00000000 ObjectName=0x3d91cdec ...}	_OBJECT_ATTRIBUTES *
Length	24	unsigned long
RootDirectory	0x00000000	void *
ObjectName	0x3d91cdec struct _UNICODE_STRING fn {Length=60 MaximumLength=62 Buffer=0x41300098 "\\?\C:\My path" }	_UNICODE_STRING *
Length	60	unsigned short
MaximumLength	62	unsigned short
Buffer	0x41300098 "\\?\C:\My path"	wchar_t *
92 L'\'	wchar_t
Attributes	64	unsigned long
SecurityDescriptor	0x00000000	void *
SecurityQualityOfService	0x00000000	void *
&hdlNTOut	0x00494320 void * hdlNTOut	void * *
&ioStatus	0x3d91cbb0 struct _IO_STATUS_BLOCK ioStatus {Status=0 Pointer=0x00000000 Information=0 }	_IO_STATUS_BLOCK *
Status	0	long
Pointer	0x00000000	void *
Information	0	unsigned long
foundNTDLL	0x776e00f4 _NtCreateFile@44	long (void * *, unsigned long, _OBJECT_ATTRIBUTES *, _IO_STATUS_BLOCK *, _LARGE_INTEGER *, unsigned long, unsigned long, unsigned long, unsigned long, void *, unsigned long)*
ntStatus	-1073741773	long



A backslash on the end of the path gets the same output. The "L\" in ObjectName.Buffer is the only thing that doesn't look right. All was done without calling Initializeobjectattributes, but was something else missed?
Thanks for reading. :)

解决方案

The question was incomplete as it didn't explicitly say what tempDest was initialise with, although the '\\?\C:\myPath' looks okay in the output.
For the ordinary CreateDirectoryW function the drive constant to populate tempDest worked:

const wchar_t *driveIDBaseW = L"\\\\?\\C:\\";



But this produced the STATUS_OBJECT_NAME_INVALID error. However the substituting the second backslash for the wildcard worked for NtCreateFile:

const wchar_t *driveIDBaseWNT = L"\\??\\C:\\";


Thanks for the pointers, I've learnt a fair bit, albeit a little cross-eyed after poring through the old OSR driver threads. :)


这篇关于NtCreateFile返回大目录的否定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆