mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-19 19:13:22 +08:00
add: secondary callback data (issue #14)
This commit is contained in:
parent
64bdab59cc
commit
15eae98a0f
@ -590,6 +590,7 @@
|
|||||||
<ClInclude Include="pymodule.h" />
|
<ClInclude Include="pymodule.h" />
|
||||||
<ClInclude Include="pyprocess.h" />
|
<ClInclude Include="pyprocess.h" />
|
||||||
<ClInclude Include="pysymengine.h" />
|
<ClInclude Include="pysymengine.h" />
|
||||||
|
<ClInclude Include="pytagged.h" />
|
||||||
<ClInclude Include="pythreadstate.h" />
|
<ClInclude Include="pythreadstate.h" />
|
||||||
<ClInclude Include="pytypedvar.h" />
|
<ClInclude Include="pytypedvar.h" />
|
||||||
<ClInclude Include="pytypeinfo.h" />
|
<ClInclude Include="pytypeinfo.h" />
|
||||||
@ -623,6 +624,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="pymodule.cpp" />
|
<ClCompile Include="pymodule.cpp" />
|
||||||
<ClCompile Include="pyprocess.cpp" />
|
<ClCompile Include="pyprocess.cpp" />
|
||||||
|
<ClCompile Include="pytagged.cpp" />
|
||||||
<ClCompile Include="pytypedvar.cpp" />
|
<ClCompile Include="pytypedvar.cpp" />
|
||||||
<ClCompile Include="pytypeinfo.cpp" />
|
<ClCompile Include="pytypeinfo.cpp" />
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
@ -81,6 +81,9 @@
|
|||||||
<ClInclude Include="pydataaccess.h">
|
<ClInclude Include="pydataaccess.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="pytagged.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
@ -248,6 +251,9 @@
|
|||||||
<ClCompile Include="pyprocess.cpp">
|
<ClCompile Include="pyprocess.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="pytagged.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="pykd.def">
|
<None Include="pykd.def">
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "pytypeinfo.h"
|
#include "pytypeinfo.h"
|
||||||
#include "pycpucontext.h"
|
#include "pycpucontext.h"
|
||||||
#include "pyprocess.h"
|
#include "pyprocess.h"
|
||||||
|
#include "pytagged.h"
|
||||||
|
|
||||||
using namespace pykd;
|
using namespace pykd;
|
||||||
|
|
||||||
@ -597,6 +598,12 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
python::def( "removeSyntheticSymbol", pykd::removeSyntheticSymbol,
|
python::def( "removeSyntheticSymbol", pykd::removeSyntheticSymbol,
|
||||||
"The removeSyntheticSymbol function removes a synthetic symbol from a module in the current proces" );
|
"The removeSyntheticSymbol function removes a synthetic symbol from a module in the current proces" );
|
||||||
|
|
||||||
|
// secondary callback data
|
||||||
|
python::def("enumTagged", pykd::enumTagged,
|
||||||
|
"Return the list of secondary callback data IDs (as a strings)" );
|
||||||
|
python::def("loadTaggedBuffer", pykd::loadTaggedBuffer,
|
||||||
|
"Read the buffer of secondary callback data by ID" );
|
||||||
|
|
||||||
python::class_<kdlib::NumBehavior, boost::noncopyable>( "numVariant", "numVariant", python::no_init )
|
python::class_<kdlib::NumBehavior, boost::noncopyable>( "numVariant", "numVariant", python::no_init )
|
||||||
.def("__init__", python::make_constructor(&NumVariantAdaptor::getVariant) )
|
.def("__init__", python::make_constructor(&NumVariantAdaptor::getVariant) )
|
||||||
.def( "__eq__", &NumVariantAdaptor::eq )
|
.def( "__eq__", &NumVariantAdaptor::eq )
|
||||||
|
76
pykd/pytagged.cpp
Normal file
76
pykd/pytagged.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "pytagged.h"
|
||||||
|
#include "kdlib\tagged.h"
|
||||||
|
#include "kdlib\exceptions.h"
|
||||||
|
|
||||||
|
#include "pythreadstate.h"
|
||||||
|
#include "stladaptor.h"
|
||||||
|
|
||||||
|
#include <rpc.h>
|
||||||
|
#pragma comment(lib, "Rpcrt4.lib")
|
||||||
|
|
||||||
|
|
||||||
|
namespace pykd {
|
||||||
|
|
||||||
|
|
||||||
|
void __declspec(noreturn) throwRpcStatus( const std::string &functionName, RPC_STATUS status )
|
||||||
|
{
|
||||||
|
std::stringstream sstr;
|
||||||
|
sstr << "Call " << functionName << " failed\n";
|
||||||
|
sstr << "RPC_STATUS 0x" << std::hex << status;
|
||||||
|
throw kdlib::DbgException( sstr.str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
python::list enumTagged()
|
||||||
|
{
|
||||||
|
std::list<kdlib::TaggedId> ids;
|
||||||
|
{
|
||||||
|
AutoRestorePyState pystate;
|
||||||
|
ids = std::move( kdlib::enumTagged() );
|
||||||
|
}
|
||||||
|
|
||||||
|
python::list result;
|
||||||
|
|
||||||
|
for (const auto &id : ids)
|
||||||
|
{
|
||||||
|
RPC_WSTR id_str = nullptr;
|
||||||
|
auto status = ::UuidToString(&id, &id_str);
|
||||||
|
if (RPC_S_OK != status)
|
||||||
|
throwRpcStatus("UuidToString", status);
|
||||||
|
|
||||||
|
const auto stringFree =
|
||||||
|
[](RPC_WSTR *str)
|
||||||
|
{
|
||||||
|
auto status = ::RpcStringFree(str);
|
||||||
|
if (RPC_S_OK != status)
|
||||||
|
throwRpcStatus("RpcStringFree", status);
|
||||||
|
};
|
||||||
|
std::unique_ptr<RPC_WSTR, decltype(stringFree)> freeGuard{&id_str, stringFree};
|
||||||
|
|
||||||
|
result.append( std::wstring(reinterpret_cast<wchar_t *>(id_str)) );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
python::list loadTaggedBuffer(const std::wstring &id_str)
|
||||||
|
{
|
||||||
|
const auto rcp_str =
|
||||||
|
reinterpret_cast<RPC_WSTR>( const_cast<wchar_t *>(id_str.c_str()) );
|
||||||
|
kdlib::TaggedId id;
|
||||||
|
auto status = ::UuidFromString(rcp_str, &id);
|
||||||
|
if (RPC_S_OK != status)
|
||||||
|
throwRpcStatus("UuidFromString", status);
|
||||||
|
|
||||||
|
|
||||||
|
kdlib::TaggedBuffer buff;
|
||||||
|
{
|
||||||
|
AutoRestorePyState pystate;
|
||||||
|
buff = std::move( kdlib::loadTaggedBuffer(id) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return vectorToList(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pykd
|
12
pykd/pytagged.h
Normal file
12
pykd/pytagged.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace python = boost::python;
|
||||||
|
|
||||||
|
namespace pykd {
|
||||||
|
|
||||||
|
python::list enumTagged();
|
||||||
|
|
||||||
|
python::list loadTaggedBuffer(const std::wstring &id_str);
|
||||||
|
|
||||||
|
} // namespace pykd
|
@ -27,6 +27,7 @@ import excepttest
|
|||||||
import targetprocess
|
import targetprocess
|
||||||
import ehloadtest
|
import ehloadtest
|
||||||
import synsymtest
|
import synsymtest
|
||||||
|
import taggedtest
|
||||||
|
|
||||||
pykd.initialize()
|
pykd.initialize()
|
||||||
|
|
||||||
@ -65,6 +66,7 @@ def getTestSuite( singleName = "" ):
|
|||||||
unittest.TestLoader().loadTestsFromTestCase( mspdbtest.MsPdbTest ),
|
unittest.TestLoader().loadTestsFromTestCase( mspdbtest.MsPdbTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( targetprocess.ProcessTest ),
|
unittest.TestLoader().loadTestsFromTestCase( targetprocess.ProcessTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ),
|
unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ),
|
||||||
|
unittest.TestLoader().loadTestsFromTestCase( taggedtest.TaggedTest ),
|
||||||
|
|
||||||
#unittest.TestLoader().loadTestsFromTestCase( excepttest.ExceptionTest ),
|
#unittest.TestLoader().loadTestsFromTestCase( excepttest.ExceptionTest ),
|
||||||
] )
|
] )
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
<Compile Include="regtest.py" />
|
<Compile Include="regtest.py" />
|
||||||
<Compile Include="stacktest.py" />
|
<Compile Include="stacktest.py" />
|
||||||
<Compile Include="synsymtest.py" />
|
<Compile Include="synsymtest.py" />
|
||||||
|
<Compile Include="taggedtest.py" />
|
||||||
<Compile Include="target.py" />
|
<Compile Include="target.py" />
|
||||||
<Compile Include="targetprocess.py" />
|
<Compile Include="targetprocess.py" />
|
||||||
<Compile Include="testutils.py" />
|
<Compile Include="testutils.py" />
|
||||||
|
31
test/scripts/taggedtest.py
Normal file
31
test/scripts/taggedtest.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import unittest
|
||||||
|
import pykd
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
class TaggedTest(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
dump_file = os.path.join( os.path.dirname(sys.argv[0]),
|
||||||
|
r"..\..\kdlibcpp\kdlib\tests\dumps\win8_x64_mem.cab" )
|
||||||
|
self.dump_id = pykd.loadDump( dump_file )
|
||||||
|
|
||||||
|
self._existing_id = "D03DC06F-D88E-44C5-BA2A-FAE035172D19"
|
||||||
|
self._non_existing_id = "88597A32-1493-41CA-BF87-2A950DF4CEE0"
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pykd.closeDump( self.dump_id )
|
||||||
|
|
||||||
|
def testEnum(self):
|
||||||
|
ids = pykd.enumTagged()
|
||||||
|
|
||||||
|
self.assertTrue( self._existing_id.lower() in [i.lower() for i in ids] )
|
||||||
|
|
||||||
|
self.assertFalse( self._non_existing_id.lower() in [i.lower() for i in ids] )
|
||||||
|
|
||||||
|
|
||||||
|
def testLoadBuffer(self):
|
||||||
|
buff = pykd.loadTaggedBuffer( self._existing_id )
|
||||||
|
self.assertEqual( len(buff), 0x410 )
|
||||||
|
|
||||||
|
self.assertRaises( pykd.DbgException, pykd.loadTaggedBuffer, self._non_existing_id )
|
||||||
|
|
Loading…
Reference in New Issue
Block a user