Browse Source

引入frida il2cppDumper

Imy 1 year ago
parent
commit
a3d8eaa7c9
45 changed files with 2620 additions and 2 deletions
  1. 1 1
      agent/HookImpl.js
  2. 5 0
      agent/dumpconfig.js
  3. 410 0
      agent/dumper.js
  4. 132 0
      agent/il2cpp/CSDumper.js
  5. 38 0
      agent/il2cpp/Il2CppTypeEnum.js
  6. 70 0
      agent/il2cpp/JsonCreate.js
  7. 3 0
      agent/il2cpp/hacker/IDAScript.js
  8. 155 0
      agent/il2cpp/hacker/Il2cppBridgeApi.js
  9. 345 0
      agent/il2cpp/hacker/Il2cppHacker.js
  10. 6 0
      agent/il2cpp/hacker/Il2cppHackerAction.js
  11. 140 0
      agent/il2cpp/hacker/Il2cppHackerApi.js
  12. 14 0
      agent/il2cpp/hacker/StructSize.js
  13. 3 0
      agent/il2cpp/hacker/UnityConstans.js
  14. 75 0
      agent/il2cpp/hacker/struct/Il2cppString.js
  15. 321 0
      agent/il2cpp/il2cppApi.js
  16. 93 0
      agent/il2cpp/struct/Il2CppClass.js
  17. 58 0
      agent/il2cpp/struct/Il2CppFieldInfo.js
  18. 10 0
      agent/il2cpp/struct/Il2CppGenericContext.js
  19. 9 0
      agent/il2cpp/struct/Il2CppGenericInst.js
  20. 10 0
      agent/il2cpp/struct/Il2CppGenericMethod.js
  21. 55 0
      agent/il2cpp/struct/Il2CppGlobalMetadataHeader.js
  22. 57 0
      agent/il2cpp/struct/Il2CppImage.js
  23. 12 0
      agent/il2cpp/struct/Il2CppMetadataUsageList.js
  24. 12 0
      agent/il2cpp/struct/Il2CppMetadataUsagePair.js
  25. 19 0
      agent/il2cpp/struct/Il2CppPropertyInfo.js
  26. 25 0
      agent/il2cpp/struct/Il2CppType.js
  27. 20 0
      agent/il2cpp/struct/Il2cppGenericInstObj.js
  28. 22 0
      agent/il2cpp/struct/Il2cppMetadataRegistration.js
  29. 27 0
      agent/il2cpp/struct/Il2cppMetadataUsageObj.js
  30. 7 0
      agent/il2cpp/struct/InvokerMethod.js
  31. 76 0
      agent/il2cpp/struct/MethodInfo.js
  32. 11 0
      agent/il2cpp/struct/NativeStruct.js
  33. 5 0
      agent/il2cpp/struct/ParameterInfo.js
  34. 27 0
      agent/il2cpp/struct/structItem.js
  35. 98 0
      agent/il2cpp/struct/utils.js
  36. 112 0
      agent/il2cpp/tabledefs.js
  37. 5 0
      agent/il2cpp/unityStruct/MonoBehaviour.js
  38. 5 0
      agent/il2cpp/unityStruct/UnityBehaviour.js
  39. 19 0
      agent/il2cpp/unityStruct/UnityCamera.js
  40. 16 0
      agent/il2cpp/unityStruct/UnityComponent.js
  41. 18 0
      agent/il2cpp/unityStruct/UnityObject.js
  42. 26 0
      agent/il2cpp/unityStruct/UnityTransform.js
  43. 18 0
      agent/il2cpp/unityStruct/UnityVector3.js
  44. 4 1
      agent/index.ts
  45. 26 0
      agent/safeSelf.js

+ 1 - 1
agent/HookImpl.js

@@ -29,7 +29,7 @@ export let HookImpl = {
            let metadataReg = module.base.add(0x9AD308).readPointer();
            let codeReg = module.base.add(0x9AD300).readPointer();
 
-           let injectso = Module.load("/data/data/com.DefaultCompany.Demo/files/libil2cppdumper.so");
+           let injectso = Module.load("/data/data/com.DefaultCompany.Demo1/files/libil2cppdumper.so");
            let nativePointer1 = injectso.findExportByName("_ZN12Il2CppDumper5startEPvS0_S0_S0_");
            console.log("my so inject addr "+nativePointer1)
 

+ 5 - 0
agent/dumpconfig.js

@@ -0,0 +1,5 @@
+export const pkg_name = "com.xiangjian.ftxd";
+
+export const soName="libil2cpp.so";
+export const path = "/data/data/" + pkg_name;
+export const DUMP_FILE_PATH = path + "/dump.cs";

+ 410 - 0
agent/dumper.js

@@ -0,0 +1,410 @@
+import {DUMP_FILE_PATH, soName} from "./dumpconfig";
+import {il2cppApi} from "./il2cpp/il2cppApi";
+import {log} from "./logger";
+
+let classAllCount = 0;
+let file = new File(DUMP_FILE_PATH, "wb");
+let il2cpp_got = false;
+let once =false;
+export var dumper = {
+    waitInject: function () {
+        log("waitInject");
+
+        let open = Module.findExportByName(null, "open");
+        //fopen替换
+        log("等待Il2cpp:" + open);
+        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) {
+                        il2cpp_got = true;
+                        // Interceptor.detachAll();
+                        dumper.start();
+                    }
+                }
+            })
+        }
+    },
+    start: function () {
+        let module = Process.findModuleByName(soName);
+        log("module:"+module);
+        if (module == null) {
+            if (il2cpp_got) {
+                setTimeout(function () {
+                    //执行
+                    dumper.start();
+                }, 5000);
+                return;
+            }
+            this.waitInject();
+            return
+        }
+        //延迟一下
+        log("module "+module.path +" addr "+module.base);
+        setTimeout(function (){
+            if (once){
+                return
+            }
+            once=true;
+            module = Process.findModuleByName(soName);
+            let baseAddress = module.base;
+
+            log("base address:" + baseAddress);
+
+
+            let domain = il2cppApi.il2cpp_domain_get();
+            let size_t = Memory.alloc(Process.pointerSize);
+            log("domain:" + domain + " baseAddress:" + baseAddress);
+            //可能还没加载
+
+            let assemblies = il2cppApi.il2cpp_domain_get_assemblies(domain, size_t);
+            let assemblies_count = size_t.readInt();
+            log("assemblies_count:" + assemblies_count + " pointerSize:" + Process.pointerSize
+                + " assemblies:" + assemblies);
+            if (assemblies_count===0){
+                setTimeout(function (){
+                    this.start();
+                },2000);
+                return;
+            }
+            let il2CppImageArray = new Array();
+
+            for (let i = 0; i < assemblies_count; i++) {
+                let assembly = assemblies.add(Process.pointerSize * i).readPointer();
+
+                let Il2CppImage = il2cppApi.il2cpp_assembly_get_image(assembly);
+                let typeStart = Il2CppImage.typeStart();
+                log("typeStart:" + typeStart + " name:" + Il2CppImage.nameNoExt()+" typeCount:"+Il2CppImage.typeCount());
+                dumper.out(" // Image :" + i + " " + Il2CppImage.nameNoExt() + " - " + Il2CppImage.typeStart() + "\n")
+                il2CppImageArray.push(Il2CppImage);
+            }
+            for (let i = 0; i < il2CppImageArray.length; i++) {
+                log("process: " + (i + 1) + "/" + assemblies_count);
+                let Il2CppImage = il2CppImageArray[i];
+                let nameNoExt = Il2CppImage.nameNoExt();
+                let start = Il2CppImage.typeStart();
+                let class_count = Il2CppImage.typeCount();
+                // log("name:"+nameNoExt +" start:"+start +" count:"+class_count)
+                // if (nameNoExt === "Assembly-CSharp") {
+                // // dll
+                // this.out("\n//assembly Image -->:" + nameNoExt + "    startIndex:" + start + "   typeCount:" + class_count);
+                dumper.findAllClass(Il2CppImage);
+                // }
+            }
+            log("dump end")
+            log("classAllCount:" + classAllCount);
+            // log("nativeFunNotExistMap:" + il2cppApi.nativeFunNotExistMap.size);
+            if (il2cppApi.nativeFunNotExistMap.size > 0) {
+                log("some NativeFun is un exist ,parser will be not accurate :");
+                il2cppApi.nativeFunNotExistMap.forEach(function (value, key) {
+                    log(key + "");
+                })
+            }
+            log("module "+module.path +" addr "+module.base);
+
+        },20000);
+
+
+
+    },
+    findAllClass: function (il2cppImage) {
+        let class_count = il2cppImage.typeCount();
+        classAllCount = classAllCount + class_count;
+        log("findAllClass "+il2cppImage.name()+"  class_count:" + class_count)
+        for (let i = 0; i < class_count; i++) {
+            log("class process:"+i +"/"+class_count)
+            let il2CppClass = il2cppImage.getClass(i);
+            let il2CppType = il2CppClass.getType();
+            let declaringType = il2CppClass.getDeclaringType();
+            if (!declaringType.isNull()) {
+                // log("declaringType:" + declaringType.name() + " class:" + il2CppClass.name());
+            }
+            this.dumpType(il2CppType);
+        }
+    },
+    dumpType: function (il2CppType) {
+        let klass = il2cppApi.il2cpp_class_from_type(il2CppType);
+        let il2CppImage = il2cppApi.il2cpp_class_get_image(klass);
+        this.out("\n//Namespace:" + klass.namespaze() + "  Image->" + il2CppImage.name() + "\n")
+        let flags = klass.flags();
+        let Serializable = flags & tabledefs.TYPE_ATTRIBUTE_SERIALIZABLE;
+        if (Serializable) {
+            this.out('[Serializable]\n')
+        }
+        let visibility = flags & tabledefs.TYPE_ATTRIBUTE_VISIBILITY_MASK;
+        switch (visibility) {
+            case tabledefs.TYPE_ATTRIBUTE_PUBLIC:
+            case tabledefs.TYPE_ATTRIBUTE_NESTED_PUBLIC:
+                this.out("public ")
+                break;
+            case tabledefs.TYPE_ATTRIBUTE_NOT_PUBLIC:
+            case tabledefs.TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM:
+            case tabledefs.TYPE_ATTRIBUTE_NESTED_ASSEMBLY:
+                this.out("internal ")
+                break;
+            case tabledefs.TYPE_ATTRIBUTE_NESTED_PRIVATE:
+                this.out("private ")
+                break;
+            case tabledefs.TYPE_ATTRIBUTE_NESTED_FAMILY:
+                this.out("protected ")
+                break;
+            case tabledefs.TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM:
+                this.out("protected internal ")
+                break;
+        }
+        let isValuetype = klass.valueType();
+        let IsEnum = klass.enumType();
+        if (flags & tabledefs.TYPE_ATTRIBUTE_ABSTRACT && flags & tabledefs.TYPE_ATTRIBUTE_SEALED) {
+            this.out("static ")
+        } else if (!(flags & tabledefs.TYPE_ATTRIBUTE_INTERFACE) && flags & tabledefs.TYPE_ATTRIBUTE_ABSTRACT) {
+            this.out("abstract ")
+        } else if (!isValuetype && !IsEnum && flags & tabledefs.TYPE_ATTRIBUTE_SEALED) {
+            this.out("sealed ")
+        }
+        if (flags & tabledefs.TYPE_ATTRIBUTE_INTERFACE) {
+            this.out("interface ")
+        } else if (IsEnum) {
+            this.out("enum ")
+        } else if (isValuetype) {
+            this.out("struct ");
+        } else {
+            this.out("class ");
+        }
+        let name = klass.name();
+        //获取泛型
+        if (name.indexOf("`") !== -1) {
+            let split = name.split("`");
+            name = split[0];
+            name = name + klass.getGenericName();
+        }
+        this.out(name + " ");
+        let klass_parent = klass.parent();
+        //父类
+        let hasParent = false;
+        if (!isValuetype && !IsEnum && !klass_parent.isNull()) {
+            let parent_cls_type = klass_parent.getType();
+            let typeEnum = parent_cls_type.getTypeEnum();
+            if (typeEnum === Il2CppTypeEnum.IL2CPP_TYPE_OBJECT) {
+                //not out
+            } else {
+                hasParent = true;
+                this.out(": " + klass_parent.name());
+            }
+        }
+        //实现接口类
+        let iter = Memory.alloc(Process.pointerSize);
+        let interfaces;
+        while (!(interfaces = klass.getInterfaces(iter)).isNull()) {
+            let interfaces_name = interfaces.name();
+            if (interfaces_name.indexOf("`") !== -1) {
+                let split = interfaces_name.split("`");
+                interfaces_name = split[0];
+                interfaces_name = interfaces_name + interfaces.getGenericName();
+            }
+            if (!hasParent) {
+                this.out(": " + interfaces_name)
+                hasParent = true;
+            } else {
+                this.out(", " + interfaces_name);
+            }
+        }
+        this.out("\n{\n")
+        this.dumpFiled(klass);
+        this.dumpPropertyInfo(klass);
+        this.dumpMethod(klass);
+        this.out("\n}");
+
+    },
+    dumpMethod: function (klass) {
+        let iter = Memory.alloc(Process.pointerSize);
+        let methodInfo;
+        let isFirst = true;
+        let baseAddr = Module.findBaseAddress(soName);
+        while (!(methodInfo = klass.getMethods(iter)).isNull()) {
+            if (isFirst) {
+                this.out("\n\t//methods\n");
+                isFirst = false;
+            }
+
+            let methodPointer = methodInfo.getMethodPointer();
+            let generic = methodInfo.is_generic();
+            let inflated = methodInfo.is_inflated();
+            // log("generic:"+generic +" inflated:"+inflated +"name:"+methodInfo.name());
+            if (!methodPointer.isNull()) {
+                let number = methodPointer - baseAddr;
+                if (number===0x4CC8B94){
+                    let nativePointer = klass.add(16).readPointer();
+                    logHHex(nativePointer);
+                    log("class :"+klass.name()+ "length:"+klass.name().length);
+                }
+                this.out("\t// RVA: 0x" + number.toString(16).toUpperCase());
+                this.out("  VA: 0x");
+                this.out(methodPointer.toString(16).toUpperCase());
+
+            } else {
+                this.out("\t// RVA: 0x  VA: 0x0");
+            }
+            //非必须
+            // log("slot:" + methodInfo.getSlot());
+            // if (methodInfo.getSlot() !== 65535) {
+            //     this.out(" Slot: " + methodInfo.getSlot());
+            // }
+            this.out("\n\t");
+            let methodModifier = utils.get_method_modifier(methodInfo.getFlags());
+            this.out(methodModifier);
+
+            let returnType = methodInfo.getReturnType();
+            let return_cls = il2cppApi.il2cpp_class_from_type(returnType);
+            this.out(return_cls.name() + " " + methodInfo.name() + "(");
+            let paramCount = methodInfo.getParamCount();
+            // log("paramCount:" + paramCount);
+            if (paramCount > 0) {
+                for (let i = 0; i < paramCount; i++) {
+                    let paramType = methodInfo.getParam(i);
+                    let paramCls = il2cppApi.il2cpp_class_from_type(paramType);
+                    let name = paramCls.name();
+                    //获取泛型
+                    if (name.indexOf("`") !== -1) {
+                        let split = name.split("`");
+                        name = split[0];
+                        name = name + paramCls.getGenericName();
+                    }
+                    this.out(name + " " + methodInfo.getParamName(i));
+                    if (i + 1 !== paramCount) {
+                        this.out(", ");
+                    } else {
+                        this.out(") { }\n");
+                    }
+                }
+            } else {
+                this.out("){ }\n");
+            }
+
+        }
+    },
+
+    dumpPropertyInfo: function (klass) {
+        let iter = Memory.alloc(Process.pointerSize);
+        let propertyInfo;
+        let isFirst = true;
+        while (!(propertyInfo = klass.getProperties(iter)).isNull()) {
+            if (isFirst) {
+                this.out("\n\t// Properties\n");
+                isFirst = false;
+            }
+            this.out("\t");
+            //获取getSet
+            // log(" dumpPropertyInfo get:" + propertyInfo.getMethod().isNull());
+            let pro_class;
+            let method = propertyInfo.getMethod();
+            let setMethod = propertyInfo.setMethod();
+            if (method.isNull() && setMethod.isNull()) {
+
+                continue;
+            }
+            if (!method.isNull()) {
+                let methodModifier = utils.get_method_modifier(method.getFlags());
+                // let methodPointer = method.getMethodPointer()
+                // log("methodModifier:" + methodModifier + " methodPointer:" + methodPointer);
+                this.out(methodModifier);
+                pro_class = il2cppApi.il2cpp_class_from_type(method.getReturnType());
+            } else if (!setMethod.isNull()) {
+                let setModifier = utils.get_method_modifier(setMethod.getFlags());
+                this.out(setModifier);
+                pro_class = il2cppApi.il2cpp_class_from_type(setMethod.getReturnType());
+            }
+            // log("pro_class:"+pro_class +"propertyInfo:"+propertyInfo.getName() +" method:"+method +" setMethod:"+setMethod)
+            this.out(pro_class.name() + " " + propertyInfo.getName() + " { ");
+
+            if (!method.isNull()) {
+                this.out("get; ");
+            }
+            if (!setMethod.isNull()) {
+                this.out("set; ");
+            }
+            this.out("}\n");
+        }
+    },
+    dumpFiled: function (klass) {
+        // log("dumpFiled class :" + klass.name())
+        let filedCount = klass.filedCount();
+        // log("fieldCount:" + filedCount);
+        if (filedCount > 0) {
+            let iter = Memory.alloc(Process.pointerSize);
+            let filedInfo;
+            this.out("\t//Fileds\n");
+            while (!(filedInfo = klass.getFieldsInfo(iter)).isNull()) {
+                let flags = filedInfo.getFlags();
+                this.out("\t")
+                let access = flags & tabledefs.FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
+                switch (access) {
+                    case tabledefs.FIELD_ATTRIBUTE_PRIVATE:
+                        this.out("private ")
+                        break;
+                    case tabledefs.FIELD_ATTRIBUTE_PUBLIC:
+                        this.out("public ")
+                        break;
+                    case tabledefs.FIELD_ATTRIBUTE_FAMILY:
+                        this.out("protected ")
+                        break;
+                    case tabledefs.FIELD_ATTRIBUTE_ASSEMBLY:
+                    case tabledefs.FIELD_ATTRIBUTE_FAM_AND_ASSEM:
+                        this.out("internal ")
+                        break;
+                    case tabledefs.FIELD_ATTRIBUTE_FAM_OR_ASSEM:
+                        this.out("protected internal ")
+                        break;
+                }
+                if (flags & tabledefs.FIELD_ATTRIBUTE_LITERAL) {
+                    this.out("const ")
+                } else {
+                    if (flags & tabledefs.FIELD_ATTRIBUTE_STATIC) {
+                        this.out("static ")
+                    }
+                    if (flags & tabledefs.FIELD_ATTRIBUTE_INIT_ONLY) {
+                        this.out("readonly ")
+                    }
+                }
+                let fieldClass = filedInfo.getFiledClass();
+                let name = fieldClass.name(); //参数名
+                let offset = filedInfo.getOffset();//偏移
+                // //如果是泛型变量则进行补充
+                if (name.indexOf("`") !== -1) { //`1 `2 `3 说明是泛型类型 解析泛型变量
+                    let genericName = fieldClass.getGenericName();
+                    let split = name.split("`");
+                    name = split[0];
+                    name = name + genericName;
+                }
+                this.out(name + " " + filedInfo.getFiledName());
+                //获取常量的初始值
+                // let filed_info_cpp_type = filedInfo.getType(); //获取变量参数类型
+                // log("filed_info_cpp_type:" + filed_info_cpp_type.getTypeEnum() + name + " " + filedInfo.getFiledName());
+
+                if (flags & tabledefs.FIELD_ATTRIBUTE_LITERAL) {
+                    // let staticValue = filedInfo.getStaticValue();
+                    // if (staticValue !== null) {
+                    //     this.out(" = " + staticValue + ";\n");
+                    // }
+                    this.out(";\n");
+                } else {
+                    this.out(" ;// 0x" + offset.toString(16).toUpperCase() + "\n");
+                }
+
+            }
+        }
+    },
+
+    out: function (string) {
+        file.write(string);
+        file.flush();
+    }
+}

