gpt4 book ai didi

c - 在不知道返回类型的情况下将结构的成员初始化为函数指针

转载 作者:太空宇宙 更新时间:2023-11-04 02:07:49 25 4
gpt4 key购买 nike

我有这个结构:

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 访问) ), 利用返回值。

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

最佳答案

场景

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;

分析

你写的不是类型安全的(所以编译器帮不了你太多),但是你获取的是保存指向“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;

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

xyz_data_something->myfb = &real_sys_read;

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

综合

您应该拥有这两个函数类型类型定义之一:

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;
}

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

关于c - 在不知道返回类型的情况下将结构的成员初始化为函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18815440/

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