UE4逆向实战:手把手教你用CE定位GName和DumpName(4.23以下版本适用)

UE4引擎分析获取UWord,GName,GetName,GObjectArray UE4引擎具有很多固定特征和特性 所以我们在逆向UE4引擎开发的游戏的时候,可以利用这些特征和特性. 当然,正常思路逆向也是没问题的(例如我们的ttw课程全数据逆向),你就当多了一个针对于该引擎逆向的快捷方式 或则多了一个思路即可. 正常逆向+引擎分析,使逆向结果全面且快速. 阅读详情

UE4逆向实战:从GName定位到DumpName的完整操作指南(4.23以下版本)

如果你对虚幻引擎4(UE4)的逆向工程感兴趣,尤其是想了解游戏对象名称系统的内部工作原理,那么这篇文章就是为你准备的。在UE4游戏的安全分析、外挂开发或模组制作中,理解并能够提取游戏中的对象名称是至关重要的一步。今天,我将带你深入UE4 4.23以下版本的核心,手把手教你如何定位关键的GName全局变量,并实现DumpName操作。

与那些只讲理论的教程不同,这篇文章完全从实战出发。我会假设你已经有了一些基础的逆向知识,比如知道如何使用调试器和内存扫描工具,但即使你是初学者,跟着步骤走也能掌握核心技巧。我们将使用Cheat Engine(CE)作为主要工具,因为它免费、强大且社区支持完善。整个过程就像侦探破案一样,通过线索一步步找到目标,既有挑战性又有成就感。

1. 理解UE4的FName系统与GName全局变量

在开始动手之前,有必要先理解我们要找的是什么。UE4使用一种称为FName的高效字符串管理系统,它不像普通字符串那样直接存储文本内容,而是将字符串存储在全局的**名称池(Name Pool)**中,每个字符串分配一个唯一的索引。FName对象本身只存储这个索引,比较和传递时只操作索引,大大提升了性能。

这个全局名称池就是通过GName(或TNameEntryArray)这个全局变量来管理的。在UE4 4.23之前的版本中,GName是一个直接可访问的全局数组;而在4.23及之后版本中,它被封装在FNamePool结构中,访问方式有所不同。我们今天聚焦在4.23以下版本。

为什么GName如此重要?

  • 它是所有游戏对象名称的中央存储库
  • 通过它可以将FName索引转换为可读的字符串
  • 是逆向分析中定位游戏对象、函数和属性的关键入口点

从源码层面看,FName的核心结构是这样的:

// 简化版的FName结构(基于UE4 4.22)
class FName
{
public:
    // 获取名称字符串
    FORCEINLINE FString ToString() const
    {
        return GetDisplayNameEntry()->GetPlainNameString();
    }
    
private:
    // 名称索引(核心数据)
    FNameEntryId ComparisonIndex;
    // 显示索引(可能不同)
    FNameEntryId DisplayIndex;
    // 编号(用于区分同名对象)
    int32 Number;
};

而GName实际上是一个TNameEntryArray类型的全局数组,存储着所有的FNameEntry对象,每个FNameEntry包含实际的字符串数据。我们的目标就是找到这个全局数组在内存中的位置。

2. 准备工作与环境配置

在开始逆向之前,确保你准备好了以下工具和环境:

必需工具清单:

  • Cheat Engine 7.4+ - 我们的主要逆向工具
  • IDA Pro 或 Ghidra - 用于静态分析(可选但推荐)
  • UE4 4.22或更早版本的游戏 - 作为分析目标
  • Process Hacker 或 Process Explorer - 查看进程信息
  • 文本编辑器 - 记录偏移和地址

目标游戏选择建议: 对于初学者,我推荐选择以下类型的游戏作为练习目标:

  1. 单机UE4游戏 - 没有反作弊,分析更简单
  2. 小体量独立游戏 - 加载快,结构相对简单
  3. 已知使用UE4 4.22或更早版本的游戏 - 确保方法适用

注意:请仅在你有合法权限的游戏上进行逆向分析,比如自己购买的游戏或明确允许修改的游戏。尊重开发者的劳动成果和版权。

Cheat Engine基础配置:

  1. 下载并安装最新版Cheat Engine
  2. 首次运行可能需要关闭一些杀毒软件的实时保护(CE有时会被误报)
  3. 熟悉CE的基本操作:附加进程、内存扫描、查看内存区域、下断点

实战前的心理准备: 逆向工程很少有一次成功的情况。你可能会遇到游戏更新导致偏移变化、反调试保护、或者自己理解错误的情况。保持耐心,把每次失败都当作学习的机会。我刚开始时,为了找一个简单的偏移花了整整两天时间,但现在回想起来,那些挫折让我对内存布局有了更深的理解。

