该文件包含本机汇编代码,我想在当前进程中运行它。\n但我不想创建真正的文件(.com 或 .exe),所以我尝试:
\n\n...\nusing namespace std;\ntypedef void bitcode();\nvoid testcode(){\n cout<<"test";\n};\nint main()\n{\n bitcode *c=&testcode; // bitcode *c stands for the file containing the assembly code.\n bitcode *d=reinterpret_cast<bitcode*> (malloc(20));\n memcpy(d, c, 20);\n d(); // it doesn\'t work\n return 0;\n};\nRun Code Online (Sandbox Code Playgroud)\n\n但是,当我调用 d(); 时它不起作用。我想知道使用 C/C++ 执行此操作的正确方法是什么。
\n\n(我使用的是Windows,如果你能告诉我如何在Linux上制作它,我\xe2\x80\x99d将非常感激)
\n\n多谢!
\n\nPS:我不是在问“在另一个中运行可执行文件而不创建新进程”。
\n伊格纳西奥描述了如何做到这一点的总体轮廓。
\n\n由于您使用的是 Windows,因此您需要的函数不是VirtualAlloc,malloc特别是带有PAGE_EXECUTE_READWRITE用于获取写入内存并执行它的权限的标志。
然后,根据文档,您仍然VirtualProtect需要在写入内存之后和执行之前使用显式设置执行标志。
最后,使用内存后,您需要使用VirtualFree而不是释放它free。
std::size_t size = 20;\nvoid* mem = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);\n// Write assembly opcodes to mem\n\nDWORD old_protect;\nVirtualProtect(mem, size, PAGE_EXECUTE_READWRITE, &old_protect);\ntypedef (void)(*fptr)();\nfptr f = *reinterpret_cast<fptr*>(&mem);\n\nf();\n\n// Later \xe2\x80\xa6\nVirtualFree(mem, 0, MEM_RELEASE);\nRun Code Online (Sandbox Code Playgroud)\n\n请注意 中添加的间接寻址reinterpret_cast。这是避免未定义行为所必需的:C++ 不允许在对象指针和函数指针之间进行转换。然而,上面的代码是实现定义的,因此就 C++ 而言是可以的。
此外,请注意,为了简单起见,我省略了上面的错误检查代码。您不能在实际代码中执行此操作。有关正确错误处理的信息,请参阅文档。
\n\n在 Linux 上,工作流程类似,只是对函数使用不同的名称。
\n| 归档时间: |
|
| 查看次数: |
5519 次 |
| 最近记录: |