UE4引擎分析获取UWord,GName,GetName,GObjectArray

Posted 任鸟飞逆向~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4引擎分析获取UWord,GName,GetName,GObjectArray相关的知识,希望对你有一定的参考价值。

UE4引擎具有很多固定特征和特性

所以我们在逆向UE4引擎开发的游戏的时候,可以利用这些特征和特性.

当然,正常思路逆向也是没问题的(例如我们的ttw课程全数据逆向),你就当多了一个针对于该引擎逆向的快捷方式 或则多了一个思路即可.

正常逆向+引擎分析,使逆向结果全面且快速.

了解一下我们的学习顺序,

先熟悉UE4特性,找到UWord,GName,GetName,GObject等关键数据(入门阶段不使用IDA,但是效率更快)

然后把这些数据跟正常逆向的关系对应清晰,以提高对UE4的熟悉

再学习UE4正向开发和源码,从根本上了解该引擎

最后完整性dump游戏数据,边角数据用逆向方式补全即可

1.查看游戏的引擎版本

首先我们来查看游戏引擎版本

游戏启动程序所在目录如下:(任何UE4游戏都是类似目录)

我们可以右键属性查看游戏版本,如果长期分析经验以后,可以根据版本做出更多的判断

实际情况还是我们跟着最新版本即可,老版本等于淘汰.

下面这个4.26.2.0 已经是目前的新版本了

同时需要注意,附加进程也是

2.UWorld

首先我们先来获取一下UE4引擎中的UWorld.

UWorld其实就是世界数组基地址 .

世界数组基地址下面挂着一个包含所有对象的数组,这在我们讲FPS专题的时候已经讲解过了,忘了的同学可以翻回FPS转体复习一下.

根据ue4引擎世界对象数组的特点,我们可以采取以下方式来进行扫描,

例如 打枪数组对象数量 +1或则+2,拿出手雷 +1或者+2,也就是说出现新物品+不定数量,还有什么增加方式,大家可以找到以后多观察一下.

例如手雷增加,原本手雷不在模型上显示,打出的子弹也是有对象的,所以子弹打中某个碰撞体也会增加。

RPG也是相同,对象只会增加不会减少这是他的一个很容易被利用的特点,所以我们就利用这个道理进行扫描.

进入游戏,选择一个小地图,方便我们可以搜少点的值

搜索0-1000

像障碍物或则目标开枪 搜索增加的数值 增加可能是1可能是2

最终可以锁定地址

到OD中下断追表达式:

r14+B0

往上继续追 得到表达式 r15+B0

追到函数头部 得到表达式 [rcx+30]+B0

返回,发现 [rax+30]+B0 此时RAX 来源于一个call

这地方有三种方法

第一种直接调call 取得的返回值就是 UWORD 里的值

第二种方法直接CE搜索就可以搜索到UWORD的基地址

UWorld = deathlystillnessgame-win64-shipping.exe+460F4F0

第三种也可以继续逆向来源

call 内来源

继续进call, 由于是虚表可以进入很多位置,算法也都不同

其中有一个是我们追熟悉的位置

再进call

好像发现了什么吗?

就是天堂W里类似取对象的call,可以参考天堂W,他的过程类似于一个加密过程,忘记了 可以回去看下天堂W课程

其实这里追不到UWORD的基地址,但是我们得到的加密表达式 是可以执行UWORD里的的,一样是可以当UWORD来使用.

相比之下,低版本的UE4的UWORD就比较好找了

例如

低版本吃鸡模拟器的世界数组数量如下:

[["BattleRoyaleTrainer-Win64-Shipping.exe"+2AF0FB8] +138 ]+ b8

[["BattleRoyaleTrainer-Win64-Shipping.exe"+2AF0FB8 ] +30 ]+ b8

"BattleRoyaleTrainer-Win64-Shipping.exe"+2AF0FB8就是UWORD

经过了正常逆向,我们看看还有什么快捷方式来搜索到UWORD

就是引擎特征码了.

