七猫的藏经阁

其实只是垃圾箱

VC知识库BLOG 首页 新随笔 联系 聚合 登录
  195 Posts :: 0 Stories :: 640 Comments :: 5 Trackbacks

公告

其实我们每个人都是井底之蛙,最多在不同的井而已。

留言簿(3)

随笔分类

随笔档案

文章分类

文章档案

相册

收藏夹

好友

搜索

最新评论

阅读排行榜

评论排行榜

#ifndef _OB_
#define _OB_

//
// System Initialization procedure for OB subcomponent of NTOS
//
BOOLEAN
ObInitSystem( VOID );


NTSTATUS
ObInitProcess(
    PEPROCESS ParentProcess OPTIONAL,
    PEPROCESS NewProcess
    );

VOID
ObInitProcess2(
    PEPROCESS NewProcess
    );

VOID
ObKillProcess(
    BOOLEAN AcquireLock,
    PEPROCESS Process
    );

// begin_ntddk begin_wdm begin_nthal begin_ntifs
//
// Object Manager types
//

typedef struct _OBJECT_HANDLE_INFORMATION {
    ULONG HandleAttributes;
    ACCESS_MASK GrantedAccess;
} OBJECT_HANDLE_INFORMATION, *POBJECT_HANDLE_INFORMATION;

// end_ntddk end_wdm end_nthal end_ntifs

typedef struct _OBJECT_DUMP_CONTROL {
    PVOID Stream;
    ULONG Detail;
} OB_DUMP_CONTROL, *POB_DUMP_CONTROL;

typedef VOID (*OB_DUMP_METHOD)(
    IN PVOID Object,
    IN POB_DUMP_CONTROL Control OPTIONAL
    );

typedef enum _OB_OPEN_REASON {
    ObCreateHandle,
    ObOpenHandle,
    ObDuplicateHandle,
    ObInheritHandle,
    ObMaxOpenReason
} OB_OPEN_REASON;


typedef VOID (*OB_OPEN_METHOD)(
    IN OB_OPEN_REASON OpenReason,
    IN PEPROCESS Process OPTIONAL,
    IN PVOID Object,
    IN ACCESS_MASK GrantedAccess,
    IN ULONG HandleCount
    );

typedef BOOLEAN (*OB_OKAYTOCLOSE_METHOD)(
    IN PEPROCESS Process OPTIONAL,
    IN PVOID Object,
    IN HANDLE Handle
    );

typedef VOID (*OB_CLOSE_METHOD)(
    IN PEPROCESS Process OPTIONAL,
    IN PVOID Object,
    IN ACCESS_MASK GrantedAccess,
    IN ULONG ProcessHandleCount,
    IN ULONG SystemHandleCount
    );

typedef VOID (*OB_DELETE_METHOD)(
    IN PVOID Object
    );

typedef NTSTATUS (*OB_PARSE_METHOD)(
    IN PVOID ParseObject,
    IN PVOID ObjectType,
    IN OUT PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE AccessMode,
    IN ULONG Attributes,
    IN OUT PUNICODE_STRING CompleteName,
    IN OUT PUNICODE_STRING RemainingName,
    IN OUT PVOID Context OPTIONAL,
    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
    OUT PVOID *Object
    );

typedef NTSTATUS (*OB_SECURITY_METHOD)(
    IN PVOID Object,
    IN SECURITY_OPERATION_CODE OperationCode,
    IN PSECURITY_INFORMATION SecurityInformation,
    IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
    IN OUT PULONG CapturedLength,
    IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
    IN POOL_TYPE PoolType,
    IN PGENERIC_MAPPING GenericMapping
    );

typedef NTSTATUS (*OB_QUERYNAME_METHOD)(
    IN PVOID Object,
    IN BOOLEAN HasObjectName,
    OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
    IN ULONG Length,
    OUT PULONG ReturnLength
    );

/*

    A security method and its caller must obey the following w.r.t.
    capturing and probing parameters:

    For a query operation, the caller must pass a kernel space address for
    CapturedLength.  The caller should be able to assume that it points to
    valid data that will not change.  In addition, the SecurityDescriptor
    parameter (which will receive the result of the query operation) must
    be probed for write up to the length given in CapturedLength.  The
    security method itself must always write to the SecurityDescriptor
    buffer in a try clause in case the caller de-allocates it.

    For a set operation, the SecurityDescriptor parameter must have
    been captured via SeCaptureSecurityDescriptor.  This parameter is
    not optional, and therefore may not be NULL.

*/


//
// Object Type Structure
//

