I'm decompiling a very old game, and my goal is to restore 100% native code. As such, I would need to preserve the existing architecture as much as possible (e.g. just using std::function
isn't really helpful).
I have a collection of static functions with different number of parameters. They are stored in structure like this:
struct ScriptFunction
{
const wchar_t* m_name;
void* m_func; // ptr to specific function
void* m_returnType;
int m_argCount;
};
And are populated like this:
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},
...
So, how can I invoke ScriptFunction::m_func with given m_argCount and void** arguments? I have to push parameters somehow on stack and invoke func-call, but I have no idea.
Some asm code? va_list? But how to fill it in run-time?
UPD: Invoker looks like this
void CScriptAccessible::InvokeInternal(ScriptFunction* scriptFunc, void** args)
{
// here I have to push params from **args** to stack
// and somehow call ScriptFunction::m_func
// In assembly I could see pushes to stack in a loop (driven by
// ScriptFunction::m_argCount). But I'm wondering, whether it's
// possible to do in C++ (push args on stack and call function by just address)
}