From b89b425a53b8d2108de3b7008483cacae5101951 Mon Sep 17 00:00:00 2001 From: Nullptr <52071314+Dr-TSNG@users.noreply.github.com> Date: Thu, 17 Mar 2022 19:52:05 +0800 Subject: [PATCH] Switch into mainline core branch --- app/.gitignore | 2 - app/build.gradle.kts | 100 ---------- app/src/main/AndroidManifest.xml | 27 --- .../main/assets/original_signature_info.ini | 1 - app/src/main/assets/xposed_init | 1 - .../java/org/lsposed/lspatch/tester/Hook.java | 18 -- .../lsposed/lspatch/tester/MainActivity.java | 49 ----- app/src/main/res/layout/activity_main.xml | 14 -- .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 6387 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 10413 -> 0 bytes app/src/main/res/values/strings.xml | 4 - appstub/build.gradle.kts | 20 +- .../appstub/LSPAppComponentFactoryStub.java | 4 +- build.gradle.kts | 177 +++++++++++++++++- core | 2 +- gradle.properties | 24 +-- gradle/wrapper/gradle-wrapper.properties | 2 +- imanager/build.gradle.kts | 22 +-- manager/build.gradle.kts | 29 +-- patch-jar/build.gradle.kts | 4 +- patch-loader/.gitignore | 2 + patch-loader/build.gradle.kts | 74 ++++++++ {app => patch-loader}/proguard-rules.pro | 0 patch-loader/src/main/AndroidManifest.xml | 2 + .../de/robv/android/xposed/XposedHelper.java | 0 .../lspatch/loader/LSPApplication.java | 16 +- .../org/lsposed/lspatch/loader/LSPLoader.java | 0 .../lspatch/loader/ManagerResolver.java | 0 .../lspatch/loader/util/FileUtils.java | 0 .../org/lsposed/lspatch/loader/util/XLog.java | 3 +- .../lsposed/lspd/nativebridge/SigBypass.java | 5 + patch-loader/src/main/jni/CMakeLists.txt | 27 +++ patch-loader/src/main/jni/api/patch_main.cpp | 36 ++++ .../include/art/runtime/jit/profile_saver.h | 56 ++++++ .../include/art/runtime/oat_file_manager.h | 64 +++++++ .../src/main/jni/src/jni/bypass_sig.cpp | 51 +++++ .../src/main/jni/src/jni/bypass_sig.h | 9 + .../src/main/jni/src/patch_loader.cpp | 118 ++++++++++++ patch-loader/src/main/jni/src/patch_loader.h | 51 +++++ .../main/java/org/lsposed/patch/LSPatch.java | 4 +- settings.gradle.kts | 69 ++++--- 41 files changed, 737 insertions(+), 350 deletions(-) delete mode 100644 app/.gitignore delete mode 100644 app/build.gradle.kts delete mode 100644 app/src/main/AndroidManifest.xml delete mode 100644 app/src/main/assets/original_signature_info.ini delete mode 100644 app/src/main/assets/xposed_init delete mode 100644 app/src/main/java/org/lsposed/lspatch/tester/Hook.java delete mode 100644 app/src/main/java/org/lsposed/lspatch/tester/MainActivity.java delete mode 100644 app/src/main/res/layout/activity_main.xml delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png delete mode 100644 app/src/main/res/values/strings.xml create mode 100644 patch-loader/.gitignore create mode 100644 patch-loader/build.gradle.kts rename {app => patch-loader}/proguard-rules.pro (100%) create mode 100644 patch-loader/src/main/AndroidManifest.xml rename {app => patch-loader}/src/main/java/de/robv/android/xposed/XposedHelper.java (100%) rename {app => patch-loader}/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java (97%) rename {app => patch-loader}/src/main/java/org/lsposed/lspatch/loader/LSPLoader.java (100%) rename {app => patch-loader}/src/main/java/org/lsposed/lspatch/loader/ManagerResolver.java (100%) rename {app => patch-loader}/src/main/java/org/lsposed/lspatch/loader/util/FileUtils.java (100%) rename {app => patch-loader}/src/main/java/org/lsposed/lspatch/loader/util/XLog.java (95%) create mode 100644 patch-loader/src/main/java/org/lsposed/lspd/nativebridge/SigBypass.java create mode 100644 patch-loader/src/main/jni/CMakeLists.txt create mode 100644 patch-loader/src/main/jni/api/patch_main.cpp create mode 100644 patch-loader/src/main/jni/include/art/runtime/jit/profile_saver.h create mode 100644 patch-loader/src/main/jni/include/art/runtime/oat_file_manager.h create mode 100644 patch-loader/src/main/jni/src/jni/bypass_sig.cpp create mode 100644 patch-loader/src/main/jni/src/jni/bypass_sig.h create mode 100644 patch-loader/src/main/jni/src/patch_loader.cpp create mode 100644 patch-loader/src/main/jni/src/patch_loader.h diff --git a/app/.gitignore b/app/.gitignore deleted file mode 100644 index c3dca1b..0000000 --- a/app/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build -/target diff --git a/app/build.gradle.kts b/app/build.gradle.kts deleted file mode 100644 index 55e4c53..0000000 --- a/app/build.gradle.kts +++ /dev/null @@ -1,100 +0,0 @@ -val androidCompileSdkVersion: Int by rootProject.extra -val androidMinSdkVersion: Int by rootProject.extra -val androidTargetSdkVersion: Int by rootProject.extra - -val androidSourceCompatibility: JavaVersion by rootProject.extra -val androidTargetCompatibility: JavaVersion by rootProject.extra - -plugins { - id("com.android.application") -} - -android { - flavorDimensions += "api" - productFlavors { - create("Riru") { - dimension = "api" - } - } - - compileSdk = androidCompileSdkVersion - - defaultConfig { - minSdk = androidMinSdkVersion - targetSdk = androidTargetSdkVersion - - multiDexEnabled = false - - signingConfigs.create("config") { - val androidStoreFile = project.findProperty("androidStoreFile") as String? - if (!androidStoreFile.isNullOrEmpty()) { - storeFile = file(androidStoreFile) - storePassword = project.property("androidStorePassword") as String - keyAlias = project.property("androidKeyAlias") as String - keyPassword = project.property("androidKeyPassword") as String - } - } - - compileOptions { - sourceCompatibility = androidSourceCompatibility - targetCompatibility = androidTargetCompatibility - } - } - - buildTypes { - debug { - isDebuggable = true - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - signingConfig = if (signingConfigs["config"].storeFile != null) signingConfigs["config"] else signingConfigs["debug"] - } - release { - isDebuggable = false - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - signingConfig = if (signingConfigs["config"].storeFile != null) signingConfigs["config"] else signingConfigs["debug"] - } - } - - lint { - abortOnError = false - } -} - -androidComponents.onVariants { variant -> - val variantCapped = variant.name.capitalize() - val variantLowered = variant.name.toLowerCase() - - task("copyDex$variantCapped") { - dependsOn("assemble$variantCapped") - from("$buildDir/intermediates/dex/$variantCapped/mergeDex$variantCapped/classes.dex") - rename("classes.dex", "lsp.dex") - into("${rootProject.projectDir}/out/assets/dex") - } - - task("copySo$variantCapped") { - dependsOn("assemble$variantCapped") - from("$buildDir/intermediates/merged_native_libs/$variantCapped/out/lib") - into("${rootProject.projectDir}/out/assets/so") - } - - task("copy$variantCapped") { - dependsOn("copySo$variantCapped") - dependsOn("copyDex$variantCapped") - - doLast { - println("Dex and so files has been copied to ${rootProject.projectDir}${File.separator}out") - } - } -} - -dependencies { - compileOnly(projects.hiddenapiStubs) - implementation(projects.daemonService) - implementation(projects.lspcore) - implementation(projects.hiddenapiBridge) - implementation(projects.share) - implementation(projects.imanager) - - implementation("com.google.code.gson:gson:2.9.0") -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml deleted file mode 100644 index 069c784..0000000 --- a/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/assets/original_signature_info.ini b/app/src/main/assets/original_signature_info.ini deleted file mode 100644 index 8d3701e..0000000 --- a/app/src/main/assets/original_signature_info.ini +++ /dev/null @@ -1 +0,0 @@ -palceholder \ No newline at end of file diff --git a/app/src/main/assets/xposed_init b/app/src/main/assets/xposed_init deleted file mode 100644 index 755e655..0000000 --- a/app/src/main/assets/xposed_init +++ /dev/null @@ -1 +0,0 @@ -org.lsposed.lspatch.tester.Hook diff --git a/app/src/main/java/org/lsposed/lspatch/tester/Hook.java b/app/src/main/java/org/lsposed/lspatch/tester/Hook.java deleted file mode 100644 index e88a44d..0000000 --- a/app/src/main/java/org/lsposed/lspatch/tester/Hook.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.lsposed.lspatch.tester; - -import de.robv.android.xposed.IXposedHookLoadPackage; -import de.robv.android.xposed.XC_MethodHook; -import de.robv.android.xposed.XposedHelpers; -import de.robv.android.xposed.callbacks.XC_LoadPackage; - -public class Hook implements IXposedHookLoadPackage { - @Override - public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { - XposedHelpers.findAndHookMethod("org.lsposed.lspatch.tester.MainActivity", lpparam.classLoader, "checkXposed2", new XC_MethodHook() { - @Override - protected void afterHookedMethod(MethodHookParam param) throws Throwable { - param.setResult(true); - } - }); - } -} diff --git a/app/src/main/java/org/lsposed/lspatch/tester/MainActivity.java b/app/src/main/java/org/lsposed/lspatch/tester/MainActivity.java deleted file mode 100644 index 525a0a1..0000000 --- a/app/src/main/java/org/lsposed/lspatch/tester/MainActivity.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.lsposed.lspatch.tester; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.os.Bundle; -import android.view.View; -import android.widget.TextView; - -import org.lsposed.lspatch.R; - -import de.robv.android.xposed.XC_MethodHook; -import de.robv.android.xposed.XposedHelpers; - - -public class MainActivity extends Activity { - - @SuppressLint("SetTextI18n") - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - XposedHelpers.findAndHookMethod(this.getClass(), "checkXposed", new XC_MethodHook() { - @Override - protected void beforeHookedMethod(MethodHookParam param) throws Throwable { - param.setResult(true); - } - }); - - TextView textView = findViewById(R.id.msg); - if (checkXposed() && checkXposed2()) { - textView.setText("ok"); - } - else { - textView.setText("fail"); - } - } - - public void onClick(View view) { - } - - public boolean checkXposed() { - return false; - } - - public static boolean checkXposed2() { - return false; - } -} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index 0dc3525..0000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index b0907cac3bfd8fbfdc46e1108247f0a1055387ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6387 zcma($WmFVQySpr~^b#u_OG=0|(kva)DP1B+cP_AmARxJ*NC=Wrg0zUl5(`L)gp{N- z(%_OG?|Z*r_s2c=$2@ap&UtF)$(eXP9W_!SdLjS-K&qjxY;ZTH{xb;h@8E{&N(%r$ z+p3|gU=%dFmq%!1q&9_NsUvvk-GvvZjaIJ%uU(o!Ypc=Wv%E8e<<)SFdRM{tz(T@!nKT{;0jT2A&dgKu3 zk|GDUX<&73+f+CnZza0G4g29@hmNkl+2wP#$0yi6=u-4CD#*a8LxJLG9KlkveQ7v} z>E#)-tL=xh89y&5li1I!>Zzc!_i6V~nKP^5-+!69FtnX*f=*tr+cf&UpZtLBY|wv< zJ6r*Z5374 zi$7+B3A@szy#|*$Tb~kkzc_N~h3;oe8q95K$w@e#5FRGcF}wXTR}t#^!OnNc>Z52w zu23YrlIQY7UrLLcFSW5ctMBzwrTz=X-m{1Y!*LWUbO~;u&&q8Lu;wlGFqO2h4olL; z{rpPfr}7f=Z)eZhFw1_ITpft-VzPF1CHv-W>u;OCBJBEOEn$HmTpFjX=xN6-H5#V{ zn6Si;q3V*@lFMd>H8;M}vOp8McQcJ}^bBfV`1xb0g0`9ZZa9(wb+L_RGO6wD&I8ouM<}YVDFU ztMSz*yMDz3AkS0YO)3_lYDarEUyj?A#9s@-ln${-1Op^nD7zREi=%4Hy%V?=YS7G`L@>`3kHM4eAD%)t@F};|C zfj?B^Kox-WuPMuDp2=LPZU3Obgnl7{dD>|>*A`fn-0|^8uAHJz;<)tkTXA8lI&dHt&xG(4Il=e~QNN6o9YD7H{TR?17eM>#Z8#Y@_=7fZ?HkZX8i|mEGs5mR`uBi^ zzFh5AG^3EMyvpx(a*)!eOI1?nPTn?v0Ly$)KlQ16Xfrzh+}+Ua_I!5XU@ciwrAZ>O z<7!MU$n6`x${EB6YH$hWOMuSEw+72Lb~rgO*Yp26LGdNp*;^;HAD@(SAr(Dk;j7w! zQ>!M4rxUFYn7E?v7)2q)2rJ2%PY>A>-1O7bY~nt&n)jYnG$(iR#hvlih1p}c)I+|I zy^C;=uIJImfY zL~pm6t6Zw8FiOIY<1>EBS(<5`Cv8DBcZEpTCQ{@@-|2$Bhi;6H?Pofq1Z%b2@)&at zUA{9iaqi62D1|=T{xTe3Czr|z52P;M7EB|V-ss{qspYc0Cj~hUUURef8?i5H?e;kA z<~qW5`JIc(rCLz_oJ~>x8O2IVR%>+7%}`TBSQt%i+m+4tV?z0(?5cf&1v8cNlz7Lg z%ZS>-e!({r)+sH_1+QJvE5BqOgmfK_$X*P0*x6beoRN|0FV zBu+T9^1E5}1I>g&wC|Bn^{(R$!_A@+E4<}3n|QMU=H|GuQZRAZ+zSZ}SS{MNj&mi0 zRY+fp&8IQn-}zGeIVj+qntrIP-IpXF?2xAoyT|i)X+@HL$+|t{#ZAvBrd?L!=9aLy z%@CY;X7U41O6VpHq<1UBk2vi~afo_h1Xrb{vQ%cE|Fvi8EjFCP^~ zabJnB#=NPyBD*BaNSQW*VI+TbEmlu2&HD<4U_UQNUR_`K~u~XWideSoLc(k)vEtG^CT* zG`Zdarw^M&6C=~oi^6W#WL!BMe{E&Gg9Arbg2gg;cO^sJ#+L$ zWBP!R+lcV(p-B#aK<&Ly>?*3fngF)TwSRSmGJ!zET{Brabip#AUPyChm}S9IFG!l{ z%+I_?Cl?zVm9nbGSU`Ksi%z1{vEPpxnv}!StZLIR4yl9y>GM~KIIbNdVs|xsuCpX=J#rE`8<@v*FO%Lb)=#c`~s7W#9EDhRI!G*VBK(y z5D`)jJo4o1={q}Kg%YGhdH~@PGate(xi{(OiQn~MMSZM;!kHNh*1-e<+YS5-j3b?2 zq7SYPWMn1a!^Gqxr4d1gZ5G`QQ(&4Ag*OcnWO}~9rz5xeE3Ycol5cj$@jggn@8x2* z)UpG-U2|Av7a)Hi=b^@SNp#`PEDfswF$nyx&rD*+4SF}`_U48`=1VnBn}aEm{Funk zSWQuC>r8yUkd_D(dKEqo`7i}}{#+a?O4 zDIg~&^q#d5-Ji>``G%gDDzV<~+=*qePTy_lbVjK?!d`>ygnhxwtyL65_G4A=A}{Dh zq;iS@h|Y-wJdeGj1b{KBTkst|klERM7*Hwy#ZO<~Q$5~GzC~WjZHz>=z3~>oAVbbv zzmgOw2JQ#Kv)GT9dwrXGJKz5(Jw%&rYPjfi;TI|dyVJrvaZ*ivGRT;i>R6}8B>7*j zbJi0%9UfLcYKp+TU9qXLSp`rm`)3(g6YOdHa4cv2Y)-JCPZ&g1Z*%F~T@dw@_HA~- zxeq6NeOi{(yh(ziMZ)4yIfDP6nhTg;)$=9N_-{KO!ZB@c@e$(SVH`%0b3YF`lgX)? zmPOF$H%(2yD*LrQ;d*vDgW=s=2h+1RYg?DCXa2gXNT~W+Hu+pBZ$bO8IlS+nqXw^| zBM2iS@v_S^5P@J5V0gw2hamKs7Wro(xWlv)U$%_D)AA{;Mb;l$7?FOK*2{U?f_M(W z4#aOFFlOC*Grkxzi#w)?qgNP48e=dJ*`EYNKfLm6BlZ-j@VMi+{0T>$Y6e%gC|6;v z4=~J;U-H`Rv(<}l7sEXpm?7;(jXl{O>aLca zP;<5GjkKb?74YTOqJAtFKzq|v(-+j{(@?GPIKVS95tsog!>*S60XwAsnYHqG)dW<#@2UIte}({hi5+*r;^rQeDpKps%Ql|LRink z=CR6^g!&1h1Ks5JplDey{0{E~MNPgvQNeH21%lrCFFh~_7#;b73>@zaFo0B}hXo(J z#OVP*a2!ZeK|x0LfazsE0=vAP5xpQ58{e}Xtzn5B`l%b)PM2PI{UmZ`}XbW%4eE=4-VAbQ|zojxNh6BnLDzTlx-stKQP0|=pi5R7qw0g}ivih_z$ zN`Pc6h9K3P5vFz^s^};EaGwq5yEdpH4Um!3Lju85e*w5hg)|yEkihSklp#pqhWjij zaK_T%_)PG>g`7N9$25qwhR3WB{&pp8G2;J-#qe6%xdFHO2AeceqW`Q#`J1X4*a>V4 z;Y4EVTMA!^vxOA;$ZDCt!CPots~0yn*Erio(G!n)@W*|^D_=Wy;f*k=tF~9Zmr)dn zCzfODoJ@UXXs>1NP-A4#YmmhGXavn<+z_gJ`>cZaGo@Iz2J)=M7{{ zJ;n45y6T86%gls;?`*1bFl=sXf1H<+2AiBU`}H6YM=+eFPoz%Sg=s>Dva{ls1mJO? zTWP*i(U7Ec^3%Z$g`f%l##*mSt_wOa-d&(0A0@(ms#pY$P8SX-ZAVg)> zpsk00`SNH__*AQ#=>~|-wScS`e>RBCs6NsQ18sz`Q({qI(fOQUY10Mt%YO^v{>w>TEBSR zi>oS_n(}3A8W+^iWG~}cr3Bv#s3W>CFUJm0ejS>=V^X>!UmDV@|xH@hWB5yhc zuXagN9&cY%tMFc@?PqIxYmy+OSGU`O5gvK2Yaic7tFAiaz`*T*dLafG4tz~<{L=*n z1iRA9k6#TYhCWcSFW6P4&4yOea4q&Fy6Mbkfl&!{&@KmDXMWs7;2Q2bRU~gBtDs>o zNeUgzt#lWV4oq=C=5{Id0)=a+u5HaCtDZwXnX5u!bO%{LbXF-L40}KeG4lG*uU{E_AOMMd4ch=Q9&rc=;3fB`I@EFBuF!XcuT783*FH`4zO zxZ=AOG#fzwnh^u6!|A7Fqf5u{$IesB&EF?V9g5dyhcmbVh)|M3^!U*}qJEYbGFaK2 z#0I`dWniJzl~+;sJs^jty%7`^Yv#{r+=Q<#CleH22pEWpQ)lwX9b5uv064&fPlS+b zqZM<&o~(2`QgUJ$O29zuo%|4(uP+zAeibd;jfc(zz|+6+9EUrZ?#^|ymX-knV0Dsz zFn=Bg(*p-JjWR}+{_C#CZ~dR&on|-C9&{&ij%~0x9gtgIMPCkr_rc{WE_}pL*bCnZ z3d?M3AYq3)iUS7jPOFD3m9DVG)E&SJ1*`YXzZQib9R(``({n~0aGXEhgZnJU3vy*N zlEAeqef_?@nqICTH{?wuZFw#7F{`&i?NLpf<7G2noyziDxMHBmK=Z&P8jf>~^fSVF zFmD1h)DVg7D8erkb}OkfElv2i`s#7j5-;7~&l>SlgLRqNM90B`oFJ!3Z!I+~g7^$B zkD<7Y^U2QID5DVT!a*uS%0aL5KAD#Lk5^|WCC!!OQcFyxCl$386q*ohKGP#?pNL0_ zG0d|NfxU%N?);5-{u0rA@S7+4>7&sDwppXmJaj`?8D#?9@k90l(a-Vg>E`q1zXh9B zEsyo)21!OKE@yf_^P?a!d>O%I$~z&Bg| z{KuO5lVh07O|keMJh@ks$3EfHm`nFk6qNS&_PxPbKN1c~Ds8?;y>OzV;B0$XVQ=LQx12PJ2~x!&?qm%Tl)eivoas}<)&`&84*`tT{?ou45c+RPjX;imIsuwmXJs;5Klbii3#Q0kSLKcW+Y@xKcRce+GJ-RTlpMp(c)D`xrv zd|#_rj!Bm<&cad=Pq($+uKOY#CGCK-8EXOLAo{LJ2l({+_%87YR(e2EErULI*gm@X z*m6LuczdHTQHH`3=)x;unt9KH-4duW3nu}xk&Cu4-DS4wjNG}S$tO5H_$l1*S3Go6 z0HH1rN4WcDUK${}+a@ICZ(ZC#*`6h6EK7)q2OePook_w)c5%-9AxwoT6E*>!XDxpM zy_C$yP!`aN2TiCVLn_z`_E((J%LUYuw%2%(GBL3Cve+5zmepidD|^#$=@2Wfp!?NR zUpV2SwaMg68}9+`X#n-Ust|TK-Qk@HXu7dM*@>KO~@YA_S!geT; zxLp>TbIo9^WI=ZuT?ErRN;LqRSZX$7)+{MdSSiDnSdSwQ+6Yqb#nF393O_Ow-rRZD z1MtC55vP=~4kwe+$#2C8b3Q6*<^!T_D^X($HS$*Ns2(pd5~m<_QgfsetRt77rwh}yjg#yx`@p|%;RnzvAN8~6i5D;EQg*azSU-+F9W;M>-%sM=r4J zY%}@{t+!2883WSGMgw_85U#I}O75Rr0Q_D5;Du8|l@ zHWBq-r2&(pezi>6+daPx-qwVIQ3A6$h}GxIH72G*;HeRgyXKy?Uf!HvVg$M3Vs?lo j7HB*8-{6~e<}KKy%g|C8?m&3=nE}vH(NX@WXdCq(XawjJ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index d8ae03154975f397f8ed1b84f2d4bf9783ecfa26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10413 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 XdJ+W}DiIkV00000NkvXXu0mjfKBlg6 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml deleted file mode 100644 index 0ff0fd6..0000000 --- a/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Xposed Module Loader - \ No newline at end of file diff --git a/appstub/build.gradle.kts b/appstub/build.gradle.kts index c99fff3..4b16eba 100644 --- a/appstub/build.gradle.kts +++ b/appstub/build.gradle.kts @@ -1,23 +1,10 @@ -val androidMinSdkVersion: Int by rootProject.extra -val androidTargetSdkVersion: Int by rootProject.extra -val androidCompileSdkVersion: Int by rootProject.extra -val androidBuildToolsVersion: String by rootProject.extra - -val androidSourceCompatibility: JavaVersion by rootProject.extra -val androidTargetCompatibility: JavaVersion by rootProject.extra - plugins { id("com.android.application") } android { - compileSdk = androidCompileSdkVersion - buildToolsVersion = androidBuildToolsVersion defaultConfig { - minSdk = androidMinSdkVersion - targetSdk = androidTargetSdkVersion - multiDexEnabled = false } @@ -27,11 +14,6 @@ android { proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") } } - - compileOptions { - sourceCompatibility = androidSourceCompatibility - targetCompatibility = androidTargetCompatibility - } } androidComponents.onVariants { variant -> @@ -55,7 +37,7 @@ androidComponents.onVariants { variant -> } dependencies { - compileOnly(projects.hiddenapiStubs) + compileOnly(projects.hiddenapi.stubs) implementation("de.upb.cs.swt:axml:2.1.2") } diff --git a/appstub/src/main/java/org/lsposed/lspatch/appstub/LSPAppComponentFactoryStub.java b/appstub/src/main/java/org/lsposed/lspatch/appstub/LSPAppComponentFactoryStub.java index 36511a8..0d07f32 100644 --- a/appstub/src/main/java/org/lsposed/lspatch/appstub/LSPAppComponentFactoryStub.java +++ b/appstub/src/main/java/org/lsposed/lspatch/appstub/LSPAppComponentFactoryStub.java @@ -34,10 +34,10 @@ public class LSPAppComponentFactoryStub extends AppComponentFactory { vmInstructionSet.setAccessible(true); String arch = (String) vmInstructionSet.invoke(getRuntime.invoke(null)); - String path = cl.getResource("assets/lspatch/lspd/" + arch + "/liblspd.so").getPath().substring(5); + String path = cl.getResource("assets/lspatch/so/" + arch + "/liblspatch.so").getPath().substring(5); System.load(path); } catch (Throwable e) { Log.e("LSPatch", "load lspd error", e); } } -} \ No newline at end of file +} diff --git a/build.gradle.kts b/build.gradle.kts index 7bc6d8f..6a0a6ca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,14 +1,20 @@ +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.android.build.gradle.BaseExtension import org.eclipse.jgit.api.Git import org.eclipse.jgit.internal.storage.file.FileRepository +plugins { + id("com.android.application") apply false + id("com.android.library") apply false +} + buildscript { repositories { google() mavenCentral() } - val agpVersion by extra("7.1.2") dependencies { - classpath("com.android.tools.build:gradle:$agpVersion") classpath("org.eclipse.jgit:org.eclipse.jgit:6.0.0.202111291000-r") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10") } @@ -41,13 +47,6 @@ val androidBuildToolsVersion by extra("31.0.0") val androidSourceCompatibility by extra(JavaVersion.VERSION_11) val androidTargetCompatibility by extra(JavaVersion.VERSION_11) -allprojects { - repositories { - google() - mavenCentral() - } -} - tasks.register("clean") { delete(rootProject.buildDir) } @@ -59,3 +58,163 @@ listOf("Debug", "Release").forEach { variant -> dependsOn(projects.manager.dependencyProject.tasks["build$variant"]) } } + +fun Project.configureBaseExtension() { + extensions.findByType(BaseExtension::class)?.run { + compileSdkVersion(androidCompileSdkVersion) + ndkVersion = androidCompileNdkVersion + buildToolsVersion = androidBuildToolsVersion + + defaultConfig { + minSdk = androidMinSdkVersion + targetSdk = androidTargetSdkVersion + versionCode = verCode + versionName = verName + + signingConfigs.create("config") { + val androidStoreFile = project.findProperty("androidStoreFile") as String? + if (!androidStoreFile.isNullOrEmpty()) { + storeFile = file(androidStoreFile) + storePassword = project.property("androidStorePassword") as String + keyAlias = project.property("androidKeyAlias") as String + keyPassword = project.property("androidKeyPassword") as String + } + } + + externalNativeBuild { + cmake { + arguments += "-DEXTERNAL_ROOT=${File(rootDir.absolutePath, "core/external")}" + arguments += "-DCORE_ROOT=${File(rootDir.absolutePath, "core/core/src/main/jni")}" + abiFilters("arm64-v8a", "armeabi-v7a", "x86", "x86_64") + val flags = arrayOf( + "-Wall", + "-Qunused-arguments", + "-Wno-gnu-string-literal-operator-template", + "-fno-rtti", + "-fvisibility=hidden", + "-fvisibility-inlines-hidden", + "-fno-exceptions", + "-fno-stack-protector", + "-fomit-frame-pointer", + "-Wno-builtin-macro-redefined", + "-Wno-unused-value", + "-D__FILE__=__FILE_NAME__", + ) + cppFlags("-std=c++20", *flags) + cFlags("-std=c18", *flags) + arguments( + "-DANDROID_STL=none", + "-DVERSION_CODE=$verCode", + "-DVERSION_NAME=$verName", + ) + } + } + } + + compileOptions { + targetCompatibility(androidTargetCompatibility) + sourceCompatibility(androidSourceCompatibility) + } + + buildTypes { + all { + signingConfig = if (signingConfigs["config"].storeFile != null) signingConfigs["config"] else signingConfigs["debug"] + } + named("debug") { + externalNativeBuild { + cmake { + arguments.addAll( + arrayOf( + "-DCMAKE_CXX_FLAGS_DEBUG=-Og", + "-DCMAKE_C_FLAGS_DEBUG=-Og", + ) + ) + } + } + } + named("release") { + externalNativeBuild { + cmake { + val flags = arrayOf( + "-Wl,--exclude-libs,ALL", + "-ffunction-sections", + "-fdata-sections", + "-Wl,--gc-sections", + "-fno-unwind-tables", + "-fno-asynchronous-unwind-tables", + "-flto=thin", + "-Wl,--thinlto-cache-policy,cache_size_bytes=300m", + "-Wl,--thinlto-cache-dir=${buildDir.absolutePath}/.lto-cache", + ) + cppFlags.addAll(flags) + cFlags.addAll(flags) + val configFlags = arrayOf( + "-Oz", + "-DNDEBUG" + ).joinToString(" ") + arguments.addAll( + arrayOf( + "-DCMAKE_CXX_FLAGS_RELEASE=$configFlags", + "-DCMAKE_CXX_FLAGS_RELWITHDEBINFO=$configFlags", + "-DCMAKE_C_FLAGS_RELEASE=$configFlags", + "-DCMAKE_C_FLAGS_RELWITHDEBINFO=$configFlags", + "-DDEBUG_SYMBOLS_PATH=${buildDir.absolutePath}/symbols", + ) + ) + } + } + } + } + } + + extensions.findByType(ApplicationExtension::class)?.lint { + abortOnError = true + checkReleaseBuilds = false + } + + extensions.findByType(ApplicationAndroidComponentsExtension::class)?.let { androidComponents -> + val optimizeReleaseRes = task("optimizeReleaseRes").doLast { + val aapt2 = File( + androidComponents.sdkComponents.sdkDirectory.get().asFile, + "build-tools/${androidBuildToolsVersion}/aapt2" + ) + val zip = java.nio.file.Paths.get( + project.buildDir.path, + "intermediates", + "optimized_processed_res", + "release", + "resources-release-optimize.ap_" + ) + val optimized = File("${zip}.opt") + val cmd = exec { + commandLine( + aapt2, "optimize", + "--collapse-resource-names", + "--enable-sparse-encoding", + "-o", optimized, + zip + ) + isIgnoreExitValue = false + } + if (cmd.exitValue == 0) { + delete(zip) + optimized.renameTo(zip.toFile()) + } + } + + tasks.whenTaskAdded { + if (name == "optimizeReleaseResources") { + finalizedBy(optimizeReleaseRes) + } + } + } +} + +subprojects { + plugins.withId("com.android.application") { + configureBaseExtension() + } + plugins.withId("com.android.library") { + configureBaseExtension() + } +} diff --git a/core b/core index 216a6f0..e0de4ca 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 216a6f00435b4ab00f5fadc80c1c3b1e7ac9b20c +Subproject commit e0de4ca6d7c1757de85094672a8c069e6a90fb65 diff --git a/gradle.properties b/gradle.properties index 6a7638b..c43f29b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,20 +1,8 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true - -version_name=1.0 -version_code=1 - +android.experimental.enableNewResourceShrinker=true +android.experimental.enableNewResourceShrinker.preciseShrinking=true +android.enableAppCompileTimeRClass=true +android.nonTransitiveRClass=true +android.enableR8.fullMode=true android.useAndroidX=true - +agpVersion=7.1.2 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c17f829..d4b2d1b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/imanager/build.gradle.kts b/imanager/build.gradle.kts index df41b2f..4e6cd2a 100644 --- a/imanager/build.gradle.kts +++ b/imanager/build.gradle.kts @@ -1,11 +1,3 @@ -val androidMinSdkVersion: Int by rootProject.extra -val androidTargetSdkVersion: Int by rootProject.extra -val androidCompileSdkVersion: Int by rootProject.extra -val androidBuildToolsVersion: String by rootProject.extra - -val androidSourceCompatibility: JavaVersion by rootProject.extra -val androidTargetCompatibility: JavaVersion by rootProject.extra - plugins { id("com.android.library") } @@ -16,25 +8,13 @@ android { dimension = "api" } - compileSdk = androidCompileSdkVersion - - defaultConfig { - minSdk = androidMinSdkVersion - targetSdk = androidTargetSdkVersion - } - buildTypes { release { isMinifyEnabled = true } } - - compileOptions { - sourceCompatibility = androidSourceCompatibility - targetCompatibility = androidTargetCompatibility - } } dependencies { - api(project(":daemon-service")) + api(projects.services.daemonService) } diff --git a/manager/build.gradle.kts b/manager/build.gradle.kts index 38e5638..002280b 100644 --- a/manager/build.gradle.kts +++ b/manager/build.gradle.kts @@ -1,19 +1,8 @@ -import com.android.build.gradle.BaseExtension - -val androidCompileSdkVersion: Int by rootProject.extra -val androidMinSdkVersion: Int by rootProject.extra -val androidTargetSdkVersion: Int by rootProject.extra - val defaultManagerPackageName: String by rootProject.extra val apiCode: Int by rootProject.extra -val verCode: Int by rootProject.extra -val verName: String by rootProject.extra val coreVerCode: Int by rootProject.extra val coreVerName: String by rootProject.extra -val androidSourceCompatibility: JavaVersion by rootProject.extra -val androidTargetCompatibility: JavaVersion by rootProject.extra - plugins { id("com.android.application") id("kotlin-parcelize") @@ -21,14 +10,8 @@ plugins { } android { - compileSdk = androidCompileSdkVersion - defaultConfig { applicationId = defaultManagerPackageName - minSdk = androidMinSdkVersion - targetSdk = androidTargetSdkVersion - versionCode = verCode - versionName = verName buildConfigField("int", "API_CODE", """$apiCode""") buildConfigField("int", "CORE_VERSION_CODE", """$coreVerCode""") @@ -39,15 +22,9 @@ android { release { isMinifyEnabled = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - signingConfig = projects.app.dependencyProject.extensions.getByName("android").buildTypes["release"].signingConfig } } - compileOptions { - sourceCompatibility = androidSourceCompatibility - targetCompatibility = androidTargetCompatibility - } - kotlinOptions { jvmTarget = "11" } @@ -70,7 +47,7 @@ afterEvaluate { task("copy${variantCapped}Assets") { dependsOn(":appstub:copy$variantCapped") - dependsOn(":app:copyRiru$variantCapped") + dependsOn(":patch-loader:copy$variantCapped") tasks["merge${variantCapped}Assets"].dependsOn(this) into("$buildDir/intermediates/assets/$variantLowered/merge${variantCapped}Assets") @@ -92,11 +69,11 @@ dependencies { implementation("androidx.core:core-ktx:1.7.0") implementation("androidx.activity:activity-compose:1.5.0-alpha03") implementation("androidx.compose.material:material-icons-extended:1.1.1") - implementation("androidx.compose.material3:material3:1.0.0-alpha06") + implementation("androidx.compose.material3:material3:1.0.0-alpha07") implementation("androidx.compose.runtime:runtime-livedata:1.1.1") implementation("androidx.compose.ui:ui:1.1.1") implementation("androidx.compose.ui:ui-tooling:1.1.1") - implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0-alpha03") + implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0-alpha04") implementation("androidx.navigation:navigation-compose:2.5.0-alpha03") implementation("androidx.preference:preference:1.2.0") implementation("com.google.accompanist:accompanist-drawablepainter:0.24.2-alpha") diff --git a/patch-jar/build.gradle.kts b/patch-jar/build.gradle.kts index 4376efe..86fc9b0 100644 --- a/patch-jar/build.gradle.kts +++ b/patch-jar/build.gradle.kts @@ -35,13 +35,13 @@ val jar = tasks.jar.get() tasks.register("buildDebug") { jar.dependsOn(":appstub:copyDebug") - jar.dependsOn(":app:copyRiruDebug") + jar.dependsOn(":patch-loader:copyDebug") dependsOn(tasks.build) } tasks.register("buildRelease") { jar.dependsOn(":appstub:copyRelease") - jar.dependsOn(":app:copyRiruRelease") + jar.dependsOn(":patch-loader:copyRelease") dependsOn(tasks.build) } diff --git a/patch-loader/.gitignore b/patch-loader/.gitignore new file mode 100644 index 0000000..9ff2a37 --- /dev/null +++ b/patch-loader/.gitignore @@ -0,0 +1,2 @@ +/build +/.cxx diff --git a/patch-loader/build.gradle.kts b/patch-loader/build.gradle.kts new file mode 100644 index 0000000..b060403 --- /dev/null +++ b/patch-loader/build.gradle.kts @@ -0,0 +1,74 @@ +plugins { + id("com.android.application") +} + +android { + defaultConfig { + multiDexEnabled = false + } + + buildTypes { + debug { + isDebuggable = true + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + release { + isDebuggable = false + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + + externalNativeBuild { + cmake { + path("src/main/jni/CMakeLists.txt") + } + } + + lint { + abortOnError = false + } +} + +androidComponents.onVariants { variant -> + val variantCapped = variant.name.capitalize() + + task("copyDex$variantCapped") { + dependsOn("assemble$variantCapped") + from("$buildDir/intermediates/dex/$variantCapped/mergeDex$variantCapped/classes.dex") + rename("classes.dex", "lsp.dex") + into("${rootProject.projectDir}/out/assets/dex") + } + + task("copySo$variantCapped") { + dependsOn("assemble$variantCapped") + from( + fileTree( + "dir" to "$buildDir/intermediates/merged_native_libs/$variantCapped/out/lib", + "include" to listOf("**/liblspatch.so") + ) + ) + into("${rootProject.projectDir}/out/assets/so") + } + + task("copy$variantCapped") { + dependsOn("copySo$variantCapped") + dependsOn("copyDex$variantCapped") + + doLast { + println("Dex and so files has been copied to ${rootProject.projectDir}${File.separator}out") + } + } +} + +dependencies { + compileOnly(projects.hiddenapi.stubs) + implementation(projects.core) + implementation(projects.hiddenapi.bridge) + implementation(projects.services.daemonService) + implementation(projects.imanager) + implementation(projects.share) + + implementation("com.google.code.gson:gson:2.9.0") +} diff --git a/app/proguard-rules.pro b/patch-loader/proguard-rules.pro similarity index 100% rename from app/proguard-rules.pro rename to patch-loader/proguard-rules.pro diff --git a/patch-loader/src/main/AndroidManifest.xml b/patch-loader/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a1f5f27 --- /dev/null +++ b/patch-loader/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/app/src/main/java/de/robv/android/xposed/XposedHelper.java b/patch-loader/src/main/java/de/robv/android/xposed/XposedHelper.java similarity index 100% rename from app/src/main/java/de/robv/android/xposed/XposedHelper.java rename to patch-loader/src/main/java/de/robv/android/xposed/XposedHelper.java diff --git a/app/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java b/patch-loader/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java similarity index 97% rename from app/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java rename to patch-loader/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java index b256e0d..21e89bc 100644 --- a/app/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java +++ b/patch-loader/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java @@ -29,7 +29,7 @@ import org.lsposed.lspatch.manager.ModuleLoader; import org.lsposed.lspatch.share.Constants; import org.lsposed.lspatch.share.PatchConfig; import org.lsposed.lspd.config.ApplicationServiceClient; -import org.lsposed.lspd.core.Main; +import org.lsposed.lspd.core.Startup; import org.lsposed.lspd.models.Module; import org.lsposed.lspd.nativebridge.SigBypass; @@ -53,7 +53,6 @@ import java.util.zip.ZipFile; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedHelpers; -import de.robv.android.xposed.XposedInit; import hidden.HiddenApiBridge; /** @@ -104,10 +103,9 @@ public class LSPApplication extends ApplicationServiceClient { try { disableProfile(context); loadModules(context); - Main.forkPostCommon(false, context.getDataDir().toString(), ActivityThread.currentProcessName()); - doHook(context); + Startup.initXposed(false); Log.i(TAG, "Start loading modules"); - XposedInit.loadModules(); + Startup.bootstrapXposed(ActivityThread.currentProcessName()); // WARN: Since it uses `XResource`, the following class should not be initialized // before forkPostCommon is invoke. Otherwise, you will get failure of XResources LSPLoader.initModules(appLoadedApk); @@ -116,9 +114,11 @@ public class LSPApplication extends ApplicationServiceClient { switchClassLoader("mBaseClassLoader"); switchClassLoader("mDefaultClassLoader"); switchClassLoader("mClassLoader"); + doSigBypass(context); } catch (Throwable e) { Log.e(TAG, "Do hook", e); } + Log.i(TAG, "LSPatch bootstrap completed"); } private static Context createLoadedApkWithContext() { @@ -294,7 +294,7 @@ public class LSPApplication extends ApplicationServiceClient { return field.getInt(null); } - private static void byPassSignature(Context context) throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException { + private static void bypassSignature(Context context) throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException { final int TRANSACTION_getPackageInfo = getTranscationId("android.content.pm.IPackageManager$Stub", "TRANSACTION_getPackageInfo"); XposedHelpers.findAndHookMethod("android.os.BinderProxy", null, "transact", int.class, Parcel.class, Parcel.class, int.class, new XC_MethodHook() { @Override @@ -359,10 +359,10 @@ public class LSPApplication extends ApplicationServiceClient { }); } - private static void doHook(Context context) throws IllegalAccessException, ClassNotFoundException, IOException, NoSuchFieldException { + private static void doSigBypass(Context context) throws IllegalAccessException, ClassNotFoundException, IOException, NoSuchFieldException { if (config.sigBypassLevel >= Constants.SIGBYPASS_LV_PM) { XLog.d(TAG, "Original signature: " + config.originalSignature.substring(0, 16) + "..."); - byPassSignature(context); + bypassSignature(context); } if (config.sigBypassLevel >= Constants.SIGBYPASS_LV_PM_OPENAT) { String cacheApkPath; diff --git a/app/src/main/java/org/lsposed/lspatch/loader/LSPLoader.java b/patch-loader/src/main/java/org/lsposed/lspatch/loader/LSPLoader.java similarity index 100% rename from app/src/main/java/org/lsposed/lspatch/loader/LSPLoader.java rename to patch-loader/src/main/java/org/lsposed/lspatch/loader/LSPLoader.java diff --git a/app/src/main/java/org/lsposed/lspatch/loader/ManagerResolver.java b/patch-loader/src/main/java/org/lsposed/lspatch/loader/ManagerResolver.java similarity index 100% rename from app/src/main/java/org/lsposed/lspatch/loader/ManagerResolver.java rename to patch-loader/src/main/java/org/lsposed/lspatch/loader/ManagerResolver.java diff --git a/app/src/main/java/org/lsposed/lspatch/loader/util/FileUtils.java b/patch-loader/src/main/java/org/lsposed/lspatch/loader/util/FileUtils.java similarity index 100% rename from app/src/main/java/org/lsposed/lspatch/loader/util/FileUtils.java rename to patch-loader/src/main/java/org/lsposed/lspatch/loader/util/FileUtils.java diff --git a/app/src/main/java/org/lsposed/lspatch/loader/util/XLog.java b/patch-loader/src/main/java/org/lsposed/lspatch/loader/util/XLog.java similarity index 95% rename from app/src/main/java/org/lsposed/lspatch/loader/util/XLog.java rename to patch-loader/src/main/java/org/lsposed/lspatch/loader/util/XLog.java index c769e8d..a7e9fd8 100644 --- a/app/src/main/java/org/lsposed/lspatch/loader/util/XLog.java +++ b/patch-loader/src/main/java/org/lsposed/lspatch/loader/util/XLog.java @@ -1,7 +1,6 @@ package org.lsposed.lspatch.loader.util; - -import org.lsposed.lspd.BuildConfig; +import org.lsposed.lspatch.loader.BuildConfig; public class XLog { diff --git a/patch-loader/src/main/java/org/lsposed/lspd/nativebridge/SigBypass.java b/patch-loader/src/main/java/org/lsposed/lspd/nativebridge/SigBypass.java new file mode 100644 index 0000000..8fd4ccf --- /dev/null +++ b/patch-loader/src/main/java/org/lsposed/lspd/nativebridge/SigBypass.java @@ -0,0 +1,5 @@ +package org.lsposed.lspd.nativebridge; + +public class SigBypass { + public static native void enableOpenatHook(String origApkPath, String cacheApkPath); +} diff --git a/patch-loader/src/main/jni/CMakeLists.txt b/patch-loader/src/main/jni/CMakeLists.txt new file mode 100644 index 0000000..5f1e66d --- /dev/null +++ b/patch-loader/src/main/jni/CMakeLists.txt @@ -0,0 +1,27 @@ +project(lspatch) +cmake_minimum_required(VERSION 3.4.1) + +add_subdirectory(${CORE_ROOT} core) + +aux_source_directory(src SRC_LIST) +aux_source_directory(src/jni SRC_LIST) +set(SRC_LIST ${SRC_LIST} api/patch_main.cpp) + +add_library(${PROJECT_NAME} SHARED ${SRC_LIST}) + +target_include_directories(${PROJECT_NAME} PUBLIC include) +target_include_directories(${PROJECT_NAME} PRIVATE src) + +target_link_libraries(${PROJECT_NAME} core log) + +if (DEFINED DEBUG_SYMBOLS_PATH) + set(DEBUG_SYMBOLS_PATH ${DEBUG_SYMBOLS_PATH}/${API}) + message(STATUS "Debug symbols will be placed at ${DEBUG_SYMBOLS_PATH}") + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${DEBUG_SYMBOLS_PATH}/${ANDROID_ABI} + COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $ + ${DEBUG_SYMBOLS_PATH}/${ANDROID_ABI}/${PROJECT_NAME}.debug + COMMAND ${CMAKE_STRIP} --strip-all $ + COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink ${DEBUG_SYMBOLS_PATH}/${ANDROID_ABI}/${PROJECT_NAME}.debug + $) +endif() diff --git a/patch-loader/src/main/jni/api/patch_main.cpp b/patch-loader/src/main/jni/api/patch_main.cpp new file mode 100644 index 0000000..1be8db0 --- /dev/null +++ b/patch-loader/src/main/jni/api/patch_main.cpp @@ -0,0 +1,36 @@ +/* + * This file is part of LSPosed. + * + * LSPosed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LSPosed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LSPosed. If not, see . + * + * Copyright (C) 2022 LSPosed Contributors + */ + +// +// Created by Nullptr on 2022/3/17. +// + +#include + +#include "patch_loader.h" + +JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { + return JNI_ERR; + } + lspd::PatchLoader::Init(); + lspd::PatchLoader::GetInstance()->Load(env); + return JNI_VERSION_1_6; +} diff --git a/patch-loader/src/main/jni/include/art/runtime/jit/profile_saver.h b/patch-loader/src/main/jni/include/art/runtime/jit/profile_saver.h new file mode 100644 index 0000000..ca54350 --- /dev/null +++ b/patch-loader/src/main/jni/include/art/runtime/jit/profile_saver.h @@ -0,0 +1,56 @@ +// +// Created by loves on 6/19/2021. +// + +#ifndef LSPATCH_PROFILE_SAVER_H +#define LSPATCH_PROFILE_SAVER_H + +#include "utils/hook_helper.hpp" + +using namespace lsplant; + +namespace art { + CREATE_MEM_HOOK_STUB_ENTRY( + "_ZN3art12ProfileSaver20ProcessProfilingInfoEbPt", + bool, ProcessProfilingInfo, (void * thiz, bool, uint16_t *), { + LOGD("skipped profile saving"); + return true; + }); + + CREATE_MEM_HOOK_STUB_ENTRY( + "_ZN3art12ProfileSaver20ProcessProfilingInfoEbbPt", + bool, ProcessProfilingInfoWithBool, (void * thiz, bool, bool, uint16_t *), { + LOGD("skipped profile saving"); + return true; + }); + + CREATE_HOOK_STUB_ENTRY( + "execve", + int, execve, (const char *pathname, const char *argv[], char *const envp[]), { + if (strstr(pathname, "dex2oat")) { + size_t count = 0; + while (argv[count++] != nullptr); + std::unique_ptr new_args = std::make_unique( + count + 1); + for (size_t i = 0; i < count - 1; ++i) + new_args[i] = argv[i]; + new_args[count - 1] = "--inline-max-code-units=0"; + new_args[count] = nullptr; + + LOGD("dex2oat by disable inline!"); + int ret = backup(pathname, new_args.get(), envp); + return ret; + } + int ret = backup(pathname, argv, envp); + return ret; + }); + + + static void DisableInline(const HookHandler &handler) { + HookSyms(handler, ProcessProfilingInfo, ProcessProfilingInfoWithBool); + HookSymNoHandle(handler, reinterpret_cast(&::execve), execve); + } +} + + +#endif //LSPATCH_PROFILE_SAVER_H diff --git a/patch-loader/src/main/jni/include/art/runtime/oat_file_manager.h b/patch-loader/src/main/jni/include/art/runtime/oat_file_manager.h new file mode 100644 index 0000000..d72be48 --- /dev/null +++ b/patch-loader/src/main/jni/include/art/runtime/oat_file_manager.h @@ -0,0 +1,64 @@ +/* + * This file is part of LSPosed. + * + * LSPosed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LSPosed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LSPosed. If not, see . + * + * Copyright (C) 2021 - 2022 LSPosed Contributors + */ + +#ifndef LSPATCH_OAT_FILE_MANAGER_H +#define LSPATCH_OAT_FILE_MANAGER_H + +#include "context.h" +#include "utils/hook_helper.hpp" + +using namespace lsplant; + +namespace art { + CREATE_MEM_HOOK_STUB_ENTRY( + "_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobjectPKc", + void, RunBackgroundVerificationWithContext, + (void * thiz, const std::vector &dex_files, + jobject class_loader, + const char *class_loader_context), { + if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) { + LOGD("Disabled background verification"); + return; + } + backup(thiz, dex_files, class_loader, class_loader_context); + }); + + CREATE_MEM_HOOK_STUB_ENTRY( + "_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobject", + void, RunBackgroundVerification, + (void * thiz, const std::vector &dex_files, + jobject class_loader), { + if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) { + LOGD("Disabled background verification"); + return; + } + backup(thiz, dex_files, class_loader); + }); + + + static void DisableBackgroundVerification(const lsplant::HookHandler &handler) { + const int api_level = lspd::GetAndroidApiLevel(); + if (api_level >= __ANDROID_API_Q__) { + HookSyms(handler, RunBackgroundVerificationWithContext, RunBackgroundVerification); + } + } +} + + +#endif //LSPATCH_OAT_FILE_MANAGER_H diff --git a/patch-loader/src/main/jni/src/jni/bypass_sig.cpp b/patch-loader/src/main/jni/src/jni/bypass_sig.cpp new file mode 100644 index 0000000..c546fbc --- /dev/null +++ b/patch-loader/src/main/jni/src/jni/bypass_sig.cpp @@ -0,0 +1,51 @@ +// +// Created by VIP on 2021/4/25. +// + +#include "bypass_sig.h" +#include "elf_util.h" +#include "logging.h" +#include "native_util.h" +#include "patch_loader.h" +#include "utils/hook_helper.hpp" +#include "utils/jni_helper.hpp" + +namespace lspd { + + std::string apkPath; + std::string redirectPath; + + CREATE_HOOK_STUB_ENTRY( + "__openat", + int, __openat, + (int fd, const char* pathname, int flag, int mode), { + if (pathname == apkPath) { + LOGD("redirect openat"); + return backup(fd, redirectPath.c_str(), flag, mode); + } + return backup(fd, pathname, flag, mode); + }); + + LSP_DEF_NATIVE_METHOD(void, SigBypass, enableOpenatHook, jstring origApkPath, jstring cacheApkPath) { + auto sym_openat = SandHook::ElfImg("libc.so").getSymbAddress("__openat"); + auto r = HookSymNoHandle(handler, sym_openat, __openat); + if (!r) { + LOGE("Hook __openat fail"); + return; + } + lsplant::JUTFString str1(env, origApkPath); + lsplant::JUTFString str2(env, cacheApkPath); + apkPath = str1.get(); + redirectPath = str2.get(); + LOGD("apkPath %s", apkPath.c_str()); + LOGD("redirectPath %s", redirectPath.c_str()); + } + + static JNINativeMethod gMethods[] = { + LSP_NATIVE_METHOD(SigBypass, enableOpenatHook, "(Ljava/lang/String;Ljava/lang/String;)V") + }; + + void RegisterBypass(JNIEnv* env) { + REGISTER_LSP_NATIVE_METHODS(SigBypass); + } +} diff --git a/patch-loader/src/main/jni/src/jni/bypass_sig.h b/patch-loader/src/main/jni/src/jni/bypass_sig.h new file mode 100644 index 0000000..66b69ce --- /dev/null +++ b/patch-loader/src/main/jni/src/jni/bypass_sig.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace lspd { + + void RegisterBypass(JNIEnv* env); + +} // namespace lspd diff --git a/patch-loader/src/main/jni/src/patch_loader.cpp b/patch-loader/src/main/jni/src/patch_loader.cpp new file mode 100644 index 0000000..fc727aa --- /dev/null +++ b/patch-loader/src/main/jni/src/patch_loader.cpp @@ -0,0 +1,118 @@ +/* + * This file is part of LSPosed. + * + * LSPosed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LSPosed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LSPosed. If not, see . + * + * Copyright (C) 2022 LSPosed Contributors + */ + +// +// Created by Nullptr on 2022/3/17. +// + +#include "art/runtime/oat_file_manager.h" +#include "art/runtime/jit/profile_saver.h" +#include "elf_util.h" +#include "jni/bypass_sig.h" +#include "native_hook.h" +#include "native_util.h" +#include "patch_loader.h" +#include "symbol_cache.h" +#include "utils/jni_helper.hpp" + +using namespace lsplant; + +namespace lspd { + + void PatchLoader::LoadDex(JNIEnv* env, Context::PreloadedDex&& dex) { + auto class_activity_thread = JNI_FindClass(env, "android/app/ActivityThread"); + auto class_activity_thread_app_bind_data = JNI_FindClass(env, "android/app/ActivityThread$AppBindData"); + auto class_loaded_apk = JNI_FindClass(env, "android/app/LoadedApk"); + + auto mid_current_activity_thread = JNI_GetStaticMethodID(env, class_activity_thread, "currentActivityThread", + "()Landroid/app/ActivityThread;"); + auto mid_get_classloader = JNI_GetMethodID(env, class_loaded_apk, "getClassLoader", "()Ljava/lang/ClassLoader;"); + auto fid_m_bound_application = JNI_GetFieldID(env, class_activity_thread, "mBoundApplication", + "Landroid/app/ActivityThread$AppBindData;"); + auto fid_info = JNI_GetFieldID(env, class_activity_thread_app_bind_data, "info", "Landroid/app/LoadedApk;"); + + auto activity_thread = JNI_CallStaticObjectMethod(env, class_activity_thread, mid_current_activity_thread); + auto m_bound_application = JNI_GetObjectField(env, activity_thread, fid_m_bound_application); + auto info = JNI_GetObjectField(env, m_bound_application, fid_info); + auto stub_classloader = JNI_CallObjectMethod(env, info, mid_get_classloader); + + if (!stub_classloader) [[unlikely]] { + LOGE("getStubClassLoader failed!!!"); + return; + } + + auto in_memory_classloader = JNI_FindClass(env, "dalvik/system/InMemoryDexClassLoader"); + auto mid_init = JNI_GetMethodID(env, in_memory_classloader, "", + "(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V"); + auto byte_buffer_class = JNI_FindClass(env, "java/nio/ByteBuffer"); + auto dex_buffer = env->NewDirectByteBuffer(dex.data(), dex.size()); + if (auto my_cl = JNI_NewObject(env, in_memory_classloader, mid_init, dex_buffer, stub_classloader)) { + inject_class_loader_ = JNI_NewGlobalRef(env, my_cl); + } else { + LOGE("InMemoryDexClassLoader creation failed!!!"); + return; + } + + env->DeleteLocalRef(dex_buffer); + } + + void PatchLoader::InitHooks(JNIEnv* env, const lsplant::InitInfo& initInfo) { + handler = initInfo; + Context::InitHooks(env, handler); + art::DisableInline(handler); + art::DisableBackgroundVerification(handler); + RegisterBypass(env); + } + + void PatchLoader::SetupEntryClass(JNIEnv* env) { + if (auto entry_class = FindClassFromLoader(env, GetCurrentClassLoader(), + "org.lsposed.lspatch.loader.LSPApplication")) { + entry_class_ = JNI_NewGlobalRef(env, entry_class); + } + } + + void PatchLoader::Load(JNIEnv* env) { + InitSymbolCache(nullptr); + lsplant::InitInfo initInfo{ + .inline_hooker = [](auto t, auto r) { + void* bk = nullptr; + return HookFunction(t, r, &bk) == RS_SUCCESS ? bk : nullptr; + }, + .inline_unhooker = [](auto t) { + return UnhookFunction(t) == RT_SUCCESS; + }, + .art_symbol_resolver = [](auto symbol) { + return GetArt()->getSymbAddress(symbol); + }, + }; + InstallInlineHooks(initInfo); + + auto stub = JNI_FindClass(env, "org/lsposed/lspatch/appstub/LSPAppComponentFactoryStub"); + auto dex_field = JNI_GetStaticFieldID(env, stub, "dex", "[B"); + + auto array = (jbyteArray) env->GetStaticObjectField(stub, dex_field); + auto dex = PreloadedDex{env->GetByteArrayElements(array, nullptr), static_cast(JNI_GetArrayLength(env, array))}; + + LoadDex(env, std::move(dex)); + InitHooks(env, initInfo); + + SetupEntryClass(env); + FindAndCall(env, "onLoad", "()V"); + } +} // namespace lspd diff --git a/patch-loader/src/main/jni/src/patch_loader.h b/patch-loader/src/main/jni/src/patch_loader.h new file mode 100644 index 0000000..56fcd40 --- /dev/null +++ b/patch-loader/src/main/jni/src/patch_loader.h @@ -0,0 +1,51 @@ +/* + * This file is part of LSPosed. + * + * LSPosed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LSPosed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LSPosed. If not, see . + * + * Copyright (C) 2022 LSPosed Contributors + */ + +// +// Created by Nullptr on 2022/3/17. +// + +#pragma once + +#include "context.h" + +namespace lspd { + + inline lsplant::InitInfo handler; + + class PatchLoader : public Context { + public: + inline static void Init() { + instance_ = std::make_unique(); + } + + inline static PatchLoader* GetInstance() { + return static_cast(instance_.get()); + } + + void Load(JNIEnv* env); + + protected: + void InitHooks(JNIEnv* env, const lsplant::InitInfo& initInfo) override; + + void LoadDex(JNIEnv* env, PreloadedDex&& dex) override; + + void SetupEntryClass(JNIEnv* env) override; + }; +} // namespace lspd diff --git a/patch/src/main/java/org/lsposed/patch/LSPatch.java b/patch/src/main/java/org/lsposed/patch/LSPatch.java index 2713f83..6fea97f 100644 --- a/patch/src/main/java/org/lsposed/patch/LSPatch.java +++ b/patch/src/main/java/org/lsposed/patch/LSPatch.java @@ -240,8 +240,8 @@ public class LSPatch { // copy so and dex files into the unzipped apk // do not put liblspd.so into apk!lib because x86 native bridge causes crash for (String arch : APK_LIB_PATH_ARRAY) { - String entryName = "assets/lspatch/lspd/" + arch + "/liblspd.so"; - try (var is = getClass().getClassLoader().getResourceAsStream("assets/so/" + (arch.equals("arm") ? "armeabi-v7a" : (arch.equals("arm64") ? "arm64-v8a" : arch)) + "/liblspd.so")) { + String entryName = "assets/lspatch/so/" + arch + "/liblspatch.so"; + try (var is = getClass().getClassLoader().getResourceAsStream("assets/so/" + (arch.equals("arm") ? "armeabi-v7a" : (arch.equals("arm64") ? "arm64-v8a" : arch)) + "/liblspatch.so")) { dstZFile.add(entryName, is, false); // no compress for so } catch (Throwable e) { // More exception info diff --git a/settings.gradle.kts b/settings.gradle.kts index e2cfb5a..f0e2d14 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,27 +1,50 @@ -rootProject.name = "LSPatch" - enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -include(":daemon-service") -include(":hiddenapi-bridge") -include(":hiddenapi-stubs") -include(":interface") -include(":lspcore") -include(":manager-service") +pluginManagement { + val agpVersion: String by settings + repositories { + gradlePluginPortal() + google() + mavenCentral() + } + plugins { + id("com.android.library") version agpVersion + id("com.android.application") version agpVersion + } +} -project(":daemon-service").projectDir = file("core/daemon-service") -project(":hiddenapi-bridge").projectDir = file("core/hiddenapi-bridge") -project(":hiddenapi-stubs").projectDir = file("core/hiddenapi-stubs") -project(":interface").projectDir = file("core/service/interface") -project(":lspcore").projectDir = file("core/core") -project(":manager-service").projectDir = file("core/manager-service") +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} -include(":apkzlib") -include(":app") -include(":appstub") -include(":axmlprinter") -include(":imanager") -include(":manager") -include(":patch") -include(":patch-jar") -include(":share") +rootProject.name = "LSPatch" +include( + ":apkzlib", + ":appstub", + ":axmlprinter", + ":core", + ":hiddenapi:bridge", + ":hiddenapi:stubs", + ":imanager", + ":manager", + ":patch", + ":patch-jar", + ":patch-loader", + ":services:daemon-service", + ":services:manager-service", + ":services:xposed-service:interface", + ":share" +) + +project(":core").projectDir = file("core/core") +project(":hiddenapi:bridge").projectDir = file("core/hiddenapi/bridge") +project(":hiddenapi:stubs").projectDir = file("core/hiddenapi/stubs") +project(":services:daemon-service").projectDir = file("core/services/daemon-service") +project(":services:manager-service").projectDir = file("core/services/manager-service") +project(":services:xposed-service:interface").projectDir = file("core/services/xposed-service/interface") + +buildCache { local { removeUnusedEntriesAfterDays = 1 } }