溺的文档
Dumper-7 · 第 4 篇 / 共 4 篇

Dumper-7 代码生成管线

2026-06-30 · 阅读 5

本文是 Dumper-7 解读系列的第四篇,承接:

本文讲解最后一个阶段:把 Manager 层整理好的结构化数据,输出成可编译的 C++ SDK,以及三种辅助格式(USMAP / IDA 映射 / Dumpspace JSON)。

目录

  1. 概述:Generate 阶段与生成器协议
  2. CppGenerator 总流程与文件结构
  3. GenerateStruct:单个结构体/类的生成
  4. GenerateMembers:成员与 padding 生成
  5. GenerateEnum:枚举生成
  6. 函数生成与 ProcessEvent 调用桩
  7. 类型字符串映射
  8. Basic 基础设施与运行时定位
  9. 预定义成员与函数注入
  10. 文件头与依赖 include
  11. SDK 编译自测
  12. 三种辅助输出格式
  13. 关键函数索引

1. 概述:Generate 阶段与生成器协议

main()InitEngineCore()InitInternal() 之后,依次驱动四个生成器:

Generator::Generate<CppGenerator>();      // C++ SDK(主产物)
Generator::Generate<MappingGenerator>();  // .usmap 二进制映射
Generator::Generate<IDAMappingGenerator>();// .idmap IDA 符号
Generator::Generate<DumpspaceGenerator>();// Dumpspace JSON

四个生成器都满足同一个 C++20 concept GeneratorImplementation(见 Generator.h),即必须提供:

template<typename GeneratorType>
concept GeneratorImplementation = requires(GeneratorType t)
{
    GeneratorType::PredefinedMembers;   // PredefinedMemberLookupMapType
    GeneratorType::MainFolderName;      // 主目录名
    GeneratorType::SubfolderName;       // 子目录名
    GeneratorType::MainFolder; GeneratorType::Subfolder;  // fs::path
    GeneratorType::Generate();
    GeneratorType::InitPredefinedMembers();
    GeneratorType::InitPredefinedFunctions();
};

Generator::Generate<T>() 是统一模板驱动:首次调用时建立输出目录、转储 GObjects 与 EditorOnly 元数据,然后挂接该生成器的预定义成员表,最后调用其 Generate()

template<GeneratorImplementation GeneratorType>
static void Generate()
{
    if (DumperFolder.empty()) { SetupDumperFolder(); ObjectArray::DumpObjects(...); ... }
    SetupFolders(GeneratorType::MainFolderName, GeneratorType::MainFolder, ...);

    GeneratorType::InitPredefinedMembers();
    GeneratorType::InitPredefinedFunctions();
    MemberManager::SetPredefinedMemberLookupPtr(&GeneratorType::PredefinedMembers);

    GeneratorType::Generate();
}

这套协议让"再加一种输出格式"变得容易:实现一个满足 concept 的类即可,无需改动收集层。


2. CppGenerator 总流程与文件结构

CppGenerator 是项目的核心,约 9000 行。Generate() 分三个阶段。

2.1 三阶段流程

void CppGenerator::Generate()
{
    // ── 阶段一:全局基础文件 ──
    GenerateSDKHeader(SDK.hpp);               // 总 include 枢纽
    GeneratePropertyFixupFile(PropertyFixup.hpp);   // 未知属性占位
    GenerateNameCollisionsInl(NameCollisions.inl);  // 跨包重名的前向声明
    GenerateUnrealContainers(UnrealContainers.hpp); // TArray/TMap/TSet/FString
    GenerateUnicodeLib(UtfN.hpp);             // Unicode 编解码

    // ── 阶段二:SDK 运行时基础设施 ──
    GenerateBasicFiles(Basic.hpp, Basic.cpp, Assertions.inl);

    // ── 阶段三:逐包生成 ──
    for (PackageInfoHandle Package : PackageManager::IterateOverPackageInfos())
    {
        // 按需创建 {Package}_classes.hpp / _structs.hpp / _parameters.hpp / _functions.cpp
        // 生成枚举 → structs 文件
        // 按拓扑序生成结构体、类(DependencyManager 回调)
    }

    if constexpr (Settings::Debug::bShouldGenerateSDKCompilationTestScript)
        GenerateSDKTestScript(SDKTest.py);
}

2.2 产物目录结构

