какую функцию установить "имя_программы_включения"?и когда? - PullRequest
0 голосов
/ 11 сентября 2018

Вот немного информации, которую я получил о program_invocation_name:

  • Это значение содержит имя, которое использовалось для вызова вызывающей программы.
  • Это значение автоматически инициализируется.
  • Это значение является глобальной переменной.
    ( Итак, на первый взгляд, я думал, что оно было в <.bss> или <.data>.
    Но оно было в stack области памятиСтранно ...
    )


Вот представление отладчика program_invocation_name:

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


Проблема)

Я следил за ходом выполнения от начала программы до конца, но не смог найти в тот момент , который program_invocation_name установлен.


Вопрос)

Q1 .Кто (какая функция) установил это значение?(loader устанавливает это значение ..?)
Q2 .Как программа узнает, распознают его как global variable, хотя это значение находится в stack?
Q3 .Иногда некоторые двоичные файлы работают без этого значения.В этом случае это проблема loader?

1 Ответ

0 голосов
/ 12 сентября 2018

Кто (какая функция) установил это значение? (загрузчик устанавливает это значение ..?)

Вы можете ответить на это, установив на нем точку наблюдения:

(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 (многие руткиты делают это)), а затем program_invocation_name продолжит указывать на местоположение стека где имя программы было раньше, но больше нет.

...