typedef struct _OBJECT_TYPE_INITIALIZER {
    USHORT Length;
    BOOLEAN UseDefaultObject;
    BOOLEAN Reserved;
    ULONG InvalidAttributes;
    GENERIC_MAPPING GenericMapping;
    ULONG ValidAccessMask;
    BOOLEAN SecurityRequired;
    BOOLEAN MaintainHandleCount;
    BOOLEAN MaintainTypeList;
    POOL_TYPE PoolType;
    ULONG DefaultPagedPoolCharge;
    ULONG DefaultNonPagedPoolCharge;
    OB_DUMP_METHOD DumpProcedure;
    OB_OPEN_METHOD OpenProcedure;
    OB_CLOSE_METHOD CloseProcedure;
    OB_DELETE_METHOD DeleteProcedure;
    OB_PARSE_METHOD ParseProcedure;
    OB_SECURITY_METHOD SecurityProcedure;
    OB_QUERYNAME_METHOD QueryNameProcedure;
    OB_OKAYTOCLOSE_METHOD OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;

typedef struct _OBJECT_TYPE {
    ERESOURCE Mutex;
    LIST_ENTRY TypeList;
    UNICODE_STRING Name;            // Copy from object header for convenience
    PVOID DefaultObject;
    ULONG Index;
    ULONG TotalNumberOfObjects;
    ULONG TotalNumberOfHandles;
    ULONG HighWaterNumberOfObjects;
    ULONG HighWaterNumberOfHandles;
    OBJECT_TYPE_INITIALIZER TypeInfo;
#ifdef POOL_TAGGING
    ULONG Key;
#endif //POOL_TAGGING
} OBJECT_TYPE, *POBJECT_TYPE;

//
// Object Directory Structure
//

#define NUMBER_HASH_BUCKETS 37

typedef struct _OBJECT_DIRECTORY {
    struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[ NUMBER_HASH_BUCKETS ];
    struct _OBJECT_DIRECTORY_ENTRY **LookupBucket;
    BOOLEAN LookupFound;
    USHORT SymbolicLinkUsageCount;
    struct _DEVICE_MAP *DeviceMap;
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;

//
// Object Directory Entry Structure
//
typedef struct _OBJECT_DIRECTORY_ENTRY {
    struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
    PVOID Object;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;


//
// Symbolic Link Object Structure
//

typedef struct _OBJECT_SYMBOLIC_LINK {
    LARGE_INTEGER CreationTime;
    UNICODE_STRING LinkTarget;
    UNICODE_STRING LinkTargetRemaining;
    PVOID LinkTargetObject;
    ULONG DosDeviceDriveIndex;  // 1-based index into KUSER_SHARED_DATA.DosDeviceDriveType
} OBJECT_SYMBOLIC_LINK, *POBJECT_SYMBOLIC_LINK;


//
// Device Map Structure
//

typedef struct _DEVICE_MAP {
    ULONG ReferenceCount;
    POBJECT_DIRECTORY DosDevicesDirectory;
    ULONG DriveMap;
    UCHAR DriveType[ 32 ];
} DEVICE_MAP, *PDEVICE_MAP;

extern PDEVICE_MAP ObSystemDeviceMap;

//
// Object Handle Count Database
//

typedef struct _OBJECT_HANDLE_COUNT_ENTRY {
    PEPROCESS Process;
    ULONG HandleCount;
} OBJECT_HANDLE_COUNT_ENTRY, *POBJECT_HANDLE_COUNT_ENTRY;

typedef struct _OBJECT_HANDLE_COUNT_DATABASE {
    ULONG CountEntries;
    OBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[ 1 ];
} OBJECT_HANDLE_COUNT_DATABASE, *POBJECT_HANDLE_COUNT_DATABASE;

//
// Object Header Structure
//
// The SecurityQuotaCharged is the amount of quota charged to cover
// the GROUP and DISCRETIONARY ACL fields of the security descriptor
// only.  The OWNER and SYSTEM ACL fields get charged for at a fixed
// rate that may be less than or greater than the amount actually used.
//
// If the object has no security, then the SecurityQuotaCharged and the
// SecurityQuotaInUse fields are set to zero.
//
// Modification of the OWNER and SYSTEM ACL fields should never fail
// due to quota exceeded problems.  Modifications to the GROUP and
// DISCRETIONARY ACL fields may fail due to quota exceeded problems.
//
//


typedef struct _OBJECT_CREATE_INFORMATION {
    ULONG Attributes;
    HANDLE RootDirectory;
    PVOID ParseContext;
    KPROCESSOR_MODE ProbeMode;
    ULONG PagedPoolCharge;
    ULONG NonPagedPoolCharge;
    ULONG SecurityDescriptorCharge;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    PSECURITY_QUALITY_OF_SERVICE SecurityQos;
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;

typedef struct _OBJECT_HEADER {
    LONG PointerCount;
    union {
        LONG HandleCount;
        PSINGLE_LIST_ENTRY SEntry;
    };
    POBJECT_TYPE Type;
    UCHAR NameInfoOffset;
    UCHAR HandleInfoOffset;
    UCHAR QuotaInfoOffset;
    UCHAR Flags;
    union {
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
        PVOID QuotaBlockCharged;
    };

    PSECURITY_DESCRIPTOR SecurityDescriptor;
    QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER;

typedef struct _OBJECT_HEADER_QUOTA_INFO {
    ULONG PagedPoolCharge;
    ULONG NonPagedPoolCharge;
    ULONG SecurityDescriptorCharge;
    PEPROCESS ExclusiveProcess;
} OBJECT_HEADER_QUOTA_INFO, *POBJECT_HEADER_QUOTA_INFO;

typedef struct _OBJECT_HEADER_HANDLE_INFO {
    union {
        POBJECT_HANDLE_COUNT_DATABASE HandleCountDataBase;
        OBJECT_HANDLE_COUNT_ENTRY SingleEntry;
    };
} OBJECT_HEADER_HANDLE_INFO, *POBJECT_HEADER_HANDLE_INFO;

typedef struct _OBJECT_HEADER_NAME_INFO {
    POBJECT_DIRECTORY Directory;
    UNICODE_STRING Name;
    ULONG Reserved;
#if DBG
    ULONG Reserved2 ;
    LONG DbgDereferenceCount ;
#endif
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;

typedef struct _OBJECT_HEADER_CREATOR_INFO {
    LIST_ENTRY TypeList;
    HANDLE CreatorUniqueProcess;
    USHORT CreatorBackTraceIndex;
    USHORT Reserved;
} OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;

#define OB_FLAG_NEW_OBJECT              0x01
#define OB_FLAG_KERNEL_OBJECT           0x02
#define OB_FLAG_CREATOR_INFO            0x04
#define OB_FLAG_EXCLUSIVE_OBJECT        0x08
#define OB_FLAG_PERMANENT_OBJECT        0x10
#define OB_FLAG_DEFAULT_SECURITY_QUOTA  0x20
#define OB_FLAG_SINGLE_HANDLE_ENTRY     0x40

#define OBJECT_TO_OBJECT_HEADER( o ) \
    CONTAINING_RECORD( (o), OBJECT_HEADER, Body )

#define OBJECT_HEADER_TO_EXCLUSIVE_PROCESS( oh ) ((oh->Flags & OB_FLAG_EXCLUSIVE_OBJECT) == 0 ? \
    NULL : (((POBJECT_HEADER_QUOTA_INFO)((PCHAR)(oh) - (oh)->QuotaInfoOffset))->ExclusiveProcess))


#define OBJECT_HEADER_TO_QUOTA_INFO( oh ) ((POBJECT_HEADER_QUOTA_INFO) \
    ((oh)->QuotaInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->QuotaInfoOffset)))

#define OBJECT_HEADER_TO_HANDLE_INFO( oh ) ((POBJECT_HEADER_HANDLE_INFO) \
    ((oh)->HandleInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->HandleInfoOffset)))

#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
    ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))

#define OBJECT_HEADER_TO_CREATOR_INFO( oh ) ((POBJECT_HEADER_CREATOR_INFO) \
    (((oh)->Flags & OB_FLAG_CREATOR_INFO) == 0 ? NULL : ((PCHAR)(oh) - sizeof(OBJECT_HEADER_CREATOR_INFO))))