{GameVersion}-{GameName}/          (DumperFolder)
└── CppSDK/                        (MainFolder)
    ├── SDK.hpp                    总入口:#include 所有包文件
    ├── PropertyFixup.hpp          未识别属性的占位定义
    ├── NameCollisions.inl         跨包同名类型的前向声明
    ├── UnrealContainers.hpp       TArray / TMap / TSet / TWeakObjectPtr / FString...
    ├── UtfN.hpp                   UTF 编解码库
    ├── Assertions.inl             (可选) static_assert 宏集中文件
    ├── SDKTest.py                 (可选) 编译自测脚本
    └── SDK/                       (Subfolder)
        ├── Basic.hpp              UObject/UClass/FName/ProcessEvent/偏移常量...
        ├── Basic.cpp              GetImageBase / FindClass 等实现
        ├── {Package}_classes.hpp
        ├── {Package}_structs.hpp
        ├── {Package}_parameters.hpp
        └── {Package}_functions.cpp

把 struct / class / parameters / functions 拆成四类文件,是为了能用前向声明 + 分文件包含来打破循环依赖(见数据收集文档第 4 节)。


3. GenerateStruct:单个结构体/类的生成

GenerateStruct() 负责输出一个 struct/class/union 的完整定义。流程:

  1. 头部注释 + 声明行:包含全名、相对大小(本类新增字节)、总大小、父类大小,以及 class/struct/unionalignasfinal: public Super 等修饰:
