我搞乱了共享库注入(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::cout
在 libmain
中写入时尚未初始化.
关于c++ - 无法通过函数为全局变量赋值(Linux 上的共享库注入(inject)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63120091/