TIB自定义存储

时间:2012-02-13 13:34:39

标签: windows low-level memory-segmentation

经过相当多的谷歌搜索和here的一些提示后,我终于设法FS段的find a layout(由windows用来存储TIB数据)。我特别感兴趣的是PSDK中提供的ArbitraryUserPointer成员:

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文档没有此条款)。

最后,通过单个ArbitraryUserPointer直接访问__readfsdword(0x14)是安全的还是首选通过线性TIB地址使用它? (仍然需要从FS读取。)

2 个答案:

答案 0 :(得分:5)

ArbitraryUserPointer是一个不常用的内部字段。操作系统在内部使用它,如果你覆盖它,你将破坏东西。我承认它名字很差。

答案 1 :(得分:0)

如果您还在寻找答案,我也遇到了同样的问题并发布了我的问题,与您的问题类似:

Thread-local storage in kernel mode?

我需要内核模式驱动程序中的TLS等效项。确切地说,我有一个深层函数调用树,它起源于某个点(例如驱动程序的调度例程),我需要传递上下文信息。

在我的特定情况下,问题是我不需要持久性存储,我只需要一个特定于线程的占位符来处理单个顶级函数调用。因此,我决定在TLS数组中使用任意条目进行函数调用,并在完成后 - 恢复其原始值。

您可以通过以下方式获取TLS阵列:

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

BTW我不知道为什么通常通过阅读fs:[0x18]的内容来访问TIB。它只是由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];
}