StructFile << std::format(R"(
// {FullName}
// 0x{SizeWithoutSuper:04X} (0x{TotalSize:04X} - 0x{SuperSize:04X})
{pragmaPack}{templateText}{class|struct|union}{alignas} {UniqueName}{final}{: public Super}
{{
)", ...);
  1. 成员:调用 GenerateMembers()(见第 4 节)。
  2. 函数:调用 GenerateFunctions(),包括自动注入的 StaticClass()GetDefaultObj() 等。
  3. 闭合 };
  4. 静态断言(可选):若开启 bGenerateAssertionFile,为该类生成校验内存布局的宏:
static_assert(alignof(UniqueName) == 0x...);
static_assert(sizeof(UniqueName)  == 0x...);
static_assert(offsetof(UniqueName, Member) == 0x...);

静态断言是 SDK 正确性的最后一道防线:一旦生成的布局与游戏实际内存不符,编译期就会报错,而不是运行时崩溃。它们可内联在结构体后,也可集中到 Assertions.inl(由 bGenerateInlineAssertionsForStructSize/Members 控制)。


4. GenerateMembers:成员与 padding 生成

GenerateMembers() 是保证"生成的结构体内存布局与游戏完全一致"的核心。它在成员之间精确插入字节填充与位域填充。

4.1 状态跟踪

遍历成员时维护若干游标:

int32 PrevPropertyEnd        = SuperSize;   // 上一个成员的结束偏移
int32 PrevBitPropertyEnd     = 0;
int32 PrevBitPropertyEndBit  = 1;           // 上一个位域在其字节内的结束位
uint8 PrevBitPropertySize    = 0x1;
uint64 PrevNumBitsInUnderlayingType = 0x8;
bool  bLastPropertyWasBitField = false;

4.2 三类填充

对每个成员,按需生成三种填充:

① 成员间字节填充——当前成员偏移大于上一个成员结束偏移时:

if (MemberOffset > PrevPropertyEnd && !bIsUnion)
    OutMembers += GenerateBytePadding(PrevPropertyEnd, MemberOffset - PrevPropertyEnd, "Fixing Size After Last Property");

② 位域内比特填充——同一字节内两个位域之间有空隙时:

if (PrevBitPropertyEndBit < BitFieldIndex && !bIsUnion)
    OutMembers += GenerateBitPadding(MemberSize, PrevBitPropertyEndBit, MemberOffset,
                                     BitFieldIndex - PrevBitPropertyEndBit, "Fixing Bit-Field Size Between Bits");

③ 结构体尾部填充——遍历结束后,若总大小大于最后成员结束:

const int32 MissingByteCount = Struct.GetUnalignedSize() - PrevPropertyEnd;
if (MissingByteCount > 0x0)
    OutMembers += GenerateBytePadding(PrevPropertyEnd, MissingByteCount, "Fixing Struct Size After Last Property");

两个填充生成器分别产出字节数组与匿名位域:

// uint8 Pad_0x394[0x4];   // 0x0394(0x0004)(原因)
GenerateBytePadding(Offset, PadSize, Reason);

// uint32 BitPad_0x398_1 : 7;   // 0x0398(0x0004)(原因)
GenerateBitPadding(UnderlayingSizeBytes, PrevBitEndBit, Offset, PadSize, Reason);

4.3 成员声明

非填充成员根据类型生成声明,并处理数组维度、位域宽度、默认值:

if (Member.GetArrayDim() > 1)  MemberName += std::format("[0x{:X}]", Member.GetArrayDim());
else if (bIsBitField)          MemberName += " : " + std::to_string(Member.GetBitCount());
if (Member.HasDefaultValue())  MemberName += " = " + Member.GetDefaultValue();

4.4 生成示例(示意)

// Engine.Character
// 0x0020 (0x03A0 - 0x0380)
class ACharacter final : public APawn
{
public:
    class USkeletalMeshComponent*  Mesh;                  // 0x0380(0x0008)
    float                          Health;                // 0x0390(0x0004)
    uint8                          Pad_0x394[0x4];        // 0x0394(0x0004)(Fixing Size After Last Property)
    bool                           bCanMove : 1;          // 0x0398(0x0001)
    uint8                          BitPad_0x398_1 : 7;    // 0x0398(0x0001)(Fixing Bit-Field Size Between Bits)
    uint32                         MovementMode;          // 0x039C(0x0004)
};
static_assert(offsetof(ACharacter, Health) == 0x0390);
static_assert(sizeof(ACharacter) == 0x03A0);

5. GenerateEnum:枚举生成

GenerateEnum() 输出 enum class,底层类型由 EnumManager 推断(见数据收集文档第 6 节),值名由冲突信息决定后缀:

// Engine.EWeaponType
// NumValues: 0x0003
enum class EWeaponType : uint8
{
    EWT_Rifle  = 0,
    EWT_Pistol = 1,
    EWT_Sniper = 2,
};

底层类型字符串由大小与符号性组合得到(int8/uint8/int16/uint16/.../uint64)。


6. 函数生成与 ProcessEvent 调用桩

UE 的蓝图可调用函数(UFunction)在 SDK 中被包装成普通 C++ 方法,内部通过 UObject::ProcessEvent 间接调用引擎。GenerateSingleFunction() 同时产出"头文件声明"与"cpp 实现"。

6.1 GenerateFunctionInfo:解析签名

GenerateFunctionInfo() 遍历函数的参数属性(带 Parm 标志),按 UE 的参数标志决定 C++ 形参写法:

UE 属性标志 C++ 处理
ReturnParm 作为返回类型
OutParm 且非引用 指针 T*
ReferenceParm 引用 T&
ConstParm const
结构体/数组/字符串/Map/Set 等大对象(非 out) const T& 传,并标记 bIsMoveParam
struct ParamInfo
{
    bool bIsOutPtr, bIsOutRef, bIsMoveParam, bIsRetParam, bIsConst;
    EPropertyFlags PropFlags;
    std::string Type, Name;
};

6.2 实现体:ProcessEvent 桩

生成的实现把实参填入参数结构体,调用 ProcessEvent,再把 out 参数回写:

bool ACharacter::SetMovementSpeed(float NewSpeed)
{
    static class UFunction* Func = nullptr;
    if (Func == nullptr)
        Func = Class->GetFunction("Character", "SetMovementSpeed");

    Params::ACharacter_SetMovementSpeed_Params Parms{};
    Parms.NewSpeed = NewSpeed;

    UObject::ProcessEvent(Func, &Parms);

    return Parms.ReturnValue;
}

要点:

  • Funcstatic 缓存,只查一次;
  • Native 函数调用前后会临时清/恢复 FunctionFlags 中的 Native 位(否则引擎会走原生执行路径而非 ProcessEvent);
  • out 指针参数:if (p != nullptr) *p = Parms.p;;out 引用参数:p = Parms.p;;可移动类型用 std::move
  • 静态函数通过 GetDefaultObj()-> 调用,接口函数通过 AsUObject()-> 调用。

6.3 参数结构体

每个有参数的函数生成一个 _params 结构体(放在 _parameters.hppParams 命名空间),其布局同样经 GenerateStruct 精确填充:

namespace Params
{
    struct ACharacter_SetMovementSpeed_Params
    {
        float NewSpeed;     // 0x0000(0x0004)
        bool  ReturnValue;  // 0x0004(0x0001)
    };
}

参数结构体本质上就是把 FunctionWrapper::AsStruct() 当成普通结构体生成——这正是 Wrapper 抽象层(数据收集文档第 10 节)带来的复用。


7. 类型字符串映射

GetMemberTypeStringWithoutConst() 把 UE 反射属性映射成 C++ 类型字符串,是连接"反射类型系统"与"C++ 类型"的桥梁。它按 EClassCastFlags 逐类判定:

UE 属性 C++ 类型
ByteProperty(带枚举) 枚举名;否则 uint8
Int/Int64/UInt32/... int32/int64/uint32/...
Float/Double float/double
BoolProperty 原生 bool,或按大小取整型(位域)
NameProperty/StrProperty/TextProperty class FName/FString/FText
ObjectProperty class X*
ClassProperty class UClass*TSubclassOf<X>
StructProperty struct X(循环时走修复类型)
ArrayProperty TArray<内部类型>(递归)
MapProperty TMap<K, V>(递归)
SetProperty TSet<元素>(递归)
WeakObjectProperty TWeakObjectPtr<X>
Lazy/Soft Object/Class TLazyObjectPtr/TSoftObjectPtr/TSoftClassPtr<X>
DelegateProperty TDelegate<签名>
MulticastInlineDelegateProperty TMulticastInlineDelegate<签名>
InterfaceProperty TScriptInterface<I>
EnumProperty 枚举名;否则底层属性类型
无法识别 类名_(带下划线后缀,并在 PropertyFixup.hpp 占位)

容器类型通过递归调用自身得到内部类型字符串,因此 TArray<TMap<FName, TArray<int32>>> 这样的深层嵌套也能正确展开。

循环依赖修复:当 StructProperty 的目标结构体与当前包构成循环(IsCyclicWithPackage),不能直接 #include,于是生成一个等大的占位类型(GetCycleFixupType),保证 sizeof 正确,留待使用者强转。


8. Basic 基础设施与运行时定位

GenerateBasicFiles() 生成 SDK 运行所必需的"地基"。

8.1 Basic.hpp 主要内容

  • 命名空间与对齐宏SDK_NAMESPACE_START/ENDSDK_ALIGN 等;
  • 偏移常量:把 Dumper 找到的关键偏移写死进 SDK,供运行时直接访问:
namespace Offsets
{
    constexpr int32 GObjects        = 0x...;  // 全局对象数组
    constexpr int32 AppendString    = 0x...;  // FName::AppendString
    constexpr int32 GNames          = 0x...;  // 名称表
    constexpr int32 GWorld          = 0x...;  // 当前 UWorld
    constexpr int32 ProcessEvent    = 0x...;  // ProcessEvent 函数偏移
    constexpr int32 ProcessEventIdx = 0x...;  // ProcessEvent 在虚表中的索引
}
  • InSDKUtilsGetImageBase()(可由 Settings::CppGenerator::GetImageBaseFuncBody 自定义)、GetVirtualFunction()CallGameFunction()
  • 对象查找辅助FindClassByName/FindClassByFullName/GetObjectByIndex 等;
  • StaticClass 模板:为每个类提供按名缓存的 StaticClass() 实现,蓝图生成类则用"对象索引 + FName 校验"做缓存失效检测。

8.2 Basic.cpp

实现平台相关的 GetImageBase()(默认 GetModuleHandle(0))、FindClass*StringToName 等,并 #include CoreUObjectEngine 的类文件。

bAddManualOverrideOptions 开启时,SDK 还会暴露手动设置 GObjects/GNames/AppendString 地址的接口,应对 Dumper 自动定位失败的加密游戏。


9. 预定义成员与函数注入

InitPredefinedMembers() / InitPredefinedFunctions() 把无法从反射获取的成员/方法注入核心类(机制见数据收集文档第 11 节)。

9.1 注入的成员

UObject/UField/UStruct/UEnum/UFunction/UClass 等手工补齐反射里没有的字段,例如 UObject

PredefinedMember { .Type = "inline class TUObjectArrayWrapper", .Name = "GObjects", .bIsStatic = true };
PredefinedMember { .Type = "void*",         .Name = "VTable",  .Offset = Off::UObject::Vft };
PredefinedMember { .Type = "EObjectFlags",  .Name = "Flags",   .Offset = Off::UObject::Flags };
PredefinedMember { .Type = "int32",         .Name = "Index",   .Offset = Off::UObject::Index };
PredefinedMember { .Type = "class UClass*", .Name = "Class",   .Offset = Off::UObject::Class };
PredefinedMember { .Type = "class FName",   .Name = "Name",    .Offset = Off::UObject::Name };
PredefinedMember { .Type = "class UObject*",.Name = "Outer",   .Offset = Off::UObject::Outer };

还包括两个 SDK 用户最常用的"惊喜"成员,直接用 Dumper 找到的偏移注入:

  • ULevel::ActorsTArray<AActor*>);
  • UDataTable::RowMapTMap<FName, uint8*>)。

