Skip to content

Commit

Permalink
Opt, 使用匿名空间隐藏减少不必要的公开符号
Browse files Browse the repository at this point in the history
  • Loading branch information
mingkuang-Chuyu committed May 20, 2024
1 parent 45f19fa commit 0bce0d8
Show file tree
Hide file tree
Showing 10 changed files with 4,558 additions and 4,553 deletions.
14 changes: 7 additions & 7 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 @@ -24,9 +24,9 @@ goto:eof

:: BuildObj YY_Thunks_for_Vista.obj NTDDI_WIN6
:BuildObj
cl /O1 /Os /Oi /GS- /arch:IA32 /Z7 /MT /Fo"objs\\%Platform%\\%1" /Zl /c /D "NDEBUG" /D "YY_Thunks_Support_Version=%2" "%~dp0Thunks\YY_Thunks.cpp"
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
::进行函数名称进行修正 __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%

LibMaker.exe AppendWeak /MACHINE:%Platform% /DEF:"%~dp0def\\%Platform%\\PSAPI2Kernel32.def" /OUT:"%~dp0..\\objs\\%Platform%\\%1"
Expand Down Expand Up @@ -58,4 +58,4 @@ goto:eof
:Buildarm64
set PointType=8
call:BuildObj YY_Thunks_for_Win10_RS3.obj NTDDI_WIN10_RS3
goto:eof
goto:eof
207 changes: 102 additions & 105 deletions src/Shared/HookThunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,143 +4,140 @@
跨模块ABI兼容的Thunk逻辑。
*/

