Hopefully an API guru will see what's wrong here.
Note: The code is mostly based on this article: https://docs.microsoft.com/en-us/window ... -a-pe-file
Code: Select all
EnableExplicit
#WINTRUST_MAX_HEADER_BYTES_TO_MAP_DEFAULT = $00A00000
#WINTRUST_MAX_HASH_BYTES_TO_MAP_DEFAULT = $00100000
#WTD_UI_ALL = 1
#WTD_UI_NONE = 2
#WTD_UI_NOBAD = 3
#WTD_UI_NOGOOD = 4
#WTD_REVOKE_NONE = $00000000
#WTD_REVOKE_WHOLECHAIN = $00000001
#WTD_CHOICE_FILE = 1
#WTD_CHOICE_CATALOG = 2
#WTD_CHOICE_BLOB = 3
#WTD_CHOICE_SIGNER = 4
#WTD_CHOICE_CERT = 5
#WTD_STATEACTION_IGNORE = $00000000
#WTD_STATEACTION_VERIFY = $00000001
#WTD_STATEACTION_CLOSE = $00000002
#WTD_STATEACTION_AUTO_CACHE = $00000003
#WTD_STATEACTION_AUTO_CACHE_FLUSH = $00000004
#WTD_PROV_FLAGS_MASK = $0000FFFF
#WTD_USE_IE4_TRUST_FLAG = $00000001
#WTD_NO_IE4_CHAIN_FLAG = $00000002
#WTD_NO_POLICY_USAGE_FLAG = $00000004
#WTD_REVOCATION_CHECK_NONE = $00000010
#WTD_REVOCATION_CHECK_END_CERT = $00000020
#WTD_REVOCATION_CHECK_CHAIN = $00000040
#WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = $00000080
#WTD_SAFER_FLAG = $00000100
#WTD_HASH_ONLY_FLAG = $00000200
#WTD_USE_DEFAULT_OSVER_CHECK = $00000400
#WTD_LIFETIME_SIGNING_FLAG = $00000800
#WTD_CACHE_ONLY_URL_RETRIEVAL = $00001000
#WTD_UICONTEXT_EXECUTE = 0
#WTD_UICONTEXT_INSTALL = 1
#WTCI_DONT_OPEN_STORES = $00000001
#WTCI_OPEN_ONLY_ROOT = $00000002
#WTCI_USE_LOCAL_MACHINE = $00000004
#WTPF_TRUSTTEST = $00000020
#WTPF_TESTCANBEVALID = $00000080
#WTPF_IGNOREEXPIRATION = $00000100
#WTPF_IGNOREREVOKATION = $00000200
#WTPF_OFFLINEOK_IND = $00000400
#WTPF_OFFLINEOK_COM = $00000800
#WTPF_OFFLINEOKNBU_IND = $00001000
#WTPF_OFFLINEOKNBU_COM = $00002000
#WTPF_VERIFY_V1_OFF = $00010000
#WTPF_IGNOREREVOCATIONONTS = $00020000
#WTPF_ALLOWONLYPERTRUST = $00040000
#TRUSTERROR_STEP_WVTPARAMS = 0
#TRUSTERROR_STEP_FILEIO = 2
#TRUSTERROR_STEP_SIP = 3
#TRUSTERROR_STEP_SIPSUBJINFO = 5
#TRUSTERROR_STEP_CATALOGFILE = 6
#TRUSTERROR_STEP_CERTSTORE = 7
#TRUSTERROR_STEP_MESSAGE = 8
#TRUSTERROR_STEP_MSG_SIGNERCOUNT = 9
#TRUSTERROR_STEP_MSG_INNERCNTTYPE = 10
#TRUSTERROR_STEP_MSG_INNERCNT = 11
#TRUSTERROR_STEP_MSG_STORE = 12
#TRUSTERROR_STEP_MSG_SIGNERINFO = 13
#TRUSTERROR_STEP_MSG_SIGNERCERT = 14
#TRUSTERROR_STEP_MSG_CERTCHAIN = 15
#TRUSTERROR_STEP_MSG_COUNTERSIGINFO = 16
#TRUSTERROR_STEP_MSG_COUNTERSIGCERT = 17
#TRUSTERROR_STEP_VERIFY_MSGHASH = 18
#TRUSTERROR_STEP_VERIFY_MSGINDIRECTDATA = 19
#TRUSTERROR_STEP_FINAL_WVTINIT = 30
#TRUSTERROR_STEP_FINAL_INITPROV = 31
#TRUSTERROR_STEP_FINAL_OBJPROV = 32
#TRUSTERROR_STEP_FINAL_SIGPROV = 33
#TRUSTERROR_STEP_FINAL_CERTPROV = 34
#TRUSTERROR_STEP_FINAL_CERTCHKPROV = 35
#TRUSTERROR_STEP_FINAL_POLICYPROV = 36
#TRUSTERROR_STEP_FINAL_UIPROV = 37
#TRUSTERROR_MAX_STEPS = 38
#CPD_USE_NT5_CHAIN_FLAG = $80000000
#CPD_REVOCATION_CHECK_NONE = $00010000
#CPD_REVOCATION_CHECK_END_CERT = $00020000
#CPD_REVOCATION_CHECK_CHAIN = $00040000
#CPD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = $00080000
#CPD_UISTATE_MODE_PROMPT = $00000000
#CPD_UISTATE_MODE_BLOCK = $00000001
#CPD_UISTATE_MODE_ALLOW = $00000002
#CPD_UISTATE_MODE_MASK = $00000003
#CERT_CONFIDENCE_SIG = $10000000
#CERT_CONFIDENCE_TIME = $01000000
#CERT_CONFIDENCE_TIMENEST = $00100000
#CERT_CONFIDENCE_AUTHIDEXT = $00010000
#CERT_CONFIDENCE_HYGIENE = $00001000
#CERT_CONFIDENCE_HIGHEST = $11111000
#DWACTION_ALLOCANDFILL = 1
#DWACTION_FREE = 2
#szOID_TRUSTED_CODESIGNING_CA_LIST = "1.3.6.1.4.1.311.2.2.1"
#szOID_TRUSTED_CLIENT_AUTH_CA_LIST = "1.3.6.1.4.1.311.2.2.2"
#szOID_TRUSTED_SERVER_AUTH_CA_LIST = "1.3.6.1.4.1.311.2.2.3"
#SPC_TIME_STAMP_REQUEST_OBJID = "1.3.6.1.4.1.311.3.2.1"
#SPC_INDIRECT_DATA_OBJID = "1.3.6.1.4.1.311.2.1.4"
#SPC_SP_AGENCY_INFO_OBJID = "1.3.6.1.4.1.311.2.1.10"
#SPC_STATEMENT_TYPE_OBJID = "1.3.6.1.4.1.311.2.1.11"
#SPC_SP_OPUS_INFO_OBJID = "1.3.6.1.4.1.311.2.1.12"
#SPC_CERT_EXTENSIONS_OBJID = "1.3.6.1.4.1.311.2.1.14"
#SPC_PE_IMAGE_DATA_OBJID = "1.3.6.1.4.1.311.2.1.15"
#SPC_RAW_FILE_DATA_OBJID = "1.3.6.1.4.1.311.2.1.18"
#SPC_STRUCTURED_STORAGE_DATA_OBJID = "1.3.6.1.4.1.311.2.1.19"
#SPC_JAVA_CLASS_DATA_OBJID = "1.3.6.1.4.1.311.2.1.20"
#SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID = "1.3.6.1.4.1.311.2.1.21"
#SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID = "1.3.6.1.4.1.311.2.1.22"
#SPC_CAB_DATA_OBJID = "1.3.6.1.4.1.311.2.1.25"
#SPC_GLUE_RDN_OBJID = "1.3.6.1.4.1.311.2.1.25"
#SPC_MINIMAL_CRITERIA_OBJID = "1.3.6.1.4.1.311.2.1.26"
#SPC_FINANCIAL_CRITERIA_OBJID = "1.3.6.1.4.1.311.2.1.27"
#SPC_LINK_OBJID = "1.3.6.1.4.1.311.2.1.28"
#SPC_SIGINFO_OBJID = "1.3.6.1.4.1.311.2.1.30"
#SPC_PE_IMAGE_PAGE_HASHES_V1_OBJID = "1.3.6.1.4.1.311.2.3.1"
#SPC_PE_IMAGE_PAGE_HASHES_V2_OBJID = "1.3.6.1.4.1.311.2.3.2"
#CAT_NAMEVALUE_OBJID = "1.3.6.1.4.1.311.12.2.1"
#CAT_MEMBERINFO_OBJID = "1.3.6.1.4.1.311.12.2.2"
#SPC_SP_AGENCY_INFO_STRUCT =(2000)
#SPC_MINIMAL_CRITERIA_STRUCT =(2001)
#SPC_FINANCIAL_CRITERIA_STRUCT =(2002)
#SPC_INDIRECT_DATA_CONTENT_STRUCT =(2003)
#SPC_PE_IMAGE_DATA_STRUCT =(2004)
#SPC_LINK_STRUCT =(2005)
#SPC_STATEMENT_TYPE_STRUCT =(2006)
#SPC_SP_OPUS_INFO_STRUCT =(2007)
#SPC_CAB_DATA_STRUCT =(2008)
#SPC_JAVA_CLASS_DATA_STRUCT =(2009)
#SPC_SIGINFO_STRUCT =(2130)
#CAT_NAMEVALUE_STRUCT =(2221)
#CAT_MEMBERINFO_STRUCT =(2222)
#SPC_UUID_LENGTH = 16
#WIN_CERT_REVISION_1_0 =($0100)
#WIN_CERT_REVISION_2_0 =($0200)
#WIN_CERT_TYPE_X509 =($0001)
#WIN_CERT_TYPE_PKCS_SIGNED_DATA =($0002)
#WIN_CERT_TYPE_RESERVED_1 =($0003)
#WIN_CERT_TYPE_TS_STACK_SIGNED =($0004)
#WT_TRUSTDBDIALOG_NO_UI_FLAG = $00000001
#WT_TRUSTDBDIALOG_ONLY_PUB_TAB_FLAG = $00000002
#WT_TRUSTDBDIALOG_WRITE_LEGACY_REG_FLAG = $00000100
#WT_TRUSTDBDIALOG_WRITE_IEAK_STORE_FLAG = $00000200
Structure WINTRUST_DATA
cbStruct.l
*pPolicyCallbackData
*pSIPClientData
dwUIChoice.l
fdwRevocationChecks.l
dwUnionChoice.l
*pPointer
dwStateAction.l
hWVTStateData.l
*pwszURLReference
dwProvFlags.l
dwUIContext.l
EndStructure
Structure WINTRUST_FILE_INFO
cbStruct.l
*pcwszFilePath
hFile.l
*pgKnownSubject
EndStructure
Structure WINTRUST_CATALOG_INFO
cbStruct.l
dwCatalogVersion.l
*pcwszCatalogFilePath
*pcwszMemberTag
*pcwszMemberFilePath
hMemberFile.l
EndStructure
Structure CATALOG_INFO
cbStruct.l
wszCatalogFile.b[520]
EndStructure
#WTD_CHOICE_FILE = 1
#WTD_CHOICE_CATALOG = 2
#WTD_UI_NONE = 2
#WTD_REVOKE_NONE = 0
#WTD_STATEACTION_IGNORE = 0
#WTD_STATEACTION_VERIFY = 1
#WTD_SAFER_FLAG = 256
define CLIB
CLIB=OpenLibrary(#PB_Any,"wintrust.dll")
Prototype CryptCATAdminAcquireContext(*phCatAdmin, *pgSubsystem, dwFlags.l)
Prototype CryptCATAdminReleaseContext(hCatAdmin.l, dwFlags.l)
Prototype CryptCATAdminCalcHashFromFileHandle(hFile.l, *pcbHash, *pbHash, dwFlags.l)
Prototype CryptCATAdminEnumCatalogFromHash(hCatAdmin.l, *pbHash, cbHash.l, dwFlags.l, *phPrevCatInfo)
Prototype CryptCATCatalogInfoFromContext(hCatInfo.l, *psCatInfo, dwFlags.l)
Prototype CryptCATAdminReleaseCatalogContext(hCatAdmin.l, hCatInfo.l, dwFlags.l)
Prototype WinVerifyTrust(HWND.l, *pgActionID, *pWVTData)
global CryptCATAdminAcquireContext.CryptCATAdminAcquireContext = GetFunction(CLIB,"CryptCATAdminAcquireContext")
global CryptCATAdminReleaseContext.CryptCATAdminReleaseContext = GetFunction(CLIB,"CryptCATAdminReleaseContext")
global CryptCATAdminCalcHashFromFileHandle.CryptCATAdminCalcHashFromFileHandle = GetFunction(CLIB,"CryptCATAdminCalcHashFromFileHandle")
global CryptCATAdminEnumCatalogFromHash.CryptCATAdminEnumCatalogFromHash = GetFunction(CLIB,"CryptCATAdminEnumCatalogFromHash")
global CryptCATCatalogInfoFromContext.CryptCATCatalogInfoFromContext = GetFunction(CLIB,"CryptCATCatalogInfoFromContext")
global CryptCATAdminReleaseCatalogContext.CryptCATAdminReleaseCatalogContext = GetFunction(CLIB,"CryptCATAdminReleaseCatalogContext")
global WinVerifyTrust.WinVerifyTrust = GetFunction(CLIB,"WinVerifyTrust")
debug WinVerifyTrust
Procedure CheckFileTrust(FilePath.s)
Define bRet.l
Define wd.WINTRUST_DATA
Define wfi.WINTRUST_FILE_INFO
Define wci.WINTRUST_CATALOG_INFO
Define ci.CATALOG_INFO
Define hCatAdmin.i
Define bRet.l, hFile.l
Define hr.l
Define pszMemberTag.s
Define dwCnt.l
Dim byHash.b(99)
Define dw.l
Define hCatInfo.l
ClearStructure(@wd, WINTRUST_DATA)
ClearStructure(@wfi, WINTRUST_FILE_INFO)
ClearStructure(@wci, WINTRUST_CATALOG_INFO)
ClearStructure(@ci, CATALOG_INFO)
bRet = #False
hCatAdmin = #Null
If(Not(CryptCATAdminAcquireContext(@hCatAdmin, #Null, 0)))
debug "!!!!"
ProcedureReturn #False
EndIf
;********************
;Open file
;********************
hFile = CreateFile_(@FilePath, #GENERIC_READ, #FILE_SHARE_READ, #Null, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, #Null)
If (hFile = #INVALID_HANDLE_VALUE)
Debug ("CheckFileTrust(): CreateFile FAILED, GetLastError = " + Hex(GetLastError_()))
CryptCATAdminReleaseContext(hCatAdmin, 0)
ProcedureReturn #False
EndIf
dwCnt = 100
CryptCATAdminCalcHashFromFileHandle(hFile, @dwCnt, @byHash(), 0)
;********************
;Close file
;********************
CloseHandle_(hFile)
;********************
;Compute member tag
;********************
For dw = 0 To dwCnt - 1
pszMemberTag + Right("0" + Hex(byHash(dw)), 2)
Next
Debug ("CheckFileTrust(): MemberTag = " + pszMemberTag)
hCatInfo = CryptCATAdminEnumCatalogFromHash(hCatAdmin, @byHash(), dwCnt, 0, #Null)
If (hCatInfo = #Null)
Debug ("CheckFileTrust(): CryptCATAdminEnumCatalogFromHash FAILED, start verifying embedded signature.")
wd\cbStruct = SizeOf(wd)
; Use default code signing EKU.
wd\pPolicyCallbackData = #Null
; No data to pass to SIP.
wd\pSIPClientData = #Null
; Disable WVT UI.
wd\dwUIChoice = #WTD_UI_NONE
; No revocation checking.
wd\fdwRevocationChecks = #WTD_REVOKE_NONE
; Verify an embedded signature on a file.
wd\dwUnionChoice = #WTD_CHOICE_FILE
; Default verification.
wd\dwStateAction = #WTD_STATEACTION_IGNORE
; Not applicable for default verification of embedded signature.
wd\hWVTStateData = #Null
; Not used.
wd\pwszURLReference = #Null
; Default.
wd\dwProvFlags = #WTD_SAFER_FLAG
; This is not applicable if there is no UI because it changes
; the UI to accommodate running applications instead of
; installing applications.
wd\dwUIContext = #Null
; Set pFile.
wfi\cbStruct = SizeOf(WINTRUST_FILE_INFO)
wfi\pcwszFilePath = @FilePath
wfi\hFile = #Null
wfi\pgKnownSubject = #Null
wd\pPointer = @wfi
Else
If(Not(CryptCATCatalogInfoFromContext(hCatInfo, @ci, 0)))
Debug ("CheckFileTrust(): CryptCATCatalogInfoFromContext FAILED, GetLastError = " + Hex(GetLastError_()))
EndIf
wci\cbStruct = SizeOf(wci)
wci\pcwszCatalogFilePath = @ci\wszCatalogFile[0]
debug peekS(wci\pcwszCatalogFilePath)
debug FilePath
wci\pcwszMemberFilePath = @FilePath
wci\pcwszMemberTag = @pszMemberTag
wd\cbStruct = SizeOf(wd)
wd\dwUnionChoice = #WTD_CHOICE_CATALOG
wd\pPointer = @wci
wd\dwUIChoice = #WTD_UI_NONE
wd\fdwRevocationChecks = #WTD_REVOKE_NONE
wd\dwStateAction = #WTD_STATEACTION_VERIFY
wd\dwProvFlags = 0
wd\hWVTStateData = #Null
wd\pwszURLReference = #Null
EndIf
Define action.GUID
;********************
; WINTRUST_ACTION_GENERIC_VERIFY_V2 (Authenticode)
;********************
With action
\Data1 = $AAC56B
\Data2 = $CD44
\Data3 = $11D0
\Data4[0] = $8C
\Data4[1] = $C2
\Data4[2] = $00
\Data4[3] = $C0
\Data4[4] = $4F
\Data4[5] = $C2
\Data4[6] = $95
\Data4[7] = $EE
EndWith
hr = WinVerifyTrust(#INVALID_HANDLE_VALUE, @action, @wd)
debug "hr: 0x" + hex(hr)
If (hCatInfo <> #Null)
CryptCATAdminReleaseCatalogContext(hCatAdmin, hCatInfo, 0)
EndIf
CryptCATAdminReleaseContext(hCatAdmin, 0)
If (hr = 0)
wd\dwStateAction = #WTD_STATEACTION_CLOSE
WinVerifyTrust(#INVALID_HANDLE_VALUE, @action, @wd)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Define.s szFile = "C:\Program Files\Internet Explorer\iexplore.exe"
debug szFile + " - " + CheckFileTrust(szFile)
Define.s szFile = "c:\windows\system32\notepad.exe"
debug szFile + " - " + CheckFileTrust(szFile)