From 66600dcbc4ef86a0763fabcc9cc26bafe1113f59 Mon Sep 17 00:00:00 2001 From: Miran Date: Sun, 24 Nov 2024 23:36:39 +0100 Subject: [PATCH 1/2] Added stack pointer validation for call function/method opcodes. --- .../MemoryOperations/MemoryOperations.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cleo_plugins/MemoryOperations/MemoryOperations.cpp b/cleo_plugins/MemoryOperations/MemoryOperations.cpp index d2ecb49d..66d69f84 100644 --- a/cleo_plugins/MemoryOperations/MemoryOperations.cpp +++ b/cleo_plugins/MemoryOperations/MemoryOperations.cpp @@ -161,8 +161,11 @@ class MemoryOperations SCRIPT_VAR* arguments_end = arguments + numArg; numPop *= 4; // bytes peer argument DWORD result; + int oriSp, postSp; // stack validation _asm { + mov oriSp, esp + // transfer args to stack lea ecx, arguments call_func_loop : @@ -179,6 +182,21 @@ class MemoryOperations call func mov result, eax // get result add esp, numPop // cleanup stack + + mov postSp, esp + } + + // validate stack pointer + if (postSp != oriSp) + { + _asm + { + mov esp, oriSp // fix stack pointer + } + + int diff = oriSp - postSp; + SHOW_ERROR("Function call left stack position changed (%s%d) in script %s \nScript suspended.", diff > 0 ? "+" : "", diff, CLEO::ScriptInfoStr(thread).c_str()); + return thread->Suspend(); } if (returnArg) From c9fa064dca7cc09901b58148ec92be276ea73172 Mon Sep 17 00:00:00 2001 From: Miran Date: Wed, 27 Nov 2024 17:51:23 +0100 Subject: [PATCH 2/2] More detailed error message. --- cleo_plugins/MemoryOperations/MemoryOperations.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cleo_plugins/MemoryOperations/MemoryOperations.cpp b/cleo_plugins/MemoryOperations/MemoryOperations.cpp index 66d69f84..bac53f2c 100644 --- a/cleo_plugins/MemoryOperations/MemoryOperations.cpp +++ b/cleo_plugins/MemoryOperations/MemoryOperations.cpp @@ -195,7 +195,8 @@ class MemoryOperations } int diff = oriSp - postSp; - SHOW_ERROR("Function call left stack position changed (%s%d) in script %s \nScript suspended.", diff > 0 ? "+" : "", diff, CLEO::ScriptInfoStr(thread).c_str()); + int requiredPop = (numPop + diff) / 4; + SHOW_ERROR("Function call left stack position changed (%s%d). This usually happens when incorrect calling convention is used. \nArgument 'pop' value should have been %d in script %s \nScript suspended.", diff > 0 ? "+" : "", diff, requiredPop, CLEO::ScriptInfoStr(thread).c_str()); return thread->Suspend(); }