From d45a314e04a20fe9c81abb20745e15a90c5c5e82 Mon Sep 17 00:00:00 2001 From: axhlzy Date: Tue, 23 Apr 2024 16:44:56 +0800 Subject: [PATCH] fix B_Text --- Il2cppHook/agent/base/globle.ts | 10 +-- .../Graphic/MaskableGraphic/Text/export.ts | 71 +++++++++---------- Il2cppHook/agent/utils/common.ts | 21 ++++-- 3 files changed, 54 insertions(+), 48 deletions(-) diff --git a/Il2cppHook/agent/base/globle.ts b/Il2cppHook/agent/base/globle.ts index 8bd0fb26..581abb9f 100644 --- a/Il2cppHook/agent/base/globle.ts +++ b/Il2cppHook/agent/base/globle.ts @@ -46,7 +46,7 @@ export function GET_F(type: EpFunc): T { } // 记录全局变量 -let MAP_GLOABE_OBJ = new Map() +const MAP_GLOABE_OBJ = new Map() export const GET_G = (gKey: GKEY): any => MAP_GLOABE_OBJ.get(gKey) @@ -61,9 +61,9 @@ export function SET_G(gKey: GKEY, obj: any): Map { export function GET_MAP(tKay: MapKAY): Map { if (MAP_GLOABE_OBJ.get(tKay)) { - return MAP_GLOABE_OBJ.get(tKay) as Map + return MAP_GLOABE_OBJ.get(tKay) } else { - let tmp = new Map() + const tmp = new Map() SET_MAP(tKay, tmp) return tmp } @@ -74,11 +74,11 @@ export function SET_MAP(tKay: MapKAY, map: Map): void { } export function SET_MAP_VALUE(tKay: MapKAY, key: K, value: V): void { - SET_MAP(tKay, GET_MAP(tKay).set(key, value)) + SET_MAP(tKay, GET_MAP(tKay)!.set(key, value)) } export function GET_MAP_VALUE(tKay: MapKAY, key: K): any { - return GET_MAP(tKay).get(key) + return GET_MAP(tKay)!.get(key) } export function GET_ARRAY(tKay: ArrKAY): Array { diff --git a/Il2cppHook/agent/expand/TypeExtends/mscorlibObj/Object/Component/Behavior/MonoBehaviour/UIBehaviour/Graphic/MaskableGraphic/Text/export.ts b/Il2cppHook/agent/expand/TypeExtends/mscorlibObj/Object/Component/Behavior/MonoBehaviour/UIBehaviour/Graphic/MaskableGraphic/Text/export.ts index 396dc64f..23ad0705 100644 --- a/Il2cppHook/agent/expand/TypeExtends/mscorlibObj/Object/Component/Behavior/MonoBehaviour/UIBehaviour/Graphic/MaskableGraphic/Text/export.ts +++ b/Il2cppHook/agent/expand/TypeExtends/mscorlibObj/Object/Component/Behavior/MonoBehaviour/UIBehaviour/Graphic/MaskableGraphic/Text/export.ts @@ -73,16 +73,16 @@ const setFont = (index: number) => { // \n 0x0A | \r 0x0D | \t 0x09 | [空格] 0x20 | [换行] 0x0D 0x0A const B_Text = (): void => { - let mapRecord = new Map() - let strMap = new Map() + const strRecordMap = new Map() + const strReplaceMap = new Map() - strMap.set("SETTINGS", "设置") - strMap.set("Setting", "SETTINGS") - strMap.set("選擇角色", "选择角色") - strMap.set("ADDED", "已添加") - strMap.set("ON", "开") - strMap.set("Loading...", "加载中...") - strMap.set("More games", "更多游戏") + strReplaceMap.set("SETTINGS", "设置") + strReplaceMap.set("Setting", "SETTINGS") + strReplaceMap.set("選擇角色", "选择角色") + strReplaceMap.set("ADDED", "已添加") + strReplaceMap.set("ON", "开") + strReplaceMap.set("Loading...", "加载中...") + strReplaceMap.set("More games", "更多游戏") try { LOGD("Enable TMP_Text Hook".padEnd(30, " ") + "| class : " + findClass("TMP_Text")) @@ -121,12 +121,12 @@ const B_Text = (): void => { function TMP_Text(showGobj: boolean) { A(find_method("Unity.TextMeshPro", "TMP_Text", "get_transform", 0), (args, ctx) => { - let aimStr = "|" + readU16(callFunction(["Unity.TextMeshPro", "TMP_Text", "get_text", 0], args[0])) + "|" - if (filterDuplicateOBJ(String(args[0]), 30) == -1) return + const aimStr = "|" + readU16(callFunction(["Unity.TextMeshPro", "TMP_Text", "get_text", 0], args[0])) + "|" + if (filterDuplicateOBJ(aimStr, 30) == -1) return worksWithText(args[0], "TMP_Text") LOGD("\n[TMP_Text]\t" + args[0] + "\t" + aimStr + "\t" + getPlatformCtx(ctx).lr) - if (strMap.size != 0) { - let repStr = strMap.get(aimStr.substring(1, aimStr.length - 1)) + if (strReplaceMap.size != 0) { + const repStr = strReplaceMap.get(aimStr.substring(1, aimStr.length - 1)) if (repStr != undefined) { callFunction(find_method("Unity.TextMeshPro", "TMP_Text", "set_text", 1), args[0], allocUStr(repStr)) LOGH(" \n\t {REP} " + aimStr + " ---> " + repStr) @@ -149,12 +149,12 @@ const B_Text = (): void => { function TextMeshPro() { // A(find_method("Unity.TextMeshPro", "TextMeshPro", "get_transform", 0), (args) => { A(Il2Cpp.Api.TextMeshPro._get_transform, (args) => { - let aimStr = "|" + new TMPro_TMP_Text(args[0]).get_text() + "|" - if (filterDuplicateOBJ(String(args[0])) == -1) return + const aimStr = "|" + new TMPro_TMP_Text(args[0]).get_text() + "|" + if (filterDuplicateOBJ(aimStr) == -1) return worksWithText(args[0], "TextMeshPro") LOG("\n[TextMeshPro] " + args[0] + "\t" + aimStr, LogColor.C35) - if (strMap.size != 0) { - let repStr = strMap.get(aimStr.substring(1, aimStr.length - 1)) + if (strReplaceMap.size != 0) { + const repStr = strReplaceMap.get(aimStr.substring(1, aimStr.length - 1)) if (repStr != undefined) { callFunction(find_method("Unity.TextMeshPro", "TextMeshPro", "set_text", 1), args[0], allocUStr(repStr)) LOGH("\n\t { REP } " + aimStr + " ---> " + repStr) @@ -178,12 +178,11 @@ const B_Text = (): void => { worksWithText(args[0], "Text") if (showGameObj) new Il2Cpp.Component(args[0]).get_gameObject().showSelf() }, (ret, ctx) => { - let aimStr = "|" + readU16(ret) + "|" - if (filterDuplicateOBJ(String(ret)) == -1) return - getPlatformCtx + const aimStr = "|" + readU16(ret) + "|" + if (filterDuplicateOBJ(aimStr) == -1) return LOGG("\n[Text_Get] " + getPlatformCtxWithArgV(ctx, 0) + "\t" + aimStr) - if (strMap.size != 0) { - let repStr = strMap.get(aimStr.substring(1, aimStr.length - 1)) + if (strReplaceMap.size != 0) { + const repStr = strReplaceMap.get(aimStr.substring(1, aimStr.length - 1)) if (repStr != undefined) { ret.replace(allocUStr(repStr)) // callFunction(find_method("UnityEngine.UI", 'Text', 'set_text', 1), p_size == 4 ? ctx.r0 : ctx.x0, allocStr(repStr, "")) @@ -193,13 +192,13 @@ const B_Text = (): void => { }) // A(find_method("UnityEngine.UI", "Text", "set_text", 1), (args, ctx) => { - A(Il2Cpp.Api.Text._set_text, (args, ctx) => { - if (filterDuplicateOBJ(String(args[1])) == -1) return + A(Il2Cpp.Api.Text._set_text, (args:NativePointer[], _ctx:CpuContext) => { + const aimStr = "|" + readU16(args[1]) + "|" + if (filterDuplicateOBJ(aimStr) == -1 || filterDuplicateOBJ(args[0].toString()) == -1) return worksWithText(args[0], "Text") - let aimStr = "|" + readU16(args[1]) + "|" LOGO("\n[Text_Set] " + args[0] + "\t" + aimStr) - if (strMap.size != 0) { - let repStr = strMap.get(aimStr.substring(1, aimStr.length - 1)) + if (strReplaceMap.size != 0) { + const repStr = strReplaceMap.get(aimStr.substring(1, aimStr.length - 1)) if (repStr != undefined) { args[1] = allocUStr(repStr) LOGH(` \n\t {REP} ${aimStr} ---> ${repStr}`) @@ -213,12 +212,12 @@ const B_Text = (): void => { function HookTrackText() { A(find_method('UnityEngine.UI', 'FontUpdateTracker', 'TrackText', 1), (args) => { - let aimStr = "|" + callFunctionRUS(["UnityEngine.UI", 'Text', 'get_text', 0], args[0]) + "|" - if (filterDuplicateOBJ(String(callFunctionRUS(["UnityEngine.UI", 'Text', 'get_text', 0], args[0]))) == -1) return + const aimStr = "|" + callFunctionRUS(["UnityEngine.UI", 'Text', 'get_text', 0], args[0]) + "|" + if (filterDuplicateOBJ(aimStr) == -1) return LOGD(`\n[FontUpdateTracker] ${args[0]} \t ${aimStr}`) worksWithText(args[0], "Text") - if (strMap.size != 0) { - let repStr = strMap.get(aimStr.substring(1, aimStr.length - 1)) + if (strReplaceMap.size != 0) { + const repStr = strReplaceMap.get(aimStr.substring(1, aimStr.length - 1)) if (repStr != undefined) { args[1] = allocUStr(repStr) LOGH(` \n\t {REP} ${aimStr} ---> ${repStr}`) @@ -229,12 +228,12 @@ const B_Text = (): void => { function HookPrint() { A(find_method('Assembly-CSharp', 'NGUIText', 'Print', 4), (args) => { - let aimStr = "|" + readU16(args[0]) + "|" + const aimStr = "|" + readU16(args[0]) + "|" if (filterDuplicateOBJ(aimStr) == -1) return LOGD(`\n[NGUIText] ${args[0]} \t ${aimStr}`) worksWithText(args[0], "Text", true) - if (strMap.size != 0) { - let repStr = strMap.get(aimStr.substring(1, aimStr.length - 1)) + if (strReplaceMap.size != 0) { + let repStr = strReplaceMap.get(aimStr.substring(1, aimStr.length - 1)) if (repStr != undefined) { args[0] = allocUStr(repStr) LOGH(` \n\t {REP} ${aimStr} ---> ${repStr}`) @@ -261,8 +260,8 @@ const B_Text = (): void => { } function worksWithText(textPtr: NativePointer, typeStr: string, printHex: boolean = false) { - if (mapRecord.get(typeStr) == null) { - mapRecord.set(typeStr, 1) + if (strRecordMap.get(typeStr) == null) { + strRecordMap.set(typeStr, 1) getTypeParent(textPtr) } if (printHex) { diff --git a/Il2cppHook/agent/utils/common.ts b/Il2cppHook/agent/utils/common.ts index 04d6ea6e..834d6582 100644 --- a/Il2cppHook/agent/utils/common.ts +++ b/Il2cppHook/agent/utils/common.ts @@ -70,7 +70,7 @@ var cancelAllNopedFunction = () => arr_nop_addr.forEach((addr) => Interceptor.re //detach ---> A(mPtr) const detachAll = (mPtr?: ARGM) => { - let map_attach_listener = GET_MAP(MapKAY.map_attach_listener) + const map_attach_listener = GET_MAP(MapKAY.map_attach_listener) if (typeof mPtr == "number") mPtr = ptr(mPtr) if (mPtr == undefined) { map_attach_listener.clear() @@ -332,17 +332,24 @@ export const TIME_SIMPLE = (): string => new Date().toLocaleTimeString().split(" /** * 大于最大出现次数返回值为 -1 * 主要是为了过滤比如setActive中重复出现的一直频繁调用的obj - * @param {String} objstr 重复出现的str + * @param {String | string} objstr 重复出现的str * @param {int} maxCount 最大出现次数 * @returns ? -1 */ -const filterDuplicateOBJ = (objstr: string, maxCount: number = 10) => { - if (!GET_MAP(MapKAY.outFilterMap).has(objstr)) { - SET_MAP_VALUE(MapKAY.outFilterMap, objstr, 0) +const debug = false +const filterDuplicateOBJ = (objstr: string | String, maxCount: number = 10) => { + if (debug) LOGW(`Enter filterDuplicateOBJ 1 ${objstr} ${maxCount}`) + const localObjStr : string = objstr + '' + if (debug) LOGW(`Enter filterDuplicateOBJ 2 ${localObjStr}`) + if (GET_MAP(MapKAY.outFilterMap) == undefined || !GET_MAP(MapKAY.outFilterMap)!.has(localObjStr)) { + SET_MAP_VALUE(MapKAY.outFilterMap, localObjStr, 0) + if (debug) LOGW(`3`) return 0 } - let count = Number(GET_MAP_VALUE(MapKAY.outFilterMap, objstr)) + 1 - SET_MAP_VALUE(MapKAY.outFilterMap, objstr, count) + if (debug) LOGW(`4`) + const count = GET_MAP_VALUE(MapKAY.outFilterMap, localObjStr) + 1 + if (debug) LOGW(`5 -> ${count}`) + SET_MAP_VALUE(MapKAY.outFilterMap, localObjStr, count) return (count >= maxCount) ? -1 : count }