marcussacana/StringReloads
GitHub: marcussacana/StringReloads
一款通过底层代码注入实现游戏文本替换与字体修改的本地化翻译辅助工具,支持多种视觉小说引擎的自动化安装。
Stars: 122 | Forks: 16
# StringsReloads v7.6
[](https://ci.appveyor.com/project/marcussacana/StringReloads)
这是一个使用低级代码注入字符串的工具
* 帮助翻译游戏而不被发现封包/加密方式。
* 帮助使用非 ASCII 字符。
* 提供可自定义的自动换行(Auto-WordWrap)。
* 帮助更改游戏字体大小(如可行)
* 帮助修复非等宽字符间距(如可行)
* 只需少量的汇编知识即可使用
我们注入字符串的策略是,使用 Stud_PE 或 CFF Explorer 等工具创建一个新区段,以便在可执行文件中获得追加新代码的空间。一种常见的方法是替换原始指令并跳转到你的代码。通常一个跳转指令长度为 5 个字节,有时你需要替换不止一条指令,并且不要忘记在代码执行完毕后,还原原有的 CMP 和 TEST 等指令(当然,前提是存在这些指令)。
### 调用算法示例:
```
@StrInject: ;Declare StrInject Label
push EDX ;Backup EDX, ECX, EBX Registers
push ECX
push EBX
push EAX ;The EAX is the string pointer or a unicode character
call GetProc ;Here the Srl.Process Pointer is catched
call EAX
pop EBX ;Restore EDX, ECX, EBX Registers from the "Backup"
pop ECX
pop EDX
jmp RetPnt ;Continue the Execution
```
我们有多种方法来获取 Srl.Process 指针,下面这个示例适用于主模块动态分配的游戏。如果你已经将导出函数注入到了游戏的可执行文件中,就可以使用下面这个示例。你可以使用 Stud_PE 或 CFF Explorer 来完成此操作,同时你还需要创建一个新的可执行文件区段来追加我们的新代码。
在此示例中,导入表中的 Srl.Process 地址始终是相对于我们新建的可执行文件区段的。
在下面的代码中,获取到的 EIP 指向 "pop EAX",而导入表中的 Srl.Process 假设为 0x02B9C400,"pop EAX" 位于 0x02B9E44C,因此...
0x02B9E44C - 0x02B9C400 = 0x204C,现在如果用 EIP 减去这个值,我们就可以得到 Srl.Process 指针的位置。
如果你想使用 SRL 来输入非 ASCII 字符,你需要调用 Srl.Process,并将 GetGlyph 函数获取的字符传递给它。
### 获取 Srl.Process 示例:
```
@GetProc:
call @Nxt ;Call the label Nxt
@Nxt: ;Declare the Nxt label
pop EAX ;Catch the EIP :)
sub EAX, 0x204C ;Subtract the Difference from the EIP and Import Address
mov EAX, [EAX] ;Read the import table
ret
```
### 最快的重载方法:
在遇到一些游戏在循环内重载字符串的问题之后,我创建了 GetDirectProcess。导入此函数的方法与上述的 SRL.Process 相同,但你需要修改 GetProc,下面是一段示例代码:
```
@GetProc:
call @Nxt ;Call the label Nxt
@Nxt: ;Declare the Nxt label
pop EAX ;Catch the EIP :)
cmp dword [EAX+0x21], 0;Verify if already have the Address
jne @Finish
push EAX ;Backup NXT Address
sub EAX, 0x2050 ;Subtract the Difference from the EIP and Import Address
mov EAX, [EAX] ;Read the import table
call EAX ;Calls the GetDirectProcess
pop EBX ;Recovery NXT Address
mov [EBX+0x21], EAX ;Save the Process Address
mov EAX, EBX ;Prepare to Finish
@Finish:
add EAX, 0x21 ;Ajust Pointer
mov EAX, [EAX] ;Read the Process Address
ret
@Ptr:
dd 0 ;Here is the @Nxt: + 0x21
```
此方法没有参数,只需调用并获取 EAX 即可,EAX 就是指向 Process 函数的指针。
### 自动安装功能:
SRL 具有一项功能,可以在游戏引擎中自动安装 SRL,而无需你了解如何对游戏打补丁。
首先,在[此处](https://github.com/marcussacana/StringReloads/releases/latest)下载 SRL,将其解压到游戏目录,然后将 SRLWrapper.dll 重命名为 d3d9.dll、dinput8.dll 或任何其他受支持的 wrapper([在此查看受支持的类型](https://github.com/marcussacana/StringReloads/tree/master/SRLWrapper/Wrapper)),接着在 SRL.ini 中将 AutoInstall 设置为 true。
#### 受支持的引擎:
- AdvHD
- SoftPal
- CMVS32 和 CMVS64
- ExHIBIT
- EntisGLS
- Favorite (FVP)
某些 SoftPal 游戏需要借助自动安装程序进行手动设置,点击下方链接查看示例:
[](http://www.youtube.com/watch?v=RAgZQBWqiJQ "SRL SoftPal Auto-Install Feature")
EntisGLS 自动安装功能仅允许你修改引擎内部的 XML 配置,借此你可以设置自定义字体并加载解包后的文件。
只需在生成的 `EntisGLSConfig.xml` 文件中添加 ` `,SRL 就会自动强制游戏使用你的自定义设置。
注意:优先级取决于行数靠前的配置,请将此行添加到其他 ` ` 或 ` ` 块的顶部。
### 字体修改器
人们对 String Reloads 最常见的功能需求之一就是字体修改器,该功能适用于绝大多数未使用预渲染字体的游戏,且设置简单。
首先,在[此处](https://github.com/marcussacana/StringReloads/releases/latest)下载 SRL,将其解压到游戏目录,然后将 SRLWrapper.dll 重命名为 d3d9.dll、dinput8.dll 或任何其他受支持的 wrapper([在此查看受支持的类型](https://github.com/marcussacana/StringReloads/tree/master/SRLWrapper/Wrapper))。
现在,你需要在 SRL.ini 中启用 CreateFont hook,我们有 4 种 CreateFont 变体:CreateFontA、CreateFontW、CreateFontIndirectA 和 CreateFontIndirectW。
通常,一款游戏只会使用这 4 种选项中的一种。要确定应该启用哪个 hook,正确的方法是在游戏的可执行文件中查找是否包含字符串 "CreateFontA"、"CreateFontW"、"CreateFontIndirectA" 或 "CreateFontIndirectW"... 或者,如果你想省事或者有点疯狂,你可以直接全部启用,但不建议这么做。
当你启用 CreateFont hook 后,SRL 就能够修改游戏字体的少部分内容,例如字体大小(并不适用于所有引擎)和字体本身。
在 SRL.ini 的末尾,你可以找到一个默认的“示例”字体重映射条目,即 `[Font.0]`。你可以通过在块名中添加递增的数字来添加更多字体重载参数,例如 `[Font.1]`、`[Font.2]`、`[Font.3]`...
- 在 `From` 参数中,你可以设置要修改的“原始”字体名称,其中 * 表示所有字体。
- 在 `FromWidth` 或 `FromHeight` 中,你可以通过指定字体的原始大小来匹配需要修改的字体。(默认被注释掉)
- 在 `FromCharset` 中,你可以通过指定字符集来匹配需要修改的字体。(默认被注释掉)
- 在 `To` 参数中,你可以设置你的“目标”字体名称。
- 在 `Charset` 参数中,你可以强制指定要使用的字体字符集,其中 0 = 自动,注释掉 = 不修改,932 = SJIS,查看更多数值请点击[这里](https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers)
- 在 `Width`、`Height` 参数中,你可以修改字体大小。数字可以是绝对大小或相对大小,`+5` 或 `-1` 是根据原始字体大小计算的相对值。在值前面加上 `.` 前缀表示该值为绝对值,因此无论原始字体大小是多少,`.-1` 都会变成 -1。
- 如果你愿意,`Width`、`Height` 参数还可以更加动态化。你可以将值设置为在运行时计算的表达式,例如,如果你将 `Width` 设置为 `if([Width] < 0, [Width] * -1, [Width])`,此表达式会检查 Width 是否为负数,如果是则将其转为正数,否则不进行任何操作。
表达式可以包含以下参数:`[Width]`、`[Height]`、`[Charset]`、`[Facename]`,你可以查看[这里](https://github.com/ncalc/ncalc/wiki)了解表达式用法的详细信息。
此外,在 `[StringReloads]` 块中,你可以找到 `LoadLocalFonts` 参数。将此参数设置为 true 后,SRL 将使游戏能够直接从游戏目录(或其子目录)加载字体,而无需在宿主系统中安装该字体。
### 依赖项:
* [DllExport](https://github.com/3F/DllExport) (已包含)
### 实用工具:
* [Multiline Assembly](http://rammichael.com/multimate-assembler) (允许在指定位置写入一段代码块)
* (例如使用 <0x02B9E44A> 来指定写入代码的位置)
* 自动构建:[AppVeyor](https://ci.appveyor.com/project/marcussacana/StringReloads/build/artifacts)
* 最新构建:[下载](https://ci.appveyor.com/api/projects/marcussacana/StringReloads/artifacts/SRL/bin/SRLEngine.zip)
* 自动发布:[访问](https://github.com/marcussacana/StringReloads/releases/latest)
标签:UML, 云资产清单, 字符串注入, 汇编, 游戏模组, 游戏汉化, 端点可见性, 逆向工程