首页
社区
课程
招聘
[原创]纯静态分析DumpSDK所需的加密数据,动态定位加密UWorld、GameInstance、Object的未加密地址
发表于: 2天前 726

[原创]纯静态分析DumpSDK所需的加密数据,动态定位加密UWorld、GameInstance、Object的未加密地址

2天前
726

因为游戏采用了一种执行时解密技术,相关技术介绍文章:击败 Theia 反篡改完整脱壳方案(Arc Raiders PioneerGame.exe),当然内容仅提供思路,如果照搬原文的解法,其实已经很早失效了。后续考虑单开一章进行该技术的讲解。其实直接Dump就可以获取到我们所需的所有数据的。

在之前的文章中我们已经演示了通过字符串:aMissingtablein定位(定位到函数execGetDataTableRowFromName),原理这里我们就不再赘述。
那么我们这里就拿到了FProperty结构体的大小。

我们直接进入我们的TheSameLayout函数后他的内部会调用ArePropertiesTheSame函数,从中可以拿到我们的ElementSize。
因为ArePropertiesTheSame基本在所有UE引擎游戏中都是直接内联的,所以在ida中就是以下这种状态:

我们对这一行按下tab键后获取ArrayDim和ElementSize的偏移:

我们这里并不能确定ElementSize是其中哪一个,只能通过注入后看ElementSize的值或者动态分析才能确定。当然肯定是两者其一。
这里的第一个if对应函数确实是我们FField结构体下Name的偏移,但是这里并不好直接复制解密算法,我们在其他位置找能直接复制的。

我们回到execGetDataTableRowFromName中依次定位->Generic_GetDataTableRowFromName->CopyScriptStruct
其中调用了:

那么MinAlignment出现两次,PropertiesSize出现一次对应IDA中:

当然这里存在默认构造函数,导致我们如果用UE源码跟的话篇幅会变大,所以我们用有pdb的对照观看:

execGetDataTableRowFromName->CopyScriptStruct->CopyCompleteValue_InContainer->ContainerPtrToValuePtr->ContainerVoidPtrToValuePtrInternal

对应我们的ida中的位置:

这样我们就获取到了Offset的解密算法:

在类TFieldIterator的构造函数中

对应ida的样式:

我们在UE引擎中可以定位到函数:FArrayProperty::ImportTextInnerItem
函数内有字符串:
text "UTF-16LE", '%s is a fixed-sized array of %i values. Additional '
我们在ida中定位:

可以看到UE引擎在没有魔改的情况下:

我们的FName是在+0x0的位置,但是这款游戏将结构进行了修改。我们只需要在源码内找到任何一个使用了FFieldClass.Name的位置即可定位偏移。
这里我们提供字符串:aFboolproperty text "UTF-16LE", 'FBoolProperty',可以定位到函数 FBoolProperty::StaticClass()或者FBoolProperty::Construct(),然后我们定位到函数FFieldClass::FFieldClass,FFieldClass的构造函数中使用到了FFieldClass.Name。
这样我们就拿到了FFieldClass.Name的解密算法:


我们如果直接看伪代码发现所需参数v10并没有给它赋值.

但是函数内部却对这个变量进行了解引用取值,这时候我们看汇编代码即可。
可以看到rcx=rsp+58h,那么我们模拟两次+0x10解引用,rsp+0x68解引用是我们这里的rax,rax=rsp+30,然后再+0x10解引用,讲就是我们的xmm0,也就是这里的参数其实就是我们的v9,我们外部移植时去掉多余的解引用即可。在ProcessEvent和StaticFindObject中用到了同样的方式,我们不管是通过注入调用还是使用vt断点断在主线程上下文调用,都需要构建相同的多层结构体进行传参即可。剩余的FName::ToString基本照抄即可,能最快还原。

定位方式依旧是之前文章提到的先定位ProcessEvent然后在内部找到UFunction::Invoke。该游戏对UFunction::Invoke进行了混淆:
不过只要不是vmp我们静态逐句分析都能定位到我们要的数据,快速定位方式就是一个一个分支的查看2个参数的函数(针对该游戏分析了一年多依旧适用的方式,仅针对该游戏).

这个函数内部依旧混淆。我们只需要找到一个形同ProcessEvent调用特征的(函数指针,三个参数),
我们查找v43的来源即可:

这样我们就轻松的定位到了Func的偏移0x150.

依旧是和以前文章一样的路径,通过aSTime3f3f3f定位函数UEnum::GetNameByValue。一次性就可以修复完UEnum结构体。在此不再赘述。

字符串:aFindremappedfi text "UTF-16LE", 'FindRemappedFieldImpl',0
定位到函数:FindRemappedFieldImpl<FField> 可以拿到SuperStruct的偏移


传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!

收藏
免费 19
打赏
分享
最新回复 (10)
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2天前
0
雪    币: 3414
活跃值: (7558)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
11111111111111111111111
1天前
0
雪    币: 112
活跃值: (9115)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
tql
1天前
0
雪    币: 1908
活跃值: (7333)
能力值: ( LV7,RANK:118 )
在线值:
发帖
回帖
粉丝
5
1
1天前
0
雪    币: 3063
活跃值: (6013)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
666
1天前
0
雪    币: 29
活跃值: (875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
6666666666
23小时前
0
雪    币: 11691
活跃值: (7606)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习了,多谢分享
15小时前
0
雪    币: 138
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
11111111
9小时前
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
学习
9小时前
0
雪    币: 187
活跃值: (532)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
学习
3小时前
0
游客
登录 | 注册 方可回帖
返回