要获取系统调用的参数,您必须一一读取寄存器。为此,您需要知道哪些寄存器将存储系统调用的哪些参数。几个月前,我自己编写了一个这样的程序。基本上每个寄存器存储的内容是:
regs.rdi - 存储第一个参数
regs.rsi - 存储第二个参数
regs.rdx - 存储第三个参数
regs.r10 - 存储第四个参数
regs.r8 - 存储第五个参数
regs.r9 - 存储第六个参数
This table http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/提供了更详细的描述(请注意,它特定于 x86-64 架构)。
现在,您必须仔细阅读每个系统调用的文档才能理解它们并分别为它们编写代码。阅读不同的论点有不同的方法。
让我们采取read()
系统调用来演示这一点。
我们将看到不同类型的参数并了解如何访问它们。
第一个参数(int fd)
由于它是一个数字,因此将直接保存在寄存器中regs.rdi
.
在我的代码中,我需要获取该文件fd
指向所以我使用了以下代码。
sprintf(fdpath,"/proc/%u/fd/%llu",proc,regs.rdi);
size = readlink(fdpath, filepath, 256); //this gives the filepath for a particular fd
filepath[size] = '\0';
printf("File-%s-\n", filepath);
第二个参数 (void *buf) ptr 输入缓冲区
要阅读本文,您需要使用PTRACE_PEEKDATA
/ PTRACE_PEEKTEXT
请求(第一个参数ptrace()
)来读取字节。自从ptrace()
仅读取并返回8
一次字节,您需要使用迭代执行此操作long
多变的。应该还有另一个char *
指向内存的开头,稍后将使用它来读取字符串。
我使用的代码如下。
char message[1000];
char* temp_char2 = message;
int j = 0;
long temp_long;
while( j < (regs.rdx/8) ) //regs.rdx stores the size of the input buffer
{
temp_long = ptrace(PTRACE_PEEKDATA, proc, regs.rsi + (j*8) , NULL);
memcpy(temp_char2, &temp_long, 8);
temp_char2 += sizeof(long);
++j;
}
message[regs.rdx] = '\0';
printf("Message-%s-\n\n", message);
我只能说这么多。我想你可以通过这种方式读取大多数系统调用的几乎所有参数。
至于系统调用的名称。我把操作系统映射并做了一个手册switch
case 来获取系统调用的名称。
希望这可以帮助。 :)