gpt4 book ai didi

c - PTRACE_GET_SYSCALL_INFO 未声明 : including sys/ptrace. h 似乎没有获取所有 ptrace 代码

转载 作者:行者123 更新时间:2023-11-30 16:07:45 28 4
gpt4 key购买 nike

来自手册页:

PTRACE_GET_SYSCALL_INFO (since Linux 5.3)

Retrieve information about the system call that caused the stop. The information is placed into the buffer pointed by the data argument, which should be a pointer to a buffer of type struct ptrace_syscall_info. The addr argument contains the size of the buffer pointed to by the data argument (i.e., sizeof(struct ptrace_syscall_info)). The return value contains the number of bytes available to be written by the kernel. If the size of the data to be written by the kernel exceeds the size specified by the addr argument, the output data is truncated.

>cat /proc/version
Linux version 5.3.0-kali2-amd64 (devel@kali.org) (gcc version 9.2.1 20191109 (Debian 9.2.1-19)) #1 SMP Debian 5.3.9-3kali1 (2019-11-20)
>

现在,我编写了这个小程序,由两个文件组成。

helpers.h

#ifndef HELPERS
#define HELPERS
//helpers.h
#include <errno.h>
#include <sys/ptrace.h>
#include <sys/types.h>


const char* op_to_string(__u8 op)
{
switch (op) {
case (PTRACE_SYSCALL_INFO_ENTRY):
return "SYSCALL_INFO_ENTRY";
break;
case (PTRACE_SYSCALL_INFO_EXIT):
return "SYSCALL_INFO_EXIT";
break;
case (PTRACE_SYSCALL_INFO_SECCOMP):
return "SYSCALL_INFO_SECCOMP";
break;
default:
fprintf(stderr, "op-to-string: Invalid op code");
}
}


void err_wrap(const int ret, const int success, const char *msg)
{
if (ret != success)
{
perror(msg);
}
}


void print_regs(const struct user_regs_struct regs) {
printf ("r15: %16llx %30s\n", regs.r15, "general purpose registers");
printf ("r14: %16llx\n", regs.r14);
printf ("r13: %16llx\n", regs.r13);
printf ("r12: %16llx\n", regs.r12);
printf ("rbp: %16llx\n", regs.rbp);
printf ("rbx: %16llx\n", regs.rbx);
printf ("r11: %16llx\n", regs.r11);
printf ("r10: %16llx\n", regs.r10);
printf ("r9: %16llx %s\n", regs.r9, "6.");
printf ("r8: %16llx %s\n", regs.r8, "5.");
printf ("rax: %16llx\n", regs.rax);
printf ("rcx: %16llx %s\n", regs.rcx, "4.");
printf ("rdx: %16llx %s\n", regs.rdx, "3.");
printf ("rsi: %16llx %s\n", regs.rsi, "2.");
printf ("rdi: %16llx %30s\n", regs.rdi, "1. function/syscall argument"); // aka "parameter registers"
printf ("orig_rax:%16llx\n", regs.orig_rax);
printf ("rip: %16llx %30s\n", regs.rip, "instruction pointer");
printf ("cs: %16llx\n", regs.cs);
printf ("eflags: %16llx\n", regs.eflags);
printf ("rsp: %16llx %30s\n", regs.rsp, " Stack Pointer (current location in stack)");
printf ("ss: %16llx\n", regs.ss);
printf ("fs_base: %16llx\n", regs.fs_base);
printf ("gs_base: %16llx\n", regs.gs_base);
printf ("ds: %16llx\n", regs.ds);
printf ("es: %16llx\n", regs.es);
printf ("fs: %16llx\n", regs.fs);
printf ("gs: %16llx\n", regs.gs);
}

void print_syscall_info(struct ptrace_syscall_info sys_info) {
__u8 op = sys_info.op;
printf("Type of system call stop: %20s (%x)\n", op_to_string(op), op);
printf("Arch: %16llx\n", sys_info.arch);
}

#endif

tracetest.c

#include <stdio.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <sys/user.h>

#include <syscall.h>

#include "helpers.h"

// long ptrace(enum __ptrace_request request, pid_t pid,
// void *addr, void *data);



void child_code();
void parent_code(pid_t pid);

int main(const int argc, char *argv[])
{
pid_t pid;
switch (pid = fork())
{
case -1:
perror("fork");
break;
case 0:
child_code();
break;
default: //parent code
parent_code(pid);
}

return 0;
}

void parent_code(pid_t pid)
{
printf("Parent code\n");
int status;
if (wait(&status) == -1)
{
perror("parent wait one");
}
printf("Finished waiting\n");
printf("PID wait status is: %llx\n", status);
printf("My PID is %d\n", getpid());
err_wrap(
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_EXITKILL),
0, "ptrace-set-options");
struct user_regs_struct regs;
struct ptrace_syscall_info syscall_info;

