diff --git a/pykd/pykdver.h b/pykd/pykdver.h index 5b87b1e..9e43c01 100644 --- a/pykd/pykdver.h +++ b/pykd/pykdver.h @@ -2,7 +2,7 @@ #define PYKD_VERSION_MAJOR 0 #define PYKD_VERSION_MINOR 3 #define PYKD_VERSION_SUBVERSION 2 -#define PYKD_VERSION_BUILDNO 6 +#define PYKD_VERSION_BUILDNO 7 #define __VER_STR2__(x) #x #define __VER_STR1__(x) __VER_STR2__(x) diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 98629ec..f9eb93f 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -418,6 +418,7 @@ BOOST_PYTHON_MODULE( pykd ) "Define custom function prototype" ) ); python::def( "callFunctionByPtr", python::raw_function(pykd::callFunctionByVar, 1) ); python::def( "callFunctionByAddr", python::raw_function(pykd::callFunctionByOffset, 2) ); + python::def( "callFunctionRaw", python::raw_function(pykd::callFunctionRaw, 1) ); python::def( "getTypeFromSource", &pykd::getTypeFromSource, getTypeFromSource_( python::args("sourceCode", "typeName", "compileOptions"), "Create typeInfo class from C/C++ source code") ); diff --git a/pykd/pytypeinfo.cpp b/pykd/pytypeinfo.cpp index f891722..632bd6d 100644 --- a/pykd/pytypeinfo.cpp +++ b/pykd/pytypeinfo.cpp @@ -159,6 +159,7 @@ python::list TypeInfoAdapter::getElementDir(kdlib::TypeInfo &typeInfo) /////////////////////////////////////////////////////////////////////////////// + python::object callTypedVar(kdlib::TypedVarPtr& funcobj, python::tuple& args) { kdlib::TypedValue retVal; @@ -176,6 +177,30 @@ python::object callTypedVar(kdlib::TypedVarPtr& funcobj, python::tuple& args) continue; } + python::extract getStrVar(args[i]); + if ( getStrVar.check() ) + { + std::wstringstream sstr; + + if ( funcobj->getType()->getElement(i)->getName() == L"Char*" ) + { + std::string strArg = _bstr_t( getStrVar().c_str() ); + sstr << "Char[" << std::dec << strArg.size() + 1 << ']'; + argLst.push_back( kdlib::loadTypedVar(sstr.str(), kdlib::getCacheAccessor( strArg.c_str(), strArg.size() + 1 ) ) ); + continue; + } + + if ( funcobj->getType()->getElement(i)->getName() == L"WChar*" ) + { + std::wstring strArg = getStrVar(); + sstr << "WChar[" << std::dec << strArg.size() + 1 << ']'; + argLst.push_back( kdlib::loadTypedVar(sstr.str(), kdlib::getCacheAccessor( strArg.c_str(), 2*(strArg.size() + 1) ) ) ); + continue; + } + + throw kdlib::TypeException(L"failed convert string argument"); + } + python::extract getNumVar(args[i]); if ( getNumVar.check() ) { @@ -184,8 +209,15 @@ python::object callTypedVar(kdlib::TypedVarPtr& funcobj, python::tuple& args) continue; } - kdlib::NumVariant var= NumVariantAdaptor::convertToVariant(args[i]); - argLst.push_back( var ); + + if ( python::extract(args[i]).check() ) + { + kdlib::NumVariant var= NumVariantAdaptor::convertToVariant(args[i]); + argLst.push_back( var ); + continue; + } + + throw kdlib::TypeException(L"failed convert argument"); } { @@ -227,4 +259,77 @@ python::object callFunctionByOffset( python::tuple& args, python::dict& kwargs) /////////////////////////////////////////////////////////////////////////////// +python::object callFunctionRaw( python::tuple& args, python::dict& kwargs) +{ + kdlib::MEMOFFSET_64 funcaddr = python::extract(args[0]); + + kdlib::CallingConventionType callingConvention = kdlib::CallingConventionType::CallConv_NearC; + + if ( kwargs.has_key("callingConvention") ) + callingConvention = python::extract(kwargs["callingConvention"]); + + size_t argCount = python::len(args); + + kdlib::TypedValueList argLst; + + for ( size_t i = 0; i < argCount; ++i ) + { + python::extract getTypedVar(args[i]); + if ( getTypedVar.check() ) + { + argLst.push_back( getTypedVar() ); + continue; + } + + python::extract getStrVar(args[i]); + if ( getStrVar.check() ) + { + std::string strArg = getStrVar(); + std::wstringstream sstr; + sstr << L"Char[" << std::dec << strArg.size() + 1 << L']'; + argLst.push_back( kdlib::loadTypedVar(sstr.str(), kdlib::getCacheAccessor( strArg.c_str(), strArg.size() + 1 ) ) ); + continue; + } + + python::extract getWStrVar(args[i]); + if ( getWStrVar.check() ) + { + std::wstring strArg = getWStrVar(); + std::wstringstream sstr; + sstr << L"WChar[" << std::dec << strArg.size() + 1 << L']'; + argLst.push_back( kdlib::loadTypedVar(sstr.str(), kdlib::getCacheAccessor( strArg.c_str(), 2*(strArg.size() + 1) ) ) ); + continue; + } + + python::extract getNumVar(args[i]); + if ( getNumVar.check() ) + { + kdlib::NumVariant var = getNumVar(); + argLst.push_back( var ); + continue; + } + + if ( python::extract(args[i]).check() ) + { + kdlib::NumVariant var= NumVariantAdaptor::convertToVariant(args[i]); + argLst.push_back( var ); + continue; + } + + throw kdlib::TypeException(L"failed convert argument"); + } + + kdlib::NumVariant retVal; + + { + AutoRestorePyState pystate; + retVal = kdlib::callRaw(funcaddr, callingConvention, argLst); + } + + return NumVariantAdaptor::convertToPython(retVal); +} + +/////////////////////////////////////////////////////////////////////////////// + + } // pykd namespace diff --git a/pykd/pytypeinfo.h b/pykd/pytypeinfo.h index 54a1929..8f2543f 100644 --- a/pykd/pytypeinfo.h +++ b/pykd/pytypeinfo.h @@ -48,6 +48,8 @@ python::object callFunctionByVar( python::tuple& args, python::dict& kwargs ); python::object callFunctionByOffset( python::tuple& args, python::dict& kwargs); +python::object callFunctionRaw( python::tuple& args, python::dict& kwargs); + inline kdlib::TypeInfoPtr getTypeInfoByName( const std::wstring &name ) { diff --git a/samples/um/createfile.py b/samples/um/createfile.py index b4e6f5a..5916bee 100644 --- a/samples/um/createfile.py +++ b/samples/um/createfile.py @@ -1,4 +1,4 @@ - + import pykd GENERIC_READ = 0x80000000 @@ -27,13 +27,10 @@ def main(): CreateFileW_Type.append("dwFlagsAndAttributes", DWORD ) CreateFileW_Type.append("hTemplateFile", HANDLE ) - fileNameBuf = pykd.stackAlloc(100) - pykd.writeWStr(fileNameBuf, "C:\\temp\\testfile.txt") - CreateFileW = pykd.typedVar( CreateFileW_Type, kernel32.CreateFileW ) fileHandle = CreateFileW( - fileNameBuf, + "C:\\temp\\testfile.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL, @@ -43,7 +40,5 @@ def main(): print "File Handle", hex(fileHandle) - pykd.stackFree(100) - if __name__ == "__main__": main()