Linux AMD64从复制的程序集调用C库函数 [英] Linux AMD64 call C library functions from copied assembly
问题描述
如何从memcpy的汇编函数中调用C库函数?
How do I call from an memcpy'ed assembly function a C library functions?
我正在制作一个示例测试代码,说明如何在Linux和AMD64上分配和更改内存保护以运行从C任意生成的代码. 我要做的是,在我的主程序旁边(用C编写)编译了一个小的GAS汇编函数,然后在运行时将汇编二进制blob复制到分段可执行内存中并跳转到其中. 这部分工作正常.
I'm making an example test code how one can allocate and change memory protection on Linux, AMD64 to run arbitrarily generated code from C. What I done is that I compile an small GAS assembly function along side my main program (written in C) and then copy the assembly binary blob onto piece executable memory in run-time and jump into it. This part works OK.
但是如果我从复制的程序集blob调用C库puts(),则会由于错误的函数地址而导致segfault?我该如何解决?
But I if call C library puts() from the copied assembly blob it results in segfault due to bad function address?! How do I fix it?
汇编代码blob:
.text
.global _print_hello_size
.global _print_hello
.type _print_hello,@function
_print_hello:
push %rbp
mov %rsp, %rbp
# puts("Hello World\n")
mov $_message, %rdi
call puts # <-- SEGFAULT
pop %rbp
ret
procend: # mark end address of the _print_hello code
.section .rodata
_message:
.asciz "Hello, world\n"
_print_hello_size:
.long procend - _print_hello
然后在C main()中执行(伪代码):
Then in C main() I do (pseudo code):
// Import assembler function and its size
extern "C" void _print_hello(void);
extern "C" const long _print_hello_size;
int main() {
// Use special function that allocates Read-Write-Executable memory
void * memexec = MallocExecutableMemory(1024);
// Copy the binary asm blob, memexec is aligned to at least 16-bytes
memcpy(memexec, (void*)_print_hello, _print_hello_size);
void (*jmpfunc)(void) = (void (*)(void))memexec;
jmpfunc(); // Works, jumps into copied assembly func
return 0;
}
即使有可能,甚至以后甚至都不会编译asm blob,而只是将示例程序编码为 unsigned char execblob [] = {0xCC,0xCC,0xC3,..} 并复制到可执行区域.此位代码探索如何从C开始生成asm.
Later if this is even possible would not even compile the asm blob, but just encode the example program in in unsigned char execblob[] = { 0xCC,0xCC,0xC3,..} and copy that into the executable region. This bit code exploration how to start generating asm from C.
推荐答案
也许你可以
push %rbp
mov %rsp, %rbp
# puts("Hello World\n")
mov $_message, %rdi
mov $puts, %eax
call %eax
pop %rbp
ret
,因此强制call
成为绝对值.问题是汇编程序是否不会出于自身目的对其进行优化.
and thus forcing the call
to become an absolute one. The question is whether the assembler won't optimize this out for its own purposes.
这篇关于Linux AMD64从复制的程序集调用C库函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!