//-------------------------------------------------------------------------- // 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(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; }