while(1)
{
err_wrap(ptrace(PTRACE_SYSCALL, pid, 0, 0), 0, "ptrace-syscall first"); //Stop at next syscall.
if (wait(&status) == -1)
{
perror("parent wait one");
}
printf("syscall-entry-stop\n");
err_wrap(
ptrace(PTRACE_GET_SYSCALL_INFO, pid, sizeof(struct ptrace_syscall_info), &syscall_info),
0, "ptrace-get-syscall-info");
err_wrap(
ptrace(PTRACE_GETREGS, pid, 0, &regs),
0,
"ptrace-getregs");

print_regs(regs);
print_syscall_info(syscall_info);
}

}

void child_code() {
printf("Child code\n");
printf("Parent is: %d\n", getppid());
err_wrap(ptrace(PTRACE_TRACEME, 0,0,0), 0, "ptrace-traceme");
err_wrap(raise(SIGSTOP), 0, "raise");

unsigned int pleb = 0xffbbcde8;
int x = 0;
printf("Hello WoRld\n");

printf("Pleb is: %llx\n", pleb);
printf("x is: %d\n", x);
}

考虑到所有因素,我的代码应该正常运行而不会出现错误,但似乎 PTRACE_GET_SYSCALL_INFO 内容实际上并未包含在内,因为 gcc 正在提示:

>gcc -g -o tracetest tracetest.c
In file included from tracetest.c:10:
helpers.h:9:26: error: unknown type name ‘__u8’
9 | const char* op_to_string(__u8 op)
| ^~~~
helpers.h:72:32: warning: ‘struct ptrace_syscall_info’ declared inside parameter list will not be visible outside of this definition or declaration
72 | void print_syscall_info(struct ptrace_syscall_info sys_info) {
| ^~~~~~~~~~~~~~~~~~~
helpers.h:72:52: error: parameter 1 (‘sys_info’) has incomplete type
72 | void print_syscall_info(struct ptrace_syscall_info sys_info) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
helpers.h: In function ‘print_syscall_info’:
helpers.h:73:2: error: unknown type name ‘__u8’
73 | __u8 op = sys_info.op;
| ^~~~
helpers.h:74:54: warning: implicit declaration of function ‘op_to_string’ [-Wimplicit-function-declaration]
74 | printf("Type of system call stop: %20s (%x)\n", op_to_string(op), op);
| ^~~~~~~~~~~~
tracetest.c: In function ‘parent_code’:
tracetest.c:55:29: error: storage size of ‘syscall_info’ isn’t known
55 | struct ptrace_syscall_info syscall_info;
| ^~~~~~~~~~~~
tracetest.c:66:11: error: ‘PTRACE_GET_SYSCALL_INFO’ undeclared (first use in this function); did you mean ‘PTRACE_GETSIGINFO’?
66 | ptrace(PTRACE_GET_SYSCALL_INFO, pid, sizeof(struct ptrace_syscall_info), &syscall_info),
| ^~~~~~~~~~~~~~~~~~~~~~~
| PTRACE_GETSIGINFO
tracetest.c:66:11: note: each undeclared identifier is reported only once for each function it appears in
tracetest.c:66:48: error: invalid application of ‘sizeof’ to incomplete type ‘struct ptrace_syscall_info’
66 | ptrace(PTRACE_GET_SYSCALL_INFO, pid, sizeof(struct ptrace_syscall_info), &syscall_info),
| ^~~~~~

但是,如果我#include <linux/ptrace.h> ,那么我没有收到这些错误,而是显示了函数 ptrace.h 的隐式声明,老实说我认为这也不是很好。

我应该包含什么才能使此功能达到预期目的?我还包含了 sys/types.h ,但我仍然收到有关 __u8 的错误是一个未知的类型名称,但它是 ptrace.c 源代码中使用的类型,因此它不应该抛出任何错误。

ptrace 手册页的顶部显示:

#include <sys/ptrace.h>
long ptrace(enum __ptrace_request request, pid_t pid,
void *addr, void *data);`

所以我认为这个单一的包含就足够了,但它不起作用。

提前致谢。

最佳答案

这是因为 glibc 并未完全更新所有最新的 Linux 功能。您可以#include <linux/ptrace.h>#include <sys/ptrace.h>获取PTRACE_GET_SYSCALL_INFO .

关于c - PTRACE_GET_SYSCALL_INFO 未声明 : including sys/ptrace. h 似乎没有获取所有 ptrace 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59538074/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com