import t, c from stdint import * from w32.win32process import TlsAlloc, TlsGetValue, TlsSetValue import stdlib import stdio import string # Maximum provider stack depth (compiler verifies sufficiency; increase if needed) _MAX_PROVIDER_DEPTH: t.CDefine = 32 @t.Object class _ProviderStack: """Provider stack, stores pairs of field names and pointers.""" names: t.CArray[VOIDPTR, 32] ptrs: t.CArray[VOIDPTR, 32] top: UINT64 # TLS index (global; all threads share the same index) _tls_index: ULONG = 0 @t.TLS def _init_tls(): """Initialize TLS index (executes once; subsequent calls are skipped).""" global _tls_index # 双保险:TPV 已正式实现 @t.TLS(函数级一次性守卫,首次执行后置 # __tls_init_done 标志,后续调用直接返回),此判重守卫保留以兼容 # 尚未重建的旧 TPV.exe。_tls_index 初始为 0(TlsAlloc 成功不会返回 0)。 if _tls_index == 0: _tls_index = TlsAlloc() def _get_stack() -> _ProviderStack | t.CPtr: """Obtain current thread's provider stack. Allocate one if none exists.""" _init_tls() stack: _ProviderStack | t.CPtr = TlsGetValue(_tls_index) if stack == None: stack = stdlib.malloc(_ProviderStack.__sizeof__()) string.memset(stack, 0, _ProviderStack.__sizeof__()) TlsSetValue(_tls_index, stack) return stack def _push_provider(field_name: str, ptr: t.CPtr): """Push a provider (field_name, ptr) onto the stack.""" stack: _ProviderStack | t.CPtr = _get_stack() if stack.top >= _MAX_PROVIDER_DEPTH: stdio.printf("[with] ERROR: provider stack overflow (depth=%lu, max=%d), field '%s' not injected\n", stack.top, _MAX_PROVIDER_DEPTH, field_name) return stack.names[stack.top] = field_name stack.ptrs[stack.top] = ptr stack.top = stack.top + 1 def _pop_provider(): """Pop the top provider entry from the stack.""" stack: _ProviderStack | t.CPtr = _get_stack() if stack.top > 0: stack.top = stack.top - 1 def _find_provider(field_name: str) -> t.CPtr: """Search for matching field_name starting from stack top. Return associated pointer, or NULL if no match found.""" stack: _ProviderStack | t.CPtr = _get_stack() for i in range(stack.top - 1, -1, -1): # 字段名用 strcmp 内容比较:编译器对每次 create_global_string 生成 # 独立的字符串常量(TPV 不去重),push/find 的指针地址不同, # 指针 == 永假会导致 provider 匹配失败(__mbuddy__ 注入不上)。 if string.strcmp((str)(stack.names[i]), field_name) == 0: return stack.ptrs[i] return None