-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ea255dc
commit 59a9538
Showing
24 changed files
with
367 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System.Runtime.InteropServices; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.Text; | ||
|
||
/// <summary>Provides helpers for parsing C# source code.</summary> | ||
public static unsafe class CSharpHelper | ||
{ | ||
/// <summary>Given some C# source text and a type name, determines the namespace of the type.</summary> | ||
[UnmanagedCallersOnly(EntryPoint = nameof(GetClassNamespace))] | ||
public static int GetClassNamespace(byte* pText, int textLength, byte* pClassName, void* state, delegate* unmanaged<byte*, void*, void> callback) | ||
{ | ||
using var text = new UnmanagedMemoryStream(pText, textLength); | ||
var className = Marshal.PtrToStringUTF8((nint)pClassName)!; | ||
|
||
try | ||
{ | ||
// Parse the source into a SyntaxTree and use NamespaceSyntaxWalker | ||
// to determine which namespace the requested class is located in. | ||
var tree = SyntaxFactory.ParseSyntaxTree(SourceText.From(text)); | ||
var walker = new NamespaceSyntaxWalker(className); | ||
walker.Visit(tree.GetRoot()); | ||
|
||
// Now we either have a namespace or an empty string. | ||
var namespaceName = Marshal.StringToCoTaskMemUTF8(walker.Namespace); | ||
|
||
try | ||
{ | ||
callback((byte*)namespaceName, state); | ||
} | ||
finally | ||
{ | ||
Marshal.FreeCoTaskMem(namespaceName); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
return Marshal.GetHRForException(ex); | ||
} | ||
|
||
return 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<Project> | ||
<PropertyGroup> | ||
<UseArtifactsOutput>true</UseArtifactsOutput> | ||
</PropertyGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
|
||
/// <summary>A <see cref="CSharpSyntaxWalker"/> implementation for locating the namespace of a class.</summary> | ||
public sealed class NamespaceSyntaxWalker : CSharpSyntaxWalker | ||
{ | ||
/// <summary>The name of the class to locate the namespace of.</summary> | ||
public string ClassName { get; } | ||
|
||
/// <summary>The namespace of the requested class.</summary> | ||
public string Namespace { get; private set; } | ||
|
||
/// <summary>Initializes a new <see cref="NamespaceSyntaxWalker"/> instance.</summary> | ||
/// <param name="className"></param> | ||
public NamespaceSyntaxWalker(string className) | ||
{ | ||
Namespace = string.Empty; | ||
ClassName = className; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override void Visit(SyntaxNode? node) | ||
{ | ||
if (node is TypeDeclarationSyntax type && type.Identifier.ValueText == ClassName) | ||
{ | ||
for (var parent = node.Parent; parent != null; parent = parent.Parent) | ||
{ | ||
// We don't want a nested type that happens to share its name | ||
// with the source file to result in a false-positive here. | ||
if (parent is TypeDeclarationSyntax) | ||
break; | ||
|
||
if (parent is BaseNamespaceDeclarationSyntax ns) | ||
{ | ||
Namespace = ns.Name.ToString(); | ||
return; | ||
} | ||
} | ||
} | ||
|
||
base.Visit(node); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
@echo off | ||
dotnet publish -c Release -r win-x64 -p:PublishAot=true -p:DebugType=none |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
cmake_minimum_required(VERSION 3.20) | ||
project(UnityNamespacePatch) | ||
|
||
# Find Microsoft Detours | ||
find_path(DETOURS_INCLUDE_DIRS detours.h PATH_SUFFIXES detours REQUIRED) | ||
find_library(DETOURS_LIBRARIES detours REQUIRED) | ||
|
||
# Find source files | ||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS "source/*.cpp") | ||
file(GLOB_RECURSE INCLUDES CONFIGURE_DEPENDS "include/*.h") | ||
|
||
# Initialize target | ||
set(TARGET_NAME "version") | ||
add_library(${TARGET_NAME} SHARED ${SOURCES} ${INCLUDES}) | ||
target_include_directories(${TARGET_NAME} PRIVATE include ${DETOURS_INCLUDE_DIRS}) | ||
target_link_directories(${TARGET_NAME} PRIVATE libraries) | ||
target_link_libraries(${TARGET_NAME} PRIVATE delayimp dbghelp pathcch Unity CSharpHelper ${DETOURS_LIBRARIES}) | ||
|
||
# Enable delay loading for Unity | ||
target_link_options(${TARGET_NAME} PRIVATE "/DELAYLOAD:Unity.exe") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
@echo off | ||
cmake -G "Visual Studio 17 2022" -A x64 -B build -DCMAKE_TOOLCHAIN_FILE="%VCPKG_ROOT%\scripts\buildsystems\vcpkg.cmake" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
@echo off | ||
pushd libraries | ||
for %%f in (*.def) do ( | ||
lib /MACHINE:X64 /DEF:%%~nxf /OUT:%%~nf.lib | ||
) | ||
popd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#pragma once | ||
#include <Windows.h> | ||
|
||
extern "C" HRESULT GetClassNamespace(const char* text, int textLen, const char* className, void* state, void(*callback)(const char*, void*)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#pragma once | ||
#include "basic_string.h" | ||
#include "dynamic_array.h" | ||
|
||
namespace CSharpParser | ||
{ | ||
core::string GetClassAndNamespace(const core::string& text, core::string& className, core::string& namespaceName, int& errorLine, const dynamic_array<core::string>* defines); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#pragma once | ||
|
||
enum MemLabelIdentifier | ||
{ | ||
}; | ||
|
||
struct AllocationRootWithSalt | ||
{ | ||
unsigned m_Salt; | ||
unsigned m_RootReferenceIndex; | ||
}; | ||
|
||
struct MemLabelId | ||
{ | ||
AllocationRootWithSalt m_RootReferenceWithSalt; | ||
MemLabelIdentifier identifier; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#pragma once | ||
#include "MemLabelId.h" | ||
|
||
namespace core | ||
{ | ||
template<class T> | ||
class StringStorageDefault | ||
{ | ||
enum | ||
{ | ||
kInternalBufferCapacity = 0xF, | ||
}; | ||
protected: | ||
T* m_data; | ||
|
||
union | ||
{ | ||
size_t m_capacity; | ||
T m_internal[(kInternalBufferCapacity + 1) / sizeof(T)]; | ||
}; | ||
|
||
size_t m_size; | ||
MemLabelId m_label; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#pragma once | ||
|
||
void InitSymbolHandler(); | ||
void ReleaseSymbolHandler(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#pragma once | ||
#include "MemLabelId.h" | ||
#include "StringStorageDefault.h" | ||
|
||
namespace core | ||
{ | ||
template<class T, class TStorage = StringStorageDefault<T>> | ||
class basic_string : TStorage | ||
{ | ||
public: | ||
basic_string() = default; | ||
const T* c_str() const; | ||
size_t length() const; | ||
basic_string& operator=(const T* copyStr); | ||
static basic_string create_from_external(const T* referenceStr, const MemLabelId& label); | ||
static basic_string create_from_external(const T* referenceStr, size_t referenceStrLen, const MemLabelId& label); | ||
}; | ||
|
||
using string = basic_string<char>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#pragma once | ||
#include "MemLabelId.h" | ||
|
||
struct dynamic_array_detail | ||
{ | ||
void* m_ptr; | ||
MemLabelId m_label; | ||
size_t m_size; | ||
size_t m_capacity; | ||
}; | ||
|
||
template<typename T, int = 0> | ||
struct dynamic_array : dynamic_array_detail | ||
{ | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
NAME "CSharpHelper.dll" | ||
EXPORTS | ||
GetClassNamespace |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
NAME "Unity.exe" | ||
EXPORTS | ||
?GetClassAndNamespace@CSharpParser@@YA?AV?$basic_string@DV?$StringStorageDefault@D@core@@@core@@AEBV23@AEAV23@1AEAHPEBU?$dynamic_array@V?$basic_string@DV?$StringStorageDefault@D@core@@@core@@$0A@@@@Z | ||
??$?0PEBD@?$basic_string@DV?$StringStorageDefault@D@core@@@core@@QEAA@PEBD0AEBUMemLabelId@@@Z | ||
??4?$basic_string@DV?$StringStorageDefault@D@core@@@core@@QEAAAEAV01@PEBD@Z | ||
?c_str@?$basic_string@DV?$StringStorageDefault@D@core@@@core@@QEBAPEBDXZ | ||
?create_from_external@?$basic_string@DV?$StringStorageDefault@D@core@@@core@@SA?AV12@PEBD_KAEBUMemLabelId@@@Z | ||
?create_from_external@?$basic_string@DV?$StringStorageDefault@D@core@@@core@@SA?AV12@PEBDAEBUMemLabelId@@@Z | ||
?length@?$basic_string@DV?$StringStorageDefault@D@core@@@core@@QEBA_KXZ | ||
?kMemString@@3UMemLabelId@@A |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include <Windows.h> | ||
#include <DbgHelp.h> | ||
#include <delayimp.h> | ||
#include "SymbolHandler.h" | ||
|
||
FARPROC WINAPI DliNotifyHook(unsigned dliNotify, PDelayLoadInfo pdli) | ||
{ | ||
switch (dliNotify) | ||
{ | ||
case dliNoteStartProcessing: | ||
InitSymbolHandler(); | ||
break; | ||
case dliNotePreGetProcAddress: | ||
if (pdli->dlp.fImportByName) | ||
{ | ||
SYMBOL_INFO Symbol{}; | ||
Symbol.SizeOfStruct = sizeof(Symbol); | ||
|
||
if (SymFromName(GetCurrentProcess(), pdli->dlp.szProcName, &Symbol)) | ||
{ | ||
return (FARPROC)Symbol.Address; | ||
} | ||
} | ||
break; | ||
case dliNoteEndProcessing: | ||
ReleaseSymbolHandler(); | ||
break; | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
ExternC const PfnDliHook __pfnDliNotifyHook2 = DliNotifyHook; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#include <Windows.h> | ||
#include <DbgHelp.h> | ||
#include <PathCch.h> | ||
#include "SymbolHandler.h" | ||
|
||
static ULONG g_SymbolHandlerRef = 0; | ||
|
||
void InitSymbolHandler() | ||
{ | ||
if (InterlockedIncrement(&g_SymbolHandlerRef) == 1) | ||
{ | ||
WCHAR UserSearchPath[MAX_PATH]; | ||
GetModuleFileNameW(GetModuleHandle(NULL), UserSearchPath, MAX_PATH); | ||
PathCchRemoveFileSpec(UserSearchPath, MAX_PATH); | ||
SymSetOptions(SYMOPT_IGNORE_CVREC); | ||
SymInitializeW(GetCurrentProcess(), UserSearchPath, TRUE); | ||
} | ||
} | ||
|
||
void ReleaseSymbolHandler() | ||
{ | ||
if (InterlockedDecrement(&g_SymbolHandlerRef) == 0) | ||
{ | ||
SymCleanup(GetCurrentProcess()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#include <Windows.h> | ||
#include <DbgHelp.h> | ||
#include <detours.h> | ||
#include "CSharpHelper.h" | ||
#include "CSharpParser.h" | ||
#include "SymbolHandler.h" | ||
#include <string> | ||
|
||
BOOL AttachGetClassAndNamespaceDetour() | ||
{ | ||
static decltype(&CSharpParser::GetClassAndNamespace) Pointer; | ||
static decltype(Pointer) Detour = [](const core::string& text, core::string& className, core::string& namespaceName, int& errorLine, const dynamic_array<core::string> *defines) | ||
{ | ||
errorLine = -1; | ||
|
||
GetClassNamespace(text.c_str(), text.length(), className.c_str(), &namespaceName, [](auto namespaceName, auto state) | ||
{ | ||
*(core::string*)state = namespaceName; | ||
}); | ||
|
||
// Return value is an error message string. | ||
return core::string{}; | ||
}; | ||
|
||
SYMBOL_INFO Symbol{}; | ||
Symbol.SizeOfStruct = sizeof(Symbol); | ||
|
||
if (!SymFromName(GetCurrentProcess(), "?GetClassAndNamespace@CSharpParser@@YA?AV?$basic_string@DV?$StringStorageDefault@D@core@@@core@@AEBV23@AEAV23@1AEAHPEBU?$dynamic_array@V?$basic_string@DV?$StringStorageDefault@D@core@@@core@@$0A@@@@Z", &Symbol)) | ||
return FALSE; | ||
|
||
*(ULONG64*)&Pointer = Symbol.Address; | ||
DetourAttach((void**)&Pointer, Detour); | ||
return TRUE; | ||
} | ||
|
||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | ||
{ | ||
if (fdwReason != DLL_PROCESS_ATTACH) | ||
return TRUE; | ||
|
||
InitSymbolHandler(); | ||
DetourTransactionBegin(); | ||
AttachGetClassAndNamespaceDetour(); | ||
DetourTransactionCommit(); | ||
ReleaseSymbolHandler(); | ||
return TRUE; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#pragma comment(linker, "/export:GetFileVersionInfoA=C:\\Windows\\System32\\version.GetFileVersionInfoA") | ||
#pragma comment(linker, "/export:GetFileVersionInfoByHandle=C:\\Windows\\System32\\version.GetFileVersionInfoByHandle") | ||
#pragma comment(linker, "/export:GetFileVersionInfoExA=C:\\Windows\\System32\\version.GetFileVersionInfoExA") | ||
#pragma comment(linker, "/export:GetFileVersionInfoExW=C:\\Windows\\System32\\version.GetFileVersionInfoExW") | ||
#pragma comment(linker, "/export:GetFileVersionInfoSizeA=C:\\Windows\\System32\\version.GetFileVersionInfoSizeA") | ||
#pragma comment(linker, "/export:GetFileVersionInfoSizeExA=C:\\Windows\\System32\\version.GetFileVersionInfoSizeExA") | ||
#pragma comment(linker, "/export:GetFileVersionInfoSizeExW=C:\\Windows\\System32\\version.GetFileVersionInfoSizeExW") | ||
#pragma comment(linker, "/export:GetFileVersionInfoSizeW=C:\\Windows\\System32\\version.GetFileVersionInfoSizeW") | ||
#pragma comment(linker, "/export:GetFileVersionInfoW=C:\\Windows\\System32\\version.GetFileVersionInfoW") | ||
#pragma comment(linker, "/export:VerFindFileA=C:\\Windows\\System32\\version.VerFindFileA") | ||
#pragma comment(linker, "/export:VerFindFileW=C:\\Windows\\System32\\version.VerFindFileW") | ||
#pragma comment(linker, "/export:VerInstallFileA=C:\\Windows\\System32\\version.VerInstallFileA") | ||
#pragma comment(linker, "/export:VerInstallFileW=C:\\Windows\\System32\\version.VerInstallFileW") | ||
#pragma comment(linker, "/export:VerLanguageNameA=C:\\Windows\\System32\\version.VerLanguageNameA") | ||
#pragma comment(linker, "/export:VerLanguageNameW=C:\\Windows\\System32\\version.VerLanguageNameW") | ||
#pragma comment(linker, "/export:VerQueryValueA=C:\\Windows\\System32\\version.VerQueryValueA") | ||
#pragma comment(linker, "/export:VerQueryValueW=C:\\Windows\\System32\\version.VerQueryValueW") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Unity Namespace Patch | ||
An experimental patch for Unity 2021.x that adds support for file-scoped namespaces. | ||
|
||
# Installation | ||
Copy `version.dll` and `CSharpHelper.dll` into the Unity editor folder (next to `Unity.exe`). |