Does anyone have a simple method of determining whether the running EXE has been modified? With or without code signing, Windows doesn’t help.
For example, I did a search and replace on Clarion.exe and changed “SoftVelocity” to “HardVelocity” and nothing complained when I ran the EXE. If you inspect the code signing certificate, it says it’s invalid, but the program runs anyway. So why bother with code signing if it can’t detect modified code? No wonder viruses can modify executables with impunity!
So firstly, yes, exe’s can be changed without windows complaining. Your program needs to explicitly check the certificate on startup if you want to prevent that. I don’t have the code to do that to hand, but Wolfgang did a webinar on this, and posted code to the newsgroup.
20+ years ago, before code signing certificates were a thing, we had a similar requirement from the Venezuelan government to ensure our code for dealing with fiscal printers hadn’t been tampered with.
IIRC we came up with a post-compile process that used extra fields in the MZ DOS header of the executable to store the current date & time. Then when the application ran it checked the timestamp we added against the date/time the OS had for the file and if they were different it refused to run
There may be a reasonable way to implement this as a class and template. There should be a Checksum written into the PE Header by the Linker every build.
Checksum: The image file checksum. The algorithm for computing the checksum is incorporated into IMAGHELP.DLL. The following are checked for validation at load time: all Drivers, any DLL loaded at boot time, and any DLL that is loaded into a critical Windows process.
The Checksum is Not required to be correct nor checked for ordinary binaries, as noted above, only Drivers and critical.
Maybe @anon77170705 can confirm if the Clarion Linker follows the Microsoft standard. The below link gives the code for the Checksum algorithm (not sure it is correct). And it discusses it’s use for spotting malware.
Note: I don’t think this method is not going to work for digitally signed binaries because the signature is part of the file added after the Linker calculated. Also malware could update the Linker Checksum in the header.
Clarification: I’m looking for a program that can inspect ANY EXE or DLL that has been signed and tell me if it has been tampered with. I have the template that can tell if my (signed) application is broken when it runs.
The closest I can find is Airlock Digital but it isn’t open source
@CarlBarnes “There should be a Checksum written into the [PE Header] by the Linker every build.”
A long time ago the CW linker used it’s own checksum. When I complained about it (probably to Ole or Richard Chapman, but I forget who) they didn’t care. Don’t know if that’s changed by now.
FWIW, in case anyone is interested the IQCQO.DLL that the example app ships with appears to be a C DLL that’s “just” a wrapper around the WinVerifyTrust() API call using the WINTRUST_ACTION_GENERIC_VERIFY_V2 GUID
I wrote this before @PaulAttryde posted about IQCQO.
That relies on 2 functions ReturnSigningInfo and VerifySignature in IQCQO.DLL.
The IQCQO DLL properties shows No Details and No Digital Signature. Did @Graham_Dawson say the source of that DLL? Seems like a bad idea to check security using an unknown unsigned DLL.
Code excerpt:
MAP
module('IQCQO')
ReturnSigningInfo(const *cstring inFilename,*cstring outputStr,*long bufferSize),long,C,raw,name('ReturnSigningInfo')
VerifySignature(const *cstring inFilename,*cstring outputStr,*long bufferSize),long,C,raw,name('VerifySignature')
end
END
... CODE ...
bufferSizeNeeded = size(CStrBuffer)
result = VerifySignature(filename,CStrBuffer,bufferSizeNeeded)
IF result
Message('Error ' & CStrBuffer,filename)
ELSE
Message(CStrBuffer,filename)
END
IF CStrBuffer <> 'The file is not signed<13,10>'
bufferSizeNeeded = size(CStrBuffer)
result = ReturnSigningInfo(filename,CStrBuffer,bufferSizeNeeded)
IF result
message('Error ' & CStrBuffer,filename)
ELSE
message(CStrBuffer,filename)
END
END