-
-
[转帖]IoGetDeviceObjectPointer
-
发表于: 2010-9-28 16:56 4697
-
lkd> u IoGetDeviceObjectPointer l 100
nt!IoGetDeviceObjectPointer:
8056b782 8bff mov edi,edi
8056b784 55 push ebp
8056b785 8bec mov ebp,esp
8056b787 83ec20 sub esp,20h ;32字节空间
8056b78a 8b4508 mov eax,dword ptr [ebp+8] ;参数ObjectName
8056b78d 56 push esi
8056b78e 57 push edi
8056b78f 6a40 push 40h ;ZwOpenFile参数 OpenOptions
8056b791 33f6 xor esi,esi
8056b793 8945e8 mov dword ptr [ebp-18h],eax ;ObjectName
8056b796 56 push esi ;ZwOpenFile参数 ShareAccess
8056b797 8d45f8 lea eax,[ebp-8] ;ZwOpenFile参数 IoStatusBlock
8056b79a 50 push eax
8056b79b 8d45e0 lea eax,[ebp-20h] ;ZwOpenFile参数 ObjectAttributes
8056b79e 50 push eax
8056b79f ff750c push dword ptr [ebp+0Ch] ;ZwOpenFile参数 DesiredAccess
8056b7a2 8d4508 lea eax,[ebp+8]
8056b7a5 50 push eax ;ZwOpenFile参数 FileHandle
8056b7a6 c745e018000000 mov dword ptr [ebp-20h],18h ;_Length
8056b7ad 8975e4 mov dword ptr [ebp-1Ch],esi ;RootDirectory
8056b7b0 c745ec00020000 mov dword ptr [ebp-14h],200h ;Attributes
8056b7b7 8975f0 mov dword ptr [ebp-10h],esi ;SecurityDescriptor
8056b7ba 8975f4 mov dword ptr [ebp-0Ch],esi ;SecurityQualityOfService
8056b7bd e8de36f9ff call nt!ZwOpenFile (804feea0)
8056b7c2 8bf8 mov edi,eax
8056b7c4 3bfe cmp edi,esi ;判断返回值 STATUS_SUCCESS = 0
8056b7c6 7c36 jl nt!IoGetDeviceObjectPointer+0x7c (8056b7fe)
;调用ZwOpenFile成功后
8056b7c8 56 push esi ;HandleInformation
8056b7c9 8d450c lea eax,[ebp+0Ch]
8056b7cc 50 push eax ;Object
8056b7cd 56 push esi ;AccessMode
8056b7ce ff35d81d5580 push dword ptr [nt!IoFileObjectType (80551dd8)] ;ObjectType
8056b7d4 56 push esi ;DesiredAccess
8056b7d5 ff7508 push dword ptr [ebp+8] ; Handle
8056b7d8 e87f530400 call nt!ObReferenceObjectByHandle (805b0b5c)
8056b7dd 8bf8 mov edi,eax
8056b7df 3bfe cmp edi,esi
8056b7e1 7c13 jl nt!IoGetDeviceObjectPointer+0x74 (8056b7f6) ;ObReferenceObjectByHandle失败跳转
;ObReferenceObjectByHandle成功后
8056b7e3 8b450c mov eax,dword ptr [ebp+0Ch] ;object
8056b7e6 8b4d10 mov ecx,dword ptr [ebp+10h] ;FileObject
8056b7e9 50 push eax ;IoGetRelatedDeviceObject 参数 FileObject
8056b7ea 8901 mov dword ptr [ecx],eax ;函数出参数
8056b7ec e8a33ef8ff call nt!IoGetRelatedDeviceObject (804ef694)
8056b7f1 8b4d14 mov ecx,dword ptr [ebp+14h] ;取IoGetRelatedDeviceObject 参数DeviceObject
8056b7f4 8901 mov dword ptr [ecx],eax ;IoGetRelatedDeviceObject返回值保存
8056b7f6 ff7508 push dword ptr [ebp+8]
8056b7f9 e8862ff9ff call nt!ZwClose (804fe784)
8056b7fe 8bc7 mov eax,edi ;ZwOpenFile失败
8056b800 5f pop edi
8056b801 5e pop esi
8056b802 c9 leave
8056b803 c21000 ret 10h
由于汇编中可以直接用函数参数作为栈变量来进行读写,而C中不允许,因此我们自己额外定义几个栈变量。
逆向为c的代码:
NTSTATUS
IoGetDeviceObjectPointer(
IN PUNICODE_STRING ObjectName,
IN ACCESS_MASK DesiredAccess,
OUT PFILE_OBJECT *FileObject,
OUT PDEVICE_OBJECT *DeviceObject
)
{
IO_STATUS_BLOCK ioStatus;
OBJECT_ATTRIBUTES objectAttributes;
//额外定义出来的栈变量。由于C与汇编的游戏规则不同。
PFILE_OBJECT fileObject;
HANDLE fileHandle;
NTSTATUS status;
InitializeObjectAttributes( &objectAttributes,
ObjectName,
OBJ_KERNEL_HANDLE,
(HANDLE) NULL,
(PSECURITY_DESCRIPTOR) NULL );
status = ZwOpenFile( &fileHandle,
DesiredAccess,
&objectAttributes,
&ioStatus,
0,
0x40 );
if (status >= 0)
{
status = ObReferenceObjectByHandle( fileHandle,
0,
IoFileObjectType,
0,
(PVOID *) &fileObject,
0 );
if (status >= 0)
{
*FileObject = fileObject;
*DeviceObject = IoGetRelatedDeviceObject( fileObject );
}
ZwClose( fileHandle );
}
return status;
}
分析:
1。 IoGetDeviceObjectPointer函数中 ObReferenceObjectByHandle增加了其所对应的文件对象的引用,因此该函数调用后,调用ObDereferenceObject减小引用计数。
2。 IoGetDeviceObjectPointer函数中IoGetRelatedDeviceObject的调用是里面的重点。 看IoGetRelatedDeviceObject的说明,就能理解这个函数参数3,参数4的关系。
IoGetRelatedDeviceObject
Given a file object, the IoGetRelatedDeviceObject routine returns a pointer to the corresponding device object.
PDEVICE_OBJECT
IoGetRelatedDeviceObject(
IN PFILE_OBJECT FileObject
);
Parameters
FileObject
Pointer to the file object.
Return Value
IoGetRelatedDeviceObject returns a pointer to the device object.
Headers
Declared in wdm.h and ntddk.h. Include wdm.h or ntddk.h.
Comments
When called on a file object that represents the underlying storage device, IoGetRelatedDeviceObject returns the highest-level device object in the storage device stack. To obtain the highest-level device object in the file system driver stack, drivers must call IoGetRelatedDeviceObject on a file object that represents the file system's driver stack, and the file system must currently be mounted. (Otherwise, the storage device stack is traversed instead of the file system stack.)
To ensure that the file system is mounted on the storage device, the driver must have specified an appropriate access mask, such as FILE_READ_DATA or FILE_WRITE_ATTRIBUTES, when opening the file or device represented by the file object. Specifying FILE_READ_ATTRIBUTES does not cause the file system to be mounted.
The caller must be running at IRQL <= DISPATCH_LEVEL. Usually, callers of this routine are running at IRQL = PASSIVE_LEVEL.
nt!IoGetDeviceObjectPointer:
8056b782 8bff mov edi,edi
8056b784 55 push ebp
8056b785 8bec mov ebp,esp
8056b787 83ec20 sub esp,20h ;32字节空间
8056b78a 8b4508 mov eax,dword ptr [ebp+8] ;参数ObjectName
8056b78d 56 push esi
8056b78e 57 push edi
8056b78f 6a40 push 40h ;ZwOpenFile参数 OpenOptions
8056b791 33f6 xor esi,esi
8056b793 8945e8 mov dword ptr [ebp-18h],eax ;ObjectName
8056b796 56 push esi ;ZwOpenFile参数 ShareAccess
8056b797 8d45f8 lea eax,[ebp-8] ;ZwOpenFile参数 IoStatusBlock
8056b79a 50 push eax
8056b79b 8d45e0 lea eax,[ebp-20h] ;ZwOpenFile参数 ObjectAttributes
8056b79e 50 push eax
8056b79f ff750c push dword ptr [ebp+0Ch] ;ZwOpenFile参数 DesiredAccess
8056b7a2 8d4508 lea eax,[ebp+8]
8056b7a5 50 push eax ;ZwOpenFile参数 FileHandle
8056b7a6 c745e018000000 mov dword ptr [ebp-20h],18h ;_Length
8056b7ad 8975e4 mov dword ptr [ebp-1Ch],esi ;RootDirectory
8056b7b0 c745ec00020000 mov dword ptr [ebp-14h],200h ;Attributes
8056b7b7 8975f0 mov dword ptr [ebp-10h],esi ;SecurityDescriptor
8056b7ba 8975f4 mov dword ptr [ebp-0Ch],esi ;SecurityQualityOfService
8056b7bd e8de36f9ff call nt!ZwOpenFile (804feea0)
8056b7c2 8bf8 mov edi,eax
8056b7c4 3bfe cmp edi,esi ;判断返回值 STATUS_SUCCESS = 0
8056b7c6 7c36 jl nt!IoGetDeviceObjectPointer+0x7c (8056b7fe)
;调用ZwOpenFile成功后
8056b7c8 56 push esi ;HandleInformation
8056b7c9 8d450c lea eax,[ebp+0Ch]
8056b7cc 50 push eax ;Object
8056b7cd 56 push esi ;AccessMode
8056b7ce ff35d81d5580 push dword ptr [nt!IoFileObjectType (80551dd8)] ;ObjectType
8056b7d4 56 push esi ;DesiredAccess
8056b7d5 ff7508 push dword ptr [ebp+8] ; Handle
8056b7d8 e87f530400 call nt!ObReferenceObjectByHandle (805b0b5c)
8056b7dd 8bf8 mov edi,eax
8056b7df 3bfe cmp edi,esi
8056b7e1 7c13 jl nt!IoGetDeviceObjectPointer+0x74 (8056b7f6) ;ObReferenceObjectByHandle失败跳转
;ObReferenceObjectByHandle成功后
8056b7e3 8b450c mov eax,dword ptr [ebp+0Ch] ;object
8056b7e6 8b4d10 mov ecx,dword ptr [ebp+10h] ;FileObject
8056b7e9 50 push eax ;IoGetRelatedDeviceObject 参数 FileObject
8056b7ea 8901 mov dword ptr [ecx],eax ;函数出参数
8056b7ec e8a33ef8ff call nt!IoGetRelatedDeviceObject (804ef694)
8056b7f1 8b4d14 mov ecx,dword ptr [ebp+14h] ;取IoGetRelatedDeviceObject 参数DeviceObject
8056b7f4 8901 mov dword ptr [ecx],eax ;IoGetRelatedDeviceObject返回值保存
8056b7f6 ff7508 push dword ptr [ebp+8]
8056b7f9 e8862ff9ff call nt!ZwClose (804fe784)
8056b7fe 8bc7 mov eax,edi ;ZwOpenFile失败
8056b800 5f pop edi
8056b801 5e pop esi
8056b802 c9 leave
8056b803 c21000 ret 10h
由于汇编中可以直接用函数参数作为栈变量来进行读写,而C中不允许,因此我们自己额外定义几个栈变量。
逆向为c的代码:
NTSTATUS
IoGetDeviceObjectPointer(
IN PUNICODE_STRING ObjectName,
IN ACCESS_MASK DesiredAccess,
OUT PFILE_OBJECT *FileObject,
OUT PDEVICE_OBJECT *DeviceObject
)
{
IO_STATUS_BLOCK ioStatus;
OBJECT_ATTRIBUTES objectAttributes;
//额外定义出来的栈变量。由于C与汇编的游戏规则不同。
PFILE_OBJECT fileObject;
HANDLE fileHandle;
NTSTATUS status;
InitializeObjectAttributes( &objectAttributes,
ObjectName,
OBJ_KERNEL_HANDLE,
(HANDLE) NULL,
(PSECURITY_DESCRIPTOR) NULL );
status = ZwOpenFile( &fileHandle,
DesiredAccess,
&objectAttributes,
&ioStatus,
0,
0x40 );
if (status >= 0)
{
status = ObReferenceObjectByHandle( fileHandle,
0,
IoFileObjectType,
0,
(PVOID *) &fileObject,
0 );
if (status >= 0)
{
*FileObject = fileObject;
*DeviceObject = IoGetRelatedDeviceObject( fileObject );
}
ZwClose( fileHandle );
}
return status;
}
分析:
1。 IoGetDeviceObjectPointer函数中 ObReferenceObjectByHandle增加了其所对应的文件对象的引用,因此该函数调用后,调用ObDereferenceObject减小引用计数。
2。 IoGetDeviceObjectPointer函数中IoGetRelatedDeviceObject的调用是里面的重点。 看IoGetRelatedDeviceObject的说明,就能理解这个函数参数3,参数4的关系。
IoGetRelatedDeviceObject
Given a file object, the IoGetRelatedDeviceObject routine returns a pointer to the corresponding device object.
PDEVICE_OBJECT
IoGetRelatedDeviceObject(
IN PFILE_OBJECT FileObject
);
Parameters
FileObject
Pointer to the file object.
Return Value
IoGetRelatedDeviceObject returns a pointer to the device object.
Headers
Declared in wdm.h and ntddk.h. Include wdm.h or ntddk.h.
Comments
When called on a file object that represents the underlying storage device, IoGetRelatedDeviceObject returns the highest-level device object in the storage device stack. To obtain the highest-level device object in the file system driver stack, drivers must call IoGetRelatedDeviceObject on a file object that represents the file system's driver stack, and the file system must currently be mounted. (Otherwise, the storage device stack is traversed instead of the file system stack.)
To ensure that the file system is mounted on the storage device, the driver must have specified an appropriate access mask, such as FILE_READ_DATA or FILE_WRITE_ATTRIBUTES, when opening the file or device represented by the file object. Specifying FILE_READ_ATTRIBUTES does not cause the file system to be mounted.
The caller must be running at IRQL <= DISPATCH_LEVEL. Usually, callers of this routine are running at IRQL = PASSIVE_LEVEL.
赞赏
看原图
赞赏
雪币:
留言: