TIB Custom Storage

别来无恙 提交于 2019-12-10 11:28:59

问题


After quite a bit of googling and some hints given here, I finally managed to find a layout of the FS segment (used by windows to store TIB data). Of particular interest to me is the ArbitraryUserPointer member provided in the PSDK:

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;

How safe exactly is it to use this variable (under Vista and above)? and does it still exist on x64?

Secondary to that is the access of this variable. I'm using MSVC, and as such I have access to the __readfsdword & __readgsqword intrinsics, however, MSDN for some reason marks these as privileged instructions:

These intrinsics are only available in kernel mode, and the routines are only available as intrinsics.

They are of course not kernel only, but why are they marked as such, just incorrect documentation? (my offline VS 2008 docs don't have this clause).

Finally, is it safe to access ArbitraryUserPointer directly via a single __readfsdword(0x14) or is it preferred to use it via the linear TIB address? (which will still require a read from FS).


回答1:


ArbitraryUserPointer is an internal field not for general use. The operating system uses it internally, and if you overwrite it, you will corrupt stuff. I concede that it has a very poor name.




回答2:


In case you're still for an answer, I've had the same problem too and posted my question, similar to yours:

Thread-local storage in kernel mode?

I need a TLS-equivalent in the kernel-mode driver. To be exact, I have a deep function call tree which originates at some point (driver's dispatch routine for instance), and I need to pass the context information.

In my specific case the catch is that I don't need a persistent storage, I just need a thread-specific placeholder for something for a single top-level function call. Hence I decided to use an arbitrary entry in the TLS array for the function call, and after it's done - restore its original value.

You get the TLS array by the following:

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

BTW I have no idea why the TIB is usually accessed by reading the contents of fs:[0x18]. It's just pointed by the fs selector. But this is how all the MS's code accesses it, hence I decided to do this as well.

Next, you choose an arbitrary TLS index, say 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];
}


来源:https://stackoverflow.com/questions/9261455/tib-custom-storage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!