NTKERNELAPI
NTSTATUS
ObCreateObjectType(
    IN PUNICODE_STRING TypeName,
    IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
    IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
    OUT POBJECT_TYPE *ObjectType
    );

VOID
FASTCALL
ObFreeObjectCreateInfoBuffer(
    IN POBJECT_CREATE_INFORMATION ObjectCreateInfo
    );

// begin_nthal

NTKERNELAPI
VOID
ObDeleteCapturedInsertInfo(
    IN PVOID Object
    );

NTKERNELAPI
NTSTATUS
ObCreateObject(
    IN KPROCESSOR_MODE ProbeMode,
    IN POBJECT_TYPE ObjectType,
    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    IN KPROCESSOR_MODE OwnershipMode,
    IN OUT PVOID ParseContext OPTIONAL,
    IN ULONG ObjectBodySize,
    IN ULONG PagedPoolCharge,
    IN ULONG NonPagedPoolCharge,
    OUT PVOID *Object
    );


NTKERNELAPI
NTSTATUS
ObInsertObject(
    IN PVOID Object,
    IN PACCESS_STATE PassedAccessState OPTIONAL,
    IN ACCESS_MASK DesiredAccess OPTIONAL,
    IN ULONG ObjectPointerBias,
    OUT PVOID *NewObject OPTIONAL,
    OUT PHANDLE Handle
    );

// end_nthal

NTKERNELAPI                                                     // ntddk wdm nthal ntifs
NTSTATUS                                                        // ntddk wdm nthal ntifs
ObReferenceObjectByHandle(                                      // ntddk wdm nthal ntifs
    IN HANDLE Handle,                                           // ntddk wdm nthal ntifs
    IN ACCESS_MASK DesiredAccess,                               // ntddk wdm nthal ntifs
    IN POBJECT_TYPE ObjectType OPTIONAL,                        // ntddk wdm nthal ntifs
    IN KPROCESSOR_MODE AccessMode,                              // ntddk wdm nthal ntifs
    OUT PVOID *Object,                                          // ntddk wdm nthal ntifs
    OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL   // ntddk wdm nthal ntifs
    );                                                          // ntddk wdm nthal ntifs


NTKERNELAPI
NTSTATUS
ObOpenObjectByName(
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN POBJECT_TYPE ObjectType,
    IN KPROCESSOR_MODE AccessMode,
    IN OUT PACCESS_STATE PassedAccessState OPTIONAL,
    IN ACCESS_MASK DesiredAccess OPTIONAL,
    IN OUT PVOID ParseContext OPTIONAL,
    OUT PHANDLE Handle
    );


NTKERNELAPI                                                     // ntifs
NTSTATUS                                                        // ntifs
ObOpenObjectByPointer(                                          // ntifs
    IN PVOID Object,                                            // ntifs
    IN ULONG HandleAttributes,                                  // ntifs
    IN PACCESS_STATE PassedAccessState OPTIONAL,                // ntifs
    IN ACCESS_MASK DesiredAccess OPTIONAL,                      // ntifs
    IN POBJECT_TYPE ObjectType OPTIONAL,                        // ntifs
    IN KPROCESSOR_MODE AccessMode,                              // ntifs
    OUT PHANDLE Handle                                          // ntifs
    );                                                          // ntifs

NTSTATUS
ObReferenceObjectByName(
    IN PUNICODE_STRING ObjectName,
    IN ULONG Attributes,
    IN PACCESS_STATE PassedAccessState OPTIONAL,
    IN ACCESS_MASK DesiredAccess OPTIONAL,
    IN POBJECT_TYPE ObjectType,
    IN KPROCESSOR_MODE AccessMode,
    IN OUT PVOID ParseContext OPTIONAL,
    OUT PVOID *Object
    );

NTKERNELAPI                                                     // ntifs
VOID                                                            // ntifs
ObMakeTemporaryObject(                                          // ntifs
    IN PVOID Object                                             // ntifs
    );                                                          // ntifs


NTKERNELAPI
BOOLEAN
ObFindHandleForObject(
    IN PEPROCESS Process,
    IN PVOID Object,
    IN POBJECT_TYPE ObjectType OPTIONAL,
    IN POBJECT_HANDLE_INFORMATION MatchCriteria OPTIONAL,
    OUT PHANDLE Handle
    );

// begin_ntddk begin_wdm begin_nthal begin_ntifs

#define ObDereferenceObject(a)                                     \
        ObfDereferenceObject(a)

//  end_wdm end_ntddk end_nthal end_ntifs

#if defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTSRV_) || defined(_NTHAL_)

//  begin_wdm begin_ntddk begin_nthal begin_ntifs
#define ObReferenceObject(Object) ObfReferenceObject(Object)

NTKERNELAPI
VOID
FASTCALL
ObfReferenceObject(
    IN PVOID Object
    );

//  end_wdm end_ntddk end_nthal end_ntifs
#else

#define ObReferenceObject(Object) {                                \
    POBJECT_HEADER ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); \
    InterlockedIncrement(&ObjectHeader->PointerCount);             \
}

#endif

//  begin_wdm begin_ntddk begin_nthal begin_ntifs

NTKERNELAPI
NTSTATUS
ObReferenceObjectByPointer(
    IN PVOID Object,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_TYPE ObjectType,
    IN KPROCESSOR_MODE AccessMode
    );

NTKERNELAPI
VOID
FASTCALL
ObfDereferenceObject(
    IN PVOID Object
    );

// end_ntddk end_wdm end_nthal end_ntifs

NTSTATUS
ObWaitForSingleObject(
    IN HANDLE Handle,
    IN BOOLEAN Alertable,
    IN PLARGE_INTEGER Timeout OPTIONAL
    );

NTKERNELAPI                                                     // ntifs
NTSTATUS                                                        // ntifs
ObQueryNameString(                                              // ntifs
    IN PVOID Object,                                            // ntifs
    OUT POBJECT_NAME_INFORMATION ObjectNameInfo,                // ntifs
    IN ULONG Length,                                            // ntifs
    OUT PULONG ReturnLength                                     // ntifs
    );                                                          // ntifs
                                                                // ntifs
NTKERNELAPI                                                     // ntifs
ULONG                                                           // ntifs
ObGetObjectPointerCount(                                        // ntifs
    IN PVOID Object                                             // ntifs
    );                                                          // ntifs

#if DBG
PUNICODE_STRING
ObGetObjectName(
    IN PVOID Object
    );
