diff --git a/src/core/modules/memory/memory_function.cpp b/src/core/modules/memory/memory_function.cpp index 550822741..423069ae0 100755 --- a/src/core/modules/memory/memory_function.cpp +++ b/src/core/modules/memory/memory_function.cpp @@ -155,20 +155,11 @@ CFunction::CFunction(unsigned long ulAddr, object oCallingConvention, object oAr // A custom calling convention will be used... m_eCallingConvention = CONV_CUSTOM; m_oCallingConvention = oCallingConvention(m_tArgs, m_eReturnType); - - // FIXME: - // This is required to fix a crash, but it will also cause a memory leak, - // because no calling convention object that is created via this method will ever be deleted. - // TODO: Pretty sure this was required due to the missing held type definition. It was added, but wasn't tested yet. - Py_INCREF(m_oCallingConvention.ptr()); m_pCallingConvention = extract(m_oCallingConvention); } // Step 4: Get the DynCall calling convention m_iCallingConvention = GetDynCallConvention(m_eCallingConvention); - - // We allocated the calling convention, we are responsible to cleanup. - m_bAllocatedCallingConvention = true; } CFunction::CFunction(unsigned long ulAddr, Convention_t eCallingConvention, @@ -180,9 +171,6 @@ CFunction::CFunction(unsigned long ulAddr, Convention_t eCallingConvention, m_pCallingConvention = NULL; m_oCallingConvention = object(); - // We didn't allocate the calling convention, someone else is responsible for it. - m_bAllocatedCallingConvention = false; - m_tArgs = tArgs; m_eReturnType = eReturnType; m_oConverter = oConverter; @@ -190,24 +178,8 @@ CFunction::CFunction(unsigned long ulAddr, Convention_t eCallingConvention, CFunction::~CFunction() { - // If we didn't allocate the calling convention, then it is not our responsibility. - if (!m_bAllocatedCallingConvention) - return; - - // If we created calling convention, clean it up. - // This does not apply to hooked calling convention. - if (m_oCallingConvention.is_none()) - { + if (m_oCallingConvention.is_none() && !m_pCallingConvention->m_bHooked) delete m_pCallingConvention; - } - else - { - ICallingConventionWrapper* _pCallingConventionWrapper = extract(m_oCallingConvention); - - Py_DECREF(m_oCallingConvention.ptr()); - - delete _pCallingConventionWrapper; - } m_pCallingConvention = NULL; } @@ -398,9 +370,6 @@ void CFunction::AddHook(HookType_t eType, PyObject* pCallable) if (!pHook) { pHook = HookFunctionHelper((void *) m_ulAddr, m_pCallingConvention); - - // DynamicHooks will handle our convention from there, regardless if we allocated it or not. - m_bAllocatedCallingConvention = false; } // Add the hook handler. If it's already added, it won't be added twice @@ -420,9 +389,6 @@ bool CFunction::AddHook(HookType_t eType, HookHandlerFn* pFunc) if (!pHook) return false; - - // DynamicHooks will handle our convention from there, regardless if we allocated it or not. - m_bAllocatedCallingConvention = false; } pHook->AddCallback(eType, pFunc); @@ -447,6 +413,7 @@ void CFunction::DeleteHook() g_mapCallbacks.erase(pHook); // Set the calling convention to NULL, because DynamicHooks will delete it otherwise. + pHook->m_pCallingConvention->m_bHooked = false; pHook->m_pCallingConvention = NULL; GetHookManager()->UnhookFunction((void *) m_ulAddr); } \ No newline at end of file diff --git a/src/core/modules/memory/memory_wrap.cpp b/src/core/modules/memory/memory_wrap.cpp index 0b8e9e44a..a7bde7c7e 100755 --- a/src/core/modules/memory/memory_wrap.cpp +++ b/src/core/modules/memory/memory_wrap.cpp @@ -827,20 +827,24 @@ void export_registers(scope _memory) // ============================================================================ void export_calling_convention(scope _memory) { - class_( + class_, boost::noncopyable>( "CallingConvention", "An an abstract class that is used to create custom calling " "conventions (only available for hooking function and not for" " calling functions).\n", - init< object, DataType_t, optional >( - (arg("arg_types"), arg("return_type"), arg("alignment")=4, arg("default_convention")=CONV_CUSTOM), + no_init) + + .def("__init__", + make_constructor(&ICallingConventionWrapper::__init__, + default_call_policies(), + (arg("arg_types"), arg("return_type"), arg("alignment")=4, arg("default_convention")=CONV_CUSTOM) + ), "Initialize the calling convention.\n" "\n" ":param iterable arg_types: A list of :class:`DataType` values that define the argument types of a function.\n" ":param DataType return_type: The return type of a function.\n" ":param int alignment: The stack alignment.\n" ":param Convention_t default_convention: The default convention for un override function." - ) ) .def("get_registers", diff --git a/src/core/modules/memory/memory_wrap.h b/src/core/modules/memory/memory_wrap.h index 7b6d42160..0d2673973 100755 --- a/src/core/modules/memory/memory_wrap.h +++ b/src/core/modules/memory/memory_wrap.h @@ -62,12 +62,28 @@ class ICallingConventionWrapper: public ICallingConvention, public wrapperm_bHooked) + return; + + delete pThis; + } + + static boost::shared_ptr __init__( + object oArgTypes, DataType_t returnType, int iAlignment=4, Convention_t eDefaultConv=CONV_CUSTOM) + { + return boost::shared_ptr( + new ICallingConventionWrapper(oArgTypes, returnType, iAlignment, eDefaultConv), &Deleter + ); + } + virtual std::list GetRegisters() { override get_registers = get_override("get_registers"); diff --git a/src/thirdparty/DynamicHooks/include/convention.h b/src/thirdparty/DynamicHooks/include/convention.h index cb737b250..2a42afcaf 100644 --- a/src/thirdparty/DynamicHooks/include/convention.h +++ b/src/thirdparty/DynamicHooks/include/convention.h @@ -143,8 +143,14 @@ class ICallingConvention m_vecArgTypes = vecArgTypes; m_returnType = returnType; m_iAlignment = iAlignment; + m_bHooked = false; } + /* + Destructs the calling convention. + */ + virtual ~ICallingConvention() {}; + /* This should return a list of Register_t values. These registers will be saved for later access. @@ -187,6 +193,7 @@ class ICallingConvention std::vector m_vecArgTypes; DataType_t m_returnType; int m_iAlignment; + bool m_bHooked; }; #endif // _CONVENTION_H \ No newline at end of file