mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 19:53:22 +08:00
315 lines
9.0 KiB
C++
315 lines
9.0 KiB
C++
#pragma once
|
|
|
|
|
|
#include "boost/python/object.hpp"
|
|
#include "boost/python/wrapper.hpp"
|
|
|
|
#include "kdlib/dataaccessor.h"
|
|
#include "kdlib/exceptions.h"
|
|
|
|
#include "pythreadstate.h"
|
|
|
|
namespace python = boost::python;
|
|
|
|
namespace pykd {
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
using kdlib::ImplementException;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class PythonObjectAccessor : public kdlib::DataAccessor
|
|
{
|
|
|
|
public:
|
|
|
|
PythonObjectAccessor(python::object& obj, size_t pos = 0) : m_object(obj)
|
|
{
|
|
m_pystate = PyThreadState_Get();
|
|
m_startPos = pos;
|
|
}
|
|
|
|
public:
|
|
|
|
virtual size_t getLength() const {
|
|
AutoSavePythonState pystate(&m_pystate);
|
|
return python::len(m_object);
|
|
}
|
|
|
|
virtual unsigned char readByte(size_t pos=0) const {
|
|
return readValue<unsigned char>(pos);
|
|
}
|
|
|
|
virtual void writeByte(unsigned char value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual char readSignByte(size_t pos=0) const {
|
|
return readValue<char>(pos);
|
|
}
|
|
|
|
virtual void writeSignByte(char value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual unsigned short readWord(size_t pos=0) const {
|
|
return readValue<unsigned short>(pos);
|
|
}
|
|
|
|
virtual void writeWord(unsigned short value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual short readSignWord(size_t pos=0) const {
|
|
return readValue<short>(pos);
|
|
}
|
|
|
|
virtual void writeSignWord(short value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual unsigned long readDWord(size_t pos=0) const {
|
|
return readValue<unsigned long>(pos);
|
|
}
|
|
|
|
virtual void writeDWord(unsigned long value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual long readSignDWord(size_t pos=0) const {
|
|
return readValue<long>(pos);
|
|
}
|
|
|
|
virtual void writeSignDWord(long value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual unsigned long long readQWord(size_t pos=0) const {
|
|
return readValue<unsigned long long>(pos);
|
|
}
|
|
|
|
virtual void writeQWord(unsigned long long value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual long long readSignQWord(size_t pos=0) const {
|
|
return readValue<long long>(pos);
|
|
}
|
|
|
|
virtual void writeSignQWord(long long value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual float readFloat(size_t pos=0) const {
|
|
return readValue<float>(pos);
|
|
}
|
|
|
|
virtual void writeFloat(float value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual double readDouble(size_t pos=0) const {
|
|
return readValue<double>(pos);
|
|
}
|
|
|
|
virtual void writeDouble(double value, size_t pos=0) {
|
|
writeValue(value,pos);
|
|
}
|
|
|
|
virtual void readBytes( std::vector<unsigned char>& dataRange, size_t count, size_t pos=0) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeBytes( const std::vector<unsigned char>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange,pos);
|
|
}
|
|
|
|
void readWords( std::vector<unsigned short>& dataRange, size_t count, size_t pos) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeWords( const std::vector<unsigned short>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange,pos);
|
|
}
|
|
|
|
virtual void readDWords( std::vector<unsigned long>& dataRange, size_t count, size_t pos=0) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeDWords( const std::vector<unsigned long>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange,pos);
|
|
}
|
|
|
|
virtual void readQWords( std::vector<unsigned long long>& dataRange, size_t count, size_t pos=0) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeQWords( const std::vector<unsigned long long>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange,pos);
|
|
}
|
|
|
|
virtual void readSignBytes( std::vector<char>& dataRange, size_t count, size_t pos=0) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeSignBytes( const std::vector<char>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange,pos);
|
|
}
|
|
|
|
virtual void readSignWords( std::vector<short>& dataRange, size_t count, size_t pos=0) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeSignWords( const std::vector<short>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange,pos);
|
|
}
|
|
|
|
virtual void readSignDWords( std::vector<long>& dataRange, size_t count, size_t pos=0) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeSignDWords( const std::vector<long>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange, pos);
|
|
}
|
|
|
|
virtual void readSignQWords( std::vector<long long>& dataRange, size_t count, size_t pos=0) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeSignQWords( const std::vector<long long>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange,pos);
|
|
}
|
|
|
|
virtual void readFloats( std::vector<float>& dataRange, size_t count, size_t pos=0) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeFloats( const std::vector<float>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange, pos);
|
|
}
|
|
|
|
virtual void readDoubles( std::vector<double>& dataRange, size_t count, size_t pos=0) const {
|
|
readValues(dataRange, count, pos);
|
|
}
|
|
|
|
virtual void writeDoubles( const std::vector<double>& dataRange, size_t pos=0) {
|
|
writeValues(dataRange, pos);
|
|
}
|
|
|
|
virtual kdlib::DataAccessorPtr copy( size_t startOffset = 0, size_t length = 0 ) {
|
|
AutoSavePythonState pystate(&m_pystate);
|
|
return kdlib::DataAccessorPtr( new PythonObjectAccessor(m_object, startOffset) );
|
|
}
|
|
|
|
virtual std::wstring getLocationAsStr() const {
|
|
return L"python byte sequance";
|
|
}
|
|
|
|
virtual kdlib::MEMOFFSET_64 getAddress() const {
|
|
throw kdlib::DbgException("python accessor error");
|
|
}
|
|
|
|
virtual kdlib::VarStorage getStorageType() const {
|
|
throw kdlib::DbgException("python accessor error");
|
|
}
|
|
|
|
virtual std::wstring getRegisterName() const {
|
|
throw kdlib::DbgException("python accessor error");
|
|
}
|
|
|
|
private:
|
|
|
|
python::object m_object;
|
|
|
|
mutable PyThreadState* m_pystate;
|
|
|
|
size_t m_startPos;
|
|
|
|
template<typename T>
|
|
T readValue(size_t pos) const
|
|
{
|
|
AutoSavePythonState pystate(&m_pystate);
|
|
try
|
|
{
|
|
return readValueUnsafe<T>(pos);
|
|
}
|
|
catch( python::error_already_set const & )
|
|
{}
|
|
|
|
throw kdlib::DbgException("python accessor error");
|
|
}
|
|
|
|
template<typename T>
|
|
T readValueUnsafe(size_t pos) const
|
|
{
|
|
unsigned long long value = 0;
|
|
for ( size_t i = sizeof(T); i > 0; --i)
|
|
value = ( value << 8 ) + python::extract<unsigned char>(m_object[m_startPos + pos*sizeof(T) + i - 1])();
|
|
|
|
return *reinterpret_cast<T*>(&value);
|
|
}
|
|
|
|
template<typename T>
|
|
void writeValue(T value, size_t pos)
|
|
{
|
|
AutoSavePythonState pystate(&m_pystate);
|
|
try
|
|
{
|
|
writeValueUnsafe(value,pos);
|
|
return;
|
|
}
|
|
catch( python::error_already_set const & )
|
|
{}
|
|
|
|
throw kdlib::DbgException("python accessor error");
|
|
}
|
|
|
|
template<typename T>
|
|
void writeValueUnsafe(T value, size_t pos)
|
|
{
|
|
unsigned long long val = *reinterpret_cast<unsigned long long*>(&value);
|
|
for ( size_t i = 0; i < sizeof(T); ++i )
|
|
m_object[m_startPos + pos*sizeof(T) + i] = static_cast<unsigned char>( ( val >> (8*i)) & 0xFF );
|
|
}
|
|
|
|
template<typename T>
|
|
void readValues( std::vector<T>& dataRange, size_t count, size_t pos) const
|
|
{
|
|
AutoSavePythonState pystate(&m_pystate);
|
|
try
|
|
{
|
|
dataRange.resize(count);
|
|
for ( size_t i = 0; i < count; ++i )
|
|
dataRange[i] = readValueUnsafe<T>(pos + i);
|
|
return;
|
|
}
|
|
catch( python::error_already_set const & )
|
|
{}
|
|
|
|
throw kdlib::DbgException("python accessor error");
|
|
}
|
|
|
|
template<typename T>
|
|
void writeValues( const std::vector<T>& dataRange, size_t pos)
|
|
{
|
|
AutoSavePythonState pystate(&m_pystate);
|
|
try
|
|
{
|
|
for ( size_t i = 0; i < dataRange.size(); ++i )
|
|
writeValueUnsafe(dataRange[i], pos + i );
|
|
return;
|
|
}
|
|
catch( python::error_already_set const & )
|
|
{}
|
|
|
|
throw kdlib::DbgException("python accessor error");
|
|
}
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
}
|