我们用XDBG 搜索所有模块字符串,需要等待一会,速度会比较慢,用IDA搜索这个速度更慢

xdbg搜索字符串: SeamlessTravel FlushLevelStreaming

剩余唯一一个结果

用IDA搜索这个速度慢,而且IDA搜索到的位置可能会不全,可以用xdbg搜索字符串,用IDA查看伪代码

跳转到这个地址向上翻可以得到btr edx,0x7,再向上遇到的第一个基地址,就是UWorld

UWorld = deathlystillnessgame-win64-shipping.exe+460F4F0

跟我们正常逆向的结果一样的

当然,正常逆的方式是比较通用的,特征的方式很容易在几个版本之后失效,当然失效以后,我们可以在通过正向开发的方式找到新的特征不是吗?

有了UWORD ,实际上我们就能遍历到周围环境所有对象.

3.GName

什么是GName?GName保存着UE4整个世界对象的名字

世界对象下只有Key(可以理解成名称ID),没有直接的名字的,所以想要获取名字必须要先搞定GName

说的直白点,GName是存放游戏里面所有名称字符串的基地址

分析清晰这些字符串的结构

然后通过GetName函数(也就是从Key到字符串的转换)调用取得名称字符串

名称字符串内存中的格式一般如下:

None

ByteProperty

...

...

前两个 一般是None 和ByteProperty

CE扫描ByteProperty, 以后版本不是 ByteProperty怎么办? 可以正向编译一个最新版本,看看里面任意一个相对比较特殊的字符串即可,我们不是要一个精确的位置

一个大概的位置即可

所有地址拉下来

CTRL+b 挨个查看,找到连续字符串,并且开头第一个是None,当然目前所有版本都是这样,改动我们可以人为识别

观察结构 就是 2字节+一个字符串 再2字节 再一个字符串 以此类推(后面我们会知道这个2字节就是加密长度)

那么ByteProperty字符串 - 8 的位置应该就是结构头部

CE直接搜索 2024E3C0008 - 8 = 2024E3C0000

直接得到基地址 , 再 -10就是 GName

GName = "DeathlyStillnessGame-Win64-Shipping.exe"+44BDB80

这里直接说他是GName视乎有些无赖,其实就是无赖... 那么我们用正常逆向的方法来追到GName以及GetName算法

4.GetName

我们对字符串下访问断,例如ByteProperty

小退或则开始游戏会断下

字符串下断


| CC                | int3                                                 |
| CC                | int3                                                 |
| CC                | int3                                                 |
| 48:895C24 08      | mov qword ptr ss:[rsp+0x8],rbx                       |
| 4D:8BD0           | mov r10,r8                                           |
| 4C:8BCA           | mov r9,rdx                                           | rcx
| 4C:8BD9           | mov r11,rcx                                          | rcx -rdx + r9
| 4D:85C0           | test r8,r8                                           |
| 74 23             | je deathlystillnessgame-win64-shipping.7FF6F18A3EF6  |
| 4C:2BDA           | sub r11,rdx                                          | r11+ r9 = r11-rdx + r9
| 48:8D1D D3DC6F02  | lea rbx,qword ptr ds:[0x7FF6F3FA1BB0]                |
| 0F1F00            | nop dword ptr ds:[rax],eax                           |
| 43:0FB6040B       | movzx eax,byte ptr ds:[r11+r9]                       | r11+r9  r9是堆栈地址 R11只是堆栈和真实地址的偏移
| 45:0FB601         | movzx r8d,byte ptr ds:[r9]                           | 断下的位置
| 4D:8D49 01        | lea r9,qword ptr ds:[r9+0x1]                         |
| 41:3AC0           | cmp al,r8b                                           |
| 75 0C             | jne deathlystillnessgame-win64-shipping.7FF6F18A3EFE |
| 84C0              | test al,al                                           |
| 75 2C             | jne deathlystillnessgame-win64-shipping.7FF6F18A3F22 |
| 33C0              | xor eax,eax                                          |
| 48:8B5C24 08      | mov rbx,qword ptr ss:[rsp+0x8]                       |
| C3                | ret                                                  |
| 41:0FBED0         | movsx edx,r8b                                        |
| 0FBEC8            | movsx ecx,al                                         |
| 0BD1              | or edx,ecx                                           |
| F7C2 80FFFFFF     | test edx,0xFFFFFF80                                  |
| 75 21             | jne deathlystillnessgame-win64-shipping.7FF6F18A3F30 |

