检查堆栈上的环境变量
我知道环境变量在内存中的堆栈上方,我想列出它们,或者至少能够使用gdb
来检查它们。首先,我将堆栈指针的地址放置,但是由于变量放置在堆栈上方,我该如何知道我应该增加地址的数量?
(gdb) info register rsp
rsp 0x7fffffffdf48 0x7fffffffdf48
(gdb) x/32s $rsp + 0x(mmm..)
我浏览网络时看到的一个例子是
x/32s $rsp + 0x240 // Why 0x240, exactly?
我认为我误解了SMTH。
I know that environment variables are above the stack in memory, and I want to list them or at least be able to see them through examining the stack using gdb
. First I take the address of the stack pointer but since the variables are placed above the stack, how do I know by how much I should increment the address?
(gdb) info register rsp
rsp 0x7fffffffdf48 0x7fffffffdf48
(gdb) x/32s $rsp + 0x(mmm..)
An example I saw while browsing the web was
x/32s $rsp + 0x240 // Why 0x240, exactly?
I think I misunderstood smth.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是Linux实现细节,
envp
vector(以及argv
),其元素存储在堆栈内存中 main 线程(仅)。 nofollow noreferrer“> system v Application v Application v Application二进制二进制界面AMD64 amd64 at lp64 and ILP322222222222222222222222222222222222222222。编程模型(请参见图3.9:初始过程堆栈)要求可执行的输入点_start
get %rsp 指向argc
,然后是argv
向量,然后是envp
向量,都在 main thread堆栈中。_start
(通常由您的语言/编译器运行时实现)消耗多少堆栈时运行时间的供应商,ABI仅与入口点有关_start
。高级后卫可以从主线程启动其他线程,然后终止主线程而无需终止过程。这样,没有线程堆栈包含环境。它还可以擦除其
argv
和envp
和/或向量指向的元素,以使它们在过程地址空间中变得无法使用。但是,后者不会影响/proc/proc/self/code>或
/proc/proc/proc/self/cmdline
由内核维护。确切的位置在
envp
参数为main
中。 C标准不需要任何东西,例如,线程堆栈是实现细节。这可能取决于选项,并与当前的堆栈一起编译了代码。
询问
x
显示一个较大的数组以查看环境变量:It is Linux implementation detail that
envp
vector (along withargv
) and its elements are stored in the stack memory of the main thread (only). System V Application Binary Interface AMD64 with LP64 and ILP32 Programming Models (see Figure 3.9: Initial Process Stack) requires that executable entry point_start
gets%rsp
which points toargc
, followed byargv
vector, followed byenvp
vector, all in the main thread stack. How much of the stack is consumed by_start
(normally implemented by your language/compiler run-time) when it invokesmain
is an implementation detail which depends on the version and the vendor of the run-time, the ABI is only concerned with entry point_start
.An advanced defender can start other threads from the main thread and then terminate the main thread without terminating the process. This way, no thread stack contains the environment. It can also wipe its
argv
andenvp
and/or the elements the vectors point to, so that they become unavailable in the process address space. The latter, however, doesn't affect/proc/self/environ
or/proc/self/cmdline
maintained by the kernel.The exact location is in
envp
argument tomain
. The C standard doesn't require anything beyond that, e.g. the thread stack is an implementation detail.That may depend on options the code was compiled with and the current stacktrace.
Ask
x
to display a larger array to see the environment variables:更新:
那是微不足道的:到GDB中的
main
级别的步骤,打印rbp
注册的值,然后使用您对堆栈布局的理解(请参见下文)。示例:
上面,您可以将
& argv [0] == 0x00007fffffffedb8
作为堆栈上的第三个字(其他两个是rbp
和返回地址)。使用下面的第一个示例代码恢复完整的argv []
和envp []
。如果您在
main()
中,在Linux上,您可以知道 Exact 堆栈的布局,并且可以检查argc
,argv []
和envp []
使用例如,此代码:您还可以利用GLIBC实际将
envp []
转换为main()
作为第三参数的事实:如果您是而不是在
main(Main()
中,并且不能具有main()
保存& argv [0]
在全局中,那么事情变得更棘手。您可以分析
/proc/proc/self/maps
以找出堆栈边界,并以这种方式检查堆栈(请参阅“ kernel设置的堆栈” e节在这里)。Update:
That's trivial: step to the
main
level in GDB, print the value of theRBP
register, and then use your understanding of stack layout (see below).Example:
Above, you can see the
&argv[0] == 0x00007fffffffedb8
as the 3rd word on the stack (the other two are the previous value ofRBP
and the return address). Use the first example code below to recover completeargv[]
andenvp[]
.If you are in
main()
, on Linux, you can know the exact layout of stack, and can examineargc
,argv[]
andenvp[]
using e.g. this code:You could also leverage the fact that GLIBC actually passes
envp[]
tomain()
as the 3rd argument:If you are not in
main()
, and can't havemain()
save&argv[0]
in a global, then things get trickier.You can parse
/proc/self/maps
to figure out stack boundaries, and examine the stack that way (see "stack set by kernel" section here).