English 中文(简体)
为什么这个NASM代码会打印出我的环境变量?
原标题:
  • 时间:2008-12-03 16:50:56
  •  标签:

我这学期刚刚结束了一门计算机体系结构课程,在这门课程中,我们除了其他事情外,还涉及到了 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命令所显示的。为什么会打印出我的环境变量?

最佳回答

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

这其实是有道理的,因为命令行参数由系统/加载器处理,环境变量也是如此,因此它们存储在彼此附近是有道理的。要解决这个问题,您需要找到命令行参数的长度并只打印那么多个字符。或者,由于我假设它们是空终止字符串,在达到零字节之前打印。

EDIT: I assume that both command line arguments and environment variables are stored in the initialized data section (.data in NASM, I believe)

问题回答

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

只要你好奇心在作祟,你可能想要弄清楚如何打印你字符串的地址(我想它是以传参的方式传入程序并从栈中弹出的)。此外,编写一个十六进制转储程序,这样你就可以查看那些内存以及其他你感到好奇的地址。这有助于你发现程序空间的一些信息。

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

我没有调查启动进程的细节,但我认为每次启动新的 shell 时,都会为其制作一个环境的副本。你可能正在看到通过你运行的命令或编写的脚本启动的 shell 的剩余部分。





相关问题
热门标签