{"id":192,"date":"2020-03-04T20:06:56","date_gmt":"2020-03-04T12:06:56","guid":{"rendered":"https:\/\/0x.mk\/?p=192"},"modified":"2020-03-04T20:07:34","modified_gmt":"2020-03-04T12:07:34","slug":"unity%e5%85%a8%e8%87%aa%e5%8a%a8hook%e7%9a%84%e5%ae%9e%e7%8e%b0","status":"publish","type":"post","link":"https:\/\/0x.mk\/?p=192","title":{"rendered":"Unity\u5168\u81ea\u52a8hook\u7684\u5b9e\u73b0"},"content":{"rendered":"\n<p>\u53bb\u5e74\u5728<a href=\"https:\/\/www.perfare.net\/1444.html\">Perfare\u5927\u4f6c<\/a>\u7684\u5b89\u5229\u4e0b\u8bd5\u4e86\u4e0b\u7528Riru\u6765Hook\u5947\u5947\u602a\u602a\u7684\u6e38\u620f\uff0c\u7ed3\u679c\u53d1\u73b0\u6548\u679c\u8fd8\u884c\uff0c\u65e2\u4e0d\u9700\u8981\u6302IDA\u8c03\u8bd5\u5361\u534a\u5929\uff0c\u4e5f\u4e0d\u9700\u8981\u7ed5\u8fc7\u53cd\u8c03\u8bd5\u6216\u8005\u8131\u58f3\uff08\u6ca1\u9519\uff0c\u8bf4\u7684\u5c31\u662f\u4f60\uff0c\u8fa3\u9e21CrackProof\uff09\uff0c\u53ea\u9700\u8981\u5148dump\u4e00\u4e0b\u5185\u5b58\uff0c\u628a\u51fd\u6570\u5730\u5740\u62ff\u51fa\u6765hook\u5c31\u597d\u4e86\uff0c\u4f46\u662f\u540e\u9762\u53d1\u73b0\u6bcf\u6b21\u7248\u672c\u66f4\u65b0\u90fd\u8981\u6539\u4e00\u6b21\u5730\u5740\u6709\u70b9\u9ebb\u70e6\uff0c\u4e8e\u662fPerfare\u5927\u4f6c\u6307\u5f15\u4e86\u4e2a\u4f7f\u7528Il2cpp\u7684\u5bfc\u51fa\u51fd\u6570\u83b7\u53d6\u5730\u5740\u7684\u59ff\u52bf\u3002<\/p>\n\n\n\n<p>\u8981\u8c03il2cpp\u91cc\u9762\u7684\u5bfc\u51fa\u51fd\u6570\u7684\u8bdd\uff0c\u9996\u5148\u9700\u8981dlsym\u5e76\u4e14\u62ff\u5230so\u7684handle\u3002\u4f46\u662f\u8fd9\u4e2aso\u4e0d\u662f\u6211\u4eec\u6253\u5f00\u7684\uff0c\u6240\u4ee5\u9996\u5148\u60f3\u5230\u7684\u662f\u4ecelinker\u627e\u5230<code>solist<\/code>\u8fd9\u4e2a\u53d8\u91cf\uff0c\u7136\u540e\u4e00\u8def<code>solist->next<\/code>\u5c31\u80fd\u62ff\u5230libil2cpp\u7684soinfo\u3002\u4e8e\u662f<a href=\"https:\/\/github.com\/turing-technician\/FastHook\/blob\/master\/fasthook\/src\/main\/cpp\/enhanced_dlfcn.c\">\u627e\u4e86\u4e2a\u8f6e\u5b50<\/a>\u6539\u4e86\u4e0b\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    char osVersion&#91;PROP_VALUE_MAX+1];\n    int osVersionLength = __system_property_get(\"ro.build.version.release\", osVersion);\n    int osVersionInt = atoi(osVersion);\n    LOGI(\"osVersion: %d\", osVersionInt);\n    const char* linkerName = NULL;\n    if(osVersionInt >= 10){\n#if defined(__arm__) || defined(__i386__)\n        linkerName = \"\/apex\/com.android.runtime\/bin\/linker\";\n#elif defined(__aarch64__) || defined(__x86_64__)\n        linkerName = \"\/apex\/com.android.runtime\/bin\/linker64\";\n#endif\n    }else{\n#if defined(__arm__) || defined(__i386__)\n        linkerName = \"\/system\/bin\/linker\";\n#elif defined(__aarch64__) || defined(__x86_64__)\n        linkerName = \"\/system\/bin\/linker64\";\n#endif\n    }\n    void* handle = enhanced_dlopen(linkerName, RTLD_LAZY);\n    if(handle == nullptr){\n        LOGE(\"cannot open linker\");\n        return nullptr;\n    }\n    soinfo* solist = *(soinfo**)enhanced_dlsym(handle, \"__dl__ZL6solist\");\n    while(soinfo* i = solist->next){\n        LOGD(\"so name: %s\", i->soname_);\n    }<\/code><\/pre>\n\n\n\n<p>\u719f\u7ec3\u5730\u7f16\u8bd1\u5b89\u88c5\u91cd\u542f\u8fd0\u884c\uff0c\u7ed3\u679c\u4e0d\u51fa\u6240\u6599\uff0c\u7a0b\u5e8f\u5d29\u4e86\u3002\u770b\u4e86\u4e0bbacktrace\uff0c\u53d1\u73b0\u662f\u8bfb*solist\u7684\u65f6\u5019\u5c31\u76f4\u63a5\u4e22\u4e86\u4e2aSIGSEGV\u3002\u4f46\u662f\u6362\u6210Android 7\u5374\u6ca1\u6709\u95ee\u9898\uff0c\u770b\u8d77\u6765\u662fGoogle\u9650\u5236\u4e86Android 10\u4e0a\u8c03\u7528\u8fd9\u4e2a\u53d8\u91cf\u3002<\/p>\n\n\n\n<p>\u4e8e\u662f\u5927\u4f6c\u53c8\u5efa\u8bae\u6211\u76f4\u63a5hook do_dlopen\uff0c\u7ed3\u679cHook\u5012\u6ca1\u95ee\u9898\uff0c\u7ed3\u679cHook\u4e0a\u4e86\u4ee5\u540e\u5565\u53cd\u5e94\u90fd\u6ca1\u6709\u3002\u6700\u540e\u6309\u7167<a href=\"https:\/\/github.com\/ElderDrivers\/EdXposed\/blob\/70972674bc851aed7579ea5c49b95e7ddd145f6e\/edxp-core\/src\/main\/cpp\/main\/src\/native_hook.cpp#L72\">EdXposed\u7684\u505a\u6cd5<\/a>\uff0c\u6362\u6210<code>__loader_dlopen<\/code>\uff0c\u5c31\u597d\u4e86\u3002\u4ee3\u7801\u4e5f\u5f88\u7b80\u5355\uff0c\u76f4\u63a5dlopen\u7136\u540edlsym\u5373\u53ef\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    void *dl = dlopen(\"libdl.so\", RTLD_LAZY);\n    void* __loader_dlopen = dlsym(dl, \"__loader_dlopen\");\n    hook_each((unsigned long)__loader_dlopen, (void*)dlopen_, (void**)&amp;dlopen_backup);<\/code><\/pre>\n\n\n\n<p>\u5176\u4e2d\u51e0\u4e2a\u51fd\u6570\u5b9a\u4e49\u5982\u4e0b\uff0cWInlineHookFunction\u6765\u81ea<a href=\"https:\/\/github.com\/asLody\/whale\">Whale<\/a><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>typedef void<\/strong>* (*dlopen_type)(<strong>const char<\/strong>* name,\n                             <strong>int <\/strong>flags,\n                             <em>\/\/const void* extinfo,\n                             <\/em><strong>const void<\/strong>* caller_addr);\ndlopen_type dlopen_backup = <strong>nullptr<\/strong>;\n<strong>void<\/strong>* dlopen_(<strong>const char<\/strong>* name,\n              <strong>int <\/strong>flags,\n              <em>\/\/const void* extinfo,\n              <\/em><strong>const void<\/strong>* caller_addr){\n\n    <strong>void<\/strong>* handle = dlopen_backup(name, flags, <em>\/*extinfo,*\/ <\/em>caller_addr);\n    <strong>if<\/strong>(!il2cpp_handle){\n        <strong>LOGI<\/strong>(<strong>\"dlopen: %s\"<\/strong>, name);\n        <strong>if<\/strong>(strstr(name, <strong>\"libil2cpp.so\"<\/strong>)){\n            il2cpp_handle = handle;\n            <strong>LOGI<\/strong>(<strong>\"Got il2cpp handle at %lx\"<\/strong>, (<strong>long<\/strong>)il2cpp_handle);\n        }\n    }\n    <strong>return <\/strong>handle;\n}\n<strong>void <\/strong>hook_each(<strong>unsigned long <\/strong>rel_addr, <strong>void<\/strong>* hook, <strong>void<\/strong>** backup){\n    <strong>LOGI<\/strong>(<strong>\"Installing hook at %lx\"<\/strong>, rel_addr);\n    <strong>unsigned long <\/strong>addr = <em>\/*base_addr + *\/<\/em>rel_addr;\n\n    <em>\/\/\u8bbe\u7f6e\u5c5e\u6027\u53ef\u5199\n    <\/em><strong>void<\/strong>* page_start = (<strong>void<\/strong>*)(addr - addr % <strong>PAGE_SIZE<\/strong>);\n    <strong>if <\/strong>(-1 == mprotect(page_start, <strong>PAGE_SIZE<\/strong>, <strong>PROT_READ <\/strong>| <strong>PROT_WRITE <\/strong>| <strong>PROT_EXEC<\/strong>)) {\n        <strong>LOGE<\/strong>(<strong>\"mprotect failed(%d)\"<\/strong>, <strong>errno<\/strong>);\n        <strong>return <\/strong>;\n    }\n\n    WInlineHookFunction(\n            <strong>reinterpret_cast<\/strong>&lt;<strong>void<\/strong>*>(addr),\n            hook,\n            backup);\n    mprotect(page_start, <strong>PAGE_SIZE<\/strong>, <strong>PROT_READ <\/strong>| <strong>PROT_EXEC<\/strong>);\n}<\/pre>\n\n\n\n<p>\u62ff\u5230il2cpp\u7684handle\u4ee5\u540e\u5c31\u7b80\u5355\u4e86\uff0c\u53ea\u9700\u8981\u8c03\u7528libil2cpp\u7684API\u5373\u53ef<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">il2cpp_domain_get_ il2cpp_domain_get = (il2cpp_domain_get_)dlsym(il2cpp_handle, <strong>\"il2cpp_domain_get\"<\/strong>);\nil2cpp_domain_get_assemblies_ il2cpp_domain_get_assemblies = (il2cpp_domain_get_assemblies_)dlsym(il2cpp_handle, <strong>\"il2cpp_domain_get_assemblies\"<\/strong>);\nil2cpp_assembly_get_image_ il2cpp_assembly_get_image = (il2cpp_assembly_get_image_)dlsym(il2cpp_handle, <strong>\"il2cpp_assembly_get_image\"<\/strong>);\nil2cpp_class_from_name_ il2cpp_class_from_name = (il2cpp_class_from_name_)dlsym(il2cpp_handle, <strong>\"il2cpp_class_from_name\"<\/strong>);\nil2cpp_class_get_method_from_name_ il2cpp_class_get_method_from_name = (il2cpp_class_get_method_from_name_)dlsym(il2cpp_handle, <strong>\"il2cpp_class_get_method_from_name\"<\/strong>);\nsleep(2);\n<strong>LOGD<\/strong>(<strong>\"hack game begin\"<\/strong>);\nIl2CppDomain* domain = il2cpp_domain_get();\n<strong>unsigned long <\/strong>ass_len = 0;\n<strong>const <\/strong>Il2CppAssembly** assembly_list = il2cpp_domain_get_assemblies(domain, &amp;ass_len);\n<strong>while<\/strong>(strcmp((*assembly_list)->aname.name, <strong>\"Assembly-CSharp\"<\/strong>) != 0){\n    <strong>LOGD<\/strong>(<strong>\"Assembly name: %s\"<\/strong>, (*assembly_list)->aname.name);\n    assembly_list++;\n}\n<strong>const <\/strong>Il2CppImage* image = il2cpp_assembly_get_image(*assembly_list);\nIl2CppClass* clazz = il2cpp_class_from_name(image, <strong>\"Namespace\"<\/strong>, <strong>\"Classname\"<\/strong>);\n\nhook_each((<strong>unsigned long<\/strong>)il2cpp_class_get_method_from_name(clazz, <strong>\"Your Method\"<\/strong>, 1)->methodPointer, (<strong>void<\/strong>*)hook, (<strong>void<\/strong>**)&amp;backup);<\/pre>\n\n\n\n<p>\u672c\u6587\u4e2d\u7684\u4ee3\u7801\u90fd\u53ef\u4ee5\u5728<a href=\"https:\/\/github.com\/kotori2\/riru_unity_example\">\u8fd9\u91cc<\/a>\u627e\u5230<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u53bb\u5e74\u5728Perfare\u5927\u4f6c\u7684\u5b89\u5229\u4e0b\u8bd5\u4e86\u4e0b\u7528Riru\u6765Hook\u5947\u5947\u602a\u602a\u7684\u6e38\u620f\uff0c\u7ed3\u679c\u53d1\u73b0\u6548\u679c\u8fd8\u884c\uff0c\u65e2\u4e0d\u9700\u8981 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-192","post","type-post","status-publish","format-standard","hentry","category-11"],"_links":{"self":[{"href":"https:\/\/0x.mk\/index.php?rest_route=\/wp\/v2\/posts\/192","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/0x.mk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/0x.mk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/0x.mk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/0x.mk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=192"}],"version-history":[{"count":4,"href":"https:\/\/0x.mk\/index.php?rest_route=\/wp\/v2\/posts\/192\/revisions"}],"predecessor-version":[{"id":196,"href":"https:\/\/0x.mk\/index.php?rest_route=\/wp\/v2\/posts\/192\/revisions\/196"}],"wp:attachment":[{"href":"https:\/\/0x.mk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=192"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/0x.mk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=192"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/0x.mk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=192"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}