| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -260,14 +260,12 @@ Set(SOURCEPYTHON_MEMORY_MODULE_HEADERS | |||
| 260 | 260 | core/modules/memory/memory_tools.h | |
| 261 | 261 | core/modules/memory/memory_scanner.h | |
| 262 | 262 | core/modules/memory/memory_hooks.h | |
| 263 | - core/modules/memory/memory_callback.h | ||
| 264 | 263 | ) | |
| 265 | 264 | ||
| 266 | 265 | Set(SOURCEPYTHON_MEMORY_MODULE_SOURCES | |
| 267 | 266 | core/modules/memory/memory_scanner.cpp | |
| 268 | 267 | core/modules/memory/memory_tools.cpp | |
| 269 | 268 | core/modules/memory/memory_hooks.cpp | |
| 270 | - core/modules/memory/memory_callback.cpp | ||
| 271 | 269 | core/modules/memory/memory_wrap_python.cpp | |
| 272 | 270 | ) | |
| 273 | 271 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,8 +21,9 @@ class CStackData | |||
| 21 | 21 | public: | |
| 22 | 22 | CStackData(CHook* pHook); | |
| 23 | 23 | ||
| 24 | - object GetItem(unsigned int iIndex); | ||
| 25 | - void SetItem(unsigned int iIndex, object value); | ||
| 24 | + object GetItem(unsigned int iIndex); | ||
| 25 | + void SetItem(unsigned int iIndex, object value); | ||
| 26 | + CRegisters* GetRegisters() { return m_pHook->m_pRegisters; } | ||
| 26 | 27 | ||
| 27 | 28 | protected: | |
| 28 | 29 | CHook* m_pHook; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -72,17 +72,7 @@ int GetDynCallConvention(Convention_t eConv) | |||
| 72 | 72 | } | |
| 73 | 73 | ||
| 74 | 74 | BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Unsupported calling convention.") | |
| 75 | - return 0; | ||
| 76 | - } | ||
| 77 | - | ||
| 78 | - std::vector<DataType_t> ObjectToDataTypeVector(object oArgTypes) | ||
| 79 | - { | ||
| 80 | - std::vector<DataType_t> vecArgTypes; | ||
| 81 | - for(int i=0; i < len(oArgTypes); i++) | ||
| 82 | - { | ||
| 83 | - vecArgTypes.push_back(extract<DataType_t>(oArgTypes[i])); | ||
| 84 | - } | ||
| 85 | - return vecArgTypes; | ||
| 75 | + return -1; | ||
| 86 | 76 | } | |
| 87 | 77 | ||
| 88 | 78 | ICallingConvention* MakeDynamicHooksConvention(Convention_t eConv, std::vector<DataType_t> vecArgTypes, DataType_t returnType, int iAlignment=4) | |
@@ -103,7 +93,7 @@ ICallingConvention* MakeDynamicHooksConvention(Convention_t eConv, std::vector<D | |||
| 103 | 93 | #endif | |
| 104 | 94 | ||
| 105 | 95 | BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Unsupported calling convention.") | |
| 106 | - return 0; | ||
| 96 | + return NULL; | ||
| 107 | 97 | } | |
| 108 | 98 | ||
| 109 | 99 | //----------------------------------------------------------------------------- | |
@@ -241,17 +231,52 @@ CPointer* CPointer::Realloc(int iSize) | |||
| 241 | 231 | return new CPointer((unsigned long) UTIL_Realloc((void *) m_ulAddr, iSize)); | |
| 242 | 232 | } | |
| 243 | 233 | ||
| 244 | - CFunction* CPointer::MakeFunction(Convention_t eConv, object args, object return_type) | ||
| 234 | + CFunction* CPointer::MakeFunction(object oCallingConvention, object args, object oReturnType) | ||
| 245 | 235 | { | |
| 246 | 236 | if (!IsValid()) | |
| 247 | 237 | BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Pointer is NULL.") | |
| 248 | 238 | ||
| 249 | - return new CFunction(m_ulAddr, eConv, args, return_type); | ||
| 239 | + Convention_t _eCallingConvention = CONV_NONE; | ||
| 240 | + int _iCallingConvention = -1; | ||
| 241 | + object _oCallingConvention = object(); | ||
| 242 | + ICallingConvention* _pCallingConvention = NULL; | ||
| 243 | + tuple _tArgs = tuple(args); | ||
| 244 | + object _oReturnType = oReturnType; | ||
| 245 | + DataType_t _eReturnType; | ||
| 246 | + | ||
| 247 | + // Get the enum return type | ||
| 248 | + try | ||
| 249 | + { | ||
| 250 | + _eReturnType = extract<DataType_t>(oReturnType); | ||
| 251 | + } | ||
| 252 | + catch( ... ) | ||
| 253 | + { | ||
| 254 | + PyErr_Clear(); | ||
| 255 | + _eReturnType = DATA_TYPE_POINTER; | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + try | ||
| 259 | + { | ||
| 260 | + // If this line succeeds the user wants to create a function with the built-in calling conventions | ||
| 261 | + _eCallingConvention = extract<Convention_t>(oCallingConvention); | ||
| 262 | + _iCallingConvention = GetDynCallConvention(_eCallingConvention); | ||
| 263 | + _pCallingConvention = MakeDynamicHooksConvention(_eCallingConvention, ObjectToDataTypeVector(args), _eReturnType); | ||
| 264 | + } | ||
| 265 | + catch( ... ) | ||
| 266 | + { | ||
| 267 | + // If this happens, we won't be able to call the function, because we are using a custom calling convention | ||
| 268 | + PyErr_Clear(); | ||
| 269 | + | ||
| 270 | + _oCallingConvention = oCallingConvention(args, _eReturnType); | ||
| 271 | + _pCallingConvention = extract<ICallingConvention*>(_oCallingConvention); | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + return new CFunction(m_ulAddr, _eCallingConvention, _iCallingConvention, _oCallingConvention, _pCallingConvention, _tArgs, _eReturnType, _oReturnType); | ||
| 250 | 275 | } | |
| 251 | 276 | ||
| 252 | - CFunction* CPointer::MakeVirtualFunction(int iIndex, Convention_t eConv, object args, object return_type) | ||
| 277 | + CFunction* CPointer::MakeVirtualFunction(int iIndex, object oCallingConvention, object args, object return_type) | ||
| 253 | 278 | { | |
| 254 | - return GetVirtualFunc(iIndex)->MakeFunction(eConv, args, return_type); | ||
| 279 | + return GetVirtualFunc(iIndex)->MakeFunction(oCallingConvention, args, return_type); | ||
| 255 | 280 | } | |
| 256 | 281 | ||
| 257 | 282 | void CPointer::CallCallback(PyObject* self, char* szCallback) | |
@@ -301,48 +326,51 @@ void CPointer::__del__(PyObject* self) | |||
| 301 | 326 | //----------------------------------------------------------------------------- | |
| 302 | 327 | // CFunction class | |
| 303 | 328 | //----------------------------------------------------------------------------- | |
| 304 | - CFunction::CFunction(unsigned long ulAddr, Convention_t eConv, object args, object return_type) | ||
| 305 | - : CPointer(ulAddr) | ||
| 329 | + CFunction::CFunction(unsigned long ulAddr, Convention_t eCallingConvention, | ||
| 330 | + int iCallingConvention, object oCallingConvention, | ||
| 331 | + ICallingConvention* pCallingConvention, tuple tArgs, | ||
| 332 | + DataType_t eReturnType, object oReturnType) | ||
| 333 | + :CPointer(ulAddr) | ||
| 306 | 334 | { | |
| 307 | - m_eConv = eConv; | ||
| 308 | - m_Args = tuple(args); | ||
| 309 | - m_oReturnType = return_type; | ||
| 310 | - | ||
| 311 | - DataType_t eReturnType; | ||
| 312 | - | ||
| 313 | - // Try to get the return type | ||
| 314 | - try | ||
| 315 | - { | ||
| 316 | - eReturnType = extract<DataType_t>(m_oReturnType); | ||
| 317 | - } | ||
| 318 | - catch( ... ) | ||
| 319 | - { | ||
| 320 | - PyErr_Clear(); | ||
| 335 | + m_eCallingConvention = eCallingConvention; | ||
| 336 | + m_iCallingConvention = iCallingConvention; | ||
| 337 | + m_oCallingConvention = oCallingConvention; | ||
| 338 | + m_pCallingConvention = pCallingConvention; | ||
| 339 | + m_tArgs = tArgs; | ||
| 340 | + m_eReturnType = eReturnType; | ||
| 341 | + m_oReturnType = oReturnType; | ||
| 342 | + } | ||
| 321 | 343 | ||
| 322 | - // It failed, so let's handle it as a pointer | ||
| 323 | - eReturnType = DATA_TYPE_POINTER; | ||
| 324 | - } | ||
| 344 | + bool CFunction::IsCallable() | ||
| 345 | + { | ||
| 346 | + return (m_eCallingConvention != CONV_NONE) && (m_iCallingConvention != -1); | ||
| 347 | + } | ||
| 325 | 348 | ||
| 326 | - m_pCallingConvention = MakeDynamicHooksConvention(eConv, ObjectToDataTypeVector(args), eReturnType); | ||
| 349 | + bool CFunction::IsHookable() | ||
| 350 | + { | ||
| 351 | + return m_pCallingConvention != NULL; | ||
| 327 | 352 | } | |
| 328 | 353 | ||
| 329 | 354 | object CFunction::Call(tuple args, dict kw) | |
| 330 | 355 | { | |
| 356 | + if (!IsCallable()) | ||
| 357 | + BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function is not callable.") | ||
| 358 | + | ||
| 331 | 359 | if (!IsValid()) | |
| 332 | 360 | BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function pointer is NULL.") | |
| 333 | 361 | ||
| 334 | - if (len(args) != len(m_Args)) | ||
| 362 | + if (len(args) != len(m_tArgs)) | ||
| 335 | 363 | BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Number of passed arguments is not equal to the required number.") | |
| 336 | 364 | ||
| 337 | 365 | // Reset VM and set the calling convention | |
| 338 | 366 | dcReset(g_pCallVM); | |
| 339 | - dcMode(g_pCallVM, GetDynCallConvention(m_eConv)); | ||
| 367 | + dcMode(g_pCallVM, m_iCallingConvention); | ||
| 340 | 368 | ||
| 341 | 369 | // Loop through all passed arguments and add them to the VM | |
| 342 | 370 | for(int i=0; i < len(args); i++) | |
| 343 | 371 | { | |
| 344 | 372 | object arg = args[i]; | |
| 345 | - switch(extract<DataType_t>(m_Args[i])) | ||
| 373 | + switch(extract<DataType_t>(m_tArgs[i])) | ||
| 346 | 374 | { | |
| 347 | 375 | case DATA_TYPE_BOOL: dcArgBool(g_pCallVM, extract<bool>(arg)); break; | |
| 348 | 376 | case DATA_TYPE_CHAR: dcArgChar(g_pCallVM, extract<char>(arg)); break; | |
@@ -369,23 +397,8 @@ object CFunction::Call(tuple args, dict kw) | |||
| 369 | 397 | } | |
| 370 | 398 | } | |
| 371 | 399 | ||
| 372 | - DataType_t return_type; | ||
| 373 | - | ||
| 374 | - // Try to get the return type | ||
| 375 | - try | ||
| 376 | - { | ||
| 377 | - return_type = extract<DataType_t>(m_oReturnType); | ||
| 378 | - } | ||
| 379 | - catch( ... ) | ||
| 380 | - { | ||
| 381 | - PyErr_Clear(); | ||
| 382 | - | ||
| 383 | - // It failed, so let's handle it as a pointer | ||
| 384 | - return m_oReturnType(ptr(new CPointer(dcCallPointer(g_pCallVM, m_ulAddr)))); | ||
| 385 | - } | ||
| 386 | - | ||
| 387 | 400 | // Call the function | |
| 388 | - switch(return_type) | ||
| 401 | + switch(m_eReturnType) | ||
| 389 | 402 | { | |
| 390 | 403 | case DATA_TYPE_VOID: dcCallVoid(g_pCallVM, m_ulAddr); break; | |
| 391 | 404 | case DATA_TYPE_BOOL: return object(dcCallBool(g_pCallVM, m_ulAddr)); | |
@@ -401,7 +414,13 @@ object CFunction::Call(tuple args, dict kw) | |||
| 401 | 414 | case DATA_TYPE_ULONG_LONG: return object((unsigned long long) dcCallLongLong(g_pCallVM, m_ulAddr)); | |
| 402 | 415 | case DATA_TYPE_FLOAT: return object(dcCallFloat(g_pCallVM, m_ulAddr)); | |
| 403 | 416 | case DATA_TYPE_DOUBLE: return object(dcCallDouble(g_pCallVM, m_ulAddr)); | |
| 404 | - case DATA_TYPE_POINTER: return object(ptr(new CPointer(dcCallPointer(g_pCallVM, m_ulAddr)))); | ||
| 417 | + case DATA_TYPE_POINTER: | ||
| 418 | + { | ||
| 419 | + CPointer* pPtr = new CPointer(dcCallPointer(g_pCallVM, m_ulAddr)); | ||
| 420 | + if (!m_oReturnType.is_none()) | ||
| 421 | + return m_oReturnType(ptr(pPtr)); | ||
| 422 | + return object(ptr(pPtr)); | ||
| 423 | + } | ||
| 405 | 424 | case DATA_TYPE_STRING: return object((const char *) dcCallPointer(g_pCallVM, m_ulAddr)); | |
| 406 | 425 | default: BOOST_RAISE_EXCEPTION(PyExc_TypeError, "Unknown return type.") | |
| 407 | 426 | } | |
@@ -410,42 +429,38 @@ object CFunction::Call(tuple args, dict kw) | |||
| 410 | 429 | ||
| 411 | 430 | object CFunction::CallTrampoline(tuple args, dict kw) | |
| 412 | 431 | { | |
| 432 | + if (!IsCallable()) | ||
| 433 | + BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function is not callable.") | ||
| 434 | + | ||
| 413 | 435 | if (!IsValid()) | |
| 414 | 436 | BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function pointer is NULL.") | |
| 415 | 437 | ||
| 416 | 438 | CHook* pHook = GetHookManager()->FindHook((void *) m_ulAddr); | |
| 417 | 439 | if (!pHook) | |
| 418 | 440 | BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function was not hooked.") | |
| 419 | 441 | ||
| 420 | - return CFunction((unsigned long) pHook->m_pTrampoline, m_eConv, m_Args, m_oReturnType).Call(args, kw); | ||
| 442 | + return CFunction((unsigned long) pHook->m_pTrampoline, m_eCallingConvention, | ||
| 443 | + m_iCallingConvention, m_oCallingConvention, m_pCallingConvention, m_tArgs, | ||
| 444 | + m_eReturnType, m_oReturnType).Call(args, kw); | ||
| 421 | 445 | } | |
| 422 | 446 | ||
| 423 | 447 | handle<> CFunction::AddHook(HookType_t eType, PyObject* pCallable) | |
| 424 | 448 | { | |
| 449 | + if (!IsHookable()) | ||
| 450 | + BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function is not hookable.") | ||
| 451 | + | ||
| 425 | 452 | if (!IsValid()) | |
| 426 | 453 | BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Function pointer is NULL.") | |
| 427 | 454 | ||
| 428 | - // Generate the argument string | ||
| 429 | - DataType_t return_type; | ||
| 430 | - try | ||
| 431 | - { | ||
| 432 | - return_type = extract<DataType_t>(m_oReturnType); | ||
| 433 | - } | ||
| 434 | - catch ( ... ) | ||
| 435 | - { | ||
| 436 | - PyErr_Clear(); | ||
| 437 | - return_type = DATA_TYPE_POINTER; | ||
| 438 | - } | ||
| 439 | - | ||
| 440 | 455 | // Hook the function | |
| 441 | 456 | CHook* pHook = GetHookManager()->HookFunction((void *) m_ulAddr, m_pCallingConvention); | |
| 442 | - | ||
| 457 | + | ||
| 443 | 458 | // Add the hook handler. If it's already added, it won't be added twice | |
| 444 | - pHook->AddCallback(eType, (HookHandlerFn *) &SP_HookHandler); | ||
| 445 | - | ||
| 459 | + pHook->AddCallback(eType, (HookHandlerFn *) (void *) &SP_HookHandler); | ||
| 460 | + | ||
| 446 | 461 | // Add the callback to our map | |
| 447 | 462 | g_mapCallbacks[pHook][eType].push_back(pCallable); | |
| 448 | - | ||
| 463 | + | ||
| 449 | 464 | // Return the callback, so we can use this method as a decorator | |
| 450 | 465 | return handle<>(borrowed(pCallable)); | |
| 451 | 466 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -140,11 +140,22 @@ inline void UTIL_Dealloc(void* ptr) | |||
| 140 | 140 | #endif | |
| 141 | 141 | } | |
| 142 | 142 | ||
| 143 | + inline std::vector<DataType_t> ObjectToDataTypeVector(object oArgTypes) | ||
| 144 | + { | ||
| 145 | + std::vector<DataType_t> vecArgTypes; | ||
| 146 | + for(int i=0; i < len(oArgTypes); i++) | ||
| 147 | + { | ||
| 148 | + vecArgTypes.push_back(extract<DataType_t>(oArgTypes[i])); | ||
| 149 | + } | ||
| 150 | + return vecArgTypes; | ||
| 151 | + } | ||
| 152 | + | ||
| 143 | 153 | //----------------------------------------------------------------------------- | |
| 144 | 154 | // Convention enum | |
| 145 | 155 | //----------------------------------------------------------------------------- | |
| 146 | 156 | enum Convention_t | |
| 147 | 157 | { | |
| 158 | + CONV_NONE, | ||
| 148 | 159 | CONV_CDECL, | |
| 149 | 160 | CONV_THISCALL, | |
| 150 | 161 | CONV_STDCALL | |
@@ -233,8 +244,8 @@ class CPointer | |||
| 233 | 244 | virtual CPointer* Realloc(int iSize); | |
| 234 | 245 | virtual void Dealloc() { UTIL_Dealloc((void *) m_ulAddr); m_ulAddr = 0; } | |
| 235 | 246 | ||
| 236 | - CFunction* MakeFunction(Convention_t eConv, boost::python::object args, object return_type); | ||
| 237 | - CFunction* MakeVirtualFunction(int iIndex, Convention_t eConv, boost::python::object args, object return_type); | ||
| 247 | + CFunction* MakeFunction(object oCallingConvention, object args, object return_type); | ||
| 248 | + CFunction* MakeVirtualFunction(int iIndex, object oCallingConvention, object args, object return_type); | ||
| 238 | 249 | ||
| 239 | 250 | static void CallCallback(PyObject* self, char* szCallback); | |
| 240 | 251 | static void PreDealloc(PyObject* self); | |
@@ -253,7 +264,12 @@ class CPointer | |||
| 253 | 264 | class CFunction: public CPointer | |
| 254 | 265 | { | |
| 255 | 266 | public: | |
| 256 | - CFunction(unsigned long ulAddr, Convention_t eConv, boost::python::object args, object return_type); | ||
| 267 | + CFunction(unsigned long ulAddr, Convention_t eCallingConvention, int iCallingConvention, | ||
| 268 | + object oCallingConvention, ICallingConvention* pCallingConvention, | ||
| 269 | + boost::python::tuple tArgs, DataType_t eReturnType, object oReturnType); | ||
| 270 | + | ||
| 271 | + bool IsCallable(); | ||
| 272 | + bool IsHookable(); | ||
| 257 | 273 | ||
| 258 | 274 | object Call(boost::python::tuple args, dict kw); | |
| 259 | 275 | object CallTrampoline(boost::python::tuple args, dict kw); | |
@@ -274,9 +290,20 @@ class CFunction: public CPointer | |||
| 274 | 290 | { RemoveHook(HOOKTYPE_POST, pCallable); } | |
| 275 | 291 | ||
| 276 | 292 | public: | |
| 277 | - boost::python::tuple m_Args; | ||
| 293 | + boost::python::tuple m_tArgs; | ||
| 278 | 294 | object m_oReturnType; | |
| 279 | - Convention_t m_eConv; | ||
| 295 | + DataType_t m_eReturnType; | ||
| 296 | + | ||
| 297 | + // Shared built-in calling convention identifier | ||
| 298 | + Convention_t m_eCallingConvention; | ||
| 299 | + | ||
| 300 | + // DynCall calling convention | ||
| 301 | + int m_iCallingConvention; | ||
| 302 | + | ||
| 303 | + // Custom DynamicHooks calling convention | ||
| 304 | + object m_oCallingConvention; | ||
| 305 | + | ||
| 306 | + // DynamicHooks calling convention (built-in and custom) | ||
| 280 | 307 | ICallingConvention* m_pCallingConvention; | |
| 281 | 308 | }; | |
| 282 | 309 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments