0x00 前言
总结部分 Honkai 3 Bypass MTP的方案,持续更新
0x01 方案1:hook tersafe2
本方案借鉴Google空间(现OurPlay)的做法。使用Google空间启动崩坏3,查看maps下存在关键内容:

使用ida分析之,搜索字符串“tersafe2.so”,查看引用:

逐步回溯,得到基本流程如下:


我们分别看看这个unk_118F3A和关键函数sub_4010C是什么:

试试用最后几个hex字符“00 00 B0 E1 1E FF 2F 51”在libtersafe2.so里能搜索到什么?:


可知实际返回的是orig_ tersafe_sysopen(a1,"",a3,a4,a5,a6,a7,a8,a9,a10,a11)
。接下来我们就可以依葫芦画瓢,使用hookzz构造类似的hook
我们使用多开分身构造dkplugin后,因为其自身的libchaos.so已经实现了对dlopen的hook,可以参照VA中的写法,“借用”相关接口:
//VirtualApp/IOUniformer.cpp
HOOK_DEF(void*, dlopen, const char *filename, int flag) {
int res;
const char *redirect_path = relocate_path(filename, &res);
void *ret = orig_dlopen(redirect_path, flag);
onSoLoaded(filename, ret);
ALOGD("dlopen : %s, return : %p.", redirect_path, ret);
FREE(redirect_path, filename);
return ret;
}
HOOK_DEF(void*, do_dlopen_V19, const char *filename, int flag, const void *extinfo) {
int res;
const char *redirect_path = relocate_path(filename, &res);
void *ret = orig_do_dlopen_V19(redirect_path, flag, extinfo);
onSoLoaded(filename, ret);
ALOGD("do_dlopen : %s, return : %p.", redirect_path, ret);
FREE(redirect_path, filename);
return ret;
}
HOOK_DEF(void*, do_dlopen_V24, const char *name, int flags, const void *extinfo,
void *caller_addr) {
int res;
const char *redirect_path = relocate_path(name, &res);
void *ret = orig_do_dlopen_V24(redirect_path, flags, extinfo, caller_addr);
onSoLoaded(name, ret);
ALOGD("do_dlopen : %s, return : %p.", redirect_path, ret);
FREE(redirect_path, name);
return ret;
}
void onSoLoaded(const char *name, void *handle) {
}

//jni\module_ReplaceDlopen.cpp
char* LIB_PATH;
bool count = false;
void initLibPath() {
LIB_PATH = (char *)"/data/app/dkplugin.gxs.oza-Lwm7ENsog-HIXC1rUIv9Jw==/lib/arm/libchaos.so";
}
void onSoLoaded(const char *name, void *handle) {
if (!count && strstr(name, "libtersafe2.so")) {
count = true;
anti_tersafe2((int32_t) handle);
}
}
void *(*_R_dlopen)(const char *, int);
void *R_dlopen(const char *name, int flag) {
void *handle = _R_dlopen(name, flag);
onSoLoaded(name, handle);
return handle;
}
void *(*_R_dlopen_V19)(const char *, int, int);
void *R_dlopen_V19(const char *name, int flag1, int flag2) {
void *handle = _R_dlopen_V19(name, flag1, flag2);
onSoLoaded(name, handle);
return handle;
}
void *(*_R_dlopen_V24)(const char *, int, int, int);
void *R_dlopen_V24(const char *name, int flag1, int flag2, int flag3) {
void *handle = _R_dlopen_V24(name, flag1, flag2, flag3);
onSoLoaded(name, handle);
return handle;
}
void *(*_R_dlopen_V26)(const char *, int, int, int);
void *R_dlopen_V26(const char *name, int flag1, int flag2, int flag3) {
void *handle = _R_dlopen_V26(name, flag1, flag2, flag3);
onSoLoaded(name, handle);
return handle;
}
void ReplaceDlopen() {
initLibPath();
void *handle = dlopen(LIB_PATH, RTLD_NOW);
if (!handle)
return;
void *dlopen_addr = dlsym(handle, "replace_dlopen");
if (!dlopen_addr)
return;
void *V19_addr = dlsym(handle, "replace_do_dlopen_V19");
if (!V19_addr)
return;
void *V24_addr = dlsym(handle, "replace_do_dlopen_V24");
if (!V24_addr)
return;
void *V26_addr = dlsym(handle, "replace_do_dlopen_V26");
if (!V26_addr)
return;
ZzHook((void *)dlopen_addr, (void *)R_dlopen, (void **)&_R_dlopen, NULL, NULL, false);
ZzHook((void *)V19_addr, (void *)R_dlopen_V19, (void **)&_R_dlopen_V19, NULL, NULL, false);
ZzHook((void *)V24_addr, (void *)R_dlopen_V24, (void **)&_R_dlopen_V24, NULL, NULL, false);
ZzHook((void *)V26_addr, (void *)R_dlopen_V26, (void **)&_R_dlopen_V26, NULL, NULL, false);
LOGI("dlopen hook done.\nhandle >> 0x%lX", (long)handle);
}
//jni\module_AntiMtp.cpp
//tersafe2hex 00 00 B0 E1 1E FF 2F 51
int (*orig_tersafe_sysopen)(int, const char*, int, int, int, int, int, int, int, int, int);
int new_tersafe_sysopen(int a1, const char* a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11) {
return orig_tersafe_sysopen(a1, "", a3, a4, a5, a6, a7, a8, a9, a10, a11);
}
void anti_tersafe2(int32_t handle) {
long tersafe2 = get_module_base("libtersafe2.so");
ZzHook((void *)(tersafe2 + 0xD6820), (void *)new_tersafe_sysopen, (void **)&orig_tersafe_sysopen, NULL, NULL, false);
LOGI("anti_tersafe2 done.");
}
0x02 方案2:hook il2cpp & tprt
//jni\module_AntiMtp.cpp
unsigned long NOP = 0xE320F000;
unsigned long BXLR = 0xE12FFF1E;
void anti_tersafe2_inIl2cppLib(long base_addr) {
unsigned long addr = base_addr + 0x6A1DC54;//SDKMTPManager$$Tp2UserLogin
unsigned long addr2 = base_addr + 0x0C63014;//NetworkManager$$OnGetValidDipatchServerData中的SDKMTPManager$$InitMTP
unsigned long addr3 = base_addr + 0x378E1B4;//MonoMTP$$Tp2UserLogin
ZzRuntimeCodePatch((void *)addr, (void *)&BXLR, 4);
ZzRuntimeCodePatch((void *)addr2, (void *)&NOP, 4);
ZzRuntimeCodePatch((void *)addr3, (void *)&BXLR, 4);
LOGI("anti_tersafe2_inIl2cppLib done.");
}
hook了上述三个点位之后还是不够的,体现在游戏在正常运行120秒左右闪退。hook sleep并打印后发现存在10秒和120秒的轮询。遂hook之并返回86400秒:
//jni\module_AntiMtp.cpp
int new_sleep(unsigned int seconds) {
if ((seconds == 120) || (seconds == 10)) {
return sleep(86400);
}
return sleep(seconds);
}
void *anti_tprt(void *arg) {
while (true) {
long tprt = get_module_base("libtprt.so");
if (tprt != 0) {
xhook_register(".*/libtprt\\.so$", "sleep", (void *)new_sleep, NULL);
xhook_refresh(0);
break;
}
usleep(500000);
}
return NULL;
}
Comments | 4 条评论
有点问题,可以 联系你,咨询你一下吗? QQ 1435708276
#该评论为私密评论#
#该评论为私密评论#
#该评论为私密评论#