什么函数设置“ program_invocation_name”?什么时候?

时间:2018-09-11 11:59:18

标签: assembly x86 binary executable elf

以下是有关program_invocation_name的一些信息:

  • 此值包含用于调用调用程序的名称。
  • 该值会自动初始化。
  • 此值为全局变量。
    因此,乍一看,我认为它位于<.bss><.data>中。
    但这是在stack内存区域中。太奇怪了...


这是program_invocation_name的调试器视图:

pwndbg> x/s program_invocation_name
0xbffff302: "/tmp/my_program"


问题)

我从程序的开始到结束都遵循执行流程,但是我找不到 时刻 ,已经设置了program_invocation_name


问题)

第一季度 。谁(什么功能)设置此值? (loader设置此值。.?)
第二季度 。尽管此值位于global variable中,但程序如何知道将其识别为stack
第三季度 。有时,某些二进制文件运行时没有此值。在这种情况下,是loader的问题吗?

1 个答案:

答案 0 :(得分:3)

  

谁(什么功能)设置此值? (加载程序设置此值..?)

您可以通过在其上设置观察点来对此进行回答:

(gdb) start

Temporary breakpoint 1, main () at t.c:5
5     return 0;
(gdb) info var program_invocation_name
All variables matching regular expression "program_invocation_name":

Non-debugging symbols:
0x00007ffff7dd43b8  program_invocation_name
0x00007ffff7dd43b8  program_invocation_name
(gdb) watch *(char **)0x00007ffff7dd43b8
Hardware watchpoint 2: *(char **)0x00007ffff7dd43b8
(gdb) run
Starting program: /tmp/a.out
Hardware watchpoint 2: *(char **)0x00007ffff7dd43b8

Old value = <unreadable>
New value = 0x7ffff7b9b7a5 ""
0x00007ffff7de4c02 in _dl_relocate_object () from /lib64/ld-linux-x86-64.so.2
(gdb) c
Continuing.
Hardware watchpoint 2: *(char **)0x00007ffff7dd43b8

Old value = 0x7ffff7b9b7a5 ""
New value = 0x7fffffffdfa7 "/tmp/a.out"
0x00007ffff7b22963 in __init_misc () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0  0x00007ffff7b22963 in __init_misc () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff7a5a134 in _init () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff7de886a in call_init.part () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7de89bb in _dl_init () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7dd9c5a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#5  0x0000000000000001 in ?? ()
#6  0x00007fffffffdfa7 in ?? ()
  

ZQ2。程序知道如何将其识别为全局变量,尽管该值位于堆栈中?

变量.data部分中的全局变量:

(gdb) info sym 0x00007ffff7dd43b8
program_invocation_name in section .data of /lib/x86_64-linux-gnu/libc.so.6

这是一个指向堆栈的指针(它指向内核将argv[]传递给进程的堆栈区域)。

  

Q3。有时,某些二进制文件运行时没有此值。在这种情况下,是装载机的问题吗?

没有该变量的二进制文件将无法运行。但是变量可能指向空字符串(例如,如果父进程未使用通常的调用约定,而是执行了execl("/tmp/a.out", (char*)NULL)之类的操作)。

此外,程序可以“擦除”其自己的堆栈(例如,由于堆栈溢出或有意从ps隐藏(许多rootkit这样做)),然后program_invocation_name将继续指向到程序名称曾经是但不再是的堆栈位置。