3. 使用Cheat Engine定位GName的实战步骤

现在进入实战环节。我将以《BattleRoyaleTrainer》(一个UE4单机训练游戏)为例,展示完整的定位过程。你可以用任何UE4 4.23以下的游戏跟随操作。

3.1 第一步:定位关键字符串特征

UE4引擎在初始化时会注册大量硬编码的名称,如"None"、"ByteProperty"、"IntProperty"等。这些字符串在内存中的位置与GName有直接关系,是我们寻找GName的重要线索。

操作步骤:

  1. 启动游戏和Cheat Engine
  2. 在CE中选择游戏进程并附加
  3. 点击"Memory View"打开内存查看器
  4. 在内存查看器中右键选择"Search for → String references"
  5. 在弹出的对话框中输入"ByteProperty"(不含引号)
  6. 确保搜索选项设置为"Case sensitive"和"Entire block"

你会看到类似这样的结果:

地址                    反汇编
00007FF6A1B3D120        push rbx
00007FF6A1B3D122        sub rsp, 20h
00007FF6A1B3D126        mov rbx, rcx
00007FF6A1B3D129        lea rcx, [00007FF6A3A8F2D0h] ; "ByteProperty"
00007FF6A1B3D130        call 00007FF6A1B3CF00

关键技巧:

  • 不要只看第一个结果,往下滚动查找在代码段(.text)中的引用
  • 注意那些在函数开头附近被引用的字符串,很可能是初始化函数
  • 记录下字符串地址,比如上面的00007FF6A3A8F2D0

3.2 第二步:分析字符串引用函数

找到字符串引用后,我们需要查看是哪个函数在使用它。在内存查看器中双击字符串地址,CE会跳转到引用该字符串的代码位置。

常见的GName相关函数特征:

  1. FName::ToString() - 将FName转换为字符串
  2. FName::GetDisplayNameEntry() - 获取名称条目
  3. 静态初始化函数 - 在游戏启动时注册硬编码名称

以"ByteProperty"为例,我们可能会看到这样的代码模式:

; 典型的GName初始化代码模式
mov     rcx, [GName地址]      ; 加载GName指针
lea     rdx, [字符串地址]      ; 加载"ByteProperty"地址
call    RegisterNameFunction   ; 调用注册函数

实际操作:

  1. 在字符串引用处按Ctrl+D查看反汇编
  2. 向上滚动查看函数开头(通常有push rbp, mov rbp, rsp等序言)
  3. 寻找对全局变量的访问指令,如mov rax, [7FF6A3B45000h]

识别GName访问模式: GName通常以以下形式被访问:

  • 直接内存访问:mov rax, [GName地址]
  • 相对RIP访问:lea rax, [rip+GName偏移]
  • 通过函数获取:call GetGNameFunction

3.3 第三步:追踪GName的交叉引用

一旦找到可能初始化或使用GName的函数,我们需要追踪它的交叉引用。在CE中,你可以:

  1. 在函数内的GName访问指令上右键
  2. 选择"Find out what accesses this address"
  3. CE会记录所有访问该地址的代码

实际案例追踪: 假设我们在00007FF6A1B3D130处找到了对"ByteProperty"的引用,向上分析函数:

; 函数开头
00007FF6A1B3D120  push    rbx
00007FF6A1B3D122  sub     rsp, 20h
00007FF6A1B3D126  mov     rbx, rcx
00007FF6A1B3D129  lea     rcx, [00007FF6A3A8F2D0h] ; "ByteProperty"
00007FF6A1B3D130  call    00007FF6A1B3CF00         ; 注册函数
00007FF6A1B3D135  mov     rcx, rbx
00007FF6A1B3D138  add     rsp, 20h
00007FF6A1B3D13C  pop     rbx
00007FF6A1B3D13D  ret

这个函数看起来是在注册名称。我们需要找到它被谁调用,以及GName在哪里被初始化。在函数开头00007FF6A1B3D120处右键选择"Find references to this address"。

如果幸运的话,你可能会找到一个像这样的初始化函数:

; GName初始化函数(简化版)
GName_Init:
    push    rbp
    mov     rbp, rsp
    sub     rsp, 40h
    mov     [rbp+var_18], rbx
    mov     [rbp+var_10], rsi
    mov     [rbp+var_8], rdi
    
    ; 初始化GName数组
    lea     rax, GName            ; 关键!这里加载GName地址
    mov     [rax], 0
    mov     [rax+8], 0
    ...
    
    ; 注册硬编码名称
    lea     rcx, [Str_None]
    call    RegisterName
    lea     rcx, [Str_ByteProperty]  ; 我们找到的字符串
    call    RegisterName
    ...

3.4 第四步:验证找到的GName地址