+ 132 - 0
agent/il2cpp/CSDumper.js

@@ -0,0 +1,132 @@
+import {soName} from "../config";
+import {Il2CppGlobalMetadataHeader} from "./struct/Il2CppGlobalMetadataHeader";
+import {log, log4AndroidE, LogColor, logColor, logHHex, logHHexLength} from "../logger";
+import {Il2cppMetadataRegistration} from "./struct/Il2cppMetadataRegistration";
+import {il2cppApi} from "./il2cppApi";
+import {Tprt} from "../mtp/tprt";
+import {on} from "../../_agent";
+import {strace} from "../mtp/strace";
+import {Il2CppClass} from "./struct/Il2CppClass";
+import {lolm} from "../lolm";
+
+
+
+
+let s_GlobalMetadataHeader=0xc98fec8
+let s_Il2CppMetadataRegistration=0xc98feb0
+let s_Il2CppCodeRegistration=0xc98fea8
+let il2cppHandler;
+let once=false;
+export let CSDumper ={
+    loadApk:function (){
+      loadApk();
+    },
+    init:function (){
+        findIl2cppHandler();
+
+    },
+    start:function (){
+
+        if (once){
+            return
+        }
+        once=true
+        //延迟一下吧
+        setTimeout(function (){
+            let module = Process.findModuleByName(soName);
+            if (module!==null){
+                log("加强版dumper开始工作")
+                log("base:"+module.path);
+                let nativePointer = module.base.add(s_GlobalMetadataHeader);
+                let il2CppGlobalMetadataHeader = new Il2CppGlobalMetadataHeader(nativePointer.readPointer());
+                log("il2CppGlobalMetadataHeader log ")
+
+                logHHexLength(il2CppGlobalMetadataHeader,128)
+
+                let nativePointer1 = module.base.add(s_Il2CppMetadataRegistration);
+                let il2cppMetadataRegistration = new Il2cppMetadataRegistration(nativePointer1.readPointer());
+                let il2CppCodeRegistration = module.base.add(s_Il2CppCodeRegistration).readPointer();
+                let dumperSo = Module.load("/system/lib64/libcodec2_server.so");
+                log("dumperSo "+dumperSo);
+                let nativePointer2 = dumperSo.findExportByName("_ZN8CSDumper5startEPvS0_S0_S0_");
+                let start_fun = new NativeFunction(nativePointer2,"void",['pointer','pointer','pointer','pointer']);
+                log("il2CppGlobalMetadataHeader ");
+                logHHex(il2CppGlobalMetadataHeader);
+                start_fun(il2CppGlobalMetadataHeader,il2cppMetadataRegistration,il2CppCodeRegistration,il2cppHandler);
+
+            }
+        },10000);
+
+    }
+}
+function  findIl2cppHandler (){
+    let dlopen = Module.findExportByName(null,"dlopen");
+    if (dlopen != null) {
+        log("fk dlopen");
+        Interceptor.attach(dlopen, {
+            onEnter: function (args) {
+                let path = args[0].readCString();
+                if (path!=null){
+                    if (path.indexOf(soName) !== -1) {
+                        this.hook = true;
+                    }
+                }
+            },
+            onLeave: function (retval) {
+                if (this.hook) {
+                    // Interceptor.detachAll();
+
+                        let s = retval.toString();
+                        log("got il2cpp Handler:"+s);
+                        il2cppHandler = new NativePointer(s);
+                        loadSO();
+                }
+            }
+        })
+    }
+}
+
+function loadApk(){
+    let module = Module.load("/data/data/com.tencent.lolm/files/libbridge.so");
+
+    // Java.perform(function (){
+    //     log("load apk")
+    //     // Module.load("/system/lib64/libcodec2_server.so");
+    //     // setTimeout(function (){
+    //     //
+    //     // },5000);
+    //
+    // })
+
+}
+function  loadSO(){
+    if (once){
+        return
+    }
+    once=true;
+    let id = Process.id;
+    log(" id "+id);
+    //loadAPK
+
+    // setTimeout(function (){
+    //     let dumperSo = Module.load("/system/lib64/libcodec2_server.so");
+    //     log("dumperSo "+dumperSo);
+    //     // let lolStart = dumperSo.findExportByName("_ZN9LoLHelper5startEPv");
+    //     // let nativeFunction = new NativeFunction(lolStart,'void',['pointer']);
+    //     // nativeFunction(il2cppHandler);
+    //
+    //     // strace.start(soName,0x4c6c8a0,18);
+    //     // let module = Process.findModuleByName(soName);
+    //     // Interceptor.attach(module.base.add(0x4c75730),{
+    //     //     onEnter:function (args){
+    //     //         this.self =args[0].readPointer();
+    //     //     },
+    //     //     onLeave:function (ret){
+    //     //         let il2CppClass = new Il2CppClass(this.self);
+    //     //         log(" onActorReborn  ret call" +il2CppClass.name());
+    //     //     }
+    //     // })
+    // },3000);
+
+
+}

+ 38 - 0
agent/il2cpp/Il2CppTypeEnum.js

