问题描述
如何从共享对象中找到程序的argc
和argv
?我正在用 C 编写一个库,它将通过 LD_PRELOAD
加载.我已经能够以两种不同的方式找到堆栈:
How do I find a program's argc
and argv
from a shared object? I am writing a library in C that will be loaded via LD_PRELOAD
. I've been able to find the stack two different ways:
- 通过内联
__asm__
调用读取rsp
. - 读取
/proc//maps
并解析堆栈条目.
- Read
rsp
via inline__asm__
call. - Read
/proc/<pid>/maps
and parse the entry for stack.
然后我可以创建一个指针,将它指向堆栈段,然后遍历查找数据.问题是我无法找出一种有效的方法来确定哪些字节是 argc
以及指向 argv
字符串的指针的指针.
I can then create a pointer, point it at the stack segment, then iterate through looking for data. The problem is I can't figure out an efficient way to determine what bytes are argc
and the pointer to the pointer to the argv
strings.
我知道 /proc/<pid>/cmdline
还包含参数,每个参数由 0x00
分隔,但我有兴趣在内存中查找所有内容.
I know that /proc/<pid>/cmdline
also contains the arguments, each separated by 0x00
, but I'm interested in finding everything in memory.
在 gdb 中,我看到 argc
的 DWORD
后跟一个 QWORD
,它是第一个指针.argc
地址前的 20 个字节是一个指向主程序代码段的指针.但这不是识别 argc
和 argv
的确定性方法.
In gdb I see a DWORD
for argc
followed by a QWORD
which is the first pointer. 20 bytes before the address of argc
is a pointer that points back into the main program's code segment. But that's not a deterministic way to identify argc
and argv
.
我看过一些帖子,但没有工作代码:
I've seen a few posts but no working code:
- http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.system/2005-07/0296.html
- https://sourceware.org/ml/libc-help/2009-11/msg00010.html
推荐答案
您的第二个链接中的此响应包含对我来说很好用的工作源代码(基于 Gnu/Linux elf 的系统),包括在 LD_PRELOAD
期间.
This response in your second link contains working source code which worked fine for me (Gnu/Linux elf-based system), including during LD_PRELOAD
.
代码很短;它由一个函数组成:
The code is very short; it consists of a function:
int foo(int argc, char **argv, char **env) {
// Do something with argc, argv (and env, if desired)
}
以及 .init_array
部分中指向该函数的指针:
and a pointer to that function in the .init_array
section:
__attribute__((section(".init_array"))) static void *foo_constructor = &foo;
将其放入共享库,然后 LD_PRELOADing 共享库肯定会在我尝试时触发对 foo
的调用,并且显然使用 argc
和 argv
稍后将传递给 main
(以及 environ
的值).
Putting that into a shared library and then LD_PRELOADing the shared library certainly triggered the call to foo
when I tried it, and it was clearly called with the argc
and argv
which would later be passed to main
(and also the value of environ
).
这篇关于从库中查找 argc 和 argv的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!