符号链接枚举

我又回来了……2个月没什么进步了,在修炼软件产品与市场……

N年前,注册邮箱ID,zzz被人用过,一怒之下,前面随便敲了3个字母,

于是自己现在什么ID都是dhbzzz了……

不多说了,代码贴上,利用微软未公开的一些API枚举符号链接。

-------------------------------------------------------------------------------

代码
//--------------------------------------------------------------------------
// Copyright (C), 2004-2010, Zhengzz, All Rights Reserved
//
// FileName:    EnumSymbolink.cpp
//
// Author:      zhengzz
//
// Date:        2009-07-20
//
// Description: 枚举符号链接
//
// History:     <author>zhengzz<time>2009-07-20<version>1.0
//
//-------------------------------------------------------------------------

#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(21024);
    
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;
}




 

posted @ 2010-04-29 10:13  zhengzongzhao  阅读(632)  评论(0编辑  收藏  举报