mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.1.x] add: synthetic symbols implementation
git-svn-id: https://pykd.svn.codeplex.com/svn@71929 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
283f911a73
commit
bc3259e916
@ -12,6 +12,15 @@ DebugClientPtr g_dbgClient( DebugClient::createDbgClient() );
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DebugClient::DebugClient( IDebugClient4 *client )
|
||||
: DbgObject( client )
|
||||
, m_symSymbols( new SyntheticSymbols(*m_symbols, *this) )
|
||||
, m_internalDbgEventHandler(client, m_symSymbols)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DebugClientPtr DebugClient::createDbgClient() {
|
||||
|
||||
HRESULT hres;
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "pyaux.h"
|
||||
#include "disasm.h"
|
||||
#include "cpureg.h"
|
||||
#include "inteventhandler.h"
|
||||
#include "synsymbol.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -97,11 +99,11 @@ public:
|
||||
void loadDump( const std::wstring &fileName );
|
||||
|
||||
Module loadModuleByName( const std::string &moduleName ) {
|
||||
return Module( m_client, moduleName );
|
||||
return Module( m_client, m_symSymbols, moduleName );
|
||||
}
|
||||
|
||||
Module loadModuleByOffset( ULONG64 offset ) {
|
||||
return Module( m_client, offset );
|
||||
return Module( m_client, m_symSymbols, offset );
|
||||
}
|
||||
|
||||
DbgExtensionPtr loadExtension( const std::wstring &extPath ) {
|
||||
@ -191,6 +193,35 @@ public:
|
||||
return m_pyThreadState;
|
||||
}
|
||||
|
||||
void addSyntheticSymbol(
|
||||
ULONG64 addr,
|
||||
ULONG size,
|
||||
const std::string &symName
|
||||
)
|
||||
{
|
||||
return m_symSymbols->add(addr, size, symName);
|
||||
}
|
||||
|
||||
void delAllSyntheticSymbols()
|
||||
{
|
||||
return m_symSymbols->clear();
|
||||
}
|
||||
|
||||
ULONG delSyntheticSymbol(
|
||||
ULONG64 addr
|
||||
)
|
||||
{
|
||||
return m_symSymbols->remove(addr);
|
||||
}
|
||||
|
||||
ULONG delSyntheticSymbolsMask(
|
||||
const std::string &moduleName,
|
||||
const std::string &symName
|
||||
)
|
||||
{
|
||||
return m_symSymbols->removeByMask(moduleName, symName);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<typename T>
|
||||
@ -200,7 +231,10 @@ private:
|
||||
//python::list
|
||||
//loadArray( ULONG64 offset, ULONG count, bool phyAddr );
|
||||
|
||||
DebugClient( IDebugClient4 *client ) : DbgObject( client ) {}
|
||||
SynSymbolsPtr m_symSymbols; // DebugClient is creator
|
||||
InternalDbgEventHandler m_internalDbgEventHandler;
|
||||
|
||||
DebugClient( IDebugClient4 *client );
|
||||
|
||||
PyThreadStateSaver m_pyThreadState;
|
||||
};
|
||||
@ -235,6 +269,38 @@ void setExecutionStatus( ULONG status );
|
||||
|
||||
void waitForEvent();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Synthetic symbols global finctions:
|
||||
|
||||
inline void addSyntheticSymbol(
|
||||
ULONG64 addr,
|
||||
ULONG size,
|
||||
const std::string &symName
|
||||
)
|
||||
{
|
||||
return g_dbgClient->addSyntheticSymbol(addr, size, symName);
|
||||
}
|
||||
|
||||
inline void delAllSyntheticSymbols()
|
||||
{
|
||||
return g_dbgClient->delAllSyntheticSymbols();
|
||||
}
|
||||
|
||||
inline ULONG delSyntheticSymbol(
|
||||
ULONG64 addr
|
||||
)
|
||||
{
|
||||
return g_dbgClient->delSyntheticSymbol(addr);
|
||||
}
|
||||
|
||||
inline ULONG delSyntheticSymbolsMask(
|
||||
const std::string &moduleName,
|
||||
const std::string &symName
|
||||
)
|
||||
{
|
||||
return g_dbgClient->delSyntheticSymbolsMask(moduleName, symName);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<ULONG status>
|
||||
|
@ -234,7 +234,15 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def( "trace", &pykd::DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_INTO>,
|
||||
"Change debugger status to DEBUG_STATUS_STEP_INTO" )
|
||||
.def( "waitForEvent", &pykd::DebugClient::waitForEvent,
|
||||
"Wait for events that breaks into the debugger" );
|
||||
"Wait for events that breaks into the debugger" )
|
||||
.def( "addSynSymbol", &pykd::DebugClient::addSyntheticSymbol,
|
||||
"Add new synthetic symbol for virtual address" )
|
||||
.def( "delAllSynSymbols", &pykd::DebugClient::delAllSyntheticSymbols,
|
||||
"Delete all synthetic symbol for all modules")
|
||||
.def( "delSynSymbol", &pykd::DebugClient::delSyntheticSymbol,
|
||||
"Delete synthetic symbols by virtual address" )
|
||||
.def( "delSynSymbolsMask", &pykd::DebugClient::delSyntheticSymbolsMask,
|
||||
"Delete synthetic symbols by mask of module and symbol name");
|
||||
|
||||
python::def( "addr64", &addr64,
|
||||
"Extend address to 64 bits formats" );
|
||||
@ -318,6 +326,16 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Read an signed mashine's word wide integer from the target memory" );
|
||||
python::def( "ptrPtr", &ptrPtr,
|
||||
"Read an pointer value from the target memory" );
|
||||
|
||||
boost::python::def( "addSynSymbol", &addSyntheticSymbol,
|
||||
"Add new synthetic symbol for virtual address" );
|
||||
boost::python::def( "delAllSynSymbols", &delAllSyntheticSymbols,
|
||||
"Delete all synthetic symbol for all modules");
|
||||
boost::python::def( "delSynSymbol", &delSyntheticSymbol,
|
||||
"Delete synthetic symbols by virtual address" );
|
||||
boost::python::def( "delSynSymbolsMask", &delSyntheticSymbolsMask,
|
||||
"Delete synthetic symbols by mask of module and symbol name");
|
||||
|
||||
python::def( "loadExt", &pykd::loadExtension,
|
||||
"Load a debuger extension" );
|
||||
python::def( "loadModule", &loadModuleByName,
|
||||
@ -610,6 +628,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
// wrapper for standart python exceptions
|
||||
python::register_exception_translator<pykd::PyException>( &PyException::exceptionTranslate );
|
||||
|
||||
#define _DECL_BASE_EXCEPT_STR .def( "__str__", &pykd::DbgException::print )
|
||||
|
||||
// base exception
|
||||
python::class_<pykd::DbgException> dbgExceptionClass( "BaseException",
|
||||
"Pykd base exception class",
|
||||
@ -618,17 +638,17 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def( python::init<std::string>( python::args("desc"), "constructor" ) )
|
||||
.def( "desc", &pykd::DbgException::getDesc,
|
||||
"Get exception description" )
|
||||
.def( "__str__", &pykd::DbgException::print);
|
||||
_DECL_BASE_EXCEPT_STR;
|
||||
pykd::DbgException::setTypeObject( dbgExceptionClass.ptr() );
|
||||
python::register_exception_translator<pykd::DbgException>(
|
||||
&pykd::DbgException::exceptionTranslate );
|
||||
|
||||
// DIA exceptions
|
||||
python::class_<pyDia::Exception, python::bases<DbgException> > diaException(
|
||||
"DiaException", "Debug interface access exception",
|
||||
python::no_init );
|
||||
"DiaException", "Debug interface access exception", python::no_init);
|
||||
diaException
|
||||
.def( "hres", &pyDia::Exception::getRes );
|
||||
.def( "hres", &pyDia::Exception::getRes )
|
||||
_DECL_BASE_EXCEPT_STR;
|
||||
pyDia::Exception::setTypeObject( diaException.ptr() );
|
||||
python::register_exception_translator<pyDia::Exception>(
|
||||
&pyDia::Exception::exceptionTranslate );
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <dbgeng.h>
|
||||
#include "dbgexcept.h"
|
||||
#include "synsymbol.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
@ -11,7 +12,8 @@ class DbgObject {
|
||||
|
||||
protected:
|
||||
|
||||
DbgObject( IDebugClient4 *client ) {
|
||||
DbgObject( IDebugClient4 *client )
|
||||
{
|
||||
|
||||
m_client = client;
|
||||
|
||||
@ -50,7 +52,6 @@ protected:
|
||||
CComPtr<IDebugAdvanced2> m_advanced;
|
||||
CComPtr<IDebugDataSpaces4> m_dataSpaces;
|
||||
CComPtr<IDebugRegisters2> m_registers;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
76
pykd/inteventhandler.cpp
Normal file
76
pykd/inteventhandler.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "inteventhandler.h"
|
||||
#include "dbgexcept.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
InternalDbgEventHandler::InternalDbgEventHandler(
|
||||
IDebugClient4 *client,
|
||||
SynSymbolsPtr synSymbols
|
||||
) : m_synSymbols(synSymbols)
|
||||
{
|
||||
HRESULT hres = client->CreateClient(&m_client);
|
||||
if (FAILED(hres))
|
||||
throw DbgException("Call IDebugClient::CreateClient failed");
|
||||
|
||||
m_client->SetEventCallbacks(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
InternalDbgEventHandler::~InternalDbgEventHandler()
|
||||
{
|
||||
m_client->Release();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT InternalDbgEventHandler::GetInterestMask(
|
||||
__out PULONG Mask
|
||||
)
|
||||
{
|
||||
*Mask =
|
||||
DEBUG_EVENT_CHANGE_SYMBOL_STATE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT InternalDbgEventHandler::ChangeSymbolState(
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
)
|
||||
{
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
if (DEBUG_CSS_LOADS & Flags)
|
||||
hres = symLoaded(Argument);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT InternalDbgEventHandler::symLoaded(
|
||||
__in ULONG64 ModuleAddress
|
||||
)
|
||||
{
|
||||
if (!ModuleAddress)
|
||||
{
|
||||
// f.e. is case ".reload /f image.exe", if for image.exe no symbols
|
||||
m_synSymbols->restoreAll();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
m_synSymbols->restoreForModule(ModuleAddress);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // namespace pykd
|
45
pykd/inteventhandler.h
Normal file
45
pykd/inteventhandler.h
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// Internal debug event handler
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <DbgEng.h>
|
||||
#include "synsymbol.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
class InternalDbgEventHandler : public DebugBaseEventCallbacks {
|
||||
public:
|
||||
|
||||
InternalDbgEventHandler(
|
||||
IDebugClient4 *client,
|
||||
SynSymbolsPtr synSymbols
|
||||
);
|
||||
~InternalDbgEventHandler();
|
||||
|
||||
protected:
|
||||
|
||||
// IUnknown impls
|
||||
STDMETHOD_(ULONG, AddRef)() { return 1; }
|
||||
STDMETHOD_(ULONG, Release)() { return 1; }
|
||||
|
||||
// IDebugEventCallbacks impls
|
||||
STDMETHOD(GetInterestMask)(
|
||||
__out PULONG Mask
|
||||
);
|
||||
|
||||
STDMETHOD(ChangeSymbolState)(
|
||||
__in ULONG Flags,
|
||||
__in ULONG64 Argument
|
||||
);
|
||||
|
||||
private:
|
||||
|
||||
HRESULT symLoaded(__in ULONG64 ModuleAddress);
|
||||
|
||||
IDebugClient *m_client;
|
||||
SynSymbolsPtr m_synSymbols;
|
||||
};
|
||||
|
||||
}; // namespace pykd
|
@ -20,7 +20,9 @@ Module loadModuleByOffset( ULONG64 offset ) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module::Module( IDebugClient4 *client, const std::string& moduleName ) : DbgObject( client )
|
||||
Module::Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, const std::string& moduleName )
|
||||
: DbgObject( client )
|
||||
, m_synSymbols(synSymbols)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
@ -36,6 +38,8 @@ Module::Module( IDebugClient4 *client, const std::string& moduleName ) : DbgObje
|
||||
throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
|
||||
|
||||
m_size = moduleParam.Size;
|
||||
m_timeDataStamp = moduleParam.TimeDateStamp;
|
||||
m_checkSumm = moduleParam.Checksum;
|
||||
|
||||
char imageName[0x100];
|
||||
|
||||
@ -55,7 +59,9 @@ Module::Module( IDebugClient4 *client, const std::string& moduleName ) : DbgObje
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Module::Module( IDebugClient4 *client, ULONG64 offset ) : DbgObject( client )
|
||||
Module::Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, ULONG64 offset )
|
||||
: DbgObject( client )
|
||||
, m_synSymbols(synSymbols)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
@ -102,6 +108,8 @@ Module::Module( IDebugClient4 *client, ULONG64 offset ) : DbgObject( client )
|
||||
throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
|
||||
|
||||
m_size = moduleParam.Size;
|
||||
m_timeDataStamp = moduleParam.TimeDateStamp;
|
||||
m_checkSumm = moduleParam.Checksum;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
@ -198,5 +206,18 @@ Module::getTypedVarByAddr( ULONG64 addr )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG Module::getRvaByName(const std::string &symName)
|
||||
{
|
||||
try {
|
||||
pyDia::SymbolPtr sym = getDia()->getChildByName( symName );
|
||||
return sym->getRva();
|
||||
}
|
||||
catch (const pyDia::Exception &) {
|
||||
}
|
||||
return (ULONG)m_synSymbols->getRvaByName(m_timeDataStamp, m_checkSumm, symName);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // end of namespace pykd
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "diawrapper.h"
|
||||
#include "typeinfo.h"
|
||||
#include "typedvar.h"
|
||||
#include "synsymbol.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
@ -15,9 +16,9 @@ class Module : private DbgObject {
|
||||
|
||||
public:
|
||||
|
||||
Module( IDebugClient4 *client, const std::string& moduleName );
|
||||
Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, const std::string& moduleName );
|
||||
|
||||
Module( IDebugClient4 *client, ULONG64 offset );
|
||||
Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, ULONG64 offset );
|
||||
|
||||
std::string getName() {
|
||||
return m_name;
|
||||
@ -47,16 +48,12 @@ public:
|
||||
|
||||
ULONG64
|
||||
getSymbol( const std::string &symbolname ) {
|
||||
pyDia::SymbolPtr sym = getDia()->getChildByName( symbolname );
|
||||
|
||||
return m_base + sym->getRva();
|
||||
return m_base + getRvaByName(symbolname);
|
||||
}
|
||||
|
||||
ULONG
|
||||
getSymbolRva( const std::string &symbolname ) {
|
||||
pyDia::SymbolPtr sym = getDia()->getChildByName( symbolname );
|
||||
|
||||
return sym->getRva();
|
||||
return getRvaByName(symbolname);
|
||||
}
|
||||
|
||||
TypeInfoPtr getTypeByName( const std::string &typeName ) {
|
||||
@ -73,6 +70,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
ULONG getRvaByName(const std::string &symName);
|
||||
|
||||
pyDia::GlobalScopePtr& getDia() {
|
||||
if (!m_dia)
|
||||
m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
|
||||
@ -84,7 +83,12 @@ private:
|
||||
std::string m_imageName;
|
||||
ULONG64 m_base;
|
||||
ULONG m_size;
|
||||
|
||||
pyDia::GlobalScopePtr m_dia;
|
||||
|
||||
ULONG m_timeDataStamp;
|
||||
ULONG m_checkSumm;
|
||||
SynSymbolsPtr m_synSymbols;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Version="9.00"
|
||||
Name="pykd"
|
||||
ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}"
|
||||
RootNamespace="pykd"
|
||||
@ -401,6 +401,10 @@
|
||||
RelativePath=".\disasm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\inteventhandler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\module.cpp"
|
||||
>
|
||||
@ -445,6 +449,14 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\synsymbol.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\synsymhelpers.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\typedvar.cpp"
|
||||
>
|
||||
@ -511,6 +523,10 @@
|
||||
RelativePath=".\intbase.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\inteventhandler.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\module.h"
|
||||
>
|
||||
@ -527,6 +543,14 @@
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\synsymbol.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\synsymhelpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\typedvar.h"
|
||||
>
|
||||
|
248
pykd/synsymbol.cpp
Normal file
248
pykd/synsymbol.cpp
Normal file
@ -0,0 +1,248 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "dbgmem.h"
|
||||
#include "dbgexcept.h"
|
||||
#include "dbgclient.h"
|
||||
#include "synsymhelpers.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SyntheticSymbols::SyntheticSymbols(
|
||||
IDebugSymbols3 &symbols,
|
||||
DebugClient &dbgClient
|
||||
) : m_symbols(symbols)
|
||||
, m_dbgClient(dbgClient)
|
||||
{
|
||||
m_allSymbolsLock.reset(new boost::recursive_mutex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SyntheticSymbols::add(
|
||||
ULONG64 addr,
|
||||
ULONG size,
|
||||
const std::string &symName
|
||||
)
|
||||
{
|
||||
addr = m_dbgClient.addr64(addr);
|
||||
|
||||
// add new synthetic symbol to debug engine
|
||||
DEBUG_MODULE_AND_ID dbgModuleAndId = { 0 };
|
||||
HRESULT hres =
|
||||
m_symbols.AddSyntheticSymbol(
|
||||
addr,
|
||||
size,
|
||||
symName.c_str(),
|
||||
DEBUG_ADDSYNTHSYM_DEFAULT,
|
||||
&dbgModuleAndId);
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException(buildExceptDesc("IDebugSymbols3::AddSyntheticSymbol", hres));
|
||||
|
||||
// add/update symbol for target module (in internal map)
|
||||
SymbolsScopedLock lock(*m_allSymbolsLock);
|
||||
|
||||
ModSymbols &modSymbols =
|
||||
m_allSymbols[SynSymHelper(m_symbols).modByBase(dbgModuleAndId.ModuleBase)];
|
||||
SymbolData &symData = modSymbols[addr - dbgModuleAndId.ModuleBase];
|
||||
|
||||
symData.m_name = symName;
|
||||
symData.m_size = size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG SyntheticSymbols::remove(ULONG64 addr)
|
||||
{
|
||||
addr = m_dbgClient.addr64(addr);
|
||||
|
||||
SynSymHelper synSymHelper(m_symbols);
|
||||
|
||||
// find target module
|
||||
ULONG64 moduleBase;
|
||||
SymbolsScopedLock lock(*m_allSymbolsLock);
|
||||
AllSymbols::iterator itModSymbols =
|
||||
m_allSymbols.find(synSymHelper.modByOffset(addr, moduleBase));
|
||||
if (itModSymbols == m_allSymbols.end())
|
||||
return 0;
|
||||
|
||||
// remove symbol from internal map
|
||||
itModSymbols->second.erase(addr - moduleBase);
|
||||
|
||||
// remove symbol from debug engine
|
||||
return synSymHelper.removeSyntheticSymbols(addr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG SyntheticSymbols::removeByMask(
|
||||
const std::string &moduleName,
|
||||
const std::string &symName
|
||||
)
|
||||
{
|
||||
SynSymHelper synSymHelper(m_symbols);
|
||||
|
||||
std::vector<DEBUG_MODULE_AND_ID> dbgSymbols;
|
||||
HRESULT hres =
|
||||
synSymHelper.getSymbolsByMaks(
|
||||
moduleName + "!" + symName,
|
||||
dbgSymbols);
|
||||
if (FAILED(hres))
|
||||
throw DbgException(buildExceptDesc("IDebugSymbols3::GetSymbolEntriesByName", hres));
|
||||
|
||||
if (dbgSymbols.empty())
|
||||
return 0;
|
||||
|
||||
ULONG removed = 0;
|
||||
|
||||
SymbolsScopedLock lock(*m_allSymbolsLock);
|
||||
for (ULONG i =0; i < dbgSymbols.size(); ++i)
|
||||
{
|
||||
DEBUG_SYMBOL_ENTRY dbgSymbolInfo;
|
||||
HRESULT hres =
|
||||
m_symbols.GetSymbolEntryInformation(
|
||||
&dbgSymbols[i],
|
||||
&dbgSymbolInfo);
|
||||
if (FAILED(hres))
|
||||
continue;
|
||||
|
||||
// try find modules in internal map
|
||||
AllSymbols::iterator itModSymbols =
|
||||
m_allSymbols.find(synSymHelper.modByBase(dbgSymbolInfo.ModuleBase));
|
||||
if (itModSymbols == m_allSymbols.end())
|
||||
continue;
|
||||
|
||||
// try find symbol
|
||||
ModSymbols::iterator itSymbol =
|
||||
itModSymbols->second.find(dbgSymbolInfo.Offset - dbgSymbolInfo.ModuleBase);
|
||||
if (itSymbol == itModSymbols->second.end())
|
||||
continue;
|
||||
|
||||
// remove from debug engine
|
||||
if (synSymHelper.removeSyntheticSymbols(dbgSymbols[i]))
|
||||
++removed;
|
||||
|
||||
// remove from internal map
|
||||
itModSymbols->second.erase(itSymbol);
|
||||
|
||||
if (itModSymbols->second.empty())
|
||||
m_allSymbols.erase(itModSymbols);
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SyntheticSymbols::clear()
|
||||
{
|
||||
SymbolsScopedLock lock(*m_allSymbolsLock);
|
||||
|
||||
// clean symbols from debug engine
|
||||
forEachLoadedModule( SynSymRemoveAll(m_symbols) );
|
||||
|
||||
// clean internal map
|
||||
m_allSymbols.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SyntheticSymbols::restoreForModule(ULONG64 moduleBase)
|
||||
{
|
||||
SymbolsScopedLock lock(*m_allSymbolsLock);
|
||||
|
||||
SynSymRestore restorer(m_symbols);
|
||||
AllSymbols::iterator itFoundModule =
|
||||
m_allSymbols.find( restorer.modByBase(moduleBase) );
|
||||
if (itFoundModule == m_allSymbols.end())
|
||||
return;
|
||||
|
||||
forEachFromModule(moduleBase, itFoundModule->second, restorer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SyntheticSymbols::restoreAll()
|
||||
{
|
||||
SymbolsScopedLock lock(*m_allSymbolsLock);
|
||||
|
||||
// clean symbols from debug engine
|
||||
forEachLoadedModule( SynSymRestore(m_symbols) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG64 SyntheticSymbols::getRvaByName(
|
||||
ULONG timeDataStamp,
|
||||
ULONG checkSumm,
|
||||
const std::string &symName
|
||||
)
|
||||
{
|
||||
SymbolsScopedLock lock(*m_allSymbolsLock);
|
||||
AllSymbols::iterator itFoundModule =
|
||||
m_allSymbols.find( ModuleId(timeDataStamp, checkSumm) );
|
||||
if (itFoundModule == m_allSymbols.end())
|
||||
throw DbgException("Synthetic symbol is not found");
|
||||
|
||||
|
||||
ModSymbols::iterator itSynSymbol = itFoundModule->second.begin();
|
||||
while (itSynSymbol != itFoundModule->second.end())
|
||||
{
|
||||
if (boost::iequals(symName, itSynSymbol->second.m_name))
|
||||
return itSynSymbol->first;
|
||||
|
||||
++itSynSymbol;
|
||||
}
|
||||
throw DbgException("Synthetic symbol is not found");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SyntheticSymbols::forEachFromModule(
|
||||
ULONG64 moduleBase,
|
||||
const ModSymbols &modSymbols,
|
||||
ISynSymForEach &forEach
|
||||
)
|
||||
{
|
||||
ModSymbols::const_iterator itSynSymbol = modSymbols.begin();
|
||||
while (itSynSymbol != modSymbols.end())
|
||||
{
|
||||
forEach.symbol(moduleBase, itSynSymbol->first, itSynSymbol->second);
|
||||
++itSynSymbol;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SyntheticSymbols::forEachLoadedModule(ISynSymForEach &forEach)
|
||||
{
|
||||
// for loaded and unloaded modules...
|
||||
std::vector<DEBUG_MODULE_PARAMETERS> dbgModules;
|
||||
if (!SUCCEEDED(forEach.getAllModules(dbgModules)) || dbgModules.empty())
|
||||
{
|
||||
SymbolsScopedLock lock(*m_allSymbolsLock);
|
||||
m_allSymbols.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<DEBUG_MODULE_PARAMETERS>::iterator itModule = dbgModules.begin();
|
||||
while (itModule != dbgModules.end())
|
||||
{
|
||||
// ...do it!
|
||||
AllSymbols::const_iterator itFoundModule =
|
||||
m_allSymbols.find( ModuleId(*itModule) );
|
||||
if (itFoundModule != m_allSymbols.end())
|
||||
forEachFromModule(itModule->Base, itFoundModule->second, forEach);
|
||||
|
||||
++itModule;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // namespace pykd
|
144
pykd/synsymbol.h
Normal file
144
pykd/synsymbol.h
Normal file
@ -0,0 +1,144 @@
|
||||
//
|
||||
// Synthetic symbol
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dbgexcept.h"
|
||||
#include <DbgEng.h>
|
||||
#include <map>
|
||||
#include <boost\thread\win32\recursive_mutex.hpp>
|
||||
|
||||
namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
interface ISynSymForEach;
|
||||
class DebugClient;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SyntheticSymbols {
|
||||
public:
|
||||
SyntheticSymbols(
|
||||
IDebugSymbols3 &symbols,
|
||||
DebugClient &dbgClient
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Python API:
|
||||
|
||||
// add new synthetic symbol
|
||||
void add(
|
||||
ULONG64 addr,
|
||||
ULONG size,
|
||||
const std::string &symName
|
||||
);
|
||||
|
||||
// remove synthetic symbols by address
|
||||
ULONG remove(ULONG64 addr);
|
||||
|
||||
// remove synthetic symbols by module and symbol names
|
||||
ULONG removeByMask(
|
||||
const std::string &moduleName,
|
||||
const std::string &symName
|
||||
);
|
||||
|
||||
// remove all synthetic symbols from all modules
|
||||
void clear();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Debug event callback manager API:
|
||||
|
||||
void restoreForModule(ULONG64 moduleBase);
|
||||
void restoreAll();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Module API:
|
||||
|
||||
ULONG64 getRvaByName(
|
||||
ULONG timeDataStamp,
|
||||
ULONG checkSumm,
|
||||
const std::string &symName
|
||||
);
|
||||
|
||||
public:
|
||||
|
||||
// unique module ID
|
||||
struct ModuleId {
|
||||
ULONG m_timeDataStamp;
|
||||
ULONG m_checkSumm;
|
||||
|
||||
ModuleId(ULONG timeDataStamp, ULONG checkSumm)
|
||||
: m_timeDataStamp(timeDataStamp)
|
||||
, m_checkSumm(checkSumm)
|
||||
{
|
||||
}
|
||||
|
||||
ModuleId(const DEBUG_MODULE_PARAMETERS &dbgModuleParameters)
|
||||
: m_timeDataStamp(dbgModuleParameters.TimeDateStamp)
|
||||
, m_checkSumm(dbgModuleParameters.Checksum)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const ModuleId &rhs) const
|
||||
{
|
||||
return
|
||||
m_timeDataStamp == rhs.m_timeDataStamp &&
|
||||
m_checkSumm == rhs.m_checkSumm;
|
||||
}
|
||||
bool operator < (const ModuleId &rhs) const
|
||||
{
|
||||
return
|
||||
m_timeDataStamp < rhs.m_timeDataStamp &&
|
||||
m_checkSumm < rhs.m_checkSumm;
|
||||
}
|
||||
};
|
||||
|
||||
// symbol data
|
||||
struct SymbolData {
|
||||
std::string m_name;
|
||||
ULONG m_size;
|
||||
};
|
||||
|
||||
// synthetic symbols of one module: offset -> name+size
|
||||
typedef ULONG64 SYM_OFFSET;
|
||||
typedef std::map<SYM_OFFSET, SymbolData> ModSymbols;
|
||||
|
||||
// synthetic symbols of all modules
|
||||
typedef std::map<ModuleId, ModSymbols> AllSymbols;
|
||||
|
||||
private:
|
||||
|
||||
// lock of static map
|
||||
typedef boost::shared_ptr<boost::recursive_mutex> SymbolsLock;
|
||||
typedef boost::recursive_mutex::scoped_lock SymbolsScopedLock;
|
||||
|
||||
private:
|
||||
|
||||
// execute for all symbols from modules
|
||||
void forEachFromModule(
|
||||
ULONG64 moduleBase,
|
||||
const ModSymbols &modSymbols,
|
||||
ISynSymForEach &forEach
|
||||
);
|
||||
|
||||
// execute for all symbols all loaded modules
|
||||
void forEachLoadedModule(ISynSymForEach &forEach);
|
||||
|
||||
private:
|
||||
|
||||
SymbolsLock m_allSymbolsLock;
|
||||
AllSymbols m_allSymbols;
|
||||
|
||||
DebugClient &m_dbgClient;
|
||||
IDebugSymbols3 &m_symbols;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef boost::shared_ptr<SyntheticSymbols> SynSymbolsPtr;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // namespace pykd
|
152
pykd/synsymhelpers.cpp
Normal file
152
pykd/synsymhelpers.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
|
||||
#include <stdafx.h>
|
||||
|
||||
#include "dbgexcept.h"
|
||||
#include "synsymhelpers.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SynSymHelper::removeSyntheticSymbols(
|
||||
const DEBUG_MODULE_AND_ID &dbgSymbols
|
||||
)
|
||||
{
|
||||
return SUCCEEDED(
|
||||
m_symbols.RemoveSyntheticSymbol(
|
||||
const_cast<DEBUG_MODULE_AND_ID *>(&dbgSymbols)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG SynSymHelper::removeSyntheticSymbols(
|
||||
const std::vector<DEBUG_MODULE_AND_ID> &arrSymbols
|
||||
)
|
||||
{
|
||||
ULONG countOfRemoved = 0;
|
||||
for (ULONG i = 0; i < arrSymbols.size(); ++i)
|
||||
{
|
||||
if (removeSyntheticSymbols(arrSymbols[i]))
|
||||
++countOfRemoved;
|
||||
}
|
||||
return countOfRemoved;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG SynSymHelper::removeSyntheticSymbols(ULONG64 addr)
|
||||
{
|
||||
ULONG entries = 0;
|
||||
m_symbols.GetSymbolEntriesByOffset(addr, 0, NULL, NULL, 0, &entries);
|
||||
if (!entries)
|
||||
return 0;
|
||||
|
||||
std::vector<DEBUG_MODULE_AND_ID> arrSymbols(entries);
|
||||
HRESULT hres = m_symbols.GetSymbolEntriesByOffset(
|
||||
addr,
|
||||
0,
|
||||
&arrSymbols[0],
|
||||
NULL,
|
||||
(ULONG)arrSymbols.size(),
|
||||
NULL);
|
||||
if (SUCCEEDED(hres))
|
||||
return removeSyntheticSymbols(arrSymbols);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SyntheticSymbols::ModuleId SynSymHelper::modByBase(ULONG64 moduleBase)
|
||||
{
|
||||
DEBUG_MODULE_PARAMETERS dbgModuleParameters;
|
||||
HRESULT hres =
|
||||
m_symbols.GetModuleParameters(
|
||||
1,
|
||||
&moduleBase,
|
||||
0,
|
||||
&dbgModuleParameters);
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException(buildExceptDesc("IDebugSymbols3::GetModuleParameters", hres));
|
||||
|
||||
return SyntheticSymbols::ModuleId(dbgModuleParameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SyntheticSymbols::ModuleId SynSymHelper::modByOffset(
|
||||
ULONG64 moduleOffset,
|
||||
ULONG64 &moduleBase
|
||||
)
|
||||
{
|
||||
HRESULT hres =
|
||||
m_symbols.GetModuleByOffset(moduleOffset, 0, NULL, &moduleBase);
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException(buildExceptDesc("IDebugSymbols3::GetModuleByOffset", hres));
|
||||
|
||||
return modByBase(moduleBase);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT SynSymHelper::getAllModules(
|
||||
std::vector<DEBUG_MODULE_PARAMETERS> &dbgModules
|
||||
)
|
||||
{
|
||||
ULONG nLoaded;
|
||||
ULONG nUnloaded;
|
||||
HRESULT hres = m_symbols.GetNumberModules(&nLoaded, &nUnloaded);
|
||||
if (FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if (!nLoaded && !nUnloaded)
|
||||
{
|
||||
dbgModules.clear();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
dbgModules.resize(nLoaded + nUnloaded);
|
||||
return
|
||||
m_symbols.GetModuleParameters(
|
||||
nLoaded + nUnloaded,
|
||||
NULL,
|
||||
0,
|
||||
&dbgModules[0]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT SynSymHelper::getSymbolsByMaks(
|
||||
const std::string &symMask,
|
||||
std::vector<DEBUG_MODULE_AND_ID> &dbgSymbols
|
||||
)
|
||||
{
|
||||
ULONG entries = 0;
|
||||
m_symbols.GetSymbolEntriesByName(
|
||||
symMask.c_str(),
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
&entries);
|
||||
if (!entries)
|
||||
{
|
||||
dbgSymbols.clear();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
dbgSymbols.resize(entries);
|
||||
|
||||
return
|
||||
m_symbols.GetSymbolEntriesByName(
|
||||
symMask.c_str(),
|
||||
0,
|
||||
&dbgSymbols[0],
|
||||
entries,
|
||||
NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // namespace pykd
|
107
pykd/synsymhelpers.h
Normal file
107
pykd/synsymhelpers.h
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// Synthetic symbol helpers
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "synsymbol.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SynSymHelper {
|
||||
public:
|
||||
SynSymHelper(IDebugSymbols3 &symbols) : m_symbols(symbols) {}
|
||||
|
||||
// remove array of synthetic symbols from debug engine
|
||||
bool removeSyntheticSymbols(
|
||||
const DEBUG_MODULE_AND_ID &dbgSymbols
|
||||
);
|
||||
ULONG removeSyntheticSymbols(
|
||||
const std::vector<DEBUG_MODULE_AND_ID> &arrSymbols
|
||||
);
|
||||
ULONG removeSyntheticSymbols(ULONG64 addr);
|
||||
|
||||
// buid ModuleId by base of image
|
||||
SyntheticSymbols::ModuleId modByBase(ULONG64 moduleBase);
|
||||
|
||||
// buid ModuleId by offset in image
|
||||
SyntheticSymbols::ModuleId modByOffset(
|
||||
ULONG64 moduleOffset,
|
||||
ULONG64 &moduleBase
|
||||
);
|
||||
|
||||
// get array of all modules
|
||||
HRESULT getAllModules(std::vector<DEBUG_MODULE_PARAMETERS> &dbgModules);
|
||||
|
||||
// get symbols by mask
|
||||
HRESULT getSymbolsByMaks(
|
||||
const std::string &symMask,
|
||||
std::vector<DEBUG_MODULE_AND_ID> &dbgSymbols
|
||||
);
|
||||
|
||||
protected:
|
||||
IDebugSymbols3 &m_symbols;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Enumerator all synthetic symbols for loaded modules
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
interface ISynSymForEach : public SynSymHelper {
|
||||
ISynSymForEach(IDebugSymbols3 &symbols) : SynSymHelper(symbols) {}
|
||||
|
||||
virtual void symbol(
|
||||
const ULONG64 moduleBase,
|
||||
SyntheticSymbols::SYM_OFFSET offset,
|
||||
const SyntheticSymbols::SymbolData &symData
|
||||
) = 0;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Remove symbols from loaded modules
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class SynSymRemoveAll : public ISynSymForEach
|
||||
{
|
||||
public:
|
||||
SynSymRemoveAll(IDebugSymbols3 &symbols) : ISynSymForEach(symbols) {}
|
||||
|
||||
virtual void symbol(
|
||||
const ULONG64 moduleBase,
|
||||
SyntheticSymbols::SYM_OFFSET offset,
|
||||
const SyntheticSymbols::SymbolData &/*symData*/
|
||||
) override
|
||||
{
|
||||
removeSyntheticSymbols(moduleBase + offset);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Restore symbols for loaded modules
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class SynSymRestore : public ISynSymForEach
|
||||
{
|
||||
public:
|
||||
SynSymRestore(IDebugSymbols3 &symbols) : ISynSymForEach(symbols) {}
|
||||
|
||||
virtual void symbol(
|
||||
const ULONG64 moduleBase,
|
||||
SyntheticSymbols::SYM_OFFSET offset,
|
||||
const SyntheticSymbols::SymbolData &symData
|
||||
) override
|
||||
{
|
||||
m_symbols.AddSyntheticSymbol(
|
||||
moduleBase + offset,
|
||||
symData.m_size,
|
||||
symData.m_name.c_str(),
|
||||
DEBUG_ADDSYNTHSYM_DEFAULT,
|
||||
NULL);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // namespace pykd
|
@ -22,6 +22,7 @@ import eventtest
|
||||
import typedvar
|
||||
import memtest
|
||||
import intbase
|
||||
import synsymtest
|
||||
|
||||
def getTestSuite( singleName = "" ):
|
||||
if singleName == "":
|
||||
@ -36,6 +37,7 @@ def getTestSuite( singleName = "" ):
|
||||
unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( intbase.IntBaseTest ),
|
||||
unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest )
|
||||
] )
|
||||
else:
|
||||
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
|
||||
@ -59,4 +61,4 @@ if __name__ == "__main__":
|
||||
|
||||
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )
|
||||
|
||||
#a = raw_input("\npress return\n")
|
||||
a = raw_input("\npress return\n")
|
68
test/scripts/synsymtest.py
Normal file
68
test/scripts/synsymtest.py
Normal file
@ -0,0 +1,68 @@
|
||||
"""Synthetic symbols tests"""
|
||||
|
||||
import unittest
|
||||
import target
|
||||
import pykd
|
||||
|
||||
class SynSymTest(unittest.TestCase):
|
||||
"""Unit tests of synthetic symbols"""
|
||||
|
||||
def testAdd(self):
|
||||
"""Add new synthetic symbol"""
|
||||
pykd.addSynSymbol(
|
||||
target.module.offset("FuncWithName0")-1, 1, "synSym1")
|
||||
self.assertEqual(
|
||||
target.module.offset("FuncWithName0")-1,
|
||||
target.module.offset("synSym1"))
|
||||
|
||||
def testDel(self):
|
||||
"""Remove synthetic symbol"""
|
||||
pykd.addSynSymbol(
|
||||
target.module.offset("FuncWithName0")-2, 1, "synSym2")
|
||||
self.assertEqual(
|
||||
pykd.delSynSymbol( target.module.offset("synSym2") ), 1 )
|
||||
|
||||
exceptionOccurred = True
|
||||
try:
|
||||
target.module.rva("synSym2")
|
||||
exceptionOccurred = False
|
||||
except pykd.BaseException:
|
||||
pass
|
||||
self.assertTrue(exceptionOccurred)
|
||||
|
||||
def testDelAll(self):
|
||||
"""Remove all synthetic symbols"""
|
||||
pykd.addSynSymbol(
|
||||
target.module.offset("FuncWithName0")-3, 1, "synSym3")
|
||||
pykd.delAllSynSymbols()
|
||||
|
||||
exceptionOccurred = True
|
||||
try:
|
||||
target.module.rva("synSym3")
|
||||
exceptionOccurred = False
|
||||
except pykd.BaseException:
|
||||
pass
|
||||
self.assertTrue(exceptionOccurred)
|
||||
|
||||
def testDelByMask(self):
|
||||
"""Remove synthetic symbol by mask"""
|
||||
pykd.addSynSymbol(
|
||||
target.module.offset("FuncWithName0")-4, 1, "synSym4")
|
||||
self.assertTrue( pykd.delSynSymbolsMask( "*", "synSym4" ) >= 1 )
|
||||
|
||||
exceptionOccurred = True
|
||||
try:
|
||||
target.module.rva("synSym4")
|
||||
exceptionOccurred = False
|
||||
except pykd.BaseException:
|
||||
pass
|
||||
self.assertTrue(exceptionOccurred)
|
||||
|
||||
def testReload(self):
|
||||
"""Restore synthetic symbols after reload module symbols"""
|
||||
pykd.addSynSymbol(
|
||||
target.module.offset("FuncWithName0")-5, 1, "synSym5")
|
||||
target.module.reload()
|
||||
self.assertEqual(
|
||||
target.module.offset("FuncWithName0")-5,
|
||||
target.module.offset("synSym5"))
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Version="9.00"
|
||||
Name="targetapp"
|
||||
ProjectGUID="{C6254E16-AB8E-41EE-887D-31458E93FC68}"
|
||||
RootNamespace="targetapp"
|
||||
@ -440,6 +440,10 @@
|
||||
RelativePath="..\scripts\regtest.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\synsymtest.py"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\scripts\target.py"
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user