import {il2cppApi} from "../il2cppApi"; import {log, logHHex} from "../../logger"; import { DUMP_SO_PATH, GetMethodInfoFromIndex_Addr, GetTypeInfoFromTypeIndex_Addr, IDA_SCRIPT_PATH, MEMORY_DUMP_SO_PATH, soName, stringLiteralPath } from "../../config"; import {Action_dumpSo, Action_getGameObject, Action_getObject, Action_getStringLiteral} from "./Il2cppHackerAction"; import {Il2cppString} from "./struct/Il2cppString"; import {Il2CppGlobalMetadataHeader} from "../struct/Il2CppGlobalMetadataHeader"; import {Il2cppMetadataRegistration} from "../struct/Il2cppMetadataRegistration"; import {Il2cppHackerApi} from "./Il2cppHackerApi"; import {Il2cppMetadataUsageObj} from "../struct/Il2cppMetadataUsageObj"; import {Il2cppBridgeApi} from "./Il2cppBridgeApi"; import {Tabledefs} from "../tabledefs"; import {Il2CppClass} from "../struct/Il2CppClass"; import {MethodInfo} from "../struct/MethodInfo"; import {Il2CppType} from "../struct/Il2CppType"; import {JsonCreate} from "../JsonCreate"; import {Il2CppFieldInfo} from "../struct/Il2CppFieldInfo"; let il2cpp_got = false; let INIT_SUCCESS = -2; let s_Il2CppMetadataRegistration_addr = 0x82e550; let s_GlobalMetadataHeader = 0x82e568; let s_Il2CppCodeRegistration_addr = 0x82e54c; // let s_Il2CppMetadataRegistration_addr = 0xA02CC0; // let s_GlobalMetadataHeader = 0XA02CF0; // let s_Il2CppCodeRegistration_addr =0XA02CB8; let il2cpp_path; let il2cppHandler; let dumpModule = null; let process; let once=false; export var Il2cppHacker = { getEncodeIndexType(index) { return ((index & 0xE0000000) >> 29); }, createObject: function () { if (!il2cpp_got) { Il2cppHacker.waitInject(Action_getObject); return; } let addr = Module.findBaseAddress(soName); let stringLiteral_2053 = addr.add(0x73f240); logHHex(stringLiteral_2053); log("uint :" + stringLiteral_2053.readU32()); // a01013 let Il2CppMetadataUsage = this.getEncodeIndexType(stringLiteral_2053.readU32()); log("Il2CppMetadataUsage:" + Il2CppMetadataUsage); }, dumpIDAScript: function () { if (s_Il2CppMetadataRegistration_addr == null) { log("you must know the s_Il2CppMetadataRegistration addr"); return; } if (!il2cpp_got) { this.waitInject(Action_getStringLiteral); return; } let addr = Module.findBaseAddress(soName); if (addr == null) { setTimeout(function () { Il2cppHacker.dumpIDAScript(); }, 5000);//该延迟很关键 return; } //直接调用SO // Il2cppBridgeApi.startInject(il2cppHandler); let nativePointer = addr.add(s_GlobalMetadataHeader).readPointer(); let il2CppGlobalMetadataHeader = new Il2CppGlobalMetadataHeader(nativePointer); // log("addr:" + addr + " il2CppGlobalMetadataHeader:" + il2CppGlobalMetadataHeader); // // let nativePointer1 = addr.add(0x7df388); // logHHex(nativePointer1); // let number = il2CppGlobalMetadataHeader.version(); // log("Il2cppVer:" + number); // // 可以使用该版本 let metadata_reg = addr.add(s_Il2CppMetadataRegistration_addr).readPointer(); let il2cppMetadataRegistration = new Il2cppMetadataRegistration(metadata_reg); let codeRegistration = addr.add(s_Il2CppCodeRegistration_addr).readPointer(); this.metadataInit(il2CppGlobalMetadataHeader, il2cppMetadataRegistration, il2cppHandler, codeRegistration); }, createIDAScript: function () { let stringLiteralCount = Il2cppBridgeApi.getStringLiteralCount(); log("stringLiteralCount:" + stringLiteralCount); //输出ScriptString for (let i = 0; i < stringLiteralCount; i++) { let objFromIndex = Il2cppBridgeApi.getStringLiteralObjFromIndex(i); if (!objFromIndex.isNull()) { let stringLiteralString = objFromIndex.stringLiteral_string(); let il2cppConstantOffset = objFromIndex.getIl2cppConstantOffset(); JsonCreate.addStringLiteralToStringLiteralMap(il2cppConstantOffset, stringLiteralString); JsonCreate.addStringLiteralToScript(il2cppConstantOffset, stringLiteralString); } } //输出ScriptMetadata // let il2CppMetadataRegistrationTypeCount = Il2cppBridgeApi.getIl2CppMetadataRegistrationTypeCount(); // log("il2CppMetadataRegistrationTypeCount:" + il2CppMetadataRegistrationTypeCount); // let count = 0; // for (let i = 0; i < il2CppMetadataRegistrationTypeCount; i++) { // let il2CppMetadataTypeInfoFromIndex = Il2cppBridgeApi.getIl2CppMetadataTypeInfoFromIndex(i); // if (!il2CppMetadataTypeInfoFromIndex.isNull()) { // count++; // let il2cppConstantOffset = il2CppMetadataTypeInfoFromIndex.getIl2cppConstantOffset(); // let obj = il2CppMetadataTypeInfoFromIndex.obj(); // let il2CppClass = new Il2CppClass(obj); // let namespaze = il2CppClass.namespaze(); // let name = il2CppClass.getGenericName(); // JsonCreate.addTypeInfoToScript(il2cppConstantOffset, namespaze, name); // } // } // log("typeInfo总数量:" + count); // let cppTypeCount = 0; // for (let i = 0; i < il2CppMetadataRegistrationTypeCount; i++) { // let il2CppTypeInfoFromIndex = Il2cppBridgeApi.getIl2CppTypeInfoFromIndex(i); // if (!il2CppTypeInfoFromIndex.isNull()) { // cppTypeCount++; // let offset = il2CppTypeInfoFromIndex.getIl2cppConstantOffset(); // let obj1 = il2CppTypeInfoFromIndex.obj(); // let il2CppType = new Il2CppType(obj1); // let klass = il2cppApi.il2cpp_class_from_type(il2CppType); // let namespaze1 = klass.namespaze(); // let name1 = klass.name(); // JsonCreate.addCppTypeToScript(offset, namespaze1, name1); // } // } // log("CppType总数量:" + cppTypeCount); // // let fieldRefsCount = Il2cppBridgeApi.getFieldRefsCount(); // let fieldCount = 0; // for (let i = 0; i < fieldRefsCount; i++) { // let fieldInfoObjFromIndex = Il2cppBridgeApi.getFieldInfoObjFromIndex(i); // if (!fieldInfoObjFromIndex.isNull()) { // fieldCount++; // let offset = fieldInfoObjFromIndex.getIl2cppConstantOffset(); // let obj2 = fieldInfoObjFromIndex.obj(); // let il2CppFieldInfo = new Il2CppFieldInfo(obj2); // let filedName = il2CppFieldInfo.getFiledName(); // let parent = il2CppFieldInfo.getParent(); // JsonCreate.addFieldInfoToScript(offset, parent.name(), filedName); // } // } // log("fieldInfo总数量:" + fieldCount); // // //输出ScriptMethod // //泛型实现方法地址 // let genericMethodCount = 0; // let il2cppGenericInstObjCount = Il2cppBridgeApi.getIl2cppGenericInstObjCount(); // for (let i = 0; i < il2cppGenericInstObjCount; i++) { // let genericInstObjFromIndex = Il2cppBridgeApi.getIl2cppGenericInstObjFromIndex(i); // if (!genericInstObjFromIndex.isNull()) { // genericMethodCount++; // JsonCreate.addMethodInfoToScriptMethod(genericInstObjFromIndex.spaze(), // genericInstObjFromIndex.className(), genericInstObjFromIndex.methodName(), genericInstObjFromIndex.addr()); // JsonCreate.addAddressToScriptAddress(genericInstObjFromIndex.addr()); // } // } // log("泛型方法数量:" + genericMethodCount); // let methodTableCount = Il2cppBridgeApi.getMethodTableCount(); // log("C# 方法数量:" + methodTableCount); // for (let i = 0; i < methodTableCount; i++) { // let il2cppMethodObjFromIndex = Il2cppBridgeApi.getIl2cppMethodObjFromIndex(i); // JsonCreate.addMethodInfoToScriptMethod(il2cppMethodObjFromIndex.spaze(), il2cppMethodObjFromIndex.className(), // il2cppMethodObjFromIndex.methodName(), il2cppMethodObjFromIndex.addr()) // JsonCreate.addAddressToScriptAddress(il2cppMethodObjFromIndex.addr()); // } // //输出常量表里的方法 // // let metadataMethodTableCount = Il2cppBridgeApi.getMetadataMethodTableCount(); // for (let i = 0; i < metadataMethodTableCount; i++) { // let metadataMethodObjFromIndex = Il2cppBridgeApi.getMetadataMethodObjFromIndex(i); // if (!metadataMethodObjFromIndex.isNull()) { // let obj3 = metadataMethodObjFromIndex.obj(); // let methodInfo = new MethodInfo(obj3); // if (!methodInfo.isNull()) { // let constantOffset = metadataMethodObjFromIndex.getIl2cppConstantOffset(); // let klass = methodInfo.getClass(); // let class_name = klass.name(); // //获取泛型 // if (class_name.indexOf("`") !== -1) { // let split = class_name.split("`"); // class_name = split[0]; // class_name = class_name + klass.getGenericName(); // } // JsonCreate.addMetadataMethodToScript(constantOffset, klass.namespaze(), class_name, // methodInfo.name(), methodInfo.getMethodPointerOffsetToInt()); // } // // } // // } // log("常量表方法数量:" + metadataMethodTableCount); // // //输出到文件里 // let stringLiteralFile = new File(stringLiteralPath, "wb"); // stringLiteralFile.write(JsonCreate.parserStringLiteralToString()); // stringLiteralFile.flush(); // stringLiteralFile.close(); // // // let IDAScriptPath = new File(IDA_SCRIPT_PATH, "wb"); // IDAScriptPath.write(JsonCreate.parserScriptToString()); // IDAScriptPath.flush(); // IDAScriptPath.close(); // log("out script success , path is " + IDA_SCRIPT_PATH); }, metadataInit: function (il2CppGlobalMetadataHeader, il2cppMetadataRegistration, il2cppHandler, s_Il2CppCodeRegistration_addr) { let module = this.getDumpModule(); // Il2cppBridgeApi.setGetTypeInfoFromTypeIndexAddr(GetTypeInfoFromTypeIndex_Addr); let medatadataInit = new NativeFunction(module.findExportByName("_ZN14MetadataParser4initEPvS0_S0_S0_"), "int", ['pointer', 'pointer', 'pointer', 'pointer']); medatadataInit(il2CppGlobalMetadataHeader, il2cppMetadataRegistration, il2cppHandler, s_Il2CppCodeRegistration_addr); // Il2cppHacker.createIDAScript(); }, getDumpModule: function () { if (dumpModule == null) { dumpModule = Module.load(DUMP_SO_PATH); } return dumpModule; }, dumpSo: function () { log("il2cpp got:" + il2cpp_got); let addr = Module.findBaseAddress(soName); log("addr:" + addr); if (addr == null) { if (il2cpp_got) { setTimeout(function () { Il2cppHacker.dumpSo(); }, 1000); return; } Il2cppHacker.waitInject(Action_dumpSo); return; } if (once){ return; } once=true; setTimeout(function (){ let module = Process.findModuleByName(soName); log("module:"+module.base +" 64:"+module.base.readU64() +" size:"+module.size); let nativePointer = new NativePointer(module.base); console.log(hexdump(nativePointer, { offset: 0, length: 64, header: true, ansi: true })) // Il2cppBridgeApi.start64(module.base.readU64(),module.size); Memory.protect(ptr(module.base), module.size, 'rwx'); let arrayBuffer = nativePointer.readByteArray(module.size); let file = new File(MEMORY_DUMP_SO_PATH, "wb"); send("写入前") file.write(arrayBuffer); file.flush(); file.close(); log("lib地址:" + module.base + " size:" + module.size); log("dump so 结束") },10000); }, getGameObject: function () { if (!il2cpp_got) { Il2cppHacker.waitInject(Action_getGameObject); return; } let addr = Module.findBaseAddress(soName); log("addr:" + addr); if (addr == null) { setTimeout(function () { Il2cppHacker.getGameObject(); }, 1000); return; } log("start getGameObj :" + addr); var objMgr_on_start = new NativeFunction(addr.add(0x6D7AB4), 'void', ['pointer']); Interceptor.replace(addr.add(0x6D7AB4), new NativeCallback(function (self) { objMgr_on_start(self); log(" objMgr on start after call"); //得到赋值 let il2cppString = new Il2cppString(self.add(0x20).readPointer()); //读取指针的地址 let cString = il2cppString.getCString(); log("cString:" + cString); //获取il2cpp // Il2cppHackerApi.getMethodInfo("UnityEngine", "Object", "FindObjectOfType", 0); }, "void", ['pointer'])); }, waitInject: function (action) { let open = Module.findExportByName(null, "open"); log("wait il2cpp"); if (open != null) { Interceptor.attach(open, { onEnter: function (args) { let path = args[0].readCString(); // log("path:" + path); if (path.indexOf(soName) !== -1) { this.hook = true; } }, onLeave: function (retval) { // log("this.hook:" + this.hook); if (this.hook) { log("got il2cpp"); il2cpp_got = true; // Interceptor.detachAll(); Il2cppHacker.jumpAction(action) } }, }) } }, jumpAction: function (action) { switch (action) { case Action_getGameObject: Il2cppHacker.getGameObject(); break; case Action_getStringLiteral: Il2cppHacker.dumpIDAScript(); break; case Action_getObject: Il2cppHacker.createObject(); break case Action_dumpSo: Il2cppHacker.dumpSo(); break } } }