#endif // DBG

NTSTATUS
ObQueryTypeName(
    IN PVOID Object,
    PUNICODE_STRING ObjectTypeName,
    IN ULONG Length,
    OUT PULONG ReturnLength
    );

NTSTATUS
ObQueryTypeInfo(
    IN POBJECT_TYPE ObjectType,
    OUT POBJECT_TYPE_INFORMATION ObjectTypeInfo,
    IN ULONG Length,
    OUT PULONG ReturnLength
    );

NTSTATUS
ObDumpObjectByHandle(
    IN HANDLE Handle,
    IN POB_DUMP_CONTROL Control OPTIONAL
    );


NTSTATUS
ObDumpObjectByPointer(
    IN PVOID Object,
    IN POB_DUMP_CONTROL Control OPTIONAL
    );

NTSTATUS
ObSetDeviceMap(
    IN PEPROCESS TargetProcess,
    IN HANDLE DirectoryHandle
    );

NTSTATUS
ObQueryDeviceMapInformation(
    IN PEPROCESS TargetProcess,
    OUT PPROCESS_DEVICEMAP_INFORMATION DeviceMapInformation
    );

VOID
ObInheritDeviceMap(
    IN PEPROCESS NewProcess,
    IN PEPROCESS ParentProcess
    );

VOID
ObDereferenceDeviceMap(
    IN PEPROCESS Process
    );

// begin_ntsrv begin_ntddk
NTSTATUS
ObGetObjectSecurity(
    IN PVOID Object,
    OUT PSECURITY_DESCRIPTOR *SecurityDescriptor,
    OUT PBOOLEAN MemoryAllocated
    );

VOID
ObReleaseObjectSecurity(
    IN PSECURITY_DESCRIPTOR SecurityDescriptor,
    IN BOOLEAN MemoryAllocated
    );
// end_ntsrv end_ntddk

NTSTATUS
ObAssignObjectSecurityDescriptor(
    IN PVOID Object,
    IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL,
    IN POOL_TYPE PoolType
    );

NTSTATUS
ObValidateSecurityQuota(
    IN PVOID Object,
    IN ULONG NewSize
    );

NTKERNELAPI
BOOLEAN
ObCheckCreateObjectAccess(
    IN PVOID DirectoryObject,
    IN ACCESS_MASK CreateAccess,
    IN PACCESS_STATE AccessState OPTIONAL,
    IN PUNICODE_STRING ComponentName,
    IN BOOLEAN TypeMutexLocked,
    IN KPROCESSOR_MODE PreviousMode,
    OUT PNTSTATUS AccessStatus
   );

NTKERNELAPI
BOOLEAN
ObCheckObjectAccess(
    IN PVOID Object,
    IN PACCESS_STATE AccessState,
    IN BOOLEAN TypeMutexLocked,
    IN KPROCESSOR_MODE AccessMode,
    OUT PNTSTATUS AccessStatus
    );


NTKERNELAPI
NTSTATUS
ObAssignSecurity(
    IN PACCESS_STATE AccessState,
    IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
    IN PVOID Object,
    IN POBJECT_TYPE ObjectType
    );

NTSTATUS                                                        // ntifs
ObQueryObjectAuditingByHandle(                                  // ntifs
    IN HANDLE Handle,                                           // ntifs
    OUT PBOOLEAN GenerateOnClose                                // ntifs
    );                                                          // ntifs

NTSTATUS
ObSetSecurityObjectByPointer (
    IN PVOID Object,
    IN SECURITY_INFORMATION SecurityInformation,
    IN PSECURITY_DESCRIPTOR SecurityDescriptor
    );

#if DEVL

typedef BOOLEAN (*OB_ENUM_OBJECT_TYPE_ROUTINE)(
    IN PVOID Object,
    IN PUNICODE_STRING ObjectName,
    IN ULONG HandleCount,
    IN ULONG PointerCount,
    IN PVOID Parameter
    );

NTSTATUS
ObEnumerateObjectsByType(
    IN POBJECT_TYPE ObjectType,
    IN OB_ENUM_OBJECT_TYPE_ROUTINE EnumerationRoutine,
    IN PVOID Parameter
    );

NTSTATUS
ObGetHandleInformation(
    OUT PSYSTEM_HANDLE_INFORMATION HandleInformation,
    IN ULONG Length,
    OUT PULONG ReturnLength OPTIONAL
    );

NTSTATUS
ObGetObjectInformation(
    IN PCHAR UserModeBufferAddress,
    OUT PSYSTEM_OBJECTTYPE_INFORMATION ObjectInformation,
    IN ULONG Length,
    OUT PULONG ReturnLength OPTIONAL
    );

NTKERNELAPI
NTSTATUS
ObSetSecurityDescriptorInfo(
    IN PVOID Object,
    IN PSECURITY_INFORMATION SecurityInformation,
    IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
    IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
    IN POOL_TYPE PoolType,
    IN PGENERIC_MAPPING GenericMapping
    );

NTKERNELAPI
NTSTATUS
ObQuerySecurityDescriptorInfo(
    IN PSECURITY_INFORMATION SecurityInformation,
    OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
    IN OUT PULONG Length,
    IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor
    );

NTSTATUS
ObDeassignSecurity (
    IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor
    );

posted on 2005-03-14 10:36 七猫到此一游 阅读(4383) 评论(7)  编辑 收藏

Feedback

# ObReferenceObjectByHandle 2005-03-14 10:37 七猫的垃圾箱
NTSTATUS
ObReferenceObjectByHandle (
IN HANDLE Handle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
OUT PVOID *Object,
OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL
)

/*++

Routine Description:

Given a handle to an object this routine returns a pointer
to the body of the object with proper ref counts

Arguments:

Handle - Supplies a handle to the object being referenced. It can
also be the result of NtCurrentProcess or NtCurrentThread

DesiredAccess - Supplies the access being requested by the caller

ObjectType - Optionally supplies the type of the object we
are expecting

AccessMode - Supplies the processor mode of the access

Object - Receives a pointer to the object body if the operation
is successful

HandleInformation - Optionally receives information regarding the
input handle.

Return Value:

An appropriate NTSTATUS value

--*/