9.2 注入的函数

UObject 注入一整套使用 SDK 必备的方法:

方法 作用
FindObject<T> / FindObjectFast<T> 遍历 GObjects 按名查找对象
FindClass / FindClassFast 查找 UClass
GetName() / GetFullName() 取对象名 / 完整名
IsA(UClass*) / IsA(FName) / IsA(EClassCastFlags) 三种类型检查重载
ProcessEvent(UFunction*, void*) 通过虚表索引调用引擎 ProcessEvent(内联)

UStruct 则注入 IsChildOfGetPropertiesFindMember 等。这些函数体以原始字符串字面量直接写在 PredefinedFunction::Body 中,bIsBodyInline 决定它写进头文件还是 cpp。


10. 文件头与依赖 include

WriteFileHead() 为每个文件写头部,最关键的是根据 PackageManager 的依赖信息生成 #include 列表

const DependencyListType& List =
    (Type == EFileType::Structs) ? Dep.StructsDependencies :
    (Type == EFileType::Classes) ? Dep.ClassesDependencies :
                                   Dep.ParametersDependencies;

for (const auto& [PackageIndex, Requirements] : List)
{
    if (Requirements.bShouldIncludeStructs) File << "#include \"" + Name + "_structs.hpp\"\n";
    if (Requirements.bShouldIncludeClasses) File << "#include \"" + Name + "_classes.hpp\"\n";
}

