我的博客小站

VerifyFile验证文件签名

摘自金山pcmanager:http://code.ijinshan.com/trac/browser/pcmanager/src/publish/communits?order=name

功能只适用于2000和xp,win7下不行。

// testst.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <WinTrust.h>
#include <SoftPub.h>
//#pragma comment(lib, "WinTrust.lib")



#ifndef _VERIFY_FILE_INC_
#define _VERIFY_FILE_INC_
HANDLE  AcquireVerifyHandle();
void    ReleaseVerifyHandle(HANDLE hHandle);
// 返回 0 失败
// 返回 1 通过 win 签名
// 返回 2 通过 cat 签名
int     VerifyFile(HANDLE hHandle, LPCTSTR lpPath);
BOOL    IsVerifiedFile(LPCTSTR lpPath);
#endif /* _VERIFY_FILE_INC_ */


typedef HANDLE HCATADMIN;
typedef HANDLE HCATINFO;
typedef BOOL (WINAPI* PFN_CryptCATAdminAcquireContext)(HCATADMIN* phCatAdmin, const GUID* pgSubsystem, DWORD dwFlags);
typedef BOOL (WINAPI* PFN_CryptCATAdminReleaseContext)(HCATADMIN hCatAdmin, DWORD dwFlags);
typedef BOOL (WINAPI* PFN_CryptCATAdminCalcHashFromFileHandle)(HANDLE hFile, DWORD* pcbHash, BYTE* pbHash, DWORD dwFlags);
typedef HCATINFO (WINAPI* PFN_CryptCATAdminEnumCatalogFromHash)(HCATADMIN hCatAdmin, BYTE* pbHash, DWORD cbHash, DWORD dwFlags, HCATINFO* phPrevCatInfo );
typedef BOOL (WINAPI* PFN_CryptCATAdminReleaseCatalogContext)(HCATADMIN hCatAdmin, HCATINFO hCatInfo, DWORD dwFlags);
typedef LONG (WINAPI* PFN_WinVerifyTrust)(HWND hWnd, GUID* pgActionID, WINTRUST_DATA* pWinTrustData);
static PFN_CryptCATAdminAcquireContext __pfnCryptCATAdminAcquireContext = NULL;
static PFN_CryptCATAdminReleaseContext __pfnCryptCATAdminReleaseContext = NULL;
static PFN_CryptCATAdminCalcHashFromFileHandle __pfnCryptCATAdminCalcHashFromFileHandle = NULL;
static PFN_CryptCATAdminEnumCatalogFromHash __pfnCryptCATAdminEnumCatalogFromHash = NULL;
static PFN_CryptCATAdminReleaseCatalogContext __pfnCryptCATAdminReleaseCatalogContext = NULL;
static PFN_WinVerifyTrust __pfnWinVerifyTrust = NULL;
static int LoadWinTrustDll()
{
    static int nResult = 0;

    if ( nResult == 0 )
    {
        nResult = -1;
        HMODULE hModule = LoadLibraryW(SP_POLICY_PROVIDER_DLL_NAME);
        if ( hModule != NULL )
        {
            (FARPROC&)__pfnCryptCATAdminAcquireContext = GetProcAddress(hModule, "CryptCATAdminAcquireContext");
            if ( __pfnCryptCATAdminAcquireContext == NULL )
            {
                goto _Failed_Exit;
            }
            (FARPROC&)__pfnCryptCATAdminReleaseContext = GetProcAddress(hModule, "CryptCATAdminReleaseContext");
            if ( __pfnCryptCATAdminReleaseContext == NULL )
            {
                goto _Failed_Exit;
            }
            (FARPROC&)__pfnCryptCATAdminCalcHashFromFileHandle = GetProcAddress(hModule, "CryptCATAdminCalcHashFromFileHandle");
            if ( __pfnCryptCATAdminCalcHashFromFileHandle == NULL )
            {
                goto _Failed_Exit;
            }
            (FARPROC&)__pfnCryptCATAdminEnumCatalogFromHash = GetProcAddress(hModule, "CryptCATAdminEnumCatalogFromHash");
            if ( __pfnCryptCATAdminEnumCatalogFromHash == NULL )
            {
                goto _Failed_Exit;
            }
            (FARPROC&)__pfnCryptCATAdminReleaseCatalogContext = GetProcAddress(hModule, "CryptCATAdminReleaseCatalogContext");
            if ( __pfnCryptCATAdminReleaseCatalogContext == NULL )
            {
                goto _Failed_Exit;
            }
            (FARPROC&)__pfnWinVerifyTrust = GetProcAddress(hModule, "WinVerifyTrust");
            if ( __pfnWinVerifyTrust == NULL )
            {
                goto _Failed_Exit;
            }
            nResult = 1;
        }
_Failed_Exit:;
    }
    return nResult;
}
static BOOL CalcCatHash(LPCWSTR lpFileName, DWORD* pcbHash, BYTE** ppbHash)
{
    HANDLE hFile = CreateFileW(lpFileName, 
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        0, 
        NULL
        );
    if ( hFile != INVALID_HANDLE_VALUE )
    {
        DWORD Err;
        LPBYTE Hash = NULL;
        DWORD HashSize = 0;

        //
        // Start out with a hash buffer size that should be large enough for
        // most requests.
        //
        HashSize = 100;

        do
        {
            Hash = (LPBYTE)LocalAlloc(LPTR, HashSize);

            if(!Hash)
            {
                Err = ERROR_NOT_ENOUGH_MEMORY;
                break;
            }

            if( __pfnCryptCATAdminCalcHashFromFileHandle(hFile, &HashSize, Hash, 0))
            {
                Err = NO_ERROR;
            }
            else
            {
                Err = GetLastError();

                //
                // If this API did screw up and not set last error, go ahead
                // and set something.
                //
                if(Err == NO_ERROR)
                {
                    Err = ERROR_INVALID_DATA;
                }

                LocalFree(Hash);

                if(Err != ERROR_INSUFFICIENT_BUFFER)
                {
                    //
                    // The API failed for some reason other than
                    // buffer-too-small.  We gotta bail.
                    //
                    Hash = NULL;  // reset this so we won't try to free it later
                    break;
                }
            }
        } while(Err != NO_ERROR);

        CloseHandle(hFile);
        if(Err == NO_ERROR)
        {
            *pcbHash = HashSize;
            *ppbHash = Hash;
            return TRUE;
        }
    }
    *pcbHash = 0;
    *ppbHash = NULL;
    return FALSE;
}
HANDLE  AcquireVerifyHandle()
{
    if ( LoadWinTrustDll() != 1 )
    {
        return NULL;
    }

    HANDLE hHandle = NULL;
    if ( __pfnCryptCATAdminAcquireContext(&hHandle, NULL, 0) )
    {
        return hHandle;
    }
    return NULL;
}
void ReleaseVerifyHandle(HANDLE hHandle)
{
    if ( LoadWinTrustDll() != 1 )
    {
        return ;
    }
    __pfnCryptCATAdminReleaseContext(hHandle, 0);
}
int VerifyFile(HANDLE hHandle, LPCTSTR lpPath)
{
    int nResult = 0;
    if ( LoadWinTrustDll() != 1 )
    {
        return 0;
    }
    WINTRUST_DATA wd = { 0 };
    WINTRUST_FILE_INFO wfi = { 0 };
    GUID guid = WINTRUST_ACTION_GENERIC_VERIFY_V2;

    wfi.cbStruct = sizeof(WINTRUST_FILE_INFO); 
    wfi.pcwszFilePath = lpPath; 

    wd.cbStruct = sizeof(WINTRUST_DATA);
    wd.dwUnionChoice = WTD_CHOICE_FILE;
    wd.pFile = &wfi;
    wd.dwUIChoice = WTD_UI_NONE;
    wd.fdwRevocationChecks = WTD_REVOKE_NONE;
    wd.dwStateAction = WTD_STATEACTION_AUTO_CACHE;
    wd.dwProvFlags = WTD_REVOCATION_CHECK_NONE;
    if ( __pfnWinVerifyTrust(NULL, &guid , &wd) == 0 ) // pe Ç©Ãû
    {
        MessageBox(0,_T("1"),0,0);
        nResult = 1;
    }
    else
    {
        if ( hHandle != NULL )
        {
            // cat Ç©Ãû
            LPBYTE lpHash;
            DWORD dwHashSize;

            if ( CalcCatHash(lpPath, &dwHashSize, &lpHash))
            {
                HANDLE hCatalogContext = __pfnCryptCATAdminEnumCatalogFromHash(hHandle, lpHash, dwHashSize, 0, NULL);
                if ( NULL != hCatalogContext)
                {
                    __pfnCryptCATAdminReleaseCatalogContext(hHandle, hCatalogContext, 0);
                    MessageBox(0,_T("2"),0,0);
                    nResult = 2;
                }

                LocalFree(lpHash);
                lpHash = NULL;
            }
        }
    }
    return nResult;
}
BOOL IsVerifiedFile(LPCTSTR lpPath)
{
    BOOL bResult = FALSE;

    HANDLE hHandle = AcquireVerifyHandle();
    if ( hHandle != NULL )
    {
        __try
        {
            // Ñé֤ǩÃûÒì³££¬±ÀÀ£ÔÚϵͳº¯ÊýÀïÃæ
            // ÔÝʱÎÞ·¨È·¶¨Ô­Òò
            if ( VerifyFile(hHandle, lpPath) != 0 )
            {
                bResult = TRUE;
            }
        }
        __except ( EXCEPTION_EXECUTE_HANDLER )
        {
        }

        ReleaseVerifyHandle(hHandle);
    }
    return bResult;
}

int _tmain(int argc, _TCHAR* argv[])
{
    IsVerifiedFile(_T("C:\\Windows\\System32\\kernel32.dll"));
    return 0;
}

posted on 2012-04-17 15:48  BIGSING  阅读(2490)  评论(0编辑  收藏  举报

导航

我的博客小站