返回追rcx

追字符串是什么表达式指向的, 发现整个表达式都是由ID(也可以叫Key)决定的

全部分析流程如下:


| 48:895C24 20      | mov qword ptr ss:[rsp+0x20],rbx                      |
| 55                | push rbp                                             |
| 56                | push rsi                                             |
| 57                | push rdi                                             |
| 41:56             | push r14                                             |
| 41:57             | push r15                                             |
| 48:8D6C24 C9      | lea rbp,qword ptr ss:[rsp-0x37]                      |
| 48:81EC A0000000  | sub rsp,0xA0                                         |
| 48:8B05 E9105703  | mov rax,qword ptr ds:[0x7FF6F4F2B7B8]                |
| 48:33C4           | xor rax,rsp                                          |
| 48:8945 2F        | mov qword ptr ss:[rbp+0x2F],rax                      |
| 41:0F1000         | movups xmm0,xmmword ptr ds:[r8]                      |
| 4C:8BF2           | mov r14,rdx                                          |
| 48:8BD9           | mov rbx,rcx                                          | rcx==rbx==GName  返回可得
| 0F10C8            | movups xmm1,xmm0                                     |
| 0F2945 D7         | movaps xmmword ptr ss:[rbp-0x29],xmm0                |
| 48:8B55 D7        | mov rdx,qword ptr ss:[rbp-0x29]                      |
| 66:0F73D9 08      | psrldq xmm1,0x8                                      |
| 6648:0F7EC8       | movq rax,xmm1                                        |
| 6641:0F7EC8       | movd r8d,xmm1                                        |
| 48:C1E8 20        | shr rax,0x20                                         |
| 0F1145 07         | movups xmmword ptr ss:[rbp+0x7],xmm0                 |
| 84C0              | test al,al                                           |
| 75 0B             | jne deathlystillnessgame-win64-shipping.7FF6F19BA711 | 0
| 48:8D4D E7        | lea rcx,qword ptr ss:[rbp-0x19]                      |
| E8 F11DFFFF       | call deathlystillnessgame-win64-shipping.7FF6F19AC50 |
| EB 09             | jmp deathlystillnessgame-win64-shipping.7FF6F19BA71A | 1
| 48:8D4D D7        | lea rcx,qword ptr ss:[rbp-0x29]                      |
| E8 D61EFFFF       | call deathlystillnessgame-win64-shipping.7FF6F19AC5F |
| 0F1000            | movups xmm0,xmmword ptr ds:[rax]                     |
| C645 2B 00        | mov byte ptr ss:[rbp+0x2B],0x0                       | 00007FF6F4FEDB80
| 66:0F7EC7         | movd edi,xmm0                                        | rbx==Gname   Gname+10040+0*40
| 0F1145 17         | movups xmmword ptr ss:[rbp+0x17],xmm0                | [[rbx+10040+040+10]+n*4]
| 48:81C7 01040000  | add rdi,0x401                                        | [[rbx+(rdi+401)*40+10]+n*4]
| 48:C1E7 06        | shl rdi,0x6                                          | [[rbx+rdi*40+10]+n*4]
| 48:03FB           | add rdi,rbx                                          | [[rdi+rbx+10]+n*4]
| 48:8BCF           | mov rcx,rdi                                          |
| FF15 E0D04202     | call qword ptr ds:[<&RtlAcquireSRWLockExclusive>]    |
| 8B5D 1B           | mov ebx,dword ptr ss:[rbp+0x1B]                      |
| 48:8B47 10        | mov rax,qword ptr ds:[rdi+0x10]                      | rax = [[rdi+10]+n*4]
| 44:8B7F 0C        | mov r15d,dword ptr ds:[rdi+0xC]                      |
| 41:23DF           | and ebx,r15d                                         |
| 48:8D3498         | lea rsi,qword ptr ds:[rax+rbx4]                     |
| 8B0498            | mov eax,dword ptr ds:[rax+rbx4]                     | 数组中取ID 给eax  这里rbx是多少不用管,因为我们要遍历全部
| 85C0              | test eax,eax                                         |
| 0F84 DE000000     | je deathlystillnessgame-win64-shipping.7FF6F19BA83B  | 不跳>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
| 0F1F00            | nop dword ptr ds:[rax],eax                           |
| 8BC8              | mov ecx,eax                                          |
| 81E1 000000E0     | and ecx,0xE0000000                                   |
| 3B4D 1F           | cmp ecx,dword ptr ss:[rbp+0x1F]                      |
| 0F85 9D000000     | jne deathlystillnessgame-win64-shipping.7FF6F19BA80E | 不跳>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
| 25 FFFFFF1F       | and eax,0x1FFFFFFF                                   | and 1FFFFFFF
| 8BD0              | mov edx,eax                                          | eax>>0x10 第几页
| 0FB7C8            | movzx ecx,ax                                         | ax 字符串偏移
| C1EA 10           | shr edx,0x10                                         | edx>>0x10 第几页
| 8955 C7           | mov dword ptr ss:[rbp-0x39],edx                      |
| 894D CB           | mov dword ptr ss:[rbp-0x35],ecx                      |实际是这  ecx字符串偏移
| 48:8B45 C7        | mov rax,qword ptr ss:[rbp-0x39]                      |来源于这
| 48:8B4F 18        | mov rcx,qword ptr ds:[rdi+0x18]                      |
| 48:C1E8 20        | shr rax,0x20                                         | (rax>>0x20)*2 字符串字符串数*2 ==前面字符串长度
| 44:8D0400         | lea r8d,qword ptr ds:[rax+rax]                       | r8 ==前面字符串长度
| 4C:0344D1 10      | add r8,qword ptr ds:[rcx+rdx8+0x10]                 | 字符串==[rcx+rdx*8+10]+r8(前面字节长度)+2(头部2字节)
| 41:0FB710         | movzx edx,word ptr ds:[r8]                           | 头部两字节
| 66:3B55 23        | cmp dx,word ptr ss:[rbp+0x23]                        |
| 75 6B             | jne deathlystillnessgame-win64-shipping.7FF6F19BA80E | 不跳>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
| 0FB7C2            | movzx eax,dx                                         | 头部两字节给了 eax
| 49:8D48 02        | lea rcx,qword ptr ds:[r8+0x2]                        | 字符串== r8+2  跳过 头部2字节  因为我们之前知道 字符串前面有2字节长度
| C1E8 06           | shr eax,0x6                                          | 头部两字节>>6   解密长度  >>6以后我们知道哦 原来是字符串长度 不难观察哦
| F6C2 01           | test dl,0x1                                          |
| 74 11             | je deathlystillnessgame-win64-shipping.7FF6F19BA7C3  | 来源都是rcx  字符串== rcx
| 8945 FF           | mov dword ptr ss:[rbp-0x1],eax                       |
| 48:8D45 F7        | lea rax,qword ptr ss:[rbp-0x9]                       |
| 48:894D F7        | mov qword ptr ss:[rbp-0x9],rcx                       | rcx 来源一
| C645 03 01        | mov byte ptr ss:[rbp+0x3],0x1                        |
| EB 0F             | jmp deathlystillnessgame-win64-shipping.7FF6F19BA7D2 |
| 8945 DF           | mov dword ptr ss:[rbp-0x21],eax                      |
| 48:8D45 D7        | lea rax,qword ptr ss:[rbp-0x29]                      |
| 48:894D D7        | mov qword ptr ss:[rbp-0x29],rcx                      | rcx  来源二
| C645 E3 00        | mov byte ptr ss:[rbp-0x1D],0x0                       |
| 0F1000            | movups xmm0,xmmword ptr ds:[rax]                     | 字符串==[rax]
| 48:8B55 07        | mov rdx,qword ptr ss:[rbp+0x7]                       |
| 0F2945 E7         | movaps xmmword ptr ss:[rbp-0x19],xmm0                | 字符串==XMM0
| 48:8B4D E7        | mov rcx,qword ptr ss:[rbp-0x19]                      | 字符串==[rbp-19]
| 66:0F73D8 08      | psrldq xmm0,0x8                                      |
| 66:0F7EC0         | movd eax,xmm0                                        |
| 4C:63C0           | movsxd r8,eax                                        |
| 48:8B45 0F        | mov rax,qword ptr ss:[rbp+0xF]                       |
| 48:C1E8 20        | shr rax,0x20                                         |
| 84C0              | test al,al                                           |
| 75 07             | jne deathlystillnessgame-win64-shipping.7FF6F19BA800 |
| E8 C296EEFF       | call deathlystillnessgame-win64-shipping.7FF6F18A3EC | 返回call====上面是从这里返回的
| EB 05             | jmp deathlystillnessgame-win64-shipping.7FF6F19BA805 |
| E8 BB97EEFF       | call deathlystillnessgame-win64-shipping.7FF6F18A3FC |
| 85C0              | test eax,eax                                         |
| 0F94C0            | sete al                                              |

