Windows XP 上的线程本地存储访问

逆向工程 拆卸 视窗 线
2021-06-16 10:54:14

最近,Microsoft Visual Studio 2015 编译器终于符合 C++ 标准的要求,为函数本地静态生成线程安全代码。在大多数情况下,这工作得很好,但我在 Windows XP 上遇到了以下 3 条指令导致崩溃的情况:

mov     eax,dword ptr fs:[0000002Ch]
mov     ecx,dword ptr [MyModule!_tls_index (102eea44)]
mov     ecx,dword ptr [eax+ecx*4]

显然,编译器似乎通过首先插入当前线程的 TLS 插槽来实现线程安全。fs:2Ch应该导致每个文档的 TLS 数组。但是在 Windows XP 上,fs:2Ch似乎没有设置。这对我来说返回 0,下一条指令_tls_index也是如此(也是 0。)这导致第三条指令在访问无效内存时爆炸。

有人知道为什么fs:2Ch不能在 Windows XP 上设置吗?函数局部静态在我们的代码中使用,我无法想象没有其他人会遇到这种情况。

1个回答

如果您的模块是由可执行文件动态加载的 DLL,则不会在 Windows XP 上为 DLL 初始化线程本地存储。

引用我的“终极”反调试参考,第 4 节,第 25 页:

“在 Windows Vista 及更高版本上,动态加载的 DLL 也支持线程本地存储。这与现有的可移植可执行格式文档直接矛盾,该文档指出“静态声明的 TLS 数据对象......只能在静态加载的图像中使用文件。这一事实使得在 DLL 中使用静态线程本地存储数据变得不可靠,除非您知道 DLL 或与其静态链接的任何内容永远不会使用 LoadLibrary API 函数动态加载”。