我能确定函数的二进制代码会按顺序复制吗



如果这个问题已经存在,我很抱歉,因为我希望使用这种方法,但我不知道这是怎么回事。所以,我的目的是从内存中执行函数序列,为此我复制了第一个和最后一个函数的大小。

这是我的第一次尝试:

source.cpp
void func1(int var1, int var2)
{
func2();
func3();
//etc.
}
void func2(...){...}
void func3(...){...}
void funcn(){return 123;}//last func as border, I do not use it
//////////////////////////////////////////////////
main.cpp
#include"source.cpp"
long long size= (long long)funcn-(long long)func1;// i got size of binary code of this funcs;
// and then i can memcpy it to file or smth else and execute by adress of first

首先,它工作正常,但在更新我的功能后,它崩溃了。大小已变为负数。然后我试着把它更硬地连接到内存上:

source.cpp
extern void(*pfunc1)(int, int);
extern void(*pfuncn)();
void(*pfunc1)(int , int) = &func1;
void(*funcn)() = &funcn;
static void __declspec(noinline) func1(int var1, int var2)
{
//the same impl
}
static void __declspec(noinline) func2(...){...}
static void __declspec(noinline) func3(...){...}
static void __declspec(noinline) funcn(...){retunr 123;}
//////////////////////////////////
main.cpp
#include"source.cpp"
long long size= (long long) pfuncn - (long long) pfunc1;
//same impl

这在我第一次更新后就起作用了,但后来我不得不再次更新,现在这给了我错误的尺寸。大小接近900+字节。我更改了一些函数,大小变为350+字节,我没有更改那么多。我禁用了优化和内联优化。

所以我的问题是,如何确保我的func1的地址比上一个funcn的地址少,以及如何改变它们在内存中的位置。感谢您的关注。

// and then i can memcpy it to file or smth else and execute by adress of first

将其复制到内存中,然后在分配的内存中调用它,然后按分配地址调用。

需要说明的是:

您不能将代码从一个位置复制到另一个位置并希望它能工作

  1. 不能保证调用函数所需的所有代码位于相邻块中
  2. 不能保证函数指针实际指向所需代码的开头
  3. 无法保证您可以有效地写入可执行内存。对于操作系统来说,你看起来很像病毒
  4. 不能保证代码是可重定位的(在移动到不同的位置后能够工作(。为此,它只需要使用相对地址

简而言之:除非你有超出标准C++范围的支持工具,否则不要考虑它。

GCC系列!

您可以强制编译器将整个函数放在单独的部分中。然后你就可以知道函数所在的内存区域了。

int __attribute__((section(".foosection"))) foo()
{
/* some code here */
}

在.text中的链接器脚本中,您需要添加

.text :
{

/* ... */
__foosection_start = .;
*(*foosection)
*(.foosection*) 
__foosection_end = .;
/* .... */

在你想知道或使用它的地方

extern unsigned char __foosection_start[];
extern unsigned char __foosection_end[];
void printfoo()
{
printf("foosection start: %p, foosection end: %pn ", (void *)__foosection_start, (void *)__foosection_end);
}

这可能是不可能的,因为您没有提到一个要求,但为什么不使用函数指针数组呢?

std::function<void()> funcs[] = {
func2,
func3,
[](){ /* and an inline lambda, because why not */ },
};
// Call them in sequence like so: 
for (auto& func: funcs) {
func();
}

最新更新