返回是GName

00007FF69D0ECD66  | 803D B7D76203 00  | cmp byte ptr ds:[0x7FF6A071A524],0x0                    |
00007FF69D0ECD6D  | 74 09             | je deathlystillnessgame-win64-shipping.7FF69D0ECD78     |
00007FF69D0ECD6F  | 48:8D05 0A0E6403  | lea rax,qword ptr ds:[0x7FF6A072DB80]                   | Gname 在这里
00007FF69D0ECD76  | EB 13             | jmp deathlystillnessgame-win64-shipping.7FF69D0ECD8B    |
00007FF69D0ECD78  | 48:8D0D 010E6403  | lea rcx,qword ptr ds:[0x7FF6A072DB80]                   |
00007FF69D0ECD7F  | E8 6C050000       | call deathlystillnessgame-win64-shipping.7FF69D0ED2F0   |
00007FF69D0ECD84  | C605 99D76203 01  | mov byte ptr ds:[0x7FF6A071A524],0x1                    |
00007FF69D0ECD8B  | 0F1003            | movups xmm0,xmmword ptr ds:[rbx]                        |
00007FF69D0ECD8E  | 4C:8D4424 20      | lea r8,qword ptr ss:[rsp+0x20]                          |
00007FF69D0ECD93  | 48:8BC8           | mov rcx,rax                                             | 
00007FF69D0ECD96  | 48:8D5424 30      | lea rdx,qword ptr ss:[rsp+0x30]                         | 
00007FF69D0ECD9B  | 0F294424 20       | movaps xmmword ptr ss:[rsp+0x20],xmm0                   | 
00007FF69D0ECDA0  | E8 0BD90000       | call deathlystillnessgame-win64-shipping.7FF69D0FA6B0   | 返回call  2
00007FF69D0ECDA5  | 48:8B5C24 58      | mov rbx,qword ptr ss:[rsp+0x58]                         |
00007FF69D0ECDAA  | 8B08              | mov ecx,dword ptr ds:[rax]                              | 
00007FF69D0ECDAC  | 48:8BC7           | mov rax,rdi                                             |
00007FF69D0ECDAF  | 890F              | mov dword ptr ds:[rdi],ecx                              |