@@ -0,0 +1,38 @@
+export var Il2CppTypeEnum = {
+    IL2CPP_TYPE_END :0x00,
+    IL2CPP_TYPE_VOID : 0x01,
+    IL2CPP_TYPE_BOOLEAN : 0x02,
+    IL2CPP_TYPE_CHAR :0x03,
+    IL2CPP_TYPE_I1 : 0x04,
+    IL2CPP_TYPE_U1 : 0x05,
+    IL2CPP_TYPE_I2 : 0x06,
+    IL2CPP_TYPE_U2 : 0x07,
+    IL2CPP_TYPE_I4 : 0x08,
+    IL2CPP_TYPE_U4 : 0x09,
+    IL2CPP_TYPE_I8 : 0x0a,
+    IL2CPP_TYPE_U8 : 0x0b,
+    IL2CPP_TYPE_R4 : 0x0c,
+    IL2CPP_TYPE_R8 : 0x0d,
+    IL2CPP_TYPE_STRING : 0x0e,
+    IL2CPP_TYPE_PTR : 0x0f,
+    IL2CPP_TYPE_BYREF : 0x10,
+    IL2CPP_TYPE_VALUETYPE : 0x11,
+    IL2CPP_TYPE_CLASS : 0x12,
+    IL2CPP_TYPE_VAR : 0x13,
+    IL2CPP_TYPE_ARRAY : 0x14,
+    IL2CPP_TYPE_GENERICINST : 0x15,
+    IL2CPP_TYPE_TYPEDBYREF : 0x16,
+    IL2CPP_TYPE_I : 0x18,
+    IL2CPP_TYPE_U : 0x19,
+    IL2CPP_TYPE_FNPTR : 0x1b,
+    IL2CPP_TYPE_OBJECT : 0x1c,
+    IL2CPP_TYPE_SZARRAY : 0x1d,
+    IL2CPP_TYPE_MVAR : 0x1e,
+    IL2CPP_TYPE_CMOD_REQD : 0x1f,
+    IL2CPP_TYPE_CMOD_OPT : 0x20,
+    IL2CPP_TYPE_INTERNAL : 0x21,
+    IL2CPP_TYPE_MODIFIER : 0x40,
+    IL2CPP_TYPE_SENTINEL : 0x41,
+    IL2CPP_TYPE_PINNED : 0x45,
+    IL2CPP_TYPE_ENUM : 0x55
+};

+ 70 - 0
agent/il2cpp/JsonCreate.js

@@ -0,0 +1,70 @@
+
+let stringLiteral=[];
+let script ={};
+let scriptString=[];
+let scriptMethod=[];
+let scriptMetadata=[]; //typeInfo
+let scriptMetadataMethod=[];
+let addresses=[];
+export var JsonCreate = {
+
+
+    addStringLiteralToStringLiteralMap: function (addr,value) {
+        let string ={};
+        string.Value =value;
+        string.Address ="0x"+addr.toString(16).toUpperCase();
+        stringLiteral.push(string);
+    },
+    parserStringLiteralToString: function (){
+        return JSON.stringify(stringLiteral);
+    },
+    addStringLiteralToScript(addr, stringLiteral) {
+        let string ={};
+        string.Address =parseInt(addr);
+        string.Value =stringLiteral;
+        scriptString.push(string);
+    },
+    parserScriptToString:function (){
+        script.ScriptMethod=scriptMethod;
+        script.ScriptString =scriptString;
+        script.ScriptMetadata=scriptMetadata;
+        script.ScriptMetadataMethod=scriptMetadataMethod;
+        script.Addresses=addresses;
+        return JSON.stringify(script);
+    },
+
+    addTypeInfoToScript(addr, namespaze, name) {
+        let metadata={};
+        metadata.Address=parseInt(addr);
+        metadata.Name =namespaze+"."+name+"_TypeInfo";
+        scriptMetadata.push(metadata);
+    },
+    addCppTypeToScript(addr, namespaze, name) {
+        let metadata={};
+        metadata.Address=parseInt(addr);
+        metadata.Name =namespaze+"."+name+"_var";
+        scriptMetadata.push(metadata);
+    },
+    addFieldInfoToScript(addr, name, filedName) {
+        let metadata={};
+        metadata.Address=parseInt(addr);
+        metadata.Name ="Field$"+name+"."+filedName;
+        scriptMetadata.push(metadata);
+    },
+    addMethodInfoToScriptMethod(spaze,className,methodName,addr) {
+        let method ={};
+        method.Address=parseInt(addr);
+        method.Name =spaze+"."+className+"$$"+methodName;
+        scriptMethod.push(method);
+    },
+    addMetadataMethodToScript(addr,spaze,className,methodName,methodAddr) {
+        let method={};
+        method.Address=parseInt(addr);
+        method.Name="method$"+spaze+"."+className+"."+methodName;
+        method.MethodAddress=parseInt(methodAddr);
+        scriptMetadataMethod.push(method);
+    },
+    addAddressToScriptAddress(addr) {
+        addresses.push(parseInt(addr));
+    }
+}

+ 3 - 0
agent/il2cpp/hacker/IDAScript.js

@@ -0,0 +1,3 @@
+export var IDAScript = {
+
+}

+ 155 - 0
agent/il2cpp/hacker/Il2cppBridgeApi.js

@@ -0,0 +1,155 @@
+
+import {Il2cppHacker} from "./Il2cppHacker";
+import {Il2cppMetadataUsageObj} from "../struct/Il2cppMetadataUsageObj";
+import {Il2cppGenericInstObj} from "../struct/Il2cppGenericInstObj";
+
+
+let nativeFunMap = new Map();
+export var Il2cppBridgeApi = {
+    nativeFunNotExistMap: new Map(),
+
+
+
+
+
+    il2cpp_usage_obj_get_usage(medataUsage){
+        let getusage = this.load("_ZN14MetadataParser26il2cpp_usage_obj_get_usageEP22IL2CppMetadataUsageObj","uint32",['pointer']);
+        return getusage(medataUsage);
+    },
+    il2cpp_usage_obj_get_obj(medataUsage){
+        let il2cpp_usage_obj_get_obj = this.load("_ZN14MetadataParser24il2cpp_usage_obj_get_objEP22IL2CppMetadataUsageObj","pointer",['pointer']);
+        return il2cpp_usage_obj_get_obj(medataUsage);
+    },
+    il2cpp_usage_obj_get_addr(medataUsage){
+        let addr = this.load("_ZN14MetadataParser25il2cpp_usage_obj_get_addrEP22IL2CppMetadataUsageObj","uint64",['pointer']);
+        return addr(medataUsage);
+    },
+    il2cpp_usage_obj_get_metadataUsageIndex(medataUsage){
+        let metadataIndex = this.load("_ZN14MetadataParser39il2cpp_usage_obj_get_metadataUsageIndexEP22IL2CppMetadataUsageObj","uint32",['pointer']);
+        return metadataIndex(medataUsage);
+    },
+    il2cpp_usage_obj_get_stringLiteralIndex(medataUsage){
+        let il2cpp_usage_obj_get_stringLiteralIndex = this.load("_ZN14MetadataParser39il2cpp_usage_obj_get_stringLiteralIndexEP22IL2CppMetadataUsageObj","uint32",['pointer']);
+        return il2cpp_usage_obj_get_stringLiteralIndex(medataUsage);
+    },
+    il2cpp_usage_obj_get_stringLiteral(medataUsage){
+        let il2cpp_usage_obj_get_stringLiteral = this.load("_ZN14MetadataParser34il2cpp_usage_obj_get_stringLiteralEP22IL2CppMetadataUsageObj","pointer",['pointer']);
+        return il2cpp_usage_obj_get_stringLiteral(medataUsage);
+    },
+    getIl2cppConstantOffset(addr){
+        let getIl2cppConstantOffset = this.load("_ZN14MetadataParser23getIl2cppConstantOffsetEm","uint64",['uint64']);
+        return getIl2cppConstantOffset(addr);
+    },
+
+    getStringLiteralCount(){
+        let getStringLiteralCount = this.load("_ZN14MetadataParser21getStringLiteralCountEv","uint",[]);
+        return getStringLiteralCount();
+    },
+    getStringLiteralObjFromIndex(index){
+        let getStringLiteralObjFromIndex = this.load("_ZN14MetadataParser28getStringLiteralObjFromIndexEj","pointer",['uint32']);
+        return new Il2cppMetadataUsageObj(getStringLiteralObjFromIndex(index));
+    },
+    setGetTypeInfoFromTypeIndexAddr(addr){
+        let setGetTypeInfoFromTypeIndexAddr = this.load("_ZN14MetadataParser31setGetTypeInfoFromTypeIndexAddrEm","void",['uint64']);
+        return setGetTypeInfoFromTypeIndexAddr(addr);
+    },
+    getIl2CppMetadataRegistrationTypeCount(){
+        let getIl2CppMetadataRegistrationTypeCount = this.load("_ZN14MetadataParser38getIl2CppMetadataRegistrationTypeCountEv","uint",[]);
+        return getIl2CppMetadataRegistrationTypeCount();
+    },
+    getIl2CppMetadataTypeInfoFromIndex(index){
+        let getIl2CppMetadataTypeInfoFromIndex = this.load("_ZN14MetadataParser34getIl2CppMetadataTypeInfoFromIndexEj","pointer",['uint32']);
+        return new  Il2cppMetadataUsageObj(getIl2CppMetadataTypeInfoFromIndex(index));
+    },
+    getIl2CppTypeInfoFromIndex(index){
+        let getIl2CppTypeInfoFromIndex = this.load("_ZN14MetadataParser26getIl2CppTypeInfoFromIndexEj","pointer",['uint32']);
+        return new  Il2cppMetadataUsageObj(getIl2CppTypeInfoFromIndex(index));
+    },
+    getFieldRefsCount(){
+        let getFieldRefsCount = this.load("_ZN14MetadataParser17getFieldRefsCountEv","uint",[]);
+        return getFieldRefsCount();
+    },
+    getFieldInfoObjFromIndex(index){
+        let getFieldInfoObjFromIndex = this.load("_ZN14MetadataParser24getFieldInfoObjFromIndexEj","pointer",['uint32']);
+        return new  Il2cppMetadataUsageObj(getFieldInfoObjFromIndex(index));
+    },
+    getIl2cppGenericInstObjCount(){
+        let getIl2cppGenericInstObjCount = this.load("_ZN14MetadataParser28getIl2cppGenericInstObjCountEv","int32",[]);
+        return getIl2cppGenericInstObjCount();
+    },
+    getIl2cppGenericInstObjFromIndex(index){
+        let getIl2cppGenericInstObjFromIndex = this.load("_ZN14MetadataParser32getIl2cppGenericInstObjFromIndexEj","pointer",['uint32']);
+        return new  Il2cppGenericInstObj(getIl2cppGenericInstObjFromIndex(index));
+    },
+    il2cpp_genericInst_obj_get_method_addr(obj){
+        let il2cpp_genericInst_obj_get_method_addr = this.load("_ZN18Il2cppBridgeHelper38il2cpp_genericInst_obj_get_method_addrEP20Il2cppGenericInstObj","uint64",['pointer']);
+        return il2cpp_genericInst_obj_get_method_addr(obj);
+    },
+
+    il2cpp_genericInst_obj_get_class_name(obj){
+        let il2cpp_genericInst_obj_get_class_name = this.load("_ZN18Il2cppBridgeHelper37il2cpp_genericInst_obj_get_class_nameEP20Il2cppGenericInstObj","pointer",['pointer']);
+        return il2cpp_genericInst_obj_get_class_name(obj);
+    },
+    il2cpp_genericInst_obj_get_class_spaze(obj){
+        let il2cpp_genericInst_obj_get_class_spaze = this.load("_ZN18Il2cppBridgeHelper38il2cpp_genericInst_obj_get_class_spazeEP20Il2cppGenericInstObj","pointer",['pointer']);
+        return il2cpp_genericInst_obj_get_class_spaze(obj);
+    },
+    il2cpp_genericInst_obj_get_method_name(obj){
+        let il2cpp_genericInst_obj_get_method_name = this.load("_ZN18Il2cppBridgeHelper38il2cpp_genericInst_obj_get_method_nameEP20Il2cppGenericInstObj","pointer",['pointer']);
+        return il2cpp_genericInst_obj_get_method_name(obj);
+    },
+
+    getMethodTableCount(){
+        let getMethodTableCount = this.load("_ZN14MetadataParser19getMethodTableCountEv","int32",[]);
+        return getMethodTableCount();
+    },
+    getIl2cppMethodObjFromIndex(index){
+        let getIl2cppMethodObjFromIndex = this.load("_ZN14MetadataParser27getIl2cppMethodObjFromIndexEj","pointer",['uint32']);
+        return new Il2cppGenericInstObj(getIl2cppMethodObjFromIndex(index));
+    },
+    start64(base, size) {
+        let _ZN8SoDumper7start64Emm = this.load("_ZN8SoDumper7start64Emm","void",["uint64","uint64"]);
+        return _ZN8SoDumper7start64Emm(base,size);
+    },
+    getMetadataMethodTableCount(){
+        let getMetadataMethodTableCount = this.load("_ZN14MetadataParser27getMetadataMethodTableCountEv","int32",[]);
+        return getMetadataMethodTableCount();
+    },
+    getMetadataMethodObjFromIndex(index){
+        let getMetadataMethodObjFromIndex = this.load("_ZN14MetadataParser29getMetadataMethodObjFromIndexEj","pointer",['uint32']);
+        return new Il2cppMetadataUsageObj(getMetadataMethodObjFromIndex(index));
+    },
+    startInject(il2cppHandler) {
+        let _Z6injectPv = this.load("_Z6injectPv","void",['pointer']);
+        return _Z6injectPv(il2cppHandler);
+    },
+    /**
+     * 使用内存缓存加快dump速度
+     * @param exportName
+     * @param reType
+     * @param argTypes
+     * @returns {any}
+     */
+    load: function (exportName, reType, argTypes) {
+        // new NativeFunction(Module.findExportByName(soName, "il2cpp_domain_get"), 'pointer', []);
+        let cacheFun = nativeFunMap.get(exportName);
+        if (cacheFun == null) {
+            let isExist = this.nativeFunNotExistMap.get(exportName);
+            if (isExist === -1) {
+                return undefined;
+            }
+            let nativePointer = Il2cppHacker.getDumpModule().findExportByName(exportName);
+            if (nativePointer == null) {
+                this.nativeFunNotExistMap.set(exportName, -1);
+                return undefined;
+            } else {
+                cacheFun = new NativeFunction(nativePointer, reType, argTypes);
+                nativeFunMap.set(exportName, cacheFun);
+            }
+
+        }
+        return nativeFunMap.get(exportName);
+    },
+
+
+}