{
ACCESS_MASK GrantedAccess;
PHANDLE_TABLE HandleTable;
POBJECT_HEADER ObjectHeader;
PHANDLE_TABLE_ENTRY ObjectTableEntry;
PEPROCESS Process;
NTSTATUS Status;
PETHREAD Thread;
BOOLEAN AttachedToProcess = FALSE;

ObpValidateIrql("ObReferenceObjectByHandle");

//
// Protect ourselves from being interrupted while we hold a handle table
// entry lock
//

KeEnterCriticalRegion();

try {

//
// If the handle is equal to the current process handle and the object
// type is NULL or type process, then attempt to translate a handle to
// the current process. Otherwise, check if the handle is the current
// thread handle.
//

if (Handle == NtCurrentProcess()) {

if ((ObjectType == PsProcessType) || (ObjectType == NULL)) {

Process = PsGetCurrentProcess();
GrantedAccess = Process->GrantedAccess;

if ((SeComputeDeniedAccesses(GrantedAccess, DesiredAccess) == 0) ||
(AccessMode == KernelMode)) {

ObjectHeader = OBJECT_TO_OBJECT_HEADER(Process);

if (ARGUMENT_PRESENT(HandleInformation)) {

HandleInformation->GrantedAccess = GrantedAccess;
HandleInformation->HandleAttributes = 0;
}

ObpIncrPointerCount(ObjectHeader);
*Object = Process;

ASSERT( *Object != NULL );

Status = STATUS_SUCCESS;
leave;

} else {

Status = STATUS_ACCESS_DENIED;
}

} else {

Status = STATUS_OBJECT_TYPE_MISMATCH;
}

//
// If the handle is equal to the current thread handle and the object
// type is NULL or type thread, then attempt to translate a handle to
// the current thread. Otherwise, the we'll try and translate the
// handle
//

} else if (Handle == NtCurrentThread()) {

if ((ObjectType == PsThreadType) || (ObjectType == NULL)) {

Thread = PsGetCurrentThread();
GrantedAccess = Thread->GrantedAccess;

if ((SeComputeDeniedAccesses(GrantedAccess, DesiredAccess) == 0) ||
(AccessMode == KernelMode)) {

ObjectHeader = OBJECT_TO_OBJECT_HEADER(Thread);

if (ARGUMENT_PRESENT(HandleInformation)) {

HandleInformation->GrantedAccess = GrantedAccess;
HandleInformation->HandleAttributes = 0;
}

ObpIncrPointerCount(ObjectHeader);
*Object = Thread;

ASSERT( *Object != NULL );

Status = STATUS_SUCCESS;
leave;

} else {

Status = STATUS_ACCESS_DENIED;
}

} else {

Status = STATUS_OBJECT_TYPE_MISMATCH;
}

//
// Otherwise the handle is not a built in value. It must be an index
// into a handle table.
//

} else {

#if DBG
//
// On checked builds, check that if the Kernel handle bit is set,
// then we're coming from Kernel mode. We should probably fail the
// call if bit set && !Kmode
//
// We know we're NOT a builtin handle at this point
//

ASSERT((Handle < 0) ? (AccessMode == KernelMode) : TRUE);
#endif

//
// First get a pointer to either the processes handle table or the
// global kernel handle table. If it is the kernel handle then we
// need to clear the handle bit and attach to the system process
//

if (IsKernelHandle( Handle, AccessMode )) {

//
// Make the handle look like a regular handle
//

Handle = DecodeKernelHandle( Handle );

//
// The global kernel handle table
//

HandleTable = ObpKernelHandleTable;

} else {

HandleTable = ObpGetObjectTable();
}

ASSERT(HandleTable != NULL);

//
// Translate the specified handle to an object table index.
//

ObjectTableEntry = ExMapHandleToPointer( HandleTable, Handle );

//
// Make sure the object table entry really does exist
//

if (ObjectTableEntry != NULL) {

ObjectHeader = (POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->Object)) & ~OBJ_HANDLE_ATTRIBUTES);

if ((ObjectHeader->Type == ObjectType) || (ObjectType == NULL)) {

#if i386 && !FPO
if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {

if ((AccessMode != KernelMode) || ARGUMENT_PRESENT(HandleInformation)) {

GrantedAccess = ObpTranslateGrantedAccessIndex( ObjectTableEntry->GrantedAccessIndex );
}

} else {

GrantedAccess = ObjectTableEntry->GrantedAccess;
}
#else
GrantedAccess = ObjectTableEntry->GrantedAccess;

#endif // i386 && !FPO

if ((SeComputeDeniedAccesses(GrantedAccess, DesiredAccess) == 0) ||
(AccessMode == KernelMode)) {

//
// Access to the object is allowed. Return the handle
// information is requested, increment the object
// pointer count, unlock the handle table and return
// a success status.
//
// Note that this is the only successful return path
// out of this routine if the user did not specify
// the current process or current thread in the input
// handle.
//

if (ARGUMENT_PRESENT(HandleInformation)) {

HandleInformation->GrantedAccess = GrantedAccess;
HandleInformation->HandleAttributes = ObjectTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
}

ObpIncrPointerCount(ObjectHeader);
*Object = &ObjectHeader->Body;

ASSERT( *Object != NULL );

ExUnlockHandleTableEntry( HandleTable, ObjectTableEntry );

Status = STATUS_SUCCESS;
leave;

} else {

Status = STATUS_ACCESS_DENIED;
}

} else {

Status = STATUS_OBJECT_TYPE_MISMATCH;
}

ExUnlockHandleTableEntry( HandleTable, ObjectTableEntry );

} else {

Status = STATUS_INVALID_HANDLE;
}
}

//
// If we are attached to the system process then return
// back to our caller
//

if (AttachedToProcess) {

KeDetachProcess();
}

//
// No handle translation is possible. Set the object address to NULL
// and return an error status.
//

*Object = NULL;

} finally {

KeLeaveCriticalRegion();
}

return Status;
}

# ObReferenceObjectByName 2005-03-14 10:38 七猫的垃圾箱
NTSTATUS
ObReferenceObjectByName (
IN PUNICODE_STRING ObjectName,
IN ULONG Attributes,
IN PACCESS_STATE AccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *Object
)

/*++

Routine Description:

Given a name of an object this routine returns a pointer
to the body of the object with proper ref counts

Arguments:

ObjectName - Supplies the name of the object being referenced

Attributes - Supplies the desired handle attributes

AccessState - Supplies an optional pointer to the current access
status describing already granted access types, the privileges used
to get them, and any access types yet to be granted.

DesiredAccess - Optionally supplies the desired access to the
for the object

ObjectType - Specifies the object type according to the caller

AccessMode - Supplies the processor mode of the access

ParseContext - Optionally supplies a context to pass down to the
parse routine

Object - Receives a pointer to the referenced object body

Return Value:

An appropriate NTSTATUS value

--*/