namespace YY
namespace YY::Thunks::internal
{
namespace Thunks
namespace
{
namespace internal
union HookThunkData
{
union HookThunkData
private:
static HookThunkData* volatile pFreeRoot;
// Windows最小地址管理粒度是64K,所以我们就直接申请一个64K
static constexpr size_t kAllocBufferBytesCount = 64 * 1024;

public:
HookThunkData* volatile pNext;
// 可以供内存执行权限的一段区域
struct
{
private:
static HookThunkData* volatile pFreeRoot;
// Windows最小地址管理粒度是64K,所以我们就直接申请一个64K
static constexpr size_t kAllocBufferBytesCount = 64 * 1024;

public:
HookThunkData* volatile pNext;
// 可以供内存执行权限的一段区域
struct
{
unsigned char ShellCode[60];
// 内存块的引用计数。
// 1. 如果是Buffer第一块内存的引用计数,那么引用归零时彻底释放整个缓冲区。
// 2. 如果不是Buffer第一块内存的引用计数,引用归零时减少一次该缓冲区第一块内存的引用计数。
ULONG uRef;
};

static HookThunkData* __fastcall Alloc()
unsigned char ShellCode[60];
// 内存块的引用计数。
// 1. 如果是Buffer第一块内存的引用计数,那么引用归零时彻底释放整个缓冲区。
// 2. 如果不是Buffer第一块内存的引用计数,引用归零时减少一次该缓冲区第一块内存的引用计数。
ULONG uRef;
};

static HookThunkData* __fastcall Alloc()
{
__declspec(allocate(".YYThr$AAB")) static void* s_FreeAllHookThunkData = reinterpret_cast<void*>(&HookThunkData::FreeAll);
__foreinclude(s_FreeAllHookThunkData);

for (auto _pLast = pFreeRoot; _pLast;)
{
__declspec(allocate(".YYThr$AAB")) static void* s_FreeAllHookThunkData = reinterpret_cast<void*>(&HookThunkData::FreeAll);
__foreinclude(s_FreeAllHookThunkData);
auto _pNext = _pLast->pNext;

for (auto _pLast = pFreeRoot; _pLast;)
auto _pResult = (HookThunkData*)InterlockedCompareExchange((volatile uintptr_t*)&pFreeRoot, (uintptr_t)_pNext, (uintptr_t)_pLast);
if (_pResult == _pLast)
{
auto _pNext = _pLast->pNext;

auto _pResult = (HookThunkData*)InterlockedCompareExchange((volatile uintptr_t*)&pFreeRoot, (uintptr_t)_pNext, (uintptr_t)_pLast);
if (_pResult == _pLast)
{
_pResult->pNext = nullptr;
_pResult->pNext = nullptr;

InterlockedIncrement(&_pResult->uRef);
return _pResult;
}
_pLast = _pResult;
InterlockedIncrement(&_pResult->uRef);
return _pResult;
}
_pLast = _pResult;
}

// 缓存区域已经耗尽,申请新的内存。
auto _pResult = (HookThunkData*)VirtualAlloc(nullptr, kAllocBufferBytesCount, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!_pResult)
return nullptr;
// 缓存区域已经耗尽,申请新的内存。
auto _pResult = (HookThunkData*)VirtualAlloc(nullptr, kAllocBufferBytesCount, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!_pResult)
return nullptr;

// 因为当前需要返回 _pResult,所以引用计数额外 + 1
_pResult->uRef = kAllocBufferBytesCount / sizeof(HookThunkData) + 1;
// 因为当前需要返回 _pResult,所以引用计数额外 + 1
_pResult->uRef = kAllocBufferBytesCount / sizeof(HookThunkData) + 1;

static_assert(kAllocBufferBytesCount % sizeof(HookThunkData) == 0, "");
// 因为等会需要返回一块内存,所以第一快内存我们就需要跳过,不添加到pFreeRoot了。
const auto _pFirstBuffer = _pResult + 1;
const auto _pLastBuffer = reinterpret_cast<HookThunkData*>((uintptr_t)_pResult + kAllocBufferBytesCount - sizeof(HookThunkData));
static_assert(kAllocBufferBytesCount % sizeof(HookThunkData) == 0, "");
// 因为等会需要返回一块内存,所以第一快内存我们就需要跳过,不添加到pFreeRoot了。
const auto _pFirstBuffer = _pResult + 1;
const auto _pLastBuffer = reinterpret_cast<HookThunkData*>((uintptr_t)_pResult + kAllocBufferBytesCount - sizeof(HookThunkData));

for (auto _pItem = _pFirstBuffer; ;)
{
_pItem->uRef = 1;
if (_pItem == _pLastBuffer)
break;
auto _pNext = _pItem + 1;
_pItem->pNext = _pNext;
_pItem = _pNext;
}
for (auto _pItem = _pFirstBuffer; ;)
{
_pItem->uRef = 1;
if (_pItem == _pLastBuffer)
break;
auto _pNext = _pItem + 1;
_pItem->pNext = _pNext;
_pItem = _pNext;
}

for (auto _pLast = pFreeRoot; ;)
for (auto _pLast = pFreeRoot; ;)
{
_pLastBuffer->pNext = _pLast;
auto _pResult = (HookThunkData*)InterlockedCompareExchange((volatile uintptr_t*)&pFreeRoot, (uintptr_t)_pFirstBuffer, (uintptr_t)_pLast);
if (_pResult == _pLast)
{
_pLastBuffer->pNext = _pLast;
auto _pResult = (HookThunkData*)InterlockedCompareExchange((volatile uintptr_t*)&pFreeRoot, (uintptr_t)_pFirstBuffer, (uintptr_t)_pLast);
if (_pResult == _pLast)
{
break;
}
_pLast = _pResult;
break;
}
return _pResult;
_pLast = _pResult;
}
return _pResult;
}

void __fastcall Free()
{
// 防止内存执行区域被人利用,数据全部清除!!
memset(ShellCode, 0, sizeof(ShellCode));
void __fastcall Free()
{
// 防止内存执行区域被人利用,数据全部清除!!
memset(ShellCode, 0, sizeof(ShellCode));

if (Release() == 0)
return;
if (Release() == 0)
return;

// 重新将内存加入缓存区域。
for (auto _pLast = pFreeRoot; ;)
// 重新将内存加入缓存区域。
for (auto _pLast = pFreeRoot; ;)
{
pNext = _pLast;
auto _pResult = (HookThunkData*)InterlockedCompareExchange((volatile uintptr_t*)&pFreeRoot, (uintptr_t)this, (uintptr_t)_pLast);
if (_pResult == _pLast)
{
pNext = _pLast;
auto _pResult = (HookThunkData*)InterlockedCompareExchange((volatile uintptr_t*)&pFreeRoot, (uintptr_t)this, (uintptr_t)_pLast);
if (_pResult == _pLast)
{
return;
}
_pLast = _pResult;
return;
}
_pLast = _pResult;
}
}

private:
static void __cdecl FreeAll() noexcept
private:
static void __cdecl FreeAll() noexcept
{
HookThunkData* _pRoot = (HookThunkData*)InterlockedExchange((volatile uintptr_t*)&pFreeRoot, (uintptr_t)nullptr);
for (auto _pItem = _pRoot; _pItem; )
{
HookThunkData* _pRoot = (HookThunkData*)InterlockedExchange((volatile uintptr_t*)&pFreeRoot, (uintptr_t)nullptr);
for (auto _pItem = _pRoot; _pItem; )
{
auto _pNext = _pItem->pNext;
_pItem->Release();
auto _pNext = _pItem->pNext;
_pItem->Release();

_pItem = _pNext;
}
_pItem = _pNext;
}
}

/// <summary>
/// 减少一次内存引用。
/// </summary>
/// <returns>返回新的引用计数。</returns>
ULONG __fastcall Release() noexcept
/// <summary>
/// 减少一次内存引用。
/// </summary>
/// <returns>返回新的引用计数。</returns>
ULONG __fastcall Release() noexcept
{
const auto _uNewRef = InterlockedDecrement(&uRef);
if (_uNewRef == 0)
{
const auto _uNewRef = InterlockedDecrement(&uRef);
if (_uNewRef == 0)
// 引用归0,这块内存可能来自于其他模块,并且目标模块已经释放。
auto _pFirstBlock = reinterpret_cast<HookThunkData*>(uintptr_t(this) & (~(kAllocBufferBytesCount - 1)));
if (_pFirstBlock == this || InterlockedDecrement(&_pFirstBlock->uRef) == 0)
{
// 引用归0,这块内存可能来自于其他模块,并且目标模块已经释放。
auto _pFirstBlock = reinterpret_cast<HookThunkData*>(uintptr_t(this) & (~(kAllocBufferBytesCount - 1)));
if (_pFirstBlock == this || InterlockedDecrement(&_pFirstBlock->uRef) == 0)
{
VirtualFree(_pFirstBlock, 0, MEM_RELEASE);
}
VirtualFree(_pFirstBlock, 0, MEM_RELEASE);
}

return _uNewRef;
}
};

HookThunkData* volatile HookThunkData::pFreeRoot = nullptr;
}
return _uNewRef;
}
};

HookThunkData* volatile HookThunkData::pFreeRoot = nullptr;
}
}
Loading

0 comments on commit 0bce0d8

Please sign in to comment.