整理公式:

GName = "DeathlyStillnessGame-Win64-Shipping.exe"+44BDB80

GName+10040+n*40 Key结构体数组开始指针

n== 0 到 F 也可以根据 对象+18 里的值是否等于 GName 判断

$-18 0000000000000000

$-10 0000000000000000

$-8 0000000000000000

$ ==> 0000000000000000====从这开始

$+8 00001FFF0000142A

$+10 0000029723510000

$+18 00007FF6F4FEDB80

$+20 000000250000142A

$+28 0000000000000000

$+30 0000000000000000

$+38 0000000000000000

$+40 0000000000000000====第2个对象

$+48 00001FFF000013E0

$+50 0000029726CE0000

$+58 00007FF6F4FEDB80

$+60 0000002B000013E0

$+68 0000000000000000

$+70 0000000000000000

$+78 0000000000000000

$+80 0000000000000000====第3个对象

$+88 00001FFF00001407

$+90 0000029726D90000

$+98 00007FF6F4FEDB80

$+A0 0000002E00001407

$+A8 0000000000000000

$+B0 0000000000000000

$+B8 0000000000000000

每个对象 +10 进入 存放了1FFF个4字节的ID

ID == [[GName+10040+n*40+10]+i*4]

最上面

拉到最下面了

[00007FF6F4FEDB80+10040+n*40+10]+ i*4 (n==0 到F i ==0到 1FFE) 这样可以取得游戏中的全部ID

