- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在研究缓冲区溢出并解决一些兵棋推演。存在一个问题,即缓冲区上方的所有堆栈内存都设置为 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()
的可选第三个参数)与全局变量 environ
和 argv[argc+1]
相同,也是一系列指向堆栈上层字符串的指针的开始; argv 和 envp 指针指向的字符串位于两个数组后面。
这是 Mac OS X 上的布局(10.7.5,如果重要的话,但可能不重要),但我确信您会在其他类 Unix 系统上找到相同的布局。
关于linux - 为什么LD_PRELOAD的值在栈上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16121364/
我的代码如下:preload.c,内容如下: #include #include int __attribute__((constructor)) main_init(void) {
我尝试使用 LD_PRELOAD 来 Hook sprintf function ,所以我将打印到缓冲区的结果: #define _GNU_SOURCE #include #include int
实际问题 我有一个默认情况下使用 EGL 和 SDL 1.2 分别处理图形和用户输入的可执行文件。使用 LD_PRELOAD ,我已经用 GLFW 替换了两者。 这正常工作,除非用户安装了 GLFW
我用 C 代码编写二进制文件。如何防止其他用户在我的二进制文件上使用 LD_PRELOAD? 使用LD_PRELOAD时,是否有任何信号可以让我处理并中断程序? 如果我静态编译二进制文件,我听说 LD
我用 C 代码编写二进制文件。如何防止其他用户在我的二进制文件上使用 LD_PRELOAD? 使用LD_PRELOAD时,是否有任何信号可以让我处理并中断程序? 如果我静态编译二进制文件,我听说 LD
这可能会很尴尬: 我在其他项目中使用库预加载,但我无法让这个最小的示例工作: weakref.h: void f_weak() __attribute__((weak)); weakref.c: #i
目前,我有一个应用程序可以: execlp(java_exec、java_args等); 启动 jar 文件。 有没有办法将其前置 LD_PRELOAD="mylib.so" ? 我找不到告诉 exe
我有一个 LD_PRELOAD 文件。在什么操作系统和条件下,我应该编译这个预加载以在大多数系统 (Unix/Linux) 上工作。最想要的是 FreeBSD、Ubuntu、CenstOS、Solar
我有一个用 C 编写的客户端和一个服务器。为了保护我实现的连接: 我自己连接并接受 Diffie-Hellman key 。 我自己发送和接收,以便使用 AES 加密流量。基本上,我用数据加密缓冲区并
我在 Google 的 tcmalloc 上看到了这条建议文档页面。 You can use TCMalloc in applications you didn't compile yourself,
在 Ubuntu 16.04 系统上,一直在尝试将 ld_preload 与自定义编译的 libpcap.so 一起使用并运行 tcpdump。 编译 libpcap (1.8.0) ./config
我正在尝试 LD_PRELOAD 一个声明如下的函数 // header1.h typedef enum { ... } enum1; // header2.h typedef enum { ...
我们有一个在嵌入式 powerpc 上运行的用 g++ 编译的多线程 c++ 应用程序。为了在持续集成测试中对此进行内存泄漏测试,我们创建了一个使用 ld_preload 加载的堆分析器。 我们想保证
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
是否可以使用 LD_PRELOAD 覆盖其中一个 linux 内核函数? 例如,我想在 Linux/net/ipv4/syncookie.c 中为我的程序 fooserver。我可以使用 LD_PRE
我编写了 LD_PRELOAD 模块,我的所有源代码都在 source.cpp 中,但现在我需要添加 crypt.cpp 文件以及我需要的一些类,如何使用多个 .cpp 文件通过 g++ 编译 LD_
我有这个小测试代码atfork_demo.c: #include #include void hello_from_fork_prepare() { printf("Hello from
我有我的 .so 库,我将它注入(inject)到我的 Ubuntu 服务器上的各种进程中。但是我找到了我用常规命令启动的二进制文件: LD_PRELOAD=/home/glinkd/preload3
我需要在 Linux 中记录所有终端命令。我在 C 中找到了正确工作的库,但它仅在我运行 LD_PRELOAD=/usr/local/bin/bashpreload.so/bin/bash 时有效:
操作系统: Ubuntu 16.04 64 位 python : 2.7.12 我有一个非常简单的 Python 程序,它只加载了两个库 libhidapi-hidraw 和 libpcProxAPI
我是一名优秀的程序员,十分优秀!