返回> 网站首页 

查看某进程占有了哪些文件

yoours2011-07-07 17:09:28 阅读 1126

简介一边听听音乐,一边写写文章。

#include "tlhelp32.h"

DWORD GetPIDbyName(char *strName)
{
    HANDLE          hprocessSnap = NULL;
    PROCESSENTRY32 pe32;
    memset(&pe32, 0, sizeof(PROCESSENTRY32));
    
    hprocessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//创建进程快照
    // 如果创建快照失败就返回1;
    if (hprocessSnap == INVALID_HANDLE_VALUE)
    {
        printf("\nCreateToolhelp32Snapshot()failed:%d",GetLastError());
        return 0;
    }
    pe32.dwSize = sizeof(PROCESSENTRY32);   //初始化pe32的dwsize值
    //遍历快照
    if (Process32First(hprocessSnap,&pe32))
    {   
        do
        {   
            //如果name(要查找的进程的名字)等于pe32.szExeFile(本进程的名字),就返pe32.the32ProcessID          (进程ID)
            if (!stricmp(strName, pe32.szExeFile))
            {
                return (DWORD)pe32.th32ProcessID;
            }
        }while (Process32Next(hprocessSnap,&pe32));
    }
    
    //如果没找到就返回0
    CloseHandle (hprocessSnap);
    return 0;
}

// Enable the SeDebugPrivilege
void EnableDebugPriv( void )
{
    HANDLE hToken;
    LUID sedebugnameValue;
    TOKEN_PRIVILEGES tkp;
    
    // enable the SeDebugPrivilege
    if ( ! OpenProcessToken( GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
    {
        _tprintf( _T("OpenProcessToken() failed, Error = %d SeDebugPrivilege is not available.\n") , GetLastError() );
        return;
    }
    
    if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
    {
        _tprintf( _T("LookupPrivilegeValue() failed, Error = %d SeDebugPrivilege is not available.\n"), GetLastError() );
        CloseHandle( hToken );
        return;
    }
    
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = sedebugnameValue;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
    if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
        _tprintf( _T("AdjustTokenPrivileges() failed, Error = %d SeDebugPrivilege is not available.\n"), GetLastError() );
    
    CloseHandle( hToken );
}

typedef struct _SYSTEM_HANDLE
{
    DWORD    ProcessID;
    WORD    HandleType;
    WORD    HandleNumber;
    DWORD    KernelAddress;
    DWORD    Flags;
} SYSTEM_HANDLE;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
    DWORD            Count;
    SYSTEM_HANDLE    Handles[1];
}SYSTEM_HANDLE_INFORMATION;

typedef DWORD (WINAPI *PNtQueryObject)( HANDLE, DWORD, VOID*, DWORD, VOID* );
typedef DWORD (__stdcall *PNtQuerySystemInformation)( DWORD, VOID*, DWORD, ULONG* );
typedef DWORD (WINAPI *PNtQueryInformationFile)(HANDLE, PVOID,    PVOID, DWORD, DWORD );

PNtQuerySystemInformation NtQuerySystemInformation = (PNtQuerySystemInformation)GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
                    _T("NtQuerySystemInformation") );
PNtQueryObject                NtQueryObject = (PNtQueryObject)GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
                    _T("NtQueryObject") );

PNtQueryInformationFile NtQueryInformationFile = (PNtQueryInformationFile)
GetProcAddress(    GetModuleHandle( _T( "ntdll.dll" ) ),
                    _T("NtQueryInformationFile") );

BOOL IsSupportedHandle( SYSTEM_HANDLE& handle )
{
    //Here you can filter the handles you don't want in the Handle list
    
    OSVERSIONINFOEX osvi;
    BOOL bOsVersionInfoEx;
    
    // Try calling GetVersionEx using the OSVERSIONINFOEX structure,
    // which is supported on Windows 2000.
    //
    // If that fails, try using the OSVERSIONINFO structure.
    
    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    
    bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi);
    
    if( bOsVersionInfoEx == 0 )
    {
        // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
        
        osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
        if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
            return FALSE;
    }

    // Windows 2000 supports everything :)
    if ( osvi.dwMajorVersion >= 5 )
        return TRUE;
    
    //NT4 System process doesn't like if we bother his internal security :)
    if ( handle.ProcessID == 2 && handle.HandleType == 16 )
        return FALSE;
    
    return TRUE;
}

void LPCWSTR2CString( LPCWSTR strW, CString& str )
{
#ifdef UNICODE
    // if it is already UNICODE, no problem
    str = strW;
#else
    str = _T("");
    
    TCHAR* actChar = (TCHAR*)strW;
    
    if ( actChar == _T('\0') )
        return;
    
    ULONG len = wcslen(strW) + 1;
    TCHAR* pBuffer = new TCHAR[ len ];
    TCHAR* pNewStr = pBuffer;
    
    while ( len-- )
    {
        *(pNewStr++) = *actChar;
        actChar += 2;
    }
    
    str = pBuffer;
    
    delete [] pBuffer;
#endif
}