取得所有ID,注意判断是否为0 ,0其实对应的就是None

得到ID以后:

第几页 = (ID and 0x1FFFFFFF)>>0x10

字符串偏移 =WORD (ID and 0x1FFFFFFF)

长度== WORD PTR :[[Gname+第几页*8+10]+字符串偏移*2 ] >> 6

内容地址 = [Gname+第几页*8+10]+字符串偏移*2 +2(头部2字节)

这样就可以遍历出全部字符串了

一共8W+ ,还是非常多的,运行不卡,输出会比较卡,怕卡的同学可以把字符串全部相加以后 一起输出.

ps:可以观察一下

头部两字节/ 0x40 (>>6) 就是真实长度, 这种可能有不同的加密方法,通过上面的方法都是可以逆向出来的

GetName 其他的方法

当然找GetName我们也可以用IDA 或则 XDBG 搜索ByteProperty

IDA搜索 ByteProperty,搜索到多个

IDA ctlr+X 转到引用,发现 连续字符串的就是我们要的

XDBG也一样

跳过去 跟IDA是一样的

同时告诉你们个秘密,还记得我们之前分析的位置吗

这个头部下断返回的是GName

如果我们在头部查找引用

会发现很多个引用,但是其实 除了我们返回GName的位置

其他都是一个地方

也就是 XDBG 和IDA 搜索字符串的位置

IDA中我们点F5

然后拉到函数头部 点X 查看调用

其中一个是getname,挨个分析下参数即可,当然XDBG也可以

具体算法和我们上面分析的差不多,不再赘述

这里注意:

我们通过这样方式找到的GetName函数只能静态观察,因为,他是访问不断的

因为他只有在游戏初始化的时候调用分配一次

而逆向的算法和他其实是一个,是可以随时断下查看的, 也就是说动态调试的方式是不能主动断到GetName的,但是可以断到算法

5.GObjectArray

GObject 是保存着世界的对象地址

我们先利用特征找到

xdbg扫描字符串CanvasObject

得到一个结果,跳转到该条代码,并向上翻找带有sar的代码

这一条下面的基地址就是Gobject

Gobject=deathlystillnessgame-win64-shipping.exe+44D6128

发现没发现 这个基地址 贼眼熟

他就是之前 获取对象call,里面的基地址,这个数组套数组的基地址就是 GObject

6.旧版本UE4案例吃鸡模拟器----三件套分析

游戏进程在..../Binaries/Win64内

UWorld

xdbg搜索字符串: SeamlessTravel FlushLevelStreaming

用IDA搜索这个速度慢,而且IDA搜索到的位置可能会不全,可以用xdbg搜索字符串,用IDA查看伪代码