由于循环依赖已在 PackageManager::PostInit() 阶段打破(删边 + 前向声明),这里写出的依赖图保证无环,#include 顺序安全。文件头还负责:UTF-8 BOM、#pragma once、Basic.hpp 包含、32 位平台的 #pragma pack(push, 0x4)、SDK 命名空间开启等。WriteFileEnd() 则负责闭合命名空间与 #pragma pack


11. SDK 编译自测

为了验证生成的 SDK 真的能编译,CppGenerator 可生成并执行一个 Python 脚本:

  • GenerateSDKTestScript():写出 SDKTest.py,内含一段示例 TestMain.cpp(演示获取 UEngine/UWorld、遍历 GObjects、访问 Level->Actors 等)与一份 CMakeLists.txt,用 MSVC 和 Clang 两种编译器各编译一次。
  • ExecuteSDKCompilationTestScript():用 CreateProcessW 调起 python SDKTest.py,必要时临时生成脚本并在跑完后自删。

Settings::Debug::bShouldGenerateSDKCompilationTestScriptbExecuteSDKTestScript 两个开关控制。


12. 三种辅助输出格式

除 C++ SDK 外,Dumper-7 还生成三种面向不同工具链的格式。

生成器 产物 格式 消费方
MappingGenerator .usmap 二进制(压缩) UE 资源反序列化工具(Unversioned Properties)
IDAMappingGenerator .idmap + ReadMe.txt 二进制(无压缩) IDA 插件(自动命名虚表与 Exec 函数)
DumpspaceGenerator JSON 文本 Dumpspace 在线查看器

12.1 MappingGenerator(USMAP)

用途:UE4.12+ 的"Unversioned Properties"在序列化时不再写入属性名,外部工具需要一张 .usmap 映射表才能解析 pak/uasset。

文件结构

[文件头]
  uint16 Magic = 0x30C4
  uint8  Version            (EUsmapVersion,当前 ExplicitEnumValues = 4)
  [可选包版本信息]
  uint8  CompressionMethod  (None/Oodle/Brotli/ZStandard,默认 ZStandard)
  uint32 CompressedSize
  uint32 DecompressedSize