{
UNICODE_STRING CapturedObjectName;
BOOLEAN DirectoryLocked;
PVOID ExistingObject;
ACCESS_STATE LocalAccessState;
AUX_ACCESS_DATA AuxData;
NTSTATUS Status;

PAGED_CODE();

ObpValidateIrql("ObReferenceObjectByName");

//
// If the object name descriptor is not specified, or the object name
// length is zero (tested after capture), then the object name is
// invalid.
//

if (ObjectName == NULL) {

return STATUS_OBJECT_NAME_INVALID;
}

//
// Capture the object name.
//

Status = ObpCaptureObjectName( AccessMode,
ObjectName,
&CapturedObjectName,
TRUE );

if (NT_SUCCESS(Status)) {

//
// No buffer has been allocated for a zero length name so no free
// needed
//

if (CapturedObjectName.Length == 0) {

return STATUS_OBJECT_NAME_INVALID;
}

//
// If the access state is not specified, then create the access
// state.
//

if (!ARGUMENT_PRESENT(AccessState)) {

AccessState = &LocalAccessState;

Status = SeCreateAccessState( &LocalAccessState,
&AuxData,
DesiredAccess,
&ObjectType->TypeInfo.GenericMapping );

if (!NT_SUCCESS(Status)) {

goto FreeBuffer;
}
}

//
// Lookup object by name.
//

Status = ObpLookupObjectName( NULL,
&CapturedObjectName,
Attributes,
ObjectType,
AccessMode,
ParseContext,
NULL,
NULL,
AccessState,
&DirectoryLocked,
&ExistingObject );

//
// If the directory is returned locked, then unlock it.
//

if (DirectoryLocked) {

ObpLeaveRootDirectoryMutex();
}

//
// If the lookup was successful, then return the existing
// object if access is allowed. Otherwise, return NULL.
//

*Object = NULL;

if (NT_SUCCESS(Status)) {

if (ObpCheckObjectReference( ExistingObject,
AccessState,
FALSE,
AccessMode,
&Status )) {

*Object = ExistingObject;
}
}

//
// If the access state was generated, then delete the access
// state.
//

if (AccessState == &LocalAccessState) {

SeDeleteAccessState(AccessState);
}

//
// Free the object name buffer.
//

FreeBuffer:

ObpFreeObjectNameBuffer(&CapturedObjectName);
}

return Status;
}


# 这个是对应于ntqueryinformation相应调用的 2005-03-14 10:39 七猫的垃圾箱
NTSTATUS
ObpCaptureHandleInformation (
IN OUT PSYSTEM_HANDLE_TABLE_ENTRY_INFO *HandleEntryInfo,
IN HANDLE UniqueProcessId,
IN PHANDLE_TABLE_ENTRY ObjectTableEntry,
IN HANDLE HandleIndex,
IN ULONG Length,
IN OUT PULONG RequiredLength
)

/*++

Routine Description:

This is the callback routine of ObGetHandleInformation

Arguments:

HandleEntryInfo - Supplies a pointer to the output buffer to receive
the handle information

UniqueProcessId - Supplies the process id of the caller

ObjectTableEntry - Supplies the handle table entry that is being
captured

HandleIndex - Supplies the index for the preceding handle table entry

Length - Specifies the length, in bytes, of the original user buffer

RequiredLength - Specifies the length, in bytes, that has already been
used in the buffer to store information. On return this receives
the updated number of bytes being used.

Note that the HandleEntryInfo does not necessarily point to the
start of the original user buffer. It will have been offset by
the feed-in RequiredLength value.

Return Value:

An appropriate status value

--*/

{
NTSTATUS Status;
POBJECT_HEADER ObjectHeader;

//
// Figure out who much size we really need to contain this extra record
// and then check that it fits.
//

*RequiredLength += sizeof( SYSTEM_HANDLE_TABLE_ENTRY_INFO );

if (Length < *RequiredLength) {

Status = STATUS_INFO_LENGTH_MISMATCH;

} else {

//
// Get the object header from the table entry and then copy over the information
//

ObjectHeader = (POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->Object)) & ~OBJ_HANDLE_ATTRIBUTES);

(*HandleEntryInfo)->UniqueProcessId = (USHORT)((ULONG_PTR)UniqueProcessId);
(*HandleEntryInfo)->HandleAttributes = (UCHAR)(ObjectTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES);
(*HandleEntryInfo)->ObjectTypeIndex = (UCHAR)(ObjectHeader->Type->Index);
(*HandleEntryInfo)->HandleValue = (USHORT)((ULONG_PTR)(HandleIndex));
(*HandleEntryInfo)->Object = &ObjectHeader->Body;
(*HandleEntryInfo)->CreatorBackTraceIndex = 0;

#if i386 && !FPO

if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {

(*HandleEntryInfo)->CreatorBackTraceIndex = ObjectTableEntry->CreatorBackTraceIndex;
(*HandleEntryInfo)->GrantedAccess = ObpTranslateGrantedAccessIndex( ObjectTableEntry->GrantedAccessIndex );

} else {

(*HandleEntryInfo)->GrantedAccess = ObjectTableEntry->GrantedAccess;
}

#else

(*HandleEntryInfo)->GrantedAccess = ObjectTableEntry->GrantedAccess;

#endif // i386 && !FPO

(*HandleEntryInfo)++;

Status = STATUS_SUCCESS;
}

return( Status );
}

# NtDuplicateObject 2005-03-14 10:42 七猫的垃圾箱
NTSTATUS
NtDuplicateObject (
IN HANDLE SourceProcessHandle,
IN HANDLE SourceHandle,
IN HANDLE TargetProcessHandle OPTIONAL,
OUT PHANDLE TargetHandle OPTIONAL,
IN ACCESS_MASK DesiredAccess,
IN ULONG HandleAttributes,
IN ULONG Options
)

