如何在正确提供 argc、argv、envp 的 NASM 中调用用 C 编写的链接可执行文件中的主函数
How to call a main function in a linked executable written in C from NASM with argc,argv,envp supplied correctly
我正在将 C 程序链接到 NASM 可执行文件。汇编文件调用链接C程序中的main函数
virus: infect.c virus.o
$(CC) $(LFLAGS) $^ -o $@
virus.o: virus.asm template.asm.inc
$(ASM) $(AFLAGS) $< -o $@
我尝试了什么:
infect.c
以这种方式包含主要功能:
int main(int argc, char *const argv[], char *const envp[]) {
DIR *dir;
struct dirent *ent;
struct stat st;
int vfd, xfd, magic;
pid_t pid;
off_t offset;
ino_t inode;
vfd = open(argv[0], O_RDONLY);
...
因为我想从virus.asm
调用infect.c
中的main
函数。主要功能应该 infact 在 virus.asm
中,因为在可执行文件中不能有两个主要功能,我将 infect.c
中的 main
功能更改为
int infect(int argc, char *const argv[], char *const envp[]) {
DIR *dir;
struct dirent *ent;
struct stat st;
int vfd, xfd, magic;
pid_t pid;
off_t offset;
ino_t inode;
vfd = open(argv[0], O_RDONLY);
...
1) 我不知道如何从 NASM 程序集调用这个 infact 函数,这是我在 virus.asm
文件
中尝试的
extern infect
main:
call infect
程序运行,但没有产生预期的效果。 infect.c
是一种 ELF 病毒,应该在 CWD 中寻找文件并感染它们。
2) 问题似乎是我在调用
时没有正确处理 int argc, char *const argv[], char *const envp[]
如何使用提供的 argc
、argv
和 envp
从 virus.asm
正确调用 infect.c
中的函数,以便程序能够工作正常吗?
您可以在 asm 文件中提供 _start 入口点。下面是在 AMD64 和 linux 内核上为 elf abi 设置 argc、argv 和 envp 的示例代码。它不适用于真实代码,因为它不执行通常的初始化过程,例如为 tls 设置 fs 段、初始化静态变量等...但它让您初步了解需要完成的工作!
备忘录 [argc -> %rdi ; argv -> %rsi ;环境 -> %rdx ]
.global _start
.type _start,@function
.align 16
_start:
.cfi_startproc
.cfi_undefined rip
/*nullify rbp as required by doc*/
xor %rbp, %rbp
/*move argc to rdi and advance rsp*/
popq %rdi
/*set argv*/
movq %rsp, %rsi
/*now envp is at rsp+8*argc+8*/
lea 8(%rsp, %rdi, 8), %rdx
/*realign stack*/
push %rdi
/*push rsp to the stack*/
callq main
/*call _exit at return*/
movq %rax,%rdi
mov 1, %rax
syscall
.cfi_endproc
_start:
xor rbp, rbp
pop rdi
mov rsi, rsp
lea rdx, [rsp+rdi+8*8]
push rdi
call main
mov rdi, rax
mov eax, 1
int 80h
在 _start 函数中执行第一件事。如果您需要稍后执行,请确保保存以下寄存器
; save initial program state
mov rbx, rsp
mov r14, rdi
mov r15, rsi
然后就可以重新加载这些寄存器,调用上面的指令调用main
我正在将 C 程序链接到 NASM 可执行文件。汇编文件调用链接C程序中的main函数
virus: infect.c virus.o
$(CC) $(LFLAGS) $^ -o $@
virus.o: virus.asm template.asm.inc
$(ASM) $(AFLAGS) $< -o $@
我尝试了什么:
infect.c
以这种方式包含主要功能:
int main(int argc, char *const argv[], char *const envp[]) {
DIR *dir;
struct dirent *ent;
struct stat st;
int vfd, xfd, magic;
pid_t pid;
off_t offset;
ino_t inode;
vfd = open(argv[0], O_RDONLY);
...
因为我想从virus.asm
调用infect.c
中的main
函数。主要功能应该 infact 在 virus.asm
中,因为在可执行文件中不能有两个主要功能,我将 infect.c
中的 main
功能更改为
int infect(int argc, char *const argv[], char *const envp[]) {
DIR *dir;
struct dirent *ent;
struct stat st;
int vfd, xfd, magic;
pid_t pid;
off_t offset;
ino_t inode;
vfd = open(argv[0], O_RDONLY);
...
1) 我不知道如何从 NASM 程序集调用这个 infact 函数,这是我在 virus.asm
文件
extern infect
main:
call infect
程序运行,但没有产生预期的效果。 infect.c
是一种 ELF 病毒,应该在 CWD 中寻找文件并感染它们。
2) 问题似乎是我在调用
时没有正确处理int argc, char *const argv[], char *const envp[]
如何使用提供的 argc
、argv
和 envp
从 virus.asm
正确调用 infect.c
中的函数,以便程序能够工作正常吗?
您可以在 asm 文件中提供 _start 入口点。下面是在 AMD64 和 linux 内核上为 elf abi 设置 argc、argv 和 envp 的示例代码。它不适用于真实代码,因为它不执行通常的初始化过程,例如为 tls 设置 fs 段、初始化静态变量等...但它让您初步了解需要完成的工作!
备忘录 [argc -> %rdi ; argv -> %rsi ;环境 -> %rdx ]
.global _start
.type _start,@function
.align 16
_start:
.cfi_startproc
.cfi_undefined rip
/*nullify rbp as required by doc*/
xor %rbp, %rbp
/*move argc to rdi and advance rsp*/
popq %rdi
/*set argv*/
movq %rsp, %rsi
/*now envp is at rsp+8*argc+8*/
lea 8(%rsp, %rdi, 8), %rdx
/*realign stack*/
push %rdi
/*push rsp to the stack*/
callq main
/*call _exit at return*/
movq %rax,%rdi
mov 1, %rax
syscall
.cfi_endproc
_start:
xor rbp, rbp
pop rdi
mov rsi, rsp
lea rdx, [rsp+rdi+8*8]
push rdi
call main
mov rdi, rax
mov eax, 1
int 80h
在 _start 函数中执行第一件事。如果您需要稍后执行,请确保保存以下寄存器
; save initial program state
mov rbx, rsp
mov r14, rdi
mov r15, rsi
然后就可以重新加载这些寄存器,调用上面的指令调用main