+ 345 - 0
agent/il2cpp/hacker/Il2cppHacker.js

@@ -0,0 +1,345 @@
+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
+        }
+    }
+}

+ 6 - 0
agent/il2cpp/hacker/Il2cppHackerAction.js

@@ -0,0 +1,6 @@
+
+
+export  let Action_getGameObject =1;
+export  let Action_getStringLiteral=2;
+export  let Action_getObject=3;
+export  let Action_dumpSo=4;

+ 140 - 0
agent/il2cpp/hacker/Il2cppHackerApi.js

@@ -0,0 +1,140 @@
+import {il2cppApi} from "../il2cppApi";
+import {log, LogColor, logColor} from "../../logger";
+import {soName} from "../../config";
+
+let il2CppImageArray = new Array();
+let il2cppBaseAddr = undefined;
+let needLog =false;
+let methodAddrMap =new Map();
+export var Il2cppHackerApi = {
+
+    getGameObjectName: function (addr) {
+
+
+    },
+
+    getMethodAddr(Il2cppImageName, spaceze, className, methodName, methodCount) {
+        //判断缓存是否有
+        let cache = getCache(Il2cppImageName,spaceze,className,methodName,methodCount);
+        if (cache!==undefined){
+            return cache;
+        }
+        let il2cppImage = this.getTargetCppImage(Il2cppImageName);
+
+        let il2CppClass = il2cppApi.il2cpp_class_from_name(il2cppImage, spaceze, className);
+        // log("il2cppClass:" + il2CppClass.namespaze() + " name:" + il2CppClass.name());
+        let methodInfo = il2cppApi.il2cpp_class_get_method_from_name(il2CppClass, methodName, methodCount);
+        if (il2cppBaseAddr === undefined) {
+            il2cppBaseAddr = Process.findModuleByName(soName);
+        }
+        if (needLog){
+            logColor("-------------------------------------start---------------------------------------------------------", LogColor.RED);
+        }
+        let addr;
+        let  number;
+        let methodPointer;
+        if (!methodInfo.isNull()) {
+             methodPointer = methodInfo.getMethodPointer();
+             number = methodPointer - il2cppBaseAddr.base;
+            addr = "0x" + number.toString(16).toUpperCase();
+            if (spaceze!==""){
+                let key = getKey(Il2cppImageName,spaceze,className,methodName,methodCount);
+                methodAddrMap.set(key,methodPointer);
+            }
+        } else {
+            addr = "0x0";
+            number=0;
+            methodPointer=0;
+        }
+        if (!needLog){
+            return methodPointer;
+        }
+        logColor(" Dll:"+Il2cppImageName,LogColor.C97);
+        logColor(" class:"+spaceze+"."+il2CppClass.name(),LogColor.C97);
+        logColor(" methodPointer offset in IDA:" + addr,LogColor.C97);
+        let methodContent;
+        //返回类型
+        let returnType = methodInfo.getReturnType();
+        let return_cls = il2cppApi.il2cpp_class_from_type(returnType);
+        let name1 = return_cls.name();
+        if (name1.indexOf("`") !== -1) {
+            let split = name1.split("`");
+            name1 = split[0];
+            name1 = name1 + return_cls.getGenericName();
+        }
+        methodContent =   name1 + " " + methodInfo.name() + "(";
+        let paramCount = methodInfo.getParamCount();
+        // log("paramCount:" + paramCount);
+        if (paramCount > 0) {
+            for (let i = 0; i < paramCount; i++) {
+                let paramType = methodInfo.getParam(i);
+                let paramCls = il2cppApi.il2cpp_class_from_type(paramType);
+                let name = paramCls.name();
+                //获取泛型
+                if (name.indexOf("`") !== -1) {
+                    let split = name.split("`");
+                    name = split[0];
+                    name = name + paramCls.getGenericName();
+                }
+                methodContent = methodContent + name + " " + methodInfo.getParamName(i);
+                if (i + 1 !== paramCount) {
+                    methodContent = methodContent + ", ";
+                } else {
+                    methodContent = methodContent + ") { }\n";
+                }
+            }
+        } else {
+            methodContent = methodContent + "){ }\n";
+        }
+        logColor(" "+methodContent,LogColor.C97);
+        logColor("-------------------------------------end----------------------------------------------------------", LogColor.RED);
+        return methodPointer;
+    },
+    getTargetCppImage(name) {
+        let cppImageArray = this.getCppImageArray();
+        if (cppImageArray.length > 0) {
+            for (let i = 0; i < cppImageArray.length; i++) {
+                let Il2CppImage = cppImageArray[i];
+                let nameNoExt = Il2CppImage.name();
+                if (nameNoExt === name) {
+                    return Il2CppImage;
+                }
+            }
+        }
+    },
+    getCppImageArray: function () {
+        if (il2CppImageArray.length !== 0) {
+            return il2CppImageArray;
+        }
+        let domain = il2cppApi.il2cpp_domain_get();
+        let size_t = Memory.alloc(Process.pointerSize);
+        //可能还没加载
+        let assemblies = il2cppApi.il2cpp_domain_get_assemblies(domain, size_t);
+        let assemblies_count = size_t.readInt();
+        log("assemblies_count:" + assemblies_count);
+
+        for (let i = 0; i < assemblies_count; i++) {
+
+            let assembly = assemblies.add(Process.pointerSize * i).readPointer();
+            let Il2CppImage = il2cppApi.il2cpp_assembly_get_image(assembly);
+            // log(" name:" + Il2CppImage.name());
+            il2CppImageArray.push(Il2CppImage);
+        }
+        return il2CppImageArray;
+    }
+}
+function  getCache(Il2cppImageName,spaceze,className,methodName,methodCount){
+
+    let key = getKey(Il2cppImageName,spaceze,className,methodName,methodCount);
+    let newVar = methodAddrMap.get(key);
+    if (newVar===undefined || newVar===null){
+        return  undefined;
+    }else {
+        return newVar;
+    }
+
+}
+
+function  getKey(Il2cppImageName,spaceze,className,methodName,methodCount){
+    return Il2cppImageName + "_" + spaceze + "_" + className + "_" + methodName + "_" + methodCount;
+}

+ 14 - 0
agent/il2cpp/hacker/StructSize.js

@@ -0,0 +1,14 @@
+export let STRUCT_TYPE_IL2CPP_METADATA_USAGE_PAIR = 1;
+export let STRUCT_TYPE_IL2CPP_METADATA_USAGE_LIST = 2;
+export var StructSize = {
+
+
+    sizeOf(struct) {
+        switch (struct) {
+            case STRUCT_TYPE_IL2CPP_METADATA_USAGE_PAIR:
+                return 8;
+            case STRUCT_TYPE_IL2CPP_METADATA_USAGE_LIST:
+                return 8;
+        }
+    }
+}

+ 3 - 0
agent/il2cpp/hacker/UnityConstans.js

@@ -0,0 +1,3 @@
+
+
+

+ 75 - 0
agent/il2cpp/hacker/struct/Il2cppString.js

@@ -0,0 +1,75 @@
+import {NativeStruct} from "../../struct/NativeStruct";
+import {il2cppApi} from "../../il2cppApi";
+
+export class Il2cppString extends NativeStruct {
+
+
+    static parser(systemString){
+        if (systemString.isNull()){
+            return"指针空";
+        }
+        let length = il2cppApi.il2cpp_string_length(systemString);
+        let il2cppStringChars = il2cppApi.il2cpp_string_chars(systemString);
+        let content="";
+        for (let i = 0; i < length; i++) {
+            let offset = i * 2;
+            let s = il2cppStringChars.add(offset).readU16().toString(16);
+            if (s.toString().length === 2) {
+                let s2 = il2cppStringChars.add(offset).readCString();
+                content = content + s2;
+            } else {
+                //转换unicode
+                let unicode = "\\u" + s.toString();
+                let decodeUnicode1 = this.decodeUnicode(unicode);
+                content = content + decodeUnicode1;
+            }
+        }
+        return content;
+    }
+    getCString() {
+        if (this.isNull()){
+            return "指针空";
+        }
+        let length = this.getLength();
+
+        //长度4字节本身偏移16 从20位开始
+        let il2cppStringChars = il2cppApi.il2cpp_string_chars(this);
+        let content="";
+        for (let i = 0; i < length; i++) {
+            let offset = i * 2;
+
+            let s = il2cppStringChars.add(offset).readU16().toString(16);
+            // console.log("il2cppStringChars:" + s);
+            //转unicode
+            if (s.toString().length === 2) {
+                let s2 = il2cppStringChars.add(offset).readCString();
+                // log("s2:"+s2);
+                content = content + s2;
+            } else {
+                //转换unicode
+                let unicode = "\\u" + s.toString();
+                // log("unicode:" + unicode);
+                let decodeUnicode1 = this.decodeUnicode(unicode);
+                content = content + decodeUnicode1;
+                // log("s2:"+this.decodeUnicode(unicode));
+            }
+            // let s1 = String.fromCharCode(unicode);
+
+        }
+        if (content === undefined) {
+            return "";
+        }
+        return content;
+    }
+
+    getLength() {
+        return il2cppApi.il2cpp_string_length(this);
+    }
+
+
+   static  decodeUnicode(str) {
+        let replace = str.replace(/\\/g, "%");
+        return unescape(replace);
+    }
+
+}

+ 321 - 0
agent/il2cpp/il2cppApi.js