/*++

Routine Description:

This function creates a handle that is a duplicate of the specified
source handle. The source handle is evaluated in the context of the
specified source process. The calling process must have
PROCESS_DUP_HANDLE access to the source process. The duplicate
handle is created with the specified attributes and desired access.
The duplicate handle is created in the handle table of the specified
target process. The calling process must have PROCESS_DUP_HANDLE
access to the target process.

Arguments:

SourceProcessHandle - Supplies a handle to the source process for the
handle being duplicated

SourceHandle - Supplies the handle being duplicated

TargetProcessHandle - Optionally supplies a handle to the target process
that is to receive the new handle

TargetHandle - Optionally returns a the new duplicated handle

DesiredAccess - Desired access for the new handle

HandleAttributes - Desired attributes for the new handle

Options - Duplication options that control things like close source,
same access, and same attributes.

Return Value:

TBS

--*/

{
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PVOID SourceObject;
POBJECT_HEADER ObjectHeader;
POBJECT_TYPE ObjectType;
PEPROCESS SourceProcess;
PEPROCESS TargetProcess;
BOOLEAN Attached;
PVOID ObjectTable;
HANDLE_TABLE_ENTRY ObjectTableEntry;
OBJECT_HANDLE_INFORMATION HandleInformation;
HANDLE NewHandle;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
ACCESS_MASK SourceAccess;
ACCESS_MASK TargetAccess;
PACCESS_STATE PassedAccessState = NULL;

//
// Get previous processor mode and probe output arguments if necessary.
//

PreviousMode = KeGetPreviousMode();

if (ARGUMENT_PRESENT( TargetHandle ) && (PreviousMode != KernelMode)) {

try {

ProbeForWriteHandle( TargetHandle );

} except( EXCEPTION_EXECUTE_HANDLER ) {

return( GetExceptionCode() );
}
}

//
// If the caller is not asking for the same access then
// validate the access they are requesting doesn't contain
// any bad bits
//

if (!(Options & DUPLICATE_SAME_ACCESS)) {

Status = ObpValidateDesiredAccess( DesiredAccess );

if (!NT_SUCCESS( Status )) {

return( Status );
}
}

//
// The Attached variable indicates if we needed to
// attach to the source process because it was not the
// current process.
//

Attached = FALSE;

//
// Given the input source process handle get a pointer
// to the source process object
//

Status = ObReferenceObjectByHandle( SourceProcessHandle,
PROCESS_DUP_HANDLE,
PsProcessType,
PreviousMode,
(PVOID *)&SourceProcess,
NULL );

if (!NT_SUCCESS( Status )) {

return Status;
}

//
// Lock down access to the process object tables
//

KeEnterCriticalRegion();

KeWaitForSingleObject( &ObpInitKillMutant,
Executive,
KernelMode,
FALSE,
NULL );

//
// Make sure the source process has an object table still
//

if ( SourceProcess->ObjectTable == NULL ) {

KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE );

KeLeaveCriticalRegion();

ObDereferenceObject( SourceProcess );

return STATUS_PROCESS_IS_TERMINATING;
}

//
// If the specified source process is not the current process, attach
// to the specified source process. Then after we reference the object
// we can detach from the process.
//

if (PsGetCurrentProcess() != SourceProcess) {

KeAttachProcess( &SourceProcess->Pcb );

Attached = TRUE;
}

//
// The the input source handle get a pointer to the
// source object itself, then detach from the process
// if necessary and check if we were given a good
// source handle.
//

Status = ObReferenceObjectByHandle( SourceHandle,
0,
(POBJECT_TYPE)NULL,
PreviousMode,
&SourceObject,
&HandleInformation );

if (Attached) {

KeDetachProcess();

Attached = FALSE;
}

if (!NT_SUCCESS( Status )) {

KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE );

KeLeaveCriticalRegion();

ObDereferenceObject( SourceProcess );

return( Status );
}

//
// We are all done if no target process handle was specified.
// This is practially a noop because the only really end result
// could be that we've closed the source handle.
//

if (!ARGUMENT_PRESENT( TargetProcessHandle )) {

//
// If no TargetProcessHandle, then only possible option is to close
// the source handle in the context of the source process.
//

if (!(Options & DUPLICATE_CLOSE_SOURCE)) {

Status = STATUS_INVALID_PARAMETER;
}

if (Options & DUPLICATE_CLOSE_SOURCE) {

KeAttachProcess( &SourceProcess->Pcb );

NtClose( SourceHandle );

KeDetachProcess();
}

KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE );

KeLeaveCriticalRegion();

ObDereferenceObject( SourceObject );
ObDereferenceObject( SourceProcess );

return( Status );
}

SourceAccess = HandleInformation.GrantedAccess;

//
// At this point the caller did specify for a target process
// So from the target process handle get a pointer to the
// target process object.
//

Status = ObReferenceObjectByHandle( TargetProcessHandle,
PROCESS_DUP_HANDLE,
PsProcessType,
PreviousMode,
(PVOID *)&TargetProcess,
NULL );

//
// If we cannot get the traget process object then close the
// source down if requsted, cleanup and return to our caller
//

if (!NT_SUCCESS( Status )) {

if (Options & DUPLICATE_CLOSE_SOURCE) {

KeAttachProcess( &SourceProcess->Pcb );

NtClose( SourceHandle );

KeDetachProcess();
}

KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE );

KeLeaveCriticalRegion();

ObDereferenceObject( SourceObject );
ObDereferenceObject( SourceProcess );

return( Status );
}

//
// Make sure the target process has not exited
//

if ( TargetProcess->ObjectTable == NULL ) {

if (Options & DUPLICATE_CLOSE_SOURCE) {

KeAttachProcess( &SourceProcess->Pcb );

NtClose( SourceHandle );

KeDetachProcess();
}

KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE );

KeLeaveCriticalRegion();

ObDereferenceObject( SourceObject );
ObDereferenceObject( SourceProcess );
ObDereferenceObject( TargetProcess );

return STATUS_PROCESS_IS_TERMINATING;
}

//
// If the specified target process is not the current process, attach
// to the specified target process.
//

if (PsGetCurrentProcess() != TargetProcess) {

KeAttachProcess( &TargetProcess->Pcb );

Attached = TRUE;
}

//
// Construct the proper desired access and attributes for the new handle
//

if (Options & DUPLICATE_SAME_ACCESS) {

DesiredAccess = SourceAccess;
}

if (Options & DUPLICATE_SAME_ATTRIBUTES) {

HandleAttributes = HandleInformation.HandleAttributes;

} else {

//
// Always propogate auditing information.
//

HandleAttributes |= HandleInformation.HandleAttributes & OBJ_AUDIT_OBJECT_CLOSE;
}

//
// Get the object header for the source object
//