搜索字符串的过程比较缓慢,注意用xdbg找完UWorld不要把搜索到的字符串关掉,后面可能还需要找其他的数据

xdbg搜索得到一个结果

跳转到这个地址向上翻可以得到btr edx,0x7,再向上遇到的第一个基地址,就是UWorld

UWorld = battleroyaletrainer-win64-shipping.exe+2AF0FB8

UWorld的找发是UE4通用的,新老版本一样

GName

找GName的关键词是ByteProperty

找Gname的目的是为了获取UE内的所有字符串及其对应的ID,ByteProperty通常是所有字符串中的第2个,也就是说其ID是1,ID为0的为None,当然这个ID并不绝对,可能会有改变

用CE扫描ByteProperty

在内存对每一个结果逐个进行观察,找到连续字符串

很幸运的是第一个结果就是这样的,而后面的挨个看了下没有这类结构的

其实我们用xdbg观察这个结构会更清晰

我们会发现,每一个字符串前面会空出0x10字节,并且这0x10字节的第一个DWORD数值是0,2,4,6,8......这种,那么我们可以猜到1E01C630000就是这个结果的头部,这时我们可以用CE对其进行扫描然后得到2个地址

这里我们选择第一个地址,由于我们扫描的none的地址,所以直接扫描两次,可以得到Gname

这两个地址都可以用,但是为了稳妥,我们用访问断的方式再追一次,

对名字下访问,然后关闭游戏时会访问这个名字,

返回追rcx

最终的来源时上面的CALL

在CALL里同样可以得到Gname

这种方法的好处是可以看到字符串的具体公式,并找到Gname的位置

出现数组的这一层,如果再向外返回,就可以来到getname的位置,getname需要传入2个参数

第一个参数是一个指向ID的指针,对于这种没有加密的老版本来说,ID传0-3FFF即可

第二个参数是一个空结构体,返回的字符串会写到这个结构体里

其实最好的方式并不是调用这个函数,因为这个函数只是为了取name字符串用,我们只要知道取name用的是什么样子的ID,然后用相应的算法和规则将所有字符串和ID一起遍历,并输出出来即可,并不一定需要调用函数,自己写的函数效率可能会高一些

Gname = battleroyaletrainer-win64-shipping.exe+2AD75C8

GObjectArray

在字符串中扫描Unexpected concurency while adding new object

这句话的含义是添加新对象时出现意外,而这句话的上面正是添加对象的判断代码,

随意找一条代码查看

仔细分析,可以发现上面的rdi+10是一个数组的起始地址,而下面一条就是添加对象的判断,在头部点击右键,查看引用可以很容易得到rdi的来源

当然,我们也可以用IDA查看伪代码

a1是函数的第一个参数,在函数处查看交叉引用,发现第一个参数就是基地址

142AD9F20-140000000=0x2AD9F20

GObject

=battleroyaletrainer-win64-shipping.exe+0x2AD9F20+10

=battleroyaletrainer-win64-shipping.exe+0x2AD9F30

7.DUMP

先简单说下DUMP

使用IDA静态分析前 ,先用xdbg 把游戏dump 一下

步骤如下:

选择进程

点DUMP

最后会有一个错的,delete即可

然后打开IDA

dump 文件直接拖进 IDA ,出现对话框,直接取消取消即可.

然后我们就可以shift+F12 分析字符串了,当然这里分析的速度会比XDBG慢一些.

本章节内容就到这里,下一章我们继续研究DUMP,欢迎大家关注公众:任鸟飞逆向,共同学习讨论

以上是关于UE4引擎分析获取UWord,GName,GetName,GObjectArray的主要内容,如果未能解决你的问题,请参考以下文章

UE4 性能及分析

RcppAmadillo中uword和整数之间的操作

UE4/UE5引擎 FPS游戏逆向工程

不推荐使用table.getn - 如何获取数组的长度?

Ubuntu18.04搭建AirSim+ROS仿真环境

UE4程序及资源加密保护方案