1

Let me explain what I'm trying to accomplish. I want to know from inside my Windows executable file if it was tampered with after it was built. For that I decided to calculate the CRC value on its own file from within and compare it with a predefined value. But what I'm encountering is that once the executable is built the CRC remains the same, but only until I re-build it again (without any changes done to the source code). That's when the CRC changes. What is the magic here? Does the compiler add some arbitrary bytes to the exe file?

PS. I'm using Microsoft Visual Studio C++ 2008 and run my tests on Windows 7 Ultimate.

ahmd0
  • 16,633
  • 33
  • 137
  • 233
  • 2
    it could be some timestamp or version number automatically embedded by the compiler/linker... – Yahia Aug 27 '11 at 22:49
  • Hmmm. Good point. So how do I bypass them. Are they at a predefined offsets? – ahmd0 Aug 27 '11 at 22:56
  • are you generating native EXE/DLL files ? – Yahia Aug 27 '11 at 22:58
  • 1
    Your code will inevitably take a nose dive on IMAGE_FILE_HEADER.TimeDateStamp. http://msdn.microsoft.com/en-us/library/ms680313%28v=VS.85%29.aspx Ignoring the PE32 file format is not an option. – Hans Passant Aug 27 '11 at 23:41
  • Yeah, that's what I just learned after Yahia's suggestion. But if I start CRC scanning of the exe file from, say, 0x200 offset it successfully bypasses all the header stuff... – ahmd0 Aug 28 '11 at 02:20

2 Answers2

2

It could be some timestamp or version number automatically embedded by the compiler/linker...

To account for that I suggest something different (based on the fact that these are native EXE/DLLs):

Just postprocess the generated file - don't assume anything about CRC32 of the resulting file before it is generated...

Windows has a really "nice" feature when loading an EXE/DLL: it just ignores anything at the end of the file that doesn't belong there.

You can use this to your advantage: append a block of bytes (for example 256 bytes) to the file. This block can contain whatever you like (hash of your file, length of your file etc.) and can be even encrypted... when you want to check you calculate the information needed (like your CRC...) and compare it to that block of your file...

To make it harder you can include different hashes and choose randomly which one you check... you can even sprinkle some random bytes into that block... Also put in a check that makes sure there is only one such block present... so you can abort or whatever you want if there is no such block, more than one such block or your check and the saved information from that block does not match.

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • Yes, this is pretty much what I am doing. I did some checks and it seems like you might be on to something about a time stamp. Does anyone know the exact offset where it's placed? This way I can simply skip that location in the CRC calculation. – ahmd0 Aug 28 '11 at 00:07
  • see the link provided in one of the comments - http://msdn.microsoft.com/en-us/library/ms680313%28v=VS.85%29.aspx BUT I wouldn't recommend "solving" this by skipping anything... the method described in my answer works without any skipping, even better is codesigning (see the answer from jgv999 above) – Yahia Aug 28 '11 at 00:12
1

Have you considered using a digital signature? The signature can be applied after compilation, and allows you to verify that the EXE has not been edited. This a perfect case for one.

You can use "SignTool.EXE" to sign your EXE.

To verify you can use the code found at:
Verify whether an executable is signed or not (signtool used to sign that exe)

I believe you would have to purchase a Code Signing Certificate (if you want it fully validated). I think GoDaddy provides the least expensive ones (right now). I have also heard that if you have an open source project, you may be able to obtain a free signing Cert. from some authorities.

Community
  • 1
  • 1
jgv999
  • 83
  • 1
  • 1
  • 6
  • Thanks. I did consider signing my executable but I'm not at the point of buying it yet. Until Microsoft "wisens up" to come up with what Apple does with their AppStore when developers pay $99 a year for any number of signed executables I'm not going to invest into this "dead end" technology. – ahmd0 Aug 28 '11 at 00:10
  • The reason I was calculating the CRC is to actually see how many copies of my shareware product get "Hacked" or "patched". It's just an internal stats... – ahmd0 Aug 28 '11 at 00:11
  • Just curious how you would know. If you are assuming people are going to hack your EXE, it seems they would not allow it to phone home. – jgv999 Aug 28 '11 at 00:26
  • Obviously who does the hacking will block the internet connection for the program to "phone home". What I'm interested is when the "hacked" executable is posted on a torrent site and is downloaded "by the masses". The way we can notify our home server is by sending a single "status code" in an HTTP request. It takes almost no time to complete and can be coupled with an update check (in a URL itself), or when a user clicks to check an online manual, or simply from a background thread when the program starts up. Obviously I understand that it won't work in 100% of the cases... – ahmd0 Aug 28 '11 at 02:17
  • I was not trying to be a jerk, was just curious about your strategy :). Thanks for enlightening me. – jgv999 Aug 28 '11 at 02:44
  • Sure, not a problem. Thank you for giving me a link to the signing cert for Windows. I actually thought that they were much more expensive.... – ahmd0 Aug 28 '11 at 03:33