Warum sys_enter_execve den Programmnamen über BPF_Get_Current_Comm erhalten

Post a reply

Smilies
:) :( :oops: :chelo: :roll: :wink: :muza: :sorry: :angel: :read: *x) :clever:
View more smilies

BBCode is ON
[img] is ON
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: Warum sys_enter_execve den Programmnamen über BPF_Get_Current_Comm erhalten

by Guest » 22 Feb 2025, 13:29

Ich entwickle EBPF -Programmierung. Manchmal kann ich den Programmnamen mit Execve nicht erhalten, aber ich kann execv und syScall (sys_execve, ...) verwenden. Der spezifische Code lautet wie folgt: < /p>

EBPF-Code < /li>
< /ol>

Code: Select all

static u32 ebpf_getppid(void)
{
struct task_struct *task = (struct task_struct *)bpf_get_current_task();
struct task_struct *parent = (struct task_struct *)BPF_CORE_READ(task, real_parent);

return BPF_CORE_READ(parent, tgid);
}

SEC("tp/syscalls/sys_enter_execve")
int tracepoint__syscalls__sys_enter_execve(struct trace_event_raw_sys_enter *ctx)
{
struct epm_command command = {};
const char *filename = (const char *)BPF_CORE_READ(ctx, args[0]);
const unsigned long *argv_ptr = (const unsigned long *)BPF_CORE_READ(ctx, args[1]);
const unsigned long *envp_ptr = (const unsigned long *)BPF_CORE_READ(ctx, args[2]);
char temp[128] = {0};

for(int i = 0; i < 4; i++){
bpf_printk("args[%d]: 0x%lx\n", i, BPF_CORE_READ(ctx, args[i]));
}

command.process_id = ebpf_getppid();
command.timestamp = bpf_ktime_get_ns();
bpf_get_current_comm(&command.process_name, sizeof(command.process_name));

bpf_probe_read_str(&command.call_prog_name, sizeof(command.call_prog_name), filename);

bpf_printk("Parent Process name: %s\n", command.process_name);
bpf_printk("Call Process name: %s\n", command.call_prog_name);

for(int i = 0; i < 64; i++) {
unsigned long arg_ptr = 0;
__builtin_memset(temp, 0, sizeof(temp));

bpf_probe_read_str(&arg_ptr, sizeof(arg_ptr), &argv_ptr[i]);
if(arg_ptr == 0) {
break;
}
bpf_probe_read_str(temp, sizeof(temp), (void *)arg_ptr);
bpf_printk("argv[%d]: %s\n", i, temp);
}

for(int i = 0; i < 64; i++) {
unsigned long env_ptr = 0;
__builtin_memset(temp, 0, sizeof(temp));

bpf_probe_read_str(&env_ptr, sizeof(env_ptr), &envp_ptr[i]);
if(env_ptr == 0) {
break;
}
bpf_probe_read_str(temp, sizeof(temp), (void *)env_ptr);
bpf_printk("envp[%d]: %s\n", i, temp);
}

bpf_map_update_elem(&epm_execve_map, &command.process_id, &command, BPF_ANY);

return 0;
}
< /code>

 Code auf Benutzerebene, der den Programmnamen nicht abrufen kann < /li>
< /ol>
< pre class = "Lang-C PrettyPrint-Override">int main() {
char *args[] = {"/usr/bin/ls", "-l", NULL, NULL};
char *envp[] = {NULL};
execve("/usr/bin/ls", args, envp);
return 0;
}
< /code>

 Code auf Benutzerebene, mit dem der Programmname < /li>
< /ol>
< pre class = "Lang-C PrettyPrint-Override">int main() {
char *args[] = {"/usr/bin/ls", "-l", NULL, NULL};
char *envp[] = {NULL};
printf("args addr: %p\n", args);
printf("envp addr: %p\n", envp);
execve("/usr/bin/ls", args, envp);
return 0;
}
Die Differenz zwischen den beiden Codes auf Anwendungsebene besteht darin, dass Printf hinzugefügt wird, um Argumente und envp zu drucken. Ich möchte fragen, was der spezifische Grund dafür ist?
Ich hoffe, die richtige Antwort auf die oben beschriebene Frage zu erhalten>

Top