Переменные среды, использующие execve() для запуска дочернего процесса
Я использую родительский процесс, который использует execve() для запуска дочернего процесса с конкретными переменными среды, которые я определил в родительском процессе. В родительском процессе, если я посмотрю на область памяти $esp + 0x240, я найду все переменные окружения. Однако, как только дочерний процесс запущен, я не могу найти адрес памяти, где были сохранены предопределенные переменные среды.
Я бы подумал, что поскольку execve() заменяет родительский процесс дочерним процессом, переменные среды, передаваемые дочернему процессу, будут расположены в 0xbffffffa минус длина строки переменной среды (в Linux). Однако, когда дочерний процесс запущен, у меня больше нет доступа к этому месту в памяти. Esp родительского процесса перед вызовом execve() равен 0xbffff120, после запуска дочернего процесса esp переходит к 0xbf9835a0. (Я предполагаю, что это потому, что у дочернего процесса есть привилегии root, которых у родительского процесса не было) Теперь, когда я смотрю на память от вершины стека до точки, где у меня больше нет доступа к памяти, нет подписано любой из переменных среды, которые были переданы из родительского процесса. Где они будут расположены? Кроме того, более общее замечание: когда вы запускаете процесс, все ли переменные среды копируются в верхнюю часть памяти в самом низу стека?
#include <stdio.h>
#include <stdlio.h>
#include <string.h>
#include <unistd.h>
char envvari[]=
"\x31\xc0\ ...." // Can be any environment variable
int main(int argc, char *argv[]) {
char *env[2] = {envvari, 0};
unsigned int i, ret;
char *buffer = (char *) malloc(160);
char *args[] = {"notesearch", buffer, 0};
ret = 0xbffffffa - (sizeof(envvari)-1) - strlen("./notesearch");
for(i=0; i < 160; i+=4)
*((unsigned int *)(buffer+i)) = ret;
execve("./notesearch", args, env);
free(buffer);
}
1 ответ
execve() не создает дочерний процесс. Это просто заменяет существующий процесс. Кроме того, execve() никогда не возвращается. fork() - системный вызов, который создает дочерний процесс. Свободный (буферный) вызов после execve() никогда не будет выполнен, если execve() успешен.