Add DMM version.dll proxy hook for CGSS

Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
2026-06-20 08:08:30 +08:00
commit 58aa9be073
15 changed files with 683 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
build/
cgss-dmm-hook.log
+6
View File
@@ -0,0 +1,6 @@
[submodule "deps/minhook"]
path = deps/minhook
url = https://github.com/TsudaKageyu/minhook.git
[submodule "deps/rapidjson"]
path = deps/rapidjson
url = https://github.com/Tencent/rapidjson.git
+54
View File
@@ -0,0 +1,54 @@
cmake_minimum_required(VERSION 3.20)
project(cgss_http_hook LANGUAGES C CXX RC ASM_MASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_library(version SHARED
src/proxy.cpp
src/hook.cpp
src/log.cpp
src/il2cpp_symbols.cpp
src/version.rc
src/version.def
deps/minhook/src/buffer.c
deps/minhook/src/hook.c
deps/minhook/src/trampoline.c
deps/minhook/src/hde/hde64.c
)
target_include_directories(version PRIVATE
src
deps/minhook/include
deps/minhook/src
deps/minhook/src/hde
)
target_compile_definitions(version PRIVATE
NOMINMAX
WIN32_LEAN_AND_MEAN
)
target_link_libraries(version PRIVATE
user32
kernel32
)
set_target_properties(version PROPERTIES
OUTPUT_NAME "version"
PREFIX ""
)
if(MINGW)
target_compile_options(version PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>"
"$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>"
)
target_link_options(version PRIVATE
"-static-libgcc"
"-static-libstdc++"
)
endif()
+71
View File
@@ -0,0 +1,71 @@
TARGET := build/version.dll
BUILD_DIR := build
OBJ_DIR := $(BUILD_DIR)/obj
BUILD ?= release
CC := x86_64-w64-mingw32-gcc
CXX := x86_64-w64-mingw32-g++
WINDRES := x86_64-w64-mingw32-windres
INCLUDES := -Isrc -Ideps/minhook/include -Ideps/minhook/src -Ideps/minhook/src/hde
DEFINES := -DNOMINMAX -DWIN32_LEAN_AND_MEAN
CFLAGS := -std=gnu11 $(DEFINES) $(INCLUDES)
CXXFLAGS := -std=gnu++20 -fno-exceptions -fno-rtti $(DEFINES) $(INCLUDES)
LDFLAGS := -shared -static-libgcc -static-libstdc++
LDLIBS := -luser32 -lkernel32
ifeq ($(BUILD),debug)
DEFINES += -D_DEBUG
CFLAGS += -O0 -g
CXXFLAGS += -O0 -g
else
CFLAGS += -O2 -ffunction-sections -fdata-sections
CXXFLAGS += -O2 -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections -s
endif
C_SRCS := \
deps/minhook/src/buffer.c \
deps/minhook/src/hook.c \
deps/minhook/src/trampoline.c \
deps/minhook/src/hde/hde64.c
CXX_SRCS := \
src/proxy.cpp \
src/hook.cpp \
src/log.cpp \
src/il2cpp_symbols.cpp
RC_SRCS := src/version.rc
DEF_FILE := src/version.def
C_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(C_SRCS))
CXX_OBJS := $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(CXX_SRCS))
RC_OBJS := $(patsubst %.rc,$(OBJ_DIR)/%.res,$(RC_SRCS))
OBJS := $(C_OBJS) $(CXX_OBJS) $(RC_OBJS)
.PHONY: all release debug clean
all: $(TARGET)
release: $(TARGET)
debug:
$(MAKE) BUILD=debug
$(TARGET): $(OBJS) $(DEF_FILE)
@mkdir -p $(dir $@)
$(CXX) $(LDFLAGS) -o $@ $(OBJS) $(DEF_FILE) $(LDLIBS)
$(OBJ_DIR)/%.o: %.c
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c $< -o $@
$(OBJ_DIR)/%.o: %.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/%.res: %.rc
@mkdir -p $(dir $@)
$(WINDRES) $(DEFINES) $(INCLUDES) $< -O coff -o $@
clean:
rm -rf $(BUILD_DIR)
+34
View File
@@ -0,0 +1,34 @@
# cgss-http-hook
面向 Windows / DMM 版 CGSS 客户端的最小 `version.dll` 代理工程。
**用途**
- 转发 `UnityPlayer.dll` 实际导入的少量 `version.dll` 导出函数
- 等待 IL2CPP 运行时初始化稳定
- 运行时 hook `Stage.NetworkUtil.GetSchemeType()`,强制返回 `0`
**目录结构**
- `src/`:代理、日志、IL2CPP 符号解析、hook 逻辑
- `deps/minhook/`:内置的 MinHook 源码
**说明**
- 本项目不依赖 `Il2CppDumper``script.json`
- `GameAssembly.dll` 出现时,IL2CPP runtime 可能还不能安全访问,因此 hook 线程会额外等待一小段时间
- 运行时日志会写到游戏目录下的 `cgss-http-hook.log`
- 生成的 DLL 包含 Windows 版本资源,定义在 `src/version.rc`
**构建**
```sh
cmake -S . -B build -G Ninja -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \
-DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++
cmake --build build
```
**输出**
- `build/version.dll`
**使用方法**
1.`build/version.dll` 复制到 `imascgstage.exe` 同目录
2. 启动游戏
3. 如果 hook 未生效,查看 `cgss-http-hook.log`
Vendored Submodule
+1
Submodule deps/minhook added at d94c64d32e
Vendored Submodule
+1
Submodule deps/rapidjson added at 24b5e7a8b2
+121
View File
@@ -0,0 +1,121 @@
#include "stdinclude.hpp"
namespace {
using GetSchemeTypeFn = int (*)();
constexpr int kHttpSchemeType = 0;
constexpr DWORD kHookPollIntervalMs = 500;
constexpr DWORD kGameAssemblySettleDelayMs = 5000;
constexpr int kHookPollMaxAttempts = 600;
volatile LONG g_hook_installed = 0;
GetSchemeTypeFn g_orig_get_scheme_type = nullptr;
volatile LONG g_logged_gameassembly = 0;
volatile LONG g_exports_state = 0;
ULONGLONG g_gameassembly_seen_tick = 0;
volatile LONG g_scheme_hook_called = 0;
int get_scheme_type_hook() {
if (InterlockedCompareExchange(&g_scheme_hook_called, 1, 0) == 0) {
hook_log("[cgss-http-hook] GetSchemeType hook invoked");
}
return kHttpSchemeType;
}
void patch_custom_preference_scheme() {
auto custom_preference = il2cpp_symbols::get_class(
"Assembly-CSharp.dll", "Cute", "CustomPreference"
);
if (!custom_preference) {
hook_log("[cgss-http-hook] failed to resolve Cute.CustomPreference");
return;
}
if (il2cpp_symbols::set_static_int_field(custom_preference, "_schemeType", kHttpSchemeType)) {
hook_log("[cgss-http-hook] patched Cute.CustomPreference._schemeType=0");
} else {
hook_log("[cgss-http-hook] failed to patch Cute.CustomPreference._schemeType");
}
}
void try_install_hook() {
if (InterlockedCompareExchange(&g_hook_installed, 1, 1) != 0) {
return;
}
auto game_assembly = GetModuleHandleW(L"GameAssembly.dll");
if (!game_assembly) {
return;
}
if (InterlockedCompareExchange(&g_logged_gameassembly, 1, 0) == 0) {
hook_log("[cgss-http-hook] GameAssembly.dll loaded");
g_gameassembly_seen_tick = GetTickCount64();
}
if (g_gameassembly_seen_tick != 0 &&
GetTickCount64() - g_gameassembly_seen_tick < kGameAssemblySettleDelayMs) {
return;
}
il2cpp_symbols::init(game_assembly);
if (!il2cpp_symbols::ready()) {
if (InterlockedCompareExchange(&g_exports_state, 1, 0) == 0) {
hook_log("[cgss-http-hook] il2cpp exports not ready");
}
return;
}
LONG prev_exports_state = InterlockedExchange(&g_exports_state, 2);
if (prev_exports_state != 2) {
hook_log("[cgss-http-hook] il2cpp exports ready");
}
patch_custom_preference_scheme();
auto addr = il2cpp_symbols::get_method_pointer(
"Assembly-CSharp.dll", "Stage", "NetworkUtil", "GetSchemeType", 0
);
if (!addr) {
hook_log("[cgss-http-hook] failed to resolve Stage.NetworkUtil.GetSchemeType");
return;
}
auto mh_status = MH_Initialize();
if (mh_status != MH_OK && mh_status != MH_ERROR_ALREADY_INITIALIZED) {
hook_log("[cgss-http-hook] MH_Initialize failed");
return;
}
auto create_status = MH_CreateHook(
reinterpret_cast<void*>(addr),
reinterpret_cast<void*>(&get_scheme_type_hook),
reinterpret_cast<void**>(&g_orig_get_scheme_type)
);
if (create_status != MH_OK && create_status != MH_ERROR_ALREADY_CREATED) {
hook_log("[cgss-http-hook] MH_CreateHook failed");
return;
}
auto enable_status = MH_EnableHook(reinterpret_cast<void*>(addr));
if (enable_status != MH_OK && enable_status != MH_ERROR_ENABLED) {
hook_log("[cgss-http-hook] MH_EnableHook failed");
return;
}
InterlockedExchange(&g_hook_installed, 1);
hook_log("[cgss-http-hook] hooked Stage.NetworkUtil.GetSchemeType");
}
DWORD WINAPI init_thread(void*) {
for (int i = 0; i < kHookPollMaxAttempts; ++i) {
try_install_hook();
if (InterlockedCompareExchange(&g_hook_installed, 1, 1) != 0) {
return 0;
}
Sleep(kHookPollIntervalMs);
}
hook_log("[cgss-http-hook] timed out waiting for hook target");
return 0;
}
}
void start_hook_thread() {
CreateThread(nullptr, 0, init_thread, nullptr, 0, nullptr);
}
+133
View File
@@ -0,0 +1,133 @@
#include "stdinclude.hpp"
il2cpp_domain_get_t il2cpp_symbols::il2cpp_domain_get = nullptr;
il2cpp_domain_assembly_open_t il2cpp_symbols::il2cpp_domain_assembly_open = nullptr;
il2cpp_assembly_get_image_t il2cpp_symbols::il2cpp_assembly_get_image = nullptr;
il2cpp_class_from_name_t il2cpp_symbols::il2cpp_class_from_name = nullptr;
il2cpp_class_get_method_from_name_t il2cpp_symbols::il2cpp_class_get_method_from_name = nullptr;
il2cpp_class_get_methods_t il2cpp_symbols::il2cpp_class_get_methods = nullptr;
il2cpp_class_get_field_from_name_t il2cpp_symbols::il2cpp_class_get_field_from_name = nullptr;
il2cpp_method_get_name_t il2cpp_symbols::il2cpp_method_get_name = nullptr;
il2cpp_thread_attach_t il2cpp_symbols::il2cpp_thread_attach = nullptr;
il2cpp_thread_current_t il2cpp_symbols::il2cpp_thread_current = nullptr;
il2cpp_runtime_class_init_t il2cpp_symbols::il2cpp_runtime_class_init = nullptr;
il2cpp_field_get_flags_t il2cpp_symbols::il2cpp_field_get_flags = nullptr;
il2cpp_field_static_set_value_t il2cpp_symbols::il2cpp_field_static_set_value = nullptr;
void* il2cpp_symbols::il2cpp_domain = nullptr;
namespace {
template <typename T>
void resolve(HMODULE module, const char* name, T& out) {
out = reinterpret_cast<T>(GetProcAddress(module, name));
}
}
void il2cpp_symbols::init(HMODULE game_module) {
resolve(game_module, "il2cpp_domain_get", il2cpp_domain_get);
resolve(game_module, "il2cpp_domain_assembly_open", il2cpp_domain_assembly_open);
resolve(game_module, "il2cpp_assembly_get_image", il2cpp_assembly_get_image);
resolve(game_module, "il2cpp_class_from_name", il2cpp_class_from_name);
resolve(game_module, "il2cpp_class_get_method_from_name", il2cpp_class_get_method_from_name);
resolve(game_module, "il2cpp_class_get_methods", il2cpp_class_get_methods);
resolve(game_module, "il2cpp_class_get_field_from_name", il2cpp_class_get_field_from_name);
resolve(game_module, "il2cpp_method_get_name", il2cpp_method_get_name);
resolve(game_module, "il2cpp_thread_attach", il2cpp_thread_attach);
resolve(game_module, "il2cpp_thread_current", il2cpp_thread_current);
resolve(game_module, "il2cpp_runtime_class_init", il2cpp_runtime_class_init);
resolve(game_module, "il2cpp_field_get_flags", il2cpp_field_get_flags);
resolve(game_module, "il2cpp_field_static_set_value", il2cpp_field_static_set_value);
}
bool il2cpp_symbols::ready() {
return il2cpp_domain_get && il2cpp_domain_assembly_open && il2cpp_assembly_get_image &&
il2cpp_class_from_name && il2cpp_class_get_method_from_name &&
il2cpp_class_get_field_from_name && il2cpp_thread_attach &&
il2cpp_runtime_class_init && il2cpp_field_get_flags && il2cpp_field_static_set_value;
}
bool il2cpp_symbols::domain_ready() {
if (!il2cpp_domain_get) {
return false;
}
if (!il2cpp_domain) {
il2cpp_domain = il2cpp_domain_get();
}
return il2cpp_domain != nullptr;
}
bool il2cpp_symbols::attach_thread() {
if (!ready()) {
return false;
}
if (!domain_ready()) {
return false;
}
if (il2cpp_thread_current && il2cpp_thread_current()) {
return true;
}
il2cpp_thread_attach(il2cpp_domain);
return true;
}
void* il2cpp_symbols::get_class(const char* assembly_name, const char* namespaze, const char* klass_name) {
if (!attach_thread()) {
hook_log("[cgss-http-hook] il2cpp domain not ready");
return nullptr;
}
if (!ready() || !il2cpp_domain) {
return nullptr;
}
auto assembly = il2cpp_domain_assembly_open(il2cpp_domain, assembly_name);
if (!assembly) {
hook_log("[cgss-http-hook] assembly not found");
return nullptr;
}
auto image = il2cpp_assembly_get_image(assembly);
if (!image) {
hook_log("[cgss-http-hook] image not found");
return nullptr;
}
auto klass = il2cpp_class_from_name(image, namespaze, klass_name);
if (!klass) {
hook_log("[cgss-http-hook] class not found");
return nullptr;
}
return klass;
}
bool il2cpp_symbols::set_static_int_field(void* klass, const char* field_name, int value) {
if (!klass || !field_name || !attach_thread()) {
return false;
}
il2cpp_runtime_class_init(klass);
auto field = il2cpp_class_get_field_from_name(klass, field_name);
if (!field) {
hook_log("[cgss-http-hook] field not found");
return false;
}
auto flags = il2cpp_field_get_flags(field);
if ((flags & 0x10U) == 0) {
hook_log("[cgss-http-hook] field is not static");
return false;
}
il2cpp_field_static_set_value(field, &value);
return true;
}
uintptr_t il2cpp_symbols::get_method_pointer(const char* assembly_name, const char* namespaze,
const char* klass_name, const char* method_name, int args_count) {
auto klass = get_class(assembly_name, namespaze, klass_name);
if (!klass) {
return 0;
}
auto method = il2cpp_class_get_method_from_name(klass, method_name, args_count);
if (!method) {
hook_log("[cgss-http-hook] method not found");
return 0;
}
return method->methodPointer;
}
+67
View File
@@ -0,0 +1,67 @@
#pragma once
#include <stdint.h>
struct MethodInfo;
struct FieldInfo;
typedef void* (*il2cpp_domain_get_t)();
typedef void* (*il2cpp_domain_assembly_open_t)(void* domain, const char* name);
typedef void* (*il2cpp_assembly_get_image_t)(void* assembly);
typedef void* (*il2cpp_class_from_name_t)(void* image, const char* namespaze, const char* name);
typedef MethodInfo* (*il2cpp_class_get_method_from_name_t)(void* klass, const char* name, int argsCount);
typedef MethodInfo* (*il2cpp_class_get_methods_t)(void* klass, void** iter);
typedef FieldInfo* (*il2cpp_class_get_field_from_name_t)(void* klass, const char* name);
typedef const char* (*il2cpp_method_get_name_t)(MethodInfo* method);
typedef void (*il2cpp_thread_attach_t)(void* domain);
typedef void* (*il2cpp_thread_current_t)();
typedef void (*il2cpp_runtime_class_init_t)(void* klass);
typedef uint32_t (*il2cpp_field_get_flags_t)(FieldInfo* field);
typedef void (*il2cpp_field_static_set_value_t)(FieldInfo* field, void* value);
struct MethodInfo
{
uintptr_t methodPointer;
uintptr_t invoker_method;
const char* name;
uintptr_t klass;
const void* return_type;
const void* parameters;
uintptr_t methodDefinition;
uintptr_t genericContainer;
uint32_t token;
uint16_t flags;
uint16_t iflags;
uint16_t slot;
uint8_t parameters_count;
uint8_t is_generic : 1;
uint8_t is_inflated : 1;
uint8_t wrapper_type : 1;
uint8_t is_marshaled_from_native : 1;
};
namespace il2cpp_symbols {
extern il2cpp_domain_get_t il2cpp_domain_get;
extern il2cpp_domain_assembly_open_t il2cpp_domain_assembly_open;
extern il2cpp_assembly_get_image_t il2cpp_assembly_get_image;
extern il2cpp_class_from_name_t il2cpp_class_from_name;
extern il2cpp_class_get_method_from_name_t il2cpp_class_get_method_from_name;
extern il2cpp_class_get_methods_t il2cpp_class_get_methods;
extern il2cpp_class_get_field_from_name_t il2cpp_class_get_field_from_name;
extern il2cpp_method_get_name_t il2cpp_method_get_name;
extern il2cpp_thread_attach_t il2cpp_thread_attach;
extern il2cpp_thread_current_t il2cpp_thread_current;
extern il2cpp_runtime_class_init_t il2cpp_runtime_class_init;
extern il2cpp_field_get_flags_t il2cpp_field_get_flags;
extern il2cpp_field_static_set_value_t il2cpp_field_static_set_value;
extern void* il2cpp_domain;
void init(HMODULE game_module);
bool ready();
bool domain_ready();
bool attach_thread();
void* get_class(const char* assembly_name, const char* namespaze, const char* klass_name);
bool set_static_int_field(void* klass, const char* field_name, int value);
uintptr_t get_method_pointer(const char* assembly_name, const char* namespaze,
const char* klass_name, const char* method_name, int args_count);
}
+55
View File
@@ -0,0 +1,55 @@
#include "stdinclude.hpp"
namespace {
HANDLE g_log_file = INVALID_HANDLE_VALUE;
HANDLE get_log_file() {
if (g_log_file != INVALID_HANDLE_VALUE) {
return g_log_file;
}
char path[MAX_PATH] = {};
DWORD len = GetModuleFileNameA(nullptr, path, MAX_PATH);
if (len == 0 || len >= MAX_PATH) {
return INVALID_HANDLE_VALUE;
}
char* last_sep = path;
for (char* p = path; *p != '\0'; ++p) {
if (*p == '\\' || *p == '/') {
last_sep = p;
}
}
*last_sep = '\0';
lstrcatA(path, "\\cgss-http-hook.log");
g_log_file = CreateFileA(
path,
FILE_APPEND_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
return g_log_file;
}
}
void hook_log(const char* message) {
if (!message) {
return;
}
OutputDebugStringA(message);
OutputDebugStringA("\r\n");
HANDLE log_file = get_log_file();
if (log_file == INVALID_HANDLE_VALUE) {
return;
}
DWORD ignored = 0;
WriteFile(log_file, message, lstrlenA(message), &ignored, nullptr);
WriteFile(log_file, "\r\n", 2, &ignored, nullptr);
}
+85
View File
@@ -0,0 +1,85 @@
#include "stdinclude.hpp"
extern "C" {
void* GetFileVersionInfoA_Original = nullptr;
void* GetFileVersionInfoSizeA_Original = nullptr;
void* VerQueryValueA_Original = nullptr;
BOOL WINAPI GetFileVersionInfoA_EXPORT(LPCSTR lptstrFilename, DWORD dwHandle, DWORD dwLen, LPVOID lpData) {
using Fn = BOOL(WINAPI*)(LPCSTR, DWORD, DWORD, LPVOID);
if (!GetFileVersionInfoA_Original) {
SetLastError(ERROR_PROC_NOT_FOUND);
return FALSE;
}
return reinterpret_cast<Fn>(GetFileVersionInfoA_Original)(lptstrFilename, dwHandle, dwLen, lpData);
}
DWORD WINAPI GetFileVersionInfoSizeA_EXPORT(LPCSTR lptstrFilename, LPDWORD lpdwHandle) {
using Fn = DWORD(WINAPI*)(LPCSTR, LPDWORD);
if (!GetFileVersionInfoSizeA_Original) {
SetLastError(ERROR_PROC_NOT_FOUND);
return 0;
}
return reinterpret_cast<Fn>(GetFileVersionInfoSizeA_Original)(lptstrFilename, lpdwHandle);
}
BOOL WINAPI VerQueryValueA_EXPORT(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID* lplpBuffer, PUINT puLen) {
using Fn = BOOL(WINAPI*)(LPCVOID, LPCSTR, LPVOID*, PUINT);
if (!VerQueryValueA_Original) {
SetLastError(ERROR_PROC_NOT_FOUND);
return FALSE;
}
return reinterpret_cast<Fn>(VerQueryValueA_Original)(pBlock, lpSubBlock, lplpBuffer, puLen);
}
}
void start_hook_thread();
namespace {
constexpr DWORD kProxyInitDelayMs = 1000;
HMODULE g_original = nullptr;
void load_original_version_dll() {
if (g_original) {
return;
}
char system_dir[MAX_PATH] = {};
GetSystemDirectoryA(system_dir, MAX_PATH);
char path[MAX_PATH] = {};
lstrcpynA(path, system_dir, MAX_PATH);
lstrcatA(path, "\\version.dll");
g_original = LoadLibraryA(path);
if (!g_original) {
hook_log("[cgss-http-hook] failed to load original version.dll");
return;
}
GetFileVersionInfoA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoA"));
GetFileVersionInfoSizeA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "GetFileVersionInfoSizeA"));
VerQueryValueA_Original = reinterpret_cast<void*>(GetProcAddress(g_original, "VerQueryValueA"));
if (!GetFileVersionInfoA_Original || !GetFileVersionInfoSizeA_Original || !VerQueryValueA_Original) {
hook_log("[cgss-http-hook] failed to resolve version exports");
return;
}
hook_log("[cgss-http-hook] version.dll initialized");
}
DWORD WINAPI init_thread(void*) {
Sleep(kProxyInitDelayMs);
load_original_version_dll();
start_hook_thread();
return 0;
}
}
BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID) {
if (reason == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(module);
CreateThread(nullptr, 0, init_thread, nullptr, 0, nullptr);
}
return TRUE;
}
+11
View File
@@ -0,0 +1,11 @@
#pragma once
#include <windows.h>
#include <cstring>
#include <MinHook.h>
#include "il2cpp_symbols.hpp"
void hook_log(const char* message);
+4
View File
@@ -0,0 +1,4 @@
EXPORTS
GetFileVersionInfoA=GetFileVersionInfoA_EXPORT
GetFileVersionInfoSizeA=GetFileVersionInfoSizeA_EXPORT
VerQueryValueA=VerQueryValueA_EXPORT
+38
View File
@@ -0,0 +1,38 @@
#include <winver.h>
#define VER_FILEVERSION 1,0,0,0
#define VER_FILEVERSION_STR "1.0.0.0\0"
#define VER_PRODUCTVERSION 1,0,0,0
#define VER_PRODUCTVERSION_STR "1.0.0.0\0"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "YumeMichi\0"
VALUE "FileDescription", "cgss-http-hook version.dll proxy\0"
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "cgss-http-hook\0"
VALUE "OriginalFilename", "version.dll\0"
VALUE "ProductName", "cgss-http-hook\0"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1200
END
END