How can I see the implementation of function execve (under x86_64 Linux), it is in the library unistd? I want this because I want to know how can I call an external program using assembler, without calling execve. I know that there is a syscall named execve, but I don't kno开发者_StackOverflow社区w how can I use it.
How can I put a variable of type char * and type char * [] into registers ?
The implementation of the execve()
function in userspace looks something like:
int execve(const char *filename, char * const argv[], char * const envp[]) {
return syscall(SYS_execve, filename, argv, envp);
}
All of the actual "work" is done in the kernel. There's nothing particularly interesting happening in libc, besides perhaps some threading cleanup.
Just take a look at the kernel sources (more specifically: arch/YOUR-ARCH/kernel/head*.S) for the system call convention on your architecture (registers and/or stack for the syscall number and the parameters).
On ARM, for example, you would load __NR_execve
into r7, load the arguments into r0, r1, r2 and then use swi 0
. You might be interested in this explantion of ARM EABI syscalls for more details.
There is no real straightforward implementation of system calls in the source code to glibc - this is generated at build time from various files defining the system call numbers.
The relevant information can be found in sysdep.h if you understand it, except for the actual system call numbers (you want __NR_execve
with, IIRC, #include <asm/unistd.h>
- I can't recall offhand what it is on x86_64).
The system call number goes in %rax, and the arguments go in %rdi %rsi %rdx. All this information (including stack alignment and something about register usage by the kernel) is commented in sysdep.h.
精彩评论