diff --git a/pykd/module.h b/pykd/module.h index f86ec5d..323c9a0 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "kdlib/module.h" namespace pykd { @@ -22,6 +24,40 @@ struct ModuleAdapter : public kdlib::Module return L"PYKD MODULE"; } + static python::list enumSymbols( kdlib::Module& module, const std::wstring &mask = L"*" ) + { + kdlib::SymbolOffsetList offsetLst = module.enumSymbols( mask ); + python::list pyLst; + for ( kdlib::SymbolOffsetList::const_iterator it = offsetLst.begin(); it != offsetLst.end(); ++it ) + pyLst.append( python::make_tuple( it->first, it->second ) ); + return pyLst; + } + + static std::wstring findSymbol( kdlib::Module& module, kdlib::MEMOFFSET_64 offset, bool showDisplacement = true ) + { + kdlib::MEMDISPLACEMENT displacement = 0; + std::wstring symbolName = module.findSymbol( offset, displacement ); + if ( !showDisplacement || displacement == 0 ) + return symbolName; + + std::wstringstream wsstr; + + wsstr << symbolName; + + if ( displacement > 0 ) + wsstr << L'+' << std::hex << displacement; + else + wsstr << L'-' << std::hex << -displacement; + + return wsstr.str(); + } + + static python::tuple findSymbolAndDisp( kdlib::Module& module, kdlib::MEMOFFSET_64 offset ) + { + kdlib::MEMDISPLACEMENT displacement = 0; + std::wstring symbolName = module.findSymbol( offset, displacement ); + return python::make_tuple( symbolName, displacement ); + } }; } // end namespace pykd diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 0d24ff5..788fb15 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -81,7 +81,9 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, kdlib::compareMemory, 3, 4 ); // //BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( TypeBuilder_createStruct, TypeBuilder::createStruct, 1, 2 ); // -//BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumSymbols, Module::enumSymbols, 0, 1 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( Module_enumSymbols, ModuleAdapter::enumSymbols, 1, 2 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( Module_findSymbol, ModuleAdapter::findSymbol, 2, 3 ); + //BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_findSymbol, Module::getSymbolNameByVa, 1, 2 ); @@ -387,12 +389,12 @@ python::class_( "numVariant", "numVarian "Return name of the image of the module" ) //.def("symfile", &Module::getSymFile, // "Return the full path to the module's symbol information" ) - //.def("offset", &Module::getSymbolOffset, - // "Return offset of the symbol" ) - //.def("findSymbol", &Module::getSymbolNameByVa, Module_findSymbol( python::args("offset", "showDisplacement"), - // "Return symbol name by virtual address" ) ) - //.def("findSymbolAndDisp", &pysupport::moduleFindSymbolAndDisp, - // "Return tuple(symbol_name, displacement) by virtual address" ) + .def("offset", &kdlib::Module::getSymbolVa, + "Return offset of the symbol" ) + .def("findSymbol", ModuleAdapter::findSymbol, Module_findSymbol( python::args("offset", "showDisplacement"), + "Return symbol name by virtual address" ) ) + .def("findSymbolAndDisp", ModuleAdapter::findSymbolAndDisp, + "Return tuple(symbol_name, displacement) by virtual address" ) //.def("rva", &Module::getSymbolRva, // "Return rva of the symbol" ) //.def("sizeof", &Module::getSymbolSize, @@ -416,8 +418,8 @@ python::class_( "numVariant", "numVarian //.def("containingRecord", &Module::containingRecordByName, // "Return instance of the typedVar class. It's value are loaded from the target memory." // "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" ) - //.def("enumSymbols", &Module::enumSymbols, Module_enumSymbols( python::args("mask"), - // "Return list of tuple ( symbolname, offset )" ) ) + .def("enumSymbols", ModuleAdapter::enumSymbols, Module_enumSymbols( python::args("mask"), + "Return list of tuple ( symbolname, offset )" ) ) //.def("checksum", &Module::getCheckSum, // "Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" ) //.def("timestamp", &Module::getTimeDataStamp, diff --git a/test/scripts/moduletest.py b/test/scripts/moduletest.py index a0c7a7d..63d3aa7 100644 --- a/test/scripts/moduletest.py +++ b/test/scripts/moduletest.py @@ -54,21 +54,29 @@ class ModuleTest( unittest.TestCase ): self.assertEqual( target.module.rva("FuncWithName0"), pykd.getOffset( target.module.name() + "!FuncWithName0") - target.module.begin() ) def testFindSymbol( self ): - self.assertEqual( "FuncWithName0", target.module.findSymbol( target.module.offset("FuncWithName0") ) ) - self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") ) ) - self.assertEqual( "targetapp!FuncWithName0", pykd.findSymbol( target.module.offset("FuncWithName0") ) ) - self.assertEqual( "targetapp!_FuncWithName2", pykd.findSymbol( target.module.offset("_FuncWithName2") ) ) - self.assertEqual( "_FuncWithName2+10", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10 ) ) - self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10, showDisplacement = False ) ) - self.assertEqual( "targetapp!_FuncWithName2+10", pykd.findSymbol( target.module.offset("_FuncWithName2") + 0x10 ) ) - self.assertEqual( "targetapp!_FuncWithName2", pykd.findSymbol( target.module.offset("_FuncWithName2") + 0x10, showDisplacement = False ) ) + self.assertEqual( "LocalStaticFunc", target.module.findSymbol( target.module.offset("LocalStaticFunc") ) ) + self.assertEqual( "CdeclFunc", target.module.findSymbol( target.module.offset("CdeclFunc") ) ) + self.assertEqual( "StdcallFunc", target.module.findSymbol( target.module.offset("StdcallFunc") ) ) + self.assertEqual( "FastcallFunc", target.module.findSymbol( target.module.offset("FastcallFunc") ) ) + self.assertEqual( "_UnderscoreFunc", target.module.findSymbol( target.module.offset("_UnderscoreFunc") ) ) + + #self.assertEqual( "FuncWithName0", target.module.findSymbol( target.module.offset("FuncWithName0") ) ) + #self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") ) ) + #self.assertEqual( "targetapp!FuncWithName0", pykd.findSymbol( target.module.offset("FuncWithName0") ) ) + #self.assertEqual( "targetapp!_FuncWithName2", pykd.findSymbol( target.module.offset("_FuncWithName2") ) ) + #self.assertEqual( "_FuncWithName2+10", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10 ) ) + #self.assertEqual( "_FuncWithName2", target.module.findSymbol( target.module.offset("_FuncWithName2") + 0x10, showDisplacement = False ) ) + #self.assertEqual( "targetapp!_FuncWithName2+10", pykd.findSymbol( target.module.offset("_FuncWithName2") + 0x10 ) ) + #self.assertEqual( "targetapp!_FuncWithName2", pykd.findSymbol( target.module.offset("_FuncWithName2") + 0x10, showDisplacement = False ) ) + pass def testFindSymbolAndDisp( self ): - vaFuncWithName0 = target.module.offset("FuncWithName0") - self.assertEqual( ("FuncWithName0", 0), target.module.findSymbolAndDisp(vaFuncWithName0) ) - self.assertEqual( ("FuncWithName0", 2), target.module.findSymbolAndDisp(vaFuncWithName0+2) ) - self.assertEqual( ("targetapp!FuncWithName0", 0), pykd.findSymbolAndDisp(vaFuncWithName0) ) - self.assertEqual( ("targetapp!FuncWithName0", 2), pykd.findSymbolAndDisp(vaFuncWithName0+2) ) + #vaFuncWithName0 = target.module.offset("FuncWithName0") + #self.assertEqual( ("FuncWithName0", 0), target.module.findSymbolAndDisp(vaFuncWithName0) ) + #self.assertEqual( ("FuncWithName0", 2), target.module.findSymbolAndDisp(vaFuncWithName0+2) ) + #self.assertEqual( ("targetapp!FuncWithName0", 0), pykd.findSymbolAndDisp(vaFuncWithName0) ) + #self.assertEqual( ("targetapp!FuncWithName0", 2), pykd.findSymbolAndDisp(vaFuncWithName0+2) ) + pass def testType( self ): self.assertEqual( "structTest", target.module.type("structTest").name() );