From f5ee8b9a9ae6f3771c9fe7c991b7124025956045 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Wed, 30 Jan 2013 06:41:09 +0000
Subject: [PATCH] [0.2.x] added : disasm::findOffset method ( Return the
 location of a processor instruction relative to a given location ) [0.2.x]
 added : disasm::jump method ( Change the current instruction  ) [0.2.x] added
 : disasm::jumprel method ( Change the current instruction  )

git-svn-id: https://pykd.svn.codeplex.com/svn@82501 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/disasm.cpp       |  6 ++++++
 pykd/disasm.h         |  8 ++++++++
 pykd/disasmengine.h   |  1 +
 pykd/python/pymod.cpp |  6 +++++-
 pykd/win/dbgasm.cpp   | 16 ++++++++++++++++
 5 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/pykd/disasm.cpp b/pykd/disasm.cpp
index 2326f75..5c5d135 100644
--- a/pykd/disasm.cpp
+++ b/pykd/disasm.cpp
@@ -50,4 +50,10 @@ Disasm::assembly( const std::string &instr )
 
 /////////////////////////////////////////////////////////////////////////////////
 
+ULONG64 Disasm::getNearInstruction( LONG delta ) {
+    return pykd::getNearInstruction( m_currentOffset, delta );
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+
 }; // end pykd namespace
diff --git a/pykd/disasm.h b/pykd/disasm.h
index 2c9fdb3..6c89d5b 100644
--- a/pykd/disasm.h
+++ b/pykd/disasm.h
@@ -23,6 +23,14 @@ public:
         return disassemble();
     }
 
+    std::string jumprel(LONG delta) {
+        m_currentOffset = getNearInstruction(delta);
+        doDisasm();
+        return disassemble();
+    }
+
+    ULONG64 getNearInstruction( LONG delta );
+
     std::string  reset() {
         m_currentOffset = m_beginOffset;
         doDisasm();
diff --git a/pykd/disasmengine.h b/pykd/disasmengine.h
index 9180bab..9efe102 100644
--- a/pykd/disasmengine.h
+++ b/pykd/disasmengine.h
@@ -4,5 +4,6 @@ namespace pykd {
 
 void disasmAssemblay( ULONG64 offset, const std::string &instruction, ULONG64 &nextOffset );
 void disasmDisassembly( ULONG64 offset, std::string &instruction, ULONG64 &nextOffset, ULONG64 &ea );
+ULONG64 getNearInstruction( ULONG64 offset, LONG delta );
 
 } // end pykd namespace 
\ No newline at end of file
diff --git a/pykd/python/pymod.cpp b/pykd/python/pymod.cpp
index 4f1e549..f81908a 100644
--- a/pykd/python/pymod.cpp
+++ b/pykd/python/pymod.cpp
@@ -563,7 +563,11 @@ BOOST_PYTHON_MODULE( pykd )
         .def( "length", &Disasm::length, "Return current instruction length" )
         .def( "instruction", &Disasm::instruction, "Returm current disassembled instruction" )
         .def( "ea", &Disasm::ea, "Return effective address for last disassembled instruction or 0" )
-        .def( "reset", &Disasm::reset, "Reset current offset to begin" );
+        .def( "reset", &Disasm::reset, "Reset current offset to begin" )
+        .def( "findOffset", &Disasm::getNearInstruction, "Return the location of a processor instruction relative to a given location" )
+        .def( "jump", &Disasm::jump, "Change current instruction" )
+        .def( "jumprel", &Disasm::jumprel, "Change current instruction" );
+
 
     python::enum_<DEBUG_CALLBACK_RESULT>("eventResult", "Return value of event handler")
         .value("Proceed", DebugCallbackProceed)
diff --git a/pykd/win/dbgasm.cpp b/pykd/win/dbgasm.cpp
index f5c3195..6e1a5f5 100644
--- a/pykd/win/dbgasm.cpp
+++ b/pykd/win/dbgasm.cpp
@@ -49,4 +49,20 @@ void disasmDisassembly( ULONG64 offset, std::string &instruction, ULONG64 &nextO
 
 ///////////////////////////////////////////////////////////////////////////////
 
+ULONG64 getNearInstruction( ULONG64 offset, LONG delta )
+{
+    PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
+
+    HRESULT  hres;
+    ULONG64  nearOffset;
+
+    hres = g_dbgEng->control->GetNearInstruction( offset, delta, &nearOffset );
+    if ( FAILED( hres ) )
+        throw DbgException( "IDebugControl::GetNearInstruction", hres );
+
+    return nearOffset;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 } // end pykd namespace