好的各位18cm的gege,时隔多日,伟大的灰大郎又回来了!!!
最近爆火的一款游戏The finals(最终决战)三测,刚干完苦力的我迫不及待打开我的小霸王准备游玩一番。卧槽!!锁子哥他们来了快跑!!!
毁灭吧,烦了。俗话说打不过就加入!!!
起初准备用看家本领CV大法一份玩一玩,结果看到隔壁群各种收数据,我慢慢发现事情没有这么简单。估计大手子dump sdk都留着发财了。总所周知,dump sdk找到GObjects以及GNames加上开源的sdkdump工具即可。
然而从这里才刚刚开始上套,一步步落入开发商的坑。满怀欢喜的打开CE搜索通用特征码却没有任何结果。后来发现搜索base 4D5A都没有。看来只能IDA了。
GObjects:搜索字符串“/Script/Angelscript”交叉引用则会看到GObject的解密
GNames:搜索字符串“ByteProperty”
就是这么朴实无华。等等,好像还没完。我发现了不得了的东西
我滴个亲娘呐。快跑!!!反手就是一个CV大法,内部可直接CALL
FNameToFString()
SDK-Dump:https://github.com/if-kdm/Discovery-SDK-Dump
实际上呢远远没有这么简单
反作弊:EasyAntiCheat +(暂且称为不知名的美女1号)
首先这个游戏对于每个不同的账号都会下发一个全新的版本所有客户端解密都不不同(更新前在我的PC,貌似在11/1晚上的更新后已经不在下发版本了)这很育碧。
游戏会对DrawText DrawLine DrawRect等等函数进行加密并且游戏运行时VirtualProtect函数所在的页 置PAGE_NOACCESS(更新前固定函数,更新后函数有所改变) 这很Byfron。不过只能算一个婴儿版本的byf
当然可以手动更改页属性 你会看到加密的.text
如果开启游戏前打开IDA CE等工具游戏会提示完整*侵害游戏不会退出。游戏中打开则会直接退出(更新后开启IDA将无法启动游戏)
对于WorldToScreen,如果像正常那样使用矩阵,也就是0x20]0x2xx]UE引擎通用矩阵,你将会得到0,此时也许你会想使用CameraManager->Location。但事实是你使用其它UE相同算法的使用相机坐标进行转换,你也会得到不正确的值。APlayerController->ProjectWorldLocationToScreen是最好的选择。
我反手就是一个
苦力活咱不干
不行!!不行!!我也要成为一次锁子哥,于是乎打开了某宝。
出于习惯,任何未知exe都会先检查一遍。运行exe会在C:\生成一个.sys
签名挺不错的。
额这个sysdiag.sys很灵性,不是sysdiag_win10.sys吗
整体来说驱动没有什么亮点没什么好说的,完全就是CV的https://github.com/haidragon/DriverInjectDll
主打一个朴实无华alloc write。不过对于免费版EAC足够了
IoControlCode:0x0x222409
好了,射了,下机
std::string GetFromFName(const uint32_t key){
unsigned __int64 v4;
/
/
r14
unsigned __int64 v5;
/
/
rdi
uint32_t chunkOffset
=
((
int
)(key) >>
16
);
WORD nameOffset
=
(WORD)key;
auto namePoolChunk
=
Process::Read<uintptr_t>(unk_7FF77B4B4980
+
(chunkOffset
*
6
)
+
(
8
*
21
)) ^
0xD0064AB34C24F50Fui64
;
auto entryOffset
=
namePoolChunk
+
(uint32_t )(
2
*
nameOffset);
v4
=
Process::Read<__int16>(entryOffset);
auto length
=
v5
=
v4 >>
6
;
if
( (v4 &
1
) !
=
0
){
/
/
wide
memcpy(v17, (a1
+
1
), (v4 >>
5
) &
0xFFFFFFFE
);
/
/
这里是第一个call实际上是一个memcpy
if
( v4 >
=
0x40u
){
.....
}
}
else
{
memcpy(v17, (a1
+
1
), (v4 >>
5
) &
0xFFFFFFFE
);
/
/
这里是第一个call实际上是一个memcpy
if
( v4 >
=
0x40u
){
.....
}
}
}
std::string GetFromFName(const uint32_t key){
unsigned __int64 v4;
/
/
r14
unsigned __int64 v5;
/
/
rdi
uint32_t chunkOffset
=
((
int
)(key) >>
16
);
WORD nameOffset
=
(WORD)key;
auto namePoolChunk
=
Process::Read<uintptr_t>(unk_7FF77B4B4980
+
(chunkOffset
*
6
)
+
(
8
*
21
)) ^
0xD0064AB34C24F50Fui64
;
auto entryOffset
=
namePoolChunk
+
(uint32_t )(
2
*
nameOffset);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!