1

我有这个结构:

typedef struct xyz_data {
    void *myfa; <------- correct
    void *myfb; <------- incorrect
}

这个函数定义:

asmlinkage ssize_t (*real_sys_read)(unsigned int fd, char __user *buf, size_t count);
asmlinkage ssize_t hooked_sys_read(unsigned int fd, char __user *buf, size_t count);

(正如您可能猜到的,这将指向内核的__NR_read)。

保存hooked_sys_read*myfa;就像简单一样xyz_data_something->myfa = hooked_sys_read,但是呢myfb?我不确定xyz_data_something->myfb = &real_sys_read会不会奏效。

我正在劫持一些系统调用(如果您对项目感兴趣,GitHub 中提供了所有内容)并且每个被劫持的系统调用都将使用该结构来调用它所属的真实系统调用(将通过 访问*myfb),利用返回值。

请记住,每个系统调用都有自己的返回类型。

4

2 回答 2

2

设想

typedef struct xyz_data {
    void *myfa;
    void *myfb;
} xyz_data;  // Type name assumed — not specified in question

asmlinkage ssize_t (*real_sys_read)(unsigned int fd, char __user *buf, size_t count);
asmlinkage ssize_t hooked_sys_read(unsigned int fd, char __user *buf, size_t count);

xyz_data *xyz_data_something = ...;

xyz_data_something->myfa = hooked_sys_read;
xyz_data_something->myfb = &real_sys_read;

分析

你写的不是类型安全的(所以编译器帮不了你太多),但你正在获取保存指向“真正的 sys read”函数的指针的变量的地址,而不是该指针的副本(因为的&)。您可以将&(and *) 应用于函数名称,它们最终都相同:

reader->myfa =    &hooked_sys_read;
reader->myfa =     hooked_sys_read;
reader->myfa =    *hooked_sys_read;
reader->myfa =   **hooked_sys_read;
reader->myfa =  ***hooked_sys_read;
reader->myfa = ****hooked_sys_read;

你不能用指向函数的指针来做到这一点。请注意,当您执行以下操作时,编译器甚至无法诊断“分配给对象指针的函数指针”问题:

xyz_data_something->myfb = &real_sys_read;

您将(函数)指针变量的地址分配给 a void *,因此您将对象指针分配给 void 指针,这是合法的 - 但不正确。

合成

您应该具有以下两种函数类型 typedef 之一:

typedef ssize_t ReadFunction(unsigned int fd, char __user *data, size_t size);
typedef ssize_t (*ReadPointer)(unsigned int fd, char __user *data, size_t size);

那么你的结构可以是:

typedef struct xyz_data
{
    ReadFunction *myfa;
    ReadFunction *myfb;
} xyz_data;

或者:

typedef struct xyz_data
{
    ReadPointer myfa;
    ReadPointer myfb;
} xyz_data;

给定一个结构指针:

xyz_data *reader = ...;

以下分配将编译干净并正常工作(对于两种结构类型):

reader->myfa = hooked_sys_read;
reader->myfb = real_sys_read;

概念证明

#include <sys/types.h>
#define asmlinkage
#define __user

asmlinkage ssize_t (*real_sys_read)(unsigned int fd, char __user *buf, size_t count);
asmlinkage ssize_t hooked_sys_read(unsigned int fd, char __user *buf, size_t count);

typedef ssize_t (*ReadPointer)(unsigned int fd, char __user *data, size_t size);

typedef struct xyz_data
{
    ReadPointer myfa;
    ReadPointer myfb;
} xyz_data;

extern xyz_data getter(void);

xyz_data getter(void)
{
    xyz_data data;
    xyz_data *reader = &data;

    reader->myfa = hooked_sys_read;
    reader->myfb = real_sys_read;
//  The next line fails to compile: assignment from incompatible pointer type
//  reader->myfb = &real_sys_read;

    reader->myfa =    &hooked_sys_read;
    reader->myfa =     hooked_sys_read;
    reader->myfa =    *hooked_sys_read;
    reader->myfa =   **hooked_sys_read;
    reader->myfa =  ***hooked_sys_read;
    reader->myfa = ****hooked_sys_read;
    return *reader;
}

它编译干净。不过,这不是好的代码——单是重复的赋值就足以让它变得糟糕。

于 2013-09-15T19:16:20.143 回答
1

您不应该将函数指针分配给 void 指针。

请参阅https://stackoverflow.com/a/5579907/1351983

于 2013-09-15T17:54:44.767 回答