2012-02-13 47 views
1

經過相當多的谷歌搜索和一些提示here,我終於設法FS段(由windows用來存儲TIB數據)的find a layout。特別感興趣的我是在PSDK提供的ArbitraryUserPointer成員:TIB定製存儲

typedef struct _NT_TIB { 
    struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; 
    PVOID StackBase; 
    PVOID StackLimit; 
    PVOID SubSystemTib; 
    union { 
     PVOID FiberData; 
     DWORD Version; 
    }; 
    PVOID ArbitraryUserPointer; 
    struct _NT_TIB *Self; 
} NT_TIB; 

如何安全究竟是它使用這個變量(在Vista及以上)?它仍然存在於X64上?

次要的是這個變量的訪問。我使用的是MSVC,正因爲如此我 有機會獲得__readfsdword & __readgsqword內部函數,但是,MSDN由於某種原因,這些標記爲特權指令:

這些內在僅在內核模式下可用,而程序僅作爲內部函數提供。

他們當然只是內核,但他們爲什麼要標明,只是不正確的文件? (我的離線VS 2008文檔沒有這條款)。

最後,直接通過單個__readfsdword(0x14)直接訪問ArbitraryUserPointer是安全的還是通過線性TIB地址使用它最好? (這仍然需要從FS讀取)。

回答

3

ArbitraryUserPointer是不是一般用途的內部領域。操作系統在內部使用它,如果覆蓋它,則會損壞內容。我承認它的名字很不好。

+2

嗯,那是令人失望的,尤其是上了年紀MSVC文章它標誌着下來,應用程序管理。在哪裏有任何文檔,哪些成員是應用程序管理vs操作系統管理的?我基本上在尋找隱藏一個不是TLS的指針的地方 – Necrolis 2012-02-14 06:45:32

+0

TLS是我在TEB中唯一可以想到的應用程序可以免費使用的東西。 (如果還有別的東西像'ArbitraryUserPointer',兩個DLL如何協商對它的控制?) – 2012-02-14 08:48:51

+0

我不可能hi-jiack SEH /堆棧安全令牌嗎? (我可以保證我不會有任何SEH /安全令牌用於我想要的用途)。除此之外,我想我會堅持'__declspec(線程)'爲我的單線程數據... – Necrolis 2012-02-14 09:07:56

0

如果你還是一個答案,我有同樣的問題也和張貼了我的問題,類似於你:

Thread-local storage in kernel mode?

我需要一個TLS相當於在內核級模式驅動。確切地說,我有一個深層的函數調用樹,它起源於某個點(例如驅動程序的調度例程),並且我需要傳遞上下文信息。

在我的具體情況下,我不需要持久性存儲,我只需要一個線程特定的佔位符,用於單個頂級函數調用。因此我決定在函數調用中使用TLS數組中的任意條目,並在完成之後恢復其原始值。

您可以通過以下獲得TLS數組:

DWORD* get_Tls() 
{ 
    return (DWORD*) (__readfsdword(0x18) + 0xe10); 
} 

順便說一句,我不知道爲什麼TIB通常是通過閱讀fs:[0x18]內容訪問。這只是由fs選擇器指出。但是,這就是所有MS的代碼如何訪問它,因此我決定也這樣做。

接下來,您可以選擇任意的TLS索引,說0

const DWORD g_dwMyTlsIndex = 0; 

void MyTopLevelFunc() 
{ 
    // prolog 
    DWORD dwOrgVal = get_Tls()[g_dwMyTlsIndex]; 
    get_Tls()[g_dwMyTlsIndex] = dwMyContextValue; 

    DoSomething(); 

    // epilog 
    get_Tls()[g_dwMyTlsIndex] = dwOrgVal; 
} 

void DoSomething() 
{ 
    DWORD dwMyContext = get_Tls()[g_dwMyTlsIndex]; 
} 
+0

我問這個問題之前,我使用這個問題,我的問題是我需要持久性存儲而不依賴於TLS,所以現在我使用虛擬'__declspec(thread)'變量 – Necrolis 2012-04-01 11:59:59