我正在反编译一个非常老的游戏,我的目标是还原100%本机代码。因此,我需要尽可能地保留现有架构(例如,仅使用amp-custom
并没有太大帮助)。
我有一组静态函数,它们具有不同数量的参数。它们存储在这样的结构中:
std::function
并且这样填充:
struct ScriptFunction
{
const wchar_t* m_name;
void* m_func; // ptr to specific function
void* m_returnType;
int m_argCount;
};
那么,如何使用给定的 m_argCount 和 void **参数调用 ScriptFunction :: m_func ?我必须以某种方式在堆栈上推送参数并调用func-call,但是我不知道。
一些asm代码? va_list?但是如何在运行时填充它?
UPD:调用方看起来像这样
ScriptFunction s_functions[206] = {
{L"AddMoveAroundDesire", &ScriptFunctions::AddMoveAroundDesire, &CScriptType::s_void, 2},
{L"AddDoNothingDesire", &ScriptFunctions::AddDoNothingDesire, &CScriptType::s_void, 2},
{L"AddAttackDesire", &ScriptFunctions::AddAttackDesire, &CScriptType::s_void, 3},
{L"AddAttackDesireEx", &ScriptFunctions::AddAttackDesireEx, &CScriptType::s_void, 4},
{L"AddGetItemDesire", &ScriptFunctions::AddGetItemDesire, &CScriptType::s_void, 2},
...
答案 0 :(得分:1)
在该语言内,仅存在switch
/ cast解决方案。这样,编译器就可以生成正确的调用约定:例如,在x86-64 Linux上,前几个参数在预定义的寄存器中传递。 (优化程序可能将不同的路径合并为跳转,成为您期望的那种展开循环。)还要记住,仅在C / C ++中根本没有“堆栈”。
顺便说一句,也不能保证为函数使用void*
(因为它可以指向任何 object 但它们不是对象),尽管它通常可以工作(并且POSIX要求{ {1}}。