gpt4 book ai didi

linux - 为什么LD_PRELOAD的值在栈上

转载 作者:太空宇宙 更新时间:2023-11-04 04:16:36 26 4
gpt4 key购买 nike

我正在研究缓冲区溢出并解决一些兵棋推演。存在一个问题,即缓冲区上方的所有堆栈内存都设置为 0,除了 main 的返回地址之外,这将是:

buffer
[0000000...][RET][000000...]

我可以覆盖那个 RET。所以我找到了一些解决这个问题的提示。就是使用LD_PRELOAD。有人说LD_PRELOAD的值不仅在堆栈的环境变量区域,而且在堆栈的某个地方。所以我设置了LD_PRELOAD并搜索它并使用gdb找到了它。

$ export LD_PRELOAD=/home/coffee/test.so
$ gdb -q abcde
(gdb) b main
Breakpoint 1 at 0x8048476
(gdb) r
Starting program: /home/coffee/abcde

Breakpoint 1, 0x8048476 in main ()
(gdb) x/s 0xbffff6df
0xbffff6df: "@èC\001@/home/coffee/test.so"
(gdb) x/s 0xbffffc59
0xbffffc59: "LD_PRELOAD=/home/coffee/test.so"
(gdb) q
The program is running. Exit anyway? (y or n) y
$

所以有!现在我知道 LD_PRELOAD 的值位于缓冲区下方的堆栈上,现在我可以利用它了!

但我想知道为什么 LD_PRELOAD 会加载到该内存地址上。该值也在堆栈的环境变量区域中!

这样做的目的是什么?谢谢。

最佳答案

探索堆栈布局的代码:

#include <inttypes.h>
#include <stdio.h>

// POSIX 2008 declares environ in <unistd.h> (Mac OS X doesn't)
extern char **environ;

static void dump_list(const char *tag, char **list)
{
char **ptr = list;
while (*ptr)
{
printf("%s[%d] 0x%.16" PRIXPTR ": %s\n",
tag, (ptr - list), (uintptr_t)*ptr, *ptr);
ptr++;
}
printf("%s[%d] 0x%.16" PRIXPTR "\n",
tag, (ptr - list), (uintptr_t)*ptr);
}

int main(int argc, char **argv, char **envp)
{
printf("%d\n", argc);
printf("argv 0x%.16" PRIXPTR "\n", (uintptr_t)argv);
printf("argv[argc+1] 0x%.16" PRIXPTR "\n", (uintptr_t)(argv+argc+1));
printf("envp 0x%.16" PRIXPTR "\n", (uintptr_t)envp);
printf("environ 0x%.16" PRIXPTR "\n", (uintptr_t)environ);

dump_list("argv", argv);
dump_list("envp", envp);
return(0);
}

将程序编译为 x 后,我在经过清理的环境中运行它:

$ env -i HOME=$HOME PATH=$HOME/bin:/bin:/usr/bin LANG=$LANG TERM=$TERM ./x a bb ccc
4
argv 0x00007FFF62074EC0
argv[argc+1] 0x00007FFF62074EE8
envp 0x00007FFF62074EE8
environ 0x00007FFF62074EE8
argv[0] 0x00007FFF62074F38: ./x
argv[1] 0x00007FFF62074F3C: a
argv[2] 0x00007FFF62074F3E: bb
argv[3] 0x00007FFF62074F41: ccc
argv[4] 0x0000000000000000
envp[0] 0x00007FFF62074F45: HOME=/Users/jleffler
envp[1] 0x00007FFF62074F5A: PATH=/Users/jleffler/bin:/bin:/usr/bin
envp[2] 0x00007FFF62074F81: LANG=en_US.UTF-8
envp[3] 0x00007FFF62074F92: TERM=xterm-color
envp[4] 0x0000000000000000
$

如果您仔细研究,您会发现 main()argv 参数是一系列指向堆栈上层字符串的指针的开始; envp(POSIX 机器上 main() 的可选第三个参数)与全局变量 environargv[argc+1] 相同,也是一系列指向堆栈上层字符串的指针的开始; argv 和 envp 指针指向的字符串位于两个数组后面。

这是 Mac OS X 上的布局(10.7.5,如果重要的话,但可能不重要),但我确信您会在其他类 Unix 系统上找到相同的布局。

关于linux - 为什么LD_PRELOAD的值在栈上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16121364/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com