@@ -0,0 +1,321 @@
+import {soName} from "../config";
+import {Il2CppImage} from "./struct/Il2CppImage";
+import {Il2CppClass} from "./struct/Il2CppClass";
+import {Il2CppType} from "./struct/Il2CppType";
+import {Il2CppFieldInfo} from "./struct/Il2CppFieldInfo";
+import {Il2CppPropertyInfo} from "./struct/Il2CppPropertyInfo";
+import {MethodInfo} from "./struct/MethodInfo";
+import {log} from "../logger";
+
+
+let nativeFunMap = new Map();
+
+export var il2cppApi = {
+    nativeFunNotExistMap: new Map(),
+    il2cpp_array_new:function (klass,size){
+        let il2cpp_array_new = this.load("il2cpp_array_new",'pointer',['pointer','uint64']);
+        return il2cpp_array_new(klass,size);
+    },
+    il2cpp_array_get_byte_length:function (array){
+        let il2cpp_array_get_byte_length = this.load("il2cpp_array_get_byte_length",'uint32',['pointer']);
+      return il2cpp_array_get_byte_length(array);
+    },
+    il2cpp_domain_get: function () {
+        return this.load("il2cpp_domain_get", 'pointer', []);
+    },
+    il2cpp_thread_attach: function (domain) {
+        return this.load("il2cpp_thread_attach", 'pointer', ['pointer']);
+    },
+    il2cpp_string_length: function (Il2cppString) {
+        let il2cpp_string_length = this.load("il2cpp_string_length", "int", ['pointer']);
+        return il2cpp_string_length(Il2cppString);
+    },
+    il2cpp_string_chars: function (Il2cppString) {
+        let il2cpp_string_chars = this.load("il2cpp_string_chars", "pointer", ['pointer']);
+        return il2cpp_string_chars(Il2cppString);
+    },
+    il2cpp_string_new: function (str) {
+        let il2cpp_string_new = this.load("il2cpp_string_new", "pointer", ['pointer']);
+        return il2cpp_string_new(str);
+    },
+    il2cpp_domain_get_assemblies: function (il2Cppdomain, size_t) {
+        let il2cpp_domain_get_assemblies = this.load("il2cpp_domain_get_assemblies", 'pointer', ['pointer', 'pointer']);
+        return il2cpp_domain_get_assemblies(il2Cppdomain, size_t);
+    },
+    il2cpp_gc_collect_a_little: function () {
+        let il2cpp_gc_collect_a_little = this.load("il2cpp_gc_collect_a_little" +
+            "", 'pointer', ['pointer', 'pointer']);
+        return il2cpp_gc_collect_a_little(il2Cppdomain, size_t);
+    },
+    il2cpp_assembly_get_image: function (il2Cppassembly) {
+        let il2cpp_assembly_get_image = this.load("il2cpp_assembly_get_image", 'pointer', ['pointer']);
+        try {
+            return new Il2CppImage(il2cpp_assembly_get_image(il2Cppassembly));
+        } catch (e) {
+            return new Il2CppImage(il2Cppassembly.readPointer());
+        }
+
+    },
+    il2cpp_image_get_class_count: function (image) {
+        // size_t il2cpp_image_get_class_count(const Il2CppImage * image)
+        let il2cpp_image_get_class_count = this.load("il2cpp_image_get_class_count", "pointer", ['pointer']);
+
+        if (il2cpp_image_get_class_count !== undefined) {
+            return il2cpp_image_get_class_count(image).toUInt32();
+        } else {
+            return image.getOffsetTypeCount();
+        }
+    },
+    il2cpp_image_get_name: function (Il2CppImage) {
+        let il2cpp_image_get_name = this.load("il2cpp_image_get_name", "pointer", ['pointer']);
+        return il2cpp_image_get_name(Il2CppImage);
+    },
+    il2cpp_image_get_class: function (il2CppImage, index) {
+        // // const Il2CppClass* il2cpp_image_get_class(const Il2CppImage * image, size_t index)
+        let il2cpp_image_get_class = this.load("il2cpp_image_get_class", 'pointer', ['pointer', 'int']);
+        let il2cppImageGetClass = il2cpp_image_get_class(il2CppImage, index);
+        return new Il2CppClass(il2cppImageGetClass);
+    },
+    il2cpp_class_get_type: function (il2CppClass) {
+        let il2cpp_class_get_type = this.load("il2cpp_class_get_type", 'pointer', ["pointer"]);
+        return new Il2CppType(il2cpp_class_get_type(il2CppClass));
+    },
+    il2cpp_class_get_element_class: function (cls) {
+        let il2cpp_class_get_element_class = this.load("il2cpp_class_get_element_class", 'pointer', ["pointer"]);
+        return new Il2CppClass(il2cpp_class_get_element_class(cls));
+    },
+    il2cpp_class_get_declaring_type: function (cls) {
+        let il2cpp_class_get_declaring_type = this.load("il2cpp_class_get_declaring_type", 'pointer', ["pointer"]);
+        return new Il2CppClass(il2cpp_class_get_declaring_type(cls));
+    },
+    il2cpp_class_from_type: function (Il2CppType) {
+        let il2cpp_class_from_type = this.load("il2cpp_class_from_type", "pointer", ["pointer"]);
+        if (Il2CppType === null) {
+            return null;
+        }
+        return new Il2CppClass(il2cpp_class_from_type(Il2CppType));
+    },
+    il2cpp_class_get_image: function (klass) {
+        let il2cpp_class_get_image = this.load("il2cpp_class_get_image", "pointer", ["pointer"]);
+        return new Il2CppImage(il2cpp_class_get_image(klass));
+    },
+    il2cpp_class_from_name: function (Il2cppImage, nameSpaze, name) {
+
+        let il2cpp_class_from_name = this.load("il2cpp_class_from_name", "pointer", ["pointer", "pointer", "pointer"]);
+        let nameSpaze_t = Memory.allocUtf8String(nameSpaze);
+        let name_t = Memory.allocUtf8String(name);
+        return new Il2CppClass(il2cpp_class_from_name(Il2cppImage, nameSpaze_t, name_t));
+    },
+    il2cpp_class_enum_basetype: function (Il2CppClass) {
+        let il2cpp_class_enum_basetype = this.load("il2cpp_class_enum_basetype", "pointer", ["pointer"]);
+        return new Il2CppType(il2cpp_class_enum_basetype(Il2CppClass));
+    },
+    il2cpp_class_value_size: function (Il2CppClass, align) {
+        let il2cpp_class_value_size = this.load("il2cpp_class_value_size", "int32", ["pointer", "pointer"]);
+        return il2cpp_class_value_size(Il2CppClass);
+    },
+    il2cpp_class_get_flags: function (Il2CppClass) {
+        let il2cpp_class_get_flags = this.load("il2cpp_class_get_flags", "int", ["pointer"]);
+        return il2cpp_class_get_flags(Il2CppClass);
+    },
+    il2cpp_class_is_valuetype: function (Il2CppClass) {
+        let il2cpp_class_is_valuetype = this.load("il2cpp_class_is_valuetype", "bool", ["pointer"]);
+        return il2cpp_class_is_valuetype(Il2CppClass);
+    },
+    il2cpp_class_is_generic: function (Il2CppClass) {
+        let il2cpp_class_is_generic = this.load("il2cpp_class_is_generic", "bool", ["pointer"]);
+        return il2cpp_class_is_generic(Il2CppClass);
+    },
+    il2cpp_class_is_enum: function (Il2CppClass) {
+        let il2cpp_class_is_enum = this.load("il2cpp_class_is_enum", "bool", ["pointer"]);
+        return il2cpp_class_is_enum(Il2CppClass)
+    },
+    il2cpp_class_get_name: function (Il2CppClass) {
+        let il2cpp_class_get_name = this.load("il2cpp_class_get_name", "pointer", ["pointer"]);
+        return il2cpp_class_get_name(Il2CppClass);
+    },
+    il2cpp_class_get_parent: function (Il2CppClass) {
+        let il2cpp_class_get_parent = this.load("il2cpp_class_get_parent", "pointer", ["pointer"]);
+        return il2cpp_class_get_parent(Il2CppClass);
+    },
+    il2cpp_class_get_interfaces: function (cls, iter) {
+        let il2cpp_class_get_interfaces = this.load("il2cpp_class_get_interfaces", 'pointer', ['pointer', 'pointer']);
+        return new Il2CppClass(il2cpp_class_get_interfaces(cls, iter));
+    },
+    il2cpp_class_get_namespace: function (Il2CppClass) {
+        let il2cpp_class_get_namespace = this.load("il2cpp_class_get_namespace", 'pointer', ['pointer']);
+        return il2cpp_class_get_namespace(Il2CppClass);
+    },
+    il2cpp_class_num_fields: function (Il2CppClass) {
+        let il2cpp_class_num_fields = this.load("il2cpp_class_num_fields", 'size_t', ['pointer']);
+        return il2cpp_class_num_fields(Il2CppClass);
+    },
+    il2cpp_class_get_fields: function (Il2CppClass, iter) {
+        let il2cpp_class_get_fields = this.load("il2cpp_class_get_fields", 'pointer', ['pointer', 'pointer']);
+        return new Il2CppFieldInfo(il2cpp_class_get_fields(Il2CppClass, iter));
+    },
+
+    il2cpp_class_get_properties: function (Il2CppClass, iter) {
+        let il2cpp_class_get_properties = this.load("il2cpp_class_get_properties", 'pointer', ['pointer', 'pointer']);
+        return new Il2CppPropertyInfo(il2cpp_class_get_properties(Il2CppClass, iter));
+    },
+    il2cpp_class_get_methods: function (Il2CppClass, iter) {
+        let il2cpp_class_get_methods = this.load("il2cpp_class_get_methods", 'pointer', ['pointer', 'pointer']);
+        return new MethodInfo(il2cpp_class_get_methods(Il2CppClass, iter));
+    },
+    il2cpp_class_get_method_from_name: function (Il2CppClass, name, argsCount) {
+        let il2cpp_class_get_method_from_name = this.load("il2cpp_class_get_method_from_name", 'pointer', ['pointer', 'pointer', "int"]);
+        let name_t = Memory.allocUtf8String(name);
+        return new MethodInfo(il2cpp_class_get_method_from_name(Il2CppClass, name_t, argsCount));
+    },
+    il2cpp_type_get_type: function (Il2CppType) {
+        let il2cpp_type_get_type = this.load("il2cpp_type_get_type", 'int', ['pointer']);
+        return il2cpp_type_get_type(Il2CppType);
+    },
+    /**
+     * 非必要参数
+     * @param Il2CppType
+     * @returns {number|*}
+     */
+    il2cpp_type_is_byref: function (Il2CppType) {
+        let il2cpp_type_is_byref = this.load("il2cpp_type_is_byref", "bool", ["pointer"]);
+        // log(" il2cpp_type_is_byref:"+il2cpp_type_is_byref);
+        if (il2cpp_type_is_byref !== undefined) {
+            return il2cpp_type_is_byref(Il2CppType);
+        }
+        return Il2CppType.add(4).readS8();
+    },
+    il2cpp_type_get_attrs:function (Il2cppType){
+        let il2cpp_type_get_attrs = this.load("il2cpp_type_get_attrs", "int32", ["pointer"]);
+        return il2cpp_type_get_attrs(Il2cppType);
+    },
+    il2cpp_type_get_object: function (Il2CppType) {
+        let il2cpp_type_get_object = this.load("il2cpp_type_get_object", 'pointer', ['pointer']);
+        return il2cpp_type_get_object(Il2CppType);
+    },
+    il2cpp_type_get_name: function (Il2CppType) {
+        let il2cpp_type_get_name = this.load("il2cpp_type_get_name", 'pointer', ['pointer']);
+        try {
+            return il2cpp_type_get_name(Il2CppType);
+        } catch (e) {
+            return null;
+        }
+    },
+
+    il2cpp_field_static_get_value: function (FieldInfo, value) {
+        let il2cpp_field_static_get_value = this.load("il2cpp_field_static_get_value", 'void', ['pointer', 'pointer']);
+        return il2cpp_field_static_get_value(FieldInfo, value);
+    },
+    il2cpp_field_get_parent: function (FieldInfo) {
+        let il2cpp_field_get_parent = this.load("il2cpp_field_get_parent", 'pointer', ['pointer']);
+        return new Il2CppClass(il2cpp_field_get_parent(FieldInfo));
+    },
+    il2cpp_field_get_flags: function (FieldInfo) {
+        let il2cpp_field_get_flags = this.load("il2cpp_field_get_flags", "int", ['pointer']);
+        return il2cpp_field_get_flags(FieldInfo);
+    },
+    il2cpp_field_get_type: function (FieldInfo) {
+        let il2cpp_field_get_type = this.load("il2cpp_field_get_type", "pointer", ['pointer']);
+        return new Il2CppType(il2cpp_field_get_type(FieldInfo));
+    },
+    il2cpp_field_get_name: function (FieldInfo) {
+        let il2cpp_field_get_name = this.load("il2cpp_field_get_name", "pointer", ['pointer']);
+        return il2cpp_field_get_name(FieldInfo);
+    },
+    il2cpp_field_get_offset: function (FieldInfo) {
+        let il2cpp_field_get_offset = this.load("il2cpp_field_get_offset", "size_t", ['pointer']);
+        return il2cpp_field_get_offset(FieldInfo);
+    },
+
+    il2cpp_property_get_get_method: function (PropertyInfo) {
+        let il2cpp_property_get_get_method = this.load("il2cpp_property_get_get_method", "pointer", ['pointer']);
+        return new MethodInfo(il2cpp_property_get_get_method(PropertyInfo));
+    },
+    il2cpp_property_get_set_method: function (PropertyInfo) {
+        let il2cpp_property_get_set_method = this.load("il2cpp_property_get_set_method", "pointer", ['pointer']);
+        return new MethodInfo(il2cpp_property_get_set_method(PropertyInfo));
+    },
+    il2cpp_property_get_name: function (PropertyInfo) {
+        let il2cpp_property_get_name = this.load("il2cpp_property_get_name", "pointer", ['pointer']);
+        return il2cpp_property_get_name(PropertyInfo);
+    },
+    il2cpp_method_get_flags: function (method, iflags) {
+        let il2cpp_method_get_flags_api = this.load("il2cpp_method_get_flags", "uint32", ['pointer', 'uint32']);
+        return il2cpp_method_get_flags_api(method, iflags);
+    },
+    il2cpp_method_get_name: function (method) {
+        let il2cpp_method_get_name = this.load("il2cpp_method_get_name", "pointer", ['pointer']);
+        return il2cpp_method_get_name(method);
+    },
+    il2cpp_method_get_class: function (method) {
+        let il2cpp_method_get_class = this.load("il2cpp_method_get_class", "pointer", ['pointer']);
+        return il2cpp_method_get_class(method);
+    },
+    il2cpp_method_get_pointer: function (method) {
+        //版本兼容有问题
+        let il2cpp_method_get_pointer = this.load("il2cpp_method_get_pointer", "pointer", ['pointer']);
+        if (il2cpp_method_get_pointer !== undefined) {
+            return il2cpp_method_get_pointer(method);
+        }
+        return method.readPointer();
+    },
+
+    il2cpp_method_get_param_count: function (method) {
+        let il2cpp_method_get_param_count = this.load("il2cpp_method_get_param_count", "uint32", ['pointer']);
+        return il2cpp_method_get_param_count(method);
+    },
+    il2cpp_method_get_return_type: function (method) {
+        let il2cpp_method_get_return_type = this.load("il2cpp_method_get_return_type", "pointer", ['pointer']);
+        return new Il2CppType(il2cpp_method_get_return_type(method));
+    },
+    il2cpp_method_get_param: function (method, index) {
+        let il2cpp_method_get_param = this.load("il2cpp_method_get_param", "pointer", ['pointer', 'uint32']);
+        return new Il2CppType(il2cpp_method_get_param(method, index));
+    },
+    il2cpp_method_is_generic: function (method) {
+        let il2cpp_method_is_generic = this.load("il2cpp_method_is_generic", "bool", ['pointer']);
+        return il2cpp_method_is_generic(method);
+    },
+    il2cpp_array_length(arg) {
+        let il2cpp_array_length = this.load("il2cpp_array_length", "uint32", ['pointer']);
+        return il2cpp_array_length(arg);
+    },
+    il2cpp_method_is_inflated: function (method) {
+        let il2cpp_method_is_inflated = this.load("il2cpp_method_is_inflated", "bool", ['pointer']);
+        return il2cpp_method_is_inflated(method);
+    },
+
+    il2cpp_method_get_param_name: function (method, index) {
+        let il2cpp_method_get_param_name = this.load("il2cpp_method_get_param_name", "pointer", ['pointer', 'uint32']);
+        return il2cpp_method_get_param_name(method, index);
+    },
+    /**
+     * 使用内存缓存加快dump速度
+     * @param exportName
+     * @param reType
+     * @param argTypes
+     * @returns {any}
+     */
+    load: function (exportName, reType, argTypes) {
+        // new NativeFunction(Module.findExportByName(soName, "il2cpp_domain_get"), 'pointer', []);
+        let cacheFun = nativeFunMap.get(exportName);
+        if (cacheFun == null) {
+            let isExist = this.nativeFunNotExistMap.get(exportName);
+            if (isExist === -1) {
+                return undefined;
+            }
+            let nativePointer = Module.findExportByName(soName, exportName);
+            if (nativePointer == null) {
+                this.nativeFunNotExistMap.set(exportName, -1);
+                return undefined;
+            } else {
+                cacheFun = new NativeFunction(nativePointer, reType, argTypes);
+                nativeFunMap.set(exportName, cacheFun);
+            }
+
+        }
+        return nativeFunMap.get(exportName);
+    },
+
+
+}

