如何用 g++ 覆盖 __libc_start_main 之类的入口点
How to override the entrypoint like __libc_start_main with g++
我们想在用户的主要功能之前注入一些功能,发现 LD_PRELOAD
覆盖 __libc_start_main
将适用于具有 gcc
的 C 程序。
但是,它不适用于默认使用 g++ 的 cpp 文件。我们已经转储了符号并发现了 gcc 和 g++ 的二进制文件之间的区别。用g++
编译后,libc start main函数被重命名,我们不知道如何覆盖它。
我可以使用 __attribute__((constructor))
而不是覆盖 __libc_start_main
在主函数之前添加逻辑。
这可能是 g++
和 gcc
之间实现的不同,我们可能不会用 g++
的当前实现覆盖它。如果我错了,请发表评论并通知我。
这是 C++ 使用的 name mangling 方案。
要绕过 mangling,请在函数定义或 extern "C"
块中使用 extern "C"
:
void no_extern_c(int, int) {}
extern "C"
void with_extern_c(int, int) {}
$ nm -D demo.so
...
00000000000005b7 T with_extern_c
00000000000005aa T _Z11no_extern_cii
通常你用它来声明属于 C API 一部分的函数,但同样的原因是为什么在那里需要它(或至少是它的一部分),那就是被破坏的名字是什么您也必须使用 C 代码。
我们想在用户的主要功能之前注入一些功能,发现 LD_PRELOAD
覆盖 __libc_start_main
将适用于具有 gcc
的 C 程序。
但是,它不适用于默认使用 g++ 的 cpp 文件。我们已经转储了符号并发现了 gcc 和 g++ 的二进制文件之间的区别。用g++
编译后,libc start main函数被重命名,我们不知道如何覆盖它。
我可以使用 __attribute__((constructor))
而不是覆盖 __libc_start_main
在主函数之前添加逻辑。
这可能是 g++
和 gcc
之间实现的不同,我们可能不会用 g++
的当前实现覆盖它。如果我错了,请发表评论并通知我。
这是 C++ 使用的 name mangling 方案。
要绕过 mangling,请在函数定义或 extern "C"
块中使用 extern "C"
:
void no_extern_c(int, int) {}
extern "C"
void with_extern_c(int, int) {}
$ nm -D demo.so
...
00000000000005b7 T with_extern_c
00000000000005aa T _Z11no_extern_cii
通常你用它来声明属于 C API 一部分的函数,但同样的原因是为什么在那里需要它(或至少是它的一部分),那就是被破坏的名字是什么您也必须使用 C 代码。