【发布时间】:2020-08-06 02:32:16
【问题描述】:
我正在尝试编写一个程序,该程序将运行动态库中的函数,其名称、参数及其类型由用户输入。我可以使用dlsym(func_name) 获得指向此函数的 void* 指针,但是我事先不知道参数的类型及其数量,因此我无法以正常方式取消引用此指针。
如果我将所有参数的字节表示复制到char * 数组中,我可以调用一个以该数组作为参数的函数吗?例如,在汇编中调用 printf 时,我可以将参数和格式字符串推送到堆栈并调用 printf。也许我可以在 C 中做类似的事情,或者使用程序集插入?
例如,假设函数是void func(int, double);,我得到了参数int a 和double b。然后我会创建一个数组:
char buf[sizeof(int) + sizeof(double)]
memcpy(buf, &a, sizeof(int))
memcpy(buf + sizeof(int), &b, sizeof(double))
并将其用作压入堆栈的参数。
用户输入函数的名称、描述其类型的字符串以及参数本身。例如:
func_name
viid
5
6
2.34
func_name 是将在 dlsym 中使用的函数的名称。 viid 表示该函数具有 void func_name(int, int, double) 类型(第一个 char 是返回类型,其余是参数。v = void,i = int,d = double)。其余的都是参数。
【问题讨论】:
-
我相信它可以通过铸造以某种方式完成。尝试将参数作为 char 数组发送,并通过转换为实际类型来读取它。这东西需要一些试验才能成功。但是如果在你得到参数之后你仍然不知道类型,这可能是一个问题,因为你不知道如何阅读参数。也许您应该发送更多参数来解释其他参数的类型。
-
不一定只有大小,还有类型。像 FP 这样的不同类型可能使用不同的堆栈。
-
我不认为你真的能做到这一点。有些变量在寄存器中传递,有些在堆栈中传递,这取决于数据类型。
-
您可能想阅读以下内容:x86 calling conventions
-
@OP 试试
libffisourceware.org/libffi
标签: c dynamic-linking