mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 19:53:22 +08:00
[+] pyDia: findByRva for global scope
git-svn-id: https://pykd.svn.codeplex.com/svn@69976 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
2d40f6c38a
commit
910849825e
@ -174,7 +174,10 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def("__getitem__", &pyDia::Symbol::getChildByIndex);
|
||||
|
||||
python::class_<pyDia::GlobalScope, python::bases<pyDia::Symbol> >("DiaScope", "class wrapper for MS DIA Symbol" )
|
||||
.def("machineType", &pyDia::GlobalScope::getMachineType, "Retrieves the type of the target CPU: IMAGE_FILE_MACHINE_XXX");
|
||||
.def("machineType", &pyDia::GlobalScope::getMachineType,
|
||||
"Retrieves the type of the target CPU: IMAGE_FILE_MACHINE_XXX")
|
||||
.def("findByRva", &pyDia::GlobalScope::findByRva,
|
||||
"Find symbol by RVA. Return tuple: (DiaSymbol, offset)");
|
||||
|
||||
// CPU type:
|
||||
DEF_PY_CONST_ULONG(IMAGE_FILE_MACHINE_I386);
|
||||
|
299
pykd/diaprint.cpp
Normal file
299
pykd/diaprint.cpp
Normal file
@ -0,0 +1,299 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "diawrapper.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace pyDia {
|
||||
|
||||
static void printVariant(
|
||||
__in const VARIANT &vtValue,
|
||||
__out std::stringstream &sstream
|
||||
)
|
||||
{
|
||||
switch (vtValue.vt)
|
||||
{
|
||||
case VT_I1:
|
||||
case VT_UI1:
|
||||
sstream << ", Value: ";
|
||||
sstream << "0x" << std::hex << vtValue.bVal;
|
||||
break;
|
||||
|
||||
case VT_BOOL:
|
||||
sstream << ", Value: ";
|
||||
sstream << vtValue.iVal ? "True" : "False";
|
||||
break;
|
||||
|
||||
case VT_I2:
|
||||
case VT_UI2:
|
||||
sstream << ", Value: ";
|
||||
sstream << "0x" << std::hex << vtValue.iVal;
|
||||
break;
|
||||
|
||||
case VT_I4:
|
||||
case VT_UI4:
|
||||
case VT_INT:
|
||||
case VT_UINT:
|
||||
case VT_ERROR:
|
||||
case VT_HRESULT:
|
||||
sstream << ", Value: ";
|
||||
sstream << "0x" << std::hex << vtValue.lVal;
|
||||
break;
|
||||
|
||||
case VT_I8:
|
||||
case VT_UI8:
|
||||
sstream << ", Value: ";
|
||||
sstream << "0x" << std::hex << vtValue.llVal;
|
||||
break;
|
||||
|
||||
case VT_R4:
|
||||
sstream << ", Value: ";
|
||||
sstream << vtValue.fltVal;
|
||||
break;
|
||||
|
||||
case VT_R8:
|
||||
sstream << ", Value: ";
|
||||
sstream << vtValue.dblVal;
|
||||
break;
|
||||
|
||||
case VT_BSTR:
|
||||
sstream << ", Value: ";
|
||||
sstream << "\"" << autoBstr::asStr(vtValue.bstrVal).c_str() << "\"";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string Symbol::printImpl(
|
||||
IDiaSymbol *_symbol,
|
||||
DWORD machineType,
|
||||
ULONG indent /*= 0*/,
|
||||
Symbol::checkSymLoop *checkLoopPrev /*= NULL*/,
|
||||
const char *prefix /*= NULL*/
|
||||
)
|
||||
{
|
||||
assert(_symbol);
|
||||
|
||||
std::stringstream sstream;
|
||||
for (ULONG i =0; i < indent; ++i)
|
||||
sstream << " ";
|
||||
if (prefix)
|
||||
sstream << prefix;
|
||||
|
||||
checkSymLoop _loop(checkLoopPrev, _symbol);
|
||||
if (_loop.check())
|
||||
{
|
||||
sstream << "<...see above...>";
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
DWORD dwValue;
|
||||
autoBstr bstrValue;
|
||||
VARIANT vtValue = { VT_EMPTY };
|
||||
bool bValue;
|
||||
LONG lValue;
|
||||
ULONGLONG ullValue;
|
||||
HRESULT hres;
|
||||
|
||||
DWORD locType = LocIsNull;
|
||||
hres = _symbol->get_locationType(&locType);
|
||||
bool bLocation = (S_OK == hres);
|
||||
if (bLocation)
|
||||
{
|
||||
hres = _symbol->get_offset(&lValue);
|
||||
const bool bNegOffset = lValue < 0;
|
||||
lValue = bNegOffset ? -1 * lValue : lValue;
|
||||
|
||||
switch (locType)
|
||||
{
|
||||
case LocIsBitField:
|
||||
case LocIsThisRel:
|
||||
assert(S_OK == hres);
|
||||
sstream << (bNegOffset ? "-" : "+") << "0x" << std::hex << lValue;
|
||||
if (LocIsBitField == locType)
|
||||
{
|
||||
hres = _symbol->get_bitPosition(&dwValue);
|
||||
if (S_OK == hres)
|
||||
sstream << ", Bit position: " << dwValue;
|
||||
}
|
||||
break;
|
||||
|
||||
case LocIsEnregistered:
|
||||
case LocIsRegRel:
|
||||
hres = _symbol->get_registerId(&dwValue);
|
||||
if (S_OK == hres)
|
||||
{
|
||||
const char *regName = NULL;
|
||||
if (IMAGE_FILE_MACHINE_I386 == machineType)
|
||||
{
|
||||
for (ULONG i = 0; i < cntI386RegName; ++i)
|
||||
{
|
||||
if (dwValue == i386RegName[i].first)
|
||||
{
|
||||
regName = i386RegName[i].second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IMAGE_FILE_MACHINE_AMD64 == machineType)
|
||||
{
|
||||
for (ULONG i = 0; i < cntI386RegName; ++i)
|
||||
{
|
||||
if (dwValue == i386RegName[i].first)
|
||||
{
|
||||
regName = i386RegName[i].second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!regName)
|
||||
{
|
||||
sstream << locTypeName[locType].second;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LocIsEnregistered == locType)
|
||||
{
|
||||
sstream << regName;
|
||||
}
|
||||
else
|
||||
{
|
||||
sstream << "[" << regName;
|
||||
sstream << (bNegOffset ? "-" : "+") << "0x" << std::hex << lValue;
|
||||
sstream << "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sstream << locTypeName[locType].second;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (S_OK == _symbol->get_relativeVirtualAddress(&dwValue))
|
||||
sstream << "RVA:0x" << std::hex << dwValue;
|
||||
else if (locType < _countof(locTypeName))
|
||||
sstream << "Location: " << locTypeName[locType].second;
|
||||
if (S_OK == hres)
|
||||
{
|
||||
sstream << ", Offset: ";
|
||||
sstream << (bNegOffset ? "-" : "+") << "0x" << std::hex << lValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool bFuncDebugRange = false;
|
||||
|
||||
hres = _symbol->get_symTag(&dwValue);
|
||||
if ((S_OK == hres) && dwValue < _countof(symTagName))
|
||||
{
|
||||
if (bLocation)
|
||||
sstream << ", ";
|
||||
|
||||
sstream << symTagName[dwValue].second;
|
||||
if (SymTagUDT == symTagName[dwValue].first)
|
||||
{
|
||||
hres = _symbol->get_udtKind(&dwValue);
|
||||
if ((S_OK == hres) && (dwValue < cntUdtKindName))
|
||||
sstream << ": " << udtKindName[dwValue].second;
|
||||
}
|
||||
|
||||
bFuncDebugRange =
|
||||
(SymTagFuncDebugStart == symTagName[dwValue].first) ||
|
||||
(SymTagFuncDebugEnd == symTagName[dwValue].first);
|
||||
}
|
||||
else
|
||||
{
|
||||
sstream << "!invalid symTag!";
|
||||
}
|
||||
sstream << ", ";
|
||||
|
||||
hres = _symbol->get_name(&bstrValue);
|
||||
if (S_OK == hres)
|
||||
sstream << "\"" << bstrValue.asStr().c_str() << "\"";
|
||||
else
|
||||
sstream << "<no-name>";
|
||||
bstrValue.free();
|
||||
|
||||
hres = _symbol->get_length(&ullValue);
|
||||
if (S_OK == hres)
|
||||
sstream << ", Length: 0x" << std::hex << ullValue;
|
||||
|
||||
bValue = false;
|
||||
try
|
||||
{
|
||||
getValueImpl(_symbol, vtValue);
|
||||
bValue = true;
|
||||
}
|
||||
catch (const Exception &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
}
|
||||
if (bValue)
|
||||
printVariant(vtValue, sstream);
|
||||
|
||||
hres = _symbol->get_baseType(&dwValue);
|
||||
if (SUCCEEDED(hres) && btNoType != dwValue)
|
||||
{
|
||||
for (ULONG i = 0; i < cntBasicTypeName; ++i)
|
||||
{
|
||||
if (basicTypeName[i].first == dwValue)
|
||||
{
|
||||
sstream << ", Basic type: " << basicTypeName[i].second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DiaSymbolPtr pType;
|
||||
hres = _symbol->get_type(&pType);
|
||||
if (S_OK == hres)
|
||||
{
|
||||
sstream << std::endl;
|
||||
sstream << printImpl(pType, machineType, indent+1, &_loop, "Type: ").c_str();
|
||||
}
|
||||
|
||||
if (bFuncDebugRange)
|
||||
return sstream.str();
|
||||
|
||||
DiaEnumSymbolsPtr symbols;
|
||||
hres =
|
||||
_symbol->findChildren(
|
||||
SymTagNull,
|
||||
NULL,
|
||||
nsCaseSensitive,
|
||||
&symbols);
|
||||
if (S_OK == hres)
|
||||
{
|
||||
if (indent <= 2)
|
||||
{
|
||||
DiaSymbolPtr child;
|
||||
ULONG celt;
|
||||
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
|
||||
{
|
||||
sstream << std::endl;
|
||||
sstream << printImpl(child, machineType, indent + 1, &_loop).c_str();
|
||||
child.Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lValue = 0;
|
||||
symbols->get_Count(&lValue);
|
||||
if (lValue)
|
||||
{
|
||||
sstream << std::endl;
|
||||
for (ULONG i =0; i < indent+1; ++i)
|
||||
sstream << " ";
|
||||
sstream << "<...>";
|
||||
}
|
||||
}
|
||||
}
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
@ -65,8 +65,6 @@ std::list< Symbol > Symbol::findChildrenImpl(
|
||||
DWORD nameCmpFlags
|
||||
)
|
||||
{
|
||||
throwIfNull(__FUNCTION__);
|
||||
|
||||
DiaEnumSymbolsPtr symbols;
|
||||
HRESULT hres =
|
||||
m_symbol->findChildren(
|
||||
@ -147,9 +145,6 @@ LONG Symbol::getOffset()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Symbol::getValueImpl(IDiaSymbol *_symbol, VARIANT &vtValue)
|
||||
{
|
||||
if (!_symbol)
|
||||
throw Exception(std::string(__FUNCTION__) + " failed, DIA object is not initialized");
|
||||
|
||||
HRESULT hres = _symbol->get_value(&vtValue);
|
||||
if (S_OK != hres)
|
||||
throw Exception("Call IDiaSymbol::get_value", hres);
|
||||
@ -203,8 +198,6 @@ python::object Symbol::getValue()
|
||||
|
||||
bool Symbol::isBasicType()
|
||||
{
|
||||
throwIfNull(__FUNCTION__);
|
||||
|
||||
DWORD baseType = btNoType;
|
||||
return
|
||||
SUCCEEDED( m_symbol->get_baseType(&baseType) ) &&
|
||||
@ -250,8 +243,6 @@ ULONG Symbol::getRegisterId()
|
||||
|
||||
Symbol Symbol::getChildByName(const std::string &_name)
|
||||
{
|
||||
throwIfNull(__FUNCTION__);
|
||||
|
||||
DiaEnumSymbolsPtr symbols;
|
||||
HRESULT hres =
|
||||
m_symbol->findChildren(
|
||||
@ -285,8 +276,6 @@ Symbol Symbol::getChildByName(const std::string &_name)
|
||||
|
||||
ULONG Symbol::getChildCount()
|
||||
{
|
||||
throwIfNull(__FUNCTION__);
|
||||
|
||||
DiaEnumSymbolsPtr symbols;
|
||||
HRESULT hres =
|
||||
m_symbol->findChildren(
|
||||
@ -309,8 +298,6 @@ ULONG Symbol::getChildCount()
|
||||
|
||||
Symbol Symbol::getChildByIndex(ULONG _index)
|
||||
{
|
||||
throwIfNull(__FUNCTION__);
|
||||
|
||||
DiaEnumSymbolsPtr symbols;
|
||||
HRESULT hres =
|
||||
m_symbol->findChildren(
|
||||
@ -349,280 +336,6 @@ std::string Symbol::print()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string Symbol::printImpl(IDiaSymbol *_symbol, DWORD machineType, ULONG indent /*= 0*/)
|
||||
{
|
||||
std::stringstream sstream;
|
||||
for (ULONG i =0; i < indent; ++i)
|
||||
sstream << " ";
|
||||
if (_symbol)
|
||||
{
|
||||
DWORD dwValue;
|
||||
autoBstr bstrValue;
|
||||
VARIANT vtValue = { VT_EMPTY };
|
||||
bool bValue;
|
||||
LONG lValue;
|
||||
ULONGLONG ullValue;
|
||||
HRESULT hres;
|
||||
|
||||
DWORD locType = LocIsNull;
|
||||
hres = _symbol->get_locationType(&locType);
|
||||
bool bLocation = (S_OK == hres);
|
||||
if (bLocation)
|
||||
{
|
||||
hres = _symbol->get_offset(&lValue);
|
||||
|
||||
const bool bNegOffset = lValue < 0;
|
||||
lValue = bNegOffset ? -1 * lValue : lValue;
|
||||
|
||||
switch (locType)
|
||||
{
|
||||
case LocIsBitField:
|
||||
case LocIsThisRel:
|
||||
assert(S_OK == hres);
|
||||
sstream << (bNegOffset ? "-" : "+") << "0x" << std::hex << lValue;
|
||||
if (LocIsBitField == locType)
|
||||
{
|
||||
hres = _symbol->get_bitPosition(&dwValue);
|
||||
if (S_OK == hres)
|
||||
sstream << ", Bit position: " << dwValue;
|
||||
}
|
||||
break;
|
||||
|
||||
case LocIsEnregistered:
|
||||
case LocIsRegRel:
|
||||
hres = _symbol->get_registerId(&dwValue);
|
||||
if (S_OK == hres)
|
||||
{
|
||||
const char *regName = NULL;
|
||||
if (IMAGE_FILE_MACHINE_I386 == machineType)
|
||||
{
|
||||
for (ULONG i = 0; i < cntI386RegName; ++i)
|
||||
{
|
||||
if (dwValue == i386RegName[i].first)
|
||||
{
|
||||
regName = i386RegName[i].second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IMAGE_FILE_MACHINE_AMD64 == machineType)
|
||||
{
|
||||
for (ULONG i = 0; i < cntI386RegName; ++i)
|
||||
{
|
||||
if (dwValue == i386RegName[i].first)
|
||||
{
|
||||
regName = i386RegName[i].second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!regName)
|
||||
{
|
||||
sstream << locTypeName[locType].second;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LocIsEnregistered == locType)
|
||||
{
|
||||
sstream << regName;
|
||||
}
|
||||
else
|
||||
{
|
||||
sstream << "[" << regName;
|
||||
sstream << (bNegOffset ? "-" : "+") << "0x" << std::hex << lValue;
|
||||
sstream << "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sstream << locTypeName[locType].second;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (S_OK == _symbol->get_relativeVirtualAddress(&dwValue))
|
||||
sstream << "RVA:0x" << std::hex << dwValue;
|
||||
else if (locType < _countof(locTypeName))
|
||||
sstream << "Location: " << locTypeName[locType].second;
|
||||
if (S_OK == hres)
|
||||
{
|
||||
sstream << ", Offset: ";
|
||||
sstream << (bNegOffset ? "-" : "+") << "0x" << std::hex << lValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hres = _symbol->get_symTag(&dwValue);
|
||||
if ((S_OK == hres) && dwValue < _countof(symTagName))
|
||||
{
|
||||
if (bLocation)
|
||||
sstream << ", ";
|
||||
|
||||
sstream << symTagName[dwValue].second;
|
||||
if (SymTagUDT == symTagName[dwValue].first)
|
||||
{
|
||||
hres = _symbol->get_udtKind(&dwValue);
|
||||
if ((S_OK == hres) && (dwValue < cntUdtKindName))
|
||||
sstream << ": " << udtKindName[dwValue].second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sstream << "!invalid symTag!";
|
||||
}
|
||||
sstream << ", ";
|
||||
|
||||
hres = _symbol->get_name(&bstrValue);
|
||||
if (S_OK == hres)
|
||||
sstream << "\"" << bstrValue.asStr().c_str() << "\"";
|
||||
else
|
||||
sstream << "<no-name>";
|
||||
bstrValue.free();
|
||||
|
||||
hres = _symbol->get_length(&ullValue);
|
||||
if (S_OK == hres)
|
||||
sstream << ", Length: 0x" << std::hex << ullValue;
|
||||
|
||||
bValue = false;
|
||||
try
|
||||
{
|
||||
getValueImpl(_symbol, vtValue);
|
||||
bValue = true;
|
||||
}
|
||||
catch (const Exception &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
}
|
||||
if (bValue)
|
||||
{
|
||||
switch (vtValue.vt)
|
||||
{
|
||||
case VT_I1:
|
||||
case VT_UI1:
|
||||
sstream << ", Value: ";
|
||||
sstream << "0x" << std::hex << vtValue.bVal;
|
||||
break;
|
||||
|
||||
case VT_BOOL:
|
||||
sstream << ", Value: ";
|
||||
sstream << vtValue.iVal ? "True" : "False";
|
||||
break;
|
||||
|
||||
case VT_I2:
|
||||
case VT_UI2:
|
||||
sstream << ", Value: ";
|
||||
sstream << "0x" << std::hex << vtValue.iVal;
|
||||
break;
|
||||
|
||||
case VT_I4:
|
||||
case VT_UI4:
|
||||
case VT_INT:
|
||||
case VT_UINT:
|
||||
case VT_ERROR:
|
||||
case VT_HRESULT:
|
||||
sstream << ", Value: ";
|
||||
sstream << "0x" << std::hex << vtValue.lVal;
|
||||
break;
|
||||
|
||||
case VT_I8:
|
||||
case VT_UI8:
|
||||
sstream << ", Value: ";
|
||||
sstream << "0x" << std::hex << vtValue.llVal;
|
||||
break;
|
||||
|
||||
case VT_R4:
|
||||
sstream << ", Value: ";
|
||||
sstream << vtValue.fltVal;
|
||||
break;
|
||||
|
||||
case VT_R8:
|
||||
sstream << ", Value: ";
|
||||
sstream << vtValue.dblVal;
|
||||
break;
|
||||
|
||||
case VT_BSTR:
|
||||
sstream << ", Value: ";
|
||||
sstream << "\"" << autoBstr::asStr(vtValue.bstrVal).c_str() << "\"";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hres = _symbol->get_baseType(&dwValue);
|
||||
if (SUCCEEDED(hres) && btNoType != dwValue)
|
||||
{
|
||||
for (ULONG i = 0; i < cntBasicTypeName; ++i)
|
||||
{
|
||||
if (basicTypeName[i].first == dwValue)
|
||||
{
|
||||
sstream << ", Basic type: " << basicTypeName[i].second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwThisSymbol = 0;
|
||||
hres = _symbol->get_symIndexId(&dwThisSymbol);
|
||||
assert(S_OK == hres);
|
||||
if (S_OK == hres)
|
||||
{
|
||||
DiaSymbolPtr pType;
|
||||
hres = _symbol->get_type(&pType);
|
||||
if (S_OK == hres)
|
||||
{
|
||||
DWORD dwTypeSymbol;
|
||||
hres = pType->get_symIndexId(&dwTypeSymbol);
|
||||
if ((S_OK == hres) && (dwTypeSymbol != dwThisSymbol))
|
||||
{
|
||||
sstream << std::endl;
|
||||
for (ULONG i =0; i < indent; ++i)
|
||||
sstream << " ";
|
||||
sstream << "Type: " << std::endl;
|
||||
sstream << printImpl(pType, machineType, indent + 1).c_str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DiaEnumSymbolsPtr symbols;
|
||||
hres =
|
||||
_symbol->findChildren(
|
||||
SymTagNull,
|
||||
NULL,
|
||||
nsCaseSensitive,
|
||||
&symbols);
|
||||
if (S_OK == hres)
|
||||
{
|
||||
if (indent <= 2)
|
||||
{
|
||||
DiaSymbolPtr child;
|
||||
ULONG celt;
|
||||
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
|
||||
{
|
||||
sstream << std::endl << printImpl(child, machineType, indent + 1).c_str();
|
||||
child.Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lValue = 0;
|
||||
symbols->get_Count(&lValue);
|
||||
if (lValue)
|
||||
{
|
||||
sstream << std::endl;
|
||||
for (ULONG i =0; i < indent+1; ++i)
|
||||
sstream << " ";
|
||||
sstream << "<...>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GlobalScope::GlobalScope(
|
||||
__inout DiaDataSourcePtr &_scope,
|
||||
__inout DiaSessionPtr &_session,
|
||||
@ -664,4 +377,27 @@ GlobalScope GlobalScope::openPdb(const std::string &filePath)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Symbol GlobalScope::findByRvaImpl(
|
||||
__in ULONG rva,
|
||||
__in ULONG symTag,
|
||||
__out LONG &displacement
|
||||
)
|
||||
{
|
||||
DiaSymbolPtr child;
|
||||
HRESULT hres =
|
||||
m_session->findSymbolByRVAEx(
|
||||
rva,
|
||||
static_cast<enum SymTagEnum>(symTag),
|
||||
&child,
|
||||
&displacement);
|
||||
if (S_OK != hres)
|
||||
throw Exception("Call IDiaSession::findSymbolByRVAEx", hres);
|
||||
if (!child)
|
||||
throw Exception("Call IDiaSession::findSymbolByRVAEx", E_UNEXPECTED);
|
||||
|
||||
return Symbol( child, m_machineType );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
@ -56,7 +56,10 @@ private:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class Symbol {
|
||||
public:
|
||||
Symbol() {}
|
||||
Symbol()
|
||||
{
|
||||
throw Exception("DiaSymbol must be created over factory from DiaScope::...");
|
||||
}
|
||||
|
||||
std::list< Symbol > findChildrenImpl(
|
||||
ULONG symTag,
|
||||
@ -138,7 +141,42 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
static std::string printImpl(IDiaSymbol *_symbol, DWORD machineType, ULONG indent = 0);
|
||||
// Check symbols loop
|
||||
class checkSymLoop
|
||||
{
|
||||
public:
|
||||
checkSymLoop(checkSymLoop *prev, IDiaSymbol *_symbol)
|
||||
: m_prev(prev)
|
||||
, m_symIndexId(0)
|
||||
{
|
||||
_symbol->get_symIndexId(&m_symIndexId);
|
||||
}
|
||||
|
||||
bool check() const
|
||||
{
|
||||
const checkSymLoop *prev = m_prev;
|
||||
while (prev)
|
||||
{
|
||||
if (prev->m_symIndexId == m_symIndexId)
|
||||
return true;
|
||||
prev = prev->m_prev;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
const checkSymLoop *m_prev;
|
||||
DWORD m_symIndexId;
|
||||
};
|
||||
|
||||
static std::string printImpl(
|
||||
IDiaSymbol *_symbol,
|
||||
DWORD machineType,
|
||||
ULONG indent = 0,
|
||||
checkSymLoop *checkLoopPrev = NULL,
|
||||
const char *prefix = NULL
|
||||
);
|
||||
|
||||
template <typename TRet>
|
||||
TRet callSymbolT(
|
||||
@ -147,8 +185,6 @@ protected:
|
||||
const char *methodName
|
||||
)
|
||||
{
|
||||
throwIfNull(funcName);
|
||||
|
||||
TRet retValue;
|
||||
HRESULT hres = (m_symbol->*method)(&retValue);
|
||||
if (S_OK != hres)
|
||||
@ -157,12 +193,6 @@ protected:
|
||||
return retValue;
|
||||
}
|
||||
|
||||
void throwIfNull(const char *desc)
|
||||
{
|
||||
if (!m_symbol)
|
||||
throw Exception(std::string(desc) + " failed, DIA object is not initialized");
|
||||
}
|
||||
|
||||
Symbol(__inout DiaSymbolPtr &_symbol, DWORD machineType)
|
||||
: m_machineType(machineType)
|
||||
{
|
||||
@ -186,13 +216,30 @@ class GlobalScope : public Symbol {
|
||||
public:
|
||||
GlobalScope() {}
|
||||
|
||||
// create GlobalScope instance
|
||||
// GlobalScope factory
|
||||
static GlobalScope openPdb(const std::string &filePath);
|
||||
|
||||
ULONG getMachineType() const {
|
||||
return m_machineType;
|
||||
}
|
||||
|
||||
// RVA -> Symbol
|
||||
python::tuple findByRva(
|
||||
ULONG rva,
|
||||
ULONG symTag
|
||||
)
|
||||
{
|
||||
LONG displacement;
|
||||
Symbol child = findByRvaImpl(rva, symTag, displacement);
|
||||
return python::make_tuple(child, displacement);
|
||||
}
|
||||
Symbol findByRvaImpl(
|
||||
__in ULONG rva,
|
||||
__in ULONG symTag,
|
||||
__out LONG &displacement
|
||||
);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
GlobalScope(
|
||||
|
@ -369,6 +369,10 @@
|
||||
RelativePath=".\diadata.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\diaprint.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\diawrapper.cpp"
|
||||
>
|
||||
|
@ -104,3 +104,16 @@ class DiaTest( unittest.TestCase ):
|
||||
gScope = pykd.diaOpenPdb( str(target.module.pdb()) )
|
||||
self.assertTrue( (gScope.machineType() == pykd.IMAGE_FILE_MACHINE_I386) or
|
||||
(gScope.machineType() == pykd.IMAGE_FILE_MACHINE_AMD64) )
|
||||
|
||||
def testFindByRva(self):
|
||||
gScope = pykd.diaOpenPdb( str(target.module.pdb()) )
|
||||
func = gScope["FuncWithName0"]
|
||||
|
||||
tplSymOffset = gScope.findByRva(func.rva(), pykd.SymTagFunction)
|
||||
self.assertEqual(tplSymOffset[0].indexId(), func.indexId())
|
||||
self.assertEqual(tplSymOffset[1], 0)
|
||||
|
||||
tplSymOffset = gScope.findByRva(func.rva() + 2, pykd.SymTagFunction)
|
||||
self.assertEqual(tplSymOffset[0].indexId(), func.indexId())
|
||||
self.assertEqual(tplSymOffset[1], 2)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user