Wow64GetThreadContext窃听? (VB.NET)

时间:2014-06-11 01:07:31

标签: .net vb.net winapi

我99.9%确定我做的一切都是正确的。 如果我在x86进程上使用Wow64GetThreadContext来接收线程上下文,它可以很好地工作,具有所有编译体系结构类型(x86,AnyCPU,x64)

如果我尝试从x64进程上的线程检索线程上下文,则它不起作用。我知道从x86调用它不应该工作,但它甚至不能从x64或AnyCPU(x64)调用来接收x64进程的线程上下文。 我收到错误:参数无效。

在代码中调用它时:

  Dim Context As New CONTEXT
  If IntPtr.Size = 8 Then
  Context.ConextFlags = &H10000 & &H2L
  Else
    Context.ConextFlags = &H10000L & &H2L
  End If
  If IntPtr.Size = 8 Then
      If Not Wow64GetThreadContext(PI.hThread, Context) Then Throw New Exception
  Else
      If Not GetThreadContext(PI.hThread, Context) Then Throw New Exception
  End If

结构:

<StructLayout(LayoutKind.Sequential)> _
Structure FLOATING_SAVE_AREA
    Dim Control, Status, Tag, ErrorO, ErrorS, DataO, DataS As UInteger
    <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=80)> Dim RegisterArea As Byte()
    Dim State As UInteger
End Structure
<StructLayout(LayoutKind.Sequential)> _
Structure CONTEXT
    Dim ConextFlags, Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 As UInteger, FloatSave As FLOATING_SAVE_AREA
    Dim SegGs, SegFs, SegEs, SegDs, Edi, Esi, Ebx, Edx, Ecx, Eax, Ebp, Eip, SegCs, EFlags, Esp, SegSs As UInteger
    <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=512)> Dim ExtendedRegisters As Byte()
End Structure

API调用:

<DllImport("kernel32.dll", SetLastError:=True, EntryPoint:="GetThreadContext"), SuppressUnmanagedCodeSecurity()> _
Private Shared Function GetThreadContext( _
ByVal hThread As IntPtr, _
ByRef lpContext As CONTEXT) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True, EntryPoint:="Wow64GetThreadContext"), SuppressUnmanagedCodeSecurity()> _
Private Shared Function Wow64GetThreadContext( _
ByVal hThread As IntPtr, _
ByRef lpContext As CONTEXT) As Boolean
End Function

1 个答案:

答案 0 :(得分:2)

您正在使用调用流程的位数来决定是使用Wow64GetThreadContext()还是GetThreadContext()。那是错的。 Wow64GetThreadContext()只能由64位进程调用(如果由32位进程调用则会失败),并且只有在目标线程在32位进程内运行时才需要使用Wow64GetThreadContext() WOW64模拟器。

如果目标线程在WOW64内部运行,请使用GetThreadContext()WOW64_CONTEXT。使用IsWow64Process()确定拥有目标线程的进程是否在WOW64内部运行。

如果目标线程未在WOW64内部运行,请使用CONTEXTCONTEXT。但请注意,<StructLayout(LayoutKind.Sequential)> _ Structure FLOATING_SAVE_AREA Dim Control, Status, Tag, ErrorO, ErrorS, DataO, DataS As UInteger <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=80)> Dim RegisterArea As Byte() Dim State As UInteger End Structure <StructLayout(LayoutKind.Sequential)> _ Structure CONTEXT32 Dim ContextFlags, Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 As UInteger Dim FloatSave As FLOATING_SAVE_AREA Dim SegGs, SegFs, SegEs, SegDs, Edi, Esi, Ebx, Edx, Ecx, Eax, Ebp, Eip, SegCs, EFlags, Esp, SegSs As UInteger <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=512)> Dim ExtendedRegisters As Byte() End Structure ' WOW64_CONTEXT is the same as CONTEXT32... <StructLayout(LayoutKind.Sequential, Pack:=16)> _ Structure M128A Dim Low As ULong Dim High As Long End Structure <StructLayout(LayoutKind.Sequential, Pack:=16)> _ Structure CONTEXT64 Dim P1Home, P2Home, P3Home, P4Home, P5Home, P6Home As ULong Dim ContextFlags, MxCsr As UInteger Dim SegCs, SegDs, SegEs, SegFs, SegGs, SegSs As UShort Dim EFlags As UIneger Dim Dr0, Dr1, Dr2, Dr3, Dr6, Dr7, Rax, Rcx, Rdx, Rbx, Rsp, Rbp, Rsi, Rdi, R8, R9, R10, R11, R12, R13, R14, R15, Rip As ULong <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPArray, SizeConst:=2)> Dim Header As M128A() <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPArray, SizeConst:=8)> Dim Legacy As M128A() Dim Xmm0, Xmm1, Xmm2, Xmm3, Xmm4, Xmm5, Xmm6, Xmm7, Xmm8, Xmm9, Xmm10, Xmm11, Xmm12, Xmm13, Xmm14, Xmm15 As M128A <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPArray, SizeConst:=26)> Dim VectorRegister As M128A() Dim VectorControl, DebugControl, LastBranchToRip, LastBranchFromRip, LastExceptionToRip, LastExceptionFromRip As ULong End Structure <DllImport("kernel32.dll", SetLastError:=True, EntryPoint:="GetThreadContext"), SuppressUnmanagedCodeSecurity()> _ Private Shared Function GetThreadContext32( _ ByVal hThread As IntPtr, _ ByRef lpContext As CONTEXT32) As Boolean End Function <DllImport("kernel32.dll", SetLastError:=True, EntryPoint:="GetThreadContext"), SuppressUnmanagedCodeSecurity()> _ Private Shared Function GetThreadContext64( _ ByVal hThread As IntPtr, _ ByRef lpContext As CONTEXT64) As Boolean End Function <DllImport("kernel32.dll", SetLastError:=True, EntryPoint:="Wow64GetThreadContext"), SuppressUnmanagedCodeSecurity()> _ Private Shared Function Wow64GetThreadContext( _ ByVal hThread As IntPtr, _ ByRef lpContext As CONTEXT32) As Boolean End Function <DllImport("kernel32.dll", SetLastError:=True, EntryPoint:="IsWow64Process"), SuppressUnmanagedCodeSecurity()> _ Private Shared Function IsWow64Process( _ ByVal hProcess as IntPtr, _ ByRef Wow64Process As Boolean) As Boolean End Function 的内容高度依赖于所使用的CPU类型,因此根据是在32位还是64位线程上调用它会有所不同,因此您需要将其考虑在内同样。

尝试更像这样的事情:

Dim IsWow64Proc As Boolean
If not IsWow64Process(PI.hProcess, IsWow64Proc) Then Throw New Exception

' If the target thread is running in WOW64 then query for CONTEXT32.
'
' Otherwise, if the calling process is 32-bit then it cannot access
' 64-bit threads so query for CONTEXT32 as well.
'
' Otherwise, this must be a 64-bit process querying a 64-bit thread
' so query for CONTEXT64...

If IsWow64Proc or IntPtr.Size = 4 Then
    Dim Context As New CONTEXT32
    Context.ContextFlags = &H10002L
    If IsWow64Proc Then
        If Not Wow64GetThreadContext(PI.hThread, Context) Then Throw New Exception
    Else
         If Not GetThreadContext32(PI.hThread, Context) Then Throw New Exception
    EndIf
    ...
Else
    Dim Context As New CONTEXT64
    Context.ContextFlags = &H100002L
    If Not GetThreadContext64(PI.hThread, Context) Then Throw New Exception
    ...
End If

{{1}}