c++ - 无法通过函数为全局变量赋值(Linux 上的共享库注入(inject))

标签 c++ segmentation-fault global-variables shared-libraries clang++

我搞乱了共享库注入(inject)并设法使其工作。但没过多久,第一个问题就出现了。如果您看一下以下代码块,您会发现它们之间的唯一区别在于,在第一个代码块中,“test”函数返回的值被分配给一个局部变量,而在第二个代码块中,它被分配给一个全局变量。

//main.cpp
#include <iostream>
#include "mem/mem.hpp"
#define PROCESS_MOD_NAME MEM_STR("/target\n")
#define LIBC_MOD_NAME    MEM_STR("/libc.so")

mem::moduleinfo_t test()
{
    mem::moduleinfo_t _modinfo;
    _modinfo.name = "testing";
    _modinfo.path = "testing";
    _modinfo.base = (mem::voidptr_t)10;
    _modinfo.end  = (mem::voidptr_t)20;
    _modinfo.size = 10;

    return _modinfo;
}

__attribute__((constructor))
void  libmain()
{
    mem::moduleinfo_t modinfo = test(); //local variable
    std::cout << "name: " << modinfo.name << std::endl;
    std::cout << "path: " << modinfo.path << std::endl;
    std::cout << "base: " << modinfo.base << std::endl;
    std::cout << "size: " << modinfo.size << std::endl;
    std::cout << "end:  " << modinfo.end  << std::endl;
}
这个有效,没有崩溃。
//main.cpp
#include <iostream>
#include "mem/mem.hpp"
#define PROCESS_MOD_NAME MEM_STR("/target\n")
#define LIBC_MOD_NAME    MEM_STR("/libc.so")

mem::moduleinfo_t test()
{
    mem::moduleinfo_t _modinfo;
    _modinfo.name = "testing";
    _modinfo.path = "testing";
    _modinfo.base = (mem::voidptr_t)10;
    _modinfo.end  = (mem::voidptr_t)20;
    _modinfo.size = 10;

    return _modinfo;
}

mem::moduleinfo_t modinfo; //global variable

__attribute__((constructor))
void  libmain()
{
    modinfo = test();
    std::cout << "name: " << modinfo.name << std::endl;
    std::cout << "path: " << modinfo.path << std::endl;
    std::cout << "base: " << modinfo.base << std::endl;
    std::cout << "size: " << modinfo.size << std::endl;
    std::cout << "end:  " << modinfo.end  << std::endl;
}
在这个代码块上,目标程序简单地崩溃了。
在 GDB 上调用“dlopen”时,输出为:
Program received signal SIGSEGV, Segmentation fault.
0xf7c19404 in __memcpy_sse2_unaligned () from /usr/lib32/libc.so.6
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(dlopen) will be abandoned.
目标程序代码为:
//target.cpp
#include <iostream>
#include <dlfcn.h>

int main()
{
    while(true);
    return 0;
}
编译此代码的命令行:
clang++ -m32 target.cpp -o build/target -ldl
clang++ -m32 -shared -fPIC main.cpp mem/mem.cpp -o build/libinject.so -ldl
无法使用全局变量是一件大事,那么可能导致此崩溃的原因是什么,我该如何解决?

最佳答案

我认为您的问题与全局变量无关(这两个示例对我来说都是段错误)。
核心问题是 C++ 全局构造函数在 C 构造函数之后运行(即标有 __attribute__((constructor)) 的函数)所以 std::coutlibmain 中写入时尚未初始化.

关于c++ - 无法通过函数为全局变量赋值(Linux 上的共享库注入(inject)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63120091/

相关文章:

c++ - 第二次检查后 flock lock 丢失

c++ - ffmpeg - 比较 2 个 AVFrames 数据

c - 不应该出现段错误吗?为什么会出现 "pointer being freed was not allocated"错误?

c - 尝试将 3D 空间中的点 append 到数组末尾时出现段错误

bash - shell 脚本错误

c++ - 获取错误 : vector iterator incompatible

C++模板问题添加两种数据类型

boost - 使用 boost syslog 和 cpp-netlib 时出现段错误

php - PHP 中 $_SERVER super 全局的来源是什么?

python - Django 和 Celery 的全局变量