在静态库的 .text 部分执行运行时 md5sum 的最简单方法
Easiest way to do runtime md5sum on the .text section of a static library
脑巢,
我正在寻找一种方法来确保我的代码没有被更改,最初的想法是找到 .text 部分的起始地址及其大小,运行 md5sum(或其他哈希)并与常量进行比较。
我的代码被编译成一个静态库,我不想散列整个二进制文件,只散列我的库。
我怎么办?它有助于添加带有保留标签的 ld 脚本吗?
系统是 arm64,我使用的是 GNU arm 编译器(linaro 实现)。
有一些工具可以让您转储 ELF 部分。 elfcat 让它变得超级简单,(elfcat --section-name=test the_file.o
) 但它也应该可以用 objdump
实现。转储该部分后,问题就减少为调整文件大小和散列文件。
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.
您的请求可能被误导的原因有多种:
任何愿意修改您的编译代码的人,也将愿意修改您要在运行时进行比较的校验和。也就是说,您似乎想要执行以下操作:
/* 0xabcd1234 is the precomputed checksum over the library. */
if (checksum_over_my_code() != 0xabcd1234) abort();
攻击者可以轻松地用一系列 NOP
指令替换整个代码,然后继续使用您修改后的库。
您的静态库(通常)不会以最终二进制文件中的字节序列结束。如果您的库中有 foo.o
和 bar.o
,并且最终用户 link 在 main.o
和 baz.o
中使用他自己的代码访问您的库,那么生成的可执行文件的 .text
部分很可能由 main.o
中的 .text
、foo.o
中的 .text
、[=15 中的 .text
组成=],最后 .text
来自 bar.o
.
当最终的可执行文件被 link 编辑时,库中的 指令 会更新(重新定位).也就是说,假设您的原始代码有 CALL foo
指令。 .text
部分中的实际字节将类似于 0xE9 0x00 0x00 0x00 0x00
(重定位记录表明 0xE9
之后的字节应该 更新 与任何foo
的最终地址是)。
link 完成后,假设 foo
在地址 0x08010203
结束,可执行文件 .text
中的字节将不再为 0。相反,它们将是 0xE9 0x03 0x02 0x01 0x08
(由于与此处无关的原因,它们实际上不会是那样,但它们肯定不会全为 0)。
因此计算存档库实际 .text
部分的校验和 完全没有意义。
脑巢,
我正在寻找一种方法来确保我的代码没有被更改,最初的想法是找到 .text 部分的起始地址及其大小,运行 md5sum(或其他哈希)并与常量进行比较。
我的代码被编译成一个静态库,我不想散列整个二进制文件,只散列我的库。
我怎么办?它有助于添加带有保留标签的 ld 脚本吗?
系统是 arm64,我使用的是 GNU arm 编译器(linaro 实现)。
有一些工具可以让您转储 ELF 部分。 elfcat 让它变得超级简单,(elfcat --section-name=test the_file.o
) 但它也应该可以用 objdump
实现。转储该部分后,问题就减少为调整文件大小和散列文件。
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.
您的请求可能被误导的原因有多种:
任何愿意修改您的编译代码的人,也将愿意修改您要在运行时进行比较的校验和。也就是说,您似乎想要执行以下操作:
/* 0xabcd1234 is the precomputed checksum over the library. */ if (checksum_over_my_code() != 0xabcd1234) abort();
攻击者可以轻松地用一系列
NOP
指令替换整个代码,然后继续使用您修改后的库。您的静态库(通常)不会以最终二进制文件中的字节序列结束。如果您的库中有
foo.o
和bar.o
,并且最终用户 link 在main.o
和baz.o
中使用他自己的代码访问您的库,那么生成的可执行文件的.text
部分很可能由main.o
中的.text
、foo.o
中的.text
、[=15 中的.text
组成=],最后.text
来自bar.o
.当最终的可执行文件被 link 编辑时,库中的 指令 会更新(重新定位).也就是说,假设您的原始代码有
CALL foo
指令。.text
部分中的实际字节将类似于0xE9 0x00 0x00 0x00 0x00
(重定位记录表明0xE9
之后的字节应该 更新 与任何foo
的最终地址是)。link 完成后,假设
foo
在地址0x08010203
结束,可执行文件.text
中的字节将不再为 0。相反,它们将是0xE9 0x03 0x02 0x01 0x08
(由于与此处无关的原因,它们实际上不会是那样,但它们肯定不会全为 0)。因此计算存档库实际
.text
部分的校验和 完全没有意义。