ywledoc 发表于 2011-4-7 18:45:58

自己实现ObReferenceObjectByHandle

比较简单,就是根据内核句柄表,再根据句柄表的一些结构,自己查找就是了。
查找部分直接从WRK里扣出来的。
怎么得到内核句柄表,看代码,抹句柄已经很正常了。
#include <ntddk.h>
#include <windef.h>

NTSTATUS
DriverEntry(
        IN PDRIVER_OBJECTDriverObject,
        IN PUNICODE_STRINGRegistryPath
        );

NTSYSAPI
NTSTATUS
NTAPI
ZwOpenDirectoryObject(
        OUT PHANDLE DirectoryHandle,
        IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObjectAttributes
        );

#pragma alloc_text(INIT ,DriverEntry)

/////////////////////
//struct
////////////////////
#define TABLE_PAGE_SIZE PAGE_SIZE
#define LEVEL_CODE_MASK 3
#define LOWLEVEL_COUNT (TABLE_PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY))
#define MIDLEVEL_COUNT (PAGE_SIZE / sizeof(PHANDLE_TABLE_ENTRY))
#define HIGHLEVEL_COUNTMAX_HANDLES / (LOWLEVEL_COUNT * MIDLEVEL_COUNT)

typedef struct _EX_PUSH_LOCK {

#define EX_PUSH_LOCK_LOCK_V          ((ULONG_PTR)0x0)
#define EX_PUSH_LOCK_LOCK            ((ULONG_PTR)0x1)


#define EX_PUSH_LOCK_WAITING         ((ULONG_PTR)0x2)

#define EX_PUSH_LOCK_WAKING          ((ULONG_PTR)0x4)

#define EX_PUSH_LOCK_MULTIPLE_SHARED ((ULONG_PTR)0x8)

#define EX_PUSH_LOCK_SHARE_INC       ((ULONG_PTR)0x10)
#define EX_PUSH_LOCK_PTR_BITS      ((ULONG_PTR)0xf)

    union {
      struct {
            ULONG_PTR Locked         : 1;
            ULONG_PTR Waiting      : 1;
            ULONG_PTR Waking         : 1;
            ULONG_PTR MultipleShared : 1;
            ULONG_PTR Shared         : sizeof (ULONG_PTR) * 8 - 4;
      };
      ULONG_PTR Value;
      PVOID Ptr;
    };
} EX_PUSH_LOCK, *PEX_PUSH_LOCK;

typedef struct _HANDLE_TABLE {

    ULONG_PTR TableCode;

    struct _EPROCESS *QuotaProcess;
    HANDLE UniqueProcessId;

#define HANDLE_TABLE_LOCKS 4

    EX_PUSH_LOCK HandleTableLock;

    LIST_ENTRY HandleTableList;

    EX_PUSH_LOCK HandleContentionEvent;

    PVOID DebugInfo;

    LONG ExtraInfoPages;

    ULONG FirstFree;

    ULONG LastFree;

    ULONG NextHandleNeedingPool;

    LONG HandleCount;

    union {
      ULONG Flags;

      BOOLEAN StrictFIFO : 1;
    };

} HANDLE_TABLE, *PHANDLE_TABLE;

typedef struct _EXHANDLE {

    union {

      struct {

            ULONG TagBits : 2;

            ULONG Index : 30;

      };

      HANDLE GenericHandleOverlay;

#define HANDLE_VALUE_INC 4

      ULONG_PTR Value;
    };

} EXHANDLE, *PEXHANDLE;

typedef struct _HANDLE_TABLE_ENTRY {

    union {

      PVOID Object;

      ULONG ObAttributes;

      PVOID InfoTable;

      ULONG_PTR Value;
    };

    union {

      union {

            ACCESS_MASK GrantedAccess;

            struct {

                USHORT GrantedAccessIndex;
                USHORT CreatorBackTraceIndex;
            };
      };

      LONG NextFreeTableEntry;
    };

} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;

