mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-19 02:53:22 +08:00
[0.3.x] added : callFunction routine ( call function in the target process )
git-svn-id: https://pykd.svn.codeplex.com/svn@91040 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
669df8e55b
commit
2c6f6c889a
@ -408,6 +408,7 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Create custom union" ) );
|
||||
python::def( "defineFunction", &pykd::defineFunction, defineFunction_( python::args("returnType", "callconv"),
|
||||
"Define custom function prototype" ) );
|
||||
python::def( "callFunction", python::raw_function(pykd::callFunctionByVar, 1) );
|
||||
|
||||
// CPU registers
|
||||
python::def( "reg", pykd::getRegisterByName,
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "kdlib/exceptions.h"
|
||||
|
||||
#include "pytypeinfo.h"
|
||||
#include "variant.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
@ -133,4 +134,150 @@ python::list TypeInfoAdapter::getElementDir(kdlib::TypeInfo &typeInfo)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
python::object callFunctionByVar( python::tuple& args, python::dict& kwargs )
|
||||
{
|
||||
kdlib::NumVariant retVal;
|
||||
|
||||
kdlib::TypedVarPtr funcvar = python::extract<kdlib::TypedVarPtr>(args[0]);
|
||||
|
||||
size_t argCount = python::len(args) - 1;
|
||||
|
||||
if ( argCount != funcvar->getType()->getElementCount() )
|
||||
throw kdlib::TypeException(L"wrong argument count");
|
||||
|
||||
kdlib::CallArgList argLst;
|
||||
|
||||
for ( size_t i = 0; i < argCount; ++i )
|
||||
{
|
||||
kdlib::TypeInfoPtr argType = funcvar->getType()->getElement(i);
|
||||
|
||||
python::object arg = args[i+1];
|
||||
|
||||
if ( argType->isBase() )
|
||||
{
|
||||
kdlib::NumVariant var= NumVariantAdaptor::convertToVariant(arg);
|
||||
|
||||
if ( argType->getName() == L"Char" )
|
||||
{
|
||||
argLst.push_back( var.asChar() );
|
||||
}
|
||||
else if ( argType->getName() == L"WChar" )
|
||||
{
|
||||
argLst.push_back( var.asShort() );
|
||||
}
|
||||
else if ( argType->getName() == L"Int1B" )
|
||||
{
|
||||
argLst.push_back( var.asChar() );
|
||||
}
|
||||
else if ( argType->getName() == L"UInt1B" )
|
||||
{
|
||||
argLst.push_back( var.asUChar() );
|
||||
}
|
||||
else if ( argType->getName() == L"Int2B" )
|
||||
{
|
||||
argLst.push_back( var.asShort() );
|
||||
}
|
||||
else if ( argType->getName() == L"UInt2B" )
|
||||
{
|
||||
argLst.push_back( var.asUShort() );
|
||||
}
|
||||
else if ( argType->getName() == L"Int4B" )
|
||||
{
|
||||
argLst.push_back( var.asLong() );
|
||||
}
|
||||
else if ( argType->getName() == L"UInt4B" )
|
||||
{
|
||||
argLst.push_back( var.asULong() );
|
||||
}
|
||||
else if ( argType->getName() == L"Int8B" )
|
||||
{
|
||||
argLst.push_back( var.asLongLong() );
|
||||
}
|
||||
else if ( argType->getName() == L"UInt8B" )
|
||||
{
|
||||
argLst.push_back(var.asULongLong());
|
||||
}
|
||||
else if ( argType->getName() == L"Long" )
|
||||
{
|
||||
argLst.push_back( var.asLong() );
|
||||
}
|
||||
else if ( argType->getName() == L"ULong" )
|
||||
{
|
||||
argLst.push_back( var.asULong() );
|
||||
}
|
||||
else if ( argType->getName() == L"Bool" )
|
||||
{
|
||||
argLst.push_back( var.asChar() );
|
||||
}
|
||||
else if ( argType->getName() == L"Float" )
|
||||
{
|
||||
argLst.push_back( var.asFloat() );
|
||||
}
|
||||
else if ( argType->getName() == L"Double")
|
||||
{
|
||||
argLst.push_back( var.asDouble() );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw kdlib::TypeException( std::wstring(L"unsupported argument type ") + argType->getName() );
|
||||
}
|
||||
}
|
||||
else if ( argType->isPointer() )
|
||||
{
|
||||
kdlib::MEMOFFSET_64 addr;
|
||||
|
||||
python::extract<kdlib::NumBehavior> getNumVar(arg);
|
||||
python::extract<unsigned long long> getLongLong(arg);
|
||||
python::extract<long> getLong(arg);
|
||||
|
||||
if ( getNumVar.check() )
|
||||
{
|
||||
kdlib::NumVariant var = getNumVar();
|
||||
addr = var.asULongLong();
|
||||
}
|
||||
if ( getLongLong.check() )
|
||||
{
|
||||
addr = getLongLong();
|
||||
}
|
||||
else if ( getLong.check() )
|
||||
{
|
||||
addr = getLong();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstringstream sstr;
|
||||
sstr << "failed to convert " << i << " argument to pointer";
|
||||
throw kdlib::TypeException(sstr.str() );
|
||||
}
|
||||
|
||||
switch ( argType->getPtrSize() )
|
||||
{
|
||||
case 4:
|
||||
argLst.push_back( static_cast<unsigned long>(addr) );
|
||||
break;
|
||||
|
||||
case 8:
|
||||
argLst.push_back( static_cast<unsigned long long>(addr) );
|
||||
break;
|
||||
|
||||
default:
|
||||
throw kdlib::TypeException(L"unsupported call argument");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw kdlib::TypeException(L"unsupported argument type");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
AutoRestorePyState pystate;
|
||||
retVal = funcvar->call(argLst);
|
||||
}
|
||||
|
||||
return NumVariantAdaptor::convertToPython(retVal);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // pykd namespace
|
||||
|
@ -44,6 +44,9 @@ inline kdlib::TypeInfoPtr defineFunction( const kdlib::TypeInfoPtr& returnType,
|
||||
return kdlib::defineFunction(returnType, callconv);
|
||||
}
|
||||
|
||||
python::object callFunctionByVar( python::tuple& args, python::dict& kwargs );
|
||||
|
||||
|
||||
inline kdlib::TypeInfoPtr getTypeInfoByName( const std::wstring &name )
|
||||
{
|
||||
AutoRestorePyState pystate;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <boost/python.hpp>
|
||||
#include <boost/python/object.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/raw_function.hpp>
|
||||
#pragma warning(pop)
|
||||
|
||||
namespace python = boost::python;
|
||||
|
@ -17,6 +17,13 @@ public:
|
||||
{
|
||||
kdlib::NumVariant var;
|
||||
|
||||
python::extract<kdlib::NumBehavior> getNumVar(obj);
|
||||
if ( getNumVar.check() )
|
||||
{
|
||||
var = getNumVar();
|
||||
return var;
|
||||
}
|
||||
|
||||
if (PyBool_Check(obj.ptr()))
|
||||
{
|
||||
if (obj.ptr() == Py_True)
|
||||
@ -43,8 +50,8 @@ public:
|
||||
|
||||
if (_PyLong_Sign(obj.ptr()) >= 0)
|
||||
{
|
||||
if (_PyLong_NumBits(obj.ptr()) > 64)
|
||||
throw pykd::OverflowException("int too big to convert");
|
||||
if (_PyLong_NumBits(obj.ptr()) > 64)
|
||||
throw pykd::OverflowException("int too big to convert");
|
||||
|
||||
var.setULongLong(PyLong_AsUnsignedLongLong(obj.ptr()));
|
||||
}
|
||||
|
@ -373,3 +373,10 @@ class TypedVarTest( unittest.TestCase ):
|
||||
def testCastTo(self):
|
||||
self.assertEqual(0xD2, target.module.typedVar( "ulonglongVar" ).castTo("UInt1B"))
|
||||
self.assertEqual(0, target.module.typedVar( "g_structTest" ).castTo("UInt4B"))
|
||||
|
||||
def testCallFunction(self):
|
||||
#funcptr = target.module.typedVar("StdcallFuncRet");
|
||||
#self.assertEqual( 200000/10, pykd.callFunction( funcptr, 10, 200000 ) )
|
||||
|
||||
funcptr = target.module.typedVar("CdeclFuncLong");
|
||||
self.assertEqual( 0xffffff000000 + 5, pykd.callFunction( funcptr, target.module.typedVar("ulonglongConst") ) )
|
||||
|
Loading…
Reference in New Issue
Block a user