ObjectHeader = OBJECT_TO_OBJECT_HEADER( SourceObject );
ObjectType = ObjectHeader->Type;

ObjectTableEntry.Object = ObjectHeader;
ObjectTableEntry.ObAttributes |= (HandleAttributes & OBJ_HANDLE_ATTRIBUTES);

//
// If any of the generic access bits are specified then map those to more
// specific access bits
//

if ((DesiredAccess & GENERIC_ACCESS) != 0) {

RtlMapGenericMask( &DesiredAccess,
&ObjectType->TypeInfo.GenericMapping );
}

//
// Make sure to preserve ACCESS_SYSTEM_SECURITY, which most likely is not
// found in the ValidAccessMask
//

TargetAccess = DesiredAccess &
(ObjectType->TypeInfo.ValidAccessMask | ACCESS_SYSTEM_SECURITY);

//
// If the access requested for the target is a superset of the
// access allowed in the source, perform full AVR. If it is a
// subset or equal, do not perform any access validation.
//
// Do not allow superset access if object type has a private security
// method, as there is no means to call them in this case to do the
// access check.
//
// If the AccessState is not passed to ObpIncrementHandleCount
// there will be no AVR.
//

if (TargetAccess & ~SourceAccess) {

if (ObjectType->TypeInfo.SecurityProcedure == SeDefaultObjectMethod) {

Status = SeCreateAccessState( &AccessState,
&AuxData,
TargetAccess, // DesiredAccess
&ObjectType->TypeInfo.GenericMapping );

PassedAccessState = &AccessState;

} else {

Status = STATUS_ACCESS_DENIED;
}

} else {

//
// Do not perform AVR
//

PassedAccessState = NULL;

Status = STATUS_SUCCESS;
}

//
// Increment the new handle count and get a pointer to
// the target processes object table
//

if ( NT_SUCCESS( Status )) {

Status = ObpIncrementHandleCount( ObDuplicateHandle,
PsGetCurrentProcess(), // this is already the target process
SourceObject,
ObjectType,
PassedAccessState,
PreviousMode,
HandleAttributes );

ObjectTable = ObpGetObjectTable();

ASSERT(ObjectTable);
}

if (Attached) {

KeDetachProcess();

Attached = FALSE;
}

if (Options & DUPLICATE_CLOSE_SOURCE) {

KeAttachProcess( &SourceProcess->Pcb );

NtClose( SourceHandle );

KeDetachProcess();
}

if (!NT_SUCCESS( Status )) {

if (PassedAccessState != NULL) {

SeDeleteAccessState( PassedAccessState );
}

KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE );

KeLeaveCriticalRegion();

ObDereferenceObject( SourceObject );
ObDereferenceObject( SourceProcess );
ObDereferenceObject( TargetProcess );

return( Status );
}

if ((PassedAccessState != NULL) && (PassedAccessState->GenerateOnClose == TRUE)) {

//
// If we performed AVR opening the handle, then mark the handle as needing
// auditing when it's closed.
//

ObjectTableEntry.ObAttributes |= OBJ_AUDIT_OBJECT_CLOSE;
}

#if i386 && !FPO

if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {

ObjectTableEntry.GrantedAccessIndex = ObpComputeGrantedAccessIndex( TargetAccess );
ObjectTableEntry.CreatorBackTraceIndex = RtlLogStackBackTrace();

} else {

ObjectTableEntry.GrantedAccess = TargetAccess;
}

#else

ObjectTableEntry.GrantedAccess = TargetAccess;

#endif // i386 && !FPO

//
// Now that we've constructed a new object table entry for the duplicated handle
// we need to add it to the object table of the target process


NewHandle = ExCreateHandle( ObjectTable, &ObjectTableEntry );

if (NewHandle) {

//
// We have a new handle to audit the creation of the new handle if
// AVR was done. And set the optional output handle variable. Note
// that if we reach here the status variable is already a success
//

if (PassedAccessState != NULL) {

SeAuditHandleCreation( PassedAccessState, NewHandle );
}

if (SeDetailedAuditing && (ObjectTableEntry.ObAttributes & OBJ_AUDIT_OBJECT_CLOSE)) {

SeAuditHandleDuplication( SourceHandle,
NewHandle,
SourceProcess,
TargetProcess );
}

if (ARGUMENT_PRESENT( TargetHandle )) {

try {

*TargetHandle = NewHandle;

} except( EXCEPTION_EXECUTE_HANDLER ) {

//
// Fall through, since we cannot undo what we have done.
//
}
}

} else {

//
// We didn't get a new handle to decrement the handle count dereference
// the necessary objects, set the optional output variable and indicate
// why we're failing
//

ObpDecrementHandleCount( TargetProcess,
ObjectHeader,
ObjectType,
TargetAccess );

ObDereferenceObject( SourceObject );

if (ARGUMENT_PRESENT( TargetHandle )) {

try {

*TargetHandle = (HANDLE)NULL;

} except( EXCEPTION_EXECUTE_HANDLER ) {

//
// Fall through so we can return the correct status.
//
}
}

Status = STATUS_INSUFFICIENT_RESOURCES;
}

//
// Cleanup from our selfs and then return to our caller
//

if (PassedAccessState != NULL) {

SeDeleteAccessState( PassedAccessState );
}

KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE );

KeLeaveCriticalRegion();

ObDereferenceObject( SourceProcess );
ObDereferenceObject( TargetProcess );

return( Status );
}

# ObGetObjectName 2005-03-14 10:43 七猫的垃圾箱
PUNICODE_STRING
ObGetObjectName (
IN PVOID Object
)

/*++

Routine description:

This routine returns a pointer to the name of object

Arguments:

Object - Supplies the object being queried

Return Value:

The address of the unicode string that stores the object
name if available and NULL otherwise

--*/

{
POBJECT_HEADER ObjectHeader;
POBJECT_HEADER_NAME_INFO NameInfo;

//
// Translate the input object to a name info structure
//

ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object );
NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );

//
// If the object has a name then return the address of
// the name otherwise return null
//

if ((NameInfo != NULL) && (NameInfo->Name.Length != 0)) {

return &NameInfo->Name;

} else {

return NULL;
}
}

# 支持猫猫 2005-03-14 10:48 未留名字
你从泄漏中找到的?

# re: windoiws句柄及相关信息,基本上来源于2K原码,我并不准备写多少,把他相关的贴出来吧。 2010-01-31 08:00 1
不知道这是什么东西

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]