获取HYP(XX游启动器)的基本信息
第一次发帖,如果有问题欢迎指出!
最近闲来无事,浅浅研究了下XX游的启动器
在程序安装目录发现一个app.conf.dat,数据被混淆了,用 010 Editor没看出有什么可读的信息,所以尝试分析启动器目录下的其他文件。
简单研究
直接将动态链接库拖入Binary Ninja发现似乎没有混淆,所以查看了几个动态链接库的函数后在HYBase.dll
中找到AppConfigManager
类,并在initialize
函数看到了疑似对app.conf.dat
操作的实现。
查看反汇编进行初步猜测
初始化:
sub_1800346d0(&var_728, HoYo::Common::FileSystem::GetAppDir())
sub_18002d2d0(&var_728, &data_1803c5040)
使用GetAppDir()
获取应用目录路径,并存储在var_728
中。
加载app.conf.dat
:
if (sub_180051760(&s, &var_728) != 0)
初步推测这个函数实现了解析数据到s中,查看sub_180051760
后发现sub_180051760
是一个配置文件加载器,并且在sub_180051760
中发现对app.conf.dat
的一些验证相关的实现,所以转至sub_180051760
继续研究。
对sub_180051760函数进行详细研究
有关的sub_180051760函数会在文末给出,因为太长了,影响阅读;为了方便理解,我在文中会将一部分伪代码简化。
1. 配置文件存在性检查
int32_t* rax_2 = sub_180052970(&var_308, arg2, 3)
uint32_t var_320 = (*rax_2).d
if (var_320 == 0 && rcx_1 == 0)
goto label_180051831
else
sub_180052dc0("exists", &var_2f8, arg2)
- 猜测:
sub_180052970
可能是检查文件是否存在或获取文件属性的函数。
var_320
表示文件状态。
- 若文件不存在,跳转到日志记录分支:
HoYo::Common::LogStream::operator<<("File not exists:")
2. 配置文件大小检查
sub_1802cd4a0(rcx_13, &var_2d8, 9, 0xffffffff)
if (var_2d0 <= 0x110)
LogStream << "File too small:"
elif (var_2d0 > 0x80000)
LogStream << "File too large:"
- 猜测:
var_2d0
存储文件大小。
- 文件大小范围限制为
0x110 (272B) <= size <= 0x80000 (524KB)
,可能是配置文件的合法范围,我还没有验证。
3.文件读取
if (var_2d0 < 0x1000)
...
rax_46 = operator new(var_2d0)
...
else
rax_44 = operator new(var_2d0 + 0x27)
std::basic_istream::read(s.q, var_2d0)
- 猜测:
- 根据文件大小动态分配内存,可能是要适应某种加密?
-读取配置文件内容,解密也在这之后进行。
4. 数据解密函数猜测
初步推测
sub_180050c80(&var_2b8, arg2, 0x21, 0x40)
int64_t* s_1 = sub_180083340(&var_2f8, &s, ...)
- 猜测:
- 初步推测
sub_180050c80
可能是解密函数(参数 0x21
和 0x40
似乎为解密模式或密钥标识)。
sub_180083340
将解密后的数据封装到 arg1
指向的结构中。
- 在查看
sub_180050c80
后发现并不是解密操作,似乎是文件流初始化函数,但也与解密有关联性所以继续向下找。
关键代码段定位
在函数后半部分(地址1800523ec
处)发现核心解密调用:
int64_t* s_1 = sub_180083340(&var_2f8, &s, &data_1803c51c0, &data_1803c51a0)
这里将读取的加密数据(s
)与两个全局数据结构传递给sub_180083340
,返回结果存储到arg1
中。这里基本上可以确认sub_180083340
时进行解密操作的函数了。
解密操作分步骤解析
-
文件读取与内存分配
- 在地址
180051f58
处分配内存:rax_46 = operator new(var_2d0)
- 通过
std::basic_istream::read
将文件内容读入缓冲区s.q
(地址180052373
)
-
解密函数调用
sub_180083340(
&var_2f8,
&s,
&data_1803c51c0,
&data_1803c51a0
)
-
结果处理
- 将解密结果
s_1
与arg1
比较
- 若不同,则将解密数据移动到
arg1
并清空临时缓冲区(地址18005243c
处)
-
寻找秘钥
使用binary ninja的code references找这两个数据被谁赋值了,找到关键函数sub_180001390
,在这里找到了疑似秘钥的字符串1qck4mmSyJ+YQ10PKzdZ6+J6AuvUAR8T
,以及这个秘钥的结构:
偏移量 |
内容 |
长度 |
编码分析 |
0x00 |
1qck4mmSyJ+YQ10PKzdZ6+J6AuvUAR8T |
32字节 |
Base64特征字符串 |
0x20 |
0x4e44496941372f53 |
8字节 |
解码为ASCII "NDIiA7/S" |
0x28 |
yTA= |
4字节 |
base64结束标记 |
最后得出秘钥的Base64编码为1qck4mmSyJ+YQ10PKzdZ6+J6AuvUAR8TS/7AiIDNyTA=
使用nodejs简单解码后输出长度,发现秘钥的长度为32字节,结合之前的猜测,这个秘钥大概率是AES-256-CBC算法的秘钥,但这个秘钥只是传入sub_180001390
函数的第一个数据,第二个数据查看后发现是一个RSA公钥,所以可能是一个混合加密。
想了一下,这个混合加密可能使用AES加密数据主体,然后用RSA公钥加密AES秘钥,在解密时先用RSA私钥解密AES秘钥,再用AES解密数据。这里突然发现如果真是按我想的思路实现,那我完全不需要管这个RSA加密,因为我已经获取到了AES秘钥,所以决定直接测试解密app.conf.dat的数据。
解密配置文件
AES-256-CBC
的初始化向量只影响第一个块,会使用第一个块的加密数据作为下一个块的iv
,以此迭代,所以在不知道初始化向量时只有第一个块数据会出错,不影响后续数据。
使用nodejs编写一个简单的解密脚本:
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const keyBase64 = '1qck4mmSyJ+YQ10PKzdZ6+J6AuvUAR8TS/7AiIDNyTA=';
const key = Buffer.from(keyBase64, 'base64');
const iv = Buffer.alloc(16);
class EncryptionHelper {
static aesDecrypt(buffer) {
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
decipher.setAutoPadding(true);
let decrypted = decipher.update(buffer);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
}
}
async function main() {
const destFileName = 'app.conf.dat';
let appDir = 'C:\\XXX Launcher';
const versionDir = findVersionDirectory(appDir);
if (!versionDir) {
console.error('未找到有效版本目录');
return;
}
const filePath = path.join(versionDir, destFileName);
try {
const buffer = fs.readFileSync(filePath);
const decryptedContent = EncryptionHelper.aesDecrypt(buffer);
console.log("解密内容:", decryptedContent);
} catch (err) {
console.error('解密失败:', err.message);
}
}
function findVersionDirectory(baseDir) {
const dirs = fs.readdirSync(baseDir, { withFileTypes: true })
.filter(d => d.isDirectory())
.map(d => path.join(baseDir, d.name))
.find(dir => /^\d+(\.\d+)+$/.test(path.basename(dir)));
return dirs;
}
main().catch(console.error);
运行后,得到app.conf.dat
的解密后数据,但不完美,不过关键信息基本都在可读的数据内。
" alt="" target="_blank" rel="noopener noreferrer nofollow" />
后续我可能会找出初始化向量,不过研究这个启动器也是一时兴起,随缘咯~
趣事
- 在
HYBase.dll
中直接搜索这个秘钥的第一部分,发现还有一个秘钥1qck4mmSyJ+YQ10PKzdZ6+J6AuvUAR8TS/7AiIDNyTA=
这个也可以解密配置文件。在图表模式下查看sub_180001390
的反汇编后发现这个可能是版本迭代时秘钥变更但没有完全清理?也可能是开发调试的残留。最后发现是我想多了,只是编码转换的问题。
- 那个RSA公钥可能用于其他的功能实现,我发现在这个公钥附近有一些api获取相关的字符串,可能用于一些敏感信息的加解密?我有了一些猜测,如果有时间继续研究,我会写另一个帖子,因为我猜测的似乎和这个帖子的主题不太相关。
相关反汇编伪代码片段
没有完整给出,太长了,大家可以自己逆向去看
18003cdc0 int64_t HoYo::Base::AppConfigManager::initialize()()
18003cdc0 {
18003cdd9 void var_7f8;
18003cdd9 int64_t rax_1 = (__security_cookie ^ &var_7f8);
18003cde6 int32_t var_7c8 = 0;
18003cdfb void var_728;
18003cdfb sub_1800346d0(&var_728, HoYo::Common::FileSystem::GetAppDir());
18003ce10 sub_18002d2d0(&var_728, &data_1803c5040);
18003ce18 int128_t s;
18003ce18 __builtin_memset(&s, 0, 0x18);
18003ce37 int64_t result;
18003ce37 int64_t var_7b0;
18003ce37 void var_618;
18003ce37
18003ce37 if (sub_180051760(&s, &var_728) != 0)
18003ce37 {
180051760 int64_t sub_180051760(int64_t* arg1, int64_t* arg2)
180051760 {
180051781 void var_378;
180051781 int64_t rax_1 = (__security_cookie ^ &var_378);
180051792 int64_t* var_328 = arg2;
18005179a int32_t var_348 = 0;
1800517a8 void var_308;
1800517a8 int32_t* rax_2 = sub_180052970(&var_308, arg2, 3);
1800517b1 uint32_t var_320 = ((int32_t)*(uint64_t*)rax_2);
1800517b7 int32_t rcx_1 = rax_2[2];
1800517ba int32_t var_2f8 = rcx_1;
1800517c8 void** var_2f0 = &data_1803c50b0;
1800517d8 var_2f8 = var_2f8;
1800517d8
1800517e7 if (var_320 == 0)
1800517e7 {
1800517eb if (rcx_1 == 0)
1800517eb goto label_180051831;
1800517eb
1800527cc sub_180052dc0("exists", &var_2f8, arg2);
1800527cc
1800517e7 }
1800517e7
1800517f6 void* const var_2b8;
1800517f6
1800517f6 if (var_320 == 1)
1800517f6 {
180051831 label_180051831:
180051831 class HoYo::Common::LogStream* rax_5 = HoYo::Common::LogStream::operator<<(HoYo::Common::Logger::Logger(&var_2b8, "D:\jenkins_home\workspace\plat-l…", 0x21, "HoYo::Base::Details::ConfigFileL…", 4), "File not exists:");
18005183a wchar16* r15_1 = arg2;
18005183a
180051842 if (arg2[3] > 7)
180051844 r15_1 = *(uint64_t*)arg2;
180051844
180051847 int64_t r14_1 = arg2[2];
18005184e var_2f8 = {0};
180051856 int64_t r8_1 = 0;
180051859 int64_t var_2e8_1 = 0;
180051861 int64_t rax_6 = 0xf;
180051866 int64_t var_2e0_1 = 0xf;
18005186e var_2f8 = 0;
180051876 int32_t var_348_1 = 2;
180051876
180051881 if (r14_1 != 0)
180051881 {
18005188e if (r14_1 > 0x7fffffff)
18005188e {
1800527d5 sub_180037230(0x16);
1800527d5
18005188e }
18005188e
1800518a7 int64_t rax_7 = __std_fs_convert_wide_to_narrow(0xfde9, r15_1, r14_1, nullptr, 0);
1800518a7
1800518b5 if (((int32_t)(rax_7 >> 0x20)) != 0)
1800518b5 {
1800527e1 sub_180037270(((int32_t)(rax_7 >> 0x20)));
1800527e1
1800518b5 }
1800518b5
1800518bb int64_t rcx_4 = ((int64_t)rax_7);
1800518be int64_t rdx_1 = var_2e8_1;
1800518be
1800518c9 if (rcx_4 > rdx_1)
1800518c9 {
1800518f6 int64_t count = (rcx_4 - rdx_1);
1800518f6
18005190a if (count > (var_2e0_1 - rdx_1))
18005190a {
18005193f int32_t var_358_2;
18005193f var_358_2 = 0;
180051955 sub_180016780(&var_2f8, count, 0, count, var_358_2);
18005190a }
18005190a else
18005190a {
18005190c var_2e8_1 = rcx_4;
180051914 int32_t* rbx_1 = &var_2f8;
180051914
180051920 if (var_2e0_1 > 0xf)
180051920 rbx_1 = var_2f8;
180051920
180051929 char* rbx_2 = ((char*)rbx_1 + rdx_1);
180051934 memset(rbx_2, 0, count);
180051939 rbx_2[count] = 0;
18005190a }
1800518c9 }
1800518c9 else
1800518c9 {
1800518cb char* rax_9 = &var_2f8;
1800518cb
1800518dc if (var_2e0_1 > 0xf)
1800518dc rax_9 = var_2f8;
1800518dc
1800518e5 var_2e8_1 = rcx_4;
1800518ed rax_9[rcx_4] = 0;
1800518c9 }
1800518c9
18005195a int32_t* r9_2 = &var_2f8;
18005195a
18005196b if (var_2e0_1 > 0xf)
18005196b r9_2 = var_2f8;
18005196b
180051983 int64_t rax_12 = __std_fs_convert_wide_to_narrow(0xfde9, r15_1, r14_1, r9_2, rax_7);
180051983
180051991 if (((int32_t)(rax_12 >> 0x20)) != 0)
180051991 {
1800527eb sub_180037270(((int32_t)(rax_12 >> 0x20)));
1800527eb
180051991 }
180051991
180051997 rax_6 = var_2e0_1;
18005199f r8_1 = var_2e8_1;
180051881 }
180051881
1800519a7 wchar16* rdx_4 = &var_2f8;
1800519a7
1800519b3 if (rax_6 > 0xf)
1800519b3 rdx_4 = var_2f8;
1800519b3
1800519bf sub_180015f00(rax_5, rdx_4, r8_1);
1800519bf
1800519d1 if (var_2e0_1 > 0xf)
1800519d1 {
1800519d6 void* rcx_9 = var_2f8;
1800519de void* rax_14 = rcx_9;
1800519de
1800519e8 if ((var_2e0_1 + 1) >= 0x1000)
1800519e8 {
1800519ee rcx_9 = *(uint64_t*)((char*)rcx_9 - 8);
1800519ee
1800519fd if ((((char*)rax_14 - rcx_9) - 8) > 0x1f)
1800519fd {
1800519ff _invalid_parameter_noinfo_noreturn();
1800519ff
1800519fd }
1800519e8 }
1800519e8
180051a06 sub_1802d3e7c(rcx_9);
1800519d1 }
1800519d1
180051a0b int64_t var_2e8_2 = 0;
180051a13 int64_t var_2e0_2 = 0xf;
180051a1f var_2f8 = 0;
180051881 goto label_180051a2f;
1800517f6 }
1800517f6
180051a64 int64_t* rcx_13 = arg2;
180051a64
180051a6c if (arg2[3] > 7)
180051a6e rcx_13 = *(uint64_t*)arg2;
180051a6e
180051a85 void var_2d8;
180051a85 enum WIN32_ERROR rax_17 = sub_1802cd4a0(rcx_13, &var_2d8, 9, 0xffffffff);
180051a85
180051a8c if (rax_17 != NO_ERROR)
180051a8c {
1800527b4 sub_180052e20("file_size", rax_17, arg2);
1800527b4
180051a8c }
180051a8c
180051aa1 uint64_t var_2d0;
180051aa1 int64_t result;
180051aa1
180051aa1 if (var_2d0 <= 0x110)
180051aa1 {
180051ada class HoYo::Common::LogStream* rax_19 = HoYo::Common::LogStream::operator<<(HoYo::Common::Logger::Logger(&var_2b8, "D:\jenkins_home\workspace\plat-l…", (rax_17 + 0x28), "HoYo::Base::Details::ConfigFileL…", 4), "File too small:");
180051ae3 int64_t* r15_2 = arg2;
180051ae3
180051aeb if (arg2[3] > 7)
180051aed r15_2 = *(uint64_t*)arg2;
180051aed
180051af0 int64_t r14_2 = arg2[2];
180051af7 var_2f8 = {0};
180051aff int64_t r8_7 = 0;
180051b02 int64_t var_2e8_3 = 0;
180051b0a int64_t rax_20 = 0xf;
180051b0f int64_t var_2e0_3 = 0xf;
180051b17 var_2f8 = 0;
180051b1f int32_t var_348_2 = 8;
180051b1f
180051b2a if (r14_2 != 0)
180051b2a {
180051b37 if (r14_2 > 0x7fffffff)
180051b37 {
1800527f4 sub_180037230(0x16);
1800527f4
180051b37 }
180051b37
180051b50 int64_t rax_21 = __std_fs_convert_wide_to_narrow(0xfde9, r15_2, r14_2, nullptr, 0);
180051b50
180051b5e if (((int32_t)(rax_21 >> 0x20)) != 0)
180051b5e {
180052800 sub_180037270(((int32_t)(rax_21 >> 0x20)));
180052800
180051b5e }
180051b5e
180051b64 int64_t rcx_16 = ((int64_t)rax_21);
180051b67 int64_t rdx_9 = var_2e8_3;
180051b67
180051b72 if (rcx_16 > rdx_9)
180051b72 {
180051b9f uint64_t count_1 = (rcx_16 - rdx_9);
180051b9f
180051bb3 if (count_1 > (var_2e0_3 - rdx_9))
180051bb3 {
180051be8 int32_t var_358_5;
180051be8 var_358_5 = 0;
180051bfe sub_180016780(&var_2f8, count_1, 0, count_1, var_358_5);
180051bb3 }
180051bb3 else
180051bb3 {
180051bb5 var_2e8_3 = rcx_16;
180051bbd int32_t* rbx_3 = &var_2f8;
180051bbd
180051bc9 if (var_2e0_3 > 0xf)
180051bc9 rbx_3 = var_2f8;
180051bc9
180051bd2 void* rbx_4 = ((char*)rbx_3 + rdx_9);
180051bdd memset(rbx_4, 0, count_1);
180051be2 *(uint8_t*)(count_1 + rbx_4) = 0;
180051bb3 }
180051b72 }
180051b72 else
180051b72 {
180051b74 char* rax_23 = &var_2f8;
180051b74
180051b85 if (var_2e0_3 > 0xf)
180051b85 rax_23 = var_2f8;
180051b85
180051b8e var_2e8_3 = rcx_16;
180051b96 rax_23[rcx_16] = 0;
180051b72 }
180051b72
180051c03 PSTR r9_4 = &var_2f8;
180051c03
180051c14 if (var_2e0_3 > 0xf)
180051c14 r9_4 = var_2f8;
180051c14
180051c2c int64_t rax_26 = __std_fs_convert_wide_to_narrow(0xfde9, r15_2, r14_2, r9_4, rax_21);
180051c2c
180051c3a if (((int32_t)(rax_26 >> 0x20)) != 0)
180051c3a {
18005280a sub_180037270(((int32_t)(rax_26 >> 0x20)));
18005280a
180051c3a }
180051c3a
180051c40 rax_20 = var_2e0_3;
180051c48 r8_7 = var_2e8_3;
180051b2a }
180051b2a
180051c50 wchar16* rdx_12 = &var_2f8;
180051c50
180051c5c if (rax_20 > 0xf)
180051c5c rdx_12 = var_2f8;
180051c5c
180051c68 sub_180015f00(rax_19, rdx_12, r8_7);
180051c68
180051c7a if (var_2e0_3 > 0xf)
180051c7a {
180051c7f void* rcx_21 = var_2f8;
180051c87 void* rax_28 = rcx_21;
180051c87
180051c91 if ((var_2e0_3 + 1) >= 0x1000)
180051c91 {
180051c97 rcx_21 = *(uint64_t*)((char*)rcx_21 - 8);
180051c97
180051ca6 if ((((char*)rax_28 - rcx_21) - 8) > 0x1f)
180051ca6 {
180051ca8 _invalid_parameter_noinfo_noreturn();
180051ca8
180051ca6 }
180051c91 }
180051c91
180051caf sub_1802d3e7c(rcx_21);
180051c7a }
180051c7a
180051cb4 int64_t var_2e8_4 = 0;
180051cbc int64_t var_2e0_4 = 0xf;
180051cc8 var_2f8 = 0;
180051a2f label_180051a2f:
180051a2f HoYo::Common::Logger::~Logger(&var_2b8);
180051a35 label_180051a35:
180051a35 result = 0;
180051a42 __security_check_cookie((rax_1 ^ &var_378));
180051a63 return result;
180051aa1 }
180051aa1
180051cdc if (var_2d0 > 0x80000)
180051cdc {
180051d17 class HoYo::Common::LogStream* rax_32 = HoYo::Common::LogStream::operator<<(HoYo::Common::Logger::Logger(&var_2b8, "D:\jenkins_home\workspace\plat-l…", 0x2e, "HoYo::Base::Details::ConfigFileL…", 4), "File too large:");
180051d20 int64_t* r15_3 = arg2;
180051d20
180051d28 if (arg2[3] > 7)
180051d2a r15_3 = *(uint64_t*)arg2;
180051d2a
180051d2d int64_t r14_3 = arg2[2];
180051d34 var_2f8 = {0};
180051d3c wchar16* r8_12 = nullptr;
180051d3f wchar16* var_2e8_5 = nullptr;
180051d47 int64_t rax_33 = 0xf;
180051d4c int64_t var_2e0_5 = 0xf;
180051d54 var_2f8 = 0;
180051d5c int32_t var_348_3 = 0x20;
180051d5c
180051d67 if (r14_3 != 0)
180051d67 {
180051d74 if (r14_3 > 0x7fffffff)
180051d74 {
180052813 sub_180037230(0x16);
180052813
180051d74 }
180051d74
180051d8d int64_t rax_34 = __std_fs_convert_wide_to_narrow(0xfde9, r15_3, r14_3, nullptr, 0);
180051d8d
180051d9b if (((int32_t)(rax_34 >> 0x20)) != 0)
180051d9b {
18005281f sub_180037270(((int32_t)(rax_34 >> 0x20)));
18005281f
180051d9b }
180051d9b
180051da1 int64_t rcx_24 = ((int64_t)rax_34);
180051da4 wchar16* rdx_16 = var_2e8_5;
180051da4
180051daf if (rcx_24 > rdx_16)
180051daf {
180051ddc uint64_t count_2 = (rcx_24 - rdx_16);
180051ddc
180051df0 if (count_2 > (var_2e0_5 - rdx_16))
180051df0 {
180051e25 int32_t var_358_8;
180051e25 var_358_8 = 0;
180051e3b sub_180016780(&var_2f8, count_2, 0, count_2, var_358_8);
180051df0 }
180051df0 else
180051df0 {
180051df2 var_2e8_5 = rcx_24;
180051dfa int32_t* rbx_5 = &var_2f8;
180051dfa
180051e06 if (var_2e0_5 > 0xf)
180051e06 rbx_5 = var_2f8;
180051e06
180051e0f void* rbx_6 = ((char*)rbx_5 + rdx_16);
180051e1a memset(rbx_6, 0, count_2);
180051e1f *(uint8_t*)(count_2 + rbx_6) = 0;
180051df0 }
180051daf }
180051daf else
180051daf {
180051db1 char* rax_36 = &var_2f8;
180051db1
180051dc2 if (var_2e0_5 > 0xf)
180051dc2 rax_36 = var_2f8;
180051dc2
180051dcb var_2e8_5 = rcx_24;
180051dd3 rax_36[rcx_24] = 0;
180051daf }
180051daf
180051e40 PSTR r9_6 = &var_2f8;
180051e40
180051e51 if (var_2e0_5 > 0xf)
180051e51 r9_6 = var_2f8;
180051e51
180051e69 int64_t rax_39 = __std_fs_convert_wide_to_narrow(0xfde9, r15_3, r14_3, r9_6, rax_34);
180051e69
180051e77 if (((int32_t)(rax_39 >> 0x20)) != 0)
180051e77 {
180052829 sub_180037270(((int32_t)(rax_39 >> 0x20)));
180052829
180051e77 }
180051e77
180051e7d rax_33 = var_2e0_5;
180051e85 r8_12 = var_2e8_5;
180051d67 }
180051d67
180051e8d wchar16* rdx_19 = &var_2f8;
180051e8d
180051e99 if (rax_33 > 0xf)
180051e99 rdx_19 = var_2f8;
180051e99
180051ea5 sub_180015f00(rax_32, rdx_19, r8_12);
180051ea5
180051eb7 if (var_2e0_5 > 0xf)
180051eb7 {
180051ebc void* rcx_29 = var_2f8;
180051ec4 void* rax_41 = rcx_29;
180051ec4
180051ece if ((var_2e0_5 + 1) >= 0x1000)
180051ece {
180051ed4 rcx_29 = *(uint64_t*)((char*)rcx_29 - 8);
180051ed4
180051ee3 if ((((char*)rax_41 - rcx_29) - 8) > 0x1f)
180051ee3 {
180051ee5 _invalid_parameter_noinfo_noreturn();
180051ee5
180051ee3 }
180051ece }
180051ece
180051eec sub_1802d3e7c(rcx_29);
180051eb7 }
180051eb7
180051ef1 int64_t var_2e8_6 = 0;
180051ef9 int64_t var_2e0_6 = 0xf;
180051f05 var_2f8 = 0;
180051d67 goto label_180051a2f;
180051cdc }
180051cdc
180051f15 int128_t s;
180051f15 __builtin_memset(&s, 0, 0x18);
180051f27 void* rax_46;
180051f27
180051f27 if (var_2d0 < 0x1000)
180051f27 {
180051f58 rax_46 = operator new(var_2d0);
180051f5d label_180051f5d:
180051f5d s = rax_46;
180051f62 void* rbx_7 = ((char*)rax_46 + var_2d0);
180051f73 memset(rax_46, 0, var_2d0);
180051f78 *(uint64_t*)((char*)s)[8] = rbx_7;
180051f84 var_2b8 = &data_1803146d0;
180051f94 void var_208;
180051f94 std::basic_ios<char,struct std::char_traits<char> >::basic_ios<char,struct std::char_traits<char> >(&var_208);
180051f9b int32_t var_348_4 = 0x40;
180051fb9 void** const _Strbuf;
180051fb9 std::basic_istream<char,struct std::char_traits<char> >::basic_istream<char,struct std::char_traits<char> >(&var_2b8, &_Strbuf, 0);
180051fd3 *(uint64_t*)(&var_2b8 + ((int64_t)*(uint32_t*)((char*)var_2b8 + 4))) = &data_1803146c8;
180051fe3 int64_t rcx_37 = ((int64_t)*(uint32_t*)((char*)var_2b8 + 4));
180051fed void var_2bc;
180051fed *(uint32_t*)(&var_2bc + rcx_37) = ((int32_t)(rcx_37 - 0xb0));
180051ffc std::basic_streambuf<char,struct std::char_traits<char> >::basic_streambuf<char,struct std::char_traits<char> >();
180052009 _Strbuf = &data_180314648;
180052011 char var_22c_1 = 0;
180052019 char var_237_1 = 0;
180052029 std::basic_streambuf<char,struct std::char_traits<char> >::_Init();
18005202f int64_t var_228_1 = 0;
18005203e int64_t var_234_1 = data_1803d1ce0;
180052046 int64_t var_240_1 = 0;
180052063 sub_180050c80(&var_2b8, arg2, 0x21, 0x40);
180052071 void var_178;
180052071
180052071 if (var_228_1 == 0)
180052071 {
1800520ac class HoYo::Common::LogStream* rax_51 = HoYo::Common::LogStream::operator<<(HoYo::Common::Logger::Logger(&var_178, "D:\jenkins_home\workspace\plat-l…", 0x3a, "HoYo::Base::Details::ConfigFileL…", 4), "Failed to open file:");
1800520b5 int64_t* r15_4 = arg2;
1800520b5
1800520bd if (arg2[3] > 7)
1800520bf r15_4 = *(uint64_t*)arg2;
1800520bf
1800520c2 int64_t r14_4 = arg2[2];
1800520c9 var_2f8 = {0};
1800520d1 wchar16* r8_18 = nullptr;
1800520d4 wchar16* var_2e8_7 = nullptr;
1800520dc int64_t rax_52 = 0xf;
1800520e1 int64_t var_2e0_7 = 0xf;
1800520e9 var_2f8 = 0;
1800520f1 int32_t var_348_5 = 0x140;
1800520f1
1800520fc if (r14_4 != 0)
1800520fc {
180052109 if (r14_4 > 0x7fffffff)
180052109 {
180052838 sub_180037230(0x16);
180052838
180052109 }
180052109
180052122 int64_t rax_53 = __std_fs_convert_wide_to_narrow(0xfde9, r15_4, r14_4, nullptr, 0);
180052122
180052130 if (((int32_t)(rax_53 >> 0x20)) != 0)
180052130 {
180052843 sub_180037270(((int32_t)(rax_53 >> 0x20)));
180052843
180052130 }
180052130
180052136 int64_t rcx_41 = ((int64_t)rax_53);
180052139 wchar16* rdx_26 = var_2e8_7;
180052139
180052144 if (rcx_41 > rdx_26)
180052144 {
180052171 uint64_t count_3 = (rcx_41 - rdx_26);
180052171
180052185 if (count_3 > (var_2e0_7 - rdx_26))
180052185 {
1800521c1 int32_t var_358_11;
1800521c1 var_358_11 = 0;
1800521d7 sub_180016780(&var_2f8, count_3, 0, count_3, var_358_11);
180052185 }
180052185 else
180052185 {
180052187 var_2e8_7 = rcx_41;
18005218f int32_t* rbx_8 = &var_2f8;
18005218f
18005219b if (var_2e0_7 > 0xf)
18005219b rbx_8 = var_2f8;
18005219b
1800521a4 void* rbx_9 = ((char*)rbx_8 + rdx_26);
1800521af memset(rbx_9, 0, count_3);
1800521b4 *(uint8_t*)((char*)rbx_9 + count_3) = 0;
180052185 }
180052144 }
180052144 else
180052144 {
180052146 int32_t* rax_55 = &var_2f8;
180052146
180052157 if (var_2e0_7 > 0xf)
180052157 rax_55 = var_2f8;
180052157
180052160 var_2e8_7 = rcx_41;
180052168 *(uint8_t*)(rcx_41 + rax_55) = 0;
180052144 }
180052144
1800521dc PSTR r9_8 = &var_2f8;
1800521dc
1800521ed if (var_2e0_7 > 0xf)
1800521ed r9_8 = var_2f8;
1800521ed
180052205 int64_t rax_58 = __std_fs_convert_wide_to_narrow(0xfde9, r15_4, r14_4, r9_8, rax_53);
180052205
180052213 if (((int32_t)(rax_58 >> 0x20)) != 0)
180052213 {
18005284c sub_180037270(((int32_t)(rax_58 >> 0x20)));
18005284c
180052213 }
180052213
180052219 rax_52 = var_2e0_7;
180052221 r8_18 = var_2e8_7;
1800520fc }
1800520fc
180052229 wchar16* rdx_29 = &var_2f8;
180052229
180052235 if (rax_52 > 0xf)
180052235 rdx_29 = var_2f8;
180052235
180052241 sub_180015f00(rax_51, rdx_29, r8_18);
180052241
180052253 if (var_2e0_7 > 0xf)
180052253 {
180052258 void* rcx_46 = var_2f8;
180052260 void* rax_60 = rcx_46;
180052260
18005226a if ((var_2e0_7 + 1) >= 0x1000)
18005226a {
180052270 rcx_46 = *(uint64_t*)((char*)rcx_46 - 8);
180052270
18005227f if ((((char*)rax_60 - rcx_46) - 8) > 0x1f)
18005227f {
180052281 _invalid_parameter_noinfo_noreturn();
180052281
18005227f }
18005226a }
18005226a
180052288 sub_1802d3e7c(rcx_46);
180052253 }
180052253
18005228d int64_t var_2e8_8 = 0;
180052295 int64_t var_2e0_8 = 0xf;
1800522a1 var_2f8 = 0;
1800522b1 HoYo::Common::Logger::~Logger(&var_178);
1800522c4 *(uint64_t*)(&var_2b8 + ((int64_t)*(uint32_t*)((char*)var_2b8 + 4))) = &data_1803146c8;
1800522d4 int64_t rcx_49 = ((int64_t)*(uint32_t*)((char*)var_2b8 + 4));
1800522de *(uint32_t*)(&var_2bc + rcx_49) = ((int32_t)(rcx_49 - 0xb0));
1800522ed sub_180051340(&_Strbuf);
1800522fa std::basic_istream<char,struct std::char_traits<char> >::~basic_istream<char,struct std::char_traits<char> >();
180052308 std::basic_ios<char,struct std::char_traits<char> >::~basic_ios<char,struct std::char_traits<char> >(&var_208);
18005230f void* rcx_52 = s;
18005230f
180052317 if (rcx_52 != 0)
180052317 {
180052321 void* rax_65 = rcx_52;
180052321
18005232b if (((char*)rbx_7 - rcx_52) >= 0x1000)
18005232b {
180052331 rcx_52 = *(uint64_t*)((char*)rcx_52 - 8);
180052331
180052340 if ((((char*)rax_65 - rcx_52) - 8) > 0x1f)
180052340 {
180052342 _invalid_parameter_noinfo_noreturn();
180052342
180052340 }
18005232b }
18005232b
180052349 sub_1802d3e7c(rcx_52);
180052351 __builtin_memset(&s, 0, 0x18);
180052317 }
180052317
18005235c result = 0;
180051a42 __security_check_cookie((rax_1 ^ &var_378));
180051a63 return result;
180052071 }
180052071
180052373 std::basic_istream<char,struct std::char_traits<char> >::read(&var_2b8, s, var_2d0);
180052386 *(uint64_t*)(&var_2b8 + ((int64_t)*(uint32_t*)((char*)var_2b8 + 4))) = &data_1803146c8;
180052396 int64_t rcx_55 = ((int64_t)*(uint32_t*)((char*)var_2b8 + 4));
1800523a0 *(uint32_t*)(&var_2bc + rcx_55) = ((int32_t)(rcx_55 - 0xb0));
1800523af sub_180051340(&_Strbuf);
1800523bc std::basic_istream<char,struct std::char_traits<char> >::~basic_istream<char,struct std::char_traits<char> >();
1800523ca std::basic_ios<char,struct std::char_traits<char> >::~basic_ios<char,struct std::char_traits<char> >(&var_208);
1800523ec int64_t* s_1 = sub_180083340(&var_2f8, &s, &data_1803c51c0, &data_1803c51a0);
180001390 int64_t sub_180001390()
180001390 {
180001399 void* rax = operator new(0x30);
1800013a5 data_1803c51c0 = rax;
1800013ac data_1803c51d0 = 0x2c;
1800013b7 data_1803c51d8 = 0x2f;
1800013c2 __builtin_strncpy(rax, "1qck4mmSyJ+YQ10PKzdZ6+J6AuvUAR8T", 0x20);
1800013d8 *(uint64_t*)((char*)rax + 0x20) = 0x4e44496941372f53;
1800013e3 __builtin_strncpy(((char*)rax + 0x28), "yTA=", 5);
1800013f5
1800013f5 return atexit(sub_18030d7c0);
180001390 }