M-am gândit să public această funcție împreună cu mecanismul logic din spatele ei. Spre deosebire de implementarea implicită din clientul Metin2, această versiune rulează codul Python direct din memorie, fără a-l salva pe disk.
Aici intervine partea voastră: trebuie să adăugați un hook (recomand librăria MinHook) pentru a intercepta conținutul scripturilor Python la momentul execuției, astfel încât să le puteți clasifica în funcție de ce conțin și de unde provin.
Funcția este doar fix-ul de bază, oferind un interpret Python mult mai securizat decât cel implicit. Cu o logică corect implementată în client (sau chiar server-side), puteți bloca majoritatea scripturilor Python externe care nu fac parte din clientul vostru oficial.
Primul care reușește să înțeleagă logica completă și să adauge ce mai trebuie pentru a face hook-ul perfect funcțional și capabil să detecteze "cod Python" injectat din surse externe va primi un bonus: dezvăluirea a 5 verificări esențiale ce pot fi aplicate pe acest mecanism.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
I decided to share this function along with its internal logic. Unlike the default Metin2 client implementation, this version runs Python code directly from memory, without saving it to disk.
This is where your contribution comes in: you’ll need to implement a hook (I recommend using MinHook) to intercept the Python code at execution time, allowing you to classify it based on its content and its origin.
The function itself is just the core fix, laying the groundwork for a much more secure Python interpreter than the default one. With proper client-side (or even server-side) logic, you can block most external Python scripts that don’t come from your official client.
The first person who fully understands the logic and adds what’s needed to make the hook fully functional, capable of detecting Python code injected from external sources, will receive a bonus: a reveal of 5 essential checks that can be applied to this mechanism.
*Link download / Code:
#ifdef ENABLE_PYTHON_CHECKS
bool CPythonLauncher::RunMemoryTextFile(const char* c_szFileName, UINT uFileSize, const VOID* c_pvFileData)
{
const CHAR* c_pcFileData = (const CHAR*)c_pvFileData;
std::string stConvFileData;
stConvFileData.reserve(uFileSize);
for (UINT i = 0; i < uFileSize; ++i)
{
if (c_pcFileData[i] != 13)
stConvFileData += c_pcFileData[i];
}
const CHAR* c_pcConvFileData = stConvFileData.c_str();
PyObject* pCompiledCode = Py_CompileString(c_pcConvFileData, c_szFileName, Py_file_input);
if (!pCompiledCode)
return false;
PyObject* pResult = PyEval_EvalCode((PyCodeObject*)pCompiledCode, m_poDic, m_poDic);
Py_DECREF(pCompiledCode);
if (!pResult)
return false;
Py_DECREF(pResult);
if (Py_FlushLine())
PyErr_Clear();
return true;
}
#else
Your old function
#endif


