You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86 32位汇编中execve传递环境变量失效问题排查

问题原因及解决方案

你的问题大概率是环境变量数组(envp)的构造不符合Linux execve系统调用的要求,或者execve的参数传递错误,导致内核无法正确识别你自定义的环境变量。以下是具体原因和修正方法:

常见错误点及修正

1. envp数组未以NULL指针终止

Linux的execve系统调用要求,环境变量数组envp必须是一个以NULL指针结尾的指针数组。如果没有这个终止符,内核无法确定环境变量的结束位置,会直接忽略无效的数组内容,只保留系统默认传递的少量变量(比如PWD)。

2. execve参数传递顺序错误

32位Linux下,execve的系统调用参数约定为:

  • eax = 59(execve的系统调用号)
  • ebx:指向/bin/sh的路径字符串指针
  • ecx:指向参数数组argv的指针(数组需以NULL结尾)
  • edx:指向环境变量数组envp的指针(数组需以NULL结尾)

如果把envp和argv的传递顺序搞反,shell会把环境变量当成命令参数,自然无法识别为环境变量。

3. 环境变量字符串未以NULL结尾

所有传递给execve的字符串(包括路径、参数、环境变量)必须是C风格的以0字节结尾的字符串。缺少终止符会导致内核解析失败,忽略该变量。

正确的代码示例

以下是能正确传递环境变量的32位x86汇编代码:

section .data
    ; 定义字符串(均以0结尾)
    shell_path db '/bin/sh', 0
    arg0       db 'sh', 0          ; argv[0],通常是程序名
    xca1_str   db 'xca1=test_val1', 0
    xca2_str   db 'xca2=test_val2', 0
    xca3_str   db 'xca3=test_val3', 0

    ; 构造argv数组:指针列表,最后以NULL结尾
    argv dd arg0, 0
    ; 构造envp数组:指针列表,最后以NULL结尾
    envp dd xca1_str, xca2_str, xca3_str, 0

section .text
    global _start
_start:
    ; 传递execve参数
    mov ebx, shell_path   ; ebx = 程序路径
    mov ecx, argv         ; ecx = 参数数组
    mov edx, envp         ; edx = 环境变量数组
    mov eax, 59           ; 32位Linux execve系统调用号
    int 0x80              ; 触发系统调用

    ; 系统调用失败后的退出逻辑
    mov eax, 1
    xor ebx, ebx
    int 0x80

手动构造栈的shellcode场景(无.data段)

如果是编写无数据段的shellcode,需要通过栈来构造argv和envp,注意栈的顺序:

section .text
    global _start
_start:
    ; 构造envp数组(栈底到栈顶:NULL -> xca3 -> xca2 -> xca1)
    push 0                  ; envp终止符
    push 0x3361783d         ; "=xca3" (小端序,实际字符串是xca3=xxx)
    push 0x3376616c         ; "lav3"
    mov eax, esp            ; eax指向xca3字符串的起始
    push eax
    push 0x3261783d         ; "=xca2"
    push 0x3276616c         ; "lav2"
    mov eax, esp
    push eax
    push 0x3161783d         ; "=xca1"
    push 0x3176616c         ; "lav1"
    mov eax, esp
    push eax
    mov edx, esp            ; edx = envp数组指针

    ; 构造argv数组(栈底到栈顶:NULL -> arg0)
    push 0
    push 0x68732f2f         ; "//sh"
    push 0x6e69622f         ; "/bin"
    mov ebx, esp            ; ebx = /bin/sh路径
    push ebx                ; arg0 = /bin/sh
    mov ecx, esp            ; ecx = argv数组指针

    ; 调用execve
    mov eax, 59
    int 0x80

验证方法

编译链接后运行程序,在弹出的shell中执行env命令,应该能看到xca1、xca2、xca3三个变量。如果仍未出现,检查:

  • 数组的NULL终止符是否存在
  • execve的参数寄存器赋值是否正确
  • 字符串的0终止字节是否缺失

内容的提问来源于stack exchange,提问作者Ahmed Tawfik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:05:09