动态执行的 ARM ASM 系统调用,可从C++重新定位
Dynamically executed ARM ASM syscall with relocations from C++
我想从C++调用ARM/ARM64 ASM代码。ASM 代码包含系统调用和对外部函数的重新定位。 ARM架构在这里不是那么重要,我只是想从概念上了解如何解决我的问题。
我有以下ASM系统调用(objdump -d
输出),它在共享库中调用:
198: d28009e8 mov x8, #0x4f // #79
19c: d4000001 svc #0x0
1a0: b140041f cmn x0, #0x1, lsl #12
1a4: da809400 cneg x0, x0, hi
1a8: 54000008 b.hi 0 <__set_errno_internal>
1ac: d65f03c0 ret
这段代码调用fstatat64
系统调用,并通过外部__set_errno_internal
函数设置errno
。readelf -r
显示了__set_errno_internal
功能的以下重新定位:
00000000000001a8 R_AARCH64_CONDBR19 __set_errno_internal
我想从C++调用这段代码,所以我将其转换为缓冲区:
unsigned char machine_code[] __attribute__((section(".text"))) =
"xe8x09x80xd2"
"x01x00x00xd4"
"x1fx04x40xb1"
"x00x94x80xda"
"x08x00x00x54" // Here we have mentioned relocation
"xc0x03x5fxd6";
编辑:重要细节 - 我选择使用缓冲区(不是内联程序集等),因为我想在这个缓冲区上运行额外的处理(例如字符串文字上的解密函数作为软件保护机制,但这在这里并不重要)在它被评估为机器代码之前。
之后,可以将缓冲区转换为函数并直接调用以执行机器代码。显然,搬迁存在问题,它不会自动修复,我必须手动修复它。但是在运行时我不能这样做.text
因为该部分是只读和可执行的。
虽然我几乎完全控制源代码,但我不能关闭堆栈保护和其他功能以使该部分可写(不要问为什么)。因此,似乎应该以某种方式在链接阶段执行重新定位修复。据我所知,共享库包含链接器修复重定位后的相对偏移量(对于类似的外部函数调用),二进制 *.so 文件应包含正确的偏移量(无需运行时重定位工作),因此在链接期间修复machine_code
该缓冲区应该是可能的。
我正在使用手动构建的Clang 7编译器,并且可以完全控制LLVM传递,因此我认为也许可以编写某种在链接期间执行的LLVM传递。虽然看起来ld
最终被调用了,所以也许 LLVM 通行证在这里无济于事(不是这里的专家)。
不同的想法也将不胜感激。 如您所见,问题非常复杂。也许您有一些方向/想法如何解决这个问题?谢谢!
已经有一个有效的打包机制来处理重新定位。它被称为dlsym()
. 虽然它不直接为您提供函数指针,但所有主要的C++编译器都支持reinterpret_cast
dlsym
到任何普通函数指针的结果。(成员函数完全是另一个问题,但这在这里无关紧要)
- 重新定位图像时如何前进到下一个内存块
- 流填充字符的默认定位
- 通过Python Distutils(用于Python C扩展)使用可重定位的设备代码编译CUDA代码
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- NS3 - python.h 文件无法定位编译错误
- 设置我的应用程序 API 感知并防止系统使其模糊和错误定位
- GLEW 未在 MSYS2 上定位 OpenGL 函数
- c++ 链接器错误"针对'.rodata.str1.1'的重新定位R_X86_64_32"链接 CXX 共享库 libsrt.so
- 如何忽略32位整数中的特定位
- 如何在C++中使用光标定位
- 使用 stdio.h 重新定位和重命名文件C++
- R 包安装错误:重新定位 0 具有无效的符号索引 11
- 对于可重定位的多平台安装,理想的 cmake 安装目录结构是什么?
- 不能使用使用 lib*.a 的 CDT ---对符号 .. 的重新定位R_X86_64_32S
- 如何在VS2015中重新定位VS2017解决方案?
- 使用 for_each 和 lambda 销毁已定位的对象
- 在"for loop"中使用GOTOXY定位
- 是否可以为虚幻引擎/Unity制作64位定位系统?
- 干净地破坏动态定位对象的向量
- 使用ENVDTE时的Java脚本-将新项目添加到现有解决方案中,并将其定位在特定的子文件夹中