直接上代码:
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
#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.\n"));
// 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\n"), 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
的文件自行观看