[压缩载荷]
  [名称表] [枚举表] [结构表]
  • 名称表uint32 数量 + 每项 uint16 长度 + 字符串。可选去重(GNameMap 哈希表)以减小体积。
  • 枚举表:每项含名称索引、成员数(v3 起为 uint16,支持大枚举)、每个成员的 (显式值 int64, 名称索引)(v4 起含显式值)。
  • 结构表:每项含名称索引、父类索引、属性数、可序列化属性数,以及每个属性的编码。
  • 属性编码属性索引 + 数组维度 + 名称索引 + 类型枚举(EMappingsTypeFlags),容器类型(Array/Set/Map/Optional)递归编码内部类型,枚举/结构追加目标名称索引。ByteProperty 若带枚举则被编码为 EnumProperty

压缩使用 ZSTD_compress(最大压缩等级)。

12.2 IDAMappingGenerator(.idmap)

用途:把虚表与原生(Exec)函数的"偏移 → 名称"导入 IDA,配合插件 IDAExecFunctionsImporter 自动重命名。

文件结构:纯粹是一个 Identifier 数组:

struct Identifier
{
    uint32 Offset;            // 相对镜像基址
    uint16 NameLength;
    char   Name[NameLength];  // 非 null 结尾
};
  • 虚表:遍历 CDO,名称为 {ClassName}_VFT,偏移取 DefaultObject.GetVft();与父类虚表相同则跳过去重。
  • Exec 函数:遍历每个类的 Native 函数,名称按 Itanium C++ ABI 修饰为 _ZN{len}{Class}{len+4}exec{Func}Ev,偏移取 Func.GetExecFunction();同址只保留一个。

例:ACharacter::Jump_ZN10ACharacter8execJumpEv

12.3 DumpspaceGenerator(JSON)

用途:为 Dumpspace 在线查看器提供结构化数据,支持网页浏览类/结构体/枚举/函数。

基于 DSGen 数据模型(DSGen.h):

enum EType { ET_Default, ET_Struct, ET_Class, ET_Enum, ET_Function };

struct MemberType {           // 类型的递归表示
    EType type; std::string typeName, extendedType;  // extendedType 存 "*"/"&"
    bool reference; std::vector<MemberType> subTypes; // 模板子类型
};

类型被序列化成数组 [typeName, 类型简写, 修饰符, 子类型数组],例如:

  • FVector*["FVector", "S", "*", []]
  • TArray<int>["TArray", "C", "", [["int", "D", "", []]]]

ClassHolder/EnumHolder/FunctionHolder 分别承载类、枚举、函数;GeneratedStaticOffsets() 还把 OFFSET_GOBJECTS/GNAMES/GWORLD/PROCESSEVENT 等关键偏移写入元数据。最终 DSGen::dump() 输出整个 JSON。

三种格式都复用了同一套 Wrapper + Manager 数据:MappingGenerator 关心序列化类型,IDAMappingGenerator 关心地址,DumpspaceGenerator 关心可读结构——正是抽象层让同一份数据服务于完全不同的消费者。


13. 关键函数索引

部分 函数 说明
入口 CppGenerator::Generate() SDK 生成主流程
结构体 GenerateStruct() 单个 struct/class 声明 + 断言
成员 GenerateMembers() 成员排列与 padding
填充 GenerateBytePadding() / GenerateBitPadding() 字节 / 位域填充
枚举 GenerateEnum() enum class 生成
函数 GenerateSingleFunction() 函数声明 + ProcessEvent 实现
签名 GenerateFunctionInfo() UFunction → C++ 签名解析
类型 GetMemberTypeStringWithoutConst() UE 属性 → C++ 类型字符串
基础 GenerateBasicFiles() Basic.hpp / Basic.cpp
预定义 InitPredefinedMembers() / InitPredefinedFunctions() 注入 UObject 等核心成员/方法
文件头 WriteFileHead() / WriteFileEnd() 头部注释 + 依赖 include / 闭合
容器 GenerateUnrealContainers() TArray/TMap/TSet/FString 实现
自测 GenerateSDKTestScript() / ExecuteSDKCompilationTestScript() 生成 / 执行编译测试
USMAP MappingGenerator::GeneratePropertyType() .usmap 属性递归编码
IDA IDAMappingGenerator::MangleFunctionName() Exec 函数名修饰 / 虚表导出
Dumpspace DumpspaceGenerator::GenerateStruct() JSON 数据模型构建

文档版本: 1.0 最后更新: 2026-06-30 基于 Dumper-7 源码分析(CppGenerator / MappingGenerator / IDAMappingGenerator / DumpspaceGenerator)

评论

  • 还没有评论,来说点什么吧。

无需注册或登录,填个昵称即可评论。