SetThreadContext x64 volatile registers

1

I have a problem with SetThreadContext. I can't change any of volatile registers (table here).

data.context.ContextFlags = CONTEXT_FULL;
SuspendThread(hThread);

GetThreadContext(hThread, &data.context);

...

CONTEXT* ctx = &data.context;
ctx->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;

ctx->Rax = (DWORD64)0x1000;
ctx->Rcx = (DWORD64)-1;
ctx->Rip = (DWORD64)allocatedMemory;
ctx->R10 = (DWORD64)0x12345678;
ctx->Rbp = (DWORD64)0xFFFFFFFF;
SetThreadContext(hThread, ctx);

ResumeThread(hThread);

That code changes Rip and Rbp registers because they are non-volatile. GetLastError returning 0. Thread opened with THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_SET_INFORMATION rights.

Why i can't change volatile registers in x64 app? In x86 application i could change any register (it was does not matter volatile or not).

P.S. Yes, i tried to call SetThreadContext with ctx->ContextFlags = CONTEXT_FULL;

c++
windows
multithreading
x86-64
cpu-registers
asked on Stack Overflow Jul 28, 2014 by Dmitry K. • edited Aug 9, 2019 by Peter Cordes

1 Answer

3

At 64 bit windows SetThreadContext sets the non-volatile registers only. (see PspGetSetContextInternal at /base/ntos/ps/amd64/psctxamd64.c in the WRK) 1

The registers that sets are: Rbx, Rsp, Rbp, Rsi, Rdi, R12-R15, Xmm6-Xmm15 only.

answered on Stack Overflow Jun 19, 2016 by Or Virnik

User contributions licensed under CC BY-SA 3.0