UEDumper 是一款一体化虚幻引擎转储器,支持虚幻引擎 4.19 - 虚幻引擎 5.3.0 和实时编辑器,您可以在运行时查看生成的 SDK 并修改游戏的内存。
借助 ImGui 库实现丰富的 GUI。
Unreal Engine 4.19 - 5.3.0 支持,无需修改代码的任何内部结构。
SDK 生成器和编辑器。
新型MDK型发电机。
实时编辑器读取/写入游戏内存。
保存 SDK 和 MDK 以便在您的 C++ 项目中使用它。
引擎的源代码有据可查。
改变引擎行为的简单定义。
支持 Dumpspace。
这个项目并非开箱即用!为了支持你的游戏,你仍然需要自行逆向工程才能找到下文所述的信息。
请下载最新版本而不是主分支,因为它可能包含不稳定的代码!
UE版本
您可以通过右键单击发货应用程序并导航至“属性”→“详细信息”来找到正确的 UE 版本
抵消或签名
图形对象
GNames
GWorld 和实时编辑器的其他偏移量,这里有一个 获取此偏移量的帮助链接
FName解密
有些游戏会对 FName 进行加密。引擎会要求您找到解密函数并添加相应的代码。
如果没有加密,您可以忽略这一点。
游戏设置
每个UE版本都有一些选项可以更改引擎的内部结构(WITH_CASE_PRESERVING_NAME、UE_BLUEPRINT_EVENTGRAPH_FASTCALLS等,均位于Engine/Userdefined/UEdefinitions.h下)。请务必了解这些选项!
请记住,某些游戏(例如 Fortnite 或 PUBG)可能会更改引擎内部不正常的结构(通过修改 UE),除非您自行修复它们,否则 UEDumper 将无法正确转储
如果您找到了所有需要的信息,您可以将其设置在下面列出的文件中。
UE版本和游戏设置
在UEdefinitions.h (Engine/Userdefined/UEdefinitions.h) 中,将 UE_VERSION 宏设置为您的 UE 版本。该文件中定义了多个针对引擎特定内部结构的宏,您也必须按照入门指南中的说明进行设置。
此外,如果您的游戏有特定的内部结构变化,您可以为您的游戏添加自定义宏。
抵消或签名
在Offsets.h (Engine/Userdefined/Offsets.h) 文件中,添加游戏所需的所有偏移量。请务必阅读文件中的所有注释,以免您疑惑引擎或实时编辑器为何找不到您的偏移量。添加偏移量时,请确保名称参数唯一,否则可能会出现错误。偏移量的 GObjects 和 GNames 必须分别名为 OFFSET_GNAMES 和 OFFSET_GOBJECTS。
同样,您可以在UEdefinitions.h中为每个游戏添加一个自定义宏,以便更轻松地切换偏移量。
FName解密
在FName_decryption.h (Engine/Core/FName_decryption.h) 中,您可以添加自定义解密函数。请确保宏 USE_FNAME_ENCRYPTION 设置为TRUE!调用函数(位于 Engine/Core/Core.cpp@EngineCore::FNameToString 中)需要从 inputBuf 参数中获取解密后的名称。此外,请检查引擎是否正确获取了 namePoolChunk/FNameEntry(位于 Engine/Core/Core.cpp@EngineCore::FNameToString 中),这可能因游戏而异!
再次,您可以在UEdefinitions.h中为每个游戏添加一个自定义宏,以便更轻松地切换解密和读取条目。
读写内存
由于几乎所有热门游戏都使用反作弊功能,您可能需要为此项目添加自定义读写函数。默认实现是基本的 ReadProcessMemory / WriteProcessMemory。您可以在driver.h (Memory/driver.h) 中添加例程。如果可能,请不要修改该函数的任何参数。如果修改了,请确保它与调用函数(位于 Memory/Memory.cpp 中的 @Memory::read 和 Memory::write)兼容。这同样适用于 getBaseAddress 函数。
修改引擎
如前所述,某些游戏(例如 Fortnite 或 PUBG)会对引擎进行手动更改,我无法通过切换宏默认实现这些更改。您必须自行弄清楚它们更改了哪些结构体。但是,任何手动定义的虚幻引擎类都位于UnrealClasses.cpp和UnrealClasses.h (Engine/UEClasses/) 中,更改应该只会显示在那里。
如果您设置了所有信息并准备好转储,那就没有什么可以阻止您了。不过,这里有一些您可能需要的工具的基本说明。
你好窗口
第一个窗口(也称为 hello 窗口)要求您输入项目名称。这是必需的,因为您可能需要保存项目或创建转储。所有文件的位置都位于应用程序目录→项目名称(这将是您的工作目录)中。您必须选择一个不存在或空的文件夹。进程名称应与目标进程的名称完全相同,并且区分大小写。
设置按钮显示您当前的宏设置和日志级别。日志级别 0-4 表示您希望记录的信息量,其中 0 表示所有内容,而 4 仅表示最重要的信息。在级别 0 下,您可能会在整个转储过程中收到数千条日志消息,因为引擎会记录转储过程中的所有异常,而这些异常在大多数情况下可以被忽略。
此外,您可以加载任何已打开的现有项目(.uedproj 文件),从而跳过转储步骤。虽然加载项目时无法使用实时编辑器,因为某些重要数据可能有所不同(也称为离线模式)。但是,您仍然可以进行更改并查看每个包。您无需担心宏不匹配,只需确保 UE 版本匹配即可。
包装窗口
转储完成后(这应该不会花费很长时间),您将获得按名称排序的所有软件包列表。点击某个软件包,它将打开软件包查看器,其中将显示您选择的任何结构体/类/枚举。您也可以显示整个软件包内容,但这在大型软件包中可能会非常卡顿。
您可以点击每个成员类型以及每个类的继承者,然后直接跳转到特定的结构体/类/枚举。此外,您还可以随时通过点击导航按钮或点击之前所在的包返回。每个打开的包的导航栏都是唯一的,不会在各个包之间共享。
您可以在左上角的搜索栏中搜索结构/类/枚举,如果找到名称,它将跳转到该名称。
有时成员旁边会显示一个编辑按钮。如果出现此按钮,则表示该成员已被手动定义,或者是一个字节数组(表示该成员缺失)。您可以手动定义它,但在此之前,建议您阅读如何读取/保存对成员的更改。
您可以随时保存项目、保存更改以及创建 SDK。这些文件将出现在您的工作目录中。保存项目后,系统会创建一个 .uedproj 文件,您可以在下次启动转储程序时使用该文件。保存更改后,系统只会保存对结构体/类所做的更改。系统会创建一个 StructDefinitions 文件,您可以使用该文件覆盖现有的 StructDefinitions 文件。建议您阅读如何使用此文件。
实时编辑器
实时编辑器允许您在游戏运行时读取游戏内存,并支持转储结构体。例如,您可以浏览整个 UWorld 类及其所有成员并写入值。请注意,实时编辑器有一定的刷新限制,每隔 x 毫秒(默认 500 毫秒)读取所有打开结构体的内存。
您可以检查某个地址(该地址应直接指向 UObject),也可以使用Offsets.h中定义的偏移量。使用偏移量时,它应该指向 UObject 的指针。例如,通用的 UWorld 信号指向一个保存 UWorld 对象地址的指针。这样,每当世界发生变化时,实时编辑器就有可能自动使用新的世界。
请记住,实时编辑器可能随时崩溃,因此请确保事先保存所有更改。
目前,实时编辑器仅允许用户覆盖非指针或自定义数据类型的成员,因为修改指针可能会导致崩溃。某些完全自定义的类型可能根本无法显示。
自定义结构、成员和数据类型
如果您不想在编辑器或转储中随处看到 uint8_t 或 int64_t,您可以在Datatypes.h (Engine/Userdefined/Datatypes.h)中设置类型的名称
如果您想完全或部分覆盖某个类,或者创建一个在编辑器和实时编辑器中均可见的新类,您可以在StructDefinitions.h (Engine/Userdefined/StructDefinitions.h) 中执行此操作。请务必阅读文件和示例,了解代码添加的位置和方法。如果您在运行时进行任何更改,则需要输入区分大小写的 PropertyType。请仅覆盖成员,切勿添加偏移量完全不同或大小完全错误的成员。这会导致 SDK 生成中断,因为大小不再匹配,实时编辑器可能会崩溃。在 StructDefinitions.h 中覆盖/添加成员始终比在编辑器中更安全,因为某些检查可能不会进行。但是,由于没有检查您定义的成员的大小是否正确,引擎会猜测您是正确的。如果您使用了错误的大小,实时编辑器和 SDK 都会出错!
在实时编辑器中添加自定义支持
这并非易事。不过,这取决于您要添加的内容。如果您想像 FVector 一样在一行中显示结构体,或者显示颜色选择器,您可以在 LiveEditor.cpp@LiveEditor::drawStructProperty 中实现。
如果您想添加对全新类型的支持,请务必从 LiveEditor::drawMembers 中调用针对特定 PropertyType 的函数。请查看现有函数的代码,了解哪些操作可以做,哪些操作不能做。请避免每帧都写入数据,也不要调用不使用无序映射的繁重函数。
感谢您的贡献!我可能不会添加对虚幻引擎 3 或更早版本的支持,但你可以。
请记住,我不会接受任何改变整个代码库、不使用任何缓存、没有记录或只是混乱的拉取请求。
这个项目规模很大,但非常稳定,几乎所有功能都使用了大量缓存,以确保正常运行和快速运行。如果您发现任何更好的解决方案,请随时创建拉取请求来实现。
使用“调试”模式时可以更好地处理错误和调试
更好的软件包生成和修复多个很少发生的小问题
转储空间生成更新
修复与日志相关的程序计时崩溃
SDK 生成现已适用于 99% 的游戏