├── .gitignore ├── ChangeFont ├── .gitignore ├── ChangeFont.sln └── MyDll │ ├── .gitignore │ ├── MyDll.vcxproj │ ├── MyDll.vcxproj.filters │ ├── MyDll.vcxproj.user │ ├── detours.h │ ├── detours.lib │ └── dllmain.cpp ├── GBK.py ├── Lib.py ├── MyDll.dll ├── README.md ├── YSTB_FILE.py ├── YSTB_GuessXorKey.exe ├── YSTB_Xor.exe ├── YSTL_Parse.exe ├── change_name_define.py ├── image └── README │ ├── 1722575060988.png │ └── 1722575074786.png ├── import_YSTB_FILE.py ├── json2triline.py ├── read_YSTB_FILE.py ├── setdll.exe └── triline2json.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/* 2 | *.code-workspace 3 | test.py 4 | *_temp.py -------------------------------------------------------------------------------- /ChangeFont/.gitignore: -------------------------------------------------------------------------------- 1 | .vs/* 2 | Release/* 3 | -------------------------------------------------------------------------------- /ChangeFont/ChangeFont.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.9.34723.18 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyDll", "MyDll\MyDll.vcxproj", "{45AD220B-326D-4C5E-92A7-0642DBB3BACC}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {45AD220B-326D-4C5E-92A7-0642DBB3BACC}.Debug|x64.ActiveCfg = Debug|x64 17 | {45AD220B-326D-4C5E-92A7-0642DBB3BACC}.Debug|x64.Build.0 = Debug|x64 18 | {45AD220B-326D-4C5E-92A7-0642DBB3BACC}.Debug|x86.ActiveCfg = Debug|Win32 19 | {45AD220B-326D-4C5E-92A7-0642DBB3BACC}.Debug|x86.Build.0 = Debug|Win32 20 | {45AD220B-326D-4C5E-92A7-0642DBB3BACC}.Release|x64.ActiveCfg = Release|x64 21 | {45AD220B-326D-4C5E-92A7-0642DBB3BACC}.Release|x64.Build.0 = Release|x64 22 | {45AD220B-326D-4C5E-92A7-0642DBB3BACC}.Release|x86.ActiveCfg = Release|Win32 23 | {45AD220B-326D-4C5E-92A7-0642DBB3BACC}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {6C6F4CCB-65F5-4690-A975-FD3FE42AE158} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /ChangeFont/MyDll/.gitignore: -------------------------------------------------------------------------------- 1 | Release/* -------------------------------------------------------------------------------- /ChangeFont/MyDll/MyDll.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 17.0 23 | Win32Proj 24 | {45ad220b-326d-4c5e-92a7-0642dbb3bacc} 25 | MyDll 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v143 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | true 77 | WIN32;_DEBUG;MYDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 78 | true 79 | NotUsing 80 | pch.h 81 | MultiThreadedDebug 82 | 83 | 84 | Windows 85 | true 86 | false 87 | 88 | 89 | 90 | 91 | Level3 92 | true 93 | true 94 | true 95 | WIN32;NDEBUG;MYDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 96 | true 97 | NotUsing 98 | pch.h 99 | MultiThreadedDLL 100 | 101 | 102 | Windows 103 | true 104 | true 105 | true 106 | false 107 | 108 | 109 | 110 | 111 | Level3 112 | true 113 | _DEBUG;MYDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 114 | true 115 | NotUsing 116 | pch.h 117 | 118 | 119 | Windows 120 | true 121 | false 122 | 123 | 124 | 125 | 126 | Level3 127 | true 128 | true 129 | true 130 | NDEBUG;MYDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 131 | true 132 | Use 133 | pch.h 134 | 135 | 136 | Windows 137 | true 138 | true 139 | true 140 | false 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /ChangeFont/MyDll/MyDll.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 23 | 24 | 头文件 25 | 26 | 27 | -------------------------------------------------------------------------------- /ChangeFont/MyDll/MyDll.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /ChangeFont/MyDll/detours.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Core Detours Functionality (detours.h of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #pragma once 11 | #ifndef _DETOURS_H_ 12 | #define _DETOURS_H_ 13 | 14 | #define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH 15 | 16 | ////////////////////////////////////////////////////////////////////////////// 17 | // 18 | 19 | #ifdef DETOURS_INTERNAL 20 | 21 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 22 | #define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 23 | 24 | #pragma warning(disable:4068) // unknown pragma (suppress) 25 | 26 | #if _MSC_VER >= 1900 27 | #pragma warning(push) 28 | #pragma warning(disable:4091) // empty typedef 29 | #endif 30 | 31 | // Suppress declspec(dllimport) for the sake of Detours 32 | // users that provide kernel32 functionality themselves. 33 | // This is ok in the mainstream case, it will just cost 34 | // an extra instruction calling some functions, which 35 | // LTCG optimizes away. 36 | // 37 | #define _KERNEL32_ 1 38 | #define _USER32_ 1 39 | 40 | #include 41 | #if (_MSC_VER < 1310) 42 | #else 43 | #pragma warning(push) 44 | #if _MSC_VER > 1400 45 | #pragma warning(disable:6102 6103) // /analyze warnings 46 | #endif 47 | #include 48 | #include 49 | #pragma warning(pop) 50 | #endif 51 | #include 52 | 53 | // Allow Detours to cleanly compile with the MingW toolchain. 54 | // 55 | #ifdef __GNUC__ 56 | #define __try 57 | #define __except(x) if (0) 58 | #include 59 | #include 60 | #endif 61 | 62 | // From winerror.h, as this error isn't found in some SDKs: 63 | // 64 | // MessageId: ERROR_DYNAMIC_CODE_BLOCKED 65 | // 66 | // MessageText: 67 | // 68 | // The operation was blocked as the process prohibits dynamic code generation. 69 | // 70 | #define ERROR_DYNAMIC_CODE_BLOCKED 1655L 71 | 72 | #endif // DETOURS_INTERNAL 73 | 74 | ////////////////////////////////////////////////////////////////////////////// 75 | // 76 | 77 | #undef DETOURS_X64 78 | #undef DETOURS_X86 79 | #undef DETOURS_IA64 80 | #undef DETOURS_ARM 81 | #undef DETOURS_ARM64 82 | #undef DETOURS_BITS 83 | #undef DETOURS_32BIT 84 | #undef DETOURS_64BIT 85 | 86 | #if defined(_X86_) 87 | #define DETOURS_X86 88 | #define DETOURS_OPTION_BITS 64 89 | 90 | #elif defined(_AMD64_) 91 | #define DETOURS_X64 92 | #define DETOURS_OPTION_BITS 32 93 | 94 | #elif defined(_IA64_) 95 | #define DETOURS_IA64 96 | #define DETOURS_OPTION_BITS 32 97 | 98 | #elif defined(_ARM_) 99 | #define DETOURS_ARM 100 | 101 | #elif defined(_ARM64_) 102 | #define DETOURS_ARM64 103 | 104 | #else 105 | #error Unknown architecture (x86, amd64, ia64, arm, arm64) 106 | #endif 107 | 108 | #ifdef _WIN64 109 | #undef DETOURS_32BIT 110 | #define DETOURS_64BIT 1 111 | #define DETOURS_BITS 64 112 | // If all 64bit kernels can run one and only one 32bit architecture. 113 | //#define DETOURS_OPTION_BITS 32 114 | #else 115 | #define DETOURS_32BIT 1 116 | #undef DETOURS_64BIT 117 | #define DETOURS_BITS 32 118 | // If all 64bit kernels can run one and only one 32bit architecture. 119 | //#define DETOURS_OPTION_BITS 32 120 | #endif 121 | 122 | /////////////////////////////////////////////////////////////// Helper Macros. 123 | // 124 | #define DETOURS_STRINGIFY_(x) #x 125 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 126 | 127 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 128 | 129 | ////////////////////////////////////////////////////////////////////////////// 130 | // 131 | 132 | #if (_MSC_VER < 1299) && !defined(__MINGW32__) 133 | typedef LONG LONG_PTR; 134 | typedef ULONG ULONG_PTR; 135 | #endif 136 | 137 | ///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. 138 | // 139 | // These definitions are include so that Detours will build even if the 140 | // compiler doesn't have full SAL 2.0 support. 141 | // 142 | #ifndef DETOURS_DONT_REMOVE_SAL_20 143 | 144 | #ifdef DETOURS_TEST_REMOVE_SAL_20 145 | #undef _Analysis_assume_ 146 | #undef _Benign_race_begin_ 147 | #undef _Benign_race_end_ 148 | #undef _Field_range_ 149 | #undef _Field_size_ 150 | #undef _In_ 151 | #undef _In_bytecount_ 152 | #undef _In_count_ 153 | #undef __in_ecount 154 | #undef _In_opt_ 155 | #undef _In_opt_bytecount_ 156 | #undef _In_opt_count_ 157 | #undef _In_opt_z_ 158 | #undef _In_range_ 159 | #undef _In_reads_ 160 | #undef _In_reads_bytes_ 161 | #undef _In_reads_opt_ 162 | #undef _In_reads_opt_bytes_ 163 | #undef _In_reads_or_z_ 164 | #undef _In_z_ 165 | #undef _Inout_ 166 | #undef _Inout_opt_ 167 | #undef _Inout_z_count_ 168 | #undef _Out_ 169 | #undef _Out_opt_ 170 | #undef _Out_writes_ 171 | #undef _Outptr_result_maybenull_ 172 | #undef _Readable_bytes_ 173 | #undef _Success_ 174 | #undef _Writable_bytes_ 175 | #undef _Pre_notnull_ 176 | #endif 177 | 178 | #if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) 179 | #define _Outptr_result_maybenull_ _Deref_out_opt_z_ 180 | #endif 181 | 182 | #if defined(_In_count_) && !defined(_In_reads_) 183 | #define _In_reads_(x) _In_count_(x) 184 | #endif 185 | 186 | #if defined(_In_opt_count_) && !defined(_In_reads_opt_) 187 | #define _In_reads_opt_(x) _In_opt_count_(x) 188 | #endif 189 | 190 | #if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) 191 | #define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) 192 | #endif 193 | 194 | #if defined(_In_bytecount_) && !defined(_In_reads_bytes_) 195 | #define _In_reads_bytes_(x) _In_bytecount_(x) 196 | #endif 197 | 198 | #ifndef _In_ 199 | #define _In_ 200 | #endif 201 | 202 | #ifndef _In_bytecount_ 203 | #define _In_bytecount_(x) 204 | #endif 205 | 206 | #ifndef _In_count_ 207 | #define _In_count_(x) 208 | #endif 209 | 210 | #ifndef __in_ecount 211 | #define __in_ecount(x) 212 | #endif 213 | 214 | #ifndef _In_opt_ 215 | #define _In_opt_ 216 | #endif 217 | 218 | #ifndef _In_opt_bytecount_ 219 | #define _In_opt_bytecount_(x) 220 | #endif 221 | 222 | #ifndef _In_opt_count_ 223 | #define _In_opt_count_(x) 224 | #endif 225 | 226 | #ifndef _In_opt_z_ 227 | #define _In_opt_z_ 228 | #endif 229 | 230 | #ifndef _In_range_ 231 | #define _In_range_(x,y) 232 | #endif 233 | 234 | #ifndef _In_reads_ 235 | #define _In_reads_(x) 236 | #endif 237 | 238 | #ifndef _In_reads_bytes_ 239 | #define _In_reads_bytes_(x) 240 | #endif 241 | 242 | #ifndef _In_reads_opt_ 243 | #define _In_reads_opt_(x) 244 | #endif 245 | 246 | #ifndef _In_reads_opt_bytes_ 247 | #define _In_reads_opt_bytes_(x) 248 | #endif 249 | 250 | #ifndef _In_reads_or_z_ 251 | #define _In_reads_or_z_ 252 | #endif 253 | 254 | #ifndef _In_z_ 255 | #define _In_z_ 256 | #endif 257 | 258 | #ifndef _Inout_ 259 | #define _Inout_ 260 | #endif 261 | 262 | #ifndef _Inout_opt_ 263 | #define _Inout_opt_ 264 | #endif 265 | 266 | #ifndef _Inout_z_count_ 267 | #define _Inout_z_count_(x) 268 | #endif 269 | 270 | #ifndef _Out_ 271 | #define _Out_ 272 | #endif 273 | 274 | #ifndef _Out_opt_ 275 | #define _Out_opt_ 276 | #endif 277 | 278 | #ifndef _Out_writes_ 279 | #define _Out_writes_(x) 280 | #endif 281 | 282 | #ifndef _Outptr_result_maybenull_ 283 | #define _Outptr_result_maybenull_ 284 | #endif 285 | 286 | #ifndef _Writable_bytes_ 287 | #define _Writable_bytes_(x) 288 | #endif 289 | 290 | #ifndef _Readable_bytes_ 291 | #define _Readable_bytes_(x) 292 | #endif 293 | 294 | #ifndef _Success_ 295 | #define _Success_(x) 296 | #endif 297 | 298 | #ifndef _Pre_notnull_ 299 | #define _Pre_notnull_ 300 | #endif 301 | 302 | #ifdef DETOURS_INTERNAL 303 | 304 | #pragma warning(disable:4615) // unknown warning type (suppress with older compilers) 305 | 306 | #ifndef _Benign_race_begin_ 307 | #define _Benign_race_begin_ 308 | #endif 309 | 310 | #ifndef _Benign_race_end_ 311 | #define _Benign_race_end_ 312 | #endif 313 | 314 | #ifndef _Field_size_ 315 | #define _Field_size_(x) 316 | #endif 317 | 318 | #ifndef _Field_range_ 319 | #define _Field_range_(x,y) 320 | #endif 321 | 322 | #ifndef _Analysis_assume_ 323 | #define _Analysis_assume_(x) 324 | #endif 325 | 326 | #endif // DETOURS_INTERNAL 327 | #endif // DETOURS_DONT_REMOVE_SAL_20 328 | 329 | ////////////////////////////////////////////////////////////////////////////// 330 | // 331 | #ifndef GUID_DEFINED 332 | #define GUID_DEFINED 333 | typedef struct _GUID 334 | { 335 | DWORD Data1; 336 | WORD Data2; 337 | WORD Data3; 338 | BYTE Data4[ 8 ]; 339 | } GUID; 340 | 341 | #ifdef INITGUID 342 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 343 | const GUID name \ 344 | = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } 345 | #else 346 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 347 | const GUID name 348 | #endif // INITGUID 349 | #endif // !GUID_DEFINED 350 | 351 | #if defined(__cplusplus) 352 | #ifndef _REFGUID_DEFINED 353 | #define _REFGUID_DEFINED 354 | #define REFGUID const GUID & 355 | #endif // !_REFGUID_DEFINED 356 | #else // !__cplusplus 357 | #ifndef _REFGUID_DEFINED 358 | #define _REFGUID_DEFINED 359 | #define REFGUID const GUID * const 360 | #endif // !_REFGUID_DEFINED 361 | #endif // !__cplusplus 362 | 363 | #ifndef ARRAYSIZE 364 | #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) 365 | #endif 366 | 367 | // 368 | ////////////////////////////////////////////////////////////////////////////// 369 | 370 | #ifdef __cplusplus 371 | extern "C" { 372 | #endif // __cplusplus 373 | 374 | /////////////////////////////////////////////////// Instruction Target Macros. 375 | // 376 | #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) 377 | #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) 378 | #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" 379 | 380 | extern const GUID DETOUR_EXE_RESTORE_GUID; 381 | extern const GUID DETOUR_EXE_HELPER_GUID; 382 | 383 | #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! 384 | typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; 385 | 386 | #ifndef DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 387 | #define DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 32 388 | #endif // !DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 389 | 390 | /////////////////////////////////////////////////////////// Binary Structures. 391 | // 392 | #pragma pack(push, 8) 393 | typedef struct _DETOUR_SECTION_HEADER 394 | { 395 | DWORD cbHeaderSize; 396 | DWORD nSignature; 397 | DWORD nDataOffset; 398 | DWORD cbDataSize; 399 | 400 | DWORD nOriginalImportVirtualAddress; 401 | DWORD nOriginalImportSize; 402 | DWORD nOriginalBoundImportVirtualAddress; 403 | DWORD nOriginalBoundImportSize; 404 | 405 | DWORD nOriginalIatVirtualAddress; 406 | DWORD nOriginalIatSize; 407 | DWORD nOriginalSizeOfImage; 408 | DWORD cbPrePE; 409 | 410 | DWORD nOriginalClrFlags; 411 | DWORD reserved1; 412 | DWORD reserved2; 413 | DWORD reserved3; 414 | 415 | // Followed by cbPrePE bytes of data. 416 | } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; 417 | 418 | typedef struct _DETOUR_SECTION_RECORD 419 | { 420 | DWORD cbBytes; 421 | DWORD nReserved; 422 | GUID guid; 423 | } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; 424 | 425 | typedef struct _DETOUR_CLR_HEADER 426 | { 427 | // Header versioning 428 | ULONG cb; 429 | USHORT MajorRuntimeVersion; 430 | USHORT MinorRuntimeVersion; 431 | 432 | // Symbol table and startup information 433 | IMAGE_DATA_DIRECTORY MetaData; 434 | ULONG Flags; 435 | 436 | // Followed by the rest of the IMAGE_COR20_HEADER 437 | } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; 438 | 439 | typedef struct _DETOUR_EXE_RESTORE 440 | { 441 | DWORD cb; 442 | DWORD cbidh; 443 | DWORD cbinh; 444 | DWORD cbclr; 445 | 446 | PBYTE pidh; 447 | PBYTE pinh; 448 | PBYTE pclr; 449 | 450 | IMAGE_DOS_HEADER idh; 451 | union { 452 | IMAGE_NT_HEADERS inh; // all environments have this 453 | #ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this 454 | IMAGE_NT_HEADERS32 inh32; 455 | #endif 456 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this 457 | IMAGE_NT_HEADERS64 inh64; 458 | #endif 459 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this 460 | BYTE raw[sizeof(IMAGE_NT_HEADERS64) + 461 | sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS]; 462 | #else 463 | BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS]; 464 | #endif 465 | }; 466 | DETOUR_CLR_HEADER clr; 467 | 468 | } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; 469 | 470 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC 471 | C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108); 472 | #endif 473 | 474 | // The size can change, but assert for clarity due to the muddying #ifdefs. 475 | #ifdef _WIN64 476 | C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688); 477 | #else 478 | C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678); 479 | #endif 480 | 481 | typedef struct _DETOUR_EXE_HELPER 482 | { 483 | DWORD cb; 484 | DWORD pid; 485 | DWORD nDlls; 486 | CHAR rDlls[4]; 487 | } DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; 488 | 489 | #pragma pack(pop) 490 | 491 | #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ 492 | { \ 493 | sizeof(DETOUR_SECTION_HEADER),\ 494 | DETOUR_SECTION_HEADER_SIGNATURE,\ 495 | sizeof(DETOUR_SECTION_HEADER),\ 496 | (cbSectionSize),\ 497 | \ 498 | 0,\ 499 | 0,\ 500 | 0,\ 501 | 0,\ 502 | \ 503 | 0,\ 504 | 0,\ 505 | 0,\ 506 | 0,\ 507 | } 508 | 509 | ///////////////////////////////////////////////////////////// Binary Typedefs. 510 | // 511 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( 512 | _In_opt_ PVOID pContext, 513 | _In_opt_ LPCSTR pszFile, 514 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 515 | 516 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( 517 | _In_opt_ PVOID pContext, 518 | _In_ LPCSTR pszOrigFile, 519 | _In_ LPCSTR pszFile, 520 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 521 | 522 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( 523 | _In_opt_ PVOID pContext, 524 | _In_ ULONG nOrigOrdinal, 525 | _In_ ULONG nOrdinal, 526 | _Out_ ULONG *pnOutOrdinal, 527 | _In_opt_ LPCSTR pszOrigSymbol, 528 | _In_opt_ LPCSTR pszSymbol, 529 | _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); 530 | 531 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( 532 | _In_opt_ PVOID pContext); 533 | 534 | typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, 535 | _In_ ULONG nOrdinal, 536 | _In_opt_ LPCSTR pszName, 537 | _In_opt_ PVOID pCode); 538 | 539 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, 540 | _In_opt_ HMODULE hModule, 541 | _In_opt_ LPCSTR pszFile); 542 | 543 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, 544 | _In_ DWORD nOrdinal, 545 | _In_opt_ LPCSTR pszFunc, 546 | _In_opt_ PVOID pvFunc); 547 | 548 | // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. 549 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, 550 | _In_ DWORD nOrdinal, 551 | _In_opt_ LPCSTR pszFunc, 552 | _In_opt_ PVOID* ppvFunc); 553 | 554 | typedef VOID * PDETOUR_BINARY; 555 | typedef VOID * PDETOUR_LOADED_BINARY; 556 | 557 | //////////////////////////////////////////////////////////// Transaction APIs. 558 | // 559 | LONG WINAPI DetourTransactionBegin(VOID); 560 | LONG WINAPI DetourTransactionAbort(VOID); 561 | LONG WINAPI DetourTransactionCommit(VOID); 562 | LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); 563 | 564 | LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); 565 | 566 | LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, 567 | _In_ PVOID pDetour); 568 | 569 | LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, 570 | _In_ PVOID pDetour, 571 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 572 | _Out_opt_ PVOID *ppRealTarget, 573 | _Out_opt_ PVOID *ppRealDetour); 574 | 575 | LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, 576 | _In_ PVOID pDetour); 577 | 578 | BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); 579 | BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); 580 | PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); 581 | PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); 582 | 583 | ////////////////////////////////////////////////////////////// Code Functions. 584 | // 585 | PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, 586 | _In_ LPCSTR pszFunction); 587 | PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, 588 | _Out_opt_ PVOID *ppGlobals); 589 | PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, 590 | _Inout_opt_ PVOID *ppDstPool, 591 | _In_ PVOID pSrc, 592 | _Out_opt_ PVOID *ppTarget, 593 | _Out_opt_ LONG *plExtra); 594 | BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, 595 | _In_ BOOL fLimitReferencesToModule); 596 | PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget, 597 | _Out_ PDWORD pcbAllocatedSize); 598 | BOOL WINAPI DetourIsFunctionImported(_In_ PBYTE pbCode, 599 | _In_ PBYTE pbAddress); 600 | 601 | ///////////////////////////////////////////////////// Loaded Binary Functions. 602 | // 603 | HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); 604 | HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); 605 | PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); 606 | ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); 607 | BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, 608 | _In_opt_ PVOID pContext, 609 | _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); 610 | BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, 611 | _In_opt_ PVOID pContext, 612 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 613 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); 614 | 615 | BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, 616 | _In_opt_ PVOID pContext, 617 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 618 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); 619 | 620 | _Writable_bytes_(*pcbData) 621 | _Readable_bytes_(*pcbData) 622 | _Success_(return != NULL) 623 | PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, 624 | _In_ REFGUID rguid, 625 | _Out_opt_ DWORD *pcbData); 626 | 627 | _Writable_bytes_(*pcbData) 628 | _Readable_bytes_(*pcbData) 629 | _Success_(return != NULL) 630 | PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, 631 | _Out_opt_ DWORD *pcbData); 632 | 633 | DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); 634 | 635 | BOOL WINAPI DetourFreePayload(_In_ PVOID pvData); 636 | ///////////////////////////////////////////////// Persistent Binary Functions. 637 | // 638 | 639 | PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); 640 | 641 | _Writable_bytes_(*pcbData) 642 | _Readable_bytes_(*pcbData) 643 | _Success_(return != NULL) 644 | PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, 645 | _Out_opt_ GUID *pGuid, 646 | _Out_ DWORD *pcbData, 647 | _Inout_ DWORD *pnIterator); 648 | 649 | _Writable_bytes_(*pcbData) 650 | _Readable_bytes_(*pcbData) 651 | _Success_(return != NULL) 652 | PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, 653 | _In_ REFGUID rguid, 654 | _Out_ DWORD *pcbData); 655 | 656 | PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, 657 | _In_ REFGUID rguid, 658 | _In_reads_opt_(cbData) PVOID pData, 659 | _In_ DWORD cbData); 660 | BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); 661 | BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); 662 | BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); 663 | BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, 664 | _In_opt_ PVOID pContext, 665 | _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, 666 | _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, 667 | _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, 668 | _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); 669 | BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); 670 | BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); 671 | 672 | /////////////////////////////////////////////////// Create Process & Load Dll. 673 | // 674 | _Success_(return != NULL) 675 | PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess, 676 | _In_ REFGUID rguid, 677 | _Out_opt_ DWORD *pcbData); 678 | 679 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( 680 | _In_opt_ LPCSTR lpApplicationName, 681 | _Inout_opt_ LPSTR lpCommandLine, 682 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 683 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 684 | _In_ BOOL bInheritHandles, 685 | _In_ DWORD dwCreationFlags, 686 | _In_opt_ LPVOID lpEnvironment, 687 | _In_opt_ LPCSTR lpCurrentDirectory, 688 | _In_ LPSTARTUPINFOA lpStartupInfo, 689 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 690 | 691 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( 692 | _In_opt_ LPCWSTR lpApplicationName, 693 | _Inout_opt_ LPWSTR lpCommandLine, 694 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 695 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 696 | _In_ BOOL bInheritHandles, 697 | _In_ DWORD dwCreationFlags, 698 | _In_opt_ LPVOID lpEnvironment, 699 | _In_opt_ LPCWSTR lpCurrentDirectory, 700 | _In_ LPSTARTUPINFOW lpStartupInfo, 701 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 702 | 703 | BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, 704 | _Inout_opt_ LPSTR lpCommandLine, 705 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 706 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 707 | _In_ BOOL bInheritHandles, 708 | _In_ DWORD dwCreationFlags, 709 | _In_opt_ LPVOID lpEnvironment, 710 | _In_opt_ LPCSTR lpCurrentDirectory, 711 | _In_ LPSTARTUPINFOA lpStartupInfo, 712 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 713 | _In_ LPCSTR lpDllName, 714 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 715 | 716 | BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, 717 | _Inout_opt_ LPWSTR lpCommandLine, 718 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 719 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 720 | _In_ BOOL bInheritHandles, 721 | _In_ DWORD dwCreationFlags, 722 | _In_opt_ LPVOID lpEnvironment, 723 | _In_opt_ LPCWSTR lpCurrentDirectory, 724 | _In_ LPSTARTUPINFOW lpStartupInfo, 725 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 726 | _In_ LPCSTR lpDllName, 727 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 728 | 729 | #ifdef UNICODE 730 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllW 731 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW 732 | #else 733 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllA 734 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA 735 | #endif // !UNICODE 736 | 737 | BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, 738 | _Inout_opt_ LPSTR lpCommandLine, 739 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 740 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 741 | _In_ BOOL bInheritHandles, 742 | _In_ DWORD dwCreationFlags, 743 | _In_opt_ LPVOID lpEnvironment, 744 | _In_opt_ LPCSTR lpCurrentDirectory, 745 | _In_ LPSTARTUPINFOA lpStartupInfo, 746 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 747 | _In_ LPCSTR lpDllName, 748 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 749 | 750 | BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, 751 | _Inout_opt_ LPWSTR lpCommandLine, 752 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 753 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 754 | _In_ BOOL bInheritHandles, 755 | _In_ DWORD dwCreationFlags, 756 | _In_opt_ LPVOID lpEnvironment, 757 | _In_opt_ LPCWSTR lpCurrentDirectory, 758 | _In_ LPSTARTUPINFOW lpStartupInfo, 759 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 760 | _In_ LPCSTR lpDllName, 761 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 762 | 763 | #ifdef UNICODE 764 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW 765 | #else 766 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA 767 | #endif // !UNICODE 768 | 769 | BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, 770 | _Inout_opt_ LPSTR lpCommandLine, 771 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 772 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 773 | _In_ BOOL bInheritHandles, 774 | _In_ DWORD dwCreationFlags, 775 | _In_opt_ LPVOID lpEnvironment, 776 | _In_opt_ LPCSTR lpCurrentDirectory, 777 | _In_ LPSTARTUPINFOA lpStartupInfo, 778 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 779 | _In_ DWORD nDlls, 780 | _In_reads_(nDlls) LPCSTR *rlpDlls, 781 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 782 | 783 | BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, 784 | _Inout_opt_ LPWSTR lpCommandLine, 785 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 786 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 787 | _In_ BOOL bInheritHandles, 788 | _In_ DWORD dwCreationFlags, 789 | _In_opt_ LPVOID lpEnvironment, 790 | _In_opt_ LPCWSTR lpCurrentDirectory, 791 | _In_ LPSTARTUPINFOW lpStartupInfo, 792 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 793 | _In_ DWORD nDlls, 794 | _In_reads_(nDlls) LPCSTR *rlpDlls, 795 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 796 | 797 | #ifdef UNICODE 798 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW 799 | #else 800 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA 801 | #endif // !UNICODE 802 | 803 | BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, 804 | _In_ LPCSTR lpDllName, 805 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 806 | 807 | BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, 808 | _In_ LPCSTR lpDllName, 809 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 810 | 811 | #ifdef UNICODE 812 | #define DetourProcessViaHelper DetourProcessViaHelperW 813 | #else 814 | #define DetourProcessViaHelper DetourProcessViaHelperA 815 | #endif // !UNICODE 816 | 817 | BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, 818 | _In_ DWORD nDlls, 819 | _In_reads_(nDlls) LPCSTR *rlpDlls, 820 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 821 | 822 | BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, 823 | _In_ DWORD nDlls, 824 | _In_reads_(nDlls) LPCSTR *rlpDlls, 825 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 826 | 827 | #ifdef UNICODE 828 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW 829 | #else 830 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA 831 | #endif // !UNICODE 832 | 833 | BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, 834 | _In_reads_(nDlls) LPCSTR *rlpDlls, 835 | _In_ DWORD nDlls); 836 | 837 | BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, 838 | _In_ HMODULE hImage, 839 | _In_ BOOL bIs32Bit, 840 | _In_reads_(nDlls) LPCSTR *rlpDlls, 841 | _In_ DWORD nDlls); 842 | 843 | BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, 844 | _In_ REFGUID rguid, 845 | _In_reads_bytes_(cbData) LPCVOID pvData, 846 | _In_ DWORD cbData); 847 | _Success_(return != NULL) 848 | PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess, 849 | _In_ REFGUID rguid, 850 | _In_reads_bytes_(cbData) LPCVOID pvData, 851 | _In_ DWORD cbData); 852 | 853 | BOOL WINAPI DetourRestoreAfterWith(VOID); 854 | BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 855 | _In_ DWORD cbData); 856 | BOOL WINAPI DetourIsHelperProcess(VOID); 857 | VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, 858 | _In_ HINSTANCE, 859 | _In_ LPSTR, 860 | _In_ INT); 861 | 862 | // 863 | ////////////////////////////////////////////////////////////////////////////// 864 | #ifdef __cplusplus 865 | } 866 | #endif // __cplusplus 867 | 868 | /////////////////////////////////////////////////// Type-safe overloads for C++ 869 | // 870 | #if __cplusplus >= 201103L || _MSVC_LANG >= 201103L 871 | #include 872 | 873 | template 874 | struct DetoursIsFunctionPointer : std::false_type {}; 875 | 876 | template 877 | struct DetoursIsFunctionPointer : std::is_function::type> {}; 878 | 879 | template< 880 | typename T, 881 | typename std::enable_if::value, int>::type = 0> 882 | LONG DetourAttach(_Inout_ T *ppPointer, 883 | _In_ T pDetour) noexcept 884 | { 885 | return DetourAttach( 886 | reinterpret_cast(ppPointer), 887 | reinterpret_cast(pDetour)); 888 | } 889 | 890 | template< 891 | typename T, 892 | typename std::enable_if::value, int>::type = 0> 893 | LONG DetourAttachEx(_Inout_ T *ppPointer, 894 | _In_ T pDetour, 895 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 896 | _Out_opt_ T *ppRealTarget, 897 | _Out_opt_ T *ppRealDetour) noexcept 898 | { 899 | return DetourAttachEx( 900 | reinterpret_cast(ppPointer), 901 | reinterpret_cast(pDetour), 902 | ppRealTrampoline, 903 | reinterpret_cast(ppRealTarget), 904 | reinterpret_cast(ppRealDetour)); 905 | } 906 | 907 | template< 908 | typename T, 909 | typename std::enable_if::value, int>::type = 0> 910 | LONG DetourDetach(_Inout_ T *ppPointer, 911 | _In_ T pDetour) noexcept 912 | { 913 | return DetourDetach( 914 | reinterpret_cast(ppPointer), 915 | reinterpret_cast(pDetour)); 916 | } 917 | 918 | #endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L 919 | // 920 | ////////////////////////////////////////////////////////////////////////////// 921 | 922 | //////////////////////////////////////////////// Detours Internal Definitions. 923 | // 924 | #ifdef __cplusplus 925 | #ifdef DETOURS_INTERNAL 926 | 927 | #define NOTHROW 928 | // #define NOTHROW (nothrow) 929 | 930 | ////////////////////////////////////////////////////////////////////////////// 931 | // 932 | #if (_MSC_VER < 1299) && !defined(__GNUC__) 933 | #include 934 | typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; 935 | typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; 936 | typedef IMAGEHLP_SYMBOL SYMBOL_INFO; 937 | typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; 938 | 939 | static inline 940 | LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) 941 | { 942 | return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); 943 | } 944 | #else 945 | #pragma warning(push) 946 | #pragma warning(disable:4091) // empty typedef 947 | #include 948 | #pragma warning(pop) 949 | #endif 950 | 951 | #ifdef IMAGEAPI // defined by DBGHELP.H 952 | typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); 953 | 954 | typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, 955 | _In_opt_ LPCSTR UserSearchPath, 956 | _In_ BOOL fInvadeProcess); 957 | typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); 958 | typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); 959 | typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, 960 | _In_opt_ HANDLE hFile, 961 | _In_opt_ LPSTR ImageName, 962 | _In_opt_ LPSTR ModuleName, 963 | _In_ DWORD64 BaseOfDll, 964 | _In_ DWORD SizeOfDll); 965 | typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, 966 | _In_ DWORD64 qwAddr, 967 | _Out_ PIMAGEHLP_MODULE64 ModuleInfo); 968 | typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, 969 | _In_ LPSTR Name, 970 | _Out_ PSYMBOL_INFO Symbol); 971 | 972 | typedef struct _DETOUR_SYM_INFO 973 | { 974 | HANDLE hProcess; 975 | HMODULE hDbgHelp; 976 | PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; 977 | PF_SymInitialize pfSymInitialize; 978 | PF_SymSetOptions pfSymSetOptions; 979 | PF_SymGetOptions pfSymGetOptions; 980 | PF_SymLoadModule64 pfSymLoadModule64; 981 | PF_SymGetModuleInfo64 pfSymGetModuleInfo64; 982 | PF_SymFromName pfSymFromName; 983 | } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; 984 | 985 | PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); 986 | 987 | #endif // IMAGEAPI 988 | 989 | #if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) 990 | #error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) 991 | #endif 992 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 993 | 994 | #ifdef _DEBUG 995 | 996 | int Detour_AssertExprWithFunctionName(int reportType, const char* filename, int linenumber, const char* FunctionName, const char* msg); 997 | 998 | #define DETOUR_ASSERT_EXPR_WITH_FUNCTION(expr, msg) \ 999 | (void) ((expr) || \ 1000 | (1 != Detour_AssertExprWithFunctionName(_CRT_ASSERT, __FILE__, __LINE__,__FUNCTION__, msg)) || \ 1001 | (_CrtDbgBreak(), 0)) 1002 | 1003 | #define DETOUR_ASSERT(expr) DETOUR_ASSERT_EXPR_WITH_FUNCTION((expr), #expr) 1004 | 1005 | #else// _DEBUG 1006 | #define DETOUR_ASSERT(expr) 1007 | #endif// _DEBUG 1008 | 1009 | #ifndef DETOUR_TRACE 1010 | #if DETOUR_DEBUG 1011 | #define DETOUR_TRACE(x) printf x 1012 | #define DETOUR_BREAK() __debugbreak() 1013 | #include 1014 | #include 1015 | #else 1016 | #define DETOUR_TRACE(x) 1017 | #define DETOUR_BREAK() 1018 | #endif 1019 | #endif 1020 | 1021 | #if 1 || defined(DETOURS_IA64) 1022 | 1023 | // 1024 | // IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. 1025 | // 1026 | 1027 | #define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) 1028 | 1029 | #define DETOUR_IA64_TEMPLATE_OFFSET (0) 1030 | #define DETOUR_IA64_TEMPLATE_SIZE (5) 1031 | 1032 | #define DETOUR_IA64_INSTRUCTION_SIZE (41) 1033 | #define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) 1034 | #define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 1035 | #define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 1036 | 1037 | C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); 1038 | 1039 | __declspec(align(16)) struct DETOUR_IA64_BUNDLE 1040 | { 1041 | public: 1042 | union 1043 | { 1044 | BYTE data[16]; 1045 | UINT64 wide[2]; 1046 | }; 1047 | 1048 | enum { 1049 | A_UNIT = 1u, 1050 | I_UNIT = 2u, 1051 | M_UNIT = 3u, 1052 | B_UNIT = 4u, 1053 | F_UNIT = 5u, 1054 | L_UNIT = 6u, 1055 | X_UNIT = 7u, 1056 | }; 1057 | struct DETOUR_IA64_METADATA 1058 | { 1059 | ULONG nTemplate : 8; // Instruction template. 1060 | ULONG nUnit0 : 4; // Unit for slot 0 1061 | ULONG nUnit1 : 4; // Unit for slot 1 1062 | ULONG nUnit2 : 4; // Unit for slot 2 1063 | }; 1064 | 1065 | protected: 1066 | static const DETOUR_IA64_METADATA s_rceCopyTable[33]; 1067 | 1068 | UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 1069 | 1070 | bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, 1071 | _In_ BYTE slot, 1072 | _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 1073 | 1074 | // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 1075 | // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. 1076 | 1077 | // 00 1078 | // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. 1079 | // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] 1080 | // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] 1081 | // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] 1082 | // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] 1083 | // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] 1084 | // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] 1085 | // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] 1086 | BYTE GetTemplate() const; 1087 | // Get 4 bit opcodes. 1088 | BYTE GetInst0() const; 1089 | BYTE GetInst1() const; 1090 | BYTE GetInst2() const; 1091 | BYTE GetUnit(BYTE slot) const; 1092 | BYTE GetUnit0() const; 1093 | BYTE GetUnit1() const; 1094 | BYTE GetUnit2() const; 1095 | // Get 37 bit data. 1096 | UINT64 GetData0() const; 1097 | UINT64 GetData1() const; 1098 | UINT64 GetData2() const; 1099 | 1100 | // Get/set the full 41 bit instructions. 1101 | UINT64 GetInstruction(BYTE slot) const; 1102 | UINT64 GetInstruction0() const; 1103 | UINT64 GetInstruction1() const; 1104 | UINT64 GetInstruction2() const; 1105 | void SetInstruction(BYTE slot, UINT64 instruction); 1106 | void SetInstruction0(UINT64 instruction); 1107 | void SetInstruction1(UINT64 instruction); 1108 | void SetInstruction2(UINT64 instruction); 1109 | 1110 | // Get/set bitfields. 1111 | static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); 1112 | static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); 1113 | 1114 | // Get specific read-only fields. 1115 | static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode 1116 | static UINT64 GetX(UINT64 instruction); // 1bit opcode extension 1117 | static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension 1118 | static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension 1119 | 1120 | // Get/set specific fields. 1121 | static UINT64 GetImm7a(UINT64 instruction); 1122 | static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); 1123 | static UINT64 GetImm13c(UINT64 instruction); 1124 | static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); 1125 | static UINT64 GetSignBit(UINT64 instruction); 1126 | static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); 1127 | static UINT64 GetImm20a(UINT64 instruction); 1128 | static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); 1129 | static UINT64 GetImm20b(UINT64 instruction); 1130 | static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); 1131 | 1132 | static UINT64 SignExtend(UINT64 Value, UINT64 Offset); 1133 | 1134 | BOOL IsMovlGp() const; 1135 | 1136 | VOID SetInst(BYTE Slot, BYTE nInst); 1137 | VOID SetInst0(BYTE nInst); 1138 | VOID SetInst1(BYTE nInst); 1139 | VOID SetInst2(BYTE nInst); 1140 | VOID SetData(BYTE Slot, UINT64 nData); 1141 | VOID SetData0(UINT64 nData); 1142 | VOID SetData1(UINT64 nData); 1143 | VOID SetData2(UINT64 nData); 1144 | BOOL SetNop(BYTE Slot); 1145 | BOOL SetNop0(); 1146 | BOOL SetNop1(); 1147 | BOOL SetNop2(); 1148 | 1149 | public: 1150 | BOOL IsBrl() const; 1151 | VOID SetBrl(); 1152 | VOID SetBrl(UINT64 target); 1153 | UINT64 GetBrlTarget() const; 1154 | VOID SetBrlTarget(UINT64 target); 1155 | VOID SetBrlImm(UINT64 imm); 1156 | UINT64 GetBrlImm() const; 1157 | 1158 | UINT64 GetMovlGp() const; 1159 | VOID SetMovlGp(UINT64 gp); 1160 | 1161 | VOID SetStop(); 1162 | 1163 | UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; 1164 | }; 1165 | #endif // DETOURS_IA64 1166 | 1167 | #ifdef DETOURS_ARM 1168 | 1169 | #define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) 1170 | #define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) 1171 | 1172 | #endif // DETOURS_ARM 1173 | 1174 | ////////////////////////////////////////////////////////////////////////////// 1175 | 1176 | #ifdef __cplusplus 1177 | extern "C" { 1178 | #endif // __cplusplus 1179 | 1180 | #define DETOUR_OFFLINE_LIBRARY(x) \ 1181 | PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ 1182 | _Inout_opt_ PVOID *ppDstPool, \ 1183 | _In_ PVOID pSrc, \ 1184 | _Out_opt_ PVOID *ppTarget, \ 1185 | _Out_opt_ LONG *plExtra); \ 1186 | \ 1187 | BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ 1188 | _In_ BOOL fLimitReferencesToModule); \ 1189 | 1190 | DETOUR_OFFLINE_LIBRARY(X86) 1191 | DETOUR_OFFLINE_LIBRARY(X64) 1192 | DETOUR_OFFLINE_LIBRARY(ARM) 1193 | DETOUR_OFFLINE_LIBRARY(ARM64) 1194 | DETOUR_OFFLINE_LIBRARY(IA64) 1195 | 1196 | #undef DETOUR_OFFLINE_LIBRARY 1197 | 1198 | ////////////////////////////////////////////////////////////////////////////// 1199 | // 1200 | // Helpers for manipulating page protection. 1201 | // 1202 | 1203 | _Success_(return != FALSE) 1204 | BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, 1205 | _In_ PVOID pAddress, 1206 | _In_ SIZE_T nSize, 1207 | _In_ DWORD dwNewProtect, 1208 | _Out_ PDWORD pdwOldProtect); 1209 | 1210 | _Success_(return != FALSE) 1211 | BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, 1212 | _In_ SIZE_T nSize, 1213 | _In_ DWORD dwNewProtect, 1214 | _Out_ PDWORD pdwOldProtect); 1215 | 1216 | // Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID 1217 | BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right); 1218 | #ifdef __cplusplus 1219 | } 1220 | #endif // __cplusplus 1221 | 1222 | ////////////////////////////////////////////////////////////////////////////// 1223 | 1224 | #define MM_ALLOCATION_GRANULARITY 0x10000 1225 | 1226 | ////////////////////////////////////////////////////////////////////////////// 1227 | 1228 | #endif // DETOURS_INTERNAL 1229 | #endif // __cplusplus 1230 | 1231 | #endif // _DETOURS_H_ 1232 | // 1233 | //////////////////////////////////////////////////////////////// End of File. 1234 | -------------------------------------------------------------------------------- /ChangeFont/MyDll/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyxjyx1234/YURIS_TOOLS/348b30bda623c99782d0fe396068d8801d25096b/ChangeFont/MyDll/detours.lib -------------------------------------------------------------------------------- /ChangeFont/MyDll/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "detours.h" 3 | #pragma comment( lib, "detours.lib") 4 | 5 | extern void change_font(); 6 | 7 | VOID __declspec(dllexport) stratmessage() 8 | { 9 | //MessageBoxW(NULL, L"本补丁由jyxjyx1234/ALyCE免费制作并发布于github/2dfan,使用cluade-3-5-sonnet进行翻译,仅供交流学习。如遇运行问题可到github或2dfan补丁评论区反馈。", NULL, NULL); 10 | } 11 | 12 | // 原始的CreateFontIndirectA函数指针 13 | static HFONT(WINAPI* Real_CreateFontIndirectA)(CONST LOGFONTA* lplf) = CreateFontIndirectA; 14 | 15 | // Hook函数 16 | HFONT WINAPI Mine_CreateFontIndirectA(LOGFONTA* lplf) 17 | { 18 | if (lplf != NULL) 19 | { 20 | lplf->lfCharSet = 0x86; 21 | strncpy_s(lplf->lfFaceName, LF_FACESIZE, "宋体", _TRUNCATE); 22 | lplf->lfFaceName[LF_FACESIZE - 1] = '\0'; 23 | } 24 | return Real_CreateFontIndirectA(lplf); 25 | } 26 | 27 | void change_font() { 28 | DetourRestoreAfterWith(); 29 | DetourTransactionBegin(); 30 | DetourUpdateThread(GetCurrentThread()); 31 | DetourAttach(&(PVOID&)Real_CreateFontIndirectA, Mine_CreateFontIndirectA); 32 | DetourTransactionCommit(); 33 | } 34 | 35 | BOOL APIENTRY DllMain( HMODULE hModule, 36 | DWORD ul_reason_for_call, 37 | LPVOID lpReserved 38 | ) 39 | { 40 | switch (ul_reason_for_call) 41 | { 42 | case DLL_PROCESS_ATTACH: 43 | stratmessage(); 44 | change_font(); 45 | break; 46 | case DLL_THREAD_ATTACH: 47 | break; 48 | case DLL_THREAD_DETACH: 49 | break; 50 | case DLL_PROCESS_DETACH: 51 | break; 52 | } 53 | return TRUE; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /GBK.py: -------------------------------------------------------------------------------- 1 | from Lib import * 2 | import os 3 | 4 | ori_exe_name="シストリ.exe"#原exe名称 5 | 6 | ori_exe = open_file_b(ori_exe_name) 7 | 8 | gbk_list = bytes([ 9 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 10 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 12 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 13 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 14 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 15 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 16 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 17 | 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 18 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 19 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 20 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 21 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 22 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 23 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 24 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00]) 25 | 26 | sjis_list = bytes([ 27 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 28 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 29 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 30 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 31 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 32 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 33 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 34 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 35 | 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 36 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 37 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 38 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 39 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 40 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 41 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 42 | 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00]) 43 | 44 | if ori_exe.find(sjis_list) == -1: 45 | print("已经修改,或此游戏不支持!") 46 | raise RuntimeError 47 | new_exe = ori_exe.replace(sjis_list,gbk_list) 48 | 49 | new_exe_name = ori_exe_name.replace(".exe","_chs.exe") 50 | save_file_b(new_exe_name, new_exe) 51 | 52 | os.makedirs("Release\\",exist_ok=True) 53 | os.system("setdll /d:MyDll.dll "+new_exe_name) 54 | os.system(f"copy {new_exe_name} Release\\") 55 | os.system(f"copy MyDll.dll Release\\") -------------------------------------------------------------------------------- /Lib.py: -------------------------------------------------------------------------------- 1 | #一些常用的函数 2 | import json 3 | 4 | def open_file_b(path)->bytes: 5 | return open(path,'rb').read() 6 | 7 | def from_bytes(b:bytes)->int: 8 | return int.from_bytes(b, byteorder='little', signed=False) 9 | 10 | def save_file_b(path,data)->None: 11 | with open(path,'wb') as f: 12 | f.write(data) 13 | 14 | def save_json(path:str,data)->None: 15 | with open(path,'w',encoding='utf8') as f: 16 | json.dump(data,f,ensure_ascii=False,indent=4) 17 | 18 | def open_json(path:str): 19 | f = open(path,'r',encoding='utf8') 20 | return json.load(f) 21 | 22 | def to_bytes(num:int,length:int)->bytes: 23 | return num.to_bytes(length,byteorder='little') 24 | -------------------------------------------------------------------------------- /MyDll.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyxjyx1234/YURIS_TOOLS/348b30bda623c99782d0fe396068d8801d25096b/MyDll.dll -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YURIS_TOOLS 2 | 3 | yuris引擎的处理工具,可以处理新版本(4.xx、5.xx)的一部分yuris引擎的汉化。如果有BUG或者问题欢迎提Issues。 4 | 5 | 本工具中有部分编译自[ZQF-ReVN/RxYuris at f3d87c05e621789275e82cf73dfc24b9351d5380 (github.com)](https://github.com/ZQF-ReVN/RxYuris/tree/f3d87c05e621789275e82cf73dfc24b9351d5380) 6 | 7 | ## 使用说明 8 | 9 | ### 拆包 10 | 11 | 使用garbro拆包,拆包时选择“尝试猜测”。将拆包得到的 `ybn`文件放入 `ysbin`文件夹。 12 | 13 | ### 文件筛选 14 | 15 | 我只分析了文本相关的ysn文件,其他ysn文件可能会在后面的代码运行中导致bug,所以需要筛选文件。通过 `YSTL_Parse.exe`可以还原文件的原本路径和名称(本工具来自[ZQF-ReVN/RxYuris at f3d87c05e621789275e82cf73dfc24b9351d5380 (github.com)](https://github.com/ZQF-ReVN/RxYuris/tree/f3d87c05e621789275e82cf73dfc24b9351d5380)),可以筛选出游戏文本相关的文件,放入 `scr`文件夹中。 16 | 17 | ``` 18 | YSTL_Parse.exe -make 19 | ``` 20 | 21 | 在当前文件夹下,在cmd中运行以上代码可以生成一个script文件夹,里面还原了文件名。文本相关文件通常在 `userscript`文件夹中。删除其他所有不需要的文件。在当前文件夹下,在cmd中运行以下代码: 22 | 23 | ``` 24 | YSTL_Parse.exe -back 25 | ``` 26 | 27 | 在 `ysbin_new`文件夹中可以找到筛选出的文件。 28 | 29 | ### 寻找密钥 30 | 31 | 使用了异或加密。使用 `YSTB_GuessXorKey.exe` 进行猜密钥(本工具来自[ZQF-ReVN/RxYuris at f3d87c05e621789275e82cf73dfc24b9351d5380 (github.com)](https://github.com/ZQF-ReVN/RxYuris/tree/f3d87c05e621789275e82cf73dfc24b9351d5380)),选择一个ybn文件,在cmd中,在当前目录下运行以下命令: 32 | 33 | ``` 34 | YSTB_GuessXorKey.exe ysbin_new/xxxxxx.ybn 35 | ``` 36 | 37 | 这里可以选个大一点的ybn文件。这会生成一个 `key.txt`文件,其中是密钥。 38 | 39 | ### 提取文本1 40 | 41 | 使用 ` read_YSTB_FILE.py`可以将文本提取到 `triline_text_ori`文件夹中。文本格式为三行文本,从上到下分别为原文、预翻译、最终翻译。其中[]里的数字为偏移标识,请勿改动。 42 | 43 | 如果文件有加密,会自动从 `Key.txt`读取密钥。 44 | 45 | ### 提取文本2 46 | 47 | 使用 ` triline2json.py`可以进一步的把三行文本提取为适用于GalTransl使用的json以进行机翻。这里的代码并没有考虑文本拼接的问题,如果需要拼接需要自行修改代码。 48 | 49 | 这里的代码中,文本格式为:【人名】文本,如果格式有变化需要修改。 50 | 51 | json文件在 `json_ori`文件夹中。 52 | 53 | 文本的具体格式等内容随游戏变化较大,这部分建议自行根据具体游戏完成。 54 | 55 | ### 导入文本1 56 | 57 | 如果使用了GalTransl进行机翻,使用 `json2triline.py`可以将Galtransl中 `trans_cache`里的文件重新生成翻译后的三行文本。将 `trans_cache`中的文件放入 `json_trans`文件夹中,运行代码。 58 | 59 | 同样,这里的代码中,文本格式为:【人名】文本,如果格式有变化需要修改。 60 | 61 | 新的三行文本在 `triline_text_trans`中。 62 | 63 | 如果没有使用机翻,人工翻译后的三行文本也放入这个文件夹。 64 | 65 | 同样,文本的具体格式等内容随游戏变化较大,这部分建议自行根据具体游戏完成。 66 | 67 | ### 导入文本2 68 | 69 | 使用 `import_YSTB_FILE.py`可以将三行文本中的译文导入到ybn文件中。 70 | 71 | 如果发现有gbk编码不支持的符号,可以在 `YSTB_FILE.py`的 `append_trans`方法中进行替换或者删除。对于注音标识、特殊符号标识等,也可以设置进行替换为原本的编码以正确识别。 72 | 73 | 同样,如果文件有加密,会自动从 `Key.txt`读取密钥。 74 | 75 | ### 人名显示处理 76 | 77 | Yuris引擎中有文件定义了人名,如果不修改的话,对话中人名将无法正常显示。 78 | 79 | 现在的效果: 80 | 81 | ![1722575060988](image/README/1722575060988.png) 82 | 83 | 正常效果: 84 | 85 | ![1722575074786](image/README/1722575074786.png) 86 | 87 | 按照“文件筛选”中同样的步骤找到这个文件。通常名为 `キャラ名定義.txt`或类似的名字,在 `userdefine`文件夹中。找到这个文件并按上面的操作还原文件名,创建一个名为 `name_define`的文件夹并放入该文件。 88 | 89 | 使用 `change_name_define.py`可以转化该文件,自动放入 `scr_trans`和 `Release`文件夹中。 90 | 91 | ### 封包 92 | 93 | 没有研究。祈祷游戏支持免封包吧。关于免封包的研究可以参考[Dir-A_Essays_MD/Reverse/[YU-RIS] 免封包处理/[YU-RIS] 免封包处理.md at d76a81f734d8e26ac9cbf226f2c20f3d921e68fd · Dir-A/Dir-A_Essays_MD (github.com)](https://github.com/Dir-A/Dir-A_Essays_MD/blob/d76a81f734d8e26ac9cbf226f2c20f3d921e68fd/Reverse/%5BYU-RIS%5D%20%E5%85%8D%E5%B0%81%E5%8C%85%E5%A4%84%E7%90%86/%5BYU-RIS%5D%20%E5%85%8D%E5%B0%81%E5%8C%85%E5%A4%84%E7%90%86.md) 94 | 95 | ### 引擎中文化 96 | 97 | 使用 `GBK.py`可以实现引擎的中文化。需要将游戏启动的exe文件放入和代码同一个文件夹中,在代码中手动填入exe名称。如果报错,说明游戏可能不支持。其中所用的setdll.exe来自[microsoft/Detours: Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form. (github.com)](https://github.com/microsoft/Detours) 98 | 99 | 生成的 `_chs.exe`即为支持gbk编码的程序,需要连同 `MyDll.dll`一同发布,在游戏运行时需要放在游戏目录下。 100 | 101 | 补丁所需要的文件会自动复制到 `Release`文件夹中。 102 | -------------------------------------------------------------------------------- /YSTB_FILE.py: -------------------------------------------------------------------------------- 1 | #YBN文件格式解析 2 | from Lib import * 3 | 4 | 5 | class YSTB_command: 6 | def __init__(self, data= 0) -> None: 7 | if data != 0: 8 | self.read_command_bytes(data) 9 | self.command_offset: int 10 | 11 | def read_command_bytes(self, data): 12 | self.opcode = data[0:4] 13 | self.read_len = from_bytes(data[4:8]) 14 | self.content_offset = from_bytes(data[8:12]) 15 | 16 | def type(self) -> str: 17 | if self.opcode == b'\x00\x00\x00\x00': 18 | return "text" 19 | elif self.opcode == b'\x16\x00\x03\x00': 20 | return "sound" 21 | elif self.opcode == b'\x00\x00\x03\x00': 22 | return "may_be_opt" 23 | elif self.opcode == b'\x21\x00\x03\x00': 24 | return "name_def" 25 | elif self.opcode == b'\x22\x00\x03\x00': 26 | return "name_def" 27 | else: 28 | return "others" 29 | 30 | 31 | class YSTB_FILE: 32 | def __init__(self, path=None, data=None, encrypt: int = None) -> None: 33 | self.encrypt = None 34 | if encrypt: 35 | self.encrypt = to_bytes(encrypt,4) 36 | if path: 37 | self.read_from_path(path) 38 | if data: 39 | self.read_from_data(data) 40 | else: 41 | pass 42 | 43 | def read_from_path(self, path: str) -> None: 44 | data = open_file_b(path) 45 | self.read_from_bytes(data) 46 | 47 | def read_from_bytes(self, data: bytes) -> None: 48 | if self.encrypt: 49 | data = list(data) 50 | for i in range(len(data)): 51 | if i < 0x20: 52 | continue 53 | data[i] = data[i] ^ self.encrypt[i%4] 54 | data = bytes(data) 55 | 56 | self.magic = data[0:4] 57 | self.version = data[4:8] 58 | self.unknown1 = data[8:12] 59 | self.part1_len = from_bytes(data[12:16]) 60 | self.command_len = from_bytes(data[16:20]) 61 | self.str_len = from_bytes(data[20:24]) 62 | self.part4_len = from_bytes(data[24:28]) 63 | self.unknown2 = data[28:32] 64 | self.part1 = data[0x20 : 0x20 + self.part1_len] 65 | self.commands = list(data[ 66 | 0x20 + self.part1_len : 67 | 0x20 + self.part1_len + self.command_len 68 | ]) 69 | self.strs = data[ 70 | 0x20 + self.part1_len + self.command_len : 71 | 0x20 + self.part1_len + self.command_len + self.str_len 72 | ] 73 | self.part4 = data[ 74 | 0x20 + self.part1_len + self.command_len + self.str_len : 75 | 0x20 + self.part1_len + self.command_len + self.str_len + self.part4_len 76 | ] 77 | self.append_region = b"" 78 | self._read_command() 79 | 80 | def save_file(self, path: str,encrypt: int = None): 81 | data = ( 82 | self.magic 83 | + self.version 84 | + self.unknown1 85 | + to_bytes(len(self.part1), 4) 86 | + to_bytes(len(self.commands), 4) 87 | + to_bytes(len(self.strs)+len(self.append_region), 4) 88 | + to_bytes(len(self.part4), 4) 89 | + self.unknown2 90 | + self.part1 91 | + bytes(self.commands) 92 | + self.strs 93 | + self.append_region 94 | + self.part4 95 | ) 96 | if encrypt: 97 | encrypt = to_bytes(encrypt, 4) 98 | data = list(data) 99 | for i in range(len(data)): 100 | if i < 0x20: 101 | continue 102 | data[i] = data[i] ^ encrypt[i%4] 103 | data = bytes(data) 104 | save_file_b(path, data) 105 | 106 | def _read_command(self) -> list: 107 | self.command_list:list[YSTB_command] = [] 108 | p = 0 109 | while p < self.command_len: 110 | command = YSTB_command(bytes(self.commands[p : p + 12])) 111 | command.command_offset = p 112 | self.command_list.append(command) 113 | p += 12 114 | 115 | def _read_bytes_from_command(self, command: YSTB_command) -> bytes: 116 | offset = command.content_offset 117 | len = command.read_len 118 | if len == 0 or len > 256: 119 | return None 120 | return self.strs[offset : offset + len] 121 | 122 | def dump_text_to_file(self, path): 123 | outputfile = open(path, "w", encoding="utf8") 124 | opt_flag = False 125 | for command in self.command_list: 126 | command_offset = command.command_offset 127 | command_type = command.type() 128 | if command_type == "text": 129 | data = self._read_bytes_from_command(command) 130 | if data != None and data[0] != 0x4d and data[0:2] != b'H\x03' and b"\x00" not in data and b"cg" not in data: 131 | try: 132 | data = data.replace(b"\x87\x55", b"") 133 | text = data.decode(encoding='sjis') 134 | except: 135 | text = data.decode(encoding='sjis',errors='ignore') 136 | print(data) 137 | print(text) 138 | print(path) 139 | print(0x20 + self.part1_len + command_offset) 140 | print(0x20 + self.part1_len + self.command_len + command.content_offset) 141 | continue 142 | outputline = f'[{command_offset}]\nORI={text}\nTR1={text}\nTR2={text}\n' 143 | outputfile.write(outputline) 144 | 145 | if opt_flag: 146 | data = self._read_bytes_from_command(command)[4:-1] 147 | #print(data) 148 | if data == b'': 149 | opt_flag = False 150 | else: 151 | try: 152 | text = data.decode(encoding='sjis') 153 | outputline = f'[{command_offset}]opt\nORI={text}\nTR1={text}\nTR2={text}\n' 154 | outputfile.write(outputline) 155 | except: 156 | pass 157 | 158 | if command_type == "may_be_opt": 159 | data = self._read_bytes_from_command(command) 160 | if data == b'\x4D\x0C\x00\x22\x45\x53\x2E\x53\x45\x4C\x2E\x53\x45\x54\x22': 161 | opt_flag = True 162 | 163 | 164 | 165 | def append_trans(self,command_offset:int,trans:str): 166 | offset = len(self.strs) + len(self.append_region) 167 | #处理gbk不支持的符号 168 | trans = trans.replace("♪","").replace("#","#").replace("〜","~").replace("@","@") 169 | trans = replace_halfwidth_with_fullwidth(trans) 170 | 171 | trans = trans.replace("≪","114514").replace("/","114515").replace("≫","114516") 172 | transdata = trans.encode(encoding='gbk') 173 | 174 | transdata = transdata.replace("114514".encode('gbk'), "≪".encode("sjis")).replace("114515".encode('gbk'), "/".encode("sjis")).replace("114516".encode('gbk'), "≫".encode("sjis")) 175 | 176 | #处理特殊标识 177 | teshulist = ["@","#"] 178 | for i in teshulist: 179 | transdata = transdata.replace(i.encode(encoding='gbk'),i.encode(encoding='sjis')) 180 | 181 | length = len(transdata) 182 | self.append_region += transdata + b'\x00' 183 | self.commands[command_offset+4:command_offset+12] = list(to_bytes(length,4) + to_bytes(offset,4)) 184 | 185 | def append_opt(self,command_offset:int,trans:str): 186 | offset = len(self.strs) + len(self.append_region) 187 | transdata = trans.encode(encoding='gbk') 188 | transdata = b'\x4D' + to_bytes(len(transdata) + 2, 2) + b'\x22' + transdata + b'\x22' 189 | length = len(transdata) 190 | self.append_region += transdata + b'\x00' 191 | self.commands[command_offset+4:command_offset+12] = list(to_bytes(length,4) + to_bytes(offset,4)) 192 | 193 | class YSTB_NAMEDEF_FILE(YSTB_FILE): 194 | def _read_command(self) -> list: 195 | self.command_list:list[YSTB_command] = [] 196 | p = 0 197 | while p < self.command_len: 198 | command = YSTB_command(bytes(self.commands[p : p + 12])) 199 | command.command_offset = p 200 | if command.type() == "name_def": 201 | self.command_list.append(command) 202 | p += 12 203 | 204 | def _append_new_namedef(self,command_offset:int,newdata:bytes): 205 | offset = len(self.strs) + len(self.append_region) 206 | length = len(newdata) 207 | self.append_region += newdata + b'\x00' 208 | self.commands[command_offset+4:command_offset+12] = list(to_bytes(length,4) + to_bytes(offset,4)) 209 | 210 | def changenamecharset(self): 211 | for command in self.command_list: 212 | command_offset = command.command_offset 213 | command_type = command.type() 214 | if command_type != "name_def": 215 | return 216 | content_data = self._read_bytes_from_command(command) 217 | print(content_data[4:-1].decode(encoding='sjis')) 218 | newdata = content_data[:4]+content_data[4:-1].decode(encoding='sjis').encode(encoding='gbk')+content_data[-1:] 219 | self._append_new_namedef(command_offset,newdata) -------------------------------------------------------------------------------- /YSTB_GuessXorKey.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyxjyx1234/YURIS_TOOLS/348b30bda623c99782d0fe396068d8801d25096b/YSTB_GuessXorKey.exe -------------------------------------------------------------------------------- /YSTB_Xor.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyxjyx1234/YURIS_TOOLS/348b30bda623c99782d0fe396068d8801d25096b/YSTB_Xor.exe -------------------------------------------------------------------------------- /YSTL_Parse.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyxjyx1234/YURIS_TOOLS/348b30bda623c99782d0fe396068d8801d25096b/YSTL_Parse.exe -------------------------------------------------------------------------------- /change_name_define.py: -------------------------------------------------------------------------------- 1 | from YSTB_FILE import * 2 | from Lib import * 3 | import os 4 | 5 | ori_path = "name_define/" 6 | out_path = "scr_trans/" 7 | release_path = "Release/ysbin/" 8 | os.makedirs(out_path,exist_ok=True) 9 | os.makedirs(release_path,exist_ok=True) 10 | 11 | try: 12 | key = open("Key.txt","r",encoding='utf8').readlines() 13 | encrypt = eval(key[0]) 14 | except: 15 | encrypt = 0x00000000 16 | 17 | filelist = os.listdir(ori_path) 18 | 19 | for filename in filelist: 20 | name_def_f = YSTB_NAMEDEF_FILE(path=ori_path+filename,encrypt=encrypt) 21 | name_def_f.changenamecharset() 22 | name_def_f.save_file(out_path+filename,encrypt=encrypt) 23 | name_def_f.save_file(release_path+filename,encrypt=encrypt) -------------------------------------------------------------------------------- /image/README/1722575060988.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyxjyx1234/YURIS_TOOLS/348b30bda623c99782d0fe396068d8801d25096b/image/README/1722575060988.png -------------------------------------------------------------------------------- /image/README/1722575074786.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyxjyx1234/YURIS_TOOLS/348b30bda623c99782d0fe396068d8801d25096b/image/README/1722575074786.png -------------------------------------------------------------------------------- /import_YSTB_FILE.py: -------------------------------------------------------------------------------- 1 | from YSTB_FILE import * 2 | import os 3 | 4 | ori_path = "ysbin_new/" 5 | trans_path = "triline_text_trans/" 6 | out_path = "scr_trans/" 7 | os.makedirs(out_path,exist_ok=True) 8 | 9 | try: 10 | key = open("Key.txt","r",encoding='utf8').readlines() 11 | encrypt = eval(key[0]) 12 | except: 13 | encrypt = 0x00000000 14 | 15 | filelist = os.listdir(trans_path) 16 | 17 | for filename in filelist: 18 | YSTB_f = YSTB_FILE(path=ori_path + filename.replace(".tra.txt", "")) 19 | try: 20 | trans_f = open(trans_path + filename, "r", encoding="utf8") 21 | except: 22 | trans_f = [] 23 | 24 | for l in trans_f: 25 | if len(l) > 0 and l[0] == "[" and "opt" not in l: 26 | command_offset = int(l[1:-2]) 27 | isOpt = False 28 | elif len(l) > 0 and l[0] == "[" and "opt" in l: 29 | command_offset = int(l[1:-5]) 30 | isOpt = True 31 | elif l[0:4] == "TR2=": 32 | transtext = l[4:-1] 33 | if not isOpt: 34 | YSTB_f.append_trans(command_offset, transtext) 35 | else: 36 | YSTB_f.append_opt(command_offset, transtext) 37 | 38 | YSTB_f.save_file(out_path + filename.replace(".tra.txt", ""), encrypt=encrypt) 39 | 40 | os.system("copy scr_trans\\* Release\\ysbin\\") -------------------------------------------------------------------------------- /json2triline.py: -------------------------------------------------------------------------------- 1 | from Lib import * 2 | import os, re 3 | 4 | ori_json_folder = "json_ori\\" 5 | trans_folder = "json_trans\\" 6 | ori_triline_folder = "triline_text_ori\\" 7 | out_triline_folder = "triline_text_trans\\" 8 | os.makedirs(out_triline_folder,exist_ok=True) 9 | 10 | filelist = os.listdir(trans_folder) 11 | 12 | for filename in filelist: 13 | filename = filename[:-5] 14 | ori_json = open_json(ori_json_folder + filename + ".json") 15 | tran_json = open_json(trans_folder + filename + ".json") 16 | ori_triline = open(ori_triline_folder + filename + ".ori.txt", 'r',encoding='utf8').readlines() 17 | out_triline = open(out_triline_folder + filename + ".tra.txt","w",encoding="utf8") 18 | 19 | p = 0 20 | for i in range(len(tran_json)): 21 | name = tran_json[i]['name'] 22 | trans = tran_json[i]['post_zh_preview'] 23 | #这里调节人名格式 24 | if name != "": 25 | trans = f"【{name}】{trans}" 26 | while True: 27 | l = ori_triline[p] 28 | if l[:4]=="TR1=": 29 | ori_triline[p]="TR1="+trans+'\n' 30 | if l[:4]=='TR2=': 31 | print(trans) 32 | ori_triline[p]="TR2="+trans+'\n' 33 | p+=1 34 | break 35 | p+=1 36 | 37 | for l in ori_triline: 38 | out_triline.write(l) 39 | out_triline.close() 40 | -------------------------------------------------------------------------------- /read_YSTB_FILE.py: -------------------------------------------------------------------------------- 1 | #从YSTB文件中读取,生成三行文本 2 | from YSTB_FILE import * 3 | import os 4 | 5 | ori_path = "ysbin_new/" 6 | out_path = "triline_text_ori/" 7 | os.makedirs(out_path,exist_ok=True) 8 | 9 | try: 10 | key = open("Key.txt","r",encoding='utf8').readlines() 11 | encrypt = eval(key[0]) 12 | except: 13 | encrypt = 0x00000000 14 | 15 | 16 | filelist = os.listdir(ori_path) 17 | 18 | for filename in filelist: 19 | if filename[-3:] != "ybn": 20 | continue 21 | ori_file_path = ori_path + filename 22 | out_file_path = out_path + filename + ".ori.txt" 23 | 24 | f = YSTB_FILE(path= ori_file_path,encrypt=encrypt) 25 | f.dump_text_to_file(out_file_path) 26 | -------------------------------------------------------------------------------- /setdll.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jyxjyx1234/YURIS_TOOLS/348b30bda623c99782d0fe396068d8801d25096b/setdll.exe -------------------------------------------------------------------------------- /triline2json.py: -------------------------------------------------------------------------------- 1 | from Lib import * 2 | import os, re 3 | 4 | ori_folder = "triline_text_ori\\" 5 | out_path = "json_ori\\" 6 | os.makedirs(out_path,exist_ok=True) 7 | os.makedirs("json_trans\\",exist_ok=True) 8 | 9 | filelist = os.listdir(ori_folder) 10 | 11 | 12 | for filename in filelist: 13 | textlist:list[str] = [] 14 | outlist = [] 15 | dic = {} 16 | 17 | ori_filep = ori_folder + filename 18 | out_filep = out_path + filename.replace(".ori.txt", ".json") 19 | 20 | ori_file = open(ori_filep, "r", encoding="utf8").readlines() 21 | # 预读取 22 | for i in range(len(ori_file)): 23 | if len(ori_file[i]) > 4 and ori_file[i][0:4] == "ORI=": 24 | textlist.append(ori_file[i][4:-1]) 25 | 26 | #需要拼接文本可能需要进一步修改代码 27 | #这里是用【人名】,实际可能需要改动 28 | 29 | for l in textlist: 30 | if "】" in l: 31 | name,message = l.split("】",2) 32 | name = name[1:] 33 | dic["name"] = name 34 | dic["message"] = message 35 | else: 36 | dic["message"] = l 37 | 38 | outlist.append(dic) 39 | dic={} 40 | 41 | save_json(out_filep,outlist) 42 | 43 | ''' 44 | #人名没有特殊标识时,可以认为「『前是人名。这样会提取到很多不是人名的,可以先提取一次,然后创建一个人名表: 45 | nameset = set()#这一行放在代码最前面 46 | 47 | ... 48 | 49 | for l in textlist: 50 | if "「" in l: 51 | name,message = l.split("「",1) 52 | message = "「" + message 53 | if len(name) >10 : 54 | dic["message"] = l 55 | else: 56 | dic["name"] = name 57 | dic["message"] = message 58 | nameset.add(name) 59 | elif "『" in l: 60 | name,message = l.split("『",1) 61 | message = "『" + message 62 | if len(name) >10 : 63 | dic["message"] = l 64 | else: 65 | dic["name"] = name 66 | dic["message"] = message 67 | nameset.add(name) 68 | else: 69 | dic["message"] = l 70 | 71 | outlist.append(dic) 72 | dic={} 73 | 74 | print(nameset)#这一行放在代码最后 75 | 76 | 77 | #然后再对nameset手动筛选,将以上代码改为: 78 | nameset = {'霧葉', ...}#这一行放在代码最前面 79 | 80 | ... 81 | 82 | for l in textlist: 83 | if "「" in l: 84 | name,message = l.split("「",1) 85 | message = "「" + message 86 | if name not in nameset: 87 | dic["message"] = l 88 | else: 89 | dic["name"] = name 90 | dic["message"] = message 91 | elif "『" in l: 92 | name,message = l.split("『",1) 93 | message = "『" + message 94 | if name not in nameset: 95 | dic["message"] = l 96 | else: 97 | dic["name"] = name 98 | dic["message"] = message 99 | else: 100 | dic["message"] = l 101 | 102 | outlist.append(dic) 103 | dic={} 104 | ''' --------------------------------------------------------------------------------