//Information functions
BOOL GetTypeToken( HANDLE h, CString& str, DWORD processId )
{
    ULONG size = 0x2000;
    UCHAR* lpBuffer = NULL;
    BOOL ret = FALSE;
    
    HANDLE handle;
    HANDLE hRemoteProcess = NULL;
    BOOL remote = processId != GetCurrentProcessId();
    
    if ( remote )
    {
        // Open the remote process
        hRemoteProcess = OpenProcess(PROCESS_DUP_HANDLE, TRUE, processId );
        
        if ( hRemoteProcess == NULL )
            return FALSE;
        
        // Duplicate the remote handle for our process
        ::DuplicateHandle( hRemoteProcess, h,    GetCurrentProcess(), &handle,    0, FALSE, DUPLICATE_SAME_ACCESS );

    }
    else
        handle = h;
    
    // Query the info size
    NtQueryObject( handle, 2, NULL, 0, &size );
    
    lpBuffer = new UCHAR[size];
    
    // Query the info size ( type )
    if ( NtQueryObject( handle, 2, lpBuffer, size, NULL ) == 0 )
    {
        str = _T("");
        LPCWSTR2CString( (LPCWSTR)(lpBuffer+0x60), str );
        
        ret = TRUE;
    }
    
    if ( remote )
    {
        if ( hRemoteProcess != NULL )
            CloseHandle( hRemoteProcess );
        
        if ( handle != NULL )
            CloseHandle( handle );
    }
    
    if ( lpBuffer != NULL )
        delete [] lpBuffer;
    
    return ret;
}
//由文件handle 得到其盘符
//成功 返回盘符大写字母 失败返回0
char GetHandleLetter(HANDLE h)
{
    BY_HANDLE_FILE_INFORMATION lpFileInformation;
    if(FALSE == GetFileInformationByHandle(h, &lpFileInformation))
        return 0;
    
    char szDisk[MAX_PATH] = {0};
    DWORD dwLength = GetLogicalDriveStrings(MAX_PATH, szDisk);
    for (DWORD i=0; i<dwLength; i++)
    {
        char szRealDisk[MAX_PATH] = {0};
        lstrcpy(szRealDisk, szDisk+i);
        DWORD dwSerial = 0;
        GetVolumeInformation(szRealDisk, NULL, NULL, &dwSerial, NULL, NULL, NULL, NULL);
        if (dwSerial == lpFileInformation.dwVolumeSerialNumber)
        {
            //这里确保返回的是大写盘符
            return szRealDisk[0] & 0xDF;
        }
    }
    return 0;
}

//查看进程文件占有用
void CGetProcFileUsedDlg::OnOK()
{
    CListBox *p = (CListBox*)GetDlgItem(IDC_LIST1);
    char        szProName[MAX_PATH] = {0};
    DWORD        dwPID = 0;
    DWORD        i=0;
    GetDlgItemText(IDC_EDIT1, szProName, MAX_PATH);
    EnableDebugPriv();
    dwPID = GetPIDbyName(szProName);
    if (dwPID == 0)
    {
        AfxMessageBox("输入的进程名有误!");
        return ;
    }
    DWORD size = 0x2000;
    DWORD needed = 0;

    SYSTEM_HANDLE_INFORMATION* pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*)
        VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_READWRITE );
    
    if ( pSysHandleInformation == NULL )
        return ;
    
    //16表示查询 句柄信息
    if (NtQuerySystemInformation(16, pSysHandleInformation, size, &needed) != 0)
    {
        if ( needed == 0 )
        {
            goto __exit;
        }
        // The size was not enough
        VirtualFree( pSysHandleInformation, 0, MEM_RELEASE );
        
        pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*)
                VirtualAlloc( NULL, size = needed + 256, MEM_COMMIT, PAGE_READWRITE );
    }
    if ( pSysHandleInformation == NULL )
        return ;
    if (NtQuerySystemInformation( 16, pSysHandleInformation, size, NULL ) != 0 )
    {
        goto __exit;
    }

    // Iterating through the objects
    for (i = 0; i < pSysHandleInformation->Count; i++ )
    {
        if ( !IsSupportedHandle( pSysHandleInformation->Handles[i] ) )
            continue;
        
        // ProcessId filtering check
        if ( pSysHandleInformation->Handles[i].ProcessID == dwPID)
        {
            CString strType;
            GetTypeToken( (HANDLE)pSysHandleInformation->Handles[i].HandleNumber, strType, dwPID );
            if (strType == "File")
            {
                HANDLE handle;
                HANDLE hTM = OpenProcess(PROCESS_DUP_HANDLE, TRUE, dwPID);
                BOOL bRet = ::DuplicateHandle(hTM,
                    (HANDLE)pSysHandleInformation->Handles[i].HandleNumber,    GetCurrentProcess(),
                    &handle, 0, TRUE, DUPLICATE_SAME_ACCESS);

                UCHAR lpBuffer[0x1000] = {0};
                DWORD iob[2];
                //9表示查询文件路径
                DWORD status = NtQueryInformationFile(handle, iob, lpBuffer, sizeof(lpBuffer), 9 );
                if (status == 0)
                {
                    CString str = GetHandleLetter(handle);
                    CString path = (wchar_t *)(lpBuffer+4);
                    if (str == "")
                    {
                        str = "_";
                    }
                    str += ":";
                    str += path;

                    p->AddString(str);
                    OutputDebugString(str);
                }
                CloseHandle(hTM);
                CloseHandle(handle);
            }
        }
    }

__exit:
    if ( pSysHandleInformation != NULL )
        VirtualFree( pSysHandleInformation, 0, MEM_RELEASE );
}

微信小程序扫码登陆

文章评论

1126人参与,0条评论