+ 93 - 0
agent/il2cpp/struct/Il2CppClass.js

@@ -0,0 +1,93 @@
+import {NativeStruct} from "./NativeStruct";
+import {il2cppApi} from "../il2cppApi";
+import {log} from "../../logger";
+
+export class Il2CppClass extends NativeStruct{
+
+    name(){
+        return il2cppApi.il2cpp_class_get_name(this).readCString();
+    }
+    namespaze(){
+        return il2cppApi.il2cpp_class_get_namespace(this).readCString();
+    }
+    flags(){
+        return il2cppApi.il2cpp_class_get_flags(this);
+    }
+
+    valueType(){
+        return il2cppApi.il2cpp_class_is_valuetype(this);
+    }
+    enumType(){
+        return il2cppApi.il2cpp_class_is_enum(this);
+    }
+    isGeneric(){
+        return il2cppApi.il2cpp_class_is_generic(this);
+    }
+    /**
+     * class_type
+     */
+    getType(){
+        return il2cppApi.il2cpp_class_get_type(this);
+    }
+
+    getElementClass(){
+        return il2cppApi.il2cpp_class_get_element_class(this);
+    }
+    getDeclaringType(){
+        return il2cppApi.il2cpp_class_get_declaring_type(this);
+    }
+    filedCount(){
+        return il2cppApi.il2cpp_class_num_fields(this);
+    }
+
+    /**
+     *
+     * @returns {Il2CppType}
+     */
+    getEnumBaseType(){
+        return il2cppApi.il2cpp_class_enum_basetype(this);
+    }
+    getFieldsInfo(iter){
+        return il2cppApi.il2cpp_class_get_fields(this,iter);
+    }
+    getProperties(iter){
+        return il2cppApi.il2cpp_class_get_properties(this,iter);
+    }
+
+    getMethods(iter){
+        return il2cppApi.il2cpp_class_get_methods(this,iter);
+    }
+    /**
+     * 获取泛型参数名
+     * @returns {string}
+     */
+    getGenericName(){
+        let type = this.getType();
+        let name = this.name();
+        if (name.indexOf("`") !== -1) {
+            // log("获取Type:Il2cpp:"+this.name() +" nameSpaze:"+this.namespaze());
+            let il2cppTypeGetName = type.getName();
+            if (il2cppTypeGetName==null){
+                return name;
+            }
+            let split = name.split("`");
+            name = split[0];
+            let indexOf = il2cppTypeGetName.indexOf(name);
+            let s = il2cppTypeGetName.substr(indexOf + name.length, il2cppTypeGetName.length - name.length);
+            let genericT ="\<System.Object\>";
+            // log(" genericT:"+genericT);
+            if (s===genericT){
+                return "\<T\>";
+            }
+            return s ;
+        }
+        return name;
+    }
+    parent(){
+        return new Il2CppClass(il2cppApi.il2cpp_class_get_parent(this));
+    }
+
+    getInterfaces(iter) {
+        return il2cppApi.il2cpp_class_get_interfaces(this,iter);
+    }
+}

+ 58 - 0
agent/il2cpp/struct/Il2CppFieldInfo.js

@@ -0,0 +1,58 @@
+import {NativeStruct} from "./NativeStruct";
+import {il2cppApi} from "../il2cppApi";
+import {utils} from "./utils";
+import {Il2CppClass} from "./Il2CppClass";
+
+export class Il2CppFieldInfo extends NativeStruct {
+
+    getFlags() {
+
+        return il2cppApi.il2cpp_field_get_flags(this);
+    }
+
+    /**
+     * 获取变量参数类型
+     * @returns {Il2CppType}
+     */
+    getType() {
+        return il2cppApi.il2cpp_field_get_type(this);
+    }
+
+    /**
+     * 获取 静态常量
+     * @param value
+     */
+    getStaticValue() {
+        let value = Memory.alloc(Process.pointerSize);
+        il2cppApi.il2cpp_field_static_get_value(this, value);
+        return utils.readTypeEnumValue(value, this.getType().getTypeEnum(), this.getFiledClass())
+    }
+
+    /**
+     *  获取变量class
+     * @returns {Il2CppClass}
+     */
+    getFiledClass() {
+        let type = this.getType();
+        return il2cppApi.il2cpp_class_from_type(type);
+    }
+    getParent(){
+        let il2CppClass = il2cppApi.il2cpp_field_get_parent(this);
+        return new Il2CppClass(il2CppClass);
+    }
+    /**
+     * 获取变量参数的命名
+     * @returns {string}
+     */
+    getFiledName() {
+        return il2cppApi.il2cpp_field_get_name(this).readCString();
+    }
+
+    /**
+     * 获取偏移
+     * @returns {*}
+     */
+    getOffset() {
+        return il2cppApi.il2cpp_field_get_offset(this);
+    }
+}

+ 10 - 0
agent/il2cpp/struct/Il2CppGenericContext.js

@@ -0,0 +1,10 @@
+import {NativeStruct} from "./NativeStruct";
+import {Il2CppGenericInst} from "./Il2CppGenericInst";
+
+export class Il2CppGenericContext extends NativeStruct{
+
+
+    method_inst(){
+        return new Il2CppGenericInst(this.add(0x8));
+    }
+}

+ 9 - 0
agent/il2cpp/struct/Il2CppGenericInst.js

@@ -0,0 +1,9 @@
+import {NativeStruct} from "./NativeStruct";
+
+export class Il2CppGenericInst extends NativeStruct{
+
+
+    type_argc(){
+        return this.readU32();
+    }
+}

+ 10 - 0
agent/il2cpp/struct/Il2CppGenericMethod.js

@@ -0,0 +1,10 @@
+import {NativeStruct} from "./NativeStruct";
+import {Il2CppGenericContext} from "./Il2CppGenericContext";
+
+export class Il2CppGenericMethod extends NativeStruct{
+
+
+    context(){
+        return new Il2CppGenericContext(this.add(0x8));
+    }
+}

+ 55 - 0
agent/il2cpp/struct/Il2CppGlobalMetadataHeader.js

@@ -0,0 +1,55 @@
+import {NativeStruct} from "./NativeStruct";
+import {log, logHHex} from "../../logger";
+import {
+    STRUCT_TYPE_IL2CPP_METADATA_USAGE_LIST,
+    STRUCT_TYPE_IL2CPP_METADATA_USAGE_PAIR,
+    StructSize
+} from "../hacker/StructSize";
+import {Il2CppMetadataUsageList} from "./Il2CppMetadataUsageList";
+import {Il2CppMetadataUsagePair} from "./Il2CppMetadataUsagePair";
+import {Tabledefs} from "../tabledefs";
+
+export class Il2CppGlobalMetadataHeader extends NativeStruct {
+
+
+    sanity() {
+        return this.readU32().toString(16).toUpperCase();
+    }
+
+    version() {
+        return this.add(0x4).readU32();
+    }
+
+    metadataUsagePairsCount() {
+        return this.add(0xcc).readU32();
+    }
+
+
+    metadataUsagePairsOffset() {
+        return this.add(0xc8).readU32();
+    }
+
+    metadataUsageListsOffset() {
+        return this.add(0xc0).readU32();
+    }
+
+    exportedTypeDefinitionsOffset(){
+        return this.add(256).readU32();
+    }
+     exportedTypeDefinitionsCount(){
+        return this.add(260).readU32();
+     }
+    metadataOffset(globalMetadata, returnStructSize, sectionOffset, itemIndex) {
+
+        // log("globalMetadata:" + globalMetadata + " size:" + returnStructSize + " offset:" + sectionOffset + " itemIndex:" + itemIndex);
+        let number = returnStructSize * itemIndex;
+        return globalMetadata.add(number).add(sectionOffset);
+    }
+
+    getEncodeIndexType(index){
+        return ((index & 0xE0000000) >> 29);
+    }
+    getDecodedMethodIndex(index){
+        return  index & 0x1FFFFFFF;
+    }
+}

+ 57 - 0
agent/il2cpp/struct/Il2CppImage.js

@@ -0,0 +1,57 @@
+import {NativeStruct} from "./NativeStruct";
+import {il2cppApi} from "../il2cppApi";
+import {getStructOffset, StructItem} from "./structItem";
+import {FromTypeDefinition_Addr, soName, UNITY_VER, UnityVer} from "../../config";
+import {Il2CppClass} from "./Il2CppClass";
+import {log} from "../../logger";
+
+let il2CppImage_struct = new Array();
+il2CppImage_struct.push(new StructItem("name", Process.pointerSize));
+il2CppImage_struct.push(new StructItem("nameNoExt", Process.pointerSize));
+
+    il2CppImage_struct.push(new StructItem("assemblyIndex", Process.pointerSize));
+
+il2CppImage_struct.push(new StructItem("typeStart", 4));
+il2CppImage_struct.push(new StructItem("typeCount", 4));
+il2CppImage_struct.push(new StructItem("exportedTypeStart", 4));
+
+export class Il2CppImage extends NativeStruct {
+
+
+    name() {
+        return il2cppApi.il2cpp_image_get_name(this).readCString();
+    }
+
+    nameNoExt() {
+        let name1 = this.name();
+        return name1.replace(".dll", "");
+    }
+
+    typeStart() {
+        return this.get("typeStart").readPointer().toInt32();
+    }
+
+    typeCount() {
+       return il2cppApi.il2cpp_image_get_class_count(this);
+      // return  this.getOffsetTypeCount();
+    }
+    getOffsetTypeCount(){
+
+        if (UNITY_VER===UnityVer.V_2020){
+            return this.add(24).readPointer().toInt32();
+        }else {
+            return this.get("typeCount").readPointer().toInt32();
+        }
+
+    }
+
+    getClass(index) {
+
+        return il2cppApi.il2cpp_image_get_class(this, index);
+
+    }
+
+    get(params) {
+        return this.add(getStructOffset(il2CppImage_struct, params));
+    }
+}

+ 12 - 0
agent/il2cpp/struct/Il2CppMetadataUsageList.js

