Search code examples
gcccompilationlinkerstatic-librariessections

Easiest way to do runtime md5sum on the .text section of a static library


Brainhive,

I'm looking for a way to make sure my code wasn't altered, initial thought was to find the start address of the .text section and the size of it, run md5sum (or other hash) and compare to a constant.

My code is compiled to a static library and I don't want to hash the entire binary, only my library.

How do I? Will it help adding an ld script with reserved labels?

System is arm64 and I'm using GNU arm compiler (linaro implementation).


Solution

  • I'm looking for a way to make sure my code wasn't altered, initial thought was to find the start address of the .text section and the size of it, run md5sum (or other hash) and compare to a constant.

    There are several reasons your request is likely misguided:

    1. Anybody who is willing to modify your compiled code, will also be willing to modify the checksum that you are going to compare against at runtime. That is, you appear to want to do something like:

      /* 0xabcd1234 is the precomputed checksum over the library. */ if (checksum_over_my_code() != 0xabcd1234) abort();

      The attacker can easily replace this entire code with a sequence of NOP instructions, and proceed to use your modified library.

    2. Your static library (usually) doesn't end up as sequence of bytes in the final binary. If you have foo.o and bar.o in your library, and the end-user links your library with his own code in main.o and baz.o, then the .text section of the resulting executable could well be composed of .text from main.o, then .text from foo.o, then .text from baz.o, and finally .text from bar.o.

    3. When the final executable is linked, the instructions in your library are updated (relocated). That is, suppose your original code has CALL foo instruction. The actual bytes in your .text section will be something like 0xE9 0x00 0x00 0x00 0x00 (with a relocation record stating that the bytes following 0xE9 should be updated with whatever the final address of foo ends up being).

      After the link is done, and assuming foo ends up at address 0x08010203, the bytes in .text of the executable will no longer be 0s. Instead they'll be 0xE9 0x03 0x02 0x01 0x08 (they actually wouldn't be that for reasons irrelevant here, but they certainly wouldn't be all 0s).

      So computing the checksum over actual .text section of your archive library is completely pointless.