파일 핸들을 통해 파일 경로 가져오기

15737 단어
직접 부호:
CHandleLook.h 파일:
#ifndef CHANDLELOOK_H
#define CHANDLELOOK_H
#include <list>
#include <map>
#include <winternl.h>

typedef NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, 
	PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
typedef NTSTATUS (WINAPI *pNtQueryObject)(
  _In_opt_   HANDLE Handle,
  _In_       OBJECT_INFORMATION_CLASS ObjectInformationClass,
  _Out_opt_  PVOID ObjectInformation,
  _In_       ULONG ObjectInformationLength,
  _Out_opt_  PULONG ReturnLength
);
typedef NTSTATUS (WINAPI *pRtlAppendUnicodeToString)(
  _Out_opt_  PUNICODE_STRING Destination,
  _In_       PCWSTR Source
);
typedef NTSTATUS
	(WINAPI *pNtOpenSymbolicLinkObject)(
	OUT PHANDLE  LinkHandle,
	IN ACCESS_MASK  DesiredAccess,
	IN POBJECT_ATTRIBUTES  ObjectAttributes
	);

typedef NTSTATUS
	(WINAPI *pNtQuerySymbolicLinkObject)(
	IN HANDLE  LinkHandle,
	IN OUT PUNICODE_STRING  LinkTarget,
	OUT PULONG  ReturnedLength OPTIONAL
);

typedef VOID 
	(WINAPI *pRtlInitUnicodeString)(
	IN OUT PUNICODE_STRING  DestinationString,
	IN PCWSTR  SourceString
	);
typedef VOID 
	(WINAPI *pRtlFreeUnicodeString)(
	IN PUNICODE_STRING  UnicodeString
	);
typedef NTSTATUS
	(*pRtlVolumeDeviceToDosName)(
	IN  PVOID  VolumeDeviceObject,
	OUT PUNICODE_STRING  DosName
	);
typedef NTSTATUS
	(WINAPI *pNtClose)(
	IN HANDLE Handle
	);


typedef struct ProcessHandle{
	DWORD ID;				//  
	CString Name;			//  
	CString Type;			//  
}ProcessHandleInfor;

class CHandleLook{
public:
	CHandleLook();
	~CHandleLook();
	void Init();
	void Clear();
	HANDLE FindHandle(CString strName);
	bool GetObjectFormHandle(HANDLE hHandle);
	std::list< ProcessHandleInfor> *GetHandleList();
private:
	void InitDriverList();
	
	bool GetHandleType(HANDLE hHandle,CString &strType);
	bool GetHandleName(HANDLE hFile,CString &strFileName);

	void ChangeListName(std::list< ProcessHandleInfor> &pNameList);
	bool GetSymNameByDriverName(const CString DriverName , CString &SymName);
	CString ChangeFilePath(CString FilePath);

	HMODULE hNtdll;
	std::list< ProcessHandleInfor> m_processInfo;	//  id
	std::map<CString ,CString > m_mpDriverName;

