From 92538913e14ff428353ff4fc9625a459e17dc902 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Wed, 16 Nov 2011 10:30:50 +0000
Subject: [PATCH] [0.1.x] added : compareMemory routine

git-svn-id: https://pykd.svn.codeplex.com/svn@71402 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgclient.h             |  2 ++
 pykd/dbgcmd.h                |  3 +++
 pykd/dbgext.cpp              |  6 ++++++
 pykd/dbgmem.cpp              | 23 +++++++++++++++++++++++
 pykd/dbgmem.h                |  3 +++
 test/scripts/memtest.py      |  4 ++++
 test/targetapp/targetapp.cpp |  2 +-
 7 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h
index d34f465..15a4cd0 100644
--- a/pykd/dbgclient.h
+++ b/pykd/dbgclient.h
@@ -46,6 +46,8 @@ public:
 
     void breakin();
 
+    bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
+
     DbgOut  dout() {
         return DbgOut( m_client );
     }
diff --git a/pykd/dbgcmd.h b/pykd/dbgcmd.h
index c2af84d..3a494c2 100644
--- a/pykd/dbgcmd.h
+++ b/pykd/dbgcmd.h
@@ -14,6 +14,9 @@ dbgCommand( const std::wstring  &command );
 ULONG64
 evaluate( const std::wstring  &expression );
 
+void
+breakin();
+
 ///////////////////////////////////////////////////////////////////////////////////
 
 class DbgExtension : private DbgObject { 
diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index a397884..1728682 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -66,6 +66,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignBytes_, loadSignBytes, 2, 3 );
 BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignWords_, loadSignWords, 2, 3 );
 BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords_, loadSignDWords, 2, 3 );
 BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 );
+BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, compareMemory, 3, 4 );
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadChars, DebugClient::loadChars, 2, 3 );
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadWChars, DebugClient::loadWChars, 2, 3 );
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadBytes, DebugClient::loadBytes, 2, 3 );
@@ -76,6 +77,7 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadSignBytes, DebugClient::
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadSignWords, DebugClient::loadSignWords, 2, 3 );
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadSignDWords, DebugClient::loadSignDWords, 2, 3 );
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_loadSignQWords, DebugClient::loadSignQWords, 2, 3 );
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( DebugClient_compareMemory, DebugClient::compareMemory, 3, 4 );
 
 
 #define DEF_PY_CONST_ULONG(x)    \
@@ -170,6 +172,8 @@ BOOST_PYTHON_MODULE( pykd )
             "Extend address to 64 bits formats" )
         .def( "breakin", &DebugClient::breakin,
             "Break into debugger" )
+        .def( "compareMemory", &DebugClient::compareMemory, DebugClient_compareMemory( python::args( "offset1", "offset2", "length", "phyAddr" ),
+            "Compare two memory buffers by virtual or physical addresses" ) )
         .def( "loadDump", &DebugClient::loadDump,
             "Load crash dump" )
         .def( "startProcess", &DebugClient::startProcess, 
@@ -259,6 +263,8 @@ BOOST_PYTHON_MODULE( pykd )
         "Extend address to 64 bits formats" );
     python::def( "breakin", &breakin,
         "Break into debugger" );
+    python::def( "compareMemory", &compareMemory, compareMemory_( python::args( "offset1", "offset2", "length", "phyAddr" ),
+        "Compare two memory buffers by virtual or physical addresses" ) );
     python::def( "createDbgClient", (DebugClientPtr(*)())&pykd::DebugClient::createDbgClient, 
         "create a new instance of the dbgClient class" );
     python::def( "loadDump", &pykd::loadDump,
diff --git a/pykd/dbgmem.cpp b/pykd/dbgmem.cpp
index a363b1d..59c7402 100644
--- a/pykd/dbgmem.cpp
+++ b/pykd/dbgmem.cpp
@@ -97,6 +97,29 @@ void readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr )
 
 /////////////////////////////////////////////////////////////////////////////////////
 
+bool DebugClient::compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
+{
+    bool        result = false;
+
+    addr1 = addr64( addr1 );
+    addr2 = addr64( addr2 );
+
+    std::vector<char>   m1(length);
+    std::vector<char>   m2(length);
+
+    readMemory( addr1, &m1[0], length, phyAddr );
+    readMemory( addr2, &m2[0], length, phyAddr );
+
+    return std::equal( m1.begin(), m1.end(), m2.begin() );
+}
+
+bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
+{
+    return g_dbgClient->compareMemory( addr1, addr2, length, phyAddr );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
 std::string DebugClient::loadChars( ULONG64 address, ULONG  number, bool phyAddr )
 {
     std::vector<char>   buffer(number);
diff --git a/pykd/dbgmem.h b/pykd/dbgmem.h
index c784772..a2ce649 100644
--- a/pykd/dbgmem.h
+++ b/pykd/dbgmem.h
@@ -15,6 +15,9 @@ readMemory( ULONG64 address, PVOID buffer, ULONG length, BOOLEAN phyAddr = FALSE
 void
 writeMemory( ULONG64 address, PVOID buffer, ULONG length, BOOLEAN phyAddr = FALSE );
 
+bool 
+compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
+
 ///////////////////////////////////////////////////////////////////////////////////
 
 std::string loadChars( ULONG64 address, ULONG  number, bool phyAddr = FALSE );
diff --git a/test/scripts/memtest.py b/test/scripts/memtest.py
index 18ecf87..5caa77d 100644
--- a/test/scripts/memtest.py
+++ b/test/scripts/memtest.py
@@ -73,3 +73,7 @@ class MemoryTest( unittest.TestCase ):
         self.assertEqual( -32640, pykd.ptrSignWord( target.module.g_bigValue ) )
         self.assertEqual( -2139062144, pykd.ptrSignDWord( target.module.g_bigValue ) )
         self.assertEqual( -9187201950435737472, pykd.ptrSignQWord( target.module.g_bigValue ) )
+
+    def testCompare( self ):
+        self.assertTrue( pykd.compareMemory( target.module.helloStr, pykd.ptrPtr(target.module.strArray), 5 ) )
+        self.assertFalse( pykd.compareMemory( target.module.helloStr, target.module.helloWStr, 5 ) )
diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp
index 4a8b643..805e097 100644
--- a/test/targetapp/targetapp.cpp
+++ b/test/targetapp/targetapp.cpp
@@ -65,7 +65,7 @@ unsigned long ulongArray[] = {0, 0xFF, 0x8000, 0x80000000, 0xFFFFFFFF };
 unsigned __int64 ulonglongArray[] = {0, 0xFF, 0xFFFFFFFF, 0x8000000000000000, 0xFFFFFFFFFFFFFFFF };
 
 int intMatrix[2][3] = { { 0, 1, 2}, { 3, 4, 5 } };
-char* strArray[] = { "hello", "bye" };
+char* strArray[] = { "Hello", "Bye" };
 int (*ptrIntMatrix)[2][3] = &intMatrix;
 char *(*ptrStrArray)[2] = &strArray;