找到可能的GName地址后,我们需要验证它是否正确。GName在内存中通常表现为一个结构体数组,具有以下特征:

GName数组的典型内存布局:

地址          数据
GName+0x00:   指向第一个FNameEntry块的指针
GName+0x08:   指向第二个FNameEntry块的指针
GName+0x10:   指向第三个FNameEntry块的指针
...

验证方法:

  1. 在CE的十六进制查看器中转到疑似GName的地址
  2. 查看该地址存储的值(应该是一个指针)
  3. 跟随该指针(右键→"Follow in dump")
  4. 你应该看到类似这样的结构:
FNameEntry内存块示例:
偏移   数据              ASCII
0x00:  00 00 00 00 00 00 00 00  ........
0x08:  4E 6F 6E 65 00 00 00 00  None....
0x10:  42 79 74 65 50 72 6F 70  ByteProp
0x18:  65 72 74 79 00 00 00 00  erty....

快速验证脚本: 你可以在CE中编写一个简单的Lua脚本来验证GName:

function verifyGName(gnameAddr)
  local blockPtr = readPointer(gnameAddr)
  if blockPtr == nil or blockPtr == 0 then
    print("无效的GName地址")
    return false
  end
  
  -- 读取第一个名称(应该是"None")
  local nameEntry = blockPtr + 0x8  -- 跳过头部信息
  local name = readString(nameEntry, 50, true)
  
  if name == "None" then
    print(
UE4逆向实战:手动定位GName与DumpName技术详解 在游戏开发与逆向工程领域,内存数据结构的解析是理解程序逻辑的核心基础。以虚幻引擎(UE4)为例,其内部通过全局名称表(GName)统一管理所有字符串资源,如类名、函数名等,这是引擎运行时进行对象识别和资源调度的关键机制。理解其原理,即通过索引(FNameEntryId)而非直接存储字符串来高效管理海量名称,对于进行游戏逻辑分析、Mod制作或安全研究具有重要技术价值。在实际应用场景中,当面对已编译且缺乏符号信息的游戏时,直接获取此表能极大简化逆向过程,如同获得程序的“地图”。本文聚焦于通过逆向工具手动定位GN 阅读详情

相关推荐

告别重复扫描!用CE修改器.ct文件管理你的变量地址库(以DevC++程序为例)

本文详细介绍了如何利用CE修改器的.ct文件高效管理变量地址库,特别针对DevC++程序开发场景。通过系统化保存变量地址、类型和注释信息,开发者可以告别重复扫描,实现调试参数的一键复用。文章还分享了命名规范、分类策略和高级操作技巧,帮助用户将零散修改转化为可复用的资产。

weixin_28703489的博客 192

告别‘盲搜’!Cheat Engine高级技巧:用指针扫描与代码注入搞定动态地址游戏

本文深入解析Cheat Engine高级技巧,教你如何通过指针扫描与代码注入应对动态地址游戏的挑战。从内存寻址原理到实战案例,详细拆解多级指针链构建和代码注入技术,帮助玩家有效绕过游戏反作弊机制,提升修改效率与稳定性。

weixin_42648844的博客 474

不止于修改器:用Cheat Engine的Lua脚本和D3D Hook给你的单机游戏‘加MOD’

本文深入探讨了如何利用Cheat Engine(CE)的Lua脚本和D3D Hook技术为单机游戏添加自定义MOD功能。从动态数据监控到游戏界面改造,CE的高阶用法远超传统数值修改,为玩家提供了强大的游戏定制能力。文章通过《上古卷轴5》和《星露谷物语》等实例,详细展示了Lua脚本和D3D Hook的实战应用,帮助用户突破游戏限制,实现个性化游戏体验。

weixin_42563415的博客 233

从游戏修改到安全测试:用Cheat Engine 7.5实战分析内存数据流(附Lua脚本示例)

本文深入探讨了Cheat Engine 7.5在内存数据流分析中的专业应用,从游戏修改扩展到安全测试领域。通过实战案例和Lua脚本示例,展示了CE在漏洞挖掘、恶意软件分析和自动化测试中的强大功能,帮助开发者掌握高效的内存监控与调试技术。

weixin_26985923的博客 427

Cheat Engine 7.5新功能全解析:从内存扫描到Lua脚本实战指南

本文深度解析Cheat Engine 7.5的核心更新与实战应用。新版本在内存扫描引擎、Lua脚本支持、多架构调试及.NET集成等方面均有显著增强,提供了更智能的指针扫描、更强大的脚本API与界面控件,并强化了对ARM64和托管代码的分析能力。文章通过实战案例,指导用户从基础内存定位到高级自动化脚本编写,将其应用于软件逆向分析与游戏模组制作等专业场景。

weixin_29251567的博客 427

独立团VIP专用游戏修改工具:CE5.6

游戏修改工具作为提升游戏体验和探索游戏内部世界的重要手段,已被广泛应用于玩家社区。本章节将为你提供一个关于游戏修改工具的基础知识概览。我们会从工具选择、安装以及基础使用技巧等方面着手,带你进入游戏修改的世界。对初学者而言,理解这些基础知识是掌握更高级游戏修改技巧的先决条件。同时,对于经验丰富的玩家,本章内容也会有助于梳理和回顾现有工具的功能和使用策略。接下来,我们将以主流游戏修改工具之一Cheat Engine(简称CE)的最新版本5.6作为示例,深入剖析其功能和应用。

weixin_42513928的博客 1362

UE4 Actor遍历的几种方式(如果有纰漏会更新)

在实际使用中我们可能会用到UE4遍历场景中的Actor。 注意: 1.不要在构造函数中遍历。 2.如果涉及到RPC和属性复制,一定是在第一次复制完成后再进行遍历,防止role没同步过来。 3.写在构造函数里可能会为空GetWorld(); for(TActorIteratorIterator(GetWorld());Iterator;++Iterator) { } 在蓝图中设置tag属性,通过tag查找Actor  UGameplayStatics::GetAllActorsWithTag TArray Actors; UGameplayStatics::GetAllActorsWithTa

拆解歌尔2718硅麦:2.75mm超小封装背后的MEMS技术解析

本文深度解析歌尔2718硅麦的2.75mm超小封装技术,探讨MEMS麦克风在微型化过程中的声学性能与结构可靠性平衡。通过ASIC芯片堆叠、纳米级应力控制等创新技术,歌尔2718在TWS耳机和智能手机中实现卓越性能,同时克服微型化带来的声学挑战。

weixin_28292761的博客 611

NMOS管和PMOS管做开关控制电路

NMOS管和PMOS管做开关控制电路

while(1) 3万+

(实测可用)STM32L431RCT6开发板-实验1 跑马灯实验

一、开发板平台简介: 1、开发板资源简介 (1)开发板主芯片型号:STM32L431RCT6 (2)开发板主芯片封装:LQFP-64_10x10x05P (3)开发板主芯片内核:ARM® Cortex®-M4 (4)开发板主芯片主频:80MHz (5)开发板主芯片Flash大小:256KB (6)开发板主芯片RAM大小:64KB

zhej2014的博客 3169

从零到一:ESP32与豆包大模型的RTC连续对话实现指南

文本实现ESP32S3 SparkBot与豆包大模型的RTC连续对话

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 4366

影楼精修-高低频磨皮算法解析

本文介绍了像素蛋糕软件中的高低频磨皮算法原理及实现思路,抛砖引玉。

Trent1985的专栏 2261

Imagiq AI-PQ 图像质量增强模块详解:联发科 ISP 中的 AI 图像管线实战解析

随着智能手机影像系统对图像质量要求的持续提升,联发科在其 Imagiq ISP 中引入了 AI 驱动的图像增强模块——AI-PQ(AI-based Picture Quality),通过 AI 模型对亮度、色彩、噪声、锐度等多个维度进行动态调节与增强,实现更加智能化和个性化的图像输出效果。AI-PQ 在实际工程中已成为影响照片风格、视频观感和多模组一致性的核心能力之一。本文围绕 Imagiq 平台最新一代 AI-PQ 模块(2024-2025年量产平台为基础),结合实机开发与调优经验,深入剖析其各子模块的算

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1423

【软件系统架构】系列六:MBSE(基于模型的系统工程)

基于模型的系统工程(MBSE)是一种以模型为核心的系统工程方法论,通过结构化、可视化的模型取代传统文档,实现从需求到验证的全生命周期管理。MBSE采用SysML建模语言,包含需求、功能、架构和验证四大要素,支持自动追踪、仿真分析和代码生成。相比文档式工程,MBSE具有变更影响自动分析、跨团队协作和高可视化等优势,广泛应用于航空航天、汽车电子等领域。典型开发流程包括需求建模、行为建模、架构建模等阶段,配合MagicDraw、Cameo等工具链实现。MBSE正与数字孪生、AI技术融合,推动自动化建模和智能验证的

moton2017的博客 2785

【Matlab光伏功率预测】基于GRU门控循环单元的光伏功率时间序列预测(附MATLAB代码)

【Matlab光伏功率预测】基于GRU门控循环单元的光伏功率时间序列预测(附MATLAB代码)

k8291121的博客 1100

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: yolov8-obb模型在海思3516DV300上的高效部署与优化实践
下一篇: 从代码实现看FOC无感算法差异:高频注入vs龙伯格观测器的STM32移植要点
vim8coder
博客等级 码龄1天 0粉丝 1693原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值