GetThreadContext - x64
Posted: Mon Jun 27, 2016 5:18 pm
In AMD64 the CONTEXT structure must start at a 16-bit boundary, otherwise the call fails.
Unfortunately PB can't perform boundary alignment outside of structures.
We need another optional parameter like this:
BAligin would be similar to __declspec(align(#)) -> https://msdn.microsoft.com/en-us/library/83ythb65.aspx
Bug Example(s):
Workaround:
Unfortunately PB can't perform boundary alignment outside of structures.
We need another optional parameter like this:
Code: Select all
Structure CONTEXT Align #PB_Structure_AlignC BAlign 16
any.l
EndStructure
Bug Example(s):
Code: Select all
EnableExplicit
; typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
CompilerIf #PB_Compiler_Processor <> #PB_Processor_x64
MessageRequester("", "This is a x64 bug only!")
CompilerEndIf
Procedure.s win_FormatErrorCode(lngErrorCode.l)
Protected str_buf.s = Space(255)
Protected tchar_count.l
tchar_count = FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, #Null, lngErrorCode, 0, @str_buf, 255, #Null)
If tchar_count > 0
str_buf = Trim(Left(str_buf, tchar_count))
Else
str_buf = ""
EndIf
ProcedureReturn str_buf
EndProcedure
Procedure ProcTest1()
Protected ctx.CONTEXT
ctx\ContextFlags = #CONTEXT_FULL
If GetThreadContext_(-2, @ctx)
PrintN("EFlags: "+Hex(ctx\EFlags))
Else
Protected last_err.l
last_err = GetLastError_()
PrintN("Error - LastError Code: "+Str(last_err)+#CRLF$+#TAB$+"LastError Msg: "+win_FormatErrorCode(last_err))
EndIf
EndProcedure
Procedure ProcTest2()
Protected align1.i
Protected ctx.CONTEXT
ctx\ContextFlags = #CONTEXT_FULL
If GetThreadContext_(-2, @ctx)
PrintN("EFlags: "+Hex(ctx\EFlags))
Else
Protected last_err.l
last_err = GetLastError_()
PrintN("Error - LastError Code: "+Str(last_err)+#CRLF$+#TAB$+"LastError Msg: "+win_FormatErrorCode(last_err))
EndIf
EndProcedure
Procedure.l ProcTest3()
Protected result.l ; <- 16-byte alignment fucked
Protected align1.i
Protected ctx.CONTEXT
ctx\ContextFlags = #CONTEXT_FULL
If GetThreadContext_(-2, @ctx)
PrintN("EFlags: "+Hex(ctx\EFlags))
Else
Protected last_err.l
last_err = GetLastError_()
PrintN("Error - LastError Code: "+Str(last_err)+#CRLF$+#TAB$+"LastError Msg: "+win_FormatErrorCode(last_err))
EndIf
ProcedureReturn result
EndProcedure
If OpenConsole()
PrintN("Running ProcTest1...")
ProcTest1()
PrintN("Running ProcTest2...")
ProcTest2()
PrintN("Running ProcTest3...")
ProcTest3()
PrintN("")
PrintN("Press enter to exit.")
Input()
EndIf
Code: Select all
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
Procedure.l GetThreadContext(ThreadHandle.i, *ThreadContext.CONTEXT)
Protected result.l
Protected ctx.CONTEXT
; In AMD64 the CONTEXT structure must start at a 16-bit boundary, otherwise the call fails.
If *ThreadContext
CopyMemory(*ThreadContext, @ctx, SizeOf(CONTEXT))
result = GetThreadContext_(ThreadHandle, @ctx)
CopyMemory(@ctx, *ThreadContext, SizeOf(CONTEXT))
Else
result = GetThreadContext_(ThreadHandle, *ThreadContext)
EndIf
ProcedureReturn result
EndProcedure
CompilerElse
Procedure.l GetThreadContext(ThreadHandle.i, *ThreadContext.CONTEXT)
ProcedureReturn GetThreadContext_(ThreadHandle, *ThreadContext)
EndProcedure
CompilerEndIf
Macro GetThreadContext_
GetThreadContext
EndMacro