@@ -0,0 +1,12 @@
+import {NativeStruct} from "./NativeStruct";
+
+export class Il2CppMetadataUsageList extends NativeStruct{
+
+
+    start(){
+        return this.readU32();
+    }
+    count(){
+        return this.add(0x4).readU32();
+    }
+}

+ 12 - 0
agent/il2cpp/struct/Il2CppMetadataUsagePair.js

@@ -0,0 +1,12 @@
+import {NativeStruct} from "./NativeStruct";
+
+export class Il2CppMetadataUsagePair extends NativeStruct{
+
+    destinationIndex(){
+        return this.readU32();
+    }
+
+    encodedSourceIndex(){
+        return this.add(0x4).readU32();
+    }
+}

+ 19 - 0
agent/il2cpp/struct/Il2CppPropertyInfo.js

@@ -0,0 +1,19 @@
+import {NativeStruct} from "./NativeStruct";
+import {il2cppApi} from "../il2cppApi";
+
+export class Il2CppPropertyInfo extends NativeStruct{
+
+    /**
+     * 获取方法信息
+     * @returns {MethodInfo}
+     */
+    getMethod(){
+        return il2cppApi.il2cpp_property_get_get_method(this);
+    }
+    setMethod(){
+        return il2cppApi.il2cpp_property_get_set_method(this);
+    }
+    getName(){
+        return il2cppApi.il2cpp_property_get_name(this).readCString();
+    }
+}

+ 25 - 0
agent/il2cpp/struct/Il2CppType.js

@@ -0,0 +1,25 @@
+import {NativeStruct} from "./NativeStruct";
+import {il2cppApi} from "../il2cppApi";
+import {log} from "../../logger";
+
+export class Il2CppType extends NativeStruct{
+
+    getName(){
+        let il2cppTypeGetName = il2cppApi.il2cpp_type_get_name(this);
+        if (il2cppTypeGetName==null){
+            return null;
+        }else {
+            return il2cppTypeGetName.readCString();
+        }
+
+    }
+
+    getTypeEnum(){
+        return il2cppApi.il2cpp_type_get_type(this);
+    }
+    byref(){
+        let il2cppTypeIsByref = il2cppApi.il2cpp_type_is_byref(this);
+        log(" il2cppTypeIsByref:"+il2cppTypeIsByref)
+        return il2cppTypeIsByref;
+    }
+}

+ 20 - 0
agent/il2cpp/struct/Il2cppGenericInstObj.js

@@ -0,0 +1,20 @@
+import {NativeStruct} from "./NativeStruct";
+import {Il2cppBridgeApi} from "../hacker/Il2cppBridgeApi";
+
+export class Il2cppGenericInstObj extends NativeStruct{
+
+
+    addr(){
+       return  Il2cppBridgeApi.il2cpp_genericInst_obj_get_method_addr(this);
+    }
+
+    className(){
+        return Il2cppBridgeApi.il2cpp_genericInst_obj_get_class_name(this).readCString();
+    }
+    spaze(){
+        return Il2cppBridgeApi.il2cpp_genericInst_obj_get_class_spaze(this).readCString();
+    }
+    methodName(){
+        return Il2cppBridgeApi.il2cpp_genericInst_obj_get_method_name(this).readCString();
+    }
+}

+ 22 - 0
agent/il2cpp/struct/Il2cppMetadataRegistration.js

@@ -0,0 +1,22 @@
+import {NativeStruct} from "./NativeStruct";
+import {UNITY_VER, UnityVer} from "../../config";
+
+export class Il2cppMetadataRegistration extends NativeStruct{
+
+   metadataUsagesCount() {
+        return this.add(112).readU32();
+    }
+
+    genericInstsCount(){
+       return this.add(0x10).readU32();
+    }
+    genericMethodTableCount(){
+        return this.add(0x20).readU32();
+    }
+    metadataUsagesCount(){
+       return this.add(0x70).readU32();
+    }
+    metadataUsages(){
+        return this.add(0x78).readPointer();
+    }
+}

+ 27 - 0
agent/il2cpp/struct/Il2cppMetadataUsageObj.js

@@ -0,0 +1,27 @@
+import {NativeStruct} from "./NativeStruct";
+import {Il2cppBridgeApi} from "../hacker/Il2cppBridgeApi";
+
+export class Il2cppMetadataUsageObj extends NativeStruct{
+
+    obj(){
+        return Il2cppBridgeApi.il2cpp_usage_obj_get_obj(this);
+    }
+    metadataUsageIndex(){
+        return Il2cppBridgeApi.il2cpp_usage_obj_get_metadataUsageIndex(this);
+    }
+    usage(){
+       return  Il2cppBridgeApi.il2cpp_usage_obj_get_usage(this);
+    }
+    addr(){
+        return Il2cppBridgeApi.il2cpp_usage_obj_get_addr(this);
+    }
+    stringLiteralIndex(){
+        return Il2cppBridgeApi.il2cpp_usage_obj_get_stringLiteralIndex(this);
+    }
+    stringLiteral_string(){
+        return Il2cppBridgeApi.il2cpp_usage_obj_get_stringLiteral(this).readCString();
+    }
+    getIl2cppConstantOffset(){
+        return Il2cppBridgeApi.getIl2cppConstantOffset(this.addr());
+    }
+}

+ 7 - 0
agent/il2cpp/struct/InvokerMethod.js

@@ -0,0 +1,7 @@
+import {NativeStruct} from "./NativeStruct";
+
+export class InvokerMethod extends NativeStruct{
+
+
+
+}

+ 76 - 0
agent/il2cpp/struct/MethodInfo.js

@@ -0,0 +1,76 @@
+import {NativeStruct} from "./NativeStruct";
+import {il2cppApi} from "../il2cppApi";
+import {log} from "../../logger";
+import {soName} from "../../config";
+import {Il2CppClass} from "./Il2CppClass";
+import {Il2CppGenericMethod} from "./Il2CppGenericMethod";
+
+
+const METHOD_INFO_OFFSET_SLOT=76;
+export class MethodInfo extends NativeStruct{
+
+    getGenericMethod(){
+            return new Il2CppGenericMethod(this.add(0x38));
+    }
+    getFlags(){
+        return il2cppApi.il2cpp_method_get_flags(this,0);
+    }
+
+    getMethodPointer(){
+        return il2cppApi.il2cpp_method_get_pointer(this);
+    }
+    getMethodPointerOffsetToInt(){
+        let methodPointer = this.getMethodPointer();
+        // log("methodPointer:"+methodPointer);
+        if (methodPointer.isNull()){
+            return 0;
+        }
+        let baseAddr = Module.findBaseAddress(soName);
+        return  methodPointer - baseAddr;
+    }
+    getMethodPointerOffset(){
+        let methodPointer = this.getMethodPointer();
+        log("methodPointer:"+methodPointer);
+        if (methodPointer.isNull()){
+            return "0x0";
+        }
+        let baseAddr = Module.findBaseAddress(soName);
+        let number = methodPointer-baseAddr;
+        return number.toString(16).toUpperCase();
+    }
+    getSlot(){
+        return this.add(METHOD_INFO_OFFSET_SLOT).readU16();
+    }
+    name(){
+        return il2cppApi.il2cpp_method_get_name(this).readCString();
+    }
+    getParamCount(){
+        return il2cppApi.il2cpp_method_get_param_count(this);
+    }
+    getParam(index){
+        return il2cppApi.il2cpp_method_get_param(this,index);
+    }
+    getParamName(index){
+        return il2cppApi.il2cpp_method_get_param_name(this,index).readCString();
+    }
+    /**
+     * 获取返回类型
+     * @returns {Il2CppType}
+     */
+    getReturnType(){
+        return il2cppApi.il2cpp_method_get_return_type(this);
+    }
+    is_generic(){
+        return il2cppApi.il2cpp_method_is_generic(this);
+    }
+    is_inflated(){
+        return il2cppApi.il2cpp_method_is_inflated(this);
+    }
+    getClass(){
+        return new Il2CppClass(il2cppApi.il2cpp_method_get_class(this));
+    }
+
+    invoker_method() {
+        return this.add(0x8).readPointer();
+    }
+}

+ 11 - 0
agent/il2cpp/struct/NativeStruct.js

@@ -0,0 +1,11 @@
+
+
+export class NativeStruct extends NativePointer{
+
+    constructor(pointer) {
+        super(pointer);
+    }
+
+
+
+}

+ 5 - 0
agent/il2cpp/struct/ParameterInfo.js

@@ -0,0 +1,5 @@
+import {NativeStruct} from "./NativeStruct";
+
+export class ParameterInfo extends NativeStruct{
+
+}

+ 27 - 0
agent/il2cpp/struct/structItem.js

@@ -0,0 +1,27 @@
+
+
+export function StructItem(param, size) { //声明对象{
+    this.param = param;
+    this.size = size;
+}
+
+
+
+export function getStructOffset(struct, name) {
+    let all = 0;
+    for (let i = 0; i < struct.length; i++) {
+        let item = struct[i];
+        let param = item.param;
+        let size = item.size;
+        if (param === name) {
+            if (i === 0) {
+                return 0;
+            } else {
+                return all;
+            }
+        } else {
+            all = all + size;
+        }
+
+    }
+}

+ 98 - 0
agent/il2cpp/struct/utils.js

@@ -0,0 +1,98 @@
+import {Il2CppTypeEnum} from "../Il2CppTypeEnum";
+import {log} from "../../logger";
+import {Tabledefs as tabledefs} from "../tabledefs";
+
+
+export var utils = {
+
+    readTypeEnumValue: function (pointer, typeEnum, fieldClass) {
+        switch (typeEnum) {
+            case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
+                return !!pointer.readS8();
+            case Il2CppTypeEnum.IL2CPP_TYPE_I1:
+                return pointer.readS8();
+            case Il2CppTypeEnum.IL2CPP_TYPE_I2:
+                return pointer.readS16();
+            case Il2CppTypeEnum.IL2CPP_TYPE_U2:
+                return pointer.readU16();
+            case Il2CppTypeEnum.IL2CPP_TYPE_I4:
+                return pointer.readS32();
+            case Il2CppTypeEnum.IL2CPP_TYPE_U4:
+                return pointer.readU32();
+            case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
+                return pointer.readU16();
+            case Il2CppTypeEnum.IL2CPP_TYPE_I8:
+                return pointer.readS64();
+            case Il2CppTypeEnum.IL2CPP_TYPE_U8:
+                return pointer.readU64();
+            case Il2CppTypeEnum.IL2CPP_TYPE_R4:
+                return pointer.readFloat();
+            case Il2CppTypeEnum.IL2CPP_TYPE_R8:
+                return pointer.readDouble();
+            case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
+                let enumBaseType = fieldClass.getEnumBaseType();
+                // log("baseType:"+enumBaseType.getTypeEnum()+"pointer:"+pointer.readS32());
+                if (enumBaseType.getTypeEnum() === Il2CppTypeEnum.IL2CPP_TYPE_I4) {
+                    return pointer.readS32();
+                }
+                return null;
+            default:
+                return null;
+
+        }
+    }
+    ,
+    get_method_static:function (flags){
+        if (flags & tabledefs.METHOD_ATTRIBUTE_STATIC){
+            return true;
+        }else {
+            return false;
+        }
+    },
+    get_method_modifier: function (flags) {
+        let content;
+        let access = flags & tabledefs.METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK;
+        switch (access) {
+            case tabledefs.METHOD_ATTRIBUTE_PRIVATE:
+                content = "private ";
+                break;
+            case tabledefs.METHOD_ATTRIBUTE_PUBLIC:
+                content = "public ";
+                break;
+            case tabledefs.METHOD_ATTRIBUTE_FAMILY:
+                content = "protected ";
+                break;
+            case tabledefs.METHOD_ATTRIBUTE_ASSEM:
+            case tabledefs.METHOD_ATTRIBUTE_FAM_AND_ASSEM:
+                content = "internal ";
+                break;
+            case tabledefs.METHOD_ATTRIBUTE_FAM_OR_ASSEM:
+                content = "protected internal ";
+                break;
+        }
+        if (flags & tabledefs.METHOD_ATTRIBUTE_STATIC) {
+            content = content + "static ";
+        }
+        if (flags & tabledefs.METHOD_ATTRIBUTE_ABSTRACT) {
+            content = content+ "abstract ";
+            if ((flags & tabledefs.METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK) === tabledefs.METHOD_ATTRIBUTE_REUSE_SLOT) {
+                content = content+ "override ";
+            }
+        } else if (flags & tabledefs.METHOD_ATTRIBUTE_FINAL) {
+            if ((flags & tabledefs.METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK) === tabledefs.METHOD_ATTRIBUTE_REUSE_SLOT) {
+                content = content+  "sealed override ";
+            }
+        } else if (flags & tabledefs.METHOD_ATTRIBUTE_VIRTUAL) {
+            if ((flags & tabledefs.METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK) === tabledefs.METHOD_ATTRIBUTE_NEW_SLOT) {
+                content = content+ "virtual ";
+            } else {
+                content = content+  "override ";
+            }
+        }
+        if (flags & tabledefs.METHOD_ATTRIBUTE_PINVOKE_IMPL) {
+            content = content+ "extern ";
+        }
+        return content;
+    }
+
+}

