On Mon Mar 20 21:06:13 2023 +0000, Mateusz Wajchęprzełóż wrote:
I don't see how can `NtCurrentTeb()` change between calls within the
same function ("function" here means what is resulted after inlining)? Do you have a (hypothetical) example of such code? TEB changes within `fiberProc` function:
#include <windows.h> #include <stdio.h> static inline __attribute__((always_inline)) void* getTEB() { void* teb; __asm__ (".byte 0x65\n\tmovq (0x30),%0" : "=r" (teb)); return teb; } static inline __attribute__((always_inline)) void* getTEB_volatile() { void* teb; __asm__ volatile (".byte 0x65\n\tmovq (0x30),%0" : "=r" (teb)); return teb; } void* testFiber; void* mainThrFiber; void* secondThrFiber; static void WINAPI fiberProc(void* arg); static DWORD WINAPI threadProc(void* arg); int main() { mainThrFiber = ConvertThreadToFiber(NULL); testFiber = CreateFiber(0, fiberProc, NULL); printf("main TEB=%p; volatile TEB=%p\n", getTEB(), getTEB_volatile()); puts("main -> fiber"); SwitchToFiber(testFiber); puts("main <- fiber"); HANDLE hThr = CreateThread(NULL, 0, threadProc, NULL, 0, NULL); WaitForSingleObject(hThr, INFINITE); return 0; } DWORD WINAPI threadProc(void* arg) { secondThrFiber = ConvertThreadToFiber(NULL); printf("thread TEB=%p; volatile TEB=%p\n", getTEB(), getTEB_volatile()); puts("thread -> fiber"); SwitchToFiber(testFiber); puts("thread <- fiber"); return 0; } void WINAPI fiberProc(void* arg) { printf("fiber TEB=%p; volatile TEB=%p\n", getTEB(), getTEB_volatile()); SwitchToFiber(mainThrFiber); printf("fiber TEB=%p; volatile TEB=%p\n", getTEB(), getTEB_volatile()); SwitchToFiber(secondThrFiber); }
I see, thanks for the example with fibers, although this seems purely theoretical as Wine code doesn't use them…