代码之家  ›  专栏  ›  技术社区  ›  dancavallaro

为什么这个NASM代码打印我的环境变量?

  •  2
  • dancavallaro  · 技术社区  · 17 年前

    我这学期刚完成一门计算机体系结构课程,除其他外,我们一直在涉猎MIPS组装并在MARS模拟器中运行它。今天,出于好奇,我开始在Ubuntu上摆弄NASM,基本上只是从教程中拼凑出一些东西,并了解NASM与MIPS的不同之处。以下是我目前正在查看的代码片段:

    global _start
    
    _start:
    
        mov eax, 4
        mov ebx, 1
        pop ecx
        pop ecx
        pop ecx
        mov edx, 200
        int 0x80
        mov eax, 1
        mov ebx, 0
        int 0x80
    

    这被保存为test.asm,并与 nasm -f elf test.asm 并与 ld -o test test.o .当我用 ./test anArgument ,它按预期打印“anArgument”,然后打印将该字符串填充到总共200个字符所需的字符数(因此 mov edx, 200 声明)。不过,有趣的是,这些填充字符(我本以为是胡言乱语)实际上来自我的环境变量的开头,如 env 命令。为什么要打印我的环境变量?

    3 回复  |  直到 16 年前
        1
  •  7
  •   user21037 user21037    17 年前

    在不知道实际答案或没有时间查找的情况下,我猜测环境变量会在命令行参数之后存储在内存中。你的代码只是缓冲区溢出到环境变量字符串中并打印出来。

    这实际上是有道理的,因为命令行参数和环境变量都是由系统/加载器处理的,所以它们存储在彼此附近是有意义的。要解决这个问题,您需要找到命令行参数的长度,并且只打印那么多字符。或者,由于我假设它们是以null结尾的字符串,请打印直到达到零字节。

    编辑: 我假设命令行参数和环境变量都存储在初始化数据部分(我相信NASM中的.data)

        2
  •  2
  •   Employed Russian Employed Russian    17 年前

    为了理解为什么要获取环境变量,您需要了解内核在进程启动时是如何安排内存的。 Here 是一个很好的图片解释(向下滚动到“堆栈布局”)。

        3
  •  1
  •   gbarry    17 年前

    只要你好奇,你可能想弄清楚如何打印字符串的地址(我认为它已经传入,你把它从堆栈中弹出)。此外,编写一个十六进制转储例程,以便您可以查看该内存和其他您感兴趣的地址。这可能会帮助您发现有关程序空间的信息。

    好奇心可能是程序员工具箱中最重要的东西。

    我还没有研究启动进程的细节,但我认为每次启动一个新的shell时,都会为它制作一个环境副本。你可能会看到由你运行的命令或你编写的脚本启动的shell的剩余部分,等等。