+ 112 - 0
agent/il2cpp/tabledefs.js

@@ -0,0 +1,112 @@
+//---tabledefs
+export var Tabledefs = {
+    TYPE_ATTRIBUTE_SERIALIZABLE: 0x00002000,
+    TYPE_ATTRIBUTE_VISIBILITY_MASK: 0x00000007,
+    TYPE_ATTRIBUTE_NOT_PUBLIC: 0x00000000,
+    TYPE_ATTRIBUTE_PUBLIC: 0x00000001,
+    TYPE_ATTRIBUTE_NESTED_PUBLIC: 0x00000002,
+    TYPE_ATTRIBUTE_NESTED_PRIVATE: 0x00000003,
+    TYPE_ATTRIBUTE_NESTED_FAMILY: 0x00000004,
+    TYPE_ATTRIBUTE_NESTED_ASSEMBLY: 0x00000005,
+    TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM: 0x00000006,
+    TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM: 0x00000007,
+
+
+    TYPE_ATTRIBUTE_ABSTRACT: 0x00000080,
+    TYPE_ATTRIBUTE_SEALED: 0x00000100,
+    TYPE_ATTRIBUTE_SPECIAL_NAME: 0x00000400,
+
+
+    TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK: 0x00000020,
+    TYPE_ATTRIBUTE_CLASS: 0x00000000,
+    TYPE_ATTRIBUTE_INTERFACE: 0x00000020,
+
+
+    FIELD_ATTRIBUTE_FIELD_ACCESS_MASK: 0x0007,
+    FIELD_ATTRIBUTE_COMPILER_CONTROLLED: 0x0000,
+    FIELD_ATTRIBUTE_PRIVATE: 0x0001,
+    FIELD_ATTRIBUTE_FAM_AND_ASSEM: 0x0002,
+    FIELD_ATTRIBUTE_ASSEMBLY: 0x0003,
+    FIELD_ATTRIBUTE_FAMILY: 0x0004,
+    FIELD_ATTRIBUTE_FAM_OR_ASSEM: 0x0005,
+    FIELD_ATTRIBUTE_PUBLIC: 0x0006,
+
+    FIELD_ATTRIBUTE_STATIC: 0x0010,
+    FIELD_ATTRIBUTE_INIT_ONLY: 0x0020,
+    FIELD_ATTRIBUTE_LITERAL: 0x0040,
+    FIELD_ATTRIBUTE_NOT_SERIALIZED: 0x0080,
+    FIELD_ATTRIBUTE_SPECIAL_NAME: 0x0200,
+    FIELD_ATTRIBUTE_PINVOKE_IMPL: 0x2000,
+
+    /* For runtime use only */
+    FIELD_ATTRIBUTE_RESERVED_MASK: 0x9500,
+    FIELD_ATTRIBUTE_RT_SPECIAL_NAME: 0x0400,
+    FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL: 0x1000,
+    FIELD_ATTRIBUTE_HAS_DEFAULT: 0x8000,
+    FIELD_ATTRIBUTE_HAS_FIELD_RVA: 0x0100,
+
+
+    /*
+    * Method Attributes (22.1.9)
+    */
+
+    METHOD_IMPL_ATTRIBUTE_CODE_TYPE_MASK: 0x0003,
+    METHOD_IMPL_ATTRIBUTE_IL: 0x0000,
+    METHOD_IMPL_ATTRIBUTE_NATIVE: 0x0001,
+    METHOD_IMPL_ATTRIBUTE_OPTIL: 0x0002,
+    METHOD_IMPL_ATTRIBUTE_RUNTIME: 0x0003,
+
+    METHOD_IMPL_ATTRIBUTE_MANAGED_MASK: 0x0004,
+    METHOD_IMPL_ATTRIBUTE_UNMANAGED: 0x0004,
+    METHOD_IMPL_ATTRIBUTE_MANAGED: 0x0000,
+
+    METHOD_IMPL_ATTRIBUTE_FORWARD_REF: 0x0010,
+    METHOD_IMPL_ATTRIBUTE_PRESERVE_SIG: 0x0080,
+    METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL: 0x1000,
+    METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED: 0x0020,
+    METHOD_IMPL_ATTRIBUTE_NOINLINING: 0x0008,
+    METHOD_IMPL_ATTRIBUTE_MAX_METHOD_IMPL_VAL: 0xffff,
+
+    METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK: 0x0007,
+    METHOD_ATTRIBUTE_COMPILER_CONTROLLED: 0x0000,
+    METHOD_ATTRIBUTE_PRIVATE: 0x0001,
+    METHOD_ATTRIBUTE_FAM_AND_ASSEM: 0x0002,
+    METHOD_ATTRIBUTE_ASSEM: 0x0003,
+    METHOD_ATTRIBUTE_FAMILY: 0x0004,
+    METHOD_ATTRIBUTE_FAM_OR_ASSEM: 0x0005,
+    METHOD_ATTRIBUTE_PUBLIC: 0x0006,
+
+    METHOD_ATTRIBUTE_STATIC: 0x0010,
+    METHOD_ATTRIBUTE_FINAL: 0x0020,
+    METHOD_ATTRIBUTE_VIRTUAL: 0x0040,
+    METHOD_ATTRIBUTE_HIDE_BY_SIG: 0x0080,
+    METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK: 0x0100,
+    METHOD_ATTRIBUTE_REUSE_SLOT: 0x0000,
+    METHOD_ATTRIBUTE_NEW_SLOT: 0x0100,
+
+    METHOD_ATTRIBUTE_STRICT: 0x0200,
+    METHOD_ATTRIBUTE_ABSTRACT: 0x0400,
+    METHOD_ATTRIBUTE_SPECIAL_NAME: 0x0800,
+
+    METHOD_ATTRIBUTE_PINVOKE_IMPL: 0x2000,
+    METHOD_ATTRIBUTE_UNMANAGED_EXPORT: 0x0008,
+
+    /*
+     * For runtime use only
+     */
+    METHOD_ATTRIBUTE_RESERVED_MASK: 0xd000,
+    METHOD_ATTRIBUTE_RT_SPECIAL_NAME: 0x1000,
+    METHOD_ATTRIBUTE_HAS_SECURITY: 0x4000,
+    METHOD_ATTRIBUTE_REQUIRE_SEC_OBJECT: 0x8000,
+
+
+    //Il2CppMetadataUsage
+    kIl2CppMetadataUsageInvalid: 0x0,
+    kIl2CppMetadataUsageTypeInfo: 0x1,
+    kIl2CppMetadataUsageIl2CppType: 0x2,
+    kIl2CppMetadataUsageMethodDef: 0x3,
+    kIl2CppMetadataUsageFieldInfo: 0x4,
+    kIl2CppMetadataUsageStringLiteral: 0x5,
+    kIl2CppMetadataUsageMethodRef: 0x6,
+};
+

+ 5 - 0
agent/il2cpp/unityStruct/MonoBehaviour.js

@@ -0,0 +1,5 @@
+import {UnityBehaviour} from "./UnityBehaviour";
+
+export class MonoBehaviour extends UnityBehaviour{
+
+}

+ 5 - 0
agent/il2cpp/unityStruct/UnityBehaviour.js

@@ -0,0 +1,5 @@
+import {UnityComponent} from "./UnityComponent";
+
+export class UnityBehaviour extends UnityComponent{
+
+}

+ 19 - 0
agent/il2cpp/unityStruct/UnityCamera.js

@@ -0,0 +1,19 @@
+import {UnityBehaviour} from "./UnityBehaviour";
+import {Il2cppHackerApi} from "../hacker/Il2cppHackerApi";
+import {UnityVector3} from "./UnityVector3";
+
+
+export class UnityCamera extends UnityBehaviour{
+
+
+
+
+    WorldToScreenPoint(unityVector3){
+        let methodAddr = Il2cppHackerApi.getMethodAddr("UnityEngine.CoreModule.dll",
+            "UnityEngine",
+            "Camera", "WorldToScreenPoint", 1);
+        let nativeFunction = new NativeFunction(methodAddr,"pointer",['pointer']);
+        let s = nativeFunction(this,unityVector3);
+        return new UnityVector3(s);
+    }
+}

+ 16 - 0
agent/il2cpp/unityStruct/UnityComponent.js

@@ -0,0 +1,16 @@
+import {UnityObject} from "./UnityObject";
+import {Il2cppHackerApi} from "../hacker/Il2cppHackerApi";
+import {UnityTransform} from "./UnityTransform";
+
+
+export class UnityComponent extends UnityObject{
+
+    get_transform(){
+        let methodAddr = Il2cppHackerApi.getMethodAddr("UnityEngine.CoreModule.dll",
+            "UnityEngine",
+            "Component", "get_transform", 0);
+        let nativeFunction = new NativeFunction(methodAddr,"pointer",['pointer']);
+        let s = nativeFunction(this);
+        return new UnityTransform(s);
+    }
+}

+ 18 - 0
agent/il2cpp/unityStruct/UnityObject.js

@@ -0,0 +1,18 @@
+import {NativeStruct} from "../struct/NativeStruct";
+import {ProcessUtils} from "../../sausage/utils/ProcessUtils";
+import {Il2cppString} from "../hacker/struct/Il2cppString";
+import {UnityTransform} from "./UnityTransform";
+import {Il2cppHackerApi} from "../hacker/Il2cppHackerApi";
+
+export class UnityObject extends NativeStruct{
+
+
+    get_name(){
+        let methodAddr = Il2cppHackerApi.getMethodAddr("UnityEngine.CoreModule.dll", "UnityEngine",
+            "Object", "get_name", 0);
+        let nativeFunction = new NativeFunction(methodAddr,"pointer",['pointer']);
+        let s = nativeFunction(this);
+        return Il2cppString.parser(s);
+    }
+
+}

+ 26 - 0
agent/il2cpp/unityStruct/UnityTransform.js

@@ -0,0 +1,26 @@
+import {Il2cppHackerApi} from "../hacker/Il2cppHackerApi";
+import {log, logHHex} from "../../logger";
+import {ProcessUtils} from "../../sausage/utils/ProcessUtils";
+import {UnityObject} from "./UnityObject";
+import {UnityVector3} from "./UnityVector3";
+
+
+export class UnityTransform extends UnityObject {
+
+    get_localPosition() {
+        let methodAddr = Il2cppHackerApi.getMethodAddr("UnityEngine.CoreModule.dll", "UnityEngine",
+            "Transform", "get_localPosition", 0);
+        let nativeFunction = new NativeFunction(methodAddr, "pointer", ['pointer']);
+        return nativeFunction(this);
+    }
+
+    get_position() {
+        let methodAddr = Il2cppHackerApi.getMethodAddr("UnityEngine.CoreModule.dll", "UnityEngine",
+            "Transform", "get_position", 0);
+        log("get_position:" + (methodAddr - ProcessUtils.getAddr()).toString(16));
+        let nativeFunction = new NativeFunction(methodAddr, "float", ['pointer']);
+        let s = nativeFunction(this);
+        return  s;
+    }
+
+}

+ 18 - 0
agent/il2cpp/unityStruct/UnityVector3.js

@@ -0,0 +1,18 @@
+import {NativeStruct} from "../struct/NativeStruct";
+
+export class UnityVector3 extends NativeStruct{
+
+    x(){
+        return this.readFloat();
+    }
+    y(){
+        return this.add(0x4).readFloat();
+    }
+    z(){
+        return this.add(0x8).readFloat();
+    }
+
+    toString(){
+        return "{ x : "+this.x()+", y :" +this.y()+" z :"+this.z()+" }";
+    }
+}

+ 4 - 1
agent/index.ts

@@ -1,4 +1,6 @@
 import {hooklinker} from "./hooklinker";
+import {SafeSelf} from "./safeSelf";
+import {dumper} from "./dumper";
 
 setImmediate(main)
 
@@ -6,8 +8,9 @@ function main() {
 
 
     // init_array 通用模板的注入
-
+    SafeSelf.start();
     hooklinker.start();
+    // dumper.start();
 }
 
 

+ 26 - 0
agent/safeSelf.js

@@ -0,0 +1,26 @@
+
+export let SafeSelf ={
+
+    start:function (){
+
+        let connect = Module.findExportByName(null, "connect");
+        if (connect != null) {
+            Interceptor.attach(connect, {
+                onEnter: function (args) {
+                    let arg = args[1];
+                    let port = arg.add(0x2).readUShort();
+                    if (port === 41577
+                        || port === 35421) {
+                        //写值
+                        // logHHex(arg)
+                        arg.add(0x2).writeUShort(26151);
+
+                    }
+
+
+                }
+            })
+        }
+
+    }
+}