unit
TrustCheckMod;
interface
function
FileIsTrusted(
const
sFilename:
string
):
Boolean
;
implementation
uses
Windows, SysUtils;
const
WTD_CHOICE_FILE =
1
;
WTD_CHOICE_CATALOG =
2
;
WTD_STATEACTION_IGNORE =
0
;
WTD_STATEACTION_VERIFY =
1
;
WTD_UI_NONE =
2
;
WTD_REVOKE_NONE =
0
;
WTD_SAFER_FLAG =
256
;
WINTRUST_ACTION_GENERIC_VERIFY_V2: TGUID =
'{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}'
;
type
CATALOG_INFO =
record
cbStruct: DWORD;
sCatalogFile:
array
[
0..
MAX_PATH]
of
WCHAR;
end
;
PCATALOG_INFO = ^CATALOG_INFO;
WINTRUST_CATALOG_INFO =
record
cbStruct: DWORD;
dwCatalogVersion: DWORD;
pcwszCatalogFilePath: LPCWSTR;
pcwszMemberTag: LPCWSTR;
pcwszMemberFilePath: LPCWSTR;
hMemberFile: THANDLE;
end
;
PWINTRUST_CATALOG_INFO = ^WINTRUST_CATALOG_INFO;
WINTRUST_FILE_INFO =
record
cbStruct: DWORD;
pcwszFilePath: LPCWSTR;
pgKnownSubject: PGUID;
hFile: THANDLE;
end
;
PWINTRUST_FILE_INFO = ^WINTRUST_FILE_INFO;
WINTRUST_DATA =
packed
record
cbStruct: DWORD;
pPolicyCallbackData:
pointer
;
pSIPClientData:
pointer
;
dwUIChoice: DWORD;
fdwRevocationChecks: DWORD;
dwUnionChoice: DWORD;
pWTDINFO:
pointer
;
pFake:
pointer
;
pFake1:
pointer
;
pFake2:
pointer
;
pFake3:
pointer
;
dwStateAction: DWORD;
hWVTStateData: THANDLE;
pwszURLReference: PWChar;
dwProvFlags: DWORD;
dwUIContext: DWORD;
end
;
PWINTRUST_DATA = ^WINTRUST_DATA;
HCatAdmin = THANDLE;
PHCatAdmin = ^HCatAdmin;
var
hLibWintrust: THANDLE;
CryptCATAdminAcquireContext:
function
(PHCatAdmin: PHCatAdmin; pgSubsystem: PGUID; dwFlags: DWORD): BOOL; stdcall;
CryptCATAdminReleaseContext:
function
(HCatAdmin: HCatAdmin; dwFlags: DWORD): BOOL; stdcall;
CryptCATAdminCalcHashFromFileHandle:
function
(hFile: THANDLE; pHashSize: PDWORD; pbHash: PByteArray; dwFlags: DWORD): BOOL; stdcall;
CryptCATAdminEnumCatalogFromHash:
function
(HCatAdmin: HCatAdmin; pbHash: PByteArray; pHashSize: DWORD; dwFlags: DWORD; phPrevCatInfo: PHandle): THANDLE; stdcall;
CryptCATCatalogInfoFromContext:
function
(hCatInfo: THANDLE; psCatInfo: PCATALOG_INFO; dwFlags: DWORD): BOOL; stdcall;
CryptCATAdminReleaseCatalogContext:
function
(HCatAdmin: HCatAdmin; hCatInfo: THANDLE; dwFlags: DWORD): BOOL; stdcall;
WinVerifyTrust:
function
(hwnd: THANDLE; pgActionID: PGUID; pWintrustData: PWINTRUST_DATA):
Longint
; stdcall;
function
FileIsTrusted(
const
sFilename:
string
):
Boolean
;
var
aByteHash:
array
[
0..255
]
of
Byte
;
iByteCount:
Integer
;
hCatAdminContext: HCatAdmin;
WTrustData: WINTRUST_DATA;
WTDCatalogInfo: WINTRUST_CATALOG_INFO;
WTDFileInfo: WINTRUST_FILE_INFO;
CatalogInfo: CATALOG_INFO;
hFile: THANDLE;
hCatalogContext: THANDLE;
swFilename:
WideString
;
swMemberTag:
WideString
;
ilRet:
Longint
;
x:
Integer
;
begin
Result :=
False
;
if
FileExists(sFilename) =
False
then
Exit;
swFilename := sFilename;
ZeroMemory(@CatalogInfo, SizeOf(CatalogInfo));
ZeroMemory(@WTDFileInfo, SizeOf(WTDFileInfo));
ZeroMemory(@WTDCatalogInfo, SizeOf(WTDCatalogInfo));
ZeroMemory(@WTrustData, SizeOf(WTrustData));
if
CryptCATAdminAcquireContext(@hCatAdminContext,
nil
,
0
) =
False
then
Exit;
hFile := CreateFile(
PChar
(
string
(sFilename)), GENERIC_READ, FILE_SHARE_READ,
nil
, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
0
);
if
hFile = INVALID_HANDLE_VALUE
then
Exit;
iByteCount := SizeOf(aByteHash);
CryptCATAdminCalcHashFromFileHandle(hFile, @iByteCount, @aByteHash,
0
);
for
x :=
0
to
iByteCount -
1
do
begin
swMemberTag := swMemberTag + IntToHex(aByteHash[x],
2
);
end
;
CloseHandle(hFile);
hCatalogContext := CryptCATAdminEnumCatalogFromHash(hCatAdminContext, @aByteHash, iByteCount,
0
,
nil
);
if
hCatalogContext =
0
then
begin
WTDFileInfo
.
cbStruct := SizeOf(WTDFileInfo);
WTDFileInfo
.
pcwszFilePath :=
PWideChar
(swFilename);
WTDFileInfo
.
pgKnownSubject :=
nil
;
WTDFileInfo
.
hFile :=
0
;
WTrustData
.
cbStruct := SizeOf(WTrustData);
WTrustData
.
dwUnionChoice := WTD_CHOICE_FILE;
WTrustData
.
pWTDINFO := @WTDFileInfo;
WTrustData
.
dwUIChoice := WTD_UI_NONE;
WTrustData
.
fdwRevocationChecks := WTD_REVOKE_NONE;
WTrustData
.
dwStateAction := WTD_STATEACTION_IGNORE;
WTrustData
.
dwProvFlags := WTD_SAFER_FLAG;
WTrustData
.
hWVTStateData :=
0
;
WTrustData
.
pwszURLReference :=
nil
;
end
else
begin
CryptCATCatalogInfoFromContext(hCatalogContext, @CatalogInfo,
0
);
WTDCatalogInfo
.
cbStruct := SizeOf(WTDCatalogInfo);
WTDCatalogInfo
.
pcwszCatalogFilePath := CatalogInfo
.
sCatalogFile;
WTDCatalogInfo
.
pcwszMemberFilePath :=
PWideChar
(swFilename);
WTDCatalogInfo
.
pcwszMemberTag :=
PWideChar
(swMemberTag);
WTrustData
.
cbStruct := SizeOf(WTrustData);
WTrustData
.
dwUnionChoice := WTD_CHOICE_CATALOG;
WTrustData
.
pWTDINFO := @WTDCatalogInfo;
WTrustData
.
dwUIChoice := WTD_UI_NONE;
WTrustData
.
fdwRevocationChecks := WTD_REVOKE_NONE;
WTrustData
.
pPolicyCallbackData :=
nil
;
WTrustData
.
pSIPClientData :=
nil
;
WTrustData
.
dwStateAction := WTD_STATEACTION_VERIFY;
WTrustData
.
dwProvFlags :=
0
;
WTrustData
.
hWVTStateData :=
0
;
WTrustData
.
pwszURLReference :=
nil
;
end
;
ilRet := WinVerifyTrust(INVALID_HANDLE_VALUE, @WINTRUST_ACTION_GENERIC_VERIFY_V2, @WTrustData);
if
ilRet =
0
then
begin
Result :=
True
end
else
Result :=
False
;
CryptCATAdminReleaseCatalogContext(hCatAdminContext, hCatalogContext,
0
);
CryptCATAdminReleaseContext(hCatAdminContext,
0
);
end
;
initialization
hLibWintrust := LoadLibrary(
'wintrust.dll'
);
if
hLibWintrust >=
32
then
begin
CryptCATAdminAcquireContext := GetProcAddress(hLibWintrust,
'CryptCATAdminAcquireContext'
);
CryptCATAdminReleaseContext := GetProcAddress(hLibWintrust,
'CryptCATAdminReleaseContext'
);
CryptCATAdminCalcHashFromFileHandle := GetProcAddress(hLibWintrust,
'CryptCATAdminCalcHashFromFileHandle'
);
CryptCATAdminEnumCatalogFromHash := GetProcAddress(hLibWintrust,
'CryptCATAdminEnumCatalogFromHash'
);
CryptCATCatalogInfoFromContext := GetProcAddress(hLibWintrust,
'CryptCATCatalogInfoFromContext'
);
CryptCATAdminReleaseCatalogContext := GetProcAddress(hLibWintrust,
'CryptCATAdminReleaseCatalogContext'
);
WinVerifyTrust := GetProcAddress(hLibWintrust,
'WinVerifyTrust'
);
end
;
finalization
FreeLibrary(hLibWintrust);
end
.