Skip to content

Commit

Permalink
Fea #83, Windows XP添加动态DLL TLS兼容
Browse files Browse the repository at this point in the history
  • Loading branch information
mingkuang-Chuyu committed May 24, 2024
1 parent 1f01599 commit 61c5216
Show file tree
Hide file tree
Showing 13 changed files with 1,046 additions and 592 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ indent_size = 4
[*.{vcxproj,xml,nuspec,targets}]
indent_style = space
indent_size = 2

[*.cmd]
charset = unset
4 changes: 2 additions & 2 deletions .github/workflows/Build&Test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,13 @@ jobs:
$RunFaild = 0
&vstest.console src\Release\YY-Thunks.UnitTest.dll "/logger:trx;LogFileName=UnitTestWin32.trx" "/Blame:CollectDump;CollectAlways=false;DumpType=full /Diag:TestResults\Win32.log"
&vstest.console src\Release\YY-Thunks.UnitTest.dll "/logger:trx;LogFileName=UnitTestWin32.trx" "/Blame:CollectDump;CollectAlways=false;DumpType=full" "/Diag:TestResults\Win32.log"
if($lastexitcode -ne 0)
{
$RunFaild = 1
}
&vstest.console src\x64\Release\YY-Thunks.UnitTest.dll "/logger:trx;LogFileName=UnitTestWin64.trx" "/Blame:CollectDump;CollectAlways=false;DumpType=full /Diag:TestResults\Win64.log"
&vstest.console src\x64\Release\YY-Thunks.UnitTest.dll "/logger:trx;LogFileName=UnitTestWin64.trx" "/Blame:CollectDump;CollectAlways=false;DumpType=full" "/Diag:TestResults\Win64.log"
if($lastexitcode -ne 0)
{
$RunFaild = 1
Expand Down
3 changes: 2 additions & 1 deletion NuGet/build/native/YY-Thunks.targets
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<MinimumRequiredVersion Condition=" '%(Link.MinimumRequiredVersion)' == '' and '$(PlatformShortName)'=='x86' and '$(YY_Thunks_File)'=='YY_Thunks_for_WinXP.obj' ">5.01</MinimumRequiredVersion>
<MinimumRequiredVersion Condition=" '%(Link.MinimumRequiredVersion)' == '' and '$(PlatformShortName)'=='x64' and '$(YY_Thunks_File)'=='YY_Thunks_for_WinXP.obj' ">5.02</MinimumRequiredVersion>
<AdditionalDependencies>$(MSBuildThisFileDirectory)objs\$(PlatformShortName)\$(YY_Thunks_File);%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol Condition="'$(ConfigurationType)'=='DynamicLibrary' and ('$(YY_Thunks_File)'=='YY_Thunks_for_WinXP.obj' or '$(YY_Thunks_File)'=='YY_Thunks_for_Win2K.obj')">DllMainCRTStartupForYY_Thunks</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
Expand All @@ -21,4 +22,4 @@
<Target Name="YY_Thunks_Update_MinimumRequiredVersion" Condition="'$(YY_Thunks_File)'=='YY_Thunks_for_Win2K.obj' and Exists('$(MSBuildThisFileDirectory)objs\$(PlatformShortName)\$(YY_Thunks_File)') and ('$(ConfigurationType)' == 'Application' Or '$(ConfigurationType)' == 'DynamicLibrary') " AfterTargets="AfterLink">
<Exec Command="%22$(MSBuildThisFileDirectory)Bin\MinimumRequiredVersionHelper.exe%22 %22$(TargetPath)%22 /MinimumRequiredVersion:5.0"/>
</Target>
</Project>
</Project>
125 changes: 71 additions & 54 deletions ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,87 +1,104 @@
# YY-Thunks - 让兼容 Windows 更轻松
# YY-Thunks - It's easier to make your apps compatible with older versions of Windows!
[![license](https://img.shields.io/github/license/Chuyu-Team/YY-Thunks)](https://github.com/Chuyu-Team/YY-Thunks/blob/master/LICENSE)
[![downloads](https://img.shields.io/github/downloads/Chuyu-Team/YY-Thunks/total)](https://github.com/Chuyu-Team/YY-Thunks/releases)
[![contributors](https://img.shields.io/github/contributors-anon/Chuyu-Team/YY-Thunks)](https://github.com/Chuyu-Team/YY-Thunks/graphs/contributors)
[![release](https://img.shields.io/github/v/release/Chuyu-Team/YY-Thunks?include_prereleases)](https://github.com/Chuyu-Team/YY-Thunks/releases)
[![nuget](https://img.shields.io/nuget/vpre/YY-Thunks)](https://www.nuget.org/packages/YY-Thunks)
[![Build&Test](https://github.com/Chuyu-Team/YY-Thunks/actions/workflows/Build&Test.yml/badge.svg)](https://github.com/Chuyu-Team/YY-Thunks/actions/workflows/Build&Test.yml)

## 1. 关于 YY-Thunks
- [简体中文](Readme.osc.md)

众所周知,从 Windows 的每次更新又会新增大量 API,这使得兼容不同版本的 Windows
需要花费很大精力。导致现在大量开源项目已经不再兼容一些早期的 Windows 版本,比如
Windows XP RTM。
## 1. About YY-Thunks

难道就没有一种快速高效的方案解决无法定位程序输入点的问题吗?
With each new version of Windows, a large number of APIs are added,
and it often takes a lot of effort to develop Windows applications
that are compatible with older systems. And some open source projects
are no longer compatible with some earlier versions of Windows, such as Windows XP and Windows 7...

YY-Thunks(鸭船),存在的目的就是抹平不同系统的差异,编译时单纯添加一个 obj
即可自动解决这些兼容性问题。让你兼容旧版本 Windows 更轻松!
Isn't there a solution to quickly deal with the problem that the old system can't find the API?

[ [鸭船交流群 633710173](https://shang.qq.com/wpa/qunwpa?idkey=21d51d8ad1d77b99ea9544b399e080ec347ca6a1bc04267fb59cebf22644a42a) ]
YY-Thunks can solve these kinds of problems quickly and without changing the code.
These compatibility issues can be resolved automatically by tweaking the linker.
It's easier to make your apps compatible with older versions of Windows!

### 1.1. 原理
[ [YY-Thunks QQ Group 633710173](https://shang.qq.com/wpa/qunwpa?idkey=21d51d8ad1d77b99ea9544b399e080ec347ca6a1bc04267fb59cebf22644a42a) ]

使用 `LoadLibrary` 以及 `GetProcAddress` 动态加载 API,不存在时做出补偿措施,
最大限度模拟原始 API 行为,让你的程序正常运行。
### 1.1. The principle of YY-Thunks

### 1.2. 亮点
Use `LoadLibrary` and `GetProcAddress` to dynamically load the API.
If the API doesn't exist, then implement its behavior and get your program running properly.

* 更快!更安全!`鸭船`内建2级缓存以及按需加载机制,同时自动加密所有函数指针,
防止内存爆破攻击。最大程度减少不需要和不必要的 `LoadLibrary` 以及
`GetProcAddress` 调用以及潜在安全风险。
* 轻松兼容 Windows XP,让你安心专注于业务逻辑。
* 完全开源且广泛接受用户意见,希望大家能踊跃的创建 PR,为`鸭船`添砖加瓦。
As follows: GetTickCount64

## 2. 使用方法
```cpp
// Windows XP not support GetTickCount64.
ULONGLONG WINAPI GetTickCount64(VOID)
{
if (auto const _pfnGetTickCount64 = try_get_GetTickCount64())
{
return _pfnGetTickCount64();
}
// Fallback
return GetTickCount();
}
```
大家可以在以下方案中任选一种,但是我们优先推荐 NuGet 方案,因为NuGet采用傻瓜式设计,使用更便捷。
### 1.2. Highlight
### 2.1. NuGet(推荐)
#### 2.1.1. C++项目
1. 项目右键 “管理 NuGet 程序包”。
2. NuGet搜索框中输入:`YY-Thunks`,搜索后点击安装。
3. 项目右键 - 属性 - YY-Thunks 中,自行调整YY-Thunks等级,允许 Windows 2000,
Windows XP 以及 Windows Vista(默认)。
4. 重新编译代码
* Faster! Safer! Built-in L2 cache and encrypt all function pointers to prevent brute-force memory searches.
Minimize unwanted, unnecessary calls to `LoadLibrary` and `GetProcAddress`.
* Make your application easily compatible with Windows XP so you can focus on your business logic.
* The code is completely open source, and everyone is welcome to create PRs to contribute to the YY-Thunks.
#### 2.1.2. .NET Native AOT项目
1.`TargetFramework`添加`Windows`系统平台,比如修改为`net8.0-windows`或者`net9.0-windows`
2. 项目右键 `管理 NuGet 程序包`
3. NuGet搜索框中输入:`YY-Thunks`,搜索后点击安装。
4. 默认兼容到Windows Vista(默认),如果需要兼容Windows XP可以将`WindowsSupportedOSPlatformVersion`调整为`5.1`
## 2. How to used?
### 2.2. 手工配置
You can choose one of the following options, but it is recommended to use NuGet first,
as NuGet is designed to be foolproof and easier to use.
1. 下载 [YY-Thunks-Binary](https://github.com/Chuyu-Team/YY-Thunks/releases)
然后解压到你的工程目录。
2. 【链接器】-【输入】-【附加依赖项】,添加
`objs\$(PlatformShortName)\YY_Thunks_for_WinXP.obj`
3. 【链接器】-【系统】-【所需的最低版本】,根据实际情况填写 `5.01`(WinXP 32位) 或者 `5.02`(WinXP x64、2003)。
4. 重新编译代码。
### 2.1. NuGet (Recommend)
#### 2.1.1. C++ Project
1. Right-click on the `Project` and select `Manage NuGet Packages`, then search for `YY-Thunks` and choose the version that suits you, and finally click Install.
2. In Project Right-Click - `Properties` - `YY-Thunks`, adjust the YY-Thunks level,
which can be set to: Windows 2000, Windows XP, and Windows Vista (default).
3. Rebuild the solution.
> 温馨提示:如果需要兼容 Vista,【所需的最低版本】无需修改,但是【附加依赖项】请选择
#### 2.1.2. .NET Native AOT Project
1. modify the value of `TargetFramework` to `net8.0-windows` or `net9.0-windows`。
2. Right-click on the `Project` and select `Manage NuGet Packages`, then search for `YY-Thunks` and choose the version that suits you, and finally click Install.
3. Optional, if you need run on Windows XP, please modify the value of `SupportedOSPlatformVersion` to `5.1`
### 2.2. Manual
1. Download and unzip [YY-Thunks-Binary](https://github.com/Chuyu-Team/YY-Thunks/releases) to project directory.
2. `Linker` - `Input` - `Additional Dependencies`, add `objs\$(PlatformShortName)\YY_Thunks_for_WinXP.obj`.
3. `Linker` - `System` - `Minimum Required Version`, set to `5.1` (WinXP 32-bit) or `5.2` (WinXP x64 or Win2003).
4. If the project is a `Dynamic Link Library`, then change `Linker` - `Advanced` - `Custom Entry Point` to `DllMainCRTStartupForYY_Thunks`
(If you ignore this step, the XP system may crash with `thread_local`).
5. Rebuild the solution.
> Note: If your app needs to be compatible with Vista or later, please set `Additional Dependencies` to
`objs\$(PlatformShortName)\YY_Thunks_for_Vista.obj`。
## 3. 兼容性
## 3. Compatibility
### 3.1. 支持的编译器
### 3.1. Supported Compiler
全平台ABI兼容。
Compatible with all platforms.
* 所有Visual Studio版本均支持
(比如:VC6.0、VS2008、VS2010、VS2015、VS2017、VS2019、VS2022等等)。
* 所有运行库模式均支持(比如:`/MD``/MT``/MDd``/MTd`)。
* It is supported by all Visual Studio versions (such as: VC6.0, VS2008, VS2010, VS2015, VS2017, VS2019, VS2022...).
* All runtime modes are supported (such as: `/MD`, `/MT`, `/MDd`, `/MTd`).
### 3.2. SDK版本要求
至少需要SDK 6.0(VS2008默认附带)
### 3.2. Windows SDK Version Requirements
At least Windows SDK 6.0 is required.
> 温馨提示:VC6.0、VS2005用户请注意,由于这些编译器默认附带的SDK版本太低。请先将SDK升级到6.0或者更高版本,然后再使用YY-Thunks,否则将发生链接失败!
高版本的SDK不影响对老系统的兼容性,请坐和放宽,安心升级。
> Note: VC6.0 and VS2005 users should note that the SDK version that comes with these compilers by default is too low.
Please upgrade the SDK to version 6.0 or later, and then use YY-Thunks, otherwise the link will not be successful!
The different SDK version don't affect your app compatibility with the old system.
### 3.3. Thunks 清单
### 3.3. Thunks API List
请参阅 [ThunksList.md](ThunksList.md)
See the [ThunksList.md](ThunksList.md)
## 4. 更新日志
## 4. Changelog
请参阅 [releases 更新日志](https://github.com/Chuyu-Team/YY-Thunks/releases)
See the [releases Changelog](https://github.com/Chuyu-Team/YY-Thunks/releases)
100 changes: 100 additions & 0 deletions Readme.ocs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# YY-Thunks - 让兼容 Windows 更轻松
[![license](https://img.shields.io/github/license/Chuyu-Team/YY-Thunks)](https://github.com/Chuyu-Team/YY-Thunks/blob/master/LICENSE)
[![downloads](https://img.shields.io/github/downloads/Chuyu-Team/YY-Thunks/total)](https://github.com/Chuyu-Team/YY-Thunks/releases)
[![contributors](https://img.shields.io/github/contributors-anon/Chuyu-Team/YY-Thunks)](https://github.com/Chuyu-Team/YY-Thunks/graphs/contributors)
[![release](https://img.shields.io/github/v/release/Chuyu-Team/YY-Thunks?include_prereleases)](https://github.com/Chuyu-Team/YY-Thunks/releases)
[![nuget](https://img.shields.io/nuget/vpre/YY-Thunks)](https://www.nuget.org/packages/YY-Thunks)
[![Build&Test](https://github.com/Chuyu-Team/YY-Thunks/actions/workflows/Build&Test.yml/badge.svg)](https://github.com/Chuyu-Team/YY-Thunks/actions/workflows/Build&Test.yml)

## 1. 关于 YY-Thunks

众所周知,从 Windows 的每次更新又会新增大量 API,这使得兼容不同版本的 Windows
需要花费很大精力。导致现在大量开源项目已经不再兼容一些早期的 Windows 版本,比如
Windows XP RTM。

难道就没有一种快速高效的方案解决无法定位程序输入点的问题吗?

YY-Thunks(鸭船),存在的目的就是抹平不同系统的差异,编译时单纯添加一个 obj
即可自动解决这些兼容性问题。让你兼容旧版本 Windows 更轻松!

[ [鸭船交流群 633710173](https://shang.qq.com/wpa/qunwpa?idkey=21d51d8ad1d77b99ea9544b399e080ec347ca6a1bc04267fb59cebf22644a42a) ]

### 1.1. 原理

使用 `LoadLibrary` 以及 `GetProcAddress` 动态加载 API,不存在时做出补偿措施,
最大限度模拟原始 API 行为,让你的程序正常运行。大概就像下面这个`GetTickCount64`函数:

```cpp
// 注意:Windows XP 不支持 GetTickCount64
ULONGLONG WINAPI GetTickCount64(VOID)
{
if (auto const _pfnGetTickCount64 = try_get_GetTickCount64())
{
return _pfnGetTickCount64();
}
// Fallback
return GetTickCount();
}
```
### 1.2. 亮点
* 更快!更安全!`鸭船`内建2级缓存以及按需加载机制,同时自动加密所有函数指针,
防止内存爆破攻击。最大程度减少不需要和不必要的 `LoadLibrary` 以及
`GetProcAddress` 调用以及潜在安全风险。
* 轻松兼容 Windows XP,让你安心专注于业务逻辑。
* 完全开源且广泛接受用户意见,希望大家能踊跃的创建 PR,为`鸭船`添砖加瓦。
## 2. 使用方法
大家可以在以下方案中任选一种,但是我们优先推荐 NuGet 方案,因为NuGet采用傻瓜式设计,使用更便捷。
### 2.1. NuGet(推荐)
#### 2.1.1. C++项目
1. 项目右键 “管理 NuGet 程序包”。
2. NuGet搜索框中输入:`YY-Thunks`,搜索后点击安装。
3. 项目右键 - 属性 - YY-Thunks 中,自行调整YY-Thunks等级,允许 Windows 2000,
Windows XP 以及 Windows Vista(默认)。
4. 重新编译代码
#### 2.1.2. .NET Native AOT项目
1. 给`TargetFramework`添加`Windows`系统平台,比如修改为`net8.0-windows`或者`net9.0-windows`。
2. 项目右键 `管理 NuGet 程序包`。
3. NuGet搜索框中输入:`YY-Thunks`,搜索后点击安装。
4. 默认兼容到Windows Vista(默认),如果需要兼容Windows XP可以将`WindowsSupportedOSPlatformVersion`调整为`5.1`。
### 2.2. 手工配置
1. 下载 [YY-Thunks-Binary](https://github.com/Chuyu-Team/YY-Thunks/releases),
然后解压到你的工程目录。
2. 【链接器】-【输入】-【附加依赖项】,添加
`objs\$(PlatformShortName)\YY_Thunks_for_WinXP.obj`。
3. 【链接器】-【系统】-【所需的最低版本】,根据实际情况填写 `5.01`(WinXP 32位) 或者 `5.02`(WinXP x64、2003)。
4. 如果是编译DLL,那么【链接器】-【高级】-【自定义入口点】更改为`DllMainCRTStartupForYY_Thunks`(不这样做XP下使用thread_local可能崩溃!)
5. 重新编译代码。
> 温馨提示:如果需要兼容 Vista,【所需的最低版本】无需修改,但是【附加依赖项】请选择
`objs\$(PlatformShortName)\YY_Thunks_for_Vista.obj`。
## 3. 兼容性
### 3.1. 支持的编译器
全平台ABI兼容。
* 所有Visual Studio版本均支持
(比如:VC6.0、VS2008、VS2010、VS2015、VS2017、VS2019、VS2022等等)。
* 所有运行库模式均支持(比如:`/MD`、`/MT`、`/MDd`、`/MTd`)。
### 3.2. SDK版本要求
至少需要SDK 6.0(VS2008默认附带)
> 温馨提示:VC6.0、VS2005用户请注意,由于这些编译器默认附带的SDK版本太低。请先将SDK升级到6.0或者更高版本,然后再使用YY-Thunks,否则将发生链接失败!
高版本的SDK不影响对老系统的兼容性,请坐和放宽,安心升级。
### 3.3. Thunks 清单
请参阅 [ThunksList.md](ThunksList.md)
## 4. 更新日志
请参阅 [releases 更新日志](https://github.com/Chuyu-Team/YY-Thunks/releases)
12 changes: 6 additions & 6 deletions src/Build.cmd
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
@echo off
@echo off
setlocal

::需要设置LibMaker.exe路径到环境变量Path。
::如果你需要LibMaker.exe,请自行到 初雨开源项目交流QQ群(633710173)群文件中下载。
::需要设置LibMaker.exe路径到环境变量Path。
::如果你需要LibMaker.exe,请自行到 初雨开源项目交流QQ群(633710173)群文件中下载。

pushd "%~dp0.."

Expand All @@ -12,7 +12,7 @@ if "%Platform%"=="" set Platform=x86

md "objs\\%Platform%"

::先生成 YY_Thunks_List.hpp
::先生成 YY_Thunks_List.hpp
msbuild "%~dp0YY-Thunks.UnitTest\YY-Thunks.UnitTest.vcxproj" -t:Build_YY_Thunks_List_hpp

call:Build%Platform%
Expand All @@ -26,8 +26,8 @@ goto:eof
:BuildObj
cl /O1 /Os /Oi /GS- /std:c++17 /arch:IA32 /Z7 /MT /Fo"objs\\%Platform%\\%1" /Zl /c /D "NDEBUG" /D "YY_Thunks_Support_Version=%2" "%~dp0Thunks\YY_Thunks.cpp"

::进行函数名称进行修正 __imp__%s_%u -> __imp__%s@%u
LibMaker.exe FixObj "%~dp0..\\objs\\%Platform%\\%1" /WeakExternFix:__security_cookie=%PointType% /WeakExternFix:__YY_Thunks_Process_Terminating=4 /WeakExternFix:__acrt_atexit_table=%PointType%
::进行函数名称进行修正 __imp__%s_%u -> __imp__%s@%u
LibMaker.exe FixObj "%~dp0..\\objs\\%Platform%\\%1" /WeakExternFix:__security_cookie=%PointType% /WeakExternFix:__YY_Thunks_Process_Terminating=4 /WeakExternFix:__acrt_atexit_table=%PointType% /WeakExternFix:__pfnDllMainCRTStartupForYY_Thunks=%PointType%

LibMaker.exe AppendWeak /MACHINE:%Platform% /DEF:"%~dp0def\\%Platform%\\PSAPI2Kernel32.def" /OUT:"%~dp0..\\objs\\%Platform%\\%1"

Expand Down
Loading

0 comments on commit 61c5216

Please sign in to comment.