免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2094 | 回复: 4
打印 上一主题 下一主题

[Linux] (堆栈)函数环境变量地址问题 求解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-01-21 11:31 |只看该作者 |倒序浏览
本帖最后由 shuimuyq 于 2016-01-21 11:43 编辑

我的代码是:
/* env.c */
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        char *env = getenv(argv[1]);

        printf("%p\n", env);
        return 0;
}

我的操作过程如下:先分别执行两个程序,再gdb调试

直接执行:
shell# export EGG="XXXXX"
shell# gcc env.c -o a -g
shell# gcc env.c -o bbbbbbbbb -g  (9个b)
shell# ./a EGG
0x7fffffffe54c
shell# ./bbbbbbbbb EGG
0x7fffffffe53c


gdb调试:
shell# gdb a
(gdb) b main
Breakpoint 1 at 0x40058c: file env.c, line 6.
(gdb) run EGG
Starting program: /root/Desktop/a EGG

Breakpoint 1, main (argc=2, argv=0x7fffffffdf98 ) at env.c:6
6                char *env = getenv(argv[1]);
(gdb) n
8                printf("%p\n", env);
(gdb) p env
$1 = 0x7fffffffe522 "xsadf"



shell# gdb bbbbbbbbb
(gdb) b main
Breakpoint 1 at 0x40058c: file env.c, line 6.
(gdb) run EGG
Starting program: /root/Desktop/bbbbbbbbb EGG

Breakpoint 1, main (argc=2, argv=0x7fffffffdf88 ) at env.c:6
6                char *env = getenv(argv[1]);
(gdb) n
8                printf("%p\n", env);
(gdb) p env
$1 = 0x7fffffffe51a "xsadf"



我的问题是:
按照堆栈理论(32位)
--------------------- 0xBFFFFFFF
|\000 \000 \000 \000| 0xBFFFFFFB (4 NULL byte)
|\000 ......     | 0xBFFFFFFA (program_name)
| ..................|
|...................| n. environment variable (env[n])
|...................| n-1. environment variable (env[n-1])
|...................|           ...
|...................| 1. environment variable (env[0])
|...................| ...
|...................| n. argument string (argv[n])
|...................| n-1. argument string (argv[n-1])
|...................| ...
|          .        |
|          .        |
|          .        |

环境变量EGG, 无论是在执行时还是调试时EGG环境变量的地址 bbbbbbbbb 比 a应该只偏移8个字节
最后的结果却是,执行时偏移16个字节 即( strlen("bbbbbbbbb" ) - strlen("a" ) ) * 2
shell# ./a EGG
0x7fffffffe54c
shell# ./bbbbbbbbb EGG
0x7fffffffe53c

调试时是偏移8字节符合预期,而且通过x/10000c $rsp, 也可以发现在环境变量之前与程序名有关的只出现一次
(gdb) p env
$1 = 0x7fffffffe522 "xsadf"      (a EGG)

(gdb) p env
$1 = 0x7fffffffe51a "xsadf"      (bbbbbbbbb EGG)

为什么会这样呢?

论坛徽章:
0
2 [报告]
发表于 2016-01-21 13:15 |只看该作者
在我电脑运行的时候,两个指针地址差了好多。。。。根本不是你说的8 或者 16 Bytes

论坛徽章:
0
3 [报告]
发表于 2016-01-21 14:09 |只看该作者
回复 2# sheepbao


    echo 0 > /proc/sys/kernel/randomize_va_space
你先执行上面的语句试试

论坛徽章:
0
4 [报告]
发表于 2016-01-22 12:05 |只看该作者
bao@bao-listome chinaUnix$ ./a EGG
0x7fffffffe212
bao@bao-listome chinaUnix$ ./bbbbbbbbbb EGG
0x7fffffffe200

gdb:
a
(gdb) p env
$1 = 0x7fffffffe201 "egg"

bbbbbbbbbb
(gdb) p env
$1 = 0x7fffffffe1f8 "egg"

论坛徽章:
0
5 [报告]
发表于 2016-01-22 12:22 |只看该作者
回复 4# sheepbao


你的bbbbbbbbbb 有10个, 不过这个没关系
最后的结果跟我的预想是一样的

直接运行时 两个程序的环境变量相差
(strlen("bbbbbbbbb" ) - strlen("a" ) ) * 2个字节
如果是10个b就相差 (10 - 1)*2 = 18个字节

你的结果也证明了 e212 - e200 = 0x12 = 18

bao@bao-listome chinaUnix$ ./a EGG
0x7fffffffe212
bao@bao-listome chinaUnix$ ./bbbbbbbbbb EGG
0x7fffffffe200

而gdb调试时相差
(strlen("bbbbbbbbb" ) - strlen("a" ) ) 个字节




我只是想知道直接运行的时候 在EGG环境变量之前 是否又添加了一个与程序名相关的数据
按照我的理解,应该只有一项才对
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP