枚举符号链接

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
// 定义函数返回值
typedef ULONG NTSTATUS;
// 宽字节字符串结构定义
typedef struct _UNICODE_STRING {
    USHORT  Length;
    USHORT  MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
// 对象属性定义
typedef struct _OBJECT_ATTRIBUTES {
    ULONG Length;
    HANDLE RootDirectory;
    UNICODE_STRING *ObjectName;
    ULONG Attributes;
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_ATTRIBUTES,*POBJECT_ATTRIBUTES;
// 基本信息定义
typedef struct _DIRECTORY_BASIC_INFORMATION {
    UNICODE_STRING ObjectName;
    UNICODE_STRING ObjectTypeName;
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;
// 返回值或状态类型定义
#define OBJ_CASE_INSENSITIVE      0x00000040L
#define DIRECTORY_QUERY           (0x0001)
#define STATUS_SUCCESS            ((NTSTATUS)0x00000000L) // ntsubauth
#define STATUS_MORE_ENTRIES       ((NTSTATUS)0x00000105L)
#define STATUS_NO_MORE_ENTRIES    ((NTSTATUS)0x8000001AL)
#define STATUS_BUFFER_TOO_SMALL   ((NTSTATUS)0xC0000023L)
#define SYMBOLIC_LINK_QUERY       (0x0001)
#define SYMBOLIC_LINK_ALL_ACCESS  (STANDARD_RIGHTS_REQUIRED | 0x1)
// 初始化对象属性宏定义
#define InitializeObjectAttributes( p, n, a, r, s ) { /
    (p)->Length = sizeof( OBJECT_ATTRIBUTES );          /
    (p)->RootDirectory = r;                             /
    (p)->Attributes = a;                                /
    (p)->ObjectName = n;                                /
    (p)->SecurityDescriptor = s;                        /
    (p)->SecurityQualityOfService = NULL;               /
}
// 字符串初始化
typedef VOID (CALLBACK* RTLINITUNICODESTRING)(PUNICODE_STRING,PCWSTR);
RTLINITUNICODESTRING RtlInitUnicodeString;
// 字符串比较
typedef
BOOLEAN
(WINAPI *RTLEQUALUNICODESTRING)(
                                const UNICODE_STRING *String1,
                                const UNICODE_STRING *String2,
                                BOOLEAN CaseInSensitive
                                );
RTLEQUALUNICODESTRING RtlEqualUnicodeString;
// 打开对象
typedef NTSTATUS (WINAPI *ZWOPENDIRECTORYOBJECT)(
    OUT PHANDLE DirectoryHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );
ZWOPENDIRECTORYOBJECT ZwOpenDirectoryObject;
// 查询对象
typedef
NTSTATUS
(WINAPI *ZWQUERYDIRECTORYOBJECT)(
                                 IN HANDLE DirectoryHandle,
                                 OUT PVOID Buffer,
                                 IN ULONG BufferLength,
                                 IN BOOLEAN ReturnSingleEntry,
                                 IN BOOLEAN RestartScan,
                                 IN OUT PULONG Context,
                                 OUT PULONG ReturnLength OPTIONAL
                                 );
ZWQUERYDIRECTORYOBJECT ZwQueryDirectoryObject;
// 打开符号链接对象
typedef
NTSTATUS
(WINAPI *ZWOPENSYMBOLICKLINKOBJECT)(
                                    OUT PHANDLE SymbolicLinkHandle,
                                    IN ACCESS_MASK DesiredAccess,
                                    IN POBJECT_ATTRIBUTES ObjectAttributes
                                    );
ZWOPENSYMBOLICKLINKOBJECT ZwOpenSymbolicLinkObject;
// 查询符号链接对象
typedef
NTSTATUS
(WINAPI *ZWQUERYSYMBOLICKLINKOBJECT)(
                                     IN HANDLE SymbolicLinkHandle,
                                     IN OUT PUNICODE_STRING TargetName,
                                     OUT PULONG ReturnLength OPTIONAL
                                     );
ZWQUERYSYMBOLICKLINKOBJECT ZwQuerySymbolicLinkObject;
// 关闭已经打开的对象
typedef
NTSTATUS
(WINAPI *ZWCLOSE)(
                  IN HANDLE Handle
                  );
ZWCLOSE ZwClose;
int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE hNtdll = NULL;
    hNtdll = LoadLibrary(_T("ntdll.dll" ));
    if ( NULL == hNtdll )
    {
        printf("[%s]--Load ntdll.dll failed(%ld)./r/n", __FUNCTION__, GetLastError());
        goto EXIT;
    }
    printf("[%s]--Load ntdll.dll sucess now get proc./r/n", __FUNCTION__);
    RtlInitUnicodeString      = (RTLINITUNICODESTRING)GetProcAddress( hNtdll, "RtlInitUnicodeString");
    RtlEqualUnicodeString     = (RTLEQUALUNICODESTRING)GetProcAddress( hNtdll, "RtlEqualUnicodeString");
    ZwOpenDirectoryObject     = (ZWOPENDIRECTORYOBJECT)GetProcAddress( hNtdll, "ZwOpenDirectoryObject");
    ZwQueryDirectoryObject    = (ZWQUERYDIRECTORYOBJECT)GetProcAddress( hNtdll, "ZwQueryDirectoryObject");
    ZwOpenSymbolicLinkObject  = (ZWOPENSYMBOLICKLINKOBJECT)GetProcAddress( hNtdll, "ZwOpenSymbolicLinkObject");
    ZwQuerySymbolicLinkObject = (ZWQUERYSYMBOLICKLINKOBJECT)GetProcAddress( hNtdll, "ZwQuerySymbolicLinkObject");
    ZwClose                   = (ZWCLOSE)GetProcAddress( hNtdll, "ZwClose");
    UNICODE_STRING     strDirName;
    OBJECT_ATTRIBUTES  oba;
    NTSTATUS           ntStatus; 
    HANDLE             hDirectory;
    RtlInitUnicodeString(&strDirName, _T("//global??"));
    InitializeObjectAttributes(&oba, &strDirName, OBJ_CASE_INSENSITIVE, NULL, NULL);
    printf("[%s]--Open directory object now./r/n", __FUNCTION__);
    ntStatus = ZwOpenDirectoryObject(&hDirectory, DIRECTORY_QUERY, &oba);
    if ( ntStatus != STATUS_SUCCESS )
    {
        printf("[%s]--Open directory object failed(%ld)./r/n", __FUNCTION__, GetLastError());
        goto EXIT;
    }
    printf("[%s]--Open directory object success./r/n", __FUNCTION__);
    UNICODE_STRING symbolicLink;
    UNICODE_STRING targetName;
    BYTE           buffer[2048] = {0};
    ULONG          ulLength  = 2048;  
    ULONG          ulContext = 0;
    ULONG          ulRet     = 0; 
    RtlInitUnicodeString(&symbolicLink, L"SymbolicLink");
    targetName.Length = 0;
    targetName.Buffer = (PWSTR)calloc(2, 1024);
    if ( targetName.Buffer == NULL )
    {
        printf("[%s]--calloc failed(%ld)./r/n", __FUNCTION__, GetLastError());
        goto EXIT;
    }
    targetName.MaximumLength = 1024;
    do
    {
        ntStatus = ZwQueryDirectoryObject(hDirectory, buffer, ulLength, TRUE, FALSE, &ulContext, &ulRet);
        if ( (ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_NO_MORE_ENTRIES) )
        {
            printf("[%s]--ZwQueryDirectoryObject failed(%ld)./r/n", __FUNCTION__, GetLastError());
            goto EXIT;
        }
        else if ( STATUS_NO_MORE_ENTRIES == ntStatus )
        {
            printf("[%s]--No more object./r/n", __FUNCTION__);
            goto EXIT;
        }
        PDIRECTORY_BASIC_INFORMATION  directoryInfo = (PDIRECTORY_BASIC_INFORMATION)buffer;
        printf("ObjectName: [%S]---ObjectTypeName: [%S]/n", 
            directoryInfo->ObjectName.Buffer, directoryInfo->ObjectTypeName.Buffer);
        if ( RtlEqualUnicodeString(&directoryInfo->ObjectTypeName, &symbolicLink, TRUE) )
        {
            OBJECT_ATTRIBUTES symbolicLinkAttributes;
            HANDLE            hSymbolicLink;
            // 初始化符号链接对象属性
            InitializeObjectAttributes(&symbolicLinkAttributes, &directoryInfo->ObjectName, 
                OBJ_CASE_INSENSITIVE, hDirectory, NULL);
            // 打开符号链接对象
            ntStatus = ZwOpenSymbolicLinkObject(&hSymbolicLink, SYMBOLIC_LINK_QUERY, &symbolicLinkAttributes);
            if ( ntStatus != STATUS_SUCCESS )
            {
                printf("[%s]--ZwOpenSymbolicLinkObject failed(%ld)./r/n", __FUNCTION__, GetLastError());
                goto EXIT;
            }
            // 查询符号链接对象
            ntStatus = ZwQuerySymbolicLinkObject(hSymbolicLink, &targetName, NULL); 
            if ( ntStatus != STATUS_SUCCESS )
            {
                printf("[%s]--ZwQuerySymbolicLinkObject failed(%ld)./r/n", __FUNCTION__, GetLastError());
                ZwClose(hSymbolicLink);
                goto EXIT;
            }
            // TODO: 添加针对符号链接的处理代码
            // 清空targetName
            memset((LPVOID)targetName.Buffer, 0, targetName.Length*sizeof(WCHAR));
            // 关闭符号链接句柄
            ZwClose(hSymbolicLink);
        }
    }while(TRUE);
EXIT:
    if ( hDirectory != NULL )
    {
        ZwClose(hDirectory);
    }
    getchar();
    return 0;
}
欢迎加QQ群:333483823进行技术讨论.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值