C++未释放函数指针是否致内存泄漏?服务器代码是否易被篡改?
问题解答
1. 未释放m_func是否会导致内存泄漏?
不会。m_func存储的是函数指针,函数代码在程序加载时由操作系统加载到代码段,这部分内存的生命周期由操作系统负责管理,不属于需要手动释放的堆内存范畴。只有通过new、malloc等方式在堆上分配的内存才需要手动释放,因此该代码不存在内存泄漏问题。
2. 封闭服务器运行时的篡改风险及解决方案
风险存在性
是的,存在篡改风险。如果攻击者能够获取进程的内存读写权限(比如通过提权、漏洞利用等方式),可以:
- 直接修改函数所在代码段的内容(若代码段未设置只读保护);
- 修改
m_func指针的值,使其指向恶意代码的内存地址,从而执行恶意逻辑。
解决方案
- 开启代码段只读保护:现代操作系统默认会将代码段标记为只读,编译时可通过增强选项加固(例如GCC使用
-Wl,-z,relro,-z,now),阻止直接修改函数代码。 - 函数完整性校验:预先计算目标函数代码的哈希值,在执行
execute()前重新计算并对比哈希,若不一致则终止执行,防止代码被篡改。 - 限制进程权限:让程序以最低必要权限运行,降低攻击者获取内存操作权限的可能性。
- 启用地址空间布局随机化(ASLR):开启ASLR后,程序每次加载时函数的内存地址会随机变化,大幅增加攻击者定位函数地址的难度。
- 优化代码结构:原代码中将函数指针转为
void*是不安全且无必要的,直接用函数指针类型存储即可,避免类型转换带来的风险,修正后的示例代码如下:
#include <vector> #include <iostream> template <typename Func> struct endpoint_t { Func m_func; endpoint_t(Func func) : m_func(func) {} auto execute() { return m_func(); } }; int hello_world() { std::cout << "Hello World! \n"; return 0; } int hello_world2() { std::cout << "Hello World 2! \n"; return 0; } int main() { std::vector<endpoint_t<int(*)()>> array; array.push_back(hello_world); array.push_back(hello_world2); for (auto& end : array) { end.execute(); } }
另外,初始测试代码中缺少模板参数,修正后可正常运行:
#include <iostream> template <typename Func> struct endpoint_t { Func m_func; endpoint_t(Func func) : m_func(func) {} auto execute() { return m_func(); } }; int hello_world() { std::cout << "Hello World! \n"; return 0; } int main() { endpoint_t<int(*)()> end(hello_world); end.execute(); }
内容的提问来源于stack exchange,提问作者user283487
相关产品推荐
相关产品推荐

