【发布时间】:2018-06-24 11:50:15
【问题描述】:
我正在反编译一款非常古老的游戏,我的目标是恢复 100% 原生代码。因此,我需要尽可能地保留现有架构(例如,仅使用 std::function 并没有真正的帮助)。
我有一组具有不同数量参数的 静态 函数。它们存储在这样的结构中:
struct ScriptFunction
{
const wchar_t* m_name;
void* m_func; // ptr to specific function
void* m_returnType;
int m_argCount;
};
并且像这样填充:
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},
...
那么,如何使用给定的 m_argCount 和 void** 参数调用 ScriptFunction::m_func ?我必须以某种方式在堆栈上推送参数并调用 func-call,但我不知道。
一些汇编代码? va_list?但是如何在运行时填充呢?
UPD: Invoker 看起来像这样
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)
}
【问题讨论】:
-
我为你删除了不需要的标签。如果你能解释一下为什么有帮助,请随时重新添加它,连同解释一起,并接受我的道歉。
-
你如何获得论点?你想如何通过它们?
-
ScriptFunctions函数(Scriptfunctions::AddMoveAroundDesire等)是静态的还是非静态的?每个人如何使用提供的ScriptFunction?这些问题对于选择调用/调用它们的选项是相当基础的,因为只有一个名为m_func的成员是一个void *和一组void **参数。 -
ScriptFunctions::* 是静态的(免费)。改变了描述。唯一的单一用法是在
CScriptAccessible::InvokeInternal内部。在汇编中,我可以看到推动堆栈循环(由ScriptFunction::m_argCount驱动)。但我想知道,是否可以在 C++ 中执行(将参数推入堆栈并仅通过地址调用函数) -
您可能还想看看this answer。
标签: c++ function-pointers