	pNtQueryInformationProcess NtQueryInformationProcess;
	pNtQueryObject	NtQueryObject;
	pRtlAppendUnicodeToString RtlAppendUnicodeToString;
	pNtOpenSymbolicLinkObject NtOpenSymbolicLinkObject;
	pNtQuerySymbolicLinkObject NtQuerySymbolicLinkObject;
	pRtlInitUnicodeString RtlInitUnicodeString;
	pRtlFreeUnicodeString RtlFreeUnicodeString;
	pNtClose NtClose;

};
//---------------------------------------------------------------------------             
typedef struct _OBJECT_BASIC_INFORMATION {
	ULONG                   Attributes;
	ACCESS_MASK             DesiredAccess;
	ULONG                   HandleCount;
	ULONG                   ReferenceCount;
	ULONG                   PagedPoolUsage;
	ULONG                   NonPagedPoolUsage;
	ULONG                   Reserved[3];
	ULONG                   NameInformationLength;
	ULONG                   TypeInformationLength;
	ULONG                   SecurityDescriptorLength;
	LARGE_INTEGER           CreationTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;//ObjectBasicInformation 0x38

typedef struct _OBJECT_NAME_INFORMATION {
	UNICODE_STRING          Name;
	WCHAR                   NameBuffer[1];
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; //ObjectNameInformation  0x08
#define POOL_TYPE ULONG
typedef struct _OBJECT_TYPE_INFORMATION {
	UNICODE_STRING          TypeName;
	ULONG                   TotalNumberOfHandles;
	ULONG                   TotalNumberOfObjects;
	WCHAR                   Unused1[8];
	ULONG                   HighWaterNumberOfHandles;
	ULONG                   HighWaterNumberOfObjects;
	WCHAR                   Unused2[8];
	ACCESS_MASK             InvalidAttributes;
	GENERIC_MAPPING         GenericMapping;
	ACCESS_MASK             ValidAttributes;
	BOOLEAN                 SecurityRequired;
	BOOLEAN                 MaintainHandleCount;
	USHORT                  MaintainTypeList;
	POOL_TYPE               PoolType;
	ULONG                   DefaultPagedPoolCharge;
	ULONG                   DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;//ObjectTypeInformation	0x70

typedef struct _OBJECT_ALL_INFORMATION {
	ULONG                   NumberOfObjectsTypes;
	PUBLIC_OBJECT_TYPE_INFORMATION ObjectTypeInformation;
	//OBJECT_TYPE_INFORMATION ObjectTypeInformation[1];
} OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION; //ObjectAllInformation		0x04+

typedef struct _OBJECT_DATA_INFORMATION {
	BOOLEAN                 InheritHandle;
	BOOLEAN                 ProtectFromClose;
} OBJECT_DATA_INFORMATION, *POBJECT_DATA_INFORMATION; //ObjectDataInformation	0x02
#endif

CHandleLook.cpp 파일:
#include "stdafx.h"
#include "CHandleLook.h"
#include <vector>
#include "UNICODE_ANSI.h"

#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)
//     
#define STATUS_BUFFER_TOO_SMALL          ((NTSTATUS)0xC0000023L)

#define BUFSIZE MAX_PATH

CHandleLook::CHandleLook(){
	hNtdll = NULL;
	Clear();
}
CHandleLook::~CHandleLook(){
	Clear();
	if(hNtdll!=NULL)
		FreeLibrary(hNtdll);
}
void CHandleLook::Clear(){
	NtQueryInformationProcess = NULL;
}
void CHandleLook::Init(){
	if(hNtdll == NULL)
		hNtdll = LoadLibrary(_T("ntdll.dll"));
	NtQueryInformationProcess = (pNtQueryInformationProcess)GetProcAddress(hNtdll,("NtQueryInformationProcess"));
	NtQueryObject = (pNtQueryObject)GetProcAddress(hNtdll,("NtQueryObject"));
	RtlAppendUnicodeToString = (pRtlAppendUnicodeToString)GetProcAddress(hNtdll,("RtlAppendUnicodeToString"));
	NtOpenSymbolicLinkObject = (pNtOpenSymbolicLinkObject)GetProcAddress(hNtdll,("NtOpenSymbolicLinkObject"));
	NtQuerySymbolicLinkObject = (pNtQuerySymbolicLinkObject)GetProcAddress(hNtdll,("NtQuerySymbolicLinkObject"));
	NtClose =  (pNtClose)GetProcAddress(hNtdll,("NtClose"));
	RtlInitUnicodeString = (pRtlInitUnicodeString)GetProcAddress(hNtdll,("RtlInitUnicodeString"));
	RtlFreeUnicodeString = (pRtlFreeUnicodeString)GetProcAddress(hNtdll,("RtlFreeUnicodeString"));
}
HANDLE CHandleLook::FindHandle(CString strName){
	return NULL;
}
std::list< ProcessHandleInfor> *CHandleLook::GetHandleList()
{
	return &m_processInfo;
}
//           
bool CHandleLook::GetObjectFormHandle(HANDLE hHandle){
	DWORD Count = 0 ;
	if(GetProcessHandleCount(hHandle , &Count) == false) return false;
	DWORD hCount;
	NTSTATUS Status = NtQueryInformationProcess(hHandle , (PROCESSINFOCLASS)20,
		(LPVOID)&hCount,sizeof(DWORD),NULL);
	HANDLE CurHandle = (HANDLE)4;
	HANDLE hFound = 0;
	DWORD MaxHandle = 1024*1024*512*4;
	std::vector< HANDLE > HandleList;
	MaxHandle = 1024*1024*4;
	if(NT_SUCCESS(Status)){
		for(size_t i =0 ; i < hCount && CurHandle <= (HANDLE)MaxHandle; ){
			if(DuplicateHandle(hHandle,(HANDLE)CurHandle,GetCurrentProcess(),
				&hFound,0,FALSE,DUPLICATE_SAME_ACCESS) == TRUE){
				i++;
				HandleList.push_back(hFound);

				CString FilePath;
				CString FileType;
				bool bRet = GetHandleName((HANDLE)hFound,FilePath);
				if(bRet == false) continue;
				bRet = GetHandleType((HANDLE)hFound,FileType);
				if(bRet == false) continue;

				ProcessHandleInfor info = {0};
				info.ID = (DWORD)CurHandle;
				info.Name = FilePath;
				info.Type = FileType;
				m_processInfo.push_back(info);
			}
			CurHandle = (HANDLE)((DWORD)CurHandle + 4);
		}
	}
	ChangeListName(m_processInfo);
	for( size_t i = 0 ; i < HandleList.size() ; i++){
		CloseHandle(HandleList[i]);
	}
	return true;
}
//      
bool CHandleLook::GetHandleType(HANDLE hHandle,CString &strType)
{
	DWORD dwSize = 0;
	NTSTATUS Status = NtQueryObject(hHandle,ObjectTypeInformation ,NULL,NULL,&dwSize);
	if(NT_SUCCESS(Status)){
		return false;
	}
	if(Status == STATUS_INFO_LENGTH_MISMATCH){
		char *buf = new char[dwSize*2];
		ZeroMemory(buf,sizeof(char)*dwSize*2);
		Status = NtQueryObject(hHandle,ObjectTypeInformation ,buf,dwSize*2,&dwSize);
		if(!NT_SUCCESS(Status)){
			delete []buf;
			return false;
		}
		PUBLIC_OBJECT_TYPE_INFORMATION* typeInfor = (PUBLIC_OBJECT_TYPE_INFORMATION*)(buf);
		strType = typeInfor->TypeName.Buffer;
		delete []buf;
		return true;
	}
	return false;
}
//      
bool CHandleLook::GetHandleName(HANDLE hFile,CString &strFileName){
	DWORD dwSize = 0;
	NTSTATUS Status = NtQueryObject(hFile,OBJECT_INFORMATION_CLASS(1) ,NULL,NULL,&dwSize);
	if(NT_SUCCESS(Status)){
		return false;
	}
	if(STATUS_INFO_LENGTH_MISMATCH == Status){
		char *buf = new char[dwSize*2];
		ZeroMemory(buf,sizeof(char)*dwSize*2);
		Status = NtQueryObject(hFile,OBJECT_INFORMATION_CLASS(1) ,buf,dwSize*2,&dwSize);
		if(NT_SUCCESS(Status)){
			POBJECT_NAME_INFORMATION pObjectName = (POBJECT_NAME_INFORMATION)buf;
			strFileName = pObjectName->Name.Buffer;
			delete []buf;
			return TRUE;
		}
		delete []buf;
	}
	return FALSE;
}
//      
void CHandleLook::ChangeListName(std::list< ProcessHandleInfor> &pNameList)
{
	InitDriverList();
	std::list< ProcessHandleInfor>::iterator it = pNameList.begin();
	for( ; it != pNameList.end() ; ++it)
	{
		if(it->Type.CompareNoCase(_T("File")) == 0){
			it->Name = ChangeFilePath(it->Name);
		}
	}
}
//          
void CHandleLook::InitDriverList()
{
	DWORD nSize = GetLogicalDriveStrings(0,NULL);
	TCHAR *DirBuf = new TCHAR[nSize+1];
	ZeroMemory(DirBuf,nSize+1);
	int nCopy = GetLogicalDriveStrings(nSize,DirBuf);
	char *NewBuf = DirBuf;
	while(nCopy > 0){
		CString strDriver = NewBuf;
		NewBuf += strDriver.GetLength()+1;
		nCopy -= strDriver.GetLength()+1;
		//m_DriverList.push_back(strDriver);
		CString strSymName;
		if(strDriver[strDriver.GetLength() -1] == _T('\\'))
		{
			strDriver = strDriver.Left(strDriver.GetLength() - 1);
		}
		bool bRet = GetSymNameByDriverName(strDriver,strSymName);
		if(bRet == true){
			m_mpDriverName[strSymName] = strDriver;
		}
	}
	delete []DirBuf;
}

//       DOS  
CString CHandleLook::ChangeFilePath(CString FilePath)
{
	CString strName = FilePath;
	std::map<CString ,CString >::iterator it = m_mpDriverName.begin();
	for( ; it != m_mpDriverName.end(); ++it){
		CString strDosName = it->first;
		CString strDriverName = it->second;
		strDosName += _T('\\');
		strDriverName += _T('\\');
		if(strDosName.CompareNoCase(strName.Left(strDosName.GetLength())) == 0){
			int nNeedLen = strName.GetLength() - strDosName.GetLength();
			CString TmpName = strName.Right(nNeedLen);
			strName = strDriverName + TmpName;
			break;
		}
	}
	return strName;
}
//       DOS  
bool CHandleLook::GetSymNameByDriverName(const CString DriverName , CString &SymName){
	//               \   ,   \??\C:        
	CString strDriverName = _T("\\??\\");
	strDriverName += DriverName;
	UNICODE_STRING uDriverName = {0};
	int ustrLen = (strDriverName.GetLength()+1);
	wchar_t *pDriverName = new wchar_t[ustrLen];
	ZeroMemory(pDriverName,sizeof(wchar_t)*ustrLen);
	bool bRet = AnsiToUnicode(strDriverName.GetBuffer(),pDriverName,ustrLen);
	if(bRet == false) return false;
	RtlInitUnicodeString(&uDriverName,(PCWSTR)pDriverName);
	
	HANDLE LinkHandle = NULL;
	OBJECT_ATTRIBUTES Object = {0};

	InitializeObjectAttributes(&Object,&uDriverName,
								OBJ_CASE_INSENSITIVE 
								,0,0);
	
	NTSTATUS status = NtOpenSymbolicLinkObject(&LinkHandle,GENERIC_READ,&Object);
	delete []pDriverName;
	pDriverName = NULL;

	if(!NT_SUCCESS(status))
	{
		
		return false;
	}
	UNICODE_STRING strUstr = {0};
	ULONG retLen = 0;
	status = NtQuerySymbolicLinkObject(LinkHandle,&strUstr,&retLen);
	if(status == STATUS_BUFFER_TOO_SMALL){
		pDriverName = new wchar_t[retLen];
		ZeroMemory(pDriverName,sizeof(wchar_t)*retLen);
		strUstr.MaximumLength = (USHORT)retLen;
		strUstr.Buffer = pDriverName;
		status = NtQuerySymbolicLinkObject(LinkHandle,&strUstr,&retLen);
	}
	if(NT_SUCCESS(status)){
		SymName = strUstr.Buffer;
	}
	if(pDriverName != NULL){
		delete []pDriverName;
		pDriverName = NULL;
	}
	if(LinkHandle != NULL)
		NtClose(LinkHandle);
	if(!NT_SUCCESS(status)) return false;
	return true;
}

//BOOL CHandleLook::GetFileNameFromHandle(HANDLE hFile , CString &strFileName) 
//{
//	BOOL bSuccess = FALSE;
//	TCHAR pszFilename[MAX_PATH+1] = {0};
//	HANDLE hFileMap;
//
//	// Get the file size.
//	DWORD dwFileSizeHi = 0;
//	DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi); 
//
//	if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
//	{
//		_tprintf(TEXT("Cannot map a file with a length of zero.
")); // return FALSE; // } // // // Create a file mapping object. // hFileMap = CreateFileMapping(hFile, // NULL, // PAGE_READONLY, // 0, // 1, // NULL); // // if (hFileMap) // { // // Create a file mapping to get the file name. // void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1); // // if (pMem) // { // if (GetMappedFileName (GetCurrentProcess(), // pMem, // pszFilename, // MAX_PATH)) // { // // // Translate path with device name to drive letters. // TCHAR szTemp[BUFSIZE]; // szTemp[0] = '\0'; // // if (GetLogicalDriveStrings(BUFSIZE-1, szTemp)) // { // TCHAR szName[MAX_PATH]; // TCHAR szDrive[3] = TEXT(" :"); // BOOL bFound = FALSE; // TCHAR* p = szTemp; // // do // { // // Copy the drive letter to the template string // *szDrive = *p; // // // Look up each device name // if (QueryDosDevice(szDrive, szName, MAX_PATH)) // { // size_t uNameLen = _tcslen(szName); // // if (uNameLen < MAX_PATH) // { // bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0 // && *(pszFilename + uNameLen) == _T('\\'); // // if (bFound) // { // // Reconstruct pszFilename using szTempFile // // Replace device path with DOS path // TCHAR szTempFile[MAX_PATH]; // StringCchPrintf(szTempFile, // MAX_PATH, // TEXT("%s%s"), // szDrive, // pszFilename+uNameLen); // StringCchCopyN(pszFilename, MAX_PATH+1, szTempFile, _tcslen(szTempFile)); // } // } // } // // // Go to the next NULL character. // while (*p++); // } while (!bFound && *p); // end of string // } // } // bSuccess = TRUE; // UnmapViewOfFile(pMem); // } // // CloseHandle(hFileMap); // } // strFileName = pszFilename; // //_tprintf(TEXT("File name is %s
"), pszFilename); // return(bSuccess); //}

UNICODE_ANSI.h 파일:
#ifndef UNICODE_ANSI_H
#define UNICODE_ANSI_H
#include <Windows.h>
static bool UnicodeToAnsi(const wchar_t *WideChar , char *MultiChar,int nSize){
	int nRet = WideCharToMultiByte(CP_ACP,0,WideChar,wcslen(WideChar) ,NULL,0,NULL,NULL);
	if(nRet <= 0) return false;
	if(nRet > nSize) return false;
	nRet = WideCharToMultiByte(CP_ACP,0,WideChar,wcslen(WideChar) ,MultiChar,nSize,NULL,NULL);
	if(nRet <= 0) return false;
	return true;
}
static bool AnsiToUnicode(const char *MultiChar , wchar_t *WideChar ,int nSize){
	int nRet = MultiByteToWideChar(CP_ACP,0,MultiChar,strlen(MultiChar),NULL,0);
	if(nRet <= 0) return false;
	if(nRet > nSize) return false;
	nRet = MultiByteToWideChar(CP_ACP,0,MultiChar,strlen(MultiChar),WideChar,nSize);
	if(nRet <= 0) return false;
	return true;
}
#endif

자세한 테스트 코드 다운로드 가능
http://download.csdn.net/detail/ab7936573/6980697
직접 보기

좋은 웹페이지 즐겨찾기