/**
* =============================================================================
* Source Python
* Copyright (C) 2012-2015 Source Python Development Team. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*
* As a special exception, the Source Python Team gives you permission
* to link the code of this program (as well as its derivative works) to
* "Half-Life 2," the "Source Engine," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, the Source.Python
* Development Team grants this exception to all derivative works.
*/
// ============================================================================
// >> INCLUDES
// ============================================================================
#include "export_main.h"
// Memory
#include "memory_scanner.h"
#include "memory_tools.h"
#include "memory_hooks.h"
#include "memory_function_info.h"
#include "memory_utilities.h"
#include "memory_wrap.h"
#include "memory_rtti.h"
// DynamicHooks
#include "registers.h"
// ============================================================================
// >> FORWARD DECLARATIONS
// ============================================================================
void export_function_info(scope);
void export_binary_file(scope);
void export_pointer(scope);
void export_type_info(scope);
void export_type_info_iter(scope);
void export_function(scope);
void export_data_type_t(scope);
void export_convention_t(scope);
void export_hook_type_t(scope);
void export_stack_data(scope);
void export_register_t(scope);
void export_register(scope);
void export_registers(scope);
void export_calling_convention(scope);
void export_functions(scope);
void export_global_variables(scope);
void export_protection(scope);
// ============================================================================
// >> Exports the _memory module
// ============================================================================
DECLARE_SP_MODULE(_memory)
{
SetHooksDisabled(false);
export_function_info(_memory);
export_binary_file(_memory);
export_pointer(_memory);
export_type_info(_memory);
export_type_info_iter(_memory);
export_function(_memory);
export_data_type_t(_memory);
export_convention_t(_memory);
export_hook_type_t(_memory);
export_stack_data(_memory);
export_register_t(_memory);
export_register(_memory);
export_registers(_memory);
export_calling_convention(_memory);
export_functions(_memory);
export_global_variables(_memory);
export_protection(_memory);
}
// ============================================================================
// >> CFunctionInfo
// ============================================================================
void export_function_info(scope _core)
{
class_ _FunctionInfo("FunctionInfo", no_init);
_FunctionInfo.def_readonly("is_virtual", &CFunctionInfo::m_bIsVirtual);
_FunctionInfo.def_readonly("this_pointer_offset", &CFunctionInfo::m_iThisPtrOffset);
_FunctionInfo.def_readonly("vtable_index", &CFunctionInfo::m_iVtableIndex);
_FunctionInfo.def_readonly("vtable_offset", &CFunctionInfo::m_iVtableOffset);
_FunctionInfo.def_readonly("return_type", &CFunctionInfo::m_eReturnType);
_FunctionInfo.add_property("argument_types", &CFunctionInfo::GetArgumentTypes);
_FunctionInfo.def_readonly("calling_convention", &CFunctionInfo::m_eCallingConvention);
}
// ============================================================================
// >> CBinaryFile
// ============================================================================
void export_binary_file(scope _memory)
{
class_("BinaryFile", no_init)
// Class methods
.def("find_pointer",
&CBinaryFile::FindPointer,
"Rips out a pointer from a function.",
("signature", arg("offset")=0, arg("level")=0),
manage_new_object_policy()
)
.def("find_address",
&CBinaryFile::FindAddress,
"Returns the address of a signature or symbol found in memory.",
args("identifier"),
manage_new_object_policy()
)
// Special methods
.def("__getitem__",
&CBinaryFile::FindAddress,
"Returns the address of a signature or symbol found in memory.",
args("identifier"),
manage_new_object_policy()
)
// Attributes
.def_readwrite("module",
&CBinaryFile::m_ulModule,
"Handle of the binary."
)
.def_readwrite("base",
&CBinaryFile::m_ulBase,
"Base address of the binary."
)
.def_readwrite("size",
&CBinaryFile::m_ulSize,
"Size of the binary."
)
.add_property("symbols",
&CBinaryFile::GetSymbols,
"Return a dict containing all symbols and their addresses."
)
;
}
// ============================================================================
// >> CPointer
// ============================================================================
#define EXPOSE_SET_TYPE(name, type) \
.def("set_" XSTRINGIFY(name), \
&CPointer::Set, \
"Sets the value at the given memory location.", \
("value", arg("offset")=0) \
)
#define EXPOSE_GET_TYPE(name, type) \
.def("get_" XSTRINGIFY(name), \
&CPointer::Get, \
"Returns the value at the given memory location.", \
(arg("offset")=0) \
)
#define EXPOSE_GET_SET_TYPE(name, type) \
EXPOSE_SET_TYPE(name, type) \
EXPOSE_GET_TYPE(name, type)
void export_pointer(scope _memory)
{
class_("Pointer", init< optional >())
.def(init())
// get/set_ methods
EXPOSE_GET_SET_TYPE(bool, bool)
EXPOSE_GET_SET_TYPE(char, char)
EXPOSE_GET_SET_TYPE(uchar, unsigned char)
EXPOSE_GET_SET_TYPE(short, short)
EXPOSE_GET_SET_TYPE(ushort, unsigned short)
EXPOSE_GET_SET_TYPE(int, int)
EXPOSE_GET_SET_TYPE(uint, unsigned int)
EXPOSE_GET_SET_TYPE(long, long)
EXPOSE_GET_SET_TYPE(ulong, unsigned long)
EXPOSE_GET_SET_TYPE(long_long, long long)
EXPOSE_GET_SET_TYPE(ulong_long, unsigned long long)
EXPOSE_GET_SET_TYPE(float, float)
EXPOSE_GET_SET_TYPE(double, double)
EXPOSE_GET_SET_TYPE(string_pointer, const char*)
.def("get_pointer",
&CPointer::GetPtr,
"Returns the value at the given memory location.",
(arg("offset")=0),
manage_new_object_policy()
)
.def("get_string_array",
&CPointer::GetStringArray,
"Returns the value at the memory location.",
(arg("offset")=0)
)
.def("set_pointer",
&CPointer::SetPtr,
"Sets the value at the given memory location.",
("value", arg("offset")=0)
)
.def("set_string_array",
&CPointer::SetStringArray,
"Sets the value at the given memory location.",
("value",arg( "offset")=0)
)
// Other methods
.def("get_virtual_func",
&CPointer::GetVirtualFunc,
"Returns the address (as a Pointer instance) of a virtual function at the given index.",
args("index"),
manage_new_object_policy()
)
.def("make_function",
GET_METHOD(CFunction*, CPointer, MakeFunction, object, object, object),
"Creates a new Function instance.",
args("convention", "arguments", "return_type"),
manage_new_object_policy()
)
.def("make_function",
GET_METHOD(CFunction*, CPointer, MakeFunction, CFunctionInfo&),
"Use the given FunctionInfo object to convert the pointer into a Function object.",
("info"),
manage_new_object_policy()
)
.def("make_virtual_function",
GET_METHOD(CFunction*, CPointer, MakeVirtualFunction, int, object, object, object),
"Creates a new Function instance.",
args("index", "convention", "arguments", "return_type"),
manage_new_object_policy()
)
.def("make_virtual_function",
GET_METHOD(CFunction*, CPointer, MakeVirtualFunction, CFunctionInfo&),
"Use the given FunctionInfo object to retrieve a virtual function and convert it into a Function object.",
("info"),
manage_new_object_policy()
)
.def("realloc",
&CPointer::PreRealloc,
"Reallocates a memory block.",
args("size"),
manage_new_object_policy()
)
.def("dealloc",
&CPointer::PreDealloc,
"Deallocates a memory block."
)
.def("__del__",
&CPointer::__del__
)
.add_property("size",
&CPointer::GetSize,
"Returns the size of the memory block."
)
.def("compare",
&CPointer::Compare,
"Compares the first bytes of both pointers. Returns 0 if they are equal. A value greater than zero indicates that the first "\
"byte that does not match in both pointers has a greater value in than in . A value less than zero indicates the opposite.",
args("other", "num")
)
.def("is_overlapping",
&CPointer::IsOverlapping,
"Returns True if the pointers are overlapping each other.",
args("destination", "num_bytes")
)
.def("search_bytes",
&CPointer::SearchBytes,
"Searches within the first of this memory block for the first occurence of and returns a pointer it.",
args("bytes", "num_bytes"),
manage_new_object_policy()
)
.def("copy",
&CPointer::Copy,
"Copies from to the pointer . Overlapping is not allowed!",
args("destination", "num_bytes")
)
.def("move",
&CPointer::Move,
"Copies from to the pointer . Overlapping is allowed!",
args("destination", "num_bytes")
)
.def("set_protection",
&CPointer::SetProtection,
"Set memory protection.",
args("protection", "size")
)
.def("protect",
&CPointer::Protect,
"Make the memory block read-only.",
args("size")
)
.def("unprotect",
&CPointer::UnProtect,
"Make the memory block read-, write- and executable.",
args("size")
)
// Special methods
.def("__int__", make_getter(&CPointer::m_ulAddr))
.def(!self)
.def(self == other())
.def(self == self)
.def(self != other())
.def(self != self)
.def(self += int())
.def(self += self)
.def(self < other())
.def(self < self)
.def(self self)
.def(self >= other())
.def(self >= self)
.def("__add__", &CPointer::operator+, manage_new_object_policy())
.def("__add__", &CPointer::operator+, manage_new_object_policy())
.def("__radd__", &CPointer::operator+, manage_new_object_policy())
.def("__radd__", &CPointer::operator+, manage_new_object_policy())
.def(self -= int())
.def(self -= self)
.def("__sub__", &CPointer::operator-, manage_new_object_policy())
.def("__sub__", &CPointer::operator-, manage_new_object_policy())
.def("__rsub__", &CPointer::operator-, manage_new_object_policy())
.def("__rsub__", &CPointer::operator-, manage_new_object_policy())
// Attributes
.def_readwrite("address",
&CPointer::m_ulAddr
)
.def_readwrite("auto_dealloc",
&CPointer::m_bAutoDealloc
)
// Properties
.add_property("type_info",
make_function(&CPointer::GetTypeInfo, manage_new_object_policy())
)
;
}
// ============================================================================
// >> IBaseType
// ============================================================================
void export_type_info(scope _memory)
{
class_ TypeInfo("TypeInfo", no_init);
TypeInfo.add_property(
"name",
&IBaseType::GetName,
"Return the class name of the type."
);
TypeInfo.def(
"is_derived_from",
GET_METHOD(bool, IBaseType, IsDerivedFrom, const char*),
"Return True if the type is derived from the given class name."
);
TypeInfo.def(
"is_derived_from",
GET_METHOD(bool, IBaseType, IsDerivedFrom, IBaseType*),
"Return True if the type is derived from the given class name."
);
TypeInfo.def(
"__iter__",
&IBaseTypeExt::__iter__,
manage_new_object_policy(),
"Return an iterator to iterate over all base classes."
);
TypeInfo.def(
"dump",
GET_METHOD(void, IBaseType, Dump),
"Dump the class hierachy to the console."
);
}
// ============================================================================
// >> IBaseTypeIter
// ============================================================================
void export_type_info_iter(scope _memory)
{
class_ _IBaseTypeIter("TypeInfoIter", init());
_IBaseTypeIter.def(
"__next__",
&IBaseTypeIter::__next__,
reference_existing_object_policy()
);
}
// ============================================================================
// >> CFunction
// ============================================================================
void export_function(scope _memory)
{
class_("Function", init())
.def(init())
.def("__call__",
very_raw_method(&CFunction::Call),
"Calls the function dynamically."
)
.def("is_callable",
&CFunction::IsCallable,
"Return True if the function is callable."
)
.def("is_hookable",
&CFunction::IsHookable,
"Return True if the function is hookable."
)
.def("is_hooked",
&CFunction::IsHooked,
"Return True if the function is hooked."
)
.def("call_trampoline",
very_raw_method(&CFunction::CallTrampoline),
"Calls the trampoline function dynamically."
)
.def("skip_hooks",
very_raw_method(&CFunction::SkipHooks),
"Call the function, but skip hooks if there are any."
)
.def("add_hook",
GET_METHOD(void, CFunction, AddHook, HookType_t eType, PyObject*),
"Adds a hook callback.",
args("hook_type", "callback")
)
.def("remove_hook",
&CFunction::RemoveHook,
"Removes a hook callback.",
args("hook_type", "callback")
)
.def("add_pre_hook",
&CFunction::AddPreHook,
"Adds a pre-hook callback."
)
.def("add_post_hook",
&CFunction::AddPostHook,
"Adds a post-hook callback."
)
.def("remove_pre_hook",
&CFunction::RemovePreHook,
"Removes a pre-hook callback."
)
.def("remove_post_hook",
&CFunction::RemovePostHook,
"Removes a post-hook callback."
)
.def("_delete_hook",
&CFunction::DeleteHook,
"Removes all hooks and restores the original function."
)
// Attributes
.def_readonly("arguments",
&CFunction::m_tArgs
)
.def_readonly("return_type",
&CFunction::m_eReturnType
)
.def_readonly("converter",
&CFunction::m_oConverter
)
.def_readonly("convention",
&CFunction::m_eCallingConvention
)
.def_readonly("custom_convention",
&CFunction::m_oCallingConvention
)
// Properties
.add_property("trampoline",
make_function(&CFunction::GetTrampoline, manage_new_object_policy()),
"Return the trampoline function if the function is hooked."
)
;
}
// ============================================================================
// >> DataType_t
// ============================================================================
void export_data_type_t(scope _memory)
{
enum_("DataType")
.value("VOID", DATA_TYPE_VOID)
.value("BOOL", DATA_TYPE_BOOL)
.value("CHAR", DATA_TYPE_CHAR)
.value("UCHAR", DATA_TYPE_UCHAR)
.value("SHORT", DATA_TYPE_SHORT)
.value("USHORT", DATA_TYPE_USHORT)
.value("INT", DATA_TYPE_INT)
.value("UINT", DATA_TYPE_UINT)
.value("LONG", DATA_TYPE_LONG)
.value("ULONG", DATA_TYPE_ULONG)
.value("LONG_LONG", DATA_TYPE_LONG_LONG)
.value("ULONG_LONG", DATA_TYPE_ULONG_LONG)
.value("FLOAT", DATA_TYPE_FLOAT)
.value("DOUBLE", DATA_TYPE_DOUBLE)
.value("POINTER", DATA_TYPE_POINTER)
.value("STRING", DATA_TYPE_STRING)
;
}
// ============================================================================
// >> Convention_t
// ============================================================================
void export_convention_t(scope _memory)
{
enum_("Convention")
.value("CUSTOM", CONV_CUSTOM)
.value("CDECL", CONV_CDECL)
.value("STDCALL", CONV_STDCALL)
.value("THISCALL", CONV_THISCALL)
.value("FASTCALL", CONV_FASTCALL)
;
}
// ============================================================================
// >> HookType_t
// ============================================================================
void export_hook_type_t(scope _memory)
{
enum_("HookType")
.value("PRE", HOOKTYPE_PRE)
.value("POST", HOOKTYPE_POST)
;
}
// ============================================================================
// >> CStackData
// ============================================================================
void export_stack_data(scope _memory)
{
class_("StackData", init())
// Special methods
.def("__getitem__",
&CStackData::GetItem,
"Returns the argument at the specified index."
)
.def("__setitem__",
&CStackData::SetItem,
"Sets the argument at the specified index."
)
.add_property("return_address",
make_function(&CStackData::GetReturnAddress, return_by_value_policy()),
"Return the 'return address' to which DynamicHooks will jump after the post-hook has finished."
)
.def("__repr__",
&CStackData::__repr__
)
.add_property("registers",
make_function(&CStackData::GetRegisters, reference_existing_object_policy())
)
.add_property(
"use_pre_registers",
&CStackData::GetUsePreRegister,
&CStackData::SetUsePreRegisters)
;
}
// ============================================================================
// >> Register_t
// ============================================================================
void export_register_t(scope _memory)
{
enum_("Register")
// ========================================================================
// >> 8-bit General purpose registers
// ========================================================================
.value("AL", AL)
.value("CL", CL)
.value("DL", DL)
.value("BL", BL)
.value("AH", AH)
.value("CH", CH)
.value("DH", DH)
.value("BH", BH)
// ========================================================================
// >> 16-bit General purpose registers
// ========================================================================
.value("AX", AX)
.value("CX", CX)
.value("DX", DX)
.value("BX", BX)
.value("SP", SP)
.value("BP", BP)
.value("SI", SI)
.value("DI", DI)
// ========================================================================
// >> 32-bit General purpose registers
// ========================================================================
.value("EAX", EAX)
.value("ECX", ECX)
.value("EDX", EDX)
.value("EBX", EBX)
.value("ESP", ESP)
.value("EBP", EBP)
.value("ESI", ESI)
.value("EDI", EDI)
// ========================================================================
// >> 64-bit MM (MMX) registers
// ========================================================================
.value("MM0", MM0)
.value("MM1", MM1)
.value("MM2", MM2)
.value("MM3", MM3)
.value("MM4", MM4)
.value("MM5", MM5)
.value("MM6", MM6)
.value("MM7", MM7)
// ========================================================================
// >> 128-bit XMM registers
// ========================================================================
.value("XMM0", XMM0)
.value("XMM1", XMM1)
.value("XMM2", XMM2)
.value("XMM3", XMM3)
.value("XMM4", XMM4)
.value("XMM5", XMM5)
.value("XMM6", XMM6)
.value("XMM7", XMM7)
// ========================================================================
// >> 16-bit Segment registers
// ========================================================================
.value("CS", CS)
.value("SS", SS)
.value("DS", DS)
.value("ES", ES)
.value("FS", FS)
.value("GS", GS)
// ========================================================================
// >> 80-bit FPU registers
// ========================================================================
.value("ST0", ST0)
// The following registers are currently not supported by DynamicHooks
/*
.value("ST1", ST1)
.value("ST2", ST2)
.value("ST3", ST3)
.value("ST4", ST4)
.value("ST5", ST5)
.value("ST6", ST6)
.value("ST7", ST7)
*/
;
}
// ============================================================================
// >> CRegister
// ============================================================================
void export_register(scope _memory)
{
class_("ProcessorRegister", no_init)
.add_property("size",
make_getter(&CRegister::m_iSize)
)
.add_property("address",
make_function(&CRegisterExt::GetAddress, manage_new_object_policy())
)
;
}
// ============================================================================
// >> CRegisters
// ============================================================================
void export_registers(scope _memory)
{
class_("Registers", no_init)
.def_readonly("al", &CRegisters::m_al)
.def_readonly("cl", &CRegisters::m_cl)
.def_readonly("dl", &CRegisters::m_dl)
.def_readonly("bl", &CRegisters::m_bl)
.def_readonly("ah", &CRegisters::m_ah)
.def_readonly("ch", &CRegisters::m_ch)
.def_readonly("dh", &CRegisters::m_dh)
.def_readonly("bh", &CRegisters::m_bh)
.def_readonly("ax", &CRegisters::m_ax)
.def_readonly("cx", &CRegisters::m_cx)
.def_readonly("dx", &CRegisters::m_dx)
.def_readonly("bx", &CRegisters::m_bx)
.def_readonly("sp", &CRegisters::m_sp)
.def_readonly("bp", &CRegisters::m_bp)
.def_readonly("si", &CRegisters::m_si)
.def_readonly("di", &CRegisters::m_di)
.def_readonly("eax", &CRegisters::m_eax)
.def_readonly("ecx", &CRegisters::m_ecx)
.def_readonly("edx", &CRegisters::m_edx)
.def_readonly("ebx", &CRegisters::m_ebx)
.def_readonly("esp", &CRegisters::m_esp)
.def_readonly("ebp", &CRegisters::m_ebp)
.def_readonly("esi", &CRegisters::m_esi)
.def_readonly("edi", &CRegisters::m_edi)
.def_readonly("mm0", &CRegisters::m_mm0)
.def_readonly("mm1", &CRegisters::m_mm1)
.def_readonly("mm2", &CRegisters::m_mm2)
.def_readonly("mm3", &CRegisters::m_mm3)
.def_readonly("mm4", &CRegisters::m_mm4)
.def_readonly("mm5", &CRegisters::m_mm5)
.def_readonly("mm6", &CRegisters::m_mm6)
.def_readonly("mm7", &CRegisters::m_mm7)
.def_readonly("xmm0", &CRegisters::m_xmm0)
.def_readonly("xmm1", &CRegisters::m_xmm1)
.def_readonly("xmm2", &CRegisters::m_xmm2)
.def_readonly("xmm3", &CRegisters::m_xmm3)
.def_readonly("xmm4", &CRegisters::m_xmm4)
.def_readonly("xmm5", &CRegisters::m_xmm5)
.def_readonly("xmm6", &CRegisters::m_xmm6)
.def_readonly("xmm7", &CRegisters::m_xmm7)
.def_readonly("cs", &CRegisters::m_cs)
.def_readonly("ss", &CRegisters::m_ss)
.def_readonly("ds", &CRegisters::m_ds)
.def_readonly("es", &CRegisters::m_es)
.def_readonly("fs", &CRegisters::m_fs)
.def_readonly("gs", &CRegisters::m_gs)
.def_readonly("st0", &CRegisters::m_st0)
// The following registers are currently not supported by DynamicHooks
/*
.def_readonly("st1", &CRegisters::m_st1)
.def_readonly("st2", &CRegisters::m_st2)
.def_readonly("st3", &CRegisters::m_st3)
.def_readonly("st4", &CRegisters::m_st4)
.def_readonly("st5", &CRegisters::m_st5)
.def_readonly("st6", &CRegisters::m_st6)
.def_readonly("st7", &CRegisters::m_st7)
*/
;
}
// ============================================================================
// >> ICallingConventionWrapper
// ============================================================================
void export_calling_convention(scope _memory)
{
class_(
"CallingConvention",
"An an abstract class that is used to create custom calling "
"conventions (only available for hooking function and not for"
" calling functions).\n",
no_init)
.def("__init__",
make_constructor(
&ICallingConventionWrapper::__init__,
post_constructor_policies<
initialize_wrapper_policies
>(
make_function(
&ICallingConventionWrapper::Initialize,
default_call_policies(),
args("self", "arg_types", "return_type", "alignment", "default_convention")
)
),
("arg_types", "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",
&ICallingConventionWrapper::GetRegisters,
"Return a list of :class:`Register` values. These registeres will be saved for later access."
)
.def("get_pop_size",
&ICallingConventionWrapper::GetPopSize,
"Return the number of bytes that should be added to the stack to clean up."
)
.def("get_argument_ptr",
&ICallingConventionWrapper::GetArgumentPtr,
(arg("index"), arg("registers")),
"Return a pointer to the argument at the given index.\n"
"\n"
":param int index: The index of the argument.\n"
":param Registers registers: A snapshot of all saved registers.",
return_by_value_policy()
)
.def("argument_ptr_changed",
&ICallingConventionWrapper::ArgumentPtrChanged,
(arg("index"), arg("registers"), arg("ptr")),
"Called when the argument pointer returned by :meth:`get_argument_ptr` has been changed.\n"
"\n"
":param int index: The index of the argument that has been changed.\n"
":param Registers registers: A snapshot of all saved registers.\n"
":param Pointer ptr: The argument pointer that has been changed."
)
.def("get_return_ptr",
&ICallingConventionWrapper::GetReturnPtr,
(arg("registers")),
"Return a pointer to the return value.\n"
"\n"
":param Registers registers: A snapshot of all saved registers.",
return_by_value_policy()
)
.def("return_ptr_changed",
&ICallingConventionWrapper::ReturnPtrChanged,
(arg("registers"), arg("ptr")),
"Called when the return value pointer returned by :meth:`get_return_ptr` has been changed.\n"
"\n"
":param Registers registers: A snapshot of all saved registers.\n"
":param Pointer ptr: The return value pointer that has been changed."
)
.add_property("argument_types",
&ICallingConventionWrapper::GetArgTypes,
"A list of :class:`DataType` values that define the argument types of a function."
)
.def_readonly("return_type",
&ICallingConventionWrapper::m_returnType,
"A :class:`DataType` value that defines the return type of a function."
)
.def_readonly("alignment",
&ICallingConventionWrapper::m_iAlignment,
"An integer that defines the stack alignment."
)
ADD_MEM_TOOLS_WRAPPER(ICallingConventionWrapper, ICallingConvention)
;
}
// ============================================================================
// >> FUNCTIONS
// ============================================================================
void export_functions(scope _memory)
{
def("find_binary",
&FindBinary,
("path", arg("srv_check")=true, arg("check_extension")=true),
"Search for a binary and return it as a :class:`BinaryFile` object.\n"
"\n"
":param str path: The path to the binary file (absolute, relative or just the name of the file if it's on the search path).\n"
":param bool srv_check: If True it will automatically check the binary for the '_srv' ending on Linux.",
reference_existing_object_policy()
);
def("alloc",
Alloc,
("size", arg("auto_dealloc")=true),
"Allocate a memory block.\n"
"\n"
":param int size: The size (in bytes) of the memory block.\n"
":param bool auto_dealloc: If True the memory block will be deallocated automatically when the return value goes out of the scope.",
manage_new_object_policy()
);
def("get_object_pointer",
&GetObjectPointer,
(arg("obj")),
"Return the pointer of the C++ object of a given Python object.\n"
"\n"
":param obj: The object you want to retrieve a pointer from."
);
def("make_object",
GET_FUNCTION(object, MakeObject, object, object),
(arg("cls"), arg("ptr")),
"Wrap a pointer using an exposed class.\n"
"\n"
":param cls: The class that should be used to wrap the pointer.\n"
":param Pointer ptr: The pointer that should be wrapped."
);
def("make_object",
GET_FUNCTION(object, MakeObject, object, CPointer *),
(arg("cls"), arg("ptr")),
"Wrap a pointer using an exposed class.\n"
"\n"
":param cls: The class that should be used to wrap the pointer.\n"
":param Pointer ptr: The pointer that should be wrapped."
);
def("get_size",
&GetSize,
(arg("cls")),
"Return the size of a class or class object of its C++ class.\n"
"\n"
":param cls: A class or class object."
);
def("get_data_type_size",
&GetDataTypeSize,
("data_type", arg("alignment")=4),
"Return the size of the data type after applying alignment.\n"
"\n"
":param DataType data_type: The data type you would like to get the size of.\n"
":param int alignment: The alignment that should be used."
);
def("get_hooks_disabled",
&GetHooksDisabled,
"Return whether or not hook callbacks are disabled.\n"
"\n"
":rtype: bool");
def("set_hooks_disabled",
&SetHooksDisabled,
"Set whether or not hook callbacks are disabled.\n"
"\n"
":param bool disabled: If ``True``, hook callbacks are disabled.");
}
// ============================================================================
// >> GLOBAL VARIABLES
// ============================================================================
dict g_oExposedClasses;
dict g_oClassInfo;
#define ADD_NATIVE_TYPE_SIZE(name, type) \
scope().attr("TYPE_SIZES")[name] = sizeof(type);
void export_global_variables(scope _memory)
{
_memory.attr("EXPOSED_CLASSES") = g_oExposedClasses;
_memory.attr("CLASS_INFO") = g_oClassInfo;
// Don't remove this! It's required for the ADD_NATIVE_TYPE_SIZE macro.
_memory.attr("TYPE_SIZES") = dict();
// Native types
ADD_NATIVE_TYPE_SIZE("BOOL", bool)
ADD_NATIVE_TYPE_SIZE("CHAR", char)
ADD_NATIVE_TYPE_SIZE("UCHAR", unsigned char)
ADD_NATIVE_TYPE_SIZE("SHORT", short)
ADD_NATIVE_TYPE_SIZE("USHORT", unsigned short)
ADD_NATIVE_TYPE_SIZE("INT", int)
ADD_NATIVE_TYPE_SIZE("UINT", unsigned int)
ADD_NATIVE_TYPE_SIZE("LONG", long)
ADD_NATIVE_TYPE_SIZE("ULONG", unsigned long)
ADD_NATIVE_TYPE_SIZE("LONG_LONG", long long)
ADD_NATIVE_TYPE_SIZE("ULONG_LONG", unsigned long long)
ADD_NATIVE_TYPE_SIZE("FLOAT", float)
ADD_NATIVE_TYPE_SIZE("DOUBLE", double)
ADD_NATIVE_TYPE_SIZE("POINTER", void*)
ADD_NATIVE_TYPE_SIZE("STRING", char*)
_memory.attr("NULL") = object(CPointer());
}
// ============================================================================
// >> Protection_t
// ============================================================================
void export_protection(scope _memory)
{
enum_ Protection("Protection");
Protection.value("NONE", PROTECTION_NONE);
Protection.value("READ", PROTECTION_READ);
Protection.value("READ_WRITE", PROTECTION_READ_WRITE);
Protection.value("EXECUTE", PROTECTION_EXECUTE);
Protection.value("EXECUTE_READ", PROTECTION_EXECUTE_READ);
Protection.value("EXECUTE_READ_WRITE", PROTECTION_EXECUTE_READ_WRITE);
}