#define NUMBER_HASH_BUCKETS 37
typedef struct _OBJECT_DIRECTORY_ENTRY {
    struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
    PVOID Object;
    ULONG HashValue;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;

typedef struct _OBJECT_DIRECTORY {
    struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[ NUMBER_HASH_BUCKETS ];
    EX_PUSH_LOCK Lock;
    PVOID        DeviceMap;
    ULONG SessionId;
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;

///////////////////////////////
//struct end
//////////////////////////////

VOID
DriverUnload(
        IN PDRIVER_OBJECTDriverObject
        )
{
}

NTSTATUS
DriverEntry(
        IN PDRIVER_OBJECTDriverObject,
        IN PUNICODE_STRINGRegistryPath
        )
{
        NTSTATUS                ntStatus;
        POBJECT_DIRECTORY        dir_obj;
        PVOID                        eprocess;        //eprocess的指针
        PHANDLE_TABLE                HandleTable;        //指向句柄表的指针
        ULONG_PTR                CapturedTable;
        ULONG                        TableLevel;
        PUCHAR                         TableLevel1;
        PUCHAR                         TableLevel2;
        PUCHAR                         TableLevel3;
        EXHANDLE                 Handle;
        HANDLE                        dir_handle;
        ULONG_PTR                 i,j,k;
        UNICODE_STRING                dir_name;
        OBJECT_ATTRIBUTES        obj_attr;
        PHANDLE_TABLE_ENTRY         Entry = NULL;
       
        //初始化驱动卸载例程
        DriverObject->DriverUnload = DriverUnload;
       
        //取得内核句柄表的指针
        eprocess = (PVOID)PsGetCurrentProcess();
        HandleTable = (PHANDLE_TABLE)*(ULONG*)((ULONG)eprocess + 0x0c4); //0x0c4是eprocess里tablecode的偏移
       
        //获得根目录(\)的句柄
        RtlInitUnicodeString( &dir_name, L"\\");
        InitializeObjectAttributes(
                                &obj_attr,
                                &dir_name,
                                OBJ_KERNEL_HANDLE,
                                NULL,
                                NULL);
        ntStatus = ZwOpenDirectoryObject(
                                &dir_handle,
                                DIRECTORY_ALL_ACCESS,
                                &obj_attr);
        if (!NT_SUCCESS(ntStatus)) {
                KdPrint(("GetRootDir @ DriverEntry : ZwOpenDirectoryObject error!\n"));
                ZwClose(dir_handle);
                return        STATUS_SUCCESS;
        }
/*方法二
        ntStatus = ObReferenceObjectByHandle(
                        dir_handle,
                        DIRECTORY_ALL_ACCESS,
                        NULL,
                        KernelMode,
                        &dir_obj,
                        NULL);
        if (!NT_SUCCESS(ntStatus)) {
                KdPrint(("GetRootDir @ DriverEntry : ObReferenceObjectByHandle error!\n"));
                ObDereferenceObject( dir_obj );
                return STATUS_SUCCESS;
        }
*/       
        //开始从内核句柄表中查找我们句柄所对应的对象
        Handle.GenericHandleOverlay = dir_handle;
        Handle.TagBits = 0;
       
        CapturedTable = *(volatile ULONG_PTR *) &(HandleTable->TableCode);

          //
          //we need to capture the current table. This routine is lock free
          //so another thread may change the table at HandleTable->TableCode
          //

        TableLevel = (ULONG)(CapturedTable & LEVEL_CODE_MASK);
        CapturedTable = CapturedTable - TableLevel;

          //
          //The lookup code depends on number of levels we have
          //

        switch (TableLevel) {
               
                case 0:
                  
                  //
                  //We have a simple index into the array, for a single level
                  //handle table
                  //


                        TableLevel1 = (PUCHAR) CapturedTable;

                  //
                  // The index for this level is already scaled by a factor of 4. Take advantage of this
                  //

                        Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1[Handle.Value *
                                                             (sizeof (HANDLE_TABLE_ENTRY) / HANDLE_VALUE_INC)];

                        break;
               
                case 1:
                  
                  //
                  //we have a 2 level handle table. We need to get the upper index
                  //and lower index into the array
                  //


                        TableLevel2 = (PUCHAR) CapturedTable;

                        i = Handle.Value % (LOWLEVEL_COUNT * HANDLE_VALUE_INC);

                        Handle.Value -= i;
                        j = Handle.Value / ((LOWLEVEL_COUNT * HANDLE_VALUE_INC) / sizeof (PHANDLE_TABLE_ENTRY));

                        TableLevel1 =(PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel2;
                        Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1;

                        break;
               
                case 2:
                  
                  //
                  //We have here a three level handle table.
                  //


                        TableLevel3 = (PUCHAR) CapturedTable;

                        i = Handle.Value% (LOWLEVEL_COUNT * HANDLE_VALUE_INC);

                        Handle.Value -= i;

                        k = Handle.Value / ((LOWLEVEL_COUNT * HANDLE_VALUE_INC) / sizeof (PHANDLE_TABLE_ENTRY));

                        j = k % (MIDLEVEL_COUNT * sizeof (PHANDLE_TABLE_ENTRY));

                        k -= j;

                        k /= MIDLEVEL_COUNT;


                        TableLevel2 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel3;
                        TableLevel1 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel2;
                        Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1;

                        break;

                default :
                        _assume (0);
        }
       
        dir_obj = (POBJECT_DIRECTORY)((ULONG)((*(ULONG*)(Entry)) & 0xFFFFFFF8) + 0x18);

        KdPrint(("GetRootDir @ DriverEntry : dir_obj is %08x\n", dir_obj));
       
        //调试版本此函数会起做用
        //程序断在这里,方便调试
        KdBreakPoint();
       
        return STATUS_SUCCESS;
}

乔丹二世 发表于 2011-4-8 09:41:04

LZ貌似抄了不少WRK的代码

ywledoc 发表于 2011-4-8 10:08:41

回复 乔丹二世 的帖子

查找部分直接从WRK里扣出来的。

马大哈 发表于 2011-4-8 10:35:40

如果做一款安全类软件或二次开发用的引擎,应该可以吧?

ywledoc 发表于 2011-4-8 11:44:31

回复 马大哈 的帖子

我?还是说这代码?

马大哈 发表于 2011-4-8 14:52:06

我说你们几个;P

ywledoc 发表于 2011-4-8 15:03:01

回复 马大哈 的帖子

管理员不是在做吗~哎~我还没人要呢~

Tesla.Angela 发表于 2011-4-8 18:17:53

回复 ywledoc 的帖子

是你处的地方不好。。。
来广东吧,广东这边的人比较务实,对于有用的人,也舍得出钱。

ywledoc 发表于 2011-4-8 20:15:28

回复 Tesla.Angela 的帖子

也得要毕业以后啦~珠海或者深圳。

马大哈 发表于 2011-4-10 09:06:24

回复 ywledoc 的帖子

加油加油!!!

sku__ 发表于 2015-1-10 10:25:31

谢谢分享
页: [1]
查看完整版本: 自己实现ObReferenceObjectByHandle