我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
答案 0 :(得分:2)
您正在使用调用流程的位数来决定是使用Wow64GetThreadContext()
还是GetThreadContext()
。那是错的。 Wow64GetThreadContext()
只能由64位进程调用(如果由32位进程调用则会失败),并且只有在目标线程在32位进程内运行时才需要使用Wow64GetThreadContext()
WOW64模拟器。
如果目标线程在WOW64内部运行,请使用GetThreadContext()
和WOW64_CONTEXT
。使用IsWow64Process()
确定拥有目标线程的进程是否在WOW64内部运行。
如果目标线程未在WOW64内部运行,请使用CONTEXT
和CONTEXT
。但请注意,<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}}