title: Win 64bit GetThreadContext returns zeroe'd out registers, or 0x57 errorcode
body: <p>I'm working on a Windows 7 64 bit machine (I have admin privs).</p>
  
  <p>I'm using Python 2.7 (64-bit) with PyDev ctypes for Eclipse to try and read the values of registers in all threads associated with a particular PID (tried both PIDs of processes running in 64 and 32 bit modes), but when I do this, the values for the registers are all zeroe'd out. When I use <code>Wow64GetThreadContext</code>, the call fails with <code>GetLastError</code> returning 0x00000057 ('invalid parameters' according to MSDN)</p>
  
  <p>I attach to the process successfully, enumerate the threads (via <code>CreateToolhelp32Snapshot</code>), find the threads that are owned by the process with the appropriate PID, and attempt to get the thread context. Here is my code for opening the thread and getting the thread context:</p>
  
  <p>Opening a thread:</p>
  
  <pre><code>def open_thread(self, thread_id):
      h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
  </code></pre>
  
  <p>Getting context:</p>
  
  <pre><code>def get_thread_context(self, thread_id = None, h_thread = None):
  
      context = CONTEXT()
      context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
  
      #alternatively, for 64
      context64 = WOW64_CONTEXT()
      context64.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
  
      #Obtain a handle to the thread
      if h_thread is None:
          self.h_thread = self.open_thread(thread_id)
  
      kernel32.SuspendThread(self.h_thread)
  
      if kernel32.GetThreadContext(self.h_thread, byref(context)):
          kernel32.ResumeThread(self.h_thread)
          return context
      else:
          kernel32.ResumeThread(self.h_thread)
          return False
  </code></pre>
  
  <p>I call this code using:</p>
  
  <pre><code>debugger.attach(int(pid))
  
  #debugger.run()
  
  list = debugger.enumerate_threads()
  
  for thread in list:
  thread_context = debugger.get_thread_context(thread)
  
      if thread_context == False:
          print "[*] Thread context is false..."
      else:
          print "[*] Dumping registers for thread ID: 0x%08x" % thread
          print "[**] Eip: 0x%016x" % thread_context.Eip
          print "[**] Esp: 0x%016x" % thread_context.Esp
          print "[**] Ebp: 0x%016x" % thread_context.Ebp
          print "[**] Eax: 0x%016x" % thread_context.Eax
          print "[**] Ebx: 0x%016x" % thread_context.Ebx
          print "[**] Ecx: 0x%016x" % thread_context.Ecx
          print "[**] Edx: 0x%016x" % thread_context.Edx
          print "[*] End DUMP"
  
  debugger.detach()
  </code></pre>
  
  <p>When I run this code using <code>GetThreadContext</code> with the CONTEXT structure, I get the context object back for each thread, but the register values are all zero.</p>
  
  <p>I have tried replacing <code>GetThreadContext</code> with <code>Wow64GetThreadContext</code> (and respectively, <code>SuspendThread</code> with <code>Wow64SuspendThread</code>), but when I do this, the call fails with error 'invalid parameters'. The arguments I give to <code>Wow64GetThreadContext</code> are the same as those I give to <code>GetThreadContext</code>, other than the name of the variables in the code I provided (this is because when I looked at their definitions in WinNT.h, they were equivalent (unless I missed something). I've defined these structures the following way:</p>
  
  <pre><code>class WOW64_CONTEXT(Structure):
  _fields_ = [
  
      ("ContextFlags", DWORD),
      ("Dr0", DWORD),
      ("Dr1", DWORD),
      ("Dr2", DWORD),
      ("Dr3", DWORD),
      ("Dr6", DWORD),
      ("Dr7", DWORD),
      ("FloatSave", WOW64_FLOATING_SAVE_AREA),
      ("SegGs", DWORD),
      ("SegFs", DWORD),
      ("SegEs", DWORD),
      ("SegDs", DWORD),
      ("Edi", DWORD),
      ("Esi", DWORD),
      ("Ebx", DWORD),
      ("Edx", DWORD),
      ("Ecx", DWORD),
      ("Eax", DWORD),
      ("Ebp", DWORD),
      ("Eip", DWORD),
      ("SegCs", DWORD),
      ("EFlags", DWORD),
      ("Esp", DWORD),
      ("SegSs", DWORD),
      ("ExtendedRegisters", BYTE * 512),
  ]
  
  class WOW64_FLOATING_SAVE_AREA(Structure):
  _fields_ = [
  
      ("ControlWord", DWORD),
      ("StatusWord", DWORD),
      ("TagWord", DWORD),
      ("ErrorOffset", DWORD),
      ("ErrorSelector", DWORD),
      ("DataOffset", DWORD),
      ("DataSelector", DWORD),
      ("RegisterArea", BYTE * 80),
      ("Cr0NpxState", DWORD),
  ]
  
  class CONTEXT(Structure):
  _fields_ = [
  
      ("ContextFlags", DWORD),
      ("Dr0", DWORD),
      ("Dr1", DWORD),
      ("Dr2", DWORD),
      ("Dr3", DWORD),
      ("Dr6", DWORD),
      ("Dr7", DWORD),
      ("FloatSave", FLOATING_SAVE_AREA),
      ("SegGs", DWORD),
      ("SegFs", DWORD),
      ("SegEs", DWORD),
      ("SegDs", DWORD),
      ("Edi", DWORD),
      ("Esi", DWORD),
      ("Ebx", DWORD),
      ("Edx", DWORD),
      ("Ecx", DWORD),
      ("Eax", DWORD),
      ("Ebp", DWORD),
      ("Eip", DWORD),
      ("SegCs", DWORD),
      ("EFlags", DWORD),
      ("Esp", DWORD),
      ("SegSs", DWORD),
      ("ExtendedRegisters", BYTE * 512),
  ]
  
  class FLOATING_SAVE_AREA(Structure):
  _fields_ = [
  
      ("ControlWord", DWORD),
      ("StatusWord", DWORD),
      ("TagWord", DWORD),
      ("ErrorOffset", DWORD),
      ("ErrorSelector", DWORD),
      ("DataOffset", DWORD),
      ("DataSelector", DWORD),
      ("RegisterArea", BYTE * 80),
      ("Cr0NpxState", DWORD),
  ]
  </code></pre>
  
  <p>I've done a fair amount of googling on this issue, and have tried the following to no avail:</p>
  
  <ul>
  <li><p>According to a comment on the MSDN: <code>CONTEXT_FULL</code> should be
  <code>CONTEXT_AMD64 | CONTEXT_CONTROL | CONTEXT_INTEGER |
  CONTEXT_FLOATING_POINT</code> to be used with Win64 properly.</p></li>
  <li><p>I've tried renaming the registers inside my CONTEXT and WOW_64CONTEXT
  structures by replacing the 'E' in the register names with 'R' (Eax
  -> Rax, etc.)</p></li>
  </ul>
  
  <p>Has anyone else used Python with ctypes to successfully get the context of a 64-bit thread on Windows?</p>