【发布时间】:2018-11-29 09:29:27
【问题描述】:
我正在尝试在 macOS 上的动态库内的 C 结构中插入声明为指针的函数。
我在 libA.dylib 中有这个结构:
libA.h:
typedef struct AStruct {
int (*sub)(AStruct *pAStruct, int a, int b);
} AStruct;
extern "C" AStruct * AStruct_new();
libA.cpp:
int sub(AStruct *pAStruct, int a, int b) {
return a - b;
}
AStruct * AStruct_new() {
AStruct *pAStruct = (AStruct *)malloc(sizeof(AStruct));
pAStruct->sub = *sub;
return pAStruct;
}
在名称修改后,我发现库中对应的名称是这样的:_Z3subP7AStructii
在我的 dylib(我将其注入客户端代码)中,我正在这样做:
typedef struct AStruct {
int (*sub)(AStruct *pAStruct, int a, int b);
} AStruct;
extern "C" int _Z3subP7AStructii(AStruct *pAStruct, int a, int b);
int _sub(AStruct *pAStruct, int a, int b) {
printf("interposed %s: ", __func__);
return pAStruct->sub(pAStruct, a, b);
} DYLD_INTERPOSE(_sub, _Z3subP7AStructii)
DYLD_INTERPOSE - 是来自 here 的 Apple 宏
相同的代码成功地适用于常规 C 函数、C++ 静态/实例方法,但无法弄清楚 struct 中的函数指针有什么问题:(
【问题讨论】:
-
与问题无关:尝试:
extern "C" int sub(....以避免名称混淆(尽管 sub 是一种常见名称)。 -
关键是我无法控制libA中的代码,这只是一个例子:(
-
还有其他问题,例如您似乎将结构
AStruct复制到您自己的代码中,这使其容易受到攻击,因为如果您的结构与libA中的结构之间甚至有一个字符不匹配,那么当您破坏one definition rule 时,您将有未定义的行为。这种不匹配甚至可能是一个空格。 -
它适用于常规 C 函数和 C++ 方法,无法理解我在这个带有结构函数指针的演示中做错了什么