C++ 如何为C++;用MS VC开发的程序++;

C++ 如何为C++;用MS VC开发的程序++;,c++,c,windows,visual-c++,portable-executable,C++,C,Windows,Visual C++,Portable Executable,我试图使用此代码将一段代码分配给一个独立的部分: #ifdef _MSC_VER #pragma section(".evil",execute) #pragma code_seg(".evil") #endif #ifdef __GNUC__ static __attribute__((section (".evil"))) #elif defined _MSC_VER static __declspec(allocate(".evil")) #endif void __invoke__s

我试图使用此代码将一段代码分配给一个独立的部分:

#ifdef _MSC_VER
#pragma section(".evil",execute)
#pragma code_seg(".evil")
#endif


#ifdef __GNUC__
static __attribute__((section (".evil")))
#elif defined _MSC_VER
static __declspec(allocate(".evil"))
#endif
void __invoke__start()
{//...
但这不起作用,编译器说

__declspec(allocate())语法只能用于静态数据

我这样做是因为我必须为一个新文件编写一些代码,而这个文件是一个可执行文件

实际上,如果程序是用MS VC++调试模式编译的,那么在程序运行时,我找不到一种方法来获得内存中某个函数的确切地址 有关完整示例,请参见以下代码:

现在,上面的问题已经解决了,但是我仍然想澄清一下,如果有可能将一些代码放到一个独立的部分中。毕竟,当我的工作有可能的时候,还有其他的好处

当我链接两个对象文件(COFF格式)时,如何确保来自不同obj文件的不同代码位于不同的部分? 还是有其他方法可以做到这一点


很抱歉我的英语不好。

您可以使用内联汇编程序找到函数开头的内存地址,然后调用函数以使用内存地址,如:

void foo(){

    __asm{
        CALL 0h          \\Put current address on top of stack
        CALL myFunction  \\Actually make a funciton call
    }

...


}

int myFunction( int addrFromASM){
    \\do something with addrFromASM+4, which will be where the rest of foo starts.
}

除了您的代码中有一些很好的UB(您假设编译器将始终按照除外的顺序放置函数)之外,您想要对这些节执行的操作可以通过在您编写的PE头中分配一个新的节并将代码放在那里来完成(参见章节表
中的段落,找到),您还需要将
BaseOfCode
设置到此章节,并相应地调整
NumberOfSections


关于函数的有趣地址,这是因为在调试模式下编译时“编辑并继续”处于打开状态,只需在项目选项中将其关闭,您的地址就会正确。

Wow,这是一个很好的方法。因此myFunction可以获取foo的地址…并执行任何操作。。感谢您的帮助!返回地址存储在
 调用myFunction
,它可以从堆栈中拉出,但不能从参数中拉出。
调用0h
只会带来麻烦。调用需要参数的函数也会带来麻烦,而且不清楚正确的调用顺序是什么,因为调用约定未指定。事实上,内联程序集一点也不需要。将函数标记为
\uu declspec(裸)
可能是个好主意,否则编译器可能会调整堆栈指针,使查找返回地址更加困难。总之,这个想法是合理的,但示例代码很糟糕。“当CALL指令在位移为零的情况下使用时,它会得到识别和特殊处理;即使没有相应的RET指令,RAS也会保持一致。"-
呼叫0h
没有问题。cdecl是默认的呼叫约定。这个主意很好,我现在知道怎么做了。再次感谢Motes。我会将其标记为接受答案。是的。我测试了一整天,发现问题在某种程度上与链接器有关。可能是符号解决或类似的工作人员。无论如何,我感到震惊的是,我只需要o将/RELEASE选项传递给链接器,所有问题都已解决。这根本没有意义…另一种方法是将/LTCG或/LTCG选项设置到链接器。两种方法都有效。因此我现在不必关闭调试功能。